Bug Summary

File:game/g_svcmds.cpp
Location:line 120, column 2
Description:Assigned value is garbage or undefined

Annotated Source Code

1/**
2 * @file
3 * @brief Server commands.
4 */
5
6/*
7All original material Copyright (C) 2002-2011 UFO: Alien Invasion.
8
9Original file from Quake 2 v3.21: quake2-2.31/game/g_svcmds.c
10Copyright (C) 1997-2001 Id Software, Inc.
11
12This program is free software; you can redistribute it and/or
13modify it under the terms of the GNU General Public License
14as published by the Free Software Foundation; either version 2
15of the License, or (at your option) any later version.
16
17This program is distributed in the hope that it will be useful,
18but WITHOUT ANY WARRANTY; without even the implied warranty of
19MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
20
21See the GNU General Public License for more details.
22
23You should have received a copy of the GNU General Public License
24along with this program; if not, write to the Free Software
25Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26
27*/
28
29
30#include "g_local.h"
31
32/**
33 * @brief PACKET FILTERING
34 * @note You can add or remove addresses from the filter list with:
35 *
36 * addip IP
37 * removeip IP
38 * The ip address is specified in dot format, and any unspecified digits will match any value, so you can specify an entire class C network with "addip 192.246.40".
39 * Removeip will only remove an address specified exactly the same way. You cannot addip a subnet, then removeip a single host.
40 *
41 * listip
42 * Prints the current list of filters.
43 *
44 * writeip
45 * Dumps "addip IP" commands to listip.cfg so it can be executed at a later date. The filter lists are not saved and restored by default, because I beleive it would cause too much confusion.
46 *
47 * sv_filterban <0 or 1>
48 * If 1 (the default), then ip addresses matching the current list will be prohibited from entering the game. This is the default setting.
49 * 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.
50 */
51
52typedef struct {
53 unsigned mask;
54 unsigned compare;
55} ipfilter_t;
56
57#define MAX_IPFILTERS1024 1024
58
59static ipfilter_t ipfilters[MAX_IPFILTERS1024];
60static int numipfilters;
61
62static bool StringToFilter (const char *s, ipfilter_t * f)
63{
64 char num[128];
65 int i, j;
66 byte b[4];
67 byte m[4];
68
69 for (i = 0; i < 4; i++) {
70 b[i] = 0;
71 m[i] = 0;
72 }
73
74 for (i = 0; i < 4; i++) {
75 if (*s < '0' || *s > '9') {
76 G_ClientPrintf(NULL__null, PRINT_CONSOLE2, "Bad filter address: %s\n", s);
77 return false;
78 }
79
80 j = 0;
81 while (isdigit(*s)) {
82 num[j++] = *s++;
83 }
84 num[j] = 0;
85 b[i] = atoi(num);
86 if (b[i] != 0)
87 m[i] = 0xFF;
88
89 if (!*s)
90 break;
91 s++;
92 }
93
94 f->mask = *(unsigned *) m;
95 f->compare = *(unsigned *) b;
96
97 return true;
98}
99
100bool SV_FilterPacket (const char *from)
101{
102 int i;
103 unsigned in;
104 byte m[4];
105 const char *p;
106
107 i = 0;
108 p = from;
109 while (*p && i < 4) {
1
Loop condition is false. Execution continues on line 120
110 m[i] = 0;
111 while (*p >= '0' && *p <= '9') {
112 m[i] = m[i] * 10 + (*p - '0');
113 p++;
114 }
115 if (!*p || *p == ':')
116 break;
117 i++, p++;
118 }
119
120 in = *(unsigned *) m;
2
Assigned value is garbage or undefined
121
122 for (i = 0; i < numipfilters; i++)
123 if ((in & ipfilters[i].mask) == ipfilters[i].compare)
124 return sv_filterban->integer;
125
126 return !sv_filterban->integer;
127}
128
129
130/**
131 * @sa SVCmd_RemoveIP_f
132 */
133static void SVCmd_AddIP_f (void)
134{
135 int i;
136
137 if (gi.Cmd_Argc() < 3) {
138 gi.DPrintf("Usage: %s <ip-mask>\n", gi.Cmd_Argv(1));
139 return;
140 }
141
142 for (i = 0; i < numipfilters; i++)
143 if (ipfilters[i].compare == ~0x0)
144 break; /* free spot */
145 if (i == numipfilters) {
146 if (numipfilters == MAX_IPFILTERS1024) {
147 gi.DPrintf("IP filter list is full\n");
148 return;
149 }
150 numipfilters++;
151 }
152
153 if (!StringToFilter(gi.Cmd_Argv(2), &ipfilters[i]))
154 ipfilters[i].compare = ~0x0;
155}
156
157/**
158 * @sa SVCmd_AddIP_f
159 */
160static void SVCmd_RemoveIP_f (void)
161{
162 ipfilter_t f;
163 int i, j;
164
165 if (gi.Cmd_Argc() < 3) {
166 gi.DPrintf("Usage: %s <ip-mask>\n", gi.Cmd_Argv(1));
167 return;
168 }
169
170 if (!StringToFilter(gi.Cmd_Argv(2), &f))
171 return;
172
173 for (i = 0; i < numipfilters; i++)
174 if (ipfilters[i].mask == f.mask && ipfilters[i].compare == f.compare) {
175 for (j = i + 1; j < numipfilters; j++)
176 ipfilters[j - 1] = ipfilters[j];
177 numipfilters--;
178 gi.DPrintf("Removed.\n");
179 return;
180 }
181 gi.DPrintf("Didn't find %s.\n", gi.Cmd_Argv(2));
182}
183
184/**
185 * @brief Shows the current ip in the filter list
186 */
187static void SVCmd_ListIP_f (void)
188{
189 int i;
190 byte b[4];
191
192 gi.DPrintf("Filter list:\n");
193 for (i = 0; i < numipfilters; i++) {
194 *(unsigned *) b = ipfilters[i].compare;
195 gi.DPrintf("%3i.%3i.%3i.%3i\n", b[0], b[1], b[2], b[3]);
196 }
197}
198
199/**
200 * @brief Store all ips in the current filter list in
201 */
202static void SVCmd_WriteIP_f (void)
203{
204 FILE *f;
205 char name[MAX_OSPATH256];
206 byte b[4];
207 int i;
208
209 Com_sprintf(name, sizeof(name), "%s/listip.cfg", gi.FS_Gamedir());
210
211 gi.DPrintf("Writing %s.\n", name);
212
213 f = fopen(name, "wb");
214 if (!f) {
215 gi.DPrintf("Couldn't open %s\n", name);
216 return;
217 }
218
219 fprintf(f, "set sv_filterban %d\n", sv_filterban->integer);
220
221 for (i = 0; i < numipfilters; i++) {
222 *(unsigned *) b = ipfilters[i].compare;
223 fprintf(f, "sv addip %i.%i.%i.%i\n", b[0], b[1], b[2], b[3]);
224 }
225
226 fclose(f);
227}
228
229/**
230 * @brief Used to add ai opponents to a game
231 * @note civilians can not be added with this function
232 * @sa AI_CreatePlayer
233 */
234static void SVCmd_AI_Add_f (void)
235{
236 int team;
237
238 if (gi.Cmd_Argc() < 3) {
239 gi.DPrintf("Usage: %s <teamnum>\n", gi.Cmd_Argv(1));
240 return;
241 }
242 team = atoi(gi.Cmd_Argv(2));
243 if (team > TEAM_CIVILIAN0 && team < MAX_TEAMS8) {
244 if (!AI_CreatePlayer(team))
245 gi.DPrintf("Couldn't create AI player.\n");
246 } else
247 gi.DPrintf("Bad team number.\n");
248}
249
250
251/**
252 * @brief Call the end game function with the given team
253 * used to e.g. abort singleplayer games and let the aliens win
254 * @sa G_MatchEndTrigger
255 */
256static void SVCmd_Win_f (void)
257{
258 int team;
259
260 if (gi.Cmd_Argc() < 3) {
261 gi.DPrintf("Usage: %s <teamnum>\n", gi.Cmd_Argv(1));
262 return;
263 }
264 team = atoi(gi.Cmd_Argv(2));
265 if (team > TEAM_CIVILIAN0 && team < MAX_TEAMS8)
266 G_MatchEndTrigger(team, 0);
267 else
268 gi.DPrintf("Bad team number.\n");
269}
270
271#ifdef DEBUG1
272static void SVCmd_ShowAll_f (void)
273{
274 edict_t *ent = NULL__null;
275
276 /* Make everything visible to anyone who can't already see it */
277 while ((ent = G_EdictsGetNextInUse(ent))) {
278 G_AppearPerishEvent(~G_VisToPM(ent->visflags), 1, ent, NULL__null);
279 G_VisFlagsAdd(ent, ~ent->visflags);
280 }
281 gi.DPrintf("All items and creatures revealed to all sides\n");
282}
283
284static void SVCmd_AddItem_f (void)
285{
286 const int team = TEAM_DEFAULT1;
287 edict_t *ent = G_EdictsGetNextLivingActorOfTeam(NULL__null, team);
288
289 if (gi.Cmd_Argc() < 3) {
290 gi.DPrintf("Usage: %s <item-id>\n", gi.Cmd_Argv(1));
291 return;
292 }
293
294 if (!ent) {
295 gi.DPrintf("Could not add item, no living members of team %i left\n", team);
296 return;
297 }
298
299 G_AddItemToFloor(ent->pos, gi.Cmd_Argv(2));
300}
301
302/**
303 * @brief Debug function to show the hole inventory of all connected clients on the server
304 */
305static void SVCmd_ActorInvList_f (void)
306{
307 player_t* player;
308 int i;
309
310 /* show inventory off all players around - include even the ai players */
311 for (i = 0, player = game.players; i < game.sv_maxplayersperteam * 2; i++, player++) {
312 if (!player->inuse)
313 continue;
314 G_InvList_f(player);
315 }
316}
317
318static void SVCmd_ListEdicts_f (void)
319{
320 edict_t *ent = NULL__null;
321 int i = 0;
322 Com_Printf("number | entnum | mapnum | type | inuse | pnum | team | size | HP | state | classname | model/ptl | pos\n");
323 while ((ent = G_EdictsGetNext(ent))) {
324 char buf[128];
325 const char *model;
326 if (ent->type == ET_PARTICLE)
327 model = ent->particle;
328 else if (ent->model)
329 model = ent->model;
330 else
331 model = "no mdl";
332 Com_sprintf(buf, sizeof(buf), "#%5i | #%5i | #%5i | %4i | %5i | %4i | %4i | %4i | %3i | %5i | %14s | %21s | %i:%i:%i",
333 i, ent->number, ent->mapNum, ent->type, ent->inuse, ent->pnum, ent->team, ent->fieldSize,
334 ent->HP, ent->state, ent->classname, model, ent->pos[0], ent->pos[1], ent->pos[2]);
335 Com_Printf("%s\n", buf);
336 i++;
337 }
338}
339#endif
340
341/**
342 * @brief ServerCommand will be called when an "sv" command is issued.
343 * The game can issue gi.Cmd_Argc() / gi.Cmd_Argv() commands to get the rest
344 * of the parameters
345 * @sa serverCommandList
346 */
347void G_ServerCommand (void)
348{
349 const char *cmd;
350
351 cmd = gi.Cmd_Argv(1);
352 if (Q_strcasecmp(cmd, "addip")strcasecmp((cmd), ("addip")) == 0)
353 SVCmd_AddIP_f();
354 else if (Q_strcasecmp(cmd, "removeip")strcasecmp((cmd), ("removeip")) == 0)
355 SVCmd_RemoveIP_f();
356 else if (Q_strcasecmp(cmd, "listip")strcasecmp((cmd), ("listip")) == 0)
357 SVCmd_ListIP_f();
358 else if (Q_strcasecmp(cmd, "writeip")strcasecmp((cmd), ("writeip")) == 0)
359 SVCmd_WriteIP_f();
360 else if (Q_strcasecmp(cmd, "ai_add")strcasecmp((cmd), ("ai_add")) == 0)
361 SVCmd_AI_Add_f();
362 else if (Q_strcasecmp(cmd, "win")strcasecmp((cmd), ("win")) == 0)
363 SVCmd_Win_f();
364#ifdef DEBUG1
365 else if (Q_strcasecmp(cmd, "debug_showall")strcasecmp((cmd), ("debug_showall")) == 0)
366 SVCmd_ShowAll_f();
367 else if (Q_strcasecmp(cmd, "debug_additem")strcasecmp((cmd), ("debug_additem")) == 0)
368 SVCmd_AddItem_f();
369 else if (Q_strcasecmp(cmd, "debug_actorinvlist")strcasecmp((cmd), ("debug_actorinvlist")) == 0)
370 SVCmd_ActorInvList_f();
371 else if (Q_strcasecmp(cmd, "debug_listedicts")strcasecmp((cmd), ("debug_listedicts")) == 0)
372 SVCmd_ListEdicts_f();
373#endif
374 else
375 gi.DPrintf("Unknown server command \"%s\"\n", cmd);
376}