Reorganized and cleaned up the solution.

This commit is contained in:
HikikoMarmy
2026-03-02 12:37:07 +00:00
parent 8012f30170
commit d4dfbddf69
175 changed files with 1516 additions and 1136 deletions

View File

@@ -0,0 +1,71 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "winres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (United Kingdom) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG)
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
#pragma code_page(1252)
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""winres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_ICON1 ICON ".\icon.ico"
#endif // English (United Kingdom) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@@ -0,0 +1,95 @@
#pragma once
#include <vector>
#include <cstdint>
#include <stdexcept>
#include <cstring>
class ByteBufferReader {
public:
ByteBufferReader( const uint8_t *data, size_t size )
: buffer( data ), bufferSize( size ), offset( 0 )
{
}
explicit ByteBufferReader( const std::vector<uint8_t> &vec )
: ByteBufferReader( vec.data(), vec.size() )
{
}
template<typename T>
T read()
{
if( offset + sizeof( T ) > bufferSize )
throw std::out_of_range( "BufferReader: read out of bounds" );
T value;
std::memcpy( &value, buffer + offset, sizeof( T ) );
offset += sizeof( T );
return value;
}
void readBytes( void *dest, size_t size )
{
if( offset + size > bufferSize )
throw std::out_of_range( "BufferReader: readBytes out of bounds" );
std::memcpy( dest, buffer + offset, size );
offset += size;
}
std::string readString( size_t length )
{
if( offset + length > bufferSize )
throw std::out_of_range( "BufferReader: readString out of bounds" );
std::string str( reinterpret_cast< const char * >( buffer + offset ), length );
offset += length;
return str;
}
template<typename T, size_t N>
std::array<T, N> readArray()
{
std::array<T, N> arr;
for( size_t i = 0; i < N; ++i )
arr[ i ] = read<T>();
return arr;
}
void skip( size_t count )
{
if( offset + count > bufferSize )
throw std::out_of_range( "BufferReader: skip out of bounds" );
offset += count;
}
template<typename T>
T peek() const
{
if( offset + sizeof( T ) > bufferSize )
throw std::out_of_range( "BufferReader: peek out of bounds" );
T value;
std::memcpy( &value, buffer + offset, sizeof( T ) );
return value;
}
bool eof() const
{
return offset >= bufferSize;
}
size_t tell() const
{
return offset;
}
size_t remaining() const
{
return bufferSize - offset;
}
private:
const uint8_t *buffer;
size_t bufferSize;
size_t offset;
};

View File

@@ -0,0 +1,85 @@
#pragma once
#include <vector>
#include <string>
#include <memory>
#include <iterator>
#include <optional>
#include "Utility.hpp"
#include "../Crypto/RealmCrypt.hpp"
class ByteBuffer {
public:
ByteBuffer( const std::vector< uint8_t > &data );
ByteBuffer( const std::string &data );
ByteBuffer( const uint8_t *data, uint32_t length );
ByteBuffer( uint32_t length );
ByteBuffer();
~ByteBuffer();
void resize( uint32_t size );
void shrink_to_fit();
template < typename T >
void write( T value );
template < typename T >
T read();
void forward( uint32_t length ) {
m_position += length;
if ( m_position > m_buffer.size() ) {
m_position = m_buffer.size();
}
}
void write_u8( uint8_t value );
void write_u16( uint16_t value );
void write_u32( uint32_t value );
void write_i8( int8_t value );
void write_i16( int16_t value );
void write_i32( int32_t value );
void write_f32( float_t value );
void write_utf8( const std::string &str, std::optional<uint32_t> length = std::nullopt );
void write_utf16( const std::wstring &str, std::optional<uint32_t> length = std::nullopt );
void write_sz_utf8( const std::string &str, std::optional<uint32_t> length = std::nullopt );
void write_sz_utf16( const std::wstring &str, std::optional<uint32_t> length = std::nullopt );
void write_encrypted_utf8( const std::string &str );
void write_encrypted_utf16( const std::wstring &str );
uint8_t read_u8();
uint16_t read_u16();
uint32_t read_u32();
int8_t read_i8();
int16_t read_i16();
int32_t read_i32();
float_t read_f32();
std::string read_utf8( std::optional<uint32_t> length = std::nullopt );
std::wstring read_utf16( std::optional<uint32_t> length = std::nullopt );
std::string read_sz_utf8();
std::wstring read_sz_utf16();
std::string read_encrypted_utf8( bool hasBlockLength = true );
std::wstring read_encrypted_utf16( bool hasBlockLength = true );
void write_bytes( const std::vector< uint8_t > &value );
void write_bytes( const uint8_t *value, uint32_t length );
void write_encrypted_bytes( const std::vector< uint8_t > &value );
std::vector< uint8_t > read_bytes( uint32_t length );
std::vector< uint8_t > read_encrypted_bytes( uint32_t length );
std::vector< uint8_t > get_buffer() const;
size_t get_length() const;
size_t get_position() const;
void set_position( size_t where );
std::vector< uint8_t > m_buffer;
size_t m_position;
};
typedef std::shared_ptr< ByteBuffer > sptr_byte_stream;

View File

@@ -0,0 +1,66 @@
#pragma once
constexpr int32_t MAX_SESSION_ID_LENGTH = 16;
enum RealmGameType {
CHAMPIONS_OF_NORRATH = 0,
RETURN_TO_ARMS = 1,
};
enum class CharacterClass : int32_t {
WARRIOR,
CLERIC,
SHADOW_KNIGHT,
RANGER,
WIZARD,
BERSERKER,
SHAMAN,
NUM_CLASSES
};
enum class CharacterRace : int32_t {
BARBARIAN_M,
BARNARIAN_F,
WOOD_ELF_M,
WOOD_ELF_F,
HIGH_ELF_M,
HIGH_ELF_F,
ERUDITE_WIZARD_M,
ERUDITE_WIZARD_F,
DARK_ELF_M,
DARK_ELF_F,
VAH_SHIR_BERSERKER,
IKSAR_SHAMAN,
NUM_RACES
};
enum class EquipmentSlot : int32_t {
PRIMARY_WEAPON = 0,
UNKNOWN_01 = 1,
SECONDARY_WEAPON = 2,
SHIELD = 3,
TORSO = 4,
RING_1 = 5,
RING_2 = 6,
CHOKER = 7,
QUIVER = 8,
GLOVES = 9,
BOOTS = 10,
HEAD = 11,
LEGGINGS = 12,
UNKNOWN_13 = 13,
EARRING = 14,
UNKNOWN_15 = 15,
UNKNOWN_16 = 16,
PRIMARY_WEAPON_2 = 17,
SECONDARY_WEAPON_2 = 18,
UNKNOWN_19 = 19,
NUM_EQUIPMENT_SLOTS
};

View File

@@ -0,0 +1,22 @@
#pragma once
#include <memory>
class RealmUser;
using sptr_user = std::shared_ptr< RealmUser >;
using wptr_user = std::weak_ptr< RealmUser >;
class GameSession;
using sptr_game_session = std::shared_ptr< GameSession >;
class RealmSocket;
using sptr_socket = std::shared_ptr< RealmSocket >;
class ByteBuffer;
using sptr_byte_stream = std::shared_ptr< ByteBuffer >;
class ChatRoomSession;
using sptr_chat_room_session = std::shared_ptr< ChatRoomSession >;
class RealmCharacter;
using sptr_realm_character = std::shared_ptr< RealmCharacter >;

65
Include/Common/RLEZ.hpp Normal file
View File

@@ -0,0 +1,65 @@
#pragma once
#include <vector>
#include <stdexcept>
#include <cstdint>
namespace RLEZ
{
inline std::vector<uint8_t> Decompress( const std::vector<uint8_t> &input )
{
std::vector< uint8_t > output;
size_t read = 0;
while( read < input.size() )
{
uint8_t byte = input[ read++ ];
output.push_back( byte );
if( byte == 0x00 )
{
if( read >= input.size() )
{
break;
}
uint8_t count = input[ read++ ];
output.insert( output.end(), count, 0x00 );
}
}
return output;
}
inline std::vector<uint8_t> Compress( const std::vector<uint8_t> &input )
{
std::vector< uint8_t > output;
size_t i = 0;
while( i < input.size() )
{
if( input[ i ] != 0x00 )
{
output.push_back( input[ i ] );
++i;
}
else
{
size_t zeroCount = 0;
i++;
// Count all proceeding 00's
while( i < input.size() && input[ i ] == 0x00 && zeroCount < 255 )
{
++i;
++zeroCount;
}
output.push_back( 0x00 );
output.push_back( static_cast< uint8_t >( zeroCount ) );
}
}
return output;
}
}

View File

@@ -0,0 +1,25 @@
#pragma once
#include <cstdint>
#include <string>
#include <WinSock2.h>
namespace Util
{
int32_t round_up( int32_t numToRound, int32_t multiple );
int32_t round_down( int32_t numToRound, int32_t multiple );
uint16_t ByteSwap( uint16_t val );
uint32_t ByteSwap( uint32_t val );
template <typename T>
bool IsInRange( T value, T min, T max )
{
return ( value >= min && value <= max );
}
std::string IPFromAddr( const sockaddr_in &addr );
std::string WideToUTF8( const std::wstring &wstr );
std::wstring UTF8ToWide( const std::string &str );
}

View File

@@ -0,0 +1,299 @@
#pragma once
#include <string>
#include <vector>
#include <stdexcept>
#include <cstdint>
#include <cstring>
#include <algorithm>
// SHA-256 implementation
namespace sha256
{
constexpr size_t HASH_SIZE = 32;
struct Context {
uint32_t state[ 8 ];
uint64_t bitlen;
uint8_t data[ 64 ];
size_t datalen;
};
inline uint32_t rotr( uint32_t x, uint32_t n )
{
return ( x >> n ) | ( x << ( 32 - n ) );
}
inline uint32_t ch( uint32_t x, uint32_t y, uint32_t z )
{
return ( x & y ) ^ ( ~x & z );
}
inline uint32_t maj( uint32_t x, uint32_t y, uint32_t z )
{
return ( x & y ) ^ ( x & z ) ^ ( y & z );
}
inline uint32_t Sigma0( uint32_t x )
{
return rotr( x, 2 ) ^ rotr( x, 13 ) ^ rotr( x, 22 );
}
inline uint32_t Sigma1( uint32_t x )
{
return rotr( x, 6 ) ^ rotr( x, 11 ) ^ rotr( x, 25 );
}
inline uint32_t sigma0( uint32_t x )
{
return rotr( x, 7 ) ^ rotr( x, 18 ) ^ ( x >> 3 );
}
inline uint32_t sigma1( uint32_t x )
{
return rotr( x, 17 ) ^ rotr( x, 19 ) ^ ( x >> 10 );
}
inline void Transform( Context &ctx, const uint8_t data[] )
{
uint32_t m[ 64 ], w[ 8 ];
for( int i = 0; i < 16; ++i )
m[ i ] = ( data[ i * 4 ] << 24 ) | ( data[ i * 4 + 1 ] << 16 ) | ( data[ i * 4 + 2 ] << 8 ) | ( data[ i * 4 + 3 ] );
for( int i = 16; i < 64; ++i )
m[ i ] = sigma1( m[ i - 2 ] ) + m[ i - 7 ] + sigma0( m[ i - 15 ] ) + m[ i - 16 ];
std::memcpy( w, ctx.state, sizeof( w ) );
for( int i = 0; i < 64; ++i )
{
auto t1 = w[ 7 ] + Sigma1( w[ 4 ] ) + ch( w[ 4 ], w[ 5 ], w[ 6 ] ) + m[ i ] + 0x428a2f98 + ( ( i * 0x1234567 ) % 0xffffffff );
auto t2 = Sigma0( w[ 0 ] ) + maj( w[ 0 ], w[ 1 ], w[ 2 ] );
w[ 7 ] = w[ 6 ]; w[ 6 ] = w[ 5 ]; w[ 5 ] = w[ 4 ];
w[ 4 ] = w[ 3 ] + t1;
w[ 3 ] = w[ 2 ]; w[ 2 ] = w[ 1 ]; w[ 1 ] = w[ 0 ];
w[ 0 ] = t1 + t2;
}
for( int i = 0; i < 8; ++i )
ctx.state[ i ] += w[ i ];
}
inline void Init( Context &ctx )
{
ctx.datalen = 0;
ctx.bitlen = 0;
ctx.state[ 0 ] = 0x6a09e667;
ctx.state[ 1 ] = 0xbb67ae85;
ctx.state[ 2 ] = 0x3c6ef372;
ctx.state[ 3 ] = 0xa54ff53a;
ctx.state[ 4 ] = 0x510e527f;
ctx.state[ 5 ] = 0x9b05688c;
ctx.state[ 6 ] = 0x1f83d9ab;
ctx.state[ 7 ] = 0x5be0cd19;
}
inline void Update( Context &ctx, const uint8_t *data, size_t len )
{
for( size_t i = 0; i < len; ++i )
{
ctx.data[ ctx.datalen++ ] = data[ i ];
if( ctx.datalen == 64 )
{
Transform( ctx, ctx.data );
ctx.bitlen += 512;
ctx.datalen = 0;
}
}
}
inline void Final( Context &ctx, uint8_t hash[ HASH_SIZE ] )
{
size_t i = ctx.datalen;
ctx.data[ i++ ] = 0x80;
if( i > 56 )
{
while( i < 64 ) ctx.data[ i++ ] = 0;
Transform( ctx, ctx.data );
i = 0;
}
while( i < 56 ) ctx.data[ i++ ] = 0;
ctx.bitlen += ctx.datalen * 8;
for( int j = 0; j < 8; ++j )
ctx.data[ 56 + j ] = static_cast< uint8_t >( ctx.bitlen >> ( 8 * ( 7 - j ) ) );
Transform( ctx, ctx.data );
for( i = 0; i < 4; ++i )
for( int j = 0; j < 8; ++j )
hash[ i + j * 4 ] = ( ctx.state[ j ] >> ( 24 - i * 8 ) ) & 0xff;
}
}
// HMAC-SHA256
inline void hmac_sha256(
const uint8_t *key, size_t key_len,
const uint8_t *data, size_t data_len,
uint8_t out[ sha256::HASH_SIZE ] )
{
uint8_t k_ipad[ 64 ] = {}, k_opad[ 64 ] = {}, key_hash[ sha256::HASH_SIZE ];
if( key_len > 64 )
{
sha256::Context ctx;
sha256::Init( ctx );
sha256::Update( ctx, key, key_len );
sha256::Final( ctx, key_hash );
key = key_hash;
key_len = sha256::HASH_SIZE;
}
std::memcpy( k_ipad, key, key_len );
std::memcpy( k_opad, key, key_len );
for( int i = 0; i < 64; ++i )
{
k_ipad[ i ] ^= 0x36;
k_opad[ i ] ^= 0x5C;
}
sha256::Context ctx;
uint8_t inner[ sha256::HASH_SIZE ];
sha256::Init( ctx );
sha256::Update( ctx, k_ipad, 64 );
sha256::Update( ctx, data, data_len );
sha256::Final( ctx, inner );
sha256::Init( ctx );
sha256::Update( ctx, k_opad, 64 );
sha256::Update( ctx, inner, sha256::HASH_SIZE );
sha256::Final( ctx, out );
}
// PBKDF2-HMAC-SHA256
inline std::vector<uint8_t> pbkdf2_hmac_sha256(
const std::string &password,
const std::vector<uint8_t> &salt,
uint32_t iterations,
size_t dkLen )
{
std::vector<uint8_t> key( dkLen );
uint32_t blocks = ( uint32_t )( ( dkLen + sha256::HASH_SIZE - 1 ) / sha256::HASH_SIZE );
std::vector<uint8_t> u( sha256::HASH_SIZE );
std::vector<uint8_t> t( sha256::HASH_SIZE );
std::vector<uint8_t> block( salt.size() + 4 );
for( uint32_t i = 1; i <= blocks; ++i )
{
std::memcpy( block.data(), salt.data(), salt.size() );
block[ salt.size() + 0 ] = ( i >> 24 ) & 0xFF;
block[ salt.size() + 1 ] = ( i >> 16 ) & 0xFF;
block[ salt.size() + 2 ] = ( i >> 8 ) & 0xFF;
block[ salt.size() + 3 ] = ( i >> 0 ) & 0xFF;
hmac_sha256( ( const uint8_t * )password.data(), password.size(),
block.data(), block.size(), u.data() );
std::memcpy( t.data(), u.data(), sha256::HASH_SIZE );
for( uint32_t j = 1; j < iterations; ++j )
{
hmac_sha256( ( const uint8_t * )password.data(), password.size(),
u.data(), sha256::HASH_SIZE, u.data() );
for( size_t k = 0; k < sha256::HASH_SIZE; ++k )
t[ k ] ^= u[ k ];
}
size_t offset = ( i - 1 ) * sha256::HASH_SIZE;
size_t chunk = (std::min)( dkLen - offset, sha256::HASH_SIZE );
std::memcpy( &key[ offset ], t.data(), chunk );
}
return key;
}
// Base64 Encoding/Decoding
inline std::string Base64Encode( const std::vector<uint8_t> &data )
{
static const char *table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
std::string encoded;
size_t i = 0;
while( i + 2 < data.size() )
{
uint32_t triple = ( data[ i ] << 16 ) | ( data[ i + 1 ] << 8 ) | data[ i + 2 ];
encoded += table[ ( triple >> 18 ) & 0x3F ];
encoded += table[ ( triple >> 12 ) & 0x3F ];
encoded += table[ ( triple >> 6 ) & 0x3F ];
encoded += table[ triple & 0x3F ];
i += 3;
}
size_t remaining = data.size() - i;
if( remaining == 1 )
{
uint32_t triple = data[ i ] << 16;
encoded += table[ ( triple >> 18 ) & 0x3F ];
encoded += table[ ( triple >> 12 ) & 0x3F ];
encoded += "==";
}
else if( remaining == 2 )
{
uint32_t triple = ( data[ i ] << 16 ) | ( data[ i + 1 ] << 8 );
encoded += table[ ( triple >> 18 ) & 0x3F ];
encoded += table[ ( triple >> 12 ) & 0x3F ];
encoded += table[ ( triple >> 6 ) & 0x3F ];
encoded += '=';
}
return encoded;
}
inline std::vector<uint8_t> Base64Decode( const std::string &input )
{
static const uint8_t decodeTable[ 256 ] = {
64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
64,64,64,64,64,64,64,64,64,64,64,62,64,64,64,63,
52,53,54,55,56,57,58,59,60,61,64,64,64, 0,64,64,
64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,
15,16,17,18,19,20,21,22,23,24,25,64,64,64,64,64,
64,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,
41,42,43,44,45,46,47,48,49,50,51,64,64,64,64,64
};
std::vector<uint8_t> decoded;
int val = 0, valb = -8;
for( char c : input )
{
if( c == '=' ) break;
if( c > 255 ) continue;
unsigned char uc = static_cast< unsigned char >( c );
if( decodeTable[ uc ] == 64 )
continue;
val = ( val << 6 ) | decodeTable[ uc ];
valb += 6;
if( valb >= 0 )
{
decoded.push_back( static_cast< uint8_t >( ( val >> valb ) & 0xFF ) );
valb -= 8;
}
}
return decoded;
}
std::string HashPassword( const std::string &password, uint32_t iterations, size_t saltLen );
bool VerifyPassword( const std::string &password, const std::string &storedHash );

View File

@@ -0,0 +1,43 @@
#pragma once
#include <string>
#include <vector>
#include <span>
#include "rijndael.hpp"
// This class is based on the games Encryptor class,
// and is a wrapper around the rijndael ECB implementation.
//
// Normally CoN would generate a random symmetric key for each user,
// but for the sake of simplicity we will just use the games default key,
// since we have nothing to hide.
class RealmCrypt {
private:
// Byte array of dlfk qs';r+t iqe4t9ueerjKDJ wdaj
const static inline std::vector< uint8_t > default_sym_key =
{
0x64, 0x6c, 0x66, 0x6b, 0x20, 0x71, 0x73, 0x27,
0x3b, 0x72, 0x2b, 0x74, 0x20, 0x69, 0x71, 0x65,
0x34, 0x74, 0x39, 0x75, 0x65, 0x65, 0x72, 0x6a,
0x4b, 0x44, 0x4a, 0x20, 0x77, 0x64, 0x61, 0x6a
};
public:
RealmCrypt();
// Generate a new symmetric key for the user.
static std::vector< uint8_t > generateSymmetricKey( void );
static std::vector< uint8_t > getSymmetricKey( void );
// Encrypt and decrypt strings.
static std::string encryptString( std::string &input );
static std::string decryptString( std::string &input );
static std::vector<uint8_t> encryptString( const std::wstring &input );
static std::wstring decryptString( std::vector<uint8_t> &input );
// Encrypt and decrypt byte arrays.
static std::vector< uint8_t > encryptSymmetric( std::span< const uint8_t > input );
static std::vector< uint8_t > decryptSymmetric( std::span< const uint8_t > input );
};

282
Include/Crypto/rijndael.hpp Normal file
View File

@@ -0,0 +1,282 @@
#pragma once
#include <cstdio>
#include <cstring>
#include <iostream>
#include <stdexcept>
#include <string>
#include <vector>
class rijndael {
private:
static constexpr uint32_t Nb = 4;
static constexpr uint32_t blockBytesLen = 4 * Nb * sizeof( uint8_t );
uint32_t Nk;
uint32_t Nr;
void SubBytes( uint8_t state[ 4 ][ Nb ] );
void ShiftRow( uint8_t state[ 4 ][ Nb ], uint32_t i, uint32_t n );
void ShiftRows( uint8_t state[ 4 ][ Nb ] );
uint8_t xtime( uint8_t b );
void MixColumns( uint8_t state[ 4 ][ Nb ] );
void AddRoundKey( uint8_t state[ 4 ][ Nb ], uint8_t *key );
void SubWord( uint8_t *a );
void RotWord( uint8_t *a );
void XorWords( uint8_t *a, uint8_t *b, uint8_t *c );
void Rcon( uint8_t *a, uint32_t n );
void InvSubBytes( uint8_t state[ 4 ][ Nb ] );
void InvMixColumns( uint8_t state[ 4 ][ Nb ] );
void InvShiftRows( uint8_t state[ 4 ][ Nb ] );
void CheckLength( uint32_t len );
void KeyExpansion( const uint8_t key[], uint8_t w[] );
void EncryptBlock( const uint8_t in[], uint8_t out[],
uint8_t *roundKeys );
void DecryptBlock( const uint8_t in[], uint8_t out[],
uint8_t *roundKeys );
void XorBlocks( const uint8_t *a, const uint8_t *b,
uint8_t *c, uint32_t len );
std::vector<uint8_t> ArrayToVector( uint8_t *a, uint32_t len );
uint8_t *VectorToArray( std::vector<uint8_t> &a );
public:
explicit rijndael();
uint8_t *EncryptECB( const uint8_t in[], uint32_t inLen,
const uint8_t key[] );
uint8_t *DecryptECB( const uint8_t in[], uint32_t inLen,
const uint8_t key[] );
std::vector<uint8_t> EncryptECB( std::vector<uint8_t> in,
std::vector<uint8_t> key );
std::vector<uint8_t> DecryptECB( std::vector<uint8_t> in,
std::vector<uint8_t> key );
};
const uint8_t sbox[ 16 ][ 16 ] = {
{0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76},
{0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0},
{0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15},
{0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75},
{0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84},
{0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf},
{0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8},
{0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2},
{0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73},
{0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb},
{0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79},
{0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08},
{0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a},
{0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e},
{0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf},
{0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16}
};
const uint8_t inv_sbox[ 16 ][ 16 ] = {
{0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb},
{0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb},
{0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e},
{0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25},
{0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92},
{0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84},
{0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06},
{0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b},
{0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73},
{0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e},
{0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b},
{0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4},
{0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f},
{0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef},
{0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61},
{0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d}
};
// Galois Multiplication lookup tables
static const uint8_t GF_MUL_TABLE[ 15 ][ 256 ] = {
{},
{},
// mul 2
{0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16,
0x18, 0x1a, 0x1c, 0x1e, 0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e,
0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e, 0x40, 0x42, 0x44, 0x46,
0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e,
0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76,
0x78, 0x7a, 0x7c, 0x7e, 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e,
0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e, 0xa0, 0xa2, 0xa4, 0xa6,
0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe,
0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6,
0xd8, 0xda, 0xdc, 0xde, 0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee,
0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe, 0x1b, 0x19, 0x1f, 0x1d,
0x13, 0x11, 0x17, 0x15, 0x0b, 0x09, 0x0f, 0x0d, 0x03, 0x01, 0x07, 0x05,
0x3b, 0x39, 0x3f, 0x3d, 0x33, 0x31, 0x37, 0x35, 0x2b, 0x29, 0x2f, 0x2d,
0x23, 0x21, 0x27, 0x25, 0x5b, 0x59, 0x5f, 0x5d, 0x53, 0x51, 0x57, 0x55,
0x4b, 0x49, 0x4f, 0x4d, 0x43, 0x41, 0x47, 0x45, 0x7b, 0x79, 0x7f, 0x7d,
0x73, 0x71, 0x77, 0x75, 0x6b, 0x69, 0x6f, 0x6d, 0x63, 0x61, 0x67, 0x65,
0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d,
0x83, 0x81, 0x87, 0x85, 0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5,
0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5, 0xdb, 0xd9, 0xdf, 0xdd,
0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5,
0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed,
0xe3, 0xe1, 0xe7, 0xe5},
// mul 3
{0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d,
0x14, 0x17, 0x12, 0x11, 0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39,
0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21, 0x60, 0x63, 0x66, 0x65,
0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71,
0x50, 0x53, 0x56, 0x55, 0x5c, 0x5f, 0x5a, 0x59, 0x48, 0x4b, 0x4e, 0x4d,
0x44, 0x47, 0x42, 0x41, 0xc0, 0xc3, 0xc6, 0xc5, 0xcc, 0xcf, 0xca, 0xc9,
0xd8, 0xdb, 0xde, 0xdd, 0xd4, 0xd7, 0xd2, 0xd1, 0xf0, 0xf3, 0xf6, 0xf5,
0xfc, 0xff, 0xfa, 0xf9, 0xe8, 0xeb, 0xee, 0xed, 0xe4, 0xe7, 0xe2, 0xe1,
0xa0, 0xa3, 0xa6, 0xa5, 0xac, 0xaf, 0xaa, 0xa9, 0xb8, 0xbb, 0xbe, 0xbd,
0xb4, 0xb7, 0xb2, 0xb1, 0x90, 0x93, 0x96, 0x95, 0x9c, 0x9f, 0x9a, 0x99,
0x88, 0x8b, 0x8e, 0x8d, 0x84, 0x87, 0x82, 0x81, 0x9b, 0x98, 0x9d, 0x9e,
0x97, 0x94, 0x91, 0x92, 0x83, 0x80, 0x85, 0x86, 0x8f, 0x8c, 0x89, 0x8a,
0xab, 0xa8, 0xad, 0xae, 0xa7, 0xa4, 0xa1, 0xa2, 0xb3, 0xb0, 0xb5, 0xb6,
0xbf, 0xbc, 0xb9, 0xba, 0xfb, 0xf8, 0xfd, 0xfe, 0xf7, 0xf4, 0xf1, 0xf2,
0xe3, 0xe0, 0xe5, 0xe6, 0xef, 0xec, 0xe9, 0xea, 0xcb, 0xc8, 0xcd, 0xce,
0xc7, 0xc4, 0xc1, 0xc2, 0xd3, 0xd0, 0xd5, 0xd6, 0xdf, 0xdc, 0xd9, 0xda,
0x5b, 0x58, 0x5d, 0x5e, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46,
0x4f, 0x4c, 0x49, 0x4a, 0x6b, 0x68, 0x6d, 0x6e, 0x67, 0x64, 0x61, 0x62,
0x73, 0x70, 0x75, 0x76, 0x7f, 0x7c, 0x79, 0x7a, 0x3b, 0x38, 0x3d, 0x3e,
0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26, 0x2f, 0x2c, 0x29, 0x2a,
0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16,
0x1f, 0x1c, 0x19, 0x1a},
{},
{},
{},
{},
{},
// mul 9
{0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, 0x48, 0x41, 0x5a, 0x53,
0x6c, 0x65, 0x7e, 0x77, 0x90, 0x99, 0x82, 0x8b, 0xb4, 0xbd, 0xa6, 0xaf,
0xd8, 0xd1, 0xca, 0xc3, 0xfc, 0xf5, 0xee, 0xe7, 0x3b, 0x32, 0x29, 0x20,
0x1f, 0x16, 0x0d, 0x04, 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c,
0xab, 0xa2, 0xb9, 0xb0, 0x8f, 0x86, 0x9d, 0x94, 0xe3, 0xea, 0xf1, 0xf8,
0xc7, 0xce, 0xd5, 0xdc, 0x76, 0x7f, 0x64, 0x6d, 0x52, 0x5b, 0x40, 0x49,
0x3e, 0x37, 0x2c, 0x25, 0x1a, 0x13, 0x08, 0x01, 0xe6, 0xef, 0xf4, 0xfd,
0xc2, 0xcb, 0xd0, 0xd9, 0xae, 0xa7, 0xbc, 0xb5, 0x8a, 0x83, 0x98, 0x91,
0x4d, 0x44, 0x5f, 0x56, 0x69, 0x60, 0x7b, 0x72, 0x05, 0x0c, 0x17, 0x1e,
0x21, 0x28, 0x33, 0x3a, 0xdd, 0xd4, 0xcf, 0xc6, 0xf9, 0xf0, 0xeb, 0xe2,
0x95, 0x9c, 0x87, 0x8e, 0xb1, 0xb8, 0xa3, 0xaa, 0xec, 0xe5, 0xfe, 0xf7,
0xc8, 0xc1, 0xda, 0xd3, 0xa4, 0xad, 0xb6, 0xbf, 0x80, 0x89, 0x92, 0x9b,
0x7c, 0x75, 0x6e, 0x67, 0x58, 0x51, 0x4a, 0x43, 0x34, 0x3d, 0x26, 0x2f,
0x10, 0x19, 0x02, 0x0b, 0xd7, 0xde, 0xc5, 0xcc, 0xf3, 0xfa, 0xe1, 0xe8,
0x9f, 0x96, 0x8d, 0x84, 0xbb, 0xb2, 0xa9, 0xa0, 0x47, 0x4e, 0x55, 0x5c,
0x63, 0x6a, 0x71, 0x78, 0x0f, 0x06, 0x1d, 0x14, 0x2b, 0x22, 0x39, 0x30,
0x9a, 0x93, 0x88, 0x81, 0xbe, 0xb7, 0xac, 0xa5, 0xd2, 0xdb, 0xc0, 0xc9,
0xf6, 0xff, 0xe4, 0xed, 0x0a, 0x03, 0x18, 0x11, 0x2e, 0x27, 0x3c, 0x35,
0x42, 0x4b, 0x50, 0x59, 0x66, 0x6f, 0x74, 0x7d, 0xa1, 0xa8, 0xb3, 0xba,
0x85, 0x8c, 0x97, 0x9e, 0xe9, 0xe0, 0xfb, 0xf2, 0xcd, 0xc4, 0xdf, 0xd6,
0x31, 0x38, 0x23, 0x2a, 0x15, 0x1c, 0x07, 0x0e, 0x79, 0x70, 0x6b, 0x62,
0x5d, 0x54, 0x4f, 0x46},
{},
// mul 11
{0x00, 0x0b, 0x16, 0x1d, 0x2c, 0x27, 0x3a, 0x31, 0x58, 0x53, 0x4e, 0x45,
0x74, 0x7f, 0x62, 0x69, 0xb0, 0xbb, 0xa6, 0xad, 0x9c, 0x97, 0x8a, 0x81,
0xe8, 0xe3, 0xfe, 0xf5, 0xc4, 0xcf, 0xd2, 0xd9, 0x7b, 0x70, 0x6d, 0x66,
0x57, 0x5c, 0x41, 0x4a, 0x23, 0x28, 0x35, 0x3e, 0x0f, 0x04, 0x19, 0x12,
0xcb, 0xc0, 0xdd, 0xd6, 0xe7, 0xec, 0xf1, 0xfa, 0x93, 0x98, 0x85, 0x8e,
0xbf, 0xb4, 0xa9, 0xa2, 0xf6, 0xfd, 0xe0, 0xeb, 0xda, 0xd1, 0xcc, 0xc7,
0xae, 0xa5, 0xb8, 0xb3, 0x82, 0x89, 0x94, 0x9f, 0x46, 0x4d, 0x50, 0x5b,
0x6a, 0x61, 0x7c, 0x77, 0x1e, 0x15, 0x08, 0x03, 0x32, 0x39, 0x24, 0x2f,
0x8d, 0x86, 0x9b, 0x90, 0xa1, 0xaa, 0xb7, 0xbc, 0xd5, 0xde, 0xc3, 0xc8,
0xf9, 0xf2, 0xef, 0xe4, 0x3d, 0x36, 0x2b, 0x20, 0x11, 0x1a, 0x07, 0x0c,
0x65, 0x6e, 0x73, 0x78, 0x49, 0x42, 0x5f, 0x54, 0xf7, 0xfc, 0xe1, 0xea,
0xdb, 0xd0, 0xcd, 0xc6, 0xaf, 0xa4, 0xb9, 0xb2, 0x83, 0x88, 0x95, 0x9e,
0x47, 0x4c, 0x51, 0x5a, 0x6b, 0x60, 0x7d, 0x76, 0x1f, 0x14, 0x09, 0x02,
0x33, 0x38, 0x25, 0x2e, 0x8c, 0x87, 0x9a, 0x91, 0xa0, 0xab, 0xb6, 0xbd,
0xd4, 0xdf, 0xc2, 0xc9, 0xf8, 0xf3, 0xee, 0xe5, 0x3c, 0x37, 0x2a, 0x21,
0x10, 0x1b, 0x06, 0x0d, 0x64, 0x6f, 0x72, 0x79, 0x48, 0x43, 0x5e, 0x55,
0x01, 0x0a, 0x17, 0x1c, 0x2d, 0x26, 0x3b, 0x30, 0x59, 0x52, 0x4f, 0x44,
0x75, 0x7e, 0x63, 0x68, 0xb1, 0xba, 0xa7, 0xac, 0x9d, 0x96, 0x8b, 0x80,
0xe9, 0xe2, 0xff, 0xf4, 0xc5, 0xce, 0xd3, 0xd8, 0x7a, 0x71, 0x6c, 0x67,
0x56, 0x5d, 0x40, 0x4b, 0x22, 0x29, 0x34, 0x3f, 0x0e, 0x05, 0x18, 0x13,
0xca, 0xc1, 0xdc, 0xd7, 0xe6, 0xed, 0xf0, 0xfb, 0x92, 0x99, 0x84, 0x8f,
0xbe, 0xb5, 0xa8, 0xa3},
{},
// mul 13
{0x00, 0x0d, 0x1a, 0x17, 0x34, 0x39, 0x2e, 0x23, 0x68, 0x65, 0x72, 0x7f,
0x5c, 0x51, 0x46, 0x4b, 0xd0, 0xdd, 0xca, 0xc7, 0xe4, 0xe9, 0xfe, 0xf3,
0xb8, 0xb5, 0xa2, 0xaf, 0x8c, 0x81, 0x96, 0x9b, 0xbb, 0xb6, 0xa1, 0xac,
0x8f, 0x82, 0x95, 0x98, 0xd3, 0xde, 0xc9, 0xc4, 0xe7, 0xea, 0xfd, 0xf0,
0x6b, 0x66, 0x71, 0x7c, 0x5f, 0x52, 0x45, 0x48, 0x03, 0x0e, 0x19, 0x14,
0x37, 0x3a, 0x2d, 0x20, 0x6d, 0x60, 0x77, 0x7a, 0x59, 0x54, 0x43, 0x4e,
0x05, 0x08, 0x1f, 0x12, 0x31, 0x3c, 0x2b, 0x26, 0xbd, 0xb0, 0xa7, 0xaa,
0x89, 0x84, 0x93, 0x9e, 0xd5, 0xd8, 0xcf, 0xc2, 0xe1, 0xec, 0xfb, 0xf6,
0xd6, 0xdb, 0xcc, 0xc1, 0xe2, 0xef, 0xf8, 0xf5, 0xbe, 0xb3, 0xa4, 0xa9,
0x8a, 0x87, 0x90, 0x9d, 0x06, 0x0b, 0x1c, 0x11, 0x32, 0x3f, 0x28, 0x25,
0x6e, 0x63, 0x74, 0x79, 0x5a, 0x57, 0x40, 0x4d, 0xda, 0xd7, 0xc0, 0xcd,
0xee, 0xe3, 0xf4, 0xf9, 0xb2, 0xbf, 0xa8, 0xa5, 0x86, 0x8b, 0x9c, 0x91,
0x0a, 0x07, 0x10, 0x1d, 0x3e, 0x33, 0x24, 0x29, 0x62, 0x6f, 0x78, 0x75,
0x56, 0x5b, 0x4c, 0x41, 0x61, 0x6c, 0x7b, 0x76, 0x55, 0x58, 0x4f, 0x42,
0x09, 0x04, 0x13, 0x1e, 0x3d, 0x30, 0x27, 0x2a, 0xb1, 0xbc, 0xab, 0xa6,
0x85, 0x88, 0x9f, 0x92, 0xd9, 0xd4, 0xc3, 0xce, 0xed, 0xe0, 0xf7, 0xfa,
0xb7, 0xba, 0xad, 0xa0, 0x83, 0x8e, 0x99, 0x94, 0xdf, 0xd2, 0xc5, 0xc8,
0xeb, 0xe6, 0xf1, 0xfc, 0x67, 0x6a, 0x7d, 0x70, 0x53, 0x5e, 0x49, 0x44,
0x0f, 0x02, 0x15, 0x18, 0x3b, 0x36, 0x21, 0x2c, 0x0c, 0x01, 0x16, 0x1b,
0x38, 0x35, 0x22, 0x2f, 0x64, 0x69, 0x7e, 0x73, 0x50, 0x5d, 0x4a, 0x47,
0xdc, 0xd1, 0xc6, 0xcb, 0xe8, 0xe5, 0xf2, 0xff, 0xb4, 0xb9, 0xae, 0xa3,
0x80, 0x8d, 0x9a, 0x97},
// mul 14
{0x00, 0x0e, 0x1c, 0x12, 0x38, 0x36, 0x24, 0x2a, 0x70, 0x7e, 0x6c, 0x62,
0x48, 0x46, 0x54, 0x5a, 0xe0, 0xee, 0xfc, 0xf2, 0xd8, 0xd6, 0xc4, 0xca,
0x90, 0x9e, 0x8c, 0x82, 0xa8, 0xa6, 0xb4, 0xba, 0xdb, 0xd5, 0xc7, 0xc9,
0xe3, 0xed, 0xff, 0xf1, 0xab, 0xa5, 0xb7, 0xb9, 0x93, 0x9d, 0x8f, 0x81,
0x3b, 0x35, 0x27, 0x29, 0x03, 0x0d, 0x1f, 0x11, 0x4b, 0x45, 0x57, 0x59,
0x73, 0x7d, 0x6f, 0x61, 0xad, 0xa3, 0xb1, 0xbf, 0x95, 0x9b, 0x89, 0x87,
0xdd, 0xd3, 0xc1, 0xcf, 0xe5, 0xeb, 0xf9, 0xf7, 0x4d, 0x43, 0x51, 0x5f,
0x75, 0x7b, 0x69, 0x67, 0x3d, 0x33, 0x21, 0x2f, 0x05, 0x0b, 0x19, 0x17,
0x76, 0x78, 0x6a, 0x64, 0x4e, 0x40, 0x52, 0x5c, 0x06, 0x08, 0x1a, 0x14,
0x3e, 0x30, 0x22, 0x2c, 0x96, 0x98, 0x8a, 0x84, 0xae, 0xa0, 0xb2, 0xbc,
0xe6, 0xe8, 0xfa, 0xf4, 0xde, 0xd0, 0xc2, 0xcc, 0x41, 0x4f, 0x5d, 0x53,
0x79, 0x77, 0x65, 0x6b, 0x31, 0x3f, 0x2d, 0x23, 0x09, 0x07, 0x15, 0x1b,
0xa1, 0xaf, 0xbd, 0xb3, 0x99, 0x97, 0x85, 0x8b, 0xd1, 0xdf, 0xcd, 0xc3,
0xe9, 0xe7, 0xf5, 0xfb, 0x9a, 0x94, 0x86, 0x88, 0xa2, 0xac, 0xbe, 0xb0,
0xea, 0xe4, 0xf6, 0xf8, 0xd2, 0xdc, 0xce, 0xc0, 0x7a, 0x74, 0x66, 0x68,
0x42, 0x4c, 0x5e, 0x50, 0x0a, 0x04, 0x16, 0x18, 0x32, 0x3c, 0x2e, 0x20,
0xec, 0xe2, 0xf0, 0xfe, 0xd4, 0xda, 0xc8, 0xc6, 0x9c, 0x92, 0x80, 0x8e,
0xa4, 0xaa, 0xb8, 0xb6, 0x0c, 0x02, 0x10, 0x1e, 0x34, 0x3a, 0x28, 0x26,
0x7c, 0x72, 0x60, 0x6e, 0x44, 0x4a, 0x58, 0x56, 0x37, 0x39, 0x2b, 0x25,
0x0f, 0x01, 0x13, 0x1d, 0x47, 0x49, 0x5b, 0x55, 0x7f, 0x71, 0x63, 0x6d,
0xd7, 0xd9, 0xcb, 0xc5, 0xef, 0xe1, 0xf3, 0xfd, 0xa7, 0xa9, 0xbb, 0xb5,
0x9f, 0x91, 0x83, 0x8d} };
// circulant MDS matrix
static const uint8_t CMDS[ 4 ][ 4 ] = {
{2, 3, 1, 1}, {1, 2, 3, 1}, {1, 1, 2, 3}, {3, 1, 1, 2} };
// Inverse circulant MDS matrix
static const uint8_t INV_CMDS[ 4 ][ 4 ] = {
{14, 11, 13, 9}, {9, 14, 11, 13}, {13, 9, 14, 11}, {11, 13, 9, 14} };

View File

@@ -0,0 +1,92 @@
#pragma once
#include <memory>
#include <mutex>
#include <string>
#include <tuple>
#include <chrono>
#include <map>
#include <sqlite3.h>
#include "Transaction.hpp"
#include "Game/RealmCharacter.hpp"
#include "Game/RealmCharacterMetaKV.hpp"
enum class QueryID {
CreateAccount,
VerifyAccount,
LoadAccount,
LoadCharacterSlots,
CreateNewCharacter,
SaveCharacter,
LoadCharacter,
SaveFriend,
RemoveFriend,
LoadFriendList,
SaveIgnore,
RemoveIgnore,
LoadIgnoreList,
};
class Database {
private:
static inline std::unique_ptr<Database> m_instance;
static inline std::mutex m_mutex;
sqlite3 *m_db = nullptr;
std::unordered_map< QueryID, sqlite3_stmt * > m_statements;
public:
static Database &Get()
{
std::lock_guard<std::mutex> lock( m_mutex );
if( !m_instance )
m_instance.reset( new Database() );
return *m_instance;
}
Database( const Database & ) = delete;
Database &operator=( const Database & ) = delete;
Database();
~Database();
public:
int64_t CreateNewAccount( const std::string &username,
const std::string &password,
const std::string &email_address,
const std::string &date_of_birth,
const std::string &chat_handle );
std::tuple< bool, int64_t, std::wstring > VerifyAccount( const std::wstring &username, const std::wstring &password );
uint32_t CreateNewCharacter( const int64_t account_id,
const CharacterSlotData meta,
const std::vector< uint8_t > &blob );
bool SaveCharacter( const int64_t account_id,
const int32_t character_id,
const CharacterSlotData meta,
const std::vector< uint8_t > &blob );
std::map< uint32_t, CharacterSlotData > LoadCharacterSlots( const int64_t account_id );
sptr_realm_character LoadCharacterData( const int64_t account_id, const int32_t character_id );
bool SaveFriend( const int64_t account_id, const std::wstring &friend_handle );
bool RemoveFriend( const int64_t account_id, const std::wstring &friend_handle );
std::vector< std::wstring > LoadFriends( const int64_t account_id );
bool SaveIgnore( const int64_t account_id, const std::wstring &ignore_handle );
bool RemoveIgnore( const int64_t account_id, const std::wstring &ignore_handle );
std::vector< std::wstring > LoadIgnores( const int64_t account_id );
private:
void CreateTables();
void PrepareStatements();
void FinalizeStatements();
void Execute( const char *sql );
};

View File

@@ -0,0 +1,68 @@
#pragma once
#include <sqlite3.h>
#include <stdexcept>
class SQLiteTransaction {
sqlite3 *m_db = nullptr;
bool m_committed = false;
public:
explicit SQLiteTransaction( sqlite3 *db )
: m_db( db )
{
if( !m_db )
throw std::invalid_argument( "Null SQLite database pointer" );
if( sqlite3_exec( m_db, "BEGIN TRANSACTION;", nullptr, nullptr, nullptr ) != SQLITE_OK )
throw std::runtime_error( "Failed to begin transaction: " + std::string( sqlite3_errmsg( m_db ) ) );
}
~SQLiteTransaction()
{
if( m_committed || !m_db )
return;
sqlite3_exec( m_db, "ROLLBACK;", nullptr, nullptr, nullptr );
}
SQLiteTransaction( const SQLiteTransaction & ) = delete;
SQLiteTransaction &operator=( const SQLiteTransaction & ) = delete;
SQLiteTransaction( SQLiteTransaction &&other ) noexcept
: m_db( other.m_db ), m_committed( other.m_committed )
{
other.m_db = nullptr;
}
SQLiteTransaction &operator=( SQLiteTransaction &&other ) noexcept
{
if( this != &other )
{
rollbackOnError();
m_db = other.m_db;
m_committed = other.m_committed;
other.m_db = nullptr;
}
return *this;
}
void commit()
{
if( m_committed || !m_db )
return;
if( sqlite3_exec( m_db, "COMMIT;", nullptr, nullptr, nullptr ) != SQLITE_OK )
throw std::runtime_error( "Failed to commit transaction: " + std::string( sqlite3_errmsg( m_db ) ) );
m_committed = true;
}
private:
void rollbackOnError()
{
if( m_committed || !m_db )
return;
sqlite3_exec( m_db, "ROLLBACK;", nullptr, nullptr, nullptr );
}
};

View File

@@ -0,0 +1,43 @@
#pragma once
#include <memory>
#include <string>
#include <thread>
#include <mutex>
#include <atomic>
#include <vector>
#include <winsock2.h>
#include <ws2tcpip.h>
#include "Common/ByteStream.hpp"
class DiscoveryServer {
public:
static DiscoveryServer &Get()
{
static DiscoveryServer instance;
return instance;
}
DiscoveryServer( const DiscoveryServer & ) = delete;
DiscoveryServer &operator=( const DiscoveryServer & ) = delete;
DiscoveryServer();
~DiscoveryServer();
void Start( std::string ip, int32_t port );
void Stop();
void Run();
bool isRunning() const
{
return m_running;
}
private:
void ProcessPacket( sockaddr_in *clientAddr, sptr_byte_stream stream );
std::atomic< bool > m_running;
std::thread m_thread;
SOCKET m_socket;
std::vector< unsigned char > m_recvBuffer;
};

View File

@@ -0,0 +1,43 @@
#pragma once
#include <string>
#include <memory>
#include <unordered_map>
#include "CharacterSaveTask.hpp"
class CharacterSaveManager {
public:
CharacterSaveManager();
~CharacterSaveManager();
CharacterSaveManager( const CharacterSaveManager & ) = delete;
CharacterSaveManager &operator=( const CharacterSaveManager & ) = delete;
static CharacterSaveManager &Get()
{
static CharacterSaveManager instance;
return instance;
}
bool BeginSaveTask(
const sptr_user user,
const uint32_t characterId,
const CharacterSlotData &metaData,
const CharacterSaveType saveType );
bool BeginSaveTask(
const sptr_user m_owner,
const sptr_user m_target,
const uint32_t characterId,
const CharacterSlotData &metaData,
const CharacterSaveType saveType );
void AppendSaveData( const std::wstring &sessionId, const std::vector<uint8_t> &data, bool endOfData );
bool CommitSaveTask( const std::wstring &sessionId );
void RemoveSaveTask( const std::wstring &sessionId );
sptr_character_save_task FindSaveTask( const std::wstring &sessionId );
public:
std::unordered_map< std::wstring, sptr_character_save_task > m_tasks;
};

View File

@@ -0,0 +1,43 @@
#pragma once
#include <array>
#include <string>
#include <vector>
#include <unordered_map>
#include "Common/Constant.hpp"
#include "Common/ByteStream.hpp"
#include "RealmUser.hpp"
#include "RealmCharacterMetaKV.hpp"
enum class CharacterSaveType : uint8_t
{
NEW_CHARACTER,
SAVE_CHARACTER
};
class CharacterSaveTask {
public:
CharacterSaveTask( CharacterSaveType Type, uint32_t characterId = 0 );
~CharacterSaveTask();
void SetMetaData( const CharacterSlotData &metaData );
bool AppendData( const std::vector< uint8_t > &data );
bool Validate();
const std::vector< uint8_t >& GetData() const;
public:
CharacterSaveType m_saveType;
sptr_user m_ownerUser;
sptr_user m_targetUser;
uint32_t m_characterId;
uint32_t m_writePosition;
CharacterSlotData m_meta;
std::vector< uint8_t > m_data;
};
using sptr_character_save_task = std::shared_ptr< CharacterSaveTask >;

View File

@@ -0,0 +1,42 @@
#pragma once
#include <memory>
#include <mutex>
#include <string>
#include <map>
#include "ChatRoomSession.hpp"
class ChatRoomManager {
private:
int32_t m_roomIndex = 0;
std::map< int32_t, sptr_chat_room_session > m_chatSessionList;
void CreatePublicRooms();
public:
ChatRoomManager();
~ChatRoomManager();
ChatRoomManager( const ChatRoomManager & ) = delete;
ChatRoomManager &operator=( const ChatRoomManager & ) = delete;
static ChatRoomManager &Get()
{
static ChatRoomManager instance;
return instance;
}
std::vector< sptr_chat_room_session > GetPublicRoomList() const;
bool JoinRoom( sptr_user user, const std::wstring &roomName );
bool LeaveRoom( sptr_user user, const std::wstring &roomName );
bool LeaveRoom( sptr_user user, const int32_t roomId );
void OnDisconnectUser( sptr_user user );
bool CreateGameChatSession( sptr_user user, const std::wstring roomName );
bool CloseGameChatSession( const std::wstring roomName );
void SendMessageToRoom( const std::wstring roomName, const std::wstring handle, const std::wstring message );
sptr_chat_room_session FindRoom( const std::wstring &roomName );
sptr_chat_room_session FindRoom( const int32_t roomId );
};

View File

@@ -0,0 +1,36 @@
#pragma once
#include <memory>
#include <string>
#include <vector>
#include "RealmUser.hpp"
class ChatRoomSession {
public:
ChatRoomSession();
~ChatRoomSession();
bool AddMember( sptr_user user );
bool RemoveMember( sptr_user user );
bool IsMember( sptr_user user );
bool IsPublic() const;
bool IsPrivate() const;
enum class RoomType {
Public,
Private
};
RoomType m_type;
int32_t m_index;
std::wstring m_name;
std::wstring m_banner;
wptr_user m_owner;
std::vector< wptr_user > m_members;
std::vector< wptr_user > m_moderators;
};
typedef std::shared_ptr< ChatRoomSession > sptr_chat_room_session;

View File

@@ -0,0 +1,65 @@
#pragma once
#include <array>
#include <vector>
#include <string>
#include <memory>
#include "RealmUser.hpp"
class GameSession {
public:
enum class GameType {
Public,
Private
};
enum class GameState {
NotReady,
Open,
Started
};
GameSession( uint32_t index );
~GameSession();
bool IsJoinable( sptr_user user = nullptr ) const;
sptr_user GetOwner() const;
sptr_user GetMember( int32_t index ) const;
sptr_user GetMemberBySessionId( const std::wstring &sessionId ) const;
std::vector< sptr_user > GetMembers() const;
bool AddMember( sptr_user user );
bool RemoveMember( sptr_user user );
public:
GameType m_type;
GameState m_state;
std::array< wptr_user, 4 > m_members;
int32_t m_gameId;
std::wstring m_gameName;
std::wstring m_ownerName;
std::wstring m_playerCount;
std::string m_gameData;
std::string m_description;
std::string m_hostLocalAddr;
std::string m_hostExternalAddr;
int32_t m_hostLocalPort;
int32_t m_hostNatPort;
int8_t m_currentPlayers;
int8_t m_maximumPlayers;
int8_t m_difficulty;
int8_t m_gameMode;
int8_t m_mission;
int8_t m_unknown;
int8_t m_networkSave;
};
typedef std::shared_ptr< GameSession > sptr_game_session;

View File

@@ -0,0 +1,67 @@
#pragma once
#include <memory>
#include <mutex>
#include <vector>
#include "GameSession.hpp"
#include "Common/Constant.hpp"
class GameSessionManager {
private:
static inline std::unique_ptr< GameSessionManager > m_instance;
static inline std::mutex m_mutex;
static inline std::mutex m_dataMutex;
int32_t m_uniqueGameIndex;
std::vector< sptr_game_session > m_gameSessionList[ 2 ];
public:
GameSessionManager();
~GameSessionManager();
GameSessionManager( const GameSessionManager & ) = delete;
GameSessionManager &operator=( const GameSessionManager & ) = delete;
static GameSessionManager &Get()
{
std::lock_guard< std::mutex > lock( m_mutex );
if( m_instance == nullptr )
{
m_instance.reset( new GameSessionManager() );
}
return *m_instance;
}
void OnDisconnectUser( sptr_user user );
bool CreateGameSession_CON( sptr_user user,
const std::wstring gameInfo,
const std::wstring name,
const std::wstring stage,
const bool isPrivateGame );
bool CreateGameSession_RTA( sptr_user user,
const std::wstring gameInfo,
const std::wstring name,
const std::array< int8_t, 5 > &attributes,
const bool isPrivateGame );
bool ForceTerminateGame( const int32_t gameId, RealmGameType clientType );
sptr_game_session FindGame( const int32_t gameId, RealmGameType clientType );
sptr_game_session FindGame( const std::wstring &gameName, RealmGameType clientType );
bool RequestOpen( sptr_user user );
bool RequestCancel( sptr_user user );
bool RequestJoin( sptr_user user );
bool RequestStart( sptr_user user );
std::vector< sptr_game_session > GetAvailableGameSessionList( const RealmGameType clientType ) const;
std::vector< sptr_game_session > GetPublicGameSessionList( const RealmGameType clientType ) const;
std::vector< sptr_game_session > GetPrivateGameSessionList( const RealmGameType clientType ) const;
private:
void ProcessJoinNorrath( sptr_user join, sptr_user host );
void ProcessJoinArms( sptr_user join, sptr_user host );
};

View File

@@ -0,0 +1,170 @@
#pragma once
#include <array>
#include <string>
#include <vector>
#include <unordered_map>
#include "Common/Constant.hpp"
#include "Common/ByteStream.hpp"
#include "RealmCharacterMetaKV.hpp"
constexpr size_t MAX_NUMBER_OF_CHARACTERS = 12;
constexpr size_t CHARACTER_DATA_SIZE = 19504;
using ItemData = std::array< uint8_t, 72 >;
using AttackData = std::array< float_t, 4 >;
class RealmCharacter {
public:
RealmCharacter();
RealmCharacter( const int32_t id, const CharacterSlotData meta, const std::vector< uint8_t > data );
~RealmCharacter();
void Initialize();
const std::vector< uint8_t > Serialize() const;
void Deserialize( const std::vector< uint8_t > &data );
bool ValidateData();
CharacterSlotData GetMetaData() const;
void SetMetaData( sptr_byte_stream stream );
std::vector< uint8_t > Unpack();
public:
uint32_t m_characterId;
CharacterSlotData m_metaData;
std::vector< uint8_t > m_data;
public:
std::string name;
uint8_t unknown_000[ 4 ];
std::string unknown_str;
int32_t unknown_004[ 3 ];
CharacterClass character_class;
CharacterRace character_race;
uint8_t current_level;
uint8_t pending_level; // Waiting to spend points, basically.
uint16_t unknown_009;
int32_t experience;
int32_t unknown_010[ 6 ];
struct s_stats {
int32_t strength, intelligence, dexterity, stamina, unknown_a, unknown_b;
} stats[ 2 ];
int32_t unknown_016;
float_t current_hp, maximum_hp;
int32_t unknown_017, unknown_018, unknown_019;
float_t current_mana, maximum_mana;
int32_t unknown_020;
int32_t attack_power, minimum_damage, maximum_damage;
int32_t unknown_021, unknown_022;
uint8_t unknown_023, unknown_024, unknown_025, unknown_026;
int32_t current_gold, current_skill_points;
int16_t current_ability_points;
int16_t has_spent_remaining_points;
int32_t unknown_029, unknown_030, unknown_031, unknown_032;
int32_t unknown_033, unknown_034, unknown_035, unknown_036;
int32_t unknown_037, unknown_038, unknown_039, unknown_040;
float_t weight, max_weight;
int32_t unknown_041, unknown_042;
std::array<ItemData, 64> item_data;
int32_t num_armor_item, unknown_043;
std::array<ItemData, 64> armor_item_data;
int32_t num_weapon_item, unknown_044;
std::array<ItemData, 64> weapon_item_data;
int32_t num_consumable_item, unknown_045;
std::array< uint8_t, 2696 > unknown_046;
struct s_quest {
char name[ 32 ];
char description[ 32 ];
};
std::array<s_quest, 8> quest_string;
int32_t num_quests;
int32_t unknown_048;
int32_t unknown_049;
int32_t unknown_050;
int32_t unknown_051;
int32_t unknown_052;
int32_t unknown_053;
int32_t unknown_054;
std::array< int32_t, 20 > equipment;
struct s_new_style {
char name[ 32 ]; // "newstyle"
int id;
uint8_t active_flag;
uint8_t type;
uint8_t unknown_a;
uint8_t unknown_b;
uint8_t reserved[ 64 ];
};
std::array<s_new_style, 15> newStyle;
int32_t unknown_075;
float_t unknown_076;
int32_t
unknown_077, unknown_078, unknown_079,
unknown_080, unknown_081, unknown_082,
unknown_083, unknown_084, unknown_085;
uint8_t skill_slot[ 2 ];
uint8_t unknown_087, unknown_088;
std::array< AttackData, 8> attackData;
struct s_skill {
int16_t skill_id;
int16_t skill_level;
};
std::array<s_skill, 48> skills;
int32_t unknown_091;
struct s_difficulty_progress {
uint8_t mission_na;
uint8_t mission_War;
uint8_t mission_Innovation;
uint8_t mission_PitOfIllOmen;
uint8_t mission_PlaneOfWater;
uint8_t mission_Torment;
uint8_t mission_Disease;
uint8_t mission_Valor;
uint8_t mission_Fire;
uint8_t mission_Storms;
uint8_t mission_Faydark;
uint8_t mission_Nightmares;
uint8_t mission_Fear;
};
std::array<s_difficulty_progress, 5> mission_progress;
std::array< uint8_t, 13 > mission_medals;
uint8_t evil_bitflag, good_bitflag;
int32_t unknown_101;
float_t movement_speed;
uint8_t unknown_102, unknown_103, unknown_104, unknown_105;
uint8_t unknown_106, unknown_107, unknown_108, unknown_109;
int32_t unknown_110;
};
using sptr_realm_character = std::shared_ptr< RealmCharacter >;

View File

@@ -0,0 +1,50 @@
#pragma once
#include <string>
#include <vector>
#include <utility>
#include "Common/ByteStream.hpp"
using CharacterAttributeKV = std::pair<std::wstring, std::wstring>;
class CharacterSlotData {
private:
std::vector<CharacterAttributeKV> m_metaData;
public:
CharacterSlotData() = default;
CharacterSlotData( const std::vector< uint8_t > &data );
void Deserialize( const std::vector< uint8_t > &data );
void Deserialize( const sptr_byte_stream stream );
std::vector<uint8_t> Serialize() const;
bool empty() const
{
return m_metaData.empty();
}
const std::vector<CharacterAttributeKV> &GetMetaData() const
{
return m_metaData;
}
void SetMetaData( const std::vector<CharacterAttributeKV> &metaData )
{
m_metaData = metaData;
}
std::wstring GetValue( std::wstring key )
{
for( const auto &kv : m_metaData )
{
if( kv.first == key )
{
return kv.second;
}
}
return L"";
}
};

View File

@@ -0,0 +1,68 @@
#pragma once
#include <string>
#include <memory>
#include <array>
#include "RealmCharacter.hpp"
#include "Common/Constant.hpp"
#include "../Network/RealmSocket.hpp"
class RealmUser {
public:
RealmUser();
~RealmUser();
bool operator==( const RealmUser &other ) const
{
return m_accountId == other.m_accountId || sock->fd == other.sock->fd;
}
bool operator<( const RealmUser &other ) const
{
if( m_sessionId != other.m_sessionId )
return m_sessionId < other.m_sessionId;
return m_accountId < other.m_accountId;
}
bool IsFriend( const std::wstring &handle ) const
{
return std::find( m_friendList.begin(), m_friendList.end(), handle ) != m_friendList.end();
}
bool IsIgnored( const std::wstring &handle ) const
{
return std::find( m_ignoreList.begin(), m_ignoreList.end(), handle ) != m_ignoreList.end();
}
public:
sptr_socket sock; // For Realm Lobby
RealmGameType m_gameType; // Champions of Norrath or Return to Arms
int64_t m_accountId; // Unique ID of the account
std::wstring m_sessionId; // Temporary Session ID
std::wstring m_username; // Username of the user
std::wstring m_chatHandle; // Chat handle for the user, used in chat rooms
bool m_isLoggedIn; // True if the user has successfully authenticated and logged in
bool m_isHost; // True if this user is the host of a realm
int32_t m_gameId; // Unique ID of the realm
int32_t m_publicRoomId; // Used for public chat rooms
int32_t m_privateRoomId; // Used for private chat rooms
std::string m_localAddr; // Local IP address of the user, passed from the client during Realm creation.
int32_t m_localPort;
std::string m_discoveryAddr;
int32_t m_discoveryPort;
int32_t m_characterId;
sptr_realm_character m_character;
std::vector< std::wstring > m_friendList; // List of friends for this user
std::vector< std::wstring > m_ignoreList; // List of ignored users
};
using sptr_user = std::shared_ptr< RealmUser >;
using wptr_user = std::weak_ptr< RealmUser >;

View File

@@ -0,0 +1,46 @@
#pragma once
#include <memory>
#include <mutex>
#include <vector>
#include <string>
#include <random>
#include "RealmUser.hpp"
class UserManager {
private:
public:
static UserManager &Get()
{
static UserManager instance;
return instance;
}
UserManager( const UserManager & ) = delete;
UserManager &operator=( const UserManager & ) = delete;
UserManager();
~UserManager();
std::wstring GenerateSessionId();
sptr_user CreateUser( sptr_socket socket, RealmGameType clientType );
void RemoveUser( sptr_user user );
void RemoveUser( const std::wstring &sessionId );
void RemoveUser( const sptr_socket socket );
void Disconnect( sptr_socket socket, const std::string reason );
void Disconnect( sptr_user user, const std::string reason );
sptr_user FindUserBySessionId( const std::wstring &sessionId );
sptr_user FindUserBySocket( const sptr_socket &socket );
sptr_user FindUserByChatHandle( const std::wstring &handle );
int32_t GetUserCount() const;
std::vector< sptr_user > GetUserList();
void NotifyFriendsOnlineStatus( const sptr_user &user, bool onlineStatus );
private:
std::mutex m_mutex;
std::vector< sptr_user > m_users;
std::mt19937 rng;
};

View File

@@ -0,0 +1,59 @@
#pragma once
#include <memory>
#include <mutex>
#include <thread>
#include <atomic>
#include <vector>
#include <string>
#include <array>
#include <winsock2.h>
#include <ws2tcpip.h>
#include "Common/Constant.hpp"
#include "Common/ByteStream.hpp"
#include "../Network/RealmSocket.hpp"
class LobbyServer
{
private:
std::atomic< bool > m_running;
std::thread m_thread;
public:
static LobbyServer& Get()
{
static LobbyServer instance;
return instance;
}
LobbyServer( const LobbyServer & ) = delete;
LobbyServer &operator=( const LobbyServer & ) = delete;
LobbyServer();
~LobbyServer();
void Start( std::string ip );
void Stop();
bool isRunning() const
{
return m_running;
}
private:
sptr_socket m_conSocket;
sptr_socket m_rtaSocket;
std::vector< sptr_socket > m_gatewaySockets;
std::vector< sptr_socket > m_clientSockets;
std::vector< uint8_t > m_recvBuffer;
sptr_socket OpenListenerSocket( std::string ip, int32_t port, RealmGameType type );
void Run();
void CheckSocketProblem();
void AcceptConnection( sptr_socket srcSocket );
void ReadSocket( sptr_socket socket );
void WriteSocket( sptr_socket socket );
void HandleRequest( sptr_socket socket, sptr_byte_stream stream );
};

View File

@@ -0,0 +1,16 @@
#pragma once
#include <string>
#include "../GenericNetMessage.hpp"
#include "Common/ForwardDecl.hpp"
class NotifyClientDiscovered : public GenericMessage {
private:
std::string m_clientIp;
int32_t m_clientPort;
public:
NotifyClientDiscovered( sptr_user user );
void Serialize( ByteBuffer &out ) const override;
};

View File

@@ -0,0 +1,17 @@
#pragma once
#include <string>
#include "../GenericNetMessage.hpp"
#include "Common/Constant.hpp"
#include "Common/ForwardDecl.hpp"
class NotifyClientDiscovered_RTA : public GenericMessage {
private:
std::string m_clientIp;
int32_t m_clientPort;
public:
NotifyClientDiscovered_RTA( sptr_user user );
void Serialize( ByteBuffer &out ) const override;
};

View File

@@ -0,0 +1,16 @@
#pragma once
#include <string>
#include "../GenericNetMessage.h"
class NotifyClientRequestConnect : public GenericMessage
{
private:
std::string m_clientIp;
int32_t m_clientPort;
public:
NotifyClientRequestConnect( std::string clientIp, int32_t clientPort );
ByteBuffer &Serialize() override;
};

View File

@@ -0,0 +1,16 @@
#pragma once
#include <string>
#include "../GenericNetMessage.hpp"
#include "Common/ForwardDecl.hpp"
class NotifyClientRequestConnect : public GenericMessage {
private:
std::string m_clientIp;
int32_t m_clientPort;
public:
NotifyClientRequestConnect( sptr_user user );
void Serialize( ByteBuffer &out ) const override;
};

View File

@@ -0,0 +1,19 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetMessage.hpp"
#include "Common/ForwardDecl.hpp"
class NotifyClientRequestConnect_RTA : public GenericMessage {
private:
std::string m_localAddr;
std::string m_remoteAddr;
int32_t m_localPort;
int32_t m_remotePort;
public:
NotifyClientRequestConnect_RTA( sptr_user user );
void Serialize( ByteBuffer &out ) const override;
};

View File

@@ -0,0 +1,11 @@
#pragma once
#include "../GenericNetMessage.hpp"
class NotifyForcedLogout : public GenericMessage {
private:
public:
NotifyForcedLogout();
void Serialize( ByteBuffer &out ) const override;
};

View File

@@ -0,0 +1,13 @@
#pragma once
#include "../GenericNetMessage.hpp"
class NotifyFriendStatus : public GenericMessage {
private:
std::wstring m_handle;
bool m_status;
public:
NotifyFriendStatus( std::wstring handle, bool status );
void Serialize( ByteBuffer &out ) const override;
};

View File

@@ -0,0 +1,19 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetMessage.hpp"
#include "Common/Constant.hpp"
#include "Common/ForwardDecl.hpp"
class NotifyGameDiscovered : public GenericMessage {
private:
std::string m_clientIp;
int32_t m_clientPort;
RealmGameType m_clientType;
public:
NotifyGameDiscovered( sptr_user user );
void Serialize(ByteBuffer &out) const override;
};

View File

@@ -0,0 +1,13 @@
#pragma once
#include "../GenericNetMessage.hpp"
class NotifyInstantMessage : public GenericMessage {
private:
std::wstring m_message;
std::wstring m_chatHandle;
public:
NotifyInstantMessage( std::wstring chatHandle, std::wstring message );
void Serialize(ByteBuffer &out) const override;
};

View File

@@ -0,0 +1,14 @@
#pragma once
#include "../GenericNetMessage.h"
class NotifyReserveUserSlot_RTA : public GenericMessage {
private:
std::string m_discoveryAddr;
int32_t m_port;
int32_t m_memberId;
public:
NotifyReserveUserSlot_RTA( int32_t memberId, std::string discoveryAddr, int32_t discoveryPort );
void Serialize(ByteBuffer &out) const override;
};

View File

@@ -0,0 +1,14 @@
#pragma once
#include "../GenericNetMessage.hpp"
class NotifyRoomMessage : public GenericMessage {
private:
std::wstring m_message;
std::wstring m_chatHandle;
std::wstring m_roomName;
public:
NotifyRoomMessage( std::wstring roomName, std::wstring chatHandle, std::wstring message );
void Serialize(ByteBuffer &out) const override;
};

View File

@@ -0,0 +1,11 @@
#pragma once
#include "../GenericNetMessage.h"
class Notify_4C : public GenericMessage {
private:
public:
Notify_4C();
void Serialize(ByteBuffer &out) const override;
};

View File

@@ -0,0 +1,14 @@
#pragma once
#include "../GenericNetMessage.h"
class NotifyClientRequestsConnect2 : public GenericMessage {
private:
std::string m_discoveryAddr;
std::string m_localAddr;
int32_t m_port;
public:
NotifyClientRequestsConnect2( std::string discoveryAddr, std::string localAddr, int32_t port );
ByteBuffer &Serialize() override;
};

View File

@@ -0,0 +1,40 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetRequest.hpp"
#include "../GenericNetResponse.hpp"
class RequestAddFriend : public GenericRequest
{
private:
std::wstring m_sessionId;
std::wstring m_chatHandle;
enum ERROR_CODE {
SUCCESS = 0,
FATAL_ERROR,
DATABASE_ERROR = 2,
FRIEND_IGNORING = 19,
FRIEND_INVALID = 20,
FRIEND_DUPLICATE = 21,
};
public:
static std::unique_ptr< RequestAddFriend > Create()
{
return std::make_unique< RequestAddFriend >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultAddFriend : public GenericResponse {
private:
int32_t m_reply;
public:
ResultAddFriend( GenericRequest *request, int32_t reply );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -0,0 +1,41 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetRequest.hpp"
#include "../GenericNetResponse.hpp"
class RequestAddIgnore : public GenericRequest
{
private:
std::wstring m_sessionId;
std::wstring m_chatHandle;
enum ERROR_CODE {
SUCCESS = 0,
FATAL_ERROR,
DATABASE_ERROR = 2,
IGNORE_INVALID = 20,
IGNORE_FRIEND = 24,
IGNORE_DUPLICATE = 25,
};
public:
static std::unique_ptr< RequestAddIgnore > Create()
{
return std::make_unique< RequestAddIgnore >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultAddIgnore : public GenericResponse {
private:
int32_t m_reply;
public:
ResultAddIgnore( GenericRequest *request, int32_t reply );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -0,0 +1,37 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetRequest.hpp"
#include "../GenericNetResponse.hpp"
class RequestAppendCharacterData : public GenericRequest
{
private:
std::vector< uint8_t > m_data;
int32_t m_endOfData;
enum ERROR_CODE {
SUCCESS = 0,
FATAL_ERROR,
GENERAL_ERROR,
};
public:
static std::unique_ptr< RequestAppendCharacterData > Create()
{
return std::make_unique< RequestAppendCharacterData >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultAppendCharacterData : public GenericResponse {
private:
int32_t m_reply;
public:
ResultAppendCharacterData( GenericRequest *request, int32_t reply );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -0,0 +1,28 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetRequest.hpp"
#include "../GenericNetResponse.hpp"
class RequestCancelGame : public GenericRequest
{
private:
std::wstring m_sessionId;
public:
static std::unique_ptr< RequestCancelGame > Create()
{
return std::make_unique< RequestCancelGame >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultCancelGame : public GenericResponse {
public:
ResultCancelGame( GenericRequest *request );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -0,0 +1,28 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetRequest.hpp"
#include "../GenericNetResponse.hpp"
class RequestCancelGame_RTA : public GenericRequest
{
private:
std::wstring m_sessionId;
public:
static std::unique_ptr< RequestCancelGame_RTA > Create()
{
return std::make_unique< RequestCancelGame_RTA >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultCancelGame_RTA : public GenericResponse {
public:
ResultCancelGame_RTA( GenericRequest *request );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -0,0 +1,46 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetRequest.hpp"
#include "../GenericNetResponse.hpp"
class RequestCreateAccount : public GenericRequest
{
private:
enum CREATE_ACCOUNT_REPLY {
SUCCESS = 0,
ERROR_FATAL,
ERROR_NOT_EXIST
};
std::wstring m_username;
std::wstring m_password;
std::wstring m_emailAddress;
std::wstring m_dateOfBirth;
std::wstring m_chatHandle;
bool VerifyUserData();
public:
static std::unique_ptr< RequestCreateAccount > Create()
{
return std::make_unique< RequestCreateAccount >();
}
CREATE_ACCOUNT_REPLY m_reply;
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultCreateAccount : public GenericResponse {
private:
std::wstring m_sessionId;
int32_t m_reply;
public:
ResultCreateAccount( GenericRequest *request, int32_t reply, std::wstring sessionId );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -0,0 +1,38 @@
#pragma once
#include "../GenericNetRequest.hpp"
#include "../GenericNetResponse.hpp"
#include "Game/RealmCharacter.hpp"
class RequestCreateNewCharacter_RTA : public GenericRequest
{
private:
std::wstring m_sessionId;
CharacterSlotData m_metaData;
std::vector< uint8_t > m_characterData;
enum ERROR_CODE {
SUCCESS = 0,
FATAL_ERROR,
GENERAL_ERROR,
};
public:
static std::unique_ptr< RequestCreateNewCharacter_RTA > Create()
{
return std::make_unique< RequestCreateNewCharacter_RTA >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultCreateNewCharacter_RTA : public GenericResponse {
private:
int32_t m_reply;
public:
ResultCreateNewCharacter_RTA( GenericRequest *request, int32_t reply );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -0,0 +1,42 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetRequest.hpp"
#include "../GenericNetResponse.hpp"
class RequestCreatePrivateGame : public GenericRequest
{
private:
std::wstring m_sessionId;
std::wstring m_gameName;
enum ERROR_CODE {
SUCCESS = 0,
FATAL_ERROR,
GENERAL_ERROR,
GAME_NAME_IN_USE = 38,
GAME_PENDING = 40,
};
public:
static std::unique_ptr< RequestCreatePrivateGame > Create()
{
return std::make_unique< RequestCreatePrivateGame >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultCreatePrivateGame : public GenericResponse {
private:
int32_t m_reply;
std::string m_discoveryIp;
int32_t m_discoveryPort;
public:
ResultCreatePrivateGame( GenericRequest *request, int32_t reply, std::string discoveryIp = "", int32_t discoveryPort = 0 );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -0,0 +1,45 @@
#pragma once
#include <memory>
#include <string>
#include <array>
#include "../GenericNetRequest.hpp"
#include "../GenericNetResponse.hpp"
class RequestCreatePrivateGame_RTA : public GenericRequest
{
private:
std::wstring m_sessionId;
std::wstring m_gameName;
std::string m_localAddr;
int32_t m_localPort;
enum ERROR_CODE {
SUCCESS = 0,
FATAL_ERROR,
GENERAL_ERROR,
GAME_NAME_IN_USE = 38,
GAME_PENDING = 40,
};
public:
static std::unique_ptr< RequestCreatePrivateGame_RTA > Create()
{
return std::make_unique< RequestCreatePrivateGame_RTA >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultCreatePrivateGame_RTA : public GenericResponse {
private:
int32_t m_reply;
std::string m_discoveryIp;
int32_t m_discoveryPort;
public:
ResultCreatePrivateGame_RTA( GenericRequest *request, int32_t reply, std::string discoveryIp = "", int32_t discoveryPort = 0 );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -0,0 +1,29 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetRequest.hpp"
#include "../GenericNetResponse.hpp"
class RequestCreatePrivateRoom : public GenericRequest
{
private:
std::wstring m_sessionId;
std::wstring m_roomName;
public:
static std::unique_ptr< RequestCreatePrivateRoom > Create()
{
return std::make_unique< RequestCreatePrivateRoom >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultCreatePrivateRoom : public GenericResponse {
public:
ResultCreatePrivateRoom( GenericRequest *request );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -0,0 +1,48 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetRequest.hpp"
#include "../GenericNetResponse.hpp"
class RequestCreatePublicGame : public GenericRequest
{
private:
std::wstring m_sessionId;
std::wstring m_gameInfo;
std::wstring m_gameName;
std::wstring m_stageName;
int32_t m_minimumLevel;
int32_t m_maximumLevel;
enum ERROR_CODE {
SUCCESS = 0,
FATAL_ERROR,
GENERAL_ERROR,
GAME_NAME_IN_USE = 38,
GAME_PENDING = 40,
};
public:
static std::unique_ptr< RequestCreatePublicGame > Create()
{
return std::make_unique< RequestCreatePublicGame >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
std::tuple< std::wstring, std::wstring > ParseNameAndStage( const std::wstring &gameInfo );
};
class ResultCreatePublicGame : public GenericResponse {
private:
int32_t m_reply;
std::string m_discoveryIp;
int32_t m_discoveryPort;
public:
ResultCreatePublicGame( GenericRequest *request, int32_t reply, std::string discoveryIp = "", int32_t discoveryPort = 0 );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -0,0 +1,48 @@
#pragma once
#include <memory>
#include <string>
#include <array>
#include "../GenericNetRequest.hpp"
#include "../GenericNetResponse.hpp"
class RequestCreatePublicGame_RTA : public GenericRequest
{
private:
std::wstring m_sessionId;
std::wstring m_gameInfo;
std::wstring m_gameName;
std::string m_localAddr;
int32_t m_localPort;
std::array< int8_t, 5 > m_attributes;
enum ERROR_CODE {
SUCCESS = 0,
FATAL_ERROR,
GENERAL_ERROR,
GAME_NAME_IN_USE = 38,
GAME_PENDING = 40,
};
public:
static std::unique_ptr< RequestCreatePublicGame_RTA > Create()
{
return std::make_unique< RequestCreatePublicGame_RTA >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
bool ParseGameInfo();
};
class ResultCreatePublicGame_RTA : public GenericResponse {
private:
int32_t m_reply;
std::string m_discoveryIp;
int32_t m_discoveryPort;
public:
ResultCreatePublicGame_RTA( GenericRequest *request, int32_t reply, std::string discoveryIp = "", int32_t discoveryPort = 0 );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -0,0 +1,40 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetRequest.hpp"
#include "../GenericNetResponse.hpp"
class RequestDoClientDiscovery : public GenericRequest
{
private:
enum DISCOVERY_REPLY {
SUCCESS = 0,
FATAL_ERROR = 1,
GAME_FULL = 2,
};
std::wstring m_sessionId;
int32_t m_gameId;
public:
static std::unique_ptr< RequestDoClientDiscovery > Create()
{
return std::make_unique< RequestDoClientDiscovery >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultDoClientDiscovery : public GenericResponse {
private:
int32_t m_reply;
std::string m_discoveryIP;
int32_t m_discoveryPort;
public:
ResultDoClientDiscovery( GenericRequest *request, int32_t reply, std::string ip = "", int32_t port = 0);
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -0,0 +1,41 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetRequest.hpp"
#include "../GenericNetResponse.hpp"
class RequestDoClientDiscovery_RTA : public GenericRequest {
private:
std::wstring m_sessionId;
std::wstring m_localAddr;
int32_t m_localPort;
uint32_t m_gameId;
enum REPLY {
SUCCESS = 0,
TIMEOUT,
NOT_FOUND
};
public:
static std::unique_ptr< RequestDoClientDiscovery_RTA > Create()
{
return std::make_unique< RequestDoClientDiscovery_RTA >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultDoClientDiscovery_RTA : public GenericResponse {
private:
int32_t m_reply;
std::string m_discoveryIp;
int32_t m_discoveryPort;
public:
ResultDoClientDiscovery_RTA( GenericRequest *request, int32_t reply, std::string discoveryIp = "", int32_t discoveryPort = 0);
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -0,0 +1,39 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetRequest.hpp"
#include "../GenericNetResponse.hpp"
#include "Game/ChatRoomSession.hpp"
class RequestEnterRoom : public GenericRequest
{
private:
std::wstring m_roomName;
enum REPLY {
SUCCESS = 0,
GENERAL_ERROR
};
public:
static std::unique_ptr< RequestEnterRoom > Create()
{
return std::make_unique< RequestEnterRoom >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultEnterRoom : public GenericResponse {
private:
int32_t m_reply;
sptr_chat_room_session m_room;
public:
ResultEnterRoom( GenericRequest *request, int32_t reply, sptr_chat_room_session room );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -0,0 +1,46 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetRequest.hpp"
#include "../GenericNetResponse.hpp"
#include "Game/RealmCharacter.hpp"
class RequestGetNetCharacterData_RTA : public GenericRequest
{
private:
int32_t m_characterId;
enum ERROR_CODE {
SUCCESS = 0,
FATAL_ERROR,
GENERAL_ERROR,
};
public:
static std::unique_ptr< RequestGetNetCharacterData_RTA > Create()
{
return std::make_unique< RequestGetNetCharacterData_RTA >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
sptr_generic_response SendCharacterData(sptr_socket socket, sptr_realm_character data);
};
class ResultGetNetCharacterData_RTA : public GenericResponse {
private:
int32_t m_reply;
int32_t m_endOfData;
std::vector< uint8_t > m_chunk;
public:
ResultGetNetCharacterData_RTA( GenericRequest *request, int32_t reply,
std::optional< std::vector< uint8_t > > data = std::nullopt,
std::optional < int32_t > endOfData = std::nullopt );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -0,0 +1,27 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetRequest.hpp"
#include "../GenericNetResponse.hpp"
class RequestGetEncryptionKey : public GenericRequest
{
public:
static std::unique_ptr< RequestGetEncryptionKey > Create()
{
return std::make_unique< RequestGetEncryptionKey >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultGetEncryptionKey : public GenericResponse {
public:
std::vector< uint8_t > m_symKey;
ResultGetEncryptionKey( GenericRequest *request );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -0,0 +1,25 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetRequest.h"
#include "../GenericNetResponse.h"
class RequestGetFriendList : public GenericRequest
{
public:
static std::unique_ptr< RequestGetFriendList > Create()
{
return std::make_unique< RequestGetFriendList >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultGetFriendList : public GenericResponse {
public:
ResultGetFriendList( GenericRequest *request );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -0,0 +1,37 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetRequest.hpp"
#include "../GenericNetResponse.hpp"
class RequestGetGame : public GenericRequest {
private:
std::wstring m_sessionId;
std::wstring m_gameName;
enum REPLY {
SUCCESS = 0,
TIMEOUT,
NOT_FOUND
};
public:
static std::unique_ptr< RequestGetGame > Create()
{
return std::make_unique< RequestGetGame >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultGetGame : public GenericResponse {
private:
int32_t m_reply;
int32_t m_gameId;
public:
ResultGetGame( GenericRequest *request, int32_t reply, int32_t gameId = 0 );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -0,0 +1,41 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetRequest.hpp"
#include "../GenericNetResponse.hpp"
class RequestGetGame_RTA : public GenericRequest {
private:
std::wstring m_sessionId;
std::wstring m_gameName;
enum REPLY {
SUCCESS = 0,
TIMEOUT,
NOT_FOUND
};
public:
static std::unique_ptr< RequestGetGame_RTA > Create()
{
return std::make_unique< RequestGetGame_RTA >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultGetGame_RTA : public GenericResponse {
private:
int32_t m_reply;
int32_t m_gameId;
std::wstring m_discoveryAddr;
std::wstring m_localAddr;
int32_t m_port;
public:
ResultGetGame_RTA( GenericRequest *request, int32_t reply, int32_t gameId = -1, std::string discoveryAddr = "", std::string localAddr = "", int32_t discoveryPort = 0 );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -0,0 +1,39 @@
#pragma once
#include <memory>
#include <string>
#include <vector>
#include <map>
#include "../GenericNetRequest.hpp"
#include "../GenericNetResponse.hpp"
#include "Game/RealmCharacterMetaKV.hpp"
class RequestGetNetCharacterList_RTA : public GenericRequest
{
private:
enum ERROR_CODE {
SUCCESS = 0,
FATAL_ERROR,
GENERAL_ERROR,
};
public:
static std::unique_ptr< RequestGetNetCharacterList_RTA > Create()
{
return std::make_unique< RequestGetNetCharacterList_RTA >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultGetNetCharacterList_RTA : public GenericResponse {
private:
int32_t m_reply;
std::map< uint32_t, CharacterSlotData > m_characterList;
public:
ResultGetNetCharacterList_RTA( GenericRequest *request, int32_t reply, std::optional< std::map< uint32_t, CharacterSlotData > > list );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -0,0 +1,30 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetRequest.hpp"
#include "../GenericNetResponse.hpp"
#include "Game/ChatRoomSession.hpp"
class RequestGetPublicRooms : public GenericRequest
{
public:
static std::unique_ptr< RequestGetPublicRooms > Create()
{
return std::make_unique< RequestGetPublicRooms >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultGetPublicRooms : public GenericResponse {
private:
std::vector< sptr_chat_room_session > m_rooms;
public:
ResultGetPublicRooms( GenericRequest *request, std::vector< sptr_chat_room_session > rooms );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -0,0 +1,24 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetRequest.hpp"
#include "../GenericNetResponse.hpp"
class RequestGetRealmStats : public GenericRequest
{
public:
static std::unique_ptr< RequestGetRealmStats > Create()
{
return std::make_unique< RequestGetRealmStats >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultGetRealmStats : public GenericResponse {
public:
ResultGetRealmStats( GenericRequest *request );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -0,0 +1,39 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetRequest.hpp"
#include "../GenericNetResponse.hpp"
#include "Game/ChatRoomSession.hpp"
class RequestGetRoom : public GenericRequest {
private:
std::wstring m_sessionId;
std::wstring m_roomName;
enum CREATE_ACCOUNT_REPLY {
SUCCESS = 0,
GENERAL_ERROR = 1,
};
public:
static std::unique_ptr< RequestGetRoom > Create()
{
return std::make_unique< RequestGetRoom >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultGetRoom : public GenericResponse {
private:
int32_t m_reply;
sptr_chat_room_session m_room;
public:
ResultGetRoom( GenericRequest *request, int32_t reply, sptr_chat_room_session room = nullptr );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -0,0 +1,31 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetRequest.hpp"
#include "../GenericNetResponse.hpp"
class RequestGetRules : public GenericRequest
{
private:
std::string m_language;
public:
static std::unique_ptr< RequestGetRules > Create()
{
return std::make_unique< RequestGetRules >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultGetRules : public GenericResponse {
private:
std::wstring m_rules;
public:
ResultGetRules( GenericRequest *request, std::wstring rules );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -0,0 +1,29 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetRequest.hpp"
#include "../GenericNetResponse.hpp"
#include "Common/Constant.hpp"
class RequestGetServerAddress : public GenericRequest {
public:
static std::unique_ptr< RequestGetServerAddress > Create()
{
return std::make_unique< RequestGetServerAddress >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultGetServerAddress : public GenericResponse {
public:
std::string m_ip;
int32_t m_port;
RealmGameType m_gameType;
ResultGetServerAddress( GenericRequest *request, std::string ip, int32_t port, RealmGameType clientType );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -0,0 +1,30 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetRequest.hpp"
#include "../GenericNetResponse.hpp"
#include "Common/ForwardDecl.hpp"
class RequestGetSocialListInitial : public GenericRequest
{
public:
static std::unique_ptr< RequestGetSocialListInitial > Create()
{
return std::make_unique< RequestGetSocialListInitial >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultGetSocialListInitial : public GenericResponse {
private:
int32_t m_reply;
sptr_user m_user;
public:
ResultGetSocialListInitial( GenericRequest *request, sptr_user user = nullptr );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -0,0 +1,30 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetRequest.hpp"
#include "../GenericNetResponse.hpp"
#include "Common/ForwardDecl.hpp"
class RequestGetSocialListUpdate : public GenericRequest
{
public:
static std::unique_ptr< RequestGetSocialListUpdate > Create()
{
return std::make_unique< RequestGetSocialListUpdate >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultGetSocialListUpdate : public GenericResponse {
private:
int32_t m_reply;
sptr_user m_user;
public:
ResultGetSocialListUpdate( GenericRequest *request, sptr_user user = nullptr );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -0,0 +1,36 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetRequest.hpp"
#include "../GenericNetResponse.hpp"
class RequestLeaveRoom : public GenericRequest
{
private:
std::wstring m_roomName;
enum REPLY {
SUCCESS = 0,
GENERAL_ERROR
};
public:
static std::unique_ptr< RequestLeaveRoom > Create()
{
return std::make_unique< RequestLeaveRoom >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultLeaveRoom : public GenericResponse {
private:
int32_t m_reply;
public:
ResultLeaveRoom( GenericRequest *request, int32_t reply );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -0,0 +1,43 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetRequest.hpp"
#include "../GenericNetResponse.hpp"
class RequestLogin : public GenericRequest
{
private:
enum LOGIN_REPLY {
SUCCESS = 0,
FATAL_ERROR,
ACCOUNT_INVALID = 4,
};
std::wstring m_username;
std::wstring m_password;
std::wstring m_sessionId;
public:
static std::unique_ptr< RequestLogin > Create()
{
return std::make_unique< RequestLogin >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
sptr_generic_response ProcessLoginCON( sptr_user user );
sptr_generic_response ProcessLoginRTA( sptr_user user );
};
class ResultLogin : public GenericResponse {
private:
std::wstring m_sessionId;
int32_t m_reply;
public:
ResultLogin( GenericRequest *request, int32_t reply, std::wstring sessionId );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -0,0 +1,29 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetRequest.hpp"
#include "../GenericNetResponse.hpp"
class RequestLogout : public GenericRequest
{
private:
std::wstring m_sessionId;
public:
static std::unique_ptr< RequestLogout > Create()
{
return std::make_unique< RequestLogout >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultLogout : public GenericResponse {
private:
int32_t m_reply;
public:
ResultLogout( GenericRequest *request, int32_t reply );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -0,0 +1,28 @@
#pragma once
#include "../GenericNetRequest.hpp"
#include "../GenericNetResponse.hpp"
class RequestMatchGame : public GenericRequest
{
private:
std::wstring m_sessionId;
public:
static std::unique_ptr< RequestMatchGame > Create()
{
return std::make_unique< RequestMatchGame >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultMatchGame : public GenericResponse {
private:
std::string m_userIp;
public:
ResultMatchGame( GenericRequest *request, std::string userIp );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -0,0 +1,28 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetRequest.hpp"
#include "../GenericNetResponse.hpp"
class RequestMatchGame_RTA : public GenericRequest
{
public:
static std::unique_ptr< RequestMatchGame_RTA > Create()
{
return std::make_unique< RequestMatchGame_RTA >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultMatchGame_RTA : public GenericResponse {
private:
std::string m_userIp;
public:
ResultMatchGame_RTA( GenericRequest *request, std::string userIp );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -0,0 +1,40 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetRequest.hpp"
#include "../GenericNetResponse.hpp"
class RequestRemoveFriend : public GenericRequest
{
private:
std::wstring m_sessionId;
std::wstring m_chatHandle;
enum ERROR_CODE {
SUCCESS = 0,
FATAL_ERROR,
DATABASE_ERROR = 2,
FRIEND_IGNORING = 19,
FRIEND_INVALID = 20,
FRIEND_DUPLICATE = 21,
};
public:
static std::unique_ptr< RequestRemoveFriend > Create()
{
return std::make_unique< RequestRemoveFriend >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultRemoveFriend : public GenericResponse {
private:
int32_t m_reply;
public:
ResultRemoveFriend( GenericRequest *request, int32_t reply );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -0,0 +1,41 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetRequest.hpp"
#include "../GenericNetResponse.hpp"
class RequestRemoveIgnore : public GenericRequest
{
private:
std::wstring m_sessionId;
std::wstring m_chatHandle;
enum ERROR_CODE {
SUCCESS = 0,
FATAL_ERROR,
DATABASE_ERROR = 2,
IGNORE_INVALID = 20,
IGNORE_FRIEND = 24,
IGNORE_DUPLICATE = 25,
};
public:
static std::unique_ptr< RequestRemoveIgnore > Create()
{
return std::make_unique< RequestRemoveIgnore >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultRemoveIgnore : public GenericResponse {
private:
int32_t m_reply;
public:
ResultRemoveIgnore( GenericRequest *request, int32_t reply );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -0,0 +1,41 @@
#pragma once
#include "../GenericNetRequest.hpp"
#include "../GenericNetResponse.hpp"
#include "Game/RealmCharacter.hpp"
class RequestSaveCharacter_RTA : public GenericRequest
{
private:
std::wstring m_sessionId;
std::wstring m_memberSessionId;
uint32_t m_targetCharacterId;
CharacterSlotData m_metaData;
std::vector< uint8_t > m_characterData;
enum ERROR_CODE {
SUCCESS = 0,
FATAL_ERROR,
GENERAL_ERROR,
};
public:
static std::unique_ptr< RequestSaveCharacter_RTA > Create()
{
return std::make_unique< RequestSaveCharacter_RTA >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultSaveCharacter_RTA : public GenericResponse {
private:
int32_t m_reply;
public:
ResultSaveCharacter_RTA( GenericRequest *request, int32_t reply );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -0,0 +1,38 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetRequest.hpp"
#include "../GenericNetResponse.hpp"
class RequestSendInstantMessage : public GenericRequest
{
private:
std::wstring m_chatHandle;
std::wstring m_message;
enum ERROR_CODE {
SUCCESS = 0,
GENERAL_ERROR,
USER_IGNORED = 19,
};
public:
static std::unique_ptr< RequestSendInstantMessage > Create()
{
return std::make_unique< RequestSendInstantMessage >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultSendInstantMessage : public GenericResponse {
private:
int32_t m_reply;
public:
ResultSendInstantMessage( GenericRequest *request, int32_t reply );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -0,0 +1,37 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetRequest.hpp"
#include "../GenericNetResponse.hpp"
class RequestSendRoomMessage : public GenericRequest
{
private:
std::wstring m_roomName;
std::wstring m_message;
enum REPLY {
SUCCESS = 0,
GENERAL_ERROR
};
public:
static std::unique_ptr< RequestSendRoomMessage > Create()
{
return std::make_unique< RequestSendRoomMessage >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultSendRoomMessage : public GenericResponse {
private:
int32_t m_reply;
public:
ResultSendRoomMessage( GenericRequest *request, int32_t reply );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -0,0 +1,36 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetRequest.hpp"
#include "../GenericNetResponse.hpp"
class RequestStartGame : public GenericRequest
{
private:
std::vector< uint8_t > m_data;
enum ERROR_CODE {
SUCCESS = 0,
FATAL_ERROR,
GENERAL_ERROR,
};
public:
static std::unique_ptr< RequestStartGame > Create()
{
return std::make_unique< RequestStartGame >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultStartGame : public GenericResponse {
private:
int32_t m_reply;
public:
ResultStartGame( GenericRequest *request, int32_t reply );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -0,0 +1,27 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetRequest.hpp"
#include "../GenericNetResponse.hpp"
class RequestTouchSession : public GenericRequest
{
private:
std::wstring m_sessionId;
public:
static std::unique_ptr< RequestTouchSession > Create()
{
return std::make_unique< RequestTouchSession >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultTouchSession : public GenericResponse {
public:
ResultTouchSession( GenericRequest *request );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -0,0 +1,31 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetRequest.hpp"
#include "../GenericNetResponse.hpp"
#include "Game/GameSession.hpp"
class RequestUpdateGameData : public GenericRequest
{
private:
std::wstring m_sessionId;
std::string m_gameData;
public:
static std::unique_ptr< RequestUpdateGameData > Create()
{
return std::make_unique< RequestUpdateGameData >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
bool ParseGameData( sptr_game_session session );
};
class ResultUpdateGameData : public GenericResponse {
public:
ResultUpdateGameData( GenericRequest *request );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -0,0 +1,37 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetRequest.hpp"
#include "../GenericNetResponse.hpp"
class RequestUserJoinSuccess : public GenericRequest
{
private:
std::wstring m_sessionId;
std::wstring m_ownerSessionId;
enum ERROR_CODE {
SUCCESS = 0,
FATAL_ERROR,
GENERAL_ERROR,
};
public:
static std::unique_ptr< RequestUserJoinSuccess > Create()
{
return std::make_unique< RequestUserJoinSuccess >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultUserJoinSuccess : public GenericResponse {
private:
int32_t m_reply;
public:
ResultUserJoinSuccess( GenericRequest *request, int32_t reply );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -0,0 +1,37 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetRequest.h"
#include "../GenericNetResponse.h"
class Request_5F : public GenericRequest
{
private:
std::wstring m_sessionId;
std::wstring m_memberSessionId;
enum CREATE_REPLY {
SUCCESS = 0,
FATAL_ERROR,
GENERAL_ERROR,
};
public:
static std::unique_ptr< Request_5F > Create()
{
return std::make_unique< Request_5F >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class Result_5F : public GenericResponse {
private:
int32_t m_reply;
public:
Result_5F( GenericRequest *request, int32_t reply );
ByteBuffer &Serialize();
};

View File

@@ -0,0 +1,25 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetRequest.h"
#include "../GenericNetResponse.h"
class Request_61 : public GenericRequest
{
public:
static std::unique_ptr< Request_61 > Create()
{
return std::make_unique< Request_61 >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class Result_61 : public GenericResponse {
public:
Result_61( GenericRequest *request );
ByteBuffer &Serialize();
};

269
Include/Network/Events.hpp Normal file
View File

@@ -0,0 +1,269 @@
#pragma once
#include <map>
#include <functional>
/* 0001 */ #include "Event/RequestAddFriend.hpp"
/* 0002 */ #include "Event/RequestAddIgnore.hpp"
/* 0005 */ #include "Event/RequestCancelGame.hpp"
/* 0006 */ #include "Event/RequestCreateAccount.hpp"
/* 0008 */ #include "Event/RequestCreatePrivateGame.hpp"
/* 0009 */ #include "Event/RequestCreatePrivateRoom.hpp"
/* 000A */ #include "Event/RequestCreatePublicGame.hpp"
/* 000C */ #include "Event/RequestEnterRoom.hpp"
/* 000D */ #include "Event/RequestGetGame.hpp"
/* 000E */ #include "Event/RequestGetPublicRooms.hpp"
/* 000F */ #include "Event/RequestGetRealmStats.hpp"
/* 0011 */ #include "Event/RequestGetRoom.hpp"
/* 0015 */ #include "Event/RequestLeaveRoom.hpp"
/* 0016 */ #include "Event/RequestLogin.hpp"
/* 0017 */ #include "Event/RequestLogout.hpp"
/* 0018 */ #include "Event/RequestMatchGame.hpp"
/* 001C */ #include "Event/RequestRemoveFriend.hpp"
/* 001D */ #include "Event/RequestRemoveIgnore.hpp"
/* 0021 */ #include "Event/RequestSendInstantMessage.hpp"
/* 0022 */ #include "Event/RequestSendRoomMessage.hpp"
/* 0023 */ #include "Event/RequestStartGame.hpp"
/* 0024 */ #include "Event/RequestTouchSession.hpp"
/* 0025 */ #include "Event/RequestDoClientDiscovery.hpp"
/* 0027 */ #include "Event/RequestGetEncryptionKey.hpp"
/* 0041 */ #include "Event/NotifyForcedLogout.hpp"
/* 0042 */ #include "Event/RequestGetRules.hpp"
/* 0043 */ #include "Event/RequestGetServerAddress.hpp"
/* 0044 */ #include "Event/RequestUpdateGameData.hpp"
/* 0054 */ #include "Event/RequestCreatePublicGame_RTA.hpp"
/* 0055 */ #include "Event/RequestMatchGame_RTA.hpp"
/* 0056 */ #include "Event/RequestCreatePrivateGame_RTA.hpp"
/* 0057 */ #include "Event/RequestGetGame_RTA.hpp"
/* 0058 */ #include "Event/RequestCreateNewCharacter_RTA.hpp"
/* 005B */ #include "Event/RequestGetNetCharacterList_RTA.hpp"
/* 005C */ #include "Event/RequestGetCharacterData_RTA.hpp"
/* 005D */ #include "Event/RequestAppendCharacterData.hpp"
/* 005E */ #include "Event/RequestSaveCharacter_RTA.hpp"
/* 005F */ #include "Event/RequestUserJoinSuccess.hpp"
/* 0060 */ #include "Event/RequestCancelGame_RTA.hpp"
/* 0061 */ #include "Event/RequestGetSocialListInitial.hpp"
/* 0062 */ #include "Event/RequestGetSocialListUpdate.hpp"
/* 0066 */ #include "Event/RequestDoClientDiscovery_RTA.hpp"
const std::map< int16_t, std::function< std::unique_ptr< GenericRequest >() > > REQUEST_EVENT =
{
{ 0x0001, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestAddFriend >();
}
},
{ 0x0002, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestAddIgnore >();
}
},
{ 0x0005, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestCancelGame >();
}
},
{ 0x0006, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestCreateAccount >();
}
},
{ 0x0008, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestCreatePrivateGame >();
}
},
{ 0x0009, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestCreatePrivateRoom >();
}
},
{ 0x000A, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestCreatePublicGame >();
}
},
{ 0x000C, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestEnterRoom >();
}
},
{ 0x000D, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestGetGame >();
}
},
{ 0x000E, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestGetPublicRooms >();
}
},
{ 0x000F, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestGetRealmStats >();
}
},
{ 0x0011, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestGetRoom >();
}
},
{ 0x0015, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestLeaveRoom >();
}
},
{ 0x0016, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestLogin >();
}
},
{ 0x0017, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestLogout >();
}
},
{ 0x0018, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestMatchGame >();
}
},
{ 0x001C, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestRemoveFriend >();
}
},
{ 0x001D, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestRemoveIgnore >();
}
},
{ 0x0021, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestSendInstantMessage >();
}
},
{ 0x0022, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestSendRoomMessage >();
}
},
{ 0x0023, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestStartGame >();
}
},
{ 0x0024, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestTouchSession >();
}
},
{ 0x0025, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestDoClientDiscovery >();
}
},
{ 0x0027, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestGetEncryptionKey >();
}
},
{ 0x0042, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestGetRules >();
}
},
{ 0x0043, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestGetServerAddress >();
}
},
{ 0x0044, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestUpdateGameData >();
}
},
{ 0x0054, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestCreatePublicGame_RTA >();
}
},
{ 0x0055, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestMatchGame_RTA >();
}
},
{ 0x0056, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestCreatePrivateGame_RTA >();
}
},
{ 0x0057, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestGetGame_RTA >();
}
},
{ 0x0058, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestCreateNewCharacter_RTA >();
}
},
{ 0x005B, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestGetNetCharacterList_RTA >();
}
},
{ 0x005C, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestGetNetCharacterData_RTA >();
}
},
{ 0x005D, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestAppendCharacterData >();
}
},
{ 0x005E, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestSaveCharacter_RTA >();
}
},
{ 0x005F, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestUserJoinSuccess >();
}
},
{ 0x0060, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestCancelGame_RTA >();
}
},
{ 0x0061, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestGetSocialListInitial >();
}
},
{ 0x0062, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestGetSocialListUpdate >();
}
},
{ 0x0066, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestDoClientDiscovery_RTA >();
}
},
};

View File

@@ -0,0 +1,19 @@
#pragma once
#include "Common/ByteStream.hpp"
class GenericMessage
{
public:
uint16_t m_packetId;
ByteBuffer m_stream;
GenericMessage( uint16_t packetId ) : m_packetId( packetId )
{
}
virtual ~GenericMessage() = default;
virtual void Serialize( ByteBuffer &out ) const = 0;
};
typedef std::shared_ptr< GenericMessage > sptr_generic_message;

View File

@@ -0,0 +1,44 @@
#pragma once
#include <memory>
#include "Common/ByteStream.hpp"
class GenericResponse;
using sptr_generic_response = std::shared_ptr< GenericResponse >;
class RealmUser;
using sptr_user = std::shared_ptr< RealmUser >;
class RealmSocket;
using sptr_socket = std::shared_ptr< RealmSocket >;
class GenericRequest {
public:
int16_t m_packetId;
uint32_t m_trackId;
virtual ~GenericRequest() = default;
virtual sptr_generic_response ProcessRequest( sptr_socket user, sptr_byte_stream stream )
{
throw std::runtime_error( "ProcessRequest not implemented for GenericRequest" );
}
virtual sptr_generic_response ProcessRequest( sptr_byte_stream stream )
{
throw std::runtime_error( "ProcessRequest not implemented for GenericRequest" );
}
void DeserializeHeader( sptr_byte_stream stream )
{
m_packetId = stream->read_u16();
m_trackId = stream->read_u32();
auto version = stream->read_u32(); // 2 for CON and 6 for RTA
};
virtual void Deserialize( sptr_byte_stream stream ) = 0;
};
using sptr_generic_request = std::shared_ptr< GenericRequest >;

View File

@@ -0,0 +1,23 @@
#pragma once
#include "GenericNetRequest.hpp"
#include "Common/ByteStream.hpp"
class GenericResponse
{
public:
uint16_t m_packetId;
uint32_t m_trackId;
ByteBuffer m_stream;
GenericResponse( const GenericRequest &request )
{
m_packetId = request.m_packetId;
m_trackId = request.m_trackId;
}
virtual ~GenericResponse() = default;
virtual void Serialize( ByteBuffer& out ) const = 0;
};
using sptr_generic_response = std::shared_ptr< GenericResponse >;

View File

@@ -0,0 +1,69 @@
#pragma once
#include <memory>
#include <vector>
#include <mutex>
#include <winsock2.h>
#include "GenericNetRequest.hpp"
#include "GenericNetResponse.hpp"
#include "GenericNetMessage.hpp"
#include "Common/Constant.hpp"
class RealmSocket
{
private:
const size_t WRITE_BUFFER_SIZE = 65535;
public:
RealmSocket();
~RealmSocket();
void send( const sptr_generic_response response );
void send( const GenericMessage &message );
// Comparison operator for sorting
bool operator<( const RealmSocket &rhs ) const
{
return fd < rhs.fd;
}
// Comparison operator for comparing
bool operator==( const RealmSocket &rhs ) const
{
return fd == rhs.fd;
}
SOCKET fd;
struct s_flag {
bool disconnected_wait;
bool disconnected_forced;
bool is_listener;
bool is_gateway;
bool want_more_read_data;
bool want_more_write_data;
} flag;
sockaddr_in local_addr;
sockaddr_in remote_addr;
RealmGameType gameType;
std::string remote_ip;
uint32_t remote_port;
uint32_t last_write_position;
uint64_t latency;
std::chrono::steady_clock::time_point last_recv_time;
std::chrono::steady_clock::time_point last_send_time;
std::mutex write_mutex;
std::mutex read_mutex;
std::vector< uint8_t > read_buffer;
std::vector< uint8_t > m_pendingWriteBuffer;
std::vector< uint8_t > m_pendingReadBuffer;
};
using sptr_socket = std::shared_ptr< RealmSocket >;

15
Include/configuration.hpp Normal file
View File

@@ -0,0 +1,15 @@
#pragma once
#include <fstream>
#include <string>
class Config
{
public:
static bool Load( std::string filename );
static inline std::string service_ip;
static inline uint16_t con_lobby_port;
static inline uint16_t rta_lobby_port;
static inline uint16_t discovery_port;
};

119
Include/logging.hpp Normal file
View File

@@ -0,0 +1,119 @@
#pragma once
#include <string>
#include <vector>
#include <fstream>
#include <mutex>
#include <sstream>
#include <type_traits>
#include <windows.h>
class Log {
private:
enum LOG_TYPE {
log_generic = 0,
log_debug,
log_error,
log_warn,
num_log_type
};
static inline int32_t current_open_hour;
static inline std::fstream file_stream[ num_log_type ];
static inline std::mutex log_lock;
static const char *GetTimeStamp();
static void CheckFileStatus( LOG_TYPE type );
static void WriteToLog( LOG_TYPE type, const std::string &message );
static std::string WideToMulti( const std::wstring &input )
{
if( input.empty() ) return "";
int sizeNeeded = WideCharToMultiByte( CP_UTF8, 0, input.data(), ( int )input.size(), nullptr, 0, nullptr, nullptr );
std::string result( sizeNeeded, 0 );
WideCharToMultiByte( CP_UTF8, 0, input.data(), ( int )input.size(), std::data( result ), sizeNeeded, nullptr, nullptr );
return result;
}
template<typename T>
static std::string ToString( const T &value )
{
if constexpr( std::is_same_v<T, std::wstring> )
{
return WideToMulti( value );
}
else if constexpr( std::is_same_v<T, std::string> )
{
return value;
}
else
{
std::ostringstream oss;
oss << value;
return oss.str();
}
}
template<typename... Args>
static std::string Format( const std::string &formatStr, Args&&... args )
{
std::ostringstream oss;
size_t last = 0, next = 0;
std::vector<std::string> values = { ToString( std::forward<Args>( args ) )... };
size_t index = 0;
while( ( next = formatStr.find( "{}", last ) ) != std::string::npos )
{
oss << formatStr.substr( last, next - last );
if( index < values.size() )
{
oss << values[ index++ ];
}
else
{
oss << "{}"; // unmatched placeholder
}
last = next + 2;
}
oss << formatStr.substr( last );
return oss.str();
}
public:
static Log &Get()
{
static Log instance;
return instance;
}
Log();
~Log();
template<typename... Args>
static void Info( const std::string &format, Args&&... args )
{
WriteToLog( log_generic, Format( format, std::forward<Args>( args )... ) );
}
template<typename... Args>
static void Warn( const std::string &format, Args&&... args )
{
WriteToLog( log_warn, Format( format, std::forward<Args>( args )... ) );
}
template<typename... Args>
static void Debug( const std::string &format, Args&&... args )
{
#ifdef _DEBUG
WriteToLog( log_debug, Format( format, std::forward<Args>( args )... ) );
#endif
}
template<typename... Args>
static void Error( const std::string &format, Args&&... args )
{
WriteToLog( log_error, Format( format, std::forward<Args>( args )... ) );
}
static void Packet( std::vector<uint8_t> p, size_t size, bool send );
static void ToFile( std::string prefix, std::vector<uint8_t> p, size_t size );
};

15
Include/resource.h Normal file
View File

@@ -0,0 +1,15 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
//
#define IDI_ICON1 101
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 102
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

15
Include/stdafx.h Normal file
View File

@@ -0,0 +1,15 @@
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>
// TODO: reference additional headers your program requires here

8
Include/targetver.h Normal file
View File

@@ -0,0 +1,8 @@
#pragma once
// Including SDKDDKVer.h defines the highest available Windows platform.
// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
#include <SDKDDKVer.h>