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.cs202
1 files changed, 202 insertions, 0 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLFileTransfer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLFileTransfer.cs
new file mode 100644
index 0000000..27ebfdd
--- /dev/null
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLFileTransfer.cs
@@ -0,0 +1,202 @@
1using System;
2using System.Collections.Generic;
3using System.Text;
4using System.Xml;
5using OpenMetaverse;
6using OpenMetaverse.Packets;
7using OpenSim.Framework;
8using OpenSim.Framework.Client;
9using OpenSim.Framework.Communications.Cache;
10using OpenSim.Framework.Statistics;
11using OpenSim.Region.Interfaces;
12using OpenSim.Region.Environment.Scenes;
13
14namespace OpenSim.Region.ClientStack.LindenUDP
15{
16 public delegate void UploadComplete(string filename, byte[] fileData, IClientAPI remoteClient);
17 public delegate void UploadAborted(string filename, ulong id, IClientAPI remoteClient);
18
19 public class LLFileTransfer
20 {
21 protected IClientAPI m_clientAPI;
22
23 protected Dictionary<ulong, XferHandler> m_handlers;
24 protected object m_handlerLock = new object();
25
26 public LLFileTransfer(IClientAPI clientAPI)
27 {
28 m_handlers = new Dictionary<ulong, XferHandler>();
29 m_clientAPI = clientAPI;
30
31 m_clientAPI.OnXferReceive += XferReceive;
32 m_clientAPI.OnAbortXfer += AbortXferHandler;
33 }
34
35 public void Close()
36 {
37 if (m_clientAPI != null)
38 {
39 m_clientAPI.OnXferReceive -= XferReceive;
40 m_clientAPI.OnAbortXfer -= AbortXferHandler;
41 m_clientAPI = null;
42 }
43 }
44
45 public bool RequestUpload(string clientFileName, UploadComplete uploadCompleteCallback, UploadAborted abortCallback)
46 {
47 if ((String.IsNullOrEmpty(clientFileName)) || (uploadCompleteCallback == null))
48 {
49 return false;
50 }
51
52 XferHandler uploader = new XferHandler(m_clientAPI, clientFileName);
53 uploader.UploadDone += uploadCompleteCallback;
54
55 if (abortCallback != null)
56 {
57 uploader.UploadAborted += abortCallback;
58 }
59
60 lock (m_handlerLock)
61 {
62 if (!m_handlers.ContainsKey(uploader.XferID))
63 {
64 m_handlers.Add(uploader.XferID, uploader);
65 uploader.RequestStartXfer(m_clientAPI);
66 return true;
67 }
68 else
69 {
70 // something went wrong with the xferID allocation
71 uploader.UploadDone -= uploadCompleteCallback;
72 if (abortCallback != null)
73 {
74 uploader.UploadAborted -= abortCallback;
75 }
76 return false;
77 }
78 }
79 }
80
81 protected void AbortXferHandler(IClientAPI remoteClient, ulong xferID)
82 {
83 lock (m_handlerLock)
84 {
85 if (m_handlers.ContainsKey(xferID))
86 {
87 m_handlers[xferID].AbortUpload(remoteClient);
88 m_handlers.Remove(xferID);
89 }
90 }
91 }
92
93 protected void XferReceive(IClientAPI remoteClient, ulong xferID, uint packetID, byte[] data)
94 {
95 lock (m_handlerLock)
96 {
97 if (m_handlers.ContainsKey(xferID))
98 {
99 m_handlers[xferID].XferReceive(remoteClient, xferID, packetID, data);
100 }
101 }
102 }
103 }
104
105 public class XferHandler
106 {
107 private AssetBase m_asset;
108
109 public event UploadComplete UploadDone;
110 public event UploadAborted UploadAborted;
111
112 private sbyte type = 0;
113
114 public ulong mXferID;
115 private UploadComplete handlerUploadDone;
116 private UploadAborted handlerAbort;
117
118 private bool m_complete = false;
119
120 public bool UploadComplete
121 {
122 get { return m_complete; }
123 }
124
125 public XferHandler(IClientAPI pRemoteClient, string pClientFilename)
126 {
127
128 m_asset = new AssetBase();
129 m_asset.FullID = UUID.Zero;
130 m_asset.Type = type;
131 m_asset.Data = new byte[0];
132 m_asset.Name = pClientFilename;
133 m_asset.Description = "empty";
134 m_asset.Local = true;
135 m_asset.Temporary = true;
136 mXferID = Util.GetNextXferID();
137 }
138
139 public ulong XferID
140 {
141 get { return mXferID; }
142 }
143
144 public void RequestStartXfer(IClientAPI pRemoteClient)
145 {
146 pRemoteClient.SendXferRequest(mXferID, m_asset.Type, m_asset.FullID, 0, Utils.StringToBytes(m_asset.Name));
147 }
148
149 /// <summary>
150 /// Process transfer data received from the client.
151 /// </summary>
152 /// <param name="xferID"></param>
153 /// <param name="packetID"></param>
154 /// <param name="data"></param>
155 public void XferReceive(IClientAPI remoteClient, ulong xferID, uint packetID, byte[] data)
156 {
157 if (mXferID == xferID)
158 {
159 if (m_asset.Data.Length > 1)
160 {
161 byte[] destinationArray = new byte[m_asset.Data.Length + data.Length];
162 Array.Copy(m_asset.Data, 0, destinationArray, 0, m_asset.Data.Length);
163 Array.Copy(data, 0, destinationArray, m_asset.Data.Length, data.Length);
164 m_asset.Data = destinationArray;
165 }
166 else
167 {
168 byte[] buffer2 = new byte[data.Length - 4];
169 Array.Copy(data, 4, buffer2, 0, data.Length - 4);
170 m_asset.Data = buffer2;
171 }
172
173 remoteClient.SendConfirmXfer(xferID, packetID);
174
175 if ((packetID & 0x80000000) != 0)
176 {
177 SendCompleteMessage(remoteClient);
178
179 }
180 }
181 }
182
183 protected void SendCompleteMessage(IClientAPI remoteClient)
184 {
185 m_complete = true;
186 handlerUploadDone = UploadDone;
187 if (handlerUploadDone != null)
188 {
189 handlerUploadDone(m_asset.Name, m_asset.Data, remoteClient);
190 }
191 }
192
193 public void AbortUpload(IClientAPI remoteClient)
194 {
195 handlerAbort = UploadAborted;
196 if (handlerAbort != null)
197 {
198 handlerAbort(m_asset.Name, mXferID, remoteClient);
199 }
200 }
201 }
202}