00001
00002
00003
00004
00005
00006 #include "g_local.h"
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 typedef struct ipFilter_s
00042 {
00043 unsigned mask;
00044 unsigned compare;
00045 } ipFilter_t;
00046
00047
00048 #ifdef _XBOX
00049 #define MAX_IPFILTERS 1
00050 #else
00051 #define MAX_IPFILTERS 1024
00052 #endif
00053
00054 static ipFilter_t ipFilters[MAX_IPFILTERS];
00055 static int numIPFilters;
00056
00057
00058
00059
00060
00061
00062 static qboolean StringToFilter (char *s, ipFilter_t *f)
00063 {
00064 char num[128];
00065 int i, j;
00066 byte b[4];
00067 byte m[4];
00068
00069 for (i=0 ; i<4 ; i++)
00070 {
00071 b[i] = 0;
00072 m[i] = 0;
00073 }
00074
00075 for (i=0 ; i<4 ; i++)
00076 {
00077 if (*s < '0' || *s > '9')
00078 {
00079 G_Printf( "Bad filter address: %s\n", s );
00080 return qfalse;
00081 }
00082
00083 j = 0;
00084 while (*s >= '0' && *s <= '9')
00085 {
00086 num[j++] = *s++;
00087 }
00088 num[j] = 0;
00089 b[i] = atoi(num);
00090 if (b[i] != 0)
00091 m[i] = 255;
00092
00093 if (!*s)
00094 break;
00095 s++;
00096 }
00097
00098 f->mask = *(unsigned *)m;
00099 f->compare = *(unsigned *)b;
00100
00101 return qtrue;
00102 }
00103
00104
00105
00106
00107
00108
00109 static void UpdateIPBans (void)
00110 {
00111 byte b[4];
00112 int i;
00113 char iplist[MAX_INFO_STRING];
00114
00115 *iplist = 0;
00116 for (i = 0 ; i < numIPFilters ; i++)
00117 {
00118 if (ipFilters[i].compare == 0xffffffff)
00119 continue;
00120
00121 *(unsigned *)b = ipFilters[i].compare;
00122 Com_sprintf( iplist + strlen(iplist), sizeof(iplist) - strlen(iplist),
00123 "%i.%i.%i.%i ", b[0], b[1], b[2], b[3]);
00124 }
00125
00126 trap_Cvar_Set( "g_banIPs", iplist );
00127 }
00128
00129
00130
00131
00132
00133
00134 qboolean G_FilterPacket (char *from)
00135 {
00136 byte m[4];
00137 int i = 0;
00138 unsigned int in;
00139 char *p;
00140
00141 while (i < 4)
00142 {
00143 m[i] = 0;
00144 i++;
00145 }
00146
00147 i = 0;
00148 p = from;
00149 while (*p && i < 4) {
00150 while (*p >= '0' && *p <= '9') {
00151 m[i] = m[i]*10 + (*p - '0');
00152 p++;
00153 }
00154 if (!*p || *p == ':')
00155 break;
00156 i++, p++;
00157 }
00158
00159 in = *(unsigned int *)m;
00160
00161 for (i=0 ; i<numIPFilters ; i++)
00162 if ( (in & ipFilters[i].mask) == ipFilters[i].compare)
00163 return g_filterBan.integer != 0;
00164
00165 return g_filterBan.integer == 0;
00166 }
00167
00168
00169
00170
00171
00172
00173 static void AddIP( char *str )
00174 {
00175 int i;
00176
00177 for (i = 0 ; i < numIPFilters ; i++)
00178 if (ipFilters[i].compare == 0xffffffff)
00179 break;
00180 if (i == numIPFilters)
00181 {
00182 if (numIPFilters == MAX_IPFILTERS)
00183 {
00184 G_Printf ("IP filter list is full\n");
00185 return;
00186 }
00187 numIPFilters++;
00188 }
00189
00190 if (!StringToFilter (str, &ipFilters[i]))
00191 ipFilters[i].compare = 0xffffffffu;
00192
00193 UpdateIPBans();
00194 }
00195
00196
00197
00198
00199
00200
00201 void G_ProcessIPBans(void)
00202 {
00203 char *s, *t;
00204 char str[MAX_TOKEN_CHARS];
00205
00206 Q_strncpyz( str, g_banIPs.string, sizeof(str) );
00207
00208 for (t = s = g_banIPs.string; *t; ) {
00209 s = strchr(s, ' ');
00210 if (!s)
00211 break;
00212 while (*s == ' ')
00213 *s++ = 0;
00214 if (*t)
00215 AddIP( t );
00216 t = s;
00217 }
00218 }
00219
00220
00221
00222
00223
00224
00225
00226 void Svcmd_AddIP_f (void)
00227 {
00228 char str[MAX_TOKEN_CHARS];
00229
00230 if ( trap_Argc() < 2 ) {
00231 G_Printf("Usage: addip <ip-mask>\n");
00232 return;
00233 }
00234
00235 trap_Argv( 1, str, sizeof( str ) );
00236
00237 AddIP( str );
00238
00239 }
00240
00241
00242
00243
00244
00245
00246 void Svcmd_RemoveIP_f (void)
00247 {
00248 ipFilter_t f;
00249 int i;
00250 char str[MAX_TOKEN_CHARS];
00251
00252 if ( trap_Argc() < 2 ) {
00253 G_Printf("Usage: sv removeip <ip-mask>\n");
00254 return;
00255 }
00256
00257 trap_Argv( 1, str, sizeof( str ) );
00258
00259 if (!StringToFilter (str, &f))
00260 return;
00261
00262 for (i=0 ; i<numIPFilters ; i++) {
00263 if (ipFilters[i].mask == f.mask &&
00264 ipFilters[i].compare == f.compare) {
00265 ipFilters[i].compare = 0xffffffffu;
00266 G_Printf ("Removed.\n");
00267
00268 UpdateIPBans();
00269 return;
00270 }
00271 }
00272
00273 G_Printf ( "Didn't find %s.\n", str );
00274 }
00275
00276
00277
00278
00279
00280
00281 void Svcmd_EntityList_f (void) {
00282 int e;
00283 gentity_t *check;
00284
00285 check = g_entities+1;
00286 for (e = 1; e < level.num_entities ; e++, check++) {
00287 if ( !check->inuse ) {
00288 continue;
00289 }
00290 G_Printf("%3i:", e);
00291 switch ( check->s.eType ) {
00292 case ET_GENERAL:
00293 G_Printf("ET_GENERAL ");
00294 break;
00295 case ET_PLAYER:
00296 G_Printf("ET_PLAYER ");
00297 break;
00298 case ET_ITEM:
00299 G_Printf("ET_ITEM ");
00300 break;
00301 case ET_MISSILE:
00302 G_Printf("ET_MISSILE ");
00303 break;
00304 case ET_MOVER:
00305 G_Printf("ET_MOVER ");
00306 break;
00307 case ET_BEAM:
00308 G_Printf("ET_BEAM ");
00309 break;
00310 case ET_PORTAL:
00311 G_Printf("ET_PORTAL ");
00312 break;
00313 case ET_SPEAKER:
00314 G_Printf("ET_SPEAKER ");
00315 break;
00316 case ET_PUSH_TRIGGER:
00317 G_Printf("ET_PUSH_TRIGGER ");
00318 break;
00319 case ET_TELEPORT_TRIGGER:
00320 G_Printf("ET_TELEPORT_TRIGGER ");
00321 break;
00322 case ET_INVISIBLE:
00323 G_Printf("ET_INVISIBLE ");
00324 break;
00325 case ET_NPC:
00326 G_Printf("ET_NPC ");
00327 break;
00328 default:
00329 G_Printf("%3i ", check->s.eType);
00330 break;
00331 }
00332
00333 if ( check->classname ) {
00334 G_Printf("%s", check->classname);
00335 }
00336 G_Printf("\n");
00337 }
00338 }
00339
00340 gclient_t *ClientForString( const char *s ) {
00341 gclient_t *cl;
00342 int i;
00343 int idnum;
00344
00345
00346 if ( s[0] >= '0' && s[0] <= '9' ) {
00347 idnum = atoi( s );
00348 if ( idnum < 0 || idnum >= level.maxclients ) {
00349 Com_Printf( "Bad client slot: %i\n", idnum );
00350 return NULL;
00351 }
00352
00353 cl = &level.clients[idnum];
00354 if ( cl->pers.connected == CON_DISCONNECTED ) {
00355 G_Printf( "Client %i is not connected\n", idnum );
00356 return NULL;
00357 }
00358 return cl;
00359 }
00360
00361
00362 for ( i=0 ; i < level.maxclients ; i++ ) {
00363 cl = &level.clients[i];
00364 if ( cl->pers.connected == CON_DISCONNECTED ) {
00365 continue;
00366 }
00367 if ( !Q_stricmp( cl->pers.netname, s ) ) {
00368 return cl;
00369 }
00370 }
00371
00372 G_Printf( "User %s is not on the server\n", s );
00373
00374 return NULL;
00375 }
00376
00377
00378
00379
00380
00381
00382
00383
00384 void Svcmd_ForceTeam_f( void ) {
00385 gclient_t *cl;
00386 char str[MAX_TOKEN_CHARS];
00387
00388
00389 trap_Argv( 1, str, sizeof( str ) );
00390 cl = ClientForString( str );
00391 if ( !cl ) {
00392 return;
00393 }
00394
00395
00396 trap_Argv( 2, str, sizeof( str ) );
00397 SetTeam( &g_entities[cl - level.clients], str );
00398 }
00399
00400 char *ConcatArgs( int start );
00401
00402
00403
00404
00405
00406
00407
00408 qboolean ConsoleCommand( void ) {
00409 char cmd[MAX_TOKEN_CHARS];
00410
00411 trap_Argv( 0, cmd, sizeof( cmd ) );
00412
00413 if ( Q_stricmp (cmd, "entitylist") == 0 ) {
00414 Svcmd_EntityList_f();
00415 return qtrue;
00416 }
00417
00418 if ( Q_stricmp (cmd, "forceteam") == 0 ) {
00419 Svcmd_ForceTeam_f();
00420 return qtrue;
00421 }
00422
00423 if (Q_stricmp (cmd, "game_memory") == 0) {
00424 Svcmd_GameMem_f();
00425 return qtrue;
00426 }
00427
00428 if (Q_stricmp (cmd, "addbot") == 0) {
00429 Svcmd_AddBot_f();
00430 return qtrue;
00431 }
00432
00433 if (Q_stricmp (cmd, "botlist") == 0) {
00434 Svcmd_BotList_f();
00435 return qtrue;
00436 }
00437
00438
00439
00440
00441
00442
00443 if (Q_stricmp (cmd, "addip") == 0) {
00444 Svcmd_AddIP_f();
00445 return qtrue;
00446 }
00447
00448 if (Q_stricmp (cmd, "removeip") == 0) {
00449 Svcmd_RemoveIP_f();
00450 return qtrue;
00451 }
00452
00453 if (Q_stricmp (cmd, "listip") == 0) {
00454 trap_SendConsoleCommand( EXEC_NOW, "g_banIPs\n" );
00455 return qtrue;
00456 }
00457
00458 if (g_dedicated.integer) {
00459 if (Q_stricmp (cmd, "say") == 0) {
00460 trap_SendServerCommand( -1, va("print \"server: %s\n\"", ConcatArgs(1) ) );
00461 return qtrue;
00462 }
00463
00464 trap_SendServerCommand( -1, va("print \"server: %s\n\"", ConcatArgs(0) ) );
00465 return qtrue;
00466 }
00467
00468 return qfalse;
00469 }
00470