Code:
#include <string>
#include <conio.h>
#include <windows.h>
#include "packet.h"
#include "struct.h"
#define BUFFER_SIZE 256
BYTE ran[] = {0x37, 0x04, 0x5D, 0x2E, 0x43, 0x3A, 0x49, 0x53, 0x50, 0x05, 0x13, 0xC9, 0x28, 0xA4, 0x4D, 0x05};
BYTE xor[] = {0x57, 0x02, 0x5B, 0x04, 0x34, 0x06, 0x01, 0x08, 0x37, 0x0A, 0x12, 0x69, 0x41, 0x38, 0x0F, 0x78};
#define VERSION 0x3a
#define FILELIST_CRC 0
#define ACCOUNT_NAME "testing22"
#define CHAR_NAME "testing22"
#define ACCOUNT_PASSWORD "notreallysecure"
#define HOME_CHANNEL MUID(0, 1)
MUID SVID;
MUID MYID;
MUID CHID;
BYTE KEY[32];
BYTE COUNTER;
SOCKET SOCK;
sockaddr_in SIN;
void WriteHex(void* A, char* B){
std::string patchstring = B;
char* token = strtok((char*)patchstring.c_str(), " ");
for(int i = 0; token != NULL; ++i){
BYTE b;
sscanf(token, "%X", &b);
((BYTE*)A)[i] = b;
token = strtok(NULL, " ");
}
}
void Talk(){
start:
SOCK = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
SIN.sin_family = AF_INET;
SIN.sin_addr.s_addr = inet_addr("89.46.35.33");
SIN.sin_port = htons(6000);
connect(SOCK, (sockaddr*)&SIN, sizeof(SIN));
PACKET_MANAGER in;
for(;;){
int rc;
rc = recv(SOCK, in.sbuffer, PACKET_MANAGER_BUFFER_SIZE, 0);
if(rc == 0 || rc == SOCKET_ERROR){
printf("DISCONNECTED\n");
goto start;
}
if(in.packet->version == 0xA){
printf("HANDSHAKE\n");
in.index = 6;
SVID = in.READ<MUID>();
MYID = in.READ<MUID>();
DWORD time = in.READ<DWORD>();
memcpy(KEY, in.buffer + 22, 4);
memcpy(KEY + 4, in.buffer + 10, 12);
memcpy(KEY + 16, ran, 16);
for(int i = 0; i < 16; ++i){
KEY[i] ^= xor[i];
}
PACKET_MANAGER out;
out.index = 8;
out.WRITE<WORD>(0x3e9);//login
out.WRITE<BYTE>(++COUNTER);//counter
out.WRITES(ACCOUNT_NAME);//name
out.WRITES(ACCOUNT_PASSWORD);//pass
out.WRITE<int>(VERSION);//version
out.WRITE<DWORD>(FILELIST_CRC);//crc
FILE* hashfile = fopen("hash.txt", "rb");
char hashstring[3 * 16];
fread(hashstring, 3, 16, hashfile);
fclose(hashfile);
BYTE hash[16];
WriteHex(hash, hashstring);
out.WRITEB(1, 16);//md5
out.WRITER((void*)hash, 16);
out.SET<WORD>(out.packet->size - 6, 6);
out.ENCRYPT(KEY);
send(SOCK, out.sbuffer, out.index, 0);
continue;
}
if(in.packet->version == 0x65){
in.DECRYPT(KEY);
}
WORD command = in.GET<WORD>(8);
switch(command){
case 0x142:{//ping
in.index = 11;
DWORD time = in.READ<DWORD>();
PACKET_MANAGER out;
out.index = 8;
out.WRITE<WORD>(0x143);//pong
out.WRITE<BYTE>(++COUNTER);//counter
out.WRITE<DWORD>(time);//time
out.SET<WORD>(out.packet->size - 6, 6);
out.ENCRYPT(KEY);
send(SOCK, out.sbuffer, out.index, 0);
break;
}
case 0x169:{//clock synch
break;
}
case 0x192:{//announce
in.index = 11;
int type = in.READ<int>();
char* msg = in.READS();
PACKET_MANAGER out;
out.index = 8;
out.WRITE<WORD>(0x4c9);//request channel chat
out.WRITE<BYTE>(++COUNTER);//counter
out.WRITE<MUID>(MYID);
out.WRITE<MUID>(CHID);
out.WRITES(msg);
out.SET<WORD>(out.packet->size - 6, 6);
out.ENCRYPT(KEY);
send(SOCK, out.sbuffer, out.index, 0);
break;
}
case 0x1f5:{//admin announce
in.index = 11;
MUID adminid = in.READ<MUID>();
char* message = in.READS();
printf("WALL: %s\n", message);
break;
}
case 0x3ea:{//response login
in.index = 11;
DWORD result = in.READ<DWORD>();
if(result != 0){
printf("LOGIN FAILED: %d\n", result);
goto start;
}
PACKET_MANAGER out;
out.index = 8;
out.WRITE<WORD>(0x6a5);//request char list
out.WRITE<BYTE>(++COUNTER);
out.WRITEB(1, 1);//dunno, but needed (message)
out.WRITE<BYTE>(0);
out.SET<WORD>(out.packet->size - 6, 6);
out.ENCRYPT(KEY);
send(SOCK, out.sbuffer, out.index, 0);
break;
}
case 0x4b7:{//response channel join
in.index = 11;
CHID = in.READ<MUID>();
DWORD type = in.READ<DWORD>();
char* name = in.READS();
printf("JOINED CHANNEL '%s'\n", name);
break;
}
case 0x4c6:{//channel player list
break;
}
case 0x4ca:{//channel chat
in.index = 11;
MUID id = in.READ<MUID>();
char* name = in.READS();
char* msg = in.READS();
int ugrade = in.READ<int>();
printf("%s: %s\n", name, msg);
if(id == MYID){
break;
}
char buffer[BUFFER_SIZE];
char* command = strtok(msg, " ");
if(command == NULL){
break;
}
if(_stricmp(command, "!stats") == 0){
sprintf_s(buffer, BUFFER_SIZE, "/stats %s", name);
char* target = strtok(NULL, "");
if(target != NULL){
sprintf_s(buffer, BUFFER_SIZE, "/stats %s", target);
}
PACKET_MANAGER out;
out.index = 8;
out.WRITE<WORD>(0x4c9);//request channel chat
out.WRITE<BYTE>(++COUNTER);//counter
out.WRITE<MUID>(MYID);//player id
out.WRITE<MUID>(MUID(0, -1));//channel id
out.WRITES(buffer);//message
out.SET<WORD>(out.packet->size - 6, 6);
out.ENCRYPT(KEY);
send(SOCK, out.sbuffer, out.index, 0);
break;
}
break;
}
case 0x4cf:{//channel rules
break;
}
case 0x522:{//stage list
break;
}
case 0x641:{
in.index = 11;
char* sender = in.READS();
char* receiver = in.READS();
char* msg = in.READS();
printf("from %s: %s\n", sender, msg);
PACKET_MANAGER out;
out.index = 8;
out.WRITE<WORD>(0x4c9);//request channel chat
out.WRITE<BYTE>(++COUNTER);//counter
out.WRITE<MUID>(MYID);
out.WRITE<MUID>(CHID);
char buffer[BUFFER_SIZE];
sprintf_s(buffer, BUFFER_SIZE, "%s says '%s'", sender, msg);
out.WRITES(buffer);
out.SET<WORD>(out.packet->size - 6, 6);
out.ENCRYPT(KEY);
send(SOCK, out.sbuffer, out.index, 0);
break;
}
case 0x6a6:{//response char list
in.index = 11;
in.READ<int>();//blob total size
in.READ<int>();//blob member size
int count = in.READ<int>();//blob member count
if(count > 0){
MTD_CharListInfo cli = in.READ<MTD_CharListInfo>();
PACKET_MANAGER out;
out.index = 8;
out.WRITE<WORD>(0x6a7);//request select char
out.WRITE<BYTE>(++COUNTER);
out.WRITE<MUID>(MYID);//player id
out.WRITE<int>(cli.nIndex);//index of char
out.SET<WORD>(out.packet->size - 6, 6);
out.ENCRYPT(KEY);
send(SOCK, out.sbuffer, out.index, 0);
break;
}
if(count == 0){
MTD_CharListInfo cli = in.READ<MTD_CharListInfo>();
PACKET_MANAGER out;
out.index = 8;
out.WRITE<WORD>(0x6af);//request create char
out.WRITE<BYTE>(++COUNTER);
out.WRITE<MUID>(MYID);//player id
out.WRITE<int>(0);//index
out.WRITES(CHAR_NAME);//name
out.WRITE<int>(0);//sex
out.WRITE<int>(0);//hair
out.WRITE<int>(0);//face
out.WRITE<int>(0);//class
out.SET<WORD>(out.packet->size - 6, 6);
out.ENCRYPT(KEY);
send(SOCK, out.sbuffer, out.index, 0);
break;
}
}
case 0x6a8:{//response select character
in.index = 11;
DWORD result = in.READ<DWORD>();
PACKET_MANAGER out;
out.index = 8;
out.WRITE<WORD>(0x4b5);//request channel join
out.WRITE<BYTE>(++COUNTER);
out.WRITE<MUID>(MYID);//player id
out.WRITE<MUID>(HOME_CHANNEL);//channel id
out.SET<WORD>(out.packet->size - 6, 6);
out.ENCRYPT(KEY);
send(SOCK, out.sbuffer, out.index, 0);
break;
}
case 0x6b0:{//response select character
in.index = 11;
DWORD result = in.READ<DWORD>();
if(result != 0){
printf("CHARACTER CREATION FAILED: %d\n", result);
goto start;
}
PACKET_MANAGER out;
out.index = 8;
out.WRITE<WORD>(0x6a5);//request char list
out.WRITE<BYTE>(++COUNTER);
out.WRITEB(1, 1);//dunno, but needed (message)
out.WRITE<BYTE>(0);
out.SET<WORD>(out.packet->size - 6, 6);
out.ENCRYPT(KEY);
send(SOCK, out.sbuffer, out.index, 0);
break;
}
default:{
print_packet((BYTE*)in.buffer, in.packet->size);
break;
}
}
}
}
int main(){
WSAData wsad;
WSAStartup(0x202, &wsad);
Talk();
return 0;
}