using PSO2SERVER.Models; using PSO2SERVER.Zone; using System; using System.Collections.Generic; using System.IO; using System.Runtime.InteropServices; using System.Runtime.Remoting.Messaging; using System.Text; namespace PSO2SERVER.Protocol { public class PacketReader : BinaryReader { private byte[] _data; // 存储数据的字节数组 private int _position; // 当前读取位置 private int _size; // 数据的总大小 public int Position => _position; public PacketReader(Stream s) : base(s) { } public PacketReader(byte[] bytes) : base(new MemoryStream(bytes)) { } public PacketReader(byte[] bytes, uint position, uint size) : base(new MemoryStream(bytes, (int) position, (int) size)) { _data = bytes; _position = 0; _size = (int)(size); } public uint ReadMagic(uint xor, uint sub) { return (ReadUInt32() ^ xor) - sub; } public string ReadAscii(uint xor, uint sub) { var magic = ReadMagic(xor, sub); if (magic == 0) { return string.Empty; } var charCount = magic - 1; var padding = 4 - (charCount & 3); //Logger.Write("charCount = " + charCount + " padding = " + padding); var data = ReadBytes((int) charCount); for (var i = 0; i < padding; i++) ReadByte(); return Encoding.ASCII.GetString(data); } public string ReadFixedLengthAscii(uint charCount) { var data = ReadBytes((int) charCount); var str = Encoding.ASCII.GetString(data); var endAt = str.IndexOf('\0'); if (endAt == -1) return str; return str.Substring(0, endAt); } public string ReadUtf16(uint xor, uint sub) { var magic = ReadMagic(xor, sub); if (magic == 0) { return ""; } var charCount = magic - 1; var padding = (magic & 1); var data = ReadBytes((int) (charCount*2)); ReadUInt16(); if (padding != 0) ReadUInt16(); return Encoding.GetEncoding("UTF-16").GetString(data); } public string ReadFixedLengthUtf16(int charCount) { var data = ReadBytes(charCount*2); var str = Encoding.GetEncoding("UTF-16").GetString(data); var endAt = str.IndexOf('\0'); if (endAt == -1) return str; return str.Substring(0, endAt); } public T ReadStruct() where T : struct { var structBytes = new byte[Marshal.SizeOf(typeof (T))]; Read(structBytes, 0, structBytes.Length); return Helper.ByteArrayToStructure(structBytes); } public ObjectHeader ReadObjectHeader() { ObjectHeader obj = new ObjectHeader { ID = ReadUInt32(), Padding = ReadUInt32(), ObjectType = (ObjectType)ReadUInt16(), MapID = ReadUInt16(), }; return obj; } public List ReadList() where T : struct { var count = ReadUInt32(); var list = new List(); for (int i = 0; i < count; i++) { list.Add(ReadStruct()); } return list; } public string ReadNullableString(uint xor, uint sub) { var magic = ReadMagic(xor, sub); if (magic == 0) { return null; } var charCount = magic - 1; var data = ReadBytes((int)charCount); return data?.Length > 0 ? Encoding.ASCII.GetString(data) : null; } public PSOLocation ReadEntityPosition() { PSOLocation pos = new PSOLocation() { RotX = Helper.FloatFromHalfPrecision(ReadUInt16()), RotY = Helper.FloatFromHalfPrecision(ReadUInt16()), RotZ = Helper.FloatFromHalfPrecision(ReadUInt16()), RotW = Helper.FloatFromHalfPrecision(ReadUInt16()), PosX = Helper.FloatFromHalfPrecision(ReadUInt16()), PosY = Helper.FloatFromHalfPrecision(ReadUInt16()), PosZ = Helper.FloatFromHalfPrecision(ReadUInt16()), }; return pos; } // 读取 Half 类型(16 位浮动点数) public Half ReadHalf() { // 读取 2 个字节 byte[] bytes = ReadBytes(2); // 使用 System.Half 来转换字节为 Half 类型 if (bytes.Length < 2) { throw new EndOfStreamException("Not enough data to read Half value."); } // 返回 Half 类型 return BitConverter.ToUInt16(bytes, 0).ToHalf(); } } // Extension method to convert UInt16 to Half public static class HalfExtensions { public static Half ToHalf(this ushort value) { return new Half(value); } } }