q2wf-portable/zbotcheck.c

110 lines
3.4 KiB
C
Raw Normal View History

/*============================================================================
ZbotCheck v1.01 for Quake 2 by Matt "WhiteFang" Ayres (matt@lithium.com)
This is provided for mod authors to implement Zbot detection, nothing more.
The code has so far proven to be reliable at detecting Zbot auto-aim clients
(cheaters). However, no guarantees of any kind are made. This is provided
as-is. You must be familiar with Quake 2 mod coding to make use of this.
In g_local.h, add to struct client_respawn_t:
short angles[2][2];
int tog;
int jitter;
float jitter_time;
float jitter_last;
Next, in p_client.c, add a simple forward declaration:
qboolean ZbotCheck(edict_t *ent, usercmd_t *ucmd);
Then in p_client.c, anywhere in the ClientThink function, call the
ZbotCheck function. Pass it the same parameters you get from ClientThink.
It will return true if the client is using a Zbot. Simple example:
if(ZbotCheck(ent, ucmd))
gi.bprintf(PRINT_HIGH, ">>> Zbot detected: %s\n",
ent->client->pers.netname);
2024-09-02 07:12:54 -04:00
//Acrid in clientconnect amd client think
added code so they cant move in client thing and clear zbot flag for players connecting
and assuming the old zbot players data
From here you can do as you please with the cheater. ZbotCheck will only
return true once, following returns will be false.
============================================================================*/
2024-09-02 07:12:54 -04:00
//#include "environ.h"
#include "g_local.h"
#define ZBOT_JITTERMAX 4
#define ZBOT_JITTERTIME 10
#define ZBOT_JITTERMOVE 500
//Set this player as a zbot, and mess with them
//This is to help solve problem where you can't actually kick them off server
void I_AM_A_ZBOT(edict_t *ent)
{
//stuffcmd(ent, "disconnect\n"); // kick out zbots.
//Really mess them up
2024-09-02 07:12:54 -04:00
// ent->movetype = MOVETYPE_NOCLIP;//9/99 not good either
//9/99 feign bug? ent->client->pers.feign = 1; nono they can get out with unfeign and play still9/99
ent->client->pers.i_am_a_bot = 1;
VectorClear (ent->avelocity);
ent->takedamage = DAMAGE_YES;
ent->s.modelindex2 = 0; // remove linked weapon model
ent->s.angles[0] = 0;
ent->s.angles[2] = 0;
ent->s.sound = 0;
ent->client->weapon_sound = 0;
ent->maxs[2] = -8;
ent->viewheight = 0;
ent->flags |= FL_NO_KNOCKBACK;
2024-09-02 07:12:54 -04:00
// ent->s.effects |=EF_COLOR_SHELL;//9/99
// ent->s.renderfx |= RF_SHELL_RED;//9/99
// stop running/footsteps
VectorClear (ent->velocity);
//dont keep firing/no model to fire/model removed from player view
ent->client->pers.lastweapon = ent->client->pers.weapon;
ent->client->pers.weapon = NULL;// needed?
ent->client->ps.gunindex = 0;
}
2024-09-02 07:12:54 -04:00
qboolean ZbotCheck(edict_t *ent, usercmd_t *ucmd)
{
int tog0, tog1;
client_respawn_t *resp = &ent->client->resp;
tog0 = resp->tog;
resp->tog ^= 1;
tog1 = resp->tog;
if(ucmd->angles[0] == resp->angles[tog1][0] &&
ucmd->angles[1] == resp->angles[tog1][1] &&
ucmd->angles[0] != resp->angles[tog0][0] &&
ucmd->angles[1] != resp->angles[tog0][1] &&
abs(ucmd->angles[0] - resp->angles[tog0][0]) +
abs(ucmd->angles[1] - resp->angles[tog0][1]) >= ZBOT_JITTERMOVE) {
if(level.time <= resp->jitter_last + 0.1) {
if(!resp->jitter)
resp->jitter_time = level.time;
if(++resp->jitter == ZBOT_JITTERMAX)
return true;
}
resp->jitter_last = level.time;
}
resp->angles[tog1][0] = ucmd->angles[0];
resp->angles[tog1][1] = ucmd->angles[1];
if(level.time > resp->jitter_time + ZBOT_JITTERTIME)
resp->jitter = 0;
return false;
}