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