aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs374
1 files changed, 200 insertions, 174 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index d04d87b..2fa9139 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -46,10 +46,10 @@ namespace OpenSim.Region.Framework.Scenes
46 { 46 {
47 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 47 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
48 48
49 private string m_inventoryFileName = String.Empty;
50 private byte[] m_inventoryFileData = new byte[0]; 49 private byte[] m_inventoryFileData = new byte[0];
51 private uint m_inventoryFileNameSerial = 0; 50 private uint m_inventoryFileNameSerial = 0;
52 private bool m_inventoryPrivileged = false; 51 private bool m_inventoryPrivileged = false;
52 private object m_inventoryFileLock = new object();
53 53
54 private Dictionary<UUID, ArrayList> m_scriptErrors = new Dictionary<UUID, ArrayList>(); 54 private Dictionary<UUID, ArrayList> m_scriptErrors = new Dictionary<UUID, ArrayList>();
55 55
@@ -505,35 +505,24 @@ namespace OpenSim.Region.Framework.Scenes
505 private void CreateScriptInstanceInternal(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) 505 private void CreateScriptInstanceInternal(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
506 { 506 {
507 m_items.LockItemsForRead(true); 507 m_items.LockItemsForRead(true);
508
508 if (m_items.ContainsKey(itemId)) 509 if (m_items.ContainsKey(itemId))
509 { 510 {
510 if (m_items.ContainsKey(itemId)) 511 TaskInventoryItem it = m_items[itemId];
511 { 512 m_items.LockItemsForRead(false);
512 m_items.LockItemsForRead(false); 513
513 CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource); 514 CreateScriptInstance(it, startParam, postOnRez, engine, stateSource);
514 }
515 else
516 {
517 m_items.LockItemsForRead(false);
518 string msg = String.Format("couldn't be found for prim {0}, {1} at {2} in {3}", m_part.Name, m_part.UUID,
519 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
520 StoreScriptError(itemId, msg);
521 m_log.ErrorFormat(
522 "[PRIM INVENTORY]: " +
523 "Couldn't start script with ID {0} since it {1}", itemId, msg);
524 }
525 } 515 }
526 else 516 else
527 { 517 {
528 m_items.LockItemsForRead(false); 518 m_items.LockItemsForRead(false);
529 string msg = String.Format("couldn't be found for prim {0}, {1}", m_part.Name, m_part.UUID); 519 string msg = String.Format("couldn't be found for prim {0}, {1} at {2} in {3}", m_part.Name, m_part.UUID,
520 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
530 StoreScriptError(itemId, msg); 521 StoreScriptError(itemId, msg);
531 m_log.ErrorFormat( 522 m_log.ErrorFormat(
532 "[PRIM INVENTORY]: Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", 523 "[PRIM INVENTORY]: " +
533 itemId, m_part.Name, m_part.UUID, 524 "Couldn't start script with ID {0} since it {1}", itemId, msg);
534 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
535 } 525 }
536
537 } 526 }
538 527
539 /// <summary> 528 /// <summary>
@@ -696,7 +685,8 @@ namespace OpenSim.Region.Framework.Scenes
696 /// </param> 685 /// </param>
697 public void StopScriptInstance(TaskInventoryItem item) 686 public void StopScriptInstance(TaskInventoryItem item)
698 { 687 {
699 m_part.ParentGroup.Scene.EventManager.TriggerStopScript(m_part.LocalId, item.ItemID); 688 if (m_part.ParentGroup.Scene != null)
689 m_part.ParentGroup.Scene.EventManager.TriggerStopScript(m_part.LocalId, item.ItemID);
700 690
701 // At the moment, even stopped scripts are counted as active, which is probably wrong. 691 // At the moment, even stopped scripts are counted as active, which is probably wrong.
702// m_part.ParentGroup.AddActiveScriptCount(-1); 692// m_part.ParentGroup.AddActiveScriptCount(-1);
@@ -880,8 +870,8 @@ namespace OpenSim.Region.Framework.Scenes
880 870
881 return items; 871 return items;
882 } 872 }
883 873
884 public SceneObjectGroup GetRezReadySceneObject(TaskInventoryItem item) 874 public bool GetRezReadySceneObjects(TaskInventoryItem item, out List<SceneObjectGroup> objlist, out List<Vector3> veclist)
885 { 875 {
886 AssetBase rezAsset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString()); 876 AssetBase rezAsset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString());
887 877
@@ -890,70 +880,102 @@ namespace OpenSim.Region.Framework.Scenes
890 m_log.WarnFormat( 880 m_log.WarnFormat(
891 "[PRIM INVENTORY]: Could not find asset {0} for inventory item {1} in {2}", 881 "[PRIM INVENTORY]: Could not find asset {0} for inventory item {1} in {2}",
892 item.AssetID, item.Name, m_part.Name); 882 item.AssetID, item.Name, m_part.Name);
893 return null; 883 objlist = null;
884 veclist = null;
885 return false;
894 } 886 }
895 887
896 string xmlData = Utils.BytesToString(rezAsset.Data); 888 Vector3 bbox;
897 SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); 889 float offsetHeight;
898 890
899 group.RootPart.AttachPoint = group.RootPart.Shape.State; 891 bool single = m_part.ParentGroup.Scene.GetObjectsToRez(rezAsset.Data, false, out objlist, out veclist, out bbox, out offsetHeight);
900 group.RootPart.AttachOffset = group.AbsolutePosition;
901 group.RootPart.AttachRotation = group.GroupRotation;
902 892
903 group.ResetIDs(); 893 for (int i = 0; i < objlist.Count; i++)
904 894 {
905 SceneObjectPart rootPart = group.GetPart(group.UUID); 895 SceneObjectGroup group = objlist[i];
906 896/*
907 // Since renaming the item in the inventory does not affect the name stored 897 group.RootPart.AttachPoint = group.RootPart.Shape.State;
908 // in the serialization, transfer the correct name from the inventory to the 898 group.RootPart.AttachedPos = group.AbsolutePosition;
909 // object itself before we rez. 899 group.RootPart.AttachRotation = group.GroupRotation;
910 rootPart.Name = item.Name; 900*/
911 rootPart.Description = item.Description; 901 group.ResetIDs();
902
903 SceneObjectPart rootPart = group.GetPart(group.UUID);
904
905 // Since renaming the item in the inventory does not affect the name stored
906 // in the serialization, transfer the correct name from the inventory to the
907 // object itself before we rez.
908 // Only do these for the first object if we are rezzing a coalescence.
909 // nahh dont mess with coalescence objects,
910 // the name in inventory can be change for inventory purpuses only
911 if (objlist.Count == 1)
912 {
913 rootPart.Name = item.Name;
914 rootPart.Description = item.Description;
915 }
916/* reverted to old code till part.ApplyPermissionsOnRez is better reviewed/fixed
917 group.SetGroup(m_part.GroupID, null);
912 918
913 SceneObjectPart[] partList = group.Parts; 919 foreach (SceneObjectPart part in group.Parts)
920 {
921 // Convert between InventoryItem classes. You can never have too many similar but slightly different classes :)
922 InventoryItemBase dest = new InventoryItemBase(item.ItemID, item.OwnerID);
923 dest.BasePermissions = item.BasePermissions;
924 dest.CurrentPermissions = item.CurrentPermissions;
925 dest.EveryOnePermissions = item.EveryonePermissions;
926 dest.GroupPermissions = item.GroupPermissions;
927 dest.NextPermissions = item.NextPermissions;
928 dest.Flags = item.Flags;
929
930 part.ApplyPermissionsOnRez(dest, false, m_part.ParentGroup.Scene);
931 }
932*/
933// old code start
934 SceneObjectPart[] partList = group.Parts;
914 935
915 group.SetGroup(m_part.GroupID, null); 936 group.SetGroup(m_part.GroupID, null);
916 937
917 // TODO: Remove magic number badness 938 // TODO: Remove magic number badness
918 if ((rootPart.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0 || (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0) // Magic number 939 if ((rootPart.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0 || (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0) // Magic number
919 {
920 if (m_part.ParentGroup.Scene.Permissions.PropagatePermissions())
921 { 940 {
922 foreach (SceneObjectPart part in partList) 941 if (m_part.ParentGroup.Scene.Permissions.PropagatePermissions())
923 { 942 {
924 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0) 943 foreach (SceneObjectPart part in partList)
925 part.EveryoneMask = item.EveryonePermissions; 944 {
926 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0) 945 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0)
927 part.NextOwnerMask = item.NextPermissions; 946 part.EveryoneMask = item.EveryonePermissions;
928 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0) 947 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0)
929 part.GroupMask = item.GroupPermissions; 948 part.NextOwnerMask = item.NextPermissions;
949 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0)
950 part.GroupMask = item.GroupPermissions;
951 }
952
953 group.ApplyNextOwnerPermissions();
930 } 954 }
931
932 group.ApplyNextOwnerPermissions();
933 } 955 }
934 }
935 956
936 foreach (SceneObjectPart part in partList) 957 foreach (SceneObjectPart part in partList)
937 {
938 // TODO: Remove magic number badness
939 if ((part.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0 || (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0) // Magic number
940 { 958 {
941 part.LastOwnerID = part.OwnerID; 959 // TODO: Remove magic number badness
942 part.OwnerID = item.OwnerID; 960 if ((part.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0 || (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0) // Magic number
943 part.Inventory.ChangeInventoryOwner(item.OwnerID); 961 {
962 part.LastOwnerID = part.OwnerID;
963 part.OwnerID = item.OwnerID;
964 part.Inventory.ChangeInventoryOwner(item.OwnerID);
965 }
966
967 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0)
968 part.EveryoneMask = item.EveryonePermissions;
969 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0)
970 part.NextOwnerMask = item.NextPermissions;
971 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0)
972 part.GroupMask = item.GroupPermissions;
944 } 973 }
945 974// old code end
946 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0) 975 rootPart.TrimPermissions();
947 part.EveryoneMask = item.EveryonePermissions;
948 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0)
949 part.NextOwnerMask = item.NextPermissions;
950 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0)
951 part.GroupMask = item.GroupPermissions;
952 } 976 }
953 977
954 rootPart.TrimPermissions(); 978 return true;
955
956 return group;
957 } 979 }
958 980
959 /// <summary> 981 /// <summary>
@@ -1077,23 +1099,6 @@ namespace OpenSim.Region.Framework.Scenes
1077 return -1; 1099 return -1;
1078 } 1100 }
1079 1101
1080 private bool CreateInventoryFileName()
1081 {
1082// m_log.DebugFormat(
1083// "[PRIM INVENTORY]: Creating inventory file for {0} {1} {2}, serial {3}",
1084// m_part.Name, m_part.UUID, m_part.LocalId, m_inventorySerial);
1085
1086 if (m_inventoryFileName == String.Empty ||
1087 m_inventoryFileNameSerial < m_inventorySerial)
1088 {
1089 m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp";
1090 m_inventoryFileNameSerial = m_inventorySerial;
1091
1092 return true;
1093 }
1094
1095 return false;
1096 }
1097 1102
1098 /// <summary> 1103 /// <summary>
1099 /// Serialize all the metadata for the items in this prim's inventory ready for sending to the client 1104 /// Serialize all the metadata for the items in this prim's inventory ready for sending to the client
@@ -1101,110 +1106,124 @@ namespace OpenSim.Region.Framework.Scenes
1101 /// <param name="xferManager"></param> 1106 /// <param name="xferManager"></param>
1102 public void RequestInventoryFile(IClientAPI client, IXfer xferManager) 1107 public void RequestInventoryFile(IClientAPI client, IXfer xferManager)
1103 { 1108 {
1104 bool changed = CreateInventoryFileName();
1105 1109
1106 bool includeAssets = false; 1110 lock (m_inventoryFileLock)
1107 if (m_part.ParentGroup.Scene.Permissions.CanEditObjectInventory(m_part.UUID, client.AgentId)) 1111 {
1108 includeAssets = true; 1112 string filename = "inventory_" + UUID.Random().ToString() + ".tmp";
1109 1113
1110 if (m_inventoryPrivileged != includeAssets) 1114 bool changed = false;
1111 changed = true; 1115 if (m_inventoryFileNameSerial < m_inventorySerial)
1116 {
1117 m_inventoryFileNameSerial = m_inventorySerial;
1118 changed = true;
1119 }
1112 1120
1113 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); 1121 if (m_inventoryFileData.Length < 2)
1122 changed = true;
1114 1123
1115 Items.LockItemsForRead(true); 1124 bool includeAssets = false;
1125 if (m_part.ParentGroup.Scene.Permissions.CanEditObjectInventory(m_part.UUID, client.AgentId))
1126 includeAssets = true;
1116 1127
1117 if (m_inventorySerial == 0) // No inventory 1128 if (m_inventoryPrivileged != includeAssets)
1118 { 1129 changed = true;
1119 client.SendTaskInventory(m_part.UUID, 0, new byte[0]);
1120 Items.LockItemsForRead(false);
1121 return;
1122 }
1123 1130
1124 if (m_items.Count == 0) // No inventory
1125 {
1126 client.SendTaskInventory(m_part.UUID, 0, new byte[0]);
1127 Items.LockItemsForRead(false);
1128 return;
1129 }
1130
1131 if (!changed)
1132 {
1133 if (m_inventoryFileData.Length > 2)
1134 {
1135 xferManager.AddNewFile(m_inventoryFileName,
1136 m_inventoryFileData);
1137 client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial,
1138 Util.StringToBytes256(m_inventoryFileName));
1139 1131
1132 Items.LockItemsForRead(true);
1133
1134 if (m_inventorySerial == 0) // No inventory
1135 {
1140 Items.LockItemsForRead(false); 1136 Items.LockItemsForRead(false);
1137 client.SendTaskInventory(m_part.UUID, 0, new byte[0]);
1138
1141 return; 1139 return;
1142 } 1140 }
1143 }
1144
1145 m_inventoryPrivileged = includeAssets;
1146
1147 foreach (TaskInventoryItem item in m_items.Values)
1148 {
1149 UUID ownerID = item.OwnerID;
1150 uint everyoneMask = 0;
1151 uint baseMask = item.BasePermissions;
1152 uint ownerMask = item.CurrentPermissions;
1153 uint groupMask = item.GroupPermissions;
1154 1141
1155 invString.AddItemStart(); 1142 if (m_items.Count == 0) // No inventory
1156 invString.AddNameValueLine("item_id", item.ItemID.ToString()); 1143 {
1157 invString.AddNameValueLine("parent_id", m_part.UUID.ToString()); 1144 Items.LockItemsForRead(false);
1158 1145 client.SendTaskInventory(m_part.UUID, 0, new byte[0]);
1159 invString.AddPermissionsStart(); 1146 return;
1160 1147 }
1161 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask));
1162 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask));
1163 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask));
1164 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask));
1165 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions));
1166 1148
1167 invString.AddNameValueLine("creator_id", item.CreatorID.ToString()); 1149 if (!changed)
1168 invString.AddNameValueLine("owner_id", ownerID.ToString()); 1150 {
1151 Items.LockItemsForRead(false);
1169 1152
1170 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString()); 1153 xferManager.AddNewFile(filename,
1154 m_inventoryFileData);
1155 client.SendTaskInventory(m_part.UUID, (short)m_inventoryFileNameSerial,
1156 Util.StringToBytes256(filename));
1171 1157
1172 invString.AddNameValueLine("group_id", item.GroupID.ToString()); 1158 return;
1173 invString.AddSectionEnd(); 1159 }
1174 1160
1175 if (includeAssets) 1161 m_inventoryPrivileged = includeAssets;
1176 invString.AddNameValueLine("asset_id", item.AssetID.ToString());
1177 else
1178 invString.AddNameValueLine("asset_id", UUID.Zero.ToString());
1179 invString.AddNameValueLine("type", Utils.AssetTypeToString((AssetType)item.Type));
1180 invString.AddNameValueLine("inv_type", Utils.InventoryTypeToString((InventoryType)item.InvType));
1181 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags));
1182 1162
1183 invString.AddSaleStart(); 1163 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero);
1184 invString.AddNameValueLine("sale_type", "not");
1185 invString.AddNameValueLine("sale_price", "0");
1186 invString.AddSectionEnd();
1187 1164
1188 invString.AddNameValueLine("name", item.Name + "|"); 1165 foreach (TaskInventoryItem item in m_items.Values)
1189 invString.AddNameValueLine("desc", item.Description + "|"); 1166 {
1167 UUID ownerID = item.OwnerID;
1168 uint everyoneMask = 0;
1169 uint baseMask = item.BasePermissions;
1170 uint ownerMask = item.CurrentPermissions;
1171 uint groupMask = item.GroupPermissions;
1172
1173 invString.AddItemStart();
1174 invString.AddNameValueLine("item_id", item.ItemID.ToString());
1175 invString.AddNameValueLine("parent_id", m_part.UUID.ToString());
1176
1177 invString.AddPermissionsStart();
1178
1179 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask));
1180 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask));
1181 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask));
1182 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask));
1183 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions));
1184
1185 invString.AddNameValueLine("creator_id", item.CreatorID.ToString());
1186 invString.AddNameValueLine("owner_id", ownerID.ToString());
1187
1188 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString());
1189
1190 invString.AddNameValueLine("group_id", item.GroupID.ToString());
1191 invString.AddSectionEnd();
1192
1193 if (includeAssets)
1194 invString.AddNameValueLine("asset_id", item.AssetID.ToString());
1195 else
1196 invString.AddNameValueLine("asset_id", UUID.Zero.ToString());
1197 invString.AddNameValueLine("type", Utils.AssetTypeToString((AssetType)item.Type));
1198 invString.AddNameValueLine("inv_type", Utils.InventoryTypeToString((InventoryType)item.InvType));
1199 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags));
1200
1201 invString.AddSaleStart();
1202 invString.AddNameValueLine("sale_type", "not");
1203 invString.AddNameValueLine("sale_price", "0");
1204 invString.AddSectionEnd();
1205
1206 invString.AddNameValueLine("name", item.Name + "|");
1207 invString.AddNameValueLine("desc", item.Description + "|");
1208
1209 invString.AddNameValueLine("creation_date", item.CreationDate.ToString());
1210 invString.AddSectionEnd();
1211 }
1190 1212
1191 invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); 1213 Items.LockItemsForRead(false);
1192 invString.AddSectionEnd();
1193 }
1194 1214
1195 Items.LockItemsForRead(false); 1215 m_inventoryFileData = Utils.StringToBytes(invString.BuildString);
1196 1216
1197 m_inventoryFileData = Utils.StringToBytes(invString.BuildString); 1217 if (m_inventoryFileData.Length > 2)
1218 {
1219 xferManager.AddNewFile(filename, m_inventoryFileData);
1220 client.SendTaskInventory(m_part.UUID, (short)m_inventoryFileNameSerial,
1221 Util.StringToBytes256(filename));
1222 return;
1223 }
1198 1224
1199 if (m_inventoryFileData.Length > 2) 1225 client.SendTaskInventory(m_part.UUID, 0, new byte[0]);
1200 {
1201 xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData);
1202 client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial,
1203 Util.StringToBytes256(m_inventoryFileName));
1204 return;
1205 } 1226 }
1206
1207 client.SendTaskInventory(m_part.UUID, 0, new byte[0]);
1208 } 1227 }
1209 1228
1210 /// <summary> 1229 /// <summary>
@@ -1221,10 +1240,17 @@ namespace OpenSim.Region.Framework.Scenes
1221// if (HasInventoryChanged) 1240// if (HasInventoryChanged)
1222// { 1241// {
1223 Items.LockItemsForRead(true); 1242 Items.LockItemsForRead(true);
1224 datastore.StorePrimInventory(m_part.UUID, Items.Values); 1243 try
1225 Items.LockItemsForRead(false); 1244 {
1245 datastore.StorePrimInventory(m_part.UUID, Items.Values);
1246 }
1247 catch {}
1226 1248
1227 HasInventoryChanged = false; 1249 HasInventoryChanged = false;
1250
1251 Items.LockItemsForRead(false);
1252
1253
1228// } 1254// }
1229 } 1255 }
1230 1256