aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
authorMelanie2011-05-20 22:38:05 +0100
committerMelanie2011-05-20 22:38:05 +0100
commite62d1cc480ef98be5621ed809c2dd7f1e8d16dd9 (patch)
tree746085bf27044b477fc4552228b14388565421ec /OpenSim
parentIf a response cannot be obtained (the script has no handler) return a more fr... (diff)
parentImplement llGetLinKNumberOfSides(). (diff)
downloadopensim-SC_OLD-e62d1cc480ef98be5621ed809c2dd7f1e8d16dd9.zip
opensim-SC_OLD-e62d1cc480ef98be5621ed809c2dd7f1e8d16dd9.tar.gz
opensim-SC_OLD-e62d1cc480ef98be5621ed809c2dd7f1e8d16dd9.tar.bz2
opensim-SC_OLD-e62d1cc480ef98be5621ed809c2dd7f1e8d16dd9.tar.xz
Merge branch 'master' into careminster-presence-refactor
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/Data/IXInventoryData.cs29
-rw-r--r--OpenSim/Data/MSSQL/MSSQLGenericTableHandler.cs35
-rw-r--r--OpenSim/Data/MSSQL/MSSQLXInventoryData.cs10
-rw-r--r--OpenSim/Data/MySQL/MySQLGenericTableHandler.cs27
-rw-r--r--OpenSim/Data/MySQL/MySQLXInventoryData.cs10
-rw-r--r--OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs28
-rw-r--r--OpenSim/Data/SQLite/SQLiteXInventoryData.cs10
-rw-r--r--OpenSim/Framework/WebUtil.cs8
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs5
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs2
-rw-r--r--OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModule.cs11
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs16
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs6
-rw-r--r--OpenSim/Services/InventoryService/XInventoryService.cs34
14 files changed, 186 insertions, 45 deletions
diff --git a/OpenSim/Data/IXInventoryData.cs b/OpenSim/Data/IXInventoryData.cs
index d85a7ef..85a5c08 100644
--- a/OpenSim/Data/IXInventoryData.cs
+++ b/OpenSim/Data/IXInventoryData.cs
@@ -74,9 +74,38 @@ namespace OpenSim.Data
74 bool StoreFolder(XInventoryFolder folder); 74 bool StoreFolder(XInventoryFolder folder);
75 bool StoreItem(XInventoryItem item); 75 bool StoreItem(XInventoryItem item);
76 76
77 /// <summary>
78 /// Delete folders where field == val
79 /// </summary>
80 /// <param name="field"></param>
81 /// <param name="val"></param>
82 /// <returns>true if the delete was successful, false if it was not</returns>
77 bool DeleteFolders(string field, string val); 83 bool DeleteFolders(string field, string val);
84
85 /// <summary>
86 /// Delete folders where field1 == val1, field2 == val2...
87 /// </summary>
88 /// <param name="fields"></param>
89 /// <param name="vals"></param>
90 /// <returns>true if the delete was successful, false if it was not</returns>
91 bool DeleteFolders(string[] fields, string[] vals);
92
93 /// <summary>
94 /// Delete items where field == val
95 /// </summary>
96 /// <param name="field"></param>
97 /// <param name="val"></param>
98 /// <returns>true if the delete was successful, false if it was not</returns>
78 bool DeleteItems(string field, string val); 99 bool DeleteItems(string field, string val);
79 100
101 /// <summary>
102 /// Delete items where field1 == val1, field2 == val2...
103 /// </summary>
104 /// <param name="fields"></param>
105 /// <param name="vals"></param>
106 /// <returns>true if the delete was successful, false if it was not</returns>
107 bool DeleteItems(string[] fields, string[] vals);
108
80 bool MoveItem(string id, string newParent); 109 bool MoveItem(string id, string newParent);
81 XInventoryItem[] GetActiveGestures(UUID principalID); 110 XInventoryItem[] GetActiveGestures(UUID principalID);
82 int GetAssetPermissions(UUID principalID, UUID assetID); 111 int GetAssetPermissions(UUID principalID, UUID assetID);
diff --git a/OpenSim/Data/MSSQL/MSSQLGenericTableHandler.cs b/OpenSim/Data/MSSQL/MSSQLGenericTableHandler.cs
index 19e8fa6..6e695ce 100644
--- a/OpenSim/Data/MSSQL/MSSQLGenericTableHandler.cs
+++ b/OpenSim/Data/MSSQL/MSSQLGenericTableHandler.cs
@@ -335,24 +335,35 @@ namespace OpenSim.Data.MSSQL
335 } 335 }
336 } 336 }
337 337
338 public virtual bool Delete(string field, string val) 338 public virtual bool Delete(string field, string key)
339 { 339 {
340 return Delete(new string[] { field }, new string[] { key });
341 }
342
343 public virtual bool Delete(string[] fields, string[] keys)
344 {
345 if (fields.Length != keys.Length)
346 return false;
347
348 List<string> terms = new List<string>();
349
340 using (SqlConnection conn = new SqlConnection(m_ConnectionString)) 350 using (SqlConnection conn = new SqlConnection(m_ConnectionString))
341 using (SqlCommand cmd = new SqlCommand()) 351 using (SqlCommand cmd = new SqlCommand())
342 { 352 {
343 string deleteCommand = String.Format("DELETE FROM {0} WHERE [{1}] = @{1}", m_Realm, field); 353 for (int i = 0; i < fields.Length; i++)
344 cmd.CommandText = deleteCommand;
345
346 cmd.Parameters.Add(m_database.CreateParameter(field, val));
347 cmd.Connection = conn;
348 conn.Open();
349
350 if (cmd.ExecuteNonQuery() > 0)
351 { 354 {
352 //m_log.Warn("[MSSQLGenericTable]: " + deleteCommand); 355 cmd.Parameters.Add(m_database.CreateParameter(fields[i], keys[i]));
353 return true; 356 terms.Add("[" + fields[i] + "] = @" + fields[i]);
354 } 357 }
355 return false; 358
359 string where = String.Join(" AND ", terms.ToArray());
360
361 string query = String.Format("DELETE * FROM {0} WHERE {1}", m_Realm, where);
362
363 cmd.Connection = conn;
364 cmd.CommandText = query;
365 conn.Open();
366 return cmd.ExecuteNonQuery() > 0;
356 } 367 }
357 } 368 }
358 } 369 }
diff --git a/OpenSim/Data/MSSQL/MSSQLXInventoryData.cs b/OpenSim/Data/MSSQL/MSSQLXInventoryData.cs
index 739eb55..dc35a2e 100644
--- a/OpenSim/Data/MSSQL/MSSQLXInventoryData.cs
+++ b/OpenSim/Data/MSSQL/MSSQLXInventoryData.cs
@@ -79,11 +79,21 @@ namespace OpenSim.Data.MSSQL
79 return m_Folders.Delete(field, val); 79 return m_Folders.Delete(field, val);
80 } 80 }
81 81
82 public bool DeleteFolders(string[] fields, string[] vals)
83 {
84 return m_Folders.Delete(fields, vals);
85 }
86
82 public bool DeleteItems(string field, string val) 87 public bool DeleteItems(string field, string val)
83 { 88 {
84 return m_Items.Delete(field, val); 89 return m_Items.Delete(field, val);
85 } 90 }
86 91
92 public bool DeleteItems(string[] fields, string[] vals)
93 {
94 return m_Items.Delete(fields, vals);
95 }
96
87 public bool MoveItem(string id, string newParent) 97 public bool MoveItem(string id, string newParent)
88 { 98 {
89 return m_Items.MoveItem(id, newParent); 99 return m_Items.MoveItem(id, newParent);
diff --git a/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs
index cfffbd8..754cf72 100644
--- a/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs
+++ b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs
@@ -264,18 +264,33 @@ namespace OpenSim.Data.MySQL
264 } 264 }
265 } 265 }
266 266
267 public virtual bool Delete(string field, string val) 267 public virtual bool Delete(string field, string key)
268 { 268 {
269 return Delete(new string[] { field }, new string[] { key });
270 }
271
272 public virtual bool Delete(string[] fields, string[] keys)
273 {
274 if (fields.Length != keys.Length)
275 return false;
276
277 List<string> terms = new List<string>();
278
269 using (MySqlCommand cmd = new MySqlCommand()) 279 using (MySqlCommand cmd = new MySqlCommand())
270 { 280 {
281 for (int i = 0 ; i < fields.Length ; i++)
282 {
283 cmd.Parameters.AddWithValue(fields[i], keys[i]);
284 terms.Add("`" + fields[i] + "` = ?" + fields[i]);
285 }
271 286
272 cmd.CommandText = String.Format("delete from {0} where `{1}` = ?{1}", m_Realm, field); 287 string where = String.Join(" and ", terms.ToArray());
273 cmd.Parameters.AddWithValue(field, val);
274 288
275 if (ExecuteNonQuery(cmd) > 0) 289 string query = String.Format("delete from {0} where {1}", m_Realm, where);
276 return true;
277 290
278 return false; 291 cmd.CommandText = query;
292
293 return ExecuteNonQuery(cmd) > 0;
279 } 294 }
280 } 295 }
281 } 296 }
diff --git a/OpenSim/Data/MySQL/MySQLXInventoryData.cs b/OpenSim/Data/MySQL/MySQLXInventoryData.cs
index 481da49..caf18a4 100644
--- a/OpenSim/Data/MySQL/MySQLXInventoryData.cs
+++ b/OpenSim/Data/MySQL/MySQLXInventoryData.cs
@@ -85,11 +85,21 @@ namespace OpenSim.Data.MySQL
85 return m_Folders.Delete(field, val); 85 return m_Folders.Delete(field, val);
86 } 86 }
87 87
88 public bool DeleteFolders(string[] fields, string[] vals)
89 {
90 return m_Folders.Delete(fields, vals);
91 }
92
88 public bool DeleteItems(string field, string val) 93 public bool DeleteItems(string field, string val)
89 { 94 {
90 return m_Items.Delete(field, val); 95 return m_Items.Delete(field, val);
91 } 96 }
92 97
98 public bool DeleteItems(string[] fields, string[] vals)
99 {
100 return m_Items.Delete(fields, vals);
101 }
102
93 public bool MoveItem(string id, string newParent) 103 public bool MoveItem(string id, string newParent)
94 { 104 {
95 return m_Items.MoveItem(id, newParent); 105 return m_Items.MoveItem(id, newParent);
diff --git a/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs b/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs
index 0d7b001..3fb2d3f 100644
--- a/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs
+++ b/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs
@@ -258,17 +258,33 @@ namespace OpenSim.Data.SQLite
258 return false; 258 return false;
259 } 259 }
260 260
261 public bool Delete(string field, string val) 261 public virtual bool Delete(string field, string key)
262 { 262 {
263 return Delete(new string[] { field }, new string[] { key });
264 }
265
266 public bool Delete(string[] fields, string[] keys)
267 {
268 if (fields.Length != keys.Length)
269 return false;
270
271 List<string> terms = new List<string>();
272
263 SqliteCommand cmd = new SqliteCommand(); 273 SqliteCommand cmd = new SqliteCommand();
264 274
265 cmd.CommandText = String.Format("delete from {0} where `{1}` = :{1}", m_Realm, field); 275 for (int i = 0 ; i < fields.Length ; i++)
266 cmd.Parameters.Add(new SqliteParameter(field, val)); 276 {
277 cmd.Parameters.Add(new SqliteParameter(":" + fields[i], keys[i]));
278 terms.Add("`" + fields[i] + "` = :" + fields[i]);
279 }
280
281 string where = String.Join(" and ", terms.ToArray());
267 282
268 if (ExecuteNonQuery(cmd, m_Connection) > 0) 283 string query = String.Format("delete * from {0} where {1}", m_Realm, where);
269 return true;
270 284
271 return false; 285 cmd.CommandText = query;
286
287 return ExecuteNonQuery(cmd, m_Connection) > 0;
272 } 288 }
273 } 289 }
274} 290}
diff --git a/OpenSim/Data/SQLite/SQLiteXInventoryData.cs b/OpenSim/Data/SQLite/SQLiteXInventoryData.cs
index ccbd86e..02edc30 100644
--- a/OpenSim/Data/SQLite/SQLiteXInventoryData.cs
+++ b/OpenSim/Data/SQLite/SQLiteXInventoryData.cs
@@ -91,11 +91,21 @@ namespace OpenSim.Data.SQLite
91 return m_Folders.Delete(field, val); 91 return m_Folders.Delete(field, val);
92 } 92 }
93 93
94 public bool DeleteFolders(string[] fields, string[] vals)
95 {
96 return m_Folders.Delete(fields, vals);
97 }
98
94 public bool DeleteItems(string field, string val) 99 public bool DeleteItems(string field, string val)
95 { 100 {
96 return m_Items.Delete(field, val); 101 return m_Items.Delete(field, val);
97 } 102 }
98 103
104 public bool DeleteItems(string[] fields, string[] vals)
105 {
106 return m_Items.Delete(fields, vals);
107 }
108
99 public bool MoveItem(string id, string newParent) 109 public bool MoveItem(string id, string newParent)
100 { 110 {
101 return m_Items.MoveItem(id, newParent); 111 return m_Items.MoveItem(id, newParent);
diff --git a/OpenSim/Framework/WebUtil.cs b/OpenSim/Framework/WebUtil.cs
index f8691dc..f176485 100644
--- a/OpenSim/Framework/WebUtil.cs
+++ b/OpenSim/Framework/WebUtil.cs
@@ -974,7 +974,7 @@ namespace OpenSim.Framework
974 } 974 }
975 catch (Exception e) 975 catch (Exception e)
976 { 976 {
977 m_log.WarnFormat("[SynchronousRestObjectRequester]: exception in sending data to {0}: {1}", requestUrl, e); 977 m_log.DebugFormat("[SynchronousRestObjectRequester]: exception in sending data to {0}: {1}", requestUrl, e);
978 return deserial; 978 return deserial;
979 } 979 }
980 finally 980 finally
@@ -999,18 +999,18 @@ namespace OpenSim.Framework
999 respStream.Close(); 999 respStream.Close();
1000 } 1000 }
1001 else 1001 else
1002 m_log.WarnFormat("[SynchronousRestObjectRequester]: Oops! no content found in response stream from {0} {1}", requestUrl, verb); 1002 m_log.DebugFormat("[SynchronousRestObjectRequester]: Oops! no content found in response stream from {0} {1}", requestUrl, verb);
1003 1003
1004 } 1004 }
1005 } 1005 }
1006 catch (System.InvalidOperationException) 1006 catch (System.InvalidOperationException)
1007 { 1007 {
1008 // This is what happens when there is invalid XML 1008 // This is what happens when there is invalid XML
1009 m_log.WarnFormat("[SynchronousRestObjectRequester]: Invalid XML {0} {1}", requestUrl, typeof(TResponse).ToString()); 1009 m_log.DebugFormat("[SynchronousRestObjectRequester]: Invalid XML {0} {1}", requestUrl, typeof(TResponse).ToString());
1010 } 1010 }
1011 catch (Exception e) 1011 catch (Exception e)
1012 { 1012 {
1013 m_log.WarnFormat("[SynchronousRestObjectRequester]: Exception on response from {0} {1}", requestUrl, e); 1013 m_log.DebugFormat("[SynchronousRestObjectRequester]: Exception on response from {0} {1}", requestUrl, e);
1014 } 1014 }
1015 1015
1016 return deserial; 1016 return deserial;
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 17242dc..431f3dc 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -1423,7 +1423,10 @@ namespace OpenSim.Region.Framework.Scenes
1423 if (item.AssetType == (int)AssetType.Link) 1423 if (item.AssetType == (int)AssetType.Link)
1424 { 1424 {
1425 InventoryItemBase linkedItem = InventoryService.GetItem(new InventoryItemBase(item.AssetID)); 1425 InventoryItemBase linkedItem = InventoryService.GetItem(new InventoryItemBase(item.AssetID));
1426 linkedItemFolderIdsToSend.Add(linkedItem.Folder); 1426
1427 // Take care of genuinely broken links where the target doesn't exist
1428 if (linkedItem != null)
1429 linkedItemFolderIdsToSend.Add(linkedItem.Folder);
1427 } 1430 }
1428 } 1431 }
1429 1432
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index bac66cb..313a469 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -620,7 +620,7 @@ namespace OpenSim.Region.Framework.Scenes
620 "delete object uuid <UUID>", 620 "delete object uuid <UUID>",
621 "Delete object by uuid", HandleDeleteObject); 621 "Delete object by uuid", HandleDeleteObject);
622 MainConsole.Instance.Commands.AddCommand("region", false, "delete object name", 622 MainConsole.Instance.Commands.AddCommand("region", false, "delete object name",
623 "delete object name <UUID>", 623 "delete object name <name>",
624 "Delete object by name", HandleDeleteObject); 624 "Delete object by name", HandleDeleteObject);
625 625
626 //Bind Storage Manager functions to some land manager functions for this scene 626 //Bind Storage Manager functions to some land manager functions for this scene
diff --git a/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModule.cs b/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModule.cs
index ce9a448..b74d6e7 100644
--- a/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModule.cs
+++ b/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModule.cs
@@ -58,12 +58,9 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
58 /// </summary> 58 /// </summary>
59 /// <remarks> 59 /// <remarks>
60 /// Config Settings Documentation. 60 /// Config Settings Documentation.
61 /// At the TOP LEVEL, e.g. in OpenSim.ini, we have the following options: 61 /// Each configuration setting can be specified in two places: OpenSim.ini or Regions.ini.
62 /// EACH REGION, in OpenSim.ini, can have the following settings under the [AutoBackupModule] section. 62 /// If specified in Regions.ini, the settings should be within the region's section name.
63 /// IMPORTANT: You may optionally specify the key name as follows for a per-region key: [Region Name].[Key Name] 63 /// If specified in OpenSim.ini, the settings should be within the [AutoBackupModule] section.
64 /// Example: My region is named Foo.
65 /// If I wanted to specify the "AutoBackupInterval" key just for this region, I would name my key "Foo.AutoBackupInterval", under the [AutoBackupModule] section of OpenSim.ini.
66 /// Instead of specifying them on a per-region basis, you can also omit the region name to specify the default setting for all regions.
67 /// Region-specific settings take precedence. 64 /// Region-specific settings take precedence.
68 /// 65 ///
69 /// AutoBackupModuleEnabled: True/False. Default: False. If True, use the auto backup module. This setting does not support per-region basis. 66 /// AutoBackupModuleEnabled: True/False. Default: False. If True, use the auto backup module. This setting does not support per-region basis.
@@ -71,7 +68,7 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
71 /// AutoBackup: True/False. Default: False. If True, activate auto backup functionality. 68 /// AutoBackup: True/False. Default: False. If True, activate auto backup functionality.
72 /// This is the only required option for enabling auto-backup; the other options have sane defaults. 69 /// This is the only required option for enabling auto-backup; the other options have sane defaults.
73 /// If False for a particular region, the auto-backup module becomes a no-op for the region, and all other AutoBackup* settings are ignored. 70 /// If False for a particular region, the auto-backup module becomes a no-op for the region, and all other AutoBackup* settings are ignored.
74 /// If False globally (the default), only regions that specifically override this with "FooRegion.AutoBackup = true" will get AutoBackup functionality. 71 /// If False globally (the default), only regions that specifically override it in Regions.ini will get AutoBackup functionality.
75 /// AutoBackupInterval: Double, non-negative value. Default: 720 (12 hours). 72 /// AutoBackupInterval: Double, non-negative value. Default: 720 (12 hours).
76 /// The number of minutes between each backup attempt. 73 /// The number of minutes between each backup attempt.
77 /// If a negative or zero value is given, it is equivalent to setting AutoBackup = False. 74 /// If a negative or zero value is given, it is equivalent to setting AutoBackup = False.
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 48a7953..c240edf 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -4887,6 +4887,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4887 return result; 4887 return result;
4888 } 4888 }
4889 4889
4890 public LSL_Integer llGetLinkNumberOfSides(int link)
4891 {
4892 m_host.AddScriptLPS(1);
4893
4894 SceneObjectPart linkedPart;
4895
4896 if (link == ScriptBaseClass.LINK_ROOT)
4897 linkedPart = m_host.ParentGroup.RootPart;
4898 else if (link == ScriptBaseClass.LINK_THIS)
4899 linkedPart = m_host;
4900 else
4901 linkedPart = m_host.ParentGroup.GetLinkNumPart(link);
4902
4903 return GetNumberOfSides(linkedPart);
4904 }
4905
4890 public LSL_Integer llGetNumberOfSides() 4906 public LSL_Integer llGetNumberOfSides()
4891 { 4907 {
4892 m_host.AddScriptLPS(1); 4908 m_host.AddScriptLPS(1);
diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
index 665f4a6..6bfee91 100644
--- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
@@ -1530,6 +1530,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
1530 public struct LSLInteger 1530 public struct LSLInteger
1531 { 1531 {
1532 public int value; 1532 public int value;
1533 private static readonly Regex castRegex = new Regex(@"(^[ ]*0[xX][0-9A-Fa-f][0-9A-Fa-f]*)|(^[ ]*(-?|\+?)[0-9][0-9]*)");
1533 1534
1534 #region Constructors 1535 #region Constructors
1535 public LSLInteger(int i) 1536 public LSLInteger(int i)
@@ -1549,9 +1550,10 @@ namespace OpenSim.Region.ScriptEngine.Shared
1549 1550
1550 public LSLInteger(string s) 1551 public LSLInteger(string s)
1551 { 1552 {
1552 Regex r = new Regex("(^[ ]*0[xX][0-9A-Fa-f][0-9A-Fa-f]*)|(^[ ]*-?[0-9][0-9]*)"); 1553 Match m = castRegex.Match(s);
1553 Match m = r.Match(s);
1554 string v = m.Groups[0].Value; 1554 string v = m.Groups[0].Value;
1555 // Leading plus sign is allowed, but ignored
1556 v = v.Replace("+", "");
1555 1557
1556 if (v == String.Empty) 1558 if (v == String.Empty)
1557 { 1559 {
diff --git a/OpenSim/Services/InventoryService/XInventoryService.cs b/OpenSim/Services/InventoryService/XInventoryService.cs
index 0af35c8..2282ee8 100644
--- a/OpenSim/Services/InventoryService/XInventoryService.cs
+++ b/OpenSim/Services/InventoryService/XInventoryService.cs
@@ -393,6 +393,10 @@ namespace OpenSim.Services.InventoryService
393 393
394 public virtual bool UpdateItem(InventoryItemBase item) 394 public virtual bool UpdateItem(InventoryItemBase item)
395 { 395 {
396 if (!m_AllowDelete)
397 if (item.AssetType == (sbyte)AssetType.Link || item.AssetType == (sbyte)AssetType.LinkFolder)
398 return false;
399
396 return m_Database.StoreItem(ConvertFromOpenSim(item)); 400 return m_Database.StoreItem(ConvertFromOpenSim(item));
397 } 401 }
398 402
@@ -411,12 +415,30 @@ namespace OpenSim.Services.InventoryService
411 public virtual bool DeleteItems(UUID principalID, List<UUID> itemIDs) 415 public virtual bool DeleteItems(UUID principalID, List<UUID> itemIDs)
412 { 416 {
413 if (!m_AllowDelete) 417 if (!m_AllowDelete)
414 return false; 418 {
415 419 // We must still allow links and links to folders to be deleted, otherwise they will build up
416 // Just use the ID... *facepalms* 420 // in the player's inventory until they can no longer log in. Deletions of links due to code bugs or
417 // 421 // similar is inconvenient but on a par with accidental movement of items. The original item is never
418 foreach (UUID id in itemIDs) 422 // touched.
419 m_Database.DeleteItems("inventoryID", id.ToString()); 423 foreach (UUID id in itemIDs)
424 {
425 if (!m_Database.DeleteItems(
426 new string[] { "inventoryID", "assetType" },
427 new string[] { id.ToString(), ((sbyte)AssetType.Link).ToString() }));
428 {
429 m_Database.DeleteItems(
430 new string[] { "inventoryID", "assetType" },
431 new string[] { id.ToString(), ((sbyte)AssetType.LinkFolder).ToString() });
432 }
433 }
434 }
435 else
436 {
437 // Just use the ID... *facepalms*
438 //
439 foreach (UUID id in itemIDs)
440 m_Database.DeleteItems("inventoryID", id.ToString());
441 }
420 442
421 return true; 443 return true;
422 } 444 }