aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules')
-rw-r--r--OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs130
-rw-r--r--OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs166
-rw-r--r--OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs43
-rw-r--r--OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs125
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs13
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs28
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs64
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs16
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs83
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs12
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs30
-rw-r--r--OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs5
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsIn/Asset/AssetServiceInConnectorModule.cs5
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs11
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs26
-rw-r--r--OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs18
-rw-r--r--OpenSim/Region/CoreModules/World/Region/RestartModule.cs263
18 files changed, 737 insertions, 305 deletions
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs
index 3d6e7f3..c66a4ea 100644
--- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs
+++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs
@@ -41,19 +41,22 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
41 /// </summary> 41 /// </summary>
42 public class AgentAssetTransactions 42 public class AgentAssetTransactions
43 { 43 {
44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 44 private static readonly ILog m_log = LogManager.GetLogger(
45 MethodBase.GetCurrentMethod().DeclaringType);
45 46
46 // Fields 47 // Fields
47 private bool m_dumpAssetsToFile; 48 private bool m_dumpAssetsToFile;
48 public AssetTransactionModule Manager; 49 private Scene m_Scene;
49 public UUID UserID; 50 public UUID UserID;
50 public Dictionary<UUID, AssetXferUploader> XferUploaders = new Dictionary<UUID, AssetXferUploader>(); 51 public Dictionary<UUID, AssetXferUploader> XferUploaders =
52 new Dictionary<UUID, AssetXferUploader>();
51 53
52 // Methods 54 // Methods
53 public AgentAssetTransactions(UUID agentID, AssetTransactionModule manager, bool dumpAssetsToFile) 55 public AgentAssetTransactions(UUID agentID, Scene scene,
56 bool dumpAssetsToFile)
54 { 57 {
58 m_Scene = scene;
55 UserID = agentID; 59 UserID = agentID;
56 Manager = manager;
57 m_dumpAssetsToFile = dumpAssetsToFile; 60 m_dumpAssetsToFile = dumpAssetsToFile;
58 } 61 }
59 62
@@ -61,7 +64,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
61 { 64 {
62 if (!XferUploaders.ContainsKey(transactionID)) 65 if (!XferUploaders.ContainsKey(transactionID))
63 { 66 {
64 AssetXferUploader uploader = new AssetXferUploader(this, m_dumpAssetsToFile); 67 AssetXferUploader uploader = new AssetXferUploader(m_Scene,
68 m_dumpAssetsToFile);
65 69
66 lock (XferUploaders) 70 lock (XferUploaders)
67 { 71 {
@@ -88,22 +92,25 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
88 } 92 }
89 } 93 }
90 94
91 public void RequestCreateInventoryItem(IClientAPI remoteClient, UUID transactionID, UUID folderID, 95 public void RequestCreateInventoryItem(IClientAPI remoteClient,
92 uint callbackID, string description, string name, sbyte invType, 96 UUID transactionID, UUID folderID, uint callbackID,
93 sbyte type, byte wearableType, uint nextOwnerMask) 97 string description, string name, sbyte invType,
98 sbyte type, byte wearableType, uint nextOwnerMask)
94 { 99 {
95 if (XferUploaders.ContainsKey(transactionID)) 100 if (XferUploaders.ContainsKey(transactionID))
96 { 101 {
97 XferUploaders[transactionID].RequestCreateInventoryItem(remoteClient, transactionID, folderID, 102 XferUploaders[transactionID].RequestCreateInventoryItem(
98 callbackID, description, name, invType, type, 103 remoteClient, transactionID, folderID,
99 wearableType, nextOwnerMask); 104 callbackID, description, name, invType, type,
105 wearableType, nextOwnerMask);
100 } 106 }
101 } 107 }
102 108
103 109
104 110
105 /// <summary> 111 /// <summary>
106 /// Get an uploaded asset. If the data is successfully retrieved, the transaction will be removed. 112 /// Get an uploaded asset. If the data is successfully retrieved,
113 /// the transaction will be removed.
107 /// </summary> 114 /// </summary>
108 /// <param name="transactionID"></param> 115 /// <param name="transactionID"></param>
109 /// <returns>The asset if the upload has completed, null if it has not.</returns> 116 /// <returns>The asset if the upload has completed, null if it has not.</returns>
@@ -125,105 +132,56 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
125 return null; 132 return null;
126 } 133 }
127 134
128 //private void CreateItemFromUpload(AssetBase asset, IClientAPI ourClient, UUID inventoryFolderID, uint nextPerms, uint wearableType) 135 public void RequestUpdateTaskInventoryItem(IClientAPI remoteClient,
129 //{ 136 SceneObjectPart part, UUID transactionID,
130 // Manager.MyScene.CommsManager.AssetCache.AddAsset(asset); 137 TaskInventoryItem item)
131 // CachedUserInfo userInfo = Manager.MyScene.CommsManager.UserProfileCacheService.GetUserDetails(
132 // ourClient.AgentId);
133
134 // if (userInfo != null)
135 // {
136 // InventoryItemBase item = new InventoryItemBase();
137 // item.Owner = ourClient.AgentId;
138 // item.Creator = ourClient.AgentId;
139 // item.ID = UUID.Random();
140 // item.AssetID = asset.FullID;
141 // item.Description = asset.Description;
142 // item.Name = asset.Name;
143 // item.AssetType = asset.Type;
144 // item.InvType = asset.Type;
145 // item.Folder = inventoryFolderID;
146 // item.BasePermissions = 0x7fffffff;
147 // item.CurrentPermissions = 0x7fffffff;
148 // item.EveryOnePermissions = 0;
149 // item.NextPermissions = nextPerms;
150 // item.Flags = wearableType;
151 // item.CreationDate = Util.UnixTimeSinceEpoch();
152
153 // userInfo.AddItem(item);
154 // ourClient.SendInventoryItemCreateUpdate(item);
155 // }
156 // else
157 // {
158 // m_log.ErrorFormat(
159 // "[ASSET TRANSACTIONS]: Could not find user {0} for inventory item creation",
160 // ourClient.AgentId);
161 // }
162 //}
163
164 public void RequestUpdateTaskInventoryItem(
165 IClientAPI remoteClient, SceneObjectPart part, UUID transactionID, TaskInventoryItem item)
166 { 138 {
167 if (XferUploaders.ContainsKey(transactionID)) 139 if (XferUploaders.ContainsKey(transactionID))
168 { 140 {
169 AssetBase asset = XferUploaders[transactionID].GetAssetData(); 141 AssetBase asset = GetTransactionAsset(transactionID);
142
143 // Only legacy viewers use this, and they prefer CAPS, which
144 // we have, so this really never runs.
145 // Allow it, but only for "safe" types.
146 if ((InventoryType)item.InvType != InventoryType.Notecard &&
147 (InventoryType)item.InvType != InventoryType.LSL)
148 return;
149
170 if (asset != null) 150 if (asset != null)
171 { 151 {
172 m_log.DebugFormat( 152 asset.FullID = UUID.Random();
173 "[ASSET TRANSACTIONS]: Updating task item {0} in {1} with asset in transaction {2}",
174 item.Name, part.Name, transactionID);
175
176 asset.Name = item.Name; 153 asset.Name = item.Name;
177 asset.Description = item.Description; 154 asset.Description = item.Description;
178 asset.Type = (sbyte)item.Type; 155 asset.Type = (sbyte)item.Type;
179 item.AssetID = asset.FullID; 156 item.AssetID = asset.FullID;
180 157
181 Manager.MyScene.AssetService.Store(asset); 158 m_Scene.AssetService.Store(asset);
182 159
183 if (part.Inventory.UpdateInventoryItem(item)) 160 part.Inventory.UpdateInventoryItem(item);
184 {
185 if ((InventoryType)item.InvType == InventoryType.Notecard)
186 remoteClient.SendAgentAlertMessage("Notecard saved", false);
187 else if ((InventoryType)item.InvType == InventoryType.LSL)
188 remoteClient.SendAgentAlertMessage("Script saved", false);
189 else
190 remoteClient.SendAgentAlertMessage("Item saved", false);
191
192 part.GetProperties(remoteClient);
193 }
194 } 161 }
195 } 162 }
196 } 163 }
197 164
198 165 public void RequestUpdateInventoryItem(IClientAPI remoteClient,
199 public void RequestUpdateInventoryItem(IClientAPI remoteClient, UUID transactionID, 166 UUID transactionID, InventoryItemBase item)
200 InventoryItemBase item)
201 { 167 {
202 if (XferUploaders.ContainsKey(transactionID)) 168 if (XferUploaders.ContainsKey(transactionID))
203 { 169 {
204 UUID assetID = UUID.Combine(transactionID, remoteClient.SecureSessionId); 170 AssetBase asset = GetTransactionAsset(transactionID);
205 171
206 AssetBase asset = Manager.MyScene.AssetService.Get(assetID.ToString()); 172 if (asset != null)
207
208 if (asset == null)
209 {
210 asset = GetTransactionAsset(transactionID);
211 }
212
213 if (asset != null && asset.FullID == assetID)
214 { 173 {
215 // Assets never get updated, new ones get created
216 asset.FullID = UUID.Random(); 174 asset.FullID = UUID.Random();
217 asset.Name = item.Name; 175 asset.Name = item.Name;
218 asset.Description = item.Description; 176 asset.Description = item.Description;
219 asset.Type = (sbyte)item.AssetType; 177 asset.Type = (sbyte)item.AssetType;
220 item.AssetID = asset.FullID; 178 item.AssetID = asset.FullID;
221 179
222 Manager.MyScene.AssetService.Store(asset); 180 m_Scene.AssetService.Store(asset);
223 }
224 181
225 IInventoryService invService = Manager.MyScene.InventoryService; 182 IInventoryService invService = m_Scene.InventoryService;
226 invService.UpdateItem(item); 183 invService.UpdateItem(item);
184 }
227 } 185 }
228 } 186 }
229 } 187 }
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs
index ae31050..82558de 100644
--- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs
+++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs
@@ -34,22 +34,19 @@ using OpenMetaverse;
34using OpenSim.Framework; 34using OpenSim.Framework;
35using OpenSim.Region.Framework.Interfaces; 35using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.Framework.Scenes; 36using OpenSim.Region.Framework.Scenes;
37using Mono.Addins;
37 38
38namespace OpenSim.Region.CoreModules.Agent.AssetTransaction 39namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
39{ 40{
40 public class AssetTransactionModule : IRegionModule, IAgentAssetTransactions 41 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "AssetTransactionModule")]
42 public class AssetTransactionModule : INonSharedRegionModule,
43 IAgentAssetTransactions
41 { 44 {
42// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 45// private static readonly ILog m_log = LogManager.GetLogger(
46// MethodBase.GetCurrentMethod().DeclaringType);
43 47
44 private readonly Dictionary<UUID, Scene> RegisteredScenes = new Dictionary<UUID, Scene>(); 48 protected Scene m_Scene;
45 private bool m_dumpAssetsToFile = false; 49 private bool m_dumpAssetsToFile = false;
46 private Scene m_scene = null;
47
48 [Obsolete]
49 public Scene MyScene
50 {
51 get{ return m_scene;}
52 }
53 50
54 /// <summary> 51 /// <summary>
55 /// Each agent has its own singleton collection of transactions 52 /// Each agent has its own singleton collection of transactions
@@ -57,33 +54,24 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
57 private Dictionary<UUID, AgentAssetTransactions> AgentTransactions = 54 private Dictionary<UUID, AgentAssetTransactions> AgentTransactions =
58 new Dictionary<UUID, AgentAssetTransactions>(); 55 new Dictionary<UUID, AgentAssetTransactions>();
59 56
57 #region IRegionModule Members
60 58
61 public AssetTransactionModule() 59 public void Initialise(IConfigSource config)
62 { 60 {
63 //m_log.Debug("creating AgentAssetTransactionModule");
64 } 61 }
65 62
66 #region IRegionModule Members 63 public void AddRegion(Scene scene)
67
68 public void Initialise(Scene scene, IConfigSource config)
69 { 64 {
70 if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID)) 65 m_Scene = scene;
71 { 66 scene.RegisterModuleInterface<IAgentAssetTransactions>(this);
72 // m_log.Debug("initialising AgentAssetTransactionModule"); 67 scene.EventManager.OnNewClient += NewClient;
73 RegisteredScenes.Add(scene.RegionInfo.RegionID, scene); 68 }
74 scene.RegisterModuleInterface<IAgentAssetTransactions>(this);
75
76 scene.EventManager.OnNewClient += NewClient;
77 }
78 69
79 // EVIL HACK! 70 public void RegionLoaded(Scene scene)
80 // This needs killing! 71 {
81 //
82 if (m_scene == null)
83 m_scene = scene;
84 } 72 }
85 73
86 public void PostInitialise() 74 public void RemoveRegion(Scene scene)
87 { 75 {
88 } 76 }
89 77
@@ -96,9 +84,9 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
96 get { return "AgentTransactionModule"; } 84 get { return "AgentTransactionModule"; }
97 } 85 }
98 86
99 public bool IsSharedModule 87 public Type ReplaceableInterface
100 { 88 {
101 get { return true; } 89 get { return typeof(IAgentAssetTransactions); }
102 } 90 }
103 91
104 #endregion 92 #endregion
@@ -111,8 +99,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
111 99
112 #region AgentAssetTransactions 100 #region AgentAssetTransactions
113 /// <summary> 101 /// <summary>
114 /// Get the collection of asset transactions for the given user. If one does not already exist, it 102 /// Get the collection of asset transactions for the given user.
115 /// is created. 103 /// If one does not already exist, it is created.
116 /// </summary> 104 /// </summary>
117 /// <param name="userID"></param> 105 /// <param name="userID"></param>
118 /// <returns></returns> 106 /// <returns></returns>
@@ -122,7 +110,10 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
122 { 110 {
123 if (!AgentTransactions.ContainsKey(userID)) 111 if (!AgentTransactions.ContainsKey(userID))
124 { 112 {
125 AgentAssetTransactions transactions = new AgentAssetTransactions(userID, this, m_dumpAssetsToFile); 113 AgentAssetTransactions transactions =
114 new AgentAssetTransactions(userID, m_Scene,
115 m_dumpAssetsToFile);
116
126 AgentTransactions.Add(userID, transactions); 117 AgentTransactions.Add(userID, transactions);
127 } 118 }
128 119
@@ -131,8 +122,9 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
131 } 122 }
132 123
133 /// <summary> 124 /// <summary>
134 /// Remove the given agent asset transactions. This should be called when a client is departing 125 /// Remove the given agent asset transactions. This should be called
135 /// from a scene (and hence won't be making any more transactions here). 126 /// when a client is departing from a scene (and hence won't be making
127 /// any more transactions here).
136 /// </summary> 128 /// </summary>
137 /// <param name="userID"></param> 129 /// <param name="userID"></param>
138 public void RemoveAgentAssetTransactions(UUID userID) 130 public void RemoveAgentAssetTransactions(UUID userID)
@@ -146,10 +138,10 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
146 } 138 }
147 139
148 /// <summary> 140 /// <summary>
149 /// Create an inventory item from data that has been received through a transaction. 141 /// Create an inventory item from data that has been received through
150 /// 142 /// a transaction.
151 /// This is called when new clothing or body parts are created. It may also be called in other 143 /// This is called when new clothing or body parts are created.
152 /// situations. 144 /// It may also be called in other situations.
153 /// </summary> 145 /// </summary>
154 /// <param name="remoteClient"></param> 146 /// <param name="remoteClient"></param>
155 /// <param name="transactionID"></param> 147 /// <param name="transactionID"></param>
@@ -161,61 +153,72 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
161 /// <param name="type"></param> 153 /// <param name="type"></param>
162 /// <param name="wearableType"></param> 154 /// <param name="wearableType"></param>
163 /// <param name="nextOwnerMask"></param> 155 /// <param name="nextOwnerMask"></param>
164 public void HandleItemCreationFromTransaction(IClientAPI remoteClient, UUID transactionID, UUID folderID, 156 public void HandleItemCreationFromTransaction(IClientAPI remoteClient,
165 uint callbackID, string description, string name, sbyte invType, 157 UUID transactionID, UUID folderID, uint callbackID,
166 sbyte type, byte wearableType, uint nextOwnerMask) 158 string description, string name, sbyte invType,
159 sbyte type, byte wearableType, uint nextOwnerMask)
167 { 160 {
168 // m_log.DebugFormat( 161// m_log.DebugFormat(
169 // "[TRANSACTIONS MANAGER] Called HandleItemCreationFromTransaction with item {0}", name); 162// "[TRANSACTIONS MANAGER] Called HandleItemCreationFromTransaction with item {0}", name);
170 163
171 AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId); 164 AgentAssetTransactions transactions =
165 GetUserTransactions(remoteClient.AgentId);
172 166
173 transactions.RequestCreateInventoryItem( 167 transactions.RequestCreateInventoryItem(remoteClient, transactionID,
174 remoteClient, transactionID, folderID, callbackID, description, 168 folderID, callbackID, description, name, invType, type,
175 name, invType, type, wearableType, nextOwnerMask); 169 wearableType, nextOwnerMask);
176 } 170 }
177 171
178 /// <summary> 172 /// <summary>
179 /// Update an inventory item with data that has been received through a transaction. 173 /// Update an inventory item with data that has been received through a
174 /// transaction.
180 /// 175 ///
181 /// This is called when clothing or body parts are updated (for instance, with new textures or 176 /// This is called when clothing or body parts are updated (for
182 /// colours). It may also be called in other situations. 177 /// instance, with new textures or colours). It may also be called in
178 /// other situations.
183 /// </summary> 179 /// </summary>
184 /// <param name="remoteClient"></param> 180 /// <param name="remoteClient"></param>
185 /// <param name="transactionID"></param> 181 /// <param name="transactionID"></param>
186 /// <param name="item"></param> 182 /// <param name="item"></param>
187 public void HandleItemUpdateFromTransaction(IClientAPI remoteClient, UUID transactionID, 183 public void HandleItemUpdateFromTransaction(IClientAPI remoteClient,
188 InventoryItemBase item) 184 UUID transactionID, InventoryItemBase item)
189 { 185 {
190 // m_log.DebugFormat( 186// m_log.DebugFormat(
191 // "[TRANSACTIONS MANAGER] Called HandleItemUpdateFromTransaction with item {0}", 187// "[TRANSACTIONS MANAGER] Called HandleItemUpdateFromTransaction with item {0}",
192 // item.Name); 188// item.Name);
193 189
194 AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId); 190 AgentAssetTransactions transactions =
191 GetUserTransactions(remoteClient.AgentId);
195 192
196 transactions.RequestUpdateInventoryItem(remoteClient, transactionID, item); 193 transactions.RequestUpdateInventoryItem(remoteClient,
194 transactionID, item);
197 } 195 }
198 196
199 /// <summary> 197 /// <summary>
200 /// Update a task inventory item with data that has been received through a transaction. 198 /// Update a task inventory item with data that has been received
199 /// through a transaction.
201 /// 200 ///
202 /// This is currently called when, for instance, a notecard in a prim is saved. The data is sent 201 /// This is currently called when, for instance, a notecard in a prim
203 /// up through a single AssetUploadRequest. A subsequent UpdateTaskInventory then references the transaction 202 /// is saved. The data is sent up through a single AssetUploadRequest.
203 /// A subsequent UpdateTaskInventory then references the transaction
204 /// and comes through this method. 204 /// and comes through this method.
205 /// </summary> 205 /// </summary>
206 /// <param name="remoteClient"></param> 206 /// <param name="remoteClient"></param>
207 /// <param name="transactionID"></param> 207 /// <param name="transactionID"></param>
208 /// <param name="item"></param> 208 /// <param name="item"></param>
209 public void HandleTaskItemUpdateFromTransaction( 209 public void HandleTaskItemUpdateFromTransaction(IClientAPI remoteClient,
210 IClientAPI remoteClient, SceneObjectPart part, UUID transactionID, TaskInventoryItem item) 210 SceneObjectPart part, UUID transactionID,
211 TaskInventoryItem item)
211 { 212 {
212 // m_log.DebugFormat( 213// m_log.DebugFormat(
213 // "[TRANSACTIONS MANAGER] Called HandleTaskItemUpdateFromTransaction with item {0}", 214// "[TRANSACTIONS MANAGER] Called HandleTaskItemUpdateFromTransaction with item {0}",
214 // item.Name); 215// item.Name);
215 216
216 AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId); 217 AgentAssetTransactions transactions =
218 GetUserTransactions(remoteClient.AgentId);
217 219
218 transactions.RequestUpdateTaskInventoryItem(remoteClient, part, transactionID, item); 220 transactions.RequestUpdateTaskInventoryItem(remoteClient, part,
221 transactionID, item);
219 } 222 }
220 223
221 /// <summary> 224 /// <summary>
@@ -227,8 +230,9 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
227 /// <param name="type"></param> 230 /// <param name="type"></param>
228 /// <param name="data"></param></param> 231 /// <param name="data"></param></param>
229 /// <param name="tempFile"></param> 232 /// <param name="tempFile"></param>
230 public void HandleUDPUploadRequest(IClientAPI remoteClient, UUID assetID, UUID transaction, sbyte type, 233 public void HandleUDPUploadRequest(IClientAPI remoteClient,
231 byte[] data, bool storeLocal, bool tempFile) 234 UUID assetID, UUID transaction, sbyte type, byte[] data,
235 bool storeLocal, bool tempFile)
232 { 236 {
233// m_log.Debug("HandleUDPUploadRequest - assetID: " + assetID.ToString() + " transaction: " + transaction.ToString() + " type: " + type.ToString() + " storelocal: " + storeLocal + " tempFile: " + tempFile); 237// m_log.Debug("HandleUDPUploadRequest - assetID: " + assetID.ToString() + " transaction: " + transaction.ToString() + " type: " + type.ToString() + " storelocal: " + storeLocal + " tempFile: " + tempFile);
234 238
@@ -251,27 +255,33 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
251 } 255 }
252 } 256 }
253 257
254 AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId); 258 AgentAssetTransactions transactions =
259 GetUserTransactions(remoteClient.AgentId);
260
261 AssetXferUploader uploader =
262 transactions.RequestXferUploader(transaction);
255 263
256 AssetXferUploader uploader = transactions.RequestXferUploader(transaction);
257 if (uploader != null) 264 if (uploader != null)
258 { 265 {
259 uploader.Initialise(remoteClient, assetID, transaction, type, data, storeLocal, tempFile); 266 uploader.Initialise(remoteClient, assetID, transaction, type,
267 data, storeLocal, tempFile);
260 } 268 }
261 } 269 }
262 270
263 /// <summary> 271 /// <summary>
264 /// Handle asset transfer data packets received in response to the asset upload request in 272 /// Handle asset transfer data packets received in response to the
265 /// HandleUDPUploadRequest() 273 /// asset upload request in HandleUDPUploadRequest()
266 /// </summary> 274 /// </summary>
267 /// <param name="remoteClient"></param> 275 /// <param name="remoteClient"></param>
268 /// <param name="xferID"></param> 276 /// <param name="xferID"></param>
269 /// <param name="packetID"></param> 277 /// <param name="packetID"></param>
270 /// <param name="data"></param> 278 /// <param name="data"></param>
271 public void HandleXfer(IClientAPI remoteClient, ulong xferID, uint packetID, byte[] data) 279 public void HandleXfer(IClientAPI remoteClient, ulong xferID,
280 uint packetID, byte[] data)
272 { 281 {
273 //m_log.Debug("xferID: " + xferID + " packetID: " + packetID + " data!"); 282 //m_log.Debug("xferID: " + xferID + " packetID: " + packetID + " data!");
274 AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId); 283 AgentAssetTransactions transactions =
284 GetUserTransactions(remoteClient.AgentId);
275 285
276 transactions.HandleXfer(xferID, packetID, data); 286 transactions.HandleXfer(xferID, packetID, data);
277 } 287 }
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs
index 4609738..a7929ba 100644
--- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs
+++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs
@@ -31,7 +31,7 @@ using System.Reflection;
31using log4net; 31using log4net;
32using OpenMetaverse; 32using OpenMetaverse;
33using OpenSim.Framework; 33using OpenSim.Framework;
34 34using OpenSim.Region.Framework.Scenes;
35using OpenSim.Services.Interfaces; 35using OpenSim.Services.Interfaces;
36 36
37namespace OpenSim.Region.CoreModules.Agent.AssetTransaction 37namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
@@ -50,17 +50,17 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
50 private bool m_finished = false; 50 private bool m_finished = false;
51 private string m_name = String.Empty; 51 private string m_name = String.Empty;
52 private bool m_storeLocal; 52 private bool m_storeLocal;
53 private AgentAssetTransactions m_userTransactions;
54 private uint nextPerm = 0; 53 private uint nextPerm = 0;
55 private IClientAPI ourClient; 54 private IClientAPI ourClient;
56 private UUID TransactionID = UUID.Zero; 55 private UUID TransactionID = UUID.Zero;
57 private sbyte type = 0; 56 private sbyte type = 0;
58 private byte wearableType = 0; 57 private byte wearableType = 0;
59 public ulong XferID; 58 public ulong XferID;
59 private Scene m_Scene;
60 60
61 public AssetXferUploader(AgentAssetTransactions transactions, bool dumpAssetToFile) 61 public AssetXferUploader(Scene scene, bool dumpAssetToFile)
62 { 62 {
63 m_userTransactions = transactions; 63 m_Scene = scene;
64 m_dumpAssetToFile = dumpAssetToFile; 64 m_dumpAssetToFile = dumpAssetToFile;
65 } 65 }
66 66
@@ -108,11 +108,13 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
108 /// <param name="packetID"></param> 108 /// <param name="packetID"></param>
109 /// <param name="data"></param> 109 /// <param name="data"></param>
110 /// <returns>True if the transfer is complete, false otherwise</returns> 110 /// <returns>True if the transfer is complete, false otherwise</returns>
111 public bool Initialise(IClientAPI remoteClient, UUID assetID, UUID transaction, sbyte type, byte[] data, 111 public bool Initialise(IClientAPI remoteClient, UUID assetID,
112 bool storeLocal, bool tempFile) 112 UUID transaction, sbyte type, byte[] data, bool storeLocal,
113 bool tempFile)
113 { 114 {
114 ourClient = remoteClient; 115 ourClient = remoteClient;
115 m_asset = new AssetBase(assetID, "blank", type, remoteClient.AgentId.ToString()); 116 m_asset = new AssetBase(assetID, "blank", type,
117 remoteClient.AgentId.ToString());
116 m_asset.Data = data; 118 m_asset.Data = data;
117 m_asset.Description = "empty"; 119 m_asset.Description = "empty";
118 m_asset.Local = storeLocal; 120 m_asset.Local = storeLocal;
@@ -137,12 +139,14 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
137 protected void RequestStartXfer() 139 protected void RequestStartXfer()
138 { 140 {
139 XferID = Util.GetNextXferID(); 141 XferID = Util.GetNextXferID();
140 ourClient.SendXferRequest(XferID, m_asset.Type, m_asset.FullID, 0, new byte[0]); 142 ourClient.SendXferRequest(XferID, m_asset.Type, m_asset.FullID,
143 0, new byte[0]);
141 } 144 }
142 145
143 protected void SendCompleteMessage() 146 protected void SendCompleteMessage()
144 { 147 {
145 ourClient.SendAssetUploadCompleteMessage(m_asset.Type, true, m_asset.FullID); 148 ourClient.SendAssetUploadCompleteMessage(m_asset.Type, true,
149 m_asset.FullID);
146 150
147 m_finished = true; 151 m_finished = true;
148 if (m_createItem) 152 if (m_createItem)
@@ -151,18 +155,20 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
151 } 155 }
152 else if (m_storeLocal) 156 else if (m_storeLocal)
153 { 157 {
154 m_userTransactions.Manager.MyScene.AssetService.Store(m_asset); 158 m_Scene.AssetService.Store(m_asset);
155 } 159 }
156 160
157 m_log.DebugFormat( 161 m_log.DebugFormat(
158 "[ASSET TRANSACTIONS]: Uploaded asset {0} for transaction {1}", m_asset.FullID, TransactionID); 162 "[ASSET TRANSACTIONS]: Uploaded asset {0} for transaction {1}",
163 m_asset.FullID, TransactionID);
159 164
160 if (m_dumpAssetToFile) 165 if (m_dumpAssetToFile)
161 { 166 {
162 DateTime now = DateTime.Now; 167 DateTime now = DateTime.Now;
163 string filename = 168 string filename =
164 String.Format("{6}_{7}_{0:d2}{1:d2}{2:d2}_{3:d2}{4:d2}{5:d2}.dat", now.Year, now.Month, now.Day, 169 String.Format("{6}_{7}_{0:d2}{1:d2}{2:d2}_{3:d2}{4:d2}{5:d2}.dat",
165 now.Hour, now.Minute, now.Second, m_asset.Name, m_asset.Type); 170 now.Year, now.Month, now.Day, now.Hour, now.Minute,
171 now.Second, m_asset.Name, m_asset.Type);
166 SaveAssetToFile(filename, m_asset.Data); 172 SaveAssetToFile(filename, m_asset.Data);
167 } 173 }
168 } 174 }
@@ -181,9 +187,10 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
181 fs.Close(); 187 fs.Close();
182 } 188 }
183 189
184 public void RequestCreateInventoryItem(IClientAPI remoteClient, UUID transactionID, UUID folderID, 190 public void RequestCreateInventoryItem(IClientAPI remoteClient,
185 uint callbackID, string description, string name, sbyte invType, 191 UUID transactionID, UUID folderID, uint callbackID,
186 sbyte type, byte wearableType, uint nextOwnerMask) 192 string description, string name, sbyte invType,
193 sbyte type, byte wearableType, uint nextOwnerMask)
187 { 194 {
188 if (TransactionID == transactionID) 195 if (TransactionID == transactionID)
189 { 196 {
@@ -212,7 +219,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
212 219
213 private void DoCreateItem(uint callbackID) 220 private void DoCreateItem(uint callbackID)
214 { 221 {
215 m_userTransactions.Manager.MyScene.AssetService.Store(m_asset); 222 m_Scene.AssetService.Store(m_asset);
216 223
217 InventoryItemBase item = new InventoryItemBase(); 224 InventoryItemBase item = new InventoryItemBase();
218 item.Owner = ourClient.AgentId; 225 item.Owner = ourClient.AgentId;
@@ -232,7 +239,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
232 item.Flags = (uint) wearableType; 239 item.Flags = (uint) wearableType;
233 item.CreationDate = Util.UnixTimeSinceEpoch(); 240 item.CreationDate = Util.UnixTimeSinceEpoch();
234 241
235 if (m_userTransactions.Manager.MyScene.AddInventoryItem(item)) 242 if (m_Scene.AddInventoryItem(item))
236 ourClient.SendInventoryItemCreateUpdate(item, callbackID); 243 ourClient.SendInventoryItemCreateUpdate(item, callbackID);
237 else 244 else
238 ourClient.SendAlertMessage("Unable to create inventory item"); 245 ourClient.SendAlertMessage("Unable to create inventory item");
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
index 0df4585..7d6d191 100644
--- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
@@ -115,8 +115,19 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
115 115
116 #endregion 116 #endregion
117 117
118 /// <summary>
119 /// Check for the existence of the baked texture assets. Request a rebake
120 /// unless checkonly is true.
121 /// </summary>
122 /// <param name="client"></param>
123 /// <param name="checkonly"></param>
118 public bool ValidateBakedTextureCache(IClientAPI client) 124 public bool ValidateBakedTextureCache(IClientAPI client)
119 { 125 {
126 return ValidateBakedTextureCache(client, true);
127 }
128
129 private bool ValidateBakedTextureCache(IClientAPI client, bool checkonly)
130 {
120 ScenePresence sp = m_scene.GetScenePresence(client.AgentId); 131 ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
121 if (sp == null) 132 if (sp == null)
122 { 133 {
@@ -131,15 +142,33 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
131 { 142 {
132 int idx = AvatarAppearance.BAKE_INDICES[i]; 143 int idx = AvatarAppearance.BAKE_INDICES[i];
133 Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx]; 144 Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx];
134 if (face == null || face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE) 145
146 // if there is no texture entry, skip it
147 if (face == null)
135 continue; 148 continue;
136 149
150 // if the texture is one of the "defaults" then skip it
151 // this should probably be more intelligent (skirt texture doesnt matter
152 // if the avatar isnt wearing a skirt) but if any of the main baked
153 // textures is default then the rest should be as well
154 if (face.TextureID == UUID.Zero || face.TextureID == AppearanceManager.DEFAULT_AVATAR_TEXTURE)
155 continue;
156
137 defonly = false; // found a non-default texture reference 157 defonly = false; // found a non-default texture reference
138 158
139 if (! CheckBakedTextureAsset(client,face.TextureID,idx)) 159 if (! CheckBakedTextureAsset(client,face.TextureID,idx))
140 return false; 160 {
161 // the asset didn't exist if we are only checking, then we found a bad
162 // one and we're done otherwise, ask for a rebake
163 if (checkonly) return false;
164
165 m_log.InfoFormat("[AVFACTORY] missing baked texture {0}, request rebake",face.TextureID);
166 client.SendRebakeAvatarTextures(face.TextureID);
167 }
141 } 168 }
142 169
170 m_log.InfoFormat("[AVFACTORY]: complete texture check for {0}",client.AgentId);
171
143 // If we only found default textures, then the appearance is not cached 172 // If we only found default textures, then the appearance is not cached
144 return (defonly ? false : true); 173 return (defonly ? false : true);
145 } 174 }
@@ -158,61 +187,43 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
158 return; 187 return;
159 } 188 }
160 189
161 // m_log.WarnFormat("[AVFACTORY]: Start SetAppearance for {0}",client.AgentId); 190 m_log.InfoFormat("[AVFACTORY]: start SetAppearance for {0}",client.AgentId);
162 191
192 // TODO: This is probably not necessary any longer, just assume the
193 // textureEntry set implies that the appearance transaction is complete
163 bool changed = false; 194 bool changed = false;
164 195
165 // Process the texture entry transactionally, this doesn't guarantee that Appearance is 196 // Process the texture entry transactionally, this doesn't guarantee that Appearance is
166 // going to be handled correctly but it does serialize the updates to the appearance 197 // going to be handled correctly but it does serialize the updates to the appearance
167 lock (m_setAppearanceLock) 198 lock (m_setAppearanceLock)
168 { 199 {
169 if (textureEntry != null)
170 {
171 changed = sp.Appearance.SetTextureEntries(textureEntry);
172
173 // m_log.WarnFormat("[AVFACTORY]: Prepare to check textures for {0}",client.AgentId);
174
175 for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
176 {
177 int idx = AvatarAppearance.BAKE_INDICES[i];
178 Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx];
179 if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE)
180 Util.FireAndForget(delegate(object o) {
181 if (! CheckBakedTextureAsset(client,face.TextureID,idx))
182 client.SendRebakeAvatarTextures(face.TextureID);
183 });
184 }
185
186 // m_log.WarnFormat("[AVFACTORY]: Complete texture check for {0}",client.AgentId);
187 }
188
189 // Process the visual params, this may change height as well 200 // Process the visual params, this may change height as well
190 if (visualParams != null) 201 if (visualParams != null)
191 { 202 {
192 if (sp.Appearance.SetVisualParams(visualParams)) 203 changed = sp.Appearance.SetVisualParams(visualParams);
193 { 204 if (sp.Appearance.AvatarHeight > 0)
194 changed = true; 205 sp.SetHeight(sp.Appearance.AvatarHeight);
195 if (sp.Appearance.AvatarHeight > 0)
196 sp.SetHeight(sp.Appearance.AvatarHeight);
197 }
198 } 206 }
199 207
200 // Send the appearance back to the avatar, not clear that this is needed 208 // Process the baked texture array
201 sp.ControllingClient.SendAvatarDataImmediate(sp); 209 if (textureEntry != null)
202 // AvatarAppearance avp = sp.Appearance; 210 {
203 // sp.ControllingClient.SendAppearance(avp.Owner,avp.VisualParams,avp.Texture.GetBytes()); 211 changed = sp.Appearance.SetTextureEntries(textureEntry) || changed;
212
213 m_log.InfoFormat("[AVFACTORY]: received texture update for {0}",client.AgentId);
214 Util.FireAndForget(delegate(object o) { ValidateBakedTextureCache(client,false); });
204 215
205 } 216 // This appears to be set only in the final stage of the appearance
206 217 // update transaction. In theory, we should be able to do an immediate
218 // appearance send and save here.
207 219
208 // If something changed in the appearance then queue an appearance save 220 QueueAppearanceSave(client.AgentId);
209 if (changed) 221 QueueAppearanceSend(client.AgentId);
210 QueueAppearanceSave(client.AgentId); 222 }
211 223
212 // And always queue up an appearance update to send out 224 }
213 QueueAppearanceSend(client.AgentId);
214 225
215 // m_log.WarnFormat("[AVFACTORY]: Complete SetAppearance for {0}:\n{1}",client.AgentId,sp.Appearance.ToString()); 226 // m_log.WarnFormat("[AVFACTORY]: complete SetAppearance for {0}:\n{1}",client.AgentId,sp.Appearance.ToString());
216 } 227 }
217 228
218 /// <summary> 229 /// <summary>
@@ -235,6 +246,10 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
235 246
236 #region UpdateAppearanceTimer 247 #region UpdateAppearanceTimer
237 248
249 /// <summary>
250 /// Queue up a request to send appearance, makes it possible to
251 /// accumulate changes without sending out each one separately.
252 /// </summary>
238 public void QueueAppearanceSend(UUID agentid) 253 public void QueueAppearanceSend(UUID agentid)
239 { 254 {
240 // m_log.WarnFormat("[AVFACTORY]: Queue appearance send for {0}", agentid); 255 // m_log.WarnFormat("[AVFACTORY]: Queue appearance send for {0}", agentid);
@@ -274,21 +289,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
274 289
275 // Send the appearance to everyone in the scene 290 // Send the appearance to everyone in the scene
276 sp.SendAppearanceToAllOtherAgents(); 291 sp.SendAppearanceToAllOtherAgents();
277 // sp.ControllingClient.SendAvatarDataImmediate(sp);
278
279 // Send the appearance back to the avatar
280 // AvatarAppearance avp = sp.Appearance;
281 // sp.ControllingClient.SendAppearance(avp.Owner, avp.VisualParams, avp.Texture.GetBytes());
282 292
283/* 293 // Send animations back to the avatar as well
284// this needs to be fixed, the flag should be on scene presence not the region module 294 sp.Animator.SendAnimPack();
285 // Start the animations if necessary
286 if (!m_startAnimationSet)
287 {
288 sp.Animator.UpdateMovementAnimations();
289 m_startAnimationSet = true;
290 }
291*/
292 } 295 }
293 296
294 private void HandleAppearanceSave(UUID agentid) 297 private void HandleAppearanceSave(UUID agentid)
@@ -374,8 +377,12 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
374 377
375 // m_log.WarnFormat("[AVFACTORY]: AvatarIsWearing called for {0}", client.AgentId); 378 // m_log.WarnFormat("[AVFACTORY]: AvatarIsWearing called for {0}", client.AgentId);
376 379
377 AvatarAppearance avatAppearance = new AvatarAppearance(sp.Appearance, false); 380 // we need to clean out the existing textures
381 sp.Appearance.ResetAppearance();
378 382
383 // operate on a copy of the appearance so we don't have to lock anything
384 AvatarAppearance avatAppearance = new AvatarAppearance(sp.Appearance, false);
385
379 foreach (AvatarWearingArgs.Wearable wear in e.NowWearing) 386 foreach (AvatarWearingArgs.Wearable wear in e.NowWearing)
380 { 387 {
381 if (wear.Type < AvatarWearable.MAX_WEARABLES) 388 if (wear.Type < AvatarWearable.MAX_WEARABLES)
@@ -388,9 +395,11 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
388 SetAppearanceAssets(sp.UUID, ref avatAppearance); 395 SetAppearanceAssets(sp.UUID, ref avatAppearance);
389 396
390 // could get fancier with the locks here, but in the spirit of "last write wins" 397 // could get fancier with the locks here, but in the spirit of "last write wins"
391 // this should work correctly 398 // this should work correctly, also, we don't need to send the appearance here
399 // since the "iswearing" will trigger a new set of visual param and baked texture changes
400 // when those complete, the new appearance will be sent
392 sp.Appearance = avatAppearance; 401 sp.Appearance = avatAppearance;
393 m_scene.AvatarService.SetAppearance(client.AgentId, sp.Appearance); 402 QueueAppearanceSave(client.AgentId);
394 } 403 }
395 404
396 private void SetAppearanceAssets(UUID userID, ref AvatarAppearance appearance) 405 private void SetAppearanceAssets(UUID userID, ref AvatarAppearance appearance)
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
index 046b05f..acf2c3e 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
@@ -37,12 +37,11 @@ using System.Xml.Linq;
37using log4net; 37using log4net;
38using OpenMetaverse; 38using OpenMetaverse;
39using OpenSim.Framework; 39using OpenSim.Framework;
40using OpenSim.Framework.Communications;
41using OpenSim.Framework.Communications.Osp;
42using OpenSim.Framework.Serialization; 40using OpenSim.Framework.Serialization;
43using OpenSim.Framework.Serialization.External; 41using OpenSim.Framework.Serialization.External;
44using OpenSim.Region.CoreModules.World.Archiver; 42using OpenSim.Region.CoreModules.World.Archiver;
45using OpenSim.Region.Framework.Scenes; 43using OpenSim.Region.Framework.Scenes;
44using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Services.Interfaces; 45using OpenSim.Services.Interfaces;
47 46
48namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver 47namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
@@ -398,20 +397,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
398 // Don't use the item ID that's in the file 397 // Don't use the item ID that's in the file
399 item.ID = UUID.Random(); 398 item.ID = UUID.Random();
400 399
401 UUID ospResolvedId = OspResolver.ResolveOspa(item.CreatorId, m_scene.UserAccountService); 400 UUID ospResolvedId = OspResolver.ResolveOspa(item.CreatorId, m_scene.UserAccountService);
402 if (UUID.Zero != ospResolvedId) 401 if (UUID.Zero != ospResolvedId) // The user exists in this grid
403 { 402 {
404 item.CreatorIdAsUuid = ospResolvedId; 403 item.CreatorIdAsUuid = ospResolvedId;
405 404
406 // XXX: For now, don't preserve the OSPA in the creator id (which actually gets persisted to the 405 // XXX: For now, don't preserve the OSPA in the creator id (which actually gets persisted to the
407 // database). Instead, replace with the UUID that we found. 406 // database). Instead, replace with the UUID that we found.
408 item.CreatorId = ospResolvedId.ToString(); 407 item.CreatorId = ospResolvedId.ToString();
408
409 item.CreatorData = string.Empty;
409 } 410 }
410 else 411 else if (item.CreatorData == null || item.CreatorData == String.Empty)
411 { 412 {
412 item.CreatorIdAsUuid = m_userInfo.PrincipalID; 413 item.CreatorIdAsUuid = m_userInfo.PrincipalID;
413 } 414 }
414 415
415 item.Owner = m_userInfo.PrincipalID; 416 item.Owner = m_userInfo.PrincipalID;
416 417
417 // Reset folder ID to the one in which we want to load it 418 // Reset folder ID to the one in which we want to load it
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
index d81703a..cab341d 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
@@ -36,8 +36,6 @@ using OpenMetaverse;
36using OpenSim.Framework; 36using OpenSim.Framework;
37using OpenSim.Framework.Serialization; 37using OpenSim.Framework.Serialization;
38using OpenSim.Framework.Serialization.External; 38using OpenSim.Framework.Serialization.External;
39using OpenSim.Framework.Communications;
40using OpenSim.Framework.Communications.Osp;
41using OpenSim.Region.CoreModules.World.Archiver; 39using OpenSim.Region.CoreModules.World.Archiver;
42using OpenSim.Region.Framework.Scenes; 40using OpenSim.Region.Framework.Scenes;
43using OpenSim.Services.Interfaces; 41using OpenSim.Services.Interfaces;
@@ -139,20 +137,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
139 m_id, succeeded, m_userInfo, m_invPath, m_saveStream, reportedException); 137 m_id, succeeded, m_userInfo, m_invPath, m_saveStream, reportedException);
140 } 138 }
141 139
142 protected void SaveInvItem(InventoryItemBase inventoryItem, string path) 140 protected void SaveInvItem(InventoryItemBase inventoryItem, string path, Dictionary<string, object> options, IUserAccountService userAccountService)
143 { 141 {
144 string filename = path + CreateArchiveItemName(inventoryItem); 142 string filename = path + CreateArchiveItemName(inventoryItem);
145 143
146 // Record the creator of this item for user record purposes (which might go away soon) 144 // Record the creator of this item for user record purposes (which might go away soon)
147 m_userUuids[inventoryItem.CreatorIdAsUuid] = 1; 145 m_userUuids[inventoryItem.CreatorIdAsUuid] = 1;
148 146
149 InventoryItemBase saveItem = (InventoryItemBase)inventoryItem.Clone(); 147 string serialization = UserInventoryItemSerializer.Serialize(inventoryItem, options, userAccountService);
150 saveItem.CreatorId = OspResolver.MakeOspa(saveItem.CreatorIdAsUuid, m_scene.UserAccountService);
151
152 string serialization = UserInventoryItemSerializer.Serialize(saveItem);
153 m_archiveWriter.WriteFile(filename, serialization); 148 m_archiveWriter.WriteFile(filename, serialization);
154 149
155 m_assetGatherer.GatherAssetUuids(saveItem.AssetID, (AssetType)saveItem.AssetType, m_assetUuids); 150 m_assetGatherer.GatherAssetUuids(inventoryItem.AssetID, (AssetType)inventoryItem.AssetType, m_assetUuids);
156 } 151 }
157 152
158 /// <summary> 153 /// <summary>
@@ -161,7 +156,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
161 /// <param name="inventoryFolder">The inventory folder to save</param> 156 /// <param name="inventoryFolder">The inventory folder to save</param>
162 /// <param name="path">The path to which the folder should be saved</param> 157 /// <param name="path">The path to which the folder should be saved</param>
163 /// <param name="saveThisFolderItself">If true, save this folder itself. If false, only saves contents</param> 158 /// <param name="saveThisFolderItself">If true, save this folder itself. If false, only saves contents</param>
164 protected void SaveInvFolder(InventoryFolderBase inventoryFolder, string path, bool saveThisFolderItself) 159 protected void SaveInvFolder(InventoryFolderBase inventoryFolder, string path, bool saveThisFolderItself, Dictionary<string, object> options, IUserAccountService userAccountService)
165 { 160 {
166 if (saveThisFolderItself) 161 if (saveThisFolderItself)
167 { 162 {
@@ -176,19 +171,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
176 171
177 foreach (InventoryFolderBase childFolder in contents.Folders) 172 foreach (InventoryFolderBase childFolder in contents.Folders)
178 { 173 {
179 SaveInvFolder(childFolder, path, true); 174 SaveInvFolder(childFolder, path, true, options, userAccountService);
180 } 175 }
181 176
182 foreach (InventoryItemBase item in contents.Items) 177 foreach (InventoryItemBase item in contents.Items)
183 { 178 {
184 SaveInvItem(item, path); 179 SaveInvItem(item, path, options, userAccountService);
185 } 180 }
186 } 181 }
187 182
188 /// <summary> 183 /// <summary>
189 /// Execute the inventory write request 184 /// Execute the inventory write request
190 /// </summary> 185 /// </summary>
191 public void Execute() 186 public void Execute(Dictionary<string, object> options, IUserAccountService userAccountService)
192 { 187 {
193 try 188 try
194 { 189 {
@@ -266,7 +261,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
266 m_invPath == String.Empty ? InventoryFolderImpl.PATH_DELIMITER : m_invPath); 261 m_invPath == String.Empty ? InventoryFolderImpl.PATH_DELIMITER : m_invPath);
267 262
268 //recurse through all dirs getting dirs and files 263 //recurse through all dirs getting dirs and files
269 SaveInvFolder(inventoryFolder, ArchiveConstants.INVENTORY_PATH, !saveFolderContentsOnly); 264 SaveInvFolder(inventoryFolder, ArchiveConstants.INVENTORY_PATH, !saveFolderContentsOnly, options, userAccountService);
270 } 265 }
271 else if (inventoryItem != null) 266 else if (inventoryItem != null)
272 { 267 {
@@ -274,14 +269,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
274 "[INVENTORY ARCHIVER]: Found item {0} {1} at {2}", 269 "[INVENTORY ARCHIVER]: Found item {0} {1} at {2}",
275 inventoryItem.Name, inventoryItem.ID, m_invPath); 270 inventoryItem.Name, inventoryItem.ID, m_invPath);
276 271
277 SaveInvItem(inventoryItem, ArchiveConstants.INVENTORY_PATH); 272 SaveInvItem(inventoryItem, ArchiveConstants.INVENTORY_PATH, options, userAccountService);
278 } 273 }
279 274
280 // Don't put all this profile information into the archive right now. 275 // Don't put all this profile information into the archive right now.
281 //SaveUsers(); 276 //SaveUsers();
282 277
283 new AssetsRequest( 278 new AssetsRequest(
284 new AssetsArchiver(m_archiveWriter), m_assetUuids, m_scene.AssetService, ReceivedAllAssets).Execute(); 279 new AssetsArchiver(m_archiveWriter),
280 m_assetUuids, m_scene.AssetService,
281 m_scene.UserAccountService, m_scene.RegionInfo.ScopeID,
282 options, ReceivedAllAssets).Execute();
285 } 283 }
286 catch (Exception) 284 catch (Exception)
287 { 285 {
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs
index 2eaca49..b33c2b1 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs
@@ -75,6 +75,24 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
75 private Dictionary<UUID, Scene> m_scenes = new Dictionary<UUID, Scene>(); 75 private Dictionary<UUID, Scene> m_scenes = new Dictionary<UUID, Scene>();
76 private Scene m_aScene; 76 private Scene m_aScene;
77 77
78 private IUserAccountService m_UserAccountService;
79 protected IUserAccountService UserAccountService
80 {
81 get
82 {
83 if (m_UserAccountService == null)
84 // What a strange thing to do...
85 foreach (Scene s in m_scenes.Values)
86 {
87 m_UserAccountService = s.RequestModuleInterface<IUserAccountService>();
88 break;
89 }
90
91 return m_UserAccountService;
92 }
93 }
94
95
78 public InventoryArchiverModule() {} 96 public InventoryArchiverModule() {}
79 97
80 public InventoryArchiverModule(bool disablePresenceChecks) 98 public InventoryArchiverModule(bool disablePresenceChecks)
@@ -106,11 +124,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
106 124
107 scene.AddCommand( 125 scene.AddCommand(
108 this, "save iar", 126 this, "save iar",
109 "save iar <first> <last> <inventory path> <password> [<IAR path>]", 127 "save iar <first> <last> <inventory path> <password> [--p|-profile=<url>] [<IAR path>]",
110 "Save user inventory archive (IAR).", 128 "Save user inventory archive (IAR).",
111 "<first> is the user's first name." + Environment.NewLine 129 "<first> is the user's first name." + Environment.NewLine
112 + "<last> is the user's last name." + Environment.NewLine 130 + "<last> is the user's last name." + Environment.NewLine
113 + "<inventory path> is the path inside the user's inventory for the folder/item to be saved." + Environment.NewLine 131 + "<inventory path> is the path inside the user's inventory for the folder/item to be saved." + Environment.NewLine
132 + "-p|--profile=<url> adds the url of the profile service to the saved user information." + Environment.NewLine
114 + "<IAR path> is the filesystem path at which to save the IAR." 133 + "<IAR path> is the filesystem path at which to save the IAR."
115 + string.Format(" If this is not given then the filename {0} in the current directory is used", DEFAULT_INV_BACKUP_FILENAME), 134 + string.Format(" If this is not given then the filename {0} in the current directory is used", DEFAULT_INV_BACKUP_FILENAME),
116 HandleSaveInvConsoleCommand); 135 HandleSaveInvConsoleCommand);
@@ -157,7 +176,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
157 { 176 {
158 try 177 try
159 { 178 {
160 new InventoryArchiveWriteRequest(id, this, m_aScene, userInfo, invPath, saveStream).Execute(); 179 new InventoryArchiveWriteRequest(id, this, m_aScene, userInfo, invPath, saveStream).Execute(options, UserAccountService);
161 } 180 }
162 catch (EntryPointNotFoundException e) 181 catch (EntryPointNotFoundException e)
163 { 182 {
@@ -197,7 +216,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
197 { 216 {
198 try 217 try
199 { 218 {
200 new InventoryArchiveWriteRequest(id, this, m_aScene, userInfo, invPath, savePath).Execute(); 219 new InventoryArchiveWriteRequest(id, this, m_aScene, userInfo, invPath, savePath).Execute(options, UserAccountService);
201 } 220 }
202 catch (EntryPointNotFoundException e) 221 catch (EntryPointNotFoundException e)
203 { 222 {
@@ -235,14 +254,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
235 if (m_scenes.Count > 0) 254 if (m_scenes.Count > 0)
236 { 255 {
237 UserAccount userInfo = GetUserInfo(firstName, lastName, pass); 256 UserAccount userInfo = GetUserInfo(firstName, lastName, pass);
238 257
239 if (userInfo != null) 258 if (userInfo != null)
240 { 259 {
241 if (CheckPresence(userInfo.PrincipalID)) 260 if (CheckPresence(userInfo.PrincipalID))
242 { 261 {
262
243 InventoryArchiveReadRequest request; 263 InventoryArchiveReadRequest request;
244 bool merge = (options.ContainsKey("merge") ? (bool)options["merge"] : false); 264 bool merge = (options.ContainsKey("merge") ? (bool)options["merge"] : false);
245 265
246 try 266 try
247 { 267 {
248 request = new InventoryArchiveReadRequest(m_aScene, userInfo, invPath, loadStream, merge); 268 request = new InventoryArchiveReadRequest(m_aScene, userInfo, invPath, loadStream, merge);
@@ -256,7 +276,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
256 276
257 return false; 277 return false;
258 } 278 }
259 279
260 UpdateClientWithLoadedNodes(userInfo, request.Execute()); 280 UpdateClientWithLoadedNodes(userInfo, request.Execute());
261 281
262 return true; 282 return true;
@@ -268,6 +288,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
268 userInfo.FirstName, userInfo.LastName, userInfo.PrincipalID); 288 userInfo.FirstName, userInfo.LastName, userInfo.PrincipalID);
269 } 289 }
270 } 290 }
291 else
292 m_log.ErrorFormat("[INVENTORY ARCHIVER]: User {0} {1} not found",
293 firstName, lastName);
271 } 294 }
272 295
273 return false; 296 return false;
@@ -368,10 +391,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
368 protected void HandleSaveInvConsoleCommand(string module, string[] cmdparams) 391 protected void HandleSaveInvConsoleCommand(string module, string[] cmdparams)
369 { 392 {
370 Guid id = Guid.NewGuid(); 393 Guid id = Guid.NewGuid();
371 394
395 Dictionary<string, object> options = new Dictionary<string, object>();
396
397 OptionSet ops = new OptionSet();
398 //ops.Add("v|version=", delegate(string v) { options["version"] = v; });
399 ops.Add("p|profile=", delegate(string v) { options["profile"] = v; });
400
401 List<string> mainParams = ops.Parse(cmdparams);
402
372 try 403 try
373 { 404 {
374 if (cmdparams.Length < 6) 405 if (mainParams.Count < 6)
375 { 406 {
376 m_log.Error( 407 m_log.Error(
377 "[INVENTORY ARCHIVER]: usage is save iar <first name> <last name> <inventory path> <user password> [<save file path>]"); 408 "[INVENTORY ARCHIVER]: usage is save iar <first name> <last name> <inventory path> <user password> [<save file path>]");
@@ -379,18 +410,20 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
379 } 410 }
380 411
381 m_log.Info("[INVENTORY ARCHIVER]: PLEASE NOTE THAT THIS FACILITY IS EXPERIMENTAL. BUG REPORTS WELCOME."); 412 m_log.Info("[INVENTORY ARCHIVER]: PLEASE NOTE THAT THIS FACILITY IS EXPERIMENTAL. BUG REPORTS WELCOME.");
382 413 if (options.ContainsKey("profile"))
383 string firstName = cmdparams[2]; 414 m_log.WarnFormat("[INVENTORY ARCHIVER]: Please be aware that inventory archives with creator information are not compatible with OpenSim 0.7.0.2 and earlier. Do not use the -profile option if you want to produce a compatible IAR");
384 string lastName = cmdparams[3]; 415
385 string invPath = cmdparams[4]; 416 string firstName = mainParams[2];
386 string pass = cmdparams[5]; 417 string lastName = mainParams[3];
387 string savePath = (cmdparams.Length > 6 ? cmdparams[6] : DEFAULT_INV_BACKUP_FILENAME); 418 string invPath = mainParams[4];
419 string pass = mainParams[5];
420 string savePath = (mainParams.Count > 6 ? mainParams[6] : DEFAULT_INV_BACKUP_FILENAME);
388 421
389 m_log.InfoFormat( 422 m_log.InfoFormat(
390 "[INVENTORY ARCHIVER]: Saving archive {0} using inventory path {1} for {2} {3}", 423 "[INVENTORY ARCHIVER]: Saving archive {0} using inventory path {1} for {2} {3}",
391 savePath, invPath, firstName, lastName); 424 savePath, invPath, firstName, lastName);
392 425
393 ArchiveInventory(id, firstName, lastName, invPath, pass, savePath, new Dictionary<string, object>()); 426 ArchiveInventory(id, firstName, lastName, invPath, pass, savePath, options);
394 } 427 }
395 catch (InventoryArchiverException e) 428 catch (InventoryArchiverException e)
396 { 429 {
@@ -518,5 +551,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
518 551
519 return false; 552 return false;
520 } 553 }
554
521 } 555 }
522} 556}
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
index 938886b2..2747e15 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
@@ -38,7 +38,6 @@ using OpenSim.Framework;
38using OpenSim.Framework.Serialization; 38using OpenSim.Framework.Serialization;
39using OpenSim.Framework.Serialization.External; 39using OpenSim.Framework.Serialization.External;
40using OpenSim.Framework.Communications; 40using OpenSim.Framework.Communications;
41using OpenSim.Framework.Communications.Osp;
42using OpenSim.Region.CoreModules.Avatar.Inventory.Archiver; 41using OpenSim.Region.CoreModules.Avatar.Inventory.Archiver;
43using OpenSim.Region.CoreModules.World.Serialiser; 42using OpenSim.Region.CoreModules.World.Serialiser;
44using OpenSim.Region.Framework.Scenes; 43using OpenSim.Region.Framework.Scenes;
@@ -96,14 +95,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
96 item1.Name = m_item1Name; 95 item1.Name = m_item1Name;
97 item1.AssetID = UUID.Random(); 96 item1.AssetID = UUID.Random();
98 item1.GroupID = UUID.Random(); 97 item1.GroupID = UUID.Random();
99 item1.CreatorId = OspResolver.MakeOspa(m_ua2.FirstName, m_ua2.LastName); 98 //item1.CreatorId = OspResolver.MakeOspa(m_ua2.FirstName, m_ua2.LastName);
100 //item1.CreatorId = userUuid.ToString(); 99 //item1.CreatorId = userUuid.ToString();
101 //item1.CreatorId = "00000000-0000-0000-0000-000000000444"; 100 item1.CreatorId = m_ua2.PrincipalID.ToString();
102 item1.Owner = UUID.Zero; 101 item1.Owner = UUID.Zero;
103 102
103 Scene scene = SceneSetupHelpers.SetupScene("Inventory");
104 UserProfileTestUtils.CreateUserWithInventory(scene, m_ua2, "hampshire");
105
104 string item1FileName 106 string item1FileName
105 = string.Format("{0}{1}", ArchiveConstants.INVENTORY_PATH, archiveItemName); 107 = string.Format("{0}{1}", ArchiveConstants.INVENTORY_PATH, archiveItemName);
106 tar.WriteFile(item1FileName, UserInventoryItemSerializer.Serialize(item1)); 108 tar.WriteFile(item1FileName, UserInventoryItemSerializer.Serialize(item1, new Dictionary<string, object>(), scene.UserAccountService));
107 tar.Close(); 109 tar.Close();
108 m_iarStream = new MemoryStream(archiveWriteStream.ToArray()); 110 m_iarStream = new MemoryStream(archiveWriteStream.ToArray());
109 } 111 }
@@ -386,7 +388,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
386 Scene scene = SceneSetupHelpers.SetupScene("inventory"); 388 Scene scene = SceneSetupHelpers.SetupScene("inventory");
387 389
388 SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule); 390 SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule);
389 391
390 UserProfileTestUtils.CreateUserWithInventory(scene, m_ua1, "meowfood"); 392 UserProfileTestUtils.CreateUserWithInventory(scene, m_ua1, "meowfood");
391 UserProfileTestUtils.CreateUserWithInventory(scene, m_ua2, "hampshire"); 393 UserProfileTestUtils.CreateUserWithInventory(scene, m_ua2, "hampshire");
392 394
@@ -551,7 +553,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
551 553
552 string item1FileName 554 string item1FileName
553 = string.Format("{0}{1}", ArchiveConstants.INVENTORY_PATH, archiveItemName); 555 = string.Format("{0}{1}", ArchiveConstants.INVENTORY_PATH, archiveItemName);
554 tar.WriteFile(item1FileName, UserInventoryItemSerializer.Serialize(item1)); 556 tar.WriteFile(item1FileName, UserInventoryItemSerializer.Serialize(item1, new Dictionary<string,object>(), null));
555 tar.Close(); 557 tar.Close();
556 558
557 MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray()); 559 MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray());
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index 56aefa5..47548c7 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -876,8 +876,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
876 } 876 }
877 877
878 agent.MakeChildAgent(); 878 agent.MakeChildAgent();
879
879 // now we have a child agent in this region. Request all interesting data about other (root) agents 880 // now we have a child agent in this region. Request all interesting data about other (root) agents
880 agent.SendInitialFullUpdateToAllClients(); 881 agent.SendOtherAgentsAvatarDataToMe();
882 agent.SendOtherAgentsAppearanceToMe();
881 883
882 CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true); 884 CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true);
883 885
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs
index ccb892e..81b65c5 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs
@@ -27,8 +27,11 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.IO;
30using System.Reflection; 31using System.Reflection;
31using System.Threading; 32using System.Threading;
33using System.Xml;
34
32using log4net; 35using log4net;
33using OpenMetaverse; 36using OpenMetaverse;
34using OpenSim.Framework; 37using OpenSim.Framework;
@@ -52,14 +55,16 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
52// private Dictionary<string, InventoryClient> m_inventoryServers = new Dictionary<string, InventoryClient>(); 55// private Dictionary<string, InventoryClient> m_inventoryServers = new Dictionary<string, InventoryClient>();
53 56
54 private Scene m_scene; 57 private Scene m_scene;
58 private string m_ProfileServerURI;
55 59
56 #endregion 60 #endregion
57 61
58 #region Constructor 62 #region Constructor
59 63
60 public HGAssetMapper(Scene scene) 64 public HGAssetMapper(Scene scene, string profileURL)
61 { 65 {
62 m_scene = scene; 66 m_scene = scene;
67 m_ProfileServerURI = profileURL;
63 } 68 }
64 69
65 #endregion 70 #endregion
@@ -95,16 +100,18 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
95 try 100 try
96 { 101 {
97 asset1.ID = url + "/" + asset.ID; 102 asset1.ID = url + "/" + asset.ID;
98// UUID temp = UUID.Zero;
99 // TODO: if the creator is local, stick this grid's URL in front
100 //if (UUID.TryParse(asset.Metadata.CreatorID, out temp))
101 // asset1.Metadata.CreatorID = ??? + "/" + asset.Metadata.CreatorID;
102 } 103 }
103 catch 104 catch
104 { 105 {
105 m_log.Warn("[HG ASSET MAPPER]: Oops."); 106 m_log.Warn("[HG ASSET MAPPER]: Oops.");
106 } 107 }
107 108
109 AdjustIdentifiers(asset1.Metadata);
110 if (asset1.Metadata.Type == (sbyte)AssetType.Object)
111 asset1.Data = AdjustIdentifiers(asset.Data);
112 else
113 asset1.Data = asset.Data;
114
108 m_scene.AssetService.Store(asset1); 115 m_scene.AssetService.Store(asset1);
109 m_log.DebugFormat("[HG ASSET MAPPER]: Posted copy of asset {0} from local asset server to {1}", asset1.ID, url); 116 m_log.DebugFormat("[HG ASSET MAPPER]: Posted copy of asset {0} from local asset server to {1}", asset1.ID, url);
110 } 117 }
@@ -118,7 +125,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
118 125
119 private void Copy(AssetBase from, AssetBase to) 126 private void Copy(AssetBase from, AssetBase to)
120 { 127 {
121 to.Data = from.Data; 128 //to.Data = from.Data; // don't copy this, it's copied elsewhere
122 to.Description = from.Description; 129 to.Description = from.Description;
123 to.FullID = from.FullID; 130 to.FullID = from.FullID;
124 to.ID = from.ID; 131 to.ID = from.ID;
@@ -129,6 +136,70 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
129 136
130 } 137 }
131 138
139 private void AdjustIdentifiers(AssetMetadata meta)
140 {
141 if (meta.CreatorID != null && meta.CreatorID != string.Empty)
142 {
143 UUID uuid = UUID.Zero;
144 UUID.TryParse(meta.CreatorID, out uuid);
145 UserAccount creator = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, uuid);
146 if (creator != null)
147 meta.CreatorID = m_ProfileServerURI + "/" + meta.CreatorID + ";" + creator.FirstName + " " + creator.LastName;
148 }
149 }
150
151 protected byte[] AdjustIdentifiers(byte[] data)
152 {
153 string xml = Utils.BytesToString(data);
154 return Utils.StringToBytes(RewriteSOP(xml));
155 }
156
157 protected string RewriteSOP(string xml)
158 {
159 XmlDocument doc = new XmlDocument();
160 doc.LoadXml(xml);
161 XmlNodeList sops = doc.GetElementsByTagName("SceneObjectPart");
162
163 foreach (XmlNode sop in sops)
164 {
165 UserAccount creator = null;
166 bool hasCreatorData = false;
167 XmlNodeList nodes = sop.ChildNodes;
168 foreach (XmlNode node in nodes)
169 {
170 if (node.Name == "CreatorID")
171 {
172 UUID uuid = UUID.Zero;
173 UUID.TryParse(node.InnerText, out uuid);
174 creator = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, uuid);
175 }
176 if (node.Name == "CreatorData" && node.InnerText != null && node.InnerText != string.Empty)
177 hasCreatorData = true;
178
179 //if (node.Name == "OwnerID")
180 //{
181 // UserAccount owner = GetUser(node.InnerText);
182 // if (owner != null)
183 // node.InnerText = m_ProfileServiceURL + "/" + node.InnerText + "/" + owner.FirstName + " " + owner.LastName;
184 //}
185 }
186
187 if (!hasCreatorData && creator != null)
188 {
189 XmlElement creatorData = doc.CreateElement("CreatorData");
190 creatorData.InnerText = m_ProfileServerURI + "/" + creator.PrincipalID + ";" + creator.FirstName + " " + creator.LastName;
191 sop.AppendChild(creatorData);
192 }
193 }
194
195 using (StringWriter wr = new StringWriter())
196 {
197 doc.Save(wr);
198 return wr.ToString();
199 }
200
201 }
202
132 // TODO: unused 203 // TODO: unused
133 // private void Dump(Dictionary<UUID, bool> lst) 204 // private void Dump(Dictionary<UUID, bool> lst)
134 // { 205 // {
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
index 125a397..34b8114 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
@@ -54,6 +54,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
54 get { return m_assMapper; } 54 get { return m_assMapper; }
55 } 55 }
56 56
57 private string m_ProfileServerURI;
58
57// private bool m_Initialized = false; 59// private bool m_Initialized = false;
58 60
59 #region INonSharedRegionModule 61 #region INonSharedRegionModule
@@ -73,6 +75,12 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
73 { 75 {
74 m_Enabled = true; 76 m_Enabled = true;
75 m_log.InfoFormat("[HG INVENTORY ACCESS MODULE]: {0} enabled.", Name); 77 m_log.InfoFormat("[HG INVENTORY ACCESS MODULE]: {0} enabled.", Name);
78
79 IConfig thisModuleConfig = source.Configs["HGInventoryAccessModule"];
80 if (thisModuleConfig != null)
81 m_ProfileServerURI = thisModuleConfig.GetString("ProfileServerURI", string.Empty);
82 else
83 m_log.Warn("[HG INVENTORY ACCESS MODULE]: HGInventoryAccessModule configs not found. ProfileServerURI not set!");
76 } 84 }
77 } 85 }
78 } 86 }
@@ -83,7 +91,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
83 return; 91 return;
84 92
85 base.AddRegion(scene); 93 base.AddRegion(scene);
86 m_assMapper = new HGAssetMapper(scene); 94 m_assMapper = new HGAssetMapper(scene, m_ProfileServerURI);
87 scene.EventManager.OnNewInventoryItemUploadComplete += UploadInventoryItem; 95 scene.EventManager.OnNewInventoryItemUploadComplete += UploadInventoryItem;
88 96
89 } 97 }
@@ -97,7 +105,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
97 string userAssetServer = string.Empty; 105 string userAssetServer = string.Empty;
98 if (IsForeignUser(avatarID, out userAssetServer)) 106 if (IsForeignUser(avatarID, out userAssetServer))
99 { 107 {
100 m_assMapper.Post(assetID, avatarID, userAssetServer); 108 Util.FireAndForget(delegate { m_assMapper.Post(assetID, avatarID, userAssetServer); });
101 } 109 }
102 } 110 }
103 111
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
index 67732ff..1ebccd1 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
@@ -53,6 +53,17 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
53 53
54 protected bool m_Enabled = false; 54 protected bool m_Enabled = false;
55 protected Scene m_Scene; 55 protected Scene m_Scene;
56 protected IUserManagement m_UserManagement;
57 protected IUserManagement UserManagementModule
58 {
59 get
60 {
61 if (m_UserManagement == null)
62 m_UserManagement = m_Scene.RequestModuleInterface<IUserManagement>();
63 return m_UserManagement;
64 }
65 }
66
56 67
57 #region INonSharedRegionModule 68 #region INonSharedRegionModule
58 69
@@ -542,6 +553,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
542 SceneObjectGroup group 553 SceneObjectGroup group
543 = SceneObjectSerializer.FromOriginalXmlFormat(itemId, xmlData); 554 = SceneObjectSerializer.FromOriginalXmlFormat(itemId, xmlData);
544 555
556 Util.FireAndForget(delegate { AddUserData(group); });
557
545 group.RootPart.FromFolderID = item.Folder; 558 group.RootPart.FromFolderID = item.Folder;
546 559
547 // If it's rezzed in world, select it. Much easier to 560 // If it's rezzed in world, select it. Much easier to
@@ -699,6 +712,13 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
699 return null; 712 return null;
700 } 713 }
701 714
715 protected void AddUserData(SceneObjectGroup sog)
716 {
717 UserManagementModule.AddUser(sog.RootPart.CreatorID, sog.RootPart.CreatorData);
718 foreach (SceneObjectPart sop in sog.Parts)
719 UserManagementModule.AddUser(sop.CreatorID, sop.CreatorData);
720 }
721
702 public virtual void TransferInventoryAssets(InventoryItemBase item, UUID sender, UUID receiver) 722 public virtual void TransferInventoryAssets(InventoryItemBase item, UUID sender, UUID receiver)
703 { 723 {
704 } 724 }
@@ -779,9 +799,13 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
779 protected virtual InventoryItemBase GetItem(UUID agentID, UUID itemID) 799 protected virtual InventoryItemBase GetItem(UUID agentID, UUID itemID)
780 { 800 {
781 IInventoryService invService = m_Scene.RequestModuleInterface<IInventoryService>(); 801 IInventoryService invService = m_Scene.RequestModuleInterface<IInventoryService>();
782 InventoryItemBase assetRequestItem = new InventoryItemBase(itemID, agentID); 802 InventoryItemBase item = new InventoryItemBase(itemID, agentID);
783 assetRequestItem = invService.GetItem(assetRequestItem); 803 item = invService.GetItem(item);
784 return assetRequestItem; 804
805 if (item.CreatorData != null && item.CreatorData != string.Empty)
806 UserManagementModule.AddUser(item.CreatorIdAsUuid, item.CreatorData);
807
808 return item;
785 } 809 }
786 810
787 #endregion 811 #endregion
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
index 0d94baa..bf84100 100644
--- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
@@ -275,6 +275,11 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
275 m_log.DebugFormat("[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}", user.Id, user.FirstName, user.LastName, user.ProfileURL); 275 m_log.DebugFormat("[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}", user.Id, user.FirstName, user.LastName, user.ProfileURL);
276 } 276 }
277 277
278 public void AddUser(UUID uuid, string first, string last, string profileURL)
279 {
280 AddUser(uuid, profileURL + ";" + first + " " + last);
281 }
282
278 //public void AddUser(UUID uuid, string userData) 283 //public void AddUser(UUID uuid, string userData)
279 //{ 284 //{
280 // if (m_UserCache.ContainsKey(uuid)) 285 // if (m_UserCache.ContainsKey(uuid))
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Asset/AssetServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Asset/AssetServiceInConnectorModule.cs
index 2324380..e25700d 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Asset/AssetServiceInConnectorModule.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Asset/AssetServiceInConnectorModule.cs
@@ -91,9 +91,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Asset
91 { 91 {
92 m_Registered = true; 92 m_Registered = true;
93 93
94 m_log.Info("[RegionAssetService]: Starting..."); 94 m_log.Info("[HGAssetService]: Starting...");
95 95
96 Object[] args = new Object[] { m_Config, MainServer.Instance, string.Empty }; 96
97 Object[] args = new Object[] { m_Config, MainServer.Instance, "HGAssetService" };
97 98
98 ServerUtils.LoadPlugin<IServiceConnector>("OpenSim.Server.Handlers.dll:AssetServiceConnector", args); 99 ServerUtils.LoadPlugin<IServiceConnector>("OpenSim.Server.Handlers.dll:AssetServiceConnector", args);
99 } 100 }
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs
index b987b5a..0699407 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs
@@ -190,7 +190,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
190 190
191 new AssetsRequest( 191 new AssetsRequest(
192 new AssetsArchiver(archiveWriter), assetUuids, 192 new AssetsArchiver(archiveWriter), assetUuids,
193 m_scene.AssetService, awre.ReceivedAllAssets).Execute(); 193 m_scene.AssetService, m_scene.UserAccountService,
194 m_scene.RegionInfo.ScopeID, options, awre.ReceivedAllAssets).Execute();
194 } 195 }
195 catch (Exception) 196 catch (Exception)
196 { 197 {
@@ -238,10 +239,10 @@ namespace OpenSim.Region.CoreModules.World.Archiver
238 } 239 }
239 240
240 m_log.InfoFormat("[ARCHIVER]: Creating version {0}.{1} OAR", majorVersion, minorVersion); 241 m_log.InfoFormat("[ARCHIVER]: Creating version {0}.{1} OAR", majorVersion, minorVersion);
241 if (majorVersion == 1) 242 //if (majorVersion == 1)
242 { 243 //{
243 m_log.WarnFormat("[ARCHIVER]: Please be aware that version 1.0 OARs are not compatible with OpenSim 0.7.0.2 and earlier. Please use the --version=0 option if you want to produce a compatible OAR"); 244 // m_log.WarnFormat("[ARCHIVER]: Please be aware that version 1.0 OARs are not compatible with OpenSim 0.7.0.2 and earlier. Please use the --version=0 option if you want to produce a compatible OAR");
244 } 245 //}
245 246
246 StringWriter sw = new StringWriter(); 247 StringWriter sw = new StringWriter();
247 XmlTextWriter xtw = new XmlTextWriter(sw); 248 XmlTextWriter xtw = new XmlTextWriter(sw);
diff --git a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
index d4a09b4..5da1656 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
@@ -34,6 +34,7 @@ using log4net;
34using OpenMetaverse; 34using OpenMetaverse;
35using OpenSim.Framework; 35using OpenSim.Framework;
36using OpenSim.Framework.Serialization; 36using OpenSim.Framework.Serialization;
37using OpenSim.Framework.Serialization.External;
37using OpenSim.Services.Interfaces; 38using OpenSim.Services.Interfaces;
38 39
39namespace OpenSim.Region.CoreModules.World.Archiver 40namespace OpenSim.Region.CoreModules.World.Archiver
@@ -100,17 +101,26 @@ namespace OpenSim.Region.CoreModules.World.Archiver
100 /// Asset service used to request the assets 101 /// Asset service used to request the assets
101 /// </value> 102 /// </value>
102 protected IAssetService m_assetService; 103 protected IAssetService m_assetService;
104 protected IUserAccountService m_userAccountService;
105 protected UUID m_scopeID; // the grid ID
103 106
104 protected AssetsArchiver m_assetsArchiver; 107 protected AssetsArchiver m_assetsArchiver;
105 108
109 protected Dictionary<string, object> m_options;
110
106 protected internal AssetsRequest( 111 protected internal AssetsRequest(
107 AssetsArchiver assetsArchiver, IDictionary<UUID, AssetType> uuids, 112 AssetsArchiver assetsArchiver, IDictionary<UUID, AssetType> uuids,
108 IAssetService assetService, AssetsRequestCallback assetsRequestCallback) 113 IAssetService assetService, IUserAccountService userService,
114 UUID scope, Dictionary<string, object> options,
115 AssetsRequestCallback assetsRequestCallback)
109 { 116 {
110 m_assetsArchiver = assetsArchiver; 117 m_assetsArchiver = assetsArchiver;
111 m_uuids = uuids; 118 m_uuids = uuids;
112 m_assetsRequestCallback = assetsRequestCallback; 119 m_assetsRequestCallback = assetsRequestCallback;
113 m_assetService = assetService; 120 m_assetService = assetService;
121 m_userAccountService = userService;
122 m_scopeID = scope;
123 m_options = options;
114 m_repliesRequired = uuids.Count; 124 m_repliesRequired = uuids.Count;
115 125
116 m_requestCallbackTimer = new System.Timers.Timer(TIMEOUT); 126 m_requestCallbackTimer = new System.Timers.Timer(TIMEOUT);
@@ -241,7 +251,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
241 { 251 {
242// m_log.DebugFormat("[ARCHIVER]: Writing asset {0}", id); 252// m_log.DebugFormat("[ARCHIVER]: Writing asset {0}", id);
243 m_foundAssetUuids.Add(asset.FullID); 253 m_foundAssetUuids.Add(asset.FullID);
244 m_assetsArchiver.WriteAsset(asset); 254
255 m_assetsArchiver.WriteAsset(PostProcess(asset));
245 } 256 }
246 else 257 else
247 { 258 {
@@ -288,5 +299,16 @@ namespace OpenSim.Region.CoreModules.World.Archiver
288 "[ARCHIVER]: Terminating archive creation since asset requster callback failed with {0}", e); 299 "[ARCHIVER]: Terminating archive creation since asset requster callback failed with {0}", e);
289 } 300 }
290 } 301 }
302
303 protected AssetBase PostProcess(AssetBase asset)
304 {
305 if (asset.Type == (sbyte)AssetType.Object && asset.Data != null && m_options.ContainsKey("profile"))
306 {
307 //m_log.DebugFormat("[ARCHIVER]: Rewriting object data for {0}", asset.ID);
308 string xml = ExternalRepresentationUtils.RewriteSOP(Utils.BytesToString(asset.Data), m_options["profile"].ToString(), m_userAccountService, m_scopeID);
309 asset.Data = Utils.StringToBytes(xml);
310 }
311 return asset;
312 }
291 } 313 }
292} 314}
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
index 622fc08..ddae20f 100644
--- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
@@ -231,7 +231,23 @@ namespace OpenSim.Region.CoreModules.World.Estate
231 231
232 private void handleEstateRestartSimRequest(IClientAPI remoteClient, int timeInSeconds) 232 private void handleEstateRestartSimRequest(IClientAPI remoteClient, int timeInSeconds)
233 { 233 {
234 m_scene.Restart(timeInSeconds); 234 IRestartModule restartModule = m_scene.RequestModuleInterface<IRestartModule>();
235 if (restartModule != null)
236 {
237 List<int> times = new List<int>();
238 while (timeInSeconds > 0)
239 {
240 times.Add(timeInSeconds);
241 if (timeInSeconds > 300)
242 timeInSeconds -= 120;
243 else if (timeInSeconds > 30)
244 timeInSeconds -= 30;
245 else
246 timeInSeconds -= 15;
247 }
248
249 restartModule.ScheduleRestart(UUID.Zero, "Region will restart in {0}", times.ToArray(), true);
250 }
235 } 251 }
236 252
237 private void handleChangeEstateCovenantRequest(IClientAPI remoteClient, UUID estateCovenantID) 253 private void handleChangeEstateCovenantRequest(IClientAPI remoteClient, UUID estateCovenantID)
diff --git a/OpenSim/Region/CoreModules/World/Region/RestartModule.cs b/OpenSim/Region/CoreModules/World/Region/RestartModule.cs
new file mode 100644
index 0000000..c65aa6a
--- /dev/null
+++ b/OpenSim/Region/CoreModules/World/Region/RestartModule.cs
@@ -0,0 +1,263 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
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.
26 */
27
28using System;
29using System.Reflection;
30using System.Timers;
31using System.Threading;
32using System.Collections.Generic;
33using log4net;
34using Nini.Config;
35using OpenMetaverse;
36using OpenSim.Framework;
37using OpenSim.Framework.Console;
38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes;
40using Timer=System.Timers.Timer;
41using Mono.Addins;
42
43namespace OpenSim.Region.CoreModules.World.Region
44{
45 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "RestartModule")]
46 public class RestartModule : INonSharedRegionModule, IRestartModule
47 {
48 private static readonly ILog m_log =
49 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
50
51 protected Scene m_Scene;
52 protected Timer m_CountdownTimer = null;
53 protected DateTime m_RestartBegin;
54 protected List<int> m_Alerts;
55 protected string m_Message;
56 protected UUID m_Initiator;
57 protected bool m_Notice = false;
58 protected IDialogModule m_DialogModule = null;
59
60 public void Initialise(IConfigSource config)
61 {
62 }
63
64 public void AddRegion(Scene scene)
65 {
66 m_Scene = scene;
67 scene.RegisterModuleInterface<IRestartModule>(this);
68 MainConsole.Instance.Commands.AddCommand("RestartModule",
69 false, "region restart bluebox",
70 "region restart bluebox <message> <time> ...",
71 "Restart the region", HandleRegionRestart);
72 MainConsole.Instance.Commands.AddCommand("RestartModule",
73 false, "region restart notice",
74 "region restart notice <message> <time> ...",
75 "Restart the region", HandleRegionRestart);
76 MainConsole.Instance.Commands.AddCommand("RestartModule",
77 false, "region restart abort",
78 "region restart abort [<message>]",
79 "Restart the region", HandleRegionRestart);
80 }
81
82 public void RegionLoaded(Scene scene)
83 {
84 m_DialogModule = m_Scene.RequestModuleInterface<IDialogModule>();
85 }
86
87 public void RemoveRegion(Scene scene)
88 {
89 }
90
91 public void Close()
92 {
93 }
94
95 public string Name
96 {
97 get { return "RestartModule"; }
98 }
99
100 public Type ReplaceableInterface
101 {
102 get { return typeof(IRestartModule); }
103 }
104
105 public TimeSpan TimeUntilRestart
106 {
107 get { return DateTime.Now - m_RestartBegin; }
108 }
109
110 public void ScheduleRestart(UUID initiator, string message, int[] alerts, bool notice)
111 {
112 if (m_CountdownTimer != null)
113 return;
114
115 if (alerts == null)
116 {
117 m_Scene.RestartNow();
118 return;
119 }
120
121 m_Message = message;
122 m_Initiator = initiator;
123 m_Notice = notice;
124 m_Alerts = new List<int>(alerts);
125 m_Alerts.Sort();
126 m_Alerts.Reverse();
127
128 if (m_Alerts[0] == 0)
129 {
130 m_Scene.RestartNow();
131 return;
132 }
133
134 int nextInterval = DoOneNotice();
135
136 SetTimer(nextInterval);
137 }
138
139 public int DoOneNotice()
140 {
141 if (m_Alerts.Count == 0 || m_Alerts[0] == 0)
142 {
143 m_Scene.RestartNow();
144 return 0;
145 }
146
147 int nextAlert = 0;
148 while (m_Alerts.Count > 1)
149 {
150 if (m_Alerts[1] == m_Alerts[0])
151 {
152 m_Alerts.RemoveAt(0);
153 continue;
154 }
155 nextAlert = m_Alerts[1];
156 break;
157 }
158
159 int currentAlert = m_Alerts[0];
160
161 m_Alerts.RemoveAt(0);
162
163 int minutes = currentAlert / 60;
164 string currentAlertString = String.Empty;
165 if (minutes > 0)
166 {
167 if (minutes == 1)
168 currentAlertString += "1 minute";
169 else
170 currentAlertString += String.Format("{0} minutes", minutes);
171 if ((currentAlert % 60) != 0)
172 currentAlertString += " and ";
173 }
174 if ((currentAlert % 60) != 0)
175 {
176 int seconds = currentAlert % 60;
177 if (seconds == 1)
178 currentAlertString += "1 second";
179 else
180 currentAlertString += String.Format("{0} seconds", seconds);
181 }
182
183 string msg = String.Format(m_Message, currentAlertString);
184
185 if (m_DialogModule != null && msg != String.Empty)
186 {
187 if (m_Notice)
188 m_DialogModule.SendGeneralAlert(msg);
189 else
190 m_DialogModule.SendNotificationToUsersInRegion(m_Initiator, "System", msg);
191 }
192
193 return currentAlert - nextAlert;
194 }
195
196 public void SetTimer(int intervalSeconds)
197 {
198 m_CountdownTimer = new Timer();
199 m_CountdownTimer.AutoReset = false;
200 m_CountdownTimer.Interval = intervalSeconds * 1000;
201 m_CountdownTimer.Elapsed += OnTimer;
202 m_CountdownTimer.Start();
203 }
204
205 private void OnTimer(object source, ElapsedEventArgs e)
206 {
207 int nextInterval = DoOneNotice();
208
209 SetTimer(nextInterval);
210 }
211
212 public void AbortRestart(string message)
213 {
214 if (m_CountdownTimer != null)
215 {
216 m_CountdownTimer.Stop();
217 m_CountdownTimer = null;
218 if (m_DialogModule != null && message != String.Empty)
219 m_DialogModule.SendGeneralAlert(message);
220 }
221 }
222
223 private void HandleRegionRestart(string module, string[] args)
224 {
225 if (!(MainConsole.Instance.ConsoleScene is Scene))
226 return;
227
228 if (MainConsole.Instance.ConsoleScene != m_Scene)
229 return;
230
231 if (args.Length < 5)
232 {
233 if (args.Length > 2)
234 {
235 if (args[2] == "abort")
236 {
237 string msg = String.Empty;
238 if (args.Length > 3)
239 msg = args[3];
240
241 AbortRestart(msg);
242
243 MainConsole.Instance.Output("Region restart aborted");
244 return;
245 }
246 }
247
248 MainConsole.Instance.Output("Error: restart region <mode> <name> <time> ...");
249 return;
250 }
251
252 bool notice = false;
253 if (args[2] == "notice")
254 notice = true;
255
256 List<int> times = new List<int>();
257 for (int i = 4 ; i < args.Length ; i++)
258 times.Add(Convert.ToInt32(args[i]));
259
260 ScheduleRestart(UUID.Zero, args[3], times.ToArray(), notice);
261 }
262 }
263}