Code:
module game.crypto.gamecrypto;
import network.packet;
private class CryptoData : DataPacket {
this() {
super();
}
}
private class CryptoCounter {
ushort m_counter = 0;
@property {
ubyte key1() {
return cast(ubyte)(m_counter & 0xFF);
}
ubyte key2() {
return cast(ubyte)(m_counter >> 8);
}
}
void increment() {
m_counter++;
}
void reset() {
m_counter = 0;
}
}
class GameCrypto {
private:
enum keySize = 256;
CryptoCounter m_encryptCounter, m_decryptCounter;
ubyte[] crypt1;
ubyte[] crypt2;
ubyte[] crypt3;
ubyte[] crypt4;
bool m_alternate;
public:
this() {
m_alternate = false;
m_encryptCounter = new CryptoCounter;
m_decryptCounter = new CryptoCounter;
crypt1 = new ubyte[256];
crypt2 = new ubyte[256];
ubyte i_key1 = 157;
ubyte i_key2 = 98;
foreach (i; 0 .. 256)
{
crypt1[i] = i_key1;
crypt2[i] = i_key2;
i_key1 = cast(ubyte)((0xF + cast(ubyte)(i_key1 * 0xFA)) * i_key1 + 0x13);
i_key2 = cast(ubyte)((0x79 - cast(ubyte)(i_key2 * 0x5C)) * i_key2 + 0x6D);
}
}
ubyte[] encrypt(ubyte[] inBuffer) {
synchronized {
ubyte[] buffer = inBuffer.dup;
foreach (i; 0 .. buffer.length) {
buffer[i] ^= 0xAB;
buffer[i] = cast(ubyte)(buffer[i] >> 4 | buffer[i] << 4);
buffer[i] ^= cast(ubyte)(crypt1[m_encryptCounter.key1] ^ crypt2[m_encryptCounter.key2]);
m_encryptCounter.increment();
}
return buffer;
}
}
ubyte[] decrypt(ubyte[] inBuffer) {
synchronized {
ubyte[] buffer = inBuffer.dup;
if (!m_alternate) {
foreach (i; 0 .. buffer.length) {
buffer[i] ^= 0xAB;
buffer[i] = cast(ubyte)(buffer[i] >> 4 | buffer[i] << 4);
buffer[i] ^= cast(ubyte)(crypt2[m_decryptCounter.key2] ^ crypt1[m_decryptCounter.key1]);
m_decryptCounter.increment();
}
}
else {
foreach (i; 0 .. buffer.length) {
buffer[i] ^= 0xAB;
buffer[i] = cast(ubyte)(buffer[i] >> 4 | buffer[i] << 4);
buffer[i] ^= cast(ubyte)(crypt4[m_decryptCounter.key2] ^ crypt3[m_decryptCounter.key1]);
m_decryptCounter.increment();
}
}
return buffer;
}
}
void setKeys(uint accountId, uint token)
{
synchronized {
uint tmpkey1 = cast(uint)((((token) + accountId) ^ 0x4321) ^ (token));
uint tmpkey2 = cast(uint)(tmpkey1 * tmpkey1);
crypt3 = new ubyte[0x100];
crypt4 = new ubyte[0x100];
auto temp = new CryptoData;
temp.write!uint(tmpkey1);
ubyte[] tmp1 = temp.pBuffer;
temp = new CryptoData;
temp.write!uint(tmpkey2);
ubyte[] tmp2 = temp.pBuffer;
foreach (i; 0 .. 256)
{
crypt3[i] = cast(ubyte)(crypt1[i] ^ tmp1[i % 4]);
crypt4[i] = cast(ubyte)(crypt2[i] ^ tmp2[i % 4]);
}
m_alternate = true;
}
}
}
I don't know what the hell I did, but it works now.






