Here's some of my code for my proxy in C#.
Envy.cs
PHP Code:
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
using System.Threading;
using System.Data.SqlClient;
using Envy.Prototypes;
using Envy.Packets;
namespace Envy.Core
{
class Envy
{
private static Socket m_nSocket;
public static Config m_serverConfig;
private static List<ProxyConnection> m_clientList = new List<ProxyConnection>();
private static void AcceptCallback(IAsyncResult iResult)
{
try
{
ProxyConnection proxyConnection;
Socket client = m_nSocket.EndAccept(iResult);
((Socket)iResult.AsyncState).BeginAccept(new AsyncCallback(AcceptCallback), ((Socket)iResult.AsyncState));
Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
server.Connect(m_serverConfig.ServerIP, m_serverConfig.ServerPort);
if (server.Connected)
{
proxyConnection = new ProxyConnection(client, server);
lock (m_clientList)
m_clientList.Add(proxyConnection);
}
}
catch
{
((Socket)iResult.AsyncState).BeginAccept(new AsyncCallback(AcceptCallback), ((Socket)iResult.AsyncState));
}
}
public static void Main(string[] args)
{
try
{
LogManager.LogType = LogLevel.All;
Console.WindowWidth = Console.BufferWidth = 120;
Console.Title = "Envy Core";
m_serverConfig = Config.Deserialize();
if (!Database.createConnection())
{
LogManager.Write(LogLevel.Error, "Error loading database");
return;
}
m_nSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
m_nSocket.Bind(new IPEndPoint(IPAddress.Any, m_serverConfig.RedirectPort));
m_nSocket.Listen(8);
m_nSocket.BeginAccept(new AsyncCallback(AcceptCallback), m_nSocket);
new Thread(new ThreadStart(ServerMonitor)).Start();
LogManager.Write(LogLevel.Info, "Redirecting to: {0}:{1}. Listening on port: {2}", m_serverConfig.ServerIP, m_serverConfig.ServerPort, m_serverConfig.RedirectPort);
PacketManagement.Initialize();
AddShellCode();
}
catch (Exception e)
{
LogManager.Write(LogLevel.Error, "Error: {0}", e);
}
}
public static void ServerMonitor()
{
DateTime serverStart = DateTime.Now;
while (true)
{
Thread.Sleep(TimeSpan.FromMinutes(5));
LogManager.Write(LogLevel.Info, "Garbage Collection : {0}kbs. Uptime: {1}", GC.GetTotalMemory(false) / 1024, (DateTime.Now - serverStart));
}
}
public static void AddShellCode()
{
ShellCode.Clear();
SqlDataReader sDR = Database.getReader("SELECT * FROM shellcode WHERE Login=1");
while (sDR.Read())
ShellCode.Add(Convert.ToString(sDR["Bytes"]), Convert.ToString(sDR["Name"]));
sDR.Close();
LogManager.Write(LogLevel.Info, "Added: {0} shellcodes.", ShellCode.getShellCodes().Count);
}
public static ProxyConnection FindClient(string szName)
{
lock (m_clientList)
{
return m_clientList.Find(c => c.m_szCharacter.ToLower() == szName.ToLower());
}
}
public static void RemoveClient(ProxyConnection proxyConnection)
{
lock (m_clientList)
{
m_clientList.Remove(proxyConnection);
}
}
public static List<ProxyConnection> GetClients()
{
return m_clientList;
}
public static List<ProxyConnection> GetStaff()
{
lock (m_clientList)
return m_clientList.FindAll(c => c.m_nUGradeID >= 252 && c.m_nUGradeID != 253);
}
}
}
ProxySocket.cs
PHP Code:
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Envy.Core;
using Envy.Packets;
namespace Envy.Prototypes
{
public class ProxyConnection
{
public Socket m_nClientSocket;
public Socket m_nServerSocket;
public string m_szClientIP = "";
public string m_szAccount = "";
public string m_szCharacter = "";
public UInt64 m_nSessionID = 0;
public Int32 m_nAID = 0;
public Int32 m_nCID = 0;
public Int32 m_nClientRecv = 0;
public Int32 m_nServerRecv = 0;
public byte m_nUGradeID = 0;
public byte m_nPGradeID = 0;
private byte[] m_bClientRecv = new byte[4096];
private byte[] m_bServerRecv = new byte[4096];
private byte[] m_bClientStream = new byte[0];
private byte[] m_bServerStream = new byte[0];
public byte[] m_bEncryptKey = new byte[32];
public bool Rank { get { return (m_nUGradeID >= 252 && m_nUGradeID != 253); } }
private Queue<GunzPacket> ClientQueue = new Queue<GunzPacket>();
private Queue<GunzPacket> ServerQueue = new Queue<GunzPacket>();
public void Notify(string sMessage, Int32 nType)
{
GunzPacket packet = new GunzPacket(0x1F5, PacketEncryption.Encrypted, 0);
packet.Write(m_nSessionID);
packet.Write(sMessage);
packet.Write(nType);
packet.Finalize(m_bEncryptKey);
byte[] bPacket = packet.getPacket();
m_nClientSocket.Send(bPacket);
}
public void ClientSend(GunzPacket Packet)
{
Packet.Finalize(m_bEncryptKey);
m_nClientSocket.Send(Packet.getPacket());
}
public void Disconnect()
{
if (m_nClientSocket.Connected)
m_nClientSocket.Shutdown(SocketShutdown.Both);
if (m_nServerSocket.Connected)
m_nServerSocket.Shutdown(SocketShutdown.Both);
}
private void OnClientRecv(IAsyncResult iResult)
{
int nIndex = 0;
try
{
nIndex = m_nClientSocket.EndReceive(iResult);
}
catch (Exception e)
{
LogManager.Write(LogLevel.Error, "[{0}]Client Error: {1}", m_szClientIP, e.Message);
Disconnect();
return;
}
if (nIndex < 1)
{
LogManager.Write(LogLevel.Info, "[{0}]Client Disconnected", m_szClientIP);
Disconnect();
return;
}
byte[] bTempData = new byte[m_bClientStream.Length + nIndex];
Buffer.BlockCopy(m_bClientRecv, 0, bTempData, m_bClientStream.Length, nIndex);
if (m_bClientStream.Length > 0)
Buffer.BlockCopy(m_bClientStream, 0, bTempData, 0, m_bClientStream.Length);
m_bClientStream = bTempData;
try
{
ProcessClientStream();
m_bClientRecv = new byte[4096];
m_nClientSocket.BeginReceive(m_bClientRecv, 0, 40*** SocketFlags.None, new AsyncCallback(OnClientRecv), m_nClientSocket);
}
catch (Exception e)
{
LogManager.Write(LogLevel.Error, "Client Processing Error: {0}", e.Message);
Disconnect();
return;
}
}
private void ProcessClientStream()
{
bool bFinishedStream = false;
Int32 nStreamPosition = 0;
while (!bFinishedStream && (nStreamPosition < m_bClientStream.Length))
{
if ((m_bClientStream.Length - nStreamPosition) >= 6)
{
byte[] bPacket = new byte[6];
Buffer.BlockCopy(m_bClientStream, nStreamPosition, bPacket, 0, 6);
if ((PacketEncryption)bPacket[0] == PacketEncryption.Encrypted)
{
GunzPacket.Decrypt(bPacket, 2, 2, m_bEncryptKey);
UInt16 nTotalSize = BitConverter.ToUInt16(bPacket, 2);
if ((m_bClientStream.Length - nStreamPosition) >= nTotalSize)
{
bPacket = new byte[nTotalSize];
Buffer.BlockCopy(m_bClientStream, nStreamPosition, bPacket, 0, nTotalSize);
GunzPacket.Decrypt(bPacket, 2, 2, m_bEncryptKey);
GunzPacket.Decrypt(bPacket, 6, nTotalSize - 6, m_bEncryptKey);
GunzPacket packet = new GunzPacket(bPacket);
lock (ClientQueue)
{
ClientQueue.Enqueue(packet);
}
ProcessClientPacketQueue(null);
nStreamPosition += nTotalSize;
}
else bFinishedStream = true;
}
else if ((PacketEncryption)bPacket[0] == PacketEncryption.Decrypted)
{
UInt16 nTotalSize = BitConverter.ToUInt16(bPacket, 2);
if ((m_bClientStream.Length - nStreamPosition) >= nTotalSize)
{
bPacket = new byte[nTotalSize];
Buffer.BlockCopy(m_bClientStream, nStreamPosition, bPacket, 0, nTotalSize);
GunzPacket packet = new GunzPacket(bPacket);
lock (ClientQueue)
{
ClientQueue.Enqueue(packet);
}
ProcessClientPacketQueue(null);
nStreamPosition += nTotalSize;
}
else
bFinishedStream = true;
}
else if ((PacketEncryption)bPacket[0] == PacketEncryption.AntiHack)
{
if ((m_bClientStream.Length - nStreamPosition) >= 20)
{
bPacket = new byte[20];
Buffer.BlockCopy(m_bClientStream, nStreamPosition, bPacket, 0, 20);
Int32 nAddress1 = BitConverter.ToInt32(bPacket, 15);
LogManager.Write(LogLevel.Info, "Found Hack: {0:X}", nAddress1);
nStreamPosition += 20;
}
}
else
{
UInt16 nTotalSize = BitConverter.ToUInt16(bPacket, 2);
nStreamPosition += nTotalSize;
}
}
else bFinishedStream = true;
}
byte[] bTempBuffer = new byte[m_bClientStream.Length - nStreamPosition];
Buffer.BlockCopy(m_bClientStream, nStreamPosition, bTempBuffer, 0, m_bClientStream.Length - nStreamPosition);
m_bClientStream = bTempBuffer;
}
private void ProcessClientPacketQueue(object pObject)
{
while (ClientQueue.Count > 0 && m_nClientSocket.Connected)
{
GunzPacket packet = ClientQueue.Dequeue();
if (PacketManagement.m_dOperation.ContainsKey (packet.getOperation()))
{
packet = PacketManagement.m_dOperation.GetValue (packet.getOperation()) (this, packet, true);
if (packet == null)
continue;
}
byte[] bPacket = packet.getPacket();
int nSize = packet.fixSize();
LogManager.Write(LogLevel.Info, "[{0}]Client Sending: {1:X}", m_szClientIP, packet.getOperation());
if (packet.getVersion() == PacketEncryption.Encrypted)
{
GunzPacket.Encrypt(bPacket, 2, 2, m_bEncryptKey);
GunzPacket.Encrypt(bPacket, 6, nSize - 6, m_bEncryptKey);
}
m_nServerSocket.Send(bPacket, nSize, SocketFlags.None);
}
}
private void OnServerRecv(IAsyncResult iResult)
{
int nIndex = 0;
try
{
nIndex = m_nServerSocket.EndReceive(iResult);
}
catch
{
Disconnect();
return;
}
if (nIndex < 1)
{
Disconnect();
return;
}
byte[] bTempData = new byte[m_bServerStream.Length + nIndex];
Buffer.BlockCopy(m_bServerRecv, 0, bTempData, m_bServerStream.Length, nIndex);
if (m_bServerStream.Length > 0)
Buffer.BlockCopy(m_bServerStream, 0, bTempData, 0, m_bServerStream.Length);
m_bServerStream = bTempData;
try
{
ProcessServerStream();
m_bServerRecv = new byte[4096];
m_nServerSocket.BeginReceive(m_bServerRecv, 0, 40*** SocketFlags.None, new AsyncCallback(OnServerRecv), m_nServerSocket);
}
catch (Exception e)
{
LogManager.Write(LogLevel.Error, "Server Processing Error: {0}", e.Message);
Disconnect();
return;
}
}
private void ProcessServerStream()
{
bool bFinishedStream = false;
Int32 nStreamPosition = 0;
while (!bFinishedStream && (nStreamPosition < m_bServerStream.Length))
{
if ((m_bServerStream.Length - nStreamPosition) >= 6)
{
byte[] bPacket = new byte[6];
Buffer.BlockCopy(m_bServerStream, nStreamPosition, bPacket, 0, 6);
if ((PacketEncryption)bPacket[0] == PacketEncryption.Exchange)
{
UInt16 nTotalSize = BitConverter.ToUInt16(bPacket, 2);
if ((m_bServerStream.Length - nStreamPosition) >= nTotalSize)
{
bPacket = new byte[nTotalSize];
Buffer.BlockCopy(m_bServerStream, nStreamPosition, bPacket, 0, nTotalSize);
int nSent = m_nClientSocket.Send(bPacket);
m_nSessionID = BitConverter.ToUInt64(bPacket, 18);
byte[] bKey = new byte[] { 0x57, 0x02, 0x5b, 0x04, 0x34, 0x06, 0x01, 0x08, 0x37, 0x0a, 0x12, 0x69, 0x41, 0x38, 0x0f, 0x78 };
byte[] bTempPacket = new byte[16];
Buffer.BlockCopy(bPacket, 10, bTempPacket, 0, 16);
Buffer.BlockCopy(bTempPacket, 12, m_bEncryptKey, 0, 4);
Buffer.BlockCopy(bTempPacket, 0, m_bEncryptKey, 4, 12);
Buffer.BlockCopy(new byte[] { 0x37, 0x04, 0x5d, 0x2e, 0x43, 0x38, 0x49, 0x53, 0x50, 0x05, 0x13, 0xc9, 0x28, 0xA4, 0x4d, 0x05 }, 0, m_bEncryptKey, 16, 16);
for (int i = 0; i < 4; ++i)
{
uint a = BitConverter.ToUInt32(bKey, i * 4);
uint b = BitConverter.ToUInt32(m_bEncryptKey, i * 4);
Buffer.BlockCopy(BitConverter.GetBytes(a ^ b), 0, m_bEncryptKey, i * 4, 4);
}
nStreamPosition += nTotalSize;
}
else bFinishedStream = true;
}
else if ((PacketEncryption)bPacket[0] == PacketEncryption.Encrypted)
{
GunzPacket.Decrypt(bPacket, 2, 2, m_bEncryptKey);
UInt16 nTotalSize = BitConverter.ToUInt16(bPacket, 2);
if ((m_bServerStream.Length - nStreamPosition) >= nTotalSize)
{
bPacket = new byte[nTotalSize];
Buffer.BlockCopy(m_bServerStream, nStreamPosition, bPacket, 0, nTotalSize);
GunzPacket.Decrypt(bPacket, 2, 2, m_bEncryptKey);
GunzPacket.Decrypt(bPacket, 6, nTotalSize - 6, m_bEncryptKey);
GunzPacket packet = new GunzPacket(bPacket);
lock (ServerQueue)
{
ServerQueue.Enqueue(packet);
//ThreadPool.QueueUserWorkItem(ProcessServerPacketQueue);
}
ProcessServerPacketQueue(null);
nStreamPosition += nTotalSize;
}
else bFinishedStream = true;
}
else if ((PacketEncryption)bPacket[0] == PacketEncryption.Decrypted)
{
UInt16 nTotalSize = BitConverter.ToUInt16(bPacket, 2);
if ((m_bServerStream.Length - nStreamPosition) >= nTotalSize)
{
bPacket = new byte[nTotalSize];
Buffer.BlockCopy(m_bServerStream, nStreamPosition, bPacket, 0, nTotalSize);
GunzPacket packet = new GunzPacket(bPacket);
lock (ServerQueue)
{
ServerQueue.Enqueue(packet);
//ThreadPool.QueueUserWorkItem(ProcessServerPacketQueue);
}
ProcessServerPacketQueue(null);
nStreamPosition += nTotalSize;
}
else bFinishedStream = true;
}
}
else bFinishedStream = true;
}
byte[] bTempBuffer = new byte[m_bServerStream.Length - nStreamPosition];
Buffer.BlockCopy(m_bServerStream, nStreamPosition, bTempBuffer, 0, m_bServerStream.Length - nStreamPosition);
m_bServerStream = bTempBuffer;
}
private void ProcessServerPacketQueue(object pObject)
{
while (ServerQueue.Count > 0 && m_nServerSocket.Connected)
{
GunzPacket packet = ServerQueue.Dequeue();
if (PacketManagement.m_dOperation.ContainsKey(packet.getOperation()))
{
packet = PacketManagement.m_dOperation.GetValue(packet.getOperation())(this, packet, false);
if (packet == null)
continue;
}
byte[] bPacket = packet.getPacket();
int nSize = packet.fixSize();
LogManager.Write(LogLevel.Info, "[{0}]Server Sending: {1:X}", m_szClientIP, packet.getOperation());
if (packet.getVersion() == PacketEncryption.Encrypted)
{
GunzPacket.Encrypt(bPacket, 2, 2, m_bEncryptKey);
GunzPacket.Encrypt(bPacket, 6, nSize - 6, m_bEncryptKey);
}
m_nClientSocket.Send(bPacket, nSize, SocketFlags.None);
}
}
public ProxyConnection(Socket clientSocket, Socket serverSocket)
{
m_nClientSocket = clientSocket;
m_nServerSocket = serverSocket;
m_szClientIP = ((IPEndPoint)m_nClientSocket.RemoteEndPoint).Address.ToString();
LogManager.Write(LogLevel.Error, "[{0}]Proxying Connection.", m_szClientIP);
m_nClientSocket.BeginReceive(m_bClientRecv, 0, 40*** SocketFlags.None, new AsyncCallback(OnClientRecv), m_nClientSocket);
m_nServerSocket.BeginReceive(m_bServerRecv, 0, 40*** SocketFlags.None, new AsyncCallback(OnServerRecv), m_nServerSocket);
}
}
}
Packet.cs
PHP 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);
}
}
}