Quake II RTX doxygen  1.0 dev
ac.c File Reference
#include "server.h"

Go to the source code of this file.

Classes

struct  ac_file_s
 
struct  ac_cvar_s
 
struct  ac_locals_t
 
struct  ac_static_t
 
struct  ac_cvarop_t
 

Macros

#define ACP_BLOCKPLAY   (1 << 0)
 
#define ACH_REQUIRED   (1 << 0)
 
#define ACH_NEGATIVE   (1 << 1)
 
#define AC_PROTOCOL_VERSION   0xAC03
 
#define AC_DEFAULT_BACKOFF   30
 
#define AC_PING_INTERVAL   60000
 
#define AC_PING_TIMEOUT   15000
 
#define AC_MESSAGE   "\220\xe1\xee\xf4\xe9\xe3\xe8\xe5\xe1\xf4\221 "
 
#define AC_SEND_SIZE   131072
 
#define AC_RECV_SIZE   1024
 
#define AC_HASHES_NAME   "anticheat-hashes.txt"
 
#define AC_CVARS_NAME   "anticheat-cvars.txt"
 
#define AC_TOKENS_NAME   "anticheat-tokens.txt"
 
#define AC_MAX_INCLUDES   16
 

Typedefs

typedef struct ac_file_s ac_file_t
 
typedef struct ac_cvar_s ac_cvar_t
 
typedef void(* ac_parse_t) (char *, int, const char *)
 

Enumerations

enum  ac_serverbyte_t {
  ACS_BAD, ACS_CLIENTACK, ACS_VIOLATION, ACS_NOACCESS,
  ACS_FILE_VIOLATION, ACS_READY, ACS_QUERYREPLY, ACS_PONG,
  ACS_UPDATE_REQUIRED, ACS_DISCONNECT, ACS_ERROR
}
 
enum  ac_clientbyte_t {
  ACC_BAD, ACC_VERSION, ACC_PREF, ACC_REQUESTCHALLENGE,
  ACC_CLIENTDISCONNECT, ACC_QUERYCLIENT, ACC_PING, ACC_UPDATECHECKS,
  ACC_SETPREFERENCES
}
 
enum  ac_opcode_t {
  OP_INVALID, OP_EQUAL, OP_NEQUAL, OP_GTEQUAL,
  OP_LTEQUAL, OP_LT, OP_GT, OP_STREQUAL,
  OP_STRNEQUAL, OP_STRSTR
}
 
enum  ac_client_t {
  AC_CLIENT_R1Q2 = 0x01, AC_CLIENT_EGL = 0x02, AC_CLIENT_APRGL = 0x04, AC_CLIENT_APRSW = 0x08,
  AC_CLIENT_Q2PRO = 0x10
}
 

Functions

static LIST_DECL (ac_required_list)
 
static LIST_DECL (ac_exempt_list)
 
static char * AC_SimpleParse (char **data_p, size_t *len_p)
 
static void AC_ParseHash (char *data, int linenum, const char *path)
 
static void AC_ParseCvar (char *data, int linenum, const char *path)
 
static void AC_ParseToken (char *data, int linenum, const char *path)
 
static qboolean AC_ParseFile (const char *path, ac_parse_t parse, int depth)
 
static void AC_LoadChecks (void)
 
static void AC_FreeChecks (void)
 
static void AC_Retry (void)
 
static void AC_Drop (void)
 
static void AC_Disable (void)
 
static void AC_Announce (client_t *client, const char *fmt,...)
 
static client_tAC_ParseClient (void)
 
static void AC_ParseViolation (void)
 
static void AC_ParseClientAck (void)
 
static void AC_ParseFileViolation (void)
 
static void AC_ParseReady (void)
 
static void AC_ParseQueryReply (void)
 
static void AC_ParseDisconnect (void)
 
static void AC_ParseError (void)
 
static qboolean AC_ParseMessage (void)
 
static void AC_Write (const char *func)
 
static void AC_ClientQuery (client_t *cl)
 
qboolean AC_ClientBegin (client_t *cl)
 
void AC_ClientAnnounce (client_t *cl)
 
char * AC_ClientConnect (client_t *cl)
 
void AC_ClientDisconnect (client_t *cl)
 
void AC_ClientToken (client_t *cl, const char *token)
 
static void AC_Spin (void)
 
static qboolean AC_Flush (void)
 
static void AC_WriteString (const char *s)
 
static void AC_SendChecks (void)
 
static void AC_SendPrefs (void)
 
static void AC_SendPing (void)
 
static void AC_SendHello (void)
 
static void AC_CheckTimeouts (void)
 
static qboolean AC_Reconnect (void)
 
void AC_Run (void)
 
void AC_Connect (unsigned mvd_spawn)
 
void AC_Disconnect (void)
 
void AC_List_f (void)
 
void AC_Info_f (void)
 
static void AC_Invalidate_f (void)
 
static void AC_Update_f (void)
 
static void AC_AddException_f (void)
 
static void AC_DelException_f (void)
 
static void AC_ListExceptions_f (void)
 
static void AC_AddRequirement_f (void)
 
static void AC_DelRequirement_f (void)
 
static void AC_ListRequirements_f (void)
 
static void ac_disable_play_changed (cvar_t *self)
 
void AC_Register (void)
 

Variables

static ac_locals_t ac
 
static ac_static_t acs
 
static byte ac_send_buffer [AC_SEND_SIZE]
 
static byte ac_recv_buffer [AC_RECV_SIZE]
 
static cvar_t * ac_required
 
static cvar_t * ac_server_address
 
static cvar_t * ac_error_action
 
static cvar_t * ac_message
 
static cvar_t * ac_badfile_action
 
static cvar_t * ac_badfile_message
 
static cvar_t * ac_badfile_max
 
static cvar_t * ac_show_violation_reason
 
static cvar_t * ac_client_disconnect_action
 
static cvar_t * ac_disable_play
 
static const char ac_clients [][8]
 
static const int ac_num_clients = q_countof(ac_clients)
 
static const ac_cvarop_t ac_cvarops []
 
static const cmdreg_t c_ac []
 

Macro Definition Documentation

◆ AC_CVARS_NAME

#define AC_CVARS_NAME   "anticheat-cvars.txt"

Definition at line 169 of file ac.c.

◆ AC_DEFAULT_BACKOFF

#define AC_DEFAULT_BACKOFF   30

Definition at line 118 of file ac.c.

◆ AC_HASHES_NAME

#define AC_HASHES_NAME   "anticheat-hashes.txt"

Definition at line 168 of file ac.c.

◆ AC_MAX_INCLUDES

#define AC_MAX_INCLUDES   16

Definition at line 172 of file ac.c.

◆ AC_MESSAGE

#define AC_MESSAGE   "\220\xe1\xee\xf4\xe9\xe3\xe8\xe5\xe1\xf4\221 "

Definition at line 123 of file ac.c.

◆ AC_PING_INTERVAL

#define AC_PING_INTERVAL   60000

Definition at line 120 of file ac.c.

◆ AC_PING_TIMEOUT

#define AC_PING_TIMEOUT   15000

Definition at line 121 of file ac.c.

◆ AC_PROTOCOL_VERSION

#define AC_PROTOCOL_VERSION   0xAC03

Definition at line 116 of file ac.c.

◆ AC_RECV_SIZE

#define AC_RECV_SIZE   1024

Definition at line 126 of file ac.c.

◆ AC_SEND_SIZE

#define AC_SEND_SIZE   131072

Definition at line 125 of file ac.c.

◆ AC_TOKENS_NAME

#define AC_TOKENS_NAME   "anticheat-tokens.txt"

Definition at line 170 of file ac.c.

◆ ACH_NEGATIVE

#define ACH_NEGATIVE   (1 << 1)

Definition at line 114 of file ac.c.

◆ ACH_REQUIRED

#define ACH_REQUIRED   (1 << 0)

Definition at line 113 of file ac.c.

◆ ACP_BLOCKPLAY

#define ACP_BLOCKPLAY   (1 << 0)

Definition at line 111 of file ac.c.

Typedef Documentation

◆ ac_cvar_t

typedef struct ac_cvar_s ac_cvar_t

◆ ac_file_t

typedef struct ac_file_s ac_file_t

◆ ac_parse_t

typedef void(* ac_parse_t) (char *, int, const char *)

Definition at line 174 of file ac.c.

Enumeration Type Documentation

◆ ac_client_t

Enumerator
AC_CLIENT_R1Q2 
AC_CLIENT_EGL 
AC_CLIENT_APRGL 
AC_CLIENT_APRSW 
AC_CLIENT_Q2PRO 

Definition at line 64 of file ac.c.

64  {
65  AC_CLIENT_R1Q2 = 0x01,
66  AC_CLIENT_EGL = 0x02,
67  AC_CLIENT_APRGL = 0x04,
68  AC_CLIENT_APRSW = 0x08,
69  AC_CLIENT_Q2PRO = 0x10
70 } ac_client_t;

◆ ac_clientbyte_t

Enumerator
ACC_BAD 
ACC_VERSION 
ACC_PREF 
ACC_REQUESTCHALLENGE 
ACC_CLIENTDISCONNECT 
ACC_QUERYCLIENT 
ACC_PING 
ACC_UPDATECHECKS 
ACC_SETPREFERENCES 

Definition at line 39 of file ac.c.

◆ ac_opcode_t

Enumerator
OP_INVALID 
OP_EQUAL 
OP_NEQUAL 
OP_GTEQUAL 
OP_LTEQUAL 
OP_LT 
OP_GT 
OP_STREQUAL 
OP_STRNEQUAL 
OP_STRSTR 

Definition at line 51 of file ac.c.

51  {
52  OP_INVALID,
53  OP_EQUAL,
54  OP_NEQUAL,
55  OP_GTEQUAL,
56  OP_LTEQUAL,
57  OP_LT,
58  OP_GT,
61  OP_STRSTR
62 } ac_opcode_t;

◆ ac_serverbyte_t

Enumerator
ACS_BAD 
ACS_CLIENTACK 
ACS_VIOLATION 
ACS_NOACCESS 
ACS_FILE_VIOLATION 
ACS_READY 
ACS_QUERYREPLY 
ACS_PONG 
ACS_UPDATE_REQUIRED 
ACS_DISCONNECT 
ACS_ERROR 

Definition at line 25 of file ac.c.

Function Documentation

◆ AC_AddException_f()

static void AC_AddException_f ( void  )
static

Definition at line 1671 of file ac.c.

1672 {
1673  SV_AddMatch_f(&ac_exempt_list);
1674 }

◆ AC_AddRequirement_f()

static void AC_AddRequirement_f ( void  )
static

Definition at line 1684 of file ac.c.

1685 {
1686  SV_AddMatch_f(&ac_required_list);
1687 }

◆ AC_Announce()

static void AC_Announce ( client_t client,
const char *  fmt,
  ... 
)
static

Definition at line 571 of file ac.c.

572 {
573  va_list argptr;
574  char string[MAX_STRING_CHARS];
575  size_t len;
576 
577  va_start(argptr, fmt);
578  len = Q_vsnprintf(string, sizeof(string), fmt, argptr);
579  va_end(argptr);
580 
581  if (len >= sizeof(string)) {
582  Com_WPrintf("%s: overflow\n", __func__);
583  return;
584  }
585 
586  MSG_WriteByte(svc_print);
587  MSG_WriteByte(PRINT_HIGH);
588  MSG_WriteData(AC_MESSAGE, sizeof(AC_MESSAGE) - 1);
589  MSG_WriteData(string, len + 1);
590 
591  if (client->state == cs_spawned) {
592  FOR_EACH_CLIENT(client) {
593  if (client->state == cs_spawned) {
595  }
596  }
597  } else {
599  }
600 
602 }

Referenced by AC_ParseFileViolation(), and AC_ParseViolation().

◆ AC_CheckTimeouts()

static void AC_CheckTimeouts ( void  )
static

Definition at line 1323 of file ac.c.

1324 {
1325  client_t *cl;
1326 
1327  if (ac.ping_pending) {
1329  Com_Printf("ANTICHEAT: Server ping timeout, disconnecting.\n");
1330  AC_Drop();
1331  return;
1332  }
1333  } else if (ac.ready) {
1335  AC_SendPing();
1336  }
1337  }
1338 
1339  FOR_EACH_CLIENT(cl) {
1340  if (cl->state < cs_connected || cl->state > cs_primed) {
1341  continue;
1342  }
1343  if (cl->ac_query_sent != AC_QUERY_SENT) {
1344  continue;
1345  }
1346  if (svs.realtime - cl->ac_query_time > 5000) {
1347  Com_WPrintf("ANTICHEAT: Query timed out for %s, possible network problem.\n", cl->name);
1348  cl->ac_valid = qfalse;
1349  sv_client = cl;
1350  sv_player = cl->edict;
1351  SV_Begin_f();
1352  sv_client = NULL;
1353  sv_player = NULL;
1354  }
1355  }
1356 }

Referenced by AC_Run().

◆ AC_ClientAnnounce()

void AC_ClientAnnounce ( client_t cl)

Definition at line 1070 of file ac.c.

1071 {
1072  if (!ac_required->integer) {
1073  return; // anticheat is not in use
1074  }
1075  if (cl->state <= cs_zombie) {
1076  return;
1077  }
1078  if (cl->ac_required == AC_EXEMPT) {
1079  SV_BroadcastPrintf(PRINT_MEDIUM, AC_MESSAGE
1080  "%s is exempt from using anticheat.\n", cl->name);
1081  } else if (cl->ac_valid) {
1082  if (cl->ac_file_failures) {
1083  SV_BroadcastPrintf(PRINT_MEDIUM, AC_MESSAGE
1084  "%s failed %d file check%s.\n",
1085  cl->name, cl->ac_file_failures,
1086  cl->ac_file_failures == 1 ? "" : "s");
1087  }
1088  } else {
1089  SV_BroadcastPrintf(PRINT_MEDIUM, AC_MESSAGE
1090  "%s is not using anticheat.\n", cl->name);
1091  }
1092 }

Referenced by SV_Begin_f().

◆ AC_ClientBegin()

qboolean AC_ClientBegin ( client_t cl)

Definition at line 1020 of file ac.c.

1021 {
1022  if (!ac_required->integer) {
1023  return qtrue; // anticheat is not in use
1024  }
1025 
1026  if (cl->ac_required == AC_EXEMPT) {
1027  return qtrue; // client is EXEMPT
1028  }
1029 
1030  if (cl->ac_valid) {
1031  return qtrue; // client is VALID
1032  }
1033 
1034  if (cl->ac_query_sent == AC_QUERY_UNSENT && ac.ready) {
1035  AC_ClientQuery(cl);
1036  return qfalse; // not yet QUERIED
1037  }
1038 
1039  if (cl->ac_required != AC_REQUIRED) {
1040  return qtrue; // anticheat is NOT REQUIRED
1041  }
1042 
1043  if (ac.ready) {
1044  // anticheat connection is UP, client is STILL INVALID
1045  // AFTER QUERY, anticheat is REQUIRED
1046  Com_Printf("ANTICHEAT: Rejected connecting client %s[%s], "
1047  "no anticheat response.\n", cl->name,
1048  NET_AdrToString(&cl->netchan->remote_address));
1049  SV_ClientPrintf(cl, PRINT_HIGH, "%s\n", ac_message->string);
1050  SV_DropClient(cl, NULL);
1051  return qfalse;
1052  }
1053 
1054  if (ac_error_action->integer == 0) {
1055  return qtrue; // error action is ALLOW
1056  }
1057 
1058  // anticheat server connection is DOWN, client is INVALID,
1059  // anticheat is REQUIRED, error action is DENY
1060  Com_Printf("ANTICHEAT: Rejected connecting client %s[%s], "
1061  "no connection to anticheat server.\n", cl->name,
1062  NET_AdrToString(&cl->netchan->remote_address));
1063  SV_ClientPrintf(cl, PRINT_HIGH,
1064  "This server is unable to take new connections right now. "
1065  "Please try again later.\n");
1066  SV_DropClient(cl, NULL);
1067  return qfalse;
1068 }

Referenced by SV_Begin_f().

◆ AC_ClientConnect()

char* AC_ClientConnect ( client_t cl)

Definition at line 1094 of file ac.c.

1095 {
1096  if (!ac_required->integer) {
1097  return ""; // anticheat is not in use
1098  }
1099 
1100  if (SV_MatchAddress(&ac_exempt_list, &net_from)) {
1101  cl->ac_required = AC_EXEMPT;
1102  return "";
1103  }
1104 
1105  if (ac_required->integer == 2) {
1106  // anticheat is required for everyone
1107  cl->ac_required = AC_REQUIRED;
1108  } else {
1109  cl->ac_required = AC_NORMAL;
1110  if (SV_MatchAddress(&ac_required_list, &net_from)) {
1111  cl->ac_required = AC_REQUIRED;
1112  }
1113  }
1114 
1115  if (ac.ready && net_from.type == NA_IP) {
1116  MSG_WriteShort(15);
1118  MSG_WriteData(net_from.ip.u8, 4);
1119  MSG_WriteData(&net_from.port, 2);
1120  MSG_WriteLong(cl->number);
1121  MSG_WriteLong(cl->challenge);
1122  AC_Write(__func__);
1123  }
1124 
1125  return " ac=1";
1126 }

Referenced by send_connect_packet().

◆ AC_ClientDisconnect()

void AC_ClientDisconnect ( client_t cl)

Definition at line 1128 of file ac.c.

1129 {
1130  cl->ac_query_sent = AC_QUERY_UNSENT;
1131  cl->ac_valid = qfalse;
1132 
1133  if (!ac.ready)
1134  return;
1135 
1136  MSG_WriteShort(9);
1138  MSG_WriteLong(cl->number);
1139  MSG_WriteLong(cl->challenge);
1140  AC_Write(__func__);
1141 }

Referenced by AC_Invalidate_f(), and SV_DropClient().

◆ AC_ClientQuery()

static void AC_ClientQuery ( client_t cl)
static

Definition at line 1002 of file ac.c.

1003 {
1004  cl->ac_query_sent = AC_QUERY_SENT;
1005  cl->ac_query_time = svs.realtime;
1006 
1007  if (!ac.ready)
1008  return;
1009 
1010  //if (ac_nag_time->integer)
1011  // cl->anticheat_nag_time = svs.realtime;
1012 
1013  MSG_WriteShort(9);
1015  MSG_WriteLong(cl->number);
1016  MSG_WriteLong(cl->challenge);
1017  AC_Write(__func__);
1018 }

Referenced by AC_ClientBegin().

◆ AC_ClientToken()

void AC_ClientToken ( client_t cl,
const char *  token 
)

Definition at line 1143 of file ac.c.

1144 {
1145  string_entry_t *tok;
1146  client_t *other;
1147 
1148  if (!ac_required->integer) {
1149  return; // anticheat is not in use
1150  }
1151 
1152  for (tok = acs.tokens; tok; tok = tok->next) {
1153  if (!strcmp(tok->string, token)) {
1154  break;
1155  }
1156  }
1157 
1158  if (!tok) {
1159  return;
1160  }
1161 
1163  // FIXME: after `svacupdate' this check is incorrect
1164  if (other->ac_token == tok->string) {
1165  SV_DropClient(other, "duplicate anticheat token");
1166  }
1167  }
1168 
1169  Com_Printf(
1170  "ANTICHEAT: %s bypassed anticheat requirements with token '%s'\n",
1171  cl->name, tok->string);
1172  cl->ac_token = tok->string;
1173  cl->ac_required = AC_EXEMPT;
1174 }

Referenced by SV_CvarResult_f().

◆ AC_Connect()

void AC_Connect ( unsigned  mvd_spawn)

Definition at line 1437 of file ac.c.

1438 {
1439  int attempts;
1440 
1441  if (!ac_required->integer) {
1442  return;
1443  }
1444 
1445 #if USE_CLIENT
1446  if (!dedicated->integer) {
1447  Com_Printf("ANTICHEAT: Only supported on dedicated servers, disabling.\n");
1448  Cvar_SetByVar(ac_required, "0", FROM_CODE);
1449  return;
1450  }
1451 #endif
1452  if (mvd_spawn) {
1453  Com_Printf("ANTICHEAT: Only supported on game servers, disabling.\n");
1454  Cvar_SetByVar(ac_required, "0", FROM_CODE);
1455  return;
1456  }
1457 
1458  AC_LoadChecks();
1459 
1460  Com_Printf("ANTICHEAT: Attempting to connect to %s...\n", ac_server_address->string);
1461  Sys_RunConsole();
1462 
1464  if (!AC_Reconnect()) {
1465  return;
1466  }
1467 
1468  // synchronize startup
1469  for (attempts = 0; attempts < 50; attempts++) {
1470  AC_Spin();
1471  if (ac.ready || !ac.stream.state) {
1472  return;
1473  }
1474  }
1475 
1476  Com_WPrintf("ANTICHEAT: Still not ready, resuming server initialization.\n");
1477 }

Referenced by SV_InitGame().

◆ AC_DelException_f()

static void AC_DelException_f ( void  )
static

Definition at line 1675 of file ac.c.

1676 {
1677  SV_DelMatch_f(&ac_exempt_list);
1678 }

◆ AC_DelRequirement_f()

static void AC_DelRequirement_f ( void  )
static

Definition at line 1688 of file ac.c.

1689 {
1690  SV_DelMatch_f(&ac_required_list);
1691 }

◆ AC_Disable()

static void AC_Disable ( void  )
static

Definition at line 565 of file ac.c.

566 {
567  AC_Disconnect();
568  Cvar_SetByVar(ac_required, "0", FROM_CODE);
569 }

Referenced by AC_ParseError(), and AC_ParseMessage().

◆ ac_disable_play_changed()

static void ac_disable_play_changed ( cvar_t *  self)
static

Definition at line 1714 of file ac.c.

1715 {
1716  if (ac.connected) {
1717  AC_SendPrefs();
1718  }
1719 }

Referenced by AC_Register().

◆ AC_Disconnect()

void AC_Disconnect ( void  )

Definition at line 1479 of file ac.c.

1480 {
1482 
1483  AC_FreeChecks();
1484 
1485  memset(&ac, 0, sizeof(ac));
1486  memset(&acs, 0, sizeof(acs));
1487  Cvar_FullSet("anticheat", "0", CVAR_ROM, FROM_CODE);
1488 }

Referenced by AC_Disable(), and SV_Shutdown().

◆ AC_Drop()

static void AC_Drop ( void  )
static

Definition at line 525 of file ac.c.

526 {
527  client_t *cl;
528 
530 
531  if (!ac.connected) {
532  Com_Printf("ANTICHEAT: Server connection failed.\n");
533  AC_Retry();
534  acs.retry_backoff += 5;
535  return;
536  }
537 
539  cl->ac_valid = qfalse;
540  cl->ac_file_failures = 0;
541  }
542 
543  // inform
544  if (ac.ready) {
545  SV_BroadcastPrintf(PRINT_HIGH, AC_MESSAGE
546  "This server has lost the connection to the anticheat server. "
547  "Any anticheat clients are no longer valid.\n");
548 
549  if (ac_required->integer == 2) {
550  SV_BroadcastPrintf(PRINT_HIGH, AC_MESSAGE
551  "You will need to reconnect once the server has "
552  "re-established the anticheat connection.\n");
553  }
555  } else {
556  acs.retry_backoff += 30; // this generally indicates a server problem
557  }
558 
559  Com_WPrintf("ANTICHEAT: Lost connection to anticheat server!\n");
560  AC_Retry();
561 
562  memset(&ac, 0, sizeof(ac));
563 }

Referenced by AC_CheckTimeouts(), AC_ParseMessage(), and AC_Run().

◆ AC_Flush()

static qboolean AC_Flush ( void  )
static

Definition at line 1196 of file ac.c.

1197 {
1198  byte *src = msg_write.data;
1199  size_t ret, len = msg_write.cursize;
1200 
1201  SZ_Clear(&msg_write);
1202 
1203  if (!ac.connected) {
1204  return qfalse;
1205  }
1206 
1207  while (1) {
1208  ret = FIFO_Write(&ac.stream.send, src, len);
1210 
1211  if (ret == len) {
1212  break;
1213  }
1214 
1215  len -= ret;
1216  src += ret;
1217 
1218  Com_WPrintf("ANTICHEAT: Send buffer length exceeded, "
1219  "server may be frozen for a short while!\n");
1220  do {
1221  AC_Spin();
1222  if (!ac.connected) {
1223  return qfalse;
1224  }
1225  } while (FIFO_Usage(&ac.stream.send) > AC_SEND_SIZE / 2);
1226  }
1227 
1228  return qtrue;
1229 }

Referenced by AC_SendChecks(), AC_SendHello(), AC_SendPing(), and AC_SendPrefs().

◆ AC_FreeChecks()

static void AC_FreeChecks ( void  )
static

Definition at line 476 of file ac.c.

477 {
478  ac_file_t *f, *fn;
479  ac_cvar_t *c, *cn;
480  string_entry_t *t, *tn;
481 
482  for (f = acs.files; f; f = fn) {
483  fn = f->next;
484  Z_Free(f);
485  }
486  acs.files = NULL;
487 
488  for (c = acs.cvars; c; c = cn) {
489  cn = c->next;
490  Z_Free(c);
491  }
492  acs.cvars = NULL;
493 
494  for (t = acs.tokens; t; t = tn) {
495  tn = t->next;
496  Z_Free(t);
497  }
498  acs.tokens = NULL;
499 
500  acs.hashlist_name[0] = 0;
501  acs.num_files = 0;
502  acs.num_cvars = 0;
503 }

Referenced by AC_Disconnect(), and AC_Update_f().

◆ AC_Info_f()

void AC_Info_f ( void  )

Definition at line 1549 of file ac.c.

1550 {
1551  client_t *cl;
1552  string_entry_t *bad;
1553  char *substring, *filesubstring;
1554  int clientID;
1555 
1556  if (!svs.initialized) {
1557  Com_Printf("No server running.\n");
1558  return;
1559  }
1560 
1561  if (!ac_required->integer) {
1562  Com_Printf("The anticheat module is not in use on this server.\n"
1563  "For information on anticheat, please visit http://antiche.at/\n");
1564  return;
1565  }
1566 
1567  if (Cmd_Argc() == 1) {
1568  if (!sv_client) {
1569  Com_Printf("Usage: %s [substring|id] [filesubstring]\n", Cmd_Argv(0));
1570  return;
1571  }
1572  cl = sv_client;
1573  filesubstring = "";
1574  } else {
1575  substring = Cmd_Argv(1);
1576  filesubstring = Cmd_Argv(2);
1577 
1578  if (COM_IsUint(substring)) {
1579  clientID = atoi(substring);
1580  if (clientID < 0 || clientID >= sv_maxclients->integer) {
1581  Com_Printf("Invalid client ID.\n");
1582  return;
1583  }
1584  cl = &svs.client_pool[clientID];
1585  if (cl->state < cs_spawned) {
1586  Com_Printf("Player is not active.\n");
1587  return;
1588  }
1589  } else {
1590  FOR_EACH_CLIENT(cl) {
1591  if (cl->state < cs_spawned) {
1592  continue;
1593  }
1594  if (strstr(cl->name, substring)) {
1595  goto found;
1596  }
1597  }
1598  Com_Printf("Player not found.\n");
1599  return;
1600  }
1601  }
1602 
1603 found:
1604  if (!cl->ac_valid) {
1605  Com_Printf("%s is not using anticheat.\n", cl->name);
1606  return;
1607  }
1608 
1609  if (cl->ac_bad_files) {
1610  Com_Printf("File check failures for %s:\n", cl->name);
1611  for (bad = cl->ac_bad_files; bad; bad = bad->next) {
1612  if (!filesubstring[0] || strstr(bad->string, filesubstring)) {
1613  Com_Printf("%s\n", bad->string);
1614  }
1615  }
1616  } else {
1617  Com_Printf("%s has no file check failures.\n", cl->name);
1618  }
1619 }

Referenced by SV_AC_Info_f().

◆ AC_Invalidate_f()

static void AC_Invalidate_f ( void  )
static

Definition at line 1621 of file ac.c.

1622 {
1623  client_t *cl;
1624 
1625  if (!svs.initialized) {
1626  Com_Printf("No server running.\n");
1627  return;
1628  }
1629  if (!ac.ready) {
1630  Com_Printf("Anticheat is not ready.\n");
1631  return;
1632  }
1633 
1634  FOR_EACH_CLIENT(cl) {
1635  if (cl->state > cs_connected) {
1637  }
1638  }
1639 
1640  Com_Printf("All clients marked as invalid.\n");
1641 }

◆ AC_List_f()

void AC_List_f ( void  )

Definition at line 1490 of file ac.c.

1491 {
1492  client_t *cl;
1493  char *sub;
1494  int i;
1495 
1496  if (!svs.initialized) {
1497  Com_Printf("No server running.\n");
1498  return;
1499  }
1500 
1501  if (!ac_required->integer) {
1502  Com_Printf("The anticheat module is not in use on this server.\n"
1503  "For information on anticheat, please visit http://antiche.at/\n");
1504  return;
1505  }
1506 
1507  sub = Cmd_Argv(1);
1508 
1509  Com_Printf(
1510  "+----------------+--------+-----+------+\n"
1511  "| Player Name |AC Valid|Files|Client|\n"
1512  "+----------------+--------+-----+------+\n");
1513 
1514  FOR_EACH_CLIENT(cl) {
1515  if (cl->state < cs_spawned) {
1516  continue;
1517  }
1518 
1519  if (*sub && !strstr(cl->name, sub)) {
1520  continue;
1521  }
1522 
1523  if (cl->ac_required == AC_EXEMPT) {
1524  Com_Printf("|%-16s| exempt | N/A | N/A |\n", cl->name);
1525  } else if (cl->ac_valid) {
1526  i = cl->ac_client_type;
1527  if (i < 0 || i >= ac_num_clients) {
1528  i = 0;
1529  }
1530  Com_Printf("|%-16s| yes | %3d |%-6s|\n", cl->name,
1531  cl->ac_file_failures, ac_clients[i]);
1532  } else {
1533  Com_Printf("|%-16s| NO | N/A | N/A |\n", cl->name);
1534  }
1535  }
1536 
1537  Com_Printf("+----------------+--------+-----+------+\n");
1538 
1539  if (ac.ready) {
1540  Com_Printf("File check list in use: %s\n", acs.hashlist_name);
1541  }
1542 
1543  Com_Printf(
1544  "This Quake II server is %sconnected to the anticheat server.\n"
1545  "For information on anticheat, please visit http://antiche.at/\n",
1546  ac.ready ? "" : "NOT ");
1547 }

Referenced by SV_AC_List_f().

◆ AC_ListExceptions_f()

static void AC_ListExceptions_f ( void  )
static

Definition at line 1679 of file ac.c.

1680 {
1681  SV_ListMatches_f(&ac_exempt_list);
1682 }

◆ AC_ListRequirements_f()

static void AC_ListRequirements_f ( void  )
static

Definition at line 1692 of file ac.c.

1693 {
1694  SV_ListMatches_f(&ac_required_list);
1695 }

◆ AC_LoadChecks()

static void AC_LoadChecks ( void  )
static

Definition at line 450 of file ac.c.

451 {
453  Com_Printf("ANTICHEAT: Missing " AC_HASHES_NAME ", "
454  "not using any file checks.\n");
455  strcpy(acs.hashlist_name, "none");
456  } else if (!acs.num_files) {
457  Com_Printf("ANTICHEAT: No file hashes were loaded, "
458  "please check the " AC_HASHES_NAME ".\n");
459  strcpy(acs.hashlist_name, "none");
460  } else if (!acs.hashlist_name[0]) {
461  Q_snprintf(acs.hashlist_name, MAX_QPATH, "unknown (%d %s)",
462  acs.num_files, acs.num_files == 1 ? "entry" : "entries");
463  }
464 
466  Com_Printf("ANTICHEAT: Missing " AC_CVARS_NAME ", "
467  "not using any cvar checks.\n");
468  } else if (!acs.num_cvars) {
469  Com_Printf("ANTICHEAT: No cvar checks were loaded, "
470  "please check the " AC_CVARS_NAME ".\n");
471  }
472 
473  AC_ParseFile("anticheat-tokens.txt", AC_ParseToken, 0);
474 }

Referenced by AC_Connect(), and AC_Update_f().

◆ AC_ParseClient()

static client_t* AC_ParseClient ( void  )
static

Definition at line 604 of file ac.c.

605 {
606  client_t *cl;
607  unsigned clientID;
608  unsigned challenge;
609 
610  if (msg_read.readcount + 6 > msg_read.cursize) {
611  Com_DPrintf("ANTICHEAT: Message too short in %s\n", __func__);
612  return NULL;
613  }
614 
615  clientID = MSG_ReadWord();
616  challenge = MSG_ReadLong();
617 
618  if (clientID >= sv_maxclients->integer) {
619  Com_WPrintf("ANTICHEAT: Illegal client ID: %u\n", clientID);
620  return NULL;
621  }
622 
623  cl = &svs.client_pool[clientID];
624 
625  // we check challenge to ensure we don't get
626  // a race condition if a client reconnects.
627  if (cl->challenge != challenge) {
628  return NULL;
629  }
630 
631  if (cl->state < cs_assigned) {
632  return NULL;
633  }
634 
635  return cl;
636 }

Referenced by AC_ParseClientAck(), AC_ParseDisconnect(), AC_ParseFileViolation(), AC_ParseQueryReply(), and AC_ParseViolation().

◆ AC_ParseClientAck()

static void AC_ParseClientAck ( void  )
static

Definition at line 711 of file ac.c.

712 {
713  client_t *cl;
714 
715  cl = AC_ParseClient();
716  if (!cl) {
717  return;
718  }
719 
720  if (msg_read.readcount + 1 > msg_read.cursize) {
721  Com_DPrintf("ANTICHEAT: Message too short in %s\n", __func__);
722  return;
723  }
724 
725  if (cl->state > cs_primed) {
726  Com_DPrintf("ANTICHEAT: %s with client in state %d\n",
727  __func__, cl->state);
728  return;
729  }
730 
731  Com_DPrintf("ANTICHEAT: %s for %s\n", __func__, cl->name);
732  cl->ac_client_type = MSG_ReadByte();
733  cl->ac_valid = qtrue;
734 }

Referenced by AC_ParseMessage().

◆ AC_ParseCvar()

static void AC_ParseCvar ( char *  data,
int  linenum,
const char *  path 
)
static

Definition at line 288 of file ac.c.

289 {
290  char *values[256], *p;
291  byte lengths[256];
292  char *name, *opstr, *val, *def;
293  size_t len, namelen, vallen, deflen;
294  ac_cvar_t *cvar;
295  const ac_cvarop_t *op;
296  int i, num_values;
297 
298  name = AC_SimpleParse(&data, &namelen);
299  if (!data) {
300  Com_WPrintf("ANTICHEAT: Incomplete line %d in %s\n", linenum, path);
301  return;
302  }
303  opstr = AC_SimpleParse(&data, NULL);
304  if (!data) {
305  Com_WPrintf("ANTICHEAT: Incomplete line %d in %s\n", linenum, path);
306  return;
307  }
308  val = AC_SimpleParse(&data, &vallen);
309  if (!data) {
310  Com_WPrintf("ANTICHEAT: Incomplete line %d in %s\n", linenum, path);
311  return;
312  }
313  def = AC_SimpleParse(&data, &deflen);
314 
315  if (namelen < 1 || namelen >= 64) {
316  Com_WPrintf("ANTICHEAT: Invalid cvar name length on line %d in %s\n", linenum, path);
317  return;
318  }
319  if (deflen < 1 || deflen >= 64) {
320  Com_WPrintf("ANTICHEAT: Invalid default value length on line %d in %s\n", linenum, path);
321  return;
322  }
323 
324  for (op = ac_cvarops; op->str[0]; op++) {
325  if (!strcmp(opstr, op->str)) {
326  break;
327  }
328  }
329  if (!op->str[0]) {
330  Com_WPrintf("ANTICHEAT: Unknown opcode '%s' on line %d in %s\n", opstr, linenum, path);
331  return;
332  }
333 
334  num_values = 0;
335  while (1) {
336  if (num_values == op->max_values) {
337  Com_WPrintf("ANTICHEAT: Too many values for opcode '%s' on line %d in %s\n", opstr, linenum, path);
338  return;
339  }
340  if (!val[0]) {
341  Com_WPrintf("ANTICHEAT: Empty value on line %d in %s\n", linenum, path);
342  return;
343  }
344  p = strchr(val, ',');
345  if (p) {
346  *p = 0;
347  }
348  len = strlen(val);
349  if (len >= 64) {
350  Com_WPrintf("ANTICHEAT: Too long value on line %d in %s\n", linenum, path);
351  return;
352  }
353  values[num_values] = val;
354  lengths[num_values++] = (byte)(len + 1);
355  if (!p) {
356  break;
357  }
358  val = p + 1;
359  }
360 
361  Z_TagReserve(sizeof(*cvar) + num_values * sizeof(char *) +
362  namelen + 1 + deflen + 1 + vallen + 1, TAG_SERVER);
363  cvar = Z_ReservedAlloc(sizeof(*cvar));
364  cvar->values = Z_ReservedAlloc(num_values * sizeof(char *));
365  cvar->name = Z_ReservedAlloc(namelen + 1);
366  memcpy(cvar->name, name, namelen + 1);
367  cvar->def = Z_ReservedAlloc(deflen + 1);
368  memcpy(cvar->def, def, deflen + 1);
369  cvar->num_values = num_values;
370  for (i = 0; i < num_values; i++) {
371  cvar->values[i] = Z_ReservedAlloc(lengths[i]);
372  memcpy(cvar->values[i], values[i], lengths[i]);
373  }
374  cvar->op = op->code;
375  cvar->next = acs.cvars;
376  acs.cvars = cvar;
377  acs.num_cvars++;
378 }

Referenced by AC_LoadChecks().

◆ AC_ParseDisconnect()

static void AC_ParseDisconnect ( void  )
static

Definition at line 875 of file ac.c.

876 {
877  client_t *cl;
878 
879  cl = AC_ParseClient();
880  if (cl) {
881  Com_Printf("ANTICHEAT: Dropping %s, disconnect message.\n", cl->name);
882  SV_DropClient(cl, NULL);
883  }
884 }

Referenced by AC_ParseMessage().

◆ AC_ParseError()

static void AC_ParseError ( void  )
static

Definition at line 886 of file ac.c.

887 {
888  char string[MAX_STRING_CHARS];
889 
890  MSG_ReadString(string, sizeof(string));
891  Com_EPrintf("ANTICHEAT: %s\n", string);
892  AC_Disable();
893 }

Referenced by AC_ParseMessage().

◆ AC_ParseFile()

static qboolean AC_ParseFile ( const char *  path,
ac_parse_t  parse,
int  depth 
)
static

Definition at line 391 of file ac.c.

392 {
393  char *raw, *data, *p;
394  int linenum = 1;
395  qerror_t ret;
396 
397  ret = FS_LoadFile(path, (void **)&raw);
398  if (!raw) {
399  if (ret != Q_ERR_NOENT || depth) {
400  Com_WPrintf("ANTICHEAT: Could not %s %s: %s\n",
401  depth ? "include" : "load", path, Q_ErrorString(ret));
402  }
403  return qfalse;
404  }
405 
406  data = raw;
407  while (*data) {
408  p = strchr(data, '\n');
409  if (p) {
410  if (p > data && *(p - 1) == '\r') {
411  *(p - 1) = 0;
412  }
413  *p = 0;
414  }
415 
416  switch (*data) {
417  case '/':
418  case '#':
419  case 0:
420  break;
421  case '\\':
422  if (!strncmp(data + 1, "include ", 8)) {
423  if (depth == AC_MAX_INCLUDES) {
424  Com_WPrintf("ANTICHEAT: Includes too deeply nested.\n");
425  } else {
426  AC_ParseFile(data + 9, parse, depth + 1);
427  }
428  } else {
429  Com_WPrintf("ANTICHEAT: Unknown directive %s on line %d in %s\n", data + 1, linenum, path);
430  }
431  break;
432  default:
433  parse(data, linenum, path);
434  break;
435  }
436 
437  if (!p) {
438  break;
439  }
440 
441  linenum++;
442  data = p + 1;
443  }
444 
445  FS_FreeFile(raw);
446 
447  return qtrue;
448 }

Referenced by AC_LoadChecks().

◆ AC_ParseFileViolation()

static void AC_ParseFileViolation ( void  )
static

Definition at line 736 of file ac.c.

737 {
738  string_entry_t *bad;
739  client_t *cl;
740  char path[MAX_QPATH];
741  char hash[MAX_QPATH];
742  int action;
743  size_t pathlen;
744  ac_file_t *f;
745 
746  cl = AC_ParseClient();
747  if (!cl) {
748  return;
749  }
750 
751  if (msg_read.readcount + 1 > msg_read.cursize) {
752  Com_DPrintf("ANTICHEAT: Message too short in %s\n", __func__);
753  return;
754  }
755 
756  pathlen = MSG_ReadString(path, sizeof(path));
757  if (pathlen >= sizeof(path)) {
758  Com_WPrintf("ANTICHEAT: Oversize path in %s\n", __func__);
759  pathlen = sizeof(path) - 1;
760  }
761 
762  if (msg_read.readcount < msg_read.cursize) {
763  MSG_ReadString(hash, sizeof(hash));
764  } else {
765  strcpy(hash, "no hash?");
766  }
767 
768  cl->ac_file_failures++;
769 
770  action = ac_badfile_action->integer;
771  for (f = acs.files; f; f = f->next) {
772  if (!strcmp(f->path, path)) {
773  if (f->flags & ACH_REQUIRED) {
774  action = 0;
775  break;
776  }
777  }
778  }
779 
780  Com_Printf("ANTICHEAT FILE VIOLATION: %s[%s] has a modified %s [%s]\n",
781  cl->name, NET_AdrToString(&cl->netchan->remote_address), path, hash);
782  switch (action) {
783  case 0:
784  AC_Announce(cl, "%s was kicked for modified %s\n", cl->name, path);
785  break;
786  case 1:
787  SV_ClientPrintf(cl, PRINT_HIGH, AC_MESSAGE
788  "Your file %s has been modified. "
789  "Please replace it with a known valid copy.\n", path);
790  break;
791  case 2:
792  // spamalicious :)
793  AC_Announce(cl, "%s has a modified %s\n", cl->name, path);
794  break;
795  }
796 
797  // show custom msg
798  if (ac_badfile_message->string[0]) {
799  SV_ClientPrintf(cl, PRINT_HIGH, "%s\n", ac_badfile_message->string);
800  }
801 
802  if (!action) {
803  SV_DropClient(cl, NULL);
804  return;
805  }
806 
807  if (ac_badfile_max->integer > 0 && cl->ac_file_failures > ac_badfile_max->integer) {
808  AC_Announce(cl, "%s was kicked for too many modified files\n", cl->name);
809  SV_DropClient(cl, NULL);
810  return;
811  }
812 
813  bad = SV_Malloc(sizeof(*bad) + pathlen);
814  memcpy(bad->string, path, pathlen + 1);
815  bad->next = cl->ac_bad_files;
816  cl->ac_bad_files = bad;
817 }

Referenced by AC_ParseMessage().

◆ AC_ParseHash()

static void AC_ParseHash ( char *  data,
int  linenum,
const char *  path 
)
static

Definition at line 223 of file ac.c.

224 {
225  char *pstr, *hstr;
226  size_t pathlen, hashlen;
227  int flags;
228  byte hash[20];
229  ac_file_t *file;
230  int i;
231 
232  if (*data == '!') {
233  Q_strlcpy(acs.hashlist_name, data + 1, sizeof(acs.hashlist_name));
234  return;
235  }
236 
237  pstr = AC_SimpleParse(&data, &pathlen);
238  if (!data) {
239  Com_WPrintf("ANTICHEAT: Incomplete line %d in %s\n", linenum, path);
240  return;
241  }
242  hstr = AC_SimpleParse(&data, &hashlen);
243 
244  if (pathlen < 1 || pathlen >= MAX_QPATH) {
245  Com_WPrintf("ANTICHEAT: Invalid quake path length on line %d in %s\n", linenum, path);
246  return;
247  }
248  if (strchr(pstr, '\\') || !Q_isalnum(pstr[0])) {
249  Com_WPrintf("ANTICHEAT: Malformed quake path on line %d in %s\n", linenum, path);
250  return;
251  }
252 
253  if (hashlen != 40) {
254 badhash:
255  Com_WPrintf("ANTICHEAT: Malformed hash on line %d in %s\n", linenum, path);
256  return;
257  }
258 
259  for (i = 0; i < 20; i++, hstr += 2) {
260  int c1 = Q_charhex(hstr[0]);
261  int c2 = Q_charhex(hstr[1]);
262  if (c1 == -1 || c2 == -1) {
263  goto badhash;
264  }
265  hash[i] = (c1 << 4) | c2;
266  }
267 
268  // parse optional flags
269  flags = 0;
270  if (data) {
271  if (strstr(data, "required")) {
272  flags |= ACH_REQUIRED;
273  }
274  if (strstr(data, "negative")) {
275  flags |= ACH_NEGATIVE;
276  }
277  }
278 
279  file = SV_Malloc(sizeof(*file) + pathlen);
280  memcpy(file->hash, hash, sizeof(file->hash));
281  memcpy(file->path, pstr, pathlen + 1);
282  file->flags = flags;
283  file->next = acs.files;
284  acs.files = file;
285  acs.num_files++;
286 }

Referenced by AC_LoadChecks().

◆ AC_ParseMessage()

static qboolean AC_ParseMessage ( void  )
static

Definition at line 895 of file ac.c.

896 {
897  uint16_t msglen;
898  int cmd;
899 
900  // parse msglen
901  if (!ac.msglen) {
902  if (!FIFO_TryRead(&ac.stream.recv, &msglen, 2)) {
903  return qfalse;
904  }
905  if (!msglen) {
906  return qtrue;
907  }
908  msglen = LittleShort(msglen);
909  if (msglen > AC_RECV_SIZE) {
910  Com_EPrintf("ANTICHEAT: Oversize message: %u bytes\n", msglen);
911  AC_Drop();
912  return qfalse;
913  }
914  ac.msglen = msglen;
915  }
916 
917  // read this message
918  if (!FIFO_ReadMessage(&ac.stream.recv, ac.msglen)) {
919  return qfalse;
920  }
921 
922  ac.msglen = 0;
923 
924  cmd = MSG_ReadByte();
925  switch (cmd) {
926  case ACS_VIOLATION:
928  break;
929  case ACS_CLIENTACK:
931  break;
932  case ACS_FILE_VIOLATION:
934  break;
935  case ACS_READY:
936  AC_ParseReady();
937  break;
938  case ACS_QUERYREPLY:
940  break;
941  case ACS_ERROR:
942  AC_ParseError();
943  return qfalse;
944  case ACS_NOACCESS:
945  Com_WPrintf("ANTICHEAT: You do not have permission to "
946  "use the anticheat server. Anticheat disabled.\n");
947  AC_Disable();
948  return qfalse;
949  case ACS_UPDATE_REQUIRED:
950  Com_WPrintf("ANTICHEAT: The anticheat server is no longer "
951  "compatible with this version of " APPLICATION ". "
952  "Please make sure you are using the latest " APPLICATION " version. "
953  "Anticheat disabled.\n");
954  AC_Disable();
955  return qfalse;
956  case ACS_DISCONNECT:
958  return qfalse;
959  case ACS_PONG:
960  ac.ping_pending = qfalse;
962  break;
963  default:
964  Com_EPrintf("ANTICHEAT: Unknown command byte %d, please make "
965  "sure you are using the latest " APPLICATION " version. "
966  "Anticheat disabled.\n", cmd);
967  AC_Disable();
968  return qfalse;
969  }
970 
971  if (msg_read.readcount > msg_read.cursize) {
972  Com_WPrintf("ANTICHEAT: Read %"PRIz" bytes past end of message %d\n",
973  msg_read.readcount - msg_read.cursize, cmd);
974  }
975 
976  return qtrue;
977 }

Referenced by AC_Run().

◆ AC_ParseQueryReply()

static void AC_ParseQueryReply ( void  )
static

Definition at line 829 of file ac.c.

830 {
831  client_t *cl;
832  int type, valid;
833 
834  cl = AC_ParseClient();
835  if (!cl) {
836  return;
837  }
838 
839  if (msg_read.readcount + 2 > msg_read.cursize) {
840  Com_DPrintf("ANTICHEAT: Message too short in %s\n", __func__);
841  return;
842  }
843 
844  valid = MSG_ReadByte();
845  type = MSG_ReadByte();
846 
847  cl->ac_query_sent = AC_QUERY_DONE;
848  if (valid == 1) {
849  cl->ac_client_type = type;
850  cl->ac_valid = qtrue;
851  }
852 
853  if (cl->state < cs_connected || cl->state > cs_primed) {
854  Com_WPrintf("ANTICHEAT: %s with client in state %d\n",
855  __func__, cl->state);
856  SV_DropClient(cl, NULL);
857  return;
858  }
859 
860  Com_DPrintf("ANTICHEAT: %s for %s\n", __func__, cl->name);
861 
862  // SV_Begin_f will handle possible map change
863  sv_client = cl;
864  sv_player = cl->edict;
865  SV_Begin_f();
866  sv_client = NULL;
867  sv_player = NULL;
868 }

Referenced by AC_ParseMessage().

◆ AC_ParseReady()

static void AC_ParseReady ( void  )
static

Definition at line 819 of file ac.c.

820 {
821  ac.ready = qtrue;
824  Com_Printf("ANTICHEAT: Ready to serve anticheat clients.\n");
825  Cvar_FullSet("anticheat", ac_required->string,
826  CVAR_SERVERINFO | CVAR_ROM, FROM_CODE);
827 }

Referenced by AC_ParseMessage().

◆ AC_ParseToken()

static void AC_ParseToken ( char *  data,
int  linenum,
const char *  path 
)
static

Definition at line 380 of file ac.c.

381 {
382  string_entry_t *tok;
383  size_t len = strlen(data);
384 
385  tok = SV_Malloc(sizeof(*tok) + len);
386  memcpy(tok->string, data, len + 1);
387  tok->next = acs.tokens;
388  acs.tokens = tok;
389 }

Referenced by AC_LoadChecks().

◆ AC_ParseViolation()

static void AC_ParseViolation ( void  )
static

Definition at line 638 of file ac.c.

639 {
640  client_t *cl;
641  char reason[32];
642  char clientreason[64];
643 
644  cl = AC_ParseClient();
645  if (!cl) {
646  return;
647  }
648 
649  if (msg_read.readcount + 1 > msg_read.cursize) {
650  Com_DPrintf("ANTICHEAT: Message too short in %s\n", __func__);
651  return;
652  }
653 
654  MSG_ReadString(reason, sizeof(reason));
655 
656  if (msg_read.readcount < msg_read.cursize) {
657  MSG_ReadString(clientreason, sizeof(clientreason));
658  } else {
659  clientreason[0] = 0;
660  }
661 
662  // FIXME: should we notify other players about anticheat violations
663  // found before clientbegin? one side says yes to expose cheaters,
664  // other side says no since client will have no previous message to
665  // show that they're trying to join. currently showing messages only
666  // for spawned clients.
667 
668  // fixme maybe
669  if (strcmp(reason, "disconnected")) {
670  char showreason[32];
671 
672  if (ac_show_violation_reason->integer)
673  Q_snprintf(showreason, sizeof(showreason), " (%s)", reason);
674  else
675  showreason[0] = 0;
676 
677  AC_Announce(cl, "%s was kicked for anticheat violation%s\n",
678  cl->name, showreason);
679 
680  Com_Printf("ANTICHEAT VIOLATION: %s[%s] was kicked: %s\n",
681  cl->name, NET_AdrToString(&cl->netchan->remote_address), reason);
682 
683  if (clientreason[0])
684  SV_ClientPrintf(cl, PRINT_HIGH, "%s\n", clientreason);
685 
686  // hack to fix late zombies race condition
687  cl->lastmessage = svs.realtime;
688  SV_DropClient(cl, NULL);
689  return;
690  }
691 
692  if (!cl->ac_valid) {
693  return;
694  }
695 
696  Com_Printf("ANTICHEAT DISCONNECT: %s[%s] disconnected from "
697  "anticheat server\n", cl->name,
698  NET_AdrToString(&cl->netchan->remote_address));
699 
700  if (ac_client_disconnect_action->integer == 1) {
701  AC_Announce(cl, "%s lost connection to anticheat server.\n", cl->name);
702  SV_DropClient(cl, NULL);
703  return;
704  }
705 
706  AC_Announce(cl, "%s lost connection to anticheat server, "
707  "client is no longer valid.\n", cl->name);
708  cl->ac_valid = qfalse;
709 }

Referenced by AC_ParseMessage().

◆ AC_Reconnect()

static qboolean AC_Reconnect ( void  )
static

Definition at line 1358 of file ac.c.

1359 {
1360  netadr_t address;
1361 
1362  if (!NET_StringToAdr(ac_server_address->string, &address, PORT_SERVER)) {
1363  Com_WPrintf("ANTICHEAT: Unable to lookup %s.\n",
1364  ac_server_address->string);
1365  goto fail;
1366  }
1367 
1368  if (NET_Connect(&address, &ac.stream) == NET_ERROR) {
1369  Com_EPrintf("ANTICHEAT: %s to %s.\n",
1370  NET_ErrorString(), NET_AdrToString(&address));
1371  goto fail;
1372  }
1373 
1374  ac.stream.send.data = ac_send_buffer;
1375  ac.stream.send.size = AC_SEND_SIZE;
1376  ac.stream.recv.data = ac_recv_buffer;
1377  ac.stream.recv.size = AC_RECV_SIZE;
1378  acs.retry_time = 0;
1379  return qtrue;
1380 
1381 fail:
1382  acs.retry_backoff += 60;
1383  AC_Retry();
1384  return qfalse;
1385 }

Referenced by AC_Connect(), and AC_Run().

◆ AC_Register()

void AC_Register ( void  )

Definition at line 1721 of file ac.c.

1722 {
1723  ac_required = Cvar_Get("sv_anticheat_required", "0", CVAR_LATCH);
1724  ac_server_address = Cvar_Get("sv_anticheat_server_address", "anticheat.r1ch.net", CVAR_LATCH);
1725  ac_error_action = Cvar_Get("sv_anticheat_error_action", "0", 0);
1726  ac_message = Cvar_Get("sv_anticheat_message",
1727  "This server requires the r1ch.net anticheat module. "
1728  "Please see http://antiche.at/ for more details.", 0);
1729  ac_badfile_action = Cvar_Get("sv_anticheat_badfile_action", "0", 0);
1730  ac_badfile_message = Cvar_Get("sv_anticheat_badfile_message", "", 0);
1731  ac_badfile_max = Cvar_Get("sv_anticheat_badfile_max", "0", 0);
1732  ac_show_violation_reason = Cvar_Get("sv_anticheat_show_violation_reason", "0", 0);
1733  ac_client_disconnect_action = Cvar_Get("sv_anticheat_client_disconnect_action", "0", 0);
1734  ac_disable_play = Cvar_Get("sv_anticheat_disable_play", "0", 0);
1736 
1737  Cmd_Register(c_ac);
1738 }

Referenced by SV_Init().

◆ AC_Retry()

static void AC_Retry ( void  )
static

Definition at line 513 of file ac.c.

514 {
515  char buf[MAX_QPATH];
516  time_t clock;
517 
518  Com_FormatTimeLong(buf, sizeof(buf), acs.retry_backoff);
519  Com_Printf("ANTICHEAT: Re%s in %s.\n",
520  ac.connected ? "connecting" : "trying", buf);
521  clock = time(NULL);
522  acs.retry_time = clock + acs.retry_backoff;
523 }

Referenced by AC_Drop(), and AC_Reconnect().

◆ AC_Run()

void AC_Run ( void  )

Definition at line 1388 of file ac.c.

1389 {
1390  neterr_t ret = NET_AGAIN;
1391  time_t clock;
1392 
1393  if (acs.retry_time) {
1394  clock = time(NULL);
1395  if (acs.retry_time < clock) {
1396  Com_Printf("ANTICHEAT: Attempting to reconnect to anticheat server...\n");
1397  AC_Reconnect();
1398  }
1399  return;
1400  }
1401 
1402  if (!ac.stream.state) {
1403  return;
1404  }
1405 
1406  if (!ac.connected) {
1407  ret = NET_RunConnect(&ac.stream);
1408  if (ret == NET_OK) {
1409  Com_Printf("ANTICHEAT: Connected to anticheat server!\n");
1410  ac.connected = qtrue;
1411  AC_SendHello();
1412  }
1413  }
1414 
1415  if (ac.connected) {
1416  ret = NET_RunStream(&ac.stream);
1417  if (ret == NET_OK) {
1418  while (AC_ParseMessage())
1419  ;
1421  }
1422  AC_CheckTimeouts();
1423  }
1424 
1425  switch (ret) {
1426  case NET_ERROR:
1427  Com_EPrintf("ANTICHEAT: %s to %s.\n", NET_ErrorString(),
1428  NET_AdrToString(&ac.stream.address));
1429  case NET_CLOSED:
1430  AC_Drop();
1431  break;
1432  default:
1433  break;
1434  }
1435 }

Referenced by AC_Spin(), and SV_Frame().

◆ AC_SendChecks()

static void AC_SendChecks ( void  )
static

Definition at line 1243 of file ac.c.

1244 {
1245  ac_file_t *f, *p;
1246  ac_cvar_t *c;
1247  int i;
1248 
1249  MSG_WriteShort(9);
1253  AC_Flush();
1254 
1255  for (f = acs.files, p = NULL; f; p = f, f = f->next) {
1256  MSG_WriteData(f->hash, sizeof(f->hash));
1257  MSG_WriteByte(f->flags);
1258  if (p && !strcmp(f->path, p->path)) {
1259  MSG_WriteByte(0);
1260  } else {
1261  AC_WriteString(f->path);
1262  }
1263  AC_Flush();
1264  }
1265 
1266  for (c = acs.cvars; c; c = c->next) {
1267  AC_WriteString(c->name);
1268  MSG_WriteByte(c->op);
1269  MSG_WriteByte(c->num_values);
1270  for (i = 0; i < c->num_values; i++) {
1271  AC_WriteString(c->values[i]);
1272  }
1273  AC_WriteString(c->def);
1274  AC_Flush();
1275  }
1276 }

Referenced by AC_SendHello(), and AC_Update_f().

◆ AC_SendHello()

static void AC_SendHello ( void  )
static

Definition at line 1302 of file ac.c.

1303 {
1304  size_t hostlen = strlen(sv_hostname->string);
1305  size_t verlen = strlen(com_version->string);
1306 
1307  MSG_WriteByte(0x02);
1308  MSG_WriteShort(22 + hostlen + verlen); // why 22 instead of 9?
1311  MSG_WriteShort(hostlen);
1312  MSG_WriteData(sv_hostname->string, hostlen);
1313  MSG_WriteShort(verlen);
1314  MSG_WriteData(com_version->string, verlen);
1315  MSG_WriteLong(net_port->integer);
1316  AC_Flush();
1317 
1318  AC_SendChecks();
1319  AC_SendPrefs();
1320  AC_SendPing();
1321 }

Referenced by AC_Run().

◆ AC_SendPing()

static void AC_SendPing ( void  )
static

Definition at line 1292 of file ac.c.

1293 {
1295  ac.ping_pending = qtrue;
1296 
1297  MSG_WriteShort(1);
1299  AC_Flush();
1300 }

Referenced by AC_CheckTimeouts(), and AC_SendHello().

◆ AC_SendPrefs()

static void AC_SendPrefs ( void  )
static

Definition at line 1278 of file ac.c.

1279 {
1280  int prefs = 0;
1281 
1282  if (ac_disable_play->integer) {
1283  prefs |= ACP_BLOCKPLAY;
1284  }
1285 
1286  MSG_WriteShort(5);
1288  MSG_WriteLong(prefs);
1289  AC_Flush();
1290 }

Referenced by ac_disable_play_changed(), and AC_SendHello().

◆ AC_SimpleParse()

static char* AC_SimpleParse ( char **  data_p,
size_t *  len_p 
)
static

Definition at line 196 of file ac.c.

197 {
198  char *data, *p;
199 
200  data = *data_p;
201  if (!data) {
202  if (len_p) {
203  *len_p = 0;
204  }
205  return NULL;
206  }
207 
208  p = Q_strchrnul(data, '\t');
209  if (*p) {
210  *p = 0;
211  *data_p = p + 1;
212  } else {
213  *data_p = NULL;
214  }
215 
216  if (len_p) {
217  *len_p = p - data;
218  }
219 
220  return data;
221 }

Referenced by AC_ParseCvar(), and AC_ParseHash().

◆ AC_Spin()

static void AC_Spin ( void  )
static

Definition at line 1184 of file ac.c.

1185 {
1186  // sleep on stdin and AC server socket
1187  NET_Sleepv(100,
1188 #ifndef _WIN32
1189  STDIN_FILENO,
1190 #endif
1191  ac.stream.socket, -1);
1192  Sys_RunConsole();
1193  AC_Run();
1194 }

Referenced by AC_Connect(), and AC_Flush().

◆ AC_Update_f()

static void AC_Update_f ( void  )
static

Definition at line 1643 of file ac.c.

1644 {
1645  client_t *cl;
1646 
1647  if (!svs.initialized) {
1648  Com_Printf("No server running.\n");
1649  return;
1650  }
1651  if (!ac_required->integer) {
1652  Com_Printf("Anticheat is not in use.\n");
1653  return;
1654  }
1655 
1656  AC_FreeChecks();
1657  AC_LoadChecks();
1658 
1659  if (ac.connected) {
1660  AC_SendChecks();
1661  }
1662 
1663  // reset all tokens
1664  FOR_EACH_CLIENT(cl) {
1665  cl->ac_token = NULL;
1666  }
1667 
1668  Com_Printf("Anticheat configuration updated.\n");
1669 }

◆ AC_Write()

static void AC_Write ( const char *  func)
static

Definition at line 987 of file ac.c.

988 {
989  byte *src = msg_write.data;
990  size_t len = msg_write.cursize;
991 
993 
994  if (!FIFO_TryWrite(&ac.stream.send, src, len)) {
995  Com_WPrintf("ANTICHEAT: Send buffer exceeded in %s\n", func);
996  return;
997  }
998 
1000 }

Referenced by AC_ClientConnect(), AC_ClientDisconnect(), and AC_ClientQuery().

◆ AC_WriteString()

static void AC_WriteString ( const char *  s)
static

Definition at line 1231 of file ac.c.

1232 {
1233  size_t len = strlen(s);
1234 
1235  if (len > 255) {
1236  len = 255;
1237  }
1238 
1239  MSG_WriteByte(len);
1240  MSG_WriteData(s, len);
1241 }

Referenced by AC_SendChecks().

◆ LIST_DECL() [1/2]

static LIST_DECL ( ac_exempt_list  )
static

◆ LIST_DECL() [2/2]

static LIST_DECL ( ac_required_list  )
static

Variable Documentation

◆ ac

◆ ac_badfile_action

cvar_t* ac_badfile_action
static

Definition at line 141 of file ac.c.

Referenced by AC_ParseFileViolation(), and AC_Register().

◆ ac_badfile_max

cvar_t* ac_badfile_max
static

Definition at line 143 of file ac.c.

Referenced by AC_ParseFileViolation(), and AC_Register().

◆ ac_badfile_message

cvar_t* ac_badfile_message
static

Definition at line 142 of file ac.c.

Referenced by AC_ParseFileViolation(), and AC_Register().

◆ ac_client_disconnect_action

cvar_t* ac_client_disconnect_action
static

Definition at line 145 of file ac.c.

Referenced by AC_ParseViolation(), and AC_Register().

◆ ac_clients

const char ac_clients[][8]
static
Initial value:
= {
"???",
"R1Q2",
"EGL",
"Apr GL",
"Apr SW",
"Q2PRO"
}

Definition at line 148 of file ac.c.

Referenced by AC_List_f().

◆ ac_cvarops

const ac_cvarop_t ac_cvarops[]
static
Initial value:
= {
{ "=", OP_EQUAL, 254 },
{ "==", OP_EQUAL, 254 },
{ "!=", OP_NEQUAL, 254 },
{ ">=", OP_GTEQUAL, 1 },
{ "<=", OP_LTEQUAL, 1 },
{ "<", OP_LT, 1 },
{ ">", OP_GT, 1 },
{ "eq", OP_STREQUAL, 254 },
{ "ne", OP_STRNEQUAL, 254 },
{ "~", OP_STRSTR, 254 },
{ "" }
}

Definition at line 182 of file ac.c.

Referenced by AC_ParseCvar().

◆ ac_disable_play

cvar_t* ac_disable_play
static

Definition at line 146 of file ac.c.

Referenced by AC_Register(), and AC_SendPrefs().

◆ ac_error_action

cvar_t* ac_error_action
static

Definition at line 139 of file ac.c.

Referenced by AC_ClientBegin(), and AC_Register().

◆ ac_message

cvar_t* ac_message
static

Definition at line 140 of file ac.c.

Referenced by AC_ClientBegin(), and AC_Register().

◆ ac_num_clients

const int ac_num_clients = q_countof(ac_clients)
static

Definition at line 157 of file ac.c.

Referenced by AC_List_f().

◆ ac_recv_buffer

byte ac_recv_buffer[AC_RECV_SIZE]
static

Definition at line 135 of file ac.c.

Referenced by AC_Reconnect().

◆ ac_required

◆ ac_send_buffer

byte ac_send_buffer[AC_SEND_SIZE]
static

Definition at line 134 of file ac.c.

Referenced by AC_Reconnect().

◆ ac_server_address

cvar_t* ac_server_address
static

Definition at line 138 of file ac.c.

Referenced by AC_Connect(), AC_Reconnect(), and AC_Register().

◆ ac_show_violation_reason

cvar_t* ac_show_violation_reason
static

Definition at line 144 of file ac.c.

Referenced by AC_ParseViolation(), and AC_Register().

◆ acs

◆ c_ac

const cmdreg_t c_ac[]
static
Initial value:
= {
{ "svaclist", AC_List_f },
{ "svacinfo", AC_Info_f },
{ "svacupdate", AC_Update_f },
{ "svacinvalidate", AC_Invalidate_f },
{ "addacexception", AC_AddException_f },
{ "delacexception", AC_DelException_f },
{ "listacexceptions", AC_ListExceptions_f },
{ "addacrequirement", AC_AddRequirement_f },
{ "delacrequirement", AC_DelRequirement_f },
{ "listacrequirements", AC_ListRequirements_f },
{ NULL }
}

Definition at line 1697 of file ac.c.

Referenced by AC_Register().

ACS_FILE_VIOLATION
@ ACS_FILE_VIOLATION
Definition: ac.c:30
AC_FreeChecks
static void AC_FreeChecks(void)
Definition: ac.c:476
ac_static_t::num_files
int num_files
Definition: ac.c:101
Z_ReservedAlloc
void * Z_ReservedAlloc(size_t size)
Definition: zone.c:349
ac_cvarop_t
Definition: ac.c:176
SV_DelMatch_f
void SV_DelMatch_f(list_t *list)
Definition: commands.c:1119
OP_STRNEQUAL
@ OP_STRNEQUAL
Definition: ac.c:60
AC_ListRequirements_f
static void AC_ListRequirements_f(void)
Definition: ac.c:1692
AC_ListExceptions_f
static void AC_ListExceptions_f(void)
Definition: ac.c:1679
AC_Write
static void AC_Write(const char *func)
Definition: ac.c:987
AC_Reconnect
static qboolean AC_Reconnect(void)
Definition: ac.c:1358
AC_ParseFileViolation
static void AC_ParseFileViolation(void)
Definition: ac.c:736
AC_LoadChecks
static void AC_LoadChecks(void)
Definition: ac.c:450
ACS_READY
@ ACS_READY
Definition: ac.c:31
cs_spawned
@ cs_spawned
Definition: server.h:192
ACC_PREF
@ ACC_PREF
Definition: ac.c:42
ACS_ERROR
@ ACS_ERROR
Definition: ac.c:36
OP_STRSTR
@ OP_STRSTR
Definition: ac.c:61
msg_read
sizebuf_t msg_read
Definition: msg.c:37
NET_Connect
neterr_t NET_Connect(const netadr_t *peer, netstream_t *s)
Definition: net.c:1536
ac_required
static cvar_t * ac_required
Definition: ac.c:137
AC_CLIENT_R1Q2
@ AC_CLIENT_R1Q2
Definition: ac.c:65
svs
server_static_t svs
Definition: init.c:21
NET_AdrToString
char * NET_AdrToString(const netadr_t *a)
Definition: net.c:257
AC_WriteString
static void AC_WriteString(const char *s)
Definition: ac.c:1231
ac_cvar_s::name
char * name
Definition: ac.c:84
AC_Disable
static void AC_Disable(void)
Definition: ac.c:565
ac_static_t::hashlist_name
char hashlist_name[MAX_QPATH]
Definition: ac.c:108
Com_FormatTimeLong
size_t Com_FormatTimeLong(char *buffer, size_t size, time_t t)
Definition: utils.c:408
ac_cvarop_t::code
ac_opcode_t code
Definition: ac.c:178
Q_snprintf
size_t Q_snprintf(char *dest, size_t size, const char *fmt,...)
Definition: shared.c:846
ACS_UPDATE_REQUIRED
@ ACS_UPDATE_REQUIRED
Definition: ac.c:34
ac_cvar_s::op
ac_opcode_t op
Definition: ac.c:83
AC_ParseHash
static void AC_ParseHash(char *data, int linenum, const char *path)
Definition: ac.c:223
AC_MAX_INCLUDES
#define AC_MAX_INCLUDES
Definition: ac.c:172
data_p
static byte * data_p
Definition: mem.c:100
FIFO_ReadMessage
qboolean FIFO_ReadMessage(fifo_t *fifo, size_t msglen)
Definition: fifo.c:89
AC_AddRequirement_f
static void AC_AddRequirement_f(void)
Definition: ac.c:1684
ac
static ac_locals_t ac
Definition: ac.c:128
AC_PING_TIMEOUT
#define AC_PING_TIMEOUT
Definition: ac.c:121
Cvar_Get
cvar_t * Cvar_Get(const char *var_name, const char *var_value, int flags)
Definition: cvar.c:257
Q_ErrorString
const char * Q_ErrorString(qerror_t error)
Definition: error.c:51
client_s::state
clstate_t state
Definition: server.h:260
AC_DEFAULT_BACKOFF
#define AC_DEFAULT_BACKOFF
Definition: ac.c:118
AC_AddException_f
static void AC_AddException_f(void)
Definition: ac.c:1671
MSG_RELIABLE
#define MSG_RELIABLE
Definition: server.h:214
AC_CLIENT_Q2PRO
@ AC_CLIENT_Q2PRO
Definition: ac.c:69
MSG_ReadWord
int MSG_ReadWord(void)
Definition: msg.c:1503
ACC_VERSION
@ ACC_VERSION
Definition: ac.c:41
ACS_PONG
@ ACS_PONG
Definition: ac.c:33
AC_ParseQueryReply
static void AC_ParseQueryReply(void)
Definition: ac.c:829
ACC_SETPREFERENCES
@ ACC_SETPREFERENCES
Definition: ac.c:48
AC_CheckTimeouts
static void AC_CheckTimeouts(void)
Definition: ac.c:1323
NET_UpdateStream
void NET_UpdateStream(netstream_t *s)
Definition: net.c:1628
OP_LTEQUAL
@ OP_LTEQUAL
Definition: ac.c:56
ACS_CLIENTACK
@ ACS_CLIENTACK
Definition: ac.c:27
ACS_QUERYREPLY
@ ACS_QUERYREPLY
Definition: ac.c:32
AC_Drop
static void AC_Drop(void)
Definition: ac.c:525
AC_Flush
static qboolean AC_Flush(void)
Definition: ac.c:1196
ACS_VIOLATION
@ ACS_VIOLATION
Definition: ac.c:28
ac_locals_t::ping_pending
qboolean ping_pending
Definition: ac.c:90
NET_RunConnect
neterr_t NET_RunConnect(netstream_t *s)
Definition: net.c:1581
ACS_DISCONNECT
@ ACS_DISCONNECT
Definition: ac.c:35
ac_server_address
static cvar_t * ac_server_address
Definition: ac.c:138
AC_Retry
static void AC_Retry(void)
Definition: ac.c:513
NET_CloseStream
void NET_CloseStream(netstream_t *s)
Definition: net.c:1371
Q_vsnprintf
size_t Q_vsnprintf(char *dest, size_t size, const char *fmt, va_list argptr)
Definition: shared.c:791
other
@ other
Definition: ogg.c:63
ac_disable_play
static cvar_t * ac_disable_play
Definition: ac.c:146
SV_ListMatches_f
void SV_ListMatches_f(list_t *list)
Definition: commands.c:1176
AC_ParseViolation
static void AC_ParseViolation(void)
Definition: ac.c:638
acs
static ac_static_t acs
Definition: ac.c:129
ac_locals_t::last_ping
unsigned last_ping
Definition: ac.c:91
sv_client
client_t * sv_client
Definition: main.c:32
MSG_WriteByte
void MSG_WriteByte(int c)
Definition: msg.c:107
AC_CLIENT_EGL
@ AC_CLIENT_EGL
Definition: ac.c:66
ACC_PING
@ ACC_PING
Definition: ac.c:46
AC_ParseMessage
static qboolean AC_ParseMessage(void)
Definition: ac.c:895
AC_CLIENT_APRGL
@ AC_CLIENT_APRGL
Definition: ac.c:67
Cmd_Argv
char * Cmd_Argv(int arg)
Definition: cmd.c:899
ACC_CLIENTDISCONNECT
@ ACC_CLIENTDISCONNECT
Definition: ac.c:44
ac_locals_t::msglen
size_t msglen
Definition: ac.c:93
AC_ParseReady
static void AC_ParseReady(void)
Definition: ac.c:819
ac_cvarop_t::max_values
int max_values
Definition: ac.c:179
ACS_BAD
@ ACS_BAD
Definition: ac.c:26
ac_cvarop_t::str
char str[4]
Definition: ac.c:177
Cmd_Argc
int Cmd_Argc(void)
Definition: cmd.c:889
SV_ClientAddMessage
void SV_ClientAddMessage(client_t *client, int flags)
Definition: send.c:399
AC_Update_f
static void AC_Update_f(void)
Definition: ac.c:1643
Q_strchrnul
char * Q_strchrnul(const char *s, int c)
Definition: shared.c:879
net_from
netadr_t net_from
Definition: net.c:90
AC_CLIENT_APRSW
@ AC_CLIENT_APRSW
Definition: ac.c:68
FOR_EACH_CLIENT
#define FOR_EACH_CLIENT(client)
Definition: server.h:239
SV_Malloc
#define SV_Malloc(size)
Definition: server.h:54
AC_DelException_f
static void AC_DelException_f(void)
Definition: ac.c:1675
AC_PING_INTERVAL
#define AC_PING_INTERVAL
Definition: ac.c:120
com_version
cvar_t * com_version
Definition: common.c:84
dedicated
cvar_t * dedicated
Definition: g_main.c:46
AC_ParseFile
static qboolean AC_ParseFile(const char *path, ac_parse_t parse, int depth)
Definition: ac.c:391
ACC_REQUESTCHALLENGE
@ ACC_REQUESTCHALLENGE
Definition: ac.c:43
ac_badfile_action
static cvar_t * ac_badfile_action
Definition: ac.c:141
msg_write
sizebuf_t msg_write
Definition: msg.c:34
NET_ErrorString
const char * NET_ErrorString(void)
Definition: net.c:659
OP_GTEQUAL
@ OP_GTEQUAL
Definition: ac.c:55
net_port
cvar_t * net_port
Definition: net.c:88
ac_file_s::next
struct ac_file_s * next
Definition: ac.c:73
ac_locals_t::ready
qboolean ready
Definition: ac.c:89
Z_Free
void Z_Free(void *ptr)
Definition: zone.c:147
server_static_s::client_pool
client_t * client_pool
Definition: server.h:456
ac_static_t::files
ac_file_t * files
Definition: ac.c:100
AC_PROTOCOL_VERSION
#define AC_PROTOCOL_VERSION
Definition: ac.c:116
server_static_s::initialized
qboolean initialized
Definition: server.h:453
ac_locals_t::connected
qboolean connected
Definition: ac.c:88
ac_message
static cvar_t * ac_message
Definition: ac.c:140
Cmd_Register
void Cmd_Register(const cmdreg_t *reg)
Definition: cmd.c:1572
MSG_ReadLong
int MSG_ReadLong(void)
Definition: msg.c:1517
cs_zombie
@ cs_zombie
Definition: server.h:187
ac_static_t::num_cvars
int num_cvars
Definition: ac.c:104
ac_file_s::hash
byte hash[20]
Definition: ac.c:74
ac_static_t::tokens
string_entry_t * tokens
Definition: ac.c:106
AC_ParseError
static void AC_ParseError(void)
Definition: ac.c:886
AC_CVARS_NAME
#define AC_CVARS_NAME
Definition: ac.c:169
NET_StringToAdr
qboolean NET_StringToAdr(const char *s, netadr_t *a, int default_port)
Definition: net.c:332
ACP_BLOCKPLAY
#define ACP_BLOCKPLAY
Definition: ac.c:111
Cvar_SetByVar
void Cvar_SetByVar(cvar_t *var, const char *value, from_t from)
Definition: cvar.c:345
AC_ParseDisconnect
static void AC_ParseDisconnect(void)
Definition: ac.c:875
Q_strlcpy
size_t Q_strlcpy(char *dst, const char *src, size_t size)
Definition: shared.c:715
OP_LT
@ OP_LT
Definition: ac.c:57
AC_SendPing
static void AC_SendPing(void)
Definition: ac.c:1292
MSG_WriteShort
void MSG_WriteShort(int c)
Definition: msg.c:125
SV_DropClient
void SV_DropClient(client_t *client, const char *reason)
Definition: main.c:212
ac_cvar_s::num_values
int num_values
Definition: ac.c:81
ac_cvar_s::def
char * def
Definition: ac.c:84
Cvar_FullSet
cvar_t * Cvar_FullSet(const char *var_name, const char *value, int flags, from_t from)
Definition: cvar.c:437
ac_locals_t::stream
netstream_t stream
Definition: ac.c:92
ac_clientbyte_t
ac_clientbyte_t
Definition: ac.c:39
AC_RECV_SIZE
#define AC_RECV_SIZE
Definition: ac.c:126
ac_file_s::path
char path[1]
Definition: ac.c:76
ACC_QUERYCLIENT
@ ACC_QUERYCLIENT
Definition: ac.c:45
ac_file_s
Definition: ac.c:72
Z_TagReserve
void Z_TagReserve(size_t size, memtag_t tag)
Definition: zone.c:342
cl
client_state_t cl
Definition: main.c:99
OP_EQUAL
@ OP_EQUAL
Definition: ac.c:53
sv_hostname
cvar_t * sv_hostname
Definition: main.c:65
ac_cvar_s
Definition: ac.c:79
COM_IsUint
qboolean COM_IsUint(const char *s)
Definition: shared.c:330
c
statCounters_t c
Definition: main.c:30
SV_BroadcastPrintf
void SV_BroadcastPrintf(int level, const char *fmt,...)
Definition: send.c:154
ac_error_action
static cvar_t * ac_error_action
Definition: ac.c:139
AC_SimpleParse
static char * AC_SimpleParse(char **data_p, size_t *len_p)
Definition: ac.c:196
MSG_WriteLong
void MSG_WriteLong(int c)
Definition: msg.c:144
cs_assigned
@ cs_assigned
Definition: server.h:189
ac_cvar_s::next
struct ac_cvar_s * next
Definition: ac.c:80
ac_badfile_message
static cvar_t * ac_badfile_message
Definition: ac.c:142
AC_Invalidate_f
static void AC_Invalidate_f(void)
Definition: ac.c:1621
ac_static_t::retry_time
time_t retry_time
Definition: ac.c:97
AC_ClientQuery
static void AC_ClientQuery(client_t *cl)
Definition: ac.c:1002
MSG_ReadString
size_t MSG_ReadString(char *dest, size_t size)
Definition: msg.c:1531
ac_num_clients
static const int ac_num_clients
Definition: ac.c:157
AC_Run
void AC_Run(void)
Definition: ac.c:1388
SV_Begin_f
void SV_Begin_f(void)
Definition: user.c:488
ac_recv_buffer
static byte ac_recv_buffer[AC_RECV_SIZE]
Definition: ac.c:135
AC_Announce
static void AC_Announce(client_t *client, const char *fmt,...)
Definition: ac.c:571
server_static_s::realtime
unsigned realtime
Definition: server.h:454
ac_static_t::retry_backoff
int retry_backoff
Definition: ac.c:98
OP_INVALID
@ OP_INVALID
Definition: ac.c:52
ac_badfile_max
static cvar_t * ac_badfile_max
Definition: ac.c:143
ACH_NEGATIVE
#define ACH_NEGATIVE
Definition: ac.c:114
cs_primed
@ cs_primed
Definition: server.h:191
SV_ClientPrintf
void SV_ClientPrintf(client_t *client, int level, const char *fmt,...)
Definition: send.c:121
ac_clients
static const char ac_clients[][8]
Definition: ac.c:148
AC_HASHES_NAME
#define AC_HASHES_NAME
Definition: ac.c:168
sv_player
edict_t * sv_player
Definition: main.c:33
AC_DelRequirement_f
static void AC_DelRequirement_f(void)
Definition: ac.c:1688
client_s
Definition: server.h:256
ac_send_buffer
static byte ac_send_buffer[AC_SEND_SIZE]
Definition: ac.c:134
ac_client_disconnect_action
static cvar_t * ac_client_disconnect_action
Definition: ac.c:145
AC_SendHello
static void AC_SendHello(void)
Definition: ac.c:1302
AC_ParseClient
static client_t * AC_ParseClient(void)
Definition: ac.c:604
AC_Disconnect
void AC_Disconnect(void)
Definition: ac.c:1479
SV_MatchAddress
addrmatch_t * SV_MatchAddress(list_t *list, netadr_t *addr)
Definition: main.c:370
ACC_BAD
@ ACC_BAD
Definition: ac.c:40
ACH_REQUIRED
#define ACH_REQUIRED
Definition: ac.c:113
OP_GT
@ OP_GT
Definition: ac.c:58
NET_RunStream
neterr_t NET_RunStream(netstream_t *s)
Definition: net.c:1647
AC_ParseClientAck
static void AC_ParseClientAck(void)
Definition: ac.c:711
ACC_UPDATECHECKS
@ ACC_UPDATECHECKS
Definition: ac.c:47
MSG_ReadByte
int MSG_ReadByte(void)
Definition: msg.c:1475
AC_Info_f
void AC_Info_f(void)
Definition: ac.c:1549
ac_cvarops
static const ac_cvarop_t ac_cvarops[]
Definition: ac.c:182
ac_opcode_t
ac_opcode_t
Definition: ac.c:51
ac_file_s::flags
int flags
Definition: ac.c:75
ac_cvar_s::values
char ** values
Definition: ac.c:82
AC_ClientDisconnect
void AC_ClientDisconnect(client_t *cl)
Definition: ac.c:1128
FIFO_Write
size_t FIFO_Write(fifo_t *fifo, const void *buffer, size_t len)
Definition: fifo.c:50
AC_ParseCvar
static void AC_ParseCvar(char *data, int linenum, const char *path)
Definition: ac.c:288
ac_show_violation_reason
static cvar_t * ac_show_violation_reason
Definition: ac.c:144
ac_static_t::cvars
ac_cvar_t * cvars
Definition: ac.c:103
AC_SendPrefs
static void AC_SendPrefs(void)
Definition: ac.c:1278
ACS_NOACCESS
@ ACS_NOACCESS
Definition: ac.c:29
c_ac
static const cmdreg_t c_ac[]
Definition: ac.c:1697
ac_client_t
ac_client_t
Definition: ac.c:64
SV_AddMatch_f
void SV_AddMatch_f(list_t *list)
Definition: commands.c:1082
AC_SEND_SIZE
#define AC_SEND_SIZE
Definition: ac.c:125
cs_connected
@ cs_connected
Definition: server.h:190
AC_Spin
static void AC_Spin(void)
Definition: ac.c:1184
OP_NEQUAL
@ OP_NEQUAL
Definition: ac.c:54
AC_MESSAGE
#define AC_MESSAGE
Definition: ac.c:123
SZ_Clear
void SZ_Clear(sizebuf_t *buf)
Definition: sizebuf.c:40
ac_serverbyte_t
ac_serverbyte_t
Definition: ac.c:25
ac_disable_play_changed
static void ac_disable_play_changed(cvar_t *self)
Definition: ac.c:1714
AC_SendChecks
static void AC_SendChecks(void)
Definition: ac.c:1243
OP_STREQUAL
@ OP_STREQUAL
Definition: ac.c:59
AC_ParseToken
static void AC_ParseToken(char *data, int linenum, const char *path)
Definition: ac.c:380
AC_List_f
void AC_List_f(void)
Definition: ac.c:1490
sv_maxclients
cvar_t * sv_maxclients
Definition: main.c:58