aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack
diff options
context:
space:
mode:
authorAdam Frisby2007-07-11 08:10:25 +0000
committerAdam Frisby2007-07-11 08:10:25 +0000
commite2ff441e31328e60c8bb1d4bb32fa4ac64f91978 (patch)
tree8405b6cef57b66a58f31a24c859846085d0b81f7 /OpenSim/Region/ClientStack
parent* Wiping trunk in prep for Sugilite (diff)
parent* Applying dalien's patches from bug#177 and #179 (diff)
downloadopensim-SC-e2ff441e31328e60c8bb1d4bb32fa4ac64f91978.zip
opensim-SC-e2ff441e31328e60c8bb1d4bb32fa4ac64f91978.tar.gz
opensim-SC-e2ff441e31328e60c8bb1d4bb32fa4ac64f91978.tar.bz2
opensim-SC-e2ff441e31328e60c8bb1d4bb32fa4ac64f91978.tar.xz
* Bringing Sugilite in to trunk
Diffstat (limited to 'OpenSim/Region/ClientStack')
-rw-r--r--OpenSim/Region/ClientStack/Assets/InventoryCache.cs337
-rw-r--r--OpenSim/Region/ClientStack/ClientStackNetworkHandler.cs40
-rw-r--r--OpenSim/Region/ClientStack/ClientView.API.cs1122
-rw-r--r--OpenSim/Region/ClientStack/ClientView.AgentAssetUpload.cs357
-rw-r--r--OpenSim/Region/ClientStack/ClientView.PacketHandlers.cs236
-rw-r--r--OpenSim/Region/ClientStack/ClientView.ProcessPackets.cs596
-rw-r--r--OpenSim/Region/ClientStack/ClientView.cs293
-rw-r--r--OpenSim/Region/ClientStack/ClientViewBase.cs326
-rw-r--r--OpenSim/Region/ClientStack/PacketServer.cs184
-rw-r--r--OpenSim/Region/ClientStack/RegionApplicationBase.cs117
-rw-r--r--OpenSim/Region/ClientStack/UDPServer.cs196
11 files changed, 3804 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..082c0d0
--- /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
29using System;
30using System.Collections.Generic;
31using System.Text;
32using libsecondlife;
33using libsecondlife.Packets;
34using OpenSim.Framework.Interfaces;
35using OpenSim.Framework.Inventory;
36using OpenSim.Framework.Types;
37using OpenSim.Region.ClientStack;
38
39namespace 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 Encoding _enc = 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, 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, 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 = 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 = 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 = 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..f4e537c
--- /dev/null
+++ b/OpenSim/Region/ClientStack/ClientStackNetworkHandler.cs
@@ -0,0 +1,40 @@
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*/
28using System.Net.Sockets;
29
30namespace OpenSim.Region.ClientStack
31{
32
33 public interface ClientStackNetworkHandler
34 {
35 void SendPacketTo(byte[] buffer, int size, SocketFlags flags, uint circuitcode);// EndPoint packetSender);
36 void RemoveClientCircuit(uint circuitcode);
37 void RegisterPacketServer(PacketServer server);
38 }
39
40}
diff --git a/OpenSim/Region/ClientStack/ClientView.API.cs b/OpenSim/Region/ClientStack/ClientView.API.cs
new file mode 100644
index 0000000..225e906
--- /dev/null
+++ b/OpenSim/Region/ClientStack/ClientView.API.cs
@@ -0,0 +1,1122 @@
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*/
28using System;
29using System.Collections.Generic;
30using System.Net;
31using System.Text;
32using Axiom.Math;
33using libsecondlife;
34using libsecondlife.Packets;
35using OpenSim.Framework.Console;
36using OpenSim.Framework.Interfaces;
37using OpenSim.Framework.Types;
38
39namespace OpenSim.Region.ClientStack
40{
41 partial class ClientView
42 {
43 public event ImprovedInstantMessage OnInstantMessage;
44 public event ChatFromViewer OnChatFromViewer;
45 public event RezObject OnRezObject;
46 public event GenericCall4 OnDeRezObject;
47 public event ModifyTerrain OnModifyTerrain;
48 public event GenericCall OnRegionHandShakeReply;
49 public event GenericCall OnRequestWearables;
50 public event SetAppearance OnSetAppearance;
51 public event GenericCall2 OnCompleteMovementToRegion;
52 public event UpdateAgent OnAgentUpdate;
53 public event StartAnim OnStartAnim;
54 public event GenericCall OnRequestAvatarsData;
55 public event LinkObjects OnLinkObjects;
56 public event UpdateVector OnGrapObject;
57 public event ObjectSelect OnDeGrapObject;
58 public event ObjectDuplicate OnObjectDuplicate;
59 public event MoveObject OnGrapUpdate;
60 public event GenericCall4 OnAddPrim;
61 public event UpdateShape OnUpdatePrimShape;
62 public event ObjectSelect OnObjectSelect;
63 public event GenericCall7 OnObjectDescription;
64 public event GenericCall7 OnObjectName;
65 public event UpdatePrimFlags OnUpdatePrimFlags;
66 public event UpdatePrimTexture OnUpdatePrimTexture;
67 public event UpdateVector OnUpdatePrimGroupPosition;
68 public event UpdateVector OnUpdatePrimSinglePosition;
69 public event UpdatePrimRotation OnUpdatePrimGroupRotation;
70 public event UpdatePrimSingleRotation OnUpdatePrimSingleRotation;
71 public event UpdatePrimGroupRotation OnUpdatePrimGroupMouseRotation;
72 public event UpdateVector OnUpdatePrimScale;
73 public event StatusChange OnChildAgentStatus;
74 public event GenericCall2 OnStopMovement;
75 public event NewAvatar OnNewAvatar;
76 public event GenericCall6 OnRemoveAvatar;
77 public event RequestMapBlocks OnRequestMapBlocks;
78 public event TeleportLocationRequest OnTeleportLocationRequest;
79
80 public event UUIDNameRequest OnNameFromUUIDRequest;
81
82 public event ParcelPropertiesRequest OnParcelPropertiesRequest;
83 public event ParcelDivideRequest OnParcelDivideRequest;
84 public event ParcelJoinRequest OnParcelJoinRequest;
85 public event ParcelPropertiesUpdateRequest OnParcelPropertiesUpdateRequest;
86
87 public event EstateOwnerMessageRequest OnEstateOwnerMessage;
88 /// <summary>
89 ///
90 /// </summary>
91 public LLVector3 StartPos
92 {
93 get
94 {
95 return startpos;
96 }
97 set
98 {
99 startpos = value;
100 }
101 }
102
103 /// <summary>
104 ///
105 /// </summary>
106 public LLUUID AgentId
107 {
108 get
109 {
110 return this.AgentID;
111 }
112 }
113
114 /// <summary>
115 ///
116 /// </summary>
117 public string FirstName
118 {
119 get
120 {
121 return this.firstName;
122 }
123
124 }
125
126 /// <summary>
127 ///
128 /// </summary>
129 public string LastName
130 {
131 get
132 {
133 return this.lastName;
134 }
135 }
136
137 #region World/Avatar to Client
138
139 /// <summary>
140 ///
141 /// </summary>
142 /// <param name="regionInfo"></param>
143 public void SendRegionHandshake(RegionInfo regionInfo)
144 {
145 Encoding _enc = Encoding.ASCII;
146 RegionHandshakePacket handshake = new RegionHandshakePacket();
147
148 handshake.RegionInfo.BillableFactor = regionInfo.estateSettings.billableFactor;
149 handshake.RegionInfo.IsEstateManager = false;
150 handshake.RegionInfo.TerrainHeightRange00 = regionInfo.estateSettings.terrainHeightRange0;
151 handshake.RegionInfo.TerrainHeightRange01 = regionInfo.estateSettings.terrainHeightRange1;
152 handshake.RegionInfo.TerrainHeightRange10 = regionInfo.estateSettings.terrainHeightRange2;
153 handshake.RegionInfo.TerrainHeightRange11 = regionInfo.estateSettings.terrainHeightRange3;
154 handshake.RegionInfo.TerrainStartHeight00 = regionInfo.estateSettings.terrainStartHeight0;
155 handshake.RegionInfo.TerrainStartHeight01 = regionInfo.estateSettings.terrainStartHeight1;
156 handshake.RegionInfo.TerrainStartHeight10 = regionInfo.estateSettings.terrainStartHeight2;
157 handshake.RegionInfo.TerrainStartHeight11 = regionInfo.estateSettings.terrainStartHeight3;
158 handshake.RegionInfo.SimAccess = (byte)regionInfo.estateSettings.simAccess;
159 handshake.RegionInfo.WaterHeight = regionInfo.estateSettings.waterHeight;
160
161
162 handshake.RegionInfo.RegionFlags = (uint)regionInfo.estateSettings.regionFlags;
163
164 handshake.RegionInfo.SimName = _enc.GetBytes(regionInfo.RegionName + "\0");
165 handshake.RegionInfo.SimOwner = regionInfo.MasterAvatarAssignedUUID;
166 handshake.RegionInfo.TerrainBase0 = regionInfo.estateSettings.terrainBase0;
167 handshake.RegionInfo.TerrainBase1 = regionInfo.estateSettings.terrainBase1;
168 handshake.RegionInfo.TerrainBase2 = regionInfo.estateSettings.terrainBase2;
169 handshake.RegionInfo.TerrainBase3 = regionInfo.estateSettings.terrainBase3;
170 handshake.RegionInfo.TerrainDetail0 = regionInfo.estateSettings.terrainDetail0;
171 handshake.RegionInfo.TerrainDetail1 = regionInfo.estateSettings.terrainDetail1;
172 handshake.RegionInfo.TerrainDetail2 = regionInfo.estateSettings.terrainDetail2;
173 handshake.RegionInfo.TerrainDetail3 = regionInfo.estateSettings.terrainDetail3;
174 handshake.RegionInfo.CacheID = LLUUID.Random(); //I guess this is for the client to remember an old setting?
175
176 this.OutPacket(handshake);
177 }
178
179 /// <summary>
180 ///
181 /// </summary>
182 /// <param name="regInfo"></param>
183 public void MoveAgentIntoRegion(RegionInfo regInfo, LLVector3 pos, LLVector3 look)
184 {
185 AgentMovementCompletePacket mov = new AgentMovementCompletePacket();
186 mov.AgentData.SessionID = this.SessionID;
187 mov.AgentData.AgentID = this.AgentID;
188 mov.Data.RegionHandle = regInfo.RegionHandle;
189 mov.Data.Timestamp = 1172750370; // TODO - dynamicalise this
190
191 if ((pos.X == 0) && (pos.Y == 0) && (pos.Z == 0))
192 {
193 mov.Data.Position = this.startpos;
194 }
195 else
196 {
197 mov.Data.Position = pos;
198 }
199 mov.Data.LookAt = look;
200
201 OutPacket(mov);
202 }
203
204 /// <summary>
205 ///
206 /// </summary>
207 /// <param name="message"></param>
208 /// <param name="type"></param>
209 /// <param name="fromPos"></param>
210 /// <param name="fromName"></param>
211 /// <param name="fromAgentID"></param>
212 public void SendChatMessage(string message, byte type, LLVector3 fromPos, string fromName, LLUUID fromAgentID)
213 {
214 SendChatMessage(Helpers.StringToField(message), type, fromPos, fromName, fromAgentID);
215 }
216
217 /// <summary>
218 ///
219 /// </summary>
220 /// <param name="message"></param>
221 /// <param name="type"></param>
222 /// <param name="fromPos"></param>
223 /// <param name="fromName"></param>
224 /// <param name="fromAgentID"></param>
225 public void SendChatMessage(byte[] message, byte type, LLVector3 fromPos, string fromName, LLUUID fromAgentID)
226 {
227 Encoding enc = Encoding.ASCII;
228 ChatFromSimulatorPacket reply = new ChatFromSimulatorPacket();
229 reply.ChatData.Audible = 1;
230 reply.ChatData.Message = message;
231 reply.ChatData.ChatType = type;
232 reply.ChatData.SourceType = 1;
233 reply.ChatData.Position = fromPos;
234 reply.ChatData.FromName = enc.GetBytes(fromName + "\0");
235 reply.ChatData.OwnerID = fromAgentID;
236 reply.ChatData.SourceID = fromAgentID;
237
238 this.OutPacket(reply);
239 }
240
241 /// <summary>
242 ///
243 /// </summary>
244 /// <remarks>TODO</remarks>
245 /// <param name="message"></param>
246 /// <param name="target"></param>
247 public void SendInstantMessage(string message, LLUUID target)
248 {
249 ImprovedInstantMessagePacket msg = new ImprovedInstantMessagePacket();
250 msg.AgentData.AgentID = this.AgentID;
251 msg.AgentData.SessionID = this.SessionID;
252
253 msg.MessageBlock.Dialog = 0;
254 msg.MessageBlock.FromGroup = false;
255 msg.MessageBlock.ID = target.Combine(this.AgentID);
256 msg.MessageBlock.Offline = 0;
257 msg.MessageBlock.ParentEstateID = 0;
258 msg.MessageBlock.Position = new LLVector3();
259 msg.MessageBlock.RegionID = new LLUUID();
260 msg.MessageBlock.Timestamp = 0;
261 msg.MessageBlock.ToAgentID = target;
262
263 this.OutPacket(msg);
264 }
265
266 /// <summary>
267 /// Send the region heightmap to the client
268 /// </summary>
269 /// <param name="map">heightmap</param>
270 public virtual void SendLayerData(float[] map)
271 {
272 try
273 {
274 int[] patches = new int[4];
275
276 for (int y = 0; y < 16; y++)
277 {
278 for (int x = 0; x < 16; x = x + 4)
279 {
280 patches[0] = x + 0 + y * 16;
281 patches[1] = x + 1 + y * 16;
282 patches[2] = x + 2 + y * 16;
283 patches[3] = x + 3 + y * 16;
284
285 Packet layerpack = TerrainManager.CreateLandPacket(map, patches);
286 OutPacket(layerpack);
287 }
288 }
289 }
290 catch (Exception e)
291 {
292 MainLog.Instance.Warn("ClientView API.cs: SendLayerData() - Failed with exception " + e.ToString());
293 }
294 }
295
296 /// <summary>
297 /// Sends a specified patch to a client
298 /// </summary>
299 /// <param name="px">Patch coordinate (x) 0..16</param>
300 /// <param name="py">Patch coordinate (y) 0..16</param>
301 /// <param name="map">heightmap</param>
302 public void SendLayerData(int px, int py, float[] map)
303 {
304 try
305 {
306 int[] patches = new int[1];
307 int patchx, patchy;
308 patchx = px / 16;
309 patchy = py / 16;
310
311 patches[0] = patchx + 0 + patchy * 16;
312
313 Packet layerpack = TerrainManager.CreateLandPacket(map, patches);
314 OutPacket(layerpack);
315 }
316 catch (Exception e)
317 {
318 MainLog.Instance.Warn("ClientView API .cs: SendLayerData() - Failed with exception " + e.ToString());
319 }
320 }
321
322 /// <summary>
323 ///
324 /// </summary>
325 /// <param name="neighbourHandle"></param>
326 /// <param name="neighbourIP"></param>
327 /// <param name="neighbourPort"></param>
328 public void InformClientOfNeighbour(ulong neighbourHandle, IPEndPoint neighbourEndPoint )
329 {
330 IPAddress neighbourIP = neighbourEndPoint.Address;
331 ushort neighbourPort = (ushort) neighbourEndPoint.Port;
332
333 EnableSimulatorPacket enablesimpacket = new EnableSimulatorPacket();
334 enablesimpacket.SimulatorInfo = new EnableSimulatorPacket.SimulatorInfoBlock();
335 enablesimpacket.SimulatorInfo.Handle = neighbourHandle;
336
337 byte[] byteIP = neighbourIP.GetAddressBytes();
338 enablesimpacket.SimulatorInfo.IP = (uint)byteIP[3] << 24;
339 enablesimpacket.SimulatorInfo.IP += (uint)byteIP[2] << 16;
340 enablesimpacket.SimulatorInfo.IP += (uint)byteIP[1] << 8;
341 enablesimpacket.SimulatorInfo.IP += (uint)byteIP[0];
342 enablesimpacket.SimulatorInfo.Port = neighbourPort;
343 OutPacket(enablesimpacket);
344 }
345
346 /// <summary>
347 ///
348 /// </summary>
349 /// <returns></returns>
350 public AgentCircuitData RequestClientInfo()
351 {
352 AgentCircuitData agentData = new AgentCircuitData();
353 agentData.AgentID = this.AgentId;
354 agentData.SessionID = this.SessionID;
355 agentData.SecureSessionID = this.SecureSessionID;
356 agentData.circuitcode = this.CircuitCode;
357 agentData.child = false;
358 agentData.firstname = this.firstName;
359 agentData.lastname = this.lastName;
360
361 return agentData;
362 }
363
364 public void CrossRegion(ulong newRegionHandle, LLVector3 pos, LLVector3 lookAt, IPEndPoint externalIPEndPoint)
365 {
366 LLVector3 look = new LLVector3(lookAt.X * 10, lookAt.Y * 10, lookAt.Z * 10);
367
368 CrossedRegionPacket newSimPack = new CrossedRegionPacket();
369 newSimPack.AgentData = new CrossedRegionPacket.AgentDataBlock();
370 newSimPack.AgentData.AgentID = this.AgentID;
371 newSimPack.AgentData.SessionID = this.SessionID;
372 newSimPack.Info = new CrossedRegionPacket.InfoBlock();
373 newSimPack.Info.Position = pos;
374 newSimPack.Info.LookAt = look; // new LLVector3(0.0f, 0.0f, 0.0f); // copied from Avatar.cs - SHOULD BE DYNAMIC!!!!!!!!!!
375 newSimPack.RegionData = new CrossedRegionPacket.RegionDataBlock();
376 newSimPack.RegionData.RegionHandle = newRegionHandle;
377 byte[] byteIP = externalIPEndPoint.Address.GetAddressBytes();
378 newSimPack.RegionData.SimIP = (uint)byteIP[3] << 24;
379 newSimPack.RegionData.SimIP += (uint)byteIP[2] << 16;
380 newSimPack.RegionData.SimIP += (uint)byteIP[1] << 8;
381 newSimPack.RegionData.SimIP += (uint)byteIP[0];
382 newSimPack.RegionData.SimPort = (ushort)externalIPEndPoint.Port;
383 newSimPack.RegionData.SeedCapability = new byte[0];
384
385 this.OutPacket(newSimPack);
386 //this.DowngradeClient();
387 }
388
389 public void SendMapBlock(List<MapBlockData> mapBlocks)
390 {
391 Encoding _enc = Encoding.ASCII;
392
393 MapBlockReplyPacket mapReply = new MapBlockReplyPacket();
394 mapReply.AgentData.AgentID = this.AgentID;
395 mapReply.Data = new MapBlockReplyPacket.DataBlock[mapBlocks.Count];
396 mapReply.AgentData.Flags = 0;
397
398 for (int i = 0; i < mapBlocks.Count; i++)
399 {
400 mapReply.Data[i] = new MapBlockReplyPacket.DataBlock();
401 mapReply.Data[i].MapImageID = mapBlocks[i].MapImageId;
402 mapReply.Data[i].X = mapBlocks[i].X;
403 mapReply.Data[i].Y = mapBlocks[i].Y;
404 mapReply.Data[i].WaterHeight = mapBlocks[i].WaterHeight;
405 mapReply.Data[i].Name = _enc.GetBytes(mapBlocks[i].Name);
406 mapReply.Data[i].RegionFlags = mapBlocks[i].RegionFlags;
407 mapReply.Data[i].Access = mapBlocks[i].Access;
408 mapReply.Data[i].Agents = mapBlocks[i].Agents;
409 }
410 this.OutPacket(mapReply);
411 }
412
413 public void SendLocalTeleport(LLVector3 position, LLVector3 lookAt, uint flags)
414 {
415 TeleportLocalPacket tpLocal = new TeleportLocalPacket();
416 tpLocal.Info.AgentID = this.AgentID;
417 tpLocal.Info.TeleportFlags = flags;
418 tpLocal.Info.LocationID = 2;
419 tpLocal.Info.LookAt = lookAt;
420 tpLocal.Info.Position = position;
421 OutPacket(tpLocal);
422 }
423
424 public void SendRegionTeleport(ulong regionHandle, byte simAccess, IPEndPoint newRegionEndPoint, uint locationID, uint flags)
425 {
426 TeleportFinishPacket teleport = new TeleportFinishPacket();
427 teleport.Info.AgentID = this.AgentID;
428 teleport.Info.RegionHandle = regionHandle;
429 teleport.Info.SimAccess = simAccess;
430 teleport.Info.SeedCapability = new byte[0];
431
432 IPAddress oIP = newRegionEndPoint.Address;
433 byte[] byteIP = oIP.GetAddressBytes();
434 uint ip = (uint)byteIP[3] << 24;
435 ip += (uint)byteIP[2] << 16;
436 ip += (uint)byteIP[1] << 8;
437 ip += (uint)byteIP[0];
438
439 teleport.Info.SimIP = ip;
440 teleport.Info.SimPort = (ushort)newRegionEndPoint.Port;
441 teleport.Info.LocationID = 4;
442 teleport.Info.TeleportFlags = 1 << 4;
443 OutPacket(teleport);
444 }
445
446 /// <summary>
447 ///
448 /// </summary>
449 public void SendTeleportCancel()
450 {
451 TeleportCancelPacket tpCancel = new TeleportCancelPacket();
452 tpCancel.Info.SessionID = this.SessionID;
453 tpCancel.Info.AgentID = this.AgentID;
454
455 OutPacket(tpCancel);
456 }
457
458 /// <summary>
459 ///
460 /// </summary>
461 public void SendTeleportLocationStart()
462 {
463 TeleportStartPacket tpStart = new TeleportStartPacket();
464 tpStart.Info.TeleportFlags = 16; // Teleport via location
465 OutPacket(tpStart);
466 }
467
468 public void SendMoneyBalance(LLUUID transaction, bool success, byte[] description, int balance)
469 {
470 MoneyBalanceReplyPacket money = new MoneyBalanceReplyPacket();
471 money.MoneyData.AgentID = this.AgentID;
472 money.MoneyData.TransactionID = transaction;
473 money.MoneyData.TransactionSuccess = success;
474 money.MoneyData.Description = description;
475 money.MoneyData.MoneyBalance = balance;
476 OutPacket(money);
477 }
478
479 public void SendStartPingCheck(byte seq)
480 {
481 StartPingCheckPacket pc = new StartPingCheckPacket();
482 pc.PingID.PingID = seq;
483 OutPacket(pc);
484 }
485
486 public void SendKillObject(ulong regionHandle, uint avatarLocalID)
487 {
488 KillObjectPacket kill = new KillObjectPacket();
489 kill.ObjectData = new KillObjectPacket.ObjectDataBlock[1];
490 kill.ObjectData[0] = new KillObjectPacket.ObjectDataBlock();
491 kill.ObjectData[0].ID = avatarLocalID;
492 OutPacket(kill);
493 }
494
495
496 #region Appearance/ Wearables Methods
497
498 /// <summary>
499 ///
500 /// </summary>
501 /// <param name="wearables"></param>
502 public void SendWearables(AvatarWearable[] wearables)
503 {
504 AgentWearablesUpdatePacket aw = new AgentWearablesUpdatePacket();
505 aw.AgentData.AgentID = this.AgentID;
506 aw.AgentData.SerialNum = 0;
507 aw.AgentData.SessionID = this.SessionID;
508
509 aw.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[13];
510 AgentWearablesUpdatePacket.WearableDataBlock awb;
511 for (int i = 0; i < wearables.Length; i++)
512 {
513 awb = new AgentWearablesUpdatePacket.WearableDataBlock();
514 awb.WearableType = (byte)i;
515 awb.AssetID = wearables[i].AssetID;
516 awb.ItemID = wearables[i].ItemID;
517 aw.WearableData[i] = awb;
518 }
519
520 this.OutPacket(aw);
521 }
522
523 /// <summary>
524 ///
525 /// </summary>
526 /// <param name="agentID"></param>
527 /// <param name="visualParams"></param>
528 /// <param name="textureEntry"></param>
529 public void SendAppearance(LLUUID agentID, byte[] visualParams, byte[] textureEntry)
530 {
531 AvatarAppearancePacket avp = new AvatarAppearancePacket();
532 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[218];
533 avp.ObjectData.TextureEntry = textureEntry;
534
535 AvatarAppearancePacket.VisualParamBlock avblock = null;
536 for (int i = 0; i < visualParams.Length; i++)
537 {
538 avblock = new AvatarAppearancePacket.VisualParamBlock();
539 avblock.ParamValue = visualParams[i];
540 avp.VisualParam[i] = avblock;
541 }
542
543 avp.Sender.IsTrial = false;
544 avp.Sender.ID = agentID;
545 OutPacket(avp);
546 }
547
548 public void SendAnimation(LLUUID animID, int seq, LLUUID sourceAgentId)
549 {
550 AvatarAnimationPacket ani = new AvatarAnimationPacket();
551 ani.AnimationSourceList = new AvatarAnimationPacket.AnimationSourceListBlock[1];
552 ani.AnimationSourceList[0] = new AvatarAnimationPacket.AnimationSourceListBlock();
553 ani.AnimationSourceList[0].ObjectID = sourceAgentId;
554 ani.Sender = new AvatarAnimationPacket.SenderBlock();
555 ani.Sender.ID = sourceAgentId;
556 ani.AnimationList = new AvatarAnimationPacket.AnimationListBlock[1];
557 ani.AnimationList[0] = new AvatarAnimationPacket.AnimationListBlock();
558 ani.AnimationList[0].AnimID = animID;
559 ani.AnimationList[0].AnimSequenceID = seq;
560 this.OutPacket(ani);
561 }
562
563 #endregion
564
565 #region Avatar Packet/data sending Methods
566
567 /// <summary>
568 ///
569 /// </summary>
570 /// <param name="regionInfo"></param>
571 /// <param name="firstName"></param>
572 /// <param name="lastName"></param>
573 /// <param name="avatarID"></param>
574 /// <param name="avatarLocalID"></param>
575 /// <param name="Pos"></param>
576 public void SendAvatarData(ulong regionHandle, string firstName, string lastName, LLUUID avatarID, uint avatarLocalID, LLVector3 Pos, byte[] textureEntry)
577 {
578 Encoding _enc = Encoding.ASCII;
579 //send a objectupdate packet with information about the clients avatar
580
581 ObjectUpdatePacket objupdate = new ObjectUpdatePacket();
582 objupdate.RegionData.RegionHandle = regionHandle;
583 objupdate.RegionData.TimeDilation = 64096;
584 objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
585 objupdate.ObjectData[0] = this.CreateDefaultAvatarPacket(textureEntry);
586 //give this avatar object a local id and assign the user a name
587
588 objupdate.ObjectData[0].ID = avatarLocalID;
589 objupdate.ObjectData[0].FullID = avatarID;
590 objupdate.ObjectData[0].NameValue = _enc.GetBytes("FirstName STRING RW SV " + firstName + "\nLastName STRING RW SV " + lastName + " \0");
591 LLVector3 pos2 = new LLVector3((float)Pos.X, (float)Pos.Y, (float)Pos.Z);
592 byte[] pb = pos2.GetBytes();
593 Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 16, pb.Length);
594
595 OutPacket(objupdate);
596
597 }
598
599 /// <summary>
600 ///
601 /// </summary>
602 /// <param name="regionHandle"></param>
603 /// <param name="timeDilation"></param>
604 /// <param name="localID"></param>
605 /// <param name="position"></param>
606 /// <param name="velocity"></param>
607 public void SendAvatarTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, LLVector3 position, LLVector3 velocity)
608 {
609 ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock = this.CreateAvatarImprovedBlock(localID, position, velocity);
610 ImprovedTerseObjectUpdatePacket terse = new ImprovedTerseObjectUpdatePacket();
611 terse.RegionData.RegionHandle = regionHandle;
612 terse.RegionData.TimeDilation = timeDilation;
613 terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1];
614 terse.ObjectData[0] = terseBlock;
615
616 this.OutPacket(terse);
617 }
618
619 #endregion
620
621 #region Primitive Packet/data Sending Methods
622
623 /// <summary>
624 ///
625 /// </summary>
626 /// <param name="localID"></param>
627 /// <param name="rotation"></param>
628 /// <param name="attachPoint"></param>
629 public void AttachObject(uint localID, LLQuaternion rotation, byte attachPoint)
630 {
631 ObjectAttachPacket attach = new ObjectAttachPacket();
632 attach.AgentData.AgentID = this.AgentID;
633 attach.AgentData.SessionID = this.SessionID;
634 attach.AgentData.AttachmentPoint = attachPoint;
635 attach.ObjectData = new ObjectAttachPacket.ObjectDataBlock[1];
636 attach.ObjectData[0] = new ObjectAttachPacket.ObjectDataBlock();
637 attach.ObjectData[0].ObjectLocalID = localID;
638 attach.ObjectData[0].Rotation = rotation;
639
640 this.OutPacket(attach);
641 }
642
643 /// <summary>
644 /// Sends a full ObjectUpdatePacket to a client to inform it of a new primitive
645 /// or big changes to a existing primitive.
646 /// </summary>
647 /// <param name="regionHandle"></param>
648 /// <param name="timeDilation"></param>
649 /// <param name="localID"></param>
650 /// <param name="primData"></param>
651 /// <param name="pos"></param>
652 /// <param name="rotation"></param>
653 /// <param name="textureID"></param>
654 public void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimData primData, LLVector3 pos, LLQuaternion rotation, LLUUID textureID, uint flags)
655 {
656 ObjectUpdatePacket outPacket = new ObjectUpdatePacket();
657 outPacket.RegionData.RegionHandle = regionHandle;
658 outPacket.RegionData.TimeDilation = timeDilation;
659 outPacket.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
660 outPacket.ObjectData[0] = this.CreatePrimUpdateBlock(primData, textureID, flags);
661 outPacket.ObjectData[0].ID = localID;
662 outPacket.ObjectData[0].FullID = primData.FullID;
663 byte[] pb = pos.GetBytes();
664 Array.Copy(pb, 0, outPacket.ObjectData[0].ObjectData, 0, pb.Length);
665 byte[] rot = rotation.GetBytes();
666 Array.Copy(rot, 0, outPacket.ObjectData[0].ObjectData, 48, rot.Length);
667 OutPacket(outPacket);
668 }
669
670 /// <summary>
671 /// Sends a full ObjectUpdatePacket to a client to inform it of a new primitive
672 /// or big changes to a existing primitive.
673 /// Uses default rotation
674 /// </summary>
675 /// <param name="primData"></param>
676 /// <param name="pos"></param>
677 public void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimData primData, LLVector3 pos, LLUUID textureID , uint flags)
678 {
679 ObjectUpdatePacket outPacket = new ObjectUpdatePacket();
680 outPacket.RegionData.RegionHandle = regionHandle;
681 outPacket.RegionData.TimeDilation = timeDilation;
682 outPacket.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
683 outPacket.ObjectData[0] = this.CreatePrimUpdateBlock(primData, textureID, flags);
684 outPacket.ObjectData[0].ID = localID;
685 outPacket.ObjectData[0].FullID = primData.FullID;
686 byte[] pb = pos.GetBytes();
687 Array.Copy(pb, 0, outPacket.ObjectData[0].ObjectData, 0, pb.Length);
688
689 OutPacket(outPacket);
690 }
691
692
693 public void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, LLVector3 pos, LLQuaternion rotation, LLUUID textureID, uint flags, LLUUID objectID, LLUUID ownerID, string text, uint parentID)
694 {
695 ObjectUpdatePacket outPacket = new ObjectUpdatePacket();
696 outPacket.RegionData.RegionHandle = regionHandle;
697 outPacket.RegionData.TimeDilation = timeDilation;
698 outPacket.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
699 outPacket.ObjectData[0] = this.CreatePrimUpdateBlock(primShape, textureID, flags);
700 outPacket.ObjectData[0].ID = localID;
701 outPacket.ObjectData[0].FullID = objectID;
702 outPacket.ObjectData[0].OwnerID = ownerID;
703 outPacket.ObjectData[0].Text = enc.GetBytes(text);
704 outPacket.ObjectData[0].ParentID = parentID;
705 byte[] pb = pos.GetBytes();
706 Array.Copy(pb, 0, outPacket.ObjectData[0].ObjectData, 0, pb.Length);
707 byte[] rot = rotation.GetBytes();
708 Array.Copy(rot, 0, outPacket.ObjectData[0].ObjectData, 36, rot.Length);
709 OutPacket(outPacket);
710 }
711
712 public void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, LLVector3 pos, LLUUID textureID, uint flags, LLUUID objectID, LLUUID ownerID, string text, uint parentID)
713 {
714 ObjectUpdatePacket outPacket = new ObjectUpdatePacket();
715 outPacket.RegionData.RegionHandle = regionHandle;
716 outPacket.RegionData.TimeDilation = timeDilation;
717 outPacket.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
718 outPacket.ObjectData[0] = this.CreatePrimUpdateBlock(primShape, textureID, flags);
719 outPacket.ObjectData[0].ID = localID;
720 outPacket.ObjectData[0].FullID = objectID;
721 outPacket.ObjectData[0].OwnerID = ownerID;
722 outPacket.ObjectData[0].Text = enc.GetBytes(text);
723 outPacket.ObjectData[0].ParentID = parentID;
724 byte[] pb = pos.GetBytes();
725 Array.Copy(pb, 0, outPacket.ObjectData[0].ObjectData, 0, pb.Length);
726
727 OutPacket(outPacket);
728 }
729 /// <summary>
730 ///
731 /// </summary>
732 /// <param name="regionHandle"></param>
733 /// <param name="timeDilation"></param>
734 /// <param name="localID"></param>
735 /// <param name="position"></param>
736 /// <param name="rotation"></param>
737 public void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, LLVector3 position, LLQuaternion rotation)
738 {
739 ImprovedTerseObjectUpdatePacket terse = new ImprovedTerseObjectUpdatePacket();
740 terse.RegionData.RegionHandle = regionHandle;
741 terse.RegionData.TimeDilation = timeDilation;
742 terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1];
743 terse.ObjectData[0] = this.CreatePrimImprovedBlock(localID, position, rotation);
744
745 this.OutPacket(terse);
746 }
747
748 #endregion
749
750 #endregion
751
752 #region Helper Methods
753
754 protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateAvatarImprovedBlock(uint localID, LLVector3 pos, LLVector3 velocity)
755 {
756 byte[] bytes = new byte[60];
757 int i = 0;
758 ImprovedTerseObjectUpdatePacket.ObjectDataBlock dat = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock();
759
760 dat.TextureEntry = new byte[0];// AvatarTemplate.TextureEntry;
761
762 uint ID = localID;
763
764 bytes[i++] = (byte)(ID % 256);
765 bytes[i++] = (byte)((ID >> 8) % 256);
766 bytes[i++] = (byte)((ID >> 16) % 256);
767 bytes[i++] = (byte)((ID >> 24) % 256);
768 bytes[i++] = 0;
769 bytes[i++] = 1;
770 i += 14;
771 bytes[i++] = 128;
772 bytes[i++] = 63;
773
774 byte[] pb = pos.GetBytes();
775 Array.Copy(pb, 0, bytes, i, pb.Length);
776 i += 12;
777 ushort InternVelocityX;
778 ushort InternVelocityY;
779 ushort InternVelocityZ;
780 Vector3 internDirec = new Vector3(0, 0, 0);
781
782 internDirec = new Vector3(velocity.X, velocity.Y, velocity.Z);
783
784 internDirec = internDirec / 128.0f;
785 internDirec.x += 1;
786 internDirec.y += 1;
787 internDirec.z += 1;
788
789 InternVelocityX = (ushort)(32768 * internDirec.x);
790 InternVelocityY = (ushort)(32768 * internDirec.y);
791 InternVelocityZ = (ushort)(32768 * internDirec.z);
792
793 ushort ac = 32767;
794 bytes[i++] = (byte)(InternVelocityX % 256);
795 bytes[i++] = (byte)((InternVelocityX >> 8) % 256);
796 bytes[i++] = (byte)(InternVelocityY % 256);
797 bytes[i++] = (byte)((InternVelocityY >> 8) % 256);
798 bytes[i++] = (byte)(InternVelocityZ % 256);
799 bytes[i++] = (byte)((InternVelocityZ >> 8) % 256);
800
801 //accel
802 bytes[i++] = (byte)(ac % 256);
803 bytes[i++] = (byte)((ac >> 8) % 256);
804 bytes[i++] = (byte)(ac % 256);
805 bytes[i++] = (byte)((ac >> 8) % 256);
806 bytes[i++] = (byte)(ac % 256);
807 bytes[i++] = (byte)((ac >> 8) % 256);
808
809 //rot
810 bytes[i++] = (byte)(ac % 256);
811 bytes[i++] = (byte)((ac >> 8) % 256);
812 bytes[i++] = (byte)(ac % 256);
813 bytes[i++] = (byte)((ac >> 8) % 256);
814 bytes[i++] = (byte)(ac % 256);
815 bytes[i++] = (byte)((ac >> 8) % 256);
816 bytes[i++] = (byte)(ac % 256);
817 bytes[i++] = (byte)((ac >> 8) % 256);
818
819 //rotation vel
820 bytes[i++] = (byte)(ac % 256);
821 bytes[i++] = (byte)((ac >> 8) % 256);
822 bytes[i++] = (byte)(ac % 256);
823 bytes[i++] = (byte)((ac >> 8) % 256);
824 bytes[i++] = (byte)(ac % 256);
825 bytes[i++] = (byte)((ac >> 8) % 256);
826
827 dat.Data = bytes;
828 return (dat);
829 }
830
831 /// <summary>
832 ///
833 /// </summary>
834 /// <param name="localID"></param>
835 /// <param name="position"></param>
836 /// <param name="rotation"></param>
837 /// <returns></returns>
838 protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreatePrimImprovedBlock(uint localID, LLVector3 position, LLQuaternion rotation)
839 {
840 uint ID = localID;
841 byte[] bytes = new byte[60];
842
843 int i = 0;
844 ImprovedTerseObjectUpdatePacket.ObjectDataBlock dat = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock();
845 dat.TextureEntry = new byte[0];
846 bytes[i++] = (byte)(ID % 256);
847 bytes[i++] = (byte)((ID >> 8) % 256);
848 bytes[i++] = (byte)((ID >> 16) % 256);
849 bytes[i++] = (byte)((ID >> 24) % 256);
850 bytes[i++] = 0;
851 bytes[i++] = 0;
852
853 byte[] pb = position.GetBytes();
854 Array.Copy(pb, 0, bytes, i, pb.Length);
855 i += 12;
856 ushort ac = 32767;
857
858 //vel
859 bytes[i++] = (byte)(ac % 256);
860 bytes[i++] = (byte)((ac >> 8) % 256);
861 bytes[i++] = (byte)(ac % 256);
862 bytes[i++] = (byte)((ac >> 8) % 256);
863 bytes[i++] = (byte)(ac % 256);
864 bytes[i++] = (byte)((ac >> 8) % 256);
865
866 //accel
867 bytes[i++] = (byte)(ac % 256);
868 bytes[i++] = (byte)((ac >> 8) % 256);
869 bytes[i++] = (byte)(ac % 256);
870 bytes[i++] = (byte)((ac >> 8) % 256);
871 bytes[i++] = (byte)(ac % 256);
872 bytes[i++] = (byte)((ac >> 8) % 256);
873
874 ushort rw, rx, ry, rz;
875 rw = (ushort)(32768 * (rotation.W + 1));
876 rx = (ushort)(32768 * (rotation.X + 1));
877 ry = (ushort)(32768 * (rotation.Y + 1));
878 rz = (ushort)(32768 * (rotation.Z + 1));
879
880 //rot
881 bytes[i++] = (byte)(rx % 256);
882 bytes[i++] = (byte)((rx >> 8) % 256);
883 bytes[i++] = (byte)(ry % 256);
884 bytes[i++] = (byte)((ry >> 8) % 256);
885 bytes[i++] = (byte)(rz % 256);
886 bytes[i++] = (byte)((rz >> 8) % 256);
887 bytes[i++] = (byte)(rw % 256);
888 bytes[i++] = (byte)((rw >> 8) % 256);
889
890 //rotation vel
891 bytes[i++] = (byte)(ac % 256);
892 bytes[i++] = (byte)((ac >> 8) % 256);
893 bytes[i++] = (byte)(ac % 256);
894 bytes[i++] = (byte)((ac >> 8) % 256);
895 bytes[i++] = (byte)(ac % 256);
896 bytes[i++] = (byte)((ac >> 8) % 256);
897
898 dat.Data = bytes;
899 return dat;
900 }
901
902
903 /// <summary>
904 /// Create the ObjectDataBlock for a ObjectUpdatePacket (for a Primitive)
905 /// </summary>
906 /// <param name="primData"></param>
907 /// <returns></returns>
908 protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(PrimData primData, LLUUID textureID, uint flags)
909 {
910 ObjectUpdatePacket.ObjectDataBlock objupdate = new ObjectUpdatePacket.ObjectDataBlock();
911 this.SetDefaultPrimPacketValues(objupdate);
912 objupdate.UpdateFlags = flags;
913 this.SetPrimPacketShapeData(objupdate, primData, textureID);
914
915 return objupdate;
916 }
917
918 /// <summary>
919 /// Create the ObjectDataBlock for a ObjectUpdatePacket (for a Primitive)
920 /// </summary>
921 /// <param name="primData"></param>
922 /// <returns></returns>
923 protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(PrimitiveBaseShape primShape, LLUUID textureID, uint flags)
924 {
925 ObjectUpdatePacket.ObjectDataBlock objupdate = new ObjectUpdatePacket.ObjectDataBlock();
926 this.SetDefaultPrimPacketValues(objupdate);
927 objupdate.UpdateFlags = flags;
928 this.SetPrimPacketShapeData(objupdate, primShape, textureID);
929
930 return objupdate;
931 }
932
933
934 /// <summary>
935 /// Copy the data from a PrimData object to a ObjectUpdatePacket
936 /// </summary>
937 /// <param name="objectData"></param>
938 /// <param name="primData"></param>
939 protected void SetPrimPacketShapeData(ObjectUpdatePacket.ObjectDataBlock objectData, PrimData primData, LLUUID textureID)
940 {
941 LLObject.TextureEntry ntex = new LLObject.TextureEntry(textureID);
942 objectData.TextureEntry = ntex.ToBytes();
943 objectData.OwnerID = primData.OwnerID;
944 objectData.ParentID = primData.ParentID;
945 objectData.PCode = primData.PCode;
946 objectData.PathBegin = primData.PathBegin;
947 objectData.PathEnd = primData.PathEnd;
948 objectData.PathScaleX = primData.PathScaleX;
949 objectData.PathScaleY = primData.PathScaleY;
950 objectData.PathShearX = primData.PathShearX;
951 objectData.PathShearY = primData.PathShearY;
952 objectData.PathSkew = primData.PathSkew;
953 objectData.ProfileBegin = primData.ProfileBegin;
954 objectData.ProfileEnd = primData.ProfileEnd;
955 objectData.Scale = primData.Scale;
956 objectData.PathCurve = primData.PathCurve;
957 objectData.ProfileCurve = primData.ProfileCurve;
958 objectData.ProfileHollow = primData.ProfileHollow;
959 objectData.PathRadiusOffset = primData.PathRadiusOffset;
960 objectData.PathRevolutions = primData.PathRevolutions;
961 objectData.PathTaperX = primData.PathTaperX;
962 objectData.PathTaperY = primData.PathTaperY;
963 objectData.PathTwist = primData.PathTwist;
964 objectData.PathTwistBegin = primData.PathTwistBegin;
965 }
966
967 protected void SetPrimPacketShapeData(ObjectUpdatePacket.ObjectDataBlock objectData, PrimitiveBaseShape primData, LLUUID textureID)
968 {
969 LLObject.TextureEntry ntex = new LLObject.TextureEntry(textureID);
970 objectData.TextureEntry = ntex.ToBytes();
971 objectData.PCode = primData.PCode;
972 objectData.PathBegin = primData.PathBegin;
973 objectData.PathEnd = primData.PathEnd;
974 objectData.PathScaleX = primData.PathScaleX;
975 objectData.PathScaleY = primData.PathScaleY;
976 objectData.PathShearX = primData.PathShearX;
977 objectData.PathShearY = primData.PathShearY;
978 objectData.PathSkew = primData.PathSkew;
979 objectData.ProfileBegin = primData.ProfileBegin;
980 objectData.ProfileEnd = primData.ProfileEnd;
981 objectData.Scale = primData.Scale;
982 objectData.PathCurve = primData.PathCurve;
983 objectData.ProfileCurve = primData.ProfileCurve;
984 objectData.ProfileHollow = primData.ProfileHollow;
985 objectData.PathRadiusOffset = primData.PathRadiusOffset;
986 objectData.PathRevolutions = primData.PathRevolutions;
987 objectData.PathTaperX = primData.PathTaperX;
988 objectData.PathTaperY = primData.PathTaperY;
989 objectData.PathTwist = primData.PathTwist;
990 objectData.PathTwistBegin = primData.PathTwistBegin;
991 }
992
993 /// <summary>
994 /// Set some default values in a ObjectUpdatePacket
995 /// </summary>
996 /// <param name="objdata"></param>
997 protected void SetDefaultPrimPacketValues(ObjectUpdatePacket.ObjectDataBlock objdata)
998 {
999 objdata.PSBlock = new byte[0];
1000 objdata.ExtraParams = new byte[1];
1001 objdata.MediaURL = new byte[0];
1002 objdata.NameValue = new byte[0];
1003 objdata.Text = new byte[0];
1004 objdata.TextColor = new byte[4];
1005 objdata.JointAxisOrAnchor = new LLVector3(0, 0, 0);
1006 objdata.JointPivot = new LLVector3(0, 0, 0);
1007 objdata.Material = 3;
1008 objdata.TextureAnim = new byte[0];
1009 objdata.Sound = LLUUID.Zero;
1010 objdata.State = 0;
1011 objdata.Data = new byte[0];
1012
1013 objdata.ObjectData = new byte[60];
1014 objdata.ObjectData[46] = 128;
1015 objdata.ObjectData[47] = 63;
1016 }
1017
1018
1019 /// <summary>
1020 ///
1021 /// </summary>
1022 /// <returns></returns>
1023 protected ObjectUpdatePacket.ObjectDataBlock CreateDefaultAvatarPacket(byte[] textureEntry)
1024 {
1025 ObjectUpdatePacket.ObjectDataBlock objdata = new ObjectUpdatePacket.ObjectDataBlock(); // new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock(data1, ref i);
1026
1027 SetDefaultAvatarPacketValues(ref objdata);
1028 objdata.UpdateFlags = 61 + (9 << 8) + (130 << 16) + (16 << 24);
1029 objdata.PathCurve = 16;
1030 objdata.ProfileCurve = 1;
1031 objdata.PathScaleX = 100;
1032 objdata.PathScaleY = 100;
1033 objdata.ParentID = 0;
1034 objdata.OwnerID = LLUUID.Zero;
1035 objdata.Scale = new LLVector3(1, 1, 1);
1036 objdata.PCode = 47;
1037 if (textureEntry != null)
1038 {
1039 objdata.TextureEntry = textureEntry;
1040 }
1041 Encoding enc = Encoding.ASCII;
1042 LLVector3 pos = new LLVector3(objdata.ObjectData, 16);
1043 pos.X = 100f;
1044 objdata.ID = 8880000;
1045 objdata.NameValue = enc.GetBytes("FirstName STRING RW SV Test \nLastName STRING RW SV User \0");
1046 LLVector3 pos2 = new LLVector3(100f, 100f, 23f);
1047 //objdata.FullID=user.AgentID;
1048 byte[] pb = pos.GetBytes();
1049 Array.Copy(pb, 0, objdata.ObjectData, 16, pb.Length);
1050
1051 return objdata;
1052 }
1053
1054 /// <summary>
1055 ///
1056 /// </summary>
1057 /// <param name="objdata"></param>
1058 protected void SetDefaultAvatarPacketValues(ref ObjectUpdatePacket.ObjectDataBlock objdata)
1059 {
1060 objdata.PSBlock = new byte[0];
1061 objdata.ExtraParams = new byte[1];
1062 objdata.MediaURL = new byte[0];
1063 objdata.NameValue = new byte[0];
1064 objdata.Text = new byte[0];
1065 objdata.TextColor = new byte[4];
1066 objdata.JointAxisOrAnchor = new LLVector3(0, 0, 0);
1067 objdata.JointPivot = new LLVector3(0, 0, 0);
1068 objdata.Material = 4;
1069 objdata.TextureAnim = new byte[0];
1070 objdata.Sound = LLUUID.Zero;
1071 LLObject.TextureEntry ntex = new LLObject.TextureEntry(new LLUUID("00000000-0000-0000-5005-000000000005"));
1072 objdata.TextureEntry = ntex.ToBytes();
1073 objdata.State = 0;
1074 objdata.Data = new byte[0];
1075
1076 objdata.ObjectData = new byte[76];
1077 objdata.ObjectData[15] = 128;
1078 objdata.ObjectData[16] = 63;
1079 objdata.ObjectData[56] = 128;
1080 objdata.ObjectData[61] = 102;
1081 objdata.ObjectData[62] = 40;
1082 objdata.ObjectData[63] = 61;
1083 objdata.ObjectData[64] = 189;
1084 }
1085
1086 /// <summary>
1087 ///
1088 /// </summary>
1089 /// <param name="addPacket"></param>
1090 /// <returns></returns>
1091 protected PrimData CreatePrimFromObjectAdd(ObjectAddPacket addPacket)
1092 {
1093 PrimData PData = new PrimData();
1094 PData.CreationDate = (Int32)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;
1095 PData.PCode = addPacket.ObjectData.PCode;
1096 PData.PathBegin = addPacket.ObjectData.PathBegin;
1097 PData.PathEnd = addPacket.ObjectData.PathEnd;
1098 PData.PathScaleX = addPacket.ObjectData.PathScaleX;
1099 PData.PathScaleY = addPacket.ObjectData.PathScaleY;
1100 PData.PathShearX = addPacket.ObjectData.PathShearX;
1101 PData.PathShearY = addPacket.ObjectData.PathShearY;
1102 PData.PathSkew = addPacket.ObjectData.PathSkew;
1103 PData.ProfileBegin = addPacket.ObjectData.ProfileBegin;
1104 PData.ProfileEnd = addPacket.ObjectData.ProfileEnd;
1105 PData.Scale = addPacket.ObjectData.Scale;
1106 PData.PathCurve = addPacket.ObjectData.PathCurve;
1107 PData.ProfileCurve = addPacket.ObjectData.ProfileCurve;
1108 PData.ParentID = 0;
1109 PData.ProfileHollow = addPacket.ObjectData.ProfileHollow;
1110 PData.PathRadiusOffset = addPacket.ObjectData.PathRadiusOffset;
1111 PData.PathRevolutions = addPacket.ObjectData.PathRevolutions;
1112 PData.PathTaperX = addPacket.ObjectData.PathTaperX;
1113 PData.PathTaperY = addPacket.ObjectData.PathTaperY;
1114 PData.PathTwist = addPacket.ObjectData.PathTwist;
1115 PData.PathTwistBegin = addPacket.ObjectData.PathTwistBegin;
1116
1117 return PData;
1118 }
1119 #endregion
1120
1121 }
1122}
diff --git a/OpenSim/Region/ClientStack/ClientView.AgentAssetUpload.cs b/OpenSim/Region/ClientStack/ClientView.AgentAssetUpload.cs
new file mode 100644
index 0000000..60cd33a
--- /dev/null
+++ b/OpenSim/Region/ClientStack/ClientView.AgentAssetUpload.cs
@@ -0,0 +1,357 @@
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*/
28using System;
29using System.Collections.Generic;
30using libsecondlife;
31using libsecondlife.Packets;
32using OpenSim.Assets;
33using OpenSim.Framework.Interfaces;
34using OpenSim.Framework.Types;
35using OpenSim.Framework.Utilities;
36using OpenSim.Region.Caches;
37
38namespace OpenSim.Region.ClientStack
39{
40 partial class ClientView
41 {
42 public class AgentAssetUpload
43 {
44 private Dictionary<LLUUID, AssetTransaction> transactions = new Dictionary<LLUUID, AssetTransaction>();
45 private ClientView ourClient;
46 private AssetCache m_assetCache;
47 private InventoryCache m_inventoryCache;
48
49 public AgentAssetUpload(ClientView client, AssetCache assetCache, InventoryCache inventoryCache)
50 {
51 this.ourClient = client;
52 m_assetCache = assetCache;
53 m_inventoryCache = inventoryCache;
54 }
55
56 public void AddUpload(LLUUID transactionID, AssetBase asset)
57 {
58 AssetTransaction upload = new AssetTransaction();
59 lock (this.transactions)
60 {
61 upload.Asset = asset;
62 upload.TransactionID = transactionID;
63 this.transactions.Add(transactionID, upload);
64 }
65 if (upload.Asset.Data.Length > 2)
66 {
67 //is complete
68 upload.UploadComplete = true;
69 AssetUploadCompletePacket response = new AssetUploadCompletePacket();
70 response.AssetBlock.Type = asset.Type;
71 response.AssetBlock.Success = true;
72 response.AssetBlock.UUID = transactionID.Combine(this.ourClient.SecureSessionID);
73 this.ourClient.OutPacket(response);
74 m_assetCache.AddAsset(asset);
75 }
76 else
77 {
78 upload.UploadComplete = false;
79 upload.XferID = Util.GetNextXferID();
80 RequestXferPacket xfer = new RequestXferPacket();
81 xfer.XferID.ID = upload.XferID;
82 xfer.XferID.VFileType = upload.Asset.Type;
83 xfer.XferID.VFileID = transactionID.Combine(this.ourClient.SecureSessionID);
84 xfer.XferID.FilePath = 0;
85 xfer.XferID.Filename = new byte[0];
86 this.ourClient.OutPacket(xfer);
87 }
88
89 }
90
91 public AssetBase GetUpload(LLUUID transactionID)
92 {
93 if (this.transactions.ContainsKey(transactionID))
94 {
95 return this.transactions[transactionID].Asset;
96 }
97
98 return null;
99 }
100
101 public void HandleUploadPacket(AssetUploadRequestPacket pack, LLUUID assetID)
102 {
103 // Console.Write("asset upload request , type = " + pack.AssetBlock.Type.ToString());
104 AssetBase asset = null;
105 if (pack.AssetBlock.Type == 0)
106 {
107
108 //first packet for transaction
109 asset = new AssetBase();
110 asset.FullID = assetID;
111 asset.Type = pack.AssetBlock.Type;
112 asset.InvType = asset.Type;
113 asset.Name = "UploadedTexture" + Util.RandomClass.Next(1, 1000).ToString("000");
114 asset.Data = pack.AssetBlock.AssetData;
115
116
117 }
118 else if (pack.AssetBlock.Type == 13 | pack.AssetBlock.Type == 5 | pack.AssetBlock.Type == 7)
119 {
120
121 asset = new AssetBase();
122 asset.FullID = assetID;
123 // Console.WriteLine("skin asset id is " + assetID.ToStringHyphenated());
124 asset.Type = pack.AssetBlock.Type;
125 asset.InvType = asset.Type;
126 asset.Name = "NewClothing" + Util.RandomClass.Next(1, 1000).ToString("000");
127 asset.Data = pack.AssetBlock.AssetData;
128
129
130 }
131
132 if (asset != null)
133 {
134 this.AddUpload(pack.AssetBlock.TransactionID, asset);
135 }
136 else
137 {
138
139 //currently we don't support this asset type
140 //so lets just tell the client that the upload is complete
141 AssetUploadCompletePacket response = new AssetUploadCompletePacket();
142 response.AssetBlock.Type = pack.AssetBlock.Type;
143 response.AssetBlock.Success = true;
144 response.AssetBlock.UUID = pack.AssetBlock.TransactionID.Combine(this.ourClient.SecureSessionID);
145 this.ourClient.OutPacket(response);
146 }
147
148 }
149
150 #region Xfer packet system for larger uploads
151
152 public void HandleXferPacket(SendXferPacketPacket xferPacket)
153 {
154 lock (this.transactions)
155 {
156 foreach (AssetTransaction trans in this.transactions.Values)
157 {
158 if (trans.XferID == xferPacket.XferID.ID)
159 {
160 if (trans.Asset.Data.Length > 1)
161 {
162 byte[] newArray = new byte[trans.Asset.Data.Length + xferPacket.DataPacket.Data.Length];
163 Array.Copy(trans.Asset.Data, 0, newArray, 0, trans.Asset.Data.Length);
164 Array.Copy(xferPacket.DataPacket.Data, 0, newArray, trans.Asset.Data.Length, xferPacket.DataPacket.Data.Length);
165 trans.Asset.Data = newArray;
166 }
167 else
168 {
169 byte[] newArray = new byte[xferPacket.DataPacket.Data.Length - 4];
170 Array.Copy(xferPacket.DataPacket.Data, 4, newArray, 0, xferPacket.DataPacket.Data.Length - 4);
171 trans.Asset.Data = newArray;
172 }
173
174 if ((xferPacket.XferID.Packet & 2147483648) != 0)
175 {
176 //end of transfer
177 trans.UploadComplete = true;
178 AssetUploadCompletePacket response = new AssetUploadCompletePacket();
179 response.AssetBlock.Type = trans.Asset.Type;
180 response.AssetBlock.Success = true;
181 response.AssetBlock.UUID = trans.TransactionID.Combine(this.ourClient.SecureSessionID);
182 this.ourClient.OutPacket(response);
183
184 m_assetCache.AddAsset(trans.Asset);
185 //check if we should add it to inventory
186 if (trans.AddToInventory)
187 {
188 // m_assetCache.AddAsset(trans.Asset);
189 m_inventoryCache.AddNewInventoryItem(this.ourClient, trans.InventFolder, trans.Asset);
190 }
191
192
193 }
194 break;
195 }
196
197 }
198 }
199
200 ConfirmXferPacketPacket confirmXfer = new ConfirmXferPacketPacket();
201 confirmXfer.XferID.ID = xferPacket.XferID.ID;
202 confirmXfer.XferID.Packet = xferPacket.XferID.Packet;
203 this.ourClient.OutPacket(confirmXfer);
204 }
205
206 #endregion
207
208 public AssetBase AddUploadToAssetCache(LLUUID transactionID)
209 {
210 AssetBase asset = null;
211 if (this.transactions.ContainsKey(transactionID))
212 {
213 AssetTransaction trans = this.transactions[transactionID];
214 if (trans.UploadComplete)
215 {
216 m_assetCache.AddAsset(trans.Asset);
217 asset = trans.Asset;
218 }
219 }
220
221 return asset;
222 }
223
224 public void CreateInventoryItem(CreateInventoryItemPacket packet)
225 {
226 if (this.transactions.ContainsKey(packet.InventoryBlock.TransactionID))
227 {
228 AssetTransaction trans = this.transactions[packet.InventoryBlock.TransactionID];
229 trans.Asset.Description = Util.FieldToString(packet.InventoryBlock.Description);
230 trans.Asset.Name = Util.FieldToString(packet.InventoryBlock.Name);
231 trans.Asset.Type = packet.InventoryBlock.Type;
232 trans.Asset.InvType = packet.InventoryBlock.InvType;
233 if (trans.UploadComplete)
234 {
235 //already complete so we can add it to the inventory
236 //m_assetCache.AddAsset(trans.Asset);
237 m_inventoryCache.AddNewInventoryItem(this.ourClient, packet.InventoryBlock.FolderID, trans.Asset);
238 }
239 else
240 {
241 trans.AddToInventory = true;
242 trans.InventFolder = packet.InventoryBlock.FolderID;
243 }
244 }
245 }
246
247 private class AssetTransaction
248 {
249 public uint XferID;
250 public AssetBase Asset;
251 public bool AddToInventory;
252 public LLUUID InventFolder = LLUUID.Zero;
253 public bool UploadComplete = false;
254 public LLUUID TransactionID = LLUUID.Zero;
255
256 public AssetTransaction()
257 {
258
259 }
260 }
261
262 //new class , not currently used.
263 public class AssetXferUploader
264 {
265 private IClientAPI ourClient;
266
267 public bool UploadComplete = false;
268
269 public bool AddToInventory;
270 public LLUUID InventFolder = LLUUID.Zero;
271
272 public uint XferID;
273 public AssetBase Asset;
274 public LLUUID TransactionID = LLUUID.Zero;
275
276
277 public AssetXferUploader(IClientAPI remoteClient, LLUUID assetID, LLUUID transaction, sbyte type, byte[] data)
278 {
279 ourClient = remoteClient;
280 Asset = new AssetBase();
281 Asset.FullID = assetID;
282 Asset.InvType = type;
283 Asset.Type = type;
284 Asset.Data = data;
285 Asset.Name = "blank";
286 Asset.Description = "empty";
287 TransactionID = transaction;
288
289 if (Asset.Data.Length > 2)
290 {
291 //data block should only have data in it, if there is no more data to be uploaded
292 this.SendCompleteMessage();
293 }
294 else
295 {
296 this.ReqestStartXfer();
297 }
298 }
299
300 protected void SendCompleteMessage()
301 {
302 UploadComplete = true;
303 AssetUploadCompletePacket response = new AssetUploadCompletePacket();
304 response.AssetBlock.Type = Asset.Type;
305 response.AssetBlock.Success = true;
306 response.AssetBlock.UUID = Asset.FullID;
307 this.ourClient.OutPacket(response);
308
309 //TODO trigger event
310 }
311
312 protected void ReqestStartXfer()
313 {
314 UploadComplete = false;
315 XferID = Util.GetNextXferID();
316 RequestXferPacket xfer = new RequestXferPacket();
317 xfer.XferID.ID = XferID;
318 xfer.XferID.VFileType = Asset.Type;
319 xfer.XferID.VFileID = Asset.FullID;
320 xfer.XferID.FilePath = 0;
321 xfer.XferID.Filename = new byte[0];
322 this.ourClient.OutPacket(xfer);
323 }
324
325 public void HandleXferPacket(uint xferID, uint packetID, byte[] data)
326 {
327 if (XferID == xferID)
328 {
329 if (Asset.Data.Length > 1)
330 {
331 byte[] newArray = new byte[Asset.Data.Length + data.Length];
332 Array.Copy(Asset.Data, 0, newArray, 0, Asset.Data.Length);
333 Array.Copy(data, 0, newArray, Asset.Data.Length, data.Length);
334 Asset.Data = newArray;
335 }
336 else
337 {
338 byte[] newArray = new byte[data.Length - 4];
339 Array.Copy(data, 4, newArray, 0, data.Length - 4);
340 Asset.Data = newArray;
341 }
342
343 ConfirmXferPacketPacket confirmXfer = new ConfirmXferPacketPacket();
344 confirmXfer.XferID.ID = xferID;
345 confirmXfer.XferID.Packet = packetID;
346 this.ourClient.OutPacket(confirmXfer);
347
348 if ((packetID & 2147483648) != 0)
349 {
350 this.SendCompleteMessage();
351 }
352 }
353 }
354 }
355 }
356 }
357}
diff --git a/OpenSim/Region/ClientStack/ClientView.PacketHandlers.cs b/OpenSim/Region/ClientStack/ClientView.PacketHandlers.cs
new file mode 100644
index 0000000..e67807e
--- /dev/null
+++ b/OpenSim/Region/ClientStack/ClientView.PacketHandlers.cs
@@ -0,0 +1,236 @@
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*/
28using libsecondlife;
29using libsecondlife.Packets;
30using OpenSim.Framework.Console;
31
32namespace OpenSim.Region.ClientStack
33{
34 public partial class ClientView
35 {
36 protected virtual void RegisterLocalPacketHandlers()
37 {
38 this.AddLocalPacketHandler(PacketType.LogoutRequest, this.Logout);
39 this.AddLocalPacketHandler(PacketType.AgentCachedTexture, this.AgentTextureCached);
40 this.AddLocalPacketHandler(PacketType.MultipleObjectUpdate, this.MultipleObjUpdate);
41 }
42
43 protected virtual bool Logout(ClientView simClient, Packet packet)
44 {
45 MainLog.Instance.Verbose( "OpenSimClient.cs:ProcessInPacket() - Got a logout request");
46 //send reply to let the client logout
47 LogoutReplyPacket logReply = new LogoutReplyPacket();
48 logReply.AgentData.AgentID = this.AgentID;
49 logReply.AgentData.SessionID = this.SessionID;
50 logReply.InventoryData = new LogoutReplyPacket.InventoryDataBlock[1];
51 logReply.InventoryData[0] = new LogoutReplyPacket.InventoryDataBlock();
52 logReply.InventoryData[0].ItemID = LLUUID.Zero;
53 OutPacket(logReply);
54 //
55 this.KillClient();
56 return true;
57 }
58
59 protected bool AgentTextureCached(ClientView simclient, Packet packet)
60 {
61 // Console.WriteLine(packet.ToString());
62 AgentCachedTexturePacket chechedtex = (AgentCachedTexturePacket)packet;
63 AgentCachedTextureResponsePacket cachedresp = new AgentCachedTextureResponsePacket();
64 cachedresp.AgentData.AgentID = this.AgentID;
65 cachedresp.AgentData.SessionID = this.SessionID;
66 cachedresp.AgentData.SerialNum = this.cachedtextureserial;
67 this.cachedtextureserial++;
68 cachedresp.WearableData = new AgentCachedTextureResponsePacket.WearableDataBlock[chechedtex.WearableData.Length];
69 for (int i = 0; i < chechedtex.WearableData.Length; i++)
70 {
71 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
72 cachedresp.WearableData[i].TextureIndex = chechedtex.WearableData[i].TextureIndex;
73 cachedresp.WearableData[i].TextureID = LLUUID.Zero;
74 cachedresp.WearableData[i].HostName = new byte[0];
75 }
76 this.OutPacket(cachedresp);
77 return true;
78 }
79
80 protected bool MultipleObjUpdate(ClientView simClient, Packet packet)
81 {
82 MultipleObjectUpdatePacket multipleupdate = (MultipleObjectUpdatePacket)packet;
83 //System.Console.WriteLine("new multi update packet " + multipleupdate.ToString());
84 for (int i = 0; i < multipleupdate.ObjectData.Length; i++)
85 {
86 #region position
87 if (multipleupdate.ObjectData[i].Type == 9) //change position
88 {
89 if (OnUpdatePrimGroupPosition != null)
90 {
91 LLVector3 pos = new LLVector3(multipleupdate.ObjectData[i].Data, 0);
92 OnUpdatePrimGroupPosition(multipleupdate.ObjectData[i].ObjectLocalID, pos, this);
93 }
94
95 }
96 else if (multipleupdate.ObjectData[i].Type == 1) //single item of group change position
97 {
98 if (OnUpdatePrimSinglePosition != null)
99 {
100 libsecondlife.LLVector3 pos = new LLVector3(multipleupdate.ObjectData[i].Data, 0);
101 // System.Console.WriteLine("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z);
102 OnUpdatePrimSinglePosition(multipleupdate.ObjectData[i].ObjectLocalID, pos, this);
103 }
104 }
105 #endregion position
106 #region rotation
107 else if (multipleupdate.ObjectData[i].Type == 2)// single item of group rotation from tab
108 {
109 if (OnUpdatePrimSingleRotation != null)
110 {
111 LLQuaternion rot = new LLQuaternion(multipleupdate.ObjectData[i].Data, 0, true);
112 // Console.WriteLine("new rotation is " + rot.X + " , " + rot.Y + " , " + rot.Z + " , " + rot.W);
113 OnUpdatePrimSingleRotation(multipleupdate.ObjectData[i].ObjectLocalID, rot, this);
114 }
115 }
116 else if (multipleupdate.ObjectData[i].Type == 3)// single item of group rotation from mouse
117 {
118 if (OnUpdatePrimSingleRotation != null)
119 {
120 libsecondlife.LLQuaternion rot = new LLQuaternion(multipleupdate.ObjectData[i].Data, 12, true);
121 // Console.WriteLine("new rotation is " + rot.X + " , " + rot.Y + " , " + rot.Z + " , " + rot.W);
122 OnUpdatePrimSingleRotation(multipleupdate.ObjectData[i].ObjectLocalID, rot, this);
123 }
124 }
125 else if (multipleupdate.ObjectData[i].Type == 10)//group rotation from object tab
126 {
127 if (OnUpdatePrimGroupRotation != null)
128 {
129 libsecondlife.LLQuaternion rot = new LLQuaternion(multipleupdate.ObjectData[i].Data, 0, true);
130 // Console.WriteLine("new rotation is " + rot.X + " , " + rot.Y + " , " + rot.Z + " , " + rot.W);
131 OnUpdatePrimGroupRotation(multipleupdate.ObjectData[i].ObjectLocalID, rot, this);
132 }
133 }
134 else if (multipleupdate.ObjectData[i].Type == 11)//group rotation from mouse
135 {
136 if (OnUpdatePrimGroupMouseRotation != null)
137 {
138 libsecondlife.LLVector3 pos = new LLVector3(multipleupdate.ObjectData[i].Data, 0);
139 libsecondlife.LLQuaternion rot = new LLQuaternion(multipleupdate.ObjectData[i].Data, 12, true);
140 //Console.WriteLine("new rotation position is " + pos.X + " , " + pos.Y + " , " + pos.Z);
141 // Console.WriteLine("new rotation is " + rot.X + " , " + rot.Y + " , " + rot.Z + " , " + rot.W);
142 OnUpdatePrimGroupMouseRotation(multipleupdate.ObjectData[i].ObjectLocalID, pos, rot, this);
143 }
144 }
145 #endregion
146 #region scale
147 else if (multipleupdate.ObjectData[i].Type == 13)//group scale from object tab
148 {
149 if (OnUpdatePrimScale != null)
150 {
151 LLVector3 scale = new LLVector3(multipleupdate.ObjectData[i].Data, 12);
152 //Console.WriteLine("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
153 OnUpdatePrimScale(multipleupdate.ObjectData[i].ObjectLocalID, scale, this);
154 }
155 }
156 else if (multipleupdate.ObjectData[i].Type == 29)//group scale from mouse
157 {
158 if (OnUpdatePrimScale != null)
159 {
160 libsecondlife.LLVector3 scale = new LLVector3(multipleupdate.ObjectData[i].Data, 0);
161 // Console.WriteLine("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z );
162 // OnUpdatePrimScale(multipleupdate.ObjectData[i].ObjectLocalID, scale, this);
163 }
164 }
165 else if (multipleupdate.ObjectData[i].Type == 5)//single prim scale from object tab
166 {
167 if (OnUpdatePrimScale != null)
168 {
169 libsecondlife.LLVector3 scale = new LLVector3(multipleupdate.ObjectData[i].Data, 12);
170 // Console.WriteLine("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
171 OnUpdatePrimScale(multipleupdate.ObjectData[i].ObjectLocalID, scale, this);
172 }
173 }
174 else if (multipleupdate.ObjectData[i].Type == 21)//single prim scale from mouse
175 {
176 if (OnUpdatePrimScale != null)
177 {
178 libsecondlife.LLVector3 scale = new LLVector3(multipleupdate.ObjectData[i].Data, 12);
179 // Console.WriteLine("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
180 OnUpdatePrimScale(multipleupdate.ObjectData[i].ObjectLocalID, scale, this);
181 }
182 }
183 #endregion
184 }
185 return true;
186 }
187
188 public void RequestMapLayer()
189 {
190 //should be getting the map layer from the grid server
191 //send a layer covering the 800,800 - 1200,1200 area (should be covering the requested area)
192 MapLayerReplyPacket mapReply = new MapLayerReplyPacket();
193 mapReply.AgentData.AgentID = this.AgentID;
194 mapReply.AgentData.Flags = 0;
195 mapReply.LayerData = new MapLayerReplyPacket.LayerDataBlock[1];
196 mapReply.LayerData[0] = new MapLayerReplyPacket.LayerDataBlock();
197 mapReply.LayerData[0].Bottom = 0;
198 mapReply.LayerData[0].Left = 0;
199 mapReply.LayerData[0].Top = 30000;
200 mapReply.LayerData[0].Right = 30000;
201 mapReply.LayerData[0].ImageID = new LLUUID("00000000-0000-0000-9999-000000000006");
202 this.OutPacket(mapReply);
203 }
204
205 public void RequestMapBlocks(int minX, int minY, int maxX, int maxY)
206 {
207 /*
208 IList simMapProfiles = m_gridServer.RequestMapBlocks(minX, minY, maxX, maxY);
209 MapBlockReplyPacket mbReply = new MapBlockReplyPacket();
210 mbReply.AgentData.AgentID = this.AgentID;
211 int len;
212 if (simMapProfiles == null)
213 len = 0;
214 else
215 len = simMapProfiles.Count;
216
217 mbReply.Data = new MapBlockReplyPacket.DataBlock[len];
218 int iii;
219 for (iii = 0; iii < len; iii++)
220 {
221 Hashtable mp = (Hashtable)simMapProfiles[iii];
222 mbReply.Data[iii] = new MapBlockReplyPacket.DataBlock();
223 mbReply.Data[iii].Name = System.Text.Encoding.UTF8.GetBytes((string)mp["name"]);
224 mbReply.Data[iii].Access = System.Convert.ToByte(mp["access"]);
225 mbReply.Data[iii].Agents = System.Convert.ToByte(mp["agents"]);
226 mbReply.Data[iii].MapImageID = new LLUUID((string)mp["map-image-id"]);
227 mbReply.Data[iii].RegionFlags = System.Convert.ToUInt32(mp["region-flags"]);
228 mbReply.Data[iii].WaterHeight = System.Convert.ToByte(mp["water-height"]);
229 mbReply.Data[iii].X = System.Convert.ToUInt16(mp["x"]);
230 mbReply.Data[iii].Y = System.Convert.ToUInt16(mp["y"]);
231 }
232 this.OutPacket(mbReply);
233 */
234 }
235 }
236}
diff --git a/OpenSim/Region/ClientStack/ClientView.ProcessPackets.cs b/OpenSim/Region/ClientStack/ClientView.ProcessPackets.cs
new file mode 100644
index 0000000..3265898
--- /dev/null
+++ b/OpenSim/Region/ClientStack/ClientView.ProcessPackets.cs
@@ -0,0 +1,596 @@
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*/
28using System;
29using System.Collections.Generic;
30using System.Text;
31using libsecondlife;
32using libsecondlife.Packets;
33using OpenSim.Framework.Inventory;
34using OpenSim.Framework.Types;
35using OpenSim.Framework.Utilities;
36
37namespace OpenSim.Region.ClientStack
38{
39 public partial class ClientView
40 {
41 protected override void ProcessInPacket(Packet Pack)
42 {
43 ack_pack(Pack);
44 if (debug)
45 {
46 if (Pack.Type != PacketType.AgentUpdate)
47 {
48 Console.WriteLine(CircuitCode + ":IN: " + Pack.Type.ToString());
49 }
50 }
51
52 if (this.ProcessPacketMethod(Pack))
53 {
54 //there is a handler registered that handled this packet type
55 return;
56 }
57 else
58 {
59 Encoding _enc = Encoding.ASCII;
60
61 switch (Pack.Type)
62 {
63 case PacketType.ViewerEffect:
64 ViewerEffectPacket viewer = (ViewerEffectPacket)Pack;
65 foreach (ClientView client in m_clientThreads.Values)
66 {
67 if (client.AgentID != this.AgentID)
68 {
69 viewer.AgentData.AgentID = client.AgentID;
70 viewer.AgentData.SessionID = client.SessionID;
71 client.OutPacket(viewer);
72 }
73 }
74 break;
75
76 #region World/Avatar
77 case PacketType.ChatFromViewer:
78 ChatFromViewerPacket inchatpack = (ChatFromViewerPacket)Pack;
79 if (Util.FieldToString(inchatpack.ChatData.Message) == "")
80 {
81 //empty message so don't bother with it
82 break;
83 }
84 string fromName = ""; //ClientAvatar.firstname + " " + ClientAvatar.lastname;
85 byte[] message = inchatpack.ChatData.Message;
86 byte type = inchatpack.ChatData.Type;
87 LLVector3 fromPos = new LLVector3(); // ClientAvatar.Pos;
88 LLUUID fromAgentID = AgentID;
89 if (OnChatFromViewer != null)
90 {
91 this.OnChatFromViewer(message, type, fromPos, fromName, fromAgentID);
92 }
93 break;
94 case PacketType.ImprovedInstantMessage:
95 ImprovedInstantMessagePacket msgpack = (ImprovedInstantMessagePacket)Pack;
96
97 string IMfromName = Util.FieldToString(msgpack.MessageBlock.FromAgentName);
98 string IMmessage = Util.FieldToString(msgpack.MessageBlock.Message);
99
100 if (OnInstantMessage != null)
101 {
102 this.OnInstantMessage(msgpack.AgentData.AgentID, msgpack.MessageBlock.ToAgentID,
103 msgpack.MessageBlock.Timestamp, IMfromName, IMmessage);
104 }
105
106 break;
107
108 case PacketType.RezObject:
109 RezObjectPacket rezPacket = (RezObjectPacket)Pack;
110 AgentInventory inven = this.m_inventoryCache.GetAgentsInventory(this.AgentID);
111 if (inven != null)
112 {
113 if (inven.InventoryItems.ContainsKey(rezPacket.InventoryData.ItemID))
114 {
115 AssetBase asset = this.m_assetCache.GetAsset(inven.InventoryItems[rezPacket.InventoryData.ItemID].AssetID);
116 if (asset != null)
117 {
118 if (OnRezObject != null)
119 {
120 this.OnRezObject(asset, rezPacket.RezData.RayEnd);
121 this.m_inventoryCache.DeleteInventoryItem(this, rezPacket.InventoryData.ItemID);
122 }
123 }
124 }
125 }
126 break;
127 case PacketType.DeRezObject:
128 if (OnDeRezObject != null)
129 {
130 OnDeRezObject(Pack, this);
131 }
132 break;
133 case PacketType.ModifyLand:
134 ModifyLandPacket modify = (ModifyLandPacket)Pack;
135 if (modify.ParcelData.Length > 0)
136 {
137 if (OnModifyTerrain != null)
138 {
139 OnModifyTerrain(modify.ModifyBlock.Height, modify.ModifyBlock.Seconds, modify.ModifyBlock.BrushSize,
140 modify.ModifyBlock.Action, modify.ParcelData[0].North, modify.ParcelData[0].West);
141 }
142 }
143 break;
144 case PacketType.RegionHandshakeReply:
145 if (OnRegionHandShakeReply != null)
146 {
147 OnRegionHandShakeReply(this);
148 }
149 break;
150 case PacketType.AgentWearablesRequest:
151 if (OnRequestWearables != null)
152 {
153 OnRequestWearables(this);
154 }
155 if (OnRequestAvatarsData != null)
156 {
157 OnRequestAvatarsData(this);
158 }
159 break;
160 case PacketType.AgentSetAppearance:
161 AgentSetAppearancePacket appear = (AgentSetAppearancePacket)Pack;
162 if (OnSetAppearance != null)
163 {
164 OnSetAppearance(appear.ObjectData.TextureEntry, appear.VisualParam);
165 }
166 break;
167 case PacketType.CompleteAgentMovement:
168 if (OnCompleteMovementToRegion != null)
169 {
170 OnCompleteMovementToRegion();
171 }
172 break;
173 case PacketType.AgentUpdate:
174 if (OnAgentUpdate != null)
175 {
176 AgentUpdatePacket agenUpdate = (AgentUpdatePacket)Pack;
177 OnAgentUpdate(this, agenUpdate.AgentData.ControlFlags, agenUpdate.AgentData.BodyRotation);
178 }
179 break;
180 case PacketType.AgentAnimation:
181 if (!m_child)
182 {
183 AgentAnimationPacket AgentAni = (AgentAnimationPacket)Pack;
184 for (int i = 0; i < AgentAni.AnimationList.Length; i++)
185 {
186 if (AgentAni.AnimationList[i].StartAnim)
187 {
188 if (OnStartAnim != null)
189 {
190 OnStartAnim(AgentAni.AnimationList[i].AnimID, 1);
191 }
192 }
193 }
194 }
195 break;
196
197 #endregion
198
199 #region Objects/Prims
200 case PacketType.ObjectLink:
201 // OpenSim.Framework.Console.MainLog.Instance.Verbose( Pack.ToString());
202 ObjectLinkPacket link = (ObjectLinkPacket)Pack;
203 uint parentprimid = 0;
204 List<uint> childrenprims = new List<uint>();
205 if (link.ObjectData.Length > 1)
206 {
207 parentprimid = link.ObjectData[0].ObjectLocalID;
208
209 for (int i = 1; i < link.ObjectData.Length; i++)
210 {
211 childrenprims.Add(link.ObjectData[i].ObjectLocalID);
212 }
213 }
214 if (OnLinkObjects != null)
215 {
216 OnLinkObjects(parentprimid, childrenprims);
217 }
218 break;
219 case PacketType.ObjectAdd:
220 if (OnAddPrim != null)
221 {
222 OnAddPrim(Pack, this);
223 }
224 break;
225 case PacketType.ObjectShape:
226 ObjectShapePacket shape = (ObjectShapePacket)Pack;
227 for (int i = 0; i < shape.ObjectData.Length; i++)
228 {
229 if (OnUpdatePrimShape != null)
230 {
231 OnUpdatePrimShape(shape.ObjectData[i].ObjectLocalID, shape.ObjectData[i]);
232 }
233 }
234 break;
235 case PacketType.ObjectDuplicate:
236 ObjectDuplicatePacket dupe = (ObjectDuplicatePacket)Pack;
237 for (int i = 0; i < dupe.ObjectData.Length; i++)
238 {
239 if (OnObjectDuplicate != null)
240 {
241 OnObjectDuplicate(dupe.ObjectData[i].ObjectLocalID, dupe.SharedData.Offset, dupe.SharedData.DuplicateFlags);
242 }
243 }
244
245 break;
246
247 case PacketType.ObjectSelect:
248 ObjectSelectPacket incomingselect = (ObjectSelectPacket)Pack;
249 for (int i = 0; i < incomingselect.ObjectData.Length; i++)
250 {
251 if (OnObjectSelect != null)
252 {
253 OnObjectSelect(incomingselect.ObjectData[i].ObjectLocalID, this);
254 }
255 }
256 break;
257 case PacketType.ObjectFlagUpdate:
258 ObjectFlagUpdatePacket flags = (ObjectFlagUpdatePacket)Pack;
259 if (OnUpdatePrimFlags != null)
260 {
261 OnUpdatePrimFlags(flags.AgentData.ObjectLocalID, Pack, this);
262 }
263 break;
264 case PacketType.ObjectImage:
265 ObjectImagePacket imagePack = (ObjectImagePacket)Pack;
266 for (int i = 0; i < imagePack.ObjectData.Length; i++)
267 {
268 if (OnUpdatePrimTexture != null)
269 {
270 OnUpdatePrimTexture(imagePack.ObjectData[i].ObjectLocalID, imagePack.ObjectData[i].TextureEntry, this);
271 }
272 }
273 break;
274 case PacketType.ObjectGrab:
275 ObjectGrabPacket grap = (ObjectGrabPacket)Pack;
276 if (OnGrapObject != null)
277 {
278 OnGrapObject(grap.ObjectData.LocalID, grap.ObjectData.GrabOffset, this);
279 }
280 break;
281 case PacketType.ObjectGrabUpdate:
282 ObjectGrabUpdatePacket grapUpdate = (ObjectGrabUpdatePacket)Pack;
283 if (OnGrapUpdate != null)
284 {
285 OnGrapUpdate(grapUpdate.ObjectData.ObjectID, grapUpdate.ObjectData.GrabOffsetInitial, grapUpdate.ObjectData.GrabPosition, this);
286 }
287 break;
288 case PacketType.ObjectDeGrab:
289 ObjectDeGrabPacket deGrap = (ObjectDeGrabPacket)Pack;
290 if (OnDeGrapObject != null)
291 {
292 OnDeGrapObject(deGrap.ObjectData.LocalID, this);
293 }
294 break;
295 case PacketType.ObjectDescription:
296 ObjectDescriptionPacket objDes = (ObjectDescriptionPacket)Pack;
297 for (int i = 0; i < objDes.ObjectData.Length; i++)
298 {
299 if (OnObjectDescription != null)
300 {
301 OnObjectDescription(objDes.ObjectData[i].LocalID, enc.GetString(objDes.ObjectData[i].Description));
302 }
303 }
304 break;
305 case PacketType.ObjectName:
306 ObjectNamePacket objName = (ObjectNamePacket)Pack;
307 for (int i = 0; i < objName.ObjectData.Length; i++)
308 {
309 if (OnObjectName != null)
310 {
311 OnObjectName(objName.ObjectData[i].LocalID, enc.GetString(objName.ObjectData[i].Name));
312 }
313 }
314 break;
315 case PacketType.ObjectPermissions:
316 //Console.WriteLine("permissions set " + Pack.ToString());
317 break;
318 #endregion
319
320 #region Inventory/Asset/Other related packets
321 case PacketType.RequestImage:
322 RequestImagePacket imageRequest = (RequestImagePacket)Pack;
323 for (int i = 0; i < imageRequest.RequestImage.Length; i++)
324 {
325 m_assetCache.AddTextureRequest(this, imageRequest.RequestImage[i].Image);
326 }
327 break;
328 case PacketType.TransferRequest:
329 //Console.WriteLine("OpenSimClient.cs:ProcessInPacket() - Got transfer request");
330 TransferRequestPacket transfer = (TransferRequestPacket)Pack;
331 m_assetCache.AddAssetRequest(this, transfer);
332 break;
333 case PacketType.AssetUploadRequest:
334 AssetUploadRequestPacket request = (AssetUploadRequestPacket)Pack;
335 this.UploadAssets.HandleUploadPacket(request, request.AssetBlock.TransactionID.Combine(this.SecureSessionID));
336 break;
337 case PacketType.RequestXfer:
338 //Console.WriteLine(Pack.ToString());
339 break;
340 case PacketType.SendXferPacket:
341 this.UploadAssets.HandleXferPacket((SendXferPacketPacket)Pack);
342 break;
343 case PacketType.CreateInventoryFolder:
344 CreateInventoryFolderPacket invFolder = (CreateInventoryFolderPacket)Pack;
345 m_inventoryCache.CreateNewInventoryFolder(this, invFolder.FolderData.FolderID, (ushort)invFolder.FolderData.Type, Util.FieldToString(invFolder.FolderData.Name), invFolder.FolderData.ParentID);
346 //Console.WriteLine(Pack.ToString());
347 break;
348 case PacketType.CreateInventoryItem:
349 //Console.WriteLine(Pack.ToString());
350 CreateInventoryItemPacket createItem = (CreateInventoryItemPacket)Pack;
351 if (createItem.InventoryBlock.TransactionID != LLUUID.Zero)
352 {
353 this.UploadAssets.CreateInventoryItem(createItem);
354 }
355 else
356 {
357 // Console.Write(Pack.ToString());
358 this.CreateInventoryItem(createItem);
359 }
360 break;
361 case PacketType.FetchInventory:
362 //Console.WriteLine("fetch item packet");
363 FetchInventoryPacket FetchInventory = (FetchInventoryPacket)Pack;
364 m_inventoryCache.FetchInventory(this, FetchInventory);
365 break;
366 case PacketType.FetchInventoryDescendents:
367 FetchInventoryDescendentsPacket Fetch = (FetchInventoryDescendentsPacket)Pack;
368 m_inventoryCache.FetchInventoryDescendents(this, Fetch);
369 break;
370 case PacketType.UpdateInventoryItem:
371 UpdateInventoryItemPacket update = (UpdateInventoryItemPacket)Pack;
372 //Console.WriteLine(Pack.ToString());
373 for (int i = 0; i < update.InventoryData.Length; i++)
374 {
375 if (update.InventoryData[i].TransactionID != LLUUID.Zero)
376 {
377 AssetBase asset = m_assetCache.GetAsset(update.InventoryData[i].TransactionID.Combine(this.SecureSessionID));
378 if (asset != null)
379 {
380 // Console.WriteLine("updating inventory item, found asset" + asset.FullID.ToStringHyphenated() + " already in cache");
381 m_inventoryCache.UpdateInventoryItemAsset(this, update.InventoryData[i].ItemID, asset);
382 }
383 else
384 {
385 asset = this.UploadAssets.AddUploadToAssetCache(update.InventoryData[i].TransactionID);
386 if (asset != null)
387 {
388 //Console.WriteLine("updating inventory item, adding asset" + asset.FullID.ToStringHyphenated() + " to cache");
389 m_inventoryCache.UpdateInventoryItemAsset(this, update.InventoryData[i].ItemID, asset);
390 }
391 else
392 {
393 //Console.WriteLine("trying to update inventory item, but asset is null");
394 }
395 }
396 }
397 else
398 {
399 m_inventoryCache.UpdateInventoryItemDetails(this, update.InventoryData[i].ItemID, update.InventoryData[i]); ;
400 }
401 }
402 break;
403 case PacketType.RequestTaskInventory:
404 // Console.WriteLine(Pack.ToString());
405 RequestTaskInventoryPacket requesttask = (RequestTaskInventoryPacket)Pack;
406 ReplyTaskInventoryPacket replytask = new ReplyTaskInventoryPacket();
407 //bool foundent = false;
408 /* foreach (Entity ent in m_world.Entities.Values)
409 {
410 if (ent.localid == requesttask.InventoryData.LocalID)
411 {
412 replytask.InventoryData.TaskID = ent.uuid;
413 replytask.InventoryData.Serial = 0;
414 replytask.InventoryData.Filename = new byte[0];
415 foundent = true;
416 }
417 }
418 if (foundent)
419 {
420 this.OutPacket(replytask);
421 }*/
422 break;
423 case PacketType.UpdateTaskInventory:
424 // Console.WriteLine(Pack.ToString());
425 UpdateTaskInventoryPacket updatetask = (UpdateTaskInventoryPacket)Pack;
426 AgentInventory myinventory = this.m_inventoryCache.GetAgentsInventory(this.AgentID);
427 /*if (myinventory != null)
428 {
429 if (updatetask.UpdateData.Key == 0)
430 {
431 if (myinventory.InventoryItems[updatetask.InventoryData.ItemID] != null)
432 {
433 if (myinventory.InventoryItems[updatetask.InventoryData.ItemID].Type == 7)
434 {
435 LLUUID noteaid = myinventory.InventoryItems[updatetask.InventoryData.ItemID].AssetID;
436 AssetBase assBase = this.m_assetCache.GetAsset(noteaid);
437 if (assBase != null)
438 {
439 foreach (Entity ent in m_world.Entities.Values)
440 {
441 if (ent.localid == updatetask.UpdateData.LocalID)
442 {
443 if (ent is OpenSim.world.Primitive)
444 {
445 this.m_world.AddScript(ent, Util.FieldToString(assBase.Data));
446 }
447 }
448 }
449 }
450 }
451 }
452 }
453 }*/
454 break;
455 case PacketType.MapLayerRequest:
456 this.RequestMapLayer();
457 break;
458 case PacketType.MapBlockRequest:
459 MapBlockRequestPacket MapRequest = (MapBlockRequestPacket)Pack;
460 if (OnRequestMapBlocks != null)
461 {
462 OnRequestMapBlocks(this, MapRequest.PositionData.MinX, MapRequest.PositionData.MinY, MapRequest.PositionData.MaxX, MapRequest.PositionData.MaxY);
463 }
464 break;
465 case PacketType.TeleportLandmarkRequest:
466 TeleportLandmarkRequestPacket tpReq = (TeleportLandmarkRequestPacket)Pack;
467
468 TeleportStartPacket tpStart = new TeleportStartPacket();
469 tpStart.Info.TeleportFlags = 8; // tp via lm
470 this.OutPacket(tpStart);
471
472 TeleportProgressPacket tpProgress = new TeleportProgressPacket();
473 tpProgress.Info.Message = (new ASCIIEncoding()).GetBytes("sending_landmark");
474 tpProgress.Info.TeleportFlags = 8;
475 tpProgress.AgentData.AgentID = tpReq.Info.AgentID;
476 this.OutPacket(tpProgress);
477
478 // Fetch landmark
479 LLUUID lmid = tpReq.Info.LandmarkID;
480 AssetBase lma = this.m_assetCache.GetAsset(lmid);
481 if (lma != null)
482 {
483 AssetLandmark lm = new AssetLandmark(lma);
484
485 if (lm.RegionID == m_world.RegionInfo.SimUUID)
486 {
487 TeleportLocalPacket tpLocal = new TeleportLocalPacket();
488
489 tpLocal.Info.AgentID = tpReq.Info.AgentID;
490 tpLocal.Info.TeleportFlags = 8; // Teleport via landmark
491 tpLocal.Info.LocationID = 2;
492 tpLocal.Info.Position = lm.Position;
493 OutPacket(tpLocal);
494 }
495 else
496 {
497 TeleportCancelPacket tpCancel = new TeleportCancelPacket();
498 tpCancel.Info.AgentID = tpReq.Info.AgentID;
499 tpCancel.Info.SessionID = tpReq.Info.SessionID;
500 OutPacket(tpCancel);
501 }
502 }
503 else
504 {
505 Console.WriteLine("Cancelling Teleport - fetch asset not yet implemented");
506
507 TeleportCancelPacket tpCancel = new TeleportCancelPacket();
508 tpCancel.Info.AgentID = tpReq.Info.AgentID;
509 tpCancel.Info.SessionID = tpReq.Info.SessionID;
510 OutPacket(tpCancel);
511 }
512 break;
513 case PacketType.TeleportLocationRequest:
514 TeleportLocationRequestPacket tpLocReq = (TeleportLocationRequestPacket)Pack;
515 // Console.WriteLine(tpLocReq.ToString());
516
517 if (OnTeleportLocationRequest != null)
518 {
519 OnTeleportLocationRequest(this, tpLocReq.Info.RegionHandle, tpLocReq.Info.Position, tpLocReq.Info.LookAt, 16);
520 }
521 else
522 {
523 //no event handler so cancel request
524 TeleportCancelPacket tpCancel = new TeleportCancelPacket();
525 tpCancel.Info.SessionID = tpLocReq.AgentData.SessionID;
526 tpCancel.Info.AgentID = tpLocReq.AgentData.AgentID;
527 OutPacket(tpCancel);
528 }
529 break;
530 #endregion
531
532 case PacketType.MoneyBalanceRequest:
533 this.SendMoneyBalance(LLUUID.Zero, true, new byte[0], 1000);
534 break;
535 case PacketType.UUIDNameRequest:
536 UUIDNameRequestPacket incoming = (UUIDNameRequestPacket)Pack;
537 foreach (UUIDNameRequestPacket.UUIDNameBlockBlock UUIDBlock in incoming.UUIDNameBlock)
538 {
539 OnNameFromUUIDRequest(UUIDBlock.ID, this);
540 }
541 break;
542 #region Parcel related packets
543 case PacketType.ParcelPropertiesRequest:
544 ParcelPropertiesRequestPacket propertiesRequest = (ParcelPropertiesRequestPacket)Pack;
545 if (OnParcelPropertiesRequest != null)
546 {
547 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);
548 }
549 break;
550 case PacketType.ParcelDivide:
551 ParcelDividePacket parcelDivide = (ParcelDividePacket)Pack;
552 if (OnParcelDivideRequest != null)
553 {
554 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);
555 }
556 break;
557 case PacketType.ParcelJoin:
558 ParcelJoinPacket parcelJoin = (ParcelJoinPacket)Pack;
559 if (OnParcelJoinRequest != null)
560 {
561 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);
562 }
563 break;
564 case PacketType.ParcelPropertiesUpdate:
565 ParcelPropertiesUpdatePacket updatePacket = (ParcelPropertiesUpdatePacket)Pack;
566 if (OnParcelPropertiesUpdateRequest != null)
567 {
568 OnParcelPropertiesUpdateRequest(updatePacket, this);
569 }
570 break;
571 #endregion
572
573 #region Estate Packets
574 case PacketType.EstateOwnerMessage:
575 EstateOwnerMessagePacket messagePacket = (EstateOwnerMessagePacket)Pack;
576 if (OnEstateOwnerMessage != null)
577 {
578 OnEstateOwnerMessage(messagePacket, this);
579 }
580 break;
581 #endregion
582
583 #region unimplemented handlers
584 case PacketType.AgentIsNowWearing:
585 // AgentIsNowWearingPacket wear = (AgentIsNowWearingPacket)Pack;
586 //Console.WriteLine(Pack.ToString());
587 break;
588 case PacketType.ObjectScale:
589 //OpenSim.Framework.Console.MainLog.Instance.Verbose( Pack.ToString());
590 break;
591 #endregion
592 }
593 }
594 }
595 }
596}
diff --git a/OpenSim/Region/ClientStack/ClientView.cs b/OpenSim/Region/ClientStack/ClientView.cs
new file mode 100644
index 0000000..0fe3884
--- /dev/null
+++ b/OpenSim/Region/ClientStack/ClientView.cs
@@ -0,0 +1,293 @@
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*/
28using System;
29using System.Collections.Generic;
30using System.Net;
31using System.Text;
32using System.Threading;
33using System.Timers;
34using libsecondlife;
35using libsecondlife.Packets;
36using OpenSim.Assets;
37using OpenSim.Framework;
38using OpenSim.Framework.Console;
39using OpenSim.Framework.Interfaces;
40using OpenSim.Framework.Inventory;
41using OpenSim.Framework.Types;
42using OpenSim.Framework.Utilities;
43using OpenSim.Region.Caches;
44using Timer=System.Timers.Timer;
45
46namespace OpenSim.Region.ClientStack
47{
48 public delegate bool PacketMethod(ClientView simClient, Packet packet);
49
50 /// <summary>
51 /// Handles new client connections
52 /// Constructor takes a single Packet and authenticates everything
53 /// </summary>
54 public partial class ClientView : ClientViewBase, IClientAPI
55 {
56 public static TerrainManager TerrainManager;
57
58 protected static Dictionary<PacketType, PacketMethod> PacketHandlers = new Dictionary<PacketType, PacketMethod>(); //Global/static handlers for all clients
59 protected Dictionary<PacketType, PacketMethod> m_packetHandlers = new Dictionary<PacketType, PacketMethod>(); //local handlers for this instance
60
61 public LLUUID AgentID;
62 public LLUUID SessionID;
63 public LLUUID SecureSessionID = LLUUID.Zero;
64 public string firstName;
65 public string lastName;
66 public bool m_child = false;
67 private UseCircuitCodePacket cirpack;
68 public Thread ClientThread;
69 public LLVector3 startpos;
70
71 private AgentAssetUpload UploadAssets;
72 private LLUUID newAssetFolder = LLUUID.Zero;
73 private bool debug = false;
74 protected IWorld m_world;
75 private Dictionary<uint, ClientView> m_clientThreads;
76 private AssetCache m_assetCache;
77 private InventoryCache m_inventoryCache;
78 private int cachedtextureserial = 0;
79 protected AuthenticateSessionsBase m_authenticateSessionsHandler;
80 private Encoding enc = Encoding.ASCII;
81 // Dead client detection vars
82 private Timer clientPingTimer;
83 private int packetsReceived = 0;
84 private int probesWithNoIngressPackets = 0;
85 private int lastPacketsReceived = 0;
86
87 public ClientView(EndPoint remoteEP, UseCircuitCodePacket initialcirpack, Dictionary<uint, ClientView> clientThreads, IWorld world, AssetCache assetCache, PacketServer packServer, InventoryCache inventoryCache, AuthenticateSessionsBase authenSessions )
88 {
89 m_world = world;
90 m_clientThreads = clientThreads;
91 m_assetCache = assetCache;
92
93 m_networkServer = packServer;
94 m_inventoryCache = inventoryCache;
95 m_authenticateSessionsHandler = authenSessions;
96
97 MainLog.Instance.Verbose( "OpenSimClient.cs - Started up new client thread to handle incoming request");
98 cirpack = initialcirpack;
99 userEP = remoteEP;
100
101 this.startpos = m_authenticateSessionsHandler.GetPosition(initialcirpack.CircuitCode.Code);
102
103 PacketQueue = new BlockingQueue<QueItem>();
104
105 this.UploadAssets = new AgentAssetUpload(this, m_assetCache, m_inventoryCache);
106 AckTimer = new Timer(500);
107 AckTimer.Elapsed += new ElapsedEventHandler(AckTimer_Elapsed);
108 AckTimer.Start();
109
110 this.RegisterLocalPacketHandlers();
111
112 ClientThread = new Thread(new ThreadStart(AuthUser));
113 ClientThread.IsBackground = true;
114 ClientThread.Start();
115 }
116
117 # region Client Methods
118
119 public void KillClient()
120 {
121 clientPingTimer.Stop();
122 this.m_inventoryCache.ClientLeaving(this.AgentID, null);
123 m_world.RemoveClient(this.AgentId);
124
125 m_clientThreads.Remove(this.CircuitCode);
126 m_networkServer.RemoveClientCircuit(this.CircuitCode);
127 this.ClientThread.Abort();
128 }
129 #endregion
130
131 # region Packet Handling
132 public static bool AddPacketHandler(PacketType packetType, PacketMethod handler)
133 {
134 bool result = false;
135 lock (PacketHandlers)
136 {
137 if (!PacketHandlers.ContainsKey(packetType))
138 {
139 PacketHandlers.Add(packetType, handler);
140 result = true;
141 }
142 }
143 return result;
144 }
145
146 public bool AddLocalPacketHandler(PacketType packetType, PacketMethod handler)
147 {
148 bool result = false;
149 lock (m_packetHandlers)
150 {
151 if (!m_packetHandlers.ContainsKey(packetType))
152 {
153 m_packetHandlers.Add(packetType, handler);
154 result = true;
155 }
156 }
157 return result;
158 }
159
160 protected virtual bool ProcessPacketMethod(Packet packet)
161 {
162 bool result = false;
163 bool found = false;
164 PacketMethod method;
165 if (m_packetHandlers.TryGetValue(packet.Type, out method))
166 {
167 //there is a local handler for this packet type
168 result = method(this, packet);
169 }
170 else
171 {
172 //there is not a local handler so see if there is a Global handler
173 lock (PacketHandlers)
174 {
175 found = PacketHandlers.TryGetValue(packet.Type, out method);
176 }
177 if (found)
178 {
179 result = method(this, packet);
180 }
181 }
182 return result;
183 }
184
185 protected virtual void ClientLoop()
186 {
187 MainLog.Instance.Verbose( "OpenSimClient.cs:ClientLoop() - Entered loop");
188 while (true)
189 {
190 QueItem nextPacket = PacketQueue.Dequeue();
191 if (nextPacket.Incoming)
192 {
193 //is a incoming packet
194 if (nextPacket.Packet.Type != PacketType.AgentUpdate) {
195 packetsReceived++;
196 }
197 ProcessInPacket(nextPacket.Packet);
198 }
199 else
200 {
201 //is a out going packet
202 ProcessOutPacket(nextPacket.Packet);
203 }
204 }
205 }
206 # endregion
207
208 protected void CheckClientConnectivity(object sender, ElapsedEventArgs e)
209 {
210 if (packetsReceived == lastPacketsReceived) {
211 probesWithNoIngressPackets++;
212 if (probesWithNoIngressPackets > 30) {
213 this.KillClient();
214 } else {
215 // this will normally trigger at least one packet (ping response)
216 SendStartPingCheck(0);
217 }
218 } else {
219 // Something received in the meantime - we can reset the counters
220 probesWithNoIngressPackets = 0;
221 lastPacketsReceived = packetsReceived;
222 }
223 }
224
225 # region Setup
226
227 protected virtual void InitNewClient()
228 {
229 clientPingTimer = new Timer(1000);
230 clientPingTimer.Elapsed += new ElapsedEventHandler(CheckClientConnectivity);
231 clientPingTimer.Enabled = true;
232
233 MainLog.Instance.Verbose( "OpenSimClient.cs:InitNewClient() - Adding viewer agent to world");
234 this.m_world.AddNewClient(this, false);
235 }
236
237 protected virtual void AuthUser()
238 {
239 // AuthenticateResponse sessionInfo = m_gridServer.AuthenticateSession(cirpack.CircuitCode.SessionID, cirpack.CircuitCode.ID, cirpack.CircuitCode.Code);
240 AuthenticateResponse sessionInfo = this.m_authenticateSessionsHandler.AuthenticateSession(cirpack.CircuitCode.SessionID, cirpack.CircuitCode.ID, cirpack.CircuitCode.Code);
241 if (!sessionInfo.Authorised)
242 {
243 //session/circuit not authorised
244 MainLog.Instance.Notice("OpenSimClient.cs:AuthUser() - New user request denied to " + userEP.ToString());
245 ClientThread.Abort();
246 }
247 else
248 {
249 MainLog.Instance.Notice("OpenSimClient.cs:AuthUser() - Got authenticated connection from " + userEP.ToString());
250 //session is authorised
251 this.AgentID = cirpack.CircuitCode.ID;
252 this.SessionID = cirpack.CircuitCode.SessionID;
253 this.CircuitCode = cirpack.CircuitCode.Code;
254 this.firstName = sessionInfo.LoginInfo.First;
255 this.lastName = sessionInfo.LoginInfo.Last;
256
257 if (sessionInfo.LoginInfo.SecureSession != LLUUID.Zero)
258 {
259 this.SecureSessionID = sessionInfo.LoginInfo.SecureSession;
260 }
261 InitNewClient();
262
263 ClientLoop();
264 }
265 }
266 # endregion
267
268
269 protected override void KillThread()
270 {
271 this.ClientThread.Abort();
272 }
273
274 #region Inventory Creation
275 private void SetupInventory(AuthenticateResponse sessionInfo)
276 {
277
278 }
279 private AgentInventory CreateInventory(LLUUID baseFolder)
280 {
281 AgentInventory inventory = null;
282
283 return inventory;
284 }
285
286 private void CreateInventoryItem(CreateInventoryItemPacket packet)
287 {
288
289 }
290 #endregion
291
292 }
293}
diff --git a/OpenSim/Region/ClientStack/ClientViewBase.cs b/OpenSim/Region/ClientStack/ClientViewBase.cs
new file mode 100644
index 0000000..048f4df
--- /dev/null
+++ b/OpenSim/Region/ClientStack/ClientViewBase.cs
@@ -0,0 +1,326 @@
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*/
29using System;
30using System.Collections.Generic;
31using System.Net;
32using System.Net.Sockets;
33using System.Timers;
34using libsecondlife;
35using libsecondlife.Packets;
36using OpenSim.Framework.Console;
37using OpenSim.Framework.Utilities;
38
39namespace OpenSim.Region.ClientStack
40{
41 public class ClientViewBase
42 {
43 protected BlockingQueue<QueItem> PacketQueue;
44 protected Dictionary<uint, uint> PendingAcks = new Dictionary<uint, uint>();
45 protected Dictionary<uint, Packet> NeedAck = new Dictionary<uint, Packet>();
46
47 protected Timer AckTimer;
48 protected uint Sequence = 0;
49 protected object SequenceLock = new object();
50 protected const int MAX_APPENDED_ACKS = 10;
51 protected const int RESEND_TIMEOUT = 4000;
52 protected const int MAX_SEQUENCE = 0xFFFFFF;
53
54 public uint CircuitCode;
55 public EndPoint userEP;
56
57 protected PacketServer m_networkServer;
58
59 public ClientViewBase()
60 {
61
62 }
63
64 protected virtual void ProcessInPacket(Packet Pack)
65 {
66
67 }
68
69 protected virtual void ProcessOutPacket(Packet Pack)
70 {
71 // Keep track of when this packet was sent out
72 Pack.TickCount = Environment.TickCount;
73
74 Console.WriteLine(CircuitCode + ":OUT: " + Pack.Type.ToString());
75
76 if (!Pack.Header.Resent)
77 {
78 // Set the sequence number
79 lock (SequenceLock)
80 {
81 if (Sequence >= MAX_SEQUENCE)
82 Sequence = 1;
83 else
84 Sequence++;
85 Pack.Header.Sequence = Sequence;
86 }
87
88 if (Pack.Header.Reliable) //DIRTY HACK
89 {
90 lock (NeedAck)
91 {
92 if (!NeedAck.ContainsKey(Pack.Header.Sequence))
93 {
94 try
95 {
96 NeedAck.Add(Pack.Header.Sequence, Pack);
97 }
98 catch (Exception e) // HACKY
99 {
100 e.ToString();
101 // Ignore
102 // Seems to throw a exception here occasionally
103 // of 'duplicate key' despite being locked.
104 // !?!?!?
105 }
106 }
107 else
108 {
109 // Client.Log("Attempted to add a duplicate sequence number (" +
110 // packet.Header.Sequence + ") to the NeedAck dictionary for packet type " +
111 // packet.Type.ToString(), Helpers.LogLevel.Warning);
112 }
113 }
114
115 // Don't append ACKs to resent packets, in case that's what was causing the
116 // delivery to fail
117 if (!Pack.Header.Resent)
118 {
119 // Append any ACKs that need to be sent out to this packet
120 lock (PendingAcks)
121 {
122 if (PendingAcks.Count > 0 && PendingAcks.Count < MAX_APPENDED_ACKS &&
123 Pack.Type != PacketType.PacketAck &&
124 Pack.Type != PacketType.LogoutRequest)
125 {
126 Pack.Header.AckList = new uint[PendingAcks.Count];
127 int i = 0;
128
129 foreach (uint ack in PendingAcks.Values)
130 {
131 Pack.Header.AckList[i] = ack;
132 i++;
133 }
134
135 PendingAcks.Clear();
136 Pack.Header.AppendedAcks = true;
137 }
138 }
139 }
140 }
141 }
142
143 byte[] ZeroOutBuffer = new byte[4096];
144 byte[] sendbuffer;
145 sendbuffer = Pack.ToBytes();
146
147 try
148 {
149 if (Pack.Header.Zerocoded)
150 {
151 int packetsize = Helpers.ZeroEncode(sendbuffer, sendbuffer.Length, ZeroOutBuffer);
152 m_networkServer.SendPacketTo(ZeroOutBuffer, packetsize, SocketFlags.None, CircuitCode);//userEP);
153 }
154 else
155 {
156 m_networkServer.SendPacketTo(sendbuffer, sendbuffer.Length, SocketFlags.None, CircuitCode); //userEP);
157 }
158 }
159 catch (Exception)
160 {
161 MainLog.Instance.Warn("OpenSimClient.cs:ProcessOutPacket() - WARNING: Socket exception occurred on connection " + userEP.ToString() + " - killing thread");
162 this.KillThread();
163 }
164
165 }
166
167 public virtual void InPacket(Packet NewPack)
168 {
169 // Handle appended ACKs
170 if (NewPack.Header.AppendedAcks)
171 {
172 lock (NeedAck)
173 {
174 foreach (uint ack in NewPack.Header.AckList)
175 {
176 NeedAck.Remove(ack);
177 }
178 }
179 }
180
181 // Handle PacketAck packets
182 if (NewPack.Type == PacketType.PacketAck)
183 {
184 PacketAckPacket ackPacket = (PacketAckPacket)NewPack;
185
186 lock (NeedAck)
187 {
188 foreach (PacketAckPacket.PacketsBlock block in ackPacket.Packets)
189 {
190 NeedAck.Remove(block.ID);
191 }
192 }
193 }
194 else if ((NewPack.Type == PacketType.StartPingCheck))
195 {
196 //reply to pingcheck
197 StartPingCheckPacket startPing = (StartPingCheckPacket)NewPack;
198 CompletePingCheckPacket endPing = new CompletePingCheckPacket();
199 endPing.PingID.PingID = startPing.PingID.PingID;
200 OutPacket(endPing);
201 }
202 else
203 {
204 QueItem item = new QueItem();
205 item.Packet = NewPack;
206 item.Incoming = true;
207 this.PacketQueue.Enqueue(item);
208 }
209
210 }
211
212 public virtual void OutPacket(Packet NewPack)
213 {
214 QueItem item = new QueItem();
215 item.Packet = NewPack;
216 item.Incoming = false;
217 this.PacketQueue.Enqueue(item);
218 }
219
220 # region Low Level Packet Methods
221
222 protected void ack_pack(Packet Pack)
223 {
224 if (Pack.Header.Reliable)
225 {
226 PacketAckPacket ack_it = new PacketAckPacket();
227 ack_it.Packets = new PacketAckPacket.PacketsBlock[1];
228 ack_it.Packets[0] = new PacketAckPacket.PacketsBlock();
229 ack_it.Packets[0].ID = Pack.Header.Sequence;
230 ack_it.Header.Reliable = false;
231
232 OutPacket(ack_it);
233
234 }
235 /*
236 if (Pack.Header.Reliable)
237 {
238 lock (PendingAcks)
239 {
240 uint sequence = (uint)Pack.Header.Sequence;
241 if (!PendingAcks.ContainsKey(sequence)) { PendingAcks[sequence] = sequence; }
242 }
243 }*/
244 }
245
246 protected void ResendUnacked()
247 {
248 int now = Environment.TickCount;
249
250 lock (NeedAck)
251 {
252 foreach (Packet packet in NeedAck.Values)
253 {
254 if ((now - packet.TickCount > RESEND_TIMEOUT) && (!packet.Header.Resent))
255 {
256 MainLog.Instance.Verbose( "Resending " + packet.Type.ToString() + " packet, " +
257 (now - packet.TickCount) + "ms have passed");
258
259 packet.Header.Resent = true;
260 OutPacket(packet);
261 }
262 }
263 }
264 }
265
266 protected void SendAcks()
267 {
268 lock (PendingAcks)
269 {
270 if (PendingAcks.Count > 0)
271 {
272 if (PendingAcks.Count > 250)
273 {
274 // FIXME: Handle the odd case where we have too many pending ACKs queued up
275 MainLog.Instance.Verbose( "Too many ACKs queued up!");
276 return;
277 }
278
279 //OpenSim.Framework.Console.MainLog.Instance.WriteLine("Sending PacketAck");
280
281
282 int i = 0;
283 PacketAckPacket acks = new PacketAckPacket();
284 acks.Packets = new PacketAckPacket.PacketsBlock[PendingAcks.Count];
285
286 foreach (uint ack in PendingAcks.Values)
287 {
288 acks.Packets[i] = new PacketAckPacket.PacketsBlock();
289 acks.Packets[i].ID = ack;
290 i++;
291 }
292
293 acks.Header.Reliable = false;
294 OutPacket(acks);
295
296 PendingAcks.Clear();
297 }
298 }
299 }
300
301 protected void AckTimer_Elapsed(object sender, ElapsedEventArgs ea)
302 {
303 SendAcks();
304 ResendUnacked();
305 }
306 #endregion
307
308 protected virtual void KillThread()
309 {
310
311 }
312
313 #region Nested Classes
314
315 public class QueItem
316 {
317 public QueItem()
318 {
319 }
320
321 public Packet Packet;
322 public bool Incoming;
323 }
324 #endregion
325 }
326}
diff --git a/OpenSim/Region/ClientStack/PacketServer.cs b/OpenSim/Region/ClientStack/PacketServer.cs
new file mode 100644
index 0000000..a88c682
--- /dev/null
+++ b/OpenSim/Region/ClientStack/PacketServer.cs
@@ -0,0 +1,184 @@
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*/
28using System.Collections.Generic;
29using System.Net;
30using System.Net.Sockets;
31using libsecondlife.Packets;
32using OpenSim.Assets;
33using OpenSim.Framework;
34using OpenSim.Framework.Interfaces;
35using OpenSim.Region.Caches;
36
37namespace OpenSim.Region.ClientStack
38{
39 public class PacketServer
40 {
41 private ClientStackNetworkHandler _networkHandler;
42 private IWorld _localWorld;
43 public Dictionary<uint, ClientView> ClientThreads = new Dictionary<uint, ClientView>();
44 private ClientManager m_clientManager = new ClientManager();
45 public ClientManager ClientManager
46 {
47 get { return m_clientManager; }
48 }
49
50 public PacketServer(ClientStackNetworkHandler networkHandler)
51 {
52 _networkHandler = networkHandler;
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.m_clientManager.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 this.m_clientManager.Remove(circuitcode);
182 }
183 }
184}
diff --git a/OpenSim/Region/ClientStack/RegionApplicationBase.cs b/OpenSim/Region/ClientStack/RegionApplicationBase.cs
new file mode 100644
index 0000000..1e99c71
--- /dev/null
+++ b/OpenSim/Region/ClientStack/RegionApplicationBase.cs
@@ -0,0 +1,117 @@
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*/
28using System;
29using System.Collections.Generic;
30using System.Net;
31using OpenSim.Assets;
32using OpenSim.Framework;
33using OpenSim.Framework.Console;
34using OpenSim.Framework.Interfaces;
35using OpenSim.Framework.Servers;
36using OpenSim.Framework.Types;
37using OpenSim.Physics.Manager;
38using OpenSim.Region.Caches;
39
40namespace OpenSim.Region.ClientStack
41{
42 public class RegionApplicationBase
43 {
44 protected IGenericConfig localConfig;
45 protected PhysicsManager physManager;
46 protected AssetCache AssetCache;
47 protected InventoryCache InventoryCache;
48 protected Dictionary<EndPoint, uint> clientCircuits = new Dictionary<EndPoint, uint>();
49 protected DateTime startuptime;
50 protected NetworkServersInfo serversData;
51
52 public string m_physicsEngine;
53 public bool m_sandbox = false;
54 public bool m_loginserver;
55 public bool user_accounts = false;
56 public bool gridLocalAsset = false;
57 protected bool configFileSetup = false;
58 public string m_config;
59
60 protected List<UDPServer> m_udpServer = new List<UDPServer>();
61 protected List<RegionInfo> regionData = new List<RegionInfo>();
62 protected List<IWorld> m_localWorld = new List<IWorld>();
63 protected BaseHttpServer httpServer;
64 protected List<AuthenticateSessionsBase> AuthenticateSessionsHandler = new List<AuthenticateSessionsBase>();
65
66 protected LogBase m_log;
67
68 public RegionApplicationBase()
69 {
70
71 }
72
73 public RegionApplicationBase(bool sandBoxMode, bool startLoginServer, string physicsEngine, bool useConfigFile, bool silent, string configFile)
74 {
75 this.configFileSetup = useConfigFile;
76 m_sandbox = sandBoxMode;
77 m_loginserver = startLoginServer;
78 m_physicsEngine = physicsEngine;
79 m_config = configFile;
80 }
81
82 /*protected World m_localWorld;
83 public World LocalWorld
84 {
85 get { return m_localWorld; }
86 }*/
87
88 /// <summary>
89 /// Performs initialisation of the world, such as loading configuration from disk.
90 /// </summary>
91 public virtual void StartUp()
92 {
93 }
94
95 protected virtual void SetupLocalGridServers()
96 {
97 }
98
99 protected virtual void SetupRemoteGridServers()
100 {
101
102 }
103
104 protected virtual void SetupWorld()
105 {
106 }
107
108 protected virtual void SetupHttpListener()
109 {
110 }
111
112 protected virtual void ConnectToRemoteGridServer()
113 {
114
115 }
116 }
117}
diff --git a/OpenSim/Region/ClientStack/UDPServer.cs b/OpenSim/Region/ClientStack/UDPServer.cs
new file mode 100644
index 0000000..6eea524
--- /dev/null
+++ b/OpenSim/Region/ClientStack/UDPServer.cs
@@ -0,0 +1,196 @@
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*/
28using System;
29using System.Collections.Generic;
30using System.Net;
31using System.Net.Sockets;
32using libsecondlife.Packets;
33using OpenSim.Assets;
34using OpenSim.Framework;
35using OpenSim.Framework.Console;
36using OpenSim.Framework.Interfaces;
37using OpenSim.Region.Caches;
38
39namespace OpenSim.Region.ClientStack
40{
41
42 public class UDPServer : ClientStackNetworkHandler
43 {
44 protected Dictionary<EndPoint, uint> clientCircuits = new Dictionary<EndPoint, uint>();
45 public Socket Server;
46 protected IPEndPoint ServerIncoming;
47 protected byte[] RecvBuffer = new byte[4096];
48 protected byte[] ZeroBuffer = new byte[8192];
49 protected IPEndPoint ipeSender;
50 protected EndPoint epSender;
51 protected AsyncCallback ReceivedData;
52 protected PacketServer _packetServer;
53
54 protected int listenPort;
55 protected IWorld m_localWorld;
56 protected AssetCache m_assetCache;
57 protected InventoryCache m_inventoryCache;
58 protected LogBase m_log;
59 protected AuthenticateSessionsBase m_authenticateSessionsClass;
60
61 public PacketServer PacketServer
62 {
63 get
64 {
65 return _packetServer;
66 }
67 set
68 {
69 _packetServer = value;
70 }
71 }
72
73 public IWorld LocalWorld
74 {
75 set
76 {
77 this.m_localWorld = value;
78 this._packetServer.LocalWorld = this.m_localWorld;
79 }
80 }
81
82 public UDPServer()
83 {
84 }
85
86 public UDPServer(int port, AssetCache assetCache, InventoryCache inventoryCache, LogBase console, AuthenticateSessionsBase authenticateClass)
87 {
88 listenPort = port;
89 this.m_assetCache = assetCache;
90 this.m_inventoryCache = inventoryCache;
91 this.m_log = console;
92 this.m_authenticateSessionsClass = authenticateClass;
93 this.CreatePacketServer();
94
95 }
96
97 protected virtual void CreatePacketServer()
98 {
99 PacketServer packetServer = new PacketServer(this);
100 }
101
102 protected virtual void OnReceivedData(IAsyncResult result)
103 {
104 ipeSender = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 0);
105 epSender = (EndPoint)ipeSender;
106 Packet packet = null;
107 int numBytes = Server.EndReceiveFrom(result, ref epSender);
108 int packetEnd = numBytes - 1;
109
110 packet = Packet.BuildPacket(RecvBuffer, ref packetEnd, ZeroBuffer);
111
112 // do we already have a circuit for this endpoint
113 if (this.clientCircuits.ContainsKey(epSender))
114 {
115 //if so then send packet to the packetserver
116 this._packetServer.ClientInPacket(this.clientCircuits[epSender], packet);
117 }
118 else if (packet.Type == PacketType.UseCircuitCode)
119 {
120 // new client
121 this.AddNewClient(packet);
122 }
123 else
124 { // invalid client
125 m_log.Warn("UDPServer.cs:OnReceivedData() - WARNING: Got a packet from an invalid client - " + epSender.ToString());
126 }
127
128 Server.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender, ReceivedData, null);
129 }
130
131 protected virtual void AddNewClient(Packet packet)
132 {
133 UseCircuitCodePacket useCircuit = (UseCircuitCodePacket)packet;
134 this.clientCircuits.Add(epSender, useCircuit.CircuitCode.Code);
135
136 this.PacketServer.AddNewClient(epSender, useCircuit, m_assetCache, m_inventoryCache, m_authenticateSessionsClass);
137 }
138
139 public void ServerListener()
140 {
141 m_log.Status("UDPServer.cs:ServerListener() - Opening UDP socket on " + listenPort);
142
143 ServerIncoming = new IPEndPoint(IPAddress.Parse("0.0.0.0"), listenPort);
144 Server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
145 Server.Bind(ServerIncoming);
146
147 m_log.Verbose("UDPServer.cs:ServerListener() - UDP socket bound, getting ready to listen");
148
149 ipeSender = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 0);
150 epSender = (EndPoint)ipeSender;
151 ReceivedData = new AsyncCallback(this.OnReceivedData);
152 Server.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender, ReceivedData, null);
153
154 m_log.Verbose("UDPServer.cs:ServerListener() - Listening...");
155
156 }
157
158 public virtual void RegisterPacketServer(PacketServer server)
159 {
160 this._packetServer = server;
161 }
162
163 public virtual void SendPacketTo(byte[] buffer, int size, SocketFlags flags, uint circuitcode)//EndPoint packetSender)
164 {
165 // find the endpoint for this circuit
166 EndPoint sendto = null;
167 foreach (KeyValuePair<EndPoint, uint> p in this.clientCircuits)
168 {
169 if (p.Value == circuitcode)
170 {
171 sendto = p.Key;
172 break;
173 }
174 }
175 if (sendto != null)
176 {
177 //we found the endpoint so send the packet to it
178 this.Server.SendTo(buffer, size, flags, sendto);
179 }
180 }
181
182 public virtual void RemoveClientCircuit(uint circuitcode)
183 {
184 foreach (KeyValuePair<EndPoint, uint> p in this.clientCircuits)
185 {
186 if (p.Value == circuitcode)
187 {
188 this.clientCircuits.Remove(p.Key);
189 break;
190 }
191 }
192 }
193
194
195 }
196} \ No newline at end of file