using PSO2SERVER.Models; using System; using System.IO; using System.Runtime.InteropServices; using System.Text; namespace PSO2SERVER.Packets { 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 = (int)position; _size = (int)size; } public uint ReadMagic(uint xor, uint sub) { return (ReadUInt32() ^ xor) - sub; } // 示例方法:读取 ASCII 字符串 public string ReadAsciiForPosition(int start, int length) { // 检查读取位置是否有效 if (_position + length > _size) { throw new ArgumentOutOfRangeException("读取超出数据边界"); } // 读取数据并更新当前位置 var result = Encoding.ASCII.GetString(_data, _position, length); _position += length; // 更新当前位置 return result; } public string ReadAscii(uint xor, uint sub) { var magic = ReadMagic(xor, sub); if (magic == 0) { return ""; } 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 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; } } }