aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment/Modules
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Environment/Modules/Avatar/Inventory/InventoryArchiveReadRequest.cs238
-rw-r--r--OpenSim/Region/Environment/Modules/Avatar/Inventory/InventoryArchiveWriteRequest.cs249
2 files changed, 487 insertions, 0 deletions
diff --git a/OpenSim/Region/Environment/Modules/Avatar/Inventory/InventoryArchiveReadRequest.cs b/OpenSim/Region/Environment/Modules/Avatar/Inventory/InventoryArchiveReadRequest.cs
new file mode 100644
index 0000000..5dbaa19
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/Avatar/Inventory/InventoryArchiveReadRequest.cs
@@ -0,0 +1,238 @@
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 OpenSim 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.Collections.Generic;
30using System.IO;
31using System.IO.Compression;
32using System.Reflection;
33using System.Xml;
34using OpenMetaverse;
35using OpenSim.Region.Environment.Scenes;
36using OpenSim.Region.Environment.Modules.World.Archiver;
37using OpenSim.Framework;
38using OpenSim.Framework.Communications;
39using OpenSim.Framework.Communications.Cache;
40using log4net;
41using OpenSim.Region.Environment.Modules.World.Serialiser;
42
43
44namespace OpenSim.Region.Environment.Modules.Avatar.Inventory
45{
46 public class InventoryArchiveReadRequest
47 {
48 protected Scene scene;
49 protected TarArchiveReader archive;
50 private static System.Text.ASCIIEncoding m_asciiEncoding = new System.Text.ASCIIEncoding();
51 ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
52 CachedUserInfo userInfo;
53 UserProfileData userProfile;
54 CommunicationsManager commsManager;
55 string loadPath;
56
57 public InventoryArchiveReadRequest(Scene currentScene, CommunicationsManager commsManager)
58 {
59 List<string> serialisedObjects = new List<string>();
60 scene = currentScene;
61 this.commsManager = commsManager;
62 }
63
64 protected InventoryItemBase loadInvItem(string path, string contents)
65 {
66 InventoryItemBase item = new InventoryItemBase();
67 StringReader sr = new StringReader(contents);
68 XmlTextReader reader = new XmlTextReader(sr);
69
70 if (contents.Equals("")) return null;
71
72 reader.ReadStartElement("InventoryObject");
73 reader.ReadStartElement("Name");
74 item.Name = reader.ReadString();
75 reader.ReadEndElement();
76 reader.ReadStartElement("ID");
77 item.ID = UUID.Parse(reader.ReadString());
78 reader.ReadEndElement();
79 reader.ReadStartElement("InvType");
80 item.InvType = System.Convert.ToInt32(reader.ReadString());
81 reader.ReadEndElement();
82 reader.ReadStartElement("CreatorUUID");
83 item.Creator = UUID.Parse(reader.ReadString());
84 item.Creator = userProfile.ID;
85 reader.ReadEndElement();
86 reader.ReadStartElement("CreationDate");
87 item.CreationDate = System.Convert.ToInt32(reader.ReadString());
88 reader.ReadEndElement();
89 reader.ReadStartElement("Owner");
90 item.Owner = UUID.Parse(reader.ReadString());
91 item.Owner = userProfile.ID;
92 reader.ReadEndElement();
93 //No description would kill it
94 if (reader.IsEmptyElement)
95 {
96 reader.ReadStartElement("Description");
97 }
98 else
99 {
100 reader.ReadStartElement("Description");
101 item.Description = reader.ReadString();
102 reader.ReadEndElement();
103 }
104 reader.ReadStartElement("AssetType");
105 item.AssetType = System.Convert.ToInt32(reader.ReadString());
106 reader.ReadEndElement();
107 reader.ReadStartElement("AssetID");
108 item.AssetID = UUID.Parse(reader.ReadString());
109 reader.ReadEndElement();
110 reader.ReadStartElement("SaleType");
111 item.SaleType = System.Convert.ToByte(reader.ReadString());
112 reader.ReadEndElement();
113 reader.ReadStartElement("SalePrice");
114 item.SalePrice = System.Convert.ToInt32(reader.ReadString());
115 reader.ReadEndElement();
116 reader.ReadStartElement("BasePermissions");
117 item.BasePermissions = System.Convert.ToUInt32(reader.ReadString());
118 reader.ReadEndElement();
119 reader.ReadStartElement("CurrentPermissions");
120 item.CurrentPermissions = System.Convert.ToUInt32(reader.ReadString());
121 reader.ReadEndElement();
122 reader.ReadStartElement("EveryOnePermssions");
123 item.EveryOnePermissions = System.Convert.ToUInt32(reader.ReadString());
124 reader.ReadEndElement();
125 reader.ReadStartElement("NextPermissions");
126 item.NextPermissions = System.Convert.ToUInt32(reader.ReadString());
127 reader.ReadEndElement();
128 reader.ReadStartElement("Flags");
129 item.Flags = System.Convert.ToUInt32(reader.ReadString());
130 reader.ReadEndElement();
131 reader.ReadStartElement("GroupID");
132 item.GroupID = UUID.Parse(reader.ReadString());
133 reader.ReadEndElement();
134 reader.ReadStartElement("GroupOwned");
135 item.GroupOwned = System.Convert.ToBoolean(reader.ReadString());
136 reader.ReadEndElement();
137 //reader.ReadStartElement("ParentFolderID");
138 //item.Folder = UUID.Parse(reader.ReadString());
139 //reader.ReadEndElement();
140 //reader.ReadEndElement();
141
142 return item;
143 }
144
145 public void execute(string[] cmdparams)
146 {
147 string filePath = "ERROR";
148 int successfulAssetRestores = 0;
149 int failedAssetRestores = 0;
150
151 string firstName = cmdparams[0];
152 string lastName = cmdparams[1];
153 string invPath = cmdparams[2];
154 loadPath = (cmdparams.Length > 3 ? cmdparams[3] : "inventory.tar.gz");
155
156 archive
157 = new TarArchiveReader(new GZipStream(
158 new FileStream(loadPath, FileMode.Open), CompressionMode.Decompress));
159
160
161 userProfile = commsManager.UserService.GetUserProfile(firstName, lastName);
162 userInfo = commsManager.UserProfileCacheService.GetUserDetails(userProfile.ID);
163
164 byte[] data;
165 while ((data = archive.ReadEntry(out filePath)) != null)
166 {
167 if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH))
168 {
169 if (LoadAsset(filePath, data))
170 successfulAssetRestores++;
171 else
172 failedAssetRestores++;
173 }
174 else
175 {
176 //Load the item
177 InventoryItemBase item = loadInvItem(filePath, m_asciiEncoding.GetString(data));
178 if (item != null) userInfo.AddItem(item);
179 }
180 }
181
182 archive.Close();
183
184 m_log.InfoFormat("[ARCHIVER]: Restored {0} assets", successfulAssetRestores);
185 }
186
187 /// <summary>
188 /// Load an asset
189 /// </summary>
190 /// <param name="assetFilename"></param>
191 /// <param name="data"></param>
192 /// <returns>true if asset was successfully loaded, false otherwise</returns>
193 private bool LoadAsset(string assetPath, byte[] data)
194 {
195 IRegionSerialiser serialiser = scene.RequestModuleInterface<IRegionSerialiser>();
196 // Right now we're nastily obtaining the UUID from the filename
197 string filename = assetPath.Remove(0, ArchiveConstants.ASSETS_PATH.Length);
198 int i = filename.LastIndexOf(ArchiveConstants.ASSET_EXTENSION_SEPARATOR);
199
200 if (i == -1)
201 {
202 m_log.ErrorFormat(
203 "[ARCHIVER]: Could not find extension information in asset path {0} since it's missing the separator {1}. Skipping",
204 assetPath, ArchiveConstants.ASSET_EXTENSION_SEPARATOR);
205
206 return false;
207 }
208
209 string extension = filename.Substring(i);
210 string uuid = filename.Remove(filename.Length - extension.Length);
211
212 if (ArchiveConstants.EXTENSION_TO_ASSET_TYPE.ContainsKey(extension))
213 {
214 sbyte assetType = ArchiveConstants.EXTENSION_TO_ASSET_TYPE[extension];
215
216 m_log.DebugFormat("[ARCHIVER]: Importing asset {0}, type {1}", uuid, assetType);
217
218 AssetBase asset = new AssetBase(new UUID(uuid), "RandomName");
219
220 asset.Type = assetType;
221 asset.Data = data;
222
223 scene.AssetCache.AddAsset(asset);
224
225
226 return true;
227 }
228 else
229 {
230 m_log.ErrorFormat(
231 "[ARCHIVER]: Tried to dearchive data with path {0} with an unknown type extension {1}",
232 assetPath, extension);
233
234 return false;
235 }
236 }
237 }
238} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/Avatar/Inventory/InventoryArchiveWriteRequest.cs b/OpenSim/Region/Environment/Modules/Avatar/Inventory/InventoryArchiveWriteRequest.cs
new file mode 100644
index 0000000..45b2dd6
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/Avatar/Inventory/InventoryArchiveWriteRequest.cs
@@ -0,0 +1,249 @@
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 OpenSim 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.Collections.Generic;
30using System.IO;
31using System.IO.Compression;
32using System.Reflection;
33using System.Xml;
34using OpenMetaverse;
35using OpenSim.Region.Environment.Scenes;
36using OpenSim.Region.Environment.Modules.World.Archiver;
37using OpenSim.Framework;
38using OpenSim.Framework.Communications;
39using OpenSim.Framework.Communications.Cache;
40using log4net;
41
42
43namespace OpenSim.Region.Environment.Modules.Avatar.Inventory
44{
45 public class InventoryArchiveWriteRequest
46 {
47 protected Scene scene;
48 protected TarArchiveWriter archive;
49 protected CommunicationsManager commsManager;
50 Dictionary<UUID, int> assetUuids;
51 string savePath;
52
53
54 public InventoryArchiveWriteRequest(Scene currentScene, CommunicationsManager commsManager)
55 {
56 scene = currentScene;
57 archive = new TarArchiveWriter();
58 this.commsManager = commsManager;
59 assetUuids = new Dictionary<UUID, int>();
60 }
61
62 protected void ReceivedAllAssets(IDictionary<UUID, AssetBase> assetsFound, ICollection<UUID> assetsNotFoundUuids)
63 {
64 AssetsArchiver assetsArchiver = new AssetsArchiver(assetsFound);
65 assetsArchiver.Archive(archive);
66 archive.WriteTar(new GZipStream(new FileStream(savePath, FileMode.Create), CompressionMode.Compress));
67 }
68
69 protected void saveInvItem(InventoryItemBase inventoryItem, string path)
70 {
71 string filename
72 = string.Format("{0}{1}_{2}.xml",
73 path, inventoryItem.Name, inventoryItem.ID);
74 StringWriter sw = new StringWriter();
75 XmlTextWriter writer = new XmlTextWriter(sw);
76 writer.WriteStartElement("InventoryObject");
77 writer.WriteStartElement("Name");
78 writer.WriteString(inventoryItem.Name);
79 writer.WriteEndElement();
80 writer.WriteStartElement("ID");
81 writer.WriteString(inventoryItem.ID.ToString());
82 writer.WriteEndElement();
83 writer.WriteStartElement("InvType");
84 writer.WriteString(inventoryItem.InvType.ToString());
85 writer.WriteEndElement();
86 writer.WriteStartElement("CreatorUUID");
87 writer.WriteString(inventoryItem.Creator.ToString());
88 writer.WriteEndElement();
89 writer.WriteStartElement("CreationDate");
90 writer.WriteString(inventoryItem.CreationDate.ToString());
91 writer.WriteEndElement();
92 writer.WriteStartElement("Owner");
93 writer.WriteString(inventoryItem.Owner.ToString());
94 writer.WriteEndElement();
95 writer.WriteStartElement("Description");
96 if (inventoryItem.Description.Length > 0)
97 writer.WriteString(inventoryItem.Description);
98 else writer.WriteString("No Description");
99 writer.WriteEndElement();
100 writer.WriteStartElement("AssetType");
101 writer.WriteString(inventoryItem.AssetType.ToString());
102 writer.WriteEndElement();
103 writer.WriteStartElement("AssetID");
104 writer.WriteString(inventoryItem.AssetID.ToString());
105 writer.WriteEndElement();
106 writer.WriteStartElement("SaleType");
107 writer.WriteString(inventoryItem.SaleType.ToString());
108 writer.WriteEndElement();
109 writer.WriteStartElement("SalePrice");
110 writer.WriteString(inventoryItem.SalePrice.ToString());
111 writer.WriteEndElement();
112 writer.WriteStartElement("BasePermissions");
113 writer.WriteString(inventoryItem.BasePermissions.ToString());
114 writer.WriteEndElement();
115 writer.WriteStartElement("CurrentPermissions");
116 writer.WriteString(inventoryItem.CurrentPermissions.ToString());
117 writer.WriteEndElement();
118 writer.WriteStartElement("EveryOnePermssions");
119 writer.WriteString(inventoryItem.EveryOnePermissions.ToString());
120 writer.WriteEndElement();
121 writer.WriteStartElement("NextPermissions");
122 writer.WriteString(inventoryItem.NextPermissions.ToString());
123 writer.WriteEndElement();
124 writer.WriteStartElement("Flags");
125 writer.WriteString(inventoryItem.Flags.ToString());
126 writer.WriteEndElement();
127 writer.WriteStartElement("GroupID");
128 writer.WriteString(inventoryItem.GroupID.ToString());
129 writer.WriteEndElement();
130 writer.WriteStartElement("GroupOwned");
131 writer.WriteString(inventoryItem.GroupOwned.ToString());
132 writer.WriteEndElement();
133 writer.WriteStartElement("ParentFolderID");
134 writer.WriteString(inventoryItem.Folder.ToString());
135 writer.WriteEndElement();
136 writer.WriteEndElement();
137
138 archive.AddFile(filename, sw.ToString());
139
140 assetUuids[inventoryItem.AssetID] = 1;
141 }
142
143 protected void saveInvDir(InventoryFolderImpl inventoryFolder, string path)
144 {
145 List<InventoryFolderImpl> inventories = inventoryFolder.RequestListOfFolderImpls();
146 List<InventoryItemBase> items = inventoryFolder.RequestListOfItems();
147 string newPath = path + inventoryFolder.Name + InventoryFolderImpl.PATH_DELIMITER;
148 archive.AddDir(newPath);
149 foreach (InventoryFolderImpl folder in inventories)
150 {
151 saveInvDir(folder, newPath);
152 }
153 foreach (InventoryItemBase item in items)
154 {
155 saveInvItem(item, newPath);
156 }
157 }
158
159 public void execute(string[] cmdparams)
160 {
161 ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
162
163 string firstName = cmdparams[0];
164 string lastName = cmdparams[1];
165 string invPath = cmdparams[2];
166 savePath = (cmdparams.Length > 3 ? cmdparams[3] : "inventory.tar.gz");
167
168 UserProfileData userProfile = commsManager.UserService.GetUserProfile(firstName, lastName);
169 if (null == userProfile)
170 {
171 m_log.ErrorFormat("[CONSOLE]: Failed to find user {0} {1}", firstName, lastName);
172 return;
173 }
174
175 CachedUserInfo userInfo = commsManager.UserProfileCacheService.GetUserDetails(userProfile.ID);
176 if (null == userInfo)
177 {
178 m_log.ErrorFormat("[CONSOLE]: Failed to find user info for {0} {1} {2}", firstName, lastName, userProfile.ID);
179 return;
180 }
181
182 InventoryFolderImpl inventoryFolder = null;
183 InventoryItemBase inventoryItem = null;
184
185 if (userInfo.HasReceivedInventory)
186 {
187 // Eliminate double slashes and any leading / on the path. This might be better done within InventoryFolderImpl
188 // itself (possibly at a small loss in efficiency).
189 string[] components
190 = invPath.Split(new string[] { InventoryFolderImpl.PATH_DELIMITER }, StringSplitOptions.RemoveEmptyEntries);
191 invPath = String.Empty;
192 foreach (string c in components)
193 {
194 invPath += c + InventoryFolderImpl.PATH_DELIMITER;
195 }
196
197 // Annoyingly Split actually returns the original string if the input string consists only of delimiters
198 // Therefore if we still start with a / after the split, then we need the root folder
199 if (invPath.Length == 0)
200 {
201 inventoryFolder = userInfo.RootFolder;
202 }
203 else
204 {
205 invPath = invPath.Remove(invPath.LastIndexOf(InventoryFolderImpl.PATH_DELIMITER));
206 inventoryFolder = userInfo.RootFolder.FindFolderByPath(invPath);
207 }
208
209 // The path may point to an item instead
210 if (inventoryFolder == null)
211 {
212 inventoryItem = userInfo.RootFolder.FindItemByPath(invPath);
213 }
214 }
215 else
216 {
217 m_log.ErrorFormat("[CONSOLE]: Have not yet received inventory info for user {0} {1} {2}", firstName, lastName, userProfile.ID);
218 return;
219 }
220
221 if (null == inventoryFolder)
222 {
223 if (null == inventoryItem)
224 {
225 m_log.ErrorFormat("[CONSOLE]: Could not find inventory entry at path {0}", invPath);
226 return;
227 }
228 else
229 {
230 m_log.InfoFormat("[CONSOLE]: Found item {0} {1} at {2}", inventoryItem.Name, inventoryItem.ID,
231 invPath);
232 //get and export item info
233 saveInvItem(inventoryItem, invPath);
234 }
235 }
236 else
237 {
238 m_log.InfoFormat("[CONSOLE]: Found folder {0} {1} at {2}", inventoryFolder.Name, inventoryFolder.ID,
239 invPath);
240 //recurse through all dirs getting dirs and files
241 saveInvDir(inventoryFolder, "");
242 }
243
244 new AssetsRequest(assetUuids.Keys, scene.AssetCache, ReceivedAllAssets).Execute();
245
246 }
247
248 }
249} \ No newline at end of file