using System; using System.Collections.Generic; using System.Text; namespace XWorld.Framework.Protocol { // 手写小端二进制写入器:varint(LEB128) + zigzag,无反射,AOT/WASM 友好 public sealed class PacketWriter { private readonly List _buf; public PacketWriter(int capacity = 64) { _buf = new List(capacity); } public void WriteByte(byte v) => _buf.Add(v); public void WriteBool(bool v) => _buf.Add(v ? (byte)1 : (byte)0); public void WriteUInt16(ushort v) { _buf.Add((byte)(v & 0xFF)); _buf.Add((byte)((v >> 8) & 0xFF)); } public void WriteVarUInt(uint v) { while (v >= 0x80) { _buf.Add((byte)(v | 0x80)); v >>= 7; } _buf.Add((byte)v); } public void WriteVarInt(int v) { uint zig = (uint)((v << 1) ^ (v >> 31)); // zigzag WriteVarUInt(zig); } public void WriteVarLong(long v) { ulong zig = (ulong)((v << 1) ^ (v >> 63)); while (zig >= 0x80) { _buf.Add((byte)(zig | 0x80)); zig >>= 7; } _buf.Add((byte)zig); } public void WriteSingle(float v) { byte[] b = BitConverter.GetBytes(v); if (!BitConverter.IsLittleEndian) Array.Reverse(b); _buf.Add(b[0]); _buf.Add(b[1]); _buf.Add(b[2]); _buf.Add(b[3]); } public void WriteBytes(byte[] data) { if (data == null || data.Length == 0) { WriteVarUInt(0); return; } WriteVarUInt((uint)data.Length); _buf.AddRange(data); } public void WriteString(string s) { if (string.IsNullOrEmpty(s)) { WriteVarUInt(0); return; } byte[] b = Encoding.UTF8.GetBytes(s); WriteVarUInt((uint)b.Length); _buf.AddRange(b); } public byte[] ToArray() => _buf.ToArray(); } }