aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/world/Avatar.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/world/Avatar.cs')
-rw-r--r--src/world/Avatar.cs355
1 files changed, 355 insertions, 0 deletions
diff --git a/src/world/Avatar.cs b/src/world/Avatar.cs
new file mode 100644
index 0000000..c8469f8
--- /dev/null
+++ b/src/world/Avatar.cs
@@ -0,0 +1,355 @@
1using System;
2using System.Collections.Generic;
3using System.IO;
4using System.Text;
5using libsecondlife;
6using libsecondlife.Packets;
7using PhysicsSystem;
8using Axiom.MathLib;
9
10namespace OpenSim.world
11{
12 public class Avatar : Entity
13 {
14 public string firstname;
15 public string lastname;
16 public OpenSimClient ControllingClient;
17 private PhysicsActor _physActor;
18 private libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock AvatarTemplate;
19 private bool updateflag;
20 private bool walking;
21 private List<NewForce> forcesList = new List<NewForce>();
22 private short _updateCount;
23
24 public Avatar(OpenSimClient TheClient) {
25 ServerConsole.MainConsole.Instance.WriteLine("Avatar.cs - Loading details from grid (DUMMY)");
26 ControllingClient=TheClient;
27 SetupTemplate("avatar-template.dat");
28 position = new LLVector3(100.0f,100.0f,30.0f);
29 position.Z = OpenSim_Main.local_world.LandMap[(int)position.Y * 256 + (int)position.X]+1;
30 }
31
32 public PhysicsActor PhysActor
33 {
34 set
35 {
36 this._physActor = value;
37 }
38 }
39 public override void addForces()
40 {
41 lock(this.forcesList)
42 {
43 if(this.forcesList.Count>0)
44 {
45 for(int i=0 ; i < this.forcesList.Count; i++)
46 {
47 NewForce force = this.forcesList[i];
48 PhysicsVector phyVector = new PhysicsVector(force.X, force.Y, force.Z);
49 this._physActor.Velocity = phyVector;
50 this.updateflag = true;
51 this.velocity = new LLVector3(force.X, force.Y, force.Z); //shouldn't really be doing this
52 // but as we are setting the velocity (rather than using real forces) at the moment it is okay.
53 }
54 for(int i=0 ; i < this.forcesList.Count; i++)
55 {
56 this.forcesList.RemoveAt(0);
57 }
58 }
59 }
60 }
61
62 public override void update()
63 {
64
65 if(this.updateflag)
66 {
67 //need to send movement info
68 //so create the improvedterseobjectupdate packet
69 //use CreateTerseBlock()
70 ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock = CreateTerseBlock();
71 ImprovedTerseObjectUpdatePacket terse = new ImprovedTerseObjectUpdatePacket();
72 terse.RegionData.RegionHandle = OpenSim_Main.cfg.RegionHandle; // FIXME
73 terse.RegionData.TimeDilation = 64096;
74 terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1];
75 terse.ObjectData[0] = terseBlock;
76 foreach(OpenSimClient client in OpenSim_Main.sim.ClientThreads.Values) {
77 client.OutPacket(terse);
78 }
79
80 updateflag =false;
81 this._updateCount = 0;
82 }
83 else
84 {
85 if(walking)
86 {
87 _updateCount++;
88 if(_updateCount>3)
89 {
90 //It has been a while since last update was sent so lets send one.
91 ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock = CreateTerseBlock();
92 ImprovedTerseObjectUpdatePacket terse = new ImprovedTerseObjectUpdatePacket();
93 terse.RegionData.RegionHandle = OpenSim_Main.cfg.RegionHandle; // FIXME
94 terse.RegionData.TimeDilation = 64096;
95 terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1];
96 terse.ObjectData[0] = terseBlock;
97 foreach(OpenSimClient client in OpenSim_Main.sim.ClientThreads.Values) {
98 client.OutPacket(terse);
99 }
100 _updateCount = 0;
101 }
102 }
103 }
104 }
105
106 private void SetupTemplate(string name)
107 {
108
109 int i = 0;
110 FileInfo fInfo = new FileInfo(name);
111 long numBytes = fInfo.Length;
112 FileStream fStream = new FileStream(name, FileMode.Open, FileAccess.Read);
113 BinaryReader br = new BinaryReader(fStream);
114 byte [] data1 = br.ReadBytes((int)numBytes);
115 br.Close();
116 fStream.Close();
117
118 libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock objdata = new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock(data1, ref i);
119
120 System.Text.Encoding enc = System.Text.Encoding.ASCII;
121 libsecondlife.LLVector3 pos = new LLVector3(objdata.ObjectData, 16);
122 pos.X = 100f;
123 objdata.ID = 8880000;
124 objdata.NameValue = enc.GetBytes("FirstName STRING RW SV Test \nLastName STRING RW SV User \0");
125 libsecondlife.LLVector3 pos2 = new LLVector3(100f,100f,23f);
126 //objdata.FullID=user.AgentID;
127 byte[] pb = pos.GetBytes();
128 Array.Copy(pb, 0, objdata.ObjectData, 16, pb.Length);
129
130 AvatarTemplate = objdata;
131
132 }
133
134 public void CompleteMovement(World RegionInfo) {
135 ServerConsole.MainConsole.Instance.WriteLine("Avatar.cs:CompleteMovement() - Constructing AgentMovementComplete packet");
136 AgentMovementCompletePacket mov = new AgentMovementCompletePacket();
137 mov.AgentData.SessionID = this.ControllingClient.SessionID;
138 mov.AgentData.AgentID = this.ControllingClient.AgentID;
139 mov.Data.RegionHandle = OpenSim_Main.cfg.RegionHandle;
140 // TODO - dynamicalise this stuff
141 mov.Data.Timestamp = 1172750370;
142 mov.Data.Position = new LLVector3(100f, 100f, 23f);
143 mov.Data.LookAt = new LLVector3(0.99f, 0.042f, 0);
144
145 ControllingClient.OutPacket(mov);
146 }
147
148 public void SendInitialPosition() {
149
150 System.Text.Encoding _enc = System.Text.Encoding.ASCII;
151 //send a objectupdate packet with information about the clients avatar
152 ObjectUpdatePacket objupdate = new ObjectUpdatePacket();
153 objupdate.RegionData.RegionHandle = OpenSim_Main.cfg.RegionHandle;
154 objupdate.RegionData.TimeDilation = 64096;
155 objupdate.ObjectData = new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock[1];
156
157 objupdate.ObjectData[0] = AvatarTemplate;
158 //give this avatar object a local id and assign the user a name
159 objupdate.ObjectData[0].ID = this.localid;
160 objupdate.ObjectData[0].FullID = ControllingClient.AgentID;
161 objupdate.ObjectData[0].NameValue = _enc.GetBytes("FirstName STRING RW SV " + firstname + "\nLastName STRING RW SV " + lastname + " \0");
162
163 libsecondlife.LLVector3 pos2 = new LLVector3((float)this.position.X, (float)this.position.Y, (float)this.position.Z);
164
165 byte[] pb = pos2.GetBytes();
166
167 Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 16, pb.Length);
168 OpenSim_Main.local_world._localNumber++;
169 this.ControllingClient.OutPacket(objupdate);
170 }
171
172 public void SendInitialAppearance() {
173 AgentWearablesUpdatePacket aw = new AgentWearablesUpdatePacket();
174 aw.AgentData.AgentID = this.ControllingClient.AgentID;
175 aw.AgentData.SerialNum = 0;
176 aw.AgentData.SessionID = ControllingClient.SessionID;
177
178 aw.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[13];
179 AgentWearablesUpdatePacket.WearableDataBlock awb = new AgentWearablesUpdatePacket.WearableDataBlock();
180 awb.WearableType = (byte)0;
181 awb.AssetID = new LLUUID("66c41e39-38f9-f75a-024e-585989bfab73");
182 awb.ItemID = LLUUID.Random();
183 aw.WearableData[0] = awb;
184
185 for(int i=1; i<13; i++) {
186 awb = new AgentWearablesUpdatePacket.WearableDataBlock();
187 awb.WearableType = (byte)i;
188 awb.AssetID = new LLUUID("00000000-0000-0000-0000-000000000000");
189 awb.ItemID = new LLUUID("00000000-0000-0000-0000-000000000000");
190 aw.WearableData[i] = awb;
191 }
192
193 ControllingClient.OutPacket(aw);
194 }
195
196 public void HandleUpdate(AgentUpdatePacket pack) {
197 if(((uint)pack.AgentData.ControlFlags & (uint)MainAvatar.AgentUpdateFlags.AGENT_CONTROL_AT_POS) !=0) {
198 if(!walking)
199 {
200 //we should add a new force to the list
201 // but for now we will deal with velocities
202 NewForce newVelocity = new NewForce();
203 Axiom.MathLib.Vector3 v3 = new Axiom.MathLib.Vector3(1, 0, 0);
204 Axiom.MathLib.Quaternion q = new Axiom.MathLib.Quaternion(pack.AgentData.BodyRotation.W, pack.AgentData.BodyRotation.X, pack.AgentData.BodyRotation.Y, pack.AgentData.BodyRotation.Z);
205 Axiom.MathLib.Vector3 direc = q * v3;
206 direc.Normalize();
207
208 //work out velocity for sim physics system
209 direc = direc * ((0.03f) * 128f);
210 newVelocity.X = direc.x;
211 newVelocity.Y = direc.y;
212 newVelocity.Z = direc.z;
213 this.forcesList.Add(newVelocity);
214 walking=true;
215 }
216 }
217 else
218 {
219 if(walking)
220 {
221 NewForce newVelocity = new NewForce();
222 newVelocity.X = 0;
223 newVelocity.Y = 0;
224 newVelocity.Z = 0;
225 this.forcesList.Add(newVelocity);
226 walking = false;
227 }
228 }
229 }
230
231 //should be moved somewhere else
232 public void SendRegionHandshake(World RegionInfo) {
233 ServerConsole.MainConsole.Instance.WriteLine("Avatar.cs:SendRegionHandshake() - Creating empty RegionHandshake packet");
234 System.Text.Encoding _enc = System.Text.Encoding.ASCII;
235 RegionHandshakePacket handshake = new RegionHandshakePacket();
236
237 ServerConsole.MainConsole.Instance.WriteLine("Avatar.cs:SendRegionhandshake() - Filling in RegionHandshake details");
238 handshake.RegionInfo.BillableFactor = 0;
239 handshake.RegionInfo.IsEstateManager = false;
240 handshake.RegionInfo.TerrainHeightRange00 = 60;
241 handshake.RegionInfo.TerrainHeightRange01 = 60;
242 handshake.RegionInfo.TerrainHeightRange10 = 60;
243 handshake.RegionInfo.TerrainHeightRange11 = 60;
244 handshake.RegionInfo.TerrainStartHeight00 = 10;
245 handshake.RegionInfo.TerrainStartHeight01 = 10;
246 handshake.RegionInfo.TerrainStartHeight10 = 10;
247 handshake.RegionInfo.TerrainStartHeight11 = 10;
248 handshake.RegionInfo.SimAccess = 13;
249 handshake.RegionInfo.WaterHeight = 5;
250 handshake.RegionInfo.RegionFlags = 72458694;
251 handshake.RegionInfo.SimName = _enc.GetBytes(OpenSim_Main.cfg.RegionName + "\0");
252 handshake.RegionInfo.SimOwner = new LLUUID("00000000-0000-0000-0000-000000000000");
253 handshake.RegionInfo.TerrainBase0 = new LLUUID("b8d3965a-ad78-bf43-699b-bff8eca6c975");
254 handshake.RegionInfo.TerrainBase1 = new LLUUID("abb783e6-3e93-26c0-248a-247666855da3");
255 handshake.RegionInfo.TerrainBase2 = new LLUUID("179cdabd-398a-9b6b-1391-4dc333ba321f");
256 handshake.RegionInfo.TerrainBase3 = new LLUUID("beb169c7-11ea-fff2-efe5-0f24dc881df2");
257 handshake.RegionInfo.TerrainDetail0 = new LLUUID("00000000-0000-0000-0000-000000000000");
258 handshake.RegionInfo.TerrainDetail1 = new LLUUID("00000000-0000-0000-0000-000000000000");
259 handshake.RegionInfo.TerrainDetail2 = new LLUUID("00000000-0000-0000-0000-000000000000");
260 handshake.RegionInfo.TerrainDetail3 = new LLUUID("00000000-0000-0000-0000-000000000000");
261 handshake.RegionInfo.CacheID = new LLUUID("545ec0a5-5751-1026-8a0b-216e38a7ab37");
262
263 ServerConsole.MainConsole.Instance.WriteLine("Avatar.cs:SendRegionHandshake() - Sending RegionHandshake packet");
264 this.ControllingClient.OutPacket(handshake);
265 }
266
267 public ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateTerseBlock()
268 {
269 byte[] bytes = new byte[60];
270 int i=0;
271 ImprovedTerseObjectUpdatePacket.ObjectDataBlock dat = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock();
272
273 dat.TextureEntry = AvatarTemplate.TextureEntry;
274 libsecondlife.LLVector3 pos2 = new LLVector3(this._physActor.Position.X, this._physActor.Position.Y, this._physActor.Position.Z);
275
276 uint ID = this.localid;
277
278 bytes[i++] = (byte)(ID % 256);
279 bytes[i++] = (byte)((ID >> 8) % 256);
280 bytes[i++] = (byte)((ID >> 16) % 256);
281 bytes[i++] = (byte)((ID >> 24) % 256);
282 bytes[i++] = 0;
283 bytes[i++] = 1;
284 i += 14;
285 bytes[i++] = 128;
286 bytes[i++] = 63;
287
288 byte[] pb = pos2.GetBytes();
289 Array.Copy(pb, 0, bytes, i, pb.Length);
290 i += 12;
291 ushort InternVelocityX;
292 ushort InternVelocityY;
293 ushort InternVelocityZ;
294
295 Axiom.MathLib.Vector3 internDirec = new Axiom.MathLib.Vector3(this._physActor.Velocity.X, this._physActor.Velocity.Y, this._physActor.Velocity.Z);
296 internDirec = internDirec /128.0f;
297 internDirec.x += 1;
298 internDirec.y += 1;
299 internDirec.z += 1;
300
301 InternVelocityX = (ushort)(32768 * internDirec.x);
302 InternVelocityY = (ushort)(32768 * internDirec.y);
303 InternVelocityZ = (ushort)(32768 * internDirec.z);
304
305 ushort ac = 32767;
306 bytes[i++] = (byte)(InternVelocityX % 256);
307 bytes[i++] = (byte)((InternVelocityX >> 8) % 256);
308 bytes[i++] = (byte)(InternVelocityY % 256);
309 bytes[i++] = (byte)((InternVelocityY>> 8) % 256);
310 bytes[i++] = (byte)(InternVelocityZ % 256);
311 bytes[i++] = (byte)((InternVelocityZ >> 8) % 256);
312
313 //accel
314 bytes[i++] = (byte)(ac % 256);
315 bytes[i++] = (byte)((ac >> 8) % 256);
316 bytes[i++] = (byte)(ac % 256);
317 bytes[i++] = (byte)((ac >> 8) % 256);
318 bytes[i++] = (byte)(ac % 256);
319 bytes[i++] = (byte)((ac >> 8) % 256);
320
321 //rot
322 bytes[i++] = (byte)(ac % 256);
323 bytes[i++] = (byte)((ac >> 8) % 256);
324 bytes[i++] = (byte)(ac % 256);
325 bytes[i++] = (byte)((ac >> 8) % 256);
326 bytes[i++] = (byte)(ac % 256);
327 bytes[i++] = (byte)((ac >> 8) % 256);
328 bytes[i++] = (byte)(ac % 256);
329 bytes[i++] = (byte)((ac >> 8) % 256);
330
331 //rotation vel
332 bytes[i++] = (byte)(ac % 256);
333 bytes[i++] = (byte)((ac >> 8) % 256);
334 bytes[i++] = (byte)(ac % 256);
335 bytes[i++] = (byte)((ac >> 8) % 256);
336 bytes[i++] = (byte)(ac % 256);
337 bytes[i++] = (byte)((ac >> 8) % 256);
338
339 dat.Data=bytes;
340 return(dat);
341 }
342 }
343
344 public class NewForce
345 {
346 public float X;
347 public float Y;
348 public float Z;
349
350 public NewForce()
351 {
352
353 }
354 }
355}