Valhalla Legends Forums Archive | .NET Platform | [C#]Combination Packet Buffer/Debuffer

AuthorMessageTime
shout
[code]
using System;
using System.Text;

namespace Packet
{
internal class FIFOByteBuffer
{
byte[] data;

public FIFOByteBuffer()
{
data = new byte[0];
}

#region private functions

void AppendByte(byte Data)
{
byte[] tmp = new byte[data.Length + 1];
Buffer.BlockCopy(data, 0, tmp, 0, data.Length);
tmp[data.Length] = Data;

data = tmp;
}

public byte PeekByte()
{
if (data.Length > 1)
return data[0];
return 0;
}

public byte PeekByte(int Index)
{
if (Length - 1 > Index)
{
return data[Index];
}
return 0;
}

byte RetriveByte()
{
if (data.Length == 0)
return 0;
byte[] tmp = new byte[0];
tmp = new byte[data.Length - 1];
Buffer.BlockCopy(data, 1, tmp, 0, data.Length - 1);

byte Data = data[0];
data = tmp;

return Data;
}

#endregion

#region Byte

public void InsertByte(byte Data)
{
this.AppendByte(Data);
}

public byte GetByte()
{
return this.RetriveByte();
}

public byte GetByte(int Index)
{
return this.RetriveByte(Index);
}

public void InsertByteArray(byte[] Data)
{
for (int i = 0; i < Data.Length; i++)
this.AppendByte(Data);
}

public byte[] GetByteArray(int Length)
{
byte[] rBytes = new byte[Length];
for (int i = 0; i < Length; i++)
{
rBytes[i] = this.RetriveByte();
}
return rBytes;
}
#endregion

#region Word

public void InsertWord(short Data)
{
byte[] tmp = BitConverter.GetBytes(Data);
for (int i = 0; i < tmp.Length; i++)
this.AppendByte(tmp[i]);
}

public short GetWord()
{
byte[] tmp = new byte[2];
for (int i = 0; i > tmp.Length; i++)
tmp[i] = this.RetriveByte();

return BitConverter.ToInt16(tmp, 0);
}

public void InsertWordArray(short[] Data)
{
for (int i = 0; i < Data.Length; i++)
this.InsertWord(Data[i]);
}

public short[] GetWordArray(int Length)
{
short[] rShorts = new short[Length];
for (int i = 0; i < Length; i++)
rShorts[i] = this.GetWord();
return rShorts;
}

#endregion

#region Dword

public void InsertDword(int Data)
{
byte[] tmp = BitConverter.GetBytes(Data);
for (int i = 0; i < tmp.Length; i++)
this.AppendByte(tmp[i]);
}

public int GetDword()
{
byte[] tmp = new byte[4];
for (int i = 0; i < tmp.Length; i++)
tmp[i] = this.RetriveByte();

return BitConverter.ToInt32(tmp, 0);
}

public int GetDword(int Index)
{
byte[] tmp = new byte[4];
for (int i = 0; i < tmp.Length; i++)
tmp[i] = this.RetriveByte(Index + i);

return BitConverter.ToInt32(tmp, 0);
}

public void InsertDwordArray(int[] Data)
{
for (int i = 0; i < Data.Length; i++)
{
this.InsertDword(Data[i]);
}
}

public int[] GetDwordArray(int Length)
{
int[] rDwords = new int[Length];
for (int i = 0; i < rDwords.Length; i++)
{
rDwords[i] = this.GetDword();
}
return rDwords;
}

#endregion

#region Strings

public void InsertWideString(string Data)
{
byte[] tmp = Encoding.UTF8.GetBytes(Data);
for (int i = 0; i < tmp.Length; i++)
this.AppendByte(tmp[i]);
if (data[data.Length - 1] != 0x00)
this.AppendByte(0x00);
}

public void InsertString(string Data)
{
if (Data == string.Empty)
return;
if (Data == null)
return;
char[] ctmp = Data.ToCharArray();
byte[] tmp = new byte[ctmp.Length];
for (int i = 0; i < ctmp.Length; i++)
{
tmp[i] = (byte)ctmp[i];
}
for (int i = 0; i < tmp.Length; i++)
this.AppendByte(tmp[i]);
if (Data[Data.Length - 1] != 0x00)
this.AppendByte(0x00);
}

public string GetWideString()
{
int i = 0;
for (i = 0; ;i++)
{
if (this.PeekByte(i) == 0x00) //Finds out how long string is
break;
}

byte[] tmp = new byte[i];
for (int j = 0; j < i; j++)
tmp[j] = this.RetriveByte(); //Gets the string as a byte array

return Encoding.UTF8.GetString(tmp);
}

public string GetString()
{
int i = 0;
for (i = 0; ;i++)
{
if (this.PeekByte(i) == 0x00) //Finds out how long string is
break;
}

char[] ctmp = new char[i];
for (int j = 0; j < i; j++)
ctmp[j] = (char)this.GetByte(); //Gets the string as a byte array
this.RetriveByte(); //Null term

return new string(ctmp);
}

#endregion

public static implicit operator byte[](FIFOByteBuffer buff)
{
return buff.data;
}

public static implicit operator FIFOByteBuffer(byte[] buff)
{
FIFOByteBuffer x = new FIFOByteBuffer();
for (int i = 0; i < buff.Length; i++)
x.InsertByte(buff[i]);
return x;
}

public byte this [int Index]
{
get
{
return data[Index];
}
set
{
data[Index] = value;
}
}

public byte[] GetBnetPacket(byte PacketID)
{
FIFOByteBuffer buffer = new FIFOByteBuffer();
buffer.InsertByte(0xFF);
buffer.InsertByte(PacketID);
buffer.InsertWord((short)(this.data.Length + 4));
buffer.InsertByteArray(this.data);
return buffer;
}

public void InsertStringAsDword(string Data)
{
for (int i = 3; i > -1; i--)
this.AppendByte((byte)Data[i]);
}

public int Length
{
get
{
return data.Length;
}
}

public FIFOByteBuffer(byte[] buff)
{
this.data = buff;
}

public static FIFOByteBuffer operator +(FIFOByteBuffer x, FIFOByteBuffer y)
{
FIFOByteBuffer buff = x;
buff.InsertByteArray(y);
return buff;
}

public static bool operator ==(FIFOByteBuffer x, FIFOByteBuffer y)
{
if (x.Length != y.Length)
return false;
for (int i = 0; i < x.Length; i++)
{
if (x[i] != y[i])
return false;
}

return true;
}

public static bool operator !=(FIFOByteBuffer x, FIFOByteBuffer y)
{
if (x == y)
{
return false;
}

return true;
}

public override bool Equals(object obj)
{
return base.Equals (obj);
}

public override int GetHashCode()
{
return base.GetHashCode ();
}

public override string ToString()
{
return base.ToString();
}

public byte[] toByteArray()
{
byte[] tmp = this.data;
return tmp;
}

public int GetBnetPacketLength()
{
byte[] bLength = new byte[2];
bLength[0] = data[2];
bLength[1] = data[3];
return (int)BitConverter.ToInt16(bLength, 0);
}
}
}
[/code]

Example with parsing packets:

[code]
public static byte[] Build(Client client)
{
if (client == Client.WarCraft2)
throw new PacketException("Invalid client for this packet");
if (client == Client.WarCraft3 || client == Client.WarCraft3TFT)
throw new NotSupportedException("This packet does not support this client in this version");
FIFOByteBuffer pbuffer = new FIFOByteBuffer();
pbuffer.InsertDword(0x0000000);
pbuffer.InsertStringAsDword("IX86");
switch (client)
{
case Client.BroodWar:
pbuffer.InsertStringAsDword("SEXP");
pbuffer.InsertDword(0x000000CB);
break;

case Client.StarCraft:
pbuffer.InsertStringAsDword("STAR");
pbuffer.InsertDword(0x000000CB);
break;

case Client.Diablo2:
pbuffer.InsertStringAsDword("D2DV");
pbuffer.InsertDword(0x0000000A);
break;

case Client.Diablo2LOD:
pbuffer.InsertStringAsDword("D2XP");
pbuffer.InsertDword(0x0000000A);
break;
}
pbuffer.InsertStringAsDword("enUS");
int[] zeros = new int[4] {0,0,0,0};
pbuffer.InsertDwordArray(zeros);
pbuffer.InsertString("USA");
pbuffer.InsertString("United States");
socket.send(pbuffer.GetBnetPacket(0x50));
}
[/code]

Example de-buffer-ing :P:

[code]
private void packetstuff(byte[] recbuff)
{
FIFOByteBuffer pbuff = recbuff; //Implicit conversion from byte array
PacketHeader phead = pbuff.GetDword(); //Gets the first DWORD from the head of the buffer
int logontype = pbuff.GetDword();
int servertoken = pbuff.GetDword();
int UDPValue = pbuff.GetDword();
DateTime filetime = pbuff.GetFileTime(); //Something I forgot to put in this one...
string MPQString = pbuff.GetString(); //Reads bytes until it hits a null
//terminator, then returns as a string
int MPQVer = int.Parse(MPQString[8].ToString());
byte[] serversig;
if (logontype > 0)
serversig = pbuff.GetByteArray(128);
}
[/code]

It is also useful in hashing:

[code]

int[] keyValue = DecodeKey(key);
FIFOByteBuffer buff = new FIFOByteBuffer();
buff.InsertDword(key.Length);
buff.InsertDword(keyValue[0]);
buff.InsertDword(keyValue[1]);
buff.InsertDword(0); // 0 Unknown

FIFOByteBuffer hashbuff = new FIFOByteBuffer();
hashbuff.InsertDword(ClientToken);
hashbuff.InsertDword(ServerToken);
hashbuff.InsertDword(keyValue[0]);
hashbuff.InsertDword(keyValue[1]);
hashbuff.InsertDword(0x00); //0 unknown
hashbuff.InsertDword(keyValue[2]);

return buff + XSha1.HashData(hashbuff);

[/code]

[i]Edit: Changed code a tidbit
March 13, 2005, 3:01 PM
Myndfyr
I'm still not quite sure what this does.  Is it like a Stream?
March 15, 2005, 2:43 AM
shout
[quote author=MyndFyre link=topic=10908.msg103883#msg103883 date=1110854580]
I'm still not quite sure what this does. Is it like a Stream?
[/quote]

Yeah, I guess.

I would say its more like a byte queue class.
March 15, 2005, 3:20 PM
LoRd
Note that a packet buffer handles both outgoing and incoming packets.
March 27, 2005, 6:23 AM

Search