87 lines
2.2 KiB
C#
87 lines
2.2 KiB
C#
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<byte> _buf;
|
|
|
|
public PacketWriter(int capacity = 64)
|
|
{
|
|
_buf = new List<byte>(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();
|
|
}
|
|
}
|