aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim.RegionServer/world/Avatar.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim.RegionServer/world/Avatar.cs501
1 files changed, 501 insertions, 0 deletions
diff --git a/OpenSim.RegionServer/world/Avatar.cs b/OpenSim.RegionServer/world/Avatar.cs
new file mode 100644
index 0000000..b4a3b82
--- /dev/null
+++ b/OpenSim.RegionServer/world/Avatar.cs
@@ -0,0 +1,501 @@
1using System;
2using System.Collections.Generic;
3using System.IO;
4using System.Text;
5using libsecondlife;
6using libsecondlife.Packets;
7using OpenSim.Physics.Manager;
8using Axiom.MathLib;
9
10namespace OpenSim.world
11{
12 public class Avatar : Entity
13 {
14 public static bool PhysicsEngineFlying = false;
15 public string firstname;
16 public string lastname;
17 public SimClient ControllingClient;
18 private PhysicsActor _physActor;
19 private static libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock AvatarTemplate;
20 private bool updateflag = false;
21 private byte movementflag = 0;
22 private List<NewForce> forcesList = new List<NewForce>();
23 private short _updateCount = 0;
24 private Axiom.MathLib.Quaternion bodyRot;
25
26 public Avatar(SimClient TheClient)
27 {
28 OpenSim.Framework.Console.MainConsole.Instance.WriteLine("Avatar.cs - Loading details from grid (DUMMY)");
29 ControllingClient = TheClient;
30 localid = 8880000 + (OpenSimRoot.Instance.LocalWorld._localNumber++);
31 position = new LLVector3(100.0f, 100.0f, 30.0f);
32 position.Z = OpenSimRoot.Instance.LocalWorld.LandMap[(int)position.Y * 256 + (int)position.X] + 1;
33 }
34
35 public PhysicsActor PhysActor
36 {
37 set
38 {
39 this._physActor = value;
40 }
41 }
42
43 public override void addForces()
44 {
45 lock (this.forcesList)
46 {
47 if (this.forcesList.Count > 0)
48 {
49 for (int i = 0; i < this.forcesList.Count; i++)
50 {
51 NewForce force = this.forcesList[i];
52 PhysicsVector phyVector = new PhysicsVector(force.X, force.Y, force.Z);
53 this._physActor.Velocity = phyVector;
54 this.updateflag = true;
55 this.velocity = new LLVector3(force.X, force.Y, force.Z); //shouldn't really be doing this
56 // but as we are setting the velocity (rather than using real forces) at the moment it is okay.
57 }
58 for (int i = 0; i < this.forcesList.Count; i++)
59 {
60 this.forcesList.RemoveAt(0);
61 }
62 }
63 }
64 }
65
66 public override void update()
67 {
68
69 if (this.updateflag)
70 {
71 //need to send movement info
72 //so create the improvedterseobjectupdate packet
73 //use CreateTerseBlock()
74 ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock = CreateTerseBlock();
75 ImprovedTerseObjectUpdatePacket terse = new ImprovedTerseObjectUpdatePacket();
76 terse.RegionData.RegionHandle = OpenSimRoot.Instance.Cfg.RegionHandle; // FIXME
77 terse.RegionData.TimeDilation = 64096;
78 terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1];
79 terse.ObjectData[0] = terseBlock;
80 foreach (SimClient client in OpenSimRoot.Instance.ClientThreads.Values)
81 {
82 client.OutPacket(terse);
83 }
84
85 updateflag = false;
86 //this._updateCount = 0;
87 }
88 else
89 {
90 //if((movementflag & 1) !=0)
91 //{
92 _updateCount++;
93 if (((!PhysicsEngineFlying) && (_updateCount > 3)) || (_updateCount > 0))
94 {
95 //It has been a while since last update was sent so lets send one.
96 ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock = CreateTerseBlock();
97 ImprovedTerseObjectUpdatePacket terse = new ImprovedTerseObjectUpdatePacket();
98 terse.RegionData.RegionHandle = OpenSimRoot.Instance.Cfg.RegionHandle; // FIXME
99 terse.RegionData.TimeDilation = 64096;
100 terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1];
101 terse.ObjectData[0] = terseBlock;
102 foreach (SimClient client in OpenSimRoot.Instance.ClientThreads.Values)
103 {
104 client.OutPacket(terse);
105 }
106 _updateCount = 0;
107 }
108 //}
109 }
110 }
111
112 public static void SetupTemplate(string name)
113 {
114 int i = 0;
115 FileInfo fInfo = new FileInfo(name);
116 long numBytes = fInfo.Length;
117 FileStream fStream = new FileStream(name, FileMode.Open, FileAccess.Read);
118 BinaryReader br = new BinaryReader(fStream);
119 byte[] data1 = br.ReadBytes((int)numBytes);
120 br.Close();
121 fStream.Close();
122
123 libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock objdata = new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock(data1, ref i);
124
125 System.Text.Encoding enc = System.Text.Encoding.ASCII;
126 libsecondlife.LLVector3 pos = new LLVector3(objdata.ObjectData, 16);
127 pos.X = 100f;
128 objdata.ID = 8880000;
129 objdata.NameValue = enc.GetBytes("FirstName STRING RW SV Test \nLastName STRING RW SV User \0");
130 libsecondlife.LLVector3 pos2 = new LLVector3(100f, 100f, 23f);
131 //objdata.FullID=user.AgentID;
132 byte[] pb = pos.GetBytes();
133 Array.Copy(pb, 0, objdata.ObjectData, 16, pb.Length);
134
135 Avatar.AvatarTemplate = objdata;
136 }
137
138 public void CompleteMovement(World RegionInfo)
139 {
140 OpenSim.Framework.Console.MainConsole.Instance.WriteLine("Avatar.cs:CompleteMovement() - Constructing AgentMovementComplete packet");
141 AgentMovementCompletePacket mov = new AgentMovementCompletePacket();
142 mov.AgentData.SessionID = this.ControllingClient.SessionID;
143 mov.AgentData.AgentID = this.ControllingClient.AgentID;
144 mov.Data.RegionHandle = OpenSimRoot.Instance.Cfg.RegionHandle;
145 // TODO - dynamicalise this stuff
146 mov.Data.Timestamp = 1172750370;
147 mov.Data.Position = new LLVector3(100f, 100f, 23f);
148 mov.Data.LookAt = new LLVector3(0.99f, 0.042f, 0);
149
150 ControllingClient.OutPacket(mov);
151 }
152
153 public void SendInitialPosition()
154 {
155
156 System.Text.Encoding _enc = System.Text.Encoding.ASCII;
157 //send a objectupdate packet with information about the clients avatar
158 ObjectUpdatePacket objupdate = new ObjectUpdatePacket();
159 objupdate.RegionData.RegionHandle = OpenSimRoot.Instance.Cfg.RegionHandle;
160 objupdate.RegionData.TimeDilation = 64096;
161 objupdate.ObjectData = new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock[1];
162
163 objupdate.ObjectData[0] = AvatarTemplate;
164 //give this avatar object a local id and assign the user a name
165 objupdate.ObjectData[0].ID = this.localid;
166 this.uuid = objupdate.ObjectData[0].FullID = ControllingClient.AgentID;
167 objupdate.ObjectData[0].NameValue = _enc.GetBytes("FirstName STRING RW SV " + firstname + "\nLastName STRING RW SV " + lastname + " \0");
168
169 libsecondlife.LLVector3 pos2 = new LLVector3((float)this.position.X, (float)this.position.Y, (float)this.position.Z);
170
171 byte[] pb = pos2.GetBytes();
172
173 Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 16, pb.Length);
174 OpenSimRoot.Instance.LocalWorld._localNumber++;
175
176 foreach (SimClient client in OpenSimRoot.Instance.ClientThreads.Values)
177 {
178 client.OutPacket(objupdate);
179 if (client.AgentID != ControllingClient.AgentID)
180 {
181 SendAppearanceToOtherAgent(client);
182 }
183 }
184 //this.ControllingClient.OutPacket(objupdate);
185 }
186
187 public void SendInitialAppearance()
188 {
189 AgentWearablesUpdatePacket aw = new AgentWearablesUpdatePacket();
190 aw.AgentData.AgentID = this.ControllingClient.AgentID;
191 aw.AgentData.SerialNum = 0;
192 aw.AgentData.SessionID = ControllingClient.SessionID;
193
194 aw.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[13];
195 AgentWearablesUpdatePacket.WearableDataBlock awb = new AgentWearablesUpdatePacket.WearableDataBlock();
196 awb.WearableType = (byte)0;
197 awb.AssetID = new LLUUID("66c41e39-38f9-f75a-024e-585989bfab73");
198 awb.ItemID = LLUUID.Random();
199 aw.WearableData[0] = awb;
200
201 for (int i = 1; i < 13; i++)
202 {
203 awb = new AgentWearablesUpdatePacket.WearableDataBlock();
204 awb.WearableType = (byte)i;
205 awb.AssetID = new LLUUID("00000000-0000-0000-0000-000000000000");
206 awb.ItemID = new LLUUID("00000000-0000-0000-0000-000000000000");
207 aw.WearableData[i] = awb;
208 }
209
210 ControllingClient.OutPacket(aw);
211 }
212
213 public ObjectUpdatePacket CreateUpdatePacket()
214 {
215 System.Text.Encoding _enc = System.Text.Encoding.ASCII;
216 //send a objectupdate packet with information about the clients avatar
217 ObjectUpdatePacket objupdate = new ObjectUpdatePacket();
218 objupdate.RegionData.RegionHandle = OpenSimRoot.Instance.Cfg.RegionHandle;
219 objupdate.RegionData.TimeDilation = 64096;
220 objupdate.ObjectData = new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock[1];
221
222 objupdate.ObjectData[0] = AvatarTemplate;
223 //give this avatar object a local id and assign the user a name
224 objupdate.ObjectData[0].ID = this.localid;
225 objupdate.ObjectData[0].FullID = ControllingClient.AgentID;
226 objupdate.ObjectData[0].NameValue = _enc.GetBytes("FirstName STRING RW SV " + firstname + "\nLastName STRING RW SV " + lastname + " \0");
227
228 libsecondlife.LLVector3 pos2 = new LLVector3((float)this._physActor.Position.X, (float)this._physActor.Position.Y, (float)this._physActor.Position.Z);
229
230 byte[] pb = pos2.GetBytes();
231
232 Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 16, pb.Length);
233 return objupdate;
234 }
235
236 public void SendAppearanceToOtherAgent(SimClient userInfo)
237 {
238 AvatarAppearancePacket avp = new AvatarAppearancePacket();
239
240
241 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[218];
242 //avp.ObjectData.TextureEntry=this.avatar_template.TextureEntry;// br.ReadBytes((int)numBytes);
243
244 LLObject.TextureEntry ntex = new LLObject.TextureEntry(new LLUUID("00000000-0000-0000-0000-000000000005"));
245 avp.ObjectData.TextureEntry = ntex.ToBytes();
246
247 AvatarAppearancePacket.VisualParamBlock avblock = null;
248 for (int i = 0; i < 218; i++)
249 {
250 avblock = new AvatarAppearancePacket.VisualParamBlock();
251 avblock.ParamValue = (byte)100;
252 avp.VisualParam[i] = avblock;
253 }
254
255 avp.Sender.IsTrial = false;
256 avp.Sender.ID = ControllingClient.AgentID;
257 userInfo.OutPacket(avp);
258
259 }
260
261 public void HandleUpdate(AgentUpdatePacket pack)
262 {
263 if (((uint)pack.AgentData.ControlFlags & (uint)MainAvatar.AgentUpdateFlags.AGENT_CONTROL_FLY) != 0)
264 {
265 this._physActor.Flying = true;
266 }
267 else
268 {
269 this._physActor.Flying = false;
270 }
271 if (((uint)pack.AgentData.ControlFlags & (uint)MainAvatar.AgentUpdateFlags.AGENT_CONTROL_AT_POS) != 0)
272 {
273 Axiom.MathLib.Quaternion q = new Axiom.MathLib.Quaternion(pack.AgentData.BodyRotation.W, pack.AgentData.BodyRotation.X, pack.AgentData.BodyRotation.Y, pack.AgentData.BodyRotation.Z);
274 if (((movementflag & 1) == 0) || (q != this.bodyRot))
275 {
276 //we should add a new force to the list
277 // but for now we will deal with velocities
278 NewForce newVelocity = new NewForce();
279 Axiom.MathLib.Vector3 v3 = new Axiom.MathLib.Vector3(1, 0, 0);
280 Axiom.MathLib.Vector3 direc = q * v3;
281 direc.Normalize();
282
283 //work out velocity for sim physics system
284 direc = direc * ((0.03f) * 128f);
285 if (this._physActor.Flying)
286 direc *= 2;
287
288 newVelocity.X = direc.x;
289 newVelocity.Y = direc.y;
290 newVelocity.Z = direc.z;
291 this.forcesList.Add(newVelocity);
292 movementflag = 1;
293 this.bodyRot = q;
294 }
295 }
296 else if ((((uint)pack.AgentData.ControlFlags & (uint)MainAvatar.AgentUpdateFlags.AGENT_CONTROL_UP_POS) != 0) && (PhysicsEngineFlying))
297 {
298 if (((movementflag & 2) == 0) && this._physActor.Flying)
299 {
300 //we should add a new force to the list
301 // but for now we will deal with velocities
302 NewForce newVelocity = new NewForce();
303 Axiom.MathLib.Vector3 v3 = new Axiom.MathLib.Vector3(0, 0, 1);
304 Axiom.MathLib.Vector3 direc = v3;
305 direc.Normalize();
306
307 //work out velocity for sim physics system
308 direc = direc * ((0.03f) * 128f * 2);
309 newVelocity.X = direc.x;
310 newVelocity.Y = direc.y;
311 newVelocity.Z = direc.z;
312 this.forcesList.Add(newVelocity);
313 movementflag = 2;
314 }
315 }
316 else if ((((uint)pack.AgentData.ControlFlags & (uint)MainAvatar.AgentUpdateFlags.AGENT_CONTROL_UP_NEG) != 0) && (PhysicsEngineFlying))
317 {
318 if (((movementflag & 4) == 0) && this._physActor.Flying)
319 {
320 //we should add a new force to the list
321 // but for now we will deal with velocities
322 NewForce newVelocity = new NewForce();
323 Axiom.MathLib.Vector3 v3 = new Axiom.MathLib.Vector3(0, 0, -1);
324 //Axiom.MathLib.Quaternion q = new Axiom.MathLib.Quaternion(pack.AgentData.BodyRotation.W, pack.AgentData.BodyRotation.X, pack.AgentData.BodyRotation.Y, pack.AgentData.BodyRotation.Z);
325 Axiom.MathLib.Vector3 direc = v3;
326 direc.Normalize();
327
328 //work out velocity for sim physics system
329 direc = direc * ((0.03f) * 128f * 2);
330 newVelocity.X = direc.x;
331 newVelocity.Y = direc.y;
332 newVelocity.Z = direc.z;
333 this.forcesList.Add(newVelocity);
334 movementflag = 4;
335 }
336 }
337 else if (((uint)pack.AgentData.ControlFlags & (uint)MainAvatar.AgentUpdateFlags.AGENT_CONTROL_AT_NEG) != 0)
338 {
339 Axiom.MathLib.Quaternion q = new Axiom.MathLib.Quaternion(pack.AgentData.BodyRotation.W, pack.AgentData.BodyRotation.X, pack.AgentData.BodyRotation.Y, pack.AgentData.BodyRotation.Z);
340 if (((movementflag & 8) == 0) || (q != this.bodyRot))
341 {
342 //we should add a new force to the list
343 // but for now we will deal with velocities
344 NewForce newVelocity = new NewForce();
345 Axiom.MathLib.Vector3 v3 = new Axiom.MathLib.Vector3(-1, 0, 0);
346 Axiom.MathLib.Vector3 direc = q * v3;
347 direc.Normalize();
348
349 //work out velocity for sim physics system
350 direc = direc * ((0.03f) * 128f);
351 if (this._physActor.Flying)
352 direc *= 2;
353
354 newVelocity.X = direc.x;
355 newVelocity.Y = direc.y;
356 newVelocity.Z = direc.z;
357 this.forcesList.Add(newVelocity);
358 movementflag = 8;
359 this.bodyRot = q;
360 }
361 }
362 else
363 {
364 if ((movementflag) != 0)
365 {
366 NewForce newVelocity = new NewForce();
367 newVelocity.X = 0;
368 newVelocity.Y = 0;
369 newVelocity.Z = 0;
370 this.forcesList.Add(newVelocity);
371 movementflag = 0;
372 }
373 }
374 }
375
376 //should be moved somewhere else
377 public void SendRegionHandshake(World RegionInfo)
378 {
379 OpenSim.Framework.Console.MainConsole.Instance.WriteLine("Avatar.cs:SendRegionHandshake() - Creating empty RegionHandshake packet");
380 System.Text.Encoding _enc = System.Text.Encoding.ASCII;
381 RegionHandshakePacket handshake = new RegionHandshakePacket();
382
383 OpenSim.Framework.Console.MainConsole.Instance.WriteLine("Avatar.cs:SendRegionhandshake() - Filling in RegionHandshake details");
384 handshake.RegionInfo.BillableFactor = 0;
385 handshake.RegionInfo.IsEstateManager = false;
386 handshake.RegionInfo.TerrainHeightRange00 = 60;
387 handshake.RegionInfo.TerrainHeightRange01 = 60;
388 handshake.RegionInfo.TerrainHeightRange10 = 60;
389 handshake.RegionInfo.TerrainHeightRange11 = 60;
390 handshake.RegionInfo.TerrainStartHeight00 = 10;
391 handshake.RegionInfo.TerrainStartHeight01 = 10;
392 handshake.RegionInfo.TerrainStartHeight10 = 10;
393 handshake.RegionInfo.TerrainStartHeight11 = 10;
394 handshake.RegionInfo.SimAccess = 13;
395 handshake.RegionInfo.WaterHeight = 20;
396 handshake.RegionInfo.RegionFlags = 72458694;
397 handshake.RegionInfo.SimName = _enc.GetBytes(OpenSimRoot.Instance.Cfg.RegionName + "\0");
398 handshake.RegionInfo.SimOwner = new LLUUID("00000000-0000-0000-0000-000000000000");
399 handshake.RegionInfo.TerrainBase0 = new LLUUID("b8d3965a-ad78-bf43-699b-bff8eca6c975");
400 handshake.RegionInfo.TerrainBase1 = new LLUUID("abb783e6-3e93-26c0-248a-247666855da3");
401 handshake.RegionInfo.TerrainBase2 = new LLUUID("179cdabd-398a-9b6b-1391-4dc333ba321f");
402 handshake.RegionInfo.TerrainBase3 = new LLUUID("beb169c7-11ea-fff2-efe5-0f24dc881df2");
403 handshake.RegionInfo.TerrainDetail0 = new LLUUID("00000000-0000-0000-0000-000000000000");
404 handshake.RegionInfo.TerrainDetail1 = new LLUUID("00000000-0000-0000-0000-000000000000");
405 handshake.RegionInfo.TerrainDetail2 = new LLUUID("00000000-0000-0000-0000-000000000000");
406 handshake.RegionInfo.TerrainDetail3 = new LLUUID("00000000-0000-0000-0000-000000000000");
407 handshake.RegionInfo.CacheID = new LLUUID("545ec0a5-5751-1026-8a0b-216e38a7ab37");
408
409 OpenSim.Framework.Console.MainConsole.Instance.WriteLine("Avatar.cs:SendRegionHandshake() - Sending RegionHandshake packet");
410 this.ControllingClient.OutPacket(handshake);
411 }
412
413 public ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateTerseBlock()
414 {
415 byte[] bytes = new byte[60];
416 int i = 0;
417 ImprovedTerseObjectUpdatePacket.ObjectDataBlock dat = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock();
418
419 dat.TextureEntry = AvatarTemplate.TextureEntry;
420 libsecondlife.LLVector3 pos2 = new LLVector3(this._physActor.Position.X, this._physActor.Position.Y, this._physActor.Position.Z);
421
422 uint ID = this.localid;
423
424 bytes[i++] = (byte)(ID % 256);
425 bytes[i++] = (byte)((ID >> 8) % 256);
426 bytes[i++] = (byte)((ID >> 16) % 256);
427 bytes[i++] = (byte)((ID >> 24) % 256);
428 bytes[i++] = 0;
429 bytes[i++] = 1;
430 i += 14;
431 bytes[i++] = 128;
432 bytes[i++] = 63;
433
434 byte[] pb = pos2.GetBytes();
435 Array.Copy(pb, 0, bytes, i, pb.Length);
436 i += 12;
437 ushort InternVelocityX;
438 ushort InternVelocityY;
439 ushort InternVelocityZ;
440
441 Axiom.MathLib.Vector3 internDirec = new Axiom.MathLib.Vector3(this._physActor.Velocity.X, this._physActor.Velocity.Y, this._physActor.Velocity.Z);
442 internDirec = internDirec / 128.0f;
443 internDirec.x += 1;
444 internDirec.y += 1;
445 internDirec.z += 1;
446
447 InternVelocityX = (ushort)(32768 * internDirec.x);
448 InternVelocityY = (ushort)(32768 * internDirec.y);
449 InternVelocityZ = (ushort)(32768 * internDirec.z);
450
451 ushort ac = 32767;
452 bytes[i++] = (byte)(InternVelocityX % 256);
453 bytes[i++] = (byte)((InternVelocityX >> 8) % 256);
454 bytes[i++] = (byte)(InternVelocityY % 256);
455 bytes[i++] = (byte)((InternVelocityY >> 8) % 256);
456 bytes[i++] = (byte)(InternVelocityZ % 256);
457 bytes[i++] = (byte)((InternVelocityZ >> 8) % 256);
458
459 //accel
460 bytes[i++] = (byte)(ac % 256);
461 bytes[i++] = (byte)((ac >> 8) % 256);
462 bytes[i++] = (byte)(ac % 256);
463 bytes[i++] = (byte)((ac >> 8) % 256);
464 bytes[i++] = (byte)(ac % 256);
465 bytes[i++] = (byte)((ac >> 8) % 256);
466
467 //rot
468 bytes[i++] = (byte)(ac % 256);
469 bytes[i++] = (byte)((ac >> 8) % 256);
470 bytes[i++] = (byte)(ac % 256);
471 bytes[i++] = (byte)((ac >> 8) % 256);
472 bytes[i++] = (byte)(ac % 256);
473 bytes[i++] = (byte)((ac >> 8) % 256);
474 bytes[i++] = (byte)(ac % 256);
475 bytes[i++] = (byte)((ac >> 8) % 256);
476
477 //rotation vel
478 bytes[i++] = (byte)(ac % 256);
479 bytes[i++] = (byte)((ac >> 8) % 256);
480 bytes[i++] = (byte)(ac % 256);
481 bytes[i++] = (byte)((ac >> 8) % 256);
482 bytes[i++] = (byte)(ac % 256);
483 bytes[i++] = (byte)((ac >> 8) % 256);
484
485 dat.Data = bytes;
486 return (dat);
487 }
488 }
489
490 public class NewForce
491 {
492 public float X;
493 public float Y;
494 public float Z;
495
496 public NewForce()
497 {
498
499 }
500 }
501}