AMX Mod X Moderator
Join Date: Feb 2005
Location: NJ, USA
|
12-09-2015
, 20:14
Re: Ban if no return in 5 minutes.
|
#147
|
Changes: - Added slot reservation for players who disconnected. The servers reserved slots are set equal to the number of players in the queue. Each slot reservation will last for binr_reconnectmin minutes.
- Added disconnect reason checking to exclude players who did not disconnect by choice (time out, etc)
- Performance enhancement to make the entity think only when there are players in the queue.
The plugin now has 2 1 dependencies. I added checking for these which will make the plugin fail if they are missing. You can easily disable to disconnect reason checking if you want. - Disconnect Reason plugin, which requires you have the Orpheu module installed.
AMX-X native admin slot reservation plugin (adminslots.amxx). This I believe is enabled by default in plugins.ini.
PHP Code:
#include <amxmodx> #include <engine> #include <nvault_util>
new const Version[] = "1.4";
#define MAX_PLAYERS 32
//************************************************************************************************** //* Exclude players who disconnected for any reason other than clicking Disconnect. * * //* * //* This functionality requires that you have the Disconnect Reason plugin running, which requires * //* the orpheu module. https://forums.alliedmods.net/showthread.php?t=166239 * //************************************************************************************************** //* If you do not want to use this functionality, comment out the below #define line * //************************************************************************************************** #define EXCLUDE_TIMEOUT_DISCONNECT
#if defined EXCLUDE_TIMEOUT_DISCONNECT enum ReasonCodes { DR_TIMEDOUT, DR_DROPPED, DR_KICKED, DR_LEVELCHANGE, DR_OTHER } #endif
const BanQueueSize = 30; const Float:EntityInterval = 1.0; const MinuteSeconds = 60;
enum PlayerData { pdAuthID[ 34 ], pdDisconnectTime, }
new g_pdData[ MAX_PLAYERS + 1 ][ PlayerData ] , g_BanQueue[ BanQueueSize ][ PlayerData ]; new g_IgnorePlayers , g_HasAuthorized , g_PlayersInQueue , g_Entity , g_Vault , g_MaxPlayers; new g_pBanLeavers , g_pReconnectMinutes , g_pBanMinutes , g_pImmunityFlags , g_pReservedSlots;
public plugin_init() { register_plugin( "Ban If No Return" , Version , "bugsy" ); g_pBanLeavers = register_cvar( "binr_enabled" , "1" ); g_pReconnectMinutes = register_cvar( "binr_reconnectmin" , "5" ); g_pBanMinutes = register_cvar( "binr_banmins" , "60" ); g_pImmunityFlags = register_cvar( "binr_immunityflags" , "a" ); g_pReservedSlots = get_cvar_pointer( "sv_visiblemaxplayers" ); g_Entity = create_entity( "info_target" ); entity_set_string( g_Entity , EV_SZ_classname , "binr_entity" ); register_think( "binr_entity" , "EntityThink" );
g_MaxPlayers = get_maxplayers(); #if defined EXCLUDE_TIMEOUT_DISCONNECT if ( is_plugin_loaded( "Disconnect Reason" ) == INVALID_HANDLE ) set_fail_state( "Disconnect Reason plugin must be running!" ); #endif }
public plugin_cfg() { LoadQueue(); if ( g_PlayersInQueue ) { entity_set_float( g_Entity , EV_FL_nextthink , ( get_gametime() + EntityInterval ) ); set_pcvar_num( g_pReservedSlots , g_MaxPlayers - g_PlayersInQueue ); } g_Vault = nvault_open( "ban_if_no_return" ); nvault_prune( g_Vault , 0 , get_systime() ); }
public plugin_end() { SaveQueue(); call_think( g_Entity ); nvault_close( g_Vault ); }
public client_authorized( id ) { new iTimeStamp , szKickMessage[ 96 ] , szFlags[ 26 ]; get_pcvar_string( g_pImmunityFlags , szFlags , charsmax( szFlags ) ); g_IgnorePlayers |= ( is_user_bot( id ) || is_user_hltv( id ) || ( get_user_flags( id ) & read_flags( szFlags ) ) ? 1 : 0 ) << ( id & 31 ) ; if ( !( g_IgnorePlayers & ( 1 << ( id & 31 ) ) ) ) { get_user_authid( id , g_pdData[ id ][ pdAuthID ] , charsmax( g_pdData[][ pdAuthID ] ) ); if ( nvault_lookup( g_Vault , g_pdData[ id ][ pdAuthID ] , "" , 0 , iTimeStamp ) ) { if ( iTimeStamp > get_systime() ) { formatex( szKickMessage , charsmax( szKickMessage ) , "^nYou have been banned for %d minutes for not re-joining within %d minutes." , get_pcvar_num( g_pBanMinutes ) , get_pcvar_num( g_pReconnectMinutes ) ); message_begin( MSG_ONE , 2 , {0,0,0} , id ); write_string( szKickMessage ); message_end(); } else { nvault_remove( g_Vault , g_pdData[ id ][ pdAuthID ] ); } } else { RemoveFromBanQueue( id ); } } g_HasAuthorized |= ( 1 << ( id & 31 ) ); }
#if defined EXCLUDE_TIMEOUT_DISCONNECT public client_disconnect_reason( id , ReasonCodes:drReason , const szReason[] ) { if ( drReason != DR_DROPPED ) { g_IgnorePlayers &= ~( 1 << ( id & 31 ) ); g_HasAuthorized &= ~( 1 << ( id & 31 ) ); return; } #else public client_disconnect( id ) { #endif
if (!( g_IgnorePlayers & ( 1 << ( id & 31 ) ) ) && ( g_HasAuthorized & ( 1 << ( id & 31 ) ) ) && get_pcvar_num( g_pBanLeavers ) ) { if ( !AddToBanQueue( id ) ) set_fail_state( "Ban If No Return: Need to increase queue size." ); } g_IgnorePlayers &= ~( 1 << ( id & 31 ) ); g_HasAuthorized &= ~( 1 << ( id & 31 ) ); }
public EntityThink( iEntity ) { if( iEntity == g_Entity ) { SetBansInQueue(); if ( g_PlayersInQueue ) entity_set_float( g_Entity , EV_FL_nextthink , ( get_gametime() + EntityInterval ) ); } }
bool:AddToBanQueue( id , DisconnectTime=0 ) { new bool:bSuccess; for (new iSlot = 0 ; iSlot < BanQueueSize ; iSlot++ ) { if ( g_BanQueue[ iSlot ][ pdAuthID ][ 0 ] == EOS ) { copy( g_BanQueue[ iSlot ][ pdAuthID ] , charsmax( g_BanQueue[][ pdAuthID ] ) , g_pdData[ id ][ pdAuthID ] ); g_BanQueue[ iSlot ][ pdDisconnectTime ] = DisconnectTime ? DisconnectTime : get_systime(); bSuccess = true; if ( !g_PlayersInQueue++ ) entity_set_float( g_Entity , EV_FL_nextthink , ( get_gametime() + EntityInterval ) ); if ( !DisconnectTime ) set_pcvar_num( g_pReservedSlots , g_MaxPlayers - g_PlayersInQueue ); break; } } return bSuccess; }
RemoveFromBanQueue( id ) { for ( new iSlot = 0 ; iSlot < BanQueueSize ; iSlot++ ) { if ( equal( g_BanQueue[ iSlot ][ pdAuthID ] , g_pdData[ id ][ pdAuthID ] ) ) { g_BanQueue[ iSlot ][ pdAuthID ][ 0 ] = EOS; g_BanQueue[ iSlot ][ pdDisconnectTime ] = 0; g_PlayersInQueue--; set_pcvar_num( g_pReservedSlots , g_MaxPlayers - g_PlayersInQueue ); break; } } }
SetBansInQueue() { new iBanTime; for ( new iSlot = 0 ; iSlot < BanQueueSize ; iSlot++ ) { if ( g_BanQueue[ iSlot ][ pdAuthID ][ 0 ] ) { if ( ( get_systime() - g_BanQueue[ iSlot ][ pdDisconnectTime ] ) >= ( get_pcvar_num( g_pReconnectMinutes ) * MinuteSeconds ) ) { nvault_set( g_Vault , g_BanQueue[ iSlot ][ pdAuthID ] , "1" ); nvault_touch( g_Vault , g_BanQueue[ iSlot ][ pdAuthID ] , ( iBanTime = get_pcvar_num( g_pBanMinutes ) ) == 0 ? 0 : get_systime() + ( iBanTime * MinuteSeconds ) ); g_PlayersInQueue--; set_pcvar_num( g_pReservedSlots , g_MaxPlayers - g_PlayersInQueue ); g_BanQueue[ iSlot ][ pdAuthID ][ 0 ] = EOS; g_BanQueue[ iSlot ][ pdDisconnectTime ] = 0; } } } }
LoadQueue() { new iVault , pData[ _:PlayerData ] , iPos , iCount , iItems , iTimeStamp , szKey[ 9 ]; if ( ( iVault = nvault_util_open( "ban_if_no_return" ) ) ) { iCount = nvault_util_count( iVault ); for ( new iEntry = 0 ; iEntry < iCount ; iEntry++ ) { iPos = nvault_util_read_array( iVault , iPos , szKey , charsmax( szKey ) , pData , sizeof( pData ) , iItems , iTimeStamp ); if ( equal( szKey , "BanQueue" ) ) { copy( g_pdData[ 0 ][ pdAuthID ] , sizeof( g_pdData[][ pdAuthID ] ) , pData[ _:pdAuthID ] ); g_pdData[ 0 ][ pdDisconnectTime ] = pData[ _:pdDisconnectTime ]; AddToBanQueue( 0 , g_pdData[ 0 ][ pdDisconnectTime ] ); } } } }
SaveQueue() { new szKey[ 12 ] , iSlotIndex , pData[ _:PlayerData ]; copy( szKey , charsmax( szKey ) , "BanQueue" ); for ( new iSlot = 0 ; iSlot < BanQueueSize ; iSlot++ ) { if ( g_BanQueue[ iSlot ][ pdDisconnectTime ] ) { copy( pData[ _:pdAuthID ] , charsmax( pData[ pdAuthID ] ) , g_BanQueue[ iSlot ][ pdAuthID ] ); pData[ _:pdDisconnectTime ] = g_BanQueue[ iSlot ][ pdDisconnectTime ]; num_to_str( iSlotIndex++ , szKey[ 8 ] , charsmax( szKey ) - 8 ); nvault_set_array( g_Vault , szKey , pData , sizeof( pData ) ); nvault_touch( g_Vault , szKey , 1 ); } } }
__________________
Last edited by Bugsy; 12-11-2015 at 19:54.
|
|