aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/ClientView.API.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack/ClientView.API.cs')
-rw-r--r--OpenSim/Region/ClientStack/ClientView.API.cs976
1 files changed, 976 insertions, 0 deletions
diff --git a/OpenSim/Region/ClientStack/ClientView.API.cs b/OpenSim/Region/ClientStack/ClientView.API.cs
new file mode 100644
index 0000000..9650b42
--- /dev/null
+++ b/OpenSim/Region/ClientStack/ClientView.API.cs
@@ -0,0 +1,976 @@
1/*
2* Copyright (c) Contributors, http://www.openmetaverse.org/
3* See CONTRIBUTORS.TXT for a full list of copyright holders.
4*
5* Redistribution and use in source and binary forms, with or without
6* modification, are permitted provided that the following conditions are met:
7* * Redistributions of source code must retain the above copyright
8* notice, this list of conditions and the following disclaimer.
9* * Redistributions in binary form must reproduce the above copyright
10* notice, this list of conditions and the following disclaimer in the
11* documentation and/or other materials provided with the distribution.
12* * Neither the name of the OpenSim Project nor the
13* names of its contributors may be used to endorse or promote products
14* derived from this software without specific prior written permission.
15*
16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY
17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*
27*/
28using System;
29using System.Collections.Generic;
30using System.Text;
31using OpenSim.Framework.Interfaces;
32using OpenSim.Framework.Inventory;
33using OpenSim.Framework.Types;
34
35using libsecondlife;
36using libsecondlife.Packets;
37
38namespace OpenSim.Region.ClientStack
39{
40 partial class ClientView
41 {
42 public event ChatFromViewer OnChatFromViewer;
43 public event RezObject OnRezObject;
44 public event GenericCall4 OnDeRezObject;
45 public event ModifyTerrain OnModifyTerrain;
46 public event GenericCall OnRegionHandShakeReply;
47 public event GenericCall OnRequestWearables;
48 public event SetAppearance OnSetAppearance;
49 public event GenericCall2 OnCompleteMovementToRegion;
50 public event UpdateAgent OnAgentUpdate;
51 public event StartAnim OnStartAnim;
52 public event GenericCall OnRequestAvatarsData;
53 public event LinkObjects OnLinkObjects;
54 public event UpdateVector OnGrapObject;
55 public event ObjectSelect OnDeGrapObject;
56 public event MoveObject OnGrapUpdate;
57 public event GenericCall4 OnAddPrim;
58 public event UpdateShape OnUpdatePrimShape;
59 public event ObjectSelect OnObjectSelect;
60 public event UpdatePrimFlags OnUpdatePrimFlags;
61 public event UpdatePrimTexture OnUpdatePrimTexture;
62 public event UpdateVector OnUpdatePrimPosition;
63 public event UpdatePrimRotation OnUpdatePrimRotation;
64 public event UpdateVector OnUpdatePrimScale;
65 public event StatusChange OnChildAgentStatus;
66 public event GenericCall2 OnStopMovement;
67 public event NewAvatar OnNewAvatar;
68 public event GenericCall6 OnRemoveAvatar;
69 public event RequestMapBlocks OnRequestMapBlocks;
70 public event TeleportLocationRequest OnTeleportLocationRequest;
71
72 public event UUIDNameRequest OnNameFromUUIDRequest;
73
74 public event ParcelPropertiesRequest OnParcelPropertiesRequest;
75 public event ParcelDivideRequest OnParcelDivideRequest;
76 public event ParcelJoinRequest OnParcelJoinRequest;
77 public event ParcelPropertiesUpdateRequest OnParcelPropertiesUpdateRequest;
78
79 public event EstateOwnerMessageRequest OnEstateOwnerMessage;
80 /// <summary>
81 ///
82 /// </summary>
83 public LLVector3 StartPos
84 {
85 get
86 {
87 return startpos;
88 }
89 set
90 {
91 startpos = value;
92 }
93 }
94
95 /// <summary>
96 ///
97 /// </summary>
98 public LLUUID AgentId
99 {
100 get
101 {
102 return this.AgentID;
103 }
104 }
105
106 /// <summary>
107 ///
108 /// </summary>
109 public string FirstName
110 {
111 get
112 {
113 return this.firstName;
114 }
115
116 }
117
118 /// <summary>
119 ///
120 /// </summary>
121 public string LastName
122 {
123 get
124 {
125 return this.lastName;
126 }
127 }
128
129 #region World/Avatar to Client
130
131 /// <summary>
132 ///
133 /// </summary>
134 /// <param name="regionInfo"></param>
135 public void SendRegionHandshake(RegionInfo regionInfo)
136 {
137 System.Text.Encoding _enc = System.Text.Encoding.ASCII;
138 RegionHandshakePacket handshake = new RegionHandshakePacket();
139
140 handshake.RegionInfo.BillableFactor = regionInfo.estateSettings.billableFactor;
141 handshake.RegionInfo.IsEstateManager = false;
142 handshake.RegionInfo.TerrainHeightRange00 = regionInfo.estateSettings.terrainHeightRange0;
143 handshake.RegionInfo.TerrainHeightRange01 = regionInfo.estateSettings.terrainHeightRange1;
144 handshake.RegionInfo.TerrainHeightRange10 = regionInfo.estateSettings.terrainHeightRange2;
145 handshake.RegionInfo.TerrainHeightRange11 = regionInfo.estateSettings.terrainHeightRange3;
146 handshake.RegionInfo.TerrainStartHeight00 = regionInfo.estateSettings.terrainStartHeight0;
147 handshake.RegionInfo.TerrainStartHeight01 = regionInfo.estateSettings.terrainStartHeight1;
148 handshake.RegionInfo.TerrainStartHeight10 = regionInfo.estateSettings.terrainStartHeight2;
149 handshake.RegionInfo.TerrainStartHeight11 = regionInfo.estateSettings.terrainStartHeight3;
150 handshake.RegionInfo.SimAccess = (byte)regionInfo.estateSettings.simAccess;
151 handshake.RegionInfo.WaterHeight = regionInfo.estateSettings.waterHeight;
152
153
154 handshake.RegionInfo.RegionFlags = (uint)regionInfo.estateSettings.regionFlags;
155
156 handshake.RegionInfo.SimName = _enc.GetBytes(regionInfo.RegionName + "\0");
157 handshake.RegionInfo.SimOwner = regionInfo.MasterAvatarAssignedUUID;
158 handshake.RegionInfo.TerrainBase0 = regionInfo.estateSettings.terrainBase0;
159 handshake.RegionInfo.TerrainBase1 = regionInfo.estateSettings.terrainBase1;
160 handshake.RegionInfo.TerrainBase2 = regionInfo.estateSettings.terrainBase2;
161 handshake.RegionInfo.TerrainBase3 = regionInfo.estateSettings.terrainBase3;
162 handshake.RegionInfo.TerrainDetail0 = regionInfo.estateSettings.terrainDetail0;
163 handshake.RegionInfo.TerrainDetail1 = regionInfo.estateSettings.terrainDetail1;
164 handshake.RegionInfo.TerrainDetail2 = regionInfo.estateSettings.terrainDetail2;
165 handshake.RegionInfo.TerrainDetail3 = regionInfo.estateSettings.terrainDetail3;
166 handshake.RegionInfo.CacheID = LLUUID.Random(); //I guess this is for the client to remember an old setting?
167
168 this.OutPacket(handshake);
169 }
170
171 /// <summary>
172 ///
173 /// </summary>
174 /// <param name="regInfo"></param>
175 public void MoveAgentIntoRegion(RegionInfo regInfo, LLVector3 pos, LLVector3 look)
176 {
177 AgentMovementCompletePacket mov = new AgentMovementCompletePacket();
178 mov.AgentData.SessionID = this.SessionID;
179 mov.AgentData.AgentID = this.AgentID;
180 mov.Data.RegionHandle = regInfo.RegionHandle;
181 mov.Data.Timestamp = 1172750370; // TODO - dynamicalise this
182
183 if ((pos.X == 0) && (pos.Y == 0) && (pos.Z == 0))
184 {
185 mov.Data.Position = this.startpos;
186 }
187 else
188 {
189 mov.Data.Position = pos;
190 }
191 mov.Data.LookAt = look;
192
193 OutPacket(mov);
194 }
195
196 /// <summary>
197 ///
198 /// </summary>
199 /// <param name="message"></param>
200 /// <param name="type"></param>
201 /// <param name="fromPos"></param>
202 /// <param name="fromName"></param>
203 /// <param name="fromAgentID"></param>
204 public void SendChatMessage(string message, byte type, LLVector3 fromPos, string fromName, LLUUID fromAgentID)
205 {
206 SendChatMessage(Helpers.StringToField(message), type, fromPos, fromName, fromAgentID);
207 }
208
209 /// <summary>
210 ///
211 /// </summary>
212 /// <param name="message"></param>
213 /// <param name="type"></param>
214 /// <param name="fromPos"></param>
215 /// <param name="fromName"></param>
216 /// <param name="fromAgentID"></param>
217 public void SendChatMessage(byte[] message, byte type, LLVector3 fromPos, string fromName, LLUUID fromAgentID)
218 {
219 System.Text.Encoding enc = System.Text.Encoding.ASCII;
220 libsecondlife.Packets.ChatFromSimulatorPacket reply = new ChatFromSimulatorPacket();
221 reply.ChatData.Audible = 1;
222 reply.ChatData.Message = message;
223 reply.ChatData.ChatType = type;
224 reply.ChatData.SourceType = 1;
225 reply.ChatData.Position = fromPos;
226 reply.ChatData.FromName = enc.GetBytes(fromName + "\0");
227 reply.ChatData.OwnerID = fromAgentID;
228 reply.ChatData.SourceID = fromAgentID;
229
230 this.OutPacket(reply);
231 }
232
233
234 /// <summary>
235 /// Send the region heightmap to the client
236 /// </summary>
237 /// <param name="map">heightmap</param>
238 public virtual void SendLayerData(float[] map)
239 {
240 try
241 {
242 int[] patches = new int[4];
243
244 for (int y = 0; y < 16; y++)
245 {
246 for (int x = 0; x < 16; x = x + 4)
247 {
248 patches[0] = x + 0 + y * 16;
249 patches[1] = x + 1 + y * 16;
250 patches[2] = x + 2 + y * 16;
251 patches[3] = x + 3 + y * 16;
252
253 Packet layerpack = TerrainManager.CreateLandPacket(map, patches);
254 OutPacket(layerpack);
255 }
256 }
257 }
258 catch (Exception e)
259 {
260 OpenSim.Framework.Console.MainLog.Instance.Warn("ClientView API.cs: SendLayerData() - Failed with exception " + e.ToString());
261 }
262 }
263
264 /// <summary>
265 /// Sends a specified patch to a client
266 /// </summary>
267 /// <param name="px">Patch coordinate (x) 0..16</param>
268 /// <param name="py">Patch coordinate (y) 0..16</param>
269 /// <param name="map">heightmap</param>
270 public void SendLayerData(int px, int py, float[] map)
271 {
272 try
273 {
274 int[] patches = new int[1];
275 int patchx, patchy;
276 patchx = px / 16;
277 patchy = py / 16;
278
279 patches[0] = patchx + 0 + patchy * 16;
280
281 Packet layerpack = TerrainManager.CreateLandPacket(map, patches);
282 OutPacket(layerpack);
283 }
284 catch (Exception e)
285 {
286 OpenSim.Framework.Console.MainLog.Instance.Warn("ClientView API .cs: SendLayerData() - Failed with exception " + e.ToString());
287 }
288 }
289
290 /// <summary>
291 ///
292 /// </summary>
293 /// <param name="neighbourHandle"></param>
294 /// <param name="neighbourIP"></param>
295 /// <param name="neighbourPort"></param>
296 public void InformClientOfNeighbour(ulong neighbourHandle, System.Net.IPAddress neighbourIP, ushort neighbourPort)
297 {
298 EnableSimulatorPacket enablesimpacket = new EnableSimulatorPacket();
299 enablesimpacket.SimulatorInfo = new EnableSimulatorPacket.SimulatorInfoBlock();
300 enablesimpacket.SimulatorInfo.Handle = neighbourHandle;
301
302 byte[] byteIP = neighbourIP.GetAddressBytes();
303 enablesimpacket.SimulatorInfo.IP = (uint)byteIP[3] << 24;
304 enablesimpacket.SimulatorInfo.IP += (uint)byteIP[2] << 16;
305 enablesimpacket.SimulatorInfo.IP += (uint)byteIP[1] << 8;
306 enablesimpacket.SimulatorInfo.IP += (uint)byteIP[0];
307 enablesimpacket.SimulatorInfo.Port = neighbourPort;
308 OutPacket(enablesimpacket);
309 }
310
311 /// <summary>
312 ///
313 /// </summary>
314 /// <returns></returns>
315 public AgentCircuitData RequestClientInfo()
316 {
317 AgentCircuitData agentData = new AgentCircuitData();
318 agentData.AgentID = this.AgentId;
319 agentData.SessionID = this.SessionID;
320 agentData.SecureSessionID = this.SecureSessionID;
321 agentData.circuitcode = this.CircuitCode;
322 agentData.child = false;
323 agentData.firstname = this.firstName;
324 agentData.lastname = this.lastName;
325
326 return agentData;
327 }
328
329 public void CrossRegion(ulong newRegionHandle, LLVector3 pos, LLVector3 lookAt, System.Net.IPAddress newRegionIP, ushort newRegionPort)
330 {
331 LLVector3 look = new LLVector3(lookAt.X * 10, lookAt.Y * 10, lookAt.Z * 10);
332
333 CrossedRegionPacket newSimPack = new CrossedRegionPacket();
334 newSimPack.AgentData = new CrossedRegionPacket.AgentDataBlock();
335 newSimPack.AgentData.AgentID = this.AgentID;
336 newSimPack.AgentData.SessionID = this.SessionID;
337 newSimPack.Info = new CrossedRegionPacket.InfoBlock();
338 newSimPack.Info.Position = pos;
339 newSimPack.Info.LookAt = look; // new LLVector3(0.0f, 0.0f, 0.0f); // copied from Avatar.cs - SHOULD BE DYNAMIC!!!!!!!!!!
340 newSimPack.RegionData = new libsecondlife.Packets.CrossedRegionPacket.RegionDataBlock();
341 newSimPack.RegionData.RegionHandle = newRegionHandle;
342 byte[] byteIP = newRegionIP.GetAddressBytes();
343 newSimPack.RegionData.SimIP = (uint)byteIP[3] << 24;
344 newSimPack.RegionData.SimIP += (uint)byteIP[2] << 16;
345 newSimPack.RegionData.SimIP += (uint)byteIP[1] << 8;
346 newSimPack.RegionData.SimIP += (uint)byteIP[0];
347 newSimPack.RegionData.SimPort = newRegionPort;
348 newSimPack.RegionData.SeedCapability = new byte[0];
349
350 this.OutPacket(newSimPack);
351 //this.DowngradeClient();
352 }
353
354 public void SendMapBlock(List<MapBlockData> mapBlocks)
355 {
356 System.Text.Encoding _enc = System.Text.Encoding.ASCII;
357
358 MapBlockReplyPacket mapReply = new MapBlockReplyPacket();
359 mapReply.AgentData.AgentID = this.AgentID;
360 mapReply.Data = new MapBlockReplyPacket.DataBlock[mapBlocks.Count];
361 mapReply.AgentData.Flags = 0;
362
363 for (int i = 0; i < mapBlocks.Count; i++)
364 {
365 mapReply.Data[i] = new MapBlockReplyPacket.DataBlock();
366 mapReply.Data[i].MapImageID = mapBlocks[i].MapImageId;
367 mapReply.Data[i].X = mapBlocks[i].X;
368 mapReply.Data[i].Y = mapBlocks[i].Y;
369 mapReply.Data[i].WaterHeight = mapBlocks[i].WaterHeight;
370 mapReply.Data[i].Name = _enc.GetBytes(mapBlocks[i].Name);
371 mapReply.Data[i].RegionFlags = mapBlocks[i].RegionFlags;
372 mapReply.Data[i].Access = mapBlocks[i].Access;
373 mapReply.Data[i].Agents = mapBlocks[i].Agents;
374 }
375 this.OutPacket(mapReply);
376 }
377
378 public void SendLocalTeleport(LLVector3 position, LLVector3 lookAt, uint flags)
379 {
380 TeleportLocalPacket tpLocal = new TeleportLocalPacket();
381 tpLocal.Info.AgentID = this.AgentID;
382 tpLocal.Info.TeleportFlags = flags;
383 tpLocal.Info.LocationID = 2;
384 tpLocal.Info.LookAt = lookAt;
385 tpLocal.Info.Position = position;
386 OutPacket(tpLocal);
387 }
388
389 public void SendRegionTeleport(ulong regionHandle, byte simAccess, string ipAddress, ushort ipPort, uint locationID, uint flags)
390 {
391 TeleportFinishPacket teleport = new TeleportFinishPacket();
392 teleport.Info.AgentID = this.AgentID;
393 teleport.Info.RegionHandle = regionHandle;
394 teleport.Info.SimAccess = simAccess;
395 teleport.Info.SeedCapability = new byte[0];
396
397 System.Net.IPAddress oIP = System.Net.IPAddress.Parse(ipAddress);
398 byte[] byteIP = oIP.GetAddressBytes();
399 uint ip = (uint)byteIP[3] << 24;
400 ip += (uint)byteIP[2] << 16;
401 ip += (uint)byteIP[1] << 8;
402 ip += (uint)byteIP[0];
403
404 teleport.Info.SimIP = ip;
405 teleport.Info.SimPort = ipPort;
406 teleport.Info.LocationID = 4;
407 teleport.Info.TeleportFlags = 1 << 4;
408 OutPacket(teleport);
409 }
410
411 /// <summary>
412 ///
413 /// </summary>
414 public void SendTeleportCancel()
415 {
416 TeleportCancelPacket tpCancel = new TeleportCancelPacket();
417 tpCancel.Info.SessionID = this.SessionID;
418 tpCancel.Info.AgentID = this.AgentID;
419
420 OutPacket(tpCancel);
421 }
422
423 /// <summary>
424 ///
425 /// </summary>
426 public void SendTeleportLocationStart()
427 {
428 TeleportStartPacket tpStart = new TeleportStartPacket();
429 tpStart.Info.TeleportFlags = 16; // Teleport via location
430 OutPacket(tpStart);
431 }
432
433 public void SendMoneyBalance(LLUUID transaction, bool success, byte[] description, int balance)
434 {
435 MoneyBalanceReplyPacket money = new MoneyBalanceReplyPacket();
436 money.MoneyData.AgentID = this.AgentID;
437 money.MoneyData.TransactionID = transaction;
438 money.MoneyData.TransactionSuccess = success;
439 money.MoneyData.Description = description;
440 money.MoneyData.MoneyBalance = balance;
441 OutPacket(money);
442 }
443
444 #region Appearance/ Wearables Methods
445
446 /// <summary>
447 ///
448 /// </summary>
449 /// <param name="wearables"></param>
450 public void SendWearables(AvatarWearable[] wearables)
451 {
452 AgentWearablesUpdatePacket aw = new AgentWearablesUpdatePacket();
453 aw.AgentData.AgentID = this.AgentID;
454 aw.AgentData.SerialNum = 0;
455 aw.AgentData.SessionID = this.SessionID;
456
457 aw.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[13];
458 AgentWearablesUpdatePacket.WearableDataBlock awb;
459 for (int i = 0; i < wearables.Length; i++)
460 {
461 awb = new AgentWearablesUpdatePacket.WearableDataBlock();
462 awb.WearableType = (byte)i;
463 awb.AssetID = wearables[i].AssetID;
464 awb.ItemID = wearables[i].ItemID;
465 aw.WearableData[i] = awb;
466 }
467
468 this.OutPacket(aw);
469 }
470
471 /// <summary>
472 ///
473 /// </summary>
474 /// <param name="agentID"></param>
475 /// <param name="visualParams"></param>
476 /// <param name="textureEntry"></param>
477 public void SendAppearance(LLUUID agentID, byte[] visualParams, byte[] textureEntry)
478 {
479 AvatarAppearancePacket avp = new AvatarAppearancePacket();
480 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[218];
481 avp.ObjectData.TextureEntry = textureEntry;
482
483 AvatarAppearancePacket.VisualParamBlock avblock = null;
484 for (int i = 0; i < visualParams.Length; i++)
485 {
486 avblock = new AvatarAppearancePacket.VisualParamBlock();
487 avblock.ParamValue = visualParams[i];
488 avp.VisualParam[i] = avblock;
489 }
490
491 avp.Sender.IsTrial = false;
492 avp.Sender.ID = agentID;
493 OutPacket(avp);
494 }
495
496 #endregion
497
498 #region Avatar Packet/data sending Methods
499
500 /// <summary>
501 ///
502 /// </summary>
503 /// <param name="regionInfo"></param>
504 /// <param name="firstName"></param>
505 /// <param name="lastName"></param>
506 /// <param name="avatarID"></param>
507 /// <param name="avatarLocalID"></param>
508 /// <param name="Pos"></param>
509 public void SendAvatarData(ulong regionHandle, string firstName, string lastName, LLUUID avatarID, uint avatarLocalID, LLVector3 Pos, byte[] textureEntry)
510 {
511 System.Text.Encoding _enc = System.Text.Encoding.ASCII;
512 //send a objectupdate packet with information about the clients avatar
513
514 ObjectUpdatePacket objupdate = new ObjectUpdatePacket();
515 objupdate.RegionData.RegionHandle = regionHandle;
516 objupdate.RegionData.TimeDilation = 64096;
517 objupdate.ObjectData = new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock[1];
518 objupdate.ObjectData[0] = this.CreateDefaultAvatarPacket(textureEntry);
519 //give this avatar object a local id and assign the user a name
520
521 objupdate.ObjectData[0].ID = avatarLocalID;
522 objupdate.ObjectData[0].FullID = avatarID;
523 objupdate.ObjectData[0].NameValue = _enc.GetBytes("FirstName STRING RW SV " + firstName + "\nLastName STRING RW SV " + lastName + " \0");
524 libsecondlife.LLVector3 pos2 = new LLVector3((float)Pos.X, (float)Pos.Y, (float)Pos.Z);
525 byte[] pb = pos2.GetBytes();
526 Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 16, pb.Length);
527
528 OutPacket(objupdate);
529
530 }
531
532 /// <summary>
533 ///
534 /// </summary>
535 /// <param name="regionHandle"></param>
536 /// <param name="timeDilation"></param>
537 /// <param name="localID"></param>
538 /// <param name="position"></param>
539 /// <param name="velocity"></param>
540 public void SendAvatarTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, LLVector3 position, LLVector3 velocity)
541 {
542 ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock = this.CreateAvatarImprovedBlock(localID, position, velocity);
543 ImprovedTerseObjectUpdatePacket terse = new ImprovedTerseObjectUpdatePacket();
544 terse.RegionData.RegionHandle = regionHandle;
545 terse.RegionData.TimeDilation = timeDilation;
546 terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1];
547 terse.ObjectData[0] = terseBlock;
548
549 this.OutPacket(terse);
550 }
551
552 #endregion
553
554 #region Primitive Packet/data Sending Methods
555
556 /// <summary>
557 ///
558 /// </summary>
559 /// <param name="localID"></param>
560 /// <param name="rotation"></param>
561 /// <param name="attachPoint"></param>
562 public void AttachObject(uint localID, LLQuaternion rotation, byte attachPoint)
563 {
564 ObjectAttachPacket attach = new ObjectAttachPacket();
565 attach.AgentData.AgentID = this.AgentID;
566 attach.AgentData.SessionID = this.SessionID;
567 attach.AgentData.AttachmentPoint = attachPoint;
568 attach.ObjectData = new ObjectAttachPacket.ObjectDataBlock[1];
569 attach.ObjectData[0] = new ObjectAttachPacket.ObjectDataBlock();
570 attach.ObjectData[0].ObjectLocalID = localID;
571 attach.ObjectData[0].Rotation = rotation;
572
573 this.OutPacket(attach);
574 }
575
576 /// <summary>
577 /// Sends a full ObjectUpdatePacket to a client to inform it of a new primitive
578 /// or big changes to a existing primitive.
579 /// </summary>
580 /// <param name="regionHandle"></param>
581 /// <param name="timeDilation"></param>
582 /// <param name="localID"></param>
583 /// <param name="primData"></param>
584 /// <param name="pos"></param>
585 /// <param name="rotation"></param>
586 /// <param name="textureID"></param>
587 public void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimData primData, LLVector3 pos, LLQuaternion rotation, LLUUID textureID, uint flags)
588 {
589 ObjectUpdatePacket outPacket = new ObjectUpdatePacket();
590 outPacket.RegionData.RegionHandle = regionHandle;
591 outPacket.RegionData.TimeDilation = timeDilation;
592 outPacket.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
593 outPacket.ObjectData[0] = this.CreatePrimUpdateBlock(primData, textureID, flags);
594 outPacket.ObjectData[0].ID = localID;
595 outPacket.ObjectData[0].FullID = primData.FullID;
596 byte[] pb = pos.GetBytes();
597 Array.Copy(pb, 0, outPacket.ObjectData[0].ObjectData, 0, pb.Length);
598 byte[] rot = rotation.GetBytes();
599 Array.Copy(rot, 0, outPacket.ObjectData[0].ObjectData, 48, rot.Length);
600 OutPacket(outPacket);
601 }
602
603 /// <summary>
604 /// Sends a full ObjectUpdatePacket to a client to inform it of a new primitive
605 /// or big changes to a existing primitive.
606 /// Uses default rotation
607 /// </summary>
608 /// <param name="primData"></param>
609 /// <param name="pos"></param>
610 public void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimData primData, LLVector3 pos, LLUUID textureID , uint flags)
611 {
612 ObjectUpdatePacket outPacket = new ObjectUpdatePacket();
613 outPacket.RegionData.RegionHandle = regionHandle;
614 outPacket.RegionData.TimeDilation = timeDilation;
615 outPacket.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
616 outPacket.ObjectData[0] = this.CreatePrimUpdateBlock(primData, textureID, flags);
617 outPacket.ObjectData[0].ID = localID;
618 outPacket.ObjectData[0].FullID = primData.FullID;
619 byte[] pb = pos.GetBytes();
620 Array.Copy(pb, 0, outPacket.ObjectData[0].ObjectData, 0, pb.Length);
621
622 OutPacket(outPacket);
623 }
624
625 /// <summary>
626 ///
627 /// </summary>
628 /// <param name="regionHandle"></param>
629 /// <param name="timeDilation"></param>
630 /// <param name="localID"></param>
631 /// <param name="position"></param>
632 /// <param name="rotation"></param>
633 public void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, LLVector3 position, LLQuaternion rotation)
634 {
635 ImprovedTerseObjectUpdatePacket terse = new ImprovedTerseObjectUpdatePacket();
636 terse.RegionData.RegionHandle = regionHandle;
637 terse.RegionData.TimeDilation = timeDilation;
638 terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1];
639 terse.ObjectData[0] = this.CreatePrimImprovedBlock(localID, position, rotation);
640
641 this.OutPacket(terse);
642 }
643
644 #endregion
645
646 #endregion
647
648 #region Helper Methods
649
650 protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateAvatarImprovedBlock(uint localID, LLVector3 pos, LLVector3 velocity)
651 {
652 byte[] bytes = new byte[60];
653 int i = 0;
654 ImprovedTerseObjectUpdatePacket.ObjectDataBlock dat = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock();
655
656 dat.TextureEntry = new byte[0];// AvatarTemplate.TextureEntry;
657
658 uint ID = localID;
659
660 bytes[i++] = (byte)(ID % 256);
661 bytes[i++] = (byte)((ID >> 8) % 256);
662 bytes[i++] = (byte)((ID >> 16) % 256);
663 bytes[i++] = (byte)((ID >> 24) % 256);
664 bytes[i++] = 0;
665 bytes[i++] = 1;
666 i += 14;
667 bytes[i++] = 128;
668 bytes[i++] = 63;
669
670 byte[] pb = pos.GetBytes();
671 Array.Copy(pb, 0, bytes, i, pb.Length);
672 i += 12;
673 ushort InternVelocityX;
674 ushort InternVelocityY;
675 ushort InternVelocityZ;
676 Axiom.MathLib.Vector3 internDirec = new Axiom.MathLib.Vector3(0, 0, 0);
677
678 internDirec = new Axiom.MathLib.Vector3(velocity.X, velocity.Y, velocity.Z);
679
680 internDirec = internDirec / 128.0f;
681 internDirec.x += 1;
682 internDirec.y += 1;
683 internDirec.z += 1;
684
685 InternVelocityX = (ushort)(32768 * internDirec.x);
686 InternVelocityY = (ushort)(32768 * internDirec.y);
687 InternVelocityZ = (ushort)(32768 * internDirec.z);
688
689 ushort ac = 32767;
690 bytes[i++] = (byte)(InternVelocityX % 256);
691 bytes[i++] = (byte)((InternVelocityX >> 8) % 256);
692 bytes[i++] = (byte)(InternVelocityY % 256);
693 bytes[i++] = (byte)((InternVelocityY >> 8) % 256);
694 bytes[i++] = (byte)(InternVelocityZ % 256);
695 bytes[i++] = (byte)((InternVelocityZ >> 8) % 256);
696
697 //accel
698 bytes[i++] = (byte)(ac % 256);
699 bytes[i++] = (byte)((ac >> 8) % 256);
700 bytes[i++] = (byte)(ac % 256);
701 bytes[i++] = (byte)((ac >> 8) % 256);
702 bytes[i++] = (byte)(ac % 256);
703 bytes[i++] = (byte)((ac >> 8) % 256);
704
705 //rot
706 bytes[i++] = (byte)(ac % 256);
707 bytes[i++] = (byte)((ac >> 8) % 256);
708 bytes[i++] = (byte)(ac % 256);
709 bytes[i++] = (byte)((ac >> 8) % 256);
710 bytes[i++] = (byte)(ac % 256);
711 bytes[i++] = (byte)((ac >> 8) % 256);
712 bytes[i++] = (byte)(ac % 256);
713 bytes[i++] = (byte)((ac >> 8) % 256);
714
715 //rotation vel
716 bytes[i++] = (byte)(ac % 256);
717 bytes[i++] = (byte)((ac >> 8) % 256);
718 bytes[i++] = (byte)(ac % 256);
719 bytes[i++] = (byte)((ac >> 8) % 256);
720 bytes[i++] = (byte)(ac % 256);
721 bytes[i++] = (byte)((ac >> 8) % 256);
722
723 dat.Data = bytes;
724 return (dat);
725 }
726
727 /// <summary>
728 ///
729 /// </summary>
730 /// <param name="localID"></param>
731 /// <param name="position"></param>
732 /// <param name="rotation"></param>
733 /// <returns></returns>
734 protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreatePrimImprovedBlock(uint localID, LLVector3 position, LLQuaternion rotation)
735 {
736 uint ID = localID;
737 byte[] bytes = new byte[60];
738
739 int i = 0;
740 ImprovedTerseObjectUpdatePacket.ObjectDataBlock dat = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock();
741 dat.TextureEntry = new byte[0];
742 bytes[i++] = (byte)(ID % 256);
743 bytes[i++] = (byte)((ID >> 8) % 256);
744 bytes[i++] = (byte)((ID >> 16) % 256);
745 bytes[i++] = (byte)((ID >> 24) % 256);
746 bytes[i++] = 0;
747 bytes[i++] = 0;
748
749 byte[] pb = position.GetBytes();
750 Array.Copy(pb, 0, bytes, i, pb.Length);
751 i += 12;
752 ushort ac = 32767;
753
754 //vel
755 bytes[i++] = (byte)(ac % 256);
756 bytes[i++] = (byte)((ac >> 8) % 256);
757 bytes[i++] = (byte)(ac % 256);
758 bytes[i++] = (byte)((ac >> 8) % 256);
759 bytes[i++] = (byte)(ac % 256);
760 bytes[i++] = (byte)((ac >> 8) % 256);
761
762 //accel
763 bytes[i++] = (byte)(ac % 256);
764 bytes[i++] = (byte)((ac >> 8) % 256);
765 bytes[i++] = (byte)(ac % 256);
766 bytes[i++] = (byte)((ac >> 8) % 256);
767 bytes[i++] = (byte)(ac % 256);
768 bytes[i++] = (byte)((ac >> 8) % 256);
769
770 ushort rw, rx, ry, rz;
771 rw = (ushort)(32768 * (rotation.W + 1));
772 rx = (ushort)(32768 * (rotation.X + 1));
773 ry = (ushort)(32768 * (rotation.Y + 1));
774 rz = (ushort)(32768 * (rotation.Z + 1));
775
776 //rot
777 bytes[i++] = (byte)(rx % 256);
778 bytes[i++] = (byte)((rx >> 8) % 256);
779 bytes[i++] = (byte)(ry % 256);
780 bytes[i++] = (byte)((ry >> 8) % 256);
781 bytes[i++] = (byte)(rz % 256);
782 bytes[i++] = (byte)((rz >> 8) % 256);
783 bytes[i++] = (byte)(rw % 256);
784 bytes[i++] = (byte)((rw >> 8) % 256);
785
786 //rotation vel
787 bytes[i++] = (byte)(ac % 256);
788 bytes[i++] = (byte)((ac >> 8) % 256);
789 bytes[i++] = (byte)(ac % 256);
790 bytes[i++] = (byte)((ac >> 8) % 256);
791 bytes[i++] = (byte)(ac % 256);
792 bytes[i++] = (byte)((ac >> 8) % 256);
793
794 dat.Data = bytes;
795 return dat;
796 }
797
798
799 /// <summary>
800 /// Create the ObjectDataBlock for a ObjectUpdatePacket (for a Primitive)
801 /// </summary>
802 /// <param name="primData"></param>
803 /// <returns></returns>
804 protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(PrimData primData, LLUUID textureID, uint flags)
805 {
806 ObjectUpdatePacket.ObjectDataBlock objupdate = new ObjectUpdatePacket.ObjectDataBlock();
807 this.SetDefaultPrimPacketValues(objupdate);
808 objupdate.UpdateFlags = flags;
809 this.SetPrimPacketShapeData(objupdate, primData, textureID);
810
811 return objupdate;
812 }
813
814 /// <summary>
815 /// Copy the data from a PrimData object to a ObjectUpdatePacket
816 /// </summary>
817 /// <param name="objectData"></param>
818 /// <param name="primData"></param>
819 protected void SetPrimPacketShapeData(ObjectUpdatePacket.ObjectDataBlock objectData, PrimData primData, LLUUID textureID)
820 {
821 LLObject.TextureEntry ntex = new LLObject.TextureEntry(textureID);
822 objectData.TextureEntry = ntex.ToBytes();
823 objectData.OwnerID = primData.OwnerID;
824 objectData.PCode = primData.PCode;
825 objectData.PathBegin = primData.PathBegin;
826 objectData.PathEnd = primData.PathEnd;
827 objectData.PathScaleX = primData.PathScaleX;
828 objectData.PathScaleY = primData.PathScaleY;
829 objectData.PathShearX = primData.PathShearX;
830 objectData.PathShearY = primData.PathShearY;
831 objectData.PathSkew = primData.PathSkew;
832 objectData.ProfileBegin = primData.ProfileBegin;
833 objectData.ProfileEnd = primData.ProfileEnd;
834 objectData.Scale = primData.Scale;
835 objectData.PathCurve = primData.PathCurve;
836 objectData.ProfileCurve = primData.ProfileCurve;
837 objectData.ParentID = primData.ParentID;
838 objectData.ProfileHollow = primData.ProfileHollow;
839 objectData.PathRadiusOffset = primData.PathRadiusOffset;
840 objectData.PathRevolutions = primData.PathRevolutions;
841 objectData.PathTaperX = primData.PathTaperX;
842 objectData.PathTaperY = primData.PathTaperY;
843 objectData.PathTwist = primData.PathTwist;
844 objectData.PathTwistBegin = primData.PathTwistBegin;
845 }
846
847 /// <summary>
848 /// Set some default values in a ObjectUpdatePacket
849 /// </summary>
850 /// <param name="objdata"></param>
851 protected void SetDefaultPrimPacketValues(ObjectUpdatePacket.ObjectDataBlock objdata)
852 {
853 objdata.PSBlock = new byte[0];
854 objdata.ExtraParams = new byte[1];
855 objdata.MediaURL = new byte[0];
856 objdata.NameValue = new byte[0];
857 objdata.Text = new byte[0];
858 objdata.TextColor = new byte[4];
859 objdata.JointAxisOrAnchor = new LLVector3(0, 0, 0);
860 objdata.JointPivot = new LLVector3(0, 0, 0);
861 objdata.Material = 3;
862 objdata.TextureAnim = new byte[0];
863 objdata.Sound = LLUUID.Zero;
864 objdata.State = 0;
865 objdata.Data = new byte[0];
866
867 objdata.ObjectData = new byte[60];
868 objdata.ObjectData[46] = 128;
869 objdata.ObjectData[47] = 63;
870 }
871
872
873 /// <summary>
874 ///
875 /// </summary>
876 /// <returns></returns>
877 protected ObjectUpdatePacket.ObjectDataBlock CreateDefaultAvatarPacket(byte[] textureEntry)
878 {
879 libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock objdata = new ObjectUpdatePacket.ObjectDataBlock(); // new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock(data1, ref i);
880
881 SetDefaultAvatarPacketValues(ref objdata);
882 objdata.UpdateFlags = 61 + (9 << 8) + (130 << 16) + (16 << 24);
883 objdata.PathCurve = 16;
884 objdata.ProfileCurve = 1;
885 objdata.PathScaleX = 100;
886 objdata.PathScaleY = 100;
887 objdata.ParentID = 0;
888 objdata.OwnerID = LLUUID.Zero;
889 objdata.Scale = new LLVector3(1, 1, 1);
890 objdata.PCode = 47;
891 if (textureEntry != null)
892 {
893 objdata.TextureEntry = textureEntry;
894 }
895 System.Text.Encoding enc = System.Text.Encoding.ASCII;
896 libsecondlife.LLVector3 pos = new LLVector3(objdata.ObjectData, 16);
897 pos.X = 100f;
898 objdata.ID = 8880000;
899 objdata.NameValue = enc.GetBytes("FirstName STRING RW SV Test \nLastName STRING RW SV User \0");
900 libsecondlife.LLVector3 pos2 = new LLVector3(100f, 100f, 23f);
901 //objdata.FullID=user.AgentID;
902 byte[] pb = pos.GetBytes();
903 Array.Copy(pb, 0, objdata.ObjectData, 16, pb.Length);
904
905 return objdata;
906 }
907
908 /// <summary>
909 ///
910 /// </summary>
911 /// <param name="objdata"></param>
912 protected void SetDefaultAvatarPacketValues(ref ObjectUpdatePacket.ObjectDataBlock objdata)
913 {
914 objdata.PSBlock = new byte[0];
915 objdata.ExtraParams = new byte[1];
916 objdata.MediaURL = new byte[0];
917 objdata.NameValue = new byte[0];
918 objdata.Text = new byte[0];
919 objdata.TextColor = new byte[4];
920 objdata.JointAxisOrAnchor = new LLVector3(0, 0, 0);
921 objdata.JointPivot = new LLVector3(0, 0, 0);
922 objdata.Material = 4;
923 objdata.TextureAnim = new byte[0];
924 objdata.Sound = LLUUID.Zero;
925 LLObject.TextureEntry ntex = new LLObject.TextureEntry(new LLUUID("00000000-0000-0000-5005-000000000005"));
926 objdata.TextureEntry = ntex.ToBytes();
927 objdata.State = 0;
928 objdata.Data = new byte[0];
929
930 objdata.ObjectData = new byte[76];
931 objdata.ObjectData[15] = 128;
932 objdata.ObjectData[16] = 63;
933 objdata.ObjectData[56] = 128;
934 objdata.ObjectData[61] = 102;
935 objdata.ObjectData[62] = 40;
936 objdata.ObjectData[63] = 61;
937 objdata.ObjectData[64] = 189;
938 }
939
940 /// <summary>
941 ///
942 /// </summary>
943 /// <param name="addPacket"></param>
944 /// <returns></returns>
945 protected PrimData CreatePrimFromObjectAdd(ObjectAddPacket addPacket)
946 {
947 PrimData PData = new PrimData();
948 PData.CreationDate = (Int32)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;
949 PData.PCode = addPacket.ObjectData.PCode;
950 PData.PathBegin = addPacket.ObjectData.PathBegin;
951 PData.PathEnd = addPacket.ObjectData.PathEnd;
952 PData.PathScaleX = addPacket.ObjectData.PathScaleX;
953 PData.PathScaleY = addPacket.ObjectData.PathScaleY;
954 PData.PathShearX = addPacket.ObjectData.PathShearX;
955 PData.PathShearY = addPacket.ObjectData.PathShearY;
956 PData.PathSkew = addPacket.ObjectData.PathSkew;
957 PData.ProfileBegin = addPacket.ObjectData.ProfileBegin;
958 PData.ProfileEnd = addPacket.ObjectData.ProfileEnd;
959 PData.Scale = addPacket.ObjectData.Scale;
960 PData.PathCurve = addPacket.ObjectData.PathCurve;
961 PData.ProfileCurve = addPacket.ObjectData.ProfileCurve;
962 PData.ParentID = 0;
963 PData.ProfileHollow = addPacket.ObjectData.ProfileHollow;
964 PData.PathRadiusOffset = addPacket.ObjectData.PathRadiusOffset;
965 PData.PathRevolutions = addPacket.ObjectData.PathRevolutions;
966 PData.PathTaperX = addPacket.ObjectData.PathTaperX;
967 PData.PathTaperY = addPacket.ObjectData.PathTaperY;
968 PData.PathTwist = addPacket.ObjectData.PathTwist;
969 PData.PathTwistBegin = addPacket.ObjectData.PathTwistBegin;
970
971 return PData;
972 }
973 #endregion
974
975 }
976}