mirror of
https://github.com/HikikoMarmy/Champions-Reborn-Server.git
synced 2026-04-04 16:49:47 -03:00
Reorganized and cleaned up the solution.
This commit is contained in:
95
Include/Common/ByteBufferReader.hpp
Normal file
95
Include/Common/ByteBufferReader.hpp
Normal 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;
|
||||
};
|
||||
85
Include/Common/ByteStream.hpp
Normal file
85
Include/Common/ByteStream.hpp
Normal 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;
|
||||
66
Include/Common/Constant.hpp
Normal file
66
Include/Common/Constant.hpp
Normal 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
|
||||
};
|
||||
22
Include/Common/ForwardDecl.hpp
Normal file
22
Include/Common/ForwardDecl.hpp
Normal 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
65
Include/Common/RLEZ.hpp
Normal 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;
|
||||
}
|
||||
}
|
||||
25
Include/Common/Utility.hpp
Normal file
25
Include/Common/Utility.hpp
Normal 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 );
|
||||
}
|
||||
Reference in New Issue
Block a user