aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment/Modules/Agent/Xfer/XferModule.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Environment/Modules/Agent/Xfer/XferModule.cs')
-rw-r--r--OpenSim/Region/Environment/Modules/Agent/Xfer/XferModule.cs225
1 files changed, 225 insertions, 0 deletions
diff --git a/OpenSim/Region/Environment/Modules/Agent/Xfer/XferModule.cs b/OpenSim/Region/Environment/Modules/Agent/Xfer/XferModule.cs
new file mode 100644
index 0000000..b609f93
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/Agent/Xfer/XferModule.cs
@@ -0,0 +1,225 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using libsecondlife;
31using Nini.Config;
32using OpenSim.Framework;
33using OpenSim.Region.Environment.Interfaces;
34using OpenSim.Region.Environment.Scenes;
35
36namespace OpenSim.Region.Environment.Modules.Agent.Xfer
37{
38 public class XferModule : IRegionModule, IXfer
39 {
40 public Dictionary<string, byte[]> NewFiles = new Dictionary<string, byte[]>();
41 public Dictionary<ulong, XferDownLoad> Transfers = new Dictionary<ulong, XferDownLoad>();
42
43 private Scene m_scene;
44
45 public XferModule()
46 {
47 }
48
49 public void Initialise(Scene scene, IConfigSource config)
50 {
51 m_scene = scene;
52 m_scene.EventManager.OnNewClient += NewClient;
53
54 m_scene.RegisterModuleInterface<IXfer>(this);
55 }
56
57 public void PostInitialise()
58 {
59 }
60
61 public void Close()
62 {
63 }
64
65 public string Name
66 {
67 get { return "XferModule"; }
68 }
69
70 public bool IsSharedModule
71 {
72 get { return false; }
73 }
74
75 public void NewClient(IClientAPI client)
76 {
77 client.OnRequestXfer += RequestXfer;
78 client.OnConfirmXfer += AckPacket;
79 }
80
81 /// <summary>
82 ///
83 /// </summary>
84 /// <param name="remoteClient"></param>
85 /// <param name="xferID"></param>
86 /// <param name="fileName"></param>
87 public void RequestXfer(IClientAPI remoteClient, ulong xferID, string fileName)
88 {
89 lock (NewFiles)
90 {
91 if (NewFiles.ContainsKey(fileName))
92 {
93 if (!Transfers.ContainsKey(xferID))
94 {
95 byte[] fileData = NewFiles[fileName];
96 XferDownLoad transaction = new XferDownLoad(fileName, fileData, xferID, remoteClient);
97 Transfers.Add(xferID, transaction);
98 NewFiles.Remove(fileName);
99
100 if (transaction.StartSend())
101 {
102 Transfers.Remove(xferID);
103 }
104 }
105 }
106 }
107 }
108
109 public void AckPacket(IClientAPI remoteClient, ulong xferID, uint packet)
110 {
111 if (Transfers.ContainsKey(xferID))
112 {
113 if (Transfers[xferID].AckPacket(packet))
114 {
115 {
116 Transfers.Remove(xferID);
117 }
118 }
119 }
120 }
121
122 public bool AddNewFile(string fileName, byte[] data)
123 {
124 lock (NewFiles)
125 {
126 if (NewFiles.ContainsKey(fileName))
127 {
128 NewFiles[fileName] = data;
129 }
130 else
131 {
132 NewFiles.Add(fileName, data);
133 }
134 }
135 return true;
136 }
137
138
139 public class XferDownLoad
140 {
141 public byte[] Data = new byte[0];
142 public string FileName = String.Empty;
143 public ulong XferID = 0;
144 public int DataPointer = 0;
145 public uint Packet = 0;
146 public IClientAPI Client;
147 public uint Serial = 1;
148 private bool complete;
149
150 public XferDownLoad(string fileName, byte[] data, ulong xferID, IClientAPI client)
151 {
152 FileName = fileName;
153 Data = data;
154 XferID = xferID;
155 Client = client;
156 }
157
158 public XferDownLoad()
159 {
160 }
161
162 /// <summary>
163 /// Start a transfer
164 /// </summary>
165 /// <returns>True if the transfer is complete, false if not</returns>
166 public bool StartSend()
167 {
168 if (Data.Length < 1000)
169 {
170 // for now (testing ) we only support files under 1000 bytes
171 byte[] transferData = new byte[Data.Length + 4];
172 Array.Copy(Helpers.IntToBytes(Data.Length), 0, transferData, 0, 4);
173 Array.Copy(Data, 0, transferData, 4, Data.Length);
174 Client.SendXferPacket(XferID, 0 + 0x80000000, transferData);
175
176 complete = true;
177 }
178 else
179 {
180 byte[] transferData = new byte[1000 + 4];
181 Array.Copy(Helpers.IntToBytes(Data.Length), 0, transferData, 0, 4);
182 Array.Copy(Data, 0, transferData, 4, 1000);
183 Client.SendXferPacket(XferID, 0, transferData);
184 Packet++;
185 DataPointer = 1000;
186 }
187
188 return complete;
189 }
190
191 /// <summary>
192 /// Respond to an ack packet from the client
193 /// </summary>
194 /// <param name="packet"></param>
195 /// <returns>True if the transfer is complete, false otherwise</returns>
196 public bool AckPacket(uint packet)
197 {
198 if (!complete)
199 {
200 if ((Data.Length - DataPointer) > 1000)
201 {
202 byte[] transferData = new byte[1000];
203 Array.Copy(Data, DataPointer, transferData, 0, 1000);
204 Client.SendXferPacket(XferID, Packet, transferData);
205 Packet++;
206 DataPointer += 1000;
207 }
208 else
209 {
210 byte[] transferData = new byte[Data.Length - DataPointer];
211 Array.Copy(Data, DataPointer, transferData, 0, Data.Length - DataPointer);
212 uint endPacket = Packet |= (uint) 0x80000000;
213 Client.SendXferPacket(XferID, endPacket, transferData);
214 Packet++;
215 DataPointer += (Data.Length - DataPointer);
216
217 complete = true;
218 }
219 }
220
221 return complete;
222 }
223 }
224 }
225} \ No newline at end of file