~ubuntu-branches/ubuntu/hardy/openarena/hardy-backports

« back to all changes in this revision

Viewing changes to code/game/g_svcmds.c

  • Committer: Bazaar Package Importer
  • Author(s): Bruno "Fuddl" Kleinert
  • Date: 2007-01-20 12:28:09 UTC
  • Revision ID: james.westby@ubuntu.com-20070120122809-2yza5ojt7nqiyiam
Tags: upstream-0.6.0
ImportĀ upstreamĀ versionĀ 0.6.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
===========================================================================
 
3
Copyright (C) 1999-2005 Id Software, Inc.
 
4
 
 
5
This file is part of Quake III Arena source code.
 
6
 
 
7
Quake III Arena source code is free software; you can redistribute it
 
8
and/or modify it under the terms of the GNU General Public License as
 
9
published by the Free Software Foundation; either version 2 of the License,
 
10
or (at your option) any later version.
 
11
 
 
12
Quake III Arena source code is distributed in the hope that it will be
 
13
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
GNU General Public License for more details.
 
16
 
 
17
You should have received a copy of the GNU General Public License
 
18
along with Quake III Arena source code; if not, write to the Free Software
 
19
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
20
===========================================================================
 
21
*/
 
22
//
 
23
 
 
24
// this file holds commands that can be executed by the server console, but not remote clients
 
25
 
 
26
#include "g_local.h"
 
27
 
 
28
 
 
29
/*
 
30
==============================================================================
 
31
 
 
32
PACKET FILTERING
 
33
 
 
34
 
 
35
You can add or remove addresses from the filter list with:
 
36
 
 
37
addip <ip>
 
38
removeip <ip>
 
39
 
 
40
The ip address is specified in dot format, and you can use '*' to match any value
 
41
so you can specify an entire class C network with "addip 192.246.40.*"
 
42
 
 
43
Removeip will only remove an address specified exactly the same way.  You cannot addip a subnet, then removeip a single host.
 
44
 
 
45
listip
 
46
Prints the current list of filters.
 
47
 
 
48
g_filterban <0 or 1>
 
49
 
 
50
If 1 (the default), then ip addresses matching the current list will be prohibited from entering the game.  This is the default setting.
 
51
 
 
52
If 0, then only addresses matching the list will be allowed.  This lets you easily set up a private game, or a game that only allows players from your local network.
 
53
 
 
54
TTimo NOTE: for persistence, bans are stored in g_banIPs cvar MAX_CVAR_VALUE_STRING
 
55
The size of the cvar string buffer is limiting the banning to around 20 masks
 
56
this could be improved by putting some g_banIPs2 g_banIps3 etc. maybe
 
57
still, you should rely on PB for banning instead
 
58
 
 
59
==============================================================================
 
60
*/
 
61
 
 
62
typedef struct ipFilter_s
 
63
{
 
64
        unsigned        mask;
 
65
        unsigned        compare;
 
66
} ipFilter_t;
 
67
 
 
68
#define MAX_IPFILTERS   1024
 
69
 
 
70
static ipFilter_t       ipFilters[MAX_IPFILTERS];
 
71
static int                      numIPFilters;
 
72
 
 
73
/*
 
74
=================
 
75
StringToFilter
 
76
=================
 
77
*/
 
78
static qboolean StringToFilter (char *s, ipFilter_t *f)
 
79
{
 
80
        char    num[128];
 
81
        int             i, j;
 
82
        byte    b[4];
 
83
        byte    m[4];
 
84
        
 
85
        for (i=0 ; i<4 ; i++)
 
86
        {
 
87
                b[i] = 0;
 
88
                m[i] = 0;
 
89
        }
 
90
        
 
91
        for (i=0 ; i<4 ; i++)
 
92
        {
 
93
                if (*s < '0' || *s > '9')
 
94
                {
 
95
                        if (*s == '*') // 'match any'
 
96
                        {
 
97
                                // b[i] and m[i] to 0
 
98
                                s++;
 
99
                                if (!*s)
 
100
                                        break;
 
101
                                s++;
 
102
                                continue;
 
103
                        }
 
104
                        G_Printf( "Bad filter address: %s\n", s );
 
105
                        return qfalse;
 
106
                }
 
107
                
 
108
                j = 0;
 
109
                while (*s >= '0' && *s <= '9')
 
110
                {
 
111
                        num[j++] = *s++;
 
112
                }
 
113
                num[j] = 0;
 
114
                b[i] = atoi(num);
 
115
                m[i] = 255;
 
116
 
 
117
                if (!*s)
 
118
                        break;
 
119
                s++;
 
120
        }
 
121
        
 
122
        f->mask = *(unsigned *)m;
 
123
        f->compare = *(unsigned *)b;
 
124
        
 
125
        return qtrue;
 
126
}
 
127
 
 
128
/*
 
129
=================
 
130
UpdateIPBans
 
131
=================
 
132
*/
 
133
static void UpdateIPBans (void)
 
134
{
 
135
        byte    b[4];
 
136
        byte    m[4];
 
137
        int             i,j;
 
138
        char    iplist_final[MAX_CVAR_VALUE_STRING];
 
139
        char    ip[64];
 
140
 
 
141
        *iplist_final = 0;
 
142
        for (i = 0 ; i < numIPFilters ; i++)
 
143
        {
 
144
                if (ipFilters[i].compare == 0xffffffff)
 
145
                        continue;
 
146
 
 
147
                *(unsigned *)b = ipFilters[i].compare;
 
148
                *(unsigned *)m = ipFilters[i].mask;
 
149
                *ip = 0;
 
150
                for (j = 0 ; j < 4 ; j++)
 
151
                {
 
152
                        if (m[j]!=255)
 
153
                                Q_strcat(ip, sizeof(ip), "*");
 
154
                        else
 
155
                                Q_strcat(ip, sizeof(ip), va("%i", b[j]));
 
156
                        Q_strcat(ip, sizeof(ip), (j<3) ? "." : " ");
 
157
                }               
 
158
                if (strlen(iplist_final)+strlen(ip) < MAX_CVAR_VALUE_STRING)
 
159
                {
 
160
                        Q_strcat( iplist_final, sizeof(iplist_final), ip);
 
161
                }
 
162
                else
 
163
                {
 
164
                        Com_Printf("g_banIPs overflowed at MAX_CVAR_VALUE_STRING\n");
 
165
                        break;
 
166
                }
 
167
        }
 
168
 
 
169
        trap_Cvar_Set( "g_banIPs", iplist_final );
 
170
}
 
171
 
 
172
/*
 
173
=================
 
174
G_FilterPacket
 
175
=================
 
176
*/
 
177
qboolean G_FilterPacket (char *from)
 
178
{
 
179
        int             i;
 
180
        unsigned        in;
 
181
        byte m[4];
 
182
        char *p;
 
183
 
 
184
        i = 0;
 
185
        p = from;
 
186
        while (*p && i < 4) {
 
187
                m[i] = 0;
 
188
                while (*p >= '0' && *p <= '9') {
 
189
                        m[i] = m[i]*10 + (*p - '0');
 
190
                        p++;
 
191
                }
 
192
                if (!*p || *p == ':')
 
193
                        break;
 
194
                i++, p++;
 
195
        }
 
196
        
 
197
        in = *(unsigned *)m;
 
198
 
 
199
        for (i=0 ; i<numIPFilters ; i++)
 
200
                if ( (in & ipFilters[i].mask) == ipFilters[i].compare)
 
201
                        return g_filterBan.integer != 0;
 
202
 
 
203
        return g_filterBan.integer == 0;
 
204
}
 
205
 
 
206
/*
 
207
=================
 
208
AddIP
 
209
=================
 
210
*/
 
211
static void AddIP( char *str )
 
212
{
 
213
        int             i;
 
214
 
 
215
        for (i = 0 ; i < numIPFilters ; i++)
 
216
                if (ipFilters[i].compare == 0xffffffff)
 
217
                        break;          // free spot
 
218
        if (i == numIPFilters)
 
219
        {
 
220
                if (numIPFilters == MAX_IPFILTERS)
 
221
                {
 
222
                        G_Printf ("IP filter list is full\n");
 
223
                        return;
 
224
                }
 
225
                numIPFilters++;
 
226
        }
 
227
        
 
228
        if (!StringToFilter (str, &ipFilters[i]))
 
229
                ipFilters[i].compare = 0xffffffffu;
 
230
 
 
231
        UpdateIPBans();
 
232
}
 
233
 
 
234
/*
 
235
=================
 
236
G_ProcessIPBans
 
237
=================
 
238
*/
 
239
void G_ProcessIPBans(void) 
 
240
{
 
241
        char *s, *t;
 
242
        char            str[MAX_CVAR_VALUE_STRING];
 
243
 
 
244
        Q_strncpyz( str, g_banIPs.string, sizeof(str) );
 
245
 
 
246
        for (t = s = g_banIPs.string; *t; /* */ ) {
 
247
                s = strchr(s, ' ');
 
248
                if (!s)
 
249
                        break;
 
250
                while (*s == ' ')
 
251
                        *s++ = 0;
 
252
                if (*t)
 
253
                        AddIP( t );
 
254
                t = s;
 
255
        }
 
256
}
 
257
 
 
258
 
 
259
/*
 
260
=================
 
261
Svcmd_AddIP_f
 
262
=================
 
263
*/
 
264
void Svcmd_AddIP_f (void)
 
265
{
 
266
        char            str[MAX_TOKEN_CHARS];
 
267
 
 
268
        if ( trap_Argc() < 2 ) {
 
269
                G_Printf("Usage:  addip <ip-mask>\n");
 
270
                return;
 
271
        }
 
272
 
 
273
        trap_Argv( 1, str, sizeof( str ) );
 
274
 
 
275
        AddIP( str );
 
276
 
 
277
}
 
278
 
 
279
/*
 
280
=================
 
281
Svcmd_RemoveIP_f
 
282
=================
 
283
*/
 
284
void Svcmd_RemoveIP_f (void)
 
285
{
 
286
        ipFilter_t      f;
 
287
        int                     i;
 
288
        char            str[MAX_TOKEN_CHARS];
 
289
 
 
290
        if ( trap_Argc() < 2 ) {
 
291
                G_Printf("Usage:  sv removeip <ip-mask>\n");
 
292
                return;
 
293
        }
 
294
 
 
295
        trap_Argv( 1, str, sizeof( str ) );
 
296
 
 
297
        if (!StringToFilter (str, &f))
 
298
                return;
 
299
 
 
300
        for (i=0 ; i<numIPFilters ; i++) {
 
301
                if (ipFilters[i].mask == f.mask &&
 
302
                        ipFilters[i].compare == f.compare) {
 
303
                        ipFilters[i].compare = 0xffffffffu;
 
304
                        G_Printf ("Removed.\n");
 
305
 
 
306
                        UpdateIPBans();
 
307
                        return;
 
308
                }
 
309
        }
 
310
 
 
311
        G_Printf ( "Didn't find %s.\n", str );
 
312
}
 
313
 
 
314
/*
 
315
===================
 
316
Svcmd_EntityList_f
 
317
===================
 
318
*/
 
319
void    Svcmd_EntityList_f (void) {
 
320
        int                     e;
 
321
        gentity_t               *check;
 
322
 
 
323
        check = g_entities+1;
 
324
        for (e = 1; e < level.num_entities ; e++, check++) {
 
325
                if ( !check->inuse ) {
 
326
                        continue;
 
327
                }
 
328
                G_Printf("%3i:", e);
 
329
                switch ( check->s.eType ) {
 
330
                case ET_GENERAL:
 
331
                        G_Printf("ET_GENERAL          ");
 
332
                        break;
 
333
                case ET_PLAYER:
 
334
                        G_Printf("ET_PLAYER           ");
 
335
                        break;
 
336
                case ET_ITEM:
 
337
                        G_Printf("ET_ITEM             ");
 
338
                        break;
 
339
                case ET_MISSILE:
 
340
                        G_Printf("ET_MISSILE          ");
 
341
                        break;
 
342
                case ET_MOVER:
 
343
                        G_Printf("ET_MOVER            ");
 
344
                        break;
 
345
                case ET_BEAM:
 
346
                        G_Printf("ET_BEAM             ");
 
347
                        break;
 
348
                case ET_PORTAL:
 
349
                        G_Printf("ET_PORTAL           ");
 
350
                        break;
 
351
                case ET_SPEAKER:
 
352
                        G_Printf("ET_SPEAKER          ");
 
353
                        break;
 
354
                case ET_PUSH_TRIGGER:
 
355
                        G_Printf("ET_PUSH_TRIGGER     ");
 
356
                        break;
 
357
                case ET_TELEPORT_TRIGGER:
 
358
                        G_Printf("ET_TELEPORT_TRIGGER ");
 
359
                        break;
 
360
                case ET_INVISIBLE:
 
361
                        G_Printf("ET_INVISIBLE        ");
 
362
                        break;
 
363
                case ET_GRAPPLE:
 
364
                        G_Printf("ET_GRAPPLE          ");
 
365
                        break;
 
366
                default:
 
367
                        G_Printf("%3i                 ", check->s.eType);
 
368
                        break;
 
369
                }
 
370
 
 
371
                if ( check->classname ) {
 
372
                        G_Printf("%s", check->classname);
 
373
                }
 
374
                G_Printf("\n");
 
375
        }
 
376
}
 
377
 
 
378
gclient_t       *ClientForString( const char *s ) {
 
379
        gclient_t       *cl;
 
380
        int                     i;
 
381
        int                     idnum;
 
382
 
 
383
        // numeric values are just slot numbers
 
384
        if ( s[0] >= '0' && s[0] <= '9' ) {
 
385
                idnum = atoi( s );
 
386
                if ( idnum < 0 || idnum >= level.maxclients ) {
 
387
                        Com_Printf( "Bad client slot: %i\n", idnum );
 
388
                        return NULL;
 
389
                }
 
390
 
 
391
                cl = &level.clients[idnum];
 
392
                if ( cl->pers.connected == CON_DISCONNECTED ) {
 
393
                        G_Printf( "Client %i is not connected\n", idnum );
 
394
                        return NULL;
 
395
                }
 
396
                return cl;
 
397
        }
 
398
 
 
399
        // check for a name match
 
400
        for ( i=0 ; i < level.maxclients ; i++ ) {
 
401
                cl = &level.clients[i];
 
402
                if ( cl->pers.connected == CON_DISCONNECTED ) {
 
403
                        continue;
 
404
                }
 
405
                if ( !Q_stricmp( cl->pers.netname, s ) ) {
 
406
                        return cl;
 
407
                }
 
408
        }
 
409
 
 
410
        G_Printf( "User %s is not on the server\n", s );
 
411
 
 
412
        return NULL;
 
413
}
 
414
 
 
415
/*
 
416
===================
 
417
Svcmd_ForceTeam_f
 
418
 
 
419
forceteam <player> <team>
 
420
===================
 
421
*/
 
422
void    Svcmd_ForceTeam_f( void ) {
 
423
        gclient_t       *cl;
 
424
        char            str[MAX_TOKEN_CHARS];
 
425
 
 
426
        // find the player
 
427
        trap_Argv( 1, str, sizeof( str ) );
 
428
        cl = ClientForString( str );
 
429
        if ( !cl ) {
 
430
                return;
 
431
        }
 
432
 
 
433
        // set the team
 
434
        trap_Argv( 2, str, sizeof( str ) );
 
435
        SetTeam( &g_entities[cl - level.clients], str );
 
436
}
 
437
 
 
438
char    *ConcatArgs( int start );
 
439
 
 
440
/*
 
441
=================
 
442
ConsoleCommand
 
443
 
 
444
=================
 
445
*/
 
446
qboolean        ConsoleCommand( void ) {
 
447
        char    cmd[MAX_TOKEN_CHARS];
 
448
 
 
449
        trap_Argv( 0, cmd, sizeof( cmd ) );
 
450
 
 
451
        if ( Q_stricmp (cmd, "entitylist") == 0 ) {
 
452
                Svcmd_EntityList_f();
 
453
                return qtrue;
 
454
        }
 
455
 
 
456
        if ( Q_stricmp (cmd, "forceteam") == 0 ) {
 
457
                Svcmd_ForceTeam_f();
 
458
                return qtrue;
 
459
        }
 
460
 
 
461
        if (Q_stricmp (cmd, "game_memory") == 0) {
 
462
                Svcmd_GameMem_f();
 
463
                return qtrue;
 
464
        }
 
465
 
 
466
        if (Q_stricmp (cmd, "addbot") == 0) {
 
467
                Svcmd_AddBot_f();
 
468
                return qtrue;
 
469
        }
 
470
 
 
471
        if (Q_stricmp (cmd, "botlist") == 0) {
 
472
                Svcmd_BotList_f();
 
473
                return qtrue;
 
474
        }
 
475
 
 
476
        if (Q_stricmp (cmd, "abort_podium") == 0) {
 
477
                Svcmd_AbortPodium_f();
 
478
                return qtrue;
 
479
        }
 
480
 
 
481
        if (Q_stricmp (cmd, "addip") == 0) {
 
482
                Svcmd_AddIP_f();
 
483
                return qtrue;
 
484
        }
 
485
 
 
486
        if (Q_stricmp (cmd, "removeip") == 0) {
 
487
                Svcmd_RemoveIP_f();
 
488
                return qtrue;
 
489
        }
 
490
 
 
491
        if (Q_stricmp (cmd, "listip") == 0) {
 
492
                trap_SendConsoleCommand( EXEC_NOW, "g_banIPs\n" );
 
493
                return qtrue;
 
494
        }
 
495
 
 
496
        if (g_dedicated.integer) {
 
497
                if (Q_stricmp (cmd, "say") == 0) {
 
498
                        trap_SendServerCommand( -1, va("print \"server: %s\"", ConcatArgs(1) ) );
 
499
                        return qtrue;
 
500
                }
 
501
                // everything else will also be printed as a say command
 
502
                trap_SendServerCommand( -1, va("print \"server: %s\"", ConcatArgs(0) ) );
 
503
                return qtrue;
 
504
        }
 
505
 
 
506
        return qfalse;
 
507
}
 
508