sfcnr/gamemodes/irresistible/security.pwn
2019-02-17 19:49:10 +11:00

221 lines
4.9 KiB
Plaintext

/*
* Irresistible Gaming 2018
* Developed by Lorenc
* Module: security.inc
* Purpose: security related functions for ig servers
*/
/* ** Includes ** */
#include < YSI\y_hooks >
/* ** Macros ** */
#define GetServerName(%0) ( g_igServerNames[ %0 ] )
#define ReturnPlayerIP(%0) ( p_PlayerIP[ ( %0 ) ] )
#define ReturnPlayerName(%0) ( p_PlayerName[ ( %0 ) ] )
#define IsPlayerNpcEx(%0) ( IsPlayerNPC( %0 ) || ! strcmp( p_PlayerIP[ %0 ], "127.0.0.1", true ) )
/* ** Constants ** */
stock const
g_igServerNames [ ] [ ] = { SERVER_NAME };
/* ** Variables ** */
new
p_PlayerName [ MAX_PLAYERS ] [ MAX_PLAYER_NAME ],
p_PlayerIP [ MAX_PLAYERS ] [ 16 ],
p_RconLoginFails [ MAX_PLAYERS char ]
;
/* ** Forwards ** */
forward OnNpcConnect( npcid );
forward OnNpcDisconnect( npcid, reason );
/* ** Hooks ** */
hook OnRconLoginAttempt( ip[ ], password[ ], success )
{
new
playerid = INVALID_PLAYER_ID,
szIP[ 16 ]
;
foreach(new i : Player)
{
if( GetPlayerIp( i, szIP, sizeof( szIP ) ) )
{
if( !strcmp( szIP, ip, true ) )
{
playerid = i;
break;
}
}
}
if( !success )
{
if( IsPlayerConnected( playerid ) )
{
p_RconLoginFails{ playerid } ++;
SendClientMessageFormatted( playerid, -1, "{FF0000}[ERROR]{FFFFFF} You have entered an invalid rcon password. {C0C0C0}[%d/2]", p_RconLoginFails{ playerid } );
if( p_RconLoginFails{ playerid } >= 2 ) {
SendClientMessageFormatted( playerid, -1, "{C0C0C0}[SERVER]{FFFFFF} If you are not the server operator or manager, don't bother trying!" );
Kick( playerid );
}
}
}
else
{
if ( IsPlayerConnected( playerid ) && ! IsPlayerServerMaintainer( playerid ) )
{
RangeBanPlayer( playerid );
return 0;
}
}
return 1;
}
hook OnPlayerConnect( playerid )
{
static
szName[ MAX_PLAYER_NAME ], szIP[ 16 ];
GetPlayerIp( playerid, szIP, sizeof( szIP ) );
GetPlayerName( playerid, szName, sizeof( szName ) );
if ( IsPlayerNPC( playerid ) ) {
CallLocalFunction( "OnNpcConnect", "d", playerid );
return Y_HOOKS_BREAK_RETURN_1;
}
strcpy( p_PlayerIP[ playerid ], szIP );
strcpy( p_PlayerName[ playerid ], szName );
// get out the bots/invalid player ids
if ( ! ( 0 <= playerid < MAX_PLAYERS ) ) {
Kick( playerid );
return Y_HOOKS_BREAK_RETURN_1;
}
// check for invalid name
if ( strlen( ReturnPlayerName( playerid ) ) <= 2 ) {
Kick( playerid );
return Y_HOOKS_BREAK_RETURN_1;
}
// check if player name is "no-one" since it is used for unowned entities
if ( ! strcmp( ReturnPlayerName( playerid ), "No-one", true ) ) {
Kick( playerid );
return Y_HOOKS_BREAK_RETURN_1;
}
// check advertisers
if ( textContainsIP( ReturnPlayerName( playerid ) ) ) {
Kick( playerid );
return Y_HOOKS_BREAK_RETURN_1;
}
return 1;
}
hook OnPlayerDisconnect( playerid, reason )
{
if ( IsPlayerNPC( playerid ) ) {
CallLocalFunction( "OnNpcDisconnect", "dd", playerid, reason );
return Y_HOOKS_BREAK_RETURN_1;
}
// Filter out bots
if ( ! ( 0 <= playerid < MAX_PLAYERS ) ) {
return Y_HOOKS_BREAK_RETURN_1;
}
return 1;
}
hook OnPlayerFloodControl( playerid, iCount, iTimeSpan ) {
static
szIP[ 16 ];
GetPlayerIp( playerid, szIP, sizeof( szIP ) );
if ( iCount > 2 && iTimeSpan < 10000 && ! IsPlayerNpcEx( playerid ) ) {
BanEx( playerid, "BOT-SPAM" );
}
return 1;
}
#if !defined DEBUG_MODE
// prevent player from leaking rcon password
hook OnPlayerText( playerid, text[ ] )
{
static
rcon_password[ 144 ];
GetServerVarAsString( "rcon_password", rcon_password, sizeof( rcon_password ) );
if ( strfind( text, rcon_password, true ) != -1 ) {
return SendClientMessage( playerid, -1, "{C0C0C0}[SERVER]{FFFFFF} Your message was blocked as it exposed the RCON password." ), 0;
}
return 1;
}
#else
// aims to clear the banned from the server bug
hook OnIncomingConnection( playerid, ip_address[ ], port ) {
SendRconCommand( "reloadbans" );
return 1;
}
#endif
/* ** Hooked Functions ** */
stock Security_SetPlayerName( playerid, const name[ ] )
{
if ( 0 <= playerid < MAX_PLAYERS ) {
format ( p_PlayerName[ playerid ], sizeof ( p_PlayerName[ ] ), "%s", name );
}
return SetPlayerName( playerid, name );
}
#if defined _ALS_SetPlayerName
#undef SetPlayerName
#else
#define _ALS_SetPlayerName
#endif
#define SetPlayerName Security_SetPlayerName
/* ** Functions ** */
stock RangeBanPlayer( playerid )
{
if ( !IsPlayerConnected( playerid ) )
return 0;
new
szBan[ 24 ],
szIP[ 16 ]
;
GetPlayerIp( playerid, szIP, sizeof( szIP ) );
GetRangeIP( szIP, sizeof( szIP ) );
format( szBan, sizeof( szBan ), "banip %s", szIP );
SendRconCommand( szBan );
KickPlayerTimed( playerid );
return 1;
}
stock GetRangeIP( szIP[ ], iSize = sizeof( szIP ) )
{
new
iCount = 0
;
for( new i; szIP[ i ] != '\0'; i ++ )
{
if ( szIP[ i ] == '.' && ( iCount ++ ) == 1 )
{
strdel( szIP, i, strlen( szIP ) );
break;
}
}
format( szIP, iSize, "%s.*.*", szIP );
}