Skip to content

Commit d1bc2d3

Browse files
authored
Merge pull request #40 from danielga/fixed-x86_64-and-csteamgameserverapicontext
Fixed x86_64 support and CSteamGameServerAPIContext retrieval code
2 parents 5b8745a + 1bcc030 commit d1bc2d3

File tree

2 files changed

+158
-31
lines changed

2 files changed

+158
-31
lines changed

source/netmessage.cpp

Lines changed: 149 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -55,28 +55,80 @@ namespace NetMessage
5555

5656
#if defined SYSTEM_WINDOWS
5757

58+
#if defined ARCHITECTURE_X86_OLD
59+
5860
static const uintptr_t CLC_CmdKeyValues_offset = 916;
5961

6062
static const uintptr_t SVC_CreateStringTable_offset = 691;
6163

6264
static const uintptr_t SVC_CmdKeyValues_offset = 1935;
6365

66+
#elif defined ARCHITECTURE_X86
67+
68+
static const uintptr_t CLC_CmdKeyValues_offset = 950;
69+
70+
static const uintptr_t SVC_CreateStringTable_offset = 708;
71+
72+
static const uintptr_t SVC_CmdKeyValues_offset = 2100;
73+
74+
#elif defined ARCHITECTURE_X86_64
75+
76+
static const uintptr_t CLC_CmdKeyValues_offset = 1037;
77+
78+
static const uintptr_t SVC_CreateStringTable_offset = 773;
79+
80+
static const uintptr_t SVC_CmdKeyValues_offset = 2443;
81+
82+
#endif
83+
6484
#elif defined SYSTEM_LINUX
6585

86+
#if defined ARCHITECTURE_X86_OLD
87+
6688
static const uintptr_t CLC_CmdKeyValues_offset = 716;
6789

6890
static const uintptr_t SVC_CreateStringTable_offset = 571;
6991

7092
static const uintptr_t SVC_CmdKeyValues_offset = 1691;
7193

94+
#elif defined ARCHITECTURE_X86
95+
96+
static const uintptr_t CLC_CmdKeyValues_offset = 743;
97+
98+
static const uintptr_t SVC_CreateStringTable_offset = 567;
99+
100+
static const uintptr_t SVC_CmdKeyValues_offset = 1707;
101+
102+
#elif defined ARCHITECTURE_X86_64
103+
104+
static const uintptr_t CLC_CmdKeyValues_offset = 901;
105+
106+
static const uintptr_t SVC_CreateStringTable_offset = 676;
107+
108+
static const uintptr_t SVC_CmdKeyValues_offset = 1998;
109+
110+
#endif
111+
72112
#elif defined SYSTEM_MACOSX
73113

74-
static const uintptr_t CLC_CmdKeyValues_offset = 1002;
114+
#if defined ARCHITECTURE_X86
115+
116+
static const uintptr_t CLC_CmdKeyValues_offset = 1031;
75117

76118
static const uintptr_t SVC_CreateStringTable_offset = 675;
77119

78120
static const uintptr_t SVC_CmdKeyValues_offset = 2112;
79121

122+
#elif defined ARCHITECTURE_X86_64
123+
124+
static const uintptr_t CLC_CmdKeyValues_offset = 1012;
125+
126+
static const uintptr_t SVC_CreateStringTable_offset = 707;
127+
128+
static const uintptr_t SVC_CmdKeyValues_offset = 2301;
129+
130+
#endif
131+
80132
#endif
81133

82134
struct Container
@@ -309,6 +361,12 @@ namespace NetMessage
309361

310362
|| instruction.opcode == 0xC2
311363

364+
#if defined ARCHITECTURE_X86_64
365+
366+
|| ( instruction.len == 7 && instruction.opcode == 0xFF )
367+
368+
#endif
369+
312370
#elif defined SYSTEM_LINUX
313371

314372
|| instruction.opcode == 0x5D
@@ -318,40 +376,102 @@ namespace NetMessage
318376
;
319377
}
320378

321-
inline bool IsMoveInstruction( uint8_t opcode )
322-
{
323-
324-
#if defined SYSTEM_WINDOWS || defined SYSTEM_LINUX
379+
#if defined SYSTEM_WINDOWS
325380

326-
return opcode == 0xC7;
381+
inline bool IsPossibleVTable( const hdes &instruction, const uintptr_t funcCode, void ***vtable )
382+
{
327383

328-
#elif defined SYSTEM_MACOSX
384+
#if defined ARCHITECTURE_X86_64
329385

330-
return opcode == 0x8B;
386+
if( instruction.len == 7 &&
387+
instruction.opcode == 0x8D &&
388+
( instruction.flags & F_DISP32 ) != 0 &&
389+
instruction.disp.disp32 >= 10000 )
390+
{
391+
*vtable = reinterpret_cast<void **>( funcCode + instruction.len + instruction.disp.disp32 );
392+
return true;
393+
}
331394

332395
#endif
333396

397+
if( instruction.len == 6 &&
398+
instruction.opcode == 0xC7 &&
399+
( instruction.flags & F_IMM32 ) != 0 &&
400+
instruction.imm.imm32 >= 10000 )
401+
{
402+
*vtable = reinterpret_cast<void **>( hde_getimm( instruction ) );
403+
return true;
404+
}
405+
406+
return false;
334407
}
335408

336-
inline bool IsPossibleVTable( const hdes &instruction )
409+
#elif defined SYSTEM_LINUX
410+
411+
inline bool IsPossibleVTable( const hdes &instruction, const uintptr_t funcCode, void ***vtable )
337412
{
338413

339-
#if defined SYSTEM_LINUX
414+
#if defined ARCHITECTURE_X86_64
340415

341416
if( instruction.len == 7 &&
342-
IsMoveInstruction( instruction.opcode ) &&
417+
instruction.opcode == 0x8B &&
418+
instruction.flags & F_DISP32 &&
419+
instruction.disp.disp32 >= 10000 )
420+
{
421+
const uintptr_t address = *reinterpret_cast<const uintptr_t *>( funcCode + instruction.len + instruction.disp.disp32 );
422+
*vtable = reinterpret_cast<void **>( address + 16 );
423+
return true;
424+
}
425+
426+
if( instruction.len == 7 &&
427+
instruction.opcode == 0x8D &&
428+
( instruction.flags & F_DISP32 ) != 0 &&
429+
instruction.disp.disp32 >= 10000 )
430+
{
431+
*vtable = reinterpret_cast<void **>( funcCode + instruction.len + instruction.disp.disp32 );
432+
return true;
433+
}
434+
435+
#elif defined ARCHITECTURE_X86
436+
437+
if( instruction.opcode == 0xC7 &&
438+
( instruction.flags & F_IMM32 ) != 0 &&
439+
instruction.imm.imm32 >= 10000 &&
440+
( instruction.len == 6 || instruction.len == 7 ) )
441+
{
442+
*vtable = reinterpret_cast<void **>( hde_getimm( instruction ) );
443+
return true;
444+
}
445+
446+
#endif
447+
448+
return false;
449+
}
450+
451+
#elif defined SYSTEM_MACOSX
452+
453+
inline bool IsPossibleVTable( const hdes &instruction, const uintptr_t, void ***vtable )
454+
{
455+
if( instruction.len == 6 &&
456+
instruction.opcode == 0x8B &&
343457
( instruction.flags & F_IMM32 ) != 0 &&
344458
instruction.imm.imm32 >= 10000 )
459+
{
460+
*vtable = reinterpret_cast<void **>( hde_getimm( instruction ) );
345461
return true;
462+
}
463+
464+
return false;
465+
}
346466

347467
#endif
348468

349-
return instruction.len == 6 &&
350-
IsMoveInstruction( instruction.opcode ) &&
351-
( instruction.flags & F_IMM32 ) != 0;
469+
inline const void *AdvancePointer( const void *pointer, uint32_t offset )
470+
{
471+
return reinterpret_cast<const void *>( reinterpret_cast<uintptr_t>( pointer ) + offset );
352472
}
353473

354-
static void ResolveMessagesFromFunctionCode( GarrysMod::Lua::ILuaBase *LUA, const uint8_t *funcCode )
474+
static void ResolveMessagesFromFunctionCode( GarrysMod::Lua::ILuaBase *LUA, const void *funcCode )
355475
{
356476
CNetMessage *msg = new( std::nothrow ) CNetMessage;
357477
if( msg == nullptr )
@@ -363,31 +483,33 @@ namespace NetMessage
363483
for(
364484
uint32_t len = hde_disasm( funcCode, hs );
365485
!IsEndOfFunction( hs );
366-
funcCode += len, len = hde_disasm( funcCode, hs )
367-
)
368-
if( IsPossibleVTable( hs ) )
486+
funcCode = AdvancePointer( funcCode, len ), len = hde_disasm( funcCode, hs )
487+
)
488+
{
489+
void **vtable = nullptr;
490+
if( IsPossibleVTable( hs, reinterpret_cast<uintptr_t>( funcCode ), &vtable ) )
369491
{
370-
void **vtable = reinterpret_cast<void **>( hde_getimm( hs ) );
371492
msg->InstallVTable( vtable );
372493

373494
const char *name = msg->GetName( );
374495
if( netmessages_vtables.find( name ) == netmessages_vtables.end( ) )
375496
netmessages_vtables[name] = vtable;
376497
}
498+
}
377499

378500
msg->InstallVTable( msgvtable );
379501
delete msg;
380502
}
381503

382504
void PreInitialize( GarrysMod::Lua::ILuaBase *LUA )
383505
{
384-
auto CBaseClient_ConnectionStart =
385-
reinterpret_cast<const uint8_t *>( FunctionPointers::CBaseClient_ConnectionStart( ) );
506+
const void *CBaseClient_ConnectionStart =
507+
reinterpret_cast<const void *>( FunctionPointers::CBaseClient_ConnectionStart( ) );
386508
if( CBaseClient_ConnectionStart == nullptr )
387509
LUA->ThrowError( "failed to locate CBaseClient::ConnectionStart" );
388510

389-
auto CBaseClientState_ConnectionStart =
390-
reinterpret_cast<const uint8_t *>( FunctionPointers::CBaseClientState_ConnectionStart( ) );
511+
const void *CBaseClientState_ConnectionStart =
512+
reinterpret_cast<const void *>( FunctionPointers::CBaseClientState_ConnectionStart( ) );
391513
if( CBaseClientState_ConnectionStart == nullptr )
392514
LUA->ThrowError( "failed to locate CBaseClientState::ConnectionStart" );
393515

@@ -399,22 +521,22 @@ namespace NetMessage
399521
CBaseClientState_ConnectionStart
400522
) + SVC_CreateStringTable_offset;
401523
ResolveMessagesFromFunctionCode( LUA, reinterpret_cast<const uint8_t *>(
402-
SVC_CreateStringTable + sizeof( uintptr_t ) +
403-
*reinterpret_cast<intptr_t *>( SVC_CreateStringTable )
524+
SVC_CreateStringTable + sizeof( int32_t ) +
525+
*reinterpret_cast<int32_t *>( SVC_CreateStringTable )
404526
) );
405527

406528
uintptr_t SVC_CmdKeyValues = reinterpret_cast<uintptr_t>(
407529
CBaseClientState_ConnectionStart
408530
) + SVC_CmdKeyValues_offset;
409531
ResolveMessagesFromFunctionCode( LUA, reinterpret_cast<const uint8_t *>(
410-
SVC_CmdKeyValues + sizeof( uintptr_t ) + *reinterpret_cast<intptr_t *>( SVC_CmdKeyValues )
532+
SVC_CmdKeyValues + sizeof( int32_t ) + *reinterpret_cast<int32_t *>( SVC_CmdKeyValues )
411533
) );
412534

413535
uintptr_t CLC_CmdKeyValues = reinterpret_cast<uintptr_t>(
414536
CBaseClient_ConnectionStart
415537
) + CLC_CmdKeyValues_offset;
416538
ResolveMessagesFromFunctionCode( LUA, reinterpret_cast<const uint8_t *>(
417-
CLC_CmdKeyValues + sizeof( uintptr_t ) + *reinterpret_cast<intptr_t *>( CLC_CmdKeyValues )
539+
CLC_CmdKeyValues + sizeof( int32_t ) + *reinterpret_cast<int32_t *>( CLC_CmdKeyValues )
418540
) );
419541
}
420542

source/server/gametags.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <steam/steam_gameserver.h>
1111

1212
class CBaseServer;
13+
class CSteam3Server : public CSteamGameServerAPIContext { };
1314

1415
namespace GameTags
1516
{
@@ -22,9 +23,13 @@ namespace GameTags
2223
if( RecalculateTags_original == nullptr )
2324
LUA->ThrowError( "unable to find CBaseServer::RecalculateTags" );
2425

25-
gameserver_context = InterfacePointers::SteamGameServerAPIContext( );
26+
FunctionPointers::Steam3Server_t Steam3Server = FunctionPointers::Steam3Server( );
27+
if( Steam3Server == nullptr )
28+
LUA->ThrowError( "unable to find Steam3Server" );
29+
30+
gameserver_context = Steam3Server( );
2631
if( gameserver_context == nullptr )
27-
LUA->ThrowError( "Failed to load required CSteamGameServerAPIContext interface." );
32+
LUA->ThrowError( "unable to load CSteamGameServerAPIContext interface" );
2833
}
2934

3035
void RecalculateTags( )
@@ -63,13 +68,13 @@ namespace GameTags
6368

6469
private:
6570
static FunctionPointers::CBaseServer_RecalculateTags_t RecalculateTags_original;
66-
static CSteamGameServerAPIContext *gameserver_context;
71+
static CSteam3Server *gameserver_context;
6772
static std::string gametags_substitute;
6873
};
6974

7075
FunctionPointers::CBaseServer_RecalculateTags_t
7176
CBaseServerProxy::RecalculateTags_original = nullptr;
72-
CSteamGameServerAPIContext *CBaseServerProxy::gameserver_context = nullptr;
77+
CSteam3Server *CBaseServerProxy::gameserver_context = nullptr;
7378
std::string CBaseServerProxy::gametags_substitute;
7479

7580
void PreInitialize( GarrysMod::Lua::ILuaBase *LUA )

0 commit comments

Comments
 (0)