2022-02-27 07:53:44 -05:00
# include <STDInclude.hpp>
2017-01-19 16:23:59 -05:00
namespace Components
{
std : : string Network : : SelectedPacket ;
Utils : : Signal < Network : : CallbackRaw > Network : : StartupSignal ;
2022-05-20 18:12:46 -04:00
// Packet interception
std : : unordered_map < std : : string , Network : : NetworkCallback > Network : : Callbacks ;
2017-01-19 16:23:59 -05:00
2018-12-17 08:29:18 -05:00
Network : : Address : : Address ( const std : : string & addrString )
2017-01-19 16:23:59 -05:00
{
Game : : NET_StringToAdr ( addrString . data ( ) , & this - > address ) ;
}
2022-02-15 12:41:30 -05:00
2017-01-19 16:23:59 -05:00
Network : : Address : : Address ( sockaddr * addr )
{
Game : : SockadrToNetadr ( addr , & this - > address ) ;
}
2022-02-15 12:41:30 -05:00
2021-09-12 07:47:35 -04:00
bool Network : : Address : : operator = = ( const Network : : Address & obj ) const
2017-01-19 16:23:59 -05:00
{
return Game : : NET_CompareAdr ( this - > address , obj . address ) ;
}
2022-02-15 12:41:30 -05:00
2017-01-19 16:23:59 -05:00
void Network : : Address : : setPort ( unsigned short port )
{
this - > address . port = htons ( port ) ;
}
2022-02-15 12:41:30 -05:00
2017-01-19 16:23:59 -05:00
unsigned short Network : : Address : : getPort ( )
{
return ntohs ( this - > address . port ) ;
}
2022-02-15 12:41:30 -05:00
2017-01-19 16:23:59 -05:00
void Network : : Address : : setIP ( DWORD ip )
{
this - > address . ip . full = ip ;
}
2022-02-15 12:41:30 -05:00
2017-01-19 16:23:59 -05:00
void Network : : Address : : setIP ( Game : : netIP_t ip )
{
this - > address . ip = ip ;
}
2022-02-15 12:41:30 -05:00
2017-01-19 16:23:59 -05:00
Game : : netIP_t Network : : Address : : getIP ( )
{
return this - > address . ip ;
}
2022-02-15 12:41:30 -05:00
2017-01-19 16:23:59 -05:00
void Network : : Address : : setType ( Game : : netadrtype_t type )
{
this - > address . type = type ;
}
2022-02-15 12:41:30 -05:00
2017-01-19 16:23:59 -05:00
Game : : netadrtype_t Network : : Address : : getType ( )
{
return this - > address . type ;
}
2022-02-15 12:41:30 -05:00
2017-01-19 16:23:59 -05:00
sockaddr Network : : Address : : getSockAddr ( )
{
sockaddr addr ;
this - > toSockAddr ( & addr ) ;
return addr ;
}
2022-02-15 12:41:30 -05:00
2017-01-19 16:23:59 -05:00
void Network : : Address : : toSockAddr ( sockaddr * addr )
{
if ( addr )
{
Game : : NetadrToSockadr ( & this - > address , addr ) ;
}
}
2022-02-15 12:41:30 -05:00
2017-01-19 16:23:59 -05:00
void Network : : Address : : toSockAddr ( sockaddr_in * addr )
{
this - > toSockAddr ( reinterpret_cast < sockaddr * > ( addr ) ) ;
}
2022-02-15 12:41:30 -05:00
2017-01-19 16:23:59 -05:00
Game : : netadr_t * Network : : Address : : get ( )
{
return & this - > address ;
}
2022-02-15 12:41:30 -05:00
2017-06-25 15:54:35 -04:00
const char * Network : : Address : : getCString ( ) const
2017-01-19 16:23:59 -05:00
{
return Game : : NET_AdrToString ( this - > address ) ;
}
2022-02-15 12:41:30 -05:00
2017-06-25 15:54:35 -04:00
std : : string Network : : Address : : getString ( ) const
2017-01-19 16:23:59 -05:00
{
return this - > getCString ( ) ;
}
2022-02-15 12:41:30 -05:00
2017-01-19 16:23:59 -05:00
bool Network : : Address : : isLocal ( )
{
// According to: https://en.wikipedia.org/wiki/Private_network
// 10.X.X.X
if ( this - > getIP ( ) . bytes [ 0 ] = = 10 ) return true ;
// 192.168.X.X
if ( this - > getIP ( ) . bytes [ 0 ] = = 192 & & this - > getIP ( ) . bytes [ 1 ] = = 168 ) return true ;
// 172.16.X.X - 172.31.X.X
if ( this - > getIP ( ) . bytes [ 0 ] = = 172 & & ( this - > getIP ( ) . bytes [ 1 ] > = 16 ) & & ( this - > getIP ( ) . bytes [ 1 ] < 32 ) ) return true ;
// 127.0.0.1
if ( this - > getIP ( ) . full = = 0x0100007F ) return true ;
// TODO: Maybe check for matching localIPs and subnet mask
return false ;
}
2022-02-15 12:41:30 -05:00
2017-01-19 16:23:59 -05:00
bool Network : : Address : : isSelf ( )
{
if ( Game : : NET_IsLocalAddress ( this - > address ) ) return true ; // Loopback
2017-05-31 12:03:05 -04:00
if ( this - > getPort ( ) ! = Network : : GetPort ( ) ) return false ; // Port not equal
2017-01-19 16:23:59 -05:00
for ( int i = 0 ; i < * Game : : numIP ; + + i )
{
if ( this - > getIP ( ) . full = = Game : : localIP [ i ] . full )
{
return true ;
}
}
return false ;
}
2022-02-15 12:41:30 -05:00
2017-01-19 16:23:59 -05:00
bool Network : : Address : : isLoopback ( )
{
if ( this - > getIP ( ) . full = = 0x100007f ) // 127.0.0.1
{
return true ;
}
return Game : : NET_IsLocalAddress ( this - > address ) ;
}
2022-02-15 12:41:30 -05:00
2017-01-19 16:23:59 -05:00
bool Network : : Address : : isValid ( )
{
2021-07-17 03:49:58 -04:00
return ( this - > getType ( ) ! = Game : : netadrtype_t : : NA_BAD & & this - > getType ( ) > = Game : : netadrtype_t : : NA_BOT & & this - > getType ( ) < = Game : : netadrtype_t : : NA_IP ) ;
2017-01-19 16:23:59 -05:00
}
2022-02-15 12:41:30 -05:00
2017-01-19 16:23:59 -05:00
void Network : : OnStart ( Utils : : Slot < Network : : CallbackRaw > callback )
{
Network : : StartupSignal . connect ( callback ) ;
}
2018-12-17 08:29:18 -05:00
void Network : : Send ( Game : : netsrc_t type , Network : : Address target , const std : : string & data )
2017-01-19 16:23:59 -05:00
{
// NET_OutOfBandPrint only supports non-binary data!
//Game::NET_OutOfBandPrint(type, *target.Get(), data.data());
std : : string rawData ;
rawData . append ( " \xFF \xFF \xFF \xFF " , 4 ) ;
rawData . append ( data ) ;
//rawData.append("\0", 1);
Network : : SendRaw ( type , target , rawData ) ;
}
2018-12-17 08:29:18 -05:00
void Network : : Send ( Network : : Address target , const std : : string & data )
2017-01-19 16:23:59 -05:00
{
2018-05-09 08:33:52 -04:00
Network : : Send ( Game : : netsrc_t : : NS_CLIENT1 , target , data ) ;
2017-01-19 16:23:59 -05:00
}
2018-12-17 08:29:18 -05:00
void Network : : SendRaw ( Game : : netsrc_t type , Network : : Address target , const std : : string & data )
2017-01-19 16:23:59 -05:00
{
2017-07-09 14:53:04 -04:00
if ( ! target . isValid ( ) ) return ;
2017-01-19 16:23:59 -05:00
// NET_OutOfBandData doesn't seem to work properly
//Game::NET_OutOfBandData(type, *target.Get(), data.data(), data.size());
Game : : Sys_SendPacket ( type , data . size ( ) , data . data ( ) , * target . get ( ) ) ;
}
2018-12-17 08:29:18 -05:00
void Network : : SendRaw ( Network : : Address target , const std : : string & data )
2017-01-19 16:23:59 -05:00
{
2018-05-09 08:33:52 -04:00
Network : : SendRaw ( Game : : netsrc_t : : NS_CLIENT1 , target , data ) ;
2017-01-19 16:23:59 -05:00
}
2018-12-17 08:29:18 -05:00
void Network : : SendCommand ( Game : : netsrc_t type , Network : : Address target , const std : : string & command , const std : : string & data )
2017-01-19 16:23:59 -05:00
{
// Use space as separator (possible separators are '\n', ' ').
2017-01-31 16:02:08 -05:00
// Though, our handler only needs exactly 1 char as separator and doesn't care which char it is.
// EDIT: Most 3rd party tools expect a line break, so let's use that instead!
2017-01-19 16:23:59 -05:00
std : : string packet ;
packet . append ( command ) ;
2017-01-31 16:02:08 -05:00
packet . append ( " \n " , 1 ) ;
2017-01-19 16:23:59 -05:00
packet . append ( data ) ;
Network : : Send ( type , target , packet ) ;
}
2018-12-17 08:29:18 -05:00
void Network : : SendCommand ( Network : : Address target , const std : : string & command , const std : : string & data )
2017-01-19 16:23:59 -05:00
{
2018-05-09 08:33:52 -04:00
Network : : SendCommand ( Game : : netsrc_t : : NS_CLIENT1 , target , command , data ) ;
2017-01-19 16:23:59 -05:00
}
2018-12-17 08:29:18 -05:00
void Network : : Broadcast ( unsigned short port , const std : : string & data )
2017-01-19 16:23:59 -05:00
{
Address target ;
target . setPort ( port ) ;
target . setIP ( INADDR_BROADCAST ) ;
target . setType ( Game : : netadrtype_t : : NA_BROADCAST ) ;
2018-05-09 08:33:52 -04:00
Network : : Send ( Game : : netsrc_t : : NS_CLIENT1 , target , data ) ;
2017-01-19 16:23:59 -05:00
}
2018-12-17 08:29:18 -05:00
void Network : : BroadcastRange ( unsigned int min , unsigned int max , const std : : string & data )
2017-01-19 16:23:59 -05:00
{
for ( unsigned int i = min ; i < max ; + + i )
{
Network : : Broadcast ( static_cast < unsigned short > ( i & 0xFFFF ) , data ) ;
}
}
2018-12-17 08:29:18 -05:00
void Network : : BroadcastAll ( const std : : string & data )
2017-01-19 16:23:59 -05:00
{
Network : : BroadcastRange ( 100 , 65536 , data ) ;
}
void Network : : NetworkStart ( )
{
Network : : StartupSignal ( ) ;
}
2017-05-31 12:03:05 -04:00
unsigned short Network : : GetPort ( )
{
return static_cast < unsigned short > ( Dvar : : Var ( 0x64A3004 ) . get < unsigned int > ( ) ) ;
}
2017-01-19 16:23:59 -05:00
__declspec ( naked ) void Network : : NetworkStartStub ( )
{
__asm
{
mov eax , 64 D900h
call eax
jmp Network : : NetworkStart
}
}
__declspec ( naked ) void Network : : PacketErrorCheck ( )
{
__asm
{
cmp eax , 2746 h
jz returnIgnore
cmp eax , WSAENETRESET
jz returnIgnore
push 465325 h
retn
returnIgnore :
push 4654 C6h
retn
}
}
2021-09-12 09:16:41 -04:00
void Network : : SV_ExecuteClientMessageStub ( Game : : client_t * client , Game : : msg_t * msg )
2021-09-12 07:47:35 -04:00
{
2021-09-12 11:37:02 -04:00
if ( client - > reliableAcknowledge < 0 )
2021-09-12 09:16:41 -04:00
{
2022-06-12 17:07:53 -04:00
Logger : : Print ( Game : : conChannel_t : : CON_CHANNEL_NETWORK , " Negative reliableAcknowledge from {} - cl->reliableSequence is {}, reliableAcknowledge is {} \n " ,
2021-09-13 15:36:48 -04:00
client - > name , client - > reliableSequence , client - > reliableAcknowledge ) ;
2021-09-12 11:37:02 -04:00
client - > reliableAcknowledge = client - > reliableSequence ;
2021-09-12 09:50:58 -04:00
Network : : SendCommand ( Game : : NS_SERVER , client - > netchan . remoteAddress , " error " , " EXE_LOSTRELIABLECOMMANDS " ) ;
2021-09-12 09:16:41 -04:00
return ;
}
2021-09-12 07:47:35 -04:00
Utils : : Hook : : Call < void ( Game : : client_t * , Game : : msg_t * ) > ( 0x414D40 ) ( client , msg ) ;
}
2022-05-20 18:12:46 -04:00
void Network : : OnPacket ( const std : : string & command , const NetworkCallback & callback )
{
Network : : Callbacks [ Utils : : String : : ToLower ( command ) ] = callback ;
}
bool Network : : HandleCommand ( Game : : netadr_t * address , const char * command , const Game : : msg_t * message )
{
2022-06-25 12:21:12 -04:00
const auto command_ = Utils : : String : : ToLower ( command ) ;
const auto handler = Network : : Callbacks . find ( command_ ) ;
2022-05-20 18:12:46 -04:00
2022-06-25 12:21:12 -04:00
const auto offset = command_ . size ( ) + 5 ;
2022-05-20 18:12:46 -04:00
if ( static_cast < std : : size_t > ( message - > cursize ) < offset | | handler = = Network : : Callbacks . end ( ) )
{
return false ;
}
const std : : string data ( message - > data + offset , message - > cursize - offset ) ;
Address address_ = address ;
handler - > second ( address_ , data ) ;
return true ;
}
__declspec ( naked ) void Network : : CL_HandleCommandStub ( )
{
__asm
{
lea eax , [ esp + 0xC54 ] // address
pushad
push ebp // msg_t
push edi // Command name
push eax // netadr_t pointer
call Network : : HandleCommand
add esp , 0xC
test al , al
popad
jz unhandled
// Exit CL_DispatchConnectionlessPacket
push 0x5A9E0E
retn
unhandled :
// Proceed
push 0x5AA719
retn
}
}
2017-01-19 16:23:59 -05:00
Network : : Network ( )
{
AssertSize ( Game : : netadr_t , 20 ) ;
// maximum size in NET_OutOfBandPrint
Utils : : Hook : : Set < DWORD > ( 0x4AEF08 , 0x1FFFC ) ;
Utils : : Hook : : Set < DWORD > ( 0x4AEFA3 , 0x1FFFC ) ;
// increase max port binding attempts from 10 to 100
Utils : : Hook : : Set < BYTE > ( 0x4FD48A , 100 ) ;
// increase cl_maxpackets limit
Utils : : Hook : : Set < BYTE > ( 0x4050A1 , 125 ) ;
2017-06-29 17:03:57 -04:00
// increase snaps
//Utils::Hook::Set<BYTE>(0x405357, 40);
// default maxpackets and snaps
Utils : : Hook : : Set < BYTE > ( 0x40535B , 30 ) ;
Utils : : Hook : : Set < BYTE > ( 0x4050A5 , 125 ) ;
2017-01-19 16:23:59 -05:00
// Parse port as short in Net_AddrToString
2020-12-09 14:13:34 -05:00
Utils : : Hook : : Set < const char * > ( 0x4698E3 , " %u.%u.%u.%u:%hu " ) ;
2017-01-19 16:23:59 -05:00
// Install startup handler
Utils : : Hook ( 0x4FD4D4 , Network : : NetworkStartStub , HOOK_JUMP ) . install ( ) - > quick ( ) ;
// Prevent recvfrom error spam
Utils : : Hook ( 0x46531A , Network : : PacketErrorCheck , HOOK_JUMP ) . install ( ) - > quick ( ) ;
2021-09-12 09:16:41 -04:00
// Fix server freezer exploit
Utils : : Hook ( 0x626996 , Network : : SV_ExecuteClientMessageStub , HOOK_CALL ) . install ( ) - > quick ( ) ;
2022-05-20 18:12:46 -04:00
// Handle client packets
Utils : : Hook ( 0x5AA703 , Network : : CL_HandleCommandStub , HOOK_JUMP ) . install ( ) - > quick ( ) ;
2021-09-12 07:47:35 -04:00
2022-05-20 18:12:46 -04:00
Network : : OnPacket ( " resolveAddress " , [ ] ( const Address & address , [[maybe_unused]] const std : : string & data )
2017-01-19 16:23:59 -05:00
{
Network : : SendRaw ( address , address . getString ( ) ) ;
} ) ;
}
}