1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33: #include <sys/cdefs.h>
34: #ifndef lint
35: __RCSID("$NetBSD: answer.c,v 1.7 2004/11/05 21:30:32 dsl Exp $");
36: #endif
37:
38: # include <ctype.h>
39: # include <errno.h>
40: # include <fcntl.h>
41: # include <stdlib.h>
42: # include <unistd.h>
43: # include <sys/time.h>
44: # include "hunt.h"
45:
46: # define SCOREDECAY 15
47:
48: static char Ttyname[NAMELEN];
49:
50: int
51: answer()
52: {
53: PLAYER *pp;
54: int newsock;
55: static u_long mode;
56: static char name[NAMELEN];
57: static char team;
58: static int enter_status;
59: static int socklen;
60: static u_long machine;
61: static u_int32_t uid;
62: static SOCKET sockstruct;
63: char *cp1, *cp2;
64: int flags;
65: u_int32_t version;
66: int i;
67:
68: # ifdef INTERNET
69: socklen = sizeof sockstruct;
70: # else
71: socklen = sizeof sockstruct - 1;
72: # endif
73: errno = 0;
74: newsock = accept(Socket, (struct sockaddr *) &sockstruct, &socklen);
75: if (newsock < 0)
76: {
77: if (errno == EINTR)
78: return FALSE;
79: # ifdef LOG
80: syslog(LOG_ERR, "accept: %m");
81: # else
82: perror("accept");
83: # endif
84: cleanup(1);
85: }
86:
87: # ifdef INTERNET
88: machine = ntohl(((struct sockaddr_in *) &sockstruct)->sin_addr.s_addr);
89: # else
90: if (machine == 0)
91: machine = gethostid();
92: # endif
93: version = htonl((u_int32_t) HUNT_VERSION);
94: (void) write(newsock, (char *) &version, LONGLEN);
95: (void) read(newsock, (char *) &uid, LONGLEN);
96: uid = ntohl((unsigned long) uid);
97: (void) read(newsock, name, NAMELEN);
98: (void) read(newsock, &team, 1);
99: (void) read(newsock, (char *) &enter_status, LONGLEN);
100: enter_status = ntohl((unsigned long) enter_status);
101: (void) read(newsock, Ttyname, NAMELEN);
102: (void) read(newsock, (char *) &mode, sizeof mode);
103: mode = ntohl(mode);
104:
105:
106:
107:
108:
109: flags = fcntl(newsock, F_GETFL, 0);
110: flags |= O_NDELAY;
111: (void) fcntl(newsock, F_SETFL, flags);
112:
113:
114:
115:
116:
117:
118: for (cp1 = cp2 = name; *cp1 != '\0'; cp1++)
119: if (isprint((unsigned char)*cp1) || *cp1 == ' ')
120: *cp2++ = *cp1;
121: *cp2 = '\0';
122:
123: # ifdef INTERNET
124: if (mode == C_MESSAGE) {
125: char buf[BUFSIZ + 1];
126: int n;
127:
128: if (team == ' ')
129: (void) sprintf(buf, "%s: ", name);
130: else
131: (void) sprintf(buf, "%s[%c]: ", name, team);
132: n = strlen(buf);
133: for (pp = Player; pp < End_player; pp++) {
134: cgoto(pp, HEIGHT, 0);
135: outstr(pp, buf, n);
136: }
137: while ((n = read(newsock, buf, BUFSIZ)) > 0)
138: for (pp = Player; pp < End_player; pp++)
139: outstr(pp, buf, n);
140: for (pp = Player; pp < End_player; pp++) {
141: ce(pp);
142: sendcom(pp, REFRESH);
143: sendcom(pp, READY, 0);
144: (void) fflush(pp->p_output);
145: }
146: (void) close(newsock);
147: return FALSE;
148: }
149: else
150: # endif
151: # ifdef MONITOR
152: if (mode == C_MONITOR)
153: if (End_monitor < &Monitor[MAXMON]) {
154: pp = End_monitor++;
155: i = pp - Monitor + MAXPL + 3;
156: } else {
157: socklen = 0;
158: (void) write(newsock, (char *) &socklen,
159: sizeof socklen);
160: (void) close(newsock);
161: return FALSE;
162: }
163: else
164: # endif
165: if (End_player < &Player[MAXPL]) {
166: pp = End_player++;
167: i = pp - Player + 3;
168: } else {
169: socklen = 0;
170: (void) write(newsock, (char *) &socklen,
171: sizeof socklen);
172: (void) close(newsock);
173: return FALSE;
174: }
175:
176: #ifdef MONITOR
177: if (mode == C_MONITOR && team == ' ')
178: team = '*';
179: #endif
180: pp->p_ident = get_ident(machine, uid, name, team);
181: pp->p_output = fdopen(newsock, "w");
182: pp->p_death[0] = '\0';
183: pp->p_fd = newsock;
184: fdset[i].fd = newsock;
185: fdset[i].events = POLLIN;
186:
187: pp->p_y = 0;
188: pp->p_x = 0;
189:
190: # ifdef MONITOR
191: if (mode == C_MONITOR)
192: stmonitor(pp);
193: else
194: # endif
195: stplayer(pp, enter_status);
196: return TRUE;
197: }
198:
199: # ifdef MONITOR
200: void
201: stmonitor(pp)
202: PLAYER *pp;
203: {
204: int line;
205: PLAYER *npp;
206:
207: memcpy(pp->p_maze, Maze, sizeof Maze);
208:
209: drawmaze(pp);
210:
211: (void) sprintf(Buf, "%5.5s%c%-10.10s %c", " ", stat_char(pp),
212: pp->p_ident->i_name, pp->p_ident->i_team);
213: line = STAT_MON_ROW + 1 + (pp - Monitor);
214: for (npp = Player; npp < End_player; npp++) {
215: cgoto(npp, line, STAT_NAME_COL);
216: outstr(npp, Buf, STAT_NAME_LEN);
217: }
218: for (npp = Monitor; npp < End_monitor; npp++) {
219: cgoto(npp, line, STAT_NAME_COL);
220: outstr(npp, Buf, STAT_NAME_LEN);
221: }
222:
223: sendcom(pp, REFRESH);
224: sendcom(pp, READY, 0);
225: (void) fflush(pp->p_output);
226: }
227: # endif
228:
229: void
230: stplayer(newpp, enter_status)
231: PLAYER *newpp;
232: int enter_status;
233: {
234: int x, y;
235: PLAYER *pp;
236:
237: Nplayer++;
238:
239: for (y = 0; y < UBOUND; y++)
240: for (x = 0; x < WIDTH; x++)
241: newpp->p_maze[y][x] = Maze[y][x];
242: for ( ; y < DBOUND; y++) {
243: for (x = 0; x < LBOUND; x++)
244: newpp->p_maze[y][x] = Maze[y][x];
245: for ( ; x < RBOUND; x++)
246: newpp->p_maze[y][x] = SPACE;
247: for ( ; x < WIDTH; x++)
248: newpp->p_maze[y][x] = Maze[y][x];
249: }
250: for ( ; y < HEIGHT; y++)
251: for (x = 0; x < WIDTH; x++)
252: newpp->p_maze[y][x] = Maze[y][x];
253:
254: do {
255: x = rand_num(WIDTH - 1) + 1;
256: y = rand_num(HEIGHT - 1) + 1;
257: } while (Maze[y][x] != SPACE);
258: newpp->p_over = SPACE;
259: newpp->p_x = x;
260: newpp->p_y = y;
261: newpp->p_undershot = FALSE;
262:
263: # ifdef FLY
264: if (enter_status == Q_FLY) {
265: newpp->p_flying = rand_num(20);
266: newpp->p_flyx = 2 * rand_num(6) - 5;
267: newpp->p_flyy = 2 * rand_num(6) - 5;
268: newpp->p_face = FLYER;
269: }
270: else
271: # endif
272: {
273: newpp->p_flying = -1;
274: newpp->p_face = rand_dir();
275: }
276: newpp->p_damage = 0;
277: newpp->p_damcap = MAXDAM;
278: newpp->p_nchar = 0;
279: newpp->p_ncount = 0;
280: newpp->p_nexec = 0;
281: newpp->p_ammo = ISHOTS;
282: # ifdef BOOTS
283: newpp->p_nboots = 0;
284: # endif
285: if (enter_status == Q_SCAN) {
286: newpp->p_scan = SCANLEN;
287: newpp->p_cloak = 0;
288: }
289: else {
290: newpp->p_scan = 0;
291: newpp->p_cloak = CLOAKLEN;
292: }
293: newpp->p_ncshot = 0;
294:
295: do {
296: x = rand_num(WIDTH - 1) + 1;
297: y = rand_num(HEIGHT - 1) + 1;
298: } while (Maze[y][x] != SPACE);
299: Maze[y][x] = GMINE;
300: # ifdef MONITOR
301: for (pp = Monitor; pp < End_monitor; pp++)
302: check(pp, y, x);
303: # endif
304:
305: do {
306: x = rand_num(WIDTH - 1) + 1;
307: y = rand_num(HEIGHT - 1) + 1;
308: } while (Maze[y][x] != SPACE);
309: Maze[y][x] = MINE;
310: # ifdef MONITOR
311: for (pp = Monitor; pp < End_monitor; pp++)
312: check(pp, y, x);
313: # endif
314:
315: (void) sprintf(Buf, "%5.2f%c%-10.10s %c", newpp->p_ident->i_score,
316: stat_char(newpp), newpp->p_ident->i_name,
317: newpp->p_ident->i_team);
318: y = STAT_PLAY_ROW + 1 + (newpp - Player);
319: for (pp = Player; pp < End_player; pp++) {
320: if (pp != newpp) {
321: char smallbuf[10];
322:
323: pp->p_ammo += NSHOTS;
324: newpp->p_ammo += NSHOTS;
325: cgoto(pp, y, STAT_NAME_COL);
326: outstr(pp, Buf, STAT_NAME_LEN);
327: (void) sprintf(smallbuf, "%3d", pp->p_ammo);
328: cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL);
329: outstr(pp, smallbuf, 3);
330: }
331: }
332: # ifdef MONITOR
333: for (pp = Monitor; pp < End_monitor; pp++) {
334: cgoto(pp, y, STAT_NAME_COL);
335: outstr(pp, Buf, STAT_NAME_LEN);
336: }
337: # endif
338:
339: drawmaze(newpp);
340: drawplayer(newpp, TRUE);
341: look(newpp);
342: # ifdef FLY
343: if (enter_status == Q_FLY)
344:
345: showexpl(newpp->p_y, newpp->p_x, FLYER);
346: # endif
347: sendcom(newpp, REFRESH);
348: sendcom(newpp, READY, 0);
349: (void) fflush(newpp->p_output);
350: }
351:
352:
353:
354:
355:
356: int
357: rand_dir()
358: {
359: switch (rand_num(4)) {
360: case 0:
361: return LEFTS;
362: case 1:
363: return RIGHT;
364: case 2:
365: return BELOW;
366: case 3:
367: return ABOVE;
368: }
369:
370: return(-1);
371: }
372:
373:
374:
375:
376:
377: IDENT *
378: get_ident(machine, uid, name, team)
379: u_long machine;
380: u_long uid;
381: const char *name;
382: char team;
383: {
384: IDENT *ip;
385: static IDENT punt;
386:
387: for (ip = Scores; ip != NULL; ip = ip->i_next)
388: if ((unsigned long)ip->i_machine == machine
389: && (unsigned long)ip->i_uid == uid
390: && ip->i_team == team
391: && strncmp(ip->i_name, name, NAMELEN) == 0)
392: break;
393:
394: if (ip != NULL) {
395: if (ip->i_entries < SCOREDECAY)
396: ip->i_entries++;
397: else
398: ip->i_kills = (ip->i_kills * (SCOREDECAY - 1))
399: / SCOREDECAY;
400: ip->i_score = ip->i_kills / (double) ip->i_entries;
401: }
402: else {
403: ip = (IDENT *) malloc(sizeof (IDENT));
404: if (ip == NULL) {
405:
406: ip = &punt;
407: }
408: ip->i_machine = machine;
409: ip->i_team = team;
410: ip->i_uid = uid;
411: strncpy(ip->i_name, name, NAMELEN);
412: ip->i_kills = 0;
413: ip->i_entries = 1;
414: ip->i_score = 0;
415: ip->i_absorbed = 0;
416: ip->i_faced = 0;
417: ip->i_shot = 0;
418: ip->i_robbed = 0;
419: ip->i_slime = 0;
420: ip->i_missed = 0;
421: ip->i_ducked = 0;
422: ip->i_gkills = ip->i_bkills = ip->i_deaths = 0;
423: ip->i_stillb = ip->i_saved = 0;
424: ip->i_next = Scores;
425: Scores = ip;
426: }
427:
428: return ip;
429: }