aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorSean Dague2007-11-28 13:33:57 +0000
committerSean Dague2007-11-28 13:33:57 +0000
commit5fb81ab881adedb139369ef0bad19a80453ea129 (patch)
treecbb8f832b90f809457b2d4a9ded0b9b3a508b4f7
parentMoved the m_sceneGridService.RegisterRegion(RegionInfo); call out of LoadWorl... (diff)
downloadopensim-SC_OLD-5fb81ab881adedb139369ef0bad19a80453ea129.zip
opensim-SC_OLD-5fb81ab881adedb139369ef0bad19a80453ea129.tar.gz
opensim-SC_OLD-5fb81ab881adedb139369ef0bad19a80453ea129.tar.bz2
opensim-SC_OLD-5fb81ab881adedb139369ef0bad19a80453ea129.tar.xz
merged ClientView into a non partial class. Will
make it easier to start breaking this up into more discreet functional classes
-rw-r--r--OpenSim/Region/ClientStack/ClientView.API.cs1442
-rw-r--r--OpenSim/Region/ClientStack/ClientView.PacketHandlers.cs257
-rw-r--r--OpenSim/Region/ClientStack/ClientView.PacketQueue.cs373
-rw-r--r--OpenSim/Region/ClientStack/ClientView.ProcessPackets.cs1173
-rw-r--r--OpenSim/Region/ClientStack/ClientView.cs3091
5 files changed, 3090 insertions, 3246 deletions
diff --git a/OpenSim/Region/ClientStack/ClientView.API.cs b/OpenSim/Region/ClientStack/ClientView.API.cs
deleted file mode 100644
index 25d23be..0000000
--- a/OpenSim/Region/ClientStack/ClientView.API.cs
+++ /dev/null
@@ -1,1442 +0,0 @@
1/*
2* Copyright (c) Contributors, http://opensimulator.org/
3* See CONTRIBUTORS.TXT for a full list of copyright holders.
4*
5* Redistribution and use in source and binary forms, with or without
6* modification, are permitted provided that the following conditions are met:
7* * Redistributions of source code must retain the above copyright
8* notice, this list of conditions and the following disclaimer.
9* * Redistributions in binary form must reproduce the above copyright
10* notice, this list of conditions and the following disclaimer in the
11* documentation and/or other materials provided with the distribution.
12* * Neither the name of the OpenSim Project nor the
13* names of its contributors may be used to endorse or promote products
14* derived from this software without specific prior written permission.
15*
16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY
17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*
27*/
28using System;
29using System.Collections.Generic;
30using System.Net;
31using System.Text;
32using Axiom.Math;
33using libsecondlife;
34using libsecondlife.Packets;
35using OpenSim.Framework;
36using OpenSim.Framework.Console;
37
38namespace OpenSim.Region.ClientStack
39{
40 partial class ClientView
41 {
42 public event Action<IClientAPI> OnLogout;
43 public event Action<IClientAPI> OnConnectionClosed;
44 public event ViewerEffectEventHandler OnViewerEffect;
45 public event ImprovedInstantMessage OnInstantMessage;
46 public event ChatFromViewer OnChatFromViewer;
47 public event TextureRequest OnRequestTexture;
48 public event RezObject OnRezObject;
49 public event GenericCall4 OnDeRezObject;
50 public event ModifyTerrain OnModifyTerrain;
51 public event Action<IClientAPI> OnRegionHandShakeReply;
52 public event GenericCall2 OnRequestWearables;
53 public event SetAppearance OnSetAppearance;
54 public event GenericCall2 OnCompleteMovementToRegion;
55 public event UpdateAgent OnAgentUpdate;
56 public event AgentRequestSit OnAgentRequestSit;
57 public event AgentSit OnAgentSit;
58 public event AvatarPickerRequest OnAvatarPickerRequest;
59 public event StartAnim OnStartAnim;
60 public event Action<IClientAPI> OnRequestAvatarsData;
61 public event LinkObjects OnLinkObjects;
62 public event DelinkObjects OnDelinkObjects;
63 public event UpdateVector OnGrabObject;
64 public event ObjectSelect OnDeGrabObject;
65 public event ObjectDuplicate OnObjectDuplicate;
66 public event MoveObject OnGrabUpdate;
67 public event AddNewPrim OnAddPrim;
68 public event RequestGodlikePowers OnRequestGodlikePowers;
69 public event GodKickUser OnGodKickUser;
70 public event ObjectExtraParams OnUpdateExtraParams;
71 public event UpdateShape OnUpdatePrimShape;
72 public event ObjectSelect OnObjectSelect;
73 public event ObjectDeselect OnObjectDeselect;
74 public event GenericCall7 OnObjectDescription;
75 public event GenericCall7 OnObjectName;
76 public event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily;
77 public event UpdatePrimFlags OnUpdatePrimFlags;
78 public event UpdatePrimTexture OnUpdatePrimTexture;
79 public event UpdateVector OnUpdatePrimGroupPosition;
80 public event UpdateVector OnUpdatePrimSinglePosition;
81 public event UpdatePrimRotation OnUpdatePrimGroupRotation;
82 public event UpdatePrimSingleRotation OnUpdatePrimSingleRotation;
83 public event UpdatePrimGroupRotation OnUpdatePrimGroupMouseRotation;
84 public event UpdateVector OnUpdatePrimScale;
85 public event StatusChange OnChildAgentStatus;
86 public event GenericCall2 OnStopMovement;
87 public event Action<LLUUID> OnRemoveAvatar;
88 public event RequestMapBlocks OnRequestMapBlocks;
89 public event RequestMapName OnMapNameRequest;
90 public event TeleportLocationRequest OnTeleportLocationRequest;
91 public event DisconnectUser OnDisconnectUser;
92 public event RequestAvatarProperties OnRequestAvatarProperties;
93 public event SetAlwaysRun OnSetAlwaysRun;
94
95 public event CreateNewInventoryItem OnCreateNewInventoryItem;
96 public event CreateInventoryFolder OnCreateNewInventoryFolder;
97 public event FetchInventoryDescendents OnFetchInventoryDescendents;
98 public event FetchInventory OnFetchInventory;
99 public event RequestTaskInventory OnRequestTaskInventory;
100 public event UpdateInventoryItemTransaction OnUpdateInventoryItem;
101 public event CopyInventoryItem OnCopyInventoryItem;
102 public event UDPAssetUploadRequest OnAssetUploadRequest;
103 public event XferReceive OnXferReceive;
104 public event RequestXfer OnRequestXfer;
105 public event ConfirmXfer OnConfirmXfer;
106 public event RezScript OnRezScript;
107 public event UpdateTaskInventory OnUpdateTaskInventory;
108 public event RemoveTaskInventory OnRemoveTaskItem;
109
110 public event UUIDNameRequest OnNameFromUUIDRequest;
111
112 public event ParcelPropertiesRequest OnParcelPropertiesRequest;
113 public event ParcelDivideRequest OnParcelDivideRequest;
114 public event ParcelJoinRequest OnParcelJoinRequest;
115 public event ParcelPropertiesUpdateRequest OnParcelPropertiesUpdateRequest;
116 public event ParcelSelectObjects OnParcelSelectObjects;
117 public event ParcelObjectOwnerRequest OnParcelObjectOwnerRequest;
118 public event EstateOwnerMessageRequest OnEstateOwnerMessage;
119
120 /// <summary>
121 ///
122 /// </summary>
123 public LLVector3 StartPos
124 {
125 get { return startpos; }
126 set { startpos = value; }
127 }
128
129 /// <summary>
130 ///
131 /// </summary>
132 private LLUUID m_agentId;
133
134 public LLUUID AgentId
135 {
136 get { return m_agentId; }
137 }
138
139 /// <summary>
140 ///
141 /// </summary>
142 public string FirstName
143 {
144 get { return firstName; }
145 }
146
147 /// <summary>
148 ///
149 /// </summary>
150 public string LastName
151 {
152 get { return lastName; }
153 }
154
155 #region Scene/Avatar to Client
156
157 /// <summary>
158 ///
159 /// </summary>
160 /// <param name="regionInfo"></param>
161 public void SendRegionHandshake(RegionInfo regionInfo)
162 {
163 Encoding _enc = Encoding.ASCII;
164 RegionHandshakePacket handshake = new RegionHandshakePacket();
165
166 handshake.RegionInfo.BillableFactor = regionInfo.EstateSettings.billableFactor;
167 handshake.RegionInfo.IsEstateManager = false;
168 handshake.RegionInfo.TerrainHeightRange00 = regionInfo.EstateSettings.terrainHeightRange0;
169 handshake.RegionInfo.TerrainHeightRange01 = regionInfo.EstateSettings.terrainHeightRange1;
170 handshake.RegionInfo.TerrainHeightRange10 = regionInfo.EstateSettings.terrainHeightRange2;
171 handshake.RegionInfo.TerrainHeightRange11 = regionInfo.EstateSettings.terrainHeightRange3;
172 handshake.RegionInfo.TerrainStartHeight00 = regionInfo.EstateSettings.terrainStartHeight0;
173 handshake.RegionInfo.TerrainStartHeight01 = regionInfo.EstateSettings.terrainStartHeight1;
174 handshake.RegionInfo.TerrainStartHeight10 = regionInfo.EstateSettings.terrainStartHeight2;
175 handshake.RegionInfo.TerrainStartHeight11 = regionInfo.EstateSettings.terrainStartHeight3;
176 handshake.RegionInfo.SimAccess = (byte) regionInfo.EstateSettings.simAccess;
177 handshake.RegionInfo.WaterHeight = regionInfo.EstateSettings.waterHeight;
178
179
180 handshake.RegionInfo.RegionFlags = (uint) regionInfo.EstateSettings.regionFlags;
181
182 handshake.RegionInfo.SimName = _enc.GetBytes(regionInfo.RegionName + "\0");
183 handshake.RegionInfo.SimOwner = regionInfo.MasterAvatarAssignedUUID;
184 handshake.RegionInfo.TerrainBase0 = regionInfo.EstateSettings.terrainBase0;
185 handshake.RegionInfo.TerrainBase1 = regionInfo.EstateSettings.terrainBase1;
186 handshake.RegionInfo.TerrainBase2 = regionInfo.EstateSettings.terrainBase2;
187 handshake.RegionInfo.TerrainBase3 = regionInfo.EstateSettings.terrainBase3;
188 handshake.RegionInfo.TerrainDetail0 = regionInfo.EstateSettings.terrainDetail0;
189 handshake.RegionInfo.TerrainDetail1 = regionInfo.EstateSettings.terrainDetail1;
190 handshake.RegionInfo.TerrainDetail2 = regionInfo.EstateSettings.terrainDetail2;
191 handshake.RegionInfo.TerrainDetail3 = regionInfo.EstateSettings.terrainDetail3;
192 handshake.RegionInfo.CacheID = LLUUID.Random(); //I guess this is for the client to remember an old setting?
193
194 OutPacket(handshake, ThrottleOutPacketType.Task);
195 }
196
197 /// <summary>
198 ///
199 /// </summary>
200 /// <param name="regInfo"></param>
201 public void MoveAgentIntoRegion(RegionInfo regInfo, LLVector3 pos, LLVector3 look)
202 {
203 AgentMovementCompletePacket mov = new AgentMovementCompletePacket();
204 mov.AgentData.SessionID = m_sessionId;
205 mov.AgentData.AgentID = AgentId;
206 mov.Data.RegionHandle = regInfo.RegionHandle;
207 mov.Data.Timestamp = 1172750370; // TODO - dynamicalise this
208
209 if ((pos.X == 0) && (pos.Y == 0) && (pos.Z == 0))
210 {
211 mov.Data.Position = startpos;
212 }
213 else
214 {
215 mov.Data.Position = pos;
216 }
217 mov.Data.LookAt = look;
218
219 OutPacket(mov, ThrottleOutPacketType.Task);
220 }
221
222 /// <summary>
223 ///
224 /// </summary>
225 /// <param name="message"></param>
226 /// <param name="type"></param>
227 /// <param name="fromPos"></param>
228 /// <param name="fromName"></param>
229 /// <param name="fromAgentID"></param>
230 public void SendChatMessage(string message, byte type, LLVector3 fromPos, string fromName, LLUUID fromAgentID)
231 {
232 SendChatMessage(Helpers.StringToField(message), type, fromPos, fromName, fromAgentID);
233 }
234
235
236 public void SendChatMessage(byte[] message, byte type, LLVector3 fromPos, string fromName, LLUUID fromAgentID)
237 {
238 Encoding enc = Encoding.ASCII;
239 ChatFromSimulatorPacket reply = new ChatFromSimulatorPacket();
240 reply.ChatData.Audible = 1;
241 reply.ChatData.Message = message;
242 reply.ChatData.ChatType = type;
243 reply.ChatData.SourceType = 1;
244 reply.ChatData.Position = fromPos;
245 reply.ChatData.FromName = enc.GetBytes(fromName + "\0");
246 reply.ChatData.OwnerID = fromAgentID;
247 reply.ChatData.SourceID = fromAgentID;
248
249 OutPacket(reply, ThrottleOutPacketType.Task);
250 }
251
252 /// <summary>
253 ///
254 /// </summary>
255 /// <remarks>TODO</remarks>
256 /// <param name="message"></param>
257 /// <param name="target"></param>
258 public void SendInstantMessage(LLUUID fromAgent, LLUUID fromAgentSession, string message, LLUUID toAgent,
259 LLUUID imSessionID, string fromName, byte dialog, uint timeStamp)
260 {
261 Encoding enc = Encoding.ASCII;
262 Encoding encUTF8 = Encoding.UTF8;
263 ImprovedInstantMessagePacket msg = new ImprovedInstantMessagePacket();
264 msg.AgentData.AgentID = fromAgent;
265 msg.AgentData.SessionID = fromAgentSession;
266 msg.MessageBlock.FromAgentName = enc.GetBytes(fromName + " \0");
267 msg.MessageBlock.Dialog = dialog;
268 msg.MessageBlock.FromGroup = false;
269 msg.MessageBlock.ID = imSessionID;
270 msg.MessageBlock.Offline = 0;
271 msg.MessageBlock.ParentEstateID = 0;
272 msg.MessageBlock.Position = new LLVector3();
273 msg.MessageBlock.RegionID = LLUUID.Random();
274 msg.MessageBlock.Timestamp = timeStamp;
275 msg.MessageBlock.ToAgentID = toAgent;
276 msg.MessageBlock.Message = encUTF8.GetBytes(message + "\0");
277 msg.MessageBlock.BinaryBucket = new byte[0];
278
279 OutPacket(msg, ThrottleOutPacketType.Task);
280 }
281
282 /// <summary>
283 /// Send the region heightmap to the client
284 /// </summary>
285 /// <param name="map">heightmap</param>
286 public virtual void SendLayerData(float[] map)
287 {
288 try
289 {
290 int[] patches = new int[4];
291
292 for (int y = 0; y < 16; y++)
293 {
294 for (int x = 0; x < 16; x = x + 4)
295 {
296 patches[0] = x + 0 + y*16;
297 patches[1] = x + 1 + y*16;
298 patches[2] = x + 2 + y*16;
299 patches[3] = x + 3 + y*16;
300
301 Packet layerpack = TerrainManager.CreateLandPacket(map, patches);
302 OutPacket(layerpack, ThrottleOutPacketType.Land);
303 }
304 }
305 }
306 catch (Exception e)
307 {
308 MainLog.Instance.Warn("client",
309 "ClientView.API.cs: SendLayerData() - Failed with exception " + e.ToString());
310 }
311 }
312
313 /// <summary>
314 /// Sends a specified patch to a client
315 /// </summary>
316 /// <param name="px">Patch coordinate (x) 0..16</param>
317 /// <param name="py">Patch coordinate (y) 0..16</param>
318 /// <param name="map">heightmap</param>
319 public void SendLayerData(int px, int py, float[] map)
320 {
321 try
322 {
323 int[] patches = new int[1];
324 int patchx, patchy;
325 patchx = px;
326 patchy = py;
327
328 patches[0] = patchx + 0 + patchy*16;
329
330 Packet layerpack = TerrainManager.CreateLandPacket(map, patches);
331 OutPacket(layerpack, ThrottleOutPacketType.Land);
332 }
333 catch (Exception e)
334 {
335 MainLog.Instance.Warn("client",
336 "ClientView.API.cs: SendLayerData() - Failed with exception " + e.ToString());
337 }
338 }
339
340 /// <summary>
341 ///
342 /// </summary>
343 /// <param name="neighbourHandle"></param>
344 /// <param name="neighbourIP"></param>
345 /// <param name="neighbourPort"></param>
346 public void InformClientOfNeighbour(ulong neighbourHandle, IPEndPoint neighbourEndPoint)
347 {
348 IPAddress neighbourIP = neighbourEndPoint.Address;
349 ushort neighbourPort = (ushort) neighbourEndPoint.Port;
350
351 EnableSimulatorPacket enablesimpacket = new EnableSimulatorPacket();
352 enablesimpacket.SimulatorInfo = new EnableSimulatorPacket.SimulatorInfoBlock();
353 enablesimpacket.SimulatorInfo.Handle = neighbourHandle;
354
355 byte[] byteIP = neighbourIP.GetAddressBytes();
356 enablesimpacket.SimulatorInfo.IP = (uint) byteIP[3] << 24;
357 enablesimpacket.SimulatorInfo.IP += (uint) byteIP[2] << 16;
358 enablesimpacket.SimulatorInfo.IP += (uint) byteIP[1] << 8;
359 enablesimpacket.SimulatorInfo.IP += (uint) byteIP[0];
360 enablesimpacket.SimulatorInfo.Port = neighbourPort;
361 OutPacket(enablesimpacket, ThrottleOutPacketType.Task);
362 }
363
364 /// <summary>
365 ///
366 /// </summary>
367 /// <returns></returns>
368 public AgentCircuitData RequestClientInfo()
369 {
370 AgentCircuitData agentData = new AgentCircuitData();
371 agentData.AgentID = AgentId;
372 agentData.SessionID = m_sessionId;
373 agentData.SecureSessionID = SecureSessionID;
374 agentData.circuitcode = m_circuitCode;
375 agentData.child = false;
376 agentData.firstname = firstName;
377 agentData.lastname = lastName;
378 agentData.CapsPath = "";
379 return agentData;
380 }
381
382 public void CrossRegion(ulong newRegionHandle, LLVector3 pos, LLVector3 lookAt, IPEndPoint externalIPEndPoint,
383 string capsURL)
384 {
385 LLVector3 look = new LLVector3(lookAt.X*10, lookAt.Y*10, lookAt.Z*10);
386
387 CrossedRegionPacket newSimPack = new CrossedRegionPacket();
388 newSimPack.AgentData = new CrossedRegionPacket.AgentDataBlock();
389 newSimPack.AgentData.AgentID = AgentId;
390 newSimPack.AgentData.SessionID = m_sessionId;
391 newSimPack.Info = new CrossedRegionPacket.InfoBlock();
392 newSimPack.Info.Position = pos;
393 newSimPack.Info.LookAt = look;
394 // new LLVector3(0.0f, 0.0f, 0.0f); // copied from Avatar.cs - SHOULD BE DYNAMIC!!!!!!!!!!
395 newSimPack.RegionData = new CrossedRegionPacket.RegionDataBlock();
396 newSimPack.RegionData.RegionHandle = newRegionHandle;
397 byte[] byteIP = externalIPEndPoint.Address.GetAddressBytes();
398 newSimPack.RegionData.SimIP = (uint) byteIP[3] << 24;
399 newSimPack.RegionData.SimIP += (uint) byteIP[2] << 16;
400 newSimPack.RegionData.SimIP += (uint) byteIP[1] << 8;
401 newSimPack.RegionData.SimIP += (uint) byteIP[0];
402 newSimPack.RegionData.SimPort = (ushort) externalIPEndPoint.Port;
403 //newSimPack.RegionData.SeedCapability = new byte[0];
404 newSimPack.RegionData.SeedCapability = Helpers.StringToField(capsURL);
405
406 OutPacket(newSimPack, ThrottleOutPacketType.Task);
407 }
408
409 public void SendMapBlock(List<MapBlockData> mapBlocks)
410 {
411 MapBlockReplyPacket mapReply = new MapBlockReplyPacket();
412 mapReply.AgentData.AgentID = AgentId;
413 mapReply.Data = new MapBlockReplyPacket.DataBlock[mapBlocks.Count];
414 mapReply.AgentData.Flags = 0;
415
416 for (int i = 0; i < mapBlocks.Count; i++)
417 {
418 mapReply.Data[i] = new MapBlockReplyPacket.DataBlock();
419 mapReply.Data[i].MapImageID = mapBlocks[i].MapImageId;
420 mapReply.Data[i].X = mapBlocks[i].X;
421 mapReply.Data[i].Y = mapBlocks[i].Y;
422 mapReply.Data[i].WaterHeight = mapBlocks[i].WaterHeight;
423 mapReply.Data[i].Name = Helpers.StringToField(mapBlocks[i].Name);
424 mapReply.Data[i].RegionFlags = mapBlocks[i].RegionFlags;
425 mapReply.Data[i].Access = mapBlocks[i].Access;
426 mapReply.Data[i].Agents = mapBlocks[i].Agents;
427 }
428 OutPacket(mapReply, ThrottleOutPacketType.Land);
429 }
430
431 public void SendLocalTeleport(LLVector3 position, LLVector3 lookAt, uint flags)
432 {
433 TeleportLocalPacket tpLocal = new TeleportLocalPacket();
434 tpLocal.Info.AgentID = AgentId;
435 tpLocal.Info.TeleportFlags = flags;
436 tpLocal.Info.LocationID = 2;
437 tpLocal.Info.LookAt = lookAt;
438 tpLocal.Info.Position = position;
439 OutPacket(tpLocal, ThrottleOutPacketType.Task);
440 }
441
442 public void SendRegionTeleport(ulong regionHandle, byte simAccess, IPEndPoint newRegionEndPoint, uint locationID,
443 uint flags, string capsURL)
444 {
445 TeleportFinishPacket teleport = new TeleportFinishPacket();
446 teleport.Info.AgentID = AgentId;
447 teleport.Info.RegionHandle = regionHandle;
448 teleport.Info.SimAccess = simAccess;
449
450 teleport.Info.SeedCapability = Helpers.StringToField(capsURL);
451 //teleport.Info.SeedCapability = new byte[0];
452
453 IPAddress oIP = newRegionEndPoint.Address;
454 byte[] byteIP = oIP.GetAddressBytes();
455 uint ip = (uint) byteIP[3] << 24;
456 ip += (uint) byteIP[2] << 16;
457 ip += (uint) byteIP[1] << 8;
458 ip += (uint) byteIP[0];
459
460 teleport.Info.SimIP = ip;
461 teleport.Info.SimPort = (ushort) newRegionEndPoint.Port;
462 teleport.Info.LocationID = 4;
463 teleport.Info.TeleportFlags = 1 << 4;
464 OutPacket(teleport, ThrottleOutPacketType.Task);
465 }
466
467 /// <summary>
468 ///
469 /// </summary>
470 public void SendTeleportFailed()
471 {
472 TeleportFailedPacket tpFailed = new TeleportFailedPacket();
473 tpFailed.Info.AgentID = this.AgentId;
474 tpFailed.Info.Reason = Helpers.StringToField("unknown failure of teleport");
475
476 OutPacket(tpFailed, ThrottleOutPacketType.Task);
477 }
478
479 /// <summary>
480 ///
481 /// </summary>
482 public void SendTeleportLocationStart()
483 {
484 TeleportStartPacket tpStart = new TeleportStartPacket();
485 tpStart.Info.TeleportFlags = 16; // Teleport via location
486 OutPacket(tpStart, ThrottleOutPacketType.Task);
487 }
488
489 public void SendMoneyBalance(LLUUID transaction, bool success, byte[] description, int balance)
490 {
491 MoneyBalanceReplyPacket money = new MoneyBalanceReplyPacket();
492 money.MoneyData.AgentID = AgentId;
493 money.MoneyData.TransactionID = transaction;
494 money.MoneyData.TransactionSuccess = success;
495 money.MoneyData.Description = description;
496 money.MoneyData.MoneyBalance = balance;
497 OutPacket(money, ThrottleOutPacketType.Task);
498 }
499
500 public void SendStartPingCheck(byte seq)
501 {
502 StartPingCheckPacket pc = new StartPingCheckPacket();
503 pc.PingID.PingID = seq;
504 pc.Header.Reliable = false;
505 OutPacket(pc, ThrottleOutPacketType.Task);
506 }
507
508 public void SendKillObject(ulong regionHandle, uint localID)
509 {
510 KillObjectPacket kill = new KillObjectPacket();
511 kill.ObjectData = new KillObjectPacket.ObjectDataBlock[1];
512 kill.ObjectData[0] = new KillObjectPacket.ObjectDataBlock();
513 kill.ObjectData[0].ID = localID;
514 OutPacket(kill, ThrottleOutPacketType.Task);
515 }
516
517 public void SendInventoryFolderDetails(LLUUID ownerID, LLUUID folderID, List<InventoryItemBase> items)
518 {
519 Encoding enc = Encoding.ASCII;
520 uint FULL_MASK_PERMISSIONS = 2147483647;
521 InventoryDescendentsPacket descend = CreateInventoryDescendentsPacket(ownerID, folderID);
522
523 int count = 0;
524 if (items.Count < 40)
525 {
526 descend.ItemData = new InventoryDescendentsPacket.ItemDataBlock[items.Count];
527 descend.AgentData.Descendents = items.Count;
528 }
529 else
530 {
531 descend.ItemData = new InventoryDescendentsPacket.ItemDataBlock[40];
532 descend.AgentData.Descendents = 40;
533 }
534 int i = 0;
535 foreach (InventoryItemBase item in items)
536 {
537 descend.ItemData[i] = new InventoryDescendentsPacket.ItemDataBlock();
538 descend.ItemData[i].ItemID = item.inventoryID;
539 descend.ItemData[i].AssetID = item.assetID;
540 descend.ItemData[i].CreatorID = item.creatorsID;
541 descend.ItemData[i].BaseMask = item.inventoryBasePermissions;
542 descend.ItemData[i].CreationDate = 1000;
543 descend.ItemData[i].Description = enc.GetBytes(item.inventoryDescription + "\0");
544 descend.ItemData[i].EveryoneMask = item.inventoryEveryOnePermissions;
545 descend.ItemData[i].Flags = 1;
546 descend.ItemData[i].FolderID = item.parentFolderID;
547 descend.ItemData[i].GroupID = new LLUUID("00000000-0000-0000-0000-000000000000");
548 descend.ItemData[i].GroupMask = 0;
549 descend.ItemData[i].InvType = (sbyte) item.invType;
550 descend.ItemData[i].Name = enc.GetBytes(item.inventoryName + "\0");
551 descend.ItemData[i].NextOwnerMask = item.inventoryNextPermissions;
552 descend.ItemData[i].OwnerID = item.avatarID;
553 descend.ItemData[i].OwnerMask = item.inventoryCurrentPermissions;
554 descend.ItemData[i].SalePrice = 0;
555 descend.ItemData[i].SaleType = 0;
556 descend.ItemData[i].Type = (sbyte) item.assetType;
557 descend.ItemData[i].CRC =
558 Helpers.InventoryCRC(1000, 0, descend.ItemData[i].InvType, descend.ItemData[i].Type,
559 descend.ItemData[i].AssetID, descend.ItemData[i].GroupID, 100,
560 descend.ItemData[i].OwnerID, descend.ItemData[i].CreatorID,
561 descend.ItemData[i].ItemID, descend.ItemData[i].FolderID, FULL_MASK_PERMISSIONS,
562 1, FULL_MASK_PERMISSIONS, FULL_MASK_PERMISSIONS, FULL_MASK_PERMISSIONS);
563
564 i++;
565 count++;
566 if (i == 40)
567 {
568 OutPacket(descend, ThrottleOutPacketType.Asset);
569
570 if ((items.Count - count) > 0)
571 {
572 descend = CreateInventoryDescendentsPacket(ownerID, folderID);
573 if ((items.Count - count) < 40)
574 {
575 descend.ItemData = new InventoryDescendentsPacket.ItemDataBlock[items.Count - count];
576 descend.AgentData.Descendents = items.Count - count;
577 }
578 else
579 {
580 descend.ItemData = new InventoryDescendentsPacket.ItemDataBlock[40];
581 descend.AgentData.Descendents = 40;
582 }
583 i = 0;
584 }
585 }
586 }
587
588 if (i < 40)
589 {
590 OutPacket(descend, ThrottleOutPacketType.Asset);
591 }
592 }
593
594 private InventoryDescendentsPacket CreateInventoryDescendentsPacket(LLUUID ownerID, LLUUID folderID)
595 {
596 InventoryDescendentsPacket descend = new InventoryDescendentsPacket();
597 descend.AgentData.AgentID = AgentId;
598 descend.AgentData.OwnerID = ownerID;
599 descend.AgentData.FolderID = folderID;
600 descend.AgentData.Version = 0;
601
602 return descend;
603 }
604
605 public void SendInventoryItemDetails(LLUUID ownerID, InventoryItemBase item)
606 {
607 Encoding enc = Encoding.ASCII;
608 uint FULL_MASK_PERMISSIONS = 2147483647;
609 FetchInventoryReplyPacket inventoryReply = new FetchInventoryReplyPacket();
610 inventoryReply.AgentData.AgentID = AgentId;
611 inventoryReply.InventoryData = new FetchInventoryReplyPacket.InventoryDataBlock[1];
612 inventoryReply.InventoryData[0] = new FetchInventoryReplyPacket.InventoryDataBlock();
613 inventoryReply.InventoryData[0].ItemID = item.inventoryID;
614 inventoryReply.InventoryData[0].AssetID = item.assetID;
615 inventoryReply.InventoryData[0].CreatorID = item.creatorsID;
616 inventoryReply.InventoryData[0].BaseMask = item.inventoryBasePermissions;
617 inventoryReply.InventoryData[0].CreationDate =
618 (int) (DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;
619 inventoryReply.InventoryData[0].Description = enc.GetBytes(item.inventoryDescription + "\0");
620 inventoryReply.InventoryData[0].EveryoneMask = item.inventoryEveryOnePermissions;
621 inventoryReply.InventoryData[0].Flags = 0;
622 inventoryReply.InventoryData[0].FolderID = item.parentFolderID;
623 inventoryReply.InventoryData[0].GroupID = new LLUUID("00000000-0000-0000-0000-000000000000");
624 inventoryReply.InventoryData[0].GroupMask = 0;
625 inventoryReply.InventoryData[0].InvType = (sbyte) item.invType;
626 inventoryReply.InventoryData[0].Name = enc.GetBytes(item.inventoryName + "\0");
627 inventoryReply.InventoryData[0].NextOwnerMask = item.inventoryNextPermissions;
628 inventoryReply.InventoryData[0].OwnerID = item.avatarID;
629 inventoryReply.InventoryData[0].OwnerMask = item.inventoryCurrentPermissions;
630 inventoryReply.InventoryData[0].SalePrice = 0;
631 inventoryReply.InventoryData[0].SaleType = 0;
632 inventoryReply.InventoryData[0].Type = (sbyte) item.assetType;
633 inventoryReply.InventoryData[0].CRC =
634 Helpers.InventoryCRC(1000, 0, inventoryReply.InventoryData[0].InvType,
635 inventoryReply.InventoryData[0].Type, inventoryReply.InventoryData[0].AssetID,
636 inventoryReply.InventoryData[0].GroupID, 100,
637 inventoryReply.InventoryData[0].OwnerID, inventoryReply.InventoryData[0].CreatorID,
638 inventoryReply.InventoryData[0].ItemID, inventoryReply.InventoryData[0].FolderID,
639 FULL_MASK_PERMISSIONS, 1, FULL_MASK_PERMISSIONS, FULL_MASK_PERMISSIONS,
640 FULL_MASK_PERMISSIONS);
641
642 OutPacket(inventoryReply, ThrottleOutPacketType.Asset);
643 }
644
645 public void SendInventoryItemUpdate(InventoryItemBase Item)
646 {
647 Encoding enc = Encoding.ASCII;
648 uint FULL_MASK_PERMISSIONS = 2147483647;
649 UpdateCreateInventoryItemPacket InventoryReply = new UpdateCreateInventoryItemPacket();
650 InventoryReply.AgentData.AgentID = AgentId;
651 InventoryReply.AgentData.SimApproved = true;
652 InventoryReply.InventoryData = new UpdateCreateInventoryItemPacket.InventoryDataBlock[1];
653 InventoryReply.InventoryData[0] = new UpdateCreateInventoryItemPacket.InventoryDataBlock();
654 InventoryReply.InventoryData[0].ItemID = Item.inventoryID;
655 InventoryReply.InventoryData[0].AssetID = Item.assetID;
656 InventoryReply.InventoryData[0].CreatorID = Item.creatorsID;
657 InventoryReply.InventoryData[0].BaseMask = Item.inventoryBasePermissions;
658 InventoryReply.InventoryData[0].CreationDate = 1000;
659 InventoryReply.InventoryData[0].Description = enc.GetBytes(Item.inventoryDescription + "\0");
660 InventoryReply.InventoryData[0].EveryoneMask = Item.inventoryEveryOnePermissions;
661 InventoryReply.InventoryData[0].Flags = 0;
662 InventoryReply.InventoryData[0].FolderID = Item.parentFolderID;
663 InventoryReply.InventoryData[0].GroupID = new LLUUID("00000000-0000-0000-0000-000000000000");
664 InventoryReply.InventoryData[0].GroupMask = 0;
665 InventoryReply.InventoryData[0].InvType = (sbyte) Item.invType;
666 InventoryReply.InventoryData[0].Name = enc.GetBytes(Item.inventoryName + "\0");
667 InventoryReply.InventoryData[0].NextOwnerMask = Item.inventoryNextPermissions;
668 InventoryReply.InventoryData[0].OwnerID = Item.avatarID;
669 InventoryReply.InventoryData[0].OwnerMask = Item.inventoryCurrentPermissions;
670 InventoryReply.InventoryData[0].SalePrice = 100;
671 InventoryReply.InventoryData[0].SaleType = 0;
672 InventoryReply.InventoryData[0].Type = (sbyte) Item.assetType;
673 InventoryReply.InventoryData[0].CRC =
674 Helpers.InventoryCRC(1000, 0, InventoryReply.InventoryData[0].InvType,
675 InventoryReply.InventoryData[0].Type, InventoryReply.InventoryData[0].AssetID,
676 InventoryReply.InventoryData[0].GroupID, 100,
677 InventoryReply.InventoryData[0].OwnerID, InventoryReply.InventoryData[0].CreatorID,
678 InventoryReply.InventoryData[0].ItemID, InventoryReply.InventoryData[0].FolderID,
679 FULL_MASK_PERMISSIONS, 1, FULL_MASK_PERMISSIONS, FULL_MASK_PERMISSIONS,
680 FULL_MASK_PERMISSIONS);
681
682 OutPacket(InventoryReply, ThrottleOutPacketType.Asset);
683 }
684
685 public void SendRemoveInventoryItem(LLUUID itemID)
686 {
687 RemoveInventoryItemPacket remove = new RemoveInventoryItemPacket();
688 remove.AgentData.AgentID = AgentId;
689 remove.AgentData.SessionID = m_sessionId;
690 remove.InventoryData = new RemoveInventoryItemPacket.InventoryDataBlock[1];
691 remove.InventoryData[0] = new RemoveInventoryItemPacket.InventoryDataBlock();
692 remove.InventoryData[0].ItemID = itemID;
693
694 OutPacket(remove, ThrottleOutPacketType.Asset);
695 }
696
697 public void SendTaskInventory(LLUUID taskID, short serial, byte[] fileName)
698 {
699 ReplyTaskInventoryPacket replytask = new ReplyTaskInventoryPacket();
700 replytask.InventoryData.TaskID = taskID;
701 replytask.InventoryData.Serial = serial;
702 replytask.InventoryData.Filename = fileName;
703 OutPacket(replytask, ThrottleOutPacketType.Asset);
704 }
705
706 public void SendXferPacket(ulong xferID, uint packet, byte[] data)
707 {
708 SendXferPacketPacket sendXfer = new SendXferPacketPacket();
709 sendXfer.XferID.ID = xferID;
710 sendXfer.XferID.Packet = packet;
711 sendXfer.DataPacket.Data = data;
712 OutPacket(sendXfer, ThrottleOutPacketType.Task);
713 }
714 public void SendAvatarPickerReply(AvatarPickerReplyPacket replyPacket)
715 {
716 OutPacket(replyPacket, ThrottleOutPacketType.Task);
717 }
718
719 /// <summary>
720 ///
721 /// </summary>
722 /// <param name="message"></param>
723 public void SendAlertMessage(string message)
724 {
725 AlertMessagePacket alertPack = new AlertMessagePacket();
726 alertPack.AlertData.Message = Helpers.StringToField(message);
727 OutPacket(alertPack, ThrottleOutPacketType.Task);
728 }
729
730 /// <summary>
731 ///
732 /// </summary>
733 /// <param name="message"></param>
734 /// <param name="modal"></param>
735 public void SendAgentAlertMessage(string message, bool modal)
736 {
737 AgentAlertMessagePacket alertPack = new AgentAlertMessagePacket();
738 alertPack.AgentData.AgentID = AgentId;
739 alertPack.AlertData.Message = Helpers.StringToField(message);
740 alertPack.AlertData.Modal = modal;
741 OutPacket(alertPack, ThrottleOutPacketType.Task);
742 }
743
744 public void SendLoadURL(string objectname, LLUUID objectID, LLUUID ownerID, bool groupOwned, string message,
745 string url)
746 {
747 LoadURLPacket loadURL = new LoadURLPacket();
748 loadURL.Data.ObjectName = Helpers.StringToField(objectname);
749 loadURL.Data.ObjectID = objectID;
750 loadURL.Data.OwnerID = ownerID;
751 loadURL.Data.OwnerIsGroup = groupOwned;
752 loadURL.Data.Message = Helpers.StringToField(message);
753 loadURL.Data.URL = Helpers.StringToField(url);
754
755 OutPacket(loadURL, ThrottleOutPacketType.Task);
756 }
757
758
759 public void SendPreLoadSound(LLUUID objectID, LLUUID ownerID, LLUUID soundID)
760 {
761 PreloadSoundPacket preSound = new PreloadSoundPacket();
762 preSound.DataBlock = new PreloadSoundPacket.DataBlockBlock[1];
763 preSound.DataBlock[0] = new PreloadSoundPacket.DataBlockBlock();
764 preSound.DataBlock[0].ObjectID = objectID;
765 preSound.DataBlock[0].OwnerID = ownerID;
766 preSound.DataBlock[0].SoundID = soundID;
767 OutPacket(preSound, ThrottleOutPacketType.Task);
768 }
769
770 public void SendPlayAttachedSound(LLUUID soundID, LLUUID objectID, LLUUID ownerID, float gain, byte flags)
771 {
772 AttachedSoundPacket sound = new AttachedSoundPacket();
773 sound.DataBlock.SoundID = soundID;
774 sound.DataBlock.ObjectID = objectID;
775 sound.DataBlock.OwnerID = ownerID;
776 sound.DataBlock.Gain = gain;
777 sound.DataBlock.Flags = flags;
778
779 OutPacket(sound, ThrottleOutPacketType.Task);
780 }
781
782 public void SendSunPos(LLVector3 sunPos, LLVector3 sunVel)
783 {
784 SimulatorViewerTimeMessagePacket viewertime = new SimulatorViewerTimeMessagePacket();
785 viewertime.TimeInfo.SunDirection = sunPos;
786 viewertime.TimeInfo.SunAngVelocity = sunVel;
787 viewertime.TimeInfo.UsecSinceStart = (ulong) Util.UnixTimeSinceEpoch();
788 OutPacket(viewertime, ThrottleOutPacketType.Task);
789 }
790
791 public void SendViewerTime(int phase)
792 {
793 Console.WriteLine("SunPhase: {0}", phase);
794 SimulatorViewerTimeMessagePacket viewertime = new SimulatorViewerTimeMessagePacket();
795 //viewertime.TimeInfo.SecPerDay = 86400;
796 // viewertime.TimeInfo.SecPerYear = 31536000;
797 viewertime.TimeInfo.SecPerDay = 1000;
798 viewertime.TimeInfo.SecPerYear = 365000;
799 viewertime.TimeInfo.SunPhase = 1;
800 int sunPhase = (phase + 2)/2;
801 if ((sunPhase < 6) || (sunPhase > 36))
802 {
803 viewertime.TimeInfo.SunDirection = new LLVector3(0f, 0.8f, -0.8f);
804 Console.WriteLine("sending night");
805 }
806 else
807 {
808 if (sunPhase < 12)
809 {
810 sunPhase = 12;
811 }
812 sunPhase = sunPhase - 12;
813
814 float yValue = 0.1f*(sunPhase);
815 Console.WriteLine("Computed SunPhase: {0}, yValue: {1}", sunPhase, yValue);
816 if (yValue > 1.2f)
817 {
818 yValue = yValue - 1.2f;
819 }
820 if (yValue > 1)
821 {
822 yValue = 1;
823 }
824 if (yValue < 0)
825 {
826 yValue = 0;
827 }
828 if (sunPhase < 14)
829 {
830 yValue = 1 - yValue;
831 }
832 if (sunPhase < 12)
833 {
834 yValue *= -1;
835 }
836 viewertime.TimeInfo.SunDirection = new LLVector3(0f, yValue, 0.3f);
837 Console.WriteLine("sending sun update " + yValue);
838 }
839 viewertime.TimeInfo.SunAngVelocity = new LLVector3(0, 0.0f, 10.0f);
840 viewertime.TimeInfo.UsecSinceStart = (ulong) Util.UnixTimeSinceEpoch();
841 OutPacket(viewertime, ThrottleOutPacketType.Task);
842 }
843
844 public void SendAvatarProperties(LLUUID avatarID, string aboutText, string bornOn, string charterMember,
845 string flAbout, uint flags, LLUUID flImageID, LLUUID imageID, string profileURL,
846 LLUUID partnerID)
847 {
848 AvatarPropertiesReplyPacket avatarReply = new AvatarPropertiesReplyPacket();
849 avatarReply.AgentData.AgentID = AgentId;
850 avatarReply.AgentData.AvatarID = avatarID;
851 avatarReply.PropertiesData.AboutText = Helpers.StringToField(aboutText);
852 avatarReply.PropertiesData.BornOn = Helpers.StringToField(bornOn);
853 avatarReply.PropertiesData.CharterMember = Helpers.StringToField(charterMember);
854 avatarReply.PropertiesData.FLAboutText = Helpers.StringToField(flAbout);
855 avatarReply.PropertiesData.Flags = 0;
856 avatarReply.PropertiesData.FLImageID = flImageID;
857 avatarReply.PropertiesData.ImageID = imageID;
858 avatarReply.PropertiesData.ProfileURL = Helpers.StringToField(profileURL);
859 avatarReply.PropertiesData.PartnerID = partnerID;
860 OutPacket(avatarReply, ThrottleOutPacketType.Task);
861 }
862
863 #endregion
864
865 #region Appearance/ Wearables Methods
866
867 /// <summary>
868 ///
869 /// </summary>
870 /// <param name="wearables"></param>
871 public void SendWearables(AvatarWearable[] wearables, int serial)
872 {
873 AgentWearablesUpdatePacket aw = new AgentWearablesUpdatePacket();
874 aw.AgentData.AgentID = AgentId;
875 aw.AgentData.SerialNum = (uint) serial;
876 aw.AgentData.SessionID = m_sessionId;
877
878 aw.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[13];
879 AgentWearablesUpdatePacket.WearableDataBlock awb;
880 for (int i = 0; i < wearables.Length; i++)
881 {
882 awb = new AgentWearablesUpdatePacket.WearableDataBlock();
883 awb.WearableType = (byte) i;
884 awb.AssetID = wearables[i].AssetID;
885 awb.ItemID = wearables[i].ItemID;
886 aw.WearableData[i] = awb;
887 }
888
889 OutPacket(aw, ThrottleOutPacketType.Task);
890 }
891
892 /// <summary>
893 ///
894 /// </summary>
895 /// <param name="agentID"></param>
896 /// <param name="visualParams"></param>
897 /// <param name="textureEntry"></param>
898 public void SendAppearance(LLUUID agentID, byte[] visualParams, byte[] textureEntry)
899 {
900 AvatarAppearancePacket avp = new AvatarAppearancePacket();
901 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[218];
902 avp.ObjectData.TextureEntry = textureEntry;
903
904 AvatarAppearancePacket.VisualParamBlock avblock = null;
905 for (int i = 0; i < visualParams.Length; i++)
906 {
907 avblock = new AvatarAppearancePacket.VisualParamBlock();
908 avblock.ParamValue = visualParams[i];
909 avp.VisualParam[i] = avblock;
910 }
911
912 avp.Sender.IsTrial = false;
913 avp.Sender.ID = agentID;
914 OutPacket(avp, ThrottleOutPacketType.Task);
915 }
916
917 public void SendAnimation(LLUUID animID, int seq, LLUUID sourceAgentId)
918 {
919 AvatarAnimationPacket ani = new AvatarAnimationPacket();
920 ani.AnimationSourceList = new AvatarAnimationPacket.AnimationSourceListBlock[1];
921 ani.AnimationSourceList[0] = new AvatarAnimationPacket.AnimationSourceListBlock();
922 ani.AnimationSourceList[0].ObjectID = sourceAgentId;
923 ani.Sender = new AvatarAnimationPacket.SenderBlock();
924 ani.Sender.ID = sourceAgentId;
925 ani.AnimationList = new AvatarAnimationPacket.AnimationListBlock[1];
926 ani.AnimationList[0] = new AvatarAnimationPacket.AnimationListBlock();
927 ani.AnimationList[0].AnimID = animID;
928 ani.AnimationList[0].AnimSequenceID = seq;
929 OutPacket(ani, ThrottleOutPacketType.Task);
930 }
931
932 #endregion
933
934 #region Avatar Packet/data sending Methods
935
936 /// <summary>
937 /// send a objectupdate packet with information about the clients avatar
938 /// </summary>
939 /// <param name="regionInfo"></param>
940 /// <param name="firstName"></param>
941 /// <param name="lastName"></param>
942 /// <param name="avatarID"></param>
943 /// <param name="avatarLocalID"></param>
944 /// <param name="Pos"></param>
945 public void SendAvatarData(ulong regionHandle, string firstName, string lastName, LLUUID avatarID,
946 uint avatarLocalID, LLVector3 Pos, byte[] textureEntry, uint parentID)
947 {
948 ObjectUpdatePacket objupdate = new ObjectUpdatePacket();
949 objupdate.RegionData.RegionHandle = regionHandle;
950 objupdate.RegionData.TimeDilation = 64096;
951 objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
952 objupdate.ObjectData[0] = CreateDefaultAvatarPacket(textureEntry);
953
954 //give this avatar object a local id and assign the user a name
955 objupdate.ObjectData[0].ID = avatarLocalID;
956 objupdate.ObjectData[0].FullID = avatarID;
957 objupdate.ObjectData[0].ParentID = parentID;
958 objupdate.ObjectData[0].NameValue =
959 Helpers.StringToField("FirstName STRING RW SV " + firstName + "\nLastName STRING RW SV " + lastName);
960 LLVector3 pos2 = new LLVector3((float) Pos.X, (float) Pos.Y, (float) Pos.Z);
961 byte[] pb = pos2.GetBytes();
962 Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 16, pb.Length);
963
964 OutPacket(objupdate, ThrottleOutPacketType.Task);
965 }
966
967 /// <summary>
968 ///
969 /// </summary>
970 /// <param name="regionHandle"></param>
971 /// <param name="timeDilation"></param>
972 /// <param name="localID"></param>
973 /// <param name="position"></param>
974 /// <param name="velocity"></param>
975 public void SendAvatarTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, LLVector3 position,
976 LLVector3 velocity, LLQuaternion rotation)
977 {
978 ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock =
979 CreateAvatarImprovedBlock(localID, position, velocity, rotation);
980 ImprovedTerseObjectUpdatePacket terse = new ImprovedTerseObjectUpdatePacket();
981 terse.RegionData.RegionHandle = regionHandle;
982 terse.RegionData.TimeDilation = timeDilation;
983 terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1];
984 terse.ObjectData[0] = terseBlock;
985
986 OutPacket(terse, ThrottleOutPacketType.Task);
987 }
988
989 public void SendCoarseLocationUpdate(List<LLVector3> CoarseLocations)
990 {
991 CoarseLocationUpdatePacket loc = new CoarseLocationUpdatePacket();
992 int total = CoarseLocations.Count;
993 CoarseLocationUpdatePacket.IndexBlock ib =
994 new CoarseLocationUpdatePacket.IndexBlock();
995 loc.Location = new CoarseLocationUpdatePacket.LocationBlock[total];
996 for (int i = 0; i < total; i++)
997 {
998 CoarseLocationUpdatePacket.LocationBlock lb =
999 new CoarseLocationUpdatePacket.LocationBlock();
1000 lb.X = (byte) CoarseLocations[i].X;
1001 lb.Y = (byte) CoarseLocations[i].Y;
1002 lb.Z = (byte) (CoarseLocations[i].Z/4);
1003 loc.Location[i] = lb;
1004 }
1005 ib.You = -1;
1006 ib.Prey = -1;
1007 loc.Index = ib;
1008 OutPacket(loc, ThrottleOutPacketType.Task);
1009 }
1010
1011 #endregion
1012
1013 #region Primitive Packet/data Sending Methods
1014
1015 /// <summary>
1016 ///
1017 /// </summary>
1018 /// <param name="localID"></param>
1019 /// <param name="rotation"></param>
1020 /// <param name="attachPoint"></param>
1021 public void AttachObject(uint localID, LLQuaternion rotation, byte attachPoint)
1022 {
1023 ObjectAttachPacket attach = new ObjectAttachPacket();
1024 attach.AgentData.AgentID = AgentId;
1025 attach.AgentData.SessionID = m_sessionId;
1026 attach.AgentData.AttachmentPoint = attachPoint;
1027 attach.ObjectData = new ObjectAttachPacket.ObjectDataBlock[1];
1028 attach.ObjectData[0] = new ObjectAttachPacket.ObjectDataBlock();
1029 attach.ObjectData[0].ObjectLocalID = localID;
1030 attach.ObjectData[0].Rotation = rotation;
1031
1032 OutPacket(attach, ThrottleOutPacketType.Task);
1033 }
1034
1035 public void SendPrimitiveToClient(
1036 ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, LLVector3 pos,
1037 uint flags,
1038 LLUUID objectID, LLUUID ownerID, string text, byte[] color, uint parentID, byte[] particleSystem, LLQuaternion rotation, byte clickAction)
1039 {
1040 ObjectUpdatePacket outPacket = new ObjectUpdatePacket();
1041 outPacket.RegionData.RegionHandle = regionHandle;
1042 outPacket.RegionData.TimeDilation = timeDilation;
1043 outPacket.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
1044
1045 outPacket.ObjectData[0] = CreatePrimUpdateBlock(primShape, flags);
1046
1047 outPacket.ObjectData[0].ID = localID;
1048 outPacket.ObjectData[0].FullID = objectID;
1049 outPacket.ObjectData[0].OwnerID = ownerID;
1050 outPacket.ObjectData[0].Text = Helpers.StringToField(text);
1051 outPacket.ObjectData[0].TextColor[0] = color[0];
1052 outPacket.ObjectData[0].TextColor[1] = color[1];
1053 outPacket.ObjectData[0].TextColor[2] = color[2];
1054 outPacket.ObjectData[0].TextColor[3] = color[3];
1055 outPacket.ObjectData[0].ParentID = parentID;
1056 outPacket.ObjectData[0].PSBlock = particleSystem;
1057 outPacket.ObjectData[0].ClickAction = clickAction;
1058 //outPacket.ObjectData[0].Flags = 0;
1059 outPacket.ObjectData[0].Radius = 20;
1060
1061 byte[] pb = pos.GetBytes();
1062 Array.Copy(pb, 0, outPacket.ObjectData[0].ObjectData, 0, pb.Length);
1063
1064 byte[] rot = rotation.GetBytes();
1065 Array.Copy(rot, 0, outPacket.ObjectData[0].ObjectData, 36, rot.Length);
1066
1067 OutPacket(outPacket, ThrottleOutPacketType.Task);
1068 }
1069
1070 /// <summary>
1071 ///
1072 /// </summary>
1073 /// <param name="regionHandle"></param>
1074 /// <param name="timeDilation"></param>
1075 /// <param name="localID"></param>
1076 /// <param name="position"></param>
1077 /// <param name="rotation"></param>
1078 public void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, LLVector3 position,
1079 LLQuaternion rotation)
1080 {
1081 LLVector3 velocity = new LLVector3(0f,0f,0f);
1082 LLVector3 rotationalvelocity = new LLVector3(0f,0f,0f);
1083 ImprovedTerseObjectUpdatePacket terse = new ImprovedTerseObjectUpdatePacket();
1084 terse.RegionData.RegionHandle = regionHandle;
1085 terse.RegionData.TimeDilation = timeDilation;
1086 terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1];
1087 terse.ObjectData[0] = CreatePrimImprovedBlock(localID, position, rotation, velocity, rotationalvelocity);
1088
1089 OutPacket(terse, ThrottleOutPacketType.Task);
1090 }
1091 public void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, LLVector3 position,
1092 LLQuaternion rotation, LLVector3 velocity, LLVector3 rotationalvelocity)
1093 {
1094
1095 ImprovedTerseObjectUpdatePacket terse = new ImprovedTerseObjectUpdatePacket();
1096 terse.RegionData.RegionHandle = regionHandle;
1097 terse.RegionData.TimeDilation = timeDilation;
1098 terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1];
1099 terse.ObjectData[0] = CreatePrimImprovedBlock(localID, position, rotation, velocity, rotationalvelocity);
1100
1101 OutPacket(terse, ThrottleOutPacketType.Task);
1102 }
1103
1104
1105 #endregion
1106
1107 #region Helper Methods
1108
1109 protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateAvatarImprovedBlock(uint localID, LLVector3 pos,
1110 LLVector3 velocity,
1111 LLQuaternion rotation)
1112 {
1113 byte[] bytes = new byte[60];
1114 int i = 0;
1115 ImprovedTerseObjectUpdatePacket.ObjectDataBlock dat = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock();
1116
1117 dat.TextureEntry = new byte[0]; // AvatarTemplate.TextureEntry;
1118
1119 uint ID = localID;
1120
1121 bytes[i++] = (byte) (ID%256);
1122 bytes[i++] = (byte) ((ID >> 8)%256);
1123 bytes[i++] = (byte) ((ID >> 16)%256);
1124 bytes[i++] = (byte) ((ID >> 24)%256);
1125 bytes[i++] = 0;
1126 bytes[i++] = 1;
1127 i += 14;
1128 bytes[i++] = 128;
1129 bytes[i++] = 63;
1130
1131 byte[] pb = pos.GetBytes();
1132 Array.Copy(pb, 0, bytes, i, pb.Length);
1133 i += 12;
1134 ushort InternVelocityX;
1135 ushort InternVelocityY;
1136 ushort InternVelocityZ;
1137 Vector3 internDirec = new Vector3(0, 0, 0);
1138
1139 internDirec = new Vector3(velocity.X, velocity.Y, velocity.Z);
1140
1141 internDirec = internDirec/128.0f;
1142 internDirec.x += 1;
1143 internDirec.y += 1;
1144 internDirec.z += 1;
1145
1146 InternVelocityX = (ushort) (32768*internDirec.x);
1147 InternVelocityY = (ushort) (32768*internDirec.y);
1148 InternVelocityZ = (ushort) (32768*internDirec.z);
1149
1150 ushort ac = 32767;
1151 bytes[i++] = (byte) (InternVelocityX%256);
1152 bytes[i++] = (byte) ((InternVelocityX >> 8)%256);
1153 bytes[i++] = (byte) (InternVelocityY%256);
1154 bytes[i++] = (byte) ((InternVelocityY >> 8)%256);
1155 bytes[i++] = (byte) (InternVelocityZ%256);
1156 bytes[i++] = (byte) ((InternVelocityZ >> 8)%256);
1157
1158 //accel
1159 bytes[i++] = (byte) (ac%256);
1160 bytes[i++] = (byte) ((ac >> 8)%256);
1161 bytes[i++] = (byte) (ac%256);
1162 bytes[i++] = (byte) ((ac >> 8)%256);
1163 bytes[i++] = (byte) (ac%256);
1164 bytes[i++] = (byte) ((ac >> 8)%256);
1165
1166 //rotation
1167 ushort rw, rx, ry, rz;
1168 rw = (ushort) (32768*(rotation.W + 1));
1169 rx = (ushort) (32768*(rotation.X + 1));
1170 ry = (ushort) (32768*(rotation.Y + 1));
1171 rz = (ushort) (32768*(rotation.Z + 1));
1172
1173 //rot
1174 bytes[i++] = (byte) (rx%256);
1175 bytes[i++] = (byte) ((rx >> 8)%256);
1176 bytes[i++] = (byte) (ry%256);
1177 bytes[i++] = (byte) ((ry >> 8)%256);
1178 bytes[i++] = (byte) (rz%256);
1179 bytes[i++] = (byte) ((rz >> 8)%256);
1180 bytes[i++] = (byte) (rw%256);
1181 bytes[i++] = (byte) ((rw >> 8)%256);
1182
1183 //rotation vel
1184 bytes[i++] = (byte) (ac%256);
1185 bytes[i++] = (byte) ((ac >> 8)%256);
1186 bytes[i++] = (byte) (ac%256);
1187 bytes[i++] = (byte) ((ac >> 8)%256);
1188 bytes[i++] = (byte) (ac%256);
1189 bytes[i++] = (byte) ((ac >> 8)%256);
1190
1191 dat.Data = bytes;
1192
1193 return (dat);
1194 }
1195
1196 /// <summary>
1197 ///
1198 /// </summary>
1199 /// <param name="localID"></param>
1200 /// <param name="position"></param>
1201 /// <param name="rotation"></param>
1202 /// <returns></returns>
1203 protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreatePrimImprovedBlock(uint localID,
1204 LLVector3 position,
1205 LLQuaternion rotation, LLVector3 velocity, LLVector3 rotationalvelocity)
1206 {
1207 uint ID = localID;
1208 byte[] bytes = new byte[60];
1209
1210 int i = 0;
1211 ImprovedTerseObjectUpdatePacket.ObjectDataBlock dat = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock();
1212 dat.TextureEntry = new byte[0];
1213 bytes[i++] = (byte) (ID%256);
1214 bytes[i++] = (byte) ((ID >> 8)%256);
1215 bytes[i++] = (byte) ((ID >> 16)%256);
1216 bytes[i++] = (byte) ((ID >> 24)%256);
1217 bytes[i++] = 0;
1218 bytes[i++] = 0;
1219
1220 byte[] pb = position.GetBytes();
1221 Array.Copy(pb, 0, bytes, i, pb.Length);
1222 i += 12;
1223 ushort ac = 32767;
1224
1225 ushort velx, vely, velz;
1226 Vector3 vel = new Vector3(velocity.X, velocity.Y, velocity.Z);
1227
1228 vel = vel/128.0f;
1229 vel.x += 1;
1230 vel.y += 1;
1231 vel.z += 1;
1232 //vel
1233 velx = (ushort)(32768 * (vel.x));
1234 vely = (ushort)(32768 * (vel.y));
1235 velz = (ushort)(32768 * (vel.z));
1236
1237 bytes[i++] = (byte) (velx % 256);
1238 bytes[i++] = (byte) ((velx >> 8) % 256);
1239 bytes[i++] = (byte) (vely % 256);
1240 bytes[i++] = (byte) ((vely >> 8) % 256);
1241 bytes[i++] = (byte) (velz % 256);
1242 bytes[i++] = (byte) ((velz >> 8) % 256);
1243
1244 //accel
1245 bytes[i++] = (byte) (ac%256);
1246 bytes[i++] = (byte) ((ac >> 8)%256);
1247 bytes[i++] = (byte) (ac%256);
1248 bytes[i++] = (byte) ((ac >> 8)%256);
1249 bytes[i++] = (byte) (ac%256);
1250 bytes[i++] = (byte) ((ac >> 8)%256);
1251
1252 ushort rw, rx, ry, rz;
1253 rw = (ushort) (32768*(rotation.W + 1));
1254 rx = (ushort) (32768*(rotation.X + 1));
1255 ry = (ushort) (32768*(rotation.Y + 1));
1256 rz = (ushort) (32768*(rotation.Z + 1));
1257
1258 //rot
1259 bytes[i++] = (byte) (rx%256);
1260 bytes[i++] = (byte) ((rx >> 8)%256);
1261 bytes[i++] = (byte) (ry%256);
1262 bytes[i++] = (byte) ((ry >> 8)%256);
1263 bytes[i++] = (byte) (rz%256);
1264 bytes[i++] = (byte) ((rz >> 8)%256);
1265 bytes[i++] = (byte) (rw%256);
1266 bytes[i++] = (byte) ((rw >> 8)%256);
1267
1268 //rotation vel
1269 ushort rvelx, rvely, rvelz;
1270 Vector3 rvel = new Vector3(rotationalvelocity.X, rotationalvelocity.Y, rotationalvelocity.Z);
1271
1272 rvel = rvel / 128.0f;
1273 rvel.x += 1;
1274 rvel.y += 1;
1275 rvel.z += 1;
1276 //vel
1277 rvelx = (ushort)(32768 * (rvel.x));
1278 rvely = (ushort)(32768 * (rvel.y));
1279 rvelz = (ushort)(32768 * (rvel.z));
1280
1281 bytes[i++] = (byte)(rvelx % 256);
1282 bytes[i++] = (byte)((rvelx >> 8) % 256);
1283 bytes[i++] = (byte)(rvely % 256);
1284 bytes[i++] = (byte)((rvely >> 8) % 256);
1285 bytes[i++] = (byte)(rvelz % 256);
1286 bytes[i++] = (byte)((rvelz >> 8) % 256);
1287
1288 dat.Data = bytes;
1289 return dat;
1290 }
1291
1292 /// <summary>
1293 /// Create the ObjectDataBlock for a ObjectUpdatePacket (for a Primitive)
1294 /// </summary>
1295 /// <param name="primData"></param>
1296 /// <returns></returns>
1297 protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(PrimitiveBaseShape primShape, uint flags)
1298 {
1299 ObjectUpdatePacket.ObjectDataBlock objupdate = new ObjectUpdatePacket.ObjectDataBlock();
1300 SetDefaultPrimPacketValues(objupdate);
1301 objupdate.UpdateFlags = flags;
1302 SetPrimPacketShapeData(objupdate, primShape);
1303
1304 return objupdate;
1305 }
1306
1307 protected void SetPrimPacketShapeData(ObjectUpdatePacket.ObjectDataBlock objectData, PrimitiveBaseShape primData)
1308 {
1309 objectData.TextureEntry = primData.TextureEntry;
1310 objectData.PCode = primData.PCode;
1311 objectData.PathBegin = primData.PathBegin;
1312 objectData.PathEnd = primData.PathEnd;
1313 objectData.PathScaleX = primData.PathScaleX;
1314 objectData.PathScaleY = primData.PathScaleY;
1315 objectData.PathShearX = primData.PathShearX;
1316 objectData.PathShearY = primData.PathShearY;
1317 objectData.PathSkew = primData.PathSkew;
1318 objectData.ProfileBegin = primData.ProfileBegin;
1319 objectData.ProfileEnd = primData.ProfileEnd;
1320 objectData.Scale = primData.Scale;
1321 objectData.PathCurve = primData.PathCurve;
1322 objectData.ProfileCurve = primData.ProfileCurve;
1323 objectData.ProfileHollow = primData.ProfileHollow;
1324 objectData.PathRadiusOffset = primData.PathRadiusOffset;
1325 objectData.PathRevolutions = primData.PathRevolutions;
1326 objectData.PathTaperX = primData.PathTaperX;
1327 objectData.PathTaperY = primData.PathTaperY;
1328 objectData.PathTwist = primData.PathTwist;
1329 objectData.PathTwistBegin = primData.PathTwistBegin;
1330 objectData.ExtraParams = primData.ExtraParams;
1331 }
1332
1333 /// <summary>
1334 /// Set some default values in a ObjectUpdatePacket
1335 /// </summary>
1336 /// <param name="objdata"></param>
1337 protected void SetDefaultPrimPacketValues(ObjectUpdatePacket.ObjectDataBlock objdata)
1338 {
1339 objdata.PSBlock = new byte[0];
1340 objdata.ExtraParams = new byte[1];
1341 objdata.MediaURL = new byte[0];
1342 objdata.NameValue = new byte[0];
1343 objdata.Text = new byte[0];
1344 objdata.TextColor = new byte[4];
1345 objdata.JointAxisOrAnchor = new LLVector3(0, 0, 0);
1346 objdata.JointPivot = new LLVector3(0, 0, 0);
1347 objdata.Material = 3;
1348 objdata.TextureAnim = new byte[0];
1349 objdata.Sound = LLUUID.Zero;
1350 objdata.State = 0;
1351 objdata.Data = new byte[0];
1352
1353 objdata.ObjectData = new byte[60];
1354 objdata.ObjectData[46] = 128;
1355 objdata.ObjectData[47] = 63;
1356 }
1357
1358
1359 /// <summary>
1360 ///
1361 /// </summary>
1362 /// <returns></returns>
1363 protected ObjectUpdatePacket.ObjectDataBlock CreateDefaultAvatarPacket(byte[] textureEntry)
1364 {
1365 ObjectUpdatePacket.ObjectDataBlock objdata = new ObjectUpdatePacket.ObjectDataBlock();
1366 // new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock(data1, ref i);
1367
1368 SetDefaultAvatarPacketValues(ref objdata);
1369 objdata.UpdateFlags = 61 + (9 << 8) + (130 << 16) + (16 << 24);
1370 objdata.PathCurve = 16;
1371 objdata.ProfileCurve = 1;
1372 objdata.PathScaleX = 100;
1373 objdata.PathScaleY = 100;
1374 objdata.ParentID = 0;
1375 objdata.OwnerID = LLUUID.Zero;
1376 objdata.Scale = new LLVector3(1, 1, 1);
1377 objdata.PCode = 47;
1378 if (textureEntry != null)
1379 {
1380 objdata.TextureEntry = textureEntry;
1381 }
1382 Encoding enc = Encoding.ASCII;
1383 LLVector3 pos = new LLVector3(objdata.ObjectData, 16);
1384 pos.X = 100f;
1385 objdata.ID = 8880000;
1386 objdata.NameValue = enc.GetBytes("FirstName STRING RW SV Test \nLastName STRING RW SV User \0");
1387 //LLVector3 pos2 = new LLVector3(100f, 100f, 23f);
1388 //objdata.FullID=user.AgentId;
1389 byte[] pb = pos.GetBytes();
1390 Array.Copy(pb, 0, objdata.ObjectData, 16, pb.Length);
1391
1392 return objdata;
1393 }
1394
1395 /// <summary>
1396 ///
1397 /// </summary>
1398 /// <param name="objdata"></param>
1399 protected void SetDefaultAvatarPacketValues(ref ObjectUpdatePacket.ObjectDataBlock objdata)
1400 {
1401 objdata.PSBlock = new byte[0];
1402 objdata.ExtraParams = new byte[1];
1403 objdata.MediaURL = new byte[0];
1404 objdata.NameValue = new byte[0];
1405 objdata.Text = new byte[0];
1406 objdata.TextColor = new byte[4];
1407 objdata.JointAxisOrAnchor = new LLVector3(0, 0, 0);
1408 objdata.JointPivot = new LLVector3(0, 0, 0);
1409 objdata.Material = 4;
1410 objdata.TextureAnim = new byte[0];
1411 objdata.Sound = LLUUID.Zero;
1412 LLObject.TextureEntry ntex = new LLObject.TextureEntry(new LLUUID("00000000-0000-0000-5005-000000000005"));
1413 objdata.TextureEntry = ntex.ToBytes();
1414 objdata.State = 0;
1415 objdata.Data = new byte[0];
1416
1417 objdata.ObjectData = new byte[76];
1418 objdata.ObjectData[15] = 128;
1419 objdata.ObjectData[16] = 63;
1420 objdata.ObjectData[56] = 128;
1421 objdata.ObjectData[61] = 102;
1422 objdata.ObjectData[62] = 40;
1423 objdata.ObjectData[63] = 61;
1424 objdata.ObjectData[64] = 189;
1425 }
1426
1427 public void SendNameReply(LLUUID profileId, string firstname, string lastname)
1428 {
1429 UUIDNameReplyPacket packet = new UUIDNameReplyPacket();
1430
1431 packet.UUIDNameBlock = new UUIDNameReplyPacket.UUIDNameBlockBlock[1];
1432 packet.UUIDNameBlock[0] = new UUIDNameReplyPacket.UUIDNameBlockBlock();
1433 packet.UUIDNameBlock[0].ID = profileId;
1434 packet.UUIDNameBlock[0].FirstName = Helpers.StringToField(firstname);
1435 packet.UUIDNameBlock[0].LastName = Helpers.StringToField(lastname);
1436
1437 OutPacket(packet, ThrottleOutPacketType.Task);
1438 }
1439
1440 #endregion
1441 }
1442}
diff --git a/OpenSim/Region/ClientStack/ClientView.PacketHandlers.cs b/OpenSim/Region/ClientStack/ClientView.PacketHandlers.cs
deleted file mode 100644
index 5753018..0000000
--- a/OpenSim/Region/ClientStack/ClientView.PacketHandlers.cs
+++ /dev/null
@@ -1,257 +0,0 @@
1/*
2* Copyright (c) Contributors, http://opensimulator.org/
3* See CONTRIBUTORS.TXT for a full list of copyright holders.
4*
5* Redistribution and use in source and binary forms, with or without
6* modification, are permitted provided that the following conditions are met:
7* * Redistributions of source code must retain the above copyright
8* notice, this list of conditions and the following disclaimer.
9* * Redistributions in binary form must reproduce the above copyright
10* notice, this list of conditions and the following disclaimer in the
11* documentation and/or other materials provided with the distribution.
12* * Neither the name of the OpenSim Project nor the
13* names of its contributors may be used to endorse or promote products
14* derived from this software without specific prior written permission.
15*
16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY
17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*
27*/
28using libsecondlife;
29using libsecondlife.Packets;
30using OpenSim.Framework;
31using OpenSim.Framework.Console;
32
33namespace OpenSim.Region.ClientStack
34{
35 public partial class ClientView
36 {
37 protected virtual void RegisterLocalPacketHandlers()
38 {
39 AddLocalPacketHandler(PacketType.LogoutRequest, Logout);
40 AddLocalPacketHandler(PacketType.ViewerEffect, HandleViewerEffect);
41 AddLocalPacketHandler(PacketType.AgentCachedTexture, AgentTextureCached);
42 AddLocalPacketHandler(PacketType.MultipleObjectUpdate, MultipleObjUpdate);
43 }
44
45 private bool HandleViewerEffect(IClientAPI sender, Packet Pack)
46 {
47 ViewerEffectPacket viewer = (ViewerEffectPacket) Pack;
48
49 if (OnViewerEffect != null)
50 {
51 OnViewerEffect(sender, viewer.Effect);
52 }
53
54 return true;
55 }
56
57 protected virtual bool Logout(IClientAPI client, Packet packet)
58 {
59 MainLog.Instance.Verbose("CLIENT", "Got a logout request");
60
61 if (OnLogout != null)
62 {
63 OnLogout(client);
64 }
65
66 return true;
67 }
68
69 protected bool AgentTextureCached(IClientAPI simclient, Packet packet)
70 {
71 //System.Console.WriteLine("texture cached: " + packet.ToString());
72 AgentCachedTexturePacket chechedtex = (AgentCachedTexturePacket) packet;
73 AgentCachedTextureResponsePacket cachedresp = new AgentCachedTextureResponsePacket();
74 cachedresp.AgentData.AgentID = AgentId;
75 cachedresp.AgentData.SessionID = m_sessionId;
76 cachedresp.AgentData.SerialNum = cachedtextureserial;
77 cachedtextureserial++;
78 cachedresp.WearableData =
79 new AgentCachedTextureResponsePacket.WearableDataBlock[chechedtex.WearableData.Length];
80 for (int i = 0; i < chechedtex.WearableData.Length; i++)
81 {
82 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
83 cachedresp.WearableData[i].TextureIndex = chechedtex.WearableData[i].TextureIndex;
84 cachedresp.WearableData[i].TextureID = LLUUID.Zero;
85 cachedresp.WearableData[i].HostName = new byte[0];
86 }
87 OutPacket(cachedresp, ThrottleOutPacketType.Texture);
88 return true;
89 }
90
91 protected bool MultipleObjUpdate(IClientAPI simClient, Packet packet)
92 {
93 MultipleObjectUpdatePacket multipleupdate = (MultipleObjectUpdatePacket) packet;
94 // System.Console.WriteLine("new multi update packet " + multipleupdate.ToString());
95 for (int i = 0; i < multipleupdate.ObjectData.Length; i++)
96 {
97 #region position
98
99 if (multipleupdate.ObjectData[i].Type == 9) //change position
100 {
101 if (OnUpdatePrimGroupPosition != null)
102 {
103 LLVector3 pos = new LLVector3(multipleupdate.ObjectData[i].Data, 0);
104 OnUpdatePrimGroupPosition(multipleupdate.ObjectData[i].ObjectLocalID, pos, this);
105 }
106 }
107 else if (multipleupdate.ObjectData[i].Type == 1) //single item of group change position
108 {
109 if (OnUpdatePrimSinglePosition != null)
110 {
111 LLVector3 pos = new LLVector3(multipleupdate.ObjectData[i].Data, 0);
112 // System.Console.WriteLine("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z);
113 OnUpdatePrimSinglePosition(multipleupdate.ObjectData[i].ObjectLocalID, pos, this);
114 }
115 }
116 #endregion position
117 #region rotation
118
119 else if (multipleupdate.ObjectData[i].Type == 2) // single item of group rotation from tab
120 {
121 if (OnUpdatePrimSingleRotation != null)
122 {
123 LLQuaternion rot = new LLQuaternion(multipleupdate.ObjectData[i].Data, 0, true);
124 //System.Console.WriteLine("new tab rotation is " + rot.X + " , " + rot.Y + " , " + rot.Z + " , " + rot.W);
125 OnUpdatePrimSingleRotation(multipleupdate.ObjectData[i].ObjectLocalID, rot, this);
126 }
127 }
128 else if (multipleupdate.ObjectData[i].Type == 3) // single item of group rotation from mouse
129 {
130 if (OnUpdatePrimSingleRotation != null)
131 {
132 LLQuaternion rot = new LLQuaternion(multipleupdate.ObjectData[i].Data, 12, true);
133 //System.Console.WriteLine("new mouse rotation is " + rot.X + " , " + rot.Y + " , " + rot.Z + " , " + rot.W);
134 OnUpdatePrimSingleRotation(multipleupdate.ObjectData[i].ObjectLocalID, rot, this);
135 }
136 }
137 else if (multipleupdate.ObjectData[i].Type == 10) //group rotation from object tab
138 {
139 if (OnUpdatePrimGroupRotation != null)
140 {
141 LLQuaternion rot = new LLQuaternion(multipleupdate.ObjectData[i].Data, 0, true);
142 // Console.WriteLine("new rotation is " + rot.X + " , " + rot.Y + " , " + rot.Z + " , " + rot.W);
143 OnUpdatePrimGroupRotation(multipleupdate.ObjectData[i].ObjectLocalID, rot, this);
144 }
145 }
146 else if (multipleupdate.ObjectData[i].Type == 11) //group rotation from mouse
147 {
148 if (OnUpdatePrimGroupMouseRotation != null)
149 {
150 LLVector3 pos = new LLVector3(multipleupdate.ObjectData[i].Data, 0);
151 LLQuaternion rot = new LLQuaternion(multipleupdate.ObjectData[i].Data, 12, true);
152 //Console.WriteLine("new rotation position is " + pos.X + " , " + pos.Y + " , " + pos.Z);
153 // Console.WriteLine("new rotation is " + rot.X + " , " + rot.Y + " , " + rot.Z + " , " + rot.W);
154 OnUpdatePrimGroupMouseRotation(multipleupdate.ObjectData[i].ObjectLocalID, pos, rot, this);
155 }
156 }
157 #endregion
158 #region scale
159
160 else if (multipleupdate.ObjectData[i].Type == 13) //group scale from object tab
161 {
162 if (OnUpdatePrimScale != null)
163 {
164 LLVector3 scale = new LLVector3(multipleupdate.ObjectData[i].Data, 12);
165 //Console.WriteLine("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
166 OnUpdatePrimScale(multipleupdate.ObjectData[i].ObjectLocalID, scale, this);
167
168 // Change the position based on scale (for bug number 246)
169 LLVector3 pos = new LLVector3(multipleupdate.ObjectData[i].Data, 0);
170 // System.Console.WriteLine("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z);
171 OnUpdatePrimSinglePosition(multipleupdate.ObjectData[i].ObjectLocalID, pos, this);
172 }
173 }
174 else if (multipleupdate.ObjectData[i].Type == 29) //group scale from mouse
175 {
176 if (OnUpdatePrimScale != null)
177 {
178 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 LLVector3 pos = new LLVector3(multipleupdate.ObjectData[i].Data, 0);
182 OnUpdatePrimSinglePosition(multipleupdate.ObjectData[i].ObjectLocalID, pos, this);
183 }
184 }
185 else if (multipleupdate.ObjectData[i].Type == 5) //single prim scale from object tab
186 {
187 if (OnUpdatePrimScale != null)
188 {
189 LLVector3 scale = new LLVector3(multipleupdate.ObjectData[i].Data, 12);
190 // Console.WriteLine("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
191 OnUpdatePrimScale(multipleupdate.ObjectData[i].ObjectLocalID, scale, this);
192 }
193 }
194 else if (multipleupdate.ObjectData[i].Type == 21) //single prim scale from mouse
195 {
196 if (OnUpdatePrimScale != null)
197 {
198 LLVector3 scale = new LLVector3(multipleupdate.ObjectData[i].Data, 12);
199 // Console.WriteLine("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
200 OnUpdatePrimScale(multipleupdate.ObjectData[i].ObjectLocalID, scale, this);
201 }
202 }
203
204 #endregion
205 }
206 return true;
207 }
208
209 public void RequestMapLayer()
210 {
211 //should be getting the map layer from the grid server
212 //send a layer covering the 800,800 - 1200,1200 area (should be covering the requested area)
213 MapLayerReplyPacket mapReply = new MapLayerReplyPacket();
214 mapReply.AgentData.AgentID = AgentId;
215 mapReply.AgentData.Flags = 0;
216 mapReply.LayerData = new MapLayerReplyPacket.LayerDataBlock[1];
217 mapReply.LayerData[0] = new MapLayerReplyPacket.LayerDataBlock();
218 mapReply.LayerData[0].Bottom = 0;
219 mapReply.LayerData[0].Left = 0;
220 mapReply.LayerData[0].Top = 30000;
221 mapReply.LayerData[0].Right = 30000;
222 mapReply.LayerData[0].ImageID = new LLUUID("00000000-0000-0000-9999-000000000006");
223 OutPacket(mapReply, ThrottleOutPacketType.Land);
224 }
225
226 public void RequestMapBlocks(int minX, int minY, int maxX, int maxY)
227 {
228 /*
229 IList simMapProfiles = m_gridServer.RequestMapBlocks(minX, minY, maxX, maxY);
230 MapBlockReplyPacket mbReply = new MapBlockReplyPacket();
231 mbReply.AgentData.AgentId = this.AgentId;
232 int len;
233 if (simMapProfiles == null)
234 len = 0;
235 else
236 len = simMapProfiles.Count;
237
238 mbReply.Data = new MapBlockReplyPacket.DataBlock[len];
239 int iii;
240 for (iii = 0; iii < len; iii++)
241 {
242 Hashtable mp = (Hashtable)simMapProfiles[iii];
243 mbReply.Data[iii] = new MapBlockReplyPacket.DataBlock();
244 mbReply.Data[iii].Name = System.Text.Encoding.UTF8.GetBytes((string)mp["name"]);
245 mbReply.Data[iii].Access = System.Convert.ToByte(mp["access"]);
246 mbReply.Data[iii].Agents = System.Convert.ToByte(mp["agents"]);
247 mbReply.Data[iii].MapImageID = new LLUUID((string)mp["map-image-id"]);
248 mbReply.Data[iii].RegionFlags = System.Convert.ToUInt32(mp["region-flags"]);
249 mbReply.Data[iii].WaterHeight = System.Convert.ToByte(mp["water-height"]);
250 mbReply.Data[iii].X = System.Convert.ToUInt16(mp["x"]);
251 mbReply.Data[iii].Y = System.Convert.ToUInt16(mp["y"]);
252 }
253 this.OutPacket(mbReply, ThrottleOutPacketType.Land);
254 */
255 }
256 }
257} \ No newline at end of file
diff --git a/OpenSim/Region/ClientStack/ClientView.PacketQueue.cs b/OpenSim/Region/ClientStack/ClientView.PacketQueue.cs
deleted file mode 100644
index d7b86e8..0000000
--- a/OpenSim/Region/ClientStack/ClientView.PacketQueue.cs
+++ /dev/null
@@ -1,373 +0,0 @@
1/*
2* Copyright (c) Contributors, http://opensimulator.org/
3* See CONTRIBUTORS.TXT for a full list of copyright holders.
4*
5* Redistribution and use in source and binary forms, with or without
6* modification, are permitted provided that the following conditions are met:
7* * Redistributions of source code must retain the above copyright
8* notice, this list of conditions and the following disclaimer.
9* * Redistributions in binary form must reproduce the above copyright
10* notice, this list of conditions and the following disclaimer in the
11* documentation and/or other materials provided with the distribution.
12* * Neither the name of the OpenSim Project nor the
13* names of its contributors may be used to endorse or promote products
14* derived from this software without specific prior written permission.
15*
16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY
17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*
27*/
28using System;
29using System.Collections.Generic;
30using System.Net;
31using System.Net.Sockets;
32using System.Timers;
33using libsecondlife;
34using libsecondlife.Packets;
35using OpenSim.Framework;
36using OpenSim.Framework.Console;
37
38namespace OpenSim.Region.ClientStack
39{
40 public partial class ClientView
41 {
42 protected BlockingQueue<QueItem> PacketQueue;
43
44 protected Queue<QueItem> IncomingPacketQueue;
45 protected Queue<QueItem> OutgoingPacketQueue;
46 protected Queue<QueItem> ResendOutgoingPacketQueue;
47 protected Queue<QueItem> LandOutgoingPacketQueue;
48 protected Queue<QueItem> WindOutgoingPacketQueue;
49 protected Queue<QueItem> CloudOutgoingPacketQueue;
50 protected Queue<QueItem> TaskOutgoingPacketQueue;
51 protected Queue<QueItem> TextureOutgoingPacketQueue;
52 protected Queue<QueItem> AssetOutgoingPacketQueue;
53
54 protected Dictionary<uint, uint> PendingAcks = new Dictionary<uint, uint>();
55 protected Dictionary<uint, Packet> NeedAck = new Dictionary<uint, Packet>();
56
57 protected Timer AckTimer;
58 protected uint Sequence = 0;
59 protected object SequenceLock = new object();
60 protected const int MAX_APPENDED_ACKS = 10;
61 protected const int RESEND_TIMEOUT = 4000;
62 protected const int MAX_SEQUENCE = 0xFFFFFF;
63
64 private uint m_circuitCode;
65 public EndPoint userEP;
66
67 protected PacketServer m_networkServer;
68
69 public uint CircuitCode
70 {
71 get { return m_circuitCode; }
72 set { m_circuitCode = value; }
73 }
74
75 protected virtual void ProcessOutPacket(Packet Pack)
76 {
77 // Keep track of when this packet was sent out
78 Pack.TickCount = System.Environment.TickCount;
79
80 if (!Pack.Header.Resent)
81 {
82 // Set the sequence number
83 lock (SequenceLock)
84 {
85 if (Sequence >= MAX_SEQUENCE)
86 {
87 Sequence = 1;
88 }
89 else
90 {
91 Sequence++;
92 }
93
94 Pack.Header.Sequence = Sequence;
95 }
96
97 if (Pack.Header.Reliable) //DIRTY HACK
98 {
99 lock (NeedAck)
100 {
101 if (!NeedAck.ContainsKey(Pack.Header.Sequence))
102 {
103 try
104 {
105 NeedAck.Add(Pack.Header.Sequence, Pack);
106 }
107 catch (Exception e) // HACKY
108 {
109 e.ToString();
110 // Ignore
111 // Seems to throw a exception here occasionally
112 // of 'duplicate key' despite being locked.
113 // !?!?!?
114 }
115 }
116 else
117 {
118 // Client.Log("Attempted to add a duplicate sequence number (" +
119 // packet.Header.Sequence + ") to the NeedAck dictionary for packet type " +
120 // packet.Type.ToString(), Helpers.LogLevel.Warning);
121 }
122 }
123
124 // Don't append ACKs to resent packets, in case that's what was causing the
125 // delivery to fail
126 if (!Pack.Header.Resent)
127 {
128 // Append any ACKs that need to be sent out to this packet
129 lock (PendingAcks)
130 {
131 if (PendingAcks.Count > 0 && PendingAcks.Count < MAX_APPENDED_ACKS &&
132 Pack.Type != PacketType.PacketAck &&
133 Pack.Type != PacketType.LogoutRequest)
134 {
135 Pack.Header.AckList = new uint[PendingAcks.Count];
136 int i = 0;
137
138 foreach (uint ack in PendingAcks.Values)
139 {
140 Pack.Header.AckList[i] = ack;
141 i++;
142 }
143
144 PendingAcks.Clear();
145 Pack.Header.AppendedAcks = true;
146 }
147 }
148 }
149 }
150 }
151
152 byte[] ZeroOutBuffer = new byte[4096];
153 byte[] sendbuffer;
154 sendbuffer = Pack.ToBytes();
155
156 try
157 {
158 if (Pack.Header.Zerocoded)
159 {
160 int packetsize = Helpers.ZeroEncode(sendbuffer, sendbuffer.Length, ZeroOutBuffer);
161 m_networkServer.SendPacketTo(ZeroOutBuffer, packetsize, SocketFlags.None, m_circuitCode); //userEP);
162 }
163 else
164 {
165 m_networkServer.SendPacketTo(sendbuffer, sendbuffer.Length, SocketFlags.None, m_circuitCode);
166 //userEP);
167 }
168 }
169 catch (Exception e)
170 {
171 MainLog.Instance.Warn("client",
172 "ClientView.PacketQueue.cs:ProcessOutPacket() - WARNING: Socket exception occurred on connection " +
173 userEP.ToString() + " - killing thread");
174 MainLog.Instance.Error(e.ToString());
175 KillThread();
176 }
177 }
178
179 public virtual void InPacket(Packet NewPack)
180 {
181 // Handle appended ACKs
182 if (NewPack.Header.AppendedAcks)
183 {
184 lock (NeedAck)
185 {
186 foreach (uint ack in NewPack.Header.AckList)
187 {
188 NeedAck.Remove(ack);
189 }
190 }
191 }
192
193 // Handle PacketAck packets
194 if (NewPack.Type == PacketType.PacketAck)
195 {
196 PacketAckPacket ackPacket = (PacketAckPacket) NewPack;
197
198 lock (NeedAck)
199 {
200 foreach (PacketAckPacket.PacketsBlock block in ackPacket.Packets)
201 {
202 NeedAck.Remove(block.ID);
203 }
204 }
205 }
206 else if ((NewPack.Type == PacketType.StartPingCheck))
207 {
208 //reply to pingcheck
209 StartPingCheckPacket startPing = (StartPingCheckPacket) NewPack;
210 CompletePingCheckPacket endPing = new CompletePingCheckPacket();
211 endPing.PingID.PingID = startPing.PingID.PingID;
212 OutPacket(endPing, ThrottleOutPacketType.Task);
213 }
214 else
215 {
216 QueItem item = new QueItem();
217 item.Packet = NewPack;
218 item.Incoming = true;
219 PacketQueue.Enqueue(item);
220 }
221 }
222
223 private void ThrottleCheck(ref int TypeBytesSent, int Throttle, Queue<QueItem> q, QueItem item)
224 {
225 // The idea.. is if the packet throttle queues are empty
226 // and the client is under throttle for the type. Queue
227 // it up directly. This basically short cuts having to
228 // wait for the timer to fire to put things into the
229 // output queue
230
231 if(q.Count == 0 && TypeBytesSent <= ((int)(Throttle / throttleTimeDivisor)))
232 {
233 bytesSent += item.Packet.ToBytes().Length;
234 TypeBytesSent += item.Packet.ToBytes().Length;
235 PacketQueue.Enqueue(item);
236 }
237 else
238 {
239 q.Enqueue(item);
240 }
241 }
242
243 public virtual void OutPacket(Packet NewPack, ThrottleOutPacketType throttlePacketType)
244 {
245 QueItem item = new QueItem();
246 item.Packet = NewPack;
247 item.Incoming = false;
248 item.throttleType = throttlePacketType; // Packet throttle type
249
250 // The idea.. is if the packet throttle queues are empty and the client is under throttle for the type.
251 // Queue it up directly.
252 switch (throttlePacketType)
253 {
254 case ThrottleOutPacketType.Resend:
255 ThrottleCheck(ref ResendBytesSent, ResendthrottleOutbound, ResendOutgoingPacketQueue, item);
256 break;
257 case ThrottleOutPacketType.Texture:
258 ThrottleCheck(ref TextureBytesSent, TexturethrottleOutbound, TextureOutgoingPacketQueue, item);
259 break;
260 case ThrottleOutPacketType.Task:
261 ThrottleCheck(ref TaskBytesSent, TaskthrottleOutbound, TaskOutgoingPacketQueue, item);
262 break;
263 case ThrottleOutPacketType.Land:
264 ThrottleCheck(ref LandBytesSent, LandthrottleOutbound, LandOutgoingPacketQueue, item);
265 break;
266 case ThrottleOutPacketType.Asset:
267 ThrottleCheck(ref AssetBytesSent, AssetthrottleOutbound, AssetOutgoingPacketQueue, item);
268 break;
269 case ThrottleOutPacketType.Cloud:
270 ThrottleCheck(ref CloudBytesSent, CloudthrottleOutbound, CloudOutgoingPacketQueue, item);
271 break;
272 case ThrottleOutPacketType.Wind:
273 ThrottleCheck(ref WindBytesSent, WindthrottleOutbound, WindOutgoingPacketQueue, item);
274 break;
275
276 default:
277 // Acknowledgements and other such stuff should go directly to the blocking Queue
278 // Throttling them may and likely 'will' be problematic
279 PacketQueue.Enqueue(item);
280 break;
281 }
282 //OutgoingPacketQueue.Enqueue(item);
283 }
284
285 # region Low Level Packet Methods
286
287 protected void ack_pack(Packet Pack)
288 {
289 if (Pack.Header.Reliable)
290 {
291 PacketAckPacket ack_it = new PacketAckPacket();
292 ack_it.Packets = new PacketAckPacket.PacketsBlock[1];
293 ack_it.Packets[0] = new PacketAckPacket.PacketsBlock();
294 ack_it.Packets[0].ID = Pack.Header.Sequence;
295 ack_it.Header.Reliable = false;
296
297 OutPacket(ack_it, ThrottleOutPacketType.Unknown);
298 }
299 /*
300 if (Pack.Header.Reliable)
301 {
302 lock (PendingAcks)
303 {
304 uint sequence = (uint)Pack.Header.Sequence;
305 if (!PendingAcks.ContainsKey(sequence)) { PendingAcks[sequence] = sequence; }
306 }
307 }*/
308 }
309
310 protected void ResendUnacked()
311 {
312 int now = System.Environment.TickCount;
313
314 lock (NeedAck)
315 {
316 foreach (Packet packet in NeedAck.Values)
317 {
318 if ((now - packet.TickCount > RESEND_TIMEOUT) && (!packet.Header.Resent))
319 {
320 MainLog.Instance.Verbose("Resending " + packet.Type.ToString() + " packet, " +
321 (now - packet.TickCount) + "ms have passed");
322
323 packet.Header.Resent = true;
324 OutPacket(packet, ThrottleOutPacketType.Resend);
325 }
326 }
327 }
328 }
329
330 protected void SendAcks()
331 {
332 lock (PendingAcks)
333 {
334 if (PendingAcks.Count > 0)
335 {
336 if (PendingAcks.Count > 250)
337 {
338 // FIXME: Handle the odd case where we have too many pending ACKs queued up
339 MainLog.Instance.Verbose("Too many ACKs queued up!");
340 return;
341 }
342
343 //OpenSim.Framework.Console.MainLog.Instance.WriteLine("Sending PacketAck");
344
345
346 int i = 0;
347 PacketAckPacket acks = new PacketAckPacket();
348 acks.Packets = new PacketAckPacket.PacketsBlock[PendingAcks.Count];
349
350 foreach (uint ack in PendingAcks.Values)
351 {
352 acks.Packets[i] = new PacketAckPacket.PacketsBlock();
353 acks.Packets[i].ID = ack;
354 i++;
355 }
356
357 acks.Header.Reliable = false;
358 OutPacket(acks, ThrottleOutPacketType.Unknown);
359
360 PendingAcks.Clear();
361 }
362 }
363 }
364
365 protected void AckTimer_Elapsed(object sender, ElapsedEventArgs ea)
366 {
367 SendAcks();
368 ResendUnacked();
369 }
370
371 #endregion
372 }
373} \ No newline at end of file
diff --git a/OpenSim/Region/ClientStack/ClientView.ProcessPackets.cs b/OpenSim/Region/ClientStack/ClientView.ProcessPackets.cs
deleted file mode 100644
index f720277..0000000
--- a/OpenSim/Region/ClientStack/ClientView.ProcessPackets.cs
+++ /dev/null
@@ -1,1173 +0,0 @@
1/*
2* Copyright (c) Contributors, http://opensimulator.org/
3* See CONTRIBUTORS.TXT for a full list of copyright holders.
4*
5* Redistribution and use in source and binary forms, with or without
6* modification, are permitted provided that the following conditions are met:
7* * Redistributions of source code must retain the above copyright
8* notice, this list of conditions and the following disclaimer.
9* * Redistributions in binary form must reproduce the above copyright
10* notice, this list of conditions and the following disclaimer in the
11* documentation and/or other materials provided with the distribution.
12* * Neither the name of the OpenSim Project nor the
13* names of its contributors may be used to endorse or promote products
14* derived from this software without specific prior written permission.
15*
16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY
17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*
27*/
28using System;
29using System.Collections.Generic;
30using System.Text;
31using libsecondlife;
32using libsecondlife.Packets;
33using OpenSim.Framework;
34
35namespace OpenSim.Region.ClientStack
36{
37 public partial class ClientView
38 {
39 private int m_moneyBalance;
40
41 public int MoneyBalance
42 {
43 get { return m_moneyBalance; }
44 }
45
46 public bool AddMoney(int debit)
47 {
48 if (m_moneyBalance + debit >= 0)
49 {
50 m_moneyBalance += debit;
51 SendMoneyBalance(LLUUID.Zero, true, Helpers.StringToField("Poof Poof!"), m_moneyBalance);
52 return true;
53 }
54 else
55 {
56 return false;
57 }
58 }
59
60 protected void ProcessInPacket(Packet Pack)
61 {
62 ack_pack(Pack);
63
64 if (ProcessPacketMethod(Pack))
65 {
66 //there is a handler registered that handled this packet type
67 return;
68 }
69 else
70 {
71 Encoding _enc = Encoding.ASCII;
72
73 switch (Pack.Type)
74 {
75 #region Scene/Avatar
76
77 case PacketType.AvatarPropertiesRequest:
78 AvatarPropertiesRequestPacket avatarProperties = (AvatarPropertiesRequestPacket) Pack;
79 if (OnRequestAvatarProperties != null)
80 {
81 OnRequestAvatarProperties(this, avatarProperties.AgentData.AvatarID);
82 }
83 break;
84 case PacketType.ChatFromViewer:
85 ChatFromViewerPacket inchatpack = (ChatFromViewerPacket) Pack;
86
87 string fromName = ""; //ClientAvatar.firstname + " " + ClientAvatar.lastname;
88 byte[] message = inchatpack.ChatData.Message;
89 byte type = inchatpack.ChatData.Type;
90 LLVector3 fromPos = new LLVector3(); // ClientAvatar.Pos;
91 LLUUID fromAgentID = AgentId;
92
93 int channel = inchatpack.ChatData.Channel;
94
95 if (OnChatFromViewer != null)
96 {
97 ChatFromViewerArgs args = new ChatFromViewerArgs();
98 args.Channel = channel;
99 args.From = fromName;
100 args.Message = Helpers.FieldToUTF8String(message);
101 args.Type = (ChatTypeEnum) type;
102 args.Position = fromPos;
103
104 args.Scene = Scene;
105 args.Sender = this;
106
107 OnChatFromViewer(this, args);
108 }
109 break;
110 case PacketType.ImprovedInstantMessage:
111 ImprovedInstantMessagePacket msgpack = (ImprovedInstantMessagePacket) Pack;
112 string IMfromName = Util.FieldToString(msgpack.MessageBlock.FromAgentName);
113 string IMmessage = Helpers.FieldToUTF8String(msgpack.MessageBlock.Message);
114 if (OnInstantMessage != null)
115 {
116 OnInstantMessage(msgpack.AgentData.AgentID, msgpack.AgentData.SessionID,
117 msgpack.MessageBlock.ToAgentID, msgpack.MessageBlock.ID,
118 msgpack.MessageBlock.Timestamp, IMfromName, IMmessage,
119 msgpack.MessageBlock.Dialog);
120 }
121 break;
122 case PacketType.RezObject:
123 RezObjectPacket rezPacket = (RezObjectPacket) Pack;
124 if (OnRezObject != null)
125 {
126 OnRezObject(this, rezPacket.InventoryData.ItemID, rezPacket.RezData.RayEnd);
127 }
128 break;
129 case PacketType.DeRezObject:
130 if (OnDeRezObject != null)
131 {
132 OnDeRezObject(Pack, this);
133 }
134 break;
135 case PacketType.ModifyLand:
136 ModifyLandPacket modify = (ModifyLandPacket) Pack;
137 if (modify.ParcelData.Length > 0)
138 {
139 if (OnModifyTerrain != null)
140 {
141 OnModifyTerrain(modify.ModifyBlock.Height, modify.ModifyBlock.Seconds,
142 modify.ModifyBlock.BrushSize,
143 modify.ModifyBlock.Action, modify.ParcelData[0].North,
144 modify.ParcelData[0].West, this);
145 }
146 }
147 break;
148 case PacketType.RegionHandshakeReply:
149 if (OnRegionHandShakeReply != null)
150 {
151 OnRegionHandShakeReply(this);
152 }
153 break;
154 case PacketType.AgentWearablesRequest:
155 if (OnRequestWearables != null)
156 {
157 OnRequestWearables( );
158 }
159 if (OnRequestAvatarsData != null)
160 {
161 OnRequestAvatarsData(this);
162 }
163 break;
164 case PacketType.AgentSetAppearance:
165 //OpenSim.Framework.Console.MainLog.Instance.Verbose("set appear", Pack.ToString());
166 AgentSetAppearancePacket appear = (AgentSetAppearancePacket) Pack;
167 if (OnSetAppearance != null)
168 {
169 OnSetAppearance(appear.ObjectData.TextureEntry, appear.VisualParam);
170 }
171 break;
172 case PacketType.SetAlwaysRun:
173 SetAlwaysRunPacket run = (SetAlwaysRunPacket)Pack;
174
175 if (OnSetAlwaysRun != null)
176 OnSetAlwaysRun(this,run.AgentData.AlwaysRun);
177
178 break;
179 case PacketType.CompleteAgentMovement:
180 if (OnCompleteMovementToRegion != null)
181 {
182 OnCompleteMovementToRegion();
183 }
184 break;
185 case PacketType.AgentUpdate:
186 if (OnAgentUpdate != null)
187 {
188 AgentUpdatePacket agenUpdate = (AgentUpdatePacket) Pack;
189
190 OnAgentUpdate(this, agenUpdate); //agenUpdate.AgentData.ControlFlags, agenUpdate.AgentData.BodyRotationa);
191 }
192 break;
193 case PacketType.AgentAnimation:
194 AgentAnimationPacket AgentAni = (AgentAnimationPacket) Pack;
195 for (int i = 0; i < AgentAni.AnimationList.Length; i++)
196 {
197 if (AgentAni.AnimationList[i].StartAnim)
198 {
199 if (OnStartAnim != null)
200 {
201 OnStartAnim(this, AgentAni.AnimationList[i].AnimID, 1);
202 }
203 }
204 }
205 break;
206 case PacketType.AgentRequestSit:
207 if (OnAgentRequestSit != null)
208 {
209 AgentRequestSitPacket agentRequestSit = (AgentRequestSitPacket) Pack;
210 OnAgentRequestSit(this, agentRequestSit.AgentData.AgentID,
211 agentRequestSit.TargetObject.TargetID, agentRequestSit.TargetObject.Offset);
212 }
213 break;
214 case PacketType.AgentSit:
215 if (OnAgentSit != null)
216 {
217 AgentSitPacket agentSit = (AgentSitPacket) Pack;
218 OnAgentSit(this, agentSit.AgentData.AgentID);
219 }
220 break;
221 case PacketType.AvatarPickerRequest:
222 AvatarPickerRequestPacket avRequestQuery = (AvatarPickerRequestPacket)Pack;
223 AvatarPickerRequestPacket.AgentDataBlock Requestdata = avRequestQuery.AgentData;
224 AvatarPickerRequestPacket.DataBlock querydata = avRequestQuery.Data;
225 //System.Console.WriteLine("Agent Sends:" + Helpers.FieldToUTF8String(querydata.Name));
226 if (OnAvatarPickerRequest != null)
227 {
228 OnAvatarPickerRequest(this, Requestdata.AgentID, Requestdata.QueryID, Helpers.FieldToUTF8String(querydata.Name));
229 }
230 break;
231 #endregion
232
233 #region Objects/m_sceneObjects
234
235 case PacketType.ObjectLink:
236 //OpenSim.Framework.Console.MainLog.Instance.Verbose( Pack.ToString());
237 ObjectLinkPacket link = (ObjectLinkPacket) Pack;
238 uint parentprimid = 0;
239 List<uint> childrenprims = new List<uint>();
240 if (link.ObjectData.Length > 1)
241 {
242 parentprimid = link.ObjectData[0].ObjectLocalID;
243
244 for (int i = 1; i < link.ObjectData.Length; i++)
245 {
246 childrenprims.Add(link.ObjectData[i].ObjectLocalID);
247 }
248 }
249 if (OnLinkObjects != null)
250 {
251 OnLinkObjects(parentprimid, childrenprims);
252 }
253 break;
254 case PacketType.ObjectDelink:
255 //OpenSim.Framework.Console.MainLog.Instance.Verbose( Pack.ToString());
256 ObjectDelinkPacket delink = (ObjectDelinkPacket) Pack;
257
258 // It appears the prim at index 0 is not always the root prim (for
259 // instance, when one prim of a link set has been edited independently
260 // of the others). Therefore, we'll pass all the ids onto the delink
261 // method for it to decide which is the root.
262 List<uint> prims = new List<uint>();
263 for (int i = 0; i < delink.ObjectData.Length; i++)
264 {
265 prims.Add(delink.ObjectData[i].ObjectLocalID);
266 }
267
268 if (OnDelinkObjects != null)
269 {
270 OnDelinkObjects(prims);
271 }
272
273 break;
274 case PacketType.ObjectAdd:
275 if (OnAddPrim != null)
276 {
277 ObjectAddPacket addPacket = (ObjectAddPacket) Pack;
278 PrimitiveBaseShape shape = GetShapeFromAddPacket(addPacket);
279 OnAddPrim(AgentId, addPacket.ObjectData.RayEnd, addPacket.ObjectData.Rotation, shape);
280 }
281 break;
282 case PacketType.ObjectShape:
283 ObjectShapePacket shapePacket = (ObjectShapePacket) Pack;
284 for (int i = 0; i < shapePacket.ObjectData.Length; i++)
285 {
286 if (OnUpdatePrimShape != null)
287 {
288 OnUpdatePrimShape(shapePacket.ObjectData[i].ObjectLocalID, shapePacket.ObjectData[i]);
289 }
290 }
291 break;
292 case PacketType.ObjectExtraParams:
293 ObjectExtraParamsPacket extraPar = (ObjectExtraParamsPacket) Pack;
294 if (OnUpdateExtraParams != null)
295 {
296 OnUpdateExtraParams(extraPar.ObjectData[0].ObjectLocalID, extraPar.ObjectData[0].ParamType,
297 extraPar.ObjectData[0].ParamInUse, extraPar.ObjectData[0].ParamData);
298 }
299 break;
300 case PacketType.ObjectDuplicate:
301 ObjectDuplicatePacket dupe = (ObjectDuplicatePacket) Pack;
302 ObjectDuplicatePacket.AgentDataBlock AgentandGroupData = dupe.AgentData;
303 for (int i = 0; i < dupe.ObjectData.Length; i++)
304 {
305 if (OnObjectDuplicate != null)
306 {
307 OnObjectDuplicate(dupe.ObjectData[i].ObjectLocalID, dupe.SharedData.Offset,
308 dupe.SharedData.DuplicateFlags, AgentandGroupData.AgentID, AgentandGroupData.GroupID);
309 }
310 }
311
312 break;
313
314 case PacketType.ObjectSelect:
315 ObjectSelectPacket incomingselect = (ObjectSelectPacket) Pack;
316 for (int i = 0; i < incomingselect.ObjectData.Length; i++)
317 {
318 if (OnObjectSelect != null)
319 {
320 OnObjectSelect(incomingselect.ObjectData[i].ObjectLocalID, this);
321 }
322 }
323 break;
324 case PacketType.ObjectDeselect:
325 ObjectDeselectPacket incomingdeselect = (ObjectDeselectPacket) Pack;
326 for (int i = 0; i < incomingdeselect.ObjectData.Length; i++)
327 {
328 if (OnObjectDeselect != null)
329 {
330 OnObjectDeselect(incomingdeselect.ObjectData[i].ObjectLocalID, this);
331 }
332 }
333 break;
334 case PacketType.ObjectFlagUpdate:
335 ObjectFlagUpdatePacket flags = (ObjectFlagUpdatePacket) Pack;
336 if (OnUpdatePrimFlags != null)
337 {
338 OnUpdatePrimFlags(flags.AgentData.ObjectLocalID, Pack, this);
339 }
340 break;
341 case PacketType.ObjectImage:
342 ObjectImagePacket imagePack = (ObjectImagePacket) Pack;
343 for (int i = 0; i < imagePack.ObjectData.Length; i++)
344 {
345 if (OnUpdatePrimTexture != null)
346 {
347 OnUpdatePrimTexture(imagePack.ObjectData[i].ObjectLocalID,
348 imagePack.ObjectData[i].TextureEntry, this);
349 }
350 }
351 break;
352 case PacketType.ObjectGrab:
353 ObjectGrabPacket grab = (ObjectGrabPacket) Pack;
354 if (OnGrabObject != null)
355 {
356 OnGrabObject(grab.ObjectData.LocalID, grab.ObjectData.GrabOffset, this);
357 }
358 break;
359 case PacketType.ObjectGrabUpdate:
360 ObjectGrabUpdatePacket grabUpdate = (ObjectGrabUpdatePacket) Pack;
361 if (OnGrabUpdate != null)
362 {
363 OnGrabUpdate(grabUpdate.ObjectData.ObjectID, grabUpdate.ObjectData.GrabOffsetInitial,
364 grabUpdate.ObjectData.GrabPosition, this);
365 }
366 break;
367 case PacketType.ObjectDeGrab:
368 ObjectDeGrabPacket deGrab = (ObjectDeGrabPacket) Pack;
369 if (OnDeGrabObject != null)
370 {
371 OnDeGrabObject(deGrab.ObjectData.LocalID, this);
372 }
373 break;
374 case PacketType.ObjectDescription:
375 ObjectDescriptionPacket objDes = (ObjectDescriptionPacket) Pack;
376 for (int i = 0; i < objDes.ObjectData.Length; i++)
377 {
378 if (OnObjectDescription != null)
379 {
380 OnObjectDescription(objDes.ObjectData[i].LocalID,
381 enc.GetString(objDes.ObjectData[i].Description));
382 }
383 }
384 break;
385 case PacketType.ObjectName:
386 ObjectNamePacket objName = (ObjectNamePacket) Pack;
387 for (int i = 0; i < objName.ObjectData.Length; i++)
388 {
389 if (OnObjectName != null)
390 {
391 OnObjectName(objName.ObjectData[i].LocalID, enc.GetString(objName.ObjectData[i].Name));
392 }
393 }
394 break;
395 case PacketType.ObjectPermissions:
396 OpenSim.Framework.Console.MainLog.Instance.Verbose("CLIENT", "unhandled packet " + Pack.ToString());
397 break;
398
399 case PacketType.RequestObjectPropertiesFamily:
400 //This powers the little tooltip that appears when you move your mouse over an object
401 RequestObjectPropertiesFamilyPacket packToolTip = (RequestObjectPropertiesFamilyPacket)Pack;
402
403
404 RequestObjectPropertiesFamilyPacket.ObjectDataBlock packObjBlock = packToolTip.ObjectData;
405
406 if (OnRequestObjectPropertiesFamily != null)
407 {
408 OnRequestObjectPropertiesFamily(this, this.m_agentId, packObjBlock.RequestFlags, packObjBlock.ObjectID);
409
410
411 }
412
413 break;
414
415 #endregion
416
417 #region Inventory/Asset/Other related packets
418
419 case PacketType.RequestImage:
420 RequestImagePacket imageRequest = (RequestImagePacket) Pack;
421 //Console.WriteLine("image request: " + Pack.ToString());
422 for (int i = 0; i < imageRequest.RequestImage.Length; i++)
423 {
424 // still working on the Texture download module so for now using old method
425 // TextureRequestArgs args = new TextureRequestArgs();
426 // args.RequestedAssetID = imageRequest.RequestImage[i].Image;
427 // args.DiscardLevel = imageRequest.RequestImage[i].DiscardLevel;
428 // args.PacketNumber = imageRequest.RequestImage[i].Packet;
429
430 // if (OnRequestTexture != null)
431 // {
432 // OnRequestTexture(this, args);
433 // }
434
435 m_assetCache.AddTextureRequest(this, imageRequest.RequestImage[i].Image,
436 imageRequest.RequestImage[i].Packet,
437 imageRequest.RequestImage[i].DiscardLevel);
438 }
439 break;
440 case PacketType.TransferRequest:
441 //Console.WriteLine("ClientView.ProcessPackets.cs:ProcessInPacket() - Got transfer request");
442 TransferRequestPacket transfer = (TransferRequestPacket) Pack;
443 m_assetCache.AddAssetRequest(this, transfer);
444 break;
445 case PacketType.AssetUploadRequest:
446 AssetUploadRequestPacket request = (AssetUploadRequestPacket) Pack;
447 // Console.WriteLine("upload request " + Pack.ToString());
448 // Console.WriteLine("upload request was for assetid: " + request.AssetBlock.TransactionID.Combine(this.SecureSessionID).ToStringHyphenated());
449 if (OnAssetUploadRequest != null)
450 {
451 OnAssetUploadRequest(this, request.AssetBlock.TransactionID.Combine(SecureSessionID),
452 request.AssetBlock.TransactionID, request.AssetBlock.Type,
453 request.AssetBlock.AssetData, request.AssetBlock.StoreLocal);
454 }
455 break;
456 case PacketType.RequestXfer:
457 RequestXferPacket xferReq = (RequestXferPacket) Pack;
458 if (OnRequestXfer != null)
459 {
460 OnRequestXfer(this, xferReq.XferID.ID, Util.FieldToString(xferReq.XferID.Filename));
461 }
462 break;
463 case PacketType.SendXferPacket:
464 SendXferPacketPacket xferRec = (SendXferPacketPacket) Pack;
465 if (OnXferReceive != null)
466 {
467 OnXferReceive(this, xferRec.XferID.ID, xferRec.XferID.Packet, xferRec.DataPacket.Data);
468 }
469 break;
470 case PacketType.ConfirmXferPacket:
471 ConfirmXferPacketPacket confirmXfer = (ConfirmXferPacketPacket) Pack;
472 if (OnConfirmXfer != null)
473 {
474 OnConfirmXfer(this, confirmXfer.XferID.ID, confirmXfer.XferID.Packet);
475 }
476 break;
477 case PacketType.CreateInventoryFolder:
478 if (OnCreateNewInventoryFolder != null)
479 {
480 CreateInventoryFolderPacket invFolder = (CreateInventoryFolderPacket) Pack;
481 OnCreateNewInventoryFolder(this, invFolder.FolderData.FolderID,
482 (ushort) invFolder.FolderData.Type,
483 Util.FieldToString(invFolder.FolderData.Name),
484 invFolder.FolderData.ParentID);
485 }
486 break;
487 case PacketType.CreateInventoryItem:
488 CreateInventoryItemPacket createItem = (CreateInventoryItemPacket) Pack;
489 if (OnCreateNewInventoryItem != null)
490 {
491 OnCreateNewInventoryItem(this, createItem.InventoryBlock.TransactionID,
492 createItem.InventoryBlock.FolderID,
493 createItem.InventoryBlock.CallbackID,
494 Util.FieldToString(createItem.InventoryBlock.Description),
495 Util.FieldToString(createItem.InventoryBlock.Name),
496 createItem.InventoryBlock.InvType,
497 createItem.InventoryBlock.Type,
498 createItem.InventoryBlock.WearableType,
499 createItem.InventoryBlock.NextOwnerMask);
500 }
501 break;
502 case PacketType.FetchInventory:
503 if (OnFetchInventory != null)
504 {
505 FetchInventoryPacket FetchInventory = (FetchInventoryPacket) Pack;
506 for (int i = 0; i < FetchInventory.InventoryData.Length; i++)
507 {
508 OnFetchInventory(this, FetchInventory.InventoryData[i].ItemID,
509 FetchInventory.InventoryData[i].OwnerID);
510 }
511 }
512 break;
513 case PacketType.FetchInventoryDescendents:
514 if (OnFetchInventoryDescendents != null)
515 {
516 FetchInventoryDescendentsPacket Fetch = (FetchInventoryDescendentsPacket) Pack;
517 OnFetchInventoryDescendents(this, Fetch.InventoryData.FolderID, Fetch.InventoryData.OwnerID,
518 Fetch.InventoryData.FetchFolders, Fetch.InventoryData.FetchItems,
519 Fetch.InventoryData.SortOrder);
520 }
521 break;
522 case PacketType.UpdateInventoryItem:
523 UpdateInventoryItemPacket update = (UpdateInventoryItemPacket) Pack;
524 if (OnUpdateInventoryItem != null)
525 {
526 for (int i = 0; i < update.InventoryData.Length; i++)
527 {
528 if (update.InventoryData[i].TransactionID != LLUUID.Zero)
529 {
530 OnUpdateInventoryItem(this, update.InventoryData[i].TransactionID,
531 update.InventoryData[i].TransactionID.Combine(SecureSessionID),
532 update.InventoryData[i].ItemID);
533 }
534 }
535 }
536 //Console.WriteLine(Pack.ToString());
537 /*for (int i = 0; i < update.InventoryData.Length; i++)
538 {
539 if (update.InventoryData[i].TransactionID != LLUUID.Zero)
540 {
541 AssetBase asset = m_assetCache.GetAsset(update.InventoryData[i].TransactionID.Combine(this.SecureSessionID));
542 if (asset != null)
543 {
544 // Console.WriteLine("updating inventory item, found asset" + asset.FullID.ToStringHyphenated() + " already in cache");
545 m_inventoryCache.UpdateInventoryItemAsset(this, update.InventoryData[i].ItemID, asset);
546 }
547 else
548 {
549 asset = this.UploadAssets.AddUploadToAssetCache(update.InventoryData[i].TransactionID);
550 if (asset != null)
551 {
552 //Console.WriteLine("updating inventory item, adding asset" + asset.FullID.ToStringHyphenated() + " to cache");
553 m_inventoryCache.UpdateInventoryItemAsset(this, update.InventoryData[i].ItemID, asset);
554 }
555 else
556 {
557 //Console.WriteLine("trying to update inventory item, but asset is null");
558 }
559 }
560 }
561 else
562 {
563 m_inventoryCache.UpdateInventoryItemDetails(this, update.InventoryData[i].ItemID, update.InventoryData[i]); ;
564 }
565 }*/
566 break;
567 case PacketType.CopyInventoryItem:
568 CopyInventoryItemPacket copyitem = (CopyInventoryItemPacket) Pack;
569 if (OnCopyInventoryItem != null)
570 {
571 foreach (CopyInventoryItemPacket.InventoryDataBlock datablock in copyitem.InventoryData)
572 {
573 OnCopyInventoryItem(this, datablock.CallbackID, datablock.OldAgentID, datablock.OldItemID, datablock.NewFolderID, Util.FieldToString(datablock.NewName));
574 }
575 }
576 break;
577 case PacketType.RequestTaskInventory:
578 RequestTaskInventoryPacket requesttask = (RequestTaskInventoryPacket) Pack;
579 if (OnRequestTaskInventory != null)
580 {
581 OnRequestTaskInventory(this, requesttask.InventoryData.LocalID);
582 }
583 break;
584 case PacketType.UpdateTaskInventory:
585 //Console.WriteLine(Pack.ToString());
586 UpdateTaskInventoryPacket updatetask = (UpdateTaskInventoryPacket) Pack;
587 if (OnUpdateTaskInventory != null)
588 {
589 if (updatetask.UpdateData.Key == 0)
590 {
591 OnUpdateTaskInventory(this, updatetask.InventoryData.ItemID,
592 updatetask.InventoryData.FolderID, updatetask.UpdateData.LocalID);
593 }
594 }
595 break;
596 case PacketType.RemoveTaskInventory:
597 RemoveTaskInventoryPacket removeTask = (RemoveTaskInventoryPacket) Pack;
598 if (OnRemoveTaskItem != null)
599 {
600 OnRemoveTaskItem(this, removeTask.InventoryData.ItemID, removeTask.InventoryData.LocalID);
601 }
602 break;
603 case PacketType.MoveTaskInventory:
604 OpenSim.Framework.Console.MainLog.Instance.Verbose("CLIENT", "unhandled packet " + Pack.ToString());
605 break;
606 case PacketType.RezScript:
607 //Console.WriteLine(Pack.ToString());
608 RezScriptPacket rezScript = (RezScriptPacket) Pack;
609 if (OnRezScript != null)
610 {
611 OnRezScript(this, rezScript.InventoryBlock.ItemID, rezScript.UpdateBlock.ObjectLocalID);
612 }
613 break;
614 case PacketType.MapLayerRequest:
615 RequestMapLayer();
616 break;
617 case PacketType.MapBlockRequest:
618 MapBlockRequestPacket MapRequest = (MapBlockRequestPacket) Pack;
619 if (OnRequestMapBlocks != null)
620 {
621 OnRequestMapBlocks(this, MapRequest.PositionData.MinX, MapRequest.PositionData.MinY,
622 MapRequest.PositionData.MaxX, MapRequest.PositionData.MaxY);
623 }
624 break;
625 case PacketType.MapNameRequest:
626 MapNameRequestPacket map = (MapNameRequestPacket) Pack;
627 string mapName = UTF8Encoding.UTF8.GetString(map.NameData.Name, 0,
628 map.NameData.Name.Length - 1);
629 if (OnMapNameRequest != null)
630 {
631 OnMapNameRequest(this, mapName);
632 }
633 break;
634 case PacketType.TeleportLandmarkRequest:
635 TeleportLandmarkRequestPacket tpReq = (TeleportLandmarkRequestPacket) Pack;
636
637 TeleportStartPacket tpStart = new TeleportStartPacket();
638 tpStart.Info.TeleportFlags = 8; // tp via lm
639 OutPacket(tpStart, ThrottleOutPacketType.Task);
640
641 TeleportProgressPacket tpProgress = new TeleportProgressPacket();
642 tpProgress.Info.Message = (new ASCIIEncoding()).GetBytes("sending_landmark");
643 tpProgress.Info.TeleportFlags = 8;
644 tpProgress.AgentData.AgentID = tpReq.Info.AgentID;
645 OutPacket(tpProgress, ThrottleOutPacketType.Task);
646
647 // Fetch landmark
648 LLUUID lmid = tpReq.Info.LandmarkID;
649 AssetBase lma = m_assetCache.GetAsset(lmid);
650 if (lma != null)
651 {
652 AssetLandmark lm = new AssetLandmark(lma);
653
654 if (lm.RegionID == m_scene.RegionInfo.RegionID)
655 {
656 TeleportLocalPacket tpLocal = new TeleportLocalPacket();
657
658 tpLocal.Info.AgentID = tpReq.Info.AgentID;
659 tpLocal.Info.TeleportFlags = 8; // Teleport via landmark
660 tpLocal.Info.LocationID = 2;
661 tpLocal.Info.Position = lm.Position;
662 OutPacket(tpLocal, ThrottleOutPacketType.Task);
663 }
664 else
665 {
666 TeleportCancelPacket tpCancel = new TeleportCancelPacket();
667 tpCancel.Info.AgentID = tpReq.Info.AgentID;
668 tpCancel.Info.SessionID = tpReq.Info.SessionID;
669 OutPacket(tpCancel, ThrottleOutPacketType.Task);
670 }
671 }
672 else
673 {
674 Console.WriteLine("Cancelling Teleport - fetch asset not yet implemented");
675
676 TeleportCancelPacket tpCancel = new TeleportCancelPacket();
677 tpCancel.Info.AgentID = tpReq.Info.AgentID;
678 tpCancel.Info.SessionID = tpReq.Info.SessionID;
679 OutPacket(tpCancel, ThrottleOutPacketType.Task);
680 }
681 break;
682 case PacketType.TeleportLocationRequest:
683 TeleportLocationRequestPacket tpLocReq = (TeleportLocationRequestPacket) Pack;
684 // Console.WriteLine(tpLocReq.ToString());
685
686 if (OnTeleportLocationRequest != null)
687 {
688 OnTeleportLocationRequest(this, tpLocReq.Info.RegionHandle, tpLocReq.Info.Position,
689 tpLocReq.Info.LookAt, 16);
690 }
691 else
692 {
693 //no event handler so cancel request
694 TeleportCancelPacket tpCancel = new TeleportCancelPacket();
695 tpCancel.Info.SessionID = tpLocReq.AgentData.SessionID;
696 tpCancel.Info.AgentID = tpLocReq.AgentData.AgentID;
697 OutPacket(tpCancel, ThrottleOutPacketType.Task);
698 }
699 break;
700
701 #endregion
702
703 case PacketType.MoneyBalanceRequest:
704 SendMoneyBalance(LLUUID.Zero, true, new byte[0], MoneyBalance);
705 break;
706 case PacketType.UUIDNameRequest:
707 UUIDNameRequestPacket incoming = (UUIDNameRequestPacket) Pack;
708 foreach (UUIDNameRequestPacket.UUIDNameBlockBlock UUIDBlock in incoming.UUIDNameBlock)
709 {
710 OnNameFromUUIDRequest(UUIDBlock.ID, this);
711 }
712 break;
713
714 #region Parcel related packets
715
716 case PacketType.ParcelPropertiesRequest:
717 ParcelPropertiesRequestPacket propertiesRequest = (ParcelPropertiesRequestPacket) Pack;
718 if (OnParcelPropertiesRequest != null)
719 {
720 OnParcelPropertiesRequest((int) Math.Round(propertiesRequest.ParcelData.West),
721 (int) Math.Round(propertiesRequest.ParcelData.South),
722 (int) Math.Round(propertiesRequest.ParcelData.East),
723 (int) Math.Round(propertiesRequest.ParcelData.North),
724 propertiesRequest.ParcelData.SequenceID,
725 propertiesRequest.ParcelData.SnapSelection, this);
726 }
727 break;
728 case PacketType.ParcelDivide:
729 ParcelDividePacket landDivide = (ParcelDividePacket) Pack;
730 if (OnParcelDivideRequest != null)
731 {
732 OnParcelDivideRequest((int) Math.Round(landDivide.ParcelData.West),
733 (int) Math.Round(landDivide.ParcelData.South),
734 (int) Math.Round(landDivide.ParcelData.East),
735 (int) Math.Round(landDivide.ParcelData.North), this);
736 }
737 break;
738 case PacketType.ParcelJoin:
739 ParcelJoinPacket landJoin = (ParcelJoinPacket) Pack;
740 if (OnParcelJoinRequest != null)
741 {
742 OnParcelJoinRequest((int) Math.Round(landJoin.ParcelData.West),
743 (int) Math.Round(landJoin.ParcelData.South),
744 (int) Math.Round(landJoin.ParcelData.East),
745 (int) Math.Round(landJoin.ParcelData.North), this);
746 }
747 break;
748 case PacketType.ParcelPropertiesUpdate:
749 ParcelPropertiesUpdatePacket updatePacket = (ParcelPropertiesUpdatePacket) Pack;
750 if (OnParcelPropertiesUpdateRequest != null)
751 {
752 OnParcelPropertiesUpdateRequest(updatePacket, this);
753 }
754 break;
755 case PacketType.ParcelSelectObjects:
756 ParcelSelectObjectsPacket selectPacket = (ParcelSelectObjectsPacket) Pack;
757 if (OnParcelSelectObjects != null)
758 {
759 OnParcelSelectObjects(selectPacket.ParcelData.LocalID,
760 Convert.ToInt32(selectPacket.ParcelData.ReturnType), this);
761 }
762 break;
763 case PacketType.ParcelObjectOwnersRequest:
764 //System.Console.WriteLine(Pack.ToString());
765 ParcelObjectOwnersRequestPacket reqPacket = (ParcelObjectOwnersRequestPacket) Pack;
766 if (OnParcelObjectOwnerRequest != null)
767 {
768 OnParcelObjectOwnerRequest(reqPacket.ParcelData.LocalID, this);
769 }
770 break;
771
772 #endregion
773
774 #region Estate Packets
775
776 case PacketType.EstateOwnerMessage:
777 EstateOwnerMessagePacket messagePacket = (EstateOwnerMessagePacket) Pack;
778 if (OnEstateOwnerMessage != null)
779 {
780 OnEstateOwnerMessage(messagePacket, this);
781 }
782 break;
783
784 case PacketType.AgentThrottle:
785
786 //OpenSim.Framework.Console.MainLog.Instance.Verbose("CLIENT", "unhandled packet " + Pack.ToString());
787
788 AgentThrottlePacket atpack = (AgentThrottlePacket)Pack;
789
790 byte[] throttle = atpack.Throttle.Throttles;
791 int tResend = -1;
792 int tLand = -1;
793 int tWind = -1;
794 int tCloud = -1;
795 int tTask = -1;
796 int tTexture = -1;
797 int tAsset = -1;
798 int tall = -1;
799 int singlefloat = 4;
800
801 //Agent Throttle Block contains 7 single floatingpoint values.
802 int j = 0;
803
804 // Some Systems may be big endian...
805 // it might be smart to do this check more often...
806 if (!BitConverter.IsLittleEndian)
807 for (int i = 0; i < 7; i++)
808 Array.Reverse(throttle, j + i * singlefloat, singlefloat);
809
810 // values gotten from libsecondlife.org/wiki/Throttle. Thanks MW_
811 // bytes
812 // Convert to integer, since.. the full fp space isn't used.
813 tResend = (int)BitConverter.ToSingle(throttle, j);
814 j += singlefloat;
815 tLand = (int)BitConverter.ToSingle(throttle, j);
816 j += singlefloat;
817 tWind = (int)BitConverter.ToSingle(throttle, j);
818 j += singlefloat;
819 tCloud = (int)BitConverter.ToSingle(throttle, j);
820 j += singlefloat;
821 tTask = (int)BitConverter.ToSingle(throttle, j);
822 j += singlefloat;
823 tTexture = (int)BitConverter.ToSingle(throttle, j);
824 j += singlefloat;
825 tAsset = (int)BitConverter.ToSingle(throttle, j);
826
827 tall = tResend + tLand + tWind + tCloud + tTask + tTexture + tAsset;
828 /*
829 OpenSim.Framework.Console.MainLog.Instance.Verbose("CLIENT", "Client AgentThrottle - Got throttle:resendbytes=" + tResend +
830 " landbytes=" + tLand +
831 " windbytes=" + tWind +
832 " cloudbytes=" + tCloud +
833 " taskbytes=" + tTask +
834 " texturebytes=" + tTexture +
835 " Assetbytes=" + tAsset +
836 " Allbytes=" + tall);
837 */
838
839 // Total Sanity
840 // Make sure that the client sent sane total values.
841
842 // If the client didn't send acceptable values....
843 // Scale the clients values down until they are acceptable.
844
845 if (tall <= throttleOutboundMax)
846 {
847 // Sanity
848 // Making sure the client sends sane values
849 // This gives us a measure of control of the comms
850 // Check Max of Type
851 // Then Check Min of type
852
853 // Resend throttle
854 if (tResend <= ResendthrottleMAX)
855 ResendthrottleOutbound = tResend;
856
857 if (tResend < ResendthrottleMin)
858 ResendthrottleOutbound = ResendthrottleMin;
859
860 // Land throttle
861 if (tLand <= LandthrottleMax)
862 LandthrottleOutbound = tLand;
863
864 if (tLand < LandthrottleMin)
865 LandthrottleOutbound = LandthrottleMin;
866
867 // Wind throttle
868 if (tWind <= WindthrottleMax)
869 WindthrottleOutbound = tWind;
870
871 if (tWind < WindthrottleMin)
872 WindthrottleOutbound = WindthrottleMin;
873
874 // Cloud throttle
875 if (tCloud <= CloudthrottleMax)
876 CloudthrottleOutbound = tCloud;
877
878 if (tCloud < CloudthrottleMin)
879 CloudthrottleOutbound = CloudthrottleMin;
880
881 // Task throttle
882 if (tTask <= TaskthrottleMax)
883 TaskthrottleOutbound = tTask;
884
885 if (tTask < TaskthrottleMin)
886 TaskthrottleOutbound = TaskthrottleMin;
887
888 // Texture throttle
889 if (tTexture <= TexturethrottleMax)
890 TexturethrottleOutbound = tTexture;
891
892 if (tTexture < TexturethrottleMin)
893 TexturethrottleOutbound = TexturethrottleMin;
894
895 //Asset throttle
896 if (tAsset <= AssetthrottleMax)
897 AssetthrottleOutbound = tAsset;
898
899 if (tAsset < AssetthrottleMin)
900 AssetthrottleOutbound = AssetthrottleMin;
901
902 /* OpenSim.Framework.Console.MainLog.Instance.Verbose("THROTTLE", "Using:resendbytes=" + ResendthrottleOutbound +
903 " landbytes=" + LandthrottleOutbound +
904 " windbytes=" + WindthrottleOutbound +
905 " cloudbytes=" + CloudthrottleOutbound +
906 " taskbytes=" + TaskthrottleOutbound +
907 " texturebytes=" + TexturethrottleOutbound +
908 " Assetbytes=" + AssetthrottleOutbound +
909 " Allbytes=" + tall);
910 */
911 }
912 else
913 {
914 // The client didn't send acceptable values..
915 // so it's our job now to turn them into acceptable values
916 // We're going to first scale the values down
917 // After that we're going to check if the scaled values are sane
918
919 // We're going to be dividing by a user value.. so make sure
920 // we don't get a divide by zero error.
921 if (tall > 0)
922 {
923 // Find out the percentage of all communications
924 // the client requests for each type. We'll keep resend at
925 // it's client recommended level (won't scale it down)
926 // unless it's beyond sane values itself.
927
928 if (tResend <= ResendthrottleMAX)
929 {
930 // This is nexted because we only want to re-set the values
931 // the packet throttler uses once.
932
933 if (tResend >= ResendthrottleMin)
934 {
935 ResendthrottleOutbound = tResend;
936 }
937 else
938 {
939 ResendthrottleOutbound = ResendthrottleMin;
940 }
941 }
942 else
943 {
944 ResendthrottleOutbound = ResendthrottleMAX;
945 }
946
947
948 // Getting Percentages of communication for each type of data
949 float LandPercent = (float)(tLand / tall);
950 float WindPercent = (float)(tWind / tall);
951 float CloudPercent = (float)(tCloud / tall);
952 float TaskPercent = (float)(tTask / tall);
953 float TexturePercent = (float)(tTexture / tall);
954 float AssetPercent = (float)(tAsset / tall);
955
956 // Okay.. now we've got the percentages of total communication.
957 // Apply them to a new max total
958
959 int tLandResult = (int)(LandPercent * throttleOutboundMax);
960 int tWindResult = (int)(WindPercent * throttleOutboundMax);
961 int tCloudResult = (int)(CloudPercent * throttleOutboundMax);
962 int tTaskResult = (int)(TaskPercent * throttleOutboundMax);
963 int tTextureResult = (int)(TexturePercent * throttleOutboundMax);
964 int tAssetResult = (int)(AssetPercent * throttleOutboundMax);
965
966 // Now we have to check our scaled values for sanity
967
968 // Check Max of Type
969 // Then Check Min of type
970
971 // Land throttle
972 if (tLandResult <= LandthrottleMax)
973 LandthrottleOutbound = tLandResult;
974
975 if (tLandResult < LandthrottleMin)
976 LandthrottleOutbound = LandthrottleMin;
977
978 // Wind throttle
979 if (tWindResult <= WindthrottleMax)
980 WindthrottleOutbound = tWindResult;
981
982 if (tWindResult < WindthrottleMin)
983 WindthrottleOutbound = WindthrottleMin;
984
985 // Cloud throttle
986 if (tCloudResult <= CloudthrottleMax)
987 CloudthrottleOutbound = tCloudResult;
988
989 if (tCloudResult < CloudthrottleMin)
990 CloudthrottleOutbound = CloudthrottleMin;
991
992 // Task throttle
993 if (tTaskResult <= TaskthrottleMax)
994 TaskthrottleOutbound = tTaskResult;
995
996 if (tTaskResult < TaskthrottleMin)
997 TaskthrottleOutbound = TaskthrottleMin;
998
999 // Texture throttle
1000 if (tTextureResult <= TexturethrottleMax)
1001 TexturethrottleOutbound = tTextureResult;
1002
1003 if (tTextureResult < TexturethrottleMin)
1004 TexturethrottleOutbound = TexturethrottleMin;
1005
1006 //Asset throttle
1007 if (tAssetResult <= AssetthrottleMax)
1008 AssetthrottleOutbound = tAssetResult;
1009
1010 if (tAssetResult < AssetthrottleMin)
1011 AssetthrottleOutbound = AssetthrottleMin;
1012
1013 /* OpenSim.Framework.Console.MainLog.Instance.Verbose("THROTTLE", "Using:resendbytes=" + ResendthrottleOutbound +
1014 " landbytes=" + LandthrottleOutbound +
1015 " windbytes=" + WindthrottleOutbound +
1016 " cloudbytes=" + CloudthrottleOutbound +
1017 " taskbytes=" + TaskthrottleOutbound +
1018 " texturebytes=" + TexturethrottleOutbound +
1019 " Assetbytes=" + AssetthrottleOutbound +
1020 " Allbytes=" + tall);
1021 */
1022
1023 }
1024 else
1025 {
1026
1027 // The client sent a stupid value..
1028 // We're going to set the throttles to the minimum possible
1029 ResendthrottleOutbound = ResendthrottleMin;
1030 LandthrottleOutbound = LandthrottleMin;
1031 WindthrottleOutbound = WindthrottleMin;
1032 CloudthrottleOutbound = CloudthrottleMin;
1033 TaskthrottleOutbound = TaskthrottleMin;
1034 TexturethrottleOutbound = TexturethrottleMin;
1035 AssetthrottleOutbound = AssetthrottleMin;
1036 OpenSim.Framework.Console.MainLog.Instance.Verbose("THROTTLE", "ClientSentBadThrottle Using:resendbytes=" + ResendthrottleOutbound +
1037 " landbytes=" + LandthrottleOutbound +
1038 " windbytes=" + WindthrottleOutbound +
1039 " cloudbytes=" + CloudthrottleOutbound +
1040 " taskbytes=" + TaskthrottleOutbound +
1041 " texturebytes=" + TexturethrottleOutbound +
1042 " Assetbytes=" + AssetthrottleOutbound +
1043 " Allbytes=" + tall);
1044 }
1045
1046 }
1047 // Reset Client Throttles
1048 // This has the effect of 'wiggling the slider
1049 // causes prim and stuck textures that didn't download to download
1050
1051 ResendBytesSent = 0;
1052 LandBytesSent = 0;
1053 WindBytesSent = 0;
1054 CloudBytesSent = 0;
1055 TaskBytesSent = 0;
1056 AssetBytesSent = 0;
1057 TextureBytesSent = 0;
1058
1059 //Yay, we've finally handled the agent Throttle packet!
1060
1061
1062
1063 break;
1064
1065 #endregion
1066
1067 #region unimplemented handlers
1068 case PacketType.RequestGodlikePowers:
1069 RequestGodlikePowersPacket rglpPack = (RequestGodlikePowersPacket) Pack;
1070 RequestGodlikePowersPacket.RequestBlockBlock rblock = rglpPack.RequestBlock;
1071 LLUUID token = rblock.Token;
1072 RequestGodlikePowersPacket.AgentDataBlock ablock = rglpPack.AgentData;
1073
1074 OnRequestGodlikePowers(ablock.AgentID, ablock.SessionID, token, this);
1075
1076 break;
1077 case PacketType.GodKickUser:
1078 OpenSim.Framework.Console.MainLog.Instance.Verbose("CLIENT", "unhandled packet " + Pack.ToString());
1079
1080 GodKickUserPacket gkupack = (GodKickUserPacket) Pack;
1081
1082 if (gkupack.UserInfo.GodSessionID == SessionId && this.AgentId == gkupack.UserInfo.GodID)
1083 {
1084 OnGodKickUser(gkupack.UserInfo.GodID, gkupack.UserInfo.GodSessionID, gkupack.UserInfo.AgentID, (uint) 0, gkupack.UserInfo.Reason);
1085 }
1086 else
1087 {
1088 SendAgentAlertMessage("Kick request denied", false);
1089 }
1090 //KickUserPacket kupack = new KickUserPacket();
1091 //KickUserPacket.UserInfoBlock kupackib = kupack.UserInfo;
1092
1093 //kupack.UserInfo.AgentID = gkupack.UserInfo.AgentID;
1094 //kupack.UserInfo.SessionID = gkupack.UserInfo.GodSessionID;
1095
1096 //kupack.TargetBlock.TargetIP = (uint)0;
1097 //kupack.TargetBlock.TargetPort = (ushort)0;
1098 //kupack.UserInfo.Reason = gkupack.UserInfo.Reason;
1099
1100
1101 //OutPacket(kupack, ThrottleOutPacketType.Task);
1102 break;
1103
1104 case PacketType.StartPingCheck:
1105 // Send the client the ping response back
1106 // Pass the same PingID in the matching packet
1107 // Handled In the packet processing
1108 OpenSim.Framework.Console.MainLog.Instance.Debug("CLIENT", "possibly unhandled packet " + Pack.ToString());
1109 break;
1110 case PacketType.CompletePingCheck:
1111 // Parhaps this should be processed on the Sim to determine whether or not to drop a dead client
1112 // Dumping it to the verbose console until it's handled properly.
1113
1114 OpenSim.Framework.Console.MainLog.Instance.Verbose("CLIENT", "unhandled packet " + Pack.ToString());
1115 break;
1116 case PacketType.AgentIsNowWearing:
1117 // AgentIsNowWearingPacket wear = (AgentIsNowWearingPacket)Pack;
1118 OpenSim.Framework.Console.MainLog.Instance.Verbose("CLIENT", "unhandled packet " + Pack.ToString());
1119 break;
1120 case PacketType.ObjectScale:
1121 OpenSim.Framework.Console.MainLog.Instance.Verbose("CLIENT", "unhandled packet " + Pack.ToString());
1122 break;
1123 default:
1124 OpenSim.Framework.Console.MainLog.Instance.Verbose("CLIENT", "unhandled packet " + Pack.ToString());
1125 break;
1126
1127 #endregion
1128 }
1129 }
1130 }
1131
1132 private static PrimitiveBaseShape GetShapeFromAddPacket(ObjectAddPacket addPacket)
1133 {
1134 PrimitiveBaseShape shape = new PrimitiveBaseShape();
1135
1136 shape.PCode = addPacket.ObjectData.PCode;
1137 shape.PathBegin = addPacket.ObjectData.PathBegin;
1138 shape.PathEnd = addPacket.ObjectData.PathEnd;
1139 shape.PathScaleX = addPacket.ObjectData.PathScaleX;
1140 shape.PathScaleY = addPacket.ObjectData.PathScaleY;
1141 shape.PathShearX = addPacket.ObjectData.PathShearX;
1142 shape.PathShearY = addPacket.ObjectData.PathShearY;
1143 shape.PathSkew = addPacket.ObjectData.PathSkew;
1144 shape.ProfileBegin = addPacket.ObjectData.ProfileBegin;
1145 shape.ProfileEnd = addPacket.ObjectData.ProfileEnd;
1146 shape.Scale = addPacket.ObjectData.Scale;
1147 shape.PathCurve = addPacket.ObjectData.PathCurve;
1148 shape.ProfileCurve = addPacket.ObjectData.ProfileCurve;
1149 shape.ProfileHollow = addPacket.ObjectData.ProfileHollow;
1150 shape.PathRadiusOffset = addPacket.ObjectData.PathRadiusOffset;
1151 shape.PathRevolutions = addPacket.ObjectData.PathRevolutions;
1152 shape.PathTaperX = addPacket.ObjectData.PathTaperX;
1153 shape.PathTaperY = addPacket.ObjectData.PathTaperY;
1154 shape.PathTwist = addPacket.ObjectData.PathTwist;
1155 shape.PathTwistBegin = addPacket.ObjectData.PathTwistBegin;
1156 LLObject.TextureEntry ntex = new LLObject.TextureEntry(new LLUUID("00000000-0000-0000-9999-000000000005"));
1157 shape.TextureEntry = ntex.ToBytes();
1158 return shape;
1159 }
1160
1161 public void SendLogoutPacket()
1162 {
1163 LogoutReplyPacket logReply = new LogoutReplyPacket();
1164 logReply.AgentData.AgentID = AgentId;
1165 logReply.AgentData.SessionID = SessionId;
1166 logReply.InventoryData = new LogoutReplyPacket.InventoryDataBlock[1];
1167 logReply.InventoryData[0] = new LogoutReplyPacket.InventoryDataBlock();
1168 logReply.InventoryData[0].ItemID = LLUUID.Zero;
1169
1170 OutPacket(logReply, ThrottleOutPacketType.Task);
1171 }
1172 }
1173}
diff --git a/OpenSim/Region/ClientStack/ClientView.cs b/OpenSim/Region/ClientStack/ClientView.cs
index 28692bb..0933453 100644
--- a/OpenSim/Region/ClientStack/ClientView.cs
+++ b/OpenSim/Region/ClientStack/ClientView.cs
@@ -28,9 +28,11 @@
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Net; 30using System.Net;
31using System.Net.Sockets;
31using System.Text; 32using System.Text;
32using System.Threading; 33using System.Threading;
33using System.Timers; 34using System.Timers;
35using Axiom.Math;
34using libsecondlife; 36using libsecondlife;
35using libsecondlife.Packets; 37using libsecondlife.Packets;
36using OpenSim.Framework; 38using OpenSim.Framework;
@@ -46,7 +48,7 @@ namespace OpenSim.Region.ClientStack
46 /// Handles new client connections 48 /// Handles new client connections
47 /// Constructor takes a single Packet and authenticates everything 49 /// Constructor takes a single Packet and authenticates everything
48 /// </summary> 50 /// </summary>
49 public partial class ClientView : IClientAPI 51 public class ClientView : IClientAPI
50 { 52 {
51 public static TerrainManager TerrainManager; 53 public static TerrainManager TerrainManager;
52 54
@@ -552,5 +554,3092 @@ namespace OpenSim.Region.ClientStack
552 { 554 {
553 ClientThread.Abort(); 555 ClientThread.Abort();
554 } 556 }
557
558 // Previously ClientView.API partial class
559 public event Action<IClientAPI> OnLogout;
560 public event Action<IClientAPI> OnConnectionClosed;
561 public event ViewerEffectEventHandler OnViewerEffect;
562 public event ImprovedInstantMessage OnInstantMessage;
563 public event ChatFromViewer OnChatFromViewer;
564 public event TextureRequest OnRequestTexture;
565 public event RezObject OnRezObject;
566 public event GenericCall4 OnDeRezObject;
567 public event ModifyTerrain OnModifyTerrain;
568 public event Action<IClientAPI> OnRegionHandShakeReply;
569 public event GenericCall2 OnRequestWearables;
570 public event SetAppearance OnSetAppearance;
571 public event GenericCall2 OnCompleteMovementToRegion;
572 public event UpdateAgent OnAgentUpdate;
573 public event AgentRequestSit OnAgentRequestSit;
574 public event AgentSit OnAgentSit;
575 public event AvatarPickerRequest OnAvatarPickerRequest;
576 public event StartAnim OnStartAnim;
577 public event Action<IClientAPI> OnRequestAvatarsData;
578 public event LinkObjects OnLinkObjects;
579 public event DelinkObjects OnDelinkObjects;
580 public event UpdateVector OnGrabObject;
581 public event ObjectSelect OnDeGrabObject;
582 public event ObjectDuplicate OnObjectDuplicate;
583 public event MoveObject OnGrabUpdate;
584 public event AddNewPrim OnAddPrim;
585 public event RequestGodlikePowers OnRequestGodlikePowers;
586 public event GodKickUser OnGodKickUser;
587 public event ObjectExtraParams OnUpdateExtraParams;
588 public event UpdateShape OnUpdatePrimShape;
589 public event ObjectSelect OnObjectSelect;
590 public event ObjectDeselect OnObjectDeselect;
591 public event GenericCall7 OnObjectDescription;
592 public event GenericCall7 OnObjectName;
593 public event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily;
594 public event UpdatePrimFlags OnUpdatePrimFlags;
595 public event UpdatePrimTexture OnUpdatePrimTexture;
596 public event UpdateVector OnUpdatePrimGroupPosition;
597 public event UpdateVector OnUpdatePrimSinglePosition;
598 public event UpdatePrimRotation OnUpdatePrimGroupRotation;
599 public event UpdatePrimSingleRotation OnUpdatePrimSingleRotation;
600 public event UpdatePrimGroupRotation OnUpdatePrimGroupMouseRotation;
601 public event UpdateVector OnUpdatePrimScale;
602 public event StatusChange OnChildAgentStatus;
603 public event GenericCall2 OnStopMovement;
604 public event Action<LLUUID> OnRemoveAvatar;
605 public event RequestMapBlocks OnRequestMapBlocks;
606 public event RequestMapName OnMapNameRequest;
607 public event TeleportLocationRequest OnTeleportLocationRequest;
608 public event DisconnectUser OnDisconnectUser;
609 public event RequestAvatarProperties OnRequestAvatarProperties;
610 public event SetAlwaysRun OnSetAlwaysRun;
611
612 public event CreateNewInventoryItem OnCreateNewInventoryItem;
613 public event CreateInventoryFolder OnCreateNewInventoryFolder;
614 public event FetchInventoryDescendents OnFetchInventoryDescendents;
615 public event FetchInventory OnFetchInventory;
616 public event RequestTaskInventory OnRequestTaskInventory;
617 public event UpdateInventoryItemTransaction OnUpdateInventoryItem;
618 public event CopyInventoryItem OnCopyInventoryItem;
619 public event UDPAssetUploadRequest OnAssetUploadRequest;
620 public event XferReceive OnXferReceive;
621 public event RequestXfer OnRequestXfer;
622 public event ConfirmXfer OnConfirmXfer;
623 public event RezScript OnRezScript;
624 public event UpdateTaskInventory OnUpdateTaskInventory;
625 public event RemoveTaskInventory OnRemoveTaskItem;
626
627 public event UUIDNameRequest OnNameFromUUIDRequest;
628
629 public event ParcelPropertiesRequest OnParcelPropertiesRequest;
630 public event ParcelDivideRequest OnParcelDivideRequest;
631 public event ParcelJoinRequest OnParcelJoinRequest;
632 public event ParcelPropertiesUpdateRequest OnParcelPropertiesUpdateRequest;
633 public event ParcelSelectObjects OnParcelSelectObjects;
634 public event ParcelObjectOwnerRequest OnParcelObjectOwnerRequest;
635 public event EstateOwnerMessageRequest OnEstateOwnerMessage;
636
637 /// <summary>
638 ///
639 /// </summary>
640 public LLVector3 StartPos
641 {
642 get { return startpos; }
643 set { startpos = value; }
644 }
645
646 /// <summary>
647 ///
648 /// </summary>
649 private LLUUID m_agentId;
650
651 public LLUUID AgentId
652 {
653 get { return m_agentId; }
654 }
655
656 /// <summary>
657 ///
658 /// </summary>
659 public string FirstName
660 {
661 get { return firstName; }
662 }
663
664 /// <summary>
665 ///
666 /// </summary>
667 public string LastName
668 {
669 get { return lastName; }
670 }
671
672 #region Scene/Avatar to Client
673
674 /// <summary>
675 ///
676 /// </summary>
677 /// <param name="regionInfo"></param>
678 public void SendRegionHandshake(RegionInfo regionInfo)
679 {
680 Encoding _enc = Encoding.ASCII;
681 RegionHandshakePacket handshake = new RegionHandshakePacket();
682
683 handshake.RegionInfo.BillableFactor = regionInfo.EstateSettings.billableFactor;
684 handshake.RegionInfo.IsEstateManager = false;
685 handshake.RegionInfo.TerrainHeightRange00 = regionInfo.EstateSettings.terrainHeightRange0;
686 handshake.RegionInfo.TerrainHeightRange01 = regionInfo.EstateSettings.terrainHeightRange1;
687 handshake.RegionInfo.TerrainHeightRange10 = regionInfo.EstateSettings.terrainHeightRange2;
688 handshake.RegionInfo.TerrainHeightRange11 = regionInfo.EstateSettings.terrainHeightRange3;
689 handshake.RegionInfo.TerrainStartHeight00 = regionInfo.EstateSettings.terrainStartHeight0;
690 handshake.RegionInfo.TerrainStartHeight01 = regionInfo.EstateSettings.terrainStartHeight1;
691 handshake.RegionInfo.TerrainStartHeight10 = regionInfo.EstateSettings.terrainStartHeight2;
692 handshake.RegionInfo.TerrainStartHeight11 = regionInfo.EstateSettings.terrainStartHeight3;
693 handshake.RegionInfo.SimAccess = (byte) regionInfo.EstateSettings.simAccess;
694 handshake.RegionInfo.WaterHeight = regionInfo.EstateSettings.waterHeight;
695
696
697 handshake.RegionInfo.RegionFlags = (uint) regionInfo.EstateSettings.regionFlags;
698
699 handshake.RegionInfo.SimName = _enc.GetBytes(regionInfo.RegionName + "\0");
700 handshake.RegionInfo.SimOwner = regionInfo.MasterAvatarAssignedUUID;
701 handshake.RegionInfo.TerrainBase0 = regionInfo.EstateSettings.terrainBase0;
702 handshake.RegionInfo.TerrainBase1 = regionInfo.EstateSettings.terrainBase1;
703 handshake.RegionInfo.TerrainBase2 = regionInfo.EstateSettings.terrainBase2;
704 handshake.RegionInfo.TerrainBase3 = regionInfo.EstateSettings.terrainBase3;
705 handshake.RegionInfo.TerrainDetail0 = regionInfo.EstateSettings.terrainDetail0;
706 handshake.RegionInfo.TerrainDetail1 = regionInfo.EstateSettings.terrainDetail1;
707 handshake.RegionInfo.TerrainDetail2 = regionInfo.EstateSettings.terrainDetail2;
708 handshake.RegionInfo.TerrainDetail3 = regionInfo.EstateSettings.terrainDetail3;
709 handshake.RegionInfo.CacheID = LLUUID.Random(); //I guess this is for the client to remember an old setting?
710
711 OutPacket(handshake, ThrottleOutPacketType.Task);
712 }
713
714 /// <summary>
715 ///
716 /// </summary>
717 /// <param name="regInfo"></param>
718 public void MoveAgentIntoRegion(RegionInfo regInfo, LLVector3 pos, LLVector3 look)
719 {
720 AgentMovementCompletePacket mov = new AgentMovementCompletePacket();
721 mov.AgentData.SessionID = m_sessionId;
722 mov.AgentData.AgentID = AgentId;
723 mov.Data.RegionHandle = regInfo.RegionHandle;
724 mov.Data.Timestamp = 1172750370; // TODO - dynamicalise this
725
726 if ((pos.X == 0) && (pos.Y == 0) && (pos.Z == 0))
727 {
728 mov.Data.Position = startpos;
729 }
730 else
731 {
732 mov.Data.Position = pos;
733 }
734 mov.Data.LookAt = look;
735
736 OutPacket(mov, ThrottleOutPacketType.Task);
737 }
738
739 /// <summary>
740 ///
741 /// </summary>
742 /// <param name="message"></param>
743 /// <param name="type"></param>
744 /// <param name="fromPos"></param>
745 /// <param name="fromName"></param>
746 /// <param name="fromAgentID"></param>
747 public void SendChatMessage(string message, byte type, LLVector3 fromPos, string fromName, LLUUID fromAgentID)
748 {
749 SendChatMessage(Helpers.StringToField(message), type, fromPos, fromName, fromAgentID);
750 }
751
752
753 public void SendChatMessage(byte[] message, byte type, LLVector3 fromPos, string fromName, LLUUID fromAgentID)
754 {
755 Encoding enc = Encoding.ASCII;
756 ChatFromSimulatorPacket reply = new ChatFromSimulatorPacket();
757 reply.ChatData.Audible = 1;
758 reply.ChatData.Message = message;
759 reply.ChatData.ChatType = type;
760 reply.ChatData.SourceType = 1;
761 reply.ChatData.Position = fromPos;
762 reply.ChatData.FromName = enc.GetBytes(fromName + "\0");
763 reply.ChatData.OwnerID = fromAgentID;
764 reply.ChatData.SourceID = fromAgentID;
765
766 OutPacket(reply, ThrottleOutPacketType.Task);
767 }
768
769 /// <summary>
770 ///
771 /// </summary>
772 /// <remarks>TODO</remarks>
773 /// <param name="message"></param>
774 /// <param name="target"></param>
775 public void SendInstantMessage(LLUUID fromAgent, LLUUID fromAgentSession, string message, LLUUID toAgent,
776 LLUUID imSessionID, string fromName, byte dialog, uint timeStamp)
777 {
778 Encoding enc = Encoding.ASCII;
779 Encoding encUTF8 = Encoding.UTF8;
780 ImprovedInstantMessagePacket msg = new ImprovedInstantMessagePacket();
781 msg.AgentData.AgentID = fromAgent;
782 msg.AgentData.SessionID = fromAgentSession;
783 msg.MessageBlock.FromAgentName = enc.GetBytes(fromName + " \0");
784 msg.MessageBlock.Dialog = dialog;
785 msg.MessageBlock.FromGroup = false;
786 msg.MessageBlock.ID = imSessionID;
787 msg.MessageBlock.Offline = 0;
788 msg.MessageBlock.ParentEstateID = 0;
789 msg.MessageBlock.Position = new LLVector3();
790 msg.MessageBlock.RegionID = LLUUID.Random();
791 msg.MessageBlock.Timestamp = timeStamp;
792 msg.MessageBlock.ToAgentID = toAgent;
793 msg.MessageBlock.Message = encUTF8.GetBytes(message + "\0");
794 msg.MessageBlock.BinaryBucket = new byte[0];
795
796 OutPacket(msg, ThrottleOutPacketType.Task);
797 }
798
799 /// <summary>
800 /// Send the region heightmap to the client
801 /// </summary>
802 /// <param name="map">heightmap</param>
803 public virtual void SendLayerData(float[] map)
804 {
805 try
806 {
807 int[] patches = new int[4];
808
809 for (int y = 0; y < 16; y++)
810 {
811 for (int x = 0; x < 16; x = x + 4)
812 {
813 patches[0] = x + 0 + y*16;
814 patches[1] = x + 1 + y*16;
815 patches[2] = x + 2 + y*16;
816 patches[3] = x + 3 + y*16;
817
818 Packet layerpack = TerrainManager.CreateLandPacket(map, patches);
819 OutPacket(layerpack, ThrottleOutPacketType.Land);
820 }
821 }
822 }
823 catch (Exception e)
824 {
825 MainLog.Instance.Warn("client",
826 "ClientView.API.cs: SendLayerData() - Failed with exception " + e.ToString());
827 }
828 }
829
830 /// <summary>
831 /// Sends a specified patch to a client
832 /// </summary>
833 /// <param name="px">Patch coordinate (x) 0..16</param>
834 /// <param name="py">Patch coordinate (y) 0..16</param>
835 /// <param name="map">heightmap</param>
836 public void SendLayerData(int px, int py, float[] map)
837 {
838 try
839 {
840 int[] patches = new int[1];
841 int patchx, patchy;
842 patchx = px;
843 patchy = py;
844
845 patches[0] = patchx + 0 + patchy*16;
846
847 Packet layerpack = TerrainManager.CreateLandPacket(map, patches);
848 OutPacket(layerpack, ThrottleOutPacketType.Land);
849 }
850 catch (Exception e)
851 {
852 MainLog.Instance.Warn("client",
853 "ClientView.API.cs: SendLayerData() - Failed with exception " + e.ToString());
854 }
855 }
856
857 /// <summary>
858 ///
859 /// </summary>
860 /// <param name="neighbourHandle"></param>
861 /// <param name="neighbourIP"></param>
862 /// <param name="neighbourPort"></param>
863 public void InformClientOfNeighbour(ulong neighbourHandle, IPEndPoint neighbourEndPoint)
864 {
865 IPAddress neighbourIP = neighbourEndPoint.Address;
866 ushort neighbourPort = (ushort) neighbourEndPoint.Port;
867
868 EnableSimulatorPacket enablesimpacket = new EnableSimulatorPacket();
869 enablesimpacket.SimulatorInfo = new EnableSimulatorPacket.SimulatorInfoBlock();
870 enablesimpacket.SimulatorInfo.Handle = neighbourHandle;
871
872 byte[] byteIP = neighbourIP.GetAddressBytes();
873 enablesimpacket.SimulatorInfo.IP = (uint) byteIP[3] << 24;
874 enablesimpacket.SimulatorInfo.IP += (uint) byteIP[2] << 16;
875 enablesimpacket.SimulatorInfo.IP += (uint) byteIP[1] << 8;
876 enablesimpacket.SimulatorInfo.IP += (uint) byteIP[0];
877 enablesimpacket.SimulatorInfo.Port = neighbourPort;
878 OutPacket(enablesimpacket, ThrottleOutPacketType.Task);
879 }
880
881 /// <summary>
882 ///
883 /// </summary>
884 /// <returns></returns>
885 public AgentCircuitData RequestClientInfo()
886 {
887 AgentCircuitData agentData = new AgentCircuitData();
888 agentData.AgentID = AgentId;
889 agentData.SessionID = m_sessionId;
890 agentData.SecureSessionID = SecureSessionID;
891 agentData.circuitcode = m_circuitCode;
892 agentData.child = false;
893 agentData.firstname = firstName;
894 agentData.lastname = lastName;
895 agentData.CapsPath = "";
896 return agentData;
897 }
898
899 public void CrossRegion(ulong newRegionHandle, LLVector3 pos, LLVector3 lookAt, IPEndPoint externalIPEndPoint,
900 string capsURL)
901 {
902 LLVector3 look = new LLVector3(lookAt.X*10, lookAt.Y*10, lookAt.Z*10);
903
904 CrossedRegionPacket newSimPack = new CrossedRegionPacket();
905 newSimPack.AgentData = new CrossedRegionPacket.AgentDataBlock();
906 newSimPack.AgentData.AgentID = AgentId;
907 newSimPack.AgentData.SessionID = m_sessionId;
908 newSimPack.Info = new CrossedRegionPacket.InfoBlock();
909 newSimPack.Info.Position = pos;
910 newSimPack.Info.LookAt = look;
911 // new LLVector3(0.0f, 0.0f, 0.0f); // copied from Avatar.cs - SHOULD BE DYNAMIC!!!!!!!!!!
912 newSimPack.RegionData = new CrossedRegionPacket.RegionDataBlock();
913 newSimPack.RegionData.RegionHandle = newRegionHandle;
914 byte[] byteIP = externalIPEndPoint.Address.GetAddressBytes();
915 newSimPack.RegionData.SimIP = (uint) byteIP[3] << 24;
916 newSimPack.RegionData.SimIP += (uint) byteIP[2] << 16;
917 newSimPack.RegionData.SimIP += (uint) byteIP[1] << 8;
918 newSimPack.RegionData.SimIP += (uint) byteIP[0];
919 newSimPack.RegionData.SimPort = (ushort) externalIPEndPoint.Port;
920 //newSimPack.RegionData.SeedCapability = new byte[0];
921 newSimPack.RegionData.SeedCapability = Helpers.StringToField(capsURL);
922
923 OutPacket(newSimPack, ThrottleOutPacketType.Task);
924 }
925
926 public void SendMapBlock(List<MapBlockData> mapBlocks)
927 {
928 MapBlockReplyPacket mapReply = new MapBlockReplyPacket();
929 mapReply.AgentData.AgentID = AgentId;
930 mapReply.Data = new MapBlockReplyPacket.DataBlock[mapBlocks.Count];
931 mapReply.AgentData.Flags = 0;
932
933 for (int i = 0; i < mapBlocks.Count; i++)
934 {
935 mapReply.Data[i] = new MapBlockReplyPacket.DataBlock();
936 mapReply.Data[i].MapImageID = mapBlocks[i].MapImageId;
937 mapReply.Data[i].X = mapBlocks[i].X;
938 mapReply.Data[i].Y = mapBlocks[i].Y;
939 mapReply.Data[i].WaterHeight = mapBlocks[i].WaterHeight;
940 mapReply.Data[i].Name = Helpers.StringToField(mapBlocks[i].Name);
941 mapReply.Data[i].RegionFlags = mapBlocks[i].RegionFlags;
942 mapReply.Data[i].Access = mapBlocks[i].Access;
943 mapReply.Data[i].Agents = mapBlocks[i].Agents;
944 }
945 OutPacket(mapReply, ThrottleOutPacketType.Land);
946 }
947
948 public void SendLocalTeleport(LLVector3 position, LLVector3 lookAt, uint flags)
949 {
950 TeleportLocalPacket tpLocal = new TeleportLocalPacket();
951 tpLocal.Info.AgentID = AgentId;
952 tpLocal.Info.TeleportFlags = flags;
953 tpLocal.Info.LocationID = 2;
954 tpLocal.Info.LookAt = lookAt;
955 tpLocal.Info.Position = position;
956 OutPacket(tpLocal, ThrottleOutPacketType.Task);
957 }
958
959 public void SendRegionTeleport(ulong regionHandle, byte simAccess, IPEndPoint newRegionEndPoint, uint locationID,
960 uint flags, string capsURL)
961 {
962 TeleportFinishPacket teleport = new TeleportFinishPacket();
963 teleport.Info.AgentID = AgentId;
964 teleport.Info.RegionHandle = regionHandle;
965 teleport.Info.SimAccess = simAccess;
966
967 teleport.Info.SeedCapability = Helpers.StringToField(capsURL);
968 //teleport.Info.SeedCapability = new byte[0];
969
970 IPAddress oIP = newRegionEndPoint.Address;
971 byte[] byteIP = oIP.GetAddressBytes();
972 uint ip = (uint) byteIP[3] << 24;
973 ip += (uint) byteIP[2] << 16;
974 ip += (uint) byteIP[1] << 8;
975 ip += (uint) byteIP[0];
976
977 teleport.Info.SimIP = ip;
978 teleport.Info.SimPort = (ushort) newRegionEndPoint.Port;
979 teleport.Info.LocationID = 4;
980 teleport.Info.TeleportFlags = 1 << 4;
981 OutPacket(teleport, ThrottleOutPacketType.Task);
982 }
983
984 /// <summary>
985 ///
986 /// </summary>
987 public void SendTeleportFailed()
988 {
989 TeleportFailedPacket tpFailed = new TeleportFailedPacket();
990 tpFailed.Info.AgentID = this.AgentId;
991 tpFailed.Info.Reason = Helpers.StringToField("unknown failure of teleport");
992
993 OutPacket(tpFailed, ThrottleOutPacketType.Task);
994 }
995
996 /// <summary>
997 ///
998 /// </summary>
999 public void SendTeleportLocationStart()
1000 {
1001 TeleportStartPacket tpStart = new TeleportStartPacket();
1002 tpStart.Info.TeleportFlags = 16; // Teleport via location
1003 OutPacket(tpStart, ThrottleOutPacketType.Task);
1004 }
1005
1006 public void SendMoneyBalance(LLUUID transaction, bool success, byte[] description, int balance)
1007 {
1008 MoneyBalanceReplyPacket money = new MoneyBalanceReplyPacket();
1009 money.MoneyData.AgentID = AgentId;
1010 money.MoneyData.TransactionID = transaction;
1011 money.MoneyData.TransactionSuccess = success;
1012 money.MoneyData.Description = description;
1013 money.MoneyData.MoneyBalance = balance;
1014 OutPacket(money, ThrottleOutPacketType.Task);
1015 }
1016
1017 public void SendStartPingCheck(byte seq)
1018 {
1019 StartPingCheckPacket pc = new StartPingCheckPacket();
1020 pc.PingID.PingID = seq;
1021 pc.Header.Reliable = false;
1022 OutPacket(pc, ThrottleOutPacketType.Task);
1023 }
1024
1025 public void SendKillObject(ulong regionHandle, uint localID)
1026 {
1027 KillObjectPacket kill = new KillObjectPacket();
1028 kill.ObjectData = new KillObjectPacket.ObjectDataBlock[1];
1029 kill.ObjectData[0] = new KillObjectPacket.ObjectDataBlock();
1030 kill.ObjectData[0].ID = localID;
1031 OutPacket(kill, ThrottleOutPacketType.Task);
1032 }
1033
1034 public void SendInventoryFolderDetails(LLUUID ownerID, LLUUID folderID, List<InventoryItemBase> items)
1035 {
1036 Encoding enc = Encoding.ASCII;
1037 uint FULL_MASK_PERMISSIONS = 2147483647;
1038 InventoryDescendentsPacket descend = CreateInventoryDescendentsPacket(ownerID, folderID);
1039
1040 int count = 0;
1041 if (items.Count < 40)
1042 {
1043 descend.ItemData = new InventoryDescendentsPacket.ItemDataBlock[items.Count];
1044 descend.AgentData.Descendents = items.Count;
1045 }
1046 else
1047 {
1048 descend.ItemData = new InventoryDescendentsPacket.ItemDataBlock[40];
1049 descend.AgentData.Descendents = 40;
1050 }
1051 int i = 0;
1052 foreach (InventoryItemBase item in items)
1053 {
1054 descend.ItemData[i] = new InventoryDescendentsPacket.ItemDataBlock();
1055 descend.ItemData[i].ItemID = item.inventoryID;
1056 descend.ItemData[i].AssetID = item.assetID;
1057 descend.ItemData[i].CreatorID = item.creatorsID;
1058 descend.ItemData[i].BaseMask = item.inventoryBasePermissions;
1059 descend.ItemData[i].CreationDate = 1000;
1060 descend.ItemData[i].Description = enc.GetBytes(item.inventoryDescription + "\0");
1061 descend.ItemData[i].EveryoneMask = item.inventoryEveryOnePermissions;
1062 descend.ItemData[i].Flags = 1;
1063 descend.ItemData[i].FolderID = item.parentFolderID;
1064 descend.ItemData[i].GroupID = new LLUUID("00000000-0000-0000-0000-000000000000");
1065 descend.ItemData[i].GroupMask = 0;
1066 descend.ItemData[i].InvType = (sbyte) item.invType;
1067 descend.ItemData[i].Name = enc.GetBytes(item.inventoryName + "\0");
1068 descend.ItemData[i].NextOwnerMask = item.inventoryNextPermissions;
1069 descend.ItemData[i].OwnerID = item.avatarID;
1070 descend.ItemData[i].OwnerMask = item.inventoryCurrentPermissions;
1071 descend.ItemData[i].SalePrice = 0;
1072 descend.ItemData[i].SaleType = 0;
1073 descend.ItemData[i].Type = (sbyte) item.assetType;
1074 descend.ItemData[i].CRC =
1075 Helpers.InventoryCRC(1000, 0, descend.ItemData[i].InvType, descend.ItemData[i].Type,
1076 descend.ItemData[i].AssetID, descend.ItemData[i].GroupID, 100,
1077 descend.ItemData[i].OwnerID, descend.ItemData[i].CreatorID,
1078 descend.ItemData[i].ItemID, descend.ItemData[i].FolderID, FULL_MASK_PERMISSIONS,
1079 1, FULL_MASK_PERMISSIONS, FULL_MASK_PERMISSIONS, FULL_MASK_PERMISSIONS);
1080
1081 i++;
1082 count++;
1083 if (i == 40)
1084 {
1085 OutPacket(descend, ThrottleOutPacketType.Asset);
1086
1087 if ((items.Count - count) > 0)
1088 {
1089 descend = CreateInventoryDescendentsPacket(ownerID, folderID);
1090 if ((items.Count - count) < 40)
1091 {
1092 descend.ItemData = new InventoryDescendentsPacket.ItemDataBlock[items.Count - count];
1093 descend.AgentData.Descendents = items.Count - count;
1094 }
1095 else
1096 {
1097 descend.ItemData = new InventoryDescendentsPacket.ItemDataBlock[40];
1098 descend.AgentData.Descendents = 40;
1099 }
1100 i = 0;
1101 }
1102 }
1103 }
1104
1105 if (i < 40)
1106 {
1107 OutPacket(descend, ThrottleOutPacketType.Asset);
1108 }
1109 }
1110
1111 private InventoryDescendentsPacket CreateInventoryDescendentsPacket(LLUUID ownerID, LLUUID folderID)
1112 {
1113 InventoryDescendentsPacket descend = new InventoryDescendentsPacket();
1114 descend.AgentData.AgentID = AgentId;
1115 descend.AgentData.OwnerID = ownerID;
1116 descend.AgentData.FolderID = folderID;
1117 descend.AgentData.Version = 0;
1118
1119 return descend;
1120 }
1121
1122 public void SendInventoryItemDetails(LLUUID ownerID, InventoryItemBase item)
1123 {
1124 Encoding enc = Encoding.ASCII;
1125 uint FULL_MASK_PERMISSIONS = 2147483647;
1126 FetchInventoryReplyPacket inventoryReply = new FetchInventoryReplyPacket();
1127 inventoryReply.AgentData.AgentID = AgentId;
1128 inventoryReply.InventoryData = new FetchInventoryReplyPacket.InventoryDataBlock[1];
1129 inventoryReply.InventoryData[0] = new FetchInventoryReplyPacket.InventoryDataBlock();
1130 inventoryReply.InventoryData[0].ItemID = item.inventoryID;
1131 inventoryReply.InventoryData[0].AssetID = item.assetID;
1132 inventoryReply.InventoryData[0].CreatorID = item.creatorsID;
1133 inventoryReply.InventoryData[0].BaseMask = item.inventoryBasePermissions;
1134 inventoryReply.InventoryData[0].CreationDate =
1135 (int) (DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;
1136 inventoryReply.InventoryData[0].Description = enc.GetBytes(item.inventoryDescription + "\0");
1137 inventoryReply.InventoryData[0].EveryoneMask = item.inventoryEveryOnePermissions;
1138 inventoryReply.InventoryData[0].Flags = 0;
1139 inventoryReply.InventoryData[0].FolderID = item.parentFolderID;
1140 inventoryReply.InventoryData[0].GroupID = new LLUUID("00000000-0000-0000-0000-000000000000");
1141 inventoryReply.InventoryData[0].GroupMask = 0;
1142 inventoryReply.InventoryData[0].InvType = (sbyte) item.invType;
1143 inventoryReply.InventoryData[0].Name = enc.GetBytes(item.inventoryName + "\0");
1144 inventoryReply.InventoryData[0].NextOwnerMask = item.inventoryNextPermissions;
1145 inventoryReply.InventoryData[0].OwnerID = item.avatarID;
1146 inventoryReply.InventoryData[0].OwnerMask = item.inventoryCurrentPermissions;
1147 inventoryReply.InventoryData[0].SalePrice = 0;
1148 inventoryReply.InventoryData[0].SaleType = 0;
1149 inventoryReply.InventoryData[0].Type = (sbyte) item.assetType;
1150 inventoryReply.InventoryData[0].CRC =
1151 Helpers.InventoryCRC(1000, 0, inventoryReply.InventoryData[0].InvType,
1152 inventoryReply.InventoryData[0].Type, inventoryReply.InventoryData[0].AssetID,
1153 inventoryReply.InventoryData[0].GroupID, 100,
1154 inventoryReply.InventoryData[0].OwnerID, inventoryReply.InventoryData[0].CreatorID,
1155 inventoryReply.InventoryData[0].ItemID, inventoryReply.InventoryData[0].FolderID,
1156 FULL_MASK_PERMISSIONS, 1, FULL_MASK_PERMISSIONS, FULL_MASK_PERMISSIONS,
1157 FULL_MASK_PERMISSIONS);
1158
1159 OutPacket(inventoryReply, ThrottleOutPacketType.Asset);
1160 }
1161
1162 public void SendInventoryItemUpdate(InventoryItemBase Item)
1163 {
1164 Encoding enc = Encoding.ASCII;
1165 uint FULL_MASK_PERMISSIONS = 2147483647;
1166 UpdateCreateInventoryItemPacket InventoryReply = new UpdateCreateInventoryItemPacket();
1167 InventoryReply.AgentData.AgentID = AgentId;
1168 InventoryReply.AgentData.SimApproved = true;
1169 InventoryReply.InventoryData = new UpdateCreateInventoryItemPacket.InventoryDataBlock[1];
1170 InventoryReply.InventoryData[0] = new UpdateCreateInventoryItemPacket.InventoryDataBlock();
1171 InventoryReply.InventoryData[0].ItemID = Item.inventoryID;
1172 InventoryReply.InventoryData[0].AssetID = Item.assetID;
1173 InventoryReply.InventoryData[0].CreatorID = Item.creatorsID;
1174 InventoryReply.InventoryData[0].BaseMask = Item.inventoryBasePermissions;
1175 InventoryReply.InventoryData[0].CreationDate = 1000;
1176 InventoryReply.InventoryData[0].Description = enc.GetBytes(Item.inventoryDescription + "\0");
1177 InventoryReply.InventoryData[0].EveryoneMask = Item.inventoryEveryOnePermissions;
1178 InventoryReply.InventoryData[0].Flags = 0;
1179 InventoryReply.InventoryData[0].FolderID = Item.parentFolderID;
1180 InventoryReply.InventoryData[0].GroupID = new LLUUID("00000000-0000-0000-0000-000000000000");
1181 InventoryReply.InventoryData[0].GroupMask = 0;
1182 InventoryReply.InventoryData[0].InvType = (sbyte) Item.invType;
1183 InventoryReply.InventoryData[0].Name = enc.GetBytes(Item.inventoryName + "\0");
1184 InventoryReply.InventoryData[0].NextOwnerMask = Item.inventoryNextPermissions;
1185 InventoryReply.InventoryData[0].OwnerID = Item.avatarID;
1186 InventoryReply.InventoryData[0].OwnerMask = Item.inventoryCurrentPermissions;
1187 InventoryReply.InventoryData[0].SalePrice = 100;
1188 InventoryReply.InventoryData[0].SaleType = 0;
1189 InventoryReply.InventoryData[0].Type = (sbyte) Item.assetType;
1190 InventoryReply.InventoryData[0].CRC =
1191 Helpers.InventoryCRC(1000, 0, InventoryReply.InventoryData[0].InvType,
1192 InventoryReply.InventoryData[0].Type, InventoryReply.InventoryData[0].AssetID,
1193 InventoryReply.InventoryData[0].GroupID, 100,
1194 InventoryReply.InventoryData[0].OwnerID, InventoryReply.InventoryData[0].CreatorID,
1195 InventoryReply.InventoryData[0].ItemID, InventoryReply.InventoryData[0].FolderID,
1196 FULL_MASK_PERMISSIONS, 1, FULL_MASK_PERMISSIONS, FULL_MASK_PERMISSIONS,
1197 FULL_MASK_PERMISSIONS);
1198
1199 OutPacket(InventoryReply, ThrottleOutPacketType.Asset);
1200 }
1201
1202 public void SendRemoveInventoryItem(LLUUID itemID)
1203 {
1204 RemoveInventoryItemPacket remove = new RemoveInventoryItemPacket();
1205 remove.AgentData.AgentID = AgentId;
1206 remove.AgentData.SessionID = m_sessionId;
1207 remove.InventoryData = new RemoveInventoryItemPacket.InventoryDataBlock[1];
1208 remove.InventoryData[0] = new RemoveInventoryItemPacket.InventoryDataBlock();
1209 remove.InventoryData[0].ItemID = itemID;
1210
1211 OutPacket(remove, ThrottleOutPacketType.Asset);
1212 }
1213
1214 public void SendTaskInventory(LLUUID taskID, short serial, byte[] fileName)
1215 {
1216 ReplyTaskInventoryPacket replytask = new ReplyTaskInventoryPacket();
1217 replytask.InventoryData.TaskID = taskID;
1218 replytask.InventoryData.Serial = serial;
1219 replytask.InventoryData.Filename = fileName;
1220 OutPacket(replytask, ThrottleOutPacketType.Asset);
1221 }
1222
1223 public void SendXferPacket(ulong xferID, uint packet, byte[] data)
1224 {
1225 SendXferPacketPacket sendXfer = new SendXferPacketPacket();
1226 sendXfer.XferID.ID = xferID;
1227 sendXfer.XferID.Packet = packet;
1228 sendXfer.DataPacket.Data = data;
1229 OutPacket(sendXfer, ThrottleOutPacketType.Task);
1230 }
1231 public void SendAvatarPickerReply(AvatarPickerReplyPacket replyPacket)
1232 {
1233 OutPacket(replyPacket, ThrottleOutPacketType.Task);
1234 }
1235
1236 /// <summary>
1237 ///
1238 /// </summary>
1239 /// <param name="message"></param>
1240 public void SendAlertMessage(string message)
1241 {
1242 AlertMessagePacket alertPack = new AlertMessagePacket();
1243 alertPack.AlertData.Message = Helpers.StringToField(message);
1244 OutPacket(alertPack, ThrottleOutPacketType.Task);
1245 }
1246
1247 /// <summary>
1248 ///
1249 /// </summary>
1250 /// <param name="message"></param>
1251 /// <param name="modal"></param>
1252 public void SendAgentAlertMessage(string message, bool modal)
1253 {
1254 AgentAlertMessagePacket alertPack = new AgentAlertMessagePacket();
1255 alertPack.AgentData.AgentID = AgentId;
1256 alertPack.AlertData.Message = Helpers.StringToField(message);
1257 alertPack.AlertData.Modal = modal;
1258 OutPacket(alertPack, ThrottleOutPacketType.Task);
1259 }
1260
1261 public void SendLoadURL(string objectname, LLUUID objectID, LLUUID ownerID, bool groupOwned, string message,
1262 string url)
1263 {
1264 LoadURLPacket loadURL = new LoadURLPacket();
1265 loadURL.Data.ObjectName = Helpers.StringToField(objectname);
1266 loadURL.Data.ObjectID = objectID;
1267 loadURL.Data.OwnerID = ownerID;
1268 loadURL.Data.OwnerIsGroup = groupOwned;
1269 loadURL.Data.Message = Helpers.StringToField(message);
1270 loadURL.Data.URL = Helpers.StringToField(url);
1271
1272 OutPacket(loadURL, ThrottleOutPacketType.Task);
1273 }
1274
1275
1276 public void SendPreLoadSound(LLUUID objectID, LLUUID ownerID, LLUUID soundID)
1277 {
1278 PreloadSoundPacket preSound = new PreloadSoundPacket();
1279 preSound.DataBlock = new PreloadSoundPacket.DataBlockBlock[1];
1280 preSound.DataBlock[0] = new PreloadSoundPacket.DataBlockBlock();
1281 preSound.DataBlock[0].ObjectID = objectID;
1282 preSound.DataBlock[0].OwnerID = ownerID;
1283 preSound.DataBlock[0].SoundID = soundID;
1284 OutPacket(preSound, ThrottleOutPacketType.Task);
1285 }
1286
1287 public void SendPlayAttachedSound(LLUUID soundID, LLUUID objectID, LLUUID ownerID, float gain, byte flags)
1288 {
1289 AttachedSoundPacket sound = new AttachedSoundPacket();
1290 sound.DataBlock.SoundID = soundID;
1291 sound.DataBlock.ObjectID = objectID;
1292 sound.DataBlock.OwnerID = ownerID;
1293 sound.DataBlock.Gain = gain;
1294 sound.DataBlock.Flags = flags;
1295
1296 OutPacket(sound, ThrottleOutPacketType.Task);
1297 }
1298
1299 public void SendSunPos(LLVector3 sunPos, LLVector3 sunVel)
1300 {
1301 SimulatorViewerTimeMessagePacket viewertime = new SimulatorViewerTimeMessagePacket();
1302 viewertime.TimeInfo.SunDirection = sunPos;
1303 viewertime.TimeInfo.SunAngVelocity = sunVel;
1304 viewertime.TimeInfo.UsecSinceStart = (ulong) Util.UnixTimeSinceEpoch();
1305 OutPacket(viewertime, ThrottleOutPacketType.Task);
1306 }
1307
1308 public void SendViewerTime(int phase)
1309 {
1310 Console.WriteLine("SunPhase: {0}", phase);
1311 SimulatorViewerTimeMessagePacket viewertime = new SimulatorViewerTimeMessagePacket();
1312 //viewertime.TimeInfo.SecPerDay = 86400;
1313 // viewertime.TimeInfo.SecPerYear = 31536000;
1314 viewertime.TimeInfo.SecPerDay = 1000;
1315 viewertime.TimeInfo.SecPerYear = 365000;
1316 viewertime.TimeInfo.SunPhase = 1;
1317 int sunPhase = (phase + 2)/2;
1318 if ((sunPhase < 6) || (sunPhase > 36))
1319 {
1320 viewertime.TimeInfo.SunDirection = new LLVector3(0f, 0.8f, -0.8f);
1321 Console.WriteLine("sending night");
1322 }
1323 else
1324 {
1325 if (sunPhase < 12)
1326 {
1327 sunPhase = 12;
1328 }
1329 sunPhase = sunPhase - 12;
1330
1331 float yValue = 0.1f*(sunPhase);
1332 Console.WriteLine("Computed SunPhase: {0}, yValue: {1}", sunPhase, yValue);
1333 if (yValue > 1.2f)
1334 {
1335 yValue = yValue - 1.2f;
1336 }
1337 if (yValue > 1)
1338 {
1339 yValue = 1;
1340 }
1341 if (yValue < 0)
1342 {
1343 yValue = 0;
1344 }
1345 if (sunPhase < 14)
1346 {
1347 yValue = 1 - yValue;
1348 }
1349 if (sunPhase < 12)
1350 {
1351 yValue *= -1;
1352 }
1353 viewertime.TimeInfo.SunDirection = new LLVector3(0f, yValue, 0.3f);
1354 Console.WriteLine("sending sun update " + yValue);
1355 }
1356 viewertime.TimeInfo.SunAngVelocity = new LLVector3(0, 0.0f, 10.0f);
1357 viewertime.TimeInfo.UsecSinceStart = (ulong) Util.UnixTimeSinceEpoch();
1358 OutPacket(viewertime, ThrottleOutPacketType.Task);
1359 }
1360
1361 public void SendAvatarProperties(LLUUID avatarID, string aboutText, string bornOn, string charterMember,
1362 string flAbout, uint flags, LLUUID flImageID, LLUUID imageID, string profileURL,
1363 LLUUID partnerID)
1364 {
1365 AvatarPropertiesReplyPacket avatarReply = new AvatarPropertiesReplyPacket();
1366 avatarReply.AgentData.AgentID = AgentId;
1367 avatarReply.AgentData.AvatarID = avatarID;
1368 avatarReply.PropertiesData.AboutText = Helpers.StringToField(aboutText);
1369 avatarReply.PropertiesData.BornOn = Helpers.StringToField(bornOn);
1370 avatarReply.PropertiesData.CharterMember = Helpers.StringToField(charterMember);
1371 avatarReply.PropertiesData.FLAboutText = Helpers.StringToField(flAbout);
1372 avatarReply.PropertiesData.Flags = 0;
1373 avatarReply.PropertiesData.FLImageID = flImageID;
1374 avatarReply.PropertiesData.ImageID = imageID;
1375 avatarReply.PropertiesData.ProfileURL = Helpers.StringToField(profileURL);
1376 avatarReply.PropertiesData.PartnerID = partnerID;
1377 OutPacket(avatarReply, ThrottleOutPacketType.Task);
1378 }
1379
1380 #endregion
1381
1382 #region Appearance/ Wearables Methods
1383
1384 /// <summary>
1385 ///
1386 /// </summary>
1387 /// <param name="wearables"></param>
1388 public void SendWearables(AvatarWearable[] wearables, int serial)
1389 {
1390 AgentWearablesUpdatePacket aw = new AgentWearablesUpdatePacket();
1391 aw.AgentData.AgentID = AgentId;
1392 aw.AgentData.SerialNum = (uint) serial;
1393 aw.AgentData.SessionID = m_sessionId;
1394
1395 aw.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[13];
1396 AgentWearablesUpdatePacket.WearableDataBlock awb;
1397 for (int i = 0; i < wearables.Length; i++)
1398 {
1399 awb = new AgentWearablesUpdatePacket.WearableDataBlock();
1400 awb.WearableType = (byte) i;
1401 awb.AssetID = wearables[i].AssetID;
1402 awb.ItemID = wearables[i].ItemID;
1403 aw.WearableData[i] = awb;
1404 }
1405
1406 OutPacket(aw, ThrottleOutPacketType.Task);
1407 }
1408
1409 /// <summary>
1410 ///
1411 /// </summary>
1412 /// <param name="agentID"></param>
1413 /// <param name="visualParams"></param>
1414 /// <param name="textureEntry"></param>
1415 public void SendAppearance(LLUUID agentID, byte[] visualParams, byte[] textureEntry)
1416 {
1417 AvatarAppearancePacket avp = new AvatarAppearancePacket();
1418 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[218];
1419 avp.ObjectData.TextureEntry = textureEntry;
1420
1421 AvatarAppearancePacket.VisualParamBlock avblock = null;
1422 for (int i = 0; i < visualParams.Length; i++)
1423 {
1424 avblock = new AvatarAppearancePacket.VisualParamBlock();
1425 avblock.ParamValue = visualParams[i];
1426 avp.VisualParam[i] = avblock;
1427 }
1428
1429 avp.Sender.IsTrial = false;
1430 avp.Sender.ID = agentID;
1431 OutPacket(avp, ThrottleOutPacketType.Task);
1432 }
1433
1434 public void SendAnimation(LLUUID animID, int seq, LLUUID sourceAgentId)
1435 {
1436 AvatarAnimationPacket ani = new AvatarAnimationPacket();
1437 ani.AnimationSourceList = new AvatarAnimationPacket.AnimationSourceListBlock[1];
1438 ani.AnimationSourceList[0] = new AvatarAnimationPacket.AnimationSourceListBlock();
1439 ani.AnimationSourceList[0].ObjectID = sourceAgentId;
1440 ani.Sender = new AvatarAnimationPacket.SenderBlock();
1441 ani.Sender.ID = sourceAgentId;
1442 ani.AnimationList = new AvatarAnimationPacket.AnimationListBlock[1];
1443 ani.AnimationList[0] = new AvatarAnimationPacket.AnimationListBlock();
1444 ani.AnimationList[0].AnimID = animID;
1445 ani.AnimationList[0].AnimSequenceID = seq;
1446 OutPacket(ani, ThrottleOutPacketType.Task);
1447 }
1448
1449 #endregion
1450
1451 #region Avatar Packet/data sending Methods
1452
1453 /// <summary>
1454 /// send a objectupdate packet with information about the clients avatar
1455 /// </summary>
1456 /// <param name="regionInfo"></param>
1457 /// <param name="firstName"></param>
1458 /// <param name="lastName"></param>
1459 /// <param name="avatarID"></param>
1460 /// <param name="avatarLocalID"></param>
1461 /// <param name="Pos"></param>
1462 public void SendAvatarData(ulong regionHandle, string firstName, string lastName, LLUUID avatarID,
1463 uint avatarLocalID, LLVector3 Pos, byte[] textureEntry, uint parentID)
1464 {
1465 ObjectUpdatePacket objupdate = new ObjectUpdatePacket();
1466 objupdate.RegionData.RegionHandle = regionHandle;
1467 objupdate.RegionData.TimeDilation = 64096;
1468 objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
1469 objupdate.ObjectData[0] = CreateDefaultAvatarPacket(textureEntry);
1470
1471 //give this avatar object a local id and assign the user a name
1472 objupdate.ObjectData[0].ID = avatarLocalID;
1473 objupdate.ObjectData[0].FullID = avatarID;
1474 objupdate.ObjectData[0].ParentID = parentID;
1475 objupdate.ObjectData[0].NameValue =
1476 Helpers.StringToField("FirstName STRING RW SV " + firstName + "\nLastName STRING RW SV " + lastName);
1477 LLVector3 pos2 = new LLVector3((float) Pos.X, (float) Pos.Y, (float) Pos.Z);
1478 byte[] pb = pos2.GetBytes();
1479 Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 16, pb.Length);
1480
1481 OutPacket(objupdate, ThrottleOutPacketType.Task);
1482 }
1483
1484 /// <summary>
1485 ///
1486 /// </summary>
1487 /// <param name="regionHandle"></param>
1488 /// <param name="timeDilation"></param>
1489 /// <param name="localID"></param>
1490 /// <param name="position"></param>
1491 /// <param name="velocity"></param>
1492 public void SendAvatarTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, LLVector3 position,
1493 LLVector3 velocity, LLQuaternion rotation)
1494 {
1495 ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock =
1496 CreateAvatarImprovedBlock(localID, position, velocity, rotation);
1497 ImprovedTerseObjectUpdatePacket terse = new ImprovedTerseObjectUpdatePacket();
1498 terse.RegionData.RegionHandle = regionHandle;
1499 terse.RegionData.TimeDilation = timeDilation;
1500 terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1];
1501 terse.ObjectData[0] = terseBlock;
1502
1503 OutPacket(terse, ThrottleOutPacketType.Task);
1504 }
1505
1506 public void SendCoarseLocationUpdate(List<LLVector3> CoarseLocations)
1507 {
1508 CoarseLocationUpdatePacket loc = new CoarseLocationUpdatePacket();
1509 int total = CoarseLocations.Count;
1510 CoarseLocationUpdatePacket.IndexBlock ib =
1511 new CoarseLocationUpdatePacket.IndexBlock();
1512 loc.Location = new CoarseLocationUpdatePacket.LocationBlock[total];
1513 for (int i = 0; i < total; i++)
1514 {
1515 CoarseLocationUpdatePacket.LocationBlock lb =
1516 new CoarseLocationUpdatePacket.LocationBlock();
1517 lb.X = (byte) CoarseLocations[i].X;
1518 lb.Y = (byte) CoarseLocations[i].Y;
1519 lb.Z = (byte) (CoarseLocations[i].Z/4);
1520 loc.Location[i] = lb;
1521 }
1522 ib.You = -1;
1523 ib.Prey = -1;
1524 loc.Index = ib;
1525 OutPacket(loc, ThrottleOutPacketType.Task);
1526 }
1527
1528 #endregion
1529
1530 #region Primitive Packet/data Sending Methods
1531
1532 /// <summary>
1533 ///
1534 /// </summary>
1535 /// <param name="localID"></param>
1536 /// <param name="rotation"></param>
1537 /// <param name="attachPoint"></param>
1538 public void AttachObject(uint localID, LLQuaternion rotation, byte attachPoint)
1539 {
1540 ObjectAttachPacket attach = new ObjectAttachPacket();
1541 attach.AgentData.AgentID = AgentId;
1542 attach.AgentData.SessionID = m_sessionId;
1543 attach.AgentData.AttachmentPoint = attachPoint;
1544 attach.ObjectData = new ObjectAttachPacket.ObjectDataBlock[1];
1545 attach.ObjectData[0] = new ObjectAttachPacket.ObjectDataBlock();
1546 attach.ObjectData[0].ObjectLocalID = localID;
1547 attach.ObjectData[0].Rotation = rotation;
1548
1549 OutPacket(attach, ThrottleOutPacketType.Task);
1550 }
1551
1552 public void SendPrimitiveToClient(
1553 ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, LLVector3 pos,
1554 uint flags,
1555 LLUUID objectID, LLUUID ownerID, string text, byte[] color, uint parentID, byte[] particleSystem, LLQuaternion rotation, byte clickAction)
1556 {
1557 ObjectUpdatePacket outPacket = new ObjectUpdatePacket();
1558 outPacket.RegionData.RegionHandle = regionHandle;
1559 outPacket.RegionData.TimeDilation = timeDilation;
1560 outPacket.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
1561
1562 outPacket.ObjectData[0] = CreatePrimUpdateBlock(primShape, flags);
1563
1564 outPacket.ObjectData[0].ID = localID;
1565 outPacket.ObjectData[0].FullID = objectID;
1566 outPacket.ObjectData[0].OwnerID = ownerID;
1567 outPacket.ObjectData[0].Text = Helpers.StringToField(text);
1568 outPacket.ObjectData[0].TextColor[0] = color[0];
1569 outPacket.ObjectData[0].TextColor[1] = color[1];
1570 outPacket.ObjectData[0].TextColor[2] = color[2];
1571 outPacket.ObjectData[0].TextColor[3] = color[3];
1572 outPacket.ObjectData[0].ParentID = parentID;
1573 outPacket.ObjectData[0].PSBlock = particleSystem;
1574 outPacket.ObjectData[0].ClickAction = clickAction;
1575 //outPacket.ObjectData[0].Flags = 0;
1576 outPacket.ObjectData[0].Radius = 20;
1577
1578 byte[] pb = pos.GetBytes();
1579 Array.Copy(pb, 0, outPacket.ObjectData[0].ObjectData, 0, pb.Length);
1580
1581 byte[] rot = rotation.GetBytes();
1582 Array.Copy(rot, 0, outPacket.ObjectData[0].ObjectData, 36, rot.Length);
1583
1584 OutPacket(outPacket, ThrottleOutPacketType.Task);
1585 }
1586
1587 /// <summary>
1588 ///
1589 /// </summary>
1590 /// <param name="regionHandle"></param>
1591 /// <param name="timeDilation"></param>
1592 /// <param name="localID"></param>
1593 /// <param name="position"></param>
1594 /// <param name="rotation"></param>
1595 public void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, LLVector3 position,
1596 LLQuaternion rotation)
1597 {
1598 LLVector3 velocity = new LLVector3(0f,0f,0f);
1599 LLVector3 rotationalvelocity = new LLVector3(0f,0f,0f);
1600 ImprovedTerseObjectUpdatePacket terse = new ImprovedTerseObjectUpdatePacket();
1601 terse.RegionData.RegionHandle = regionHandle;
1602 terse.RegionData.TimeDilation = timeDilation;
1603 terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1];
1604 terse.ObjectData[0] = CreatePrimImprovedBlock(localID, position, rotation, velocity, rotationalvelocity);
1605
1606 OutPacket(terse, ThrottleOutPacketType.Task);
1607 }
1608 public void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, LLVector3 position,
1609 LLQuaternion rotation, LLVector3 velocity, LLVector3 rotationalvelocity)
1610 {
1611
1612 ImprovedTerseObjectUpdatePacket terse = new ImprovedTerseObjectUpdatePacket();
1613 terse.RegionData.RegionHandle = regionHandle;
1614 terse.RegionData.TimeDilation = timeDilation;
1615 terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1];
1616 terse.ObjectData[0] = CreatePrimImprovedBlock(localID, position, rotation, velocity, rotationalvelocity);
1617
1618 OutPacket(terse, ThrottleOutPacketType.Task);
1619 }
1620
1621
1622 #endregion
1623
1624 #region Helper Methods
1625
1626 protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateAvatarImprovedBlock(uint localID, LLVector3 pos,
1627 LLVector3 velocity,
1628 LLQuaternion rotation)
1629 {
1630 byte[] bytes = new byte[60];
1631 int i = 0;
1632 ImprovedTerseObjectUpdatePacket.ObjectDataBlock dat = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock();
1633
1634 dat.TextureEntry = new byte[0]; // AvatarTemplate.TextureEntry;
1635
1636 uint ID = localID;
1637
1638 bytes[i++] = (byte) (ID%256);
1639 bytes[i++] = (byte) ((ID >> 8)%256);
1640 bytes[i++] = (byte) ((ID >> 16)%256);
1641 bytes[i++] = (byte) ((ID >> 24)%256);
1642 bytes[i++] = 0;
1643 bytes[i++] = 1;
1644 i += 14;
1645 bytes[i++] = 128;
1646 bytes[i++] = 63;
1647
1648 byte[] pb = pos.GetBytes();
1649 Array.Copy(pb, 0, bytes, i, pb.Length);
1650 i += 12;
1651 ushort InternVelocityX;
1652 ushort InternVelocityY;
1653 ushort InternVelocityZ;
1654 Vector3 internDirec = new Vector3(0, 0, 0);
1655
1656 internDirec = new Vector3(velocity.X, velocity.Y, velocity.Z);
1657
1658 internDirec = internDirec/128.0f;
1659 internDirec.x += 1;
1660 internDirec.y += 1;
1661 internDirec.z += 1;
1662
1663 InternVelocityX = (ushort) (32768*internDirec.x);
1664 InternVelocityY = (ushort) (32768*internDirec.y);
1665 InternVelocityZ = (ushort) (32768*internDirec.z);
1666
1667 ushort ac = 32767;
1668 bytes[i++] = (byte) (InternVelocityX%256);
1669 bytes[i++] = (byte) ((InternVelocityX >> 8)%256);
1670 bytes[i++] = (byte) (InternVelocityY%256);
1671 bytes[i++] = (byte) ((InternVelocityY >> 8)%256);
1672 bytes[i++] = (byte) (InternVelocityZ%256);
1673 bytes[i++] = (byte) ((InternVelocityZ >> 8)%256);
1674
1675 //accel
1676 bytes[i++] = (byte) (ac%256);
1677 bytes[i++] = (byte) ((ac >> 8)%256);
1678 bytes[i++] = (byte) (ac%256);
1679 bytes[i++] = (byte) ((ac >> 8)%256);
1680 bytes[i++] = (byte) (ac%256);
1681 bytes[i++] = (byte) ((ac >> 8)%256);
1682
1683 //rotation
1684 ushort rw, rx, ry, rz;
1685 rw = (ushort) (32768*(rotation.W + 1));
1686 rx = (ushort) (32768*(rotation.X + 1));
1687 ry = (ushort) (32768*(rotation.Y + 1));
1688 rz = (ushort) (32768*(rotation.Z + 1));
1689
1690 //rot
1691 bytes[i++] = (byte) (rx%256);
1692 bytes[i++] = (byte) ((rx >> 8)%256);
1693 bytes[i++] = (byte) (ry%256);
1694 bytes[i++] = (byte) ((ry >> 8)%256);
1695 bytes[i++] = (byte) (rz%256);
1696 bytes[i++] = (byte) ((rz >> 8)%256);
1697 bytes[i++] = (byte) (rw%256);
1698 bytes[i++] = (byte) ((rw >> 8)%256);
1699
1700 //rotation vel
1701 bytes[i++] = (byte) (ac%256);
1702 bytes[i++] = (byte) ((ac >> 8)%256);
1703 bytes[i++] = (byte) (ac%256);
1704 bytes[i++] = (byte) ((ac >> 8)%256);
1705 bytes[i++] = (byte) (ac%256);
1706 bytes[i++] = (byte) ((ac >> 8)%256);
1707
1708 dat.Data = bytes;
1709
1710 return (dat);
1711 }
1712
1713 /// <summary>
1714 ///
1715 /// </summary>
1716 /// <param name="localID"></param>
1717 /// <param name="position"></param>
1718 /// <param name="rotation"></param>
1719 /// <returns></returns>
1720 protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreatePrimImprovedBlock(uint localID,
1721 LLVector3 position,
1722 LLQuaternion rotation, LLVector3 velocity, LLVector3 rotationalvelocity)
1723 {
1724 uint ID = localID;
1725 byte[] bytes = new byte[60];
1726
1727 int i = 0;
1728 ImprovedTerseObjectUpdatePacket.ObjectDataBlock dat = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock();
1729 dat.TextureEntry = new byte[0];
1730 bytes[i++] = (byte) (ID%256);
1731 bytes[i++] = (byte) ((ID >> 8)%256);
1732 bytes[i++] = (byte) ((ID >> 16)%256);
1733 bytes[i++] = (byte) ((ID >> 24)%256);
1734 bytes[i++] = 0;
1735 bytes[i++] = 0;
1736
1737 byte[] pb = position.GetBytes();
1738 Array.Copy(pb, 0, bytes, i, pb.Length);
1739 i += 12;
1740 ushort ac = 32767;
1741
1742 ushort velx, vely, velz;
1743 Vector3 vel = new Vector3(velocity.X, velocity.Y, velocity.Z);
1744
1745 vel = vel/128.0f;
1746 vel.x += 1;
1747 vel.y += 1;
1748 vel.z += 1;
1749 //vel
1750 velx = (ushort)(32768 * (vel.x));
1751 vely = (ushort)(32768 * (vel.y));
1752 velz = (ushort)(32768 * (vel.z));
1753
1754 bytes[i++] = (byte) (velx % 256);
1755 bytes[i++] = (byte) ((velx >> 8) % 256);
1756 bytes[i++] = (byte) (vely % 256);
1757 bytes[i++] = (byte) ((vely >> 8) % 256);
1758 bytes[i++] = (byte) (velz % 256);
1759 bytes[i++] = (byte) ((velz >> 8) % 256);
1760
1761 //accel
1762 bytes[i++] = (byte) (ac%256);
1763 bytes[i++] = (byte) ((ac >> 8)%256);
1764 bytes[i++] = (byte) (ac%256);
1765 bytes[i++] = (byte) ((ac >> 8)%256);
1766 bytes[i++] = (byte) (ac%256);
1767 bytes[i++] = (byte) ((ac >> 8)%256);
1768
1769 ushort rw, rx, ry, rz;
1770 rw = (ushort) (32768*(rotation.W + 1));
1771 rx = (ushort) (32768*(rotation.X + 1));
1772 ry = (ushort) (32768*(rotation.Y + 1));
1773 rz = (ushort) (32768*(rotation.Z + 1));
1774
1775 //rot
1776 bytes[i++] = (byte) (rx%256);
1777 bytes[i++] = (byte) ((rx >> 8)%256);
1778 bytes[i++] = (byte) (ry%256);
1779 bytes[i++] = (byte) ((ry >> 8)%256);
1780 bytes[i++] = (byte) (rz%256);
1781 bytes[i++] = (byte) ((rz >> 8)%256);
1782 bytes[i++] = (byte) (rw%256);
1783 bytes[i++] = (byte) ((rw >> 8)%256);
1784
1785 //rotation vel
1786 ushort rvelx, rvely, rvelz;
1787 Vector3 rvel = new Vector3(rotationalvelocity.X, rotationalvelocity.Y, rotationalvelocity.Z);
1788
1789 rvel = rvel / 128.0f;
1790 rvel.x += 1;
1791 rvel.y += 1;
1792 rvel.z += 1;
1793 //vel
1794 rvelx = (ushort)(32768 * (rvel.x));
1795 rvely = (ushort)(32768 * (rvel.y));
1796 rvelz = (ushort)(32768 * (rvel.z));
1797
1798 bytes[i++] = (byte)(rvelx % 256);
1799 bytes[i++] = (byte)((rvelx >> 8) % 256);
1800 bytes[i++] = (byte)(rvely % 256);
1801 bytes[i++] = (byte)((rvely >> 8) % 256);
1802 bytes[i++] = (byte)(rvelz % 256);
1803 bytes[i++] = (byte)((rvelz >> 8) % 256);
1804
1805 dat.Data = bytes;
1806 return dat;
1807 }
1808
1809 /// <summary>
1810 /// Create the ObjectDataBlock for a ObjectUpdatePacket (for a Primitive)
1811 /// </summary>
1812 /// <param name="primData"></param>
1813 /// <returns></returns>
1814 protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(PrimitiveBaseShape primShape, uint flags)
1815 {
1816 ObjectUpdatePacket.ObjectDataBlock objupdate = new ObjectUpdatePacket.ObjectDataBlock();
1817 SetDefaultPrimPacketValues(objupdate);
1818 objupdate.UpdateFlags = flags;
1819 SetPrimPacketShapeData(objupdate, primShape);
1820
1821 return objupdate;
1822 }
1823
1824 protected void SetPrimPacketShapeData(ObjectUpdatePacket.ObjectDataBlock objectData, PrimitiveBaseShape primData)
1825 {
1826 objectData.TextureEntry = primData.TextureEntry;
1827 objectData.PCode = primData.PCode;
1828 objectData.PathBegin = primData.PathBegin;
1829 objectData.PathEnd = primData.PathEnd;
1830 objectData.PathScaleX = primData.PathScaleX;
1831 objectData.PathScaleY = primData.PathScaleY;
1832 objectData.PathShearX = primData.PathShearX;
1833 objectData.PathShearY = primData.PathShearY;
1834 objectData.PathSkew = primData.PathSkew;
1835 objectData.ProfileBegin = primData.ProfileBegin;
1836 objectData.ProfileEnd = primData.ProfileEnd;
1837 objectData.Scale = primData.Scale;
1838 objectData.PathCurve = primData.PathCurve;
1839 objectData.ProfileCurve = primData.ProfileCurve;
1840 objectData.ProfileHollow = primData.ProfileHollow;
1841 objectData.PathRadiusOffset = primData.PathRadiusOffset;
1842 objectData.PathRevolutions = primData.PathRevolutions;
1843 objectData.PathTaperX = primData.PathTaperX;
1844 objectData.PathTaperY = primData.PathTaperY;
1845 objectData.PathTwist = primData.PathTwist;
1846 objectData.PathTwistBegin = primData.PathTwistBegin;
1847 objectData.ExtraParams = primData.ExtraParams;
1848 }
1849
1850 /// <summary>
1851 /// Set some default values in a ObjectUpdatePacket
1852 /// </summary>
1853 /// <param name="objdata"></param>
1854 protected void SetDefaultPrimPacketValues(ObjectUpdatePacket.ObjectDataBlock objdata)
1855 {
1856 objdata.PSBlock = new byte[0];
1857 objdata.ExtraParams = new byte[1];
1858 objdata.MediaURL = new byte[0];
1859 objdata.NameValue = new byte[0];
1860 objdata.Text = new byte[0];
1861 objdata.TextColor = new byte[4];
1862 objdata.JointAxisOrAnchor = new LLVector3(0, 0, 0);
1863 objdata.JointPivot = new LLVector3(0, 0, 0);
1864 objdata.Material = 3;
1865 objdata.TextureAnim = new byte[0];
1866 objdata.Sound = LLUUID.Zero;
1867 objdata.State = 0;
1868 objdata.Data = new byte[0];
1869
1870 objdata.ObjectData = new byte[60];
1871 objdata.ObjectData[46] = 128;
1872 objdata.ObjectData[47] = 63;
1873 }
1874
1875
1876 /// <summary>
1877 ///
1878 /// </summary>
1879 /// <returns></returns>
1880 protected ObjectUpdatePacket.ObjectDataBlock CreateDefaultAvatarPacket(byte[] textureEntry)
1881 {
1882 ObjectUpdatePacket.ObjectDataBlock objdata = new ObjectUpdatePacket.ObjectDataBlock();
1883 // new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock(data1, ref i);
1884
1885 SetDefaultAvatarPacketValues(ref objdata);
1886 objdata.UpdateFlags = 61 + (9 << 8) + (130 << 16) + (16 << 24);
1887 objdata.PathCurve = 16;
1888 objdata.ProfileCurve = 1;
1889 objdata.PathScaleX = 100;
1890 objdata.PathScaleY = 100;
1891 objdata.ParentID = 0;
1892 objdata.OwnerID = LLUUID.Zero;
1893 objdata.Scale = new LLVector3(1, 1, 1);
1894 objdata.PCode = 47;
1895 if (textureEntry != null)
1896 {
1897 objdata.TextureEntry = textureEntry;
1898 }
1899 Encoding enc = Encoding.ASCII;
1900 LLVector3 pos = new LLVector3(objdata.ObjectData, 16);
1901 pos.X = 100f;
1902 objdata.ID = 8880000;
1903 objdata.NameValue = enc.GetBytes("FirstName STRING RW SV Test \nLastName STRING RW SV User \0");
1904 //LLVector3 pos2 = new LLVector3(100f, 100f, 23f);
1905 //objdata.FullID=user.AgentId;
1906 byte[] pb = pos.GetBytes();
1907 Array.Copy(pb, 0, objdata.ObjectData, 16, pb.Length);
1908
1909 return objdata;
1910 }
1911
1912 /// <summary>
1913 ///
1914 /// </summary>
1915 /// <param name="objdata"></param>
1916 protected void SetDefaultAvatarPacketValues(ref ObjectUpdatePacket.ObjectDataBlock objdata)
1917 {
1918 objdata.PSBlock = new byte[0];
1919 objdata.ExtraParams = new byte[1];
1920 objdata.MediaURL = new byte[0];
1921 objdata.NameValue = new byte[0];
1922 objdata.Text = new byte[0];
1923 objdata.TextColor = new byte[4];
1924 objdata.JointAxisOrAnchor = new LLVector3(0, 0, 0);
1925 objdata.JointPivot = new LLVector3(0, 0, 0);
1926 objdata.Material = 4;
1927 objdata.TextureAnim = new byte[0];
1928 objdata.Sound = LLUUID.Zero;
1929 LLObject.TextureEntry ntex = new LLObject.TextureEntry(new LLUUID("00000000-0000-0000-5005-000000000005"));
1930 objdata.TextureEntry = ntex.ToBytes();
1931 objdata.State = 0;
1932 objdata.Data = new byte[0];
1933
1934 objdata.ObjectData = new byte[76];
1935 objdata.ObjectData[15] = 128;
1936 objdata.ObjectData[16] = 63;
1937 objdata.ObjectData[56] = 128;
1938 objdata.ObjectData[61] = 102;
1939 objdata.ObjectData[62] = 40;
1940 objdata.ObjectData[63] = 61;
1941 objdata.ObjectData[64] = 189;
1942 }
1943
1944 public void SendNameReply(LLUUID profileId, string firstname, string lastname)
1945 {
1946 UUIDNameReplyPacket packet = new UUIDNameReplyPacket();
1947
1948 packet.UUIDNameBlock = new UUIDNameReplyPacket.UUIDNameBlockBlock[1];
1949 packet.UUIDNameBlock[0] = new UUIDNameReplyPacket.UUIDNameBlockBlock();
1950 packet.UUIDNameBlock[0].ID = profileId;
1951 packet.UUIDNameBlock[0].FirstName = Helpers.StringToField(firstname);
1952 packet.UUIDNameBlock[0].LastName = Helpers.StringToField(lastname);
1953
1954 OutPacket(packet, ThrottleOutPacketType.Task);
1955 }
1956
1957 #endregion
1958
1959 protected virtual void RegisterLocalPacketHandlers()
1960 {
1961 AddLocalPacketHandler(PacketType.LogoutRequest, Logout);
1962 AddLocalPacketHandler(PacketType.ViewerEffect, HandleViewerEffect);
1963 AddLocalPacketHandler(PacketType.AgentCachedTexture, AgentTextureCached);
1964 AddLocalPacketHandler(PacketType.MultipleObjectUpdate, MultipleObjUpdate);
1965 }
1966
1967 private bool HandleViewerEffect(IClientAPI sender, Packet Pack)
1968 {
1969 ViewerEffectPacket viewer = (ViewerEffectPacket) Pack;
1970
1971 if (OnViewerEffect != null)
1972 {
1973 OnViewerEffect(sender, viewer.Effect);
1974 }
1975
1976 return true;
1977 }
1978
1979 protected virtual bool Logout(IClientAPI client, Packet packet)
1980 {
1981 MainLog.Instance.Verbose("CLIENT", "Got a logout request");
1982
1983 if (OnLogout != null)
1984 {
1985 OnLogout(client);
1986 }
1987
1988 return true;
1989 }
1990
1991 protected bool AgentTextureCached(IClientAPI simclient, Packet packet)
1992 {
1993 //System.Console.WriteLine("texture cached: " + packet.ToString());
1994 AgentCachedTexturePacket chechedtex = (AgentCachedTexturePacket) packet;
1995 AgentCachedTextureResponsePacket cachedresp = new AgentCachedTextureResponsePacket();
1996 cachedresp.AgentData.AgentID = AgentId;
1997 cachedresp.AgentData.SessionID = m_sessionId;
1998 cachedresp.AgentData.SerialNum = cachedtextureserial;
1999 cachedtextureserial++;
2000 cachedresp.WearableData =
2001 new AgentCachedTextureResponsePacket.WearableDataBlock[chechedtex.WearableData.Length];
2002 for (int i = 0; i < chechedtex.WearableData.Length; i++)
2003 {
2004 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
2005 cachedresp.WearableData[i].TextureIndex = chechedtex.WearableData[i].TextureIndex;
2006 cachedresp.WearableData[i].TextureID = LLUUID.Zero;
2007 cachedresp.WearableData[i].HostName = new byte[0];
2008 }
2009 OutPacket(cachedresp, ThrottleOutPacketType.Texture);
2010 return true;
2011 }
2012
2013 protected bool MultipleObjUpdate(IClientAPI simClient, Packet packet)
2014 {
2015 MultipleObjectUpdatePacket multipleupdate = (MultipleObjectUpdatePacket) packet;
2016 // System.Console.WriteLine("new multi update packet " + multipleupdate.ToString());
2017 for (int i = 0; i < multipleupdate.ObjectData.Length; i++)
2018 {
2019 #region position
2020
2021 if (multipleupdate.ObjectData[i].Type == 9) //change position
2022 {
2023 if (OnUpdatePrimGroupPosition != null)
2024 {
2025 LLVector3 pos = new LLVector3(multipleupdate.ObjectData[i].Data, 0);
2026 OnUpdatePrimGroupPosition(multipleupdate.ObjectData[i].ObjectLocalID, pos, this);
2027 }
2028 }
2029 else if (multipleupdate.ObjectData[i].Type == 1) //single item of group change position
2030 {
2031 if (OnUpdatePrimSinglePosition != null)
2032 {
2033 LLVector3 pos = new LLVector3(multipleupdate.ObjectData[i].Data, 0);
2034 // System.Console.WriteLine("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z);
2035 OnUpdatePrimSinglePosition(multipleupdate.ObjectData[i].ObjectLocalID, pos, this);
2036 }
2037 }
2038 #endregion position
2039 #region rotation
2040
2041 else if (multipleupdate.ObjectData[i].Type == 2) // single item of group rotation from tab
2042 {
2043 if (OnUpdatePrimSingleRotation != null)
2044 {
2045 LLQuaternion rot = new LLQuaternion(multipleupdate.ObjectData[i].Data, 0, true);
2046 //System.Console.WriteLine("new tab rotation is " + rot.X + " , " + rot.Y + " , " + rot.Z + " , " + rot.W);
2047 OnUpdatePrimSingleRotation(multipleupdate.ObjectData[i].ObjectLocalID, rot, this);
2048 }
2049 }
2050 else if (multipleupdate.ObjectData[i].Type == 3) // single item of group rotation from mouse
2051 {
2052 if (OnUpdatePrimSingleRotation != null)
2053 {
2054 LLQuaternion rot = new LLQuaternion(multipleupdate.ObjectData[i].Data, 12, true);
2055 //System.Console.WriteLine("new mouse rotation is " + rot.X + " , " + rot.Y + " , " + rot.Z + " , " + rot.W);
2056 OnUpdatePrimSingleRotation(multipleupdate.ObjectData[i].ObjectLocalID, rot, this);
2057 }
2058 }
2059 else if (multipleupdate.ObjectData[i].Type == 10) //group rotation from object tab
2060 {
2061 if (OnUpdatePrimGroupRotation != null)
2062 {
2063 LLQuaternion rot = new LLQuaternion(multipleupdate.ObjectData[i].Data, 0, true);
2064 // Console.WriteLine("new rotation is " + rot.X + " , " + rot.Y + " , " + rot.Z + " , " + rot.W);
2065 OnUpdatePrimGroupRotation(multipleupdate.ObjectData[i].ObjectLocalID, rot, this);
2066 }
2067 }
2068 else if (multipleupdate.ObjectData[i].Type == 11) //group rotation from mouse
2069 {
2070 if (OnUpdatePrimGroupMouseRotation != null)
2071 {
2072 LLVector3 pos = new LLVector3(multipleupdate.ObjectData[i].Data, 0);
2073 LLQuaternion rot = new LLQuaternion(multipleupdate.ObjectData[i].Data, 12, true);
2074 //Console.WriteLine("new rotation position is " + pos.X + " , " + pos.Y + " , " + pos.Z);
2075 // Console.WriteLine("new rotation is " + rot.X + " , " + rot.Y + " , " + rot.Z + " , " + rot.W);
2076 OnUpdatePrimGroupMouseRotation(multipleupdate.ObjectData[i].ObjectLocalID, pos, rot, this);
2077 }
2078 }
2079 #endregion
2080 #region scale
2081
2082 else if (multipleupdate.ObjectData[i].Type == 13) //group scale from object tab
2083 {
2084 if (OnUpdatePrimScale != null)
2085 {
2086 LLVector3 scale = new LLVector3(multipleupdate.ObjectData[i].Data, 12);
2087 //Console.WriteLine("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
2088 OnUpdatePrimScale(multipleupdate.ObjectData[i].ObjectLocalID, scale, this);
2089
2090 // Change the position based on scale (for bug number 246)
2091 LLVector3 pos = new LLVector3(multipleupdate.ObjectData[i].Data, 0);
2092 // System.Console.WriteLine("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z);
2093 OnUpdatePrimSinglePosition(multipleupdate.ObjectData[i].ObjectLocalID, pos, this);
2094 }
2095 }
2096 else if (multipleupdate.ObjectData[i].Type == 29) //group scale from mouse
2097 {
2098 if (OnUpdatePrimScale != null)
2099 {
2100 LLVector3 scale = new LLVector3(multipleupdate.ObjectData[i].Data, 12);
2101 // Console.WriteLine("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z );
2102 OnUpdatePrimScale(multipleupdate.ObjectData[i].ObjectLocalID, scale, this);
2103 LLVector3 pos = new LLVector3(multipleupdate.ObjectData[i].Data, 0);
2104 OnUpdatePrimSinglePosition(multipleupdate.ObjectData[i].ObjectLocalID, pos, this);
2105 }
2106 }
2107 else if (multipleupdate.ObjectData[i].Type == 5) //single prim scale from object tab
2108 {
2109 if (OnUpdatePrimScale != null)
2110 {
2111 LLVector3 scale = new LLVector3(multipleupdate.ObjectData[i].Data, 12);
2112 // Console.WriteLine("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
2113 OnUpdatePrimScale(multipleupdate.ObjectData[i].ObjectLocalID, scale, this);
2114 }
2115 }
2116 else if (multipleupdate.ObjectData[i].Type == 21) //single prim scale from mouse
2117 {
2118 if (OnUpdatePrimScale != null)
2119 {
2120 LLVector3 scale = new LLVector3(multipleupdate.ObjectData[i].Data, 12);
2121 // Console.WriteLine("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
2122 OnUpdatePrimScale(multipleupdate.ObjectData[i].ObjectLocalID, scale, this);
2123 }
2124 }
2125
2126 #endregion
2127 }
2128 return true;
2129 }
2130
2131 public void RequestMapLayer()
2132 {
2133 //should be getting the map layer from the grid server
2134 //send a layer covering the 800,800 - 1200,1200 area (should be covering the requested area)
2135 MapLayerReplyPacket mapReply = new MapLayerReplyPacket();
2136 mapReply.AgentData.AgentID = AgentId;
2137 mapReply.AgentData.Flags = 0;
2138 mapReply.LayerData = new MapLayerReplyPacket.LayerDataBlock[1];
2139 mapReply.LayerData[0] = new MapLayerReplyPacket.LayerDataBlock();
2140 mapReply.LayerData[0].Bottom = 0;
2141 mapReply.LayerData[0].Left = 0;
2142 mapReply.LayerData[0].Top = 30000;
2143 mapReply.LayerData[0].Right = 30000;
2144 mapReply.LayerData[0].ImageID = new LLUUID("00000000-0000-0000-9999-000000000006");
2145 OutPacket(mapReply, ThrottleOutPacketType.Land);
2146 }
2147
2148 public void RequestMapBlocks(int minX, int minY, int maxX, int maxY)
2149 {
2150 /*
2151 IList simMapProfiles = m_gridServer.RequestMapBlocks(minX, minY, maxX, maxY);
2152 MapBlockReplyPacket mbReply = new MapBlockReplyPacket();
2153 mbReply.AgentData.AgentId = this.AgentId;
2154 int len;
2155 if (simMapProfiles == null)
2156 len = 0;
2157 else
2158 len = simMapProfiles.Count;
2159
2160 mbReply.Data = new MapBlockReplyPacket.DataBlock[len];
2161 int iii;
2162 for (iii = 0; iii < len; iii++)
2163 {
2164 Hashtable mp = (Hashtable)simMapProfiles[iii];
2165 mbReply.Data[iii] = new MapBlockReplyPacket.DataBlock();
2166 mbReply.Data[iii].Name = System.Text.Encoding.UTF8.GetBytes((string)mp["name"]);
2167 mbReply.Data[iii].Access = System.Convert.ToByte(mp["access"]);
2168 mbReply.Data[iii].Agents = System.Convert.ToByte(mp["agents"]);
2169 mbReply.Data[iii].MapImageID = new LLUUID((string)mp["map-image-id"]);
2170 mbReply.Data[iii].RegionFlags = System.Convert.ToUInt32(mp["region-flags"]);
2171 mbReply.Data[iii].WaterHeight = System.Convert.ToByte(mp["water-height"]);
2172 mbReply.Data[iii].X = System.Convert.ToUInt16(mp["x"]);
2173 mbReply.Data[iii].Y = System.Convert.ToUInt16(mp["y"]);
2174 }
2175 this.OutPacket(mbReply, ThrottleOutPacketType.Land);
2176 */
2177 }
2178
2179 // Previously ClientView.PacketQueue
2180 protected BlockingQueue<QueItem> PacketQueue;
2181
2182 protected Queue<QueItem> IncomingPacketQueue;
2183 protected Queue<QueItem> OutgoingPacketQueue;
2184 protected Queue<QueItem> ResendOutgoingPacketQueue;
2185 protected Queue<QueItem> LandOutgoingPacketQueue;
2186 protected Queue<QueItem> WindOutgoingPacketQueue;
2187 protected Queue<QueItem> CloudOutgoingPacketQueue;
2188 protected Queue<QueItem> TaskOutgoingPacketQueue;
2189 protected Queue<QueItem> TextureOutgoingPacketQueue;
2190 protected Queue<QueItem> AssetOutgoingPacketQueue;
2191
2192 protected Dictionary<uint, uint> PendingAcks = new Dictionary<uint, uint>();
2193 protected Dictionary<uint, Packet> NeedAck = new Dictionary<uint, Packet>();
2194
2195 protected Timer AckTimer;
2196 protected uint Sequence = 0;
2197 protected object SequenceLock = new object();
2198 protected const int MAX_APPENDED_ACKS = 10;
2199 protected const int RESEND_TIMEOUT = 4000;
2200 protected const int MAX_SEQUENCE = 0xFFFFFF;
2201
2202 private uint m_circuitCode;
2203 public EndPoint userEP;
2204
2205 protected PacketServer m_networkServer;
2206
2207 public uint CircuitCode
2208 {
2209 get { return m_circuitCode; }
2210 set { m_circuitCode = value; }
2211 }
2212
2213 protected virtual void ProcessOutPacket(Packet Pack)
2214 {
2215 // Keep track of when this packet was sent out
2216 Pack.TickCount = System.Environment.TickCount;
2217
2218 if (!Pack.Header.Resent)
2219 {
2220 // Set the sequence number
2221 lock (SequenceLock)
2222 {
2223 if (Sequence >= MAX_SEQUENCE)
2224 {
2225 Sequence = 1;
2226 }
2227 else
2228 {
2229 Sequence++;
2230 }
2231
2232 Pack.Header.Sequence = Sequence;
2233 }
2234
2235 if (Pack.Header.Reliable) //DIRTY HACK
2236 {
2237 lock (NeedAck)
2238 {
2239 if (!NeedAck.ContainsKey(Pack.Header.Sequence))
2240 {
2241 try
2242 {
2243 NeedAck.Add(Pack.Header.Sequence, Pack);
2244 }
2245 catch (Exception e) // HACKY
2246 {
2247 e.ToString();
2248 // Ignore
2249 // Seems to throw a exception here occasionally
2250 // of 'duplicate key' despite being locked.
2251 // !?!?!?
2252 }
2253 }
2254 else
2255 {
2256 // Client.Log("Attempted to add a duplicate sequence number (" +
2257 // packet.Header.Sequence + ") to the NeedAck dictionary for packet type " +
2258 // packet.Type.ToString(), Helpers.LogLevel.Warning);
2259 }
2260 }
2261
2262 // Don't append ACKs to resent packets, in case that's what was causing the
2263 // delivery to fail
2264 if (!Pack.Header.Resent)
2265 {
2266 // Append any ACKs that need to be sent out to this packet
2267 lock (PendingAcks)
2268 {
2269 if (PendingAcks.Count > 0 && PendingAcks.Count < MAX_APPENDED_ACKS &&
2270 Pack.Type != PacketType.PacketAck &&
2271 Pack.Type != PacketType.LogoutRequest)
2272 {
2273 Pack.Header.AckList = new uint[PendingAcks.Count];
2274 int i = 0;
2275
2276 foreach (uint ack in PendingAcks.Values)
2277 {
2278 Pack.Header.AckList[i] = ack;
2279 i++;
2280 }
2281
2282 PendingAcks.Clear();
2283 Pack.Header.AppendedAcks = true;
2284 }
2285 }
2286 }
2287 }
2288 }
2289
2290 byte[] ZeroOutBuffer = new byte[4096];
2291 byte[] sendbuffer;
2292 sendbuffer = Pack.ToBytes();
2293
2294 try
2295 {
2296 if (Pack.Header.Zerocoded)
2297 {
2298 int packetsize = Helpers.ZeroEncode(sendbuffer, sendbuffer.Length, ZeroOutBuffer);
2299 m_networkServer.SendPacketTo(ZeroOutBuffer, packetsize, SocketFlags.None, m_circuitCode); //userEP);
2300 }
2301 else
2302 {
2303 m_networkServer.SendPacketTo(sendbuffer, sendbuffer.Length, SocketFlags.None, m_circuitCode);
2304 //userEP);
2305 }
2306 }
2307 catch (Exception e)
2308 {
2309 MainLog.Instance.Warn("client",
2310 "ClientView.PacketQueue.cs:ProcessOutPacket() - WARNING: Socket exception occurred on connection " +
2311 userEP.ToString() + " - killing thread");
2312 MainLog.Instance.Error(e.ToString());
2313 KillThread();
2314 }
2315 }
2316
2317 public virtual void InPacket(Packet NewPack)
2318 {
2319 // Handle appended ACKs
2320 if (NewPack.Header.AppendedAcks)
2321 {
2322 lock (NeedAck)
2323 {
2324 foreach (uint ack in NewPack.Header.AckList)
2325 {
2326 NeedAck.Remove(ack);
2327 }
2328 }
2329 }
2330
2331 // Handle PacketAck packets
2332 if (NewPack.Type == PacketType.PacketAck)
2333 {
2334 PacketAckPacket ackPacket = (PacketAckPacket) NewPack;
2335
2336 lock (NeedAck)
2337 {
2338 foreach (PacketAckPacket.PacketsBlock block in ackPacket.Packets)
2339 {
2340 NeedAck.Remove(block.ID);
2341 }
2342 }
2343 }
2344 else if ((NewPack.Type == PacketType.StartPingCheck))
2345 {
2346 //reply to pingcheck
2347 StartPingCheckPacket startPing = (StartPingCheckPacket) NewPack;
2348 CompletePingCheckPacket endPing = new CompletePingCheckPacket();
2349 endPing.PingID.PingID = startPing.PingID.PingID;
2350 OutPacket(endPing, ThrottleOutPacketType.Task);
2351 }
2352 else
2353 {
2354 QueItem item = new QueItem();
2355 item.Packet = NewPack;
2356 item.Incoming = true;
2357 PacketQueue.Enqueue(item);
2358 }
2359 }
2360
2361 private void ThrottleCheck(ref int TypeBytesSent, int Throttle, Queue<QueItem> q, QueItem item)
2362 {
2363 // The idea.. is if the packet throttle queues are empty
2364 // and the client is under throttle for the type. Queue
2365 // it up directly. This basically short cuts having to
2366 // wait for the timer to fire to put things into the
2367 // output queue
2368
2369 if(q.Count == 0 && TypeBytesSent <= ((int)(Throttle / throttleTimeDivisor)))
2370 {
2371 bytesSent += item.Packet.ToBytes().Length;
2372 TypeBytesSent += item.Packet.ToBytes().Length;
2373 PacketQueue.Enqueue(item);
2374 }
2375 else
2376 {
2377 q.Enqueue(item);
2378 }
2379 }
2380
2381 public virtual void OutPacket(Packet NewPack, ThrottleOutPacketType throttlePacketType)
2382 {
2383 QueItem item = new QueItem();
2384 item.Packet = NewPack;
2385 item.Incoming = false;
2386 item.throttleType = throttlePacketType; // Packet throttle type
2387
2388 // The idea.. is if the packet throttle queues are empty and the client is under throttle for the type.
2389 // Queue it up directly.
2390 switch (throttlePacketType)
2391 {
2392 case ThrottleOutPacketType.Resend:
2393 ThrottleCheck(ref ResendBytesSent, ResendthrottleOutbound, ResendOutgoingPacketQueue, item);
2394 break;
2395 case ThrottleOutPacketType.Texture:
2396 ThrottleCheck(ref TextureBytesSent, TexturethrottleOutbound, TextureOutgoingPacketQueue, item);
2397 break;
2398 case ThrottleOutPacketType.Task:
2399 ThrottleCheck(ref TaskBytesSent, TaskthrottleOutbound, TaskOutgoingPacketQueue, item);
2400 break;
2401 case ThrottleOutPacketType.Land:
2402 ThrottleCheck(ref LandBytesSent, LandthrottleOutbound, LandOutgoingPacketQueue, item);
2403 break;
2404 case ThrottleOutPacketType.Asset:
2405 ThrottleCheck(ref AssetBytesSent, AssetthrottleOutbound, AssetOutgoingPacketQueue, item);
2406 break;
2407 case ThrottleOutPacketType.Cloud:
2408 ThrottleCheck(ref CloudBytesSent, CloudthrottleOutbound, CloudOutgoingPacketQueue, item);
2409 break;
2410 case ThrottleOutPacketType.Wind:
2411 ThrottleCheck(ref WindBytesSent, WindthrottleOutbound, WindOutgoingPacketQueue, item);
2412 break;
2413
2414 default:
2415 // Acknowledgements and other such stuff should go directly to the blocking Queue
2416 // Throttling them may and likely 'will' be problematic
2417 PacketQueue.Enqueue(item);
2418 break;
2419 }
2420 //OutgoingPacketQueue.Enqueue(item);
2421 }
2422
2423 # region Low Level Packet Methods
2424
2425 protected void ack_pack(Packet Pack)
2426 {
2427 if (Pack.Header.Reliable)
2428 {
2429 PacketAckPacket ack_it = new PacketAckPacket();
2430 ack_it.Packets = new PacketAckPacket.PacketsBlock[1];
2431 ack_it.Packets[0] = new PacketAckPacket.PacketsBlock();
2432 ack_it.Packets[0].ID = Pack.Header.Sequence;
2433 ack_it.Header.Reliable = false;
2434
2435 OutPacket(ack_it, ThrottleOutPacketType.Unknown);
2436 }
2437 /*
2438 if (Pack.Header.Reliable)
2439 {
2440 lock (PendingAcks)
2441 {
2442 uint sequence = (uint)Pack.Header.Sequence;
2443 if (!PendingAcks.ContainsKey(sequence)) { PendingAcks[sequence] = sequence; }
2444 }
2445 }*/
2446 }
2447
2448 protected void ResendUnacked()
2449 {
2450 int now = System.Environment.TickCount;
2451
2452 lock (NeedAck)
2453 {
2454 foreach (Packet packet in NeedAck.Values)
2455 {
2456 if ((now - packet.TickCount > RESEND_TIMEOUT) && (!packet.Header.Resent))
2457 {
2458 MainLog.Instance.Verbose("Resending " + packet.Type.ToString() + " packet, " +
2459 (now - packet.TickCount) + "ms have passed");
2460
2461 packet.Header.Resent = true;
2462 OutPacket(packet, ThrottleOutPacketType.Resend);
2463 }
2464 }
2465 }
2466 }
2467
2468 protected void SendAcks()
2469 {
2470 lock (PendingAcks)
2471 {
2472 if (PendingAcks.Count > 0)
2473 {
2474 if (PendingAcks.Count > 250)
2475 {
2476 // FIXME: Handle the odd case where we have too many pending ACKs queued up
2477 MainLog.Instance.Verbose("Too many ACKs queued up!");
2478 return;
2479 }
2480
2481 //OpenSim.Framework.Console.MainLog.Instance.WriteLine("Sending PacketAck");
2482
2483
2484 int i = 0;
2485 PacketAckPacket acks = new PacketAckPacket();
2486 acks.Packets = new PacketAckPacket.PacketsBlock[PendingAcks.Count];
2487
2488 foreach (uint ack in PendingAcks.Values)
2489 {
2490 acks.Packets[i] = new PacketAckPacket.PacketsBlock();
2491 acks.Packets[i].ID = ack;
2492 i++;
2493 }
2494
2495 acks.Header.Reliable = false;
2496 OutPacket(acks, ThrottleOutPacketType.Unknown);
2497
2498 PendingAcks.Clear();
2499 }
2500 }
2501 }
2502
2503 protected void AckTimer_Elapsed(object sender, ElapsedEventArgs ea)
2504 {
2505 SendAcks();
2506 ResendUnacked();
2507 }
2508
2509 #endregion
2510 // Previously ClientView.ProcessPackets
2511 private int m_moneyBalance;
2512
2513 public int MoneyBalance
2514 {
2515 get { return m_moneyBalance; }
2516 }
2517
2518 public bool AddMoney(int debit)
2519 {
2520 if (m_moneyBalance + debit >= 0)
2521 {
2522 m_moneyBalance += debit;
2523 SendMoneyBalance(LLUUID.Zero, true, Helpers.StringToField("Poof Poof!"), m_moneyBalance);
2524 return true;
2525 }
2526 else
2527 {
2528 return false;
2529 }
2530 }
2531
2532 protected void ProcessInPacket(Packet Pack)
2533 {
2534 ack_pack(Pack);
2535
2536 if (ProcessPacketMethod(Pack))
2537 {
2538 //there is a handler registered that handled this packet type
2539 return;
2540 }
2541 else
2542 {
2543 Encoding _enc = Encoding.ASCII;
2544
2545 switch (Pack.Type)
2546 {
2547 #region Scene/Avatar
2548
2549 case PacketType.AvatarPropertiesRequest:
2550 AvatarPropertiesRequestPacket avatarProperties = (AvatarPropertiesRequestPacket) Pack;
2551 if (OnRequestAvatarProperties != null)
2552 {
2553 OnRequestAvatarProperties(this, avatarProperties.AgentData.AvatarID);
2554 }
2555 break;
2556 case PacketType.ChatFromViewer:
2557 ChatFromViewerPacket inchatpack = (ChatFromViewerPacket) Pack;
2558
2559 string fromName = ""; //ClientAvatar.firstname + " " + ClientAvatar.lastname;
2560 byte[] message = inchatpack.ChatData.Message;
2561 byte type = inchatpack.ChatData.Type;
2562 LLVector3 fromPos = new LLVector3(); // ClientAvatar.Pos;
2563 LLUUID fromAgentID = AgentId;
2564
2565 int channel = inchatpack.ChatData.Channel;
2566
2567 if (OnChatFromViewer != null)
2568 {
2569 ChatFromViewerArgs args = new ChatFromViewerArgs();
2570 args.Channel = channel;
2571 args.From = fromName;
2572 args.Message = Helpers.FieldToUTF8String(message);
2573 args.Type = (ChatTypeEnum) type;
2574 args.Position = fromPos;
2575
2576 args.Scene = Scene;
2577 args.Sender = this;
2578
2579 OnChatFromViewer(this, args);
2580 }
2581 break;
2582 case PacketType.ImprovedInstantMessage:
2583 ImprovedInstantMessagePacket msgpack = (ImprovedInstantMessagePacket) Pack;
2584 string IMfromName = Util.FieldToString(msgpack.MessageBlock.FromAgentName);
2585 string IMmessage = Helpers.FieldToUTF8String(msgpack.MessageBlock.Message);
2586 if (OnInstantMessage != null)
2587 {
2588 OnInstantMessage(msgpack.AgentData.AgentID, msgpack.AgentData.SessionID,
2589 msgpack.MessageBlock.ToAgentID, msgpack.MessageBlock.ID,
2590 msgpack.MessageBlock.Timestamp, IMfromName, IMmessage,
2591 msgpack.MessageBlock.Dialog);
2592 }
2593 break;
2594 case PacketType.RezObject:
2595 RezObjectPacket rezPacket = (RezObjectPacket) Pack;
2596 if (OnRezObject != null)
2597 {
2598 OnRezObject(this, rezPacket.InventoryData.ItemID, rezPacket.RezData.RayEnd);
2599 }
2600 break;
2601 case PacketType.DeRezObject:
2602 if (OnDeRezObject != null)
2603 {
2604 OnDeRezObject(Pack, this);
2605 }
2606 break;
2607 case PacketType.ModifyLand:
2608 ModifyLandPacket modify = (ModifyLandPacket) Pack;
2609 if (modify.ParcelData.Length > 0)
2610 {
2611 if (OnModifyTerrain != null)
2612 {
2613 OnModifyTerrain(modify.ModifyBlock.Height, modify.ModifyBlock.Seconds,
2614 modify.ModifyBlock.BrushSize,
2615 modify.ModifyBlock.Action, modify.ParcelData[0].North,
2616 modify.ParcelData[0].West, this);
2617 }
2618 }
2619 break;
2620 case PacketType.RegionHandshakeReply:
2621 if (OnRegionHandShakeReply != null)
2622 {
2623 OnRegionHandShakeReply(this);
2624 }
2625 break;
2626 case PacketType.AgentWearablesRequest:
2627 if (OnRequestWearables != null)
2628 {
2629 OnRequestWearables( );
2630 }
2631 if (OnRequestAvatarsData != null)
2632 {
2633 OnRequestAvatarsData(this);
2634 }
2635 break;
2636 case PacketType.AgentSetAppearance:
2637 //OpenSim.Framework.Console.MainLog.Instance.Verbose("set appear", Pack.ToString());
2638 AgentSetAppearancePacket appear = (AgentSetAppearancePacket) Pack;
2639 if (OnSetAppearance != null)
2640 {
2641 OnSetAppearance(appear.ObjectData.TextureEntry, appear.VisualParam);
2642 }
2643 break;
2644 case PacketType.SetAlwaysRun:
2645 SetAlwaysRunPacket run = (SetAlwaysRunPacket)Pack;
2646
2647 if (OnSetAlwaysRun != null)
2648 OnSetAlwaysRun(this,run.AgentData.AlwaysRun);
2649
2650 break;
2651 case PacketType.CompleteAgentMovement:
2652 if (OnCompleteMovementToRegion != null)
2653 {
2654 OnCompleteMovementToRegion();
2655 }
2656 break;
2657 case PacketType.AgentUpdate:
2658 if (OnAgentUpdate != null)
2659 {
2660 AgentUpdatePacket agenUpdate = (AgentUpdatePacket) Pack;
2661
2662 OnAgentUpdate(this, agenUpdate); //agenUpdate.AgentData.ControlFlags, agenUpdate.AgentData.BodyRotationa);
2663 }
2664 break;
2665 case PacketType.AgentAnimation:
2666 AgentAnimationPacket AgentAni = (AgentAnimationPacket) Pack;
2667 for (int i = 0; i < AgentAni.AnimationList.Length; i++)
2668 {
2669 if (AgentAni.AnimationList[i].StartAnim)
2670 {
2671 if (OnStartAnim != null)
2672 {
2673 OnStartAnim(this, AgentAni.AnimationList[i].AnimID, 1);
2674 }
2675 }
2676 }
2677 break;
2678 case PacketType.AgentRequestSit:
2679 if (OnAgentRequestSit != null)
2680 {
2681 AgentRequestSitPacket agentRequestSit = (AgentRequestSitPacket) Pack;
2682 OnAgentRequestSit(this, agentRequestSit.AgentData.AgentID,
2683 agentRequestSit.TargetObject.TargetID, agentRequestSit.TargetObject.Offset);
2684 }
2685 break;
2686 case PacketType.AgentSit:
2687 if (OnAgentSit != null)
2688 {
2689 AgentSitPacket agentSit = (AgentSitPacket) Pack;
2690 OnAgentSit(this, agentSit.AgentData.AgentID);
2691 }
2692 break;
2693 case PacketType.AvatarPickerRequest:
2694 AvatarPickerRequestPacket avRequestQuery = (AvatarPickerRequestPacket)Pack;
2695 AvatarPickerRequestPacket.AgentDataBlock Requestdata = avRequestQuery.AgentData;
2696 AvatarPickerRequestPacket.DataBlock querydata = avRequestQuery.Data;
2697 //System.Console.WriteLine("Agent Sends:" + Helpers.FieldToUTF8String(querydata.Name));
2698 if (OnAvatarPickerRequest != null)
2699 {
2700 OnAvatarPickerRequest(this, Requestdata.AgentID, Requestdata.QueryID, Helpers.FieldToUTF8String(querydata.Name));
2701 }
2702 break;
2703 #endregion
2704
2705 #region Objects/m_sceneObjects
2706
2707 case PacketType.ObjectLink:
2708 //OpenSim.Framework.Console.MainLog.Instance.Verbose( Pack.ToString());
2709 ObjectLinkPacket link = (ObjectLinkPacket) Pack;
2710 uint parentprimid = 0;
2711 List<uint> childrenprims = new List<uint>();
2712 if (link.ObjectData.Length > 1)
2713 {
2714 parentprimid = link.ObjectData[0].ObjectLocalID;
2715
2716 for (int i = 1; i < link.ObjectData.Length; i++)
2717 {
2718 childrenprims.Add(link.ObjectData[i].ObjectLocalID);
2719 }
2720 }
2721 if (OnLinkObjects != null)
2722 {
2723 OnLinkObjects(parentprimid, childrenprims);
2724 }
2725 break;
2726 case PacketType.ObjectDelink:
2727 //OpenSim.Framework.Console.MainLog.Instance.Verbose( Pack.ToString());
2728 ObjectDelinkPacket delink = (ObjectDelinkPacket) Pack;
2729
2730 // It appears the prim at index 0 is not always the root prim (for
2731 // instance, when one prim of a link set has been edited independently
2732 // of the others). Therefore, we'll pass all the ids onto the delink
2733 // method for it to decide which is the root.
2734 List<uint> prims = new List<uint>();
2735 for (int i = 0; i < delink.ObjectData.Length; i++)
2736 {
2737 prims.Add(delink.ObjectData[i].ObjectLocalID);
2738 }
2739
2740 if (OnDelinkObjects != null)
2741 {
2742 OnDelinkObjects(prims);
2743 }
2744
2745 break;
2746 case PacketType.ObjectAdd:
2747 if (OnAddPrim != null)
2748 {
2749 ObjectAddPacket addPacket = (ObjectAddPacket) Pack;
2750 PrimitiveBaseShape shape = GetShapeFromAddPacket(addPacket);
2751 OnAddPrim(AgentId, addPacket.ObjectData.RayEnd, addPacket.ObjectData.Rotation, shape);
2752 }
2753 break;
2754 case PacketType.ObjectShape:
2755 ObjectShapePacket shapePacket = (ObjectShapePacket) Pack;
2756 for (int i = 0; i < shapePacket.ObjectData.Length; i++)
2757 {
2758 if (OnUpdatePrimShape != null)
2759 {
2760 OnUpdatePrimShape(shapePacket.ObjectData[i].ObjectLocalID, shapePacket.ObjectData[i]);
2761 }
2762 }
2763 break;
2764 case PacketType.ObjectExtraParams:
2765 ObjectExtraParamsPacket extraPar = (ObjectExtraParamsPacket) Pack;
2766 if (OnUpdateExtraParams != null)
2767 {
2768 OnUpdateExtraParams(extraPar.ObjectData[0].ObjectLocalID, extraPar.ObjectData[0].ParamType,
2769 extraPar.ObjectData[0].ParamInUse, extraPar.ObjectData[0].ParamData);
2770 }
2771 break;
2772 case PacketType.ObjectDuplicate:
2773 ObjectDuplicatePacket dupe = (ObjectDuplicatePacket) Pack;
2774 ObjectDuplicatePacket.AgentDataBlock AgentandGroupData = dupe.AgentData;
2775 for (int i = 0; i < dupe.ObjectData.Length; i++)
2776 {
2777 if (OnObjectDuplicate != null)
2778 {
2779 OnObjectDuplicate(dupe.ObjectData[i].ObjectLocalID, dupe.SharedData.Offset,
2780 dupe.SharedData.DuplicateFlags, AgentandGroupData.AgentID, AgentandGroupData.GroupID);
2781 }
2782 }
2783
2784 break;
2785
2786 case PacketType.ObjectSelect:
2787 ObjectSelectPacket incomingselect = (ObjectSelectPacket) Pack;
2788 for (int i = 0; i < incomingselect.ObjectData.Length; i++)
2789 {
2790 if (OnObjectSelect != null)
2791 {
2792 OnObjectSelect(incomingselect.ObjectData[i].ObjectLocalID, this);
2793 }
2794 }
2795 break;
2796 case PacketType.ObjectDeselect:
2797 ObjectDeselectPacket incomingdeselect = (ObjectDeselectPacket) Pack;
2798 for (int i = 0; i < incomingdeselect.ObjectData.Length; i++)
2799 {
2800 if (OnObjectDeselect != null)
2801 {
2802 OnObjectDeselect(incomingdeselect.ObjectData[i].ObjectLocalID, this);
2803 }
2804 }
2805 break;
2806 case PacketType.ObjectFlagUpdate:
2807 ObjectFlagUpdatePacket flags = (ObjectFlagUpdatePacket) Pack;
2808 if (OnUpdatePrimFlags != null)
2809 {
2810 OnUpdatePrimFlags(flags.AgentData.ObjectLocalID, Pack, this);
2811 }
2812 break;
2813 case PacketType.ObjectImage:
2814 ObjectImagePacket imagePack = (ObjectImagePacket) Pack;
2815 for (int i = 0; i < imagePack.ObjectData.Length; i++)
2816 {
2817 if (OnUpdatePrimTexture != null)
2818 {
2819 OnUpdatePrimTexture(imagePack.ObjectData[i].ObjectLocalID,
2820 imagePack.ObjectData[i].TextureEntry, this);
2821 }
2822 }
2823 break;
2824 case PacketType.ObjectGrab:
2825 ObjectGrabPacket grab = (ObjectGrabPacket) Pack;
2826 if (OnGrabObject != null)
2827 {
2828 OnGrabObject(grab.ObjectData.LocalID, grab.ObjectData.GrabOffset, this);
2829 }
2830 break;
2831 case PacketType.ObjectGrabUpdate:
2832 ObjectGrabUpdatePacket grabUpdate = (ObjectGrabUpdatePacket) Pack;
2833 if (OnGrabUpdate != null)
2834 {
2835 OnGrabUpdate(grabUpdate.ObjectData.ObjectID, grabUpdate.ObjectData.GrabOffsetInitial,
2836 grabUpdate.ObjectData.GrabPosition, this);
2837 }
2838 break;
2839 case PacketType.ObjectDeGrab:
2840 ObjectDeGrabPacket deGrab = (ObjectDeGrabPacket) Pack;
2841 if (OnDeGrabObject != null)
2842 {
2843 OnDeGrabObject(deGrab.ObjectData.LocalID, this);
2844 }
2845 break;
2846 case PacketType.ObjectDescription:
2847 ObjectDescriptionPacket objDes = (ObjectDescriptionPacket) Pack;
2848 for (int i = 0; i < objDes.ObjectData.Length; i++)
2849 {
2850 if (OnObjectDescription != null)
2851 {
2852 OnObjectDescription(objDes.ObjectData[i].LocalID,
2853 enc.GetString(objDes.ObjectData[i].Description));
2854 }
2855 }
2856 break;
2857 case PacketType.ObjectName:
2858 ObjectNamePacket objName = (ObjectNamePacket) Pack;
2859 for (int i = 0; i < objName.ObjectData.Length; i++)
2860 {
2861 if (OnObjectName != null)
2862 {
2863 OnObjectName(objName.ObjectData[i].LocalID, enc.GetString(objName.ObjectData[i].Name));
2864 }
2865 }
2866 break;
2867 case PacketType.ObjectPermissions:
2868 OpenSim.Framework.Console.MainLog.Instance.Verbose("CLIENT", "unhandled packet " + Pack.ToString());
2869 break;
2870
2871 case PacketType.RequestObjectPropertiesFamily:
2872 //This powers the little tooltip that appears when you move your mouse over an object
2873 RequestObjectPropertiesFamilyPacket packToolTip = (RequestObjectPropertiesFamilyPacket)Pack;
2874
2875
2876 RequestObjectPropertiesFamilyPacket.ObjectDataBlock packObjBlock = packToolTip.ObjectData;
2877
2878 if (OnRequestObjectPropertiesFamily != null)
2879 {
2880 OnRequestObjectPropertiesFamily(this, this.m_agentId, packObjBlock.RequestFlags, packObjBlock.ObjectID);
2881
2882
2883 }
2884
2885 break;
2886
2887 #endregion
2888
2889 #region Inventory/Asset/Other related packets
2890
2891 case PacketType.RequestImage:
2892 RequestImagePacket imageRequest = (RequestImagePacket) Pack;
2893 //Console.WriteLine("image request: " + Pack.ToString());
2894 for (int i = 0; i < imageRequest.RequestImage.Length; i++)
2895 {
2896 // still working on the Texture download module so for now using old method
2897 // TextureRequestArgs args = new TextureRequestArgs();
2898 // args.RequestedAssetID = imageRequest.RequestImage[i].Image;
2899 // args.DiscardLevel = imageRequest.RequestImage[i].DiscardLevel;
2900 // args.PacketNumber = imageRequest.RequestImage[i].Packet;
2901
2902 // if (OnRequestTexture != null)
2903 // {
2904 // OnRequestTexture(this, args);
2905 // }
2906
2907 m_assetCache.AddTextureRequest(this, imageRequest.RequestImage[i].Image,
2908 imageRequest.RequestImage[i].Packet,
2909 imageRequest.RequestImage[i].DiscardLevel);
2910 }
2911 break;
2912 case PacketType.TransferRequest:
2913 //Console.WriteLine("ClientView.ProcessPackets.cs:ProcessInPacket() - Got transfer request");
2914 TransferRequestPacket transfer = (TransferRequestPacket) Pack;
2915 m_assetCache.AddAssetRequest(this, transfer);
2916 break;
2917 case PacketType.AssetUploadRequest:
2918 AssetUploadRequestPacket request = (AssetUploadRequestPacket) Pack;
2919 // Console.WriteLine("upload request " + Pack.ToString());
2920 // Console.WriteLine("upload request was for assetid: " + request.AssetBlock.TransactionID.Combine(this.SecureSessionID).ToStringHyphenated());
2921 if (OnAssetUploadRequest != null)
2922 {
2923 OnAssetUploadRequest(this, request.AssetBlock.TransactionID.Combine(SecureSessionID),
2924 request.AssetBlock.TransactionID, request.AssetBlock.Type,
2925 request.AssetBlock.AssetData, request.AssetBlock.StoreLocal);
2926 }
2927 break;
2928 case PacketType.RequestXfer:
2929 RequestXferPacket xferReq = (RequestXferPacket) Pack;
2930 if (OnRequestXfer != null)
2931 {
2932 OnRequestXfer(this, xferReq.XferID.ID, Util.FieldToString(xferReq.XferID.Filename));
2933 }
2934 break;
2935 case PacketType.SendXferPacket:
2936 SendXferPacketPacket xferRec = (SendXferPacketPacket) Pack;
2937 if (OnXferReceive != null)
2938 {
2939 OnXferReceive(this, xferRec.XferID.ID, xferRec.XferID.Packet, xferRec.DataPacket.Data);
2940 }
2941 break;
2942 case PacketType.ConfirmXferPacket:
2943 ConfirmXferPacketPacket confirmXfer = (ConfirmXferPacketPacket) Pack;
2944 if (OnConfirmXfer != null)
2945 {
2946 OnConfirmXfer(this, confirmXfer.XferID.ID, confirmXfer.XferID.Packet);
2947 }
2948 break;
2949 case PacketType.CreateInventoryFolder:
2950 if (OnCreateNewInventoryFolder != null)
2951 {
2952 CreateInventoryFolderPacket invFolder = (CreateInventoryFolderPacket) Pack;
2953 OnCreateNewInventoryFolder(this, invFolder.FolderData.FolderID,
2954 (ushort) invFolder.FolderData.Type,
2955 Util.FieldToString(invFolder.FolderData.Name),
2956 invFolder.FolderData.ParentID);
2957 }
2958 break;
2959 case PacketType.CreateInventoryItem:
2960 CreateInventoryItemPacket createItem = (CreateInventoryItemPacket) Pack;
2961 if (OnCreateNewInventoryItem != null)
2962 {
2963 OnCreateNewInventoryItem(this, createItem.InventoryBlock.TransactionID,
2964 createItem.InventoryBlock.FolderID,
2965 createItem.InventoryBlock.CallbackID,
2966 Util.FieldToString(createItem.InventoryBlock.Description),
2967 Util.FieldToString(createItem.InventoryBlock.Name),
2968 createItem.InventoryBlock.InvType,
2969 createItem.InventoryBlock.Type,
2970 createItem.InventoryBlock.WearableType,
2971 createItem.InventoryBlock.NextOwnerMask);
2972 }
2973 break;
2974 case PacketType.FetchInventory:
2975 if (OnFetchInventory != null)
2976 {
2977 FetchInventoryPacket FetchInventory = (FetchInventoryPacket) Pack;
2978 for (int i = 0; i < FetchInventory.InventoryData.Length; i++)
2979 {
2980 OnFetchInventory(this, FetchInventory.InventoryData[i].ItemID,
2981 FetchInventory.InventoryData[i].OwnerID);
2982 }
2983 }
2984 break;
2985 case PacketType.FetchInventoryDescendents:
2986 if (OnFetchInventoryDescendents != null)
2987 {
2988 FetchInventoryDescendentsPacket Fetch = (FetchInventoryDescendentsPacket) Pack;
2989 OnFetchInventoryDescendents(this, Fetch.InventoryData.FolderID, Fetch.InventoryData.OwnerID,
2990 Fetch.InventoryData.FetchFolders, Fetch.InventoryData.FetchItems,
2991 Fetch.InventoryData.SortOrder);
2992 }
2993 break;
2994 case PacketType.UpdateInventoryItem:
2995 UpdateInventoryItemPacket update = (UpdateInventoryItemPacket) Pack;
2996 if (OnUpdateInventoryItem != null)
2997 {
2998 for (int i = 0; i < update.InventoryData.Length; i++)
2999 {
3000 if (update.InventoryData[i].TransactionID != LLUUID.Zero)
3001 {
3002 OnUpdateInventoryItem(this, update.InventoryData[i].TransactionID,
3003 update.InventoryData[i].TransactionID.Combine(SecureSessionID),
3004 update.InventoryData[i].ItemID);
3005 }
3006 }
3007 }
3008 //Console.WriteLine(Pack.ToString());
3009 /*for (int i = 0; i < update.InventoryData.Length; i++)
3010 {
3011 if (update.InventoryData[i].TransactionID != LLUUID.Zero)
3012 {
3013 AssetBase asset = m_assetCache.GetAsset(update.InventoryData[i].TransactionID.Combine(this.SecureSessionID));
3014 if (asset != null)
3015 {
3016 // Console.WriteLine("updating inventory item, found asset" + asset.FullID.ToStringHyphenated() + " already in cache");
3017 m_inventoryCache.UpdateInventoryItemAsset(this, update.InventoryData[i].ItemID, asset);
3018 }
3019 else
3020 {
3021 asset = this.UploadAssets.AddUploadToAssetCache(update.InventoryData[i].TransactionID);
3022 if (asset != null)
3023 {
3024 //Console.WriteLine("updating inventory item, adding asset" + asset.FullID.ToStringHyphenated() + " to cache");
3025 m_inventoryCache.UpdateInventoryItemAsset(this, update.InventoryData[i].ItemID, asset);
3026 }
3027 else
3028 {
3029 //Console.WriteLine("trying to update inventory item, but asset is null");
3030 }
3031 }
3032 }
3033 else
3034 {
3035 m_inventoryCache.UpdateInventoryItemDetails(this, update.InventoryData[i].ItemID, update.InventoryData[i]); ;
3036 }
3037 }*/
3038 break;
3039 case PacketType.CopyInventoryItem:
3040 CopyInventoryItemPacket copyitem = (CopyInventoryItemPacket) Pack;
3041 if (OnCopyInventoryItem != null)
3042 {
3043 foreach (CopyInventoryItemPacket.InventoryDataBlock datablock in copyitem.InventoryData)
3044 {
3045 OnCopyInventoryItem(this, datablock.CallbackID, datablock.OldAgentID, datablock.OldItemID, datablock.NewFolderID, Util.FieldToString(datablock.NewName));
3046 }
3047 }
3048 break;
3049 case PacketType.RequestTaskInventory:
3050 RequestTaskInventoryPacket requesttask = (RequestTaskInventoryPacket) Pack;
3051 if (OnRequestTaskInventory != null)
3052 {
3053 OnRequestTaskInventory(this, requesttask.InventoryData.LocalID);
3054 }
3055 break;
3056 case PacketType.UpdateTaskInventory:
3057 //Console.WriteLine(Pack.ToString());
3058 UpdateTaskInventoryPacket updatetask = (UpdateTaskInventoryPacket) Pack;
3059 if (OnUpdateTaskInventory != null)
3060 {
3061 if (updatetask.UpdateData.Key == 0)
3062 {
3063 OnUpdateTaskInventory(this, updatetask.InventoryData.ItemID,
3064 updatetask.InventoryData.FolderID, updatetask.UpdateData.LocalID);
3065 }
3066 }
3067 break;
3068 case PacketType.RemoveTaskInventory:
3069 RemoveTaskInventoryPacket removeTask = (RemoveTaskInventoryPacket) Pack;
3070 if (OnRemoveTaskItem != null)
3071 {
3072 OnRemoveTaskItem(this, removeTask.InventoryData.ItemID, removeTask.InventoryData.LocalID);
3073 }
3074 break;
3075 case PacketType.MoveTaskInventory:
3076 OpenSim.Framework.Console.MainLog.Instance.Verbose("CLIENT", "unhandled packet " + Pack.ToString());
3077 break;
3078 case PacketType.RezScript:
3079 //Console.WriteLine(Pack.ToString());
3080 RezScriptPacket rezScript = (RezScriptPacket) Pack;
3081 if (OnRezScript != null)
3082 {
3083 OnRezScript(this, rezScript.InventoryBlock.ItemID, rezScript.UpdateBlock.ObjectLocalID);
3084 }
3085 break;
3086 case PacketType.MapLayerRequest:
3087 RequestMapLayer();
3088 break;
3089 case PacketType.MapBlockRequest:
3090 MapBlockRequestPacket MapRequest = (MapBlockRequestPacket) Pack;
3091 if (OnRequestMapBlocks != null)
3092 {
3093 OnRequestMapBlocks(this, MapRequest.PositionData.MinX, MapRequest.PositionData.MinY,
3094 MapRequest.PositionData.MaxX, MapRequest.PositionData.MaxY);
3095 }
3096 break;
3097 case PacketType.MapNameRequest:
3098 MapNameRequestPacket map = (MapNameRequestPacket) Pack;
3099 string mapName = UTF8Encoding.UTF8.GetString(map.NameData.Name, 0,
3100 map.NameData.Name.Length - 1);
3101 if (OnMapNameRequest != null)
3102 {
3103 OnMapNameRequest(this, mapName);
3104 }
3105 break;
3106 case PacketType.TeleportLandmarkRequest:
3107 TeleportLandmarkRequestPacket tpReq = (TeleportLandmarkRequestPacket) Pack;
3108
3109 TeleportStartPacket tpStart = new TeleportStartPacket();
3110 tpStart.Info.TeleportFlags = 8; // tp via lm
3111 OutPacket(tpStart, ThrottleOutPacketType.Task);
3112
3113 TeleportProgressPacket tpProgress = new TeleportProgressPacket();
3114 tpProgress.Info.Message = (new ASCIIEncoding()).GetBytes("sending_landmark");
3115 tpProgress.Info.TeleportFlags = 8;
3116 tpProgress.AgentData.AgentID = tpReq.Info.AgentID;
3117 OutPacket(tpProgress, ThrottleOutPacketType.Task);
3118
3119 // Fetch landmark
3120 LLUUID lmid = tpReq.Info.LandmarkID;
3121 AssetBase lma = m_assetCache.GetAsset(lmid);
3122 if (lma != null)
3123 {
3124 AssetLandmark lm = new AssetLandmark(lma);
3125
3126 if (lm.RegionID == m_scene.RegionInfo.RegionID)
3127 {
3128 TeleportLocalPacket tpLocal = new TeleportLocalPacket();
3129
3130 tpLocal.Info.AgentID = tpReq.Info.AgentID;
3131 tpLocal.Info.TeleportFlags = 8; // Teleport via landmark
3132 tpLocal.Info.LocationID = 2;
3133 tpLocal.Info.Position = lm.Position;
3134 OutPacket(tpLocal, ThrottleOutPacketType.Task);
3135 }
3136 else
3137 {
3138 TeleportCancelPacket tpCancel = new TeleportCancelPacket();
3139 tpCancel.Info.AgentID = tpReq.Info.AgentID;
3140 tpCancel.Info.SessionID = tpReq.Info.SessionID;
3141 OutPacket(tpCancel, ThrottleOutPacketType.Task);
3142 }
3143 }
3144 else
3145 {
3146 Console.WriteLine("Cancelling Teleport - fetch asset not yet implemented");
3147
3148 TeleportCancelPacket tpCancel = new TeleportCancelPacket();
3149 tpCancel.Info.AgentID = tpReq.Info.AgentID;
3150 tpCancel.Info.SessionID = tpReq.Info.SessionID;
3151 OutPacket(tpCancel, ThrottleOutPacketType.Task);
3152 }
3153 break;
3154 case PacketType.TeleportLocationRequest:
3155 TeleportLocationRequestPacket tpLocReq = (TeleportLocationRequestPacket) Pack;
3156 // Console.WriteLine(tpLocReq.ToString());
3157
3158 if (OnTeleportLocationRequest != null)
3159 {
3160 OnTeleportLocationRequest(this, tpLocReq.Info.RegionHandle, tpLocReq.Info.Position,
3161 tpLocReq.Info.LookAt, 16);
3162 }
3163 else
3164 {
3165 //no event handler so cancel request
3166 TeleportCancelPacket tpCancel = new TeleportCancelPacket();
3167 tpCancel.Info.SessionID = tpLocReq.AgentData.SessionID;
3168 tpCancel.Info.AgentID = tpLocReq.AgentData.AgentID;
3169 OutPacket(tpCancel, ThrottleOutPacketType.Task);
3170 }
3171 break;
3172
3173 #endregion
3174
3175 case PacketType.MoneyBalanceRequest:
3176 SendMoneyBalance(LLUUID.Zero, true, new byte[0], MoneyBalance);
3177 break;
3178 case PacketType.UUIDNameRequest:
3179 UUIDNameRequestPacket incoming = (UUIDNameRequestPacket) Pack;
3180 foreach (UUIDNameRequestPacket.UUIDNameBlockBlock UUIDBlock in incoming.UUIDNameBlock)
3181 {
3182 OnNameFromUUIDRequest(UUIDBlock.ID, this);
3183 }
3184 break;
3185
3186 #region Parcel related packets
3187
3188 case PacketType.ParcelPropertiesRequest:
3189 ParcelPropertiesRequestPacket propertiesRequest = (ParcelPropertiesRequestPacket) Pack;
3190 if (OnParcelPropertiesRequest != null)
3191 {
3192 OnParcelPropertiesRequest((int) Math.Round(propertiesRequest.ParcelData.West),
3193 (int) Math.Round(propertiesRequest.ParcelData.South),
3194 (int) Math.Round(propertiesRequest.ParcelData.East),
3195 (int) Math.Round(propertiesRequest.ParcelData.North),
3196 propertiesRequest.ParcelData.SequenceID,
3197 propertiesRequest.ParcelData.SnapSelection, this);
3198 }
3199 break;
3200 case PacketType.ParcelDivide:
3201 ParcelDividePacket landDivide = (ParcelDividePacket) Pack;
3202 if (OnParcelDivideRequest != null)
3203 {
3204 OnParcelDivideRequest((int) Math.Round(landDivide.ParcelData.West),
3205 (int) Math.Round(landDivide.ParcelData.South),
3206 (int) Math.Round(landDivide.ParcelData.East),
3207 (int) Math.Round(landDivide.ParcelData.North), this);
3208 }
3209 break;
3210 case PacketType.ParcelJoin:
3211 ParcelJoinPacket landJoin = (ParcelJoinPacket) Pack;
3212 if (OnParcelJoinRequest != null)
3213 {
3214 OnParcelJoinRequest((int) Math.Round(landJoin.ParcelData.West),
3215 (int) Math.Round(landJoin.ParcelData.South),
3216 (int) Math.Round(landJoin.ParcelData.East),
3217 (int) Math.Round(landJoin.ParcelData.North), this);
3218 }
3219 break;
3220 case PacketType.ParcelPropertiesUpdate:
3221 ParcelPropertiesUpdatePacket updatePacket = (ParcelPropertiesUpdatePacket) Pack;
3222 if (OnParcelPropertiesUpdateRequest != null)
3223 {
3224 OnParcelPropertiesUpdateRequest(updatePacket, this);
3225 }
3226 break;
3227 case PacketType.ParcelSelectObjects:
3228 ParcelSelectObjectsPacket selectPacket = (ParcelSelectObjectsPacket) Pack;
3229 if (OnParcelSelectObjects != null)
3230 {
3231 OnParcelSelectObjects(selectPacket.ParcelData.LocalID,
3232 Convert.ToInt32(selectPacket.ParcelData.ReturnType), this);
3233 }
3234 break;
3235 case PacketType.ParcelObjectOwnersRequest:
3236 //System.Console.WriteLine(Pack.ToString());
3237 ParcelObjectOwnersRequestPacket reqPacket = (ParcelObjectOwnersRequestPacket) Pack;
3238 if (OnParcelObjectOwnerRequest != null)
3239 {
3240 OnParcelObjectOwnerRequest(reqPacket.ParcelData.LocalID, this);
3241 }
3242 break;
3243
3244 #endregion
3245
3246 #region Estate Packets
3247
3248 case PacketType.EstateOwnerMessage:
3249 EstateOwnerMessagePacket messagePacket = (EstateOwnerMessagePacket) Pack;
3250 if (OnEstateOwnerMessage != null)
3251 {
3252 OnEstateOwnerMessage(messagePacket, this);
3253 }
3254 break;
3255
3256 case PacketType.AgentThrottle:
3257
3258 //OpenSim.Framework.Console.MainLog.Instance.Verbose("CLIENT", "unhandled packet " + Pack.ToString());
3259
3260 AgentThrottlePacket atpack = (AgentThrottlePacket)Pack;
3261
3262 byte[] throttle = atpack.Throttle.Throttles;
3263 int tResend = -1;
3264 int tLand = -1;
3265 int tWind = -1;
3266 int tCloud = -1;
3267 int tTask = -1;
3268 int tTexture = -1;
3269 int tAsset = -1;
3270 int tall = -1;
3271 int singlefloat = 4;
3272
3273 //Agent Throttle Block contains 7 single floatingpoint values.
3274 int j = 0;
3275
3276 // Some Systems may be big endian...
3277 // it might be smart to do this check more often...
3278 if (!BitConverter.IsLittleEndian)
3279 for (int i = 0; i < 7; i++)
3280 Array.Reverse(throttle, j + i * singlefloat, singlefloat);
3281
3282 // values gotten from libsecondlife.org/wiki/Throttle. Thanks MW_
3283 // bytes
3284 // Convert to integer, since.. the full fp space isn't used.
3285 tResend = (int)BitConverter.ToSingle(throttle, j);
3286 j += singlefloat;
3287 tLand = (int)BitConverter.ToSingle(throttle, j);
3288 j += singlefloat;
3289 tWind = (int)BitConverter.ToSingle(throttle, j);
3290 j += singlefloat;
3291 tCloud = (int)BitConverter.ToSingle(throttle, j);
3292 j += singlefloat;
3293 tTask = (int)BitConverter.ToSingle(throttle, j);
3294 j += singlefloat;
3295 tTexture = (int)BitConverter.ToSingle(throttle, j);
3296 j += singlefloat;
3297 tAsset = (int)BitConverter.ToSingle(throttle, j);
3298
3299 tall = tResend + tLand + tWind + tCloud + tTask + tTexture + tAsset;
3300 /*
3301 OpenSim.Framework.Console.MainLog.Instance.Verbose("CLIENT", "Client AgentThrottle - Got throttle:resendbytes=" + tResend +
3302 " landbytes=" + tLand +
3303 " windbytes=" + tWind +
3304 " cloudbytes=" + tCloud +
3305 " taskbytes=" + tTask +
3306 " texturebytes=" + tTexture +
3307 " Assetbytes=" + tAsset +
3308 " Allbytes=" + tall);
3309 */
3310
3311 // Total Sanity
3312 // Make sure that the client sent sane total values.
3313
3314 // If the client didn't send acceptable values....
3315 // Scale the clients values down until they are acceptable.
3316
3317 if (tall <= throttleOutboundMax)
3318 {
3319 // Sanity
3320 // Making sure the client sends sane values
3321 // This gives us a measure of control of the comms
3322 // Check Max of Type
3323 // Then Check Min of type
3324
3325 // Resend throttle
3326 if (tResend <= ResendthrottleMAX)
3327 ResendthrottleOutbound = tResend;
3328
3329 if (tResend < ResendthrottleMin)
3330 ResendthrottleOutbound = ResendthrottleMin;
3331
3332 // Land throttle
3333 if (tLand <= LandthrottleMax)
3334 LandthrottleOutbound = tLand;
3335
3336 if (tLand < LandthrottleMin)
3337 LandthrottleOutbound = LandthrottleMin;
3338
3339 // Wind throttle
3340 if (tWind <= WindthrottleMax)
3341 WindthrottleOutbound = tWind;
3342
3343 if (tWind < WindthrottleMin)
3344 WindthrottleOutbound = WindthrottleMin;
3345
3346 // Cloud throttle
3347 if (tCloud <= CloudthrottleMax)
3348 CloudthrottleOutbound = tCloud;
3349
3350 if (tCloud < CloudthrottleMin)
3351 CloudthrottleOutbound = CloudthrottleMin;
3352
3353 // Task throttle
3354 if (tTask <= TaskthrottleMax)
3355 TaskthrottleOutbound = tTask;
3356
3357 if (tTask < TaskthrottleMin)
3358 TaskthrottleOutbound = TaskthrottleMin;
3359
3360 // Texture throttle
3361 if (tTexture <= TexturethrottleMax)
3362 TexturethrottleOutbound = tTexture;
3363
3364 if (tTexture < TexturethrottleMin)
3365 TexturethrottleOutbound = TexturethrottleMin;
3366
3367 //Asset throttle
3368 if (tAsset <= AssetthrottleMax)
3369 AssetthrottleOutbound = tAsset;
3370
3371 if (tAsset < AssetthrottleMin)
3372 AssetthrottleOutbound = AssetthrottleMin;
3373
3374 /* OpenSim.Framework.Console.MainLog.Instance.Verbose("THROTTLE", "Using:resendbytes=" + ResendthrottleOutbound +
3375 " landbytes=" + LandthrottleOutbound +
3376 " windbytes=" + WindthrottleOutbound +
3377 " cloudbytes=" + CloudthrottleOutbound +
3378 " taskbytes=" + TaskthrottleOutbound +
3379 " texturebytes=" + TexturethrottleOutbound +
3380 " Assetbytes=" + AssetthrottleOutbound +
3381 " Allbytes=" + tall);
3382 */
3383 }
3384 else
3385 {
3386 // The client didn't send acceptable values..
3387 // so it's our job now to turn them into acceptable values
3388 // We're going to first scale the values down
3389 // After that we're going to check if the scaled values are sane
3390
3391 // We're going to be dividing by a user value.. so make sure
3392 // we don't get a divide by zero error.
3393 if (tall > 0)
3394 {
3395 // Find out the percentage of all communications
3396 // the client requests for each type. We'll keep resend at
3397 // it's client recommended level (won't scale it down)
3398 // unless it's beyond sane values itself.
3399
3400 if (tResend <= ResendthrottleMAX)
3401 {
3402 // This is nexted because we only want to re-set the values
3403 // the packet throttler uses once.
3404
3405 if (tResend >= ResendthrottleMin)
3406 {
3407 ResendthrottleOutbound = tResend;
3408 }
3409 else
3410 {
3411 ResendthrottleOutbound = ResendthrottleMin;
3412 }
3413 }
3414 else
3415 {
3416 ResendthrottleOutbound = ResendthrottleMAX;
3417 }
3418
3419
3420 // Getting Percentages of communication for each type of data
3421 float LandPercent = (float)(tLand / tall);
3422 float WindPercent = (float)(tWind / tall);
3423 float CloudPercent = (float)(tCloud / tall);
3424 float TaskPercent = (float)(tTask / tall);
3425 float TexturePercent = (float)(tTexture / tall);
3426 float AssetPercent = (float)(tAsset / tall);
3427
3428 // Okay.. now we've got the percentages of total communication.
3429 // Apply them to a new max total
3430
3431 int tLandResult = (int)(LandPercent * throttleOutboundMax);
3432 int tWindResult = (int)(WindPercent * throttleOutboundMax);
3433 int tCloudResult = (int)(CloudPercent * throttleOutboundMax);
3434 int tTaskResult = (int)(TaskPercent * throttleOutboundMax);
3435 int tTextureResult = (int)(TexturePercent * throttleOutboundMax);
3436 int tAssetResult = (int)(AssetPercent * throttleOutboundMax);
3437
3438 // Now we have to check our scaled values for sanity
3439
3440 // Check Max of Type
3441 // Then Check Min of type
3442
3443 // Land throttle
3444 if (tLandResult <= LandthrottleMax)
3445 LandthrottleOutbound = tLandResult;
3446
3447 if (tLandResult < LandthrottleMin)
3448 LandthrottleOutbound = LandthrottleMin;
3449
3450 // Wind throttle
3451 if (tWindResult <= WindthrottleMax)
3452 WindthrottleOutbound = tWindResult;
3453
3454 if (tWindResult < WindthrottleMin)
3455 WindthrottleOutbound = WindthrottleMin;
3456
3457 // Cloud throttle
3458 if (tCloudResult <= CloudthrottleMax)
3459 CloudthrottleOutbound = tCloudResult;
3460
3461 if (tCloudResult < CloudthrottleMin)
3462 CloudthrottleOutbound = CloudthrottleMin;
3463
3464 // Task throttle
3465 if (tTaskResult <= TaskthrottleMax)
3466 TaskthrottleOutbound = tTaskResult;
3467
3468 if (tTaskResult < TaskthrottleMin)
3469 TaskthrottleOutbound = TaskthrottleMin;
3470
3471 // Texture throttle
3472 if (tTextureResult <= TexturethrottleMax)
3473 TexturethrottleOutbound = tTextureResult;
3474
3475 if (tTextureResult < TexturethrottleMin)
3476 TexturethrottleOutbound = TexturethrottleMin;
3477
3478 //Asset throttle
3479 if (tAssetResult <= AssetthrottleMax)
3480 AssetthrottleOutbound = tAssetResult;
3481
3482 if (tAssetResult < AssetthrottleMin)
3483 AssetthrottleOutbound = AssetthrottleMin;
3484
3485 /* OpenSim.Framework.Console.MainLog.Instance.Verbose("THROTTLE", "Using:resendbytes=" + ResendthrottleOutbound +
3486 " landbytes=" + LandthrottleOutbound +
3487 " windbytes=" + WindthrottleOutbound +
3488 " cloudbytes=" + CloudthrottleOutbound +
3489 " taskbytes=" + TaskthrottleOutbound +
3490 " texturebytes=" + TexturethrottleOutbound +
3491 " Assetbytes=" + AssetthrottleOutbound +
3492 " Allbytes=" + tall);
3493 */
3494
3495 }
3496 else
3497 {
3498
3499 // The client sent a stupid value..
3500 // We're going to set the throttles to the minimum possible
3501 ResendthrottleOutbound = ResendthrottleMin;
3502 LandthrottleOutbound = LandthrottleMin;
3503 WindthrottleOutbound = WindthrottleMin;
3504 CloudthrottleOutbound = CloudthrottleMin;
3505 TaskthrottleOutbound = TaskthrottleMin;
3506 TexturethrottleOutbound = TexturethrottleMin;
3507 AssetthrottleOutbound = AssetthrottleMin;
3508 OpenSim.Framework.Console.MainLog.Instance.Verbose("THROTTLE", "ClientSentBadThrottle Using:resendbytes=" + ResendthrottleOutbound +
3509 " landbytes=" + LandthrottleOutbound +
3510 " windbytes=" + WindthrottleOutbound +
3511 " cloudbytes=" + CloudthrottleOutbound +
3512 " taskbytes=" + TaskthrottleOutbound +
3513 " texturebytes=" + TexturethrottleOutbound +
3514 " Assetbytes=" + AssetthrottleOutbound +
3515 " Allbytes=" + tall);
3516 }
3517
3518 }
3519 // Reset Client Throttles
3520 // This has the effect of 'wiggling the slider
3521 // causes prim and stuck textures that didn't download to download
3522
3523 ResendBytesSent = 0;
3524 LandBytesSent = 0;
3525 WindBytesSent = 0;
3526 CloudBytesSent = 0;
3527 TaskBytesSent = 0;
3528 AssetBytesSent = 0;
3529 TextureBytesSent = 0;
3530
3531 //Yay, we've finally handled the agent Throttle packet!
3532
3533
3534
3535 break;
3536
3537 #endregion
3538
3539 #region unimplemented handlers
3540 case PacketType.RequestGodlikePowers:
3541 RequestGodlikePowersPacket rglpPack = (RequestGodlikePowersPacket) Pack;
3542 RequestGodlikePowersPacket.RequestBlockBlock rblock = rglpPack.RequestBlock;
3543 LLUUID token = rblock.Token;
3544 RequestGodlikePowersPacket.AgentDataBlock ablock = rglpPack.AgentData;
3545
3546 OnRequestGodlikePowers(ablock.AgentID, ablock.SessionID, token, this);
3547
3548 break;
3549 case PacketType.GodKickUser:
3550 OpenSim.Framework.Console.MainLog.Instance.Verbose("CLIENT", "unhandled packet " + Pack.ToString());
3551
3552 GodKickUserPacket gkupack = (GodKickUserPacket) Pack;
3553
3554 if (gkupack.UserInfo.GodSessionID == SessionId && this.AgentId == gkupack.UserInfo.GodID)
3555 {
3556 OnGodKickUser(gkupack.UserInfo.GodID, gkupack.UserInfo.GodSessionID, gkupack.UserInfo.AgentID, (uint) 0, gkupack.UserInfo.Reason);
3557 }
3558 else
3559 {
3560 SendAgentAlertMessage("Kick request denied", false);
3561 }
3562 //KickUserPacket kupack = new KickUserPacket();
3563 //KickUserPacket.UserInfoBlock kupackib = kupack.UserInfo;
3564
3565 //kupack.UserInfo.AgentID = gkupack.UserInfo.AgentID;
3566 //kupack.UserInfo.SessionID = gkupack.UserInfo.GodSessionID;
3567
3568 //kupack.TargetBlock.TargetIP = (uint)0;
3569 //kupack.TargetBlock.TargetPort = (ushort)0;
3570 //kupack.UserInfo.Reason = gkupack.UserInfo.Reason;
3571
3572
3573 //OutPacket(kupack, ThrottleOutPacketType.Task);
3574 break;
3575
3576 case PacketType.StartPingCheck:
3577 // Send the client the ping response back
3578 // Pass the same PingID in the matching packet
3579 // Handled In the packet processing
3580 OpenSim.Framework.Console.MainLog.Instance.Debug("CLIENT", "possibly unhandled packet " + Pack.ToString());
3581 break;
3582 case PacketType.CompletePingCheck:
3583 // Parhaps this should be processed on the Sim to determine whether or not to drop a dead client
3584 // Dumping it to the verbose console until it's handled properly.
3585
3586 OpenSim.Framework.Console.MainLog.Instance.Verbose("CLIENT", "unhandled packet " + Pack.ToString());
3587 break;
3588 case PacketType.AgentIsNowWearing:
3589 // AgentIsNowWearingPacket wear = (AgentIsNowWearingPacket)Pack;
3590 OpenSim.Framework.Console.MainLog.Instance.Verbose("CLIENT", "unhandled packet " + Pack.ToString());
3591 break;
3592 case PacketType.ObjectScale:
3593 OpenSim.Framework.Console.MainLog.Instance.Verbose("CLIENT", "unhandled packet " + Pack.ToString());
3594 break;
3595 default:
3596 OpenSim.Framework.Console.MainLog.Instance.Verbose("CLIENT", "unhandled packet " + Pack.ToString());
3597 break;
3598
3599 #endregion
3600 }
3601 }
3602 }
3603
3604 private static PrimitiveBaseShape GetShapeFromAddPacket(ObjectAddPacket addPacket)
3605 {
3606 PrimitiveBaseShape shape = new PrimitiveBaseShape();
3607
3608 shape.PCode = addPacket.ObjectData.PCode;
3609 shape.PathBegin = addPacket.ObjectData.PathBegin;
3610 shape.PathEnd = addPacket.ObjectData.PathEnd;
3611 shape.PathScaleX = addPacket.ObjectData.PathScaleX;
3612 shape.PathScaleY = addPacket.ObjectData.PathScaleY;
3613 shape.PathShearX = addPacket.ObjectData.PathShearX;
3614 shape.PathShearY = addPacket.ObjectData.PathShearY;
3615 shape.PathSkew = addPacket.ObjectData.PathSkew;
3616 shape.ProfileBegin = addPacket.ObjectData.ProfileBegin;
3617 shape.ProfileEnd = addPacket.ObjectData.ProfileEnd;
3618 shape.Scale = addPacket.ObjectData.Scale;
3619 shape.PathCurve = addPacket.ObjectData.PathCurve;
3620 shape.ProfileCurve = addPacket.ObjectData.ProfileCurve;
3621 shape.ProfileHollow = addPacket.ObjectData.ProfileHollow;
3622 shape.PathRadiusOffset = addPacket.ObjectData.PathRadiusOffset;
3623 shape.PathRevolutions = addPacket.ObjectData.PathRevolutions;
3624 shape.PathTaperX = addPacket.ObjectData.PathTaperX;
3625 shape.PathTaperY = addPacket.ObjectData.PathTaperY;
3626 shape.PathTwist = addPacket.ObjectData.PathTwist;
3627 shape.PathTwistBegin = addPacket.ObjectData.PathTwistBegin;
3628 LLObject.TextureEntry ntex = new LLObject.TextureEntry(new LLUUID("00000000-0000-0000-9999-000000000005"));
3629 shape.TextureEntry = ntex.ToBytes();
3630 return shape;
3631 }
3632
3633 public void SendLogoutPacket()
3634 {
3635 LogoutReplyPacket logReply = new LogoutReplyPacket();
3636 logReply.AgentData.AgentID = AgentId;
3637 logReply.AgentData.SessionID = SessionId;
3638 logReply.InventoryData = new LogoutReplyPacket.InventoryDataBlock[1];
3639 logReply.InventoryData[0] = new LogoutReplyPacket.InventoryDataBlock();
3640 logReply.InventoryData[0].ItemID = LLUUID.Zero;
3641
3642 OutPacket(logReply, ThrottleOutPacketType.Task);
3643 }
555 } 3644 }
556} \ No newline at end of file 3645} \ No newline at end of file