aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/LindenUDP/LLFileTransfer.cs
diff options
context:
space:
mode:
authorMW2008-12-15 21:46:57 +0000
committerMW2008-12-15 21:46:57 +0000
commit1110ee877ff0cdd17098b5035f147542ccd5ca87 (patch)
treee782f46dc21907f8cbdfb419c91518e6ab57c5cf /OpenSim/Region/ClientStack/LindenUDP/LLFileTransfer.cs
parentAttempt at restoring inventory access after TPs/crossings. RemoveClient in Sc... (diff)
downloadopensim-SC-1110ee877ff0cdd17098b5035f147542ccd5ca87.zip
opensim-SC-1110ee877ff0cdd17098b5035f147542ccd5ca87.tar.gz
opensim-SC-1110ee877ff0cdd17098b5035f147542ccd5ca87.tar.bz2
opensim-SC-1110ee877ff0cdd17098b5035f147542ccd5ca87.tar.xz
More work on moving Xfer file transfer handling code to the Client stack from the various region modules that it is currently in.
Still not enabled yet.
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