diff options
Diffstat (limited to 'OpenSim/Region/ClientStack/LindenUDP/LLFileTransfer.cs')
-rw-r--r-- | OpenSim/Region/ClientStack/LindenUDP/LLFileTransfer.cs | 202 |
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 @@ | |||
1 | using System; | ||
2 | using System.Collections.Generic; | ||
3 | using System.Text; | ||
4 | using System.Xml; | ||
5 | using OpenMetaverse; | ||
6 | using OpenMetaverse.Packets; | ||
7 | using OpenSim.Framework; | ||
8 | using OpenSim.Framework.Client; | ||
9 | using OpenSim.Framework.Communications.Cache; | ||
10 | using OpenSim.Framework.Statistics; | ||
11 | using OpenSim.Region.Interfaces; | ||
12 | using OpenSim.Region.Environment.Scenes; | ||
13 | |||
14 | namespace 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 | } | ||