OpenSimMirror/OpenSim.RegionServer/world/AvatarUpdate.cs

332 lines
15 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
using System.Text;
using libsecondlife;
using libsecondlife.Packets;
namespace OpenSim.world
{
partial class Avatar
{
public override void update()
{
if (this._physActor == null)
{
//HACKHACK: Note to work out why this entity does not have a physics actor
// and prehaps create one.
return;
}
libsecondlife.LLVector3 pos2 = new LLVector3(this._physActor.Position.X, this._physActor.Position.Y, this._physActor.Position.Z);
if (this.updateflag)
{
//need to send movement info
//so create the improvedterseobjectupdate packet
//use CreateTerseBlock()
ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock = CreateTerseBlock();
ImprovedTerseObjectUpdatePacket terse = new ImprovedTerseObjectUpdatePacket();
terse.RegionData.RegionHandle = m_regionHandle; // FIXME
terse.RegionData.TimeDilation = 64096;
terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1];
terse.ObjectData[0] = terseBlock;
foreach (SimClient client in m_clientThreads.Values)
{
client.OutPacket(terse);
}
updateflag = false;
//this._updateCount = 0;
}
else
{
if ((pos2 != this.positionLastFrame) || (this.movementflag == 16))
{
_updateCount++;
if (((!PhysicsEngineFlying) && (_updateCount > 3)) || (PhysicsEngineFlying) && (_updateCount > 0))
{
//It has been a while since last update was sent so lets send one.
ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock = CreateTerseBlock();
ImprovedTerseObjectUpdatePacket terse = new ImprovedTerseObjectUpdatePacket();
terse.RegionData.RegionHandle = m_regionHandle; // FIXME
terse.RegionData.TimeDilation = 64096;
terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1];
terse.ObjectData[0] = terseBlock;
foreach (SimClient client in m_clientThreads.Values)
{
client.OutPacket(terse);
}
_updateCount = 0;
}
if (this.movementflag == 16)
{
movementflag = 0;
}
}
}
this.positionLastFrame = pos2;
if (!this.ControllingClient.m_sandboxMode)
{
if (pos2.X < 0)
{
ControllingClient.CrossSimBorder(new LLVector3(this._physActor.Position.X, this._physActor.Position.Y, this._physActor.Position.Z));
}
if (pos2.Y < 0)
{
ControllingClient.CrossSimBorder(new LLVector3(this._physActor.Position.X, this._physActor.Position.Y, this._physActor.Position.Z));
}
if (pos2.X > 255)
{
ControllingClient.CrossSimBorder(new LLVector3(this._physActor.Position.X, this._physActor.Position.Y, this._physActor.Position.Z));
}
if (pos2.Y > 255)
{
ControllingClient.CrossSimBorder(new LLVector3(this._physActor.Position.X, this._physActor.Position.Y, this._physActor.Position.Z));
}
}
}
public ObjectUpdatePacket CreateUpdatePacket()
{
System.Text.Encoding _enc = System.Text.Encoding.ASCII;
//send a objectupdate packet with information about the clients avatar
ObjectUpdatePacket objupdate = new ObjectUpdatePacket();
objupdate.RegionData.RegionHandle = m_regionHandle;
objupdate.RegionData.TimeDilation = 64096;
objupdate.ObjectData = new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock[1];
objupdate.ObjectData[0] = AvatarTemplate;
//give this avatar object a local id and assign the user a name
objupdate.ObjectData[0].ID = this.localid;
objupdate.ObjectData[0].FullID = ControllingClient.AgentID;
objupdate.ObjectData[0].NameValue = _enc.GetBytes("FirstName STRING RW SV " + firstname + "\nLastName STRING RW SV " + lastname + " \0");
libsecondlife.LLVector3 pos2 = new LLVector3((float)this._physActor.Position.X, (float)this._physActor.Position.Y, (float)this._physActor.Position.Z);
byte[] pb = pos2.GetBytes();
Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 16, pb.Length);
return objupdate;
}
public void SendInitialPosition()
{
System.Text.Encoding _enc = System.Text.Encoding.ASCII;
//send a objectupdate packet with information about the clients avatar
ObjectUpdatePacket objupdate = new ObjectUpdatePacket();
objupdate.RegionData.RegionHandle = m_regionHandle;
objupdate.RegionData.TimeDilation = 64096;
objupdate.ObjectData = new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock[1];
objupdate.ObjectData[0] = AvatarTemplate;
//give this avatar object a local id and assign the user a name
objupdate.ObjectData[0].ID = this.localid;
this.uuid = objupdate.ObjectData[0].FullID = ControllingClient.AgentID;
objupdate.ObjectData[0].NameValue = _enc.GetBytes("FirstName STRING RW SV " + firstname + "\nLastName STRING RW SV " + lastname + " \0");
libsecondlife.LLVector3 pos2 = new LLVector3((float)this.Pos.X, (float)this.Pos.Y, (float)this.Pos.Z);
byte[] pb = pos2.GetBytes();
Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 16, pb.Length);
m_world._localNumber++;
foreach (SimClient client in m_clientThreads.Values)
{
client.OutPacket(objupdate);
if (client.AgentID != ControllingClient.AgentID)
{
2007-04-10 10:45:46 +00:00
//the below line is already in Simclient.cs at line number 245 , directly below the call to this method
//if there is a problem/bug with that , then lets fix it there rather than duplicating it here
//client.ClientAvatar.SendAppearanceToOtherAgent(this.ControllingClient);
SendAppearanceToOtherAgent(client);
}
}
}
public void SendInitialAppearance()
{
AgentWearablesUpdatePacket aw = new AgentWearablesUpdatePacket();
aw.AgentData.AgentID = this.ControllingClient.AgentID;
aw.AgentData.SerialNum = 0;
aw.AgentData.SessionID = ControllingClient.SessionID;
aw.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[13];
AgentWearablesUpdatePacket.WearableDataBlock awb;
for (int i = 0; i < 13; i++)
{
awb = new AgentWearablesUpdatePacket.WearableDataBlock();
awb.WearableType = (byte)i;
awb.AssetID = this.Wearables[i].AssetID;
awb.ItemID = this.Wearables[i].ItemID;
aw.WearableData[i] = awb;
}
ControllingClient.OutPacket(aw);
}
public void SendAppearanceToOtherAgent(SimClient userInfo)
{
AvatarAppearancePacket avp = new AvatarAppearancePacket();
avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[218];
avp.ObjectData.TextureEntry = this.avatarAppearanceTexture.ToBytes();
2007-04-10 10:45:46 +00:00
//a wearable update packets should only be sent about the viewers/agents own avatar not for other avatars
//but it seems that the following code only created the packets and never actually sent them anyway
/*AgentWearablesUpdatePacket aw = new AgentWearablesUpdatePacket();
aw.AgentData.AgentID = this.ControllingClient.AgentID;
2007-04-10 10:45:46 +00:00
aw.AgentData.SessionID = userInfo.SessionID;
aw.AgentData.SerialNum = 0; //removed the use of a random number as a random number could be less than the last number, should have a counter variable for this
aw.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[13];
AgentWearablesUpdatePacket.WearableDataBlock awb;
for (int i = 0; i < 13; i++)
{
awb = new AgentWearablesUpdatePacket.WearableDataBlock();
awb.WearableType = (byte)i;
awb.AssetID = this.Wearables[i].AssetID;
awb.ItemID = this.Wearables[i].ItemID;
aw.WearableData[i] = awb;
2007-04-10 10:45:46 +00:00
}*/
AvatarAppearancePacket.VisualParamBlock avblock = null;
for (int i = 0; i < 218; i++)
{
avblock = new AvatarAppearancePacket.VisualParamBlock();
avblock.ParamValue = visualParams[i];
avp.VisualParam[i] = avblock;
}
avp.Sender.IsTrial = false;
avp.Sender.ID = ControllingClient.AgentID;
userInfo.OutPacket(avp);
}
public void SetAppearance(AgentSetAppearancePacket appear)
{
LLObject.TextureEntry tex = new LLObject.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length);
this.avatarAppearanceTexture = tex;
for (int i = 0; i < appear.VisualParam.Length; i++)
{
this.visualParams[i] = appear.VisualParam[i].ParamValue;
}
foreach (SimClient client in m_clientThreads.Values)
{
if (client.AgentID != ControllingClient.AgentID)
{
SendAppearanceToOtherAgent(client);
}
}
}
public ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateTerseBlock()
{
byte[] bytes = new byte[60];
int i = 0;
ImprovedTerseObjectUpdatePacket.ObjectDataBlock dat = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock();
dat.TextureEntry = new byte[0];// AvatarTemplate.TextureEntry;
libsecondlife.LLVector3 pos2 = new LLVector3(0, 0, 0);
lock (m_world.LockPhysicsEngine)
{
pos2 = new LLVector3(this._physActor.Position.X, this._physActor.Position.Y, this._physActor.Position.Z);
}
uint ID = this.localid;
bytes[i++] = (byte)(ID % 256);
bytes[i++] = (byte)((ID >> 8) % 256);
bytes[i++] = (byte)((ID >> 16) % 256);
bytes[i++] = (byte)((ID >> 24) % 256);
bytes[i++] = 0;
bytes[i++] = 1;
i += 14;
bytes[i++] = 128;
bytes[i++] = 63;
byte[] pb = pos2.GetBytes();
Array.Copy(pb, 0, bytes, i, pb.Length);
i += 12;
ushort InternVelocityX;
ushort InternVelocityY;
ushort InternVelocityZ;
Axiom.MathLib.Vector3 internDirec = new Axiom.MathLib.Vector3(0, 0, 0);
lock (m_world.LockPhysicsEngine)
{
internDirec = new Axiom.MathLib.Vector3(this._physActor.Velocity.X, this._physActor.Velocity.Y, this._physActor.Velocity.Z);
}
internDirec = internDirec / 128.0f;
internDirec.x += 1;
internDirec.y += 1;
internDirec.z += 1;
InternVelocityX = (ushort)(32768 * internDirec.x);
InternVelocityY = (ushort)(32768 * internDirec.y);
InternVelocityZ = (ushort)(32768 * internDirec.z);
ushort ac = 32767;
bytes[i++] = (byte)(InternVelocityX % 256);
bytes[i++] = (byte)((InternVelocityX >> 8) % 256);
bytes[i++] = (byte)(InternVelocityY % 256);
bytes[i++] = (byte)((InternVelocityY >> 8) % 256);
bytes[i++] = (byte)(InternVelocityZ % 256);
bytes[i++] = (byte)((InternVelocityZ >> 8) % 256);
//accel
bytes[i++] = (byte)(ac % 256);
bytes[i++] = (byte)((ac >> 8) % 256);
bytes[i++] = (byte)(ac % 256);
bytes[i++] = (byte)((ac >> 8) % 256);
bytes[i++] = (byte)(ac % 256);
bytes[i++] = (byte)((ac >> 8) % 256);
//rot
bytes[i++] = (byte)(ac % 256);
bytes[i++] = (byte)((ac >> 8) % 256);
bytes[i++] = (byte)(ac % 256);
bytes[i++] = (byte)((ac >> 8) % 256);
bytes[i++] = (byte)(ac % 256);
bytes[i++] = (byte)((ac >> 8) % 256);
bytes[i++] = (byte)(ac % 256);
bytes[i++] = (byte)((ac >> 8) % 256);
//rotation vel
bytes[i++] = (byte)(ac % 256);
bytes[i++] = (byte)((ac >> 8) % 256);
bytes[i++] = (byte)(ac % 256);
bytes[i++] = (byte)((ac >> 8) % 256);
bytes[i++] = (byte)(ac % 256);
bytes[i++] = (byte)((ac >> 8) % 256);
dat.Data = bytes;
return (dat);
}
// Sends animation update
public void SendAnimPack()
{
AvatarAnimationPacket ani = new AvatarAnimationPacket();
ani.AnimationSourceList = new AvatarAnimationPacket.AnimationSourceListBlock[1];
ani.AnimationSourceList[0] = new AvatarAnimationPacket.AnimationSourceListBlock();
ani.AnimationSourceList[0].ObjectID = ControllingClient.AgentID;
ani.Sender = new AvatarAnimationPacket.SenderBlock();
ani.Sender.ID = ControllingClient.AgentID;
ani.AnimationList = new AvatarAnimationPacket.AnimationListBlock[1];
ani.AnimationList[0] = new AvatarAnimationPacket.AnimationListBlock();
ani.AnimationList[0].AnimID = this.current_anim;
ani.AnimationList[0].AnimSequenceID = this.anim_seq;
//ControllingClient.OutPacket(ani);
foreach (SimClient client in m_clientThreads.Values)
{
client.OutPacket(ani);
}
}
}
}