GGM vote and temp ban system, remove old globalvote and player filter

This commit is contained in:
mittorn 2018-11-07 23:07:16 +07:00
parent 31de8a8b5c
commit 472a253943
5 changed files with 289 additions and 243 deletions

View File

@ -354,80 +354,6 @@ void UTIL_SpawnPlayer( CBasePlayer *pPlayer )
}
char *UTIL_CoopPlayerName( CBaseEntity *pPlayer )
{
if( !pPlayer )
return (char*)"unnamed(NULL)";
return (char*)( ( pPlayer->pev->netname && STRING( pPlayer->pev->netname )[0] != 0 ) ? STRING( pPlayer->pev->netname ) : "unconnected" );
}
char *badlist[256] = {
"player", // does not even can set own name
"talat",
"hmse",
"mhmd",
"aeman",
"famas",
"danek",
"ame syia",
"melih",
"aliance",
"vladick"
};
void UTIL_CoopKickPlayer(CBaseEntity *pPlayer)
{
int i;
if( !pPlayer )
return;
char *name = UTIL_CoopPlayerName( pPlayer );
SERVER_COMMAND( UTIL_VarArgs( "kick %d\n", ENTINDEX(pPlayer->pev->pContainingEntity) - 1 ) );
if( strlen( name ) < 5 )
return;
// find last slot
for( i = 0; badlist[i]; i++ );
if( i > 254 )
return;
badlist[i] = strdup( name );
}
#ifdef __WIN32 // no strcasestr
#include <windows.h>
#include <string.h>
const char *strcasestr( const char *s1, const char *s2 )
{
if( s1 == 0 || s2 == 0 )
return 0;
size_t n = strlen(s2);
while(*s1)
if(!strnicmp(s1++,s2,n))
return (s1-1);
return 0;
}
#endif
bool UTIL_CoopIsBadPlayer( CBaseEntity *plr )
{
if( !plr )
return false;
for( int i = 0; badlist[i];i++ )
if( strcasestr( (char*)UTIL_CoopPlayerName( plr ), badlist[i] ) )
return true;
return false;
}
// Collect all weapons tat player touchet in coop ant give to all players at spawn
void COOP_ClearWeaponList( void )
{
@ -641,116 +567,6 @@ bool COOP_GetOrigin( Vector *pvecNewOrigin, const Vector &vecOrigin, const char
return false;
}
// Show to all spawned players: voting, etc..
class GlobalVote
{
public:
int m_iConfirm;
int m_iBanCount;
float m_flTime;
EHANDLE m_pTrigger;
EHANDLE m_pPlayer;
void ConfirmMenu( CBasePlayer *pPlayer, CBaseEntity *trigger, const char *mapname );
void ShowGlobalMenu( const char *title, int count, const char **menu );
void Process( CBasePlayer *pPlayer, int imenu );
};
GlobalVote g_GlobalVote;
void GlobalVote::Process( CBasePlayer *pPlayer, int imenu )
{
if( pPlayer->pev->flags & FL_SPECTATOR )
return;
if( gpGlobals->time - m_flTime > 20 )
{
COOP_ResetVote();
return;
}
//g_GlobalVote.m_flTime = gpGlobals->time;
switch( g_CoopState.iVote )
{
case 1: // touch blue trigger
if( imenu == 0 ) // confirm
{
if( m_iBanCount >= 2 )
{
UTIL_CoopKickPlayer( pPlayer );
m_iConfirm-= 5;
m_iBanCount = 0;
return;
}
m_iConfirm++;
UTIL_CoopPrintMessage( "%s^7 confirmed map change\n", UTIL_CoopPlayerName( pPlayer ));
DispatchTouch( m_pTrigger->edict(), m_pPlayer->edict() );
}
if( imenu == 1 ) // cancel
{
m_iConfirm--;
if( pPlayer == m_pPlayer )
{
m_iConfirm = -10; // player mistake
g_CoopState.iVote = 0;
}
}
if( imenu == 2 )
{
m_iBanCount++;
if( m_iBanCount >= 2 && m_iConfirm > -9 )
UTIL_CoopKickPlayer( m_pPlayer );
g_CoopState.iVote = 0;
}
break;
}
}
void GlobalVote::ShowGlobalMenu( const char *title, int count, const char **menu )
{
int count2 = 0;
for( int i = 1; i <= gpGlobals->maxClients; i++ )
{
CBaseEntity *plr = UTIL_PlayerByIndex( i );
if( plr && plr->IsPlayer() && !UTIL_CoopIsBadPlayer( plr ) )
{
count2++;
CBasePlayer *player = (CBasePlayer *) plr;
GGM_PlayerMenu &m = player->m_ggm.menu.New( title );
for( int j = 0; j < count; j++ )
{
char cmd[32];
sprintf(cmd, "votemenu %d", j );
m.Add( menu[j], cmd );
}
m.Show();
}
}
m_iBanCount = 0;
}
void GlobalVote::ConfirmMenu( CBasePlayer *pPlayer, CBaseEntity *trigger, const char *mapname )
{
g_CoopState.iVote = 1;
m_flTime = gpGlobals->time;
m_pTrigger = trigger;
m_pPlayer = pPlayer;
const char *menu[] = {
"Confirm",
"Cancel",
"BAN"
};
UTIL_CoopPrintMessage( "%s^7 wants to change map ^1BACK to %s\n", UTIL_CoopPlayerName( pPlayer ), mapname );
ShowGlobalMenu(UTIL_VarArgs("Confirm changing map BACK TO %s?", mapname), ARRAYSIZE(menu), menu);
}
void COOP_NewCheckpoint( entvars_t *pevPlayer )
{
if( !pevPlayer->netname || pevPlayer->health <= 0 )
@ -824,62 +640,21 @@ CBaseEntity *UTIL_CoopGetPlayerTrain( CBaseEntity *pPlayer)
}
void COOP_ResetVote( void )
{
g_CoopState.iVote = 0;
g_GlobalVote.m_iConfirm = 0;
g_GlobalVote.m_iBanCount = 0;
g_GlobalVote.m_flTime = gpGlobals->time;
}
bool COOP_ConfirmMenu(CBaseEntity *pTrigger, CBaseEntity *pActivator, int count2, char *mapname )
{
if( gpGlobals->time - g_GlobalVote.m_flTime > 10 )
COOP_ResetVote();
//g_GlobalVote.m_flTime = gpGlobals->time;
if( mp_coop_strongcheckpoints.value )
{
// do not allow go back if there are checkpoints, but not near changelevel
if( g_CoopState.pCurrentMap->p.rgCheckpoints[0].flTime && (g_CoopState.pCurrentMap->p.rgCheckpoints[0].pos.vecOrigin - VecBModelOrigin(pTrigger->pev)).Length() > 150 )
{
COOP_ResetVote();
//UTIL_CoopPlayerMessage( pActivator, 1, 5, 0xFF0000FF, 0xFF0000FF, 0, 0.7, "Changelevel back locked by checkpoint\nCheckpoint here to activate trigger!");
ClientPrint( pActivator->pev, HUD_PRINTCENTER, "Changelevel back locked by checkpoint\nCheckpoint here to activate trigger!");
return false;
}
//if( count2 < 2 )
//return;
}
if( g_CoopState.iVote != 1 )
{
if( !UTIL_CoopIsBadPlayer( pActivator ) )
{
CBasePlayer *pPlayer = (CBasePlayer*)pActivator;
if( GGM_ChangelevelVote((CBasePlayer*)pActivator, pTrigger->edict(), mapname ) < count2 )
return false;
if( pPlayer->m_ggm.iLocalConfirm <= 0 )
pPlayer->m_ggm.iLocalConfirm = 1;
if( pPlayer->m_ggm.iLocalConfirm < 3 )
{
pPlayer->m_ggm.pChangeLevel = pTrigger->edict();
pPlayer->m_ggm.menu.New("This will change map back", false)
.Add("Confirm", "confirmchangelevel")
.Add("Cancel", "")
.Show();
}
else
{
g_GlobalVote.ConfirmMenu(pPlayer, pTrigger, mapname );
pPlayer->m_ggm.iLocalConfirm = 0;
pPlayer->m_ggm.pChangeLevel = NULL;
}
}
return false;
}
if( g_GlobalVote.m_iConfirm < count2 )
return false;
return true;
}
@ -993,7 +768,7 @@ bool COOP_ClientCommand( edict_t *pEntity )
return false;
if( pPlayer->m_ggm.iState != STATE_SPAWNED )
return false;
if( !UTIL_CoopIsBadPlayer( pPlayer ) )
if( !GGM_IsTempBanned( pPlayer ) )
COOP_NewCheckpoint( pPlayer->pev );
else
return false;
@ -1016,12 +791,6 @@ bool COOP_ClientCommand( edict_t *pEntity )
else
return false;
}
else if( FStrEq( pcmd, "votemenu" ) )
{
int i = atoi( CMD_ARGV(1) );
g_GlobalVote.Process(pPlayer, i);
return true;
}
return false;
}

View File

@ -34,7 +34,6 @@ struct COOPChangelevelData
};
void UTIL_CleanSpawnPoint( Vector origin, float radius );
char *UTIL_CoopPlayerName( CBaseEntity *pPlayer );
bool COOP_SetDefaultSpawnPosition( CBasePlayer *pPlayer );
void UTIL_CoopPrintMessage( const char *format, ... );
@ -49,7 +48,6 @@ void COOP_ResetVote( void );
void COOP_ServerActivate( void );
bool COOP_GetOrigin( Vector *pvecNewOrigin, const Vector &vecOrigin, const char *pszMapName );
class CBasePlayer;
bool UTIL_CoopIsBadPlayer( CBaseEntity *plr );
CBaseEntity *UTIL_CoopGetPlayerTrain( CBaseEntity *pPlayer);
void UTIL_SpawnPlayer( CBasePlayer *pPlayer );
void UTIL_BecomeSpectator( CBasePlayer *pPlayer );

View File

@ -49,6 +49,240 @@ cvar_t *zombietime = NULL;
static char gamedir[MAX_PATH];
void Ent_RunGC_f( void );
enum GGMVoteMode
{
VOTE_NONE = 0,
VOTE_COOP_CHANGELEVEL,
VOTE_COMMAND
};
// cancel vote after 15 seconds
#define VOTE_INACTIVE_TIME 15.0f
// ignore vote first 2 seconds
#define VOTE_MISCLICK_TIME 2.0f
struct GGMVote
{
int iMode;
EHANDLE pPlayer;
// changelevel
edict_t *pTrigger;
char szCommand[256];
char szMessage[256];
float flStartTime;
float flLastActiveTime;
int iMaxCount;
int iTempBanCount;
int iConfirm;
} g_Vote;
bool GGM_IsTempBanned( CBaseEntity *pEnt )
{
CBasePlayer *pPlayer = (CBasePlayer*)pEnt;
if( !pPlayer || !pPlayer->IsPlayer() )
return false;
if( !pPlayer->m_ggm.pState )
return false;
return pPlayer->m_ggm.pState->t.fIsTempBanned;
}
void GGM_ClearVote( void )
{
memset( &g_Vote, 0, sizeof( g_Vote ) );
}
void GGM_SendVote( CBasePlayer *pPlayer )
{
pPlayer->m_ggm.menu.New( g_Vote.szMessage )
.Add( "Confirm", "voteconfirm" )
.Add( "Cancel", "votecancel" )
.Add( "BAN", "votetempban" )
.Show();
}
void GGM_BroadcastVote( void )
{
int iCount = 0;
for( int i = 1; i <= gpGlobals->maxClients; i++ )
{
CBaseEntity *plr = UTIL_PlayerByIndex( i );
if( plr && plr->IsPlayer() && !GGM_IsTempBanned( plr ) )
{
CBasePlayer *pPlayer = (CBasePlayer *) plr;
if( pPlayer->m_ggm.iState != STATE_SPAWNED )
continue;
iCount++;
GGM_SendVote( pPlayer );
}
}
g_Vote.flLastActiveTime = g_Vote.flStartTime = gpGlobals->time;
g_Vote.iTempBanCount = 0;
g_Vote.iConfirm = 0;
g_Vote.iMaxCount = iCount;
}
void GGM_StartVoteCommand( CBasePlayer *pPlayer, const char *pszCommand, const char *pszMessage )
{
if( gpGlobals->time - g_Vote.flLastActiveTime > VOTE_INACTIVE_TIME )
GGM_ClearVote();
// vote pending
if( g_Vote.iMode )
return;
g_Vote.iMode = VOTE_COMMAND;
g_Vote.pPlayer = pPlayer;
snprintf( g_Vote.szCommand, 255, "%s\n", pszCommand);
strncpy( g_Vote.szMessage, pszMessage, 255 );
GGM_BroadcastVote();
}
void GGM_VoteCommand_f( void )
{
GGM_StartVoteCommand( NULL, CMD_ARGV(1), CMD_ARGV(2));
}
int GGM_ChangelevelVote( CBasePlayer *pPlayer, edict_t *pTrigger, const char *pszMapName )
{
if( gpGlobals->time - g_Vote.flLastActiveTime > VOTE_INACTIVE_TIME )
GGM_ClearVote();
if( g_Vote.iMode == VOTE_COOP_CHANGELEVEL )
{
if( g_Vote.pTrigger == pTrigger )
return g_Vote.iConfirm;
else
return -1;
}
if( g_Vote.iMode )
return -1;
if( !GGM_IsTempBanned( pPlayer ) )
{
if( pPlayer->m_ggm.iLocalConfirm <= 0 )
pPlayer->m_ggm.iLocalConfirm = 1;
if( pPlayer->m_ggm.iLocalConfirm < 3 )
{
pPlayer->m_ggm.pChangeLevel = pTrigger;
pPlayer->m_ggm.menu.New("This will change map back", false)
.Add("Confirm", "confirmchangelevel")
.Add("Cancel", "")
.Show();
return -1;
}
else
{
g_Vote.iMode = VOTE_COOP_CHANGELEVEL;
g_Vote.pTrigger = pTrigger;
g_Vote.pPlayer = pPlayer;
UTIL_CoopPrintMessage( "%s^7 wants to change map ^1BACK to %s\n", GGM_PlayerName( pPlayer ), pszMapName );
snprintf(g_Vote.szMessage, 255, "Change map BACK TO %s?", pszMapName );
GGM_BroadcastVote();
pPlayer->m_ggm.iLocalConfirm = 0;
pPlayer->m_ggm.pChangeLevel = NULL;
return 0;
}
}
return -1;
}
bool GGM_VoteProcess( CBasePlayer *pPlayer, const char *pszStr )
{
if( !g_Vote.iMode )
return false;
if( gpGlobals->time - g_Vote.flLastActiveTime > VOTE_INACTIVE_TIME )
{
GGM_ClearVote();
return false;
}
if( gpGlobals->time - g_Vote.flStartTime < VOTE_MISCLICK_TIME )
{
GGM_SendVote( pPlayer );
return false;
}
if( !strcmp( pszStr, "voteconfirm" ) )
{
if( g_Vote.iTempBanCount >= 3 )
{
GGM_TempBan( pPlayer );
g_Vote.iConfirm -= 5;
g_Vote.iTempBanCount = 0;
return true;
}
g_Vote.iConfirm++;
if( g_Vote.iMode == VOTE_COOP_CHANGELEVEL )
{
UTIL_CoopPrintMessage( "%s^7 confirmed map change\n", GGM_PlayerName( pPlayer ));
DispatchTouch( g_Vote.pTrigger, g_Vote.pPlayer.Get() );
}
else if( g_Vote.iMode == VOTE_COMMAND )
{
UTIL_CoopPrintMessage( "%s^7 confirmed vote\n", GGM_PlayerName( pPlayer ));
if( g_Vote.iConfirm > g_Vote.iMaxCount / 2 )
{
SERVER_COMMAND( g_Vote.szCommand );
SERVER_EXECUTE();
GGM_ClearVote();
}
}
return true;
}
else if( !strcmp( pszStr, "votecancel" ) )
{
g_Vote.iConfirm--;
if( g_Vote.pPlayer == pPlayer )
GGM_ClearVote();
return true;
}
else if( !strcmp( pszStr, "votetempban" ) )
{
g_Vote.iTempBanCount++;
if( g_Vote.iTempBanCount >= 3 )
{
GGM_TempBan( g_Vote.pPlayer );
GGM_ClearVote();
}
return true;
}
return false;
}
const char *GGM_PlayerName( CBaseEntity *pPlayer )
{
if( !pPlayer )
return "unnamed(NULL)";
return (const char*)( ( pPlayer->pev->netname && STRING( pPlayer->pev->netname )[0] != 0 ) ? STRING( pPlayer->pev->netname ) : "unconnected" );
}
void GGM_TempBan( CBaseEntity *pEnt )
{
CBasePlayer *pPlayer = (CBasePlayer*)pEnt;
if( !pEnt || pEnt->IsPlayer() )
return;
if( !pPlayer->m_ggm.pState )
return;
pPlayer->m_ggm.pState->t.fIsTempBanned = true;
SERVER_COMMAND( UTIL_VarArgs( "kick #%d\n", GETPLAYERUSERID( pPlayer->edict() ) ) );
}
static bool Q_starcmp( const char *pattern, const char *text )
{
char c, c1;
@ -661,6 +895,7 @@ void GGM_Save( const char *savename )
float health = client0->v.health;
int deadflag = client0->v.deadflag;
float zombietime_old;
bool fNeedKick = false;
SERVER_EXECUTE();
// save even with dead player
@ -671,9 +906,17 @@ void GGM_Save( const char *savename )
if( zombietime )
zombietime_old = zombietime->value;
if( !(g_engfuncs.pfnGetInfoKeyBuffer( client0 )[0]))
fNeedKick = true;
if( !(g_engfuncs.pfnGetPhysicsInfoString( client0 )[0]))
fNeedKick = true;
if( !client0->v.netname )
fNeedKick = true;
if( !strcmp( GETPLAYERAUTHID( client0 ), "VALVE_ID_LOOPBACK" ) )
fNeedKick = false;
// hack to make save work when client 0 not connected
if( !(g_engfuncs.pfnGetInfoKeyBuffer( client0 )[0]) || !(g_engfuncs.pfnGetPhysicsInfoString( client0 )[0]) || !client0->v.netname )
if( !client0->v.netname )
{
snprintf( cmd, 32, "kick #%d\n", GETPLAYERUSERID( client0 ) );
SERVER_COMMAND(cmd);
@ -846,11 +1089,24 @@ struct GGMLogin *GGM_LoadLogin( const char *uid, const char *name )
return pLogin;
}
struct GGMPlayerState *GGM_GetState( const char *uid, const char *name )
{
struct GGMPlayerState *pState;
struct GGMLogin *pLogin = GGM_LoadLogin( uid, name );
char *rgpszBadNames[] = {
"player*", // does not even can set own name
"*talat*",
"*hmse*",
"*mhmd*",
"*aeman*",
"*famas*",
"*danek*",
"ame syia*",
"*melih*",
"*aliance*",
"*alliance*",
"*vladick*",
};
if( pLogin )
{
@ -876,6 +1132,15 @@ struct GGMPlayerState *GGM_GetState( const char *uid, const char *name )
pState->szUID[32] = 0;
pState->pNext = anonymous_list;
for( int i = 0; i < ARRAYSIZE( rgpszBadNames ); i++ )
{
if( Q_stricmpext( rgpszBadNames[i], name ) )
{
pState->t.fIsTempBanned = true;
break;
}
}
return anonymous_list = pState;
}
@ -883,6 +1148,7 @@ struct GGMPlayerState *GGM_GetState( const char *uid, const char *name )
void GGM_ServerActivate( void )
{
COOP_ServerActivate();
GGM_ClearVote();
}
void GGM_SavePosition( CBasePlayer *pPlayer, struct GGMPosition *pos )
@ -1290,6 +1556,9 @@ void GGM_Register( CBasePlayer *pPlayer, const char *name, const char *password
if( !pPlayer || !pPlayer->m_ggm.pState )
return;
if( pPlayer->m_ggm.pState->t.fIsTempBanned )
return;
if( pPlayer->m_ggm.pState->fRegistered )
{
GGM_ChatPrintf( pPlayer, "Cannot register, when logged in\n" );
@ -2059,6 +2328,8 @@ bool GGM_ClientCommand( CBasePlayer *pPlayer, const char *pCmd )
return true;
else if( GGM_TouchCommand( pPlayer, pCmd ) )
return true;
else if( GGM_VoteProcess( pPlayer, pCmd ) )
return true;
else if( FStrEq(pCmd, "dumpprops") )
{
if ( g_flWeaponCheat != 0.0 )
@ -2266,6 +2537,8 @@ void GGM_RegisterCVars( void )
g_engfuncs.pfnAddServerCommand( "loadplayers", GGM_LoadPlayers_f );
g_engfuncs.pfnAddServerCommand( "ggm_save", GGM_Save_f );
g_engfuncs.pfnAddServerCommand( "ggm_load", GGM_Load_f );
g_engfuncs.pfnAddServerCommand( "ggm_votecommand", GGM_VoteCommand_f );
zombietime = CVAR_GET_POINTER("zombietime");

View File

@ -152,6 +152,7 @@ struct GGMTempState
int rgszAmmo[MAX_AMMO_SLOTS];// ammo quantities
char szWeaponName[32];
GGMPosition pos;
bool fIsTempBanned; // prevent some actions
};
struct GGMPlayerState
@ -193,5 +194,10 @@ void COOP_SetupLandmarkTransition( const char *szNextMap, const char *szNextSpot
void GGM_ClearLists( void );
void GGM_Save( const char *savename );
void GGM_Load( const char *savename );
const char *GGM_PlayerName( CBaseEntity *pPlayer );
bool GGM_IsTempBanned( CBaseEntity *plr );
void GGM_TempBan( CBaseEntity *pEnt );
int GGM_ChangelevelVote( CBasePlayer *pPlayer, edict_t *pTrigger, const char *pszMapName );
void GGM_ClearVote( void );
#endif // GRAVGUNMOD_H

View File

@ -1603,7 +1603,7 @@ void CChangeLevel::ChangeLevelNow( CBaseEntity *pActivator )
CBaseEntity *plr = UTIL_PlayerByIndex( i );
CBaseEntity *pTrain = UTIL_CoopGetPlayerTrain( plr );
if( !pTrain && UTIL_CoopIsBadPlayer( plr ) )
if( !pTrain && GGM_IsTempBanned( plr ) )
continue;
// count only players spawned more 30 seconds ago
@ -1655,7 +1655,7 @@ void CChangeLevel::ChangeLevelNow( CBaseEntity *pActivator )
if( i )
UTIL_CoopPrintMessage(
"%s touched end of map\nnext is %s %s, %d to go\n",
UTIL_CoopPlayerName( pActivator ),
GGM_PlayerName( pActivator ),
st_szNextMap, st_szNextSpot, i );
if( count2 )
{
@ -1666,7 +1666,7 @@ void CChangeLevel::ChangeLevelNow( CBaseEntity *pActivator )
pev->rendercolor.y = 255 - pev->rendercolor.x;
}
ALERT( at_console, "^3CHANGELEVEL:^7 %d %d\n", count2, count1 );
//ALERT( at_console, "^3CHANGELEVEL:^7 %d %d\n", count2, count1 );
if( !m_coopData.fIsBack && count1 > 1 && count1 < count2 / 3 )
return;
@ -1748,7 +1748,7 @@ void CChangeLevel::ChangeLevelNow( CBaseEntity *pActivator )
}
UTIL_CoopPrintMessage( "%s^7 activated changelevel, spawncheck is %d\n", UTIL_CoopPlayerName( pPlayer ), (int)!m_coopData.fSkipSpawnCheck );
UTIL_CoopPrintMessage( "%s^7 activated changelevel, spawncheck is %d\n", GGM_PlayerName( pPlayer ), (int)!m_coopData.fSkipSpawnCheck );
// This object will get removed in the call to CHANGE_LEVEL, copy the params into "safe" memory
strcpy( st_szNextMap, m_szMapName );
@ -1790,7 +1790,7 @@ void CChangeLevel::ChangeLevelNow( CBaseEntity *pActivator )
//ALERT( at_console, "Level touches %d levels\n", ChangeList( levels, 16 ) );
ALERT( at_console, "CHANGE LEVEL: %s %s\n", st_szNextMap, st_szNextSpot );
COOP_ResetVote();
GGM_ClearVote();
// loop through all clients, reset state
if( mp_coop.value )
{