26 #include "../../clib/cfgelem.h" 27 #include "../../clib/clib.h" 28 #include "../../clib/clib_endian.h" 29 #include "../../clib/logfacility.h" 30 #include "../../clib/rawtypes.h" 31 #include "../../clib/refptr.h" 32 #include "../../clib/strutil.h" 33 #include "../../plib/pkg.h" 34 #include "../globals/network.h" 35 #include "../mobile/charactr.h" 36 #include "../packetscrobj.h" 37 #include "../syshook.h" 86 unsigned char* message =
static_cast<unsigned char*
>(
data );
88 u8 msgid = message[0];
94 POLLOG.Format(
"Expected packet hook function for msg 0x{:X} but was null!\n" )
104 std::map<u32, PacketHookData*>::iterator itr;
108 if ( itr->second->function !=
nullptr )
145 unsigned short len =
cfBEu16( *( reinterpret_cast<unsigned short*>( &message[1] ) ) );
167 const unsigned char* message =
static_cast<const unsigned char*
>(
data );
185 data =
static_cast<void*
>( &outpacket->buffer[0] );
196 unsigned short len =
cfBEu16( *( reinterpret_cast<const unsigned short*>( &message[1] ) ) );
204 u16* sizeptr =
reinterpret_cast<u16*
>(
205 &outpacket->buffer[1] );
208 data =
static_cast<void*
>( &outpacket->buffer[0] );
210 inlength =
cfBEu16( *sizeptr );
221 bool subcmd_handler_exists =
false;
222 const unsigned char* message =
static_cast<const unsigned char*
>(
data );
224 u8 msgid = message[0];
233 if ( itr->second->outgoing_function !=
nullptr )
236 subcmd_handler_exists =
true;
249 unsigned short pktversion;
254 switch ( pktversion )
261 elem.
throw_error(
"Only versions 1 and 2 are currently implemented." );
267 std::string lengthstr;
273 if ( lengthstr ==
"variable" )
278 char* endptr =
nullptr;
279 temp = (
unsigned short)strtoul( lengthstr.c_str(), &endptr, 0 );
280 if ( temp == 0 || ( ( endptr !=
nullptr ) && ( *endptr !=
'\0' ) && !isspace( *endptr ) ) )
282 elem.
throw_error(
"Length must be a positive integer or 'variable'" );
295 auto existing_in_func = hook_data->
function;
298 if ( existing_in_func !=
nullptr )
299 POLLOG.Format(
"Packet hook receive function multiply defined for packet 0x{:X}!\n" )
301 if ( existing_out_func !=
nullptr )
302 POLLOG.Format(
"Packet hook send function multiply defined for packet 0x{:X}!\n" )
308 if ( stricmp( elem.
type(),
"Packet" ) != 0 )
314 std::string client_string;
319 if ( elem.
has_prop(
"ReceiveFunction" ) )
322 if ( elem.
has_prop(
"SendFunction" ) )
326 char* endptr =
nullptr;
327 unsigned int idlong = strtoul( elem.
rest(), &endptr, 0 );
328 if ( ( endptr !=
nullptr ) && ( *endptr !=
'\0' ) && !isspace( *endptr ) )
330 elem.
throw_error(
"Packet ID not defined or poorly formed" );
333 elem.
throw_error(
"Packet ID must be between 0x0 and 0xFF" );
341 unsigned char id =
static_cast<unsigned char>( idlong );
343 unsigned short subcmdoff;
344 if ( !elem.
remove_prop(
"SubCommandOffset", &subcmdoff ) )
346 unsigned short subcmdlen;
347 if ( !elem.
remove_prop(
"SubCommandLength", &subcmdlen ) )
360 pkt_data->
length = length;
363 pkt_data->
version = pktversion;
376 " does not define SubCommandOffset!" ) );
379 " does not define SubCommandLength" ) );
384 if ( stricmp( elem.
type(),
"SubPacket" ) != 0 )
390 std::string client_string;
393 if ( elem.
has_prop(
"ReceiveFunction" ) )
396 if ( elem.
has_prop(
"SendFunction" ) )
400 char* endptr =
nullptr;
401 unsigned int idlong = strtoul( elem.
rest(), &endptr, 0 );
402 if ( ( endptr !=
nullptr ) && ( *endptr !=
'\0' ) && !isspace( *endptr ) )
404 elem.
throw_error(
"Packet ID not defined or poorly formed" );
407 elem.
throw_error(
"Packet ID must be between 0x0 and 0xFF" );
409 unsigned char id =
static_cast<unsigned char>( idlong );
434 parent->
SubCommands.insert( std::make_pair( subid, SubData ) );
447 outgoing_function( nullptr ),
448 default_handler( nullptr ),
449 sub_command_offset( 0 ),
450 sub_command_length( 0 ),
459 for ( ; itr != end; ++itr )
463 if (
function !=
nullptr )
472 data->reserve( 256 );
473 for (
int i = 0; i < 256; ++i )
484 size += (
sizeof(
u32 ) +
sizeof(
PacketHookData* ) + (
sizeof(
void* ) * 3 + 1 ) / 2 );
485 if ( subs.second !=
nullptr )
486 size += subs.second->estimateSize();
502 size_t dot1 = ver.find_first_of(
'.', 0 );
503 size_t dot2 = ver.find_first_of(
'.', dot1 + 1 );
504 size_t dot3 = ver.find_first_of(
'.', dot2 + 1 );
505 if ( dot3 == std::string::npos )
508 while ( ( dot3 < ver.length() ) && ( isdigit( ver[dot3] ) ) )
514 detail.
major = atoi( ver.substr( 0, dot1 ).c_str() );
515 detail.
minor = atoi( ver.substr( dot1 + 1, dot2 - dot1 - 1 ).c_str() );
516 detail.
rev = atoi( ver.substr( dot2 + 1, dot3 - dot2 - 1 ).c_str() );
518 if ( dot3 < ver.length() )
520 if ( ( detail.
major <= 5 ) && ( detail.
minor <= 0 ) && ( detail.
rev <= 6 ) )
522 if ( ver[dot3] !=
' ' )
523 detail.
patch = ( ver[dot3] -
'a' ) + 1;
526 detail.
patch = atoi( ver.substr( dot3 + 1, ver.length() - dot3 - 1 ).c_str() );
535 POLLOG_ERROR.Format(
"Malformed client version string in Packethook: {}\n" ) << ver;
549 else if ( ver1.
rev > ver2.
rev )
551 else if ( ver1.
rev < ver2.
rev )
VersionDetailStruct getversiondetail() const
size_t estimateSize() const
PktHandlerFunc default_handler
void CallOutgoingPacketExportedFunction(Client *client, const void *&data, int &inlength, ref_ptr< Core::BPacket > &outpacket, PacketHookData *phd, bool &handled)
static void packethook_warn_if_previously_defined(u8 msgid, PacketVersion pktversion)
#define MSGLEN_2BYTELEN_DATA
std::string remove_string(const char *propname)
void load_packaged_cfgs(const char *cfgname, const char *taglist, void(*loadentry)(const Package *, Clib::ConfigElem &))
Core::ExportedFunction * function
bool call(Bscript::BObjectImp *p0)
VersionDetailStruct client_ver
u32 GetSubCmd(const unsigned char *message, PacketHookData *phd)
PacketHookData * get_packethook(u8 msgid, PacketVersion version=PacketVersion::Default)
void SetVersionDetailStruct(const std::string &ver, VersionDetailStruct &detail)
std::string hexint(unsigned short v)
const char * rest() const
std::vector< std::unique_ptr< Network::PacketHookData > > packet_hook_data_v2
POL_NORETURN void throw_error(const std::string &errmsg) const
static PktHandlerFunc get_callback(unsigned char msgid, PacketVersion version=PacketVersion::V1)
bool GetAndCheckPacketHooked(Client *client, const void *&data, PacketHookData *&phd)
static void set_handler(unsigned char msgid, int len, PktHandlerFunc func, PacketVersion version=PacketVersion::V1)
NetworkManager networkManager
std::vector< std::unique_ptr< Network::PacketHookData > > packet_hook_data
static void packethook_assert_valid_parent(u8 id, const PacketHookData *parent, const Clib::ConfigElem &elem)
void load_subpacket_entries(const Plib::Package *pkg, Clib::ConfigElem &elem)
void ExportedPacketHookHandler(Client *client, void *data)
static int load_packethook_length(Clib::ConfigElem &elem)
virtual Bscript::BObjectImp * make_ref() POL_OVERRIDE
std::unordered_map< u64, ScriptDiffData > data
bool remove_prop(const char *propname, std::string *value)
static bool is_fixed_length(const PacketHookData *phd)
unsigned short sub_command_offset
bool has_prop(const char *propname) const
Core::ExportedFunction * outgoing_function
unsigned short sub_command_length
std::map< u32, PacketHookData * > SubCommands
unsigned short remove_ushort(const char *propname)
ExportedFunction * FindExportedFunction(Clib::ConfigElem &elem, const Plib::Package *pkg, const std::string &descriptor, unsigned nargs, bool complain_if_missing)
static PacketVersion load_packethook_version(Clib::ConfigElem &elem)
Bscript::BObjectImp * make_ref()
const char * type() const
bool CompareVersionDetail(VersionDetailStruct ver1, VersionDetailStruct ver2)
void load_packet_entries(const Plib::Package *pkg, Clib::ConfigElem &elem)
static void initializeGameData(std::vector< std::unique_ptr< PacketHookData >> *data)