corrade-vassal – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 vero 1 /*
2 * Copyright (c) 2006-2014, openmetaverse.org
3 * All rights reserved.
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 *
8 * - Redistributions of source code must retain the above copyright notice, this
9 * list of conditions and the following disclaimer.
10 * - Neither the name of the openmetaverse.org nor the names
11 * of its contributors may be used to endorse or promote products derived from
12 * this software without specific prior written permission.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 * POSSIBILITY OF SUCH DAMAGE.
25 */
26  
27 using System;
28 using System.Collections.Generic;
29 using System.Text;
30 using System.Text.RegularExpressions;
31 using OpenMetaverse;
32  
33 namespace OpenMetaverse.Assets
34 {
35 /// <summary>
36 /// Represents a string of characters encoded with specific formatting properties
37 /// </summary>
38 public class AssetNotecard : Asset
39 {
40 /// <summary>Override the base classes AssetType</summary>
41 public override AssetType AssetType { get { return AssetType.Notecard; } }
42  
43 /// <summary>A text string containing main text of the notecard</summary>
44 public string BodyText;
45  
46 /// <summary>List of <see cref="OpenMetaverse.InventoryItem"/>s embedded on the notecard</summary>
47 public List<InventoryItem> EmbeddedItems;
48  
49 /// <summary>Construct an Asset of type Notecard</summary>
50 public AssetNotecard() { }
51  
52 /// <summary>
53 /// Construct an Asset object of type Notecard
54 /// </summary>
55 /// <param name="assetID">A unique <see cref="UUID"/> specific to this asset</param>
56 /// <param name="assetData">A byte array containing the raw asset data</param>
57 public AssetNotecard(UUID assetID, byte[] assetData)
58 : base(assetID, assetData)
59 {
60 }
61  
62 /// <summary>
63 /// Encode the raw contents of a string with the specific Linden Text properties
64 /// </summary>
65 public override void Encode()
66 {
67 string body = BodyText ?? String.Empty;
68  
69 StringBuilder output = new StringBuilder();
70 output.Append("Linden text version 2\n");
71 output.Append("{\n");
72 output.Append("LLEmbeddedItems version 1\n");
73 output.Append("{\n");
74  
75 int count = 0;
76  
77 if (EmbeddedItems != null)
78 {
79 count = EmbeddedItems.Count;
80 }
81  
82 output.Append("count " + count + "\n");
83  
84 if (count > 0)
85 {
86 output.Append("{\n");
87  
88 for (int i = 0; i < EmbeddedItems.Count; i++)
89 {
90 InventoryItem item = EmbeddedItems[i];
91  
92 output.Append("ext char index " + i + "\n");
93  
94 output.Append("\tinv_item\t0\n");
95 output.Append("\t{\n");
96  
97 output.Append("\t\titem_id\t" + item.UUID + "\n");
98 output.Append("\t\tparent_id\t" + item.ParentUUID + "\n");
99  
100 output.Append("\tpermissions 0\n");
101 output.Append("\t{\n");
102 output.Append("\t\tbase_mask\t" + ((uint)item.Permissions.BaseMask).ToString("x").PadLeft(8, '0') + "\n");
103 output.Append("\t\towner_mask\t" + ((uint)item.Permissions.OwnerMask).ToString("x").PadLeft(8, '0') + "\n");
104 output.Append("\t\tgroup_mask\t" + ((uint)item.Permissions.GroupMask).ToString("x").PadLeft(8, '0') + "\n");
105 output.Append("\t\teveryone_mask\t" + ((uint)item.Permissions.EveryoneMask).ToString("x").PadLeft(8, '0') + "\n");
106 output.Append("\t\tnext_owner_mask\t" + ((uint)item.Permissions.NextOwnerMask).ToString("x").PadLeft(8, '0') + "\n");
107 output.Append("\t\tcreator_id\t" + item.CreatorID + "\n");
108 output.Append("\t\towner_id\t" + item.OwnerID + "\n");
109 output.Append("\t\tlast_owner_id\t" + item.LastOwnerID + "\n");
110 output.Append("\t\tgroup_id\t" + item.GroupID + "\n");
111 if (item.GroupOwned) output.Append("\t\tgroup_owned\t1\n");
112 output.Append("\t}\n");
113  
114 if (Permissions.HasPermissions(item.Permissions.BaseMask, PermissionMask.Modify | PermissionMask.Copy | PermissionMask.Transfer) ||
115 item.AssetUUID == UUID.Zero)
116 {
117 output.Append("\t\tasset_id\t" + item.AssetUUID + "\n");
118 }
119 else
120 {
121 output.Append("\t\tshadow_id\t" + InventoryManager.EncryptAssetID(item.AssetUUID) + "\n");
122 }
123  
124 output.Append("\t\ttype\t" + Utils.AssetTypeToString(item.AssetType) + "\n");
125 output.Append("\t\tinv_type\t" + Utils.InventoryTypeToString(item.InventoryType) + "\n");
126 output.Append("\t\tflags\t" + item.Flags.ToString().PadLeft(8, '0') + "\n");
127  
128 output.Append("\tsale_info\t0\n");
129 output.Append("\t{\n");
130 output.Append("\t\tsale_type\t" + Utils.SaleTypeToString(item.SaleType) + "\n");
131 output.Append("\t\tsale_price\t" + item.SalePrice + "\n");
132 output.Append("\t}\n");
133  
134 output.Append("\t\tname\t" + item.Name.Replace('|', '_') + "|\n");
135 output.Append("\t\tdesc\t" + item.Description.Replace('|', '_') + "|\n");
136 output.Append("\t\tcreation_date\t" + Utils.DateTimeToUnixTime(item.CreationDate) + "\n");
137  
138 output.Append("\t}\n");
139  
140 if (i != EmbeddedItems.Count - 1)
141 {
142 output.Append("}\n{\n");
143 }
144 }
145  
146 output.Append("}\n");
147 }
148  
149 output.Append("}\n");
150 output.Append("Text length " + (Utils.StringToBytes(body).Length - 1).ToString() + "\n");
151 output.Append(body + "}\n");
152  
153 AssetData = Utils.StringToBytes(output.ToString());
154 }
155  
156 /// <summary>
157 /// Decode the raw asset data including the Linden Text properties
158 /// </summary>
159 /// <returns>true if the AssetData was successfully decoded</returns>
160 public override bool Decode()
161 {
162 string data = Utils.BytesToString(AssetData);
163 EmbeddedItems = new List<InventoryItem>();
164 BodyText = string.Empty;
165  
166 try
167 {
168 string[] lines = data.Split('\n');
169 int i = 0;
170 Match m;
171  
172 // Version
173 if (!(m = Regex.Match(lines[i++], @"Linden text version\s+(\d+)")).Success)
174 throw new Exception("could not determine version");
175 int notecardVersion = int.Parse(m.Groups[1].Value);
176 if (notecardVersion < 1 || notecardVersion > 2)
177 throw new Exception("unsuported version");
178 if (!(m = Regex.Match(lines[i++], @"\s*{$")).Success)
179 throw new Exception("wrong format");
180  
181 // Embedded items header
182 if (!(m = Regex.Match(lines[i++], @"LLEmbeddedItems version\s+(\d+)")).Success)
183 throw new Exception("could not determine embedded items version version");
184 if (m.Groups[1].Value != "1")
185 throw new Exception("unsuported embedded item version");
186 if (!(m = Regex.Match(lines[i++], @"\s*{$")).Success)
187 throw new Exception("wrong format");
188  
189 // Item count
190 if (!(m = Regex.Match(lines[i++], @"count\s+(\d+)")).Success)
191 throw new Exception("wrong format");
192 int count = int.Parse(m.Groups[1].Value);
193  
194 // Decode individual items
195 for (int n = 0; n < count; n++)
196 {
197 if (!(m = Regex.Match(lines[i++], @"\s*{$")).Success)
198 throw new Exception("wrong format");
199  
200 // Index
201 if (!(m = Regex.Match(lines[i++], @"ext char index\s+(\d+)")).Success)
202 throw new Exception("missing ext char index");
203 //warning CS0219: The variable `index' is assigned but its value is never used
204 //int index = int.Parse(m.Groups[1].Value);
205  
206 // Inventory item
207 if (!(m = Regex.Match(lines[i++], @"inv_item\s+0")).Success)
208 throw new Exception("missing inv item");
209  
210 // Item itself
211 UUID uuid = UUID.Zero;
212 UUID creatorID = UUID.Zero;
213 UUID ownerID = UUID.Zero;
214 UUID lastOwnerID = UUID.Zero;
215 UUID groupID = UUID.Zero;
216 Permissions permissions = Permissions.NoPermissions;
217 int salePrice = 0;
218 SaleType saleType = SaleType.Not;
219 UUID parentUUID = UUID.Zero;
220 UUID assetUUID = UUID.Zero;
221 AssetType assetType = AssetType.Unknown;
222 InventoryType inventoryType = InventoryType.Unknown;
223 uint flags = 0;
224 string name = string.Empty;
225 string description = string.Empty;
226 DateTime creationDate = Utils.Epoch;
227  
228 while (true)
229 {
230 if (!(m = Regex.Match(lines[i++], @"([^\s]+)(\s+)?(.*)?")).Success)
231 throw new Exception("wrong format");
232 string key = m.Groups[1].Value;
233 string val = m.Groups[3].Value;
234 if (key == "{")
235 continue;
236 if (key == "}")
237 break;
238 else if (key == "permissions")
239 {
240 uint baseMask = 0;
241 uint ownerMask = 0;
242 uint groupMask = 0;
243 uint everyoneMask = 0;
244 uint nextOwnerMask = 0;
245  
246 while (true)
247 {
248 if (!(m = Regex.Match(lines[i++], @"([^\s]+)(\s+)?([^\s]+)?")).Success)
249 throw new Exception("wrong format");
250 string pkey = m.Groups[1].Value;
251 string pval = m.Groups[3].Value;
252  
253 if (pkey == "{")
254 continue;
255 if (pkey == "}")
256 break;
257 else if (pkey == "creator_id")
258 {
259 creatorID = new UUID(pval);
260 }
261 else if (pkey == "owner_id")
262 {
263 ownerID = new UUID(pval);
264 }
265 else if (pkey == "last_owner_id")
266 {
267 lastOwnerID = new UUID(pval);
268 }
269 else if (pkey == "group_id")
270 {
271 groupID = new UUID(pval);
272 }
273 else if (pkey == "base_mask")
274 {
275 baseMask = uint.Parse(pval, System.Globalization.NumberStyles.AllowHexSpecifier);
276 }
277 else if (pkey == "owner_mask")
278 {
279 ownerMask = uint.Parse(pval, System.Globalization.NumberStyles.AllowHexSpecifier);
280 }
281 else if (pkey == "group_mask")
282 {
283 groupMask = uint.Parse(pval, System.Globalization.NumberStyles.AllowHexSpecifier);
284 }
285 else if (pkey == "everyone_mask")
286 {
287 everyoneMask = uint.Parse(pval, System.Globalization.NumberStyles.AllowHexSpecifier);
288 }
289 else if (pkey == "next_owner_mask")
290 {
291 nextOwnerMask = uint.Parse(pval, System.Globalization.NumberStyles.AllowHexSpecifier);
292 }
293 }
294 permissions = new Permissions(baseMask, everyoneMask, groupMask, nextOwnerMask, ownerMask);
295 }
296 else if (key == "sale_info")
297 {
298 while (true)
299 {
300 if (!(m = Regex.Match(lines[i++], @"([^\s]+)(\s+)?([^\s]+)?")).Success)
301 throw new Exception("wrong format");
302 string pkey = m.Groups[1].Value;
303 string pval = m.Groups[3].Value;
304  
305 if (pkey == "{")
306 continue;
307 if (pkey == "}")
308 break;
309 else if (pkey == "sale_price")
310 {
311 salePrice = int.Parse(pval);
312 }
313 else if (pkey == "sale_type")
314 {
315 saleType = Utils.StringToSaleType(pval);
316 }
317 }
318 }
319 else if (key == "item_id")
320 {
321 uuid = new UUID(val);
322 }
323 else if (key == "parent_id")
324 {
325 parentUUID = new UUID(val);
326 }
327 else if (key == "asset_id")
328 {
329 assetUUID = new UUID(val);
330 }
331 else if (key == "type")
332 {
333 assetType = Utils.StringToAssetType(val);
334 }
335 else if (key == "inv_type")
336 {
337 inventoryType = Utils.StringToInventoryType(val);
338 }
339 else if (key == "flags")
340 {
341 flags = uint.Parse(val, System.Globalization.NumberStyles.AllowHexSpecifier);
342 }
343 else if (key == "name")
344 {
345 name = val.Remove(val.LastIndexOf("|"));
346 }
347 else if (key == "desc")
348 {
349 description = val.Remove(val.LastIndexOf("|"));
350 }
351 else if (key == "creation_date")
352 {
353 creationDate = Utils.UnixTimeToDateTime(int.Parse(val));
354 }
355 }
356 InventoryItem finalEmbedded = InventoryManager.CreateInventoryItem(inventoryType, uuid);
357  
358 finalEmbedded.CreatorID = creatorID;
359 finalEmbedded.OwnerID = ownerID;
360 finalEmbedded.LastOwnerID = lastOwnerID;
361 finalEmbedded.GroupID = groupID;
362 finalEmbedded.Permissions = permissions;
363 finalEmbedded.SalePrice = salePrice;
364 finalEmbedded.SaleType = saleType;
365 finalEmbedded.ParentUUID = parentUUID;
366 finalEmbedded.AssetUUID = assetUUID;
367 finalEmbedded.AssetType = assetType;
368 finalEmbedded.Flags = flags;
369 finalEmbedded.Name = name;
370 finalEmbedded.Description = description;
371 finalEmbedded.CreationDate = creationDate;
372  
373 EmbeddedItems.Add(finalEmbedded);
374  
375 if (!(m = Regex.Match(lines[i++], @"\s*}$")).Success)
376 throw new Exception("wrong format");
377  
378 }
379  
380 // Text size
381 if (!(m = Regex.Match(lines[i++], @"\s*}$")).Success)
382 throw new Exception("wrong format");
383 if (!(m = Regex.Match(lines[i++], @"Text length\s+(\d+)")).Success)
384 throw new Exception("could not determine text length");
385  
386 // Read the rest of the notecard
387 while (i < lines.Length)
388 {
389 BodyText += lines[i++] + "\n";
390 }
391 BodyText = BodyText.Remove(BodyText.LastIndexOf("}"));
392 return true;
393 }
394 catch (Exception ex)
395 {
396 Logger.Log("Decoding notecard asset failed: " + ex.Message, Helpers.LogLevel.Error);
397 return false;
398 }
399 }
400 }
401 }