From 64b279351954b65243eef946df999c35310517f9 Mon Sep 17 00:00:00 2001 From: Joon Park Date: Sat, 7 Mar 2020 09:11:55 -0500 Subject: [PATCH] . --- Source/core/core/network/connection.cpp | 7 +- Source/core/core/network/connection.h | 5 +- Source/xgmsv/test_server/mmo_server.cpp | 95 ++++- Source/xgmsv/test_server/xg_crypto.h | 441 ++++++++++++++++++++++-- Source/xgmsv/test_server/xg_packet.h | 89 ++++- 5 files changed, 597 insertions(+), 40 deletions(-) diff --git a/Source/core/core/network/connection.cpp b/Source/core/core/network/connection.cpp index 94761d1..82bfe0c 100644 --- a/Source/core/core/network/connection.cpp +++ b/Source/core/core/network/connection.cpp @@ -17,8 +17,8 @@ namespace server marked_for_delete(false), parent(nullptr), socket(std::move(new_socket)), - rbuffer(1024), - wbuffer(1024), + rbuffer(4096), + wbuffer(4096), rqueue(this), wqueue(this) { @@ -55,6 +55,8 @@ namespace server uint32 id = connection->id; if (connection->marked_for_delete) { + + /* if (connection->parent) { connection->parent->remove_connection(connection); @@ -64,6 +66,7 @@ namespace server connection = nullptr; this->conneciton_count--; connections_purged++; + */ } } } diff --git a/Source/core/core/network/connection.h b/Source/core/core/network/connection.h index cb217e3..f587d35 100644 --- a/Source/core/core/network/connection.h +++ b/Source/core/core/network/connection.h @@ -32,7 +32,7 @@ namespace server frame_data() : wpos(0), rpos(0), wsize(0), packet_count(0) { - data.resize(1024); + data.resize(4096); packets.resize(128); } }; @@ -199,7 +199,8 @@ namespace server { memcpy(wptr, source, size); rpos = wpos; - wpos += size; + rend += size; + wpos = rend; return wptr; } diff --git a/Source/xgmsv/test_server/mmo_server.cpp b/Source/xgmsv/test_server/mmo_server.cpp index c81df61..efcef64 100644 --- a/Source/xgmsv/test_server/mmo_server.cpp +++ b/Source/xgmsv/test_server/mmo_server.cpp @@ -15,6 +15,85 @@ #pragma warning(push) #pragma warning(disable : 26444) +BOOL utf8ToGBK(char* str, int size) +{ + char temp[2048]; + + // UTF-8 to UTF-16 + int size_needed = MultiByteToWideChar(CP_UTF8, 0, str, size, NULL, 0); + MultiByteToWideChar(CP_UTF8, 0, str, size, (LPWSTR)temp, size_needed); + + if (size_needed > 1024) + { + return FALSE; + } + + // UTF-16 to Big5(950) + int size_needed2 = WideCharToMultiByte(936, 0, (LPCWCH)temp, size_needed, NULL, 0, NULL, NULL); + WideCharToMultiByte(936, 0, (LPCWCH)temp, size_needed, str, size, NULL, NULL); + + return TRUE; +} + +BOOL GBKToUtf8(char* str, int size) +{ + char temp[2048]; + + // UTF-8 to UTF-16 + int size_needed = MultiByteToWideChar(936, 0, str, size, NULL, 0); + MultiByteToWideChar(936, 0, str, size, (LPWSTR)temp, size_needed); + + if (size_needed > 1024) + { + return FALSE; + } + + // UTF-16 to Big5(950) + int size_needed2 = WideCharToMultiByte(CP_UTF8, 0, (LPCWCH)temp, size_needed, NULL, 0, NULL, NULL); + WideCharToMultiByte(CP_UTF8, 0, (LPCWCH)temp, size_needed, str, size, NULL, NULL); + + return TRUE; +} + +BOOL utf8ToBig5(char* str, int size) +{ + char temp[2048]; + + // UTF-8 to UTF-16 + int size_needed = MultiByteToWideChar(CP_UTF8, 0, str, size, NULL, 0); + MultiByteToWideChar(CP_UTF8, 0, str, size, (LPWSTR)temp, size_needed); + + if (size_needed > 1024) + { + return FALSE; + } + + // UTF-16 to Big5(950) + int size_needed2 = WideCharToMultiByte(950, 0, (LPCWCH)temp, size_needed, NULL, 0, NULL, NULL); + WideCharToMultiByte(950, 0, (LPCWCH)temp, size_needed, str, size, NULL, NULL); + + return TRUE; +} + +BOOL big5ToUtf8(char* str, int size) +{ + char temp[2048]; + // UTF-8 to UTF-16 + int size_needed = MultiByteToWideChar(950, 0, str, size, NULL, 0); + MultiByteToWideChar(950, 0, str, size, (LPWSTR)temp, size_needed); + + if (size_needed > 1024) + { + return FALSE; + } + + // UTF-16 to Big5(950) + int size_needed2 = WideCharToMultiByte(CP_UTF8, 0, (LPCWCH)temp, size_needed, NULL, 0, NULL, NULL); + WideCharToMultiByte(CP_UTF8, 0, (LPCWCH)temp, size_needed, str, size, NULL, NULL); + + return TRUE; +} + namespace mmo_server { using namespace server; @@ -93,13 +172,23 @@ namespace mmo_server }); //char packet4[] = "MLVlll6KdKyJmGKKII5pnmuNyMUp31qWQ7QqzcfGII5pnmuNN8X5wcMqzCuyJMAX2"; - char packet[] = "CmMMlxipiG42g1E"; + //char packet[] = "CmMMlxipiG42g1E"; //crossgate::decrypt_message(packet, sizeof(packet)); + //char packet2[] = R"(CharList 0 jason|0\\z241400\\z1\\z15\\z0\\z0\\z0\\z15\\z0\\z0\\z100\\z0\\z2\\zjason\\z2\\z游民\\z2\\z106002\\z-1| )"; - char packet2[] = "Echo nr "; + //char packet[] = "ClientLogin 0 block "; //char packet3[] = "FC "; - //crossgate::encrypt_message(packet3, sizeof(packet2) - 1); + //char packet[] = "QWHrI4t3y0x4gnZO+XBw+LGL7XYV3o5Fi98-507yuCnzU0T7YZRHP8OxQsbzdM9K-6fC9EnlhJ-eRRlhU0d4ZsWJzgBDs4Z1WPkbKs2kDNb47dw8Ff8w0tH3WMcheib0TxHZ1t0ZOrch9ID2nvd7xiZzTZHagPNmLT8RrtGLGXNAOzPph-w3eSC-HQps2DIekTuaxcYng1vgpYIgAZ8Tj9P2YjLMtU+Szf-1adkDOAcQstXdz3TukE85NMHYWfoHTv0lyhYeUk1qechP9j6FSj11vvX8HPEcvJyNLVhJI-o35jBF64unpAR+XsY1zfn3-ElvdsB7ZgXZDk7lkXoNQ6sbjmB1ath9brzXbJLzXdQb3mmDrRQ3F+4fjkiwoGn8hhzuxgLUb9BlXRc9PafSzn+C0HI5cSHLfyyoBI+41G5gQOr9-xzuxlPUb9BlXT49PaeDzn8C0mBExTCAagCAI8ZLc7W1qX5Rs0KATXAAO2Mc53Ip440JozG443chGFi-cBHklsg4kfAhEMIAyNOBlHrh3Ydz1os-c4sE-JDF9BDkhJSdGoN5LuLL3gopnMvN4DEQK7OevOQIGiO-0m3jc8t8bLhQWvUi4nse6zz7UwzdPN2wM9j95maFs6vA2EmW81VvOB5LoLDXMgIwWsE5FA44OR13216pPgyv2Lyxn6PUZLQoWYgjfYic9GY2c96MInI+OEVvSmqv3ccSysTev-4FxLjNpQDZDtG7wVyQRr3GZDBaHLFujbmI6vbvR6HeRCWzasfEcSa8gsNpZdlRC58Ce2e2JwSCdt+m50g8r22PSYCArfE8Gh87Wr3nnO4yQJSYNzBzIWV4TjEfhUwSefAmA5yd0oDzp0Ty4lHPQE9xEBJxfP1+eNGzQnwd5B1RSlWUifBr-j4A64GteBZPRZJy8Js5aQX4uJgWYCoVveOmZTAFfxWpr-cVJg3WYz6knLrpnUeFja544skgZILFG5+BKeBoUB42hoNjIeAlNwoHBRJemHwL5HPIzRWSW+9LOcHk1Z61KRU9sSBlq+oC-lf9ArCI7rk1U1v1GxngdFR+salmFfcMLX50HmY8NuQW5K9jjsUkFFan"; + char packet[] = "s7Oar2m1BIPYpdaZ1eXOVKDYpotoD5GWg-i3gjin0a3ddKFVX-TgJZBGp2PRbDC0VavRTa08l9drNWsItjIDQA"; + core::byte_buffer buf(4096); + buf.write(packet, sizeof(packet) - 1); + crossgate::decrypt_message(buf); + //crossgate::encrypt_message(buf); + + //big5ToUtf8((char*)buf.data(), buf.wpos); + + //printf("string:%s", buf.data()); core::async_every(1000ms, []() { diff --git a/Source/xgmsv/test_server/xg_crypto.h b/Source/xgmsv/test_server/xg_crypto.h index 8a307be..8889836 100644 --- a/Source/xgmsv/test_server/xg_crypto.h +++ b/Source/xgmsv/test_server/xg_crypto.h @@ -5,10 +5,66 @@ namespace server namespace crossgate { #define SEED 4595 +#define MESSAGE_SIZE(a) sizeof(a)/sizeof(char) + char mapping_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-"; + + char char9_str[] = { + 0x43, 0xd0, 0x84, 0x91, 0xc3, 0x24, 0xcd, 0x1c, + 0x3a, 0x20, 0x60, 0x80, 0x50, 0x13, 0x66, 0xce, + 0x1b, 0x37, 0x7c, 0x60, 0x70, 0xe1, 0xa2, 0x47, + 0x06, 0x8d, 0x18, 0x34, 0x60, 0x48, 0xa4, 0x18, + 0x63, 0xa2, 0x9e, 0x18, 0x35, 0x3c, 0x6e, 0xd4, + 0x33, 0x72, 0x24, 0x48, 0x91, 0x28, 0x39, 0x6a, + 0x4c, 0x59, 0xd1, 0x23, 0x43, 0x87, 0x6e, 0x3c, + 0xca, 0xf0, 0x38, 0xcd, 0xd9, 0xb0, 0x78, 0x32, + 0x3d, 0xc6, 0x80, 0x61, 0x43, 0xe3, 0x4c, 0x8a, + 0x2d, 0x62, 0xf0, 0x01, 0x01, 0x10, 0x00 + }; + + + int weird_kernel1[] = + { + // 0 1 2 3 4 5 6 7 8 + 0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF, // 0 + 0x00, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF, 0xFF, // 1 + 0x00, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF, 0xFF, 0xFF, // 2 + 0x00, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, // 3 + 0x00, 0x1F, 0x3F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 4 + 0x00, 0x3F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 5 + 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 6 + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF // 7 + }; + + int weird_kernel2[] = + { + // 0 1 2 3 4 5 6 7 8 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, // 1 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, // 2 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, // 3 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x0F, // 4 + 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, // 5 + 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, // 6 + 0x00, 0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F // 7 + }; + + // odd length encryption + struct dictionary_entry + { + unsigned char9_left : 9; + unsigned : 7; + unsigned char9_right : 9; + unsigned : 7; + + unsigned prev : 9; + unsigned : 23; + }; + + // decrypt stage 1 - int util_64to256(char* dst, const char* src, char* table, uint64 length) + int util_64to256(uint8* dst, const uint8* src, char* table, uint64 length) { unsigned int dw, dwcounter, i; char* ptr = NULL; @@ -34,7 +90,7 @@ namespace server } // decrypt stage 2 - uint64 remove_salt(char* dst, const char* src, uint64 length) + uint64 remove_salt(uint8* dst, const uint8* src, uint64 length) { // remove conditional salt int seed = SEED % length; //38 when message_size = 49 @@ -60,7 +116,8 @@ namespace server return length - 1; } - void remove_conditional_bit_reverse(char* dst, const char* src, uint64 length) + // decrypt stage 3 + void remove_conditional_bit_reverse(uint8* dst, const uint8* src, uint64 length) { // remove conditional bit reverse, seed = 4595 for (int i = 0; i < (length + 1); i++) // +1 for checksum @@ -78,49 +135,351 @@ namespace server } } - std::string decrypt_message_str(std::string packet) + // decrypt stage 4 + uint64 remove_conditional_compression(uint8* dst, uint64 dst_size, const uint8* src, uint64 length) { - std::string stage_1(packet.length(), 0); + int read_counter = 0; + const uint8* read_buffer = 0; + int read_length = 0; - // 6 bit to 8 bit string - int size = util_64to256(stage_1.data(), packet.c_str(), mapping_table, packet.length()); - // important trim right here - stage_1 = stage_1.substr(0, size - 1); + auto read_bits = [&read_counter, &read_buffer, &read_length](int input) -> int + { + int mod8 = read_counter % 8; // row 0 1 2 3 4 5 6 7 + int div8 = read_counter / 8; // column 0 1 2 3 4 5 6 7 8 - std::string stage_2(stage_1.length(), 0); - size = remove_salt(stage_2.data(), stage_1.c_str(), stage_1.length()); - stage_2 = stage_2.substr(0, strlen(stage_2.data())); + // valid input: 1 2 3 4 5 6 7 8 + if (div8 >= read_length) // || input < 1 || input > 8) unnecessary for now + { + return 0; + } - std::string stage_3(stage_2.length(), 0); - remove_conditional_bit_reverse(stage_3.data(), stage_2.c_str(), stage_2.length()); - stage_3 = stage_3.substr(1, strlen(stage_3.data()) - 1); + int index = input + mod8 * 9; + + int lo = (*(read_buffer + div8) & weird_kernel1[index]) >> mod8; + int hi = (*(read_buffer + div8 + 1) & weird_kernel2[index]) << (8 - mod8); + + read_counter += input; + + return hi | lo; + + }; + + auto read_9bits = [&read_bits](int input = 9) -> int + { + int lo = read_bits(8); // row + 1 + int hi = read_bits(1) << 8; // column + 1 + return hi + lo; + }; - return stage_3; + //input variables + read_counter = 0; + read_buffer = src; + read_length = length; // message_size - 1 + + uint8 dictionary_indices[512]; + dictionary_entry dictionary_entries[256]; + uint8 dictionary_size = 0; + + memset(dictionary_indices, 0, 512); + memset(dictionary_entries, 0, sizeof(dictionary_entry) * 256); + memset(dst, 0, dst_size); + dictionary_size = 0; + + uint16 next_char9 = 0; + uint16 curr_char9 = 0;// packet2_6[0]; + unsigned char max_dictionary_size = 0; + unsigned char curr_entry_index = 0; + char char_stack[512]; + unsigned int char_stack_size = 0; + memset(char_stack, 0, 512); + + int bytes_decoded = 0; + + for (int index = 0; index < length; index++) + { + int bits_read = read_9bits(9); + int last_char_or_something = bits_read; + + if (bits_read == 0x100) + { + break; // EOF for extended ascii + } + + //dictionary_size = max_dictionary_size; + + if (bits_read < (dictionary_size + 1 + 0x100)) + { + next_char9 = bits_read; + } + else + { + char_stack[char_stack_size++] = next_char9; + if (char_stack_size >= 512) + { + assert(false); + } + next_char9 = curr_char9; + } + + if (next_char9 > 0x100) // if extended ascii + { + while ((unsigned int)next_char9 < 512) + { + const dictionary_entry& curr_entry = dictionary_entries[next_char9 - 0x101]; + + char_stack[char_stack_size++] = curr_entry.char9_right; + next_char9 = curr_entry.char9_left; + if (char_stack_size >= 512) + { + break; + printf("error\n"); + printf("so far:%s", dst); + assert(false); + } + if (next_char9 <= 256) + { + break; + } + } + } + + char_stack[char_stack_size++] = next_char9; + if (char_stack_size >= 512) + { + assert(false); + //return -1; + } + + if (char_stack_size) + { + int increment = char_stack_size - 1; + + while (bytes_decoded < dst_size && char_stack_size) + { + dst[bytes_decoded] = char_stack[char_stack_size - 1]; + bytes_decoded++; + char_stack_size--; + } + + if (char_stack_size) + { + //error + assert(false); + break; + } + + //dictionary_size = max_dictionary_size; + bits_read = last_char_or_something; + } + + if (bytes_decoded > 1 && dictionary_size < 256) + { + auto& new_entry = dictionary_entries[dictionary_size]; + new_entry.char9_left = curr_char9; + new_entry.char9_right = next_char9; + new_entry.prev = dictionary_size; + + bits_read = last_char_or_something; + dictionary_indices[curr_char9] = dictionary_size++; + } + curr_char9 = bits_read; + } + + return bytes_decoded; } void decrypt_message(core::byte_buffer& payload) { - char* buffer = (char*)payload.data() + payload.rpos; + uint8* buffer = payload.data() + payload.rpos; uint64 payload_size = payload.rend - payload.rpos; // 6 bit to 8 bit string - uint64 descrypted_size = util_64to256(buffer, buffer, mapping_table, payload_size); + uint64 decrypted_size = util_64to256(buffer, buffer, mapping_table, payload_size); - descrypted_size--; // -1 for checksum + decrypted_size--; // -1 for checksum - descrypted_size = remove_salt(buffer, buffer, descrypted_size); - remove_conditional_bit_reverse(buffer, buffer, descrypted_size); + decrypted_size = remove_salt(buffer, buffer, decrypted_size); + remove_conditional_bit_reverse(buffer, buffer, decrypted_size); - buffer[descrypted_size] = '\0'; + uint8 workbuf[4096]; + if (buffer[0] % 2) + { + decrypted_size = remove_conditional_compression(workbuf, sizeof(workbuf), buffer + 1, decrypted_size); + memcpy(buffer, workbuf, decrypted_size); + } + + buffer[decrypted_size] = '\0'; - buffer++; payload.rpos++; - payload.rend += descrypted_size - payload_size; + payload.rend += decrypted_size - payload_size; } - uint8 apply_conditional_bit_reverse(char* dst, const char* src, uint64 length) + uint64 apply_conditional_compression(uint8* dst, uint64 dst_size, const uint8* src, uint64 length) + { + int write_counter = 0; + uint8* write_buffer = 0; + int write_length = 0; + + auto write_bits = [&write_counter, &write_buffer, &write_length](int num_bits, char input) -> int + { + int mod8 = write_counter % 8; // row 0 1 2 3 4 5 6 7 + int div8 = write_counter / 8; // column 0 1 2 3 4 5 6 7 8 + int div8_plus_1 = div8 + 1; + // valid input: 1 2 3 4 5 6 7 8 + if (write_length < div8) // || input < 1 || input > 8) unnecessary for now + { + return 0; + } + + int index = num_bits + mod8 * 9; + + *(write_buffer + div8) &= weird_kernel1[index]; + *(write_buffer + div8) |= weird_kernel1[index] & (input << mod8); + *(write_buffer + div8 + 1) &= weird_kernel2[index]; + *(write_buffer + div8 + 1) |= weird_kernel2[index] & (input >> (8 - mod8)); + + write_counter += num_bits; + + return div8 + 1; + + }; + + auto write_9bits = [&write_bits](int num_bits, int input) -> int + { + int result = 0; + if (write_bits(8, (char)(input & 0xFF)) >= 0) // encode_magic_number(8, bits) -> encode_magic_number(1, bits) + { + result = write_bits(1, (char)((input >> 8) & 0x1)); + if (result < 0) + { + result = -1; + } + } + + return result; + }; + + unsigned char dictionary_indices[512]; + dictionary_entry dictionary_entries[256]; + unsigned char dictionary_size = 0; + + memset(dictionary_indices, 0, 512); + memset(dictionary_entries, 0, sizeof(dictionary_entry) * 256); + dictionary_size = 0; + + unsigned curr_char9; + unsigned next_char9; + + int bytes_encoded = 0; + + write_buffer = dst; + write_length = length; + write_counter = 0; + memset(dst, 0, dst_size); + + //printf("Compression:\n"); + + curr_char9 = src[0]; + for (int index = 1; index < length + 1; index++) + { + if (index < length - 1) + { + next_char9 = src[index] & 0xFF; // 0xFF required because of visual studio bug + } + else + { + next_char9 = 0x100; // EOF in 9-bit extended ascii + } + + // Is there a dictionary entry? + unsigned char head_entry_index = dictionary_indices[curr_char9]; + dictionary_entry* head_entry = &dictionary_entries[head_entry_index]; + + + unsigned char curr_entry_index = head_entry_index; + + while (curr_entry_index) + { + const dictionary_entry* curr_entry = &dictionary_entries[curr_entry_index]; + + if (curr_entry->char9_right == next_char9) + { + if (curr_entry_index > 0) + { + if (index != length + 1) + { + // bytes_encoded = bytes_encoded_old; + curr_char9 = curr_entry_index + 0x101; // 0x101 is the offset to make extended 9 bit ascii + goto skip_char; + } + break; + } + else + { + assert(false); + //printf("error"); + } + } + + curr_entry_index = curr_entry->prev; + } + char out_char = '?'; + + if (curr_char9 < 0x7F) + { + out_char = curr_char9; + } + + if ((index - 1) && !((index - 1) % 8)) + { + //printf("\n"); + } + + /* + char char9_str[] = { + 43, d0, 84, 91, c3, 24, cd, 1c, + 3a, 20, 60, 80, 50, 13, 66, ce, + 1b, 37, 7c, 60, 70, e1, a2, 47, + 06, 8d, 18, 34, 60, 48, a4, 18, + 63, a2, 9e, 18, 35, 3c, 6e, d4, + 33, 72, 24, 48, 91, 28, 39, 6a, + 4c, 59, d1, 23, 43, 87, 6e, 3c, + ca, f0, 38, cd, d9, b0, 78, 32, + 3d, c6, 80, 61, 43, e3, 4c, 8a, + 2d, 62, f0, 01, 01, 10, 00 + }; + */ + //printf("|%c:0x%03x, ", out_char, curr_char9); + bytes_encoded = write_9bits(9, curr_char9); + //bytes_encoded_old = bytes_encoded; + + //if (bytes_encoded > buffer_size) + // return -1; + + if (dictionary_size < 256) + { + auto& new_entry = dictionary_entries[dictionary_size]; + new_entry.char9_left = curr_char9; + new_entry.char9_right = next_char9; + new_entry.prev = head_entry_index; + + dictionary_indices[curr_char9] = dictionary_size++; + } + + curr_char9 = next_char9; + skip_char: + if (index == length + 1) + { + break; + } + } + + return bytes_encoded; + } + + uint8 apply_conditional_bit_reverse(uint8* dst, const uint8* src, uint64 length) { char sum = 0; @@ -138,7 +497,7 @@ namespace server return sum; } - int apply_salt_and_add_checksum(char* dst, const char* src, uint64 length, uint8 checksum) + int apply_salt_and_add_checksum(uint8* dst, const uint8* src, uint64 length, uint8 checksum) { // conditional salt int seed = SEED % length; //38 when message_size = 49 @@ -165,11 +524,11 @@ namespace server return 0; } - int util_256to64(char *dst, char *src, char* table, uint64 length) + int util_256to64(uint8* dst, uint8* src, char* table, uint64 length) { - uint32 byte_counter, i; + uint32 byte_counter; - uint16 reg; + uint16 reg, i; if (!dst || !src || !table) return 0; reg = 0; @@ -193,7 +552,7 @@ namespace server void encrypt_message(core::byte_buffer& payload) { - char* buffer = (char*)payload.data() + payload.rpos; + uint8* buffer = payload.data() + payload.rpos; const uint64 payload_size = payload.rend - payload.rpos; uint64 encrypted_size = payload_size + 1; // packet_length padding @@ -206,7 +565,6 @@ namespace server header = encrypted_size; } - assert(false); /* *(_BYTE*)message_work_buffer2 = checksum; message_length = odd_length_encrypt( @@ -215,6 +573,25 @@ namespace server (unsigned __int8*)message, strlen(message)); */ + uint8 workbuf[4096]; + encrypted_size = apply_conditional_compression(workbuf + 1, sizeof(workbuf) - 1, buffer, encrypted_size); + + /* +char char9_str[] = { + 43, d0, 84, 91, c3, 24, cd, 1c, + 3a, 20, 60, 80, 50, 13, 66, ce, + 1b, 37, 7c, 60, 70, e1, a2, 47, + 06, 8d, 18, 34, 60, 48, a4, 18, + 63, a2, 9e, 18, 35, 3c, 6e, d4, + 33, 72, 24, 48, 91, 28, 39, 6a, + 4c, 59, d1, 23, 43, 87, 6e, 3c, + ca, f0, 38, cd, d9, b0, 78, 32, + 3d, c6, 80, 61, 43, e3, 4c, 8a, + 2d, 62, f0, 01, 01, 10, 00 +}; +*/ + //workbuf[0] = header; + memcpy(buffer, workbuf, encrypted_size + 1); } else { @@ -231,7 +608,7 @@ namespace server encrypted_size++; // null terminator; - char workbuf[4096]; + uint8 workbuf[4096]; uint8 checksum = apply_conditional_bit_reverse(buffer, buffer, encrypted_size); apply_salt_and_add_checksum(workbuf, buffer, encrypted_size, checksum); diff --git a/Source/xgmsv/test_server/xg_packet.h b/Source/xgmsv/test_server/xg_packet.h index fc12f87..cdaa27b 100644 --- a/Source/xgmsv/test_server/xg_packet.h +++ b/Source/xgmsv/test_server/xg_packet.h @@ -33,9 +33,89 @@ namespace server void handle_client_login(xg_packet* packet) { + enum status_code + { + success = 0, + wrong_login_or_banned = 1, + refuse = 2 + }; + + auto connection = packet->connection; + + if (!connection->send_raw("ClientLogin 0 block ")) + { + printf("handle_client_login failed.\n"); + } + printf("handle_client_login!\n"); } + void handle_char_list(xg_packet* packet) + { + enum fields + { + name = 0, + something = 1, + portrait = 2, + level = 3, + vitality = 4, + strength = 5, + toughness = 6, + quickness = 7, + magic = 8, + fire = 9, + wind = 10, + earth = 11, + water = 12, + }; + + auto connection = packet->connection; + + if (!connection->send_raw(R"(CharList 0 jason|0\\z241400\\z2\\z15\\z0\\z0\\z0\\z15\\z0\\z0\\z100\\z0\\z2\\zjason\\z2\\z游民\\z2\\z106002\\z-1| )")) + { + printf("handle_char_list failed.\n"); + } + + printf("handle_char_list!\n"); + } + + void handle_char_login(xg_packet* packet) + { + auto connection = packet->connection; + connection->send_raw(R"(LI 3I3 1JayvY 1 0 )"); + connection->send_raw(R"(CC 0 hV p J c 6 0 0 0 0 -1 )"); + connection->send_raw(R"(MN 城西医院\\z0 )"); + connection->send_raw(R"(CP 1|155|155|185|185|15|0|0|0|15|50|50|50|0|16|1|23|23|23|107|107|60|100|100|0|0|0|5000|0|jason|| )"); + connection->send_raw(R"(CP2 1|0|0|0|0|0|0|0|0|0|0|100|0|0|0|0|241400|10|100| )"); + connection->send_raw(R"(CJ 1 见习传教士 )"); + connection->send_raw(R"(CS 0|||||||||||1|||||||||||2|||||||||||3|||||||||||4|||||||||||5|||||||||||6|||||||||||7|||||||||||8|||||||||||9|||||||||||10|||||||||||11|||||||||||12|||||||||||13|||||||||||14||||||||||| )"); + connection->send_raw(R"(TITLE 敬畏的寂静|0|17|见习传教士|1|161||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||)"); + connection->send_raw(R"(I )"); + connection->send_raw(R"(EP 0 0 )"); + connection->send_raw(R"(KP 0 1|101321|4|93|93|99|99|1|16|1|48|40|34|101|100|24|0|40|60|0|10|1|新手红螳螂||0|0| )"); + connection->send_raw(R"(KP2 0 1|2|9|4|5|3|25|0|45|-10|0|0|0|0|0|0|1| )"); + connection->send_raw(R"(PT 0 0|7300|攻击|能以普通物理攻击给与打击|0|1|1141|0|1|7400|防御|能防守来自物理攻击的打击|0|1|72|1|2|407|气功弹\SLV8|给予对象前后列位置一体或数体的伤害,依等级改变攻击数。|40|1|117|2|3|1238|明净止水-Ⅴ|集中精神回复一定比例的体力,技 能和最大生命值越高回复比例上限越高(注意和回复力无关),使用后将无法闪躲物理攻击。\S|135|1|72|3|)"); + connection->send_raw(R"(FS 0 )"); + connection->send_raw(R"(MC 0 hV 0 0 p k bFX agh 0 )"); + connection->send_raw(R"(AB |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||)"); + connection->send_raw(R"(ABG |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||)"); + connection->send_raw(R"(C 1|3I3|12|6|0|106002|1|0|jason|\\z\\z|0|0|0|敬畏的寂静|0 )"); + connection->send_raw(R"(C 2|1tq|10|5|4|14088|1|0|伯舒医师|\\z\\z|0|0|0||0 37|1ty|10|17|4|14088|1|0|姆涅医师|\\z\\z|0|0|0||0 2|1ti|12|5|4|14090|1|0|实习药剂师吉可|\\z\\z|0|0|0||0 29|1xH|16|9|6|14151|1|0|实习生蜜雅|\\z\\z|0|0|0||0)"); + connection->send_raw(R"(BT 5Co 0 )"); + connection->send_raw(R"(POS 0 )"); + connection->send_raw(R"(AL 1 0|0|0|0|0|0|0|0|0|0| )"); + connection->send_raw(R"(IP 127.0.0.1 )"); + connection->send_raw(R"(MAC Y O )"); + connection->send_raw(R"(EF 0 0 )"); + connection->send_raw(R"(TK -1 P|感谢购买大灰狼魔力。wow335.taobao.com 4 0 )"); + connection->send_raw(R"(TK -1 P|[版本申明]GMSV\SAvaritia\SFeb\S\S1\S2014\S共享版 4 0 )"); + connection->send_raw(R"(TK -1 P|本服务端仅供研究使用,请勿用作商业用途。 4 0 )"); + connection->send_raw(R"(TK -1 P|项目主页\S&\S交流论坛:http://www.cgdev.me/ 4 0 )"); + connection->send_raw(R"(STK GA\SLua引擎运行正常。 )"); + connection->send_raw(R"(STK [二键魔力公告]可用\S/help\S指令查看当前可用LuaTalk指令 )"); + //connection->send_raw(R"()"); + } + struct opcode_entry { enum xg_opcode opcode; @@ -49,6 +129,8 @@ namespace server XG_FC, XG_ECHO, XG_CLIENT_LOGIN, + XG_CHAR_LIST, + XG_CHAR_LOGIN, XG_OPCODE_COUNT }; @@ -59,7 +141,9 @@ namespace server { add_opcode_entry(XG_FC, "FC", &handle_fc), add_opcode_entry(XG_ECHO, "Echo", &handle_echo), - add_opcode_entry(XG_CLIENT_LOGIN, "ClientLogin", &handle_client_login) + add_opcode_entry(XG_CLIENT_LOGIN, "ClientLogin", &handle_client_login), + add_opcode_entry(XG_CHAR_LIST, "CharList", &handle_char_list), + add_opcode_entry(XG_CHAR_LOGIN, "CharLogin", &handle_char_login), }; template @@ -80,8 +164,11 @@ namespace server { auto handler = xg_opcode_table[i].handler; handler(&xg_packet); + return; } } + + printf("Unhandled packet:%s\n", xg_packet.data); } } }