aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules
diff options
context:
space:
mode:
authorMelanie2011-10-12 00:10:15 +0200
committerMelanie2011-10-12 00:10:15 +0200
commit1c2b5d99c9601a3d301f4bc0f53389cca831ee04 (patch)
tree97fa9c758f429d5dee64234e442f2c83cd1b9994 /OpenSim/Region/CoreModules
parentMerge branch 'careminster-presence-refactor' into bigmerge (diff)
parentMerge commit '92c88121c72386f85472c6cf4891eca8b62b9867' into bigmerge (diff)
downloadopensim-SC-1c2b5d99c9601a3d301f4bc0f53389cca831ee04.zip
opensim-SC-1c2b5d99c9601a3d301f4bc0f53389cca831ee04.tar.gz
opensim-SC-1c2b5d99c9601a3d301f4bc0f53389cca831ee04.tar.bz2
opensim-SC-1c2b5d99c9601a3d301f4bc0f53389cca831ee04.tar.xz
Merge branch 'bigmerge' of ssh://3dhosting.de/var/git/careminster into bigmerge
Diffstat (limited to 'OpenSim/Region/CoreModules')
-rw-r--r--OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs184
-rw-r--r--OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs25
-rw-r--r--OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs127
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs876
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs12
-rw-r--r--OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs38
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs11
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs16
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs1
-rw-r--r--OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs9
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs12
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs15
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs15
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/LocalUserAccountServiceConnector.cs26
-rw-r--r--OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs4
15 files changed, 790 insertions, 581 deletions
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs
index ff4ec4c..eed7cd5 100644
--- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs
+++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs
@@ -41,14 +41,13 @@ 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(MethodBase.GetCurrentMethod().DeclaringType);
45 45
46 // Fields 46 // Fields
47 private bool m_dumpAssetsToFile; 47 private bool m_dumpAssetsToFile;
48 private Scene m_Scene; 48 private Scene m_Scene;
49 public UUID UserID; 49 private UUID UserID;
50 public Dictionary<UUID, AssetXferUploader> XferUploaders = 50 private Dictionary<UUID, AssetXferUploader> XferUploaders = new Dictionary<UUID, AssetXferUploader>();
51 new Dictionary<UUID, AssetXferUploader>();
52 51
53 // Methods 52 // Methods
54 public AgentAssetTransactions(UUID agentID, Scene scene, 53 public AgentAssetTransactions(UUID agentID, Scene scene,
@@ -59,36 +58,94 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
59 m_dumpAssetsToFile = dumpAssetsToFile; 58 m_dumpAssetsToFile = dumpAssetsToFile;
60 } 59 }
61 60
62 public AssetXferUploader RequestXferUploader(UUID transactionID) 61 /// <summary>
62 /// Return a xfer uploader if one does not already exist.
63 /// </summary>
64 /// <param name="transactionID"></param>
65 /// <param name="assetID">
66 /// We must transfer the new asset ID into the uploader on creation, otherwise
67 /// we can see race conditions with other threads which can retrieve an item before it is updated with the new
68 /// asset id.
69 /// </param>
70 /// <returns>
71 /// The xfer uploader requested. Null if one is already in existence.
72 /// FIXME: This is a bizarre thing to do, and is probably meant to signal an error condition if multiple
73 /// transfers are made. Needs to be corrected.
74 /// </returns>
75 public AssetXferUploader RequestXferUploader(UUID transactionID, UUID assetID)
63 { 76 {
64 if (!XferUploaders.ContainsKey(transactionID)) 77 lock (XferUploaders)
65 { 78 {
66 AssetXferUploader uploader = new AssetXferUploader(m_Scene, 79 if (!XferUploaders.ContainsKey(transactionID))
67 m_dumpAssetsToFile);
68
69 lock (XferUploaders)
70 { 80 {
81 AssetXferUploader uploader = new AssetXferUploader(this, m_Scene, assetID, m_dumpAssetsToFile);
82
83// m_log.DebugFormat(
84// "[AGENT ASSETS TRANSACTIONS]: Adding asset xfer uploader {0} since it didn't previously exist", transactionID);
85
71 XferUploaders.Add(transactionID, uploader); 86 XferUploaders.Add(transactionID, uploader);
72 }
73 87
74 return uploader; 88 return uploader;
89 }
75 } 90 }
91
92 m_log.WarnFormat("[AGENT ASSETS TRANSACTIONS]: Ignoring request for asset xfer uploader {0} since it already exists", transactionID);
93
76 return null; 94 return null;
77 } 95 }
78 96
79 public void HandleXfer(ulong xferID, uint packetID, byte[] data) 97 public void HandleXfer(ulong xferID, uint packetID, byte[] data)
80 { 98 {
99 AssetXferUploader foundUploader = null;
100
81 lock (XferUploaders) 101 lock (XferUploaders)
82 { 102 {
83 foreach (AssetXferUploader uploader in XferUploaders.Values) 103 foreach (AssetXferUploader uploader in XferUploaders.Values)
84 { 104 {
105// m_log.DebugFormat(
106// "[AGENT ASSETS TRANSACTIONS]: In HandleXfer, inspect xfer upload with xfer id {0}",
107// uploader.XferID);
108
85 if (uploader.XferID == xferID) 109 if (uploader.XferID == xferID)
86 { 110 {
87 uploader.HandleXferPacket(xferID, packetID, data); 111 foundUploader = uploader;
88 break; 112 break;
89 } 113 }
90 } 114 }
91 } 115 }
116
117 if (foundUploader != null)
118 {
119// m_log.DebugFormat(
120// "[AGENT ASSETS TRANSACTIONS]: Found xfer uploader for xfer id {0}, packet id {1}, data length {2}",
121// xferID, packetID, data.Length);
122
123 foundUploader.HandleXferPacket(xferID, packetID, data);
124 }
125 else
126 {
127 m_log.ErrorFormat(
128 "[AGENT ASSET TRANSACTIONS]: Could not find uploader for xfer id {0}, packet id {1}, data length {2}",
129 xferID, packetID, data.Length);
130 }
131 }
132
133 public bool RemoveXferUploader(UUID transactionID)
134 {
135 lock (XferUploaders)
136 {
137 bool removed = XferUploaders.Remove(transactionID);
138
139 if (!removed)
140 m_log.WarnFormat(
141 "[AGENT ASSET TRANSACTIONS]: Received request to remove xfer uploader with transaction ID {0} but none found",
142 transactionID);
143// else
144// m_log.DebugFormat(
145// "[AGENT ASSET TRANSACTIONS]: Removed xfer uploader with transaction ID {0}", transactionID);
146
147 return removed;
148 }
92 } 149 }
93 150
94 public void RequestCreateInventoryItem(IClientAPI remoteClient, 151 public void RequestCreateInventoryItem(IClientAPI remoteClient,
@@ -96,16 +153,24 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
96 string description, string name, sbyte invType, 153 string description, string name, sbyte invType,
97 sbyte type, byte wearableType, uint nextOwnerMask) 154 sbyte type, byte wearableType, uint nextOwnerMask)
98 { 155 {
99 if (XferUploaders.ContainsKey(transactionID)) 156 AssetXferUploader uploader = null;
157
158 lock (XferUploaders)
100 { 159 {
101 XferUploaders[transactionID].RequestCreateInventoryItem( 160 if (XferUploaders.ContainsKey(transactionID))
102 remoteClient, transactionID, folderID, 161 uploader = XferUploaders[transactionID];
103 callbackID, description, name, invType, type,
104 wearableType, nextOwnerMask);
105 } 162 }
106 }
107
108 163
164 if (uploader != null)
165 uploader.RequestCreateInventoryItem(
166 remoteClient, transactionID, folderID,
167 callbackID, description, name, invType, type,
168 wearableType, nextOwnerMask);
169 else
170 m_log.ErrorFormat(
171 "[AGENT ASSET TRANSACTIONS]: Could not find uploader with transaction ID {0} when handling request to create inventory item {1} from {2}",
172 transactionID, name, remoteClient.Name);
173 }
109 174
110 /// <summary> 175 /// <summary>
111 /// Get an uploaded asset. If the data is successfully retrieved, 176 /// Get an uploaded asset. If the data is successfully retrieved,
@@ -113,19 +178,18 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
113 /// </summary> 178 /// </summary>
114 /// <param name="transactionID"></param> 179 /// <param name="transactionID"></param>
115 /// <returns>The asset if the upload has completed, null if it has not.</returns> 180 /// <returns>The asset if the upload has completed, null if it has not.</returns>
116 public AssetBase GetTransactionAsset(UUID transactionID) 181 private AssetBase GetTransactionAsset(UUID transactionID)
117 { 182 {
118 if (XferUploaders.ContainsKey(transactionID)) 183 lock (XferUploaders)
119 { 184 {
120 AssetXferUploader uploader = XferUploaders[transactionID]; 185 if (XferUploaders.ContainsKey(transactionID))
121 AssetBase asset = uploader.GetAssetData();
122
123 lock (XferUploaders)
124 { 186 {
125 XferUploaders.Remove(transactionID); 187 AssetXferUploader uploader = XferUploaders[transactionID];
126 } 188 AssetBase asset = uploader.GetAssetData();
189 RemoveXferUploader(transactionID);
127 190
128 return asset; 191 return asset;
192 }
129 } 193 }
130 194
131 return null; 195 return null;
@@ -135,7 +199,15 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
135 SceneObjectPart part, UUID transactionID, 199 SceneObjectPart part, UUID transactionID,
136 TaskInventoryItem item) 200 TaskInventoryItem item)
137 { 201 {
138 if (XferUploaders.ContainsKey(transactionID)) 202 AssetXferUploader uploader = null;
203
204 lock (XferUploaders)
205 {
206 if (XferUploaders.ContainsKey(transactionID))
207 uploader = XferUploaders[transactionID];
208 }
209
210 if (uploader != null)
139 { 211 {
140 AssetBase asset = GetTransactionAsset(transactionID); 212 AssetBase asset = GetTransactionAsset(transactionID);
141 213
@@ -161,44 +233,34 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
161 m_Scene.AssetService.Store(asset); 233 m_Scene.AssetService.Store(asset);
162 } 234 }
163 } 235 }
236 else
237 {
238 m_log.ErrorFormat(
239 "[AGENT ASSET TRANSACTIONS]: Could not find uploader with transaction ID {0} when handling request to update task inventory item {1} in {2}",
240 transactionID, item.Name, part.Name);
241 }
164 } 242 }
165 243
166 public void RequestUpdateInventoryItem(IClientAPI remoteClient, 244 public void RequestUpdateInventoryItem(IClientAPI remoteClient,
167 UUID transactionID, InventoryItemBase item) 245 UUID transactionID, InventoryItemBase item)
168 { 246 {
169 if (XferUploaders.ContainsKey(transactionID)) 247 AssetXferUploader uploader = null;
170 {
171// m_log.DebugFormat("[XFER]: Asked to update item {0} ({1})",
172// item.Name, item.ID);
173
174 // Here we need to get the old asset to extract the
175 // texture UUIDs if it's a wearable.
176 if (item.AssetType == (int)AssetType.Bodypart ||
177 item.AssetType == (int)AssetType.Clothing)
178 {
179 AssetBase oldAsset = m_Scene.AssetService.Get(item.AssetID.ToString());
180 if (oldAsset != null)
181 XferUploaders[transactionID].SetOldData(oldAsset.Data);
182 }
183
184 AssetBase asset = GetTransactionAsset(transactionID);
185 248
186 if (asset != null) 249 lock (XferUploaders)
187 { 250 {
188 asset.FullID = UUID.Random(); 251 if (XferUploaders.ContainsKey(transactionID))
189 asset.Name = item.Name; 252 uploader = XferUploaders[transactionID];
190 asset.Description = item.Description; 253 }
191 asset.Type = (sbyte)item.AssetType;
192 item.AssetID = asset.FullID;
193
194 m_Scene.AssetService.Store(asset);
195
196 IInventoryService invService = m_Scene.InventoryService;
197 invService.UpdateItem(item);
198 254
199// m_log.DebugFormat("[XFER]: Updated item {0} ({1}) with asset {2}", 255 if (uploader != null)
200// item.Name, item.ID, asset.FullID); 256 {
201 } 257 uploader.RequestUpdateInventoryItem(remoteClient, transactionID, item);
258 }
259 else
260 {
261 m_log.ErrorFormat(
262 "[AGENT ASSET TRANSACTIONS]: Could not find uploader with transaction ID {0} when handling request to update inventory item {1} for {2}",
263 transactionID, item.Name, remoteClient.Name);
202 } 264 }
203 } 265 }
204 } 266 }
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs
index 82558de..a28d5d7 100644
--- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs
+++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs
@@ -172,11 +172,12 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
172 /// <summary> 172 /// <summary>
173 /// Update an inventory item with data that has been received through a 173 /// Update an inventory item with data that has been received through a
174 /// transaction. 174 /// transaction.
175 /// 175 /// </summary>
176 /// <remarks>
176 /// This is called when clothing or body parts are updated (for 177 /// This is called when clothing or body parts are updated (for
177 /// instance, with new textures or colours). It may also be called in 178 /// instance, with new textures or colours). It may also be called in
178 /// other situations. 179 /// other situations.
179 /// </summary> 180 /// </remarks>
180 /// <param name="remoteClient"></param> 181 /// <param name="remoteClient"></param>
181 /// <param name="transactionID"></param> 182 /// <param name="transactionID"></param>
182 /// <param name="item"></param> 183 /// <param name="item"></param>
@@ -184,14 +185,12 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
184 UUID transactionID, InventoryItemBase item) 185 UUID transactionID, InventoryItemBase item)
185 { 186 {
186// m_log.DebugFormat( 187// m_log.DebugFormat(
187// "[TRANSACTIONS MANAGER] Called HandleItemUpdateFromTransaction with item {0}", 188// "[ASSET TRANSACTION MODULE]: Called HandleItemUpdateFromTransaction with item {0}",
188// item.Name); 189// item.Name);
189 190
190 AgentAssetTransactions transactions = 191 AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId);
191 GetUserTransactions(remoteClient.AgentId);
192 192
193 transactions.RequestUpdateInventoryItem(remoteClient, 193 transactions.RequestUpdateInventoryItem(remoteClient, transactionID, item);
194 transactionID, item);
195 } 194 }
196 195
197 /// <summary> 196 /// <summary>
@@ -255,11 +254,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
255 } 254 }
256 } 255 }
257 256
258 AgentAssetTransactions transactions = 257 AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId);
259 GetUserTransactions(remoteClient.AgentId); 258 AssetXferUploader uploader = transactions.RequestXferUploader(transaction, assetID);
260
261 AssetXferUploader uploader =
262 transactions.RequestXferUploader(transaction);
263 259
264 if (uploader != null) 260 if (uploader != null)
265 { 261 {
@@ -279,9 +275,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
279 public void HandleXfer(IClientAPI remoteClient, ulong xferID, 275 public void HandleXfer(IClientAPI remoteClient, ulong xferID,
280 uint packetID, byte[] data) 276 uint packetID, byte[] data)
281 { 277 {
282 //m_log.Debug("xferID: " + xferID + " packetID: " + packetID + " data!"); 278// m_log.Debug("xferID: " + xferID + " packetID: " + packetID + " data length " + data.Length);
283 AgentAssetTransactions transactions = 279 AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId);
284 GetUserTransactions(remoteClient.AgentId);
285 280
286 transactions.HandleXfer(xferID, packetID, data); 281 transactions.HandleXfer(xferID, packetID, data);
287 } 282 }
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs
index a5dcdcc..4cedfe6 100644
--- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs
+++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs
@@ -48,11 +48,21 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
48 }; 48 };
49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
50 50
51 /// <summary>
52 /// Reference to the object that holds this uploader. Used to remove ourselves from it's list if we
53 /// are performing a delayed update.
54 /// </summary>
55 AgentAssetTransactions m_transactions;
56
51 private AssetBase m_asset; 57 private AssetBase m_asset;
52 private UUID InventFolder = UUID.Zero; 58 private UUID InventFolder = UUID.Zero;
53 private sbyte invType = 0; 59 private sbyte invType = 0;
60
54 private bool m_createItem = false; 61 private bool m_createItem = false;
55 private uint m_createItemCallback = 0; 62 private uint m_createItemCallback = 0;
63 private bool m_updateItem = false;
64 private InventoryItemBase m_updateItemData;
65
56 private string m_description = String.Empty; 66 private string m_description = String.Empty;
57 private bool m_dumpAssetToFile; 67 private bool m_dumpAssetToFile;
58 private bool m_finished = false; 68 private bool m_finished = false;
@@ -67,9 +77,11 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
67 public ulong XferID; 77 public ulong XferID;
68 private Scene m_Scene; 78 private Scene m_Scene;
69 79
70 public AssetXferUploader(Scene scene, bool dumpAssetToFile) 80 public AssetXferUploader(AgentAssetTransactions transactions, Scene scene, UUID assetID, bool dumpAssetToFile)
71 { 81 {
82 m_transactions = transactions;
72 m_Scene = scene; 83 m_Scene = scene;
84 m_asset = new AssetBase() { FullID = assetID };
73 m_dumpAssetToFile = dumpAssetToFile; 85 m_dumpAssetToFile = dumpAssetToFile;
74 } 86 }
75 87
@@ -82,6 +94,10 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
82 /// <returns>True if the transfer is complete, false otherwise or if the xferID was not valid</returns> 94 /// <returns>True if the transfer is complete, false otherwise or if the xferID was not valid</returns>
83 public bool HandleXferPacket(ulong xferID, uint packetID, byte[] data) 95 public bool HandleXferPacket(ulong xferID, uint packetID, byte[] data)
84 { 96 {
97// m_log.DebugFormat(
98// "[ASSET XFER UPLOADER]: Received packet {0} for xfer {1} (data length {2})",
99// packetID, xferID, data.Length);
100
85 if (XferID == xferID) 101 if (XferID == xferID)
86 { 102 {
87 if (m_asset.Data.Length > 1) 103 if (m_asset.Data.Length > 1)
@@ -116,16 +132,20 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
116 /// <param name="xferID"></param> 132 /// <param name="xferID"></param>
117 /// <param name="packetID"></param> 133 /// <param name="packetID"></param>
118 /// <param name="data"></param> 134 /// <param name="data"></param>
119 /// <returns>True if the transfer is complete, false otherwise</returns> 135 public void Initialise(IClientAPI remoteClient, UUID assetID,
120 public bool Initialise(IClientAPI remoteClient, UUID assetID,
121 UUID transaction, sbyte type, byte[] data, bool storeLocal, 136 UUID transaction, sbyte type, byte[] data, bool storeLocal,
122 bool tempFile) 137 bool tempFile)
123 { 138 {
139// m_log.DebugFormat(
140// "[ASSET XFER UPLOADER]: Initialised xfer from {0}, asset {1}, transaction {2}, type {3}, storeLocal {4}, tempFile {5}, already received data length {6}",
141// remoteClient.Name, assetID, transaction, type, storeLocal, tempFile, data.Length);
142
124 ourClient = remoteClient; 143 ourClient = remoteClient;
125 m_asset = new AssetBase(assetID, "blank", type, 144 m_asset.Name = "blank";
126 remoteClient.AgentId.ToString());
127 m_asset.Data = data;
128 m_asset.Description = "empty"; 145 m_asset.Description = "empty";
146 m_asset.Type = type;
147 m_asset.CreatorID = remoteClient.AgentId.ToString();
148 m_asset.Data = data;
129 m_asset.Local = storeLocal; 149 m_asset.Local = storeLocal;
130 m_asset.Temporary = tempFile; 150 m_asset.Temporary = tempFile;
131 151
@@ -135,21 +155,22 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
135 if (m_asset.Data.Length > 2) 155 if (m_asset.Data.Length > 2)
136 { 156 {
137 SendCompleteMessage(); 157 SendCompleteMessage();
138 return true;
139 } 158 }
140 else 159 else
141 { 160 {
142 RequestStartXfer(); 161 RequestStartXfer();
143 } 162 }
144
145 return false;
146 } 163 }
147 164
148 protected void RequestStartXfer() 165 protected void RequestStartXfer()
149 { 166 {
150 XferID = Util.GetNextXferID(); 167 XferID = Util.GetNextXferID();
151 ourClient.SendXferRequest(XferID, m_asset.Type, m_asset.FullID, 168
152 0, new byte[0]); 169// m_log.DebugFormat(
170// "[ASSET XFER UPLOADER]: Requesting Xfer of asset {0}, type {1}, transfer id {2} from {3}",
171// m_asset.FullID, m_asset.Type, XferID, ourClient.Name);
172
173 ourClient.SendXferRequest(XferID, m_asset.Type, m_asset.FullID, 0, new byte[0]);
153 } 174 }
154 175
155 protected void SendCompleteMessage() 176 protected void SendCompleteMessage()
@@ -157,18 +178,32 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
157 ourClient.SendAssetUploadCompleteMessage(m_asset.Type, true, 178 ourClient.SendAssetUploadCompleteMessage(m_asset.Type, true,
158 m_asset.FullID); 179 m_asset.FullID);
159 180
160 m_finished = true; 181 // We must lock in order to avoid a race with a separate thread dealing with an inventory item or create
161 if (m_createItem) 182 // message from other client UDP.
183 lock (this)
162 { 184 {
163 DoCreateItem(m_createItemCallback); 185 m_finished = true;
164 } 186 if (m_createItem)
165 else if (m_storeLocal) 187 {
166 { 188 DoCreateItem(m_createItemCallback);
167 m_Scene.AssetService.Store(m_asset); 189 }
190 else if (m_updateItem)
191 {
192 StoreAssetForItemUpdate(m_updateItemData);
193
194 // Remove ourselves from the list of transactions if completion was delayed until the transaction
195 // was complete.
196 // TODO: Should probably do the same for create item.
197 m_transactions.RemoveXferUploader(TransactionID);
198 }
199 else if (m_storeLocal)
200 {
201 m_Scene.AssetService.Store(m_asset);
202 }
168 } 203 }
169 204
170 m_log.DebugFormat( 205 m_log.DebugFormat(
171 "[ASSET TRANSACTIONS]: Uploaded asset {0} for transaction {1}", 206 "[ASSET XFER UPLOADER]: Uploaded asset {0} for transaction {1}",
172 m_asset.FullID, TransactionID); 207 m_asset.FullID, TransactionID);
173 208
174 if (m_dumpAssetToFile) 209 if (m_dumpAssetToFile)
@@ -214,18 +249,66 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
214 m_asset.Description = description; 249 m_asset.Description = description;
215 m_asset.Type = type; 250 m_asset.Type = type;
216 251
252 // We must lock to avoid a race with a separate thread uploading the asset.
253 lock (this)
254 {
255 if (m_finished)
256 {
257 DoCreateItem(callbackID);
258 }
259 else
260 {
261 m_createItem = true; //set flag so the inventory item is created when upload is complete
262 m_createItemCallback = callbackID;
263 }
264 }
265 }
266 }
267
268 public void RequestUpdateInventoryItem(IClientAPI remoteClient, UUID transactionID, InventoryItemBase item)
269 {
270 // We must lock to avoid a race with a separate thread uploading the asset.
271 lock (this)
272 {
273 m_asset.Name = item.Name;
274 m_asset.Description = item.Description;
275 m_asset.Type = (sbyte)item.AssetType;
276
277 // We must always store the item at this point even if the asset hasn't finished uploading, in order
278 // to avoid a race condition when the appearance module retrieves the item to set the asset id in
279 // the AvatarAppearance structure.
280 item.AssetID = m_asset.FullID;
281 m_Scene.InventoryService.UpdateItem(item);
282
217 if (m_finished) 283 if (m_finished)
218 { 284 {
219 DoCreateItem(callbackID); 285 StoreAssetForItemUpdate(item);
220 } 286 }
221 else 287 else
222 { 288 {
223 m_createItem = true; //set flag so the inventory item is created when upload is complete 289// m_log.DebugFormat(
224 m_createItemCallback = callbackID; 290// "[ASSET XFER UPLOADER]: Holding update inventory item request {0} for {1} pending completion of asset xfer for transaction {2}",
291// item.Name, remoteClient.Name, transactionID);
292
293 m_updateItem = true;
294 m_updateItemData = item;
225 } 295 }
226 } 296 }
227 } 297 }
228 298
299 /// <summary>
300 /// Store the asset for the given item.
301 /// </summary>
302 /// <param name="item"></param>
303 private void StoreAssetForItemUpdate(InventoryItemBase item)
304 {
305// m_log.DebugFormat(
306// "[ASSET XFER UPLOADER]: Storing asset {0} for earlier item update for {1} for {2}",
307// m_asset.FullID, item.Name, ourClient.Name);
308
309 m_Scene.AssetService.Store(m_asset);
310 }
311
229 private void DoCreateItem(uint callbackID) 312 private void DoCreateItem(uint callbackID)
230 { 313 {
231 ValidateAssets(); 314 ValidateAssets();
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
index a130ed2..09781c7 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
@@ -45,29 +45,47 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
45 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "AttachmentsModule")] 45 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "AttachmentsModule")]
46 public class AttachmentsModule : IAttachmentsModule, INonSharedRegionModule 46 public class AttachmentsModule : IAttachmentsModule, INonSharedRegionModule
47 { 47 {
48 #region INonSharedRegionModule
48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
49 50
50 private Scene m_scene; 51 private Scene m_scene;
51 private IDialogModule m_dialogModule; 52 private IDialogModule m_dialogModule;
53
54 /// <summary>
55 /// Are attachments enabled?
56 /// </summary>
57 public bool Enabled { get; private set; }
52 58
53 public string Name { get { return "Attachments Module"; } } 59 public string Name { get { return "Attachments Module"; } }
54 public Type ReplaceableInterface { get { return null; } } 60 public Type ReplaceableInterface { get { return null; } }
55 61
56 public void Initialise(IConfigSource source) {} 62 public void Initialise(IConfigSource source)
63 {
64 IConfig config = source.Configs["Attachments"];
65 if (config != null)
66 Enabled = config.GetBoolean("Enabled", true);
67 else
68 Enabled = true;
69 }
57 70
58 public void AddRegion(Scene scene) 71 public void AddRegion(Scene scene)
59 { 72 {
60 m_scene = scene; 73 m_scene = scene;
61 m_dialogModule = m_scene.RequestModuleInterface<IDialogModule>(); 74 m_dialogModule = m_scene.RequestModuleInterface<IDialogModule>();
62 m_scene.RegisterModuleInterface<IAttachmentsModule>(this); 75 m_scene.RegisterModuleInterface<IAttachmentsModule>(this);
63 m_scene.EventManager.OnNewClient += SubscribeToClientEvents; 76
77 if (Enabled)
78 m_scene.EventManager.OnNewClient += SubscribeToClientEvents;
79
64 // TODO: Should probably be subscribing to CloseClient too, but this doesn't yet give us IClientAPI 80 // TODO: Should probably be subscribing to CloseClient too, but this doesn't yet give us IClientAPI
65 } 81 }
66 82
67 public void RemoveRegion(Scene scene) 83 public void RemoveRegion(Scene scene)
68 { 84 {
69 m_scene.UnregisterModuleInterface<IAttachmentsModule>(this); 85 m_scene.UnregisterModuleInterface<IAttachmentsModule>(this);
70 m_scene.EventManager.OnNewClient -= SubscribeToClientEvents; 86
87 if (Enabled)
88 m_scene.EventManager.OnNewClient -= SubscribeToClientEvents;
71 } 89 }
72 90
73 public void RegionLoaded(Scene scene) {} 91 public void RegionLoaded(Scene scene) {}
@@ -76,26 +94,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
76 { 94 {
77 RemoveRegion(m_scene); 95 RemoveRegion(m_scene);
78 } 96 }
79 97
80 public void SubscribeToClientEvents(IClientAPI client) 98 #endregion
81 { 99
82 client.OnRezSingleAttachmentFromInv += RezSingleAttachmentFromInventory; 100 #region IAttachmentsModule
83 client.OnRezMultipleAttachmentsFromInv += RezMultipleAttachmentsFromInventory;
84 client.OnObjectAttach += AttachObject;
85 client.OnObjectDetach += DetachObject;
86 client.OnDetachAttachmentIntoInv += DetachSingleAttachmentToInv;
87 client.OnObjectDrop += DetachSingleAttachmentToGround;
88 }
89
90 public void UnsubscribeFromClientEvents(IClientAPI client)
91 {
92 client.OnRezSingleAttachmentFromInv -= RezSingleAttachmentFromInventory;
93 client.OnRezMultipleAttachmentsFromInv -= RezMultipleAttachmentsFromInventory;
94 client.OnObjectAttach -= AttachObject;
95 client.OnObjectDetach -= DetachObject;
96 client.OnDetachAttachmentIntoInv -= DetachSingleAttachmentToInv;
97 client.OnObjectDrop -= DetachSingleAttachmentToGround;
98 }
99 101
100 /// <summary> 102 /// <summary>
101 /// RezAttachments. This should only be called upon login on the first region. 103 /// RezAttachments. This should only be called upon login on the first region.
@@ -103,6 +105,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
103 /// </summary> 105 /// </summary>
104 public void RezAttachments(IScenePresence sp) 106 public void RezAttachments(IScenePresence sp)
105 { 107 {
108 if (!Enabled)
109 return;
110
106 if (null == sp.Appearance) 111 if (null == sp.Appearance)
107 { 112 {
108 m_log.WarnFormat("[ATTACHMENTS MODULE]: Appearance has not been initialized for agent {0}", sp.UUID); 113 m_log.WarnFormat("[ATTACHMENTS MODULE]: Appearance has not been initialized for agent {0}", sp.UUID);
@@ -133,7 +138,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
133 if (sp.PresenceType == PresenceType.Npc) 138 if (sp.PresenceType == PresenceType.Npc)
134 RezSingleAttachmentFromInventoryInternal(sp, UUID.Zero, attach.AssetID, p, null); 139 RezSingleAttachmentFromInventoryInternal(sp, UUID.Zero, attach.AssetID, p, null);
135 else 140 else
136 RezSingleAttachmentFromInventory(sp.ControllingClient, attach.ItemID, p); 141 RezSingleAttachmentFromInventory(sp, attach.ItemID, p);
137 } 142 }
138 catch (Exception e) 143 catch (Exception e)
139 { 144 {
@@ -146,13 +151,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
146 { 151 {
147// m_log.DebugFormat("[ATTACHMENTS MODULE]: Saving changed attachments for {0}", sp.Name); 152// m_log.DebugFormat("[ATTACHMENTS MODULE]: Saving changed attachments for {0}", sp.Name);
148 153
154 if (!Enabled)
155 return;
156
149 foreach (SceneObjectGroup grp in sp.GetAttachments()) 157 foreach (SceneObjectGroup grp in sp.GetAttachments())
150 { 158 {
151// if (grp.HasGroupChanged) // Resizer scripts? 159// if (grp.HasGroupChanged) // Resizer scripts?
152// { 160// {
153 grp.IsAttachment = false; 161 grp.IsAttachment = false;
154 grp.AbsolutePosition = grp.RootPart.AttachedPos; 162 grp.AbsolutePosition = grp.RootPart.AttachedPos;
155 UpdateKnownItem(sp.ControllingClient, grp); 163 UpdateKnownItem(sp, grp);
156 grp.IsAttachment = true; 164 grp.IsAttachment = true;
157// } 165// }
158 } 166 }
@@ -164,6 +172,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
164// "[ATTACHMENTS MODULE]: Deleting attachments from scene {0} for {1}, silent = {2}", 172// "[ATTACHMENTS MODULE]: Deleting attachments from scene {0} for {1}, silent = {2}",
165// m_scene.RegionInfo.RegionName, sp.Name, silent); 173// m_scene.RegionInfo.RegionName, sp.Name, silent);
166 174
175 if (!Enabled)
176 return;
177
167 foreach (SceneObjectGroup sop in sp.GetAttachments()) 178 foreach (SceneObjectGroup sop in sp.GetAttachments())
168 { 179 {
169 sop.Scene.DeleteSceneObject(sop, silent); 180 sop.Scene.DeleteSceneObject(sop, silent);
@@ -172,87 +183,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
172 sp.ClearAttachments(); 183 sp.ClearAttachments();
173 } 184 }
174 185
175 /// <summary> 186 public bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent)
176 /// Called by client
177 /// </summary>
178 /// <param name="remoteClient"></param>
179 /// <param name="objectLocalID"></param>
180 /// <param name="AttachmentPt"></param>
181 /// <param name="silent"></param>
182 public void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent)
183 {
184// m_log.DebugFormat(
185// "[ATTACHMENTS MODULE]: Attaching object local id {0} to {1} point {2} from ground (silent = {3})",
186// objectLocalID, remoteClient.Name, AttachmentPt, silent);
187
188 try
189 {
190 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
191
192 if (sp == null)
193 {
194 m_log.ErrorFormat(
195 "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1}", remoteClient.Name, remoteClient.AgentId);
196 return;
197 }
198
199 // If we can't take it, we can't attach it!
200 SceneObjectPart part = m_scene.GetSceneObjectPart(objectLocalID);
201 if (part == null)
202 return;
203
204 if (!m_scene.Permissions.CanTakeObject(part.UUID, remoteClient.AgentId))
205 {
206 remoteClient.SendAgentAlertMessage(
207 "You don't have sufficient permissions to attach this object", false);
208
209 return;
210 }
211
212 if (part.OwnerID != remoteClient.AgentId) // Not ours
213 {
214 remoteClient.SendAgentAlertMessage(
215 "You don't have sufficient permissions to attach this object", false);
216 return;
217 }
218
219 // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should
220 // be removed when that functionality is implemented in opensim
221 AttachmentPt &= 0x7f;
222
223 // Calls attach with a Zero position
224 if (AttachObject(sp, part.ParentGroup, AttachmentPt, false))
225 {
226 m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId);
227
228 // Save avatar attachment information
229 m_log.Debug(
230 "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId
231 + ", AttachmentPoint: " + AttachmentPt);
232
233 }
234 }
235 catch (Exception e)
236 {
237 m_log.ErrorFormat("[ATTACHMENTS MODULE]: exception upon Attach Object {0}{1}", e.Message, e.StackTrace);
238 }
239 }
240
241 public bool AttachObject(IClientAPI remoteClient, SceneObjectGroup group, uint AttachmentPt, bool silent)
242 {
243 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
244
245 if (sp == null)
246 {
247 m_log.ErrorFormat(
248 "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1}", remoteClient.Name, remoteClient.AgentId);
249 return false;
250 }
251
252 return AttachObject(sp, group, AttachmentPt, silent);
253 }
254
255 private bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent)
256 { 187 {
257 lock (sp.AttachmentsSyncLock) 188 lock (sp.AttachmentsSyncLock)
258 { 189 {
@@ -313,7 +244,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
313 UUID oldAttachmentItemID = attachments[0].GetFromItemID(); 244 UUID oldAttachmentItemID = attachments[0].GetFromItemID();
314 245
315 if (oldAttachmentItemID != UUID.Zero) 246 if (oldAttachmentItemID != UUID.Zero)
316 DetachSingleAttachmentToInv(oldAttachmentItemID, sp); 247 DetachSingleAttachmentToInvInternal(sp, oldAttachmentItemID);
317 else 248 else
318 m_log.WarnFormat( 249 m_log.WarnFormat(
319 "[ATTACHMENTS MODULE]: When detaching existing attachment {0} {1} at point {2} to make way for {3} {4} for {5}, couldn't find the associated item ID to adjust inventory attachment record!", 250 "[ATTACHMENTS MODULE]: When detaching existing attachment {0} {1} at point {2} to make way for {3} {4} for {5}, couldn't find the associated item ID to adjust inventory attachment record!",
@@ -323,7 +254,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
323 // Add the new attachment to inventory if we don't already have it. 254 // Add the new attachment to inventory if we don't already have it.
324 UUID newAttachmentItemID = group.GetFromItemID(); 255 UUID newAttachmentItemID = group.GetFromItemID();
325 if (newAttachmentItemID == UUID.Zero) 256 if (newAttachmentItemID == UUID.Zero)
326 newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp.ControllingClient, group).ID; 257 newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp, group).ID;
327 258
328 ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group); 259 ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group);
329 } 260 }
@@ -334,55 +265,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
334 return true; 265 return true;
335 } 266 }
336 267
337 public void RezMultipleAttachmentsFromInventory( 268 public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt)
338 IClientAPI remoteClient, 269 {
339 RezMultipleAttachmentsFromInvPacket.HeaderDataBlock header, 270 return RezSingleAttachmentFromInventory(sp, itemID, AttachmentPt, true, null);
340 RezMultipleAttachmentsFromInvPacket.ObjectDataBlock[] objects) 271 }
341 {
342 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
343
344 if (sp == null)
345 {
346 m_log.ErrorFormat(
347 "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1} in RezMultipleAttachmentsFromInventory()",
348 remoteClient.Name, remoteClient.AgentId);
349 return;
350 }
351
352 lock (sp.AttachmentsSyncLock)
353 {
354// m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing multiple attachments from inventory for {0}", sp.Name);
355
356 foreach (RezMultipleAttachmentsFromInvPacket.ObjectDataBlock obj in objects)
357 {
358 RezSingleAttachmentFromInventory(sp, obj.ItemID, obj.AttachmentPt);
359 }
360 }
361 }
362
363 public ISceneEntity RezSingleAttachmentFromInventory(IClientAPI remoteClient, UUID itemID, uint AttachmentPt)
364 {
365 return RezSingleAttachmentFromInventory(remoteClient, itemID, AttachmentPt, true, null);
366 }
367 272
368 public ISceneEntity RezSingleAttachmentFromInventory( 273 public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt, bool updateInventoryStatus, XmlDocument doc)
369 IClientAPI remoteClient, UUID itemID, uint AttachmentPt, bool updateInventoryStatus, XmlDocument doc)
370 { 274 {
371 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); 275 if (!Enabled)
372
373 if (sp == null)
374 {
375 m_log.ErrorFormat(
376 "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1} in RezSingleAttachmentFromInventory()",
377 remoteClient.Name, remoteClient.AgentId);
378 return null; 276 return null;
379 }
380
381 return RezSingleAttachmentFromInventory(sp, itemID, AttachmentPt);
382 }
383 277
384 public ISceneEntity RezSingleAttachmentFromInventory(ScenePresence sp, UUID itemID, uint AttachmentPt)
385 {
386// m_log.DebugFormat( 278// m_log.DebugFormat(
387// "[ATTACHMENTS MODULE]: RezSingleAttachmentFromInventory to point {0} from item {1} for {2}", 279// "[ATTACHMENTS MODULE]: RezSingleAttachmentFromInventory to point {0} from item {1} for {2}",
388// (AttachmentPoint)AttachmentPt, itemID, sp.Name); 280// (AttachmentPoint)AttachmentPt, itemID, sp.Name);
@@ -417,188 +309,44 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
417 return null; 309 return null;
418 } 310 }
419 311
420 SceneObjectGroup att = RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, null); 312 SceneObjectGroup att = RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, doc);
421 313
422 if (att == null) 314 if (att == null)
423 DetachSingleAttachmentToInv(itemID, sp.ControllingClient); 315 DetachSingleAttachmentToInv(sp, itemID);
424 316
425 return att; 317 return att;
426 } 318 }
427 319
428 protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal( 320 public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist)
429 IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, XmlDocument doc)
430 {
431 IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>();
432 if (invAccess != null)
433 {
434 lock (sp.AttachmentsSyncLock)
435 {
436 SceneObjectGroup objatt;
437
438 if (itemID != UUID.Zero)
439 objatt = invAccess.RezObject(sp.ControllingClient,
440 itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
441 false, false, sp.UUID, true);
442 else
443 objatt = invAccess.RezObject(sp.ControllingClient,
444 null, assetID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
445 false, false, sp.UUID, true);
446
447 // m_log.DebugFormat(
448 // "[ATTACHMENTS MODULE]: Retrieved single object {0} for attachment to {1} on point {2}",
449 // objatt.Name, remoteClient.Name, AttachmentPt);
450
451 if (objatt != null)
452 {
453 // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller.
454 objatt.HasGroupChanged = false;
455 bool tainted = false;
456 if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint)
457 tainted = true;
458
459 // This will throw if the attachment fails
460 try
461 {
462 AttachObject(sp, objatt, attachmentPt, false);
463 }
464 catch (Exception e)
465 {
466 m_log.ErrorFormat(
467 "[ATTACHMENTS MODULE]: Failed to attach {0} {1} for {2}, exception {3}{4}",
468 objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace);
469
470 // Make sure the object doesn't stick around and bail
471 sp.RemoveAttachment(objatt);
472 m_scene.DeleteSceneObject(objatt, false);
473 return null;
474 }
475
476 if (tainted)
477 objatt.HasGroupChanged = true;
478
479 // Fire after attach, so we don't get messy perms dialogs
480 // 4 == AttachedRez
481 objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4);
482 objatt.ResumeScripts();
483
484 // Do this last so that event listeners have access to all the effects of the attachment
485 m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, sp.UUID);
486
487 return objatt;
488 }
489 else
490 {
491 m_log.WarnFormat(
492 "[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}",
493 itemID, sp.Name, attachmentPt);
494 }
495
496 if (doc != null)
497 {
498 objatt.LoadScriptState(doc);
499 objatt.ResetOwnerChangeFlag();
500 }
501
502 // Fire after attach, so we don't get messy perms dialogs
503 // 4 == AttachedRez
504 objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4);
505 objatt.ResumeScripts();
506
507 // Do this last so that event listeners have access to all the effects of the attachment
508 m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, sp.UUID);
509 }
510 }
511
512 return null;
513 }
514
515 /// <summary>
516 /// Update the user inventory to reflect an attachment
517 /// </summary>
518 /// <param name="sp"></param>
519 /// <param name="AttachmentPt"></param>
520 /// <param name="itemID"></param>
521 /// <param name="att"></param>
522 private void ShowAttachInUserInventory(
523 IScenePresence sp, uint AttachmentPt, UUID itemID, SceneObjectGroup att)
524 { 321 {
525// m_log.DebugFormat( 322 if (!Enabled)
526// "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}",
527// att.Name, sp.Name, AttachmentPt, itemID);
528
529 if (UUID.Zero == itemID)
530 {
531 m_log.Error("[ATTACHMENTS MODULE]: Unable to save attachment. Error inventory item ID.");
532 return;
533 }
534
535 if (0 == AttachmentPt)
536 {
537 m_log.Error("[ATTACHMENTS MODULE]: Unable to save attachment. Error attachment point.");
538 return;
539 }
540
541 if (null == att.RootPart)
542 {
543 m_log.Error("[ATTACHMENTS MODULE]: Unable to save attachment for a prim without the rootpart!");
544 return; 323 return;
545 }
546 InventoryItemBase item = new InventoryItemBase(itemID, sp.UUID);
547
548
549
550
551
552
553 item = m_scene.InventoryService.GetItem(item);
554 bool changed = sp.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID);
555 if (changed && m_scene.AvatarFactory != null)
556 m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID);
557 }
558 324
559 public void DetachObject(uint objectLocalID, IClientAPI remoteClient) 325 // m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing multiple attachments from inventory for {0}", sp.Name);
560 { 326 lock (sp.AttachmentsSyncLock)
561// m_log.DebugFormat(
562// "[ATTACHMENTS MODULE]: DetachObject() for object {0} on {1}", objectLocalID, remoteClient.Name);
563
564 SceneObjectGroup group = m_scene.GetGroupByPrim(objectLocalID);
565 if (group != null)
566 {
567 DetachSingleAttachmentToInv(group.GetFromItemID(), remoteClient);
568 }
569 }
570
571 public void DetachSingleAttachmentToInv(UUID itemID, IClientAPI remoteClient)
572 {
573 ScenePresence presence;
574 if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence))
575 { 327 {
576 lock (presence.AttachmentsSyncLock) 328 foreach (KeyValuePair<UUID, uint> rez in rezlist)
577 { 329 {
578 // Save avatar attachment information 330 RezSingleAttachmentFromInventory(sp, rez.Key, rez.Value);
579 m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + remoteClient.AgentId + ", ItemID: " + itemID);
580
581 bool changed = presence.Appearance.DetachAttachment(itemID);
582 if (changed && m_scene.AvatarFactory != null)
583 m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId);
584
585 DetachSingleAttachmentToInv(itemID, presence);
586 } 331 }
587 } 332 }
588 } 333 }
589 334
590 public void DetachSingleAttachmentToGround(uint soLocalId, IClientAPI remoteClient) 335 public void DetachSingleAttachmentToGround(IScenePresence sp, uint soLocalId)
591 { 336 {
337 if (!Enabled)
338 return;
339
592// m_log.DebugFormat( 340// m_log.DebugFormat(
593// "[ATTACHMENTS MODULE]: DetachSingleAttachmentToGround() for {0}, object {1}", 341// "[ATTACHMENTS MODULE]: DetachSingleAttachmentToGround() for {0}, object {1}",
594// remoteClient.Name, soLocalId); 342// sp.UUID, soLocalId);
595 343
596 SceneObjectGroup so = m_scene.GetGroupByPrim(soLocalId); 344 SceneObjectGroup so = m_scene.GetGroupByPrim(soLocalId);
597 345
598 if (so == null) 346 if (so == null)
599 return; 347 return;
600 348
601 if (so.AttachedAvatar != remoteClient.AgentId) 349 if (so.AttachedAvatar != sp.UUID)
602 return; 350 return;
603 351
604 UUID inventoryID = so.GetFromItemID(); 352 UUID inventoryID = so.GetFromItemID();
@@ -607,103 +355,62 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
607// "[ATTACHMENTS MODULE]: In DetachSingleAttachmentToGround(), object is {0} {1}, associated item is {2}", 355// "[ATTACHMENTS MODULE]: In DetachSingleAttachmentToGround(), object is {0} {1}, associated item is {2}",
608// so.Name, so.LocalId, inventoryID); 356// so.Name, so.LocalId, inventoryID);
609 357
610 ScenePresence presence; 358 lock (sp.AttachmentsSyncLock)
611 if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence))
612 { 359 {
613 lock (presence.AttachmentsSyncLock) 360 if (!m_scene.Permissions.CanRezObject(
614 { 361 so.PrimCount, sp.UUID, sp.AbsolutePosition))
615 if (!m_scene.Permissions.CanRezObject( 362 return;
616 so.PrimCount, remoteClient.AgentId, presence.AbsolutePosition))
617 return;
618
619 bool changed = presence.Appearance.DetachAttachment(inventoryID);
620 if (changed && m_scene.AvatarFactory != null)
621 m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId);
622
623 presence.RemoveAttachment(so);
624 DetachSceneObjectToGround(so, presence);
625
626 List<UUID> uuids = new List<UUID>();
627 uuids.Add(inventoryID);
628 m_scene.InventoryService.DeleteItems(remoteClient.AgentId, uuids);
629 remoteClient.SendRemoveInventoryItem(inventoryID);
630 }
631 363
632 m_scene.EventManager.TriggerOnAttach(so.LocalId, so.UUID, UUID.Zero); 364 bool changed = sp.Appearance.DetachAttachment(inventoryID);
365 if (changed && m_scene.AvatarFactory != null)
366 m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID);
367
368 sp.RemoveAttachment(so);
369
370 SceneObjectPart rootPart = so.RootPart;
371 rootPart.FromItemID = UUID.Zero;
372 so.AbsolutePosition = sp.AbsolutePosition;
373 so.AttachedAvatar = UUID.Zero;
374 rootPart.SetParentLocalId(0);
375 so.ClearPartAttachmentData();
376 rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive, m_scene.m_physicalPrim);
377 so.HasGroupChanged = true;
378 rootPart.Rezzed = DateTime.Now;
379 rootPart.RemFlag(PrimFlags.TemporaryOnRez);
380 so.AttachToBackup();
381 m_scene.EventManager.TriggerParcelPrimCountTainted();
382 rootPart.ScheduleFullUpdate();
383 rootPart.ClearUndoState();
384
385 List<UUID> uuids = new List<UUID>();
386 uuids.Add(inventoryID);
387 m_scene.InventoryService.DeleteItems(sp.UUID, uuids);
388 sp.ControllingClient.SendRemoveInventoryItem(inventoryID);
633 } 389 }
634 }
635 390
636 /// <summary> 391 m_scene.EventManager.TriggerOnAttach(so.LocalId, so.UUID, UUID.Zero);
637 /// Detach the given scene object to the ground.
638 /// </summary>
639 /// <remarks>
640 /// The caller has to take care of all the other work in updating avatar appearance, inventory, etc.
641 /// </remarks>
642 /// <param name="so">The scene object to detach.</param>
643 /// <param name="sp">The scene presence from which the scene object is being detached.</param>
644 private void DetachSceneObjectToGround(SceneObjectGroup so, ScenePresence sp)
645 {
646 SceneObjectPart rootPart = so.RootPart;
647
648 rootPart.FromItemID = UUID.Zero;
649 so.AbsolutePosition = sp.AbsolutePosition;
650 so.AttachedAvatar = UUID.Zero;
651 rootPart.SetParentLocalId(0);
652 so.ClearPartAttachmentData();
653 rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive, m_scene.m_physicalPrim);
654 so.HasGroupChanged = true;
655 rootPart.Rezzed = DateTime.Now;
656 rootPart.RemFlag(PrimFlags.TemporaryOnRez);
657 so.AttachToBackup();
658 m_scene.EventManager.TriggerParcelPrimCountTainted();
659 rootPart.ScheduleFullUpdate();
660 rootPart.ClearUndoState();
661 } 392 }
662
663 // What makes this method odd and unique is it tries to detach using an UUID.... Yay for standards.
664 // To LocalId or UUID, *THAT* is the question. How now Brown UUID??
665 private void DetachSingleAttachmentToInv(UUID itemID, IScenePresence sp)
666 {
667// m_log.DebugFormat("[ATTACHMENTS MODULE]: Detaching item {0} to inventory for {1}", itemID, sp.Name);
668
669 if (itemID == UUID.Zero) // If this happened, someone made a mistake....
670 return;
671
672 // We can NOT use the dictionries here, as we are looking
673 // for an entity by the fromAssetID, which is NOT the prim UUID
674 EntityBase[] detachEntities = m_scene.GetEntities();
675 SceneObjectGroup group;
676 393
394 public void DetachSingleAttachmentToInv(IScenePresence sp, UUID itemID)
395 {
677 lock (sp.AttachmentsSyncLock) 396 lock (sp.AttachmentsSyncLock)
678 { 397 {
679 foreach (EntityBase entity in detachEntities) 398 // Save avatar attachment information
680 { 399 m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + sp.UUID + ", ItemID: " + itemID);
681 if (entity is SceneObjectGroup)
682 {
683 group = (SceneObjectGroup)entity; if (group.GetFromItemID() == itemID) { m_scene.EventManager.TriggerOnAttach(group.LocalId, itemID, UUID.Zero);
684 // CM / XMREngine!!!! Needed to conclude attach event
685 //SceneObjectSerializer.ToOriginalXmlFormat(group);
686 group.DetachToInventoryPrep();
687 m_log.Debug("[ATTACHMENTS MODULE]: Saving attachpoint: " + ((uint)group.GetAttachmentPoint()).ToString());
688 400
689 // Prepare sog for storage 401 bool changed = sp.Appearance.DetachAttachment(itemID);
690 group.AttachedAvatar = UUID.Zero; 402 if (changed && m_scene.AvatarFactory != null)
691 group.RootPart.SetParentLocalId(0); 403 m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID);
692 group.IsAttachment = false;
693 group.AbsolutePosition = group.RootPart.AttachedPos;
694
695 UpdateKnownItem(sp.ControllingClient, group);
696 m_scene.DeleteSceneObject(group, false);
697 404
698 return; 405 DetachSingleAttachmentToInvInternal(sp, itemID);
699 }
700 }
701 }
702 } 406 }
703 } 407 }
704 408
705 public void UpdateAttachmentPosition(SceneObjectGroup sog, Vector3 pos) 409 public void UpdateAttachmentPosition(SceneObjectGroup sog, Vector3 pos)
706 { 410 {
411 if (!Enabled)
412 return;
413
707 // First we save the 414 // First we save the
708 // attachment point information, then we update the relative 415 // attachment point information, then we update the relative
709 // positioning. Then we have to mark the object as NOT an 416 // positioning. Then we have to mark the object as NOT an
@@ -717,7 +424,37 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
717 sog.AttachmentPoint = attachmentPoint; 424 sog.AttachmentPoint = attachmentPoint;
718 sog.HasGroupChanged = true; 425 sog.HasGroupChanged = true;
719 } 426 }
720 427
428 #endregion
429
430 #region AttachmentModule private methods
431
432 // This is public but is not part of the IAttachmentsModule interface.
433 // RegionCombiner module needs to poke at it to deliver client events.
434 // This breaks the encapsulation of the module and should get fixed somehow.
435 public void SubscribeToClientEvents(IClientAPI client)
436 {
437 client.OnRezSingleAttachmentFromInv += Client_OnRezSingleAttachmentFromInv;
438 client.OnRezMultipleAttachmentsFromInv += Client_OnRezMultipleAttachmentsFromInv;
439 client.OnObjectAttach += Client_OnObjectAttach;
440 client.OnObjectDetach += Client_OnObjectDetach;
441 client.OnDetachAttachmentIntoInv += Client_OnDetachAttachmentIntoInv;
442 client.OnObjectDrop += Client_OnObjectDrop;
443 }
444
445 // This is public but is not part of the IAttachmentsModule interface.
446 // RegionCombiner module needs to poke at it to deliver client events.
447 // This breaks the encapsulation of the module and should get fixed somehow.
448 public void UnsubscribeFromClientEvents(IClientAPI client)
449 {
450 client.OnRezSingleAttachmentFromInv -= Client_OnRezSingleAttachmentFromInv;
451 client.OnRezMultipleAttachmentsFromInv -= Client_OnRezMultipleAttachmentsFromInv;
452 client.OnObjectAttach -= Client_OnObjectAttach;
453 client.OnObjectDetach -= Client_OnObjectDetach;
454 client.OnDetachAttachmentIntoInv -= Client_OnDetachAttachmentIntoInv;
455 client.OnObjectDrop -= Client_OnObjectDrop;
456 }
457
721 /// <summary> 458 /// <summary>
722 /// Update the attachment asset for the new sog details if they have changed. 459 /// Update the attachment asset for the new sog details if they have changed.
723 /// </summary> 460 /// </summary>
@@ -725,9 +462,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
725 /// This is essential for preserving attachment attributes such as permission. Unlike normal scene objects, 462 /// This is essential for preserving attachment attributes such as permission. Unlike normal scene objects,
726 /// these details are not stored on the region. 463 /// these details are not stored on the region.
727 /// </remarks> 464 /// </remarks>
728 /// <param name="remoteClient"></param> 465 /// <param name="sp"></param>
729 /// <param name="grp"></param> 466 /// <param name="grp"></param>
730 private void UpdateKnownItem(IClientAPI remoteClient, SceneObjectGroup grp) 467 private void UpdateKnownItem(IScenePresence sp, SceneObjectGroup grp)
731 { 468 {
732 if (grp.HasGroupChanged || grp.ContainsScripts()) 469 if (grp.HasGroupChanged || grp.ContainsScripts())
733 { 470 {
@@ -737,7 +474,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
737 474
738 string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp); 475 string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp);
739 476
740 InventoryItemBase item = new InventoryItemBase(grp.GetFromItemID(), remoteClient.AgentId); 477 InventoryItemBase item = new InventoryItemBase(grp.GetFromItemID(), sp.UUID);
741 item = m_scene.InventoryService.GetItem(item); 478 item = m_scene.InventoryService.GetItem(item);
742 479
743 if (item != null) 480 if (item != null)
@@ -747,7 +484,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
747 grp.GetPartDescription(grp.LocalId), 484 grp.GetPartDescription(grp.LocalId),
748 (sbyte)AssetType.Object, 485 (sbyte)AssetType.Object,
749 Utils.StringToBytes(sceneObjectXml), 486 Utils.StringToBytes(sceneObjectXml),
750 remoteClient.AgentId); 487 sp.UUID);
751 m_scene.AssetService.Store(asset); 488 m_scene.AssetService.Store(asset);
752 489
753 item.AssetID = asset.FullID; 490 item.AssetID = asset.FullID;
@@ -759,8 +496,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
759 m_scene.InventoryService.UpdateItem(item); 496 m_scene.InventoryService.UpdateItem(item);
760 497
761 // this gets called when the agent logs off! 498 // this gets called when the agent logs off!
762 if (remoteClient != null) 499 if (sp.ControllingClient != null)
763 remoteClient.SendInventoryItemCreateUpdate(item, 0); 500 sp.ControllingClient.SendInventoryItemCreateUpdate(item, 0);
764 } 501 }
765 } 502 }
766 else 503 else
@@ -769,8 +506,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
769 "[ATTACHMENTS MODULE]: Don't need to update asset for unchanged attachment {0}, attachpoint {1}", 506 "[ATTACHMENTS MODULE]: Don't need to update asset for unchanged attachment {0}, attachpoint {1}",
770 grp.UUID, grp.AttachmentPoint); 507 grp.UUID, grp.AttachmentPoint);
771 } 508 }
772 } 509 }
773 510
774 /// <summary> 511 /// <summary>
775 /// Attach this scene object to the given avatar. 512 /// Attach this scene object to the given avatar.
776 /// </summary> 513 /// </summary>
@@ -784,19 +521,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
784 /// <param name="attachOffset"></param> 521 /// <param name="attachOffset"></param>
785 /// <param name="silent"></param> 522 /// <param name="silent"></param>
786 private void AttachToAgent( 523 private void AttachToAgent(
787 IScenePresence avatar, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent) 524 IScenePresence sp, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent)
788 { 525 {
789// m_log.DebugFormat( 526 // m_log.DebugFormat(
790// "[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}", 527 // "[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}",
791// so.Name, avatar.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos); 528 // so.Name, avatar.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos);
792 529
793 so.DetachFromBackup(); 530 so.DetachFromBackup();
794 531
795 // Remove from database and parcel prim count 532 // Remove from database and parcel prim count
796 m_scene.DeleteFromStorage(so.UUID); 533 m_scene.DeleteFromStorage(so.UUID);
797 m_scene.EventManager.TriggerParcelPrimCountTainted(); 534 m_scene.EventManager.TriggerParcelPrimCountTainted();
798 535
799 so.AttachedAvatar = avatar.UUID; 536 so.AttachedAvatar = sp.UUID;
800 537
801 if (so.RootPart.PhysActor != null) 538 if (so.RootPart.PhysActor != null)
802 { 539 {
@@ -807,17 +544,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
807 so.AbsolutePosition = attachOffset; 544 so.AbsolutePosition = attachOffset;
808 so.RootPart.AttachedPos = attachOffset; 545 so.RootPart.AttachedPos = attachOffset;
809 so.IsAttachment = true; 546 so.IsAttachment = true;
810 so.RootPart.SetParentLocalId(avatar.LocalId); 547 so.RootPart.SetParentLocalId(sp.LocalId);
811 so.AttachmentPoint = attachmentpoint; 548 so.AttachmentPoint = attachmentpoint;
812 549
813 avatar.AddAttachment(so); 550 sp.AddAttachment(so);
814 551
815 if (!silent) 552 if (!silent)
816 { 553 {
817 so.IsSelected = false; // fudge.... 554 so.IsSelected = false; // fudge....
818 so.ScheduleGroupForFullUpdate(); 555 so.ScheduleGroupForFullUpdate();
819 } 556 }
820 557
821 // In case it is later dropped again, don't let 558 // In case it is later dropped again, don't let
822 // it get cleaned up 559 // it get cleaned up
823 so.RootPart.RemFlag(PrimFlags.TemporaryOnRez); 560 so.RootPart.RemFlag(PrimFlags.TemporaryOnRez);
@@ -829,19 +566,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
829 /// <param name="remoteClient"></param> 566 /// <param name="remoteClient"></param>
830 /// <param name="grp"></param> 567 /// <param name="grp"></param>
831 /// <returns>The user inventory item created that holds the attachment.</returns> 568 /// <returns>The user inventory item created that holds the attachment.</returns>
832 private InventoryItemBase AddSceneObjectAsNewAttachmentInInv(IClientAPI remoteClient, SceneObjectGroup grp) 569 private InventoryItemBase AddSceneObjectAsNewAttachmentInInv(IScenePresence sp, SceneObjectGroup grp)
833 { 570 {
834// m_log.DebugFormat( 571 // m_log.DebugFormat(
835// "[ATTACHMENTS MODULE]: Called AddSceneObjectAsAttachment for object {0} {1} for {2}", 572 // "[ATTACHMENTS MODULE]: Called AddSceneObjectAsAttachment for object {0} {1} for {2}",
836// grp.Name, grp.LocalId, remoteClient.Name); 573 // grp.Name, grp.LocalId, remoteClient.Name);
837 uint regionSize = Constants.RegionSize; //Avoid VS error "The operation overflows at compile time in checked mode" 574
838 Vector3 inventoryStoredPosition = new Vector3 575 Vector3 inventoryStoredPosition = new Vector3
839 (((grp.AbsolutePosition.X > (int)Constants.RegionSize) 576 (((grp.AbsolutePosition.X > (int)Constants.RegionSize)
840 ? regionSize - 6 577 ? (float)Constants.RegionSize - 6
841 : grp.AbsolutePosition.X) 578 : grp.AbsolutePosition.X)
842 , 579 ,
843 (grp.AbsolutePosition.Y > (int)Constants.RegionSize) 580 (grp.AbsolutePosition.Y > (int)Constants.RegionSize)
844 ? regionSize - 6 581 ? (float)Constants.RegionSize - 6
845 : grp.AbsolutePosition.Y, 582 : grp.AbsolutePosition.Y,
846 grp.AbsolutePosition.Z); 583 grp.AbsolutePosition.Z);
847 584
@@ -862,14 +599,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
862 grp.GetPartDescription(grp.LocalId), 599 grp.GetPartDescription(grp.LocalId),
863 (sbyte)AssetType.Object, 600 (sbyte)AssetType.Object,
864 Utils.StringToBytes(sceneObjectXml), 601 Utils.StringToBytes(sceneObjectXml),
865 remoteClient.AgentId); 602 sp.UUID);
866 603
867 m_scene.AssetService.Store(asset); 604 m_scene.AssetService.Store(asset);
868 605
869 InventoryItemBase item = new InventoryItemBase(); 606 InventoryItemBase item = new InventoryItemBase();
870 item.CreatorId = grp.RootPart.CreatorID.ToString(); 607 item.CreatorId = grp.RootPart.CreatorID.ToString();
871 item.CreatorData = grp.RootPart.CreatorData; 608 item.CreatorData = grp.RootPart.CreatorData;
872 item.Owner = remoteClient.AgentId; 609 item.Owner = sp.UUID;
873 item.ID = UUID.Random(); 610 item.ID = UUID.Random();
874 item.AssetID = asset.FullID; 611 item.AssetID = asset.FullID;
875 item.Description = asset.Description; 612 item.Description = asset.Description;
@@ -877,13 +614,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
877 item.AssetType = asset.Type; 614 item.AssetType = asset.Type;
878 item.InvType = (int)InventoryType.Object; 615 item.InvType = (int)InventoryType.Object;
879 616
880 InventoryFolderBase folder = m_scene.InventoryService.GetFolderForType(remoteClient.AgentId, AssetType.Object); 617 InventoryFolderBase folder = m_scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object);
881 if (folder != null) 618 if (folder != null)
882 item.Folder = folder.ID; 619 item.Folder = folder.ID;
883 else // oopsies 620 else // oopsies
884 item.Folder = UUID.Zero; 621 item.Folder = UUID.Zero;
885 622
886 if ((remoteClient.AgentId != grp.RootPart.OwnerID) && m_scene.Permissions.PropagatePermissions()) 623 if ((sp.UUID != grp.RootPart.OwnerID) && m_scene.Permissions.PropagatePermissions())
887 { 624 {
888 item.BasePermissions = grp.RootPart.NextOwnerMask; 625 item.BasePermissions = grp.RootPart.NextOwnerMask;
889 item.CurrentPermissions = grp.RootPart.NextOwnerMask; 626 item.CurrentPermissions = grp.RootPart.NextOwnerMask;
@@ -906,15 +643,304 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
906 643
907 if (m_scene.AddInventoryItem(item)) 644 if (m_scene.AddInventoryItem(item))
908 { 645 {
909 remoteClient.SendInventoryItemCreateUpdate(item, 0); 646 sp.ControllingClient.SendInventoryItemCreateUpdate(item, 0);
910 } 647 }
911 else 648 else
912 { 649 {
913 if (m_dialogModule != null) 650 if (m_dialogModule != null)
914 m_dialogModule.SendAlertToUser(remoteClient, "Operation failed"); 651 m_dialogModule.SendAlertToUser(sp.ControllingClient, "Operation failed");
915 } 652 }
916 653
917 return item; 654 return item;
918 } 655 }
656
657 // What makes this method odd and unique is it tries to detach using an UUID.... Yay for standards.
658 // To LocalId or UUID, *THAT* is the question. How now Brown UUID??
659 private void DetachSingleAttachmentToInvInternal(IScenePresence sp, UUID itemID)
660 {
661 // m_log.DebugFormat("[ATTACHMENTS MODULE]: Detaching item {0} to inventory for {1}", itemID, sp.Name);
662
663 if (itemID == UUID.Zero) // If this happened, someone made a mistake....
664 return;
665
666 // We can NOT use the dictionries here, as we are looking
667 // for an entity by the fromAssetID, which is NOT the prim UUID
668 EntityBase[] detachEntities = m_scene.GetEntities();
669 SceneObjectGroup group;
670
671 lock (sp.AttachmentsSyncLock)
672 {
673 foreach (EntityBase entity in detachEntities)
674 {
675 if (entity is SceneObjectGroup)
676 {
677 group = (SceneObjectGroup)entity;
678 if (group.GetFromItemID() == itemID)
679 {
680 m_scene.EventManager.TriggerOnAttach(group.LocalId, itemID, UUID.Zero);
681 sp.RemoveAttachment(group);
682
683 // Prepare sog for storage
684 group.AttachedAvatar = UUID.Zero;
685 group.RootPart.SetParentLocalId(0);
686 group.IsAttachment = false;
687 group.AbsolutePosition = group.RootPart.AttachedPos;
688
689 UpdateKnownItem(sp, group);
690 m_scene.DeleteSceneObject(group, false);
691
692 return;
693 }
694 }
695 }
696 }
697 }
698
699 protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal(
700 IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, XmlDocument doc)
701 {
702 IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>();
703 if (invAccess != null)
704 {
705 lock (sp.AttachmentsSyncLock)
706 {
707 SceneObjectGroup objatt;
708
709 if (itemID != UUID.Zero)
710 objatt = invAccess.RezObject(sp.ControllingClient,
711 itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
712 false, false, sp.UUID, true);
713 else
714 objatt = invAccess.RezObject(sp.ControllingClient,
715 null, assetID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
716 false, false, sp.UUID, true);
717
718 // m_log.DebugFormat(
719 // "[ATTACHMENTS MODULE]: Retrieved single object {0} for attachment to {1} on point {2}",
720 // objatt.Name, remoteClient.Name, AttachmentPt);
721
722 if (objatt != null)
723 {
724 // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller.
725 objatt.HasGroupChanged = false;
726 bool tainted = false;
727 if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint)
728 tainted = true;
729
730 // This will throw if the attachment fails
731 try
732 {
733 AttachObject(sp, objatt, attachmentPt, false);
734 }
735 catch (Exception e)
736 {
737 m_log.ErrorFormat(
738 "[ATTACHMENTS MODULE]: Failed to attach {0} {1} for {2}, exception {3}{4}",
739 objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace);
740
741 // Make sure the object doesn't stick around and bail
742 sp.RemoveAttachment(objatt);
743 m_scene.DeleteSceneObject(objatt, false);
744 return null;
745 }
746
747 if (tainted)
748 objatt.HasGroupChanged = true;
749
750 // Fire after attach, so we don't get messy perms dialogs
751 // 4 == AttachedRez
752 objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4);
753 objatt.ResumeScripts();
754
755 // Do this last so that event listeners have access to all the effects of the attachment
756 m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, sp.UUID);
757
758 return objatt;
759 }
760 else
761 {
762 m_log.WarnFormat(
763 "[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}",
764 itemID, sp.Name, attachmentPt);
765 }
766
767 if (doc != null)
768 {
769 objatt.LoadScriptState(doc);
770 objatt.ResetOwnerChangeFlag();
771 }
772
773 // Fire after attach, so we don't get messy perms dialogs
774 // 4 == AttachedRez
775 objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4);
776 objatt.ResumeScripts();
777
778 // Do this last so that event listeners have access to all the effects of the attachment
779 m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, sp.UUID);
780 }
781 }
782
783 return null;
784 }
785
786 /// <summary>
787 /// Update the user inventory to reflect an attachment
788 /// </summary>
789 /// <param name="sp"></param>
790 /// <param name="AttachmentPt"></param>
791 /// <param name="itemID"></param>
792 /// <param name="att"></param>
793 private void ShowAttachInUserInventory(IScenePresence sp, uint AttachmentPt, UUID itemID, SceneObjectGroup att)
794 {
795 // m_log.DebugFormat(
796 // "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}",
797 // att.Name, sp.Name, AttachmentPt, itemID);
798
799 if (UUID.Zero == itemID)
800 {
801 m_log.Error("[ATTACHMENTS MODULE]: Unable to save attachment. Error inventory item ID.");
802 return;
803 }
804
805 if (0 == AttachmentPt)
806 {
807 m_log.Error("[ATTACHMENTS MODULE]: Unable to save attachment. Error attachment point.");
808 return;
809 }
810
811 InventoryItemBase item = new InventoryItemBase(itemID, sp.UUID);
812 item = m_scene.InventoryService.GetItem(item);
813 bool changed = sp.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID);
814 if (changed && m_scene.AvatarFactory != null)
815 m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID);
816 }
817
818 #endregion
819
820 #region Client Event Handlers
821
822 private ISceneEntity Client_OnRezSingleAttachmentFromInv(IClientAPI remoteClient, UUID itemID, uint AttachmentPt)
823 {
824 if (!Enabled)
825 return null;
826
827 // m_log.DebugFormat(
828 // "[ATTACHMENTS MODULE]: Rezzing attachment to point {0} from item {1} for {2}",
829 // (AttachmentPoint)AttachmentPt, itemID, remoteClient.Name);
830
831 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
832
833 if (sp == null)
834 {
835 m_log.ErrorFormat(
836 "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1} in RezSingleAttachmentFromInventory()",
837 remoteClient.Name, remoteClient.AgentId);
838 return null;
839 }
840
841 return RezSingleAttachmentFromInventory(sp, itemID, AttachmentPt);
842 }
843
844 private void Client_OnRezMultipleAttachmentsFromInv(IClientAPI remoteClient, List<KeyValuePair<UUID, uint>> rezlist)
845 {
846 if (!Enabled)
847 return;
848
849 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
850 if (sp != null)
851 RezMultipleAttachmentsFromInventory(sp, rezlist);
852 else
853 m_log.ErrorFormat(
854 "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1} in RezMultipleAttachmentsFromInventory()",
855 remoteClient.Name, remoteClient.AgentId);
856 }
857
858 private void Client_OnObjectAttach(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent)
859 {
860 // m_log.DebugFormat(
861 // "[ATTACHMENTS MODULE]: Attaching object local id {0} to {1} point {2} from ground (silent = {3})",
862 // objectLocalID, remoteClient.Name, AttachmentPt, silent);
863
864 if (!Enabled)
865 return;
866
867 try
868 {
869 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
870
871 if (sp == null)
872 {
873 m_log.ErrorFormat(
874 "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1}", remoteClient.Name, remoteClient.AgentId);
875 return;
876 }
877
878 // If we can't take it, we can't attach it!
879 SceneObjectPart part = m_scene.GetSceneObjectPart(objectLocalID);
880 if (part == null)
881 return;
882
883 if (!m_scene.Permissions.CanTakeObject(part.UUID, remoteClient.AgentId))
884 {
885 remoteClient.SendAgentAlertMessage(
886 "You don't have sufficient permissions to attach this object", false);
887
888 return;
889 }
890
891 // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should
892 // be removed when that functionality is implemented in opensim
893 AttachmentPt &= 0x7f;
894
895 // Calls attach with a Zero position
896 if (AttachObject(sp, part.ParentGroup, AttachmentPt, false))
897 {
898 m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId);
899
900 // Save avatar attachment information
901 m_log.Debug(
902 "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId
903 + ", AttachmentPoint: " + AttachmentPt);
904
905 }
906 }
907 catch (Exception e)
908 {
909 m_log.ErrorFormat("[ATTACHMENTS MODULE]: exception upon Attach Object {0}{1}", e.Message, e.StackTrace);
910 }
911 }
912
913 private void Client_OnObjectDetach(uint objectLocalID, IClientAPI remoteClient)
914 {
915 if (!Enabled)
916 return;
917
918 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
919 SceneObjectGroup group = m_scene.GetGroupByPrim(objectLocalID);
920 if (sp != null && group != null)
921 DetachSingleAttachmentToInv(sp, group.GetFromItemID());
922 }
923
924 private void Client_OnDetachAttachmentIntoInv(UUID itemID, IClientAPI remoteClient)
925 {
926 if (!Enabled)
927 return;
928
929 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
930 if (sp != null)
931 DetachSingleAttachmentToInv(sp, itemID);
932 }
933
934 private void Client_OnObjectDrop(uint soLocalId, IClientAPI remoteClient)
935 {
936 if (!Enabled)
937 return;
938
939 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
940 if (sp != null)
941 DetachSingleAttachmentToGround(sp, soLocalId);
942 }
943
944 #endregion
919 } 945 }
920} \ No newline at end of file 946}
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
index ff3358f..86cfb32 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
@@ -106,7 +106,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
106 106
107 SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName).ParentGroup; 107 SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName).ParentGroup;
108 108
109 m_attMod.AttachObject(m_presence.ControllingClient, so, (uint)AttachmentPoint.Chest, false); 109 m_attMod.AttachObject(m_presence, so, (uint)AttachmentPoint.Chest, false);
110 110
111 // Check status on scene presence 111 // Check status on scene presence
112 Assert.That(m_presence.HasAttachments(), Is.True); 112 Assert.That(m_presence.HasAttachments(), Is.True);
@@ -140,7 +140,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
140 scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object); 140 scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object);
141 141
142 m_attMod.RezSingleAttachmentFromInventory( 142 m_attMod.RezSingleAttachmentFromInventory(
143 m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest); 143 m_presence, attItemId, (uint)AttachmentPoint.Chest);
144 144
145 // Check scene presence status 145 // Check scene presence status
146 Assert.That(m_presence.HasAttachments(), Is.True); 146 Assert.That(m_presence.HasAttachments(), Is.True);
@@ -174,8 +174,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
174 scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object); 174 scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object);
175 175
176 ISceneEntity so = m_attMod.RezSingleAttachmentFromInventory( 176 ISceneEntity so = m_attMod.RezSingleAttachmentFromInventory(
177 m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest); 177 m_presence, attItemId, (uint)AttachmentPoint.Chest);
178 m_attMod.DetachSingleAttachmentToGround(so.LocalId, m_presence.ControllingClient); 178 m_attMod.DetachSingleAttachmentToGround(m_presence, so.LocalId);
179 179
180 // Check scene presence status 180 // Check scene presence status
181 Assert.That(m_presence.HasAttachments(), Is.False); 181 Assert.That(m_presence.HasAttachments(), Is.False);
@@ -208,8 +208,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
208 scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object); 208 scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object);
209 209
210 m_attMod.RezSingleAttachmentFromInventory( 210 m_attMod.RezSingleAttachmentFromInventory(
211 m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest); 211 m_presence, attItemId, (uint)AttachmentPoint.Chest);
212 m_attMod.DetachSingleAttachmentToInv(attItemId, m_presence.ControllingClient); 212 m_attMod.DetachSingleAttachmentToInv(m_presence, attItemId);
213 213
214 // Check status on scene presence 214 // Check status on scene presence
215 Assert.That(m_presence.HasAttachments(), Is.False); 215 Assert.That(m_presence.HasAttachments(), Is.False);
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
index b6a1564..d4e1736 100644
--- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
@@ -64,15 +64,12 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
64 scene.RegisterModuleInterface<IAvatarFactory>(this); 64 scene.RegisterModuleInterface<IAvatarFactory>(this);
65 scene.EventManager.OnNewClient += NewClient; 65 scene.EventManager.OnNewClient += NewClient;
66 66
67 if (config != null) 67 IConfig sconfig = config.Configs["Startup"];
68 if (sconfig != null)
68 { 69 {
69 IConfig sconfig = config.Configs["Startup"]; 70 m_savetime = Convert.ToInt32(sconfig.GetString("DelayBeforeAppearanceSave",Convert.ToString(m_savetime)));
70 if (sconfig != null) 71 m_sendtime = Convert.ToInt32(sconfig.GetString("DelayBeforeAppearanceSend",Convert.ToString(m_sendtime)));
71 { 72 // m_log.InfoFormat("[AVFACTORY] configured for {0} save and {1} send",m_savetime,m_sendtime);
72 m_savetime = Convert.ToInt32(sconfig.GetString("DelayBeforeAppearanceSave",Convert.ToString(m_savetime)));
73 m_sendtime = Convert.ToInt32(sconfig.GetString("DelayBeforeAppearanceSend",Convert.ToString(m_sendtime)));
74 // m_log.InfoFormat("[AVFACTORY] configured for {0} save and {1} send",m_savetime,m_sendtime);
75 }
76 } 73 }
77 74
78 if (m_scene == null) 75 if (m_scene == null)
@@ -211,8 +208,17 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
211 // Process the visual params, this may change height as well 208 // Process the visual params, this may change height as well
212 if (visualParams != null) 209 if (visualParams != null)
213 { 210 {
211// string[] visualParamsStrings = new string[visualParams.Length];
212// for (int i = 0; i < visualParams.Length; i++)
213// visualParamsStrings[i] = visualParams[i].ToString();
214// m_log.DebugFormat(
215// "[AVFACTORY]: Setting visual params for {0} to {1}",
216// client.Name, string.Join(", ", visualParamsStrings));
217
218 float oldHeight = sp.Appearance.AvatarHeight;
214 changed = sp.Appearance.SetVisualParams(visualParams); 219 changed = sp.Appearance.SetVisualParams(visualParams);
215 if (sp.Appearance.AvatarHeight > 0) 220
221 if (sp.Appearance.AvatarHeight != oldHeight && sp.Appearance.AvatarHeight > 0)
216 sp.SetHeight(sp.Appearance.AvatarHeight); 222 sp.SetHeight(sp.Appearance.AvatarHeight);
217 } 223 }
218 224
@@ -416,6 +422,13 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
416 422
417 // m_log.WarnFormat("[AVFACTORY] avatar {0} save appearance",agentid); 423 // m_log.WarnFormat("[AVFACTORY] avatar {0} save appearance",agentid);
418 424
425 // This could take awhile since it needs to pull inventory
426 // We need to do it at the point of save so that there is a sufficient delay for any upload of new body part/shape
427 // assets and item asset id changes to complete.
428 // I don't think we need to worry about doing this within m_setAppearanceLock since the queueing avoids
429 // multiple save requests.
430 SetAppearanceAssets(sp.UUID, sp.Appearance);
431
419 m_scene.AvatarService.SetAppearance(agentid, sp.Appearance); 432 m_scene.AvatarService.SetAppearance(agentid, sp.Appearance);
420 } 433 }
421 434
@@ -467,7 +480,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
467 return; 480 return;
468 } 481 }
469 482
470 // m_log.WarnFormat("[AVFACTORY]: Received request for wearables of {0}", client.AgentId); 483// m_log.DebugFormat("[AVFACTORY]: Received request for wearables of {0}", client.Name);
471 484
472 client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++); 485 client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++);
473 } 486 }
@@ -502,9 +515,6 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
502 515
503 avatAppearance.GetAssetsFrom(sp.Appearance); 516 avatAppearance.GetAssetsFrom(sp.Appearance);
504 517
505 // This could take awhile since it needs to pull inventory
506 SetAppearanceAssets(sp.UUID, ref avatAppearance);
507
508 lock (m_setAppearanceLock) 518 lock (m_setAppearanceLock)
509 { 519 {
510 // Update only those fields that we have changed. This is important because the viewer 520 // Update only those fields that we have changed. This is important because the viewer
@@ -538,7 +548,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
538 return true; 548 return true;
539 } 549 }
540 550
541 private void SetAppearanceAssets(UUID userID, ref AvatarAppearance appearance) 551 private void SetAppearanceAssets(UUID userID, AvatarAppearance appearance)
542 { 552 {
543 IInventoryService invService = m_scene.InventoryService; 553 IInventoryService invService = m_scene.InventoryService;
544 554
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs
index 7753c25..d294692 100644
--- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs
@@ -24,6 +24,7 @@
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27
27using System; 28using System;
28using System.Collections; 29using System.Collections;
29using System.Collections.Generic; 30using System.Collections.Generic;
@@ -145,14 +146,14 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
145 scene.Entities[toAgentID] is ScenePresence) 146 scene.Entities[toAgentID] is ScenePresence)
146 { 147 {
147// m_log.DebugFormat( 148// m_log.DebugFormat(
148// "[INSTANT MESSAGE]: Looking for root agent {0} in {1}", 149// "[HG INSTANT MESSAGE]: Looking for root agent {0} in {1}",
149// toAgentID.ToString(), scene.RegionInfo.RegionName); 150// toAgentID.ToString(), scene.RegionInfo.RegionName);
150 151
151 ScenePresence user = (ScenePresence) scene.Entities[toAgentID]; 152 ScenePresence user = (ScenePresence) scene.Entities[toAgentID];
152 if (!user.IsChildAgent) 153 if (!user.IsChildAgent)
153 { 154 {
154 // Local message 155 // Local message
155// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to root agent {0} {1}", user.Name, toAgentID); 156// m_log.DebugFormat("[HG INSTANT MESSAGE]: Delivering IM to root agent {0} {1}", user.Name, toAgentID);
156 user.ControllingClient.SendInstantMessage(im); 157 user.ControllingClient.SendInstantMessage(im);
157 158
158 // Message sent 159 // Message sent
@@ -166,7 +167,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
166 foreach (Scene scene in m_Scenes) 167 foreach (Scene scene in m_Scenes)
167 { 168 {
168// m_log.DebugFormat( 169// m_log.DebugFormat(
169// "[INSTANT MESSAGE]: Looking for child of {0} in {1}", toAgentID, scene.RegionInfo.RegionName); 170// "[HG INSTANT MESSAGE]: Looking for child of {0} in {1}", toAgentID, scene.RegionInfo.RegionName);
170 171
171 if (scene.Entities.ContainsKey(toAgentID) && 172 if (scene.Entities.ContainsKey(toAgentID) &&
172 scene.Entities[toAgentID] is ScenePresence) 173 scene.Entities[toAgentID] is ScenePresence)
@@ -174,7 +175,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
174 // Local message 175 // Local message
175 ScenePresence user = (ScenePresence) scene.Entities[toAgentID]; 176 ScenePresence user = (ScenePresence) scene.Entities[toAgentID];
176 177
177// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to child agent {0} {1}", user.Name, toAgentID); 178// m_log.DebugFormat("[HG INSTANT MESSAGE]: Delivering IM to child agent {0} {1}", user.Name, toAgentID);
178 user.ControllingClient.SendInstantMessage(im); 179 user.ControllingClient.SendInstantMessage(im);
179 180
180 // Message sent 181 // Message sent
@@ -183,7 +184,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
183 } 184 }
184 } 185 }
185 186
186// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to {0} via XMLRPC", im.toAgentID); 187// m_log.DebugFormat("[HG INSTANT MESSAGE]: Delivering IM to {0} via XMLRPC", im.toAgentID);
187 // Is the user a local user? 188 // Is the user a local user?
188 UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, toAgentID); 189 UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, toAgentID);
189 string url = string.Empty; 190 string url = string.Empty;
diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs
index d687e6a..bc5c1ff 100644
--- a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs
@@ -154,14 +154,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
154 if (im.dialog == (byte)InstantMessageDialog.RequestTeleport) 154 if (im.dialog == (byte)InstantMessageDialog.RequestTeleport)
155 { 155 {
156 UUID sessionID = new UUID(im.imSessionID); 156 UUID sessionID = new UUID(im.imSessionID);
157 m_log.DebugFormat("[HG LURE MODULE]: RequestTeleport sessionID={0}, regionID={1}, message={2}", im.imSessionID, im.RegionID, im.message); 157
158 m_PendingLures.Add(sessionID, im, 7200); // 2 hours 158 if (!m_PendingLures.Contains(sessionID))
159 {
160 m_log.DebugFormat("[HG LURE MODULE]: RequestTeleport sessionID={0}, regionID={1}, message={2}", im.imSessionID, im.RegionID, im.message);
161 m_PendingLures.Add(sessionID, im, 7200); // 2 hours
162 }
159 163
160 // Forward. We do this, because the IM module explicitly rejects 164 // Forward. We do this, because the IM module explicitly rejects
161 // IMs of this type 165 // IMs of this type
162 if (m_TransferModule != null) 166 if (m_TransferModule != null)
163 m_TransferModule.SendInstantMessage(im, delegate(bool success) { }); 167 m_TransferModule.SendInstantMessage(im, delegate(bool success) { });
164
165 } 168 }
166 } 169 }
167 170
@@ -177,12 +180,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
177 180
178 m_log.DebugFormat("[HG LURE MODULE]: TP invite with message {0}", message); 181 m_log.DebugFormat("[HG LURE MODULE]: TP invite with message {0}", message);
179 182
183 UUID sessionID = UUID.Random();
184
180 GridInstantMessage m = new GridInstantMessage(scene, client.AgentId, 185 GridInstantMessage m = new GridInstantMessage(scene, client.AgentId,
181 client.FirstName+" "+client.LastName, targetid, 186 client.FirstName+" "+client.LastName, targetid,
182 (byte)InstantMessageDialog.RequestTeleport, false, 187 (byte)InstantMessageDialog.RequestTeleport, false,
183 message, UUID.Random(), false, presence.AbsolutePosition, 188 message, sessionID, false, presence.AbsolutePosition,
184 new Byte[0]); 189 new Byte[0]);
185 m.RegionID = client.Scene.RegionInfo.RegionID.Guid; 190 m.RegionID = client.Scene.RegionInfo.RegionID.Guid;
191
192 m_log.DebugFormat("[HG LURE MODULE]: RequestTeleport sessionID={0}, regionID={1}, message={2}", m.imSessionID, m.RegionID, m.message);
193 m_PendingLures.Add(sessionID, m, 7200); // 2 hours
186 194
187 if (m_TransferModule != null) 195 if (m_TransferModule != null)
188 { 196 {
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
index f05b090..dd6bdf7 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
@@ -150,7 +150,6 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
150 { 150 {
151 if (!m_Enabled) 151 if (!m_Enabled)
152 return; 152 return;
153
154 } 153 }
155 154
156 #endregion 155 #endregion
diff --git a/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs b/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs
index ed3e516..6f83948 100644
--- a/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs
@@ -112,10 +112,13 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL
112 112
113 public void PostInitialise() 113 public void PostInitialise()
114 { 114 {
115 m_textureManager = m_scene.RequestModuleInterface<IDynamicTextureManager>(); 115 if (m_scene != null)
116 if (m_textureManager != null)
117 { 116 {
118 m_textureManager.RegisterRender(GetContentType(), this); 117 m_textureManager = m_scene.RequestModuleInterface<IDynamicTextureManager>();
118 if (m_textureManager != null)
119 {
120 m_textureManager.RegisterRender(GetContentType(), this);
121 }
119 } 122 }
120 } 123 }
121 124
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs
index 003324f..86c0099 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs
@@ -141,11 +141,21 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization
141 141
142 if (scene != null) 142 if (scene != null)
143 { 143 {
144 string mail = String.Empty;
145
144 UserAccount account = scene.UserAccountService.GetUserAccount(UUID.Zero, new UUID(userID)); 146 UserAccount account = scene.UserAccountService.GetUserAccount(UUID.Zero, new UUID(userID));
145 147
148 //if account not found, we assume its a foreign visitor from HG, else use account data...
149 if (account != null)
150 {
151 mail = account.Email;
152 firstName = account.FirstName;
153 lastName = account.LastName;
154 }
155
146 isAuthorized 156 isAuthorized
147 = IsAuthorizedForRegion( 157 = IsAuthorizedForRegion(
148 userID, firstName, lastName, account.Email, scene.RegionInfo.RegionName, regionID, out message); 158 userID, firstName, lastName, mail, scene.RegionInfo.RegionName, regionID, out message);
149 } 159 }
150 else 160 else
151 { 161 {
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs
index 1c83f8e..097ff1a 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs
@@ -185,15 +185,18 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
185 public InventoryCollection GetFolderContent(UUID userID, UUID folderID) 185 public InventoryCollection GetFolderContent(UUID userID, UUID folderID)
186 { 186 {
187 InventoryCollection invCol = m_InventoryService.GetFolderContent(userID, folderID); 187 InventoryCollection invCol = m_InventoryService.GetFolderContent(userID, folderID);
188 Util.FireAndForget(delegate 188
189 if (UserManager != null)
189 { 190 {
190 if (UserManager != null) 191 // Protect ourselves against the caller subsequently modifying the items list
192 List<InventoryItemBase> items = new List<InventoryItemBase>(invCol.Items);
193
194 Util.FireAndForget(delegate
191 { 195 {
192 // Protect ourselves against the caller subsequently modifying the items list 196 foreach (InventoryItemBase item in items)
193 foreach (InventoryItemBase item in new List<InventoryItemBase>(invCol.Items))
194 UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData); 197 UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData);
195 } 198 });
196 }); 199 }
197 200
198 return invCol; 201 return invCol;
199 } 202 }
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs
index c9c716c..73ab4e3 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs
@@ -193,15 +193,18 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
193 public InventoryCollection GetFolderContent(UUID userID, UUID folderID) 193 public InventoryCollection GetFolderContent(UUID userID, UUID folderID)
194 { 194 {
195 InventoryCollection invCol = m_RemoteConnector.GetFolderContent(userID, folderID); 195 InventoryCollection invCol = m_RemoteConnector.GetFolderContent(userID, folderID);
196 Util.FireAndForget(delegate 196
197 if (UserManager != null)
197 { 198 {
198 if (UserManager != null) 199 // Protect ourselves against the caller subsequently modifying the items list
200 List<InventoryItemBase> items = new List<InventoryItemBase>(invCol.Items);
201
202 Util.FireAndForget(delegate
199 { 203 {
200 // Protect ourselves against the caller subsequently modifying the items list 204 foreach (InventoryItemBase item in items)
201 foreach (InventoryItemBase item in new List<InventoryItemBase>(invCol.Items))
202 UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData); 205 UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData);
203 } 206 });
204 }); 207 }
205 208
206 return invCol; 209 return invCol;
207 } 210 }
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/LocalUserAccountServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/LocalUserAccountServiceConnector.cs
index 535a637..1ffd480 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/LocalUserAccountServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/LocalUserAccountServiceConnector.cs
@@ -45,7 +45,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
45 LogManager.GetLogger( 45 LogManager.GetLogger(
46 MethodBase.GetCurrentMethod().DeclaringType); 46 MethodBase.GetCurrentMethod().DeclaringType);
47 47
48 private IUserAccountService m_UserService; 48 /// <summary>
49 /// This is not on the IUserAccountService. It's only being used so that standalone scenes can punch through
50 /// to a local UserAccountService when setting up an estate manager.
51 /// </summary>
52 public IUserAccountService UserAccountService { get; private set; }
53
49 private UserAccountCache m_Cache; 54 private UserAccountCache m_Cache;
50 55
51 private bool m_Enabled = false; 56 private bool m_Enabled = false;
@@ -86,9 +91,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
86 } 91 }
87 92
88 Object[] args = new Object[] { source }; 93 Object[] args = new Object[] { source };
89 m_UserService = ServerUtils.LoadPlugin<IUserAccountService>(serviceDll, args); 94 UserAccountService = ServerUtils.LoadPlugin<IUserAccountService>(serviceDll, args);
90 95
91 if (m_UserService == null) 96 if (UserAccountService == null)
92 { 97 {
93 m_log.ErrorFormat( 98 m_log.ErrorFormat(
94 "[LOCAL USER ACCOUNT SERVICE CONNECTOR]: Cannot load user account service specified as {0}", serviceDll); 99 "[LOCAL USER ACCOUNT SERVICE CONNECTOR]: Cannot load user account service specified as {0}", serviceDll);
@@ -119,7 +124,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
119 if (!m_Enabled) 124 if (!m_Enabled)
120 return; 125 return;
121 126
122 scene.RegisterModuleInterface<IUserAccountService>(m_UserService); 127 // FIXME: Why do we bother setting this module and caching up if we just end up registering the inner
128 // user account service?!
129 scene.RegisterModuleInterface<IUserAccountService>(UserAccountService);
123 scene.RegisterModuleInterface<IUserAccountCacheModule>(m_Cache); 130 scene.RegisterModuleInterface<IUserAccountCacheModule>(m_Cache);
124 } 131 }
125 132
@@ -148,7 +155,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
148 if (inCache) 155 if (inCache)
149 return account; 156 return account;
150 157
151 account = m_UserService.GetUserAccount(scopeID, userID); 158 account = UserAccountService.GetUserAccount(scopeID, userID);
152 m_Cache.Cache(userID, account); 159 m_Cache.Cache(userID, account);
153 160
154 return account; 161 return account;
@@ -161,7 +168,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
161 if (inCache) 168 if (inCache)
162 return account; 169 return account;
163 170
164 account = m_UserService.GetUserAccount(scopeID, firstName, lastName); 171 account = UserAccountService.GetUserAccount(scopeID, firstName, lastName);
165 if (account != null) 172 if (account != null)
166 m_Cache.Cache(account.PrincipalID, account); 173 m_Cache.Cache(account.PrincipalID, account);
167 174
@@ -170,7 +177,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
170 177
171 public UserAccount GetUserAccount(UUID scopeID, string Email) 178 public UserAccount GetUserAccount(UUID scopeID, string Email)
172 { 179 {
173 return m_UserService.GetUserAccount(scopeID, Email); 180 return UserAccountService.GetUserAccount(scopeID, Email);
174 } 181 }
175 182
176 public List<UserAccount> GetUserAccountsWhere(UUID scopeID, string query) 183 public List<UserAccount> GetUserAccountsWhere(UUID scopeID, string query)
@@ -180,17 +187,16 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
180 187
181 public List<UserAccount> GetUserAccounts(UUID scopeID, string query) 188 public List<UserAccount> GetUserAccounts(UUID scopeID, string query)
182 { 189 {
183 return m_UserService.GetUserAccounts(scopeID, query); 190 return UserAccountService.GetUserAccounts(scopeID, query);
184 } 191 }
185 192
186 // Update all updatable fields 193 // Update all updatable fields
187 // 194 //
188 public bool StoreUserAccount(UserAccount data) 195 public bool StoreUserAccount(UserAccount data)
189 { 196 {
190 return m_UserService.StoreUserAccount(data); 197 return UserAccountService.StoreUserAccount(data);
191 } 198 }
192 199
193 #endregion 200 #endregion
194
195 } 201 }
196} 202}
diff --git a/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs b/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs
index 49e3236..eb4731c 100644
--- a/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs
+++ b/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs
@@ -101,7 +101,7 @@ namespace OpenSim.Region.CoreModules.World.Objects.BuySell
101 101
102 part.ParentGroup.HasGroupChanged = true; 102 part.ParentGroup.HasGroupChanged = true;
103 103
104 part.GetProperties(client); 104 part.SendPropertiesToClient(client);
105 } 105 }
106 106
107 public bool BuyObject(IClientAPI remoteClient, UUID categoryID, uint localID, byte saleType, int salePrice) 107 public bool BuyObject(IClientAPI remoteClient, UUID categoryID, uint localID, byte saleType, int salePrice)
@@ -142,7 +142,7 @@ namespace OpenSim.Region.CoreModules.World.Objects.BuySell
142 part.SalePrice = 10; 142 part.SalePrice = 10;
143 143
144 group.HasGroupChanged = true; 144 group.HasGroupChanged = true;
145 part.GetProperties(remoteClient); 145 part.SendPropertiesToClient(remoteClient);
146 part.TriggerScriptChangedEvent(Changed.OWNER); 146 part.TriggerScriptChangedEvent(Changed.OWNER);
147 group.ResumeScripts(); 147 group.ResumeScripts();
148 part.ScheduleFullUpdate(); 148 part.ScheduleFullUpdate();