29 using System.Collections.Generic;
30 using System.Reflection;
34 using OpenSim.Framework;
35 using OpenSim.Region.Framework.Interfaces;
36 using OpenSim.Region.Framework.Scenes;
42 [Extension(Path =
"/OpenSim/RegionModules", NodeName =
"RegionModule", Id =
"XferModule")]
45 private Scene m_scene;
46 private Dictionary<string, FileData> NewFiles =
new Dictionary<string, FileData>();
47 private Dictionary<ulong, XferDownLoad> Transfers =
new Dictionary<ulong, XferDownLoad>();
49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
59 private class FileData
65 #region INonSharedRegionModule Members
74 m_scene.EventManager.OnNewClient += NewClient;
76 m_scene.RegisterModuleInterface<
IXfer>(
this);
81 m_scene.EventManager.OnNewClient -= NewClient;
83 m_scene.UnregisterModuleInterface<
IXfer>(
this);
91 public Type ReplaceableInterface
102 get {
return "XferModule"; }
107 #region IXfer Members
121 if (NewFiles.ContainsKey(fileName))
123 NewFiles[fileName].Count++;
124 NewFiles[fileName].Data = data;
128 FileData fd =
new FileData();
131 NewFiles.Add(fileName, fd);
143 client.OnConfirmXfer += AckPacket;
157 if (NewFiles.ContainsKey(fileName))
159 if (!Transfers.ContainsKey(xferID))
161 byte[] fileData = NewFiles[fileName].Data;
163 if (fileName.StartsWith(
"inventory_"))
166 Transfers.Add(xferID, transaction);
169 RemoveXferData(xferID);
172 RemoveOrDecrement(fileName);
177 m_log.WarnFormat(
"[Xfer]: {0} not found", fileName);
186 if (Transfers.ContainsKey(xferID))
189 if (Transfers[xferID].AckPacket(packet))
191 RemoveXferData(xferID);
198 private void RemoveXferData(ulong xferID)
201 if (Transfers.ContainsKey(xferID))
205 Transfers.Remove(xferID);
206 xferItem.Data =
new byte[0];
207 xferItem.DataPointer = 0;
216 if (Transfers.ContainsKey(xferID))
217 RemoveOrDecrement(Transfers[xferID].FileName);
219 RemoveXferData(xferID);
223 private void RemoveOrDecrement(
string fileName)
227 if (NewFiles.ContainsKey(fileName))
229 if (NewFiles[fileName].Count == 1)
230 NewFiles.Remove(fileName);
232 NewFiles[fileName].Count--;
236 #region Nested type: XferDownLoad
241 private bool complete;
242 public byte[] Data =
new byte[0];
243 public int DataPointer = 0;
244 public string FileName = String.Empty;
245 public uint Packet = 0;
246 public uint Serial = 1;
247 public ulong XferID = 0;
248 public bool isTaskInventory =
false;
268 if (Data.Length < 1000)
271 byte[] transferData =
new byte[Data.Length + 4];
272 Array.Copy(Utils.IntToBytes(Data.Length), 0, transferData, 0, 4);
273 Array.Copy(Data, 0, transferData, 4, Data.Length);
274 Client.SendXferPacket(XferID, 0 + 0x80000000, transferData, isTaskInventory);
279 byte[] transferData =
new byte[1000 + 4];
280 Array.Copy(Utils.IntToBytes(Data.Length), 0, transferData, 0, 4);
281 Array.Copy(Data, 0, transferData, 4, 1000);
282 Client.SendXferPacket(XferID, 0, transferData, isTaskInventory);
299 if ((Data.Length - DataPointer) > 1000)
301 byte[] transferData =
new byte[1000];
302 Array.Copy(Data, DataPointer, transferData, 0, 1000);
303 Client.SendXferPacket(XferID, Packet, transferData, isTaskInventory);
309 byte[] transferData =
new byte[Data.Length - DataPointer];
310 Array.Copy(Data, DataPointer, transferData, 0, Data.Length - DataPointer);
311 uint endPacket = Packet |= (uint) 0x80000000;
312 Client.SendXferPacket(XferID, endPacket, transferData, isTaskInventory);
314 DataPointer += (Data.Length - DataPointer);
delegate void AbortXfer(IClientAPI remoteClient, ulong xferID)
void NewClient(IClientAPI client)
bool AckPacket(uint packet)
Respond to an ack packet from the client
void AbortXfer(IClientAPI remoteClient, ulong xferID)
void Close()
This is the inverse to Initialise. After a Close(), this instance won't be usable anymore...
void RemoveRegion(Scene scene)
This is called whenever a Scene is removed. For shared modules, this can happen several times...
void RequestXfer(IClientAPI remoteClient, ulong xferID, string fileName)
void AddRegion(Scene scene)
This is called whenever a Scene is added. For shared modules, this can happen several times...
void AckPacket(IClientAPI remoteClient, ulong xferID, uint packet)
void Initialise(IConfigSource config)
This is called to initialize the region module. For shared modules, this is called exactly once...
bool StartSend()
Start a transfer
Interactive OpenSim region server
bool AddNewFile(string fileName, byte[] data)
Let the Xfer module know about a file that the client is about to request. Caller is responsible for ...
delegate void RequestXfer(IClientAPI remoteClient, ulong xferID, string fileName)
XferDownLoad(string fileName, byte[] data, ulong xferID, IClientAPI client)
void RegionLoaded(Scene scene)
This will be called once for every scene loaded. In a shared module this will be multiple times in on...