Havn't been doing much this week(end), But I've redone the byte vectors (streams).
Isn't really an "improvement", it is basically just more readable, and easier to work with.
CodecFactory.cs:
Code:
/* ######################################## *\
* ### Copyright (C) 2009 AJ Ravindiran ### *
* ### HTTP://THEAJ.NET/ <AJ@THEAJ.NET> ### *
\* ######################################## */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AJRavindiran.Jolt.RuneScape.Network.Codecs
{
/// <summary>
/// Represents a codec factory which controls incoming and outgoing bytevectors.
/// </summary>
public class CodecFactory
{
#region Fields
private int mInputOffset = 0;
private int mInputLength = 0;
private byte[] mInputBuffer;
private int mOutputOffset = 0;
private int mOutputLength = 0;
private byte[] mOutputBuffer;
private int mFrameStackPtr = -1;
private static int mFrameStackSize = 10;
private int[] mFrameStack = new int[mFrameStackSize];
private int[] mBitMaskOut = new int[32];
private int mBitPosition = 0;
#endregion
#region Properties
public int InputOffset
{
get { return mInputOffset; }
set { mInputOffset = value; }
}
public int InputLength
{
get { return mInputLength; }
set { mInputLength = value; }
}
public byte[] InputBuffer
{
get { return mInputBuffer; }
set { mInputBuffer = value; }
}
public int OutputOffset
{
get { return mOutputOffset; }
set { mOutputOffset = value; }
}
public int OutputLength
{
get { return mOutputLength; }
set { mOutputLength = value; }
}
public byte[] OutputBuffer
{
get { return mOutputBuffer; }
set { mOutputBuffer = value; }
}
#endregion
#region Constructors
public CodecFactory(int inputLength, int outputLength)
{
mInputLength = inputLength;
mOutputLength = outputLength;
mInputBuffer = new byte[inputLength];
mOutputBuffer = new byte[outputLength];
for (int i = 0; i < 32; i++)
mBitMaskOut[i] = (1 << i) - 1;
}
#endregion
#region Methods
public byte ReadByte()
{
return (byte)(mInputBuffer[mInputOffset++]);
}
public int ReadSByte()
{
return (ReadByte() & 0xff);
}
public byte ReadByteA()
{
return (byte)(ReadByte() - 128);
}
public byte ReadByteC()
{
return (byte)(-ReadByte());
}
public byte ReadByteS()
{
return (byte)(128 - ReadByte());
}
public int ReadSByteA()
{
return (ReadSByte() - 128 & 0xff);
}
public int ReadSByteC()
{
return -(ReadSByte() & 0xff);
}
public int ReadSByteS()
{
return (128 - ReadSByte() & 0xff);
}
public int Read3Bytes()
{
return (ReadSByte() << 16) | (ReadSByte() << 8) | ReadSByte();
}
public int Read2Bytes()
{
return (ReadSByte() << 8) + ReadSByte();
}
public CodecFactory ReadBytes(byte[] array, int endOffset, int startOffSet)
{
for (int i = startOffSet; i < startOffSet + endOffset; i++)
array[i] = ReadByte();
return this;
}
public CodecFactory ReadBytesReserved(byte[] array, int endOffset, int startOffSet)
{
for (int i = (startOffSet + endOffset) - 1; i >= startOffSet; i--)
array[i] = ReadByte();
return this;
}
public CodecFactory ReadBytesReserved128(byte[] array, int endOffset, int startOffset)
{
for (int i = (startOffset + endOffset) - 1; i >= startOffset; i--)
array[i] = ReadByteA();
return this;
}
public int ReadInt16()
{
mInputOffset += 2;
int i = ((mInputBuffer[mInputOffset - 2] & 0xff) << 8) + (mInputBuffer[mInputOffset - 1] & 0xff);
if (i > 32767)
i -= 0x10000;
return i;
}
public int ReadInt16A()
{
mInputOffset += 2;
int i = ((mInputBuffer[mInputOffset - 1] & 0xff) << 8)
+ (mInputBuffer[mInputOffset - 2] - 128 & 0xff);
if (i > 32767)
i -= 0x10000;
return i;
}
public int ReadInt16Endian()
{
mInputOffset += 2;
int i = ((mInputBuffer[mInputOffset - 1] & 0xff) << 8)
+ (mInputBuffer[mInputOffset - 2] & 0xff);
if (i > 32767)
i -= 0x10000;
return i;
}
public int ReadInt16EndianA()
{
mInputOffset += 2;
int i = ((mInputBuffer[mInputOffset - 1] & 0xff) << 8)
+ (mInputBuffer[mInputOffset - 2] - 128 & 0xff);
if (i > 32767)
i -= 0x10000;
return i;
}
public int ReadUInt16()
{
mInputOffset += 2;
return ((mInputBuffer[mInputOffset - 2] & 0xff) << 8)
+ (mInputBuffer[mInputOffset - 1] - 128 & 0xff);
}
public int ReadUInt16A()
{
mInputOffset += 2;
return ((mInputBuffer[mInputOffset - 2] & 0xff) << 8)
+ (mInputBuffer[mInputOffset - 1] - 128 & 0xff);
}
public int ReadUInt16Endian()
{
mInputOffset += 2;
return ((mInputBuffer[mInputOffset - 1] & 0xff) << 8)
+ (mInputBuffer[mInputOffset - 2] & 0xff);
}
public int ReadUInt16EndianA()
{
mInputOffset += 2;
return ((mInputBuffer[mInputOffset - 1] & 0xff) << 8)
+ (mInputBuffer[mInputOffset - 2] - 128 & 0xff);
}
public int ReadInt32()
{
mInputOffset += 4;
return ((mInputBuffer[mInputOffset - 4] & 0xff) << 24)
+ ((mInputBuffer[mInputOffset - 3] & 0xff) << 16)
+ ((mInputBuffer[mInputOffset - 2] & 0xff) << 8)
+ (mInputBuffer[mInputOffset - 1] & 0xff);
}
public int ReadInt32V1()
{
mInputOffset += 4;
return ((mInputBuffer[mInputOffset - 2] & 0xff) << 24)
+ ((mInputBuffer[mInputOffset - 1] & 0xff) << 16)
+ ((mInputBuffer[mInputOffset - 4] & 0xff) << 8)
+ (mInputBuffer[mInputOffset - 3] & 0xff);
}
public int ReadInt32V2()
{
mInputOffset += 4;
return ((mInputBuffer[mInputOffset - 3] & 0xff) << 24)
+ ((mInputBuffer[mInputOffset - 4] & 0xff) << 16)
+ ((mInputBuffer[mInputOffset - 1] & 0xff) << 8)
+ (mInputBuffer[mInputOffset - 2] & 0xff);
}
public long ReadInt64()
{
long l = (long)ReadInt32() & 0xffffffffL;
long l1 = (long)ReadInt32() & 0xffffffffL;
return (l << 32) + l1;
}
public long ReadInt64V2()
{
mInputOffset += 8;
return (((mInputBuffer[mInputOffset - 8] & 0xff) << 56)
+ ((mInputBuffer[mInputOffset - 7] & 0xff) << 48)
+ ((mInputBuffer[mInputOffset - 6] & 0xff) << 40)
+ ((mInputBuffer[mInputOffset - 5] & 0xff) << 32)
+ ((mInputBuffer[mInputOffset - 4] & 0xff) << 24)
+ ((mInputBuffer[mInputOffset - 3] & 0xff) << 16)
+ ((mInputBuffer[mInputOffset - 2] & 0xff) << 8)
+ (mInputBuffer[mInputOffset - 1] & 0xff));
}
public string ReadString()
{
StringBuilder sb = new StringBuilder();
byte b;
while ((b = ReadByte()) != 0)
sb.Append((char)b);
return sb.ToString();
}
public void ExpandOutBuffer()
{
byte[] oldBuffer = mOutputBuffer;
mOutputBuffer = new byte[oldBuffer.Length + 1000];
System.Array.Copy(oldBuffer, 0, mOutputBuffer, 0, oldBuffer.Length);
}
public CodecFactory AppendByte(int i)
{
if (mOutputOffset >= mOutputBuffer.Length)
ExpandOutBuffer();
mOutputBuffer[mOutputOffset++] = (byte)i;
return this;
}
public CodecFactory AppendByte(int i, int position)
{
if (position >= mOutputBuffer.Length)
ExpandOutBuffer();
mOutputBuffer[position] = (byte)i;
return this;
}
public CodecFactory AppendByteA(int i)
{
AppendByte(i + 128);
return this;
}
public CodecFactory AppendByteS(int i)
{
AppendByte(128 - i);
return this;
}
public CodecFactory AppendByteC(int i)
{
AppendByte(-i);
return this;
}
public CodecFactory AppendBytes(byte[] array, int endOffset, int startOffset)
{
for (int i = startOffset; i < startOffset + endOffset; i++)
AppendByte(array[i]);
return this;
}
public CodecFactory AppendBytesS(byte[] array, int endOffset, int startOffset)
{
for (int i = startOffset; i < startOffset + endOffset; i++)
AppendByte(-128 + array[i]);
return this;
}
public CodecFactory AppendBytesA(byte[] array, int endOffset, int startOffset)
{
for (int i = startOffset; i < startOffset + endOffset; i++)
AppendByte(array[i] - 128);
return this;
}
public CodecFactory AppendBytesC(byte[] array, int endOffset, int startOffset)
{
for (int i = startOffset; i < startOffset + endOffset; i++)
AppendByte(array[i] + 128);
return this;
}
public CodecFactory AppendBytesReverse(byte[] array, int endOffset, int startOffset)
{
for (int i = (startOffset + endOffset) - 1; i >= startOffset; i--)
AppendByte(array[i]);
return this;
}
public CodecFactory AppendBytesReverseA(byte[] array, int endOffset, int startOffset)
{
for (int i = (startOffset + endOffset) - 1; i >= startOffset; i--)
AppendByteA(array[i]);
return this;
}
public CodecFactory Append3Byte(int i)
{
AppendByte(i >> 16);
AppendByte(i >> 8);
AppendByte(i);
return this;
}
public CodecFactory AppendInt16(int i)
{
AppendByte(i >> 8);
AppendByte(i);
return this;
}
public CodecFactory AppendInt16A(int i)
{
AppendByte(i >> 8);
AppendByte(i + 128);
return this;
}
public CodecFactory AppendInt16Endian(int i)
{
AppendByte(i);
AppendByte(i >> 8);
return this;
}
public CodecFactory AppendInt16EndianA(int i)
{
AppendByte(i + 128);
AppendByte(i >> 8);
return this;
}
public CodecFactory AppendInt32(int i)
{
AppendByte(i >> 24);
AppendByte(i >> 16);
AppendByte(i >> 8);
AppendByte(i);
return this;
}
public CodecFactory AppendInt32Endian(int i)
{
AppendByte(i);
AppendByte(i >> 8);
AppendByte(i >> 16);
AppendByte(i >> 24);
return this;
}
public CodecFactory AppendInt32V1(int i)
{
AppendByte(i >> 8);
AppendByte(i);
AppendByte(i >> 24);
AppendByte(i >> 16);
return this;
}
public CodecFactory AppendInt32V2(int i)
{
AppendByte(i >> 16);
AppendByte(i >> 24);
AppendByte(i);
AppendByte(i >> 8);
return this;
}
public CodecFactory AppendInt64(long l)
{
AppendByte((int)(l >> 56));
AppendByte((int)(l >> 48));
AppendByte((int)(l >> 40));
AppendByte((int)(l >> 32));
AppendByte((int)(l >> 24));
AppendByte((int)(l >> 16));
AppendByte((int)(l >> 8));
AppendByte((int)l);
return this;
}
public byte[] StrToByteArray(string str)
{
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
return encoding.GetBytes(str);
}
public CodecFactory AppendString(string s)
{
byte[] stringBytes = StrToByteArray(s);
for (int i = 0; i < s.Length; i++)
AppendByte(stringBytes[i]);
AppendByte(0);
return this;
}
public CodecFactory AppendVarByte(int i)
{
if ((i & 255) >= 128)
AppendInt16(i - 32768);
else
AppendByte(i);
return this;
}
public CodecFactory CreateFrame(int id)
{
AppendByteA(id);
return this;
}
public CodecFactory CreateFrameByte(int id)
{
AppendByte(id);
AppendByte(0);
if (mFrameStackPtr >= mFrameStackSize - 1)
JoltEnvironment.GetLogger().WriteWarn("Stack overflow.");
else
mFrameStack[++mFrameStackPtr] = mInputOffset;
return this;
}
public CodecFactory CreateFrameInt16(int id)
{
AppendByte(id);
AppendByte(0);
if (mFrameStackPtr >= mFrameStackSize - 1)
JoltEnvironment.GetLogger().WriteWarn("Stack overflow.");
else
mFrameStack[++mFrameStackPtr] = mInputOffset;
return this;
}
public CodecFactory EndFrameByte()
{
if (mFrameStackPtr < 0)
JoltEnvironment.GetLogger().WriteWarn("Stack empty");
else
AppendFrameSize(mOutputOffset - mFrameStack[mFrameStackPtr--]);
return this;
}
public CodecFactory EndFrameInt16()
{
if (mFrameStackPtr < 0)
JoltEnvironment.GetLogger().WriteWarn("Stack empty");
else
AppendFrameSizeInt16(mOutputOffset - mFrameStack[mFrameStackPtr--]);
return this;
}
public CodecFactory AppendFrameSize(int i)
{
AppendByte(i, (mOutputOffset - i - 1));
return this;
}
public CodecFactory AppendFrameSizeInt16(int i)
{
AppendByte((i >> 8), (mOutputOffset - i - 2));
AppendByte(i, (mOutputOffset - i - 1));
return this;
}
public CodecFactory InitBitAccess()
{
mBitPosition = mOutputOffset * 8;
return this;
}
public CodecFactory FinishBitAccess()
{
mOutputOffset = (mBitPosition + 7) / 8;
return this;
}
public CodecFactory AppendBit(int bit, int pos)
{
if (pos >= mOutputBuffer.Length)
ExpandOutBuffer();
mOutputBuffer[pos] &= (byte)~bit;
return this;
}
public CodecFactory PlaceBit(int bit, int pos)
{
if (pos >= mOutputBuffer.Length)
ExpandOutBuffer();
mOutputBuffer[pos] |= (byte)bit;
return this;
}
public CodecFactory AppendBits(int numBits, int value)
{
int bytePos = mBitPosition >> 3;
int bitOffset = 8 - (mBitPosition & 7);
mBitPosition += numBits;
for (; numBits > bitOffset; bitOffset = 8)
{
AppendBit(mBitMaskOut[bitOffset], bytePos);
PlaceBit(((value >> (numBits - bitOffset)) & mBitMaskOut[bitOffset]), bytePos++);
numBits -= bitOffset;
}
if (numBits == bitOffset)
{
AppendBit(mBitMaskOut[bitOffset], bytePos);
PlaceBit((value & mBitMaskOut[bitOffset]), bytePos);
}
else
{
AppendBit((mBitMaskOut[numBits] << (bitOffset - numBits)), bytePos);
PlaceBit((value & mBitMaskOut[numBits]) << (bitOffset - numBits), bytePos);
}
return this;
}
#endregion
}
}
From the older codec factory you would use the follow code to read / write streams to the runescape client:
Code:
character.GetCodecFactory().GetDecoder().ReadSignedByte();
character.GetCodecFactory().GetDecoder().ReadUnsignedDWord();
character.GetCodecFactory().GetEncoder().WriteByte(0);
character.GetCodecFactory().GetEncoder().WriteDWord(1);
character.GetCodecFactory().GetEncoder().WriteQWord(2);
character.GetCodecFactory().GetEncoder().WriteWord128(3);
character.GetCodecFactory().GetEncoder().WriteUnsignedByte(4);
character.GetCodecFactory().GetEncoder().WriteString("something");
Now:
Code:
character.GetCodecFactory().ReadByte();
character.GetCodecFactory().ReadInt32();
character.GetCodecFactory()
.AppendByte(0)
.AppendInt32(1)
.AppendInt64(2)
.AppendInt16A(3)
.AppendSByte(4)
.AppendString("something");