Files
LuaCsForBarotraumaEP/Barotrauma/BarotraumaShared/SharedSource/Networking/Primitives/Message/Message.cs
2024-03-28 18:34:33 +02:00

1034 lines
32 KiB
C#

using Lidgren.Network;
using System;
using System.IO;
using System.IO.Compression;
using System.Runtime.InteropServices;
using System.Text;
using Microsoft.Xna.Framework;
namespace Barotrauma.Networking
{
public static class MsgConstants
{
// MTU currently set to the upper limit of what EOS P2P can do
// TODO: determine dynamically so other protocols can use a larger MTU,
// as well as handle a client with a lower MTU set outside of our control
public const int MTU = 1170;
public const int CompressionThreshold = 1000;
public const int InitialBufferSize = 256;
public const int BufferOverAllocateAmount = 4;
}
/// <summary>
/// Utility struct for writing Singles
/// </summary>
[StructLayout(LayoutKind.Explicit)]
public struct SingleUIntUnion
{
/// <summary>
/// Value as a 32 bit float
/// </summary>
[FieldOffset(0)]
public float SingleValue;
/// <summary>
/// Value as an unsigned 32 bit integer
/// </summary>
[FieldOffset(0)]
public uint UIntValue;
}
internal static class MsgWriter
{
internal static void UpdateBitLength(ref int bitLength, int bitPos)
{
bitLength = Math.Max(bitLength, bitPos);
}
internal static void WriteBoolean(ref byte[] buf, ref int bitPos, ref int bitLength, bool val)
{
#if DEBUG
int resetPos = bitPos;
#endif
EnsureBufferSize(ref buf, bitPos + 1);
int bytePos = bitPos / 8;
int bitOffset = bitPos % 8;
byte bitFlag = (byte)(1 << bitOffset);
byte bitMask = (byte)((~bitFlag) & 0xff);
buf[bytePos] &= bitMask;
if (val) buf[bytePos] |= bitFlag;
bitPos++;
UpdateBitLength(ref bitLength, bitPos);
#if DEBUG
bool testVal = MsgReader.ReadBoolean(buf, ref resetPos);
if (testVal != val || resetPos != bitPos)
{
DebugConsole.ThrowError($"Boolean written incorrectly! {testVal}, {val}; {resetPos}, {bitPos}");
}
#endif
}
internal static void WritePadBits(ref byte[] buf, ref int bitPos, ref int bitLength)
{
int bitOffset = bitPos % 8;
bitPos += ((8 - bitOffset) % 8);
UpdateBitLength(ref bitLength, bitPos);
EnsureBufferSize(ref buf, bitPos);
}
internal static void WriteByte(ref byte[] buf, ref int bitPos, ref int bitLength, byte val)
{
EnsureBufferSize(ref buf, bitPos + 8);
NetBitWriter.WriteByte(val, 8, buf, bitPos);
bitPos += 8;
UpdateBitLength(ref bitLength, bitPos);
}
internal static void WriteUInt16(ref byte[] buf, ref int bitPos, ref int bitLength, UInt16 val)
{
EnsureBufferSize(ref buf, bitPos + 16);
NetBitWriter.WriteUInt16(val, 16, buf, bitPos);
bitPos += 16;
UpdateBitLength(ref bitLength, bitPos);
}
internal static void WriteInt16(ref byte[] buf, ref int bitPos, ref int bitLength, Int16 val)
{
EnsureBufferSize(ref buf, bitPos + 16);
NetBitWriter.WriteUInt16((UInt16)val, 16, buf, bitPos);
bitPos += 16;
UpdateBitLength(ref bitLength, bitPos);
}
internal static void WriteUInt32(ref byte[] buf, ref int bitPos, ref int bitLength, UInt32 val)
{
EnsureBufferSize(ref buf, bitPos + 32);
NetBitWriter.WriteUInt32(val, 32, buf, bitPos);
bitPos += 32;
UpdateBitLength(ref bitLength, bitPos);
}
internal static void WriteInt32(ref byte[] buf, ref int bitPos, ref int bitLength, Int32 val)
{
EnsureBufferSize(ref buf, bitPos + 32);
NetBitWriter.WriteUInt32((UInt32)val, 32, buf, bitPos);
bitPos += 32;
UpdateBitLength(ref bitLength, bitPos);
}
internal static void WriteUInt64(ref byte[] buf, ref int bitPos, ref int bitLength, UInt64 val)
{
EnsureBufferSize(ref buf, bitPos + 64);
NetBitWriter.WriteUInt64(val, 64, buf, bitPos);
bitPos += 64;
UpdateBitLength(ref bitLength, bitPos);
}
internal static void WriteInt64(ref byte[] buf, ref int bitPos, ref int bitLength, Int64 val)
{
EnsureBufferSize(ref buf, bitPos + 64);
NetBitWriter.WriteUInt64((UInt64)val, 64, buf, bitPos);
bitPos += 64;
UpdateBitLength(ref bitLength, bitPos);
}
internal static void WriteSingle(ref byte[] buf, ref int bitPos, ref int bitLength, Single val)
{
// Use union to avoid BitConverter.GetBytes() which allocates memory on the heap
SingleUIntUnion su;
su.UIntValue = 0; // must initialize every member of the union to avoid warning
su.SingleValue = val;
EnsureBufferSize(ref buf, bitPos + 32);
NetBitWriter.WriteUInt32(su.UIntValue, 32, buf, bitPos);
bitPos += 32;
UpdateBitLength(ref bitLength, bitPos);
}
internal static void WriteDouble(ref byte[] buf, ref int bitPos, ref int bitLength, Double val)
{
EnsureBufferSize(ref buf, bitPos + 64);
byte[] bytes = BitConverter.GetBytes(val);
WriteBytes(ref buf, ref bitPos, ref bitLength, bytes, 0, 8);
}
internal static void WriteColorR8G8B8(ref byte[] buf, ref int bitPos, ref int bitLength, Color val)
{
EnsureBufferSize(ref buf, bitPos + 24);
WriteByte(ref buf, ref bitPos, ref bitLength, val.R);
WriteByte(ref buf, ref bitPos, ref bitLength, val.G);
WriteByte(ref buf, ref bitPos, ref bitLength, val.B);
}
internal static void WriteColorR8G8B8A8(ref byte[] buf, ref int bitPos, ref int bitLength, Color val)
{
EnsureBufferSize(ref buf, bitPos + 32);
WriteByte(ref buf, ref bitPos, ref bitLength, val.R);
WriteByte(ref buf, ref bitPos, ref bitLength, val.G);
WriteByte(ref buf, ref bitPos, ref bitLength, val.B);
WriteByte(ref buf, ref bitPos, ref bitLength, val.A);
}
internal static void WriteString(ref byte[] buf, ref int bitPos, ref int bitLength, string val)
{
if (string.IsNullOrEmpty(val))
{
WriteVariableUInt32(ref buf, ref bitPos, ref bitLength, 0u);
return;
}
byte[] bytes = Encoding.UTF8.GetBytes(val);
WriteVariableUInt32(ref buf, ref bitPos, ref bitLength, (uint)bytes.Length);
WriteBytes(ref buf, ref bitPos, ref bitLength, bytes, 0, bytes.Length);
}
internal static void WriteVariableUInt32(ref byte[] buf, ref int bitPos, ref int bitLength, uint value)
{
uint remainingValue = value;
while (remainingValue >= 0x80)
{
WriteByte(ref buf, ref bitPos, ref bitLength, (byte)(remainingValue | 0x80));
remainingValue >>= 7;
}
WriteByte(ref buf, ref bitPos, ref bitLength, (byte)remainingValue);
}
internal static void WriteRangedInteger(ref byte[] buf, ref int bitPos, ref int bitLength, int val, int min, int max)
{
uint range = (uint)(max - min);
int numberOfBits = NetUtility.BitsToHoldUInt(range);
EnsureBufferSize(ref buf, bitPos + numberOfBits);
uint rvalue = (uint)(val - min);
NetBitWriter.WriteUInt32(rvalue, numberOfBits, buf, bitPos);
bitPos += numberOfBits;
UpdateBitLength(ref bitLength, bitPos);
}
internal static void WriteRangedSingle(ref byte[] buf, ref int bitPos, ref int bitLength, Single val, Single min, Single max, int numberOfBits)
{
float range = max - min;
float unit = ((val - min) / range);
int maxVal = (1 << numberOfBits) - 1;
EnsureBufferSize(ref buf, bitPos + numberOfBits);
NetBitWriter.WriteUInt32((UInt32)(maxVal * unit), numberOfBits, buf, bitPos);
bitPos += numberOfBits;
UpdateBitLength(ref bitLength, bitPos);
}
internal static void WriteBytes(ref byte[] buf, ref int bitPos, ref int bitLength, byte[] val, int pos, int length)
{
EnsureBufferSize(ref buf, bitPos + length * 8);
NetBitWriter.WriteBytes(val, pos, length, buf, bitPos);
bitPos += length * 8;
UpdateBitLength(ref bitLength, bitPos);
}
internal static void EnsureBufferSize(ref byte[] buf, int numberOfBits)
{
int byteLen = (numberOfBits + 7) / 8;
if (buf == null)
{
buf = new byte[byteLen + MsgConstants.BufferOverAllocateAmount];
return;
}
if (buf.Length < byteLen)
{
Array.Resize(ref buf, byteLen + MsgConstants.BufferOverAllocateAmount);
}
}
}
internal static class MsgReader
{
internal static bool ReadBoolean(byte[] buf, ref int bitPos)
{
byte retval = NetBitWriter.ReadByte(buf, 1, bitPos);
bitPos++;
return retval > 0;
}
internal static void ReadPadBits(ref int bitPos)
{
int bitOffset = bitPos % 8;
bitPos += (8 - bitOffset) % 8;
}
internal static byte ReadByte(byte[] buf, ref int bitPos)
{
byte retval = NetBitWriter.ReadByte(buf, 8, bitPos);
bitPos += 8;
return retval;
}
internal static byte PeekByte(byte[] buf, ref int bitPos)
{
byte retval = NetBitWriter.ReadByte(buf, 8, bitPos);
return retval;
}
internal static UInt16 ReadUInt16(byte[] buf, ref int bitPos)
{
uint retval = NetBitWriter.ReadUInt16(buf, 16, bitPos);
bitPos += 16;
return (ushort)retval;
}
internal static Int16 ReadInt16(byte[] buf, ref int bitPos)
{
return (Int16)ReadUInt16(buf, ref bitPos);
}
internal static UInt32 ReadUInt32(byte[] buf, ref int bitPos)
{
uint retval = NetBitWriter.ReadUInt32(buf, 32, bitPos);
bitPos += 32;
return retval;
}
internal static Int32 ReadInt32(byte[] buf, ref int bitPos)
{
return (Int32)ReadUInt32(buf, ref bitPos);
}
internal static UInt64 ReadUInt64(byte[] buf, ref int bitPos)
{
ulong low = NetBitWriter.ReadUInt32(buf, 32, bitPos);
bitPos += 32;
ulong high = NetBitWriter.ReadUInt32(buf, 32, bitPos);
ulong retval = low + (high << 32);
bitPos += 32;
return retval;
}
internal static Int64 ReadInt64(byte[] buf, ref int bitPos)
{
return (Int64)ReadUInt64(buf, ref bitPos);
}
internal static Single ReadSingle(byte[] buf, ref int bitPos)
{
if ((bitPos & 7) == 0) // read directly
{
float retval = BitConverter.ToSingle(buf, bitPos >> 3);
bitPos += 32;
return retval;
}
byte[] bytes = ReadBytes(buf, ref bitPos, 4);
return BitConverter.ToSingle(bytes, 0);
}
internal static Double ReadDouble(byte[] buf, ref int bitPos)
{
if ((bitPos & 7) == 0) // read directly
{
// read directly
double retval = BitConverter.ToDouble(buf, bitPos >> 3);
bitPos += 64;
return retval;
}
byte[] bytes = ReadBytes(buf, ref bitPos, 8);
return BitConverter.ToDouble(bytes, 0);
}
internal static Color ReadColorR8G8B8(byte[] buf, ref int bitPos)
{
byte r = ReadByte(buf, ref bitPos);
byte g = ReadByte(buf, ref bitPos);
byte b = ReadByte(buf, ref bitPos);
return new Color(r, g, b, (byte)255);
}
internal static Color ReadColorR8G8B8A8(byte[] buf, ref int bitPos)
{
byte r = ReadByte(buf, ref bitPos);
byte g = ReadByte(buf, ref bitPos);
byte b = ReadByte(buf, ref bitPos);
byte a = ReadByte(buf, ref bitPos);
return new Color(r, g, b, a);
}
internal static UInt32 ReadVariableUInt32(byte[] buf, ref int bitPos)
{
int bitLength = buf.Length * 8;
int result = 0;
int shift = 0;
while (bitLength - bitPos >= 8)
{
byte chunk = ReadByte(buf, ref bitPos);
result |= (chunk & 0x7f) << shift;
shift += 7;
if ((chunk & 0x80) == 0) { return (uint)result; }
}
// ouch; failed to find enough bytes; malformed variable length number?
return (uint)result;
}
internal static String ReadString(byte[] buf, ref int bitPos)
{
int bitLength = buf.Length * 8;
int byteLen = (int)ReadVariableUInt32(buf, ref bitPos);
if (byteLen <= 0) { return String.Empty; }
if ((ulong)(bitLength - bitPos) < ((ulong)byteLen * 8))
{
// not enough data
return null;
}
if ((bitPos & 7) == 0)
{
// read directly
string retval = Encoding.UTF8.GetString(buf, bitPos >> 3, byteLen);
bitPos += (8 * byteLen);
return retval;
}
byte[] bytes = ReadBytes(buf, ref bitPos, byteLen);
return Encoding.UTF8.GetString(bytes, 0, bytes.Length);
}
internal static int ReadRangedInteger(byte[] buf, ref int bitPos, int min, int max)
{
uint range = (uint)(max - min);
int numBits = NetUtility.BitsToHoldUInt(range);
uint rvalue = NetBitWriter.ReadUInt32(buf, numBits, bitPos);
bitPos += numBits;
return (int)(min + rvalue);
}
internal static Single ReadRangedSingle(byte[] buf, ref int bitPos, Single min, Single max, int bitCount)
{
int maxInt = (1 << bitCount) - 1;
int intVal = ReadRangedInteger(buf, ref bitPos, 0, maxInt);
Single range = max - min;
return min + range * intVal / maxInt;
}
internal static byte[] ReadBytes(byte[] buf, ref int bitPos, int numberOfBytes)
{
byte[] retval = new byte[numberOfBytes];
NetBitWriter.ReadBytes(buf, numberOfBytes, bitPos, retval, 0);
bitPos += 8 * numberOfBytes;
return retval;
}
}
internal sealed class WriteOnlyMessage : IWriteMessage
{
private byte[] buf = new byte[MsgConstants.InitialBufferSize];
private int seekPos;
private int lengthBits;
public int BitPosition
{
get => seekPos;
set => seekPos = value;
}
public int BytePosition => seekPos / 8;
public byte[] Buffer => buf;
public int LengthBits
{
get
{
lengthBits = seekPos > lengthBits ? seekPos : lengthBits;
return lengthBits;
}
set
{
lengthBits = value;
seekPos = seekPos > lengthBits ? lengthBits : seekPos;
MsgWriter.EnsureBufferSize(ref buf, lengthBits);
}
}
public int LengthBytes => (LengthBits + 7) / 8;
public void WriteBoolean(bool val)
{
MsgWriter.WriteBoolean(ref buf, ref seekPos, ref lengthBits, val);
}
public void WritePadBits()
{
MsgWriter.WritePadBits(ref buf, ref seekPos, ref lengthBits);
}
public void WriteByte(byte val)
{
MsgWriter.WriteByte(ref buf, ref seekPos, ref lengthBits, val);
}
public void WriteUInt16(UInt16 val)
{
MsgWriter.WriteUInt16(ref buf, ref seekPos, ref lengthBits, val);
}
public void WriteInt16(Int16 val)
{
MsgWriter.WriteInt16(ref buf, ref seekPos, ref lengthBits, val);
}
public void WriteUInt32(UInt32 val)
{
MsgWriter.WriteUInt32(ref buf, ref seekPos, ref lengthBits, val);
}
public void WriteInt32(Int32 val)
{
MsgWriter.WriteInt32(ref buf, ref seekPos, ref lengthBits, val);
}
public void WriteUInt64(UInt64 val)
{
MsgWriter.WriteUInt64(ref buf, ref seekPos, ref lengthBits, val);
}
public void WriteInt64(Int64 val)
{
MsgWriter.WriteInt64(ref buf, ref seekPos, ref lengthBits, val);
}
public void WriteSingle(Single val)
{
MsgWriter.WriteSingle(ref buf, ref seekPos, ref lengthBits, val);
}
public void WriteDouble(Double val)
{
MsgWriter.WriteDouble(ref buf, ref seekPos, ref lengthBits, val);
}
public void WriteColorR8G8B8(Color val)
{
MsgWriter.WriteColorR8G8B8(ref buf, ref seekPos, ref lengthBits, val);
}
public void WriteColorR8G8B8A8(Color val)
{
MsgWriter.WriteColorR8G8B8A8(ref buf, ref seekPos, ref lengthBits, val);
}
public void WriteVariableUInt32(UInt32 val)
{
MsgWriter.WriteVariableUInt32(ref buf, ref seekPos, ref lengthBits, val);
}
public void WriteString(String val)
{
MsgWriter.WriteString(ref buf, ref seekPos, ref lengthBits, val);
}
public void WriteIdentifier(Identifier val)
{
WriteString(val.Value);
}
public void WriteRangedInteger(int val, int min, int max)
{
MsgWriter.WriteRangedInteger(ref buf, ref seekPos, ref lengthBits, val, min, max);
}
public void WriteRangedSingle(Single val, Single min, Single max, int bitCount)
{
MsgWriter.WriteRangedSingle(ref buf, ref seekPos, ref lengthBits, val, min, max, bitCount);
}
public void WriteBytes(byte[] val, int startPos, int length)
{
MsgWriter.WriteBytes(ref buf, ref seekPos, ref lengthBits, val, startPos, length);
}
public byte[] PrepareForSending(bool compressPastThreshold, out bool isCompressed, out int length)
{
byte[] outBuf;
if (LengthBytes <= MsgConstants.CompressionThreshold || !compressPastThreshold)
{
isCompressed = false;
outBuf = new byte[LengthBytes];
Array.Copy(buf, outBuf, LengthBytes);
length = LengthBytes;
}
else
{
using MemoryStream output = new MemoryStream();
using (DeflateStream dstream = new DeflateStream(output, CompressionLevel.Fastest))
{
dstream.Write(buf, 0, LengthBytes);
}
byte[] compressedBuf = output.ToArray();
//don't send the data as compressed if the data takes up more space after compression
//(which may happen when sending a sub/save file that's already been compressed with a better compression ratio)
if (compressedBuf.Length >= LengthBytes)
{
isCompressed = false;
outBuf = new byte[LengthBytes];
Array.Copy(buf, outBuf, LengthBytes);
length = LengthBytes;
}
else
{
isCompressed = true;
outBuf = compressedBuf;
length = outBuf.Length;
DebugConsole.Log($"Compressed message: {LengthBytes} to {length}");
}
}
return outBuf;
}
}
internal sealed class ReadOnlyMessage : IReadMessage
{
private int seekPos;
private int lengthBits;
public int BitPosition
{
get => seekPos;
set => seekPos = value;
}
public int BytePosition => seekPos / 8;
public byte[] Buffer { get; }
public int LengthBits
{
get
{
lengthBits = seekPos > lengthBits ? seekPos : lengthBits;
return lengthBits;
}
set
{
lengthBits = value;
seekPos = seekPos > lengthBits ? lengthBits : seekPos;
}
}
public int LengthBytes => (LengthBits + 7) / 8;
public NetworkConnection Sender { get; }
public ReadOnlyMessage(byte[] inBuf, bool isCompressed, int startPos, int byteLength, NetworkConnection sender)
{
Sender = sender;
if (isCompressed)
{
byte[] decompressedData;
using (MemoryStream input = new MemoryStream(inBuf, startPos, byteLength))
{
using (MemoryStream output = new MemoryStream())
{
using (DeflateStream dstream = new DeflateStream(input, CompressionMode.Decompress))
{
dstream.CopyTo(output);
}
decompressedData = output.ToArray();
}
}
Buffer = new byte[decompressedData.Length];
try
{
Array.Copy(decompressedData, 0, Buffer, 0, decompressedData.Length);
}
catch (ArgumentException e)
{
throw new ArgumentException(
$"Failed to copy the incoming compressed buffer. Source buffer length: {decompressedData.Length}, start position: {0}, length: {decompressedData.Length}, destination buffer length: {Buffer.Length}.", e);
}
lengthBits = decompressedData.Length * 8;
DebugConsole.Log("Decompressing message: " + byteLength + " to " + LengthBytes);
}
else
{
Buffer = new byte[inBuf.Length];
try
{
Array.Copy(inBuf, startPos, Buffer, 0, byteLength);
}
catch (ArgumentException e)
{
throw new ArgumentException($"Failed to copy the incoming uncompressed buffer. Source buffer length: {inBuf.Length}, start position: {startPos}, length: {byteLength}, destination buffer length: {Buffer.Length}.", e);
}
lengthBits = byteLength * 8;
}
seekPos = 0;
}
public bool ReadBoolean()
{
return MsgReader.ReadBoolean(Buffer, ref seekPos);
}
public void ReadPadBits() { MsgReader.ReadPadBits(ref seekPos); }
public byte ReadByte()
{
return MsgReader.ReadByte(Buffer, ref seekPos);
}
public byte PeekByte()
{
return MsgReader.PeekByte(Buffer, ref seekPos);
}
public UInt16 ReadUInt16()
{
return MsgReader.ReadUInt16(Buffer, ref seekPos);
}
public Int16 ReadInt16()
{
return MsgReader.ReadInt16(Buffer, ref seekPos);
}
public UInt32 ReadUInt32()
{
return MsgReader.ReadUInt32(Buffer, ref seekPos);
}
public Int32 ReadInt32()
{
return MsgReader.ReadInt32(Buffer, ref seekPos);
}
public UInt64 ReadUInt64()
{
return MsgReader.ReadUInt64(Buffer, ref seekPos);
}
public Int64 ReadInt64()
{
return MsgReader.ReadInt64(Buffer, ref seekPos);
}
public Single ReadSingle()
{
return MsgReader.ReadSingle(Buffer, ref seekPos);
}
public Double ReadDouble()
{
return MsgReader.ReadDouble(Buffer, ref seekPos);
}
public UInt32 ReadVariableUInt32()
{
return MsgReader.ReadVariableUInt32(Buffer, ref seekPos);
}
public String ReadString()
{
return MsgReader.ReadString(Buffer, ref seekPos);
}
public Identifier ReadIdentifier()
{
return ReadString().ToIdentifier();
}
public Color ReadColorR8G8B8()
{
return MsgReader.ReadColorR8G8B8(Buffer, ref seekPos);
}
public Color ReadColorR8G8B8A8()
{
return MsgReader.ReadColorR8G8B8A8(Buffer, ref seekPos);
}
public int ReadRangedInteger(int min, int max)
{
return MsgReader.ReadRangedInteger(Buffer, ref seekPos, min, max);
}
public Single ReadRangedSingle(Single min, Single max, int bitCount)
{
return MsgReader.ReadRangedSingle(Buffer, ref seekPos, min, max, bitCount);
}
public byte[] ReadBytes(int numberOfBytes)
{
return MsgReader.ReadBytes(Buffer, ref seekPos, numberOfBytes);
}
}
internal sealed class ReadWriteMessage : IWriteMessage, IReadMessage
{
private byte[] buf;
private int seekPos;
private int lengthBits;
public ReadWriteMessage()
{
buf = new byte[MsgConstants.InitialBufferSize];
seekPos = 0;
lengthBits = 0;
}
public ReadWriteMessage(byte[] b, int bitPos, int lBits, bool copyBuf)
{
buf = copyBuf ? (byte[])b.Clone() : b;
seekPos = bitPos;
lengthBits = lBits;
}
public int BitPosition
{
get => seekPos;
set => seekPos = value;
}
public int BytePosition => seekPos / 8;
public byte[] Buffer => buf;
public int LengthBits
{
get
{
lengthBits = seekPos > lengthBits ? seekPos : lengthBits;
return lengthBits;
}
set
{
lengthBits = value;
seekPos = seekPos > lengthBits ? lengthBits : seekPos;
}
}
public int LengthBytes => (LengthBits + 7) / 8;
public NetworkConnection Sender => null;
public void WriteBoolean(bool val)
{
MsgWriter.WriteBoolean(ref buf, ref seekPos, ref lengthBits, val);
}
public void WritePadBits()
{
MsgWriter.WritePadBits(ref buf, ref seekPos, ref lengthBits);
}
public void WriteByte(byte val)
{
MsgWriter.WriteByte(ref buf, ref seekPos, ref lengthBits, val);
}
public void WriteUInt16(UInt16 val)
{
MsgWriter.WriteUInt16(ref buf, ref seekPos, ref lengthBits, val);
}
public void WriteInt16(Int16 val)
{
MsgWriter.WriteInt16(ref buf, ref seekPos, ref lengthBits, val);
}
public void WriteUInt32(UInt32 val)
{
MsgWriter.WriteUInt32(ref buf, ref seekPos, ref lengthBits, val);
}
public void WriteInt32(Int32 val)
{
MsgWriter.WriteInt32(ref buf, ref seekPos, ref lengthBits, val);
}
public void WriteUInt64(UInt64 val)
{
MsgWriter.WriteUInt64(ref buf, ref seekPos, ref lengthBits, val);
}
public void WriteInt64(Int64 val)
{
MsgWriter.WriteInt64(ref buf, ref seekPos, ref lengthBits, val);
}
public void WriteSingle(Single val)
{
MsgWriter.WriteSingle(ref buf, ref seekPos, ref lengthBits, val);
}
public void WriteDouble(Double val)
{
MsgWriter.WriteDouble(ref buf, ref seekPos, ref lengthBits, val);
}
public void WriteColorR8G8B8(Color val)
{
MsgWriter.WriteColorR8G8B8(ref buf, ref seekPos, ref lengthBits, val);
}
public void WriteColorR8G8B8A8(Color val)
{
MsgWriter.WriteColorR8G8B8A8(ref buf, ref seekPos, ref lengthBits, val);
}
public void WriteVariableUInt32(UInt32 val)
{
MsgWriter.WriteVariableUInt32(ref buf, ref seekPos, ref lengthBits, val);
}
public void WriteString(String val)
{
MsgWriter.WriteString(ref buf, ref seekPos, ref lengthBits, val);
}
public void WriteIdentifier(Identifier val)
{
WriteString(val.Value);
}
public void WriteRangedInteger(int val, int min, int max)
{
MsgWriter.WriteRangedInteger(ref buf, ref seekPos, ref lengthBits, val, min, max);
}
public void WriteRangedSingle(Single val, Single min, Single max, int bitCount)
{
MsgWriter.WriteRangedSingle(ref buf, ref seekPos, ref lengthBits, val, min, max, bitCount);
}
public void WriteBytes(byte[] val, int startPos, int length)
{
MsgWriter.WriteBytes(ref buf, ref seekPos, ref lengthBits, val, startPos, length);
}
public bool ReadBoolean()
{
return MsgReader.ReadBoolean(buf, ref seekPos);
}
public void ReadPadBits() { MsgReader.ReadPadBits(ref seekPos); }
public byte ReadByte()
{
return MsgReader.ReadByte(buf, ref seekPos);
}
public byte PeekByte()
{
return MsgReader.PeekByte(buf, ref seekPos);
}
public UInt16 ReadUInt16()
{
return MsgReader.ReadUInt16(buf, ref seekPos);
}
public Int16 ReadInt16()
{
return MsgReader.ReadInt16(buf, ref seekPos);
}
public UInt32 ReadUInt32()
{
return MsgReader.ReadUInt32(buf, ref seekPos);
}
public Int32 ReadInt32()
{
return MsgReader.ReadInt32(buf, ref seekPos);
}
public UInt64 ReadUInt64()
{
return MsgReader.ReadUInt64(buf, ref seekPos);
}
public Int64 ReadInt64()
{
return MsgReader.ReadInt64(buf, ref seekPos);
}
public Single ReadSingle()
{
return MsgReader.ReadSingle(buf, ref seekPos);
}
public Double ReadDouble()
{
return MsgReader.ReadDouble(buf, ref seekPos);
}
public UInt32 ReadVariableUInt32()
{
return MsgReader.ReadVariableUInt32(buf, ref seekPos);
}
public String ReadString()
{
return MsgReader.ReadString(buf, ref seekPos);
}
public Identifier ReadIdentifier()
{
return ReadString().ToIdentifier();
}
public Color ReadColorR8G8B8()
{
return MsgReader.ReadColorR8G8B8(buf, ref seekPos);
}
public Color ReadColorR8G8B8A8()
{
return MsgReader.ReadColorR8G8B8A8(buf, ref seekPos);
}
public int ReadRangedInteger(int min, int max)
{
return MsgReader.ReadRangedInteger(buf, ref seekPos, min, max);
}
public Single ReadRangedSingle(Single min, Single max, int bitCount)
{
return MsgReader.ReadRangedSingle(buf, ref seekPos, min, max, bitCount);
}
public byte[] ReadBytes(int numberOfBytes)
{
return MsgReader.ReadBytes(buf, ref seekPos, numberOfBytes);
}
public byte[] PrepareForSending(bool compressPastThreshold, out bool isCompressed, out int outLength)
{
throw new InvalidOperationException("ReadWriteMessages are not to be sent");
}
}
}