aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region')
-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>