Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace Envy.Prototypes
{
public enum PacketEncryption : byte
{
Exchange = 0xA,
AntiHack = 0x66,
Encrypted = 0x65,
Decrypted = 0x64
}
public class MUID
{
public UInt32 uidLow;
public UInt32 uidHigh;
};
public class GunzPacket
{
private byte[] m_bBuffer = new byte[4096];
private int m_nSize = 0;
private int m_nOrgSize = 0;
private PacketEncryption m_PacketVersion;
private ushort m_PacketOperation;
private Encoding StringEncoding = Encoding.GetEncoding(1252);
public ushort getOperation()
{
return m_PacketOperation;
}
public PacketEncryption getVersion() { return m_PacketVersion; }
public byte[] getPacket()
{
return m_bBuffer;
}
public int fixSize()
{
m_nSize = m_nOrgSize;
Array.Resize<byte>(ref m_bBuffer, m_nSize);
return m_nSize;
}
public void Increase(int pVal)
{
if (m_nSize == 0 || m_bBuffer.Length < (m_nSize + pVal))
Array.Resize<byte>(ref m_bBuffer, (m_nSize + pVal));
}
public void Write(byte[] pBuffer, int iIndex, int iLen)
{
Increase(iLen);
Buffer.BlockCopy(pBuffer, iIndex, m_bBuffer, m_nSize, iLen);
m_nSize += iLen;
}
public void Write(byte pByte)
{
Increase(1);
m_bBuffer[m_nSize] = pByte;
m_nSize++;
}
public void Write(bool pBool)
{
Increase(1);
m_bBuffer[m_nSize] = Convert.ToByte(pBool);
m_nSize++;
}
public void Write(short pShort)
{
Increase(2);
Buffer.BlockCopy(BitConverter.GetBytes(pShort), 0, m_bBuffer, m_nSize, 2);
m_nSize += 2;
}
public void Write(int pInt)
{
Increase(4);
Buffer.BlockCopy(BitConverter.GetBytes(pInt), 0, m_bBuffer, m_nSize, 4);
m_nSize += 4;
}
public void Write(UInt16 pInt)
{
Increase(2);
Buffer.BlockCopy(BitConverter.GetBytes(pInt), 0, m_bBuffer, m_nSize, 2);
m_nSize += 2;
}
public void Write(UInt32 pInt)
{
Increase(4);
Buffer.BlockCopy(BitConverter.GetBytes(pInt), 0, m_bBuffer, m_nSize, 4);
m_nSize += 4;
}
public void Write(UInt64 pInt)
{
Increase(8);
Buffer.BlockCopy(BitConverter.GetBytes(pInt), 0, m_bBuffer, m_nSize, 8);
m_nSize += 8;
}
public void Write(float pFloat)
{
Increase(4);
Buffer.BlockCopy(BitConverter.GetBytes(pFloat), 0, m_bBuffer, m_nSize, 4);
m_nSize += 4;
}
public void Write(double pDouble)
{
Increase(4);
Buffer.BlockCopy(BitConverter.GetBytes(pDouble), 0, m_bBuffer, m_nSize, 4);
m_nSize += 4;
}
public void Write(long pLong)
{
Increase(8);
Buffer.BlockCopy(BitConverter.GetBytes(pLong), 0, m_bBuffer, m_nSize, 8);
m_nSize += 8;
}
public void Write(MUID pChar)
{
Write(pChar.uidLow);
Write(pChar.uidHigh);
}
public void Write(string pString)
{
if (pString == null) pString = "";
byte[] tmp = StringEncoding.GetBytes(pString);
Int16 len = (short)(tmp.Length + 2);
Write(len);
Increase(len);
Buffer.BlockCopy(tmp, 0, m_bBuffer, m_nSize, tmp.Length);
m_nSize += len;
}
public void Write(string pString, int iLen)
{
if (pString == null) pString = "";
byte[] buf = new byte[iLen];
int used = StringEncoding.GetBytes(pString, 0, pString.Length, buf, 0);
int unused = Math.Min(iLen - 1, used);
Array.Clear(buf, unused, Math.Max(1, iLen - unused));
Write(buf, 0, iLen);
}
public void Write(int pSize, int pCount)
{
int size = 8 + (pSize * pCount);
Write(size);
Write(pSize);
Write(pCount);
Increase(pSize * pCount);
}
public void WriteSkip(int pSize)
{
Increase(pSize);
Array.Clear(m_bBuffer, m_nSize, pSize);
m_nSize += pSize;
}
public bool Read(ref byte pByte)
{
if (m_bBuffer.Length - m_nSize < 1) return false;
pByte = m_bBuffer[m_nSize++];
return true;
}
public bool Read(ref bool pBool)
{
if (m_bBuffer.Length - m_nSize < 1) return false;
pBool = m_bBuffer[m_nSize++] != 0;
return true;
}
public bool Read(ref byte[] pByte, int iIndex, int iLength)
{
if (m_bBuffer.Length - m_nSize < iLength) return false;
Buffer.BlockCopy(m_bBuffer, m_nSize, pByte, iIndex, iLength);
m_nSize += iLength;
return true;
}
public bool Read(ref short pShort)
{
if (m_bBuffer.Length - m_nSize < 2) return false;
pShort = BitConverter.ToInt16(m_bBuffer, m_nSize);
m_nSize += 2;
return true;
}
public bool Read(ref int pInt)
{
if (m_bBuffer.Length - m_nSize < 4) return false;
pInt = BitConverter.ToInt32(m_bBuffer, m_nSize);
m_nSize += 4;
return true;
}
public bool Read(ref UInt16 nShort)
{
if (m_bBuffer.Length - m_nSize < 2)
return false;
nShort = BitConverter.ToUInt16(m_bBuffer, m_nSize);
m_nSize += 2;
return true;
}
public bool Read(ref UInt32 nInt)
{
if (m_bBuffer.Length - m_nSize < 4)
return false;
nInt = BitConverter.ToUInt32(m_bBuffer, m_nSize);
m_nSize += 4;
return true;
}
public bool Read(ref UInt64 nLong)
{
if (m_bBuffer.Length - m_nSize < 4) return false;
nLong = BitConverter.ToUInt64(m_bBuffer, m_nSize);
m_nSize += 8;
return true;
}
public bool Read(ref float pFloat)
{
if (m_bBuffer.Length - m_nSize < 4) return false;
pFloat = BitConverter.ToSingle(m_bBuffer, m_nSize);
m_nSize += 4;
return true;
}
public bool Read(ref long pLong)
{
if (m_bBuffer.Length - m_nSize < 8) return false;
pLong = BitConverter.ToInt64(m_bBuffer, m_nSize);
m_nSize += 4;
return true;
}
public bool Read(ref string pString)
{
short Length = 0;
if (!Read(ref Length)) return false;
if (m_bBuffer.Length - m_nSize < Length) return false;
try
{
pString = StringEncoding.GetString(m_bBuffer, m_nSize, Length);
pString = pString.Substring(0, pString.IndexOf('\0'));
m_nSize += Length;
}
catch
{
return false;
}
return true;
}
public bool Read(ref MUID uidChar)
{
return Read(ref uidChar.uidLow) && Read(ref uidChar.uidHigh);
}
public bool Read(ref byte[] bBuffer)
{
int nCount = 0, nSize = 0;
if (!Read(ref nCount, ref nSize))
return false;
Array.Resize<byte>(ref bBuffer, nSize);
return Read(ref bBuffer, 0, nSize);
}
public bool Read(ref int size, ref int count)
{
int totalsize = 0;
return Read(ref totalsize) && Read(ref size) && Read(ref count) && (m_bBuffer.Length - m_nSize) >= (size * count);
}
public static UInt16 CalculateChecksum(byte[] buf, int index, int length)
{
UInt32 sum1 = (UInt32)buf[index] + buf[index + 1] + buf[index + 2] + buf[index + 3];
UInt32 sum2 = 0;
for (int x = 6; x < length; ++x) sum2 += buf[index + x];
UInt32 sum3 = sum2 - sum1;
UInt32 sum4 = sum3 >> 0x10;
sum3 += sum4;
return (UInt16)sum3;
}
public static void Decrypt(byte[] buf, int index, int length, byte[] Key)
{
for (int i = 0; i < length; ++i)
{
byte a = buf[index + i];
a ^= 0x0F0;
byte b = (byte)(7 & a);
b <<= 5;
a >>= 3;
b = (byte)(a | b);
buf[index + i] = (byte)(b ^ Key[i % 32]);
}
}
public static void Encrypt(byte[] buf, int index, int length, byte[] Key)
{
for (int i = 0; i < length; ++i)
{
ushort a = buf[index + i];
a ^= Key[i % 32];
a <<= 3;
byte b = (byte)(a >> 8);
b |= (byte)(a & 0xFF);
b ^= 0xF0;
buf[index + i] = (byte)b;
}
}
public void Finalize(byte[] Key)
{
byte[] szBuffer = new byte[m_nSize + 8];
byte[] zero = new byte[2] { 0x00, 0x00 };
ushort wSize = (ushort)(m_nSize + 8);
Buffer.BlockCopy(BitConverter.GetBytes((byte)m_PacketVersion), 0, szBuffer, 0, 2);
Buffer.BlockCopy(BitConverter.GetBytes(m_nSize + 8), 0, szBuffer, 2, 2);
Buffer.BlockCopy(zero, 0, szBuffer, 4, 2);
Buffer.BlockCopy(BitConverter.GetBytes(m_nSize + 2), 0, szBuffer, 6, 2);
Buffer.BlockCopy(m_bBuffer, 0, szBuffer, 8, m_nSize);
ushort Command = BitConverter.ToUInt16(szBuffer, 8);
if (m_PacketVersion == PacketEncryption.Encrypted)
{
GunzPacket.Encrypt(szBuffer, 2, 2, Key);
GunzPacket.Encrypt(szBuffer, 6, m_nSize + 2, Key);
}
Buffer.BlockCopy(BitConverter.GetBytes(CalculateChecksum(szBuffer, 0, wSize)), 0, szBuffer, 4, 2);
Array.Resize<byte>(ref m_bBuffer, wSize);
Array.Clear(m_bBuffer, 0, wSize);
Buffer.BlockCopy(szBuffer, 0, m_bBuffer, 0, wSize);
}
public GunzPacket(ushort pOpcode, PacketEncryption pEncryption, byte[] pBuffer, int iLength)
{
m_PacketOperation = pOpcode;
m_PacketVersion = pEncryption;
Buffer.BlockCopy(pBuffer, 0, m_bBuffer, 0, iLength);
m_nSize = 11;
m_nOrgSize = iLength;
}
public GunzPacket(byte[] pBuffer)
{
m_PacketVersion = (PacketEncryption)pBuffer[0];
m_PacketOperation = BitConverter.ToUInt16(pBuffer, 8);
m_nOrgSize = BitConverter.ToUInt16(pBuffer, 2);
Buffer.BlockCopy(pBuffer, 0, m_bBuffer, 0, m_nOrgSize);
m_nSize = 11;
}
public GunzPacket(ushort pOpcode, PacketEncryption pEncryption, byte pCount)
{
m_PacketVersion = pEncryption;
m_PacketOperation = pOpcode;
Write((short)pOpcode);
Write(pCount);
}
}
}
4-5 minutes of developing. Get good kid.