diff options
author | MW | 2007-06-27 15:28:52 +0000 |
---|---|---|
committer | MW | 2007-06-27 15:28:52 +0000 |
commit | 646bbbc84b8010e0dacbeed5342cdb045f46cc49 (patch) | |
tree | 770b34d19855363c3c113ab9a0af9a56d821d887 /OpenSim/Region/ClientStack | |
download | opensim-SC-646bbbc84b8010e0dacbeed5342cdb045f46cc49.zip opensim-SC-646bbbc84b8010e0dacbeed5342cdb045f46cc49.tar.gz opensim-SC-646bbbc84b8010e0dacbeed5342cdb045f46cc49.tar.bz2 opensim-SC-646bbbc84b8010e0dacbeed5342cdb045f46cc49.tar.xz |
Some work on restructuring the namespaces / project names. Note this doesn't compile yet as not all the code has been changed to use the new namespaces. Am committing it now for feedback on the namespaces.
Diffstat (limited to 'OpenSim/Region/ClientStack')
-rw-r--r-- | OpenSim/Region/ClientStack/Assets/InventoryCache.cs | 337 | ||||
-rw-r--r-- | OpenSim/Region/ClientStack/ClientStackNetworkHandler.cs | 46 | ||||
-rw-r--r-- | OpenSim/Region/ClientStack/ClientView.API.cs | 975 | ||||
-rw-r--r-- | OpenSim/Region/ClientStack/ClientView.AgentAssetUpload.cs | 358 | ||||
-rw-r--r-- | OpenSim/Region/ClientStack/ClientView.PacketHandlers.cs | 198 | ||||
-rw-r--r-- | OpenSim/Region/ClientStack/ClientView.ProcessPackets.cs | 550 | ||||
-rw-r--r-- | OpenSim/Region/ClientStack/ClientView.cs | 273 | ||||
-rw-r--r-- | OpenSim/Region/ClientStack/ClientViewBase.cs | 327 | ||||
-rw-r--r-- | OpenSim/Region/ClientStack/OpenSim.Region.ClientStack.csproj | 173 | ||||
-rw-r--r-- | OpenSim/Region/ClientStack/OpenSim.Region.ClientStack.csproj.user | 12 | ||||
-rw-r--r-- | OpenSim/Region/ClientStack/PacketServer.cs | 183 | ||||
-rw-r--r-- | OpenSim/Region/ClientStack/RegionApplicationBase.cs | 129 | ||||
-rw-r--r-- | OpenSim/Region/ClientStack/UDPServer.cs | 208 | ||||
-rw-r--r-- | OpenSim/Region/ClientStack/VersionInfo.cs | 38 |
14 files changed, 3807 insertions, 0 deletions
diff --git a/OpenSim/Region/ClientStack/Assets/InventoryCache.cs b/OpenSim/Region/ClientStack/Assets/InventoryCache.cs new file mode 100644 index 0000000..5d5021c --- /dev/null +++ b/OpenSim/Region/ClientStack/Assets/InventoryCache.cs | |||
@@ -0,0 +1,337 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://www.openmetaverse.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 | */ | ||
28 | |||
29 | using System; | ||
30 | using System.Collections.Generic; | ||
31 | using libsecondlife; | ||
32 | using OpenSim; | ||
33 | using libsecondlife.Packets; | ||
34 | //using OpenSim.GridServers; | ||
35 | using OpenSim.Framework.Inventory; | ||
36 | using OpenSim.Framework.Types; | ||
37 | using OpenSim.Framework.Interfaces; | ||
38 | |||
39 | namespace OpenSim.Assets | ||
40 | { | ||
41 | /// <summary> | ||
42 | /// Description of InventoryManager. | ||
43 | /// </summary> | ||
44 | public class InventoryCache | ||
45 | { | ||
46 | private Dictionary<LLUUID, AgentInventory> _agentsInventory; | ||
47 | private List<UserServerRequest> _serverRequests; //list of requests made to user server. | ||
48 | private System.Text.Encoding _enc = System.Text.Encoding.ASCII; | ||
49 | private const uint FULL_MASK_PERMISSIONS = 2147483647; | ||
50 | |||
51 | public InventoryCache() | ||
52 | { | ||
53 | _agentsInventory = new Dictionary<LLUUID, AgentInventory>(); | ||
54 | _serverRequests = new List<UserServerRequest>(); | ||
55 | } | ||
56 | |||
57 | public void AddNewAgentsInventory(AgentInventory agentInventory) | ||
58 | { | ||
59 | if (!this._agentsInventory.ContainsKey(agentInventory.AgentID)) | ||
60 | { | ||
61 | this._agentsInventory.Add(agentInventory.AgentID, agentInventory); | ||
62 | } | ||
63 | } | ||
64 | |||
65 | public AgentInventory FetchAgentsInventory(LLUUID agentID, IUserServer userserver) | ||
66 | { | ||
67 | AgentInventory res = null; | ||
68 | if (!this._agentsInventory.ContainsKey(agentID)) | ||
69 | { | ||
70 | res = userserver.RequestAgentsInventory(agentID); | ||
71 | this._agentsInventory.Add(agentID,res); | ||
72 | } | ||
73 | return res; | ||
74 | } | ||
75 | |||
76 | public AgentInventory GetAgentsInventory(LLUUID agentID) | ||
77 | { | ||
78 | if (this._agentsInventory.ContainsKey(agentID)) | ||
79 | { | ||
80 | return this._agentsInventory[agentID]; | ||
81 | } | ||
82 | |||
83 | return null; | ||
84 | } | ||
85 | |||
86 | public void ClientLeaving(LLUUID clientID, IUserServer userserver) | ||
87 | { | ||
88 | if (this._agentsInventory.ContainsKey(clientID)) | ||
89 | { | ||
90 | if (userserver != null) | ||
91 | { | ||
92 | userserver.UpdateAgentsInventory(clientID, this._agentsInventory[clientID]); | ||
93 | } | ||
94 | this._agentsInventory.Remove(clientID); | ||
95 | } | ||
96 | } | ||
97 | |||
98 | public bool CreateNewInventoryFolder(ClientView remoteClient, LLUUID folderID) | ||
99 | { | ||
100 | return this.CreateNewInventoryFolder(remoteClient, folderID, 0); | ||
101 | } | ||
102 | |||
103 | public bool CreateNewInventoryFolder(ClientView remoteClient, LLUUID folderID, ushort type) | ||
104 | { | ||
105 | bool res = false; | ||
106 | if (folderID != LLUUID.Zero) //don't create a folder with a zero id | ||
107 | { | ||
108 | if (this._agentsInventory.ContainsKey(remoteClient.AgentID)) | ||
109 | { | ||
110 | res = this._agentsInventory[remoteClient.AgentID].CreateNewFolder(folderID, type); | ||
111 | } | ||
112 | } | ||
113 | return res; | ||
114 | } | ||
115 | |||
116 | public bool CreateNewInventoryFolder(ClientView remoteClient, LLUUID folderID, ushort type, string folderName, LLUUID parent) | ||
117 | { | ||
118 | bool res = false; | ||
119 | if (folderID != LLUUID.Zero) //don't create a folder with a zero id | ||
120 | { | ||
121 | if (this._agentsInventory.ContainsKey(remoteClient.AgentID)) | ||
122 | { | ||
123 | res = this._agentsInventory[remoteClient.AgentID].CreateNewFolder(folderID, type, folderName, parent); | ||
124 | } | ||
125 | } | ||
126 | return res; | ||
127 | } | ||
128 | |||
129 | public LLUUID AddNewInventoryItem(ClientView remoteClient, LLUUID folderID, OpenSim.Framework.Types.AssetBase asset) | ||
130 | { | ||
131 | LLUUID newItem = null; | ||
132 | if (this._agentsInventory.ContainsKey(remoteClient.AgentID)) | ||
133 | { | ||
134 | newItem = this._agentsInventory[remoteClient.AgentID].AddToInventory(folderID, asset); | ||
135 | if (newItem != null) | ||
136 | { | ||
137 | InventoryItem Item = this._agentsInventory[remoteClient.AgentID].InventoryItems[newItem]; | ||
138 | this.SendItemUpdateCreate(remoteClient, Item); | ||
139 | } | ||
140 | } | ||
141 | |||
142 | return newItem; | ||
143 | } | ||
144 | public bool DeleteInventoryItem(ClientView remoteClient, LLUUID itemID) | ||
145 | { | ||
146 | bool res = false; | ||
147 | if (this._agentsInventory.ContainsKey(remoteClient.AgentID)) | ||
148 | { | ||
149 | res = this._agentsInventory[remoteClient.AgentID].DeleteFromInventory(itemID); | ||
150 | if (res) | ||
151 | { | ||
152 | RemoveInventoryItemPacket remove = new RemoveInventoryItemPacket(); | ||
153 | remove.AgentData.AgentID = remoteClient.AgentID; | ||
154 | remove.AgentData.SessionID = remoteClient.SessionID; | ||
155 | remove.InventoryData = new RemoveInventoryItemPacket.InventoryDataBlock[1]; | ||
156 | remove.InventoryData[0] = new RemoveInventoryItemPacket.InventoryDataBlock(); | ||
157 | remove.InventoryData[0].ItemID = itemID; | ||
158 | remoteClient.OutPacket(remove); | ||
159 | } | ||
160 | } | ||
161 | |||
162 | return res; | ||
163 | } | ||
164 | |||
165 | public bool UpdateInventoryItemAsset(ClientView remoteClient, LLUUID itemID, OpenSim.Framework.Types.AssetBase asset) | ||
166 | { | ||
167 | if (this._agentsInventory.ContainsKey(remoteClient.AgentID)) | ||
168 | { | ||
169 | bool res = _agentsInventory[remoteClient.AgentID].UpdateItemAsset(itemID, asset); | ||
170 | if (res) | ||
171 | { | ||
172 | InventoryItem Item = this._agentsInventory[remoteClient.AgentID].InventoryItems[itemID]; | ||
173 | this.SendItemUpdateCreate(remoteClient, Item); | ||
174 | } | ||
175 | return res; | ||
176 | } | ||
177 | |||
178 | return false; | ||
179 | } | ||
180 | |||
181 | public bool UpdateInventoryItemDetails(ClientView remoteClient, LLUUID itemID, UpdateInventoryItemPacket.InventoryDataBlock packet) | ||
182 | { | ||
183 | if (this._agentsInventory.ContainsKey(remoteClient.AgentID)) | ||
184 | { | ||
185 | bool res = _agentsInventory[remoteClient.AgentID].UpdateItemDetails(itemID, packet); | ||
186 | if (res) | ||
187 | { | ||
188 | InventoryItem Item = this._agentsInventory[remoteClient.AgentID].InventoryItems[itemID]; | ||
189 | this.SendItemUpdateCreate(remoteClient, Item); | ||
190 | } | ||
191 | return res; | ||
192 | } | ||
193 | |||
194 | return false; | ||
195 | } | ||
196 | |||
197 | public void FetchInventoryDescendents(ClientView userInfo, FetchInventoryDescendentsPacket FetchDescend) | ||
198 | { | ||
199 | if (this._agentsInventory.ContainsKey(userInfo.AgentID)) | ||
200 | { | ||
201 | AgentInventory agentInventory = this._agentsInventory[userInfo.AgentID]; | ||
202 | if (FetchDescend.InventoryData.FetchItems) | ||
203 | { | ||
204 | if (agentInventory.InventoryFolders.ContainsKey(FetchDescend.InventoryData.FolderID)) | ||
205 | { | ||
206 | InventoryFolder Folder = agentInventory.InventoryFolders[FetchDescend.InventoryData.FolderID]; | ||
207 | InventoryDescendentsPacket Descend = new InventoryDescendentsPacket(); | ||
208 | Descend.AgentData.AgentID = userInfo.AgentID; | ||
209 | Descend.AgentData.OwnerID = Folder.OwnerID; | ||
210 | Descend.AgentData.FolderID = FetchDescend.InventoryData.FolderID; | ||
211 | Descend.AgentData.Descendents = Folder.Items.Count; | ||
212 | Descend.AgentData.Version = Folder.Items.Count; | ||
213 | |||
214 | |||
215 | Descend.ItemData = new InventoryDescendentsPacket.ItemDataBlock[Folder.Items.Count]; | ||
216 | for (int i = 0; i < Folder.Items.Count; i++) | ||
217 | { | ||
218 | |||
219 | InventoryItem Item = Folder.Items[i]; | ||
220 | Descend.ItemData[i] = new InventoryDescendentsPacket.ItemDataBlock(); | ||
221 | Descend.ItemData[i].ItemID = Item.ItemID; | ||
222 | Descend.ItemData[i].AssetID = Item.AssetID; | ||
223 | Descend.ItemData[i].CreatorID = Item.CreatorID; | ||
224 | Descend.ItemData[i].BaseMask = FULL_MASK_PERMISSIONS; | ||
225 | Descend.ItemData[i].CreationDate = 1000; | ||
226 | Descend.ItemData[i].Description = _enc.GetBytes(Item.Description + "\0"); | ||
227 | Descend.ItemData[i].EveryoneMask = FULL_MASK_PERMISSIONS; | ||
228 | Descend.ItemData[i].Flags = 1; | ||
229 | Descend.ItemData[i].FolderID = Item.FolderID; | ||
230 | Descend.ItemData[i].GroupID = new LLUUID("00000000-0000-0000-0000-000000000000"); | ||
231 | Descend.ItemData[i].GroupMask = FULL_MASK_PERMISSIONS; | ||
232 | Descend.ItemData[i].InvType = Item.InvType; | ||
233 | Descend.ItemData[i].Name = _enc.GetBytes(Item.Name + "\0"); | ||
234 | Descend.ItemData[i].NextOwnerMask = FULL_MASK_PERMISSIONS; | ||
235 | Descend.ItemData[i].OwnerID = Item.OwnerID; | ||
236 | Descend.ItemData[i].OwnerMask = FULL_MASK_PERMISSIONS; | ||
237 | Descend.ItemData[i].SalePrice = 100; | ||
238 | Descend.ItemData[i].SaleType = 0; | ||
239 | Descend.ItemData[i].Type = Item.Type; | ||
240 | Descend.ItemData[i].CRC = libsecondlife.Helpers.InventoryCRC(1000, 0, Descend.ItemData[i].InvType, Descend.ItemData[i].Type, Descend.ItemData[i].AssetID, Descend.ItemData[i].GroupID, 100, Descend.ItemData[i].OwnerID, Descend.ItemData[i].CreatorID, Descend.ItemData[i].ItemID, Descend.ItemData[i].FolderID, FULL_MASK_PERMISSIONS, 1, FULL_MASK_PERMISSIONS, FULL_MASK_PERMISSIONS, FULL_MASK_PERMISSIONS); | ||
241 | } | ||
242 | |||
243 | userInfo.OutPacket(Descend); | ||
244 | |||
245 | } | ||
246 | } | ||
247 | else | ||
248 | { | ||
249 | Console.WriteLine("fetch subfolders"); | ||
250 | } | ||
251 | } | ||
252 | } | ||
253 | |||
254 | public void FetchInventory(ClientView userInfo, FetchInventoryPacket FetchItems) | ||
255 | { | ||
256 | if (this._agentsInventory.ContainsKey(userInfo.AgentID)) | ||
257 | { | ||
258 | AgentInventory agentInventory = this._agentsInventory[userInfo.AgentID]; | ||
259 | |||
260 | for (int i = 0; i < FetchItems.InventoryData.Length; i++) | ||
261 | { | ||
262 | if (agentInventory.InventoryItems.ContainsKey(FetchItems.InventoryData[i].ItemID)) | ||
263 | { | ||
264 | InventoryItem Item = agentInventory.InventoryItems[FetchItems.InventoryData[i].ItemID]; | ||
265 | FetchInventoryReplyPacket InventoryReply = new FetchInventoryReplyPacket(); | ||
266 | InventoryReply.AgentData.AgentID = userInfo.AgentID; | ||
267 | InventoryReply.InventoryData = new FetchInventoryReplyPacket.InventoryDataBlock[1]; | ||
268 | InventoryReply.InventoryData[0] = new FetchInventoryReplyPacket.InventoryDataBlock(); | ||
269 | InventoryReply.InventoryData[0].ItemID = Item.ItemID; | ||
270 | InventoryReply.InventoryData[0].AssetID = Item.AssetID; | ||
271 | InventoryReply.InventoryData[0].CreatorID = Item.CreatorID; | ||
272 | InventoryReply.InventoryData[0].BaseMask = FULL_MASK_PERMISSIONS; | ||
273 | InventoryReply.InventoryData[0].CreationDate = (int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds; | ||
274 | InventoryReply.InventoryData[0].Description = _enc.GetBytes(Item.Description + "\0"); | ||
275 | InventoryReply.InventoryData[0].EveryoneMask = FULL_MASK_PERMISSIONS; | ||
276 | InventoryReply.InventoryData[0].Flags = 0; | ||
277 | InventoryReply.InventoryData[0].FolderID = Item.FolderID; | ||
278 | InventoryReply.InventoryData[0].GroupID = new LLUUID("00000000-0000-0000-0000-000000000000"); | ||
279 | InventoryReply.InventoryData[0].GroupMask = FULL_MASK_PERMISSIONS; | ||
280 | InventoryReply.InventoryData[0].InvType = Item.InvType; | ||
281 | InventoryReply.InventoryData[0].Name = _enc.GetBytes(Item.Name + "\0"); | ||
282 | InventoryReply.InventoryData[0].NextOwnerMask = FULL_MASK_PERMISSIONS; | ||
283 | InventoryReply.InventoryData[0].OwnerID = Item.OwnerID; | ||
284 | InventoryReply.InventoryData[0].OwnerMask = FULL_MASK_PERMISSIONS; | ||
285 | InventoryReply.InventoryData[0].SalePrice = 100; | ||
286 | InventoryReply.InventoryData[0].SaleType = 0; | ||
287 | InventoryReply.InventoryData[0].Type = Item.Type; | ||
288 | InventoryReply.InventoryData[0].CRC = libsecondlife.Helpers.InventoryCRC(1000, 0, InventoryReply.InventoryData[0].InvType, InventoryReply.InventoryData[0].Type, InventoryReply.InventoryData[0].AssetID, InventoryReply.InventoryData[0].GroupID, 100, InventoryReply.InventoryData[0].OwnerID, InventoryReply.InventoryData[0].CreatorID, InventoryReply.InventoryData[0].ItemID, InventoryReply.InventoryData[0].FolderID, FULL_MASK_PERMISSIONS, 1, FULL_MASK_PERMISSIONS, FULL_MASK_PERMISSIONS, FULL_MASK_PERMISSIONS); | ||
289 | userInfo.OutPacket(InventoryReply); | ||
290 | } | ||
291 | } | ||
292 | } | ||
293 | } | ||
294 | |||
295 | private void SendItemUpdateCreate(ClientView remoteClient, InventoryItem Item) | ||
296 | { | ||
297 | |||
298 | UpdateCreateInventoryItemPacket InventoryReply = new UpdateCreateInventoryItemPacket(); | ||
299 | InventoryReply.AgentData.AgentID = remoteClient.AgentID; | ||
300 | InventoryReply.AgentData.SimApproved = true; | ||
301 | InventoryReply.InventoryData = new UpdateCreateInventoryItemPacket.InventoryDataBlock[1]; | ||
302 | InventoryReply.InventoryData[0] = new UpdateCreateInventoryItemPacket.InventoryDataBlock(); | ||
303 | InventoryReply.InventoryData[0].ItemID = Item.ItemID; | ||
304 | InventoryReply.InventoryData[0].AssetID = Item.AssetID; | ||
305 | InventoryReply.InventoryData[0].CreatorID = Item.CreatorID; | ||
306 | InventoryReply.InventoryData[0].BaseMask = FULL_MASK_PERMISSIONS; | ||
307 | InventoryReply.InventoryData[0].CreationDate = 1000; | ||
308 | InventoryReply.InventoryData[0].Description = _enc.GetBytes(Item.Description + "\0"); | ||
309 | InventoryReply.InventoryData[0].EveryoneMask = FULL_MASK_PERMISSIONS; | ||
310 | InventoryReply.InventoryData[0].Flags = 0; | ||
311 | InventoryReply.InventoryData[0].FolderID = Item.FolderID; | ||
312 | InventoryReply.InventoryData[0].GroupID = new LLUUID("00000000-0000-0000-0000-000000000000"); | ||
313 | InventoryReply.InventoryData[0].GroupMask = FULL_MASK_PERMISSIONS; | ||
314 | InventoryReply.InventoryData[0].InvType = Item.InvType; | ||
315 | InventoryReply.InventoryData[0].Name = _enc.GetBytes(Item.Name + "\0"); | ||
316 | InventoryReply.InventoryData[0].NextOwnerMask = FULL_MASK_PERMISSIONS; | ||
317 | InventoryReply.InventoryData[0].OwnerID = Item.OwnerID; | ||
318 | InventoryReply.InventoryData[0].OwnerMask = FULL_MASK_PERMISSIONS; | ||
319 | InventoryReply.InventoryData[0].SalePrice = 100; | ||
320 | InventoryReply.InventoryData[0].SaleType = 0; | ||
321 | InventoryReply.InventoryData[0].Type = Item.Type; | ||
322 | InventoryReply.InventoryData[0].CRC = libsecondlife.Helpers.InventoryCRC(1000, 0, InventoryReply.InventoryData[0].InvType, InventoryReply.InventoryData[0].Type, InventoryReply.InventoryData[0].AssetID, InventoryReply.InventoryData[0].GroupID, 100, InventoryReply.InventoryData[0].OwnerID, InventoryReply.InventoryData[0].CreatorID, InventoryReply.InventoryData[0].ItemID, InventoryReply.InventoryData[0].FolderID, FULL_MASK_PERMISSIONS, 1, FULL_MASK_PERMISSIONS, FULL_MASK_PERMISSIONS, FULL_MASK_PERMISSIONS); | ||
323 | |||
324 | remoteClient.OutPacket(InventoryReply); | ||
325 | } | ||
326 | } | ||
327 | |||
328 | |||
329 | |||
330 | public class UserServerRequest | ||
331 | { | ||
332 | public UserServerRequest() | ||
333 | { | ||
334 | |||
335 | } | ||
336 | } | ||
337 | } | ||
diff --git a/OpenSim/Region/ClientStack/ClientStackNetworkHandler.cs b/OpenSim/Region/ClientStack/ClientStackNetworkHandler.cs new file mode 100644 index 0000000..7552195 --- /dev/null +++ b/OpenSim/Region/ClientStack/ClientStackNetworkHandler.cs | |||
@@ -0,0 +1,46 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://www.openmetaverse.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 | */ | ||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Text; | ||
31 | using System.Net; | ||
32 | using System.Net.Sockets; | ||
33 | using libsecondlife; | ||
34 | |||
35 | |||
36 | namespace OpenSim | ||
37 | { | ||
38 | |||
39 | public interface ClientStackNetworkHandler | ||
40 | { | ||
41 | void SendPacketTo(byte[] buffer, int size, SocketFlags flags, uint circuitcode);// EndPoint packetSender); | ||
42 | void RemoveClientCircuit(uint circuitcode); | ||
43 | void RegisterPacketServer(PacketServer server); | ||
44 | } | ||
45 | |||
46 | } | ||
diff --git a/OpenSim/Region/ClientStack/ClientView.API.cs b/OpenSim/Region/ClientStack/ClientView.API.cs new file mode 100644 index 0000000..902f3c7 --- /dev/null +++ b/OpenSim/Region/ClientStack/ClientView.API.cs | |||
@@ -0,0 +1,975 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://www.openmetaverse.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 | */ | ||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Text; | ||
31 | using OpenSim.Framework.Interfaces; | ||
32 | using OpenSim.Framework.Inventory; | ||
33 | using OpenSim.Framework.Types; | ||
34 | |||
35 | using libsecondlife; | ||
36 | using libsecondlife.Packets; | ||
37 | |||
38 | namespace OpenSim | ||
39 | { | ||
40 | partial class ClientView | ||
41 | { | ||
42 | public event ChatFromViewer OnChatFromViewer; | ||
43 | public event RezObject OnRezObject; | ||
44 | public event GenericCall4 OnDeRezObject; | ||
45 | public event ModifyTerrain OnModifyTerrain; | ||
46 | public event GenericCall OnRegionHandShakeReply; | ||
47 | public event GenericCall OnRequestWearables; | ||
48 | public event SetAppearance OnSetAppearance; | ||
49 | public event GenericCall2 OnCompleteMovementToRegion; | ||
50 | public event UpdateAgent OnAgentUpdate; | ||
51 | public event StartAnim OnStartAnim; | ||
52 | public event GenericCall OnRequestAvatarsData; | ||
53 | public event LinkObjects OnLinkObjects; | ||
54 | public event UpdateVector OnGrapObject; | ||
55 | public event ObjectSelect OnDeGrapObject; | ||
56 | public event MoveObject OnGrapUpdate; | ||
57 | public event GenericCall4 OnAddPrim; | ||
58 | public event UpdateShape OnUpdatePrimShape; | ||
59 | public event ObjectSelect OnObjectSelect; | ||
60 | public event UpdatePrimFlags OnUpdatePrimFlags; | ||
61 | public event UpdatePrimTexture OnUpdatePrimTexture; | ||
62 | public event UpdateVector OnUpdatePrimPosition; | ||
63 | public event UpdatePrimRotation OnUpdatePrimRotation; | ||
64 | public event UpdateVector OnUpdatePrimScale; | ||
65 | public event StatusChange OnChildAgentStatus; | ||
66 | public event GenericCall2 OnStopMovement; | ||
67 | public event NewAvatar OnNewAvatar; | ||
68 | public event GenericCall6 OnRemoveAvatar; | ||
69 | public event RequestMapBlocks OnRequestMapBlocks; | ||
70 | public event TeleportLocationRequest OnTeleportLocationRequest; | ||
71 | |||
72 | public event ParcelPropertiesRequest OnParcelPropertiesRequest; | ||
73 | public event ParcelDivideRequest OnParcelDivideRequest; | ||
74 | public event ParcelJoinRequest OnParcelJoinRequest; | ||
75 | public event ParcelPropertiesUpdateRequest OnParcelPropertiesUpdateRequest; | ||
76 | |||
77 | public event EstateOwnerMessageRequest OnEstateOwnerMessage; | ||
78 | |||
79 | /// <summary> | ||
80 | /// | ||
81 | /// </summary> | ||
82 | public LLVector3 StartPos | ||
83 | { | ||
84 | get | ||
85 | { | ||
86 | return startpos; | ||
87 | } | ||
88 | set | ||
89 | { | ||
90 | startpos = value; | ||
91 | } | ||
92 | } | ||
93 | |||
94 | /// <summary> | ||
95 | /// | ||
96 | /// </summary> | ||
97 | public LLUUID AgentId | ||
98 | { | ||
99 | get | ||
100 | { | ||
101 | return this.AgentID; | ||
102 | } | ||
103 | } | ||
104 | |||
105 | /// <summary> | ||
106 | /// | ||
107 | /// </summary> | ||
108 | public string FirstName | ||
109 | { | ||
110 | get | ||
111 | { | ||
112 | return this.firstName; | ||
113 | } | ||
114 | |||
115 | } | ||
116 | |||
117 | /// <summary> | ||
118 | /// | ||
119 | /// </summary> | ||
120 | public string LastName | ||
121 | { | ||
122 | get | ||
123 | { | ||
124 | return this.lastName; | ||
125 | } | ||
126 | } | ||
127 | |||
128 | #region World/Avatar to Client | ||
129 | |||
130 | /// <summary> | ||
131 | /// | ||
132 | /// </summary> | ||
133 | /// <param name="regionInfo"></param> | ||
134 | public void SendRegionHandshake(RegionInfo regionInfo) | ||
135 | { | ||
136 | System.Text.Encoding _enc = System.Text.Encoding.ASCII; | ||
137 | RegionHandshakePacket handshake = new RegionHandshakePacket(); | ||
138 | |||
139 | handshake.RegionInfo.BillableFactor = regionInfo.estateSettings.billableFactor; | ||
140 | handshake.RegionInfo.IsEstateManager = false; | ||
141 | handshake.RegionInfo.TerrainHeightRange00 = regionInfo.estateSettings.terrainHeightRange0; | ||
142 | handshake.RegionInfo.TerrainHeightRange01 = regionInfo.estateSettings.terrainHeightRange1; | ||
143 | handshake.RegionInfo.TerrainHeightRange10 = regionInfo.estateSettings.terrainHeightRange2; | ||
144 | handshake.RegionInfo.TerrainHeightRange11 = regionInfo.estateSettings.terrainHeightRange3; | ||
145 | handshake.RegionInfo.TerrainStartHeight00 = regionInfo.estateSettings.terrainStartHeight0; | ||
146 | handshake.RegionInfo.TerrainStartHeight01 = regionInfo.estateSettings.terrainStartHeight1; | ||
147 | handshake.RegionInfo.TerrainStartHeight10 = regionInfo.estateSettings.terrainStartHeight2; | ||
148 | handshake.RegionInfo.TerrainStartHeight11 = regionInfo.estateSettings.terrainStartHeight3; | ||
149 | handshake.RegionInfo.SimAccess = (byte)regionInfo.estateSettings.simAccess; | ||
150 | handshake.RegionInfo.WaterHeight = regionInfo.estateSettings.waterHeight; | ||
151 | |||
152 | |||
153 | handshake.RegionInfo.RegionFlags = (uint)regionInfo.estateSettings.regionFlags; | ||
154 | |||
155 | handshake.RegionInfo.SimName = _enc.GetBytes(regionInfo.RegionName + "\0"); | ||
156 | handshake.RegionInfo.SimOwner = regionInfo.MasterAvatarAssignedUUID; | ||
157 | handshake.RegionInfo.TerrainBase0 = regionInfo.estateSettings.terrainBase0; | ||
158 | handshake.RegionInfo.TerrainBase1 = regionInfo.estateSettings.terrainBase1; | ||
159 | handshake.RegionInfo.TerrainBase2 = regionInfo.estateSettings.terrainBase2; | ||
160 | handshake.RegionInfo.TerrainBase3 = regionInfo.estateSettings.terrainBase3; | ||
161 | handshake.RegionInfo.TerrainDetail0 = regionInfo.estateSettings.terrainDetail0; | ||
162 | handshake.RegionInfo.TerrainDetail1 = regionInfo.estateSettings.terrainDetail1; | ||
163 | handshake.RegionInfo.TerrainDetail2 = regionInfo.estateSettings.terrainDetail2; | ||
164 | handshake.RegionInfo.TerrainDetail3 = regionInfo.estateSettings.terrainDetail3; | ||
165 | handshake.RegionInfo.CacheID = LLUUID.Random(); //I guess this is for the client to remember an old setting? | ||
166 | |||
167 | this.OutPacket(handshake); | ||
168 | } | ||
169 | |||
170 | /// <summary> | ||
171 | /// | ||
172 | /// </summary> | ||
173 | /// <param name="regInfo"></param> | ||
174 | public void MoveAgentIntoRegion(RegionInfo regInfo, LLVector3 pos, LLVector3 look) | ||
175 | { | ||
176 | AgentMovementCompletePacket mov = new AgentMovementCompletePacket(); | ||
177 | mov.AgentData.SessionID = this.SessionID; | ||
178 | mov.AgentData.AgentID = this.AgentID; | ||
179 | mov.Data.RegionHandle = regInfo.RegionHandle; | ||
180 | mov.Data.Timestamp = 1172750370; // TODO - dynamicalise this | ||
181 | |||
182 | if ((pos.X == 0) && (pos.Y == 0) && (pos.Z == 0)) | ||
183 | { | ||
184 | mov.Data.Position = this.startpos; | ||
185 | } | ||
186 | else | ||
187 | { | ||
188 | mov.Data.Position = pos; | ||
189 | } | ||
190 | mov.Data.LookAt = look; | ||
191 | |||
192 | OutPacket(mov); | ||
193 | } | ||
194 | |||
195 | /// <summary> | ||
196 | /// | ||
197 | /// </summary> | ||
198 | /// <param name="message"></param> | ||
199 | /// <param name="type"></param> | ||
200 | /// <param name="fromPos"></param> | ||
201 | /// <param name="fromName"></param> | ||
202 | /// <param name="fromAgentID"></param> | ||
203 | public void SendChatMessage(string message, byte type, LLVector3 fromPos, string fromName, LLUUID fromAgentID) | ||
204 | { | ||
205 | SendChatMessage(Helpers.StringToField(message), type, fromPos, fromName, fromAgentID); | ||
206 | } | ||
207 | |||
208 | /// <summary> | ||
209 | /// | ||
210 | /// </summary> | ||
211 | /// <param name="message"></param> | ||
212 | /// <param name="type"></param> | ||
213 | /// <param name="fromPos"></param> | ||
214 | /// <param name="fromName"></param> | ||
215 | /// <param name="fromAgentID"></param> | ||
216 | public void SendChatMessage(byte[] message, byte type, LLVector3 fromPos, string fromName, LLUUID fromAgentID) | ||
217 | { | ||
218 | System.Text.Encoding enc = System.Text.Encoding.ASCII; | ||
219 | libsecondlife.Packets.ChatFromSimulatorPacket reply = new ChatFromSimulatorPacket(); | ||
220 | reply.ChatData.Audible = 1; | ||
221 | reply.ChatData.Message = message; | ||
222 | reply.ChatData.ChatType = type; | ||
223 | reply.ChatData.SourceType = 1; | ||
224 | reply.ChatData.Position = fromPos; | ||
225 | reply.ChatData.FromName = enc.GetBytes(fromName + "\0"); | ||
226 | reply.ChatData.OwnerID = fromAgentID; | ||
227 | reply.ChatData.SourceID = fromAgentID; | ||
228 | |||
229 | this.OutPacket(reply); | ||
230 | } | ||
231 | |||
232 | |||
233 | /// <summary> | ||
234 | /// Send the region heightmap to the client | ||
235 | /// </summary> | ||
236 | /// <param name="map">heightmap</param> | ||
237 | public virtual void SendLayerData(float[] map) | ||
238 | { | ||
239 | try | ||
240 | { | ||
241 | int[] patches = new int[4]; | ||
242 | |||
243 | for (int y = 0; y < 16; y++) | ||
244 | { | ||
245 | for (int x = 0; x < 16; x = x + 4) | ||
246 | { | ||
247 | patches[0] = x + 0 + y * 16; | ||
248 | patches[1] = x + 1 + y * 16; | ||
249 | patches[2] = x + 2 + y * 16; | ||
250 | patches[3] = x + 3 + y * 16; | ||
251 | |||
252 | Packet layerpack = TerrainManager.CreateLandPacket(map, patches); | ||
253 | OutPacket(layerpack); | ||
254 | } | ||
255 | } | ||
256 | } | ||
257 | catch (Exception e) | ||
258 | { | ||
259 | OpenSim.Framework.Console.MainLog.Instance.Warn("ClientView API.cs: SendLayerData() - Failed with exception " + e.ToString()); | ||
260 | } | ||
261 | } | ||
262 | |||
263 | /// <summary> | ||
264 | /// Sends a specified patch to a client | ||
265 | /// </summary> | ||
266 | /// <param name="px">Patch coordinate (x) 0..16</param> | ||
267 | /// <param name="py">Patch coordinate (y) 0..16</param> | ||
268 | /// <param name="map">heightmap</param> | ||
269 | public void SendLayerData(int px, int py, float[] map) | ||
270 | { | ||
271 | try | ||
272 | { | ||
273 | int[] patches = new int[1]; | ||
274 | int patchx, patchy; | ||
275 | patchx = px / 16; | ||
276 | patchy = py / 16; | ||
277 | |||
278 | patches[0] = patchx + 0 + patchy * 16; | ||
279 | |||
280 | Packet layerpack = TerrainManager.CreateLandPacket(map, patches); | ||
281 | OutPacket(layerpack); | ||
282 | } | ||
283 | catch (Exception e) | ||
284 | { | ||
285 | OpenSim.Framework.Console.MainLog.Instance.Warn("ClientView API .cs: SendLayerData() - Failed with exception " + e.ToString()); | ||
286 | } | ||
287 | } | ||
288 | |||
289 | /// <summary> | ||
290 | /// | ||
291 | /// </summary> | ||
292 | /// <param name="neighbourHandle"></param> | ||
293 | /// <param name="neighbourIP"></param> | ||
294 | /// <param name="neighbourPort"></param> | ||
295 | public void InformClientOfNeighbour(ulong neighbourHandle, System.Net.IPAddress neighbourIP, ushort neighbourPort) | ||
296 | { | ||
297 | EnableSimulatorPacket enablesimpacket = new EnableSimulatorPacket(); | ||
298 | enablesimpacket.SimulatorInfo = new EnableSimulatorPacket.SimulatorInfoBlock(); | ||
299 | enablesimpacket.SimulatorInfo.Handle = neighbourHandle; | ||
300 | |||
301 | byte[] byteIP = neighbourIP.GetAddressBytes(); | ||
302 | enablesimpacket.SimulatorInfo.IP = (uint)byteIP[3] << 24; | ||
303 | enablesimpacket.SimulatorInfo.IP += (uint)byteIP[2] << 16; | ||
304 | enablesimpacket.SimulatorInfo.IP += (uint)byteIP[1] << 8; | ||
305 | enablesimpacket.SimulatorInfo.IP += (uint)byteIP[0]; | ||
306 | enablesimpacket.SimulatorInfo.Port = neighbourPort; | ||
307 | OutPacket(enablesimpacket); | ||
308 | } | ||
309 | |||
310 | /// <summary> | ||
311 | /// | ||
312 | /// </summary> | ||
313 | /// <returns></returns> | ||
314 | public AgentCircuitData RequestClientInfo() | ||
315 | { | ||
316 | AgentCircuitData agentData = new AgentCircuitData(); | ||
317 | agentData.AgentID = this.AgentId; | ||
318 | agentData.SessionID = this.SessionID; | ||
319 | agentData.SecureSessionID = this.SecureSessionID; | ||
320 | agentData.circuitcode = this.CircuitCode; | ||
321 | agentData.child = false; | ||
322 | agentData.firstname = this.firstName; | ||
323 | agentData.lastname = this.lastName; | ||
324 | |||
325 | return agentData; | ||
326 | } | ||
327 | |||
328 | public void CrossRegion(ulong newRegionHandle, LLVector3 pos, LLVector3 lookAt, System.Net.IPAddress newRegionIP, ushort newRegionPort) | ||
329 | { | ||
330 | LLVector3 look = new LLVector3(lookAt.X * 10, lookAt.Y * 10, lookAt.Z * 10); | ||
331 | |||
332 | CrossedRegionPacket newSimPack = new CrossedRegionPacket(); | ||
333 | newSimPack.AgentData = new CrossedRegionPacket.AgentDataBlock(); | ||
334 | newSimPack.AgentData.AgentID = this.AgentID; | ||
335 | newSimPack.AgentData.SessionID = this.SessionID; | ||
336 | newSimPack.Info = new CrossedRegionPacket.InfoBlock(); | ||
337 | newSimPack.Info.Position = pos; | ||
338 | newSimPack.Info.LookAt = look; // new LLVector3(0.0f, 0.0f, 0.0f); // copied from Avatar.cs - SHOULD BE DYNAMIC!!!!!!!!!! | ||
339 | newSimPack.RegionData = new libsecondlife.Packets.CrossedRegionPacket.RegionDataBlock(); | ||
340 | newSimPack.RegionData.RegionHandle = newRegionHandle; | ||
341 | byte[] byteIP = newRegionIP.GetAddressBytes(); | ||
342 | newSimPack.RegionData.SimIP = (uint)byteIP[3] << 24; | ||
343 | newSimPack.RegionData.SimIP += (uint)byteIP[2] << 16; | ||
344 | newSimPack.RegionData.SimIP += (uint)byteIP[1] << 8; | ||
345 | newSimPack.RegionData.SimIP += (uint)byteIP[0]; | ||
346 | newSimPack.RegionData.SimPort = newRegionPort; | ||
347 | newSimPack.RegionData.SeedCapability = new byte[0]; | ||
348 | |||
349 | this.OutPacket(newSimPack); | ||
350 | //this.DowngradeClient(); | ||
351 | } | ||
352 | |||
353 | public void SendMapBlock(List<MapBlockData> mapBlocks) | ||
354 | { | ||
355 | System.Text.Encoding _enc = System.Text.Encoding.ASCII; | ||
356 | |||
357 | MapBlockReplyPacket mapReply = new MapBlockReplyPacket(); | ||
358 | mapReply.AgentData.AgentID = this.AgentID; | ||
359 | mapReply.Data = new MapBlockReplyPacket.DataBlock[mapBlocks.Count]; | ||
360 | mapReply.AgentData.Flags = 0; | ||
361 | |||
362 | for (int i = 0; i < mapBlocks.Count; i++) | ||
363 | { | ||
364 | mapReply.Data[i] = new MapBlockReplyPacket.DataBlock(); | ||
365 | mapReply.Data[i].MapImageID = mapBlocks[i].MapImageId; | ||
366 | mapReply.Data[i].X = mapBlocks[i].X; | ||
367 | mapReply.Data[i].Y = mapBlocks[i].Y; | ||
368 | mapReply.Data[i].WaterHeight = mapBlocks[i].WaterHeight; | ||
369 | mapReply.Data[i].Name = _enc.GetBytes(mapBlocks[i].Name); | ||
370 | mapReply.Data[i].RegionFlags = mapBlocks[i].RegionFlags; | ||
371 | mapReply.Data[i].Access = mapBlocks[i].Access; | ||
372 | mapReply.Data[i].Agents = mapBlocks[i].Agents; | ||
373 | } | ||
374 | this.OutPacket(mapReply); | ||
375 | } | ||
376 | |||
377 | public void SendLocalTeleport(LLVector3 position, LLVector3 lookAt, uint flags) | ||
378 | { | ||
379 | TeleportLocalPacket tpLocal = new TeleportLocalPacket(); | ||
380 | tpLocal.Info.AgentID = this.AgentID; | ||
381 | tpLocal.Info.TeleportFlags = flags; | ||
382 | tpLocal.Info.LocationID = 2; | ||
383 | tpLocal.Info.LookAt = lookAt; | ||
384 | tpLocal.Info.Position = position; | ||
385 | OutPacket(tpLocal); | ||
386 | } | ||
387 | |||
388 | public void SendRegionTeleport(ulong regionHandle, byte simAccess, string ipAddress, ushort ipPort, uint locationID, uint flags) | ||
389 | { | ||
390 | TeleportFinishPacket teleport = new TeleportFinishPacket(); | ||
391 | teleport.Info.AgentID = this.AgentID; | ||
392 | teleport.Info.RegionHandle = regionHandle; | ||
393 | teleport.Info.SimAccess = simAccess; | ||
394 | teleport.Info.SeedCapability = new byte[0]; | ||
395 | |||
396 | System.Net.IPAddress oIP = System.Net.IPAddress.Parse(ipAddress); | ||
397 | byte[] byteIP = oIP.GetAddressBytes(); | ||
398 | uint ip = (uint)byteIP[3] << 24; | ||
399 | ip += (uint)byteIP[2] << 16; | ||
400 | ip += (uint)byteIP[1] << 8; | ||
401 | ip += (uint)byteIP[0]; | ||
402 | |||
403 | teleport.Info.SimIP = ip; | ||
404 | teleport.Info.SimPort = ipPort; | ||
405 | teleport.Info.LocationID = 4; | ||
406 | teleport.Info.TeleportFlags = 1 << 4; | ||
407 | OutPacket(teleport); | ||
408 | } | ||
409 | |||
410 | /// <summary> | ||
411 | /// | ||
412 | /// </summary> | ||
413 | public void SendTeleportCancel() | ||
414 | { | ||
415 | TeleportCancelPacket tpCancel = new TeleportCancelPacket(); | ||
416 | tpCancel.Info.SessionID = this.SessionID; | ||
417 | tpCancel.Info.AgentID = this.AgentID; | ||
418 | |||
419 | OutPacket(tpCancel); | ||
420 | } | ||
421 | |||
422 | /// <summary> | ||
423 | /// | ||
424 | /// </summary> | ||
425 | public void SendTeleportLocationStart() | ||
426 | { | ||
427 | TeleportStartPacket tpStart = new TeleportStartPacket(); | ||
428 | tpStart.Info.TeleportFlags = 16; // Teleport via location | ||
429 | OutPacket(tpStart); | ||
430 | } | ||
431 | |||
432 | public void SendMoneyBalance(LLUUID transaction, bool success, byte[] description, int balance) | ||
433 | { | ||
434 | MoneyBalanceReplyPacket money = new MoneyBalanceReplyPacket(); | ||
435 | money.MoneyData.AgentID = this.AgentID; | ||
436 | money.MoneyData.TransactionID = transaction; | ||
437 | money.MoneyData.TransactionSuccess = success; | ||
438 | money.MoneyData.Description = description; | ||
439 | money.MoneyData.MoneyBalance = balance; | ||
440 | OutPacket(money); | ||
441 | } | ||
442 | |||
443 | #region Appearance/ Wearables Methods | ||
444 | |||
445 | /// <summary> | ||
446 | /// | ||
447 | /// </summary> | ||
448 | /// <param name="wearables"></param> | ||
449 | public void SendWearables(AvatarWearable[] wearables) | ||
450 | { | ||
451 | AgentWearablesUpdatePacket aw = new AgentWearablesUpdatePacket(); | ||
452 | aw.AgentData.AgentID = this.AgentID; | ||
453 | aw.AgentData.SerialNum = 0; | ||
454 | aw.AgentData.SessionID = this.SessionID; | ||
455 | |||
456 | aw.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[13]; | ||
457 | AgentWearablesUpdatePacket.WearableDataBlock awb; | ||
458 | for (int i = 0; i < wearables.Length; i++) | ||
459 | { | ||
460 | awb = new AgentWearablesUpdatePacket.WearableDataBlock(); | ||
461 | awb.WearableType = (byte)i; | ||
462 | awb.AssetID = wearables[i].AssetID; | ||
463 | awb.ItemID = wearables[i].ItemID; | ||
464 | aw.WearableData[i] = awb; | ||
465 | } | ||
466 | |||
467 | this.OutPacket(aw); | ||
468 | } | ||
469 | |||
470 | /// <summary> | ||
471 | /// | ||
472 | /// </summary> | ||
473 | /// <param name="agentID"></param> | ||
474 | /// <param name="visualParams"></param> | ||
475 | /// <param name="textureEntry"></param> | ||
476 | public void SendAppearance(LLUUID agentID, byte[] visualParams, byte[] textureEntry) | ||
477 | { | ||
478 | AvatarAppearancePacket avp = new AvatarAppearancePacket(); | ||
479 | avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[218]; | ||
480 | avp.ObjectData.TextureEntry = textureEntry; | ||
481 | |||
482 | AvatarAppearancePacket.VisualParamBlock avblock = null; | ||
483 | for (int i = 0; i < visualParams.Length; i++) | ||
484 | { | ||
485 | avblock = new AvatarAppearancePacket.VisualParamBlock(); | ||
486 | avblock.ParamValue = visualParams[i]; | ||
487 | avp.VisualParam[i] = avblock; | ||
488 | } | ||
489 | |||
490 | avp.Sender.IsTrial = false; | ||
491 | avp.Sender.ID = agentID; | ||
492 | OutPacket(avp); | ||
493 | } | ||
494 | |||
495 | #endregion | ||
496 | |||
497 | #region Avatar Packet/data sending Methods | ||
498 | |||
499 | /// <summary> | ||
500 | /// | ||
501 | /// </summary> | ||
502 | /// <param name="regionInfo"></param> | ||
503 | /// <param name="firstName"></param> | ||
504 | /// <param name="lastName"></param> | ||
505 | /// <param name="avatarID"></param> | ||
506 | /// <param name="avatarLocalID"></param> | ||
507 | /// <param name="Pos"></param> | ||
508 | public void SendAvatarData(ulong regionHandle, string firstName, string lastName, LLUUID avatarID, uint avatarLocalID, LLVector3 Pos, byte[] textureEntry) | ||
509 | { | ||
510 | System.Text.Encoding _enc = System.Text.Encoding.ASCII; | ||
511 | //send a objectupdate packet with information about the clients avatar | ||
512 | |||
513 | ObjectUpdatePacket objupdate = new ObjectUpdatePacket(); | ||
514 | objupdate.RegionData.RegionHandle = regionHandle; | ||
515 | objupdate.RegionData.TimeDilation = 64096; | ||
516 | objupdate.ObjectData = new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock[1]; | ||
517 | objupdate.ObjectData[0] = this.CreateDefaultAvatarPacket(textureEntry); | ||
518 | //give this avatar object a local id and assign the user a name | ||
519 | |||
520 | objupdate.ObjectData[0].ID = avatarLocalID; | ||
521 | objupdate.ObjectData[0].FullID = avatarID; | ||
522 | objupdate.ObjectData[0].NameValue = _enc.GetBytes("FirstName STRING RW SV " + firstName + "\nLastName STRING RW SV " + lastName + " \0"); | ||
523 | libsecondlife.LLVector3 pos2 = new LLVector3((float)Pos.X, (float)Pos.Y, (float)Pos.Z); | ||
524 | byte[] pb = pos2.GetBytes(); | ||
525 | Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 16, pb.Length); | ||
526 | |||
527 | OutPacket(objupdate); | ||
528 | |||
529 | } | ||
530 | |||
531 | /// <summary> | ||
532 | /// | ||
533 | /// </summary> | ||
534 | /// <param name="regionHandle"></param> | ||
535 | /// <param name="timeDilation"></param> | ||
536 | /// <param name="localID"></param> | ||
537 | /// <param name="position"></param> | ||
538 | /// <param name="velocity"></param> | ||
539 | public void SendAvatarTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, LLVector3 position, LLVector3 velocity) | ||
540 | { | ||
541 | ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock = this.CreateAvatarImprovedBlock(localID, position, velocity); | ||
542 | ImprovedTerseObjectUpdatePacket terse = new ImprovedTerseObjectUpdatePacket(); | ||
543 | terse.RegionData.RegionHandle = regionHandle; | ||
544 | terse.RegionData.TimeDilation = timeDilation; | ||
545 | terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1]; | ||
546 | terse.ObjectData[0] = terseBlock; | ||
547 | |||
548 | this.OutPacket(terse); | ||
549 | } | ||
550 | |||
551 | #endregion | ||
552 | |||
553 | #region Primitive Packet/data Sending Methods | ||
554 | |||
555 | /// <summary> | ||
556 | /// | ||
557 | /// </summary> | ||
558 | /// <param name="localID"></param> | ||
559 | /// <param name="rotation"></param> | ||
560 | /// <param name="attachPoint"></param> | ||
561 | public void AttachObject(uint localID, LLQuaternion rotation, byte attachPoint) | ||
562 | { | ||
563 | ObjectAttachPacket attach = new ObjectAttachPacket(); | ||
564 | attach.AgentData.AgentID = this.AgentID; | ||
565 | attach.AgentData.SessionID = this.SessionID; | ||
566 | attach.AgentData.AttachmentPoint = attachPoint; | ||
567 | attach.ObjectData = new ObjectAttachPacket.ObjectDataBlock[1]; | ||
568 | attach.ObjectData[0] = new ObjectAttachPacket.ObjectDataBlock(); | ||
569 | attach.ObjectData[0].ObjectLocalID = localID; | ||
570 | attach.ObjectData[0].Rotation = rotation; | ||
571 | |||
572 | this.OutPacket(attach); | ||
573 | } | ||
574 | |||
575 | /// <summary> | ||
576 | /// Sends a full ObjectUpdatePacket to a client to inform it of a new primitive | ||
577 | /// or big changes to a existing primitive. | ||
578 | /// </summary> | ||
579 | /// <param name="regionHandle"></param> | ||
580 | /// <param name="timeDilation"></param> | ||
581 | /// <param name="localID"></param> | ||
582 | /// <param name="primData"></param> | ||
583 | /// <param name="pos"></param> | ||
584 | /// <param name="rotation"></param> | ||
585 | /// <param name="textureID"></param> | ||
586 | public void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimData primData, LLVector3 pos, LLQuaternion rotation, LLUUID textureID, uint flags) | ||
587 | { | ||
588 | ObjectUpdatePacket outPacket = new ObjectUpdatePacket(); | ||
589 | outPacket.RegionData.RegionHandle = regionHandle; | ||
590 | outPacket.RegionData.TimeDilation = timeDilation; | ||
591 | outPacket.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; | ||
592 | outPacket.ObjectData[0] = this.CreatePrimUpdateBlock(primData, textureID, flags); | ||
593 | outPacket.ObjectData[0].ID = localID; | ||
594 | outPacket.ObjectData[0].FullID = primData.FullID; | ||
595 | byte[] pb = pos.GetBytes(); | ||
596 | Array.Copy(pb, 0, outPacket.ObjectData[0].ObjectData, 0, pb.Length); | ||
597 | byte[] rot = rotation.GetBytes(); | ||
598 | Array.Copy(rot, 0, outPacket.ObjectData[0].ObjectData, 48, rot.Length); | ||
599 | OutPacket(outPacket); | ||
600 | } | ||
601 | |||
602 | /// <summary> | ||
603 | /// Sends a full ObjectUpdatePacket to a client to inform it of a new primitive | ||
604 | /// or big changes to a existing primitive. | ||
605 | /// Uses default rotation | ||
606 | /// </summary> | ||
607 | /// <param name="primData"></param> | ||
608 | /// <param name="pos"></param> | ||
609 | public void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimData primData, LLVector3 pos, LLUUID textureID , uint flags) | ||
610 | { | ||
611 | ObjectUpdatePacket outPacket = new ObjectUpdatePacket(); | ||
612 | outPacket.RegionData.RegionHandle = regionHandle; | ||
613 | outPacket.RegionData.TimeDilation = timeDilation; | ||
614 | outPacket.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; | ||
615 | outPacket.ObjectData[0] = this.CreatePrimUpdateBlock(primData, textureID, flags); | ||
616 | outPacket.ObjectData[0].ID = localID; | ||
617 | outPacket.ObjectData[0].FullID = primData.FullID; | ||
618 | byte[] pb = pos.GetBytes(); | ||
619 | Array.Copy(pb, 0, outPacket.ObjectData[0].ObjectData, 0, pb.Length); | ||
620 | |||
621 | OutPacket(outPacket); | ||
622 | } | ||
623 | |||
624 | /// <summary> | ||
625 | /// | ||
626 | /// </summary> | ||
627 | /// <param name="regionHandle"></param> | ||
628 | /// <param name="timeDilation"></param> | ||
629 | /// <param name="localID"></param> | ||
630 | /// <param name="position"></param> | ||
631 | /// <param name="rotation"></param> | ||
632 | public void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, LLVector3 position, LLQuaternion rotation) | ||
633 | { | ||
634 | ImprovedTerseObjectUpdatePacket terse = new ImprovedTerseObjectUpdatePacket(); | ||
635 | terse.RegionData.RegionHandle = regionHandle; | ||
636 | terse.RegionData.TimeDilation = timeDilation; | ||
637 | terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1]; | ||
638 | terse.ObjectData[0] = this.CreatePrimImprovedBlock(localID, position, rotation); | ||
639 | |||
640 | this.OutPacket(terse); | ||
641 | } | ||
642 | |||
643 | #endregion | ||
644 | |||
645 | #endregion | ||
646 | |||
647 | #region Helper Methods | ||
648 | |||
649 | protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateAvatarImprovedBlock(uint localID, LLVector3 pos, LLVector3 velocity) | ||
650 | { | ||
651 | byte[] bytes = new byte[60]; | ||
652 | int i = 0; | ||
653 | ImprovedTerseObjectUpdatePacket.ObjectDataBlock dat = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock(); | ||
654 | |||
655 | dat.TextureEntry = new byte[0];// AvatarTemplate.TextureEntry; | ||
656 | |||
657 | uint ID = localID; | ||
658 | |||
659 | bytes[i++] = (byte)(ID % 256); | ||
660 | bytes[i++] = (byte)((ID >> 8) % 256); | ||
661 | bytes[i++] = (byte)((ID >> 16) % 256); | ||
662 | bytes[i++] = (byte)((ID >> 24) % 256); | ||
663 | bytes[i++] = 0; | ||
664 | bytes[i++] = 1; | ||
665 | i += 14; | ||
666 | bytes[i++] = 128; | ||
667 | bytes[i++] = 63; | ||
668 | |||
669 | byte[] pb = pos.GetBytes(); | ||
670 | Array.Copy(pb, 0, bytes, i, pb.Length); | ||
671 | i += 12; | ||
672 | ushort InternVelocityX; | ||
673 | ushort InternVelocityY; | ||
674 | ushort InternVelocityZ; | ||
675 | Axiom.MathLib.Vector3 internDirec = new Axiom.MathLib.Vector3(0, 0, 0); | ||
676 | |||
677 | internDirec = new Axiom.MathLib.Vector3(velocity.X, velocity.Y, velocity.Z); | ||
678 | |||
679 | internDirec = internDirec / 128.0f; | ||
680 | internDirec.x += 1; | ||
681 | internDirec.y += 1; | ||
682 | internDirec.z += 1; | ||
683 | |||
684 | InternVelocityX = (ushort)(32768 * internDirec.x); | ||
685 | InternVelocityY = (ushort)(32768 * internDirec.y); | ||
686 | InternVelocityZ = (ushort)(32768 * internDirec.z); | ||
687 | |||
688 | ushort ac = 32767; | ||
689 | bytes[i++] = (byte)(InternVelocityX % 256); | ||
690 | bytes[i++] = (byte)((InternVelocityX >> 8) % 256); | ||
691 | bytes[i++] = (byte)(InternVelocityY % 256); | ||
692 | bytes[i++] = (byte)((InternVelocityY >> 8) % 256); | ||
693 | bytes[i++] = (byte)(InternVelocityZ % 256); | ||
694 | bytes[i++] = (byte)((InternVelocityZ >> 8) % 256); | ||
695 | |||
696 | //accel | ||
697 | bytes[i++] = (byte)(ac % 256); | ||
698 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
699 | bytes[i++] = (byte)(ac % 256); | ||
700 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
701 | bytes[i++] = (byte)(ac % 256); | ||
702 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
703 | |||
704 | //rot | ||
705 | bytes[i++] = (byte)(ac % 256); | ||
706 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
707 | bytes[i++] = (byte)(ac % 256); | ||
708 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
709 | bytes[i++] = (byte)(ac % 256); | ||
710 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
711 | bytes[i++] = (byte)(ac % 256); | ||
712 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
713 | |||
714 | //rotation vel | ||
715 | bytes[i++] = (byte)(ac % 256); | ||
716 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
717 | bytes[i++] = (byte)(ac % 256); | ||
718 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
719 | bytes[i++] = (byte)(ac % 256); | ||
720 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
721 | |||
722 | dat.Data = bytes; | ||
723 | return (dat); | ||
724 | } | ||
725 | |||
726 | /// <summary> | ||
727 | /// | ||
728 | /// </summary> | ||
729 | /// <param name="localID"></param> | ||
730 | /// <param name="position"></param> | ||
731 | /// <param name="rotation"></param> | ||
732 | /// <returns></returns> | ||
733 | protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreatePrimImprovedBlock(uint localID, LLVector3 position, LLQuaternion rotation) | ||
734 | { | ||
735 | uint ID = localID; | ||
736 | byte[] bytes = new byte[60]; | ||
737 | |||
738 | int i = 0; | ||
739 | ImprovedTerseObjectUpdatePacket.ObjectDataBlock dat = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock(); | ||
740 | dat.TextureEntry = new byte[0]; | ||
741 | bytes[i++] = (byte)(ID % 256); | ||
742 | bytes[i++] = (byte)((ID >> 8) % 256); | ||
743 | bytes[i++] = (byte)((ID >> 16) % 256); | ||
744 | bytes[i++] = (byte)((ID >> 24) % 256); | ||
745 | bytes[i++] = 0; | ||
746 | bytes[i++] = 0; | ||
747 | |||
748 | byte[] pb = position.GetBytes(); | ||
749 | Array.Copy(pb, 0, bytes, i, pb.Length); | ||
750 | i += 12; | ||
751 | ushort ac = 32767; | ||
752 | |||
753 | //vel | ||
754 | bytes[i++] = (byte)(ac % 256); | ||
755 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
756 | bytes[i++] = (byte)(ac % 256); | ||
757 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
758 | bytes[i++] = (byte)(ac % 256); | ||
759 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
760 | |||
761 | //accel | ||
762 | bytes[i++] = (byte)(ac % 256); | ||
763 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
764 | bytes[i++] = (byte)(ac % 256); | ||
765 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
766 | bytes[i++] = (byte)(ac % 256); | ||
767 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
768 | |||
769 | ushort rw, rx, ry, rz; | ||
770 | rw = (ushort)(32768 * (rotation.W + 1)); | ||
771 | rx = (ushort)(32768 * (rotation.X + 1)); | ||
772 | ry = (ushort)(32768 * (rotation.Y + 1)); | ||
773 | rz = (ushort)(32768 * (rotation.Z + 1)); | ||
774 | |||
775 | //rot | ||
776 | bytes[i++] = (byte)(rx % 256); | ||
777 | bytes[i++] = (byte)((rx >> 8) % 256); | ||
778 | bytes[i++] = (byte)(ry % 256); | ||
779 | bytes[i++] = (byte)((ry >> 8) % 256); | ||
780 | bytes[i++] = (byte)(rz % 256); | ||
781 | bytes[i++] = (byte)((rz >> 8) % 256); | ||
782 | bytes[i++] = (byte)(rw % 256); | ||
783 | bytes[i++] = (byte)((rw >> 8) % 256); | ||
784 | |||
785 | //rotation vel | ||
786 | bytes[i++] = (byte)(ac % 256); | ||
787 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
788 | bytes[i++] = (byte)(ac % 256); | ||
789 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
790 | bytes[i++] = (byte)(ac % 256); | ||
791 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
792 | |||
793 | dat.Data = bytes; | ||
794 | return dat; | ||
795 | } | ||
796 | |||
797 | |||
798 | /// <summary> | ||
799 | /// Create the ObjectDataBlock for a ObjectUpdatePacket (for a Primitive) | ||
800 | /// </summary> | ||
801 | /// <param name="primData"></param> | ||
802 | /// <returns></returns> | ||
803 | protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(PrimData primData, LLUUID textureID, uint flags) | ||
804 | { | ||
805 | ObjectUpdatePacket.ObjectDataBlock objupdate = new ObjectUpdatePacket.ObjectDataBlock(); | ||
806 | this.SetDefaultPrimPacketValues(objupdate); | ||
807 | objupdate.UpdateFlags = flags; | ||
808 | this.SetPrimPacketShapeData(objupdate, primData, textureID); | ||
809 | |||
810 | return objupdate; | ||
811 | } | ||
812 | |||
813 | /// <summary> | ||
814 | /// Copy the data from a PrimData object to a ObjectUpdatePacket | ||
815 | /// </summary> | ||
816 | /// <param name="objectData"></param> | ||
817 | /// <param name="primData"></param> | ||
818 | protected void SetPrimPacketShapeData(ObjectUpdatePacket.ObjectDataBlock objectData, PrimData primData, LLUUID textureID) | ||
819 | { | ||
820 | LLObject.TextureEntry ntex = new LLObject.TextureEntry(textureID); | ||
821 | objectData.TextureEntry = ntex.ToBytes(); | ||
822 | objectData.OwnerID = primData.OwnerID; | ||
823 | objectData.PCode = primData.PCode; | ||
824 | objectData.PathBegin = primData.PathBegin; | ||
825 | objectData.PathEnd = primData.PathEnd; | ||
826 | objectData.PathScaleX = primData.PathScaleX; | ||
827 | objectData.PathScaleY = primData.PathScaleY; | ||
828 | objectData.PathShearX = primData.PathShearX; | ||
829 | objectData.PathShearY = primData.PathShearY; | ||
830 | objectData.PathSkew = primData.PathSkew; | ||
831 | objectData.ProfileBegin = primData.ProfileBegin; | ||
832 | objectData.ProfileEnd = primData.ProfileEnd; | ||
833 | objectData.Scale = primData.Scale; | ||
834 | objectData.PathCurve = primData.PathCurve; | ||
835 | objectData.ProfileCurve = primData.ProfileCurve; | ||
836 | objectData.ParentID = primData.ParentID; | ||
837 | objectData.ProfileHollow = primData.ProfileHollow; | ||
838 | objectData.PathRadiusOffset = primData.PathRadiusOffset; | ||
839 | objectData.PathRevolutions = primData.PathRevolutions; | ||
840 | objectData.PathTaperX = primData.PathTaperX; | ||
841 | objectData.PathTaperY = primData.PathTaperY; | ||
842 | objectData.PathTwist = primData.PathTwist; | ||
843 | objectData.PathTwistBegin = primData.PathTwistBegin; | ||
844 | } | ||
845 | |||
846 | /// <summary> | ||
847 | /// Set some default values in a ObjectUpdatePacket | ||
848 | /// </summary> | ||
849 | /// <param name="objdata"></param> | ||
850 | protected void SetDefaultPrimPacketValues(ObjectUpdatePacket.ObjectDataBlock objdata) | ||
851 | { | ||
852 | objdata.PSBlock = new byte[0]; | ||
853 | objdata.ExtraParams = new byte[1]; | ||
854 | objdata.MediaURL = new byte[0]; | ||
855 | objdata.NameValue = new byte[0]; | ||
856 | objdata.Text = new byte[0]; | ||
857 | objdata.TextColor = new byte[4]; | ||
858 | objdata.JointAxisOrAnchor = new LLVector3(0, 0, 0); | ||
859 | objdata.JointPivot = new LLVector3(0, 0, 0); | ||
860 | objdata.Material = 3; | ||
861 | objdata.TextureAnim = new byte[0]; | ||
862 | objdata.Sound = LLUUID.Zero; | ||
863 | objdata.State = 0; | ||
864 | objdata.Data = new byte[0]; | ||
865 | |||
866 | objdata.ObjectData = new byte[60]; | ||
867 | objdata.ObjectData[46] = 128; | ||
868 | objdata.ObjectData[47] = 63; | ||
869 | } | ||
870 | |||
871 | |||
872 | /// <summary> | ||
873 | /// | ||
874 | /// </summary> | ||
875 | /// <returns></returns> | ||
876 | protected ObjectUpdatePacket.ObjectDataBlock CreateDefaultAvatarPacket(byte[] textureEntry) | ||
877 | { | ||
878 | libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock objdata = new ObjectUpdatePacket.ObjectDataBlock(); // new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock(data1, ref i); | ||
879 | |||
880 | SetDefaultAvatarPacketValues(ref objdata); | ||
881 | objdata.UpdateFlags = 61 + (9 << 8) + (130 << 16) + (16 << 24); | ||
882 | objdata.PathCurve = 16; | ||
883 | objdata.ProfileCurve = 1; | ||
884 | objdata.PathScaleX = 100; | ||
885 | objdata.PathScaleY = 100; | ||
886 | objdata.ParentID = 0; | ||
887 | objdata.OwnerID = LLUUID.Zero; | ||
888 | objdata.Scale = new LLVector3(1, 1, 1); | ||
889 | objdata.PCode = 47; | ||
890 | if (textureEntry != null) | ||
891 | { | ||
892 | objdata.TextureEntry = textureEntry; | ||
893 | } | ||
894 | System.Text.Encoding enc = System.Text.Encoding.ASCII; | ||
895 | libsecondlife.LLVector3 pos = new LLVector3(objdata.ObjectData, 16); | ||
896 | pos.X = 100f; | ||
897 | objdata.ID = 8880000; | ||
898 | objdata.NameValue = enc.GetBytes("FirstName STRING RW SV Test \nLastName STRING RW SV User \0"); | ||
899 | libsecondlife.LLVector3 pos2 = new LLVector3(100f, 100f, 23f); | ||
900 | //objdata.FullID=user.AgentID; | ||
901 | byte[] pb = pos.GetBytes(); | ||
902 | Array.Copy(pb, 0, objdata.ObjectData, 16, pb.Length); | ||
903 | |||
904 | return objdata; | ||
905 | } | ||
906 | |||
907 | /// <summary> | ||
908 | /// | ||
909 | /// </summary> | ||
910 | /// <param name="objdata"></param> | ||
911 | protected void SetDefaultAvatarPacketValues(ref ObjectUpdatePacket.ObjectDataBlock objdata) | ||
912 | { | ||
913 | objdata.PSBlock = new byte[0]; | ||
914 | objdata.ExtraParams = new byte[1]; | ||
915 | objdata.MediaURL = new byte[0]; | ||
916 | objdata.NameValue = new byte[0]; | ||
917 | objdata.Text = new byte[0]; | ||
918 | objdata.TextColor = new byte[4]; | ||
919 | objdata.JointAxisOrAnchor = new LLVector3(0, 0, 0); | ||
920 | objdata.JointPivot = new LLVector3(0, 0, 0); | ||
921 | objdata.Material = 4; | ||
922 | objdata.TextureAnim = new byte[0]; | ||
923 | objdata.Sound = LLUUID.Zero; | ||
924 | LLObject.TextureEntry ntex = new LLObject.TextureEntry(new LLUUID("00000000-0000-0000-5005-000000000005")); | ||
925 | objdata.TextureEntry = ntex.ToBytes(); | ||
926 | objdata.State = 0; | ||
927 | objdata.Data = new byte[0]; | ||
928 | |||
929 | objdata.ObjectData = new byte[76]; | ||
930 | objdata.ObjectData[15] = 128; | ||
931 | objdata.ObjectData[16] = 63; | ||
932 | objdata.ObjectData[56] = 128; | ||
933 | objdata.ObjectData[61] = 102; | ||
934 | objdata.ObjectData[62] = 40; | ||
935 | objdata.ObjectData[63] = 61; | ||
936 | objdata.ObjectData[64] = 189; | ||
937 | } | ||
938 | |||
939 | /// <summary> | ||
940 | /// | ||
941 | /// </summary> | ||
942 | /// <param name="addPacket"></param> | ||
943 | /// <returns></returns> | ||
944 | protected PrimData CreatePrimFromObjectAdd(ObjectAddPacket addPacket) | ||
945 | { | ||
946 | PrimData PData = new PrimData(); | ||
947 | PData.CreationDate = (Int32)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds; | ||
948 | PData.PCode = addPacket.ObjectData.PCode; | ||
949 | PData.PathBegin = addPacket.ObjectData.PathBegin; | ||
950 | PData.PathEnd = addPacket.ObjectData.PathEnd; | ||
951 | PData.PathScaleX = addPacket.ObjectData.PathScaleX; | ||
952 | PData.PathScaleY = addPacket.ObjectData.PathScaleY; | ||
953 | PData.PathShearX = addPacket.ObjectData.PathShearX; | ||
954 | PData.PathShearY = addPacket.ObjectData.PathShearY; | ||
955 | PData.PathSkew = addPacket.ObjectData.PathSkew; | ||
956 | PData.ProfileBegin = addPacket.ObjectData.ProfileBegin; | ||
957 | PData.ProfileEnd = addPacket.ObjectData.ProfileEnd; | ||
958 | PData.Scale = addPacket.ObjectData.Scale; | ||
959 | PData.PathCurve = addPacket.ObjectData.PathCurve; | ||
960 | PData.ProfileCurve = addPacket.ObjectData.ProfileCurve; | ||
961 | PData.ParentID = 0; | ||
962 | PData.ProfileHollow = addPacket.ObjectData.ProfileHollow; | ||
963 | PData.PathRadiusOffset = addPacket.ObjectData.PathRadiusOffset; | ||
964 | PData.PathRevolutions = addPacket.ObjectData.PathRevolutions; | ||
965 | PData.PathTaperX = addPacket.ObjectData.PathTaperX; | ||
966 | PData.PathTaperY = addPacket.ObjectData.PathTaperY; | ||
967 | PData.PathTwist = addPacket.ObjectData.PathTwist; | ||
968 | PData.PathTwistBegin = addPacket.ObjectData.PathTwistBegin; | ||
969 | |||
970 | return PData; | ||
971 | } | ||
972 | #endregion | ||
973 | |||
974 | } | ||
975 | } | ||
diff --git a/OpenSim/Region/ClientStack/ClientView.AgentAssetUpload.cs b/OpenSim/Region/ClientStack/ClientView.AgentAssetUpload.cs new file mode 100644 index 0000000..914c38a --- /dev/null +++ b/OpenSim/Region/ClientStack/ClientView.AgentAssetUpload.cs | |||
@@ -0,0 +1,358 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://www.openmetaverse.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 | */ | ||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Text; | ||
31 | using OpenSim.Assets; | ||
32 | using OpenSim.Framework.Types; | ||
33 | using OpenSim.Framework.Interfaces; | ||
34 | using OpenSim.Framework.Utilities; | ||
35 | using OpenSim.Caches; | ||
36 | using libsecondlife; | ||
37 | using libsecondlife.Packets; | ||
38 | |||
39 | namespace OpenSim | ||
40 | { | ||
41 | partial class ClientView | ||
42 | { | ||
43 | public class AgentAssetUpload | ||
44 | { | ||
45 | private Dictionary<LLUUID, AssetTransaction> transactions = new Dictionary<LLUUID, AssetTransaction>(); | ||
46 | private ClientView ourClient; | ||
47 | private AssetCache m_assetCache; | ||
48 | private InventoryCache m_inventoryCache; | ||
49 | |||
50 | public AgentAssetUpload(ClientView client, AssetCache assetCache, InventoryCache inventoryCache) | ||
51 | { | ||
52 | this.ourClient = client; | ||
53 | m_assetCache = assetCache; | ||
54 | m_inventoryCache = inventoryCache; | ||
55 | } | ||
56 | |||
57 | public void AddUpload(LLUUID transactionID, AssetBase asset) | ||
58 | { | ||
59 | AssetTransaction upload = new AssetTransaction(); | ||
60 | lock (this.transactions) | ||
61 | { | ||
62 | upload.Asset = asset; | ||
63 | upload.TransactionID = transactionID; | ||
64 | this.transactions.Add(transactionID, upload); | ||
65 | } | ||
66 | if (upload.Asset.Data.Length > 2) | ||
67 | { | ||
68 | //is complete | ||
69 | upload.UploadComplete = true; | ||
70 | AssetUploadCompletePacket response = new AssetUploadCompletePacket(); | ||
71 | response.AssetBlock.Type = asset.Type; | ||
72 | response.AssetBlock.Success = true; | ||
73 | response.AssetBlock.UUID = transactionID.Combine(this.ourClient.SecureSessionID); | ||
74 | this.ourClient.OutPacket(response); | ||
75 | m_assetCache.AddAsset(asset); | ||
76 | } | ||
77 | else | ||
78 | { | ||
79 | upload.UploadComplete = false; | ||
80 | upload.XferID = Util.GetNextXferID(); | ||
81 | RequestXferPacket xfer = new RequestXferPacket(); | ||
82 | xfer.XferID.ID = upload.XferID; | ||
83 | xfer.XferID.VFileType = upload.Asset.Type; | ||
84 | xfer.XferID.VFileID = transactionID.Combine(this.ourClient.SecureSessionID); | ||
85 | xfer.XferID.FilePath = 0; | ||
86 | xfer.XferID.Filename = new byte[0]; | ||
87 | this.ourClient.OutPacket(xfer); | ||
88 | } | ||
89 | |||
90 | } | ||
91 | |||
92 | public AssetBase GetUpload(LLUUID transactionID) | ||
93 | { | ||
94 | if (this.transactions.ContainsKey(transactionID)) | ||
95 | { | ||
96 | return this.transactions[transactionID].Asset; | ||
97 | } | ||
98 | |||
99 | return null; | ||
100 | } | ||
101 | |||
102 | public void HandleUploadPacket(AssetUploadRequestPacket pack, LLUUID assetID) | ||
103 | { | ||
104 | // Console.Write("asset upload request , type = " + pack.AssetBlock.Type.ToString()); | ||
105 | AssetBase asset = null; | ||
106 | if (pack.AssetBlock.Type == 0) | ||
107 | { | ||
108 | |||
109 | //first packet for transaction | ||
110 | asset = new AssetBase(); | ||
111 | asset.FullID = assetID; | ||
112 | asset.Type = pack.AssetBlock.Type; | ||
113 | asset.InvType = asset.Type; | ||
114 | asset.Name = "UploadedTexture" + Util.RandomClass.Next(1, 1000).ToString("000"); | ||
115 | asset.Data = pack.AssetBlock.AssetData; | ||
116 | |||
117 | |||
118 | } | ||
119 | else if (pack.AssetBlock.Type == 13 | pack.AssetBlock.Type == 5 | pack.AssetBlock.Type == 7) | ||
120 | { | ||
121 | |||
122 | asset = new AssetBase(); | ||
123 | asset.FullID = assetID; | ||
124 | // Console.WriteLine("skin asset id is " + assetID.ToStringHyphenated()); | ||
125 | asset.Type = pack.AssetBlock.Type; | ||
126 | asset.InvType = asset.Type; | ||
127 | asset.Name = "NewClothing" + Util.RandomClass.Next(1, 1000).ToString("000"); | ||
128 | asset.Data = pack.AssetBlock.AssetData; | ||
129 | |||
130 | |||
131 | } | ||
132 | |||
133 | if (asset != null) | ||
134 | { | ||
135 | this.AddUpload(pack.AssetBlock.TransactionID, asset); | ||
136 | } | ||
137 | else | ||
138 | { | ||
139 | |||
140 | //currently we don't support this asset type | ||
141 | //so lets just tell the client that the upload is complete | ||
142 | AssetUploadCompletePacket response = new AssetUploadCompletePacket(); | ||
143 | response.AssetBlock.Type = pack.AssetBlock.Type; | ||
144 | response.AssetBlock.Success = true; | ||
145 | response.AssetBlock.UUID = pack.AssetBlock.TransactionID.Combine(this.ourClient.SecureSessionID); | ||
146 | this.ourClient.OutPacket(response); | ||
147 | } | ||
148 | |||
149 | } | ||
150 | |||
151 | #region Xfer packet system for larger uploads | ||
152 | |||
153 | public void HandleXferPacket(SendXferPacketPacket xferPacket) | ||
154 | { | ||
155 | lock (this.transactions) | ||
156 | { | ||
157 | foreach (AssetTransaction trans in this.transactions.Values) | ||
158 | { | ||
159 | if (trans.XferID == xferPacket.XferID.ID) | ||
160 | { | ||
161 | if (trans.Asset.Data.Length > 1) | ||
162 | { | ||
163 | byte[] newArray = new byte[trans.Asset.Data.Length + xferPacket.DataPacket.Data.Length]; | ||
164 | Array.Copy(trans.Asset.Data, 0, newArray, 0, trans.Asset.Data.Length); | ||
165 | Array.Copy(xferPacket.DataPacket.Data, 0, newArray, trans.Asset.Data.Length, xferPacket.DataPacket.Data.Length); | ||
166 | trans.Asset.Data = newArray; | ||
167 | } | ||
168 | else | ||
169 | { | ||
170 | byte[] newArray = new byte[xferPacket.DataPacket.Data.Length - 4]; | ||
171 | Array.Copy(xferPacket.DataPacket.Data, 4, newArray, 0, xferPacket.DataPacket.Data.Length - 4); | ||
172 | trans.Asset.Data = newArray; | ||
173 | } | ||
174 | |||
175 | if ((xferPacket.XferID.Packet & 2147483648) != 0) | ||
176 | { | ||
177 | //end of transfer | ||
178 | trans.UploadComplete = true; | ||
179 | AssetUploadCompletePacket response = new AssetUploadCompletePacket(); | ||
180 | response.AssetBlock.Type = trans.Asset.Type; | ||
181 | response.AssetBlock.Success = true; | ||
182 | response.AssetBlock.UUID = trans.TransactionID.Combine(this.ourClient.SecureSessionID); | ||
183 | this.ourClient.OutPacket(response); | ||
184 | |||
185 | m_assetCache.AddAsset(trans.Asset); | ||
186 | //check if we should add it to inventory | ||
187 | if (trans.AddToInventory) | ||
188 | { | ||
189 | // m_assetCache.AddAsset(trans.Asset); | ||
190 | m_inventoryCache.AddNewInventoryItem(this.ourClient, trans.InventFolder, trans.Asset); | ||
191 | } | ||
192 | |||
193 | |||
194 | } | ||
195 | break; | ||
196 | } | ||
197 | |||
198 | } | ||
199 | } | ||
200 | |||
201 | ConfirmXferPacketPacket confirmXfer = new ConfirmXferPacketPacket(); | ||
202 | confirmXfer.XferID.ID = xferPacket.XferID.ID; | ||
203 | confirmXfer.XferID.Packet = xferPacket.XferID.Packet; | ||
204 | this.ourClient.OutPacket(confirmXfer); | ||
205 | } | ||
206 | |||
207 | #endregion | ||
208 | |||
209 | public AssetBase AddUploadToAssetCache(LLUUID transactionID) | ||
210 | { | ||
211 | AssetBase asset = null; | ||
212 | if (this.transactions.ContainsKey(transactionID)) | ||
213 | { | ||
214 | AssetTransaction trans = this.transactions[transactionID]; | ||
215 | if (trans.UploadComplete) | ||
216 | { | ||
217 | m_assetCache.AddAsset(trans.Asset); | ||
218 | asset = trans.Asset; | ||
219 | } | ||
220 | } | ||
221 | |||
222 | return asset; | ||
223 | } | ||
224 | |||
225 | public void CreateInventoryItem(CreateInventoryItemPacket packet) | ||
226 | { | ||
227 | if (this.transactions.ContainsKey(packet.InventoryBlock.TransactionID)) | ||
228 | { | ||
229 | AssetTransaction trans = this.transactions[packet.InventoryBlock.TransactionID]; | ||
230 | trans.Asset.Description = Util.FieldToString(packet.InventoryBlock.Description); | ||
231 | trans.Asset.Name = Util.FieldToString(packet.InventoryBlock.Name); | ||
232 | trans.Asset.Type = packet.InventoryBlock.Type; | ||
233 | trans.Asset.InvType = packet.InventoryBlock.InvType; | ||
234 | if (trans.UploadComplete) | ||
235 | { | ||
236 | //already complete so we can add it to the inventory | ||
237 | //m_assetCache.AddAsset(trans.Asset); | ||
238 | m_inventoryCache.AddNewInventoryItem(this.ourClient, packet.InventoryBlock.FolderID, trans.Asset); | ||
239 | } | ||
240 | else | ||
241 | { | ||
242 | trans.AddToInventory = true; | ||
243 | trans.InventFolder = packet.InventoryBlock.FolderID; | ||
244 | } | ||
245 | } | ||
246 | } | ||
247 | |||
248 | private class AssetTransaction | ||
249 | { | ||
250 | public uint XferID; | ||
251 | public AssetBase Asset; | ||
252 | public bool AddToInventory; | ||
253 | public LLUUID InventFolder = LLUUID.Zero; | ||
254 | public bool UploadComplete = false; | ||
255 | public LLUUID TransactionID = LLUUID.Zero; | ||
256 | |||
257 | public AssetTransaction() | ||
258 | { | ||
259 | |||
260 | } | ||
261 | } | ||
262 | |||
263 | //new class , not currently used. | ||
264 | public class AssetXferUploader | ||
265 | { | ||
266 | private IClientAPI ourClient; | ||
267 | |||
268 | public bool UploadComplete = false; | ||
269 | |||
270 | public bool AddToInventory; | ||
271 | public LLUUID InventFolder = LLUUID.Zero; | ||
272 | |||
273 | public uint XferID; | ||
274 | public AssetBase Asset; | ||
275 | public LLUUID TransactionID = LLUUID.Zero; | ||
276 | |||
277 | |||
278 | public AssetXferUploader(IClientAPI remoteClient, LLUUID assetID, LLUUID transaction, sbyte type, byte[] data) | ||
279 | { | ||
280 | ourClient = remoteClient; | ||
281 | Asset = new AssetBase(); | ||
282 | Asset.FullID = assetID; | ||
283 | Asset.InvType = type; | ||
284 | Asset.Type = type; | ||
285 | Asset.Data = data; | ||
286 | Asset.Name = "blank"; | ||
287 | Asset.Description = "empty"; | ||
288 | TransactionID = transaction; | ||
289 | |||
290 | if (Asset.Data.Length > 2) | ||
291 | { | ||
292 | //data block should only have data in it, if there is no more data to be uploaded | ||
293 | this.SendCompleteMessage(); | ||
294 | } | ||
295 | else | ||
296 | { | ||
297 | this.ReqestStartXfer(); | ||
298 | } | ||
299 | } | ||
300 | |||
301 | protected void SendCompleteMessage() | ||
302 | { | ||
303 | UploadComplete = true; | ||
304 | AssetUploadCompletePacket response = new AssetUploadCompletePacket(); | ||
305 | response.AssetBlock.Type = Asset.Type; | ||
306 | response.AssetBlock.Success = true; | ||
307 | response.AssetBlock.UUID = Asset.FullID; | ||
308 | this.ourClient.OutPacket(response); | ||
309 | |||
310 | //TODO trigger event | ||
311 | } | ||
312 | |||
313 | protected void ReqestStartXfer() | ||
314 | { | ||
315 | UploadComplete = false; | ||
316 | XferID = Util.GetNextXferID(); | ||
317 | RequestXferPacket xfer = new RequestXferPacket(); | ||
318 | xfer.XferID.ID = XferID; | ||
319 | xfer.XferID.VFileType = Asset.Type; | ||
320 | xfer.XferID.VFileID = Asset.FullID; | ||
321 | xfer.XferID.FilePath = 0; | ||
322 | xfer.XferID.Filename = new byte[0]; | ||
323 | this.ourClient.OutPacket(xfer); | ||
324 | } | ||
325 | |||
326 | public void HandleXferPacket(uint xferID, uint packetID, byte[] data) | ||
327 | { | ||
328 | if (XferID == xferID) | ||
329 | { | ||
330 | if (Asset.Data.Length > 1) | ||
331 | { | ||
332 | byte[] newArray = new byte[Asset.Data.Length + data.Length]; | ||
333 | Array.Copy(Asset.Data, 0, newArray, 0, Asset.Data.Length); | ||
334 | Array.Copy(data, 0, newArray, Asset.Data.Length, data.Length); | ||
335 | Asset.Data = newArray; | ||
336 | } | ||
337 | else | ||
338 | { | ||
339 | byte[] newArray = new byte[data.Length - 4]; | ||
340 | Array.Copy(data, 4, newArray, 0, data.Length - 4); | ||
341 | Asset.Data = newArray; | ||
342 | } | ||
343 | |||
344 | ConfirmXferPacketPacket confirmXfer = new ConfirmXferPacketPacket(); | ||
345 | confirmXfer.XferID.ID = xferID; | ||
346 | confirmXfer.XferID.Packet = packetID; | ||
347 | this.ourClient.OutPacket(confirmXfer); | ||
348 | |||
349 | if ((packetID & 2147483648) != 0) | ||
350 | { | ||
351 | this.SendCompleteMessage(); | ||
352 | } | ||
353 | } | ||
354 | } | ||
355 | } | ||
356 | } | ||
357 | } | ||
358 | } | ||
diff --git a/OpenSim/Region/ClientStack/ClientView.PacketHandlers.cs b/OpenSim/Region/ClientStack/ClientView.PacketHandlers.cs new file mode 100644 index 0000000..32aed02 --- /dev/null +++ b/OpenSim/Region/ClientStack/ClientView.PacketHandlers.cs | |||
@@ -0,0 +1,198 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://www.openmetaverse.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 | */ | ||
28 | using System; | ||
29 | using System.Collections; | ||
30 | using System.Collections.Generic; | ||
31 | using libsecondlife; | ||
32 | using libsecondlife.Packets; | ||
33 | using Nwc.XmlRpc; | ||
34 | using System.Net; | ||
35 | using System.Net.Sockets; | ||
36 | using System.IO; | ||
37 | using System.Threading; | ||
38 | using System.Timers; | ||
39 | using OpenSim.Framework.Interfaces; | ||
40 | using OpenSim.Framework.Types; | ||
41 | using OpenSim.Framework.Inventory; | ||
42 | using OpenSim.Framework.Utilities; | ||
43 | using OpenSim.Assets; | ||
44 | |||
45 | namespace OpenSim | ||
46 | { | ||
47 | public partial class ClientView | ||
48 | { | ||
49 | protected virtual void RegisterLocalPacketHandlers() | ||
50 | { | ||
51 | this.AddLocalPacketHandler(PacketType.LogoutRequest, this.Logout); | ||
52 | this.AddLocalPacketHandler(PacketType.AgentCachedTexture, this.AgentTextureCached); | ||
53 | this.AddLocalPacketHandler(PacketType.MultipleObjectUpdate, this.MultipleObjUpdate); | ||
54 | } | ||
55 | |||
56 | protected virtual bool Logout(ClientView simClient, Packet packet) | ||
57 | { | ||
58 | OpenSim.Framework.Console.MainLog.Instance.Verbose( "OpenSimClient.cs:ProcessInPacket() - Got a logout request"); | ||
59 | //send reply to let the client logout | ||
60 | LogoutReplyPacket logReply = new LogoutReplyPacket(); | ||
61 | logReply.AgentData.AgentID = this.AgentID; | ||
62 | logReply.AgentData.SessionID = this.SessionID; | ||
63 | logReply.InventoryData = new LogoutReplyPacket.InventoryDataBlock[1]; | ||
64 | logReply.InventoryData[0] = new LogoutReplyPacket.InventoryDataBlock(); | ||
65 | logReply.InventoryData[0].ItemID = LLUUID.Zero; | ||
66 | OutPacket(logReply); | ||
67 | //tell all clients to kill our object | ||
68 | KillObjectPacket kill = new KillObjectPacket(); | ||
69 | kill.ObjectData = new KillObjectPacket.ObjectDataBlock[1]; | ||
70 | kill.ObjectData[0] = new KillObjectPacket.ObjectDataBlock(); | ||
71 | // kill.ObjectData[0].ID = this.ClientAvatar.localid; | ||
72 | foreach (ClientView client in m_clientThreads.Values) | ||
73 | { | ||
74 | client.OutPacket(kill); | ||
75 | } | ||
76 | |||
77 | this.m_inventoryCache.ClientLeaving(this.AgentID, null); | ||
78 | |||
79 | |||
80 | // m_gridServer.LogoutSession(this.SessionID, this.AgentID, this.CircuitCode); | ||
81 | /*lock (m_world.Entities) | ||
82 | { | ||
83 | m_world.Entities.Remove(this.AgentID); | ||
84 | }*/ | ||
85 | // m_world.RemoveViewerAgent(this); | ||
86 | //need to do other cleaning up here too | ||
87 | m_clientThreads.Remove(this.CircuitCode); | ||
88 | m_networkServer.RemoveClientCircuit(this.CircuitCode); | ||
89 | this.ClientThread.Abort(); | ||
90 | return true; | ||
91 | } | ||
92 | |||
93 | protected bool AgentTextureCached(ClientView simclient, Packet packet) | ||
94 | { | ||
95 | // Console.WriteLine(packet.ToString()); | ||
96 | AgentCachedTexturePacket chechedtex = (AgentCachedTexturePacket)packet; | ||
97 | AgentCachedTextureResponsePacket cachedresp = new AgentCachedTextureResponsePacket(); | ||
98 | cachedresp.AgentData.AgentID = this.AgentID; | ||
99 | cachedresp.AgentData.SessionID = this.SessionID; | ||
100 | cachedresp.AgentData.SerialNum = this.cachedtextureserial; | ||
101 | this.cachedtextureserial++; | ||
102 | cachedresp.WearableData = new AgentCachedTextureResponsePacket.WearableDataBlock[chechedtex.WearableData.Length]; | ||
103 | for (int i = 0; i < chechedtex.WearableData.Length; i++) | ||
104 | { | ||
105 | cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); | ||
106 | cachedresp.WearableData[i].TextureIndex = chechedtex.WearableData[i].TextureIndex; | ||
107 | cachedresp.WearableData[i].TextureID = LLUUID.Zero; | ||
108 | cachedresp.WearableData[i].HostName = new byte[0]; | ||
109 | } | ||
110 | this.OutPacket(cachedresp); | ||
111 | return true; | ||
112 | } | ||
113 | |||
114 | protected bool MultipleObjUpdate(ClientView simClient, Packet packet) | ||
115 | { | ||
116 | MultipleObjectUpdatePacket multipleupdate = (MultipleObjectUpdatePacket)packet; | ||
117 | for (int i = 0; i < multipleupdate.ObjectData.Length; i++) | ||
118 | { | ||
119 | if (multipleupdate.ObjectData[i].Type == 9) //change position | ||
120 | { | ||
121 | if (OnUpdatePrimPosition != null) | ||
122 | { | ||
123 | libsecondlife.LLVector3 pos = new LLVector3(multipleupdate.ObjectData[i].Data, 0); | ||
124 | OnUpdatePrimPosition(multipleupdate.ObjectData[i].ObjectLocalID, pos, this); | ||
125 | } | ||
126 | //should update stored position of the prim | ||
127 | } | ||
128 | else if (multipleupdate.ObjectData[i].Type == 10)//rotation | ||
129 | { | ||
130 | if (OnUpdatePrimRotation != null) | ||
131 | { | ||
132 | libsecondlife.LLQuaternion rot = new LLQuaternion(multipleupdate.ObjectData[i].Data, 0, true); | ||
133 | OnUpdatePrimRotation(multipleupdate.ObjectData[i].ObjectLocalID, rot, this); | ||
134 | } | ||
135 | } | ||
136 | else if (multipleupdate.ObjectData[i].Type == 13)//scale | ||
137 | { | ||
138 | if (OnUpdatePrimScale != null) | ||
139 | { | ||
140 | libsecondlife.LLVector3 scale = new LLVector3(multipleupdate.ObjectData[i].Data, 12); | ||
141 | OnUpdatePrimScale(multipleupdate.ObjectData[i].ObjectLocalID, scale, this); | ||
142 | } | ||
143 | } | ||
144 | } | ||
145 | return true; | ||
146 | } | ||
147 | |||
148 | public void RequestMapLayer() | ||
149 | { | ||
150 | //should be getting the map layer from the grid server | ||
151 | //send a layer covering the 800,800 - 1200,1200 area (should be covering the requested area) | ||
152 | MapLayerReplyPacket mapReply = new MapLayerReplyPacket(); | ||
153 | mapReply.AgentData.AgentID = this.AgentID; | ||
154 | mapReply.AgentData.Flags = 0; | ||
155 | mapReply.LayerData = new MapLayerReplyPacket.LayerDataBlock[1]; | ||
156 | mapReply.LayerData[0] = new MapLayerReplyPacket.LayerDataBlock(); | ||
157 | mapReply.LayerData[0].Bottom = 0; | ||
158 | mapReply.LayerData[0].Left = 0; | ||
159 | mapReply.LayerData[0].Top = 30000; | ||
160 | mapReply.LayerData[0].Right = 30000; | ||
161 | mapReply.LayerData[0].ImageID = new LLUUID("00000000-0000-0000-9999-000000000006"); | ||
162 | this.OutPacket(mapReply); | ||
163 | } | ||
164 | |||
165 | public void RequestMapBlocks(int minX, int minY, int maxX, int maxY) | ||
166 | { | ||
167 | /* | ||
168 | IList simMapProfiles = m_gridServer.RequestMapBlocks(minX, minY, maxX, maxY); | ||
169 | MapBlockReplyPacket mbReply = new MapBlockReplyPacket(); | ||
170 | mbReply.AgentData.AgentID = this.AgentID; | ||
171 | int len; | ||
172 | if (simMapProfiles == null) | ||
173 | len = 0; | ||
174 | else | ||
175 | len = simMapProfiles.Count; | ||
176 | |||
177 | mbReply.Data = new MapBlockReplyPacket.DataBlock[len]; | ||
178 | int iii; | ||
179 | for (iii = 0; iii < len; iii++) | ||
180 | { | ||
181 | Hashtable mp = (Hashtable)simMapProfiles[iii]; | ||
182 | mbReply.Data[iii] = new MapBlockReplyPacket.DataBlock(); | ||
183 | mbReply.Data[iii].Name = System.Text.Encoding.UTF8.GetBytes((string)mp["name"]); | ||
184 | mbReply.Data[iii].Access = System.Convert.ToByte(mp["access"]); | ||
185 | mbReply.Data[iii].Agents = System.Convert.ToByte(mp["agents"]); | ||
186 | mbReply.Data[iii].MapImageID = new LLUUID((string)mp["map-image-id"]); | ||
187 | mbReply.Data[iii].RegionFlags = System.Convert.ToUInt32(mp["region-flags"]); | ||
188 | mbReply.Data[iii].WaterHeight = System.Convert.ToByte(mp["water-height"]); | ||
189 | mbReply.Data[iii].X = System.Convert.ToUInt16(mp["x"]); | ||
190 | mbReply.Data[iii].Y = System.Convert.ToUInt16(mp["y"]); | ||
191 | } | ||
192 | this.OutPacket(mbReply); | ||
193 | */ | ||
194 | } | ||
195 | |||
196 | |||
197 | } | ||
198 | } | ||
diff --git a/OpenSim/Region/ClientStack/ClientView.ProcessPackets.cs b/OpenSim/Region/ClientStack/ClientView.ProcessPackets.cs new file mode 100644 index 0000000..191ef21 --- /dev/null +++ b/OpenSim/Region/ClientStack/ClientView.ProcessPackets.cs | |||
@@ -0,0 +1,550 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://www.openmetaverse.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 | */ | ||
28 | using System; | ||
29 | using System.Collections; | ||
30 | using System.Collections.Generic; | ||
31 | using libsecondlife; | ||
32 | using libsecondlife.Packets; | ||
33 | using Nwc.XmlRpc; | ||
34 | using System.Net; | ||
35 | using System.Net.Sockets; | ||
36 | using System.IO; | ||
37 | using System.Threading; | ||
38 | using System.Timers; | ||
39 | using OpenSim.Framework.Interfaces; | ||
40 | using OpenSim.Framework.Types; | ||
41 | using OpenSim.Framework.Inventory; | ||
42 | using OpenSim.Framework.Utilities; | ||
43 | using OpenSim.Assets; | ||
44 | |||
45 | namespace OpenSim | ||
46 | { | ||
47 | public partial class ClientView | ||
48 | { | ||
49 | protected override void ProcessInPacket(Packet Pack) | ||
50 | { | ||
51 | ack_pack(Pack); | ||
52 | if (debug) | ||
53 | { | ||
54 | if (Pack.Type != PacketType.AgentUpdate) | ||
55 | { | ||
56 | Console.WriteLine(Pack.Type.ToString()); | ||
57 | } | ||
58 | } | ||
59 | |||
60 | if (this.ProcessPacketMethod(Pack)) | ||
61 | { | ||
62 | //there is a handler registered that handled this packet type | ||
63 | return; | ||
64 | } | ||
65 | else | ||
66 | { | ||
67 | System.Text.Encoding _enc = System.Text.Encoding.ASCII; | ||
68 | |||
69 | switch (Pack.Type) | ||
70 | { | ||
71 | case PacketType.ViewerEffect: | ||
72 | ViewerEffectPacket viewer = (ViewerEffectPacket)Pack; | ||
73 | foreach (ClientView client in m_clientThreads.Values) | ||
74 | { | ||
75 | if (client.AgentID != this.AgentID) | ||
76 | { | ||
77 | viewer.AgentData.AgentID = client.AgentID; | ||
78 | viewer.AgentData.SessionID = client.SessionID; | ||
79 | client.OutPacket(viewer); | ||
80 | } | ||
81 | } | ||
82 | break; | ||
83 | |||
84 | #region World/Avatar | ||
85 | case PacketType.ChatFromViewer: | ||
86 | ChatFromViewerPacket inchatpack = (ChatFromViewerPacket)Pack; | ||
87 | if (Util.FieldToString(inchatpack.ChatData.Message) == "") | ||
88 | { | ||
89 | //empty message so don't bother with it | ||
90 | break; | ||
91 | } | ||
92 | string fromName = ""; //ClientAvatar.firstname + " " + ClientAvatar.lastname; | ||
93 | byte[] message = inchatpack.ChatData.Message; | ||
94 | byte type = inchatpack.ChatData.Type; | ||
95 | LLVector3 fromPos = new LLVector3(); // ClientAvatar.Pos; | ||
96 | LLUUID fromAgentID = AgentID; | ||
97 | if (OnChatFromViewer != null) | ||
98 | { | ||
99 | this.OnChatFromViewer(message, type, fromPos, fromName, fromAgentID); | ||
100 | } | ||
101 | break; | ||
102 | case PacketType.RezObject: | ||
103 | RezObjectPacket rezPacket = (RezObjectPacket)Pack; | ||
104 | AgentInventory inven = this.m_inventoryCache.GetAgentsInventory(this.AgentID); | ||
105 | if (inven != null) | ||
106 | { | ||
107 | if (inven.InventoryItems.ContainsKey(rezPacket.InventoryData.ItemID)) | ||
108 | { | ||
109 | AssetBase asset = this.m_assetCache.GetAsset(inven.InventoryItems[rezPacket.InventoryData.ItemID].AssetID); | ||
110 | if (asset != null) | ||
111 | { | ||
112 | if (OnRezObject != null) | ||
113 | { | ||
114 | this.OnRezObject(asset, rezPacket.RezData.RayEnd); | ||
115 | this.m_inventoryCache.DeleteInventoryItem(this, rezPacket.InventoryData.ItemID); | ||
116 | } | ||
117 | } | ||
118 | } | ||
119 | } | ||
120 | break; | ||
121 | case PacketType.DeRezObject: | ||
122 | if (OnDeRezObject != null) | ||
123 | { | ||
124 | OnDeRezObject(Pack, this); | ||
125 | } | ||
126 | break; | ||
127 | case PacketType.ModifyLand: | ||
128 | ModifyLandPacket modify = (ModifyLandPacket)Pack; | ||
129 | if (modify.ParcelData.Length > 0) | ||
130 | { | ||
131 | if (OnModifyTerrain != null) | ||
132 | { | ||
133 | OnModifyTerrain(modify.ModifyBlock.Height, modify.ModifyBlock.Seconds, modify.ModifyBlock.BrushSize, | ||
134 | modify.ModifyBlock.Action, modify.ParcelData[0].North, modify.ParcelData[0].West); | ||
135 | } | ||
136 | } | ||
137 | break; | ||
138 | case PacketType.RegionHandshakeReply: | ||
139 | if (OnRegionHandShakeReply != null) | ||
140 | { | ||
141 | OnRegionHandShakeReply(this); | ||
142 | } | ||
143 | break; | ||
144 | case PacketType.AgentWearablesRequest: | ||
145 | if (OnRequestWearables != null) | ||
146 | { | ||
147 | OnRequestWearables(this); | ||
148 | } | ||
149 | if (OnRequestAvatarsData != null) | ||
150 | { | ||
151 | OnRequestAvatarsData(this); | ||
152 | } | ||
153 | break; | ||
154 | case PacketType.AgentSetAppearance: | ||
155 | AgentSetAppearancePacket appear = (AgentSetAppearancePacket)Pack; | ||
156 | if (OnSetAppearance != null) | ||
157 | { | ||
158 | OnSetAppearance(appear.ObjectData.TextureEntry, appear.VisualParam); | ||
159 | } | ||
160 | break; | ||
161 | case PacketType.CompleteAgentMovement: | ||
162 | if (OnCompleteMovementToRegion != null) | ||
163 | { | ||
164 | OnCompleteMovementToRegion(); | ||
165 | } | ||
166 | break; | ||
167 | case PacketType.AgentUpdate: | ||
168 | if (OnAgentUpdate != null) | ||
169 | { | ||
170 | AgentUpdatePacket agenUpdate = (AgentUpdatePacket) Pack; | ||
171 | OnAgentUpdate(this, agenUpdate.AgentData.ControlFlags, agenUpdate.AgentData.BodyRotation ); | ||
172 | } | ||
173 | break; | ||
174 | case PacketType.AgentAnimation: | ||
175 | if (!m_child) | ||
176 | { | ||
177 | AgentAnimationPacket AgentAni = (AgentAnimationPacket)Pack; | ||
178 | for (int i = 0; i < AgentAni.AnimationList.Length; i++) | ||
179 | { | ||
180 | if (AgentAni.AnimationList[i].StartAnim) | ||
181 | { | ||
182 | if (OnStartAnim != null) | ||
183 | { | ||
184 | OnStartAnim(AgentAni.AnimationList[i].AnimID, 1); | ||
185 | } | ||
186 | } | ||
187 | } | ||
188 | } | ||
189 | break; | ||
190 | |||
191 | #endregion | ||
192 | |||
193 | #region Objects/Prims | ||
194 | case PacketType.ObjectLink: | ||
195 | // OpenSim.Framework.Console.MainLog.Instance.Verbose( Pack.ToString()); | ||
196 | ObjectLinkPacket link = (ObjectLinkPacket)Pack; | ||
197 | uint parentprimid = 0; | ||
198 | List<uint> childrenprims = new List<uint>(); | ||
199 | if (link.ObjectData.Length > 1) | ||
200 | { | ||
201 | parentprimid = link.ObjectData[0].ObjectLocalID; | ||
202 | |||
203 | for (int i = 1; i < link.ObjectData.Length; i++) | ||
204 | { | ||
205 | childrenprims.Add(link.ObjectData[i].ObjectLocalID); | ||
206 | } | ||
207 | } | ||
208 | if (OnLinkObjects != null) | ||
209 | { | ||
210 | OnLinkObjects(parentprimid, childrenprims); | ||
211 | } | ||
212 | break; | ||
213 | case PacketType.ObjectAdd: | ||
214 | // m_world.AddNewPrim((ObjectAddPacket)Pack, this); | ||
215 | if (OnAddPrim != null) | ||
216 | { | ||
217 | OnAddPrim(Pack, this); | ||
218 | } | ||
219 | break; | ||
220 | case PacketType.ObjectShape: | ||
221 | ObjectShapePacket shape = (ObjectShapePacket)Pack; | ||
222 | for (int i = 0; i < shape.ObjectData.Length; i++) | ||
223 | { | ||
224 | if (OnUpdatePrimShape != null) | ||
225 | { | ||
226 | OnUpdatePrimShape(shape.ObjectData[i].ObjectLocalID, shape.ObjectData[i]); | ||
227 | } | ||
228 | } | ||
229 | break; | ||
230 | case PacketType.ObjectSelect: | ||
231 | ObjectSelectPacket incomingselect = (ObjectSelectPacket)Pack; | ||
232 | for (int i = 0; i < incomingselect.ObjectData.Length; i++) | ||
233 | { | ||
234 | if (OnObjectSelect != null) | ||
235 | { | ||
236 | OnObjectSelect(incomingselect.ObjectData[i].ObjectLocalID, this); | ||
237 | } | ||
238 | } | ||
239 | break; | ||
240 | case PacketType.ObjectFlagUpdate: | ||
241 | ObjectFlagUpdatePacket flags = (ObjectFlagUpdatePacket)Pack; | ||
242 | if (OnUpdatePrimFlags != null) | ||
243 | { | ||
244 | OnUpdatePrimFlags(flags.AgentData.ObjectLocalID, Pack, this); | ||
245 | } | ||
246 | break; | ||
247 | case PacketType.ObjectImage: | ||
248 | ObjectImagePacket imagePack = (ObjectImagePacket)Pack; | ||
249 | for (int i = 0; i < imagePack.ObjectData.Length; i++) | ||
250 | { | ||
251 | if (OnUpdatePrimTexture != null) | ||
252 | { | ||
253 | OnUpdatePrimTexture(imagePack.ObjectData[i].ObjectLocalID, imagePack.ObjectData[i].TextureEntry, this); | ||
254 | } | ||
255 | } | ||
256 | break; | ||
257 | case PacketType.ObjectGrab: | ||
258 | ObjectGrabPacket grap = (ObjectGrabPacket)Pack; | ||
259 | if (OnGrapObject != null) | ||
260 | { | ||
261 | OnGrapObject(grap.ObjectData.LocalID, grap.ObjectData.GrabOffset, this); | ||
262 | } | ||
263 | break; | ||
264 | case PacketType.ObjectGrabUpdate: | ||
265 | ObjectGrabUpdatePacket grapUpdate = (ObjectGrabUpdatePacket)Pack; | ||
266 | if (OnGrapUpdate != null) | ||
267 | { | ||
268 | OnGrapUpdate(grapUpdate.ObjectData.ObjectID, grapUpdate.ObjectData.GrabOffsetInitial, grapUpdate.ObjectData.GrabPosition, this); | ||
269 | } | ||
270 | break; | ||
271 | case PacketType.ObjectDeGrab: | ||
272 | ObjectDeGrabPacket deGrap = (ObjectDeGrabPacket)Pack; | ||
273 | if (OnDeGrapObject != null) | ||
274 | { | ||
275 | OnDeGrapObject(deGrap.ObjectData.LocalID, this); | ||
276 | } | ||
277 | break; | ||
278 | #endregion | ||
279 | |||
280 | #region Inventory/Asset/Other related packets | ||
281 | case PacketType.RequestImage: | ||
282 | RequestImagePacket imageRequest = (RequestImagePacket)Pack; | ||
283 | for (int i = 0; i < imageRequest.RequestImage.Length; i++) | ||
284 | { | ||
285 | m_assetCache.AddTextureRequest(this, imageRequest.RequestImage[i].Image); | ||
286 | } | ||
287 | break; | ||
288 | case PacketType.TransferRequest: | ||
289 | //Console.WriteLine("OpenSimClient.cs:ProcessInPacket() - Got transfer request"); | ||
290 | TransferRequestPacket transfer = (TransferRequestPacket)Pack; | ||
291 | m_assetCache.AddAssetRequest(this, transfer); | ||
292 | break; | ||
293 | case PacketType.AssetUploadRequest: | ||
294 | AssetUploadRequestPacket request = (AssetUploadRequestPacket)Pack; | ||
295 | this.UploadAssets.HandleUploadPacket(request, request.AssetBlock.TransactionID.Combine(this.SecureSessionID)); | ||
296 | break; | ||
297 | case PacketType.RequestXfer: | ||
298 | //Console.WriteLine(Pack.ToString()); | ||
299 | break; | ||
300 | case PacketType.SendXferPacket: | ||
301 | this.UploadAssets.HandleXferPacket((SendXferPacketPacket)Pack); | ||
302 | break; | ||
303 | case PacketType.CreateInventoryFolder: | ||
304 | CreateInventoryFolderPacket invFolder = (CreateInventoryFolderPacket)Pack; | ||
305 | m_inventoryCache.CreateNewInventoryFolder(this, invFolder.FolderData.FolderID, (ushort)invFolder.FolderData.Type, Util.FieldToString(invFolder.FolderData.Name), invFolder.FolderData.ParentID); | ||
306 | //Console.WriteLine(Pack.ToString()); | ||
307 | break; | ||
308 | case PacketType.CreateInventoryItem: | ||
309 | //Console.WriteLine(Pack.ToString()); | ||
310 | CreateInventoryItemPacket createItem = (CreateInventoryItemPacket)Pack; | ||
311 | if (createItem.InventoryBlock.TransactionID != LLUUID.Zero) | ||
312 | { | ||
313 | this.UploadAssets.CreateInventoryItem(createItem); | ||
314 | } | ||
315 | else | ||
316 | { | ||
317 | // Console.Write(Pack.ToString()); | ||
318 | this.CreateInventoryItem(createItem); | ||
319 | } | ||
320 | break; | ||
321 | case PacketType.FetchInventory: | ||
322 | //Console.WriteLine("fetch item packet"); | ||
323 | FetchInventoryPacket FetchInventory = (FetchInventoryPacket)Pack; | ||
324 | m_inventoryCache.FetchInventory(this, FetchInventory); | ||
325 | break; | ||
326 | case PacketType.FetchInventoryDescendents: | ||
327 | FetchInventoryDescendentsPacket Fetch = (FetchInventoryDescendentsPacket)Pack; | ||
328 | m_inventoryCache.FetchInventoryDescendents(this, Fetch); | ||
329 | break; | ||
330 | case PacketType.UpdateInventoryItem: | ||
331 | UpdateInventoryItemPacket update = (UpdateInventoryItemPacket)Pack; | ||
332 | //Console.WriteLine(Pack.ToString()); | ||
333 | for (int i = 0; i < update.InventoryData.Length; i++) | ||
334 | { | ||
335 | if (update.InventoryData[i].TransactionID != LLUUID.Zero) | ||
336 | { | ||
337 | AssetBase asset = m_assetCache.GetAsset(update.InventoryData[i].TransactionID.Combine(this.SecureSessionID)); | ||
338 | if (asset != null) | ||
339 | { | ||
340 | // Console.WriteLine("updating inventory item, found asset" + asset.FullID.ToStringHyphenated() + " already in cache"); | ||
341 | m_inventoryCache.UpdateInventoryItemAsset(this, update.InventoryData[i].ItemID, asset); | ||
342 | } | ||
343 | else | ||
344 | { | ||
345 | asset = this.UploadAssets.AddUploadToAssetCache(update.InventoryData[i].TransactionID); | ||
346 | if (asset != null) | ||
347 | { | ||
348 | //Console.WriteLine("updating inventory item, adding asset" + asset.FullID.ToStringHyphenated() + " to cache"); | ||
349 | m_inventoryCache.UpdateInventoryItemAsset(this, update.InventoryData[i].ItemID, asset); | ||
350 | } | ||
351 | else | ||
352 | { | ||
353 | //Console.WriteLine("trying to update inventory item, but asset is null"); | ||
354 | } | ||
355 | } | ||
356 | } | ||
357 | else | ||
358 | { | ||
359 | m_inventoryCache.UpdateInventoryItemDetails(this, update.InventoryData[i].ItemID, update.InventoryData[i]); ; | ||
360 | } | ||
361 | } | ||
362 | break; | ||
363 | case PacketType.RequestTaskInventory: | ||
364 | // Console.WriteLine(Pack.ToString()); | ||
365 | RequestTaskInventoryPacket requesttask = (RequestTaskInventoryPacket)Pack; | ||
366 | ReplyTaskInventoryPacket replytask = new ReplyTaskInventoryPacket(); | ||
367 | bool foundent = false; | ||
368 | /* foreach (Entity ent in m_world.Entities.Values) | ||
369 | { | ||
370 | if (ent.localid == requesttask.InventoryData.LocalID) | ||
371 | { | ||
372 | replytask.InventoryData.TaskID = ent.uuid; | ||
373 | replytask.InventoryData.Serial = 0; | ||
374 | replytask.InventoryData.Filename = new byte[0]; | ||
375 | foundent = true; | ||
376 | } | ||
377 | } | ||
378 | if (foundent) | ||
379 | { | ||
380 | this.OutPacket(replytask); | ||
381 | }*/ | ||
382 | break; | ||
383 | case PacketType.UpdateTaskInventory: | ||
384 | // Console.WriteLine(Pack.ToString()); | ||
385 | UpdateTaskInventoryPacket updatetask = (UpdateTaskInventoryPacket)Pack; | ||
386 | AgentInventory myinventory = this.m_inventoryCache.GetAgentsInventory(this.AgentID); | ||
387 | /*if (myinventory != null) | ||
388 | { | ||
389 | if (updatetask.UpdateData.Key == 0) | ||
390 | { | ||
391 | if (myinventory.InventoryItems[updatetask.InventoryData.ItemID] != null) | ||
392 | { | ||
393 | if (myinventory.InventoryItems[updatetask.InventoryData.ItemID].Type == 7) | ||
394 | { | ||
395 | LLUUID noteaid = myinventory.InventoryItems[updatetask.InventoryData.ItemID].AssetID; | ||
396 | AssetBase assBase = this.m_assetCache.GetAsset(noteaid); | ||
397 | if (assBase != null) | ||
398 | { | ||
399 | foreach (Entity ent in m_world.Entities.Values) | ||
400 | { | ||
401 | if (ent.localid == updatetask.UpdateData.LocalID) | ||
402 | { | ||
403 | if (ent is OpenSim.world.Primitive) | ||
404 | { | ||
405 | this.m_world.AddScript(ent, Util.FieldToString(assBase.Data)); | ||
406 | } | ||
407 | } | ||
408 | } | ||
409 | } | ||
410 | } | ||
411 | } | ||
412 | } | ||
413 | }*/ | ||
414 | break; | ||
415 | case PacketType.MapLayerRequest: | ||
416 | this.RequestMapLayer(); | ||
417 | break; | ||
418 | case PacketType.MapBlockRequest: | ||
419 | MapBlockRequestPacket MapRequest = (MapBlockRequestPacket)Pack; | ||
420 | if (OnRequestMapBlocks != null) | ||
421 | { | ||
422 | OnRequestMapBlocks(this, MapRequest.PositionData.MinX, MapRequest.PositionData.MinY, MapRequest.PositionData.MaxX, MapRequest.PositionData.MaxY); | ||
423 | } | ||
424 | break; | ||
425 | case PacketType.TeleportLandmarkRequest: | ||
426 | TeleportLandmarkRequestPacket tpReq = (TeleportLandmarkRequestPacket)Pack; | ||
427 | |||
428 | TeleportStartPacket tpStart = new TeleportStartPacket(); | ||
429 | tpStart.Info.TeleportFlags = 8; // tp via lm | ||
430 | this.OutPacket(tpStart); | ||
431 | |||
432 | TeleportProgressPacket tpProgress = new TeleportProgressPacket(); | ||
433 | tpProgress.Info.Message = (new System.Text.ASCIIEncoding()).GetBytes("sending_landmark"); | ||
434 | tpProgress.Info.TeleportFlags = 8; | ||
435 | tpProgress.AgentData.AgentID = tpReq.Info.AgentID; | ||
436 | this.OutPacket(tpProgress); | ||
437 | |||
438 | // Fetch landmark | ||
439 | LLUUID lmid = tpReq.Info.LandmarkID; | ||
440 | AssetBase lma = this.m_assetCache.GetAsset(lmid); | ||
441 | if (lma != null) | ||
442 | { | ||
443 | AssetLandmark lm = new AssetLandmark(lma); | ||
444 | |||
445 | if (lm.RegionID == m_regionData.SimUUID) | ||
446 | { | ||
447 | TeleportLocalPacket tpLocal = new TeleportLocalPacket(); | ||
448 | |||
449 | tpLocal.Info.AgentID = tpReq.Info.AgentID; | ||
450 | tpLocal.Info.TeleportFlags = 8; // Teleport via landmark | ||
451 | tpLocal.Info.LocationID = 2; | ||
452 | tpLocal.Info.Position = lm.Position; | ||
453 | OutPacket(tpLocal); | ||
454 | } | ||
455 | else | ||
456 | { | ||
457 | TeleportCancelPacket tpCancel = new TeleportCancelPacket(); | ||
458 | tpCancel.Info.AgentID = tpReq.Info.AgentID; | ||
459 | tpCancel.Info.SessionID = tpReq.Info.SessionID; | ||
460 | OutPacket(tpCancel); | ||
461 | } | ||
462 | } | ||
463 | else | ||
464 | { | ||
465 | Console.WriteLine("Cancelling Teleport - fetch asset not yet implemented"); | ||
466 | |||
467 | TeleportCancelPacket tpCancel = new TeleportCancelPacket(); | ||
468 | tpCancel.Info.AgentID = tpReq.Info.AgentID; | ||
469 | tpCancel.Info.SessionID = tpReq.Info.SessionID; | ||
470 | OutPacket(tpCancel); | ||
471 | } | ||
472 | break; | ||
473 | case PacketType.TeleportLocationRequest: | ||
474 | TeleportLocationRequestPacket tpLocReq = (TeleportLocationRequestPacket)Pack; | ||
475 | // Console.WriteLine(tpLocReq.ToString()); | ||
476 | |||
477 | if (OnTeleportLocationRequest != null) | ||
478 | { | ||
479 | OnTeleportLocationRequest(this, tpLocReq.Info.RegionHandle, tpLocReq.Info.Position, tpLocReq.Info.LookAt, 16); | ||
480 | } | ||
481 | else | ||
482 | { | ||
483 | //no event handler so cancel request | ||
484 | TeleportCancelPacket tpCancel = new TeleportCancelPacket(); | ||
485 | tpCancel.Info.SessionID = tpLocReq.AgentData.SessionID; | ||
486 | tpCancel.Info.AgentID = tpLocReq.AgentData.AgentID; | ||
487 | OutPacket(tpCancel); | ||
488 | } | ||
489 | break; | ||
490 | #endregion | ||
491 | |||
492 | case PacketType.MoneyBalanceRequest: | ||
493 | this.SendMoneyBalance(LLUUID.Zero, true, new byte[0], 1000); | ||
494 | break; | ||
495 | |||
496 | #region Parcel related packets | ||
497 | case PacketType.ParcelPropertiesRequest: | ||
498 | ParcelPropertiesRequestPacket propertiesRequest = (ParcelPropertiesRequestPacket)Pack; | ||
499 | if (OnParcelPropertiesRequest != null) | ||
500 | { | ||
501 | OnParcelPropertiesRequest((int)Math.Round(propertiesRequest.ParcelData.West), (int)Math.Round(propertiesRequest.ParcelData.South), (int)Math.Round(propertiesRequest.ParcelData.East), (int)Math.Round(propertiesRequest.ParcelData.North), propertiesRequest.ParcelData.SequenceID, propertiesRequest.ParcelData.SnapSelection, this); | ||
502 | } | ||
503 | break; | ||
504 | case PacketType.ParcelDivide: | ||
505 | ParcelDividePacket parcelDivide = (ParcelDividePacket)Pack; | ||
506 | if (OnParcelDivideRequest != null) | ||
507 | { | ||
508 | OnParcelDivideRequest((int)Math.Round(parcelDivide.ParcelData.West), (int)Math.Round(parcelDivide.ParcelData.South), (int)Math.Round(parcelDivide.ParcelData.East), (int)Math.Round(parcelDivide.ParcelData.North), this); | ||
509 | } | ||
510 | break; | ||
511 | case PacketType.ParcelJoin: | ||
512 | ParcelJoinPacket parcelJoin = (ParcelJoinPacket)Pack; | ||
513 | if (OnParcelJoinRequest != null) | ||
514 | { | ||
515 | OnParcelJoinRequest((int)Math.Round(parcelJoin.ParcelData.West), (int)Math.Round(parcelJoin.ParcelData.South), (int)Math.Round(parcelJoin.ParcelData.East), (int)Math.Round(parcelJoin.ParcelData.North), this); | ||
516 | } | ||
517 | break; | ||
518 | case PacketType.ParcelPropertiesUpdate: | ||
519 | ParcelPropertiesUpdatePacket updatePacket = (ParcelPropertiesUpdatePacket)Pack; | ||
520 | if (OnParcelPropertiesUpdateRequest != null) | ||
521 | { | ||
522 | OnParcelPropertiesUpdateRequest(updatePacket, this); | ||
523 | } | ||
524 | break; | ||
525 | #endregion | ||
526 | |||
527 | #region Estate Packets | ||
528 | case PacketType.EstateOwnerMessage: | ||
529 | EstateOwnerMessagePacket messagePacket = (EstateOwnerMessagePacket)Pack; | ||
530 | if (OnEstateOwnerMessage != null) | ||
531 | { | ||
532 | OnEstateOwnerMessage(messagePacket, this); | ||
533 | } | ||
534 | break; | ||
535 | #endregion | ||
536 | |||
537 | #region unimplemented handlers | ||
538 | case PacketType.AgentIsNowWearing: | ||
539 | // AgentIsNowWearingPacket wear = (AgentIsNowWearingPacket)Pack; | ||
540 | //Console.WriteLine(Pack.ToString()); | ||
541 | break; | ||
542 | case PacketType.ObjectScale: | ||
543 | //OpenSim.Framework.Console.MainLog.Instance.Verbose( Pack.ToString()); | ||
544 | break; | ||
545 | #endregion | ||
546 | } | ||
547 | } | ||
548 | } | ||
549 | } | ||
550 | } | ||
diff --git a/OpenSim/Region/ClientStack/ClientView.cs b/OpenSim/Region/ClientStack/ClientView.cs new file mode 100644 index 0000000..312da9d --- /dev/null +++ b/OpenSim/Region/ClientStack/ClientView.cs | |||
@@ -0,0 +1,273 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://www.openmetaverse.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 | */ | ||
28 | using System; | ||
29 | using System.Collections; | ||
30 | using System.Collections.Generic; | ||
31 | using libsecondlife; | ||
32 | using libsecondlife.Packets; | ||
33 | using Nwc.XmlRpc; | ||
34 | using System.Net; | ||
35 | using System.Net.Sockets; | ||
36 | using System.IO; | ||
37 | using System.Threading; | ||
38 | using System.Timers; | ||
39 | using OpenSim.Framework; | ||
40 | using OpenSim.Framework.Interfaces; | ||
41 | using OpenSim.Framework.Types; | ||
42 | using OpenSim.Framework.Inventory; | ||
43 | using OpenSim.Framework.Utilities; | ||
44 | using OpenSim.Assets; | ||
45 | using OpenSim.Caches; | ||
46 | |||
47 | namespace OpenSim | ||
48 | { | ||
49 | public delegate bool PacketMethod(ClientView simClient, Packet packet); | ||
50 | |||
51 | /// <summary> | ||
52 | /// Handles new client connections | ||
53 | /// Constructor takes a single Packet and authenticates everything | ||
54 | /// </summary> | ||
55 | public partial class ClientView : ClientViewBase, IClientAPI | ||
56 | { | ||
57 | public static TerrainManager TerrainManager; | ||
58 | |||
59 | protected static Dictionary<PacketType, PacketMethod> PacketHandlers = new Dictionary<PacketType, PacketMethod>(); //Global/static handlers for all clients | ||
60 | protected Dictionary<PacketType, PacketMethod> m_packetHandlers = new Dictionary<PacketType, PacketMethod>(); //local handlers for this instance | ||
61 | |||
62 | public LLUUID AgentID; | ||
63 | public LLUUID SessionID; | ||
64 | public LLUUID SecureSessionID = LLUUID.Zero; | ||
65 | public string firstName; | ||
66 | public string lastName; | ||
67 | public bool m_child = false; | ||
68 | private UseCircuitCodePacket cirpack; | ||
69 | public Thread ClientThread; | ||
70 | public LLVector3 startpos; | ||
71 | |||
72 | private AgentAssetUpload UploadAssets; | ||
73 | private LLUUID newAssetFolder = LLUUID.Zero; | ||
74 | private bool debug = false; | ||
75 | protected IWorld m_world; | ||
76 | private Dictionary<uint, ClientView> m_clientThreads; | ||
77 | private AssetCache m_assetCache; | ||
78 | private InventoryCache m_inventoryCache; | ||
79 | private int cachedtextureserial = 0; | ||
80 | private RegionInfo m_regionData; | ||
81 | protected AuthenticateSessionsBase m_authenticateSessionsHandler; | ||
82 | |||
83 | public ClientView(EndPoint remoteEP, UseCircuitCodePacket initialcirpack, Dictionary<uint, ClientView> clientThreads, IWorld world, AssetCache assetCache, PacketServer packServer, InventoryCache inventoryCache, AuthenticateSessionsBase authenSessions ) | ||
84 | { | ||
85 | m_world = world; | ||
86 | m_clientThreads = clientThreads; | ||
87 | m_assetCache = assetCache; | ||
88 | |||
89 | m_networkServer = packServer; | ||
90 | m_inventoryCache = inventoryCache; | ||
91 | m_authenticateSessionsHandler = authenSessions; | ||
92 | |||
93 | OpenSim.Framework.Console.MainLog.Instance.Verbose( "OpenSimClient.cs - Started up new client thread to handle incoming request"); | ||
94 | cirpack = initialcirpack; | ||
95 | userEP = remoteEP; | ||
96 | |||
97 | this.startpos = m_authenticateSessionsHandler.GetPosition(initialcirpack.CircuitCode.Code); | ||
98 | |||
99 | PacketQueue = new BlockingQueue<QueItem>(); | ||
100 | |||
101 | this.UploadAssets = new AgentAssetUpload(this, m_assetCache, m_inventoryCache); | ||
102 | AckTimer = new System.Timers.Timer(500); | ||
103 | AckTimer.Elapsed += new ElapsedEventHandler(AckTimer_Elapsed); | ||
104 | AckTimer.Start(); | ||
105 | |||
106 | this.RegisterLocalPacketHandlers(); | ||
107 | |||
108 | ClientThread = new Thread(new ThreadStart(AuthUser)); | ||
109 | ClientThread.IsBackground = true; | ||
110 | ClientThread.Start(); | ||
111 | } | ||
112 | |||
113 | # region Client Methods | ||
114 | |||
115 | public void KillClient() | ||
116 | { | ||
117 | KillObjectPacket kill = new KillObjectPacket(); | ||
118 | kill.ObjectData = new KillObjectPacket.ObjectDataBlock[1]; | ||
119 | kill.ObjectData[0] = new KillObjectPacket.ObjectDataBlock(); | ||
120 | //kill.ObjectData[0].ID = this.ClientAvatar.localid; | ||
121 | foreach (ClientView client in m_clientThreads.Values) | ||
122 | { | ||
123 | client.OutPacket(kill); | ||
124 | } | ||
125 | |||
126 | this.m_inventoryCache.ClientLeaving(this.AgentID, null); | ||
127 | m_world.RemoveClient(this.AgentId); | ||
128 | |||
129 | m_clientThreads.Remove(this.CircuitCode); | ||
130 | m_networkServer.RemoveClientCircuit(this.CircuitCode); | ||
131 | this.ClientThread.Abort(); | ||
132 | } | ||
133 | #endregion | ||
134 | |||
135 | # region Packet Handling | ||
136 | public static bool AddPacketHandler(PacketType packetType, PacketMethod handler) | ||
137 | { | ||
138 | bool result = false; | ||
139 | lock (PacketHandlers) | ||
140 | { | ||
141 | if (!PacketHandlers.ContainsKey(packetType)) | ||
142 | { | ||
143 | PacketHandlers.Add(packetType, handler); | ||
144 | result = true; | ||
145 | } | ||
146 | } | ||
147 | return result; | ||
148 | } | ||
149 | |||
150 | public bool AddLocalPacketHandler(PacketType packetType, PacketMethod handler) | ||
151 | { | ||
152 | bool result = false; | ||
153 | lock (m_packetHandlers) | ||
154 | { | ||
155 | if (!m_packetHandlers.ContainsKey(packetType)) | ||
156 | { | ||
157 | m_packetHandlers.Add(packetType, handler); | ||
158 | result = true; | ||
159 | } | ||
160 | } | ||
161 | return result; | ||
162 | } | ||
163 | |||
164 | protected virtual bool ProcessPacketMethod(Packet packet) | ||
165 | { | ||
166 | bool result = false; | ||
167 | bool found = false; | ||
168 | PacketMethod method; | ||
169 | if (m_packetHandlers.TryGetValue(packet.Type, out method)) | ||
170 | { | ||
171 | //there is a local handler for this packet type | ||
172 | result = method(this, packet); | ||
173 | } | ||
174 | else | ||
175 | { | ||
176 | //there is not a local handler so see if there is a Global handler | ||
177 | lock (PacketHandlers) | ||
178 | { | ||
179 | found = PacketHandlers.TryGetValue(packet.Type, out method); | ||
180 | } | ||
181 | if (found) | ||
182 | { | ||
183 | result = method(this, packet); | ||
184 | } | ||
185 | } | ||
186 | return result; | ||
187 | } | ||
188 | |||
189 | protected virtual void ClientLoop() | ||
190 | { | ||
191 | OpenSim.Framework.Console.MainLog.Instance.Verbose( "OpenSimClient.cs:ClientLoop() - Entered loop"); | ||
192 | while (true) | ||
193 | { | ||
194 | QueItem nextPacket = PacketQueue.Dequeue(); | ||
195 | if (nextPacket.Incoming) | ||
196 | { | ||
197 | //is a incoming packet | ||
198 | ProcessInPacket(nextPacket.Packet); | ||
199 | } | ||
200 | else | ||
201 | { | ||
202 | //is a out going packet | ||
203 | ProcessOutPacket(nextPacket.Packet); | ||
204 | } | ||
205 | } | ||
206 | } | ||
207 | # endregion | ||
208 | |||
209 | # region Setup | ||
210 | |||
211 | protected virtual void InitNewClient() | ||
212 | { | ||
213 | OpenSim.Framework.Console.MainLog.Instance.Verbose( "OpenSimClient.cs:InitNewClient() - Adding viewer agent to world"); | ||
214 | this.m_world.AddNewClient(this, this.AgentID, false); | ||
215 | } | ||
216 | |||
217 | protected virtual void AuthUser() | ||
218 | { | ||
219 | // AuthenticateResponse sessionInfo = m_gridServer.AuthenticateSession(cirpack.CircuitCode.SessionID, cirpack.CircuitCode.ID, cirpack.CircuitCode.Code); | ||
220 | AuthenticateResponse sessionInfo = this.m_authenticateSessionsHandler.AuthenticateSession(cirpack.CircuitCode.SessionID, cirpack.CircuitCode.ID, cirpack.CircuitCode.Code); | ||
221 | if (!sessionInfo.Authorised) | ||
222 | { | ||
223 | //session/circuit not authorised | ||
224 | OpenSim.Framework.Console.MainLog.Instance.Notice("OpenSimClient.cs:AuthUser() - New user request denied to " + userEP.ToString()); | ||
225 | ClientThread.Abort(); | ||
226 | } | ||
227 | else | ||
228 | { | ||
229 | OpenSim.Framework.Console.MainLog.Instance.Notice("OpenSimClient.cs:AuthUser() - Got authenticated connection from " + userEP.ToString()); | ||
230 | //session is authorised | ||
231 | this.AgentID = cirpack.CircuitCode.ID; | ||
232 | this.SessionID = cirpack.CircuitCode.SessionID; | ||
233 | this.CircuitCode = cirpack.CircuitCode.Code; | ||
234 | this.firstName = sessionInfo.LoginInfo.First; | ||
235 | this.lastName = sessionInfo.LoginInfo.Last; | ||
236 | |||
237 | if (sessionInfo.LoginInfo.SecureSession != LLUUID.Zero) | ||
238 | { | ||
239 | this.SecureSessionID = sessionInfo.LoginInfo.SecureSession; | ||
240 | } | ||
241 | InitNewClient(); | ||
242 | |||
243 | ClientLoop(); | ||
244 | } | ||
245 | } | ||
246 | # endregion | ||
247 | |||
248 | |||
249 | protected override void KillThread() | ||
250 | { | ||
251 | this.ClientThread.Abort(); | ||
252 | } | ||
253 | |||
254 | #region Inventory Creation | ||
255 | private void SetupInventory(AuthenticateResponse sessionInfo) | ||
256 | { | ||
257 | |||
258 | } | ||
259 | private AgentInventory CreateInventory(LLUUID baseFolder) | ||
260 | { | ||
261 | AgentInventory inventory = null; | ||
262 | |||
263 | return inventory; | ||
264 | } | ||
265 | |||
266 | private void CreateInventoryItem(CreateInventoryItemPacket packet) | ||
267 | { | ||
268 | |||
269 | } | ||
270 | #endregion | ||
271 | |||
272 | } | ||
273 | } | ||
diff --git a/OpenSim/Region/ClientStack/ClientViewBase.cs b/OpenSim/Region/ClientStack/ClientViewBase.cs new file mode 100644 index 0000000..8b503f0 --- /dev/null +++ b/OpenSim/Region/ClientStack/ClientViewBase.cs | |||
@@ -0,0 +1,327 @@ | |||
1 | |||
2 | /* | ||
3 | * Copyright (c) Contributors, http://www.openmetaverse.org/ | ||
4 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
5 | * | ||
6 | * Redistribution and use in source and binary forms, with or without | ||
7 | * modification, are permitted provided that the following conditions are met: | ||
8 | * * Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * * Redistributions in binary form must reproduce the above copyright | ||
11 | * notice, this list of conditions and the following disclaimer in the | ||
12 | * documentation and/or other materials provided with the distribution. | ||
13 | * * Neither the name of the OpenSim Project nor the | ||
14 | * names of its contributors may be used to endorse or promote products | ||
15 | * derived from this software without specific prior written permission. | ||
16 | * | ||
17 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY | ||
18 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
19 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
20 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
21 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
22 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
23 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
24 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
27 | * | ||
28 | */ | ||
29 | using System; | ||
30 | using System.Collections; | ||
31 | using System.Collections.Generic; | ||
32 | using libsecondlife; | ||
33 | using libsecondlife.Packets; | ||
34 | using System.Net; | ||
35 | using System.Net.Sockets; | ||
36 | using System.IO; | ||
37 | using System.Threading; | ||
38 | using System.Timers; | ||
39 | using OpenSim.Framework.Utilities; | ||
40 | using OpenSim.Framework.Interfaces; | ||
41 | |||
42 | namespace OpenSim | ||
43 | { | ||
44 | public class ClientViewBase | ||
45 | { | ||
46 | protected BlockingQueue<QueItem> PacketQueue; | ||
47 | protected Dictionary<uint, uint> PendingAcks = new Dictionary<uint, uint>(); | ||
48 | protected Dictionary<uint, Packet> NeedAck = new Dictionary<uint, Packet>(); | ||
49 | |||
50 | protected System.Timers.Timer AckTimer; | ||
51 | protected uint Sequence = 0; | ||
52 | protected object SequenceLock = new object(); | ||
53 | protected const int MAX_APPENDED_ACKS = 10; | ||
54 | protected const int RESEND_TIMEOUT = 4000; | ||
55 | protected const int MAX_SEQUENCE = 0xFFFFFF; | ||
56 | |||
57 | public uint CircuitCode; | ||
58 | public EndPoint userEP; | ||
59 | |||
60 | protected PacketServer m_networkServer; | ||
61 | |||
62 | public ClientViewBase() | ||
63 | { | ||
64 | |||
65 | } | ||
66 | |||
67 | protected virtual void ProcessInPacket(Packet Pack) | ||
68 | { | ||
69 | |||
70 | } | ||
71 | |||
72 | protected virtual void ProcessOutPacket(Packet Pack) | ||
73 | { | ||
74 | // Keep track of when this packet was sent out | ||
75 | Pack.TickCount = Environment.TickCount; | ||
76 | |||
77 | if (!Pack.Header.Resent) | ||
78 | { | ||
79 | // Set the sequence number | ||
80 | lock (SequenceLock) | ||
81 | { | ||
82 | if (Sequence >= MAX_SEQUENCE) | ||
83 | Sequence = 1; | ||
84 | else | ||
85 | Sequence++; | ||
86 | Pack.Header.Sequence = Sequence; | ||
87 | } | ||
88 | |||
89 | if (Pack.Header.Reliable) //DIRTY HACK | ||
90 | { | ||
91 | lock (NeedAck) | ||
92 | { | ||
93 | if (!NeedAck.ContainsKey(Pack.Header.Sequence)) | ||
94 | { | ||
95 | try | ||
96 | { | ||
97 | NeedAck.Add(Pack.Header.Sequence, Pack); | ||
98 | } | ||
99 | catch (Exception e) // HACKY | ||
100 | { | ||
101 | e.ToString(); | ||
102 | // Ignore | ||
103 | // Seems to throw a exception here occasionally | ||
104 | // of 'duplicate key' despite being locked. | ||
105 | // !?!?!? | ||
106 | } | ||
107 | } | ||
108 | else | ||
109 | { | ||
110 | // Client.Log("Attempted to add a duplicate sequence number (" + | ||
111 | // packet.Header.Sequence + ") to the NeedAck dictionary for packet type " + | ||
112 | // packet.Type.ToString(), Helpers.LogLevel.Warning); | ||
113 | } | ||
114 | } | ||
115 | |||
116 | // Don't append ACKs to resent packets, in case that's what was causing the | ||
117 | // delivery to fail | ||
118 | if (!Pack.Header.Resent) | ||
119 | { | ||
120 | // Append any ACKs that need to be sent out to this packet | ||
121 | lock (PendingAcks) | ||
122 | { | ||
123 | if (PendingAcks.Count > 0 && PendingAcks.Count < MAX_APPENDED_ACKS && | ||
124 | Pack.Type != PacketType.PacketAck && | ||
125 | Pack.Type != PacketType.LogoutRequest) | ||
126 | { | ||
127 | Pack.Header.AckList = new uint[PendingAcks.Count]; | ||
128 | int i = 0; | ||
129 | |||
130 | foreach (uint ack in PendingAcks.Values) | ||
131 | { | ||
132 | Pack.Header.AckList[i] = ack; | ||
133 | i++; | ||
134 | } | ||
135 | |||
136 | PendingAcks.Clear(); | ||
137 | Pack.Header.AppendedAcks = true; | ||
138 | } | ||
139 | } | ||
140 | } | ||
141 | } | ||
142 | } | ||
143 | |||
144 | byte[] ZeroOutBuffer = new byte[4096]; | ||
145 | byte[] sendbuffer; | ||
146 | sendbuffer = Pack.ToBytes(); | ||
147 | |||
148 | try | ||
149 | { | ||
150 | if (Pack.Header.Zerocoded) | ||
151 | { | ||
152 | int packetsize = Helpers.ZeroEncode(sendbuffer, sendbuffer.Length, ZeroOutBuffer); | ||
153 | m_networkServer.SendPacketTo(ZeroOutBuffer, packetsize, SocketFlags.None, CircuitCode);//userEP); | ||
154 | } | ||
155 | else | ||
156 | { | ||
157 | m_networkServer.SendPacketTo(sendbuffer, sendbuffer.Length, SocketFlags.None, CircuitCode); //userEP); | ||
158 | } | ||
159 | } | ||
160 | catch (Exception) | ||
161 | { | ||
162 | OpenSim.Framework.Console.MainLog.Instance.Warn("OpenSimClient.cs:ProcessOutPacket() - WARNING: Socket exception occurred on connection " + userEP.ToString() + " - killing thread"); | ||
163 | this.KillThread(); | ||
164 | } | ||
165 | |||
166 | } | ||
167 | |||
168 | public virtual void InPacket(Packet NewPack) | ||
169 | { | ||
170 | // Handle appended ACKs | ||
171 | if (NewPack.Header.AppendedAcks) | ||
172 | { | ||
173 | lock (NeedAck) | ||
174 | { | ||
175 | foreach (uint ack in NewPack.Header.AckList) | ||
176 | { | ||
177 | NeedAck.Remove(ack); | ||
178 | } | ||
179 | } | ||
180 | } | ||
181 | |||
182 | // Handle PacketAck packets | ||
183 | if (NewPack.Type == PacketType.PacketAck) | ||
184 | { | ||
185 | PacketAckPacket ackPacket = (PacketAckPacket)NewPack; | ||
186 | |||
187 | lock (NeedAck) | ||
188 | { | ||
189 | foreach (PacketAckPacket.PacketsBlock block in ackPacket.Packets) | ||
190 | { | ||
191 | NeedAck.Remove(block.ID); | ||
192 | } | ||
193 | } | ||
194 | } | ||
195 | else if ((NewPack.Type == PacketType.StartPingCheck)) | ||
196 | { | ||
197 | //reply to pingcheck | ||
198 | libsecondlife.Packets.StartPingCheckPacket startPing = (libsecondlife.Packets.StartPingCheckPacket)NewPack; | ||
199 | libsecondlife.Packets.CompletePingCheckPacket endPing = new CompletePingCheckPacket(); | ||
200 | endPing.PingID.PingID = startPing.PingID.PingID; | ||
201 | OutPacket(endPing); | ||
202 | } | ||
203 | else | ||
204 | { | ||
205 | QueItem item = new QueItem(); | ||
206 | item.Packet = NewPack; | ||
207 | item.Incoming = true; | ||
208 | this.PacketQueue.Enqueue(item); | ||
209 | } | ||
210 | |||
211 | } | ||
212 | |||
213 | public virtual void OutPacket(Packet NewPack) | ||
214 | { | ||
215 | QueItem item = new QueItem(); | ||
216 | item.Packet = NewPack; | ||
217 | item.Incoming = false; | ||
218 | this.PacketQueue.Enqueue(item); | ||
219 | } | ||
220 | |||
221 | # region Low Level Packet Methods | ||
222 | |||
223 | protected void ack_pack(Packet Pack) | ||
224 | { | ||
225 | if (Pack.Header.Reliable) | ||
226 | { | ||
227 | libsecondlife.Packets.PacketAckPacket ack_it = new PacketAckPacket(); | ||
228 | ack_it.Packets = new PacketAckPacket.PacketsBlock[1]; | ||
229 | ack_it.Packets[0] = new PacketAckPacket.PacketsBlock(); | ||
230 | ack_it.Packets[0].ID = Pack.Header.Sequence; | ||
231 | ack_it.Header.Reliable = false; | ||
232 | |||
233 | OutPacket(ack_it); | ||
234 | |||
235 | } | ||
236 | /* | ||
237 | if (Pack.Header.Reliable) | ||
238 | { | ||
239 | lock (PendingAcks) | ||
240 | { | ||
241 | uint sequence = (uint)Pack.Header.Sequence; | ||
242 | if (!PendingAcks.ContainsKey(sequence)) { PendingAcks[sequence] = sequence; } | ||
243 | } | ||
244 | }*/ | ||
245 | } | ||
246 | |||
247 | protected void ResendUnacked() | ||
248 | { | ||
249 | int now = Environment.TickCount; | ||
250 | |||
251 | lock (NeedAck) | ||
252 | { | ||
253 | foreach (Packet packet in NeedAck.Values) | ||
254 | { | ||
255 | if ((now - packet.TickCount > RESEND_TIMEOUT) && (!packet.Header.Resent)) | ||
256 | { | ||
257 | OpenSim.Framework.Console.MainLog.Instance.Verbose( "Resending " + packet.Type.ToString() + " packet, " + | ||
258 | (now - packet.TickCount) + "ms have passed"); | ||
259 | |||
260 | packet.Header.Resent = true; | ||
261 | OutPacket(packet); | ||
262 | } | ||
263 | } | ||
264 | } | ||
265 | } | ||
266 | |||
267 | protected void SendAcks() | ||
268 | { | ||
269 | lock (PendingAcks) | ||
270 | { | ||
271 | if (PendingAcks.Count > 0) | ||
272 | { | ||
273 | if (PendingAcks.Count > 250) | ||
274 | { | ||
275 | // FIXME: Handle the odd case where we have too many pending ACKs queued up | ||
276 | OpenSim.Framework.Console.MainLog.Instance.Verbose( "Too many ACKs queued up!"); | ||
277 | return; | ||
278 | } | ||
279 | |||
280 | //OpenSim.Framework.Console.MainLog.Instance.WriteLine("Sending PacketAck"); | ||
281 | |||
282 | |||
283 | int i = 0; | ||
284 | PacketAckPacket acks = new PacketAckPacket(); | ||
285 | acks.Packets = new PacketAckPacket.PacketsBlock[PendingAcks.Count]; | ||
286 | |||
287 | foreach (uint ack in PendingAcks.Values) | ||
288 | { | ||
289 | acks.Packets[i] = new PacketAckPacket.PacketsBlock(); | ||
290 | acks.Packets[i].ID = ack; | ||
291 | i++; | ||
292 | } | ||
293 | |||
294 | acks.Header.Reliable = false; | ||
295 | OutPacket(acks); | ||
296 | |||
297 | PendingAcks.Clear(); | ||
298 | } | ||
299 | } | ||
300 | } | ||
301 | |||
302 | protected void AckTimer_Elapsed(object sender, ElapsedEventArgs ea) | ||
303 | { | ||
304 | SendAcks(); | ||
305 | ResendUnacked(); | ||
306 | } | ||
307 | #endregion | ||
308 | |||
309 | protected virtual void KillThread() | ||
310 | { | ||
311 | |||
312 | } | ||
313 | |||
314 | #region Nested Classes | ||
315 | |||
316 | public class QueItem | ||
317 | { | ||
318 | public QueItem() | ||
319 | { | ||
320 | } | ||
321 | |||
322 | public Packet Packet; | ||
323 | public bool Incoming; | ||
324 | } | ||
325 | #endregion | ||
326 | } | ||
327 | } | ||
diff --git a/OpenSim/Region/ClientStack/OpenSim.Region.ClientStack.csproj b/OpenSim/Region/ClientStack/OpenSim.Region.ClientStack.csproj new file mode 100644 index 0000000..0b19359 --- /dev/null +++ b/OpenSim/Region/ClientStack/OpenSim.Region.ClientStack.csproj | |||
@@ -0,0 +1,173 @@ | |||
1 | <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||
2 | <PropertyGroup> | ||
3 | <ProjectType>Local</ProjectType> | ||
4 | <ProductVersion>8.0.50727</ProductVersion> | ||
5 | <SchemaVersion>2.0</SchemaVersion> | ||
6 | <ProjectGuid>{DC3698B2-0000-0000-0000-000000000000}</ProjectGuid> | ||
7 | <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> | ||
8 | <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> | ||
9 | <ApplicationIcon></ApplicationIcon> | ||
10 | <AssemblyKeyContainerName> | ||
11 | </AssemblyKeyContainerName> | ||
12 | <AssemblyName>OpenSim.Region.ClientStack</AssemblyName> | ||
13 | <DefaultClientScript>JScript</DefaultClientScript> | ||
14 | <DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout> | ||
15 | <DefaultTargetSchema>IE50</DefaultTargetSchema> | ||
16 | <DelaySign>false</DelaySign> | ||
17 | <OutputType>Library</OutputType> | ||
18 | <AppDesignerFolder></AppDesignerFolder> | ||
19 | <RootNamespace>OpenSim.Region.ClientStack</RootNamespace> | ||
20 | <StartupObject></StartupObject> | ||
21 | <FileUpgradeFlags> | ||
22 | </FileUpgradeFlags> | ||
23 | </PropertyGroup> | ||
24 | <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> | ||
25 | <AllowUnsafeBlocks>False</AllowUnsafeBlocks> | ||
26 | <BaseAddress>285212672</BaseAddress> | ||
27 | <CheckForOverflowUnderflow>False</CheckForOverflowUnderflow> | ||
28 | <ConfigurationOverrideFile> | ||
29 | </ConfigurationOverrideFile> | ||
30 | <DefineConstants>TRACE;DEBUG</DefineConstants> | ||
31 | <DocumentationFile></DocumentationFile> | ||
32 | <DebugSymbols>True</DebugSymbols> | ||
33 | <FileAlignment>4096</FileAlignment> | ||
34 | <Optimize>False</Optimize> | ||
35 | <OutputPath>..\..\..\bin\</OutputPath> | ||
36 | <RegisterForComInterop>False</RegisterForComInterop> | ||
37 | <RemoveIntegerChecks>False</RemoveIntegerChecks> | ||
38 | <TreatWarningsAsErrors>False</TreatWarningsAsErrors> | ||
39 | <WarningLevel>4</WarningLevel> | ||
40 | <NoWarn></NoWarn> | ||
41 | </PropertyGroup> | ||
42 | <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> | ||
43 | <AllowUnsafeBlocks>False</AllowUnsafeBlocks> | ||
44 | <BaseAddress>285212672</BaseAddress> | ||
45 | <CheckForOverflowUnderflow>False</CheckForOverflowUnderflow> | ||
46 | <ConfigurationOverrideFile> | ||
47 | </ConfigurationOverrideFile> | ||
48 | <DefineConstants>TRACE</DefineConstants> | ||
49 | <DocumentationFile></DocumentationFile> | ||
50 | <DebugSymbols>False</DebugSymbols> | ||
51 | <FileAlignment>4096</FileAlignment> | ||
52 | <Optimize>True</Optimize> | ||
53 | <OutputPath>..\..\..\bin\</OutputPath> | ||
54 | <RegisterForComInterop>False</RegisterForComInterop> | ||
55 | <RemoveIntegerChecks>False</RemoveIntegerChecks> | ||
56 | <TreatWarningsAsErrors>False</TreatWarningsAsErrors> | ||
57 | <WarningLevel>4</WarningLevel> | ||
58 | <NoWarn></NoWarn> | ||
59 | </PropertyGroup> | ||
60 | <ItemGroup> | ||
61 | <Reference Include="Axiom.MathLib.dll" > | ||
62 | <HintPath>..\..\..\bin\Axiom.MathLib.dll</HintPath> | ||
63 | <Private>False</Private> | ||
64 | </Reference> | ||
65 | <Reference Include="Db4objects.Db4o.dll" > | ||
66 | <HintPath>..\..\..\bin\Db4objects.Db4o.dll</HintPath> | ||
67 | <Private>False</Private> | ||
68 | </Reference> | ||
69 | <Reference Include="libsecondlife.dll" > | ||
70 | <HintPath>..\..\..\bin\libsecondlife.dll</HintPath> | ||
71 | <Private>False</Private> | ||
72 | </Reference> | ||
73 | <Reference Include="OpenSim.FrameworkGenericConfig.Xml" > | ||
74 | <HintPath>OpenSim.FrameworkGenericConfig.Xml.dll</HintPath> | ||
75 | <Private>False</Private> | ||
76 | </Reference> | ||
77 | <Reference Include="System" > | ||
78 | <HintPath>System.dll</HintPath> | ||
79 | <Private>False</Private> | ||
80 | </Reference> | ||
81 | <Reference Include="System.Xml" > | ||
82 | <HintPath>System.Xml.dll</HintPath> | ||
83 | <Private>False</Private> | ||
84 | </Reference> | ||
85 | <Reference Include="XMLRPC.dll" > | ||
86 | <HintPath>..\..\..\bin\XMLRPC.dll</HintPath> | ||
87 | <Private>False</Private> | ||
88 | </Reference> | ||
89 | </ItemGroup> | ||
90 | <ItemGroup> | ||
91 | <ProjectReference Include="..\..\Framework\General\OpenSim.Framework.csproj"> | ||
92 | <Name>OpenSim.Framework</Name> | ||
93 | <Project>{8ACA2445-0000-0000-0000-000000000000}</Project> | ||
94 | <Package>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</Package> | ||
95 | <Private>False</Private> | ||
96 | </ProjectReference> | ||
97 | <ProjectReference Include="..\..\Framework\Console\OpenSim.Framework.Console.csproj"> | ||
98 | <Name>OpenSim.Framework.Console</Name> | ||
99 | <Project>{A7CD0630-0000-0000-0000-000000000000}</Project> | ||
100 | <Package>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</Package> | ||
101 | <Private>False</Private> | ||
102 | </ProjectReference> | ||
103 | <ProjectReference Include="..\..\Framework\Servers\OpenSim.Framework.Servers.csproj"> | ||
104 | <Name>OpenSim.Framework.Servers</Name> | ||
105 | <Project>{2CC71860-0000-0000-0000-000000000000}</Project> | ||
106 | <Package>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</Package> | ||
107 | <Private>False</Private> | ||
108 | </ProjectReference> | ||
109 | <ProjectReference Include="..\Caches\OpenSim.Region.Caches.csproj"> | ||
110 | <Name>OpenSim.Region.Caches</Name> | ||
111 | <Project>{61FCCDB3-0000-0000-0000-000000000000}</Project> | ||
112 | <Package>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</Package> | ||
113 | <Private>False</Private> | ||
114 | </ProjectReference> | ||
115 | <ProjectReference Include="..\Physics\Manager\OpenSim.Region.Physics.Manager.csproj"> | ||
116 | <Name>OpenSim.Region.Physics.Manager</Name> | ||
117 | <Project>{F4FF31EB-0000-0000-0000-000000000000}</Project> | ||
118 | <Package>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</Package> | ||
119 | <Private>False</Private> | ||
120 | </ProjectReference> | ||
121 | <ProjectReference Include="..\Terrain.BasicTerrain\OpenSim.Region.Terrain.BasicTerrain.csproj"> | ||
122 | <Name>OpenSim.Region.Terrain.BasicTerrain</Name> | ||
123 | <Project>{C9E0F891-0000-0000-0000-000000000000}</Project> | ||
124 | <Package>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</Package> | ||
125 | <Private>False</Private> | ||
126 | </ProjectReference> | ||
127 | </ItemGroup> | ||
128 | <ItemGroup> | ||
129 | <Compile Include="ClientStackNetworkHandler.cs"> | ||
130 | <SubType>Code</SubType> | ||
131 | </Compile> | ||
132 | <Compile Include="ClientView.AgentAssetUpload.cs"> | ||
133 | <SubType>Code</SubType> | ||
134 | </Compile> | ||
135 | <Compile Include="ClientView.API.cs"> | ||
136 | <SubType>Code</SubType> | ||
137 | </Compile> | ||
138 | <Compile Include="ClientView.cs"> | ||
139 | <SubType>Code</SubType> | ||
140 | </Compile> | ||
141 | <Compile Include="ClientView.PacketHandlers.cs"> | ||
142 | <SubType>Code</SubType> | ||
143 | </Compile> | ||
144 | <Compile Include="ClientView.ProcessPackets.cs"> | ||
145 | <SubType>Code</SubType> | ||
146 | </Compile> | ||
147 | <Compile Include="ClientViewBase.cs"> | ||
148 | <SubType>Code</SubType> | ||
149 | </Compile> | ||
150 | <Compile Include="PacketServer.cs"> | ||
151 | <SubType>Code</SubType> | ||
152 | </Compile> | ||
153 | <Compile Include="RegionApplicationBase.cs"> | ||
154 | <SubType>Code</SubType> | ||
155 | </Compile> | ||
156 | <Compile Include="UDPServer.cs"> | ||
157 | <SubType>Code</SubType> | ||
158 | </Compile> | ||
159 | <Compile Include="VersionInfo.cs"> | ||
160 | <SubType>Code</SubType> | ||
161 | </Compile> | ||
162 | <Compile Include="Assets\InventoryCache.cs"> | ||
163 | <SubType>Code</SubType> | ||
164 | </Compile> | ||
165 | </ItemGroup> | ||
166 | <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" /> | ||
167 | <PropertyGroup> | ||
168 | <PreBuildEvent> | ||
169 | </PreBuildEvent> | ||
170 | <PostBuildEvent> | ||
171 | </PostBuildEvent> | ||
172 | </PropertyGroup> | ||
173 | </Project> | ||
diff --git a/OpenSim/Region/ClientStack/OpenSim.Region.ClientStack.csproj.user b/OpenSim/Region/ClientStack/OpenSim.Region.ClientStack.csproj.user new file mode 100644 index 0000000..6841907 --- /dev/null +++ b/OpenSim/Region/ClientStack/OpenSim.Region.ClientStack.csproj.user | |||
@@ -0,0 +1,12 @@ | |||
1 | <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||
2 | <PropertyGroup> | ||
3 | <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> | ||
4 | <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> | ||
5 | <ReferencePath>C:\New Folder\second-life-viewer\opensim-dailys2\opensim15-06\NameSpaceChanges\bin\</ReferencePath> | ||
6 | <LastOpenVersion>8.0.50727</LastOpenVersion> | ||
7 | <ProjectView>ProjectFiles</ProjectView> | ||
8 | <ProjectTrust>0</ProjectTrust> | ||
9 | </PropertyGroup> | ||
10 | <PropertyGroup Condition = " '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' " /> | ||
11 | <PropertyGroup Condition = " '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " /> | ||
12 | </Project> | ||
diff --git a/OpenSim/Region/ClientStack/PacketServer.cs b/OpenSim/Region/ClientStack/PacketServer.cs new file mode 100644 index 0000000..229570c --- /dev/null +++ b/OpenSim/Region/ClientStack/PacketServer.cs | |||
@@ -0,0 +1,183 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://www.openmetaverse.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 | */ | ||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Text; | ||
31 | using libsecondlife.Packets; | ||
32 | using OpenSim.Framework.Interfaces; | ||
33 | using OpenSim.Framework; | ||
34 | using System.Net; | ||
35 | using System.Net.Sockets; | ||
36 | using OpenSim.Assets; | ||
37 | using OpenSim.Caches; | ||
38 | |||
39 | namespace OpenSim | ||
40 | { | ||
41 | public class PacketServer | ||
42 | { | ||
43 | private ClientStackNetworkHandler _networkHandler; | ||
44 | private IWorld _localWorld; | ||
45 | public Dictionary<uint, ClientView> ClientThreads = new Dictionary<uint, ClientView>(); | ||
46 | public Dictionary<uint, IClientAPI> ClientAPIs = new Dictionary<uint, IClientAPI>(); | ||
47 | protected uint serverPort; | ||
48 | |||
49 | public PacketServer(ClientStackNetworkHandler networkHandler, uint port) | ||
50 | { | ||
51 | _networkHandler = networkHandler; | ||
52 | this.serverPort = port; | ||
53 | _networkHandler.RegisterPacketServer(this); | ||
54 | } | ||
55 | |||
56 | public IWorld LocalWorld | ||
57 | { | ||
58 | set | ||
59 | { | ||
60 | this._localWorld = value; | ||
61 | } | ||
62 | } | ||
63 | |||
64 | /// <summary> | ||
65 | /// | ||
66 | /// </summary> | ||
67 | /// <param name="circuitCode"></param> | ||
68 | /// <param name="packet"></param> | ||
69 | public virtual void ClientInPacket(uint circuitCode, Packet packet) | ||
70 | { | ||
71 | if (this.ClientThreads.ContainsKey(circuitCode)) | ||
72 | { | ||
73 | ClientThreads[circuitCode].InPacket(packet); | ||
74 | } | ||
75 | } | ||
76 | |||
77 | /// <summary> | ||
78 | /// | ||
79 | /// </summary> | ||
80 | /// <param name="circuitCode"></param> | ||
81 | /// <returns></returns> | ||
82 | public virtual bool AddNewCircuitCodeClient(uint circuitCode) | ||
83 | { | ||
84 | return false; | ||
85 | } | ||
86 | |||
87 | /// <summary> | ||
88 | /// | ||
89 | /// </summary> | ||
90 | /// <param name="packet"></param> | ||
91 | public virtual void SendPacketToAllClients(Packet packet) | ||
92 | { | ||
93 | |||
94 | } | ||
95 | |||
96 | /// <summary> | ||
97 | /// | ||
98 | /// </summary> | ||
99 | /// <param name="packet"></param> | ||
100 | /// <param name="simClient"></param> | ||
101 | public virtual void SendPacketToAllExcept(Packet packet, ClientView simClient) | ||
102 | { | ||
103 | |||
104 | } | ||
105 | |||
106 | /// <summary> | ||
107 | /// | ||
108 | /// </summary> | ||
109 | /// <param name="packetType"></param> | ||
110 | /// <param name="handler"></param> | ||
111 | public virtual void AddClientPacketHandler(PacketType packetType, PacketMethod handler) | ||
112 | { | ||
113 | |||
114 | } | ||
115 | |||
116 | /// <summary> | ||
117 | /// | ||
118 | /// </summary> | ||
119 | public virtual void RegisterClientPacketHandlers() | ||
120 | { | ||
121 | |||
122 | } | ||
123 | |||
124 | /// <summary> | ||
125 | /// | ||
126 | /// </summary> | ||
127 | /// <param name="remoteEP"></param> | ||
128 | /// <param name="initialcirpack"></param> | ||
129 | /// <param name="clientThreads"></param> | ||
130 | /// <param name="world"></param> | ||
131 | /// <param name="assetCache"></param> | ||
132 | /// <param name="packServer"></param> | ||
133 | /// <param name="inventoryCache"></param> | ||
134 | /// <param name="authenSessions"></param> | ||
135 | /// <returns></returns> | ||
136 | protected virtual ClientView CreateNewClient(EndPoint remoteEP, UseCircuitCodePacket initialcirpack, Dictionary<uint, ClientView> clientThreads, IWorld world, AssetCache assetCache, PacketServer packServer, InventoryCache inventoryCache, AuthenticateSessionsBase authenSessions) | ||
137 | { | ||
138 | return new ClientView(remoteEP, initialcirpack, clientThreads, world, assetCache, packServer, inventoryCache, authenSessions ); | ||
139 | } | ||
140 | |||
141 | /// <summary> | ||
142 | /// | ||
143 | /// </summary> | ||
144 | /// <param name="epSender"></param> | ||
145 | /// <param name="useCircuit"></param> | ||
146 | /// <param name="assetCache"></param> | ||
147 | /// <param name="inventoryCache"></param> | ||
148 | /// <param name="authenticateSessionsClass"></param> | ||
149 | /// <returns></returns> | ||
150 | public virtual bool AddNewClient(EndPoint epSender, UseCircuitCodePacket useCircuit, AssetCache assetCache, InventoryCache inventoryCache, AuthenticateSessionsBase authenticateSessionsClass) | ||
151 | { | ||
152 | ClientView newuser = | ||
153 | CreateNewClient(epSender, useCircuit, ClientThreads, _localWorld, assetCache, this, inventoryCache, | ||
154 | authenticateSessionsClass); | ||
155 | |||
156 | this.ClientThreads.Add(useCircuit.CircuitCode.Code, newuser); | ||
157 | this.ClientAPIs.Add(useCircuit.CircuitCode.Code, (IClientAPI)newuser); | ||
158 | |||
159 | return true; | ||
160 | } | ||
161 | |||
162 | /// <summary> | ||
163 | /// | ||
164 | /// </summary> | ||
165 | /// <param name="buffer"></param> | ||
166 | /// <param name="size"></param> | ||
167 | /// <param name="flags"></param> | ||
168 | /// <param name="circuitcode"></param> | ||
169 | public virtual void SendPacketTo(byte[] buffer, int size, SocketFlags flags, uint circuitcode) | ||
170 | { | ||
171 | this._networkHandler.SendPacketTo(buffer, size, flags, circuitcode); | ||
172 | } | ||
173 | |||
174 | /// <summary> | ||
175 | /// | ||
176 | /// </summary> | ||
177 | /// <param name="circuitcode"></param> | ||
178 | public virtual void RemoveClientCircuit(uint circuitcode) | ||
179 | { | ||
180 | this._networkHandler.RemoveClientCircuit(circuitcode); | ||
181 | } | ||
182 | } | ||
183 | } | ||
diff --git a/OpenSim/Region/ClientStack/RegionApplicationBase.cs b/OpenSim/Region/ClientStack/RegionApplicationBase.cs new file mode 100644 index 0000000..b421fbd --- /dev/null +++ b/OpenSim/Region/ClientStack/RegionApplicationBase.cs | |||
@@ -0,0 +1,129 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://www.openmetaverse.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 | */ | ||
28 | using System; | ||
29 | using System.Text; | ||
30 | using System.IO; | ||
31 | using System.Threading; | ||
32 | using System.Net; | ||
33 | using System.Net.Sockets; | ||
34 | using System.Timers; | ||
35 | using System.Reflection; | ||
36 | using System.Collections; | ||
37 | using System.Collections.Generic; | ||
38 | using libsecondlife; | ||
39 | using libsecondlife.Packets; | ||
40 | using OpenSim.Terrain; | ||
41 | using OpenSim.Framework.Interfaces; | ||
42 | using OpenSim.Framework.Types; | ||
43 | using OpenSim.Framework; | ||
44 | using OpenSim.Assets; | ||
45 | using OpenSim.Caches; | ||
46 | using OpenSim.Framework.Console; | ||
47 | using OpenSim.Physics.Manager; | ||
48 | using Nwc.XmlRpc; | ||
49 | using OpenSim.Framework.Servers; | ||
50 | using OpenSim.Framework.GenericConfig; | ||
51 | |||
52 | namespace OpenSim | ||
53 | { | ||
54 | public class RegionApplicationBase | ||
55 | { | ||
56 | protected IGenericConfig localConfig; | ||
57 | protected PhysicsManager physManager; | ||
58 | protected AssetCache AssetCache; | ||
59 | protected InventoryCache InventoryCache; | ||
60 | protected Dictionary<EndPoint, uint> clientCircuits = new Dictionary<EndPoint, uint>(); | ||
61 | protected DateTime startuptime; | ||
62 | protected NetworkServersInfo serversData; | ||
63 | |||
64 | public string m_physicsEngine; | ||
65 | public bool m_sandbox = false; | ||
66 | public bool m_loginserver; | ||
67 | public bool user_accounts = false; | ||
68 | public bool gridLocalAsset = false; | ||
69 | protected bool configFileSetup = false; | ||
70 | public string m_config; | ||
71 | |||
72 | protected List<UDPServer> m_udpServer = new List<UDPServer>(); | ||
73 | protected List<RegionInfo> regionData = new List<RegionInfo>(); | ||
74 | protected List<IWorld> m_localWorld = new List<IWorld>(); | ||
75 | protected BaseHttpServer httpServer; | ||
76 | protected List<AuthenticateSessionsBase> AuthenticateSessionsHandler = new List<AuthenticateSessionsBase>(); | ||
77 | |||
78 | protected LogBase m_log; | ||
79 | |||
80 | public RegionApplicationBase() | ||
81 | { | ||
82 | |||
83 | } | ||
84 | |||
85 | public RegionApplicationBase(bool sandBoxMode, bool startLoginServer, string physicsEngine, bool useConfigFile, bool silent, string configFile) | ||
86 | { | ||
87 | this.configFileSetup = useConfigFile; | ||
88 | m_sandbox = sandBoxMode; | ||
89 | m_loginserver = startLoginServer; | ||
90 | m_physicsEngine = physicsEngine; | ||
91 | m_config = configFile; | ||
92 | } | ||
93 | |||
94 | /*protected World m_localWorld; | ||
95 | public World LocalWorld | ||
96 | { | ||
97 | get { return m_localWorld; } | ||
98 | }*/ | ||
99 | |||
100 | /// <summary> | ||
101 | /// Performs initialisation of the world, such as loading configuration from disk. | ||
102 | /// </summary> | ||
103 | public virtual void StartUp() | ||
104 | { | ||
105 | } | ||
106 | |||
107 | protected virtual void SetupLocalGridServers() | ||
108 | { | ||
109 | } | ||
110 | |||
111 | protected virtual void SetupRemoteGridServers() | ||
112 | { | ||
113 | |||
114 | } | ||
115 | |||
116 | protected virtual void SetupWorld() | ||
117 | { | ||
118 | } | ||
119 | |||
120 | protected virtual void SetupHttpListener() | ||
121 | { | ||
122 | } | ||
123 | |||
124 | protected virtual void ConnectToRemoteGridServer() | ||
125 | { | ||
126 | |||
127 | } | ||
128 | } | ||
129 | } | ||
diff --git a/OpenSim/Region/ClientStack/UDPServer.cs b/OpenSim/Region/ClientStack/UDPServer.cs new file mode 100644 index 0000000..f2a02d9 --- /dev/null +++ b/OpenSim/Region/ClientStack/UDPServer.cs | |||
@@ -0,0 +1,208 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://www.openmetaverse.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 | */ | ||
28 | using System; | ||
29 | using System.Text; | ||
30 | using System.IO; | ||
31 | using System.Threading; | ||
32 | using System.Net; | ||
33 | using System.Net.Sockets; | ||
34 | using System.Timers; | ||
35 | using System.Reflection; | ||
36 | using System.Collections; | ||
37 | using System.Collections.Generic; | ||
38 | using libsecondlife; | ||
39 | using libsecondlife.Packets; | ||
40 | using OpenSim.Terrain; | ||
41 | using OpenSim.Framework.Interfaces; | ||
42 | using OpenSim.Framework.Types; | ||
43 | using OpenSim.Assets; | ||
44 | using OpenSim.Caches; | ||
45 | using OpenSim.Framework.Console; | ||
46 | using OpenSim.Framework; | ||
47 | using Nwc.XmlRpc; | ||
48 | using OpenSim.Servers; | ||
49 | using OpenSim.GenericConfig; | ||
50 | |||
51 | namespace OpenSim | ||
52 | { | ||
53 | |||
54 | public class UDPServer : ClientStackNetworkHandler | ||
55 | { | ||
56 | protected Dictionary<EndPoint, uint> clientCircuits = new Dictionary<EndPoint, uint>(); | ||
57 | public Socket Server; | ||
58 | protected IPEndPoint ServerIncoming; | ||
59 | protected byte[] RecvBuffer = new byte[4096]; | ||
60 | protected byte[] ZeroBuffer = new byte[8192]; | ||
61 | protected IPEndPoint ipeSender; | ||
62 | protected EndPoint epSender; | ||
63 | protected AsyncCallback ReceivedData; | ||
64 | protected PacketServer _packetServer; | ||
65 | |||
66 | protected int listenPort; | ||
67 | protected IWorld m_localWorld; | ||
68 | protected AssetCache m_assetCache; | ||
69 | protected InventoryCache m_inventoryCache; | ||
70 | protected LogBase m_log; | ||
71 | protected AuthenticateSessionsBase m_authenticateSessionsClass; | ||
72 | |||
73 | public PacketServer PacketServer | ||
74 | { | ||
75 | get | ||
76 | { | ||
77 | return _packetServer; | ||
78 | } | ||
79 | set | ||
80 | { | ||
81 | _packetServer = value; | ||
82 | } | ||
83 | } | ||
84 | |||
85 | public IWorld LocalWorld | ||
86 | { | ||
87 | set | ||
88 | { | ||
89 | this.m_localWorld = value; | ||
90 | this._packetServer.LocalWorld = this.m_localWorld; | ||
91 | } | ||
92 | } | ||
93 | |||
94 | public UDPServer() | ||
95 | { | ||
96 | } | ||
97 | |||
98 | public UDPServer(int port, AssetCache assetCache, InventoryCache inventoryCache, LogBase console, AuthenticateSessionsBase authenticateClass) | ||
99 | { | ||
100 | listenPort = port; | ||
101 | this.m_assetCache = assetCache; | ||
102 | this.m_inventoryCache = inventoryCache; | ||
103 | this.m_log = console; | ||
104 | this.m_authenticateSessionsClass = authenticateClass; | ||
105 | this.CreatePacketServer(); | ||
106 | |||
107 | } | ||
108 | |||
109 | protected virtual void CreatePacketServer() | ||
110 | { | ||
111 | PacketServer packetServer = new PacketServer(this, (uint) listenPort); | ||
112 | } | ||
113 | |||
114 | protected virtual void OnReceivedData(IAsyncResult result) | ||
115 | { | ||
116 | ipeSender = new IPEndPoint(IPAddress.Any, 0); | ||
117 | epSender = (EndPoint)ipeSender; | ||
118 | Packet packet = null; | ||
119 | int numBytes = Server.EndReceiveFrom(result, ref epSender); | ||
120 | int packetEnd = numBytes - 1; | ||
121 | |||
122 | packet = Packet.BuildPacket(RecvBuffer, ref packetEnd, ZeroBuffer); | ||
123 | |||
124 | // do we already have a circuit for this endpoint | ||
125 | if (this.clientCircuits.ContainsKey(epSender)) | ||
126 | { | ||
127 | //if so then send packet to the packetserver | ||
128 | this._packetServer.ClientInPacket(this.clientCircuits[epSender], packet); | ||
129 | } | ||
130 | else if (packet.Type == PacketType.UseCircuitCode) | ||
131 | { | ||
132 | // new client | ||
133 | this.AddNewClient(packet); | ||
134 | } | ||
135 | else | ||
136 | { // invalid client | ||
137 | m_log.Warn("UDPServer.cs:OnReceivedData() - WARNING: Got a packet from an invalid client - " + epSender.ToString()); | ||
138 | } | ||
139 | |||
140 | Server.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender, ReceivedData, null); | ||
141 | } | ||
142 | |||
143 | protected virtual void AddNewClient(Packet packet) | ||
144 | { | ||
145 | UseCircuitCodePacket useCircuit = (UseCircuitCodePacket)packet; | ||
146 | this.clientCircuits.Add(epSender, useCircuit.CircuitCode.Code); | ||
147 | |||
148 | this.PacketServer.AddNewClient(epSender, useCircuit, m_assetCache, m_inventoryCache, m_authenticateSessionsClass); | ||
149 | } | ||
150 | |||
151 | public void ServerListener() | ||
152 | { | ||
153 | m_log.Status("UDPServer.cs:ServerListener() - Opening UDP socket on " + listenPort); | ||
154 | |||
155 | ServerIncoming = new IPEndPoint(IPAddress.Any, listenPort); | ||
156 | Server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); | ||
157 | Server.Bind(ServerIncoming); | ||
158 | |||
159 | m_log.Verbose("UDPServer.cs:ServerListener() - UDP socket bound, getting ready to listen"); | ||
160 | |||
161 | ipeSender = new IPEndPoint(IPAddress.Any, 0); | ||
162 | epSender = (EndPoint)ipeSender; | ||
163 | ReceivedData = new AsyncCallback(this.OnReceivedData); | ||
164 | Server.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender, ReceivedData, null); | ||
165 | |||
166 | m_log.Verbose("UDPServer.cs:ServerListener() - Listening..."); | ||
167 | |||
168 | } | ||
169 | |||
170 | public virtual void RegisterPacketServer(PacketServer server) | ||
171 | { | ||
172 | this._packetServer = server; | ||
173 | } | ||
174 | |||
175 | public virtual void SendPacketTo(byte[] buffer, int size, SocketFlags flags, uint circuitcode)//EndPoint packetSender) | ||
176 | { | ||
177 | // find the endpoint for this circuit | ||
178 | EndPoint sendto = null; | ||
179 | foreach (KeyValuePair<EndPoint, uint> p in this.clientCircuits) | ||
180 | { | ||
181 | if (p.Value == circuitcode) | ||
182 | { | ||
183 | sendto = p.Key; | ||
184 | break; | ||
185 | } | ||
186 | } | ||
187 | if (sendto != null) | ||
188 | { | ||
189 | //we found the endpoint so send the packet to it | ||
190 | this.Server.SendTo(buffer, size, flags, sendto); | ||
191 | } | ||
192 | } | ||
193 | |||
194 | public virtual void RemoveClientCircuit(uint circuitcode) | ||
195 | { | ||
196 | foreach (KeyValuePair<EndPoint, uint> p in this.clientCircuits) | ||
197 | { | ||
198 | if (p.Value == circuitcode) | ||
199 | { | ||
200 | this.clientCircuits.Remove(p.Key); | ||
201 | break; | ||
202 | } | ||
203 | } | ||
204 | } | ||
205 | |||
206 | |||
207 | } | ||
208 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/ClientStack/VersionInfo.cs b/OpenSim/Region/ClientStack/VersionInfo.cs new file mode 100644 index 0000000..5d1354e --- /dev/null +++ b/OpenSim/Region/ClientStack/VersionInfo.cs | |||
@@ -0,0 +1,38 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://www.openmetaverse.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 | */ | ||
28 | using System; | ||
29 | |||
30 | namespace OpenSim | ||
31 | { | ||
32 | /// <summary> | ||
33 | /// </summary> | ||
34 | public class VersionInfo | ||
35 | { | ||
36 | public static string Version = "0.3, SVN build "; | ||
37 | } | ||
38 | } | ||