aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/OpenSim.RegionServer/ClientView/ClientView.API.cs
diff options
context:
space:
mode:
authorMW2007-06-12 14:55:36 +0000
committerMW2007-06-12 14:55:36 +0000
commit3f7bd7d42c8b88882346c008255fe8503bf4c693 (patch)
treefeac3f0a6ec50d19721c2c3e0a0aac21e0c88eb6 /OpenSim/OpenSim.RegionServer/ClientView/ClientView.API.cs
parentSome rearranging of folders in OpenSim.Region (diff)
downloadopensim-SC-3f7bd7d42c8b88882346c008255fe8503bf4c693.zip
opensim-SC-3f7bd7d42c8b88882346c008255fe8503bf4c693.tar.gz
opensim-SC-3f7bd7d42c8b88882346c008255fe8503bf4c693.tar.bz2
opensim-SC-3f7bd7d42c8b88882346c008255fe8503bf4c693.tar.xz
More rearranging.
Diffstat (limited to '')
-rw-r--r--OpenSim/OpenSim.RegionServer/ClientView/ClientView.API.cs682
1 files changed, 682 insertions, 0 deletions
diff --git a/OpenSim/OpenSim.RegionServer/ClientView/ClientView.API.cs b/OpenSim/OpenSim.RegionServer/ClientView/ClientView.API.cs
new file mode 100644
index 0000000..b9773c6
--- /dev/null
+++ b/OpenSim/OpenSim.RegionServer/ClientView/ClientView.API.cs
@@ -0,0 +1,682 @@
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 GenericCall3 OnAgentUpdate;
51 public event StartAnim OnStartAnim;
52 public event GenericCall OnRequestAvatarsData;
53 public event LinkObjects OnLinkObjects;
54 public event GenericCall4 OnAddPrim;
55 public event UpdateShape OnUpdatePrimShape;
56 public event ObjectSelect OnObjectSelect;
57 public event UpdatePrimFlags OnUpdatePrimFlags;
58 public event UpdatePrimTexture OnUpdatePrimTexture;
59 public event UpdatePrimVector OnUpdatePrimPosition;
60 public event UpdatePrimRotation OnUpdatePrimRotation;
61 public event UpdatePrimVector OnUpdatePrimScale;
62 public event StatusChange OnChildAgentStatus;
63 public event GenericCall2 OnStopMovement;
64 public event NewAvatar OnNewAvatar;
65 public event GenericCall6 OnRemoveAvatar;
66
67 public event ParcelPropertiesRequest OnParcelPropertiesRequest;
68 public event ParcelDivideRequest OnParcelDivideRequest;
69 public event ParcelJoinRequest OnParcelJoinRequest;
70 public event ParcelPropertiesUpdateRequest OnParcelPropertiesUpdateRequest;
71
72 public event EstateOwnerMessageRequest OnEstateOwnerMessage;
73
74 /// <summary>
75 ///
76 /// </summary>
77 public LLVector3 StartPos
78 {
79 get
80 {
81 return startpos;
82 }
83 set
84 {
85 startpos = value;
86 }
87 }
88
89 /// <summary>
90 ///
91 /// </summary>
92 public LLUUID AgentId
93 {
94 get
95 {
96 return this.AgentID;
97 }
98 }
99
100 /// <summary>
101 ///
102 /// </summary>
103 public string FirstName
104 {
105 get
106 {
107 return this.firstName;
108 }
109
110 }
111
112 /// <summary>
113 ///
114 /// </summary>
115 public string LastName
116 {
117 get
118 {
119 return this.lastName;
120 }
121 }
122
123 #region World/Avatar to Client
124
125 /// <summary>
126 ///
127 /// </summary>
128 /// <param name="regionInfo"></param>
129 public void SendRegionHandshake(RegionInfo regionInfo)
130 {
131 System.Text.Encoding _enc = System.Text.Encoding.ASCII;
132 RegionHandshakePacket handshake = new RegionHandshakePacket();
133
134 handshake.RegionInfo.BillableFactor = regionInfo.estateSettings.billableFactor;
135 handshake.RegionInfo.IsEstateManager = false;
136 handshake.RegionInfo.TerrainHeightRange00 = regionInfo.estateSettings.terrainHeightRange0;
137 handshake.RegionInfo.TerrainHeightRange01 = regionInfo.estateSettings.terrainHeightRange1;
138 handshake.RegionInfo.TerrainHeightRange10 = regionInfo.estateSettings.terrainHeightRange2;
139 handshake.RegionInfo.TerrainHeightRange11 = regionInfo.estateSettings.terrainHeightRange3;
140 handshake.RegionInfo.TerrainStartHeight00 = regionInfo.estateSettings.terrainStartHeight0;
141 handshake.RegionInfo.TerrainStartHeight01 = regionInfo.estateSettings.terrainStartHeight1;
142 handshake.RegionInfo.TerrainStartHeight10 = regionInfo.estateSettings.terrainStartHeight2;
143 handshake.RegionInfo.TerrainStartHeight11 = regionInfo.estateSettings.terrainStartHeight3;
144 handshake.RegionInfo.SimAccess = (byte)regionInfo.estateSettings.simAccess;
145 handshake.RegionInfo.WaterHeight = regionInfo.estateSettings.waterHeight;
146
147
148 handshake.RegionInfo.RegionFlags = (uint)regionInfo.estateSettings.regionFlags;
149
150 handshake.RegionInfo.SimName = _enc.GetBytes(regionInfo.estateSettings.waterHeight + "\0");
151 handshake.RegionInfo.SimOwner = regionInfo.MasterAvatarAssignedUUID;
152 handshake.RegionInfo.TerrainBase0 = regionInfo.estateSettings.terrainBase0;
153 handshake.RegionInfo.TerrainBase1 = regionInfo.estateSettings.terrainBase1;
154 handshake.RegionInfo.TerrainBase2 = regionInfo.estateSettings.terrainBase2;
155 handshake.RegionInfo.TerrainBase3 = regionInfo.estateSettings.terrainBase3;
156 handshake.RegionInfo.TerrainDetail0 = regionInfo.estateSettings.terrainDetail0;
157 handshake.RegionInfo.TerrainDetail1 = regionInfo.estateSettings.terrainDetail1;
158 handshake.RegionInfo.TerrainDetail2 =regionInfo.estateSettings.terrainDetail2;
159 handshake.RegionInfo.TerrainDetail3 = regionInfo.estateSettings.terrainDetail3;
160 handshake.RegionInfo.CacheID = LLUUID.Random(); //I guess this is for the client to remember an old setting?
161
162 this.OutPacket(handshake);
163 }
164
165 /// <summary>
166 ///
167 /// </summary>
168 /// <param name="regInfo"></param>
169 public void MoveAgentIntoRegion(RegionInfo regInfo)
170 {
171 AgentMovementCompletePacket mov = new AgentMovementCompletePacket();
172 mov.AgentData.SessionID = this.SessionID;
173 mov.AgentData.AgentID = this.AgentID;
174 mov.Data.RegionHandle = regInfo.RegionHandle;
175 // TODO - dynamicalise this stuff
176 mov.Data.Timestamp = 1172750370;
177 mov.Data.Position = this.startpos;
178 mov.Data.LookAt = new LLVector3(0.99f, 0.042f, 0);
179
180 OutPacket(mov);
181 }
182
183 public void SendChatMessage(string message, byte type, LLVector3 fromPos, string fromName, LLUUID fromAgentID)
184 {
185 SendChatMessage( Helpers.StringToField( message ), type, fromPos, fromName, fromAgentID);
186 }
187
188 /// <summary>
189 ///
190 /// </summary>
191 /// <param name="message"></param>
192 /// <param name="type"></param>
193 /// <param name="fromPos"></param>
194 /// <param name="fromName"></param>
195 /// <param name="fromAgentID"></param>
196 public void SendChatMessage(byte[] message, byte type, LLVector3 fromPos, string fromName, LLUUID fromAgentID)
197 {
198 System.Text.Encoding enc = System.Text.Encoding.ASCII;
199 libsecondlife.Packets.ChatFromSimulatorPacket reply = new ChatFromSimulatorPacket();
200 reply.ChatData.Audible = 1;
201 reply.ChatData.Message = message;
202 reply.ChatData.ChatType = type;
203 reply.ChatData.SourceType = 1;
204 reply.ChatData.Position = fromPos;
205 reply.ChatData.FromName = enc.GetBytes(fromName + "\0");
206 reply.ChatData.OwnerID = fromAgentID;
207 reply.ChatData.SourceID = fromAgentID;
208
209 this.OutPacket(reply);
210 }
211
212
213 /// <summary>
214 /// Send the region heightmap to the client
215 /// </summary>
216 /// <param name="map">heightmap</param>
217 public virtual void SendLayerData(float[] map)
218 {
219 try
220 {
221 int[] patches = new int[4];
222
223 for (int y = 0; y < 16; y++)
224 {
225 for (int x = 0; x < 16; x = x + 4)
226 {
227 patches[0] = x + 0 + y * 16;
228 patches[1] = x + 1 + y * 16;
229 patches[2] = x + 2 + y * 16;
230 patches[3] = x + 3 + y * 16;
231
232 Packet layerpack = TerrainManager.CreateLandPacket(map, patches);
233 OutPacket(layerpack);
234 }
235 }
236 }
237 catch (Exception e)
238 {
239 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.MEDIUM, "ClientView API.cs: SendLayerData() - Failed with exception " + e.ToString());
240 }
241 }
242
243 /// <summary>
244 /// Sends a specified patch to a client
245 /// </summary>
246 /// <param name="px">Patch coordinate (x) 0..16</param>
247 /// <param name="py">Patch coordinate (y) 0..16</param>
248 /// <param name="map">heightmap</param>
249 public void SendLayerData(int px, int py, float[] map)
250 {
251 try
252 {
253 int[] patches = new int[1];
254 int patchx, patchy;
255 patchx = px / 16;
256 patchy = py / 16;
257
258 patches[0] = patchx + 0 + patchy * 16;
259
260 Packet layerpack = TerrainManager.CreateLandPacket(map, patches);
261 OutPacket(layerpack);
262 }
263 catch (Exception e)
264 {
265 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.MEDIUM, "ClientView API .cs: SendLayerData() - Failed with exception " + e.ToString());
266 }
267 }
268
269 public void InformClientOfNeighbour(ulong neighbourHandle, System.Net.IPAddress neighbourIP, ushort neighbourPort)
270 {
271 EnableSimulatorPacket enablesimpacket = new EnableSimulatorPacket();
272 enablesimpacket.SimulatorInfo = new EnableSimulatorPacket.SimulatorInfoBlock();
273 enablesimpacket.SimulatorInfo.Handle = neighbourHandle;
274
275 byte[] byteIP = neighbourIP.GetAddressBytes();
276 enablesimpacket.SimulatorInfo.IP = (uint)byteIP[3] << 24;
277 enablesimpacket.SimulatorInfo.IP += (uint)byteIP[2] << 16;
278 enablesimpacket.SimulatorInfo.IP += (uint)byteIP[1] << 8;
279 enablesimpacket.SimulatorInfo.IP += (uint)byteIP[0];
280 enablesimpacket.SimulatorInfo.Port = neighbourPort;
281 OutPacket(enablesimpacket);
282 }
283
284 public AgentCircuitData RequestClientInfo()
285 {
286 AgentCircuitData agentData = new AgentCircuitData();
287 agentData.AgentID = this.AgentId;
288 agentData.SessionID = this.SessionID;
289 agentData.SecureSessionID = this.SecureSessionID;
290 agentData.circuitcode = this.CircuitCode;
291 agentData.child = false;
292 agentData.firstname = this.firstName;
293 agentData.lastname = this.lastName;
294
295 return agentData;
296 }
297
298 #region Appearance/ Wearables Methods
299
300 /// <summary>
301 ///
302 /// </summary>
303 /// <param name="wearables"></param>
304 public void SendWearables(AvatarWearable[] wearables)
305 {
306 AgentWearablesUpdatePacket aw = new AgentWearablesUpdatePacket();
307 aw.AgentData.AgentID = this.AgentID;
308 aw.AgentData.SerialNum = 0;
309 aw.AgentData.SessionID = this.SessionID;
310
311 aw.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[13];
312 AgentWearablesUpdatePacket.WearableDataBlock awb;
313 for (int i = 0; i < wearables.Length; i++)
314 {
315 awb = new AgentWearablesUpdatePacket.WearableDataBlock();
316 awb.WearableType = (byte)i;
317 awb.AssetID = wearables[i].AssetID;
318 awb.ItemID = wearables[i].ItemID;
319 aw.WearableData[i] = awb;
320 }
321
322 this.OutPacket(aw);
323 }
324
325 /// <summary>
326 ///
327 /// </summary>
328 /// <param name="agentID"></param>
329 /// <param name="visualParams"></param>
330 /// <param name="textureEntry"></param>
331 public void SendAppearance(LLUUID agentID, byte[] visualParams, byte[] textureEntry)
332 {
333 AvatarAppearancePacket avp = new AvatarAppearancePacket();
334 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[218];
335 avp.ObjectData.TextureEntry = textureEntry;
336
337 AvatarAppearancePacket.VisualParamBlock avblock = null;
338 for (int i = 0; i < visualParams.Length; i++)
339 {
340 avblock = new AvatarAppearancePacket.VisualParamBlock();
341 avblock.ParamValue = visualParams[i];
342 avp.VisualParam[i] = avblock;
343 }
344
345 avp.Sender.IsTrial = false;
346 avp.Sender.ID = agentID;
347 OutPacket(avp);
348 }
349
350 #endregion
351
352 #region Avatar Packet/data sending Methods
353
354 /// <summary>
355 ///
356 /// </summary>
357 /// <param name="regionInfo"></param>
358 /// <param name="firstName"></param>
359 /// <param name="lastName"></param>
360 /// <param name="avatarID"></param>
361 /// <param name="avatarLocalID"></param>
362 /// <param name="Pos"></param>
363 public void SendAvatarData(RegionInfo regionInfo, string firstName, string lastName, LLUUID avatarID, uint avatarLocalID, LLVector3 Pos)
364 {
365 System.Text.Encoding _enc = System.Text.Encoding.ASCII;
366 //send a objectupdate packet with information about the clients avatar
367
368 ObjectUpdatePacket objupdate = new ObjectUpdatePacket();
369 objupdate.RegionData.RegionHandle = regionInfo.RegionHandle;
370 objupdate.RegionData.TimeDilation = 64096;
371 objupdate.ObjectData = new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock[1];
372 objupdate.ObjectData[0] = this.CreateDefaultAvatarPacket();
373 //give this avatar object a local id and assign the user a name
374
375 objupdate.ObjectData[0].ID = avatarLocalID;
376 objupdate.ObjectData[0].FullID = avatarID;
377 objupdate.ObjectData[0].NameValue = _enc.GetBytes("FirstName STRING RW SV " + firstName + "\nLastName STRING RW SV " + lastName + " \0");
378 libsecondlife.LLVector3 pos2 = new LLVector3((float)Pos.X, (float)Pos.Y, (float)Pos.Z);
379 byte[] pb = pos2.GetBytes();
380 Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 16, pb.Length);
381
382 OutPacket(objupdate);
383
384 }
385
386
387 /// <summary>
388 ///
389 /// </summary>
390 /// <param name="objdata"></param>
391 protected void SetDefaultAvatarPacketValues(ref ObjectUpdatePacket.ObjectDataBlock objdata)
392 {
393 objdata.PSBlock = new byte[0];
394 objdata.ExtraParams = new byte[1];
395 objdata.MediaURL = new byte[0];
396 objdata.NameValue = new byte[0];
397 objdata.Text = new byte[0];
398 objdata.TextColor = new byte[4];
399 objdata.JointAxisOrAnchor = new LLVector3(0, 0, 0);
400 objdata.JointPivot = new LLVector3(0, 0, 0);
401 objdata.Material = 4;
402 objdata.TextureAnim = new byte[0];
403 objdata.Sound = LLUUID.Zero;
404 LLObject.TextureEntry ntex = new LLObject.TextureEntry(new LLUUID("00000000-0000-0000-5005-000000000005"));
405 objdata.TextureEntry = ntex.ToBytes();
406 objdata.State = 0;
407 objdata.Data = new byte[0];
408
409 objdata.ObjectData = new byte[76];
410 objdata.ObjectData[15] = 128;
411 objdata.ObjectData[16] = 63;
412 objdata.ObjectData[56] = 128;
413 objdata.ObjectData[61] = 102;
414 objdata.ObjectData[62] = 40;
415 objdata.ObjectData[63] = 61;
416 objdata.ObjectData[64] = 189;
417 }
418
419 /// <summary>
420 ///
421 /// </summary>
422 /// <returns></returns>
423 protected ObjectUpdatePacket.ObjectDataBlock CreateDefaultAvatarPacket()
424 {
425 libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock objdata = new ObjectUpdatePacket.ObjectDataBlock(); // new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock(data1, ref i);
426
427 SetDefaultAvatarPacketValues(ref objdata);
428 objdata.UpdateFlags = 61 + (9 << 8) + (130 << 16) + (16 << 24);
429 objdata.PathCurve = 16;
430 objdata.ProfileCurve = 1;
431 objdata.PathScaleX = 100;
432 objdata.PathScaleY = 100;
433 objdata.ParentID = 0;
434 objdata.OwnerID = LLUUID.Zero;
435 objdata.Scale = new LLVector3(1, 1, 1);
436 objdata.PCode = 47;
437 System.Text.Encoding enc = System.Text.Encoding.ASCII;
438 libsecondlife.LLVector3 pos = new LLVector3(objdata.ObjectData, 16);
439 pos.X = 100f;
440 objdata.ID = 8880000;
441 objdata.NameValue = enc.GetBytes("FirstName STRING RW SV Test \nLastName STRING RW SV User \0");
442 libsecondlife.LLVector3 pos2 = new LLVector3(100f, 100f, 23f);
443 //objdata.FullID=user.AgentID;
444 byte[] pb = pos.GetBytes();
445 Array.Copy(pb, 0, objdata.ObjectData, 16, pb.Length);
446
447 return objdata;
448 }
449
450 #endregion
451
452 #region Primitive Packet/data Sending Methods
453
454 /// <summary>
455 ///
456 /// </summary>
457 /// <param name="localID"></param>
458 /// <param name="rotation"></param>
459 /// <param name="attachPoint"></param>
460 public void AttachObject(uint localID, LLQuaternion rotation, byte attachPoint)
461 {
462 ObjectAttachPacket attach = new ObjectAttachPacket();
463 attach.AgentData.AgentID = this.AgentID;
464 attach.AgentData.SessionID = this.SessionID;
465 attach.AgentData.AttachmentPoint = attachPoint;
466 attach.ObjectData = new ObjectAttachPacket.ObjectDataBlock[1];
467 attach.ObjectData[0] = new ObjectAttachPacket.ObjectDataBlock();
468 attach.ObjectData[0].ObjectLocalID = localID;
469 attach.ObjectData[0].Rotation = rotation;
470
471 this.OutPacket(attach);
472 }
473
474 /// <summary>
475 /// Sends a full ObjectUpdatePacket to a client to inform it of a new primitive
476 /// or big changes to a existing primitive.
477 /// </summary>
478 /// <param name="regionHandle"></param>
479 /// <param name="timeDilation"></param>
480 /// <param name="localID"></param>
481 /// <param name="primData"></param>
482 /// <param name="pos"></param>
483 /// <param name="rotation"></param>
484 /// <param name="textureID"></param>
485 public void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimData primData, LLVector3 pos, LLQuaternion rotation, LLUUID textureID)
486 {
487 ObjectUpdatePacket outPacket = new ObjectUpdatePacket();
488 outPacket.RegionData.RegionHandle = regionHandle;
489 outPacket.RegionData.TimeDilation = timeDilation;
490 outPacket.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
491 outPacket.ObjectData[0] = this.CreatePrimUpdateBlock(primData, textureID);
492 outPacket.ObjectData[0].ID = localID;
493 outPacket.ObjectData[0].FullID = primData.FullID;
494 byte[] pb = pos.GetBytes();
495 Array.Copy(pb, 0, outPacket.ObjectData[0].ObjectData, 0, pb.Length);
496 byte[] rot = rotation.GetBytes();
497 Array.Copy(rot, 0, outPacket.ObjectData[0].ObjectData, 48, rot.Length);
498 OutPacket(outPacket);
499 }
500
501 /// <summary>
502 /// Sends a full ObjectUpdatePacket to a client to inform it of a new primitive
503 /// or big changes to a existing primitive.
504 /// uses default rotation
505 /// </summary>
506 /// <param name="primData"></param>
507 /// <param name="pos"></param>
508 public void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimData primData, LLVector3 pos, LLUUID textureID)
509 {
510 ObjectUpdatePacket outPacket = new ObjectUpdatePacket();
511 outPacket.RegionData.RegionHandle = regionHandle;
512 outPacket.RegionData.TimeDilation = timeDilation;
513 outPacket.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
514 outPacket.ObjectData[0] = this.CreatePrimUpdateBlock(primData, textureID);
515 outPacket.ObjectData[0].ID = localID;
516 outPacket.ObjectData[0].FullID = primData.FullID;
517 byte[] pb = pos.GetBytes();
518 Array.Copy(pb, 0, outPacket.ObjectData[0].ObjectData, 0, pb.Length);
519
520 OutPacket(outPacket);
521 }
522
523 /// <summary>
524 /// Create the ObjectDataBlock for a ObjectUpdatePacket (for a Primitive)
525 /// </summary>
526 /// <param name="primData"></param>
527 /// <returns></returns>
528 protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(PrimData primData, LLUUID textureID)
529 {
530 ObjectUpdatePacket.ObjectDataBlock objupdate = new ObjectUpdatePacket.ObjectDataBlock();
531 this.SetDefaultPrimPacketValues(objupdate);
532 objupdate.UpdateFlags = 32 + 65536 + 131072 + 256 + 4 + 8 + 2048 + 524288 + 268435456;
533 this.SetPrimPacketShapeData(objupdate, primData, textureID);
534
535 return objupdate;
536 }
537
538 /// <summary>
539 /// Set some default values in a ObjectUpdatePacket
540 /// </summary>
541 /// <param name="objdata"></param>
542 protected void SetDefaultPrimPacketValues(ObjectUpdatePacket.ObjectDataBlock objdata)
543 {
544 objdata.PSBlock = new byte[0];
545 objdata.ExtraParams = new byte[1];
546 objdata.MediaURL = new byte[0];
547 objdata.NameValue = new byte[0];
548 objdata.Text = new byte[0];
549 objdata.TextColor = new byte[4];
550 objdata.JointAxisOrAnchor = new LLVector3(0, 0, 0);
551 objdata.JointPivot = new LLVector3(0, 0, 0);
552 objdata.Material = 3;
553 objdata.TextureAnim = new byte[0];
554 objdata.Sound = LLUUID.Zero;
555 objdata.State = 0;
556 objdata.Data = new byte[0];
557
558 objdata.ObjectData = new byte[60];
559 objdata.ObjectData[46] = 128;
560 objdata.ObjectData[47] = 63;
561 }
562
563 /// <summary>
564 /// Copy the data from a PrimData object to a ObjectUpdatePacket
565 /// </summary>
566 /// <param name="objectData"></param>
567 /// <param name="primData"></param>
568 protected void SetPrimPacketShapeData(ObjectUpdatePacket.ObjectDataBlock objectData, PrimData primData, LLUUID textureID)
569 {
570 LLObject.TextureEntry ntex = new LLObject.TextureEntry(textureID);
571 objectData.TextureEntry = ntex.ToBytes();
572 objectData.OwnerID = primData.OwnerID;
573 objectData.PCode = primData.PCode;
574 objectData.PathBegin =primData.PathBegin;
575 objectData.PathEnd = primData.PathEnd;
576 objectData.PathScaleX = primData.PathScaleX;
577 objectData.PathScaleY = primData.PathScaleY;
578 objectData.PathShearX = primData.PathShearX;
579 objectData.PathShearY = primData.PathShearY;
580 objectData.PathSkew = primData.PathSkew;
581 objectData.ProfileBegin = primData.ProfileBegin;
582 objectData.ProfileEnd = primData.ProfileEnd;
583 objectData.Scale = primData.Scale;
584 objectData.PathCurve = primData.PathCurve;
585 objectData.ProfileCurve = primData.ProfileCurve;
586 objectData.ParentID = primData.ParentID;
587 objectData.ProfileHollow = primData.ProfileHollow;
588 objectData.PathRadiusOffset = primData.PathRadiusOffset;
589 objectData.PathRevolutions = primData.PathRevolutions;
590 objectData.PathTaperX = primData.PathTaperX;
591 objectData.PathTaperY = primData.PathTaperY;
592 objectData.PathTwist = primData.PathTwist;
593 objectData.PathTwistBegin = primData.PathTwistBegin;
594 }
595
596 public void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, LLVector3 position, LLQuaternion rotation)
597 {
598 ImprovedTerseObjectUpdatePacket terse = new ImprovedTerseObjectUpdatePacket();
599 terse.RegionData.RegionHandle = regionHandle;
600 terse.RegionData.TimeDilation = timeDilation;
601 terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1];
602 terse.ObjectData[0] = this.CreatePrimImprovedBlock(localID, position, rotation);
603
604 this.OutPacket(terse);
605 }
606
607 /// <summary>
608 ///
609 /// </summary>
610 /// <param name="localID"></param>
611 /// <param name="position"></param>
612 /// <param name="rotation"></param>
613 /// <returns></returns>
614 protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreatePrimImprovedBlock(uint localID, LLVector3 position, LLQuaternion rotation)
615 {
616 uint ID = localID;
617 byte[] bytes = new byte[60];
618
619 int i = 0;
620 ImprovedTerseObjectUpdatePacket.ObjectDataBlock dat = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock();
621 dat.TextureEntry = new byte[0];
622 bytes[i++] = (byte)(ID % 256);
623 bytes[i++] = (byte)((ID >> 8) % 256);
624 bytes[i++] = (byte)((ID >> 16) % 256);
625 bytes[i++] = (byte)((ID >> 24) % 256);
626 bytes[i++] = 0;
627 bytes[i++] = 0;
628
629 byte[] pb = position.GetBytes();
630 Array.Copy(pb, 0, bytes, i, pb.Length);
631 i += 12;
632 ushort ac = 32767;
633
634 //vel
635 bytes[i++] = (byte)(ac % 256);
636 bytes[i++] = (byte)((ac >> 8) % 256);
637 bytes[i++] = (byte)(ac % 256);
638 bytes[i++] = (byte)((ac >> 8) % 256);
639 bytes[i++] = (byte)(ac % 256);
640 bytes[i++] = (byte)((ac >> 8) % 256);
641
642 //accel
643 bytes[i++] = (byte)(ac % 256);
644 bytes[i++] = (byte)((ac >> 8) % 256);
645 bytes[i++] = (byte)(ac % 256);
646 bytes[i++] = (byte)((ac >> 8) % 256);
647 bytes[i++] = (byte)(ac % 256);
648 bytes[i++] = (byte)((ac >> 8) % 256);
649
650 ushort rw, rx, ry, rz;
651 rw = (ushort)(32768 * (rotation.W + 1));
652 rx = (ushort)(32768 * (rotation.X + 1));
653 ry = (ushort)(32768 * (rotation.Y + 1));
654 rz = (ushort)(32768 * (rotation.Z + 1));
655
656 //rot
657 bytes[i++] = (byte)(rx % 256);
658 bytes[i++] = (byte)((rx >> 8) % 256);
659 bytes[i++] = (byte)(ry % 256);
660 bytes[i++] = (byte)((ry >> 8) % 256);
661 bytes[i++] = (byte)(rz % 256);
662 bytes[i++] = (byte)((rz >> 8) % 256);
663 bytes[i++] = (byte)(rw % 256);
664 bytes[i++] = (byte)((rw >> 8) % 256);
665
666 //rotation vel
667 bytes[i++] = (byte)(ac % 256);
668 bytes[i++] = (byte)((ac >> 8) % 256);
669 bytes[i++] = (byte)(ac % 256);
670 bytes[i++] = (byte)((ac >> 8) % 256);
671 bytes[i++] = (byte)(ac % 256);
672 bytes[i++] = (byte)((ac >> 8) % 256);
673
674 dat.Data = bytes;
675 return dat;
676 }
677 #endregion
678
679 #endregion
680
681 }
682}