aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Agent/AssetTransaction
diff options
context:
space:
mode:
authorsacha2010-12-04 21:50:48 +0000
committersacha2010-12-04 21:50:48 +0000
commit835103af82eb0b8c0916bbbe3c5a981e92e5a47e (patch)
tree154f02cada4bf550b7278aef31c42f9ba8da3ef5 /OpenSim/Region/CoreModules/Agent/AssetTransaction
parentadd more detail to the log in case of FORM Timeout (diff)
parentAdd some safeguards: DOn't send someone else's HUDs, don't send deleted prims (diff)
downloadopensim-SC-835103af82eb0b8c0916bbbe3c5a981e92e5a47e.zip
opensim-SC-835103af82eb0b8c0916bbbe3c5a981e92e5a47e.tar.gz
opensim-SC-835103af82eb0b8c0916bbbe3c5a981e92e5a47e.tar.bz2
opensim-SC-835103af82eb0b8c0916bbbe3c5a981e92e5a47e.tar.xz
Merge branch 'careminster-presence-refactor' of ssh://3dhosting.de/var/git/careminster into careminster-presence-refactor
Diffstat (limited to 'OpenSim/Region/CoreModules/Agent/AssetTransaction')
-rw-r--r--OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs136
-rw-r--r--OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs166
-rw-r--r--OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs158
3 files changed, 280 insertions, 180 deletions
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs
index 3d6e7f3..85e1c99 100644
--- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs
+++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs
@@ -41,19 +41,22 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
41 /// </summary> 41 /// </summary>
42 public class AgentAssetTransactions 42 public class AgentAssetTransactions
43 { 43 {
44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 44 private static readonly ILog m_log = LogManager.GetLogger(
45 MethodBase.GetCurrentMethod().DeclaringType);
45 46
46 // Fields 47 // Fields
47 private bool m_dumpAssetsToFile; 48 private bool m_dumpAssetsToFile;
48 public AssetTransactionModule Manager; 49 private Scene m_Scene;
49 public UUID UserID; 50 public UUID UserID;
50 public Dictionary<UUID, AssetXferUploader> XferUploaders = new Dictionary<UUID, AssetXferUploader>(); 51 public Dictionary<UUID, AssetXferUploader> XferUploaders =
52 new Dictionary<UUID, AssetXferUploader>();
51 53
52 // Methods 54 // Methods
53 public AgentAssetTransactions(UUID agentID, AssetTransactionModule manager, bool dumpAssetsToFile) 55 public AgentAssetTransactions(UUID agentID, Scene scene,
56 bool dumpAssetsToFile)
54 { 57 {
58 m_Scene = scene;
55 UserID = agentID; 59 UserID = agentID;
56 Manager = manager;
57 m_dumpAssetsToFile = dumpAssetsToFile; 60 m_dumpAssetsToFile = dumpAssetsToFile;
58 } 61 }
59 62
@@ -61,7 +64,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
61 { 64 {
62 if (!XferUploaders.ContainsKey(transactionID)) 65 if (!XferUploaders.ContainsKey(transactionID))
63 { 66 {
64 AssetXferUploader uploader = new AssetXferUploader(this, m_dumpAssetsToFile); 67 AssetXferUploader uploader = new AssetXferUploader(m_Scene,
68 m_dumpAssetsToFile);
65 69
66 lock (XferUploaders) 70 lock (XferUploaders)
67 { 71 {
@@ -88,22 +92,25 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
88 } 92 }
89 } 93 }
90 94
91 public void RequestCreateInventoryItem(IClientAPI remoteClient, UUID transactionID, UUID folderID, 95 public void RequestCreateInventoryItem(IClientAPI remoteClient,
92 uint callbackID, string description, string name, sbyte invType, 96 UUID transactionID, UUID folderID, uint callbackID,
93 sbyte type, byte wearableType, uint nextOwnerMask) 97 string description, string name, sbyte invType,
98 sbyte type, byte wearableType, uint nextOwnerMask)
94 { 99 {
95 if (XferUploaders.ContainsKey(transactionID)) 100 if (XferUploaders.ContainsKey(transactionID))
96 { 101 {
97 XferUploaders[transactionID].RequestCreateInventoryItem(remoteClient, transactionID, folderID, 102 XferUploaders[transactionID].RequestCreateInventoryItem(
98 callbackID, description, name, invType, type, 103 remoteClient, transactionID, folderID,
99 wearableType, nextOwnerMask); 104 callbackID, description, name, invType, type,
105 wearableType, nextOwnerMask);
100 } 106 }
101 } 107 }
102 108
103 109
104 110
105 /// <summary> 111 /// <summary>
106 /// Get an uploaded asset. If the data is successfully retrieved, the transaction will be removed. 112 /// Get an uploaded asset. If the data is successfully retrieved,
113 /// the transaction will be removed.
107 /// </summary> 114 /// </summary>
108 /// <param name="transactionID"></param> 115 /// <param name="transactionID"></param>
109 /// <returns>The asset if the upload has completed, null if it has not.</returns> 116 /// <returns>The asset if the upload has completed, null if it has not.</returns>
@@ -125,105 +132,66 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
125 return null; 132 return null;
126 } 133 }
127 134
128 //private void CreateItemFromUpload(AssetBase asset, IClientAPI ourClient, UUID inventoryFolderID, uint nextPerms, uint wearableType) 135 public void RequestUpdateTaskInventoryItem(IClientAPI remoteClient,
129 //{ 136 SceneObjectPart part, UUID transactionID,
130 // Manager.MyScene.CommsManager.AssetCache.AddAsset(asset); 137 TaskInventoryItem item)
131 // CachedUserInfo userInfo = Manager.MyScene.CommsManager.UserProfileCacheService.GetUserDetails(
132 // ourClient.AgentId);
133
134 // if (userInfo != null)
135 // {
136 // InventoryItemBase item = new InventoryItemBase();
137 // item.Owner = ourClient.AgentId;
138 // item.Creator = ourClient.AgentId;
139 // item.ID = UUID.Random();
140 // item.AssetID = asset.FullID;
141 // item.Description = asset.Description;
142 // item.Name = asset.Name;
143 // item.AssetType = asset.Type;
144 // item.InvType = asset.Type;
145 // item.Folder = inventoryFolderID;
146 // item.BasePermissions = 0x7fffffff;
147 // item.CurrentPermissions = 0x7fffffff;
148 // item.EveryOnePermissions = 0;
149 // item.NextPermissions = nextPerms;
150 // item.Flags = wearableType;
151 // item.CreationDate = Util.UnixTimeSinceEpoch();
152
153 // userInfo.AddItem(item);
154 // ourClient.SendInventoryItemCreateUpdate(item);
155 // }
156 // else
157 // {
158 // m_log.ErrorFormat(
159 // "[ASSET TRANSACTIONS]: Could not find user {0} for inventory item creation",
160 // ourClient.AgentId);
161 // }
162 //}
163
164 public void RequestUpdateTaskInventoryItem(
165 IClientAPI remoteClient, SceneObjectPart part, UUID transactionID, TaskInventoryItem item)
166 { 138 {
167 if (XferUploaders.ContainsKey(transactionID)) 139 if (XferUploaders.ContainsKey(transactionID))
168 { 140 {
169 AssetBase asset = XferUploaders[transactionID].GetAssetData(); 141 AssetBase asset = GetTransactionAsset(transactionID);
142
143 // Only legacy viewers use this, and they prefer CAPS, which
144 // we have, so this really never runs.
145 // Allow it, but only for "safe" types.
146 if ((InventoryType)item.InvType != InventoryType.Notecard &&
147 (InventoryType)item.InvType != InventoryType.LSL)
148 return;
149
170 if (asset != null) 150 if (asset != null)
171 { 151 {
172 m_log.DebugFormat( 152 asset.FullID = UUID.Random();
173 "[ASSET TRANSACTIONS]: Updating task item {0} in {1} with asset in transaction {2}",
174 item.Name, part.Name, transactionID);
175
176 asset.Name = item.Name; 153 asset.Name = item.Name;
177 asset.Description = item.Description; 154 asset.Description = item.Description;
178 asset.Type = (sbyte)item.Type; 155 asset.Type = (sbyte)item.Type;
179 item.AssetID = asset.FullID; 156 item.AssetID = asset.FullID;
180 157
181 Manager.MyScene.AssetService.Store(asset); 158 m_Scene.AssetService.Store(asset);
182 159
183 if (part.Inventory.UpdateInventoryItem(item)) 160 part.Inventory.UpdateInventoryItem(item);
184 {
185 if ((InventoryType)item.InvType == InventoryType.Notecard)
186 remoteClient.SendAgentAlertMessage("Notecard saved", false);
187 else if ((InventoryType)item.InvType == InventoryType.LSL)
188 remoteClient.SendAgentAlertMessage("Script saved", false);
189 else
190 remoteClient.SendAgentAlertMessage("Item saved", false);
191
192 part.GetProperties(remoteClient);
193 }
194 } 161 }
195 } 162 }
196 } 163 }
197 164
198 165 public void RequestUpdateInventoryItem(IClientAPI remoteClient,
199 public void RequestUpdateInventoryItem(IClientAPI remoteClient, UUID transactionID, 166 UUID transactionID, InventoryItemBase item)
200 InventoryItemBase item)
201 { 167 {
202 if (XferUploaders.ContainsKey(transactionID)) 168 if (XferUploaders.ContainsKey(transactionID))
203 { 169 {
204 UUID assetID = UUID.Combine(transactionID, remoteClient.SecureSessionId); 170 // Here we need to get the old asset to extract the
205 171 // texture UUIDs if it's a wearable.
206 AssetBase asset = Manager.MyScene.AssetService.Get(assetID.ToString()); 172 if (item.AssetType == (int)AssetType.Bodypart ||
207 173 item.AssetType == (int)AssetType.Clothing)
208 if (asset == null)
209 { 174 {
210 asset = GetTransactionAsset(transactionID); 175 AssetBase oldAsset = m_Scene.AssetService.Get(item.AssetID.ToString());
176 if (oldAsset != null)
177 XferUploaders[transactionID].SetOldData(oldAsset.Data);
211 } 178 }
212 179
213 if (asset != null && asset.FullID == assetID) 180 AssetBase asset = GetTransactionAsset(transactionID);
181
182 if (asset != null)
214 { 183 {
215 // Assets never get updated, new ones get created
216 asset.FullID = UUID.Random(); 184 asset.FullID = UUID.Random();
217 asset.Name = item.Name; 185 asset.Name = item.Name;
218 asset.Description = item.Description; 186 asset.Description = item.Description;
219 asset.Type = (sbyte)item.AssetType; 187 asset.Type = (sbyte)item.AssetType;
220 item.AssetID = asset.FullID; 188 item.AssetID = asset.FullID;
221 189
222 Manager.MyScene.AssetService.Store(asset); 190 m_Scene.AssetService.Store(asset);
223 }
224 191
225 IInventoryService invService = Manager.MyScene.InventoryService; 192 IInventoryService invService = m_Scene.InventoryService;
226 invService.UpdateItem(item); 193 invService.UpdateItem(item);
194 }
227 } 195 }
228 } 196 }
229 } 197 }
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs
index ae31050..82558de 100644
--- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs
+++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs
@@ -34,22 +34,19 @@ using OpenMetaverse;
34using OpenSim.Framework; 34using OpenSim.Framework;
35using OpenSim.Region.Framework.Interfaces; 35using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.Framework.Scenes; 36using OpenSim.Region.Framework.Scenes;
37using Mono.Addins;
37 38
38namespace OpenSim.Region.CoreModules.Agent.AssetTransaction 39namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
39{ 40{
40 public class AssetTransactionModule : IRegionModule, IAgentAssetTransactions 41 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "AssetTransactionModule")]
42 public class AssetTransactionModule : INonSharedRegionModule,
43 IAgentAssetTransactions
41 { 44 {
42// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 45// private static readonly ILog m_log = LogManager.GetLogger(
46// MethodBase.GetCurrentMethod().DeclaringType);
43 47
44 private readonly Dictionary<UUID, Scene> RegisteredScenes = new Dictionary<UUID, Scene>(); 48 protected Scene m_Scene;
45 private bool m_dumpAssetsToFile = false; 49 private bool m_dumpAssetsToFile = false;
46 private Scene m_scene = null;
47
48 [Obsolete]
49 public Scene MyScene
50 {
51 get{ return m_scene;}
52 }
53 50
54 /// <summary> 51 /// <summary>
55 /// Each agent has its own singleton collection of transactions 52 /// Each agent has its own singleton collection of transactions
@@ -57,33 +54,24 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
57 private Dictionary<UUID, AgentAssetTransactions> AgentTransactions = 54 private Dictionary<UUID, AgentAssetTransactions> AgentTransactions =
58 new Dictionary<UUID, AgentAssetTransactions>(); 55 new Dictionary<UUID, AgentAssetTransactions>();
59 56
57 #region IRegionModule Members
60 58
61 public AssetTransactionModule() 59 public void Initialise(IConfigSource config)
62 { 60 {
63 //m_log.Debug("creating AgentAssetTransactionModule");
64 } 61 }
65 62
66 #region IRegionModule Members 63 public void AddRegion(Scene scene)
67
68 public void Initialise(Scene scene, IConfigSource config)
69 { 64 {
70 if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID)) 65 m_Scene = scene;
71 { 66 scene.RegisterModuleInterface<IAgentAssetTransactions>(this);
72 // m_log.Debug("initialising AgentAssetTransactionModule"); 67 scene.EventManager.OnNewClient += NewClient;
73 RegisteredScenes.Add(scene.RegionInfo.RegionID, scene); 68 }
74 scene.RegisterModuleInterface<IAgentAssetTransactions>(this);
75
76 scene.EventManager.OnNewClient += NewClient;
77 }
78 69
79 // EVIL HACK! 70 public void RegionLoaded(Scene scene)
80 // This needs killing! 71 {
81 //
82 if (m_scene == null)
83 m_scene = scene;
84 } 72 }
85 73
86 public void PostInitialise() 74 public void RemoveRegion(Scene scene)
87 { 75 {
88 } 76 }
89 77
@@ -96,9 +84,9 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
96 get { return "AgentTransactionModule"; } 84 get { return "AgentTransactionModule"; }
97 } 85 }
98 86
99 public bool IsSharedModule 87 public Type ReplaceableInterface
100 { 88 {
101 get { return true; } 89 get { return typeof(IAgentAssetTransactions); }
102 } 90 }
103 91
104 #endregion 92 #endregion
@@ -111,8 +99,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
111 99
112 #region AgentAssetTransactions 100 #region AgentAssetTransactions
113 /// <summary> 101 /// <summary>
114 /// Get the collection of asset transactions for the given user. If one does not already exist, it 102 /// Get the collection of asset transactions for the given user.
115 /// is created. 103 /// If one does not already exist, it is created.
116 /// </summary> 104 /// </summary>
117 /// <param name="userID"></param> 105 /// <param name="userID"></param>
118 /// <returns></returns> 106 /// <returns></returns>
@@ -122,7 +110,10 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
122 { 110 {
123 if (!AgentTransactions.ContainsKey(userID)) 111 if (!AgentTransactions.ContainsKey(userID))
124 { 112 {
125 AgentAssetTransactions transactions = new AgentAssetTransactions(userID, this, m_dumpAssetsToFile); 113 AgentAssetTransactions transactions =
114 new AgentAssetTransactions(userID, m_Scene,
115 m_dumpAssetsToFile);
116
126 AgentTransactions.Add(userID, transactions); 117 AgentTransactions.Add(userID, transactions);
127 } 118 }
128 119
@@ -131,8 +122,9 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
131 } 122 }
132 123
133 /// <summary> 124 /// <summary>
134 /// Remove the given agent asset transactions. This should be called when a client is departing 125 /// Remove the given agent asset transactions. This should be called
135 /// from a scene (and hence won't be making any more transactions here). 126 /// when a client is departing from a scene (and hence won't be making
127 /// any more transactions here).
136 /// </summary> 128 /// </summary>
137 /// <param name="userID"></param> 129 /// <param name="userID"></param>
138 public void RemoveAgentAssetTransactions(UUID userID) 130 public void RemoveAgentAssetTransactions(UUID userID)
@@ -146,10 +138,10 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
146 } 138 }
147 139
148 /// <summary> 140 /// <summary>
149 /// Create an inventory item from data that has been received through a transaction. 141 /// Create an inventory item from data that has been received through
150 /// 142 /// a transaction.
151 /// This is called when new clothing or body parts are created. It may also be called in other 143 /// This is called when new clothing or body parts are created.
152 /// situations. 144 /// It may also be called in other situations.
153 /// </summary> 145 /// </summary>
154 /// <param name="remoteClient"></param> 146 /// <param name="remoteClient"></param>
155 /// <param name="transactionID"></param> 147 /// <param name="transactionID"></param>
@@ -161,61 +153,72 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
161 /// <param name="type"></param> 153 /// <param name="type"></param>
162 /// <param name="wearableType"></param> 154 /// <param name="wearableType"></param>
163 /// <param name="nextOwnerMask"></param> 155 /// <param name="nextOwnerMask"></param>
164 public void HandleItemCreationFromTransaction(IClientAPI remoteClient, UUID transactionID, UUID folderID, 156 public void HandleItemCreationFromTransaction(IClientAPI remoteClient,
165 uint callbackID, string description, string name, sbyte invType, 157 UUID transactionID, UUID folderID, uint callbackID,
166 sbyte type, byte wearableType, uint nextOwnerMask) 158 string description, string name, sbyte invType,
159 sbyte type, byte wearableType, uint nextOwnerMask)
167 { 160 {
168 // m_log.DebugFormat( 161// m_log.DebugFormat(
169 // "[TRANSACTIONS MANAGER] Called HandleItemCreationFromTransaction with item {0}", name); 162// "[TRANSACTIONS MANAGER] Called HandleItemCreationFromTransaction with item {0}", name);
170 163
171 AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId); 164 AgentAssetTransactions transactions =
165 GetUserTransactions(remoteClient.AgentId);
172 166
173 transactions.RequestCreateInventoryItem( 167 transactions.RequestCreateInventoryItem(remoteClient, transactionID,
174 remoteClient, transactionID, folderID, callbackID, description, 168 folderID, callbackID, description, name, invType, type,
175 name, invType, type, wearableType, nextOwnerMask); 169 wearableType, nextOwnerMask);
176 } 170 }
177 171
178 /// <summary> 172 /// <summary>
179 /// Update an inventory item with data that has been received through a transaction. 173 /// Update an inventory item with data that has been received through a
174 /// transaction.
180 /// 175 ///
181 /// This is called when clothing or body parts are updated (for instance, with new textures or 176 /// This is called when clothing or body parts are updated (for
182 /// colours). It may also be called in other situations. 177 /// instance, with new textures or colours). It may also be called in
178 /// other situations.
183 /// </summary> 179 /// </summary>
184 /// <param name="remoteClient"></param> 180 /// <param name="remoteClient"></param>
185 /// <param name="transactionID"></param> 181 /// <param name="transactionID"></param>
186 /// <param name="item"></param> 182 /// <param name="item"></param>
187 public void HandleItemUpdateFromTransaction(IClientAPI remoteClient, UUID transactionID, 183 public void HandleItemUpdateFromTransaction(IClientAPI remoteClient,
188 InventoryItemBase item) 184 UUID transactionID, InventoryItemBase item)
189 { 185 {
190 // m_log.DebugFormat( 186// m_log.DebugFormat(
191 // "[TRANSACTIONS MANAGER] Called HandleItemUpdateFromTransaction with item {0}", 187// "[TRANSACTIONS MANAGER] Called HandleItemUpdateFromTransaction with item {0}",
192 // item.Name); 188// item.Name);
193 189
194 AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId); 190 AgentAssetTransactions transactions =
191 GetUserTransactions(remoteClient.AgentId);
195 192
196 transactions.RequestUpdateInventoryItem(remoteClient, transactionID, item); 193 transactions.RequestUpdateInventoryItem(remoteClient,
194 transactionID, item);
197 } 195 }
198 196
199 /// <summary> 197 /// <summary>
200 /// Update a task inventory item with data that has been received through a transaction. 198 /// Update a task inventory item with data that has been received
199 /// through a transaction.
201 /// 200 ///
202 /// This is currently called when, for instance, a notecard in a prim is saved. The data is sent 201 /// This is currently called when, for instance, a notecard in a prim
203 /// up through a single AssetUploadRequest. A subsequent UpdateTaskInventory then references the transaction 202 /// is saved. The data is sent up through a single AssetUploadRequest.
203 /// A subsequent UpdateTaskInventory then references the transaction
204 /// and comes through this method. 204 /// and comes through this method.
205 /// </summary> 205 /// </summary>
206 /// <param name="remoteClient"></param> 206 /// <param name="remoteClient"></param>
207 /// <param name="transactionID"></param> 207 /// <param name="transactionID"></param>
208 /// <param name="item"></param> 208 /// <param name="item"></param>
209 public void HandleTaskItemUpdateFromTransaction( 209 public void HandleTaskItemUpdateFromTransaction(IClientAPI remoteClient,
210 IClientAPI remoteClient, SceneObjectPart part, UUID transactionID, TaskInventoryItem item) 210 SceneObjectPart part, UUID transactionID,
211 TaskInventoryItem item)
211 { 212 {
212 // m_log.DebugFormat( 213// m_log.DebugFormat(
213 // "[TRANSACTIONS MANAGER] Called HandleTaskItemUpdateFromTransaction with item {0}", 214// "[TRANSACTIONS MANAGER] Called HandleTaskItemUpdateFromTransaction with item {0}",
214 // item.Name); 215// item.Name);
215 216
216 AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId); 217 AgentAssetTransactions transactions =
218 GetUserTransactions(remoteClient.AgentId);
217 219
218 transactions.RequestUpdateTaskInventoryItem(remoteClient, part, transactionID, item); 220 transactions.RequestUpdateTaskInventoryItem(remoteClient, part,
221 transactionID, item);
219 } 222 }
220 223
221 /// <summary> 224 /// <summary>
@@ -227,8 +230,9 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
227 /// <param name="type"></param> 230 /// <param name="type"></param>
228 /// <param name="data"></param></param> 231 /// <param name="data"></param></param>
229 /// <param name="tempFile"></param> 232 /// <param name="tempFile"></param>
230 public void HandleUDPUploadRequest(IClientAPI remoteClient, UUID assetID, UUID transaction, sbyte type, 233 public void HandleUDPUploadRequest(IClientAPI remoteClient,
231 byte[] data, bool storeLocal, bool tempFile) 234 UUID assetID, UUID transaction, sbyte type, byte[] data,
235 bool storeLocal, bool tempFile)
232 { 236 {
233// m_log.Debug("HandleUDPUploadRequest - assetID: " + assetID.ToString() + " transaction: " + transaction.ToString() + " type: " + type.ToString() + " storelocal: " + storeLocal + " tempFile: " + tempFile); 237// m_log.Debug("HandleUDPUploadRequest - assetID: " + assetID.ToString() + " transaction: " + transaction.ToString() + " type: " + type.ToString() + " storelocal: " + storeLocal + " tempFile: " + tempFile);
234 238
@@ -251,27 +255,33 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
251 } 255 }
252 } 256 }
253 257
254 AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId); 258 AgentAssetTransactions transactions =
259 GetUserTransactions(remoteClient.AgentId);
260
261 AssetXferUploader uploader =
262 transactions.RequestXferUploader(transaction);
255 263
256 AssetXferUploader uploader = transactions.RequestXferUploader(transaction);
257 if (uploader != null) 264 if (uploader != null)
258 { 265 {
259 uploader.Initialise(remoteClient, assetID, transaction, type, data, storeLocal, tempFile); 266 uploader.Initialise(remoteClient, assetID, transaction, type,
267 data, storeLocal, tempFile);
260 } 268 }
261 } 269 }
262 270
263 /// <summary> 271 /// <summary>
264 /// Handle asset transfer data packets received in response to the asset upload request in 272 /// Handle asset transfer data packets received in response to the
265 /// HandleUDPUploadRequest() 273 /// asset upload request in HandleUDPUploadRequest()
266 /// </summary> 274 /// </summary>
267 /// <param name="remoteClient"></param> 275 /// <param name="remoteClient"></param>
268 /// <param name="xferID"></param> 276 /// <param name="xferID"></param>
269 /// <param name="packetID"></param> 277 /// <param name="packetID"></param>
270 /// <param name="data"></param> 278 /// <param name="data"></param>
271 public void HandleXfer(IClientAPI remoteClient, ulong xferID, uint packetID, byte[] data) 279 public void HandleXfer(IClientAPI remoteClient, ulong xferID,
280 uint packetID, byte[] data)
272 { 281 {
273 //m_log.Debug("xferID: " + xferID + " packetID: " + packetID + " data!"); 282 //m_log.Debug("xferID: " + xferID + " packetID: " + packetID + " data!");
274 AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId); 283 AgentAssetTransactions transactions =
284 GetUserTransactions(remoteClient.AgentId);
275 285
276 transactions.HandleXfer(xferID, packetID, data); 286 transactions.HandleXfer(xferID, packetID, data);
277 } 287 }
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs
index 4609738..b8c8c85 100644
--- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs
+++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs
@@ -28,16 +28,19 @@
28using System; 28using System;
29using System.IO; 29using System.IO;
30using System.Reflection; 30using System.Reflection;
31using System.Collections.Generic;
31using log4net; 32using log4net;
32using OpenMetaverse; 33using OpenMetaverse;
33using OpenSim.Framework; 34using OpenSim.Framework;
34 35using OpenSim.Region.Framework.Scenes;
35using OpenSim.Services.Interfaces; 36using OpenSim.Services.Interfaces;
36 37
37namespace OpenSim.Region.CoreModules.Agent.AssetTransaction 38namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
38{ 39{
39 public class AssetXferUploader 40 public class AssetXferUploader
40 { 41 {
42 // Viewer's notion of the default texture
43 private UUID defaultID = new UUID("5748decc-f629-461c-9a36-a35a221fe21f");
41 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
42 45
43 private AssetBase m_asset; 46 private AssetBase m_asset;
@@ -50,17 +53,18 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
50 private bool m_finished = false; 53 private bool m_finished = false;
51 private string m_name = String.Empty; 54 private string m_name = String.Empty;
52 private bool m_storeLocal; 55 private bool m_storeLocal;
53 private AgentAssetTransactions m_userTransactions;
54 private uint nextPerm = 0; 56 private uint nextPerm = 0;
55 private IClientAPI ourClient; 57 private IClientAPI ourClient;
56 private UUID TransactionID = UUID.Zero; 58 private UUID TransactionID = UUID.Zero;
57 private sbyte type = 0; 59 private sbyte type = 0;
58 private byte wearableType = 0; 60 private byte wearableType = 0;
61 private byte[] m_oldData = null;
59 public ulong XferID; 62 public ulong XferID;
63 private Scene m_Scene;
60 64
61 public AssetXferUploader(AgentAssetTransactions transactions, bool dumpAssetToFile) 65 public AssetXferUploader(Scene scene, bool dumpAssetToFile)
62 { 66 {
63 m_userTransactions = transactions; 67 m_Scene = scene;
64 m_dumpAssetToFile = dumpAssetToFile; 68 m_dumpAssetToFile = dumpAssetToFile;
65 } 69 }
66 70
@@ -108,11 +112,13 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
108 /// <param name="packetID"></param> 112 /// <param name="packetID"></param>
109 /// <param name="data"></param> 113 /// <param name="data"></param>
110 /// <returns>True if the transfer is complete, false otherwise</returns> 114 /// <returns>True if the transfer is complete, false otherwise</returns>
111 public bool Initialise(IClientAPI remoteClient, UUID assetID, UUID transaction, sbyte type, byte[] data, 115 public bool Initialise(IClientAPI remoteClient, UUID assetID,
112 bool storeLocal, bool tempFile) 116 UUID transaction, sbyte type, byte[] data, bool storeLocal,
117 bool tempFile)
113 { 118 {
114 ourClient = remoteClient; 119 ourClient = remoteClient;
115 m_asset = new AssetBase(assetID, "blank", type, remoteClient.AgentId.ToString()); 120 m_asset = new AssetBase(assetID, "blank", type,
121 remoteClient.AgentId.ToString());
116 m_asset.Data = data; 122 m_asset.Data = data;
117 m_asset.Description = "empty"; 123 m_asset.Description = "empty";
118 m_asset.Local = storeLocal; 124 m_asset.Local = storeLocal;
@@ -137,12 +143,14 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
137 protected void RequestStartXfer() 143 protected void RequestStartXfer()
138 { 144 {
139 XferID = Util.GetNextXferID(); 145 XferID = Util.GetNextXferID();
140 ourClient.SendXferRequest(XferID, m_asset.Type, m_asset.FullID, 0, new byte[0]); 146 ourClient.SendXferRequest(XferID, m_asset.Type, m_asset.FullID,
147 0, new byte[0]);
141 } 148 }
142 149
143 protected void SendCompleteMessage() 150 protected void SendCompleteMessage()
144 { 151 {
145 ourClient.SendAssetUploadCompleteMessage(m_asset.Type, true, m_asset.FullID); 152 ourClient.SendAssetUploadCompleteMessage(m_asset.Type, true,
153 m_asset.FullID);
146 154
147 m_finished = true; 155 m_finished = true;
148 if (m_createItem) 156 if (m_createItem)
@@ -151,18 +159,20 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
151 } 159 }
152 else if (m_storeLocal) 160 else if (m_storeLocal)
153 { 161 {
154 m_userTransactions.Manager.MyScene.AssetService.Store(m_asset); 162 m_Scene.AssetService.Store(m_asset);
155 } 163 }
156 164
157 m_log.DebugFormat( 165 m_log.DebugFormat(
158 "[ASSET TRANSACTIONS]: Uploaded asset {0} for transaction {1}", m_asset.FullID, TransactionID); 166 "[ASSET TRANSACTIONS]: Uploaded asset {0} for transaction {1}",
167 m_asset.FullID, TransactionID);
159 168
160 if (m_dumpAssetToFile) 169 if (m_dumpAssetToFile)
161 { 170 {
162 DateTime now = DateTime.Now; 171 DateTime now = DateTime.Now;
163 string filename = 172 string filename =
164 String.Format("{6}_{7}_{0:d2}{1:d2}{2:d2}_{3:d2}{4:d2}{5:d2}.dat", now.Year, now.Month, now.Day, 173 String.Format("{6}_{7}_{0:d2}{1:d2}{2:d2}_{3:d2}{4:d2}{5:d2}.dat",
165 now.Hour, now.Minute, now.Second, m_asset.Name, m_asset.Type); 174 now.Year, now.Month, now.Day, now.Hour, now.Minute,
175 now.Second, m_asset.Name, m_asset.Type);
166 SaveAssetToFile(filename, m_asset.Data); 176 SaveAssetToFile(filename, m_asset.Data);
167 } 177 }
168 } 178 }
@@ -181,9 +191,10 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
181 fs.Close(); 191 fs.Close();
182 } 192 }
183 193
184 public void RequestCreateInventoryItem(IClientAPI remoteClient, UUID transactionID, UUID folderID, 194 public void RequestCreateInventoryItem(IClientAPI remoteClient,
185 uint callbackID, string description, string name, sbyte invType, 195 UUID transactionID, UUID folderID, uint callbackID,
186 sbyte type, byte wearableType, uint nextOwnerMask) 196 string description, string name, sbyte invType,
197 sbyte type, byte wearableType, uint nextOwnerMask)
187 { 198 {
188 if (TransactionID == transactionID) 199 if (TransactionID == transactionID)
189 { 200 {
@@ -212,7 +223,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
212 223
213 private void DoCreateItem(uint callbackID) 224 private void DoCreateItem(uint callbackID)
214 { 225 {
215 m_userTransactions.Manager.MyScene.AssetService.Store(m_asset); 226 ValidateAssets();
227 m_Scene.AssetService.Store(m_asset);
216 228
217 InventoryItemBase item = new InventoryItemBase(); 229 InventoryItemBase item = new InventoryItemBase();
218 item.Owner = ourClient.AgentId; 230 item.Owner = ourClient.AgentId;
@@ -232,12 +244,77 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
232 item.Flags = (uint) wearableType; 244 item.Flags = (uint) wearableType;
233 item.CreationDate = Util.UnixTimeSinceEpoch(); 245 item.CreationDate = Util.UnixTimeSinceEpoch();
234 246
235 if (m_userTransactions.Manager.MyScene.AddInventoryItem(item)) 247 if (m_Scene.AddInventoryItem(item))
236 ourClient.SendInventoryItemCreateUpdate(item, callbackID); 248 ourClient.SendInventoryItemCreateUpdate(item, callbackID);
237 else 249 else
238 ourClient.SendAlertMessage("Unable to create inventory item"); 250 ourClient.SendAlertMessage("Unable to create inventory item");
239 } 251 }
240 252
253 private void ValidateAssets()
254 {
255 if (m_asset.Type == (sbyte)AssetType.Clothing ||
256 m_asset.Type == (sbyte)AssetType.Bodypart)
257 {
258 string content = System.Text.Encoding.ASCII.GetString(m_asset.Data);
259 string[] lines = content.Split(new char[] {'\n'});
260
261 List<string> validated = new List<string>();
262
263 Dictionary<int, UUID> allowed = ExtractTexturesFromOldData();
264
265 int textures = 0;
266
267 foreach (string line in lines)
268 {
269 try
270 {
271 if (line.StartsWith("textures "))
272 {
273 textures = Convert.ToInt32(line.Substring(9));
274 validated.Add(line);
275 }
276 else if (textures > 0)
277 {
278 string[] parts = line.Split(new char[] {' '});
279
280 UUID tx = new UUID(parts[1]);
281 int id = Convert.ToInt32(parts[0]);
282
283 if (tx == defaultID || tx == UUID.Zero ||
284 (allowed.ContainsKey(id) && allowed[id] == tx))
285 {
286 validated.Add(parts[0] + " " + tx.ToString());
287 }
288 else
289 {
290 int perms = m_Scene.InventoryService.GetAssetPermissions(ourClient.AgentId, tx);
291 int full = (int)(PermissionMask.Modify | PermissionMask.Transfer | PermissionMask.Copy);
292
293 if ((perms & full) != full)
294 {
295 m_log.ErrorFormat("[ASSET UPLOADER]: REJECTED update with texture {0} from {1} because they do not own the texture", tx, ourClient.AgentId);
296 validated.Add(parts[0] + " " + defaultID.ToString());
297 }
298 }
299 textures--;
300 }
301 else
302 {
303 validated.Add(line);
304 }
305 }
306 catch
307 {
308 // If it's malformed, skip it
309 }
310 }
311
312 string final = String.Join("\n", validated.ToArray());
313
314 m_asset.Data = System.Text.Encoding.ASCII.GetBytes(final);
315 }
316 }
317
241 /// <summary> 318 /// <summary>
242 /// Get the asset data uploaded in this transfer. 319 /// Get the asset data uploaded in this transfer.
243 /// </summary> 320 /// </summary>
@@ -246,10 +323,55 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
246 { 323 {
247 if (m_finished) 324 if (m_finished)
248 { 325 {
326 ValidateAssets();
249 return m_asset; 327 return m_asset;
250 } 328 }
251 329
252 return null; 330 return null;
253 } 331 }
332
333 public void SetOldData(byte[] d)
334 {
335 m_oldData = d;
336 }
337
338 private Dictionary<int,UUID> ExtractTexturesFromOldData()
339 {
340 Dictionary<int,UUID> result = new Dictionary<int,UUID>();
341 if (m_oldData == null)
342 return result;
343
344 string content = System.Text.Encoding.ASCII.GetString(m_oldData);
345 string[] lines = content.Split(new char[] {'\n'});
346
347 int textures = 0;
348
349 foreach (string line in lines)
350 {
351 try
352 {
353 if (line.StartsWith("textures "))
354 {
355 textures = Convert.ToInt32(line.Substring(9));
356 }
357 else if (textures > 0)
358 {
359 string[] parts = line.Split(new char[] {' '});
360
361 UUID tx = new UUID(parts[1]);
362 int id = Convert.ToInt32(parts[0]);
363 result[id] = tx;
364 textures--;
365 }
366 }
367 catch
368 {
369 // If it's malformed, skip it
370 }
371 }
372
373 return result;
374 }
254 } 375 }
255} 376}
377