diff --git a/Programs/Simian/Extensions/Chat.cs b/Programs/Simian/Extensions/Chat.cs new file mode 100644 index 00000000..f44fbc8b --- /dev/null +++ b/Programs/Simian/Extensions/Chat.cs @@ -0,0 +1,54 @@ +using OpenMetaverse; +using OpenMetaverse.Packets; +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading; + +namespace Simian.Extensions +{ + public class Chat : ISimianExtension + { + Simian Server; + + public Chat(Simian server) + { + Server = server; + } + + public void Start() + { + Server.UDPServer.RegisterPacketCallback(PacketType.ChatFromViewer, new UDPServer.PacketCallback(ChatFromViewerHandler)); + } + + public void Stop() + { + } + + void ChatFromViewerHandler(Packet packet, Agent agent) + { + ChatFromViewerPacket viewerChat = (ChatFromViewerPacket)packet; + + if (viewerChat.ChatData.Channel != 0) return; //not public chat + + //TODO: add distance constraints to AudibleLevel and Message + + ChatFromSimulatorPacket chat = new ChatFromSimulatorPacket(); + chat.ChatData.Audible = (byte)ChatAudibleLevel.Fully; + chat.ChatData.ChatType = viewerChat.ChatData.Type; + chat.ChatData.OwnerID = agent.ID; + chat.ChatData.SourceID = agent.ID; + chat.ChatData.SourceType = (byte)ChatSourceType.Agent; + chat.ChatData.Position = agent.Avatar.Position; + chat.ChatData.FromName = Utils.StringToBytes(agent.Avatar.Name); + chat.ChatData.Message = viewerChat.ChatData.Message; + + lock (Server.Agents) + { + foreach(Agent recipient in Server.Agents.Values) + recipient.SendPacket(chat); + } + } + + } +} diff --git a/Programs/Simian/Extensions/CoarseLocationUpdates.cs b/Programs/Simian/Extensions/CoarseLocationUpdates.cs new file mode 100644 index 00000000..4439fb04 --- /dev/null +++ b/Programs/Simian/Extensions/CoarseLocationUpdates.cs @@ -0,0 +1,66 @@ +using OpenMetaverse; +using OpenMetaverse.Packets; +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading; + +namespace Simian.Extensions +{ + public class CoarseLocationUpdates : ISimianExtension + { + Simian Server; + Timer CoarseLocationTimer; + + public CoarseLocationUpdates(Simian server) + { + Server = server; + } + + public void Start() + { + if (CoarseLocationTimer != null) CoarseLocationTimer = null; + CoarseLocationTimer = new Timer(new TimerCallback(CoarseLocationTimer_Elapsed)); + CoarseLocationTimer.Change(1000, 1000); + } + + public void Stop() + { + CoarseLocationTimer = null; + } + + void CoarseLocationTimer_Elapsed(object sender) + { + lock (Server.Agents) + { + List avatarPositions = new List(); + + CoarseLocationUpdatePacket update = new CoarseLocationUpdatePacket(); + update.AgentData = new CoarseLocationUpdatePacket.AgentDataBlock[Server.Agents.Count]; + update.Location = new CoarseLocationUpdatePacket.LocationBlock[Server.Agents.Count]; + + short i = 0; + foreach (Agent agent in Server.Agents.Values) + { + update.AgentData[i] = new CoarseLocationUpdatePacket.AgentDataBlock(); + update.AgentData[i].AgentID = agent.AgentID; + update.Location[i] = new CoarseLocationUpdatePacket.LocationBlock(); + update.Location[i].X = (byte)((int)agent.Avatar.Position.X); + update.Location[i].Y = (byte)((int)agent.Avatar.Position.Y); + update.Location[i].Z = (byte)((int)agent.Avatar.Position.Z / 4); + update.Index.Prey = -1; + i++; + } + + i = 0; + foreach (Agent recipient in Server.Agents.Values) + { + update.Index.You = i; + recipient.SendPacket(update); + i++; + } + + } + } + } +} diff --git a/Programs/Simian/Extensions/Movement.cs b/Programs/Simian/Extensions/Movement.cs new file mode 100644 index 00000000..d541670a --- /dev/null +++ b/Programs/Simian/Extensions/Movement.cs @@ -0,0 +1,95 @@ +using OpenMetaverse; +using OpenMetaverse.Packets; +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading; + +namespace Simian.Extensions +{ + public class Movement : ISimianExtension + { + Simian Server; + Timer UpdateTimer; + const float SQRT_TWO = 1.41421356f; + + public Movement(Simian server) + { + Server = server; + } + + public void Start() + { + Server.UDPServer.RegisterPacketCallback(PacketType.AgentUpdate, new UDPServer.PacketCallback(AgentUpdateHandler)); + if (UpdateTimer != null) UpdateTimer = null; + UpdateTimer = new Timer(new TimerCallback(UpdateTimer_Elapsed)); + UpdateTimer.Change(100, 100); + } + + public void Stop() + { + UpdateTimer = null; + } + + void UpdateTimer_Elapsed(object sender) + { + lock (Server.Agents) + { + foreach (Agent agent in Server.Agents.Values) + { + agent.Avatar.Velocity.X = 0f; + + Vector3 fwd = Vector3.Transform(Vector3.UnitX, Matrix4.CreateFromQuaternion(agent.Avatar.Rotation)); + Vector3 left = Vector3.Transform(Vector3.UnitY, Matrix4.CreateFromQuaternion(agent.Avatar.Rotation)); + + bool heldForward = (agent.ControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_AT_POS; + bool heldBack = (agent.ControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG; + bool heldLeft = (agent.ControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS; + bool heldRight = (agent.ControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG; + + float speed = 0.5f; + if ((heldForward || heldBack) && (heldLeft || heldRight)) + speed *= SQRT_TWO; + + if (heldForward) + { + agent.Avatar.Position.X += fwd.X * speed; + agent.Avatar.Position.Y += fwd.Y * speed; + agent.Avatar.Velocity.X += fwd.X * speed; + agent.Avatar.Velocity.Y += fwd.Y * speed; + } + if (heldBack) + { + agent.Avatar.Position.X -= fwd.X * speed; + agent.Avatar.Position.Y -= fwd.Y * speed; + agent.Avatar.Velocity.X -= fwd.X * speed; + agent.Avatar.Velocity.Y -= fwd.Y * speed; + } + if (heldLeft) + { + agent.Avatar.Position.X += left.X * speed; + agent.Avatar.Position.Y += left.Y * speed; + agent.Avatar.Velocity.X += left.X * speed; + agent.Avatar.Velocity.Y += left.Y * speed; + } + if (heldRight) + { + agent.Avatar.Position.X -= left.X * speed; + agent.Avatar.Position.Y -= left.Y * speed; + agent.Avatar.Velocity.X -= left.X * speed; + agent.Avatar.Velocity.Y -= left.Y * speed; + } + } + } + } + + void AgentUpdateHandler(Packet packet, Agent agent) + { + AgentUpdatePacket update = (AgentUpdatePacket)packet; + + agent.Avatar.Rotation = update.AgentData.BodyRotation; + agent.ControlFlags = (AgentManager.ControlFlags)update.AgentData.ControlFlags; + } + + } +} diff --git a/Programs/Simian/Extensions/SceneManager.cs b/Programs/Simian/Extensions/SceneManager.cs index 23b23bc3..9047d045 100644 --- a/Programs/Simian/Extensions/SceneManager.cs +++ b/Programs/Simian/Extensions/SceneManager.cs @@ -82,6 +82,18 @@ namespace Simian void SendFullUpdate(Agent agent, LLObject obj, byte state, uint flags) { + byte[] objectData = new byte[60]; + int pos = 0; + agent.Avatar.Position.GetBytes().CopyTo(objectData, pos); + pos += 12; + agent.Avatar.Velocity.GetBytes().CopyTo(objectData, pos); + pos += 12; + agent.Avatar.Acceleration.GetBytes().CopyTo(objectData, pos); + pos += 12; + agent.Avatar.Rotation.GetBytes().CopyTo(objectData, pos); + pos += 12; + agent.Avatar.AngularVelocity.GetBytes().CopyTo(objectData, pos); + ObjectUpdatePacket update = new ObjectUpdatePacket(); update.RegionData.RegionHandle = regionHandle; update.RegionData.TimeDilation = Helpers.FloatToByte(1f, 0f, 1f); @@ -100,7 +112,7 @@ namespace Simian update.ObjectData[0].Material = (byte)3; update.ObjectData[0].MediaURL = new byte[0]; update.ObjectData[0].NameValue = new byte[0]; - update.ObjectData[0].ObjectData = new byte[60]; + update.ObjectData[0].ObjectData = objectData; update.ObjectData[0].OwnerID = UUID.Zero; update.ObjectData[0].ParentID = 0; update.ObjectData[0].PathBegin = 0;