aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorDiva Canto2010-12-24 08:50:00 -0800
committerDiva Canto2010-12-24 08:50:00 -0800
commit3eaaaa0d994c7c994d471d511127ed0ba66ab9bc (patch)
tree94f784b0cc76ebe3c527657a8af3b5621bf212fd
parentHopefully this fixes all prim inventory issues. No more abort, no more keepin... (diff)
downloadopensim-SC_OLD-3eaaaa0d994c7c994d471d511127ed0ba66ab9bc.zip
opensim-SC_OLD-3eaaaa0d994c7c994d471d511127ed0ba66ab9bc.tar.gz
opensim-SC_OLD-3eaaaa0d994c7c994d471d511127ed0ba66ab9bc.tar.bz2
opensim-SC_OLD-3eaaaa0d994c7c994d471d511127ed0ba66ab9bc.tar.xz
One more pass at object inventory. This time, fix SceneObjectPartInventory so that it makes sure that the file is added to Xfer's before it signals the client to come and get it. This allows the simplification of the logic of Xfer's.
-rw-r--r--OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs94
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs136
2 files changed, 82 insertions, 148 deletions
diff --git a/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs b/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs
index df4ff05..b8e2820 100644
--- a/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs
+++ b/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs
@@ -27,7 +27,9 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Reflection;
30using Nini.Config; 31using Nini.Config;
32using log4net;
31using OpenMetaverse; 33using OpenMetaverse;
32using OpenSim.Framework; 34using OpenSim.Framework;
33using OpenSim.Region.Framework.Interfaces; 35using OpenSim.Region.Framework.Interfaces;
@@ -37,12 +39,11 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
37{ 39{
38 public class XferModule : IRegionModule, IXfer 40 public class XferModule : IRegionModule, IXfer
39 { 41 {
40 private static uint counter = 0;
41 private Scene m_scene; 42 private Scene m_scene;
42 private Dictionary<string, XferRequest> Requests = new Dictionary<string, XferRequest>();
43 private Dictionary<string, FileData> NewFiles = new Dictionary<string, FileData>(); 43 private Dictionary<string, FileData> NewFiles = new Dictionary<string, FileData>();
44 private Dictionary<ulong, XferDownLoad> Transfers = new Dictionary<ulong, XferDownLoad>(); 44 private Dictionary<ulong, XferDownLoad> Transfers = new Dictionary<ulong, XferDownLoad>();
45 45
46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46 47
47 public struct XferRequest 48 public struct XferRequest
48 { 49 {
@@ -90,6 +91,14 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
90 91
91 #region IXfer Members 92 #region IXfer Members
92 93
94 /// <summary>
95 /// Let the Xfer module know about a file that the client is about to request.
96 /// Caller is responsible for making sure that the file is here before
97 /// the client starts the XferRequest.
98 /// </summary>
99 /// <param name="fileName"></param>
100 /// <param name="data"></param>
101 /// <returns></returns>
93 public bool AddNewFile(string fileName, byte[] data) 102 public bool AddNewFile(string fileName, byte[] data)
94 { 103 {
95 lock (NewFiles) 104 lock (NewFiles)
@@ -97,7 +106,7 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
97 if (NewFiles.ContainsKey(fileName)) 106 if (NewFiles.ContainsKey(fileName))
98 { 107 {
99 NewFiles[fileName].Count++; 108 NewFiles[fileName].Count++;
100 //Console.WriteLine("AddNewFile " + fileName + " counter=" + NewFiles[fileName].Count); 109 NewFiles[fileName].Data = data;
101 } 110 }
102 else 111 else
103 { 112 {
@@ -105,23 +114,9 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
105 fd.Count = 1; 114 fd.Count = 1;
106 fd.Data = data; 115 fd.Data = data;
107 NewFiles.Add(fileName, fd); 116 NewFiles.Add(fileName, fd);
108 //Console.WriteLine("AddNewFile " + fileName);
109 } 117 }
110 } 118 }
111 119
112 // This happens when the Xfer request ends up coming before
113 // the fileName is added by this method. That may happen when
114 // the file generation (the event that calle this method)
115 // takes a long time. In this case, we need to kick the
116 // Xfer request mannually.
117 if (Requests.ContainsKey(fileName))
118 {
119 //Console.WriteLine("*** AddNewFile Requests.Contains " + fileName);
120
121 RequestXfer(Requests[fileName].remoteClient, Requests[fileName].xferID, fileName);
122 Requests.Remove(fileName);
123 }
124
125 return true; 120 return true;
126 } 121 }
127 122
@@ -144,23 +139,17 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
144 { 139 {
145 lock (NewFiles) 140 lock (NewFiles)
146 { 141 {
147 //Console.WriteLine("---- RequestXfer " + fileName + " ----");
148
149 if (NewFiles.ContainsKey(fileName)) 142 if (NewFiles.ContainsKey(fileName))
150 { 143 {
151 //Console.WriteLine("NewFiles.ContainsKey " + fileName + " with count=" + NewFiles[fileName].Count);
152 if (!Transfers.ContainsKey(xferID)) 144 if (!Transfers.ContainsKey(xferID))
153 { 145 {
154 //Console.WriteLine("!Transfers.ContainsKey("+xferID+")");
155 byte[] fileData = NewFiles[fileName].Data; 146 byte[] fileData = NewFiles[fileName].Data;
156 XferDownLoad transaction = new XferDownLoad(fileName, fileData, xferID, remoteClient); 147 XferDownLoad transaction = new XferDownLoad(fileName, fileData, xferID, remoteClient);
157 148
158 Transfers.Add(xferID, transaction); 149 Transfers.Add(xferID, transaction);
159 150
160 if (transaction.StartSend()) 151 if (transaction.StartSend())
161 {
162 RemoveXferData(xferID); 152 RemoveXferData(xferID);
163 }
164 153
165 // The transaction for this file is either complete or on its way 154 // The transaction for this file is either complete or on its way
166 RemoveOrDecrement(fileName); 155 RemoveOrDecrement(fileName);
@@ -168,42 +157,7 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
168 } 157 }
169 } 158 }
170 else 159 else
171 { 160 m_log.WarnFormat("[Xfer]: {0} not found", fileName);
172 ////Console.WriteLine("*** ! NewFiles.ContainsKey " + fileName);
173 //if (RequestTime.Count > 0)
174 //{
175 // //Console.WriteLine("RequestTime.Count > 0");
176 // TimeSpan ts = new TimeSpan(DateTime.UtcNow.Ticks - RequestTime[0].timeStamp.Ticks);
177 // if (ts.TotalSeconds > 30)
178 // {
179 // Console.WriteLine("ts.TotalSeconds > 30");
180 // Requests.Remove(RequestTime[0].fileName);
181 // RequestTime.RemoveAt(0);
182 // // Do we want to abort this here?
183 // //remoteClient.SendAbortXfer(xferID);
184 // }
185 //}
186
187 XferRequest nRequest = new XferRequest();
188 nRequest.remoteClient = remoteClient;
189 nRequest.xferID = xferID;
190 nRequest.fileName = fileName;
191 nRequest.timeStamp = DateTime.UtcNow;
192 nRequest.fileName = fileName;
193
194 if (!Requests.ContainsKey(fileName))
195 {
196 //Console.WriteLine("**** !Requests.ContainsKey(" + fileName + ")");
197 Requests.Add(fileName, nRequest);
198 }
199 else
200 {
201 //Console.WriteLine("**** Requests.ContainsKey(" + fileName + ")");
202 Requests.Add(fileName + "-" + counter.ToString(), nRequest);
203 counter++;
204 }
205
206 }
207 161
208 } 162 }
209 } 163 }
@@ -220,15 +174,6 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
220 RemoveXferData(xferID); 174 RemoveXferData(xferID);
221 RemoveOrDecrement(dl.FileName); 175 RemoveOrDecrement(dl.FileName);
222 } 176 }
223 else
224 {
225 if (Requests.ContainsKey(dl.FileName))
226 {
227 XferRequest req = Requests[dl.FileName];
228 req.timeStamp = DateTime.UtcNow;
229 Requests[dl.FileName] = req;
230 }
231 }
232 } 177 }
233 } 178 }
234 } 179 }
@@ -238,19 +183,12 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
238 // NewFiles must be locked! 183 // NewFiles must be locked!
239 if (Transfers.ContainsKey(xferID)) 184 if (Transfers.ContainsKey(xferID))
240 { 185 {
241 // Qualifier distinguishes between the OpenMetaverse version and the nested class
242
243 XferModule.XferDownLoad xferItem = Transfers[xferID]; 186 XferModule.XferDownLoad xferItem = Transfers[xferID];
244 //string filename = xferItem.FileName; 187 //string filename = xferItem.FileName;
245 Transfers.Remove(xferID); 188 Transfers.Remove(xferID);
246 xferItem.Data = new byte[0]; // Clear the data 189 xferItem.Data = new byte[0]; // Clear the data
247 xferItem.DataPointer = 0; 190 xferItem.DataPointer = 0;
248 191
249 // If the abort comes in
250
251 if (Requests.ContainsKey(xferItem.FileName))
252 Requests.Remove(xferItem.FileName);
253
254 } 192 }
255 } 193 }
256 194
@@ -272,13 +210,9 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
272 if (NewFiles.ContainsKey(fileName)) 210 if (NewFiles.ContainsKey(fileName))
273 { 211 {
274 if (NewFiles[fileName].Count == 1) 212 if (NewFiles[fileName].Count == 1)
275 {
276 NewFiles.Remove(fileName); 213 NewFiles.Remove(fileName);
277 }
278 else 214 else
279 {
280 NewFiles[fileName].Count--; 215 NewFiles[fileName].Count--;
281 }
282 } 216 }
283 } 217 }
284 218
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index 1177378..39ebaef 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -766,102 +766,102 @@ namespace OpenSim.Region.Framework.Scenes
766 return -1; 766 return -1;
767 } 767 }
768 768
769 private bool CreateInventoryFileName() 769 private bool CreateInventoryFile()
770 { 770 {
771 if (m_inventoryFileName == String.Empty || 771 if (m_inventoryFileName == String.Empty ||
772 m_inventoryFileNameSerial < m_inventorySerial) 772 m_inventoryFileNameSerial < m_inventorySerial)
773 { 773 {
774 // Something changed, we need to create a new file
774 m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp"; 775 m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp";
775 m_inventoryFileNameSerial = m_inventorySerial; 776 m_inventoryFileNameSerial = m_inventorySerial;
776 return true;
777 }
778 777
779 return false; 778 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero);
780 }
781 779
782 /// <summary> 780 lock (m_items)
783 /// Serialize all the metadata for the items in this prim's inventory ready for sending to the client 781 {
784 /// </summary> 782 foreach (TaskInventoryItem item in m_items.Values)
785 /// <param name="xferManager"></param> 783 {
786 public void RequestInventoryFile(IClientAPI client, IXfer xferManager) 784 UUID ownerID = item.OwnerID;
787 { 785 uint everyoneMask = 0;
788 bool changed = CreateInventoryFileName(); 786 uint baseMask = item.BasePermissions;
787 uint ownerMask = item.CurrentPermissions;
788 uint groupMask = item.GroupPermissions;
789 789
790 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); 790 invString.AddItemStart();
791 invString.AddNameValueLine("item_id", item.ItemID.ToString());
792 invString.AddNameValueLine("parent_id", m_part.UUID.ToString());
791 793
792 lock (m_items) 794 invString.AddPermissionsStart();
793 {
794 if (m_inventorySerial == 0) // No inventory
795 {
796 client.SendTaskInventory(m_part.UUID, 0, new byte[0]);
797 return;
798 }
799 795
800 client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial, 796 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask));
801 Util.StringToBytes256(m_inventoryFileName)); 797 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask));
798 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask));
799 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask));
800 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions));
802 801
803 if (!changed) 802 invString.AddNameValueLine("creator_id", item.CreatorID.ToString());
804 { 803 invString.AddNameValueLine("owner_id", ownerID.ToString());
805 if (m_inventoryFileData.Length > 2)
806 {
807 xferManager.AddNewFile(m_inventoryFileName,
808 m_inventoryFileData);
809 return;
810 }
811 }
812 804
813 foreach (TaskInventoryItem item in m_items.Values) 805 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString());
814 {
815 UUID ownerID = item.OwnerID;
816 uint everyoneMask = 0;
817 uint baseMask = item.BasePermissions;
818 uint ownerMask = item.CurrentPermissions;
819 uint groupMask = item.GroupPermissions;
820 806
821 invString.AddItemStart(); 807 invString.AddNameValueLine("group_id", item.GroupID.ToString());
822 invString.AddNameValueLine("item_id", item.ItemID.ToString()); 808 invString.AddSectionEnd();
823 invString.AddNameValueLine("parent_id", m_part.UUID.ToString());
824 809
825 invString.AddPermissionsStart(); 810 invString.AddNameValueLine("asset_id", item.AssetID.ToString());
811 invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]);
812 invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]);
813 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags));
826 814
827 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask)); 815 invString.AddSaleStart();
828 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask)); 816 invString.AddNameValueLine("sale_type", "not");
829 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask)); 817 invString.AddNameValueLine("sale_price", "0");
830 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask)); 818 invString.AddSectionEnd();
831 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions));
832 819
833 invString.AddNameValueLine("creator_id", item.CreatorID.ToString()); 820 invString.AddNameValueLine("name", item.Name + "|");
834 invString.AddNameValueLine("owner_id", ownerID.ToString()); 821 invString.AddNameValueLine("desc", item.Description + "|");
835 822
836 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString()); 823 invString.AddNameValueLine("creation_date", item.CreationDate.ToString());
824 invString.AddSectionEnd();
825 }
826 }
837 827
838 invString.AddNameValueLine("group_id", item.GroupID.ToString()); 828 m_inventoryFileData = Utils.StringToBytes(invString.BuildString);
839 invString.AddSectionEnd();
840 829
841 invString.AddNameValueLine("asset_id", item.AssetID.ToString()); 830 return true;
842 invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]); 831 }
843 invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]);
844 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags));
845 832
846 invString.AddSaleStart(); 833 // No need to recreate, the existing file is fine
847 invString.AddNameValueLine("sale_type", "not"); 834 return false;
848 invString.AddNameValueLine("sale_price", "0"); 835 }
849 invString.AddSectionEnd();
850 836
851 invString.AddNameValueLine("name", item.Name + "|"); 837 /// <summary>
852 invString.AddNameValueLine("desc", item.Description + "|"); 838 /// Serialize all the metadata for the items in this prim's inventory ready for sending to the client
839 /// </summary>
840 /// <param name="xferManager"></param>
841 public void RequestInventoryFile(IClientAPI client, IXfer xferManager)
842 {
843 bool changed = CreateInventoryFile();
853 844
854 invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); 845 if (m_inventorySerial == 0) // No inventory
855 invString.AddSectionEnd(); 846 {
856 } 847 client.SendTaskInventory(m_part.UUID, 0, new byte[0]);
848 return;
857 } 849 }
858 850
859 m_inventoryFileData = Utils.StringToBytes(invString.BuildString); 851 // In principle, we should only do the rest if the inventory changed;
852 // by sending m_inventorySerial to the client, it ought to know
853 // that nothing changed and that it doesn't need to request the file.
854 // Unfortunately, it doesn't look like the client optimizes this;
855 // the client seems to always come back and request the Xfer,
856 // no matter what value m_inventorySerial has.
860 857
861 if (m_inventoryFileData.Length > 2) 858 if (m_inventoryFileData.Length > 2)
862 { 859 // Add the file for Xfer
863 xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData); 860 xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData);
864 } 861
862 // Tell the client we're ready to Xfer the file
863 client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial,
864 Util.StringToBytes256(m_inventoryFileName));
865 } 865 }
866 866
867 /// <summary> 867 /// <summary>