aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/LindenUDP/LLFileTransfer.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack/LindenUDP/LLFileTransfer.cs')
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLFileTransfer.cs167
1 files changed, 133 insertions, 34 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLFileTransfer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLFileTransfer.cs
index 9d7b39e..e5783de 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLFileTransfer.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLFileTransfer.cs
@@ -40,18 +40,34 @@ using OpenSim.Region.Environment.Scenes;
40 40
41namespace OpenSim.Region.ClientStack.LindenUDP 41namespace OpenSim.Region.ClientStack.LindenUDP
42{ 42{
43 /// <summary>
44 /// A work in progress, to contain the SL specific file transfer code that is currently in various region modules
45 /// This file currently contains multiple classes that need to be split out into their own files.
46 /// </summary>
43 public class LLFileTransfer : IClientFileTransfer 47 public class LLFileTransfer : IClientFileTransfer
44 { 48 {
45 protected IClientAPI m_clientAPI; 49 protected IClientAPI m_clientAPI;
46 50
47 /// Dictionary of handlers for uploading files from client 51 /// Dictionary of handlers for uploading files from client
48 /// TODO: Need to add cleanup code to remove handlers that have completed their upload 52 /// TODO: Need to add cleanup code to remove handlers that have completed their upload
49 protected Dictionary<ulong, XferHandler> m_handlers; 53 protected Dictionary<ulong, XferUploadHandler> m_uploadHandlers;
50 protected object m_handlerLock = new object(); 54 protected object m_uploadHandlersLock = new object();
55
56
57 /// <summary>
58 /// Dictionary of files to be sent to clients
59 /// </summary>
60 protected static Dictionary<string, byte[]> m_files;
61
62 /// <summary>
63 /// Dictionary of Download Transfers in progess
64 /// </summary>
65 protected Dictionary<ulong, XferDownloadHandler> m_downloadHandlers = new Dictionary<ulong, XferDownloadHandler>();
66
51 67
52 public LLFileTransfer(IClientAPI clientAPI) 68 public LLFileTransfer(IClientAPI clientAPI)
53 { 69 {
54 m_handlers = new Dictionary<ulong, XferHandler>(); 70 m_uploadHandlers = new Dictionary<ulong, XferUploadHandler>();
55 m_clientAPI = clientAPI; 71 m_clientAPI = clientAPI;
56 72
57 m_clientAPI.OnXferReceive += XferReceive; 73 m_clientAPI.OnXferReceive += XferReceive;
@@ -72,10 +88,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
72 { 88 {
73 if ((String.IsNullOrEmpty(clientFileName)) || (uploadCompleteCallback == null)) 89 if ((String.IsNullOrEmpty(clientFileName)) || (uploadCompleteCallback == null))
74 { 90 {
75 return false; 91 return false;
76 } 92 }
77 93
78 XferHandler uploader = new XferHandler(m_clientAPI, clientFileName); 94 XferUploadHandler uploader = new XferUploadHandler(m_clientAPI, clientFileName);
79 95
80 return StartUpload(uploader, uploadCompleteCallback, abortCallback); 96 return StartUpload(uploader, uploadCompleteCallback, abortCallback);
81 } 97 }
@@ -87,12 +103,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
87 return false; 103 return false;
88 } 104 }
89 105
90 XferHandler uploader = new XferHandler(m_clientAPI, fileID); 106 XferUploadHandler uploader = new XferUploadHandler(m_clientAPI, fileID);
91 107
92 return StartUpload(uploader, uploadCompleteCallback, abortCallback); 108 return StartUpload(uploader, uploadCompleteCallback, abortCallback);
93 } 109 }
94 110
95 private bool StartUpload(XferHandler uploader, UploadComplete uploadCompleteCallback, UploadAborted abortCallback) 111 private bool StartUpload(XferUploadHandler uploader, UploadComplete uploadCompleteCallback, UploadAborted abortCallback)
96 { 112 {
97 uploader.UploadDone += uploadCompleteCallback; 113 uploader.UploadDone += uploadCompleteCallback;
98 uploader.UploadDone += RemoveXferHandler; 114 uploader.UploadDone += RemoveXferHandler;
@@ -102,11 +118,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
102 uploader.UploadAborted += abortCallback; 118 uploader.UploadAborted += abortCallback;
103 } 119 }
104 120
105 lock (m_handlerLock) 121 lock (m_uploadHandlersLock)
106 { 122 {
107 if (!m_handlers.ContainsKey(uploader.XferID)) 123 if (!m_uploadHandlers.ContainsKey(uploader.XferID))
108 { 124 {
109 m_handlers.Add(uploader.XferID, uploader); 125 m_uploadHandlers.Add(uploader.XferID, uploader);
110 uploader.RequestStartXfer(m_clientAPI); 126 uploader.RequestStartXfer(m_clientAPI);
111 return true; 127 return true;
112 } 128 }
@@ -126,37 +142,37 @@ namespace OpenSim.Region.ClientStack.LindenUDP
126 142
127 protected void AbortXferHandler(IClientAPI remoteClient, ulong xferID) 143 protected void AbortXferHandler(IClientAPI remoteClient, ulong xferID)
128 { 144 {
129 lock (m_handlerLock) 145 lock (m_uploadHandlersLock)
130 { 146 {
131 if (m_handlers.ContainsKey(xferID)) 147 if (m_uploadHandlers.ContainsKey(xferID))
132 { 148 {
133 m_handlers[xferID].AbortUpload(remoteClient); 149 m_uploadHandlers[xferID].AbortUpload(remoteClient);
134 m_handlers.Remove(xferID); 150 m_uploadHandlers.Remove(xferID);
135 } 151 }
136 } 152 }
137 } 153 }
138 154
139 protected void XferReceive(IClientAPI remoteClient, ulong xferID, uint packetID, byte[] data) 155 protected void XferReceive(IClientAPI remoteClient, ulong xferID, uint packetID, byte[] data)
140 { 156 {
141 lock (m_handlerLock) 157 lock (m_uploadHandlersLock)
142 { 158 {
143 if (m_handlers.ContainsKey(xferID)) 159 if (m_uploadHandlers.ContainsKey(xferID))
144 { 160 {
145 m_handlers[xferID].XferReceive(remoteClient, xferID, packetID, data); 161 m_uploadHandlers[xferID].XferReceive(remoteClient, xferID, packetID, data);
146 } 162 }
147 } 163 }
148 } 164 }
149 165
150 protected void RemoveXferHandler(string filename, UUID fileID, byte[] fileData, IClientAPI remoteClient) 166 protected void RemoveXferHandler(string filename, UUID fileID, ulong transferID, byte[] fileData, IClientAPI remoteClient)
151 { 167 {
152 168
153 } 169 }
154 } 170 }
155 171
156 public class XferHandler 172 public class XferUploadHandler
157 { 173 {
158 private AssetBase m_asset; 174 private AssetBase m_asset;
159 175
160 public event UploadComplete UploadDone; 176 public event UploadComplete UploadDone;
161 public event UploadAborted UploadAborted; 177 public event UploadAborted UploadAborted;
162 178
@@ -173,27 +189,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP
173 get { return m_complete; } 189 get { return m_complete; }
174 } 190 }
175 191
176 public XferHandler(IClientAPI pRemoteClient, string pClientFilename) 192 public XferUploadHandler(IClientAPI pRemoteClient, string pClientFilename)
177 { 193 {
194 Initialise(UUID.Zero, pClientFilename);
195 }
178 196
179 m_asset = new AssetBase(); 197 public XferUploadHandler(IClientAPI pRemoteClient, UUID fileID)
180 m_asset.FullID = UUID.Zero; 198 {
181 m_asset.Type = type; 199 Initialise(fileID, String.Empty);
182 m_asset.Data = new byte[0];
183 m_asset.Name = pClientFilename;
184 m_asset.Description = "empty";
185 m_asset.Local = true;
186 m_asset.Temporary = true;
187 mXferID = Util.GetNextXferID();
188 } 200 }
189 201
190 public XferHandler(IClientAPI pRemoteClient, UUID fileID) 202 private void Initialise(UUID fileID, string fileName)
191 { 203 {
192 m_asset = new AssetBase(); 204 m_asset = new AssetBase();
193 m_asset.FullID = fileID; 205 m_asset.FullID = fileID;
194 m_asset.Type = type; 206 m_asset.Type = type;
195 m_asset.Data = new byte[0]; 207 m_asset.Data = new byte[0];
196 m_asset.Name = String.Empty; 208 m_asset.Name = fileName;
197 m_asset.Description = "empty"; 209 m_asset.Description = "empty";
198 m_asset.Local = true; 210 m_asset.Local = true;
199 m_asset.Temporary = true; 211 m_asset.Temporary = true;
@@ -207,7 +219,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
207 219
208 public void RequestStartXfer(IClientAPI pRemoteClient) 220 public void RequestStartXfer(IClientAPI pRemoteClient)
209 { 221 {
210 if (!String.IsNullOrEmpty(m_asset.Name) ) 222 if (!String.IsNullOrEmpty(m_asset.Name))
211 { 223 {
212 pRemoteClient.SendXferRequest(mXferID, m_asset.Type, m_asset.FullID, 0, Utils.StringToBytes(m_asset.Name)); 224 pRemoteClient.SendXferRequest(mXferID, m_asset.Type, m_asset.FullID, 0, Utils.StringToBytes(m_asset.Name));
213 } 225 }
@@ -257,7 +269,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
257 handlerUploadDone = UploadDone; 269 handlerUploadDone = UploadDone;
258 if (handlerUploadDone != null) 270 if (handlerUploadDone != null)
259 { 271 {
260 handlerUploadDone(m_asset.Name, m_asset.FullID, m_asset.Data, remoteClient); 272 handlerUploadDone(m_asset.Name, m_asset.FullID, mXferID, m_asset.Data, remoteClient);
261 } 273 }
262 } 274 }
263 275
@@ -270,4 +282,91 @@ namespace OpenSim.Region.ClientStack.LindenUDP
270 } 282 }
271 } 283 }
272 } 284 }
285
286 public class XferDownloadHandler
287 {
288 public IClientAPI Client;
289 private bool complete;
290 public byte[] Data = new byte[0];
291 public int DataPointer = 0;
292 public string FileName = String.Empty;
293 public uint Packet = 0;
294 public uint Serial = 1;
295 public ulong XferID = 0;
296
297 public XferDownloadHandler(string fileName, byte[] data, ulong xferID, IClientAPI client)
298 {
299 FileName = fileName;
300 Data = data;
301 XferID = xferID;
302 Client = client;
303 }
304
305 public XferDownloadHandler()
306 {
307 }
308
309 /// <summary>
310 /// Start a transfer
311 /// </summary>
312 /// <returns>True if the transfer is complete, false if not</returns>
313 public bool StartSend()
314 {
315 if (Data.Length < 1000)
316 {
317 // for now (testing) we only support files under 1000 bytes
318 byte[] transferData = new byte[Data.Length + 4];
319 Array.Copy(Utils.IntToBytes(Data.Length), 0, transferData, 0, 4);
320 Array.Copy(Data, 0, transferData, 4, Data.Length);
321 Client.SendXferPacket(XferID, 0 + 0x80000000, transferData);
322
323 complete = true;
324 }
325 else
326 {
327 byte[] transferData = new byte[1000 + 4];
328 Array.Copy(Utils.IntToBytes(Data.Length), 0, transferData, 0, 4);
329 Array.Copy(Data, 0, transferData, 4, 1000);
330 Client.SendXferPacket(XferID, 0, transferData);
331 Packet++;
332 DataPointer = 1000;
333 }
334
335 return complete;
336 }
337
338 /// <summary>
339 /// Respond to an ack packet from the client
340 /// </summary>
341 /// <param name="packet"></param>
342 /// <returns>True if the transfer is complete, false otherwise</returns>
343 public bool AckPacket(uint packet)
344 {
345 if (!complete)
346 {
347 if ((Data.Length - DataPointer) > 1000)
348 {
349 byte[] transferData = new byte[1000];
350 Array.Copy(Data, DataPointer, transferData, 0, 1000);
351 Client.SendXferPacket(XferID, Packet, transferData);
352 Packet++;
353 DataPointer += 1000;
354 }
355 else
356 {
357 byte[] transferData = new byte[Data.Length - DataPointer];
358 Array.Copy(Data, DataPointer, transferData, 0, Data.Length - DataPointer);
359 uint endPacket = Packet |= (uint)0x80000000;
360 Client.SendXferPacket(XferID, endPacket, transferData);
361 Packet++;
362 DataPointer += (Data.Length - DataPointer);
363
364 complete = true;
365 }
366 }
367
368 return complete;
369 }
370 }
371
273} \ No newline at end of file 372} \ No newline at end of file