175 lines
6.3 KiB
C#
175 lines
6.3 KiB
C#
using PSO2SERVER.Models;
|
|
using PSO2SERVER.Protocol.Packets;
|
|
using System;
|
|
using System.Runtime.InteropServices;
|
|
|
|
namespace PSO2SERVER.Protocol.Handlers
|
|
{
|
|
[PacketHandlerAttr(0x04, 0x07)]
|
|
public class MovementHandler : PacketHandler
|
|
{
|
|
#region implemented abstract members of PacketHandler
|
|
|
|
public override void HandlePacket(Client context, byte flags, byte[] data, uint position, uint size)
|
|
{
|
|
PacketReader reader = new PacketReader(data);
|
|
// This packet is "Compressed" basically.
|
|
reader.ReadBytes(6); // Get past the junk
|
|
// For simplicity's sake, read the 3 flag bytes into a big int
|
|
byte[] flagBytes = reader.ReadBytes(3);
|
|
uint dataFlags = flagBytes[0];
|
|
dataFlags |= (uint)(flagBytes[1] << 8);
|
|
dataFlags |= (uint)(flagBytes[2] << 16);
|
|
|
|
PackedData theFlags = (PackedData)dataFlags;
|
|
|
|
// Debug
|
|
//Logger.WriteInternal("[移动] Movement 数据包来自 {0} 包含 {1} 数据.", context.Character.Name, theFlags);
|
|
|
|
// TODO: Maybe do this better someday
|
|
MovementPacket.FullMovementData dstData = new MovementPacket.FullMovementData();
|
|
|
|
if (theFlags.HasFlag(PackedData.ENT1_ID))
|
|
{
|
|
dstData.entity1.ID = (uint)reader.ReadUInt64();
|
|
}
|
|
if (theFlags.HasFlag(PackedData.ENT1_TYPE))
|
|
{
|
|
dstData.entity1.ObjectType = (ObjectType)reader.ReadUInt16();
|
|
}
|
|
if (theFlags.HasFlag(PackedData.ENT1_A))
|
|
{
|
|
dstData.entity1.MapID = reader.ReadUInt16();
|
|
}
|
|
if (theFlags.HasFlag(PackedData.ENT2_ID))
|
|
{
|
|
dstData.entity1.ID = (uint)reader.ReadUInt64();
|
|
}
|
|
if (theFlags.HasFlag(PackedData.ENT2_TYPE))
|
|
{
|
|
dstData.entity1.ObjectType = (ObjectType)reader.ReadUInt16();
|
|
}
|
|
if (theFlags.HasFlag(PackedData.ENT2_A))
|
|
{
|
|
dstData.entity1.MapID = reader.ReadUInt16();
|
|
}
|
|
if (theFlags.HasFlag(PackedData.TIMESTAMP))
|
|
{
|
|
dstData.timestamp = reader.ReadUInt32();
|
|
context.MovementTimestamp = dstData.timestamp;
|
|
}
|
|
if (theFlags.HasFlag(PackedData.ROT_X))
|
|
{
|
|
dstData.rotation.x = reader.ReadUInt16();
|
|
context.CurrentLocation.RotX = Helper.FloatFromHalfPrecision(dstData.rotation.x);
|
|
}
|
|
if (theFlags.HasFlag(PackedData.ROT_Y))
|
|
{
|
|
dstData.rotation.y = reader.ReadUInt16();
|
|
context.CurrentLocation.RotY = Helper.FloatFromHalfPrecision(dstData.rotation.y);
|
|
}
|
|
if (theFlags.HasFlag(PackedData.ROT_Z))
|
|
{
|
|
dstData.rotation.z = reader.ReadUInt16();
|
|
context.CurrentLocation.RotZ = Helper.FloatFromHalfPrecision(dstData.rotation.z);
|
|
}
|
|
if (theFlags.HasFlag(PackedData.ROT_W))
|
|
{
|
|
dstData.rotation.w = reader.ReadUInt16();
|
|
context.CurrentLocation.RotW = Helper.FloatFromHalfPrecision(dstData.rotation.w);
|
|
}
|
|
if (theFlags.HasFlag(PackedData.CUR_X))
|
|
{
|
|
dstData.currentPos.x = reader.ReadUInt16();
|
|
context.CurrentLocation.PosX = Helper.FloatFromHalfPrecision(dstData.currentPos.x);
|
|
}
|
|
if (theFlags.HasFlag(PackedData.CUR_Y))
|
|
{
|
|
dstData.currentPos.y = reader.ReadUInt16();
|
|
context.CurrentLocation.PosY = Helper.FloatFromHalfPrecision(dstData.currentPos.y);
|
|
}
|
|
if (theFlags.HasFlag(PackedData.CUR_Z))
|
|
{
|
|
dstData.currentPos.z = reader.ReadUInt16();
|
|
context.CurrentLocation.PosZ = Helper.FloatFromHalfPrecision(dstData.currentPos.z);
|
|
}
|
|
if (theFlags.HasFlag(PackedData.UNKNOWN4))
|
|
{
|
|
dstData.Unknown2 = reader.ReadUInt16();
|
|
}
|
|
if (theFlags.HasFlag(PackedData.UNK_X))
|
|
{
|
|
dstData.unknownPos.x = reader.ReadUInt16();
|
|
context.LastLocation.PosX = Helper.FloatFromHalfPrecision(dstData.unknownPos.x);
|
|
}
|
|
if (theFlags.HasFlag(PackedData.UNK_Y))
|
|
{
|
|
dstData.unknownPos.y = reader.ReadUInt16();
|
|
context.LastLocation.PosY = Helper.FloatFromHalfPrecision(dstData.unknownPos.y);
|
|
}
|
|
if (theFlags.HasFlag(PackedData.UNK_Z))
|
|
{
|
|
dstData.unknownPos.z = reader.ReadUInt16();
|
|
context.LastLocation.PosZ = Helper.FloatFromHalfPrecision(dstData.unknownPos.z);
|
|
}
|
|
if (theFlags.HasFlag(PackedData.UNKNOWN5))
|
|
{
|
|
dstData.Unknown3 = reader.ReadUInt16();
|
|
}
|
|
if (theFlags.HasFlag(PackedData.UNKNOWN6))
|
|
{
|
|
if (theFlags.HasFlag(PackedData.UNKNOWN7))
|
|
{
|
|
dstData.Unknown4 = reader.ReadByte();
|
|
}
|
|
else
|
|
{
|
|
dstData.Unknown4 = reader.ReadUInt32();
|
|
}
|
|
}
|
|
|
|
|
|
//Logger.WriteInternal("[移动] 玩家 {0} 移动中 (坐标: X{1}, Y{2}, Z{3})", context.Character.Name, context.CurrentLocation.PosX,
|
|
//context.CurrentLocation.PosY, context.CurrentLocation.PosZ);
|
|
|
|
foreach (var c in Server.Instance.Clients)
|
|
{
|
|
if (c.Character == null || c == context || c.CurrentZone != context.CurrentZone)
|
|
continue;
|
|
|
|
//c.SendPacket(0x04, 0x07, flags, data);
|
|
c.SendPacket(new MovementPacket(dstData));
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
|
|
[Flags]
|
|
public enum PackedData : Int32
|
|
{
|
|
ENT1_ID = 1,
|
|
ENT1_TYPE = 2,
|
|
ENT1_A = 4,
|
|
ENT2_ID = 8,
|
|
ENT2_TYPE = 0x10,
|
|
ENT2_A = 0x20,
|
|
TIMESTAMP = 0x40,
|
|
ROT_X = 0x80,
|
|
ROT_Y = 0x100,
|
|
ROT_Z = 0x200,
|
|
ROT_W = 0x400,
|
|
CUR_X = 0x800,
|
|
CUR_Y = 0x1000,
|
|
CUR_Z = 0x2000,
|
|
UNKNOWN4 = 0x4000,
|
|
UNK_X = 0x8000,
|
|
UNK_Y = 0x10000,
|
|
UNK_Z = 0x20000,
|
|
UNKNOWN5 = 0x40000,
|
|
UNKNOWN6 = 0x80000,
|
|
UNKNOWN7 = 0x100000
|
|
}
|
|
|
|
|
|
} |