|
|
1.1 root 1: /*
2: * Hunt
3: * Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
4: * San Francisco, California
5: *
6: * Copyright (c) 1985 Regents of the University of California.
7: * All rights reserved. The Berkeley software License Agreement
8: * specifies the terms and conditions for redistribution.
9: */
10:
11: # include "hunt.h"
12: # include <ctype.h>
13: # include <errno.h>
14: # include <fcntl.h>
15:
16: # define SCOREDECAY 15
17:
18: static char Ttyname[NAMELEN];
19:
20: answer()
21: {
22: register PLAYER *pp;
23: register int newsock;
24: static u_long mode;
25: static char name[NAMELEN];
26: static char team;
27: static int enter_status;
28: static int socklen;
29: static u_long machine;
30: static u_long uid;
31: static SOCKET sockstruct;
32: register char *cp1, *cp2;
33: int flags;
34: long version;
35:
36: # ifdef INTERNET
37: socklen = sizeof sockstruct;
38: # else
39: socklen = sizeof sockstruct - 1;
40: # endif INTERNET
41: errno = 0;
42: newsock = accept(Socket, (struct sockaddr *) &sockstruct, &socklen);
43: if (newsock < 0)
44: {
45: if (errno == EINTR)
46: return FALSE;
47: # ifdef LOG
48: syslog(LOG_ERR, "accept: %m");
49: # else LOG
50: perror("accept");
51: # endif LOG
52: cleanup(1);
53: }
54:
55: # ifdef INTERNET
56: machine = ntohl(((struct sockaddr_in *) &sockstruct)->sin_addr.s_addr);
57: # else INTERNET
58: if (machine == 0)
59: machine = gethostid();
60: # endif INTERNET
61: version = htonl((unsigned long) HUNT_VERSION);
62: (void) write(newsock, (char *) &version, LONGLEN);
63: (void) read(newsock, (char *) &uid, LONGLEN);
64: uid = ntohl((unsigned long) uid);
65: (void) read(newsock, name, NAMELEN);
66: (void) read(newsock, &team, 1);
67: (void) read(newsock, (char *) &enter_status, LONGLEN);
68: enter_status = ntohl((unsigned long) enter_status);
69: (void) read(newsock, Ttyname, NAMELEN);
70: (void) read(newsock, (char *) &mode, sizeof mode);
71: mode = ntohl(mode);
72:
73: /*
74: * Turn off blocking I/O, so a slow or dead terminal won't stop
75: * the game. All subsequent reads check how many bytes they read.
76: */
77: flags = fcntl(newsock, F_GETFL, 0);
78: flags |= O_NDELAY;
79: (void) fcntl(newsock, F_SETFL, flags);
80:
81: /*
82: * Make sure the name contains only printable characters
83: * since we use control characters for cursor control
84: * between driver and player processes
85: */
86: for (cp1 = cp2 = name; *cp1 != '\0'; cp1++)
87: if (isprint(*cp1) || *cp1 == ' ')
88: *cp2++ = *cp1;
89: *cp2 = '\0';
90:
91: # ifdef INTERNET
92: if (mode == C_MESSAGE) {
93: char buf[BUFSIZ + 1];
94: int n;
95:
96: if (team == ' ')
97: (void) sprintf(buf, "%s: ", name);
98: else
99: (void) sprintf(buf, "%s[%c]: ", name, team);
100: n = strlen(buf);
101: for (pp = Player; pp < End_player; pp++) {
102: cgoto(pp, HEIGHT, 0);
103: outstr(pp, buf, n);
104: }
105: while ((n = read(newsock, buf, BUFSIZ)) > 0)
106: for (pp = Player; pp < End_player; pp++)
107: outstr(pp, buf, n);
108: for (pp = Player; pp < End_player; pp++) {
109: ce(pp);
110: sendcom(pp, REFRESH);
111: sendcom(pp, READY, 0);
112: (void) fflush(pp->p_output);
113: }
114: (void) close(newsock);
115: return FALSE;
116: }
117: else
118: # endif
119: # ifdef MONITOR
120: if (mode == C_MONITOR)
121: if (End_monitor < &Monitor[MAXMON])
122: pp = End_monitor++;
123: else {
124: socklen = 0;
125: (void) write(newsock, (char *) &socklen,
126: sizeof socklen);
127: (void) close(newsock);
128: return FALSE;
129: }
130: else
131: # endif MONITOR
132: if (End_player < &Player[MAXPL])
133: pp = End_player++;
134: else {
135: socklen = 0;
136: (void) write(newsock, (char *) &socklen,
137: sizeof socklen);
138: (void) close(newsock);
139: return FALSE;
140: }
141:
142: #ifdef MONITOR
143: if (mode == C_MONITOR && team == ' ')
144: team = '*';
145: #endif
146: pp->p_ident = get_ident(machine, uid, name, team);
147: pp->p_output = fdopen(newsock, "w");
148: pp->p_death[0] = '\0';
149: pp->p_fd = newsock;
150: pp->p_mask = (1 << pp->p_fd);
151: Fds_mask |= pp->p_mask;
152: if (pp->p_fd >= Num_fds)
153: Num_fds = pp->p_fd + 1;
154:
155: pp->p_y = 0;
156: pp->p_x = 0;
157:
158: # ifdef MONITOR
159: if (mode == C_MONITOR)
160: stmonitor(pp);
161: else
162: # endif MONITOR
163: stplayer(pp, enter_status);
164: return TRUE;
165: }
166:
167: # ifdef MONITOR
168: stmonitor(pp)
169: register PLAYER *pp;
170: {
171: register int line;
172: register PLAYER *npp;
173:
174: bcopy((char *) Maze, (char *) pp->p_maze, sizeof Maze);
175:
176: drawmaze(pp);
177:
178: (void) sprintf(Buf, "%5.5s%c%-10.10s %c", " ", stat_char(pp),
179: pp->p_ident->i_name, pp->p_ident->i_team);
180: line = STAT_MON_ROW + 1 + (pp - Monitor);
181: for (npp = Player; npp < End_player; npp++) {
182: cgoto(npp, line, STAT_NAME_COL);
183: outstr(npp, Buf, STAT_NAME_LEN);
184: }
185: for (npp = Monitor; npp < End_monitor; npp++) {
186: cgoto(npp, line, STAT_NAME_COL);
187: outstr(npp, Buf, STAT_NAME_LEN);
188: }
189:
190: sendcom(pp, REFRESH);
191: sendcom(pp, READY, 0);
192: (void) fflush(pp->p_output);
193: }
194: # endif MONITOR
195:
196: stplayer(newpp, enter_status)
197: register PLAYER *newpp;
198: int enter_status;
199: {
200: register int x, y;
201: register PLAYER *pp;
202:
203: Nplayer++;
204:
205: for (y = 0; y < UBOUND; y++)
206: for (x = 0; x < WIDTH; x++)
207: newpp->p_maze[y][x] = Maze[y][x];
208: for ( ; y < DBOUND; y++) {
209: for (x = 0; x < LBOUND; x++)
210: newpp->p_maze[y][x] = Maze[y][x];
211: for ( ; x < RBOUND; x++)
212: newpp->p_maze[y][x] = SPACE;
213: for ( ; x < WIDTH; x++)
214: newpp->p_maze[y][x] = Maze[y][x];
215: }
216: for ( ; y < HEIGHT; y++)
217: for (x = 0; x < WIDTH; x++)
218: newpp->p_maze[y][x] = Maze[y][x];
219:
220: do {
221: x = rand_num(WIDTH - 1) + 1;
222: y = rand_num(HEIGHT - 1) + 1;
223: } while (Maze[y][x] != SPACE);
224: newpp->p_over = SPACE;
225: newpp->p_x = x;
226: newpp->p_y = y;
227: newpp->p_undershot = FALSE;
228:
229: # ifdef FLY
230: if (enter_status == Q_FLY) {
231: newpp->p_flying = rand_num(20);
232: newpp->p_flyx = 2 * rand_num(6) - 5;
233: newpp->p_flyy = 2 * rand_num(6) - 5;
234: newpp->p_face = FLYER;
235: }
236: else
237: # endif FLY
238: {
239: newpp->p_flying = -1;
240: newpp->p_face = rand_dir();
241: }
242: newpp->p_damage = 0;
243: newpp->p_damcap = MAXDAM;
244: newpp->p_nchar = 0;
245: newpp->p_ncount = 0;
246: newpp->p_nexec = 0;
247: newpp->p_ammo = ISHOTS;
248: # ifdef BOOTS
249: newpp->p_nboots = 0;
250: # endif BOOTS
251: if (enter_status == Q_SCAN) {
252: newpp->p_scan = SCANLEN;
253: newpp->p_cloak = 0;
254: }
255: else {
256: newpp->p_scan = 0;
257: newpp->p_cloak = CLOAKLEN;
258: }
259: newpp->p_ncshot = 0;
260:
261: do {
262: x = rand_num(WIDTH - 1) + 1;
263: y = rand_num(HEIGHT - 1) + 1;
264: } while (Maze[y][x] != SPACE);
265: Maze[y][x] = GMINE;
266: # ifdef MONITOR
267: for (pp = Monitor; pp < End_monitor; pp++)
268: check(pp, y, x);
269: # endif MONITOR
270:
271: do {
272: x = rand_num(WIDTH - 1) + 1;
273: y = rand_num(HEIGHT - 1) + 1;
274: } while (Maze[y][x] != SPACE);
275: Maze[y][x] = MINE;
276: # ifdef MONITOR
277: for (pp = Monitor; pp < End_monitor; pp++)
278: check(pp, y, x);
279: # endif MONITOR
280:
281: (void) sprintf(Buf, "%5.2f%c%-10.10s %c", newpp->p_ident->i_score,
282: stat_char(newpp), newpp->p_ident->i_name,
283: newpp->p_ident->i_team);
284: y = STAT_PLAY_ROW + 1 + (newpp - Player);
285: for (pp = Player; pp < End_player; pp++) {
286: if (pp != newpp) {
287: char smallbuf[10];
288:
289: pp->p_ammo += NSHOTS;
290: newpp->p_ammo += NSHOTS;
291: cgoto(pp, y, STAT_NAME_COL);
292: outstr(pp, Buf, STAT_NAME_LEN);
293: (void) sprintf(smallbuf, "%3d", pp->p_ammo);
294: cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL);
295: outstr(pp, smallbuf, 3);
296: }
297: }
298: # ifdef MONITOR
299: for (pp = Monitor; pp < End_monitor; pp++) {
300: cgoto(pp, y, STAT_NAME_COL);
301: outstr(pp, Buf, STAT_NAME_LEN);
302: }
303: # endif MONITOR
304:
305: drawmaze(newpp);
306: drawplayer(newpp, TRUE);
307: look(newpp);
308: # ifdef FLY
309: if (enter_status == Q_FLY)
310: /* Make sure that the position you enter in will be erased */
311: showexpl(newpp->p_y, newpp->p_x, FLYER);
312: # endif
313: sendcom(newpp, REFRESH);
314: sendcom(newpp, READY, 0);
315: (void) fflush(newpp->p_output);
316: }
317:
318: /*
319: * rand_dir:
320: * Return a random direction
321: */
322: rand_dir()
323: {
324: switch (rand_num(4)) {
325: case 0:
326: return LEFTS;
327: case 1:
328: return RIGHT;
329: case 2:
330: return BELOW;
331: case 3:
332: return ABOVE;
333: }
334: /* NOTREACHED */
335: }
336:
337: /*
338: * get_ident:
339: * Get the score structure of a player
340: */
341: IDENT *
342: get_ident(machine, uid, name, team)
343: u_long machine;
344: u_long uid;
345: char *name;
346: char team;
347: {
348: register IDENT *ip;
349: static IDENT punt;
350:
351: for (ip = Scores; ip != NULL; ip = ip->i_next)
352: if (ip->i_machine == machine
353: && ip->i_uid == uid
354: && ip->i_team == team
355: && strncmp(ip->i_name, name, NAMELEN) == 0)
356: break;
357:
358: if (ip != NULL) {
359: if (ip->i_entries < SCOREDECAY)
360: ip->i_entries++;
361: else
362: ip->i_kills = (ip->i_kills * (SCOREDECAY - 1))
363: / SCOREDECAY;
364: ip->i_score = ip->i_kills / (double) ip->i_entries;
365: }
366: else {
367: ip = (IDENT *) malloc(sizeof (IDENT));
368: if (ip == NULL) {
369: /* Fourth down, time to punt */
370: ip = &punt;
371: }
372: ip->i_machine = machine;
373: ip->i_team = team;
374: ip->i_uid = uid;
375: strncpy(ip->i_name, name, NAMELEN);
376: ip->i_kills = 0;
377: ip->i_entries = 1;
378: ip->i_score = 0;
379: ip->i_absorbed = 0;
380: ip->i_faced = 0;
381: ip->i_shot = 0;
382: ip->i_robbed = 0;
383: ip->i_slime = 0;
384: ip->i_missed = 0;
385: ip->i_ducked = 0;
386: ip->i_gkills = ip->i_bkills = ip->i_deaths = 0;
387: ip->i_stillb = ip->i_saved = 0;
388: ip->i_next = Scores;
389: Scores = ip;
390: }
391:
392: return ip;
393: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.