|
|
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 <errno.h>
13:
14: # define MAXPERMACH 3 /* Max player/monitor per machine */
15:
16: static char Ttyname[NAMELEN];
17:
18: answer()
19: {
20: register PLAYER *pp;
21: register int newsock;
22: register FILE *tmpfd;
23: # ifdef MONITOR
24: static FLAG monitor;
25: # endif MONITOR
26: static char name[NAMELEN];
27: static int socklen;
28: static u_long machine;
29: static u_long uid;
30: static SOCKET sockstruct;
31: # ifdef OLDIPC
32: extern SOCKET Daemon;
33: # endif OLDIPC
34:
35: # ifdef INTERNET
36: socklen = sizeof sockstruct;
37: # else
38: socklen = sizeof sockstruct - 1;
39: # endif INTERNET
40: errno = 0;
41: # ifndef OLDIPC
42: if ((newsock = accept(Socket, &sockstruct, &socklen)) < 0)
43: # else OLDIPC
44: if (accept(Socket, &sockstruct) < 0)
45: # endif OLDIPC
46: {
47: if (errno == EINTR)
48: return;
49: perror("accept");
50: cleanup(1);
51: }
52: # ifdef OLDIPC
53: newsock = Socket;
54: Socket = socket(SOCK_STREAM, 0, (struct sockaddr *) &Daemon,
55: SO_ACCEPTCONN);
56: if (Socket < 0) {
57: perror("new accept socket");
58: cleanup(1);
59: }
60: Sock_mask = (1 << Socket);
61: Fds_mask |= Sock_mask;
62: if (Socket >= Num_fds)
63: Num_fds = Socket + 1;
64: # endif OLDIPC
65:
66: tmpfd = fdopen(newsock, "w");
67:
68: # ifdef INTERNET
69: machine = ntohl(((struct sockaddr_in *) &sockstruct)->sin_addr.s_addr);
70: # else INTERNET
71: if (machine == 0)
72: machine = gethostid();
73: # endif INTERNET
74: (void) putw(getpid(), tmpfd);
75: (void) read(newsock, (char *) &uid, sizeof uid);
76: uid = ntohl(uid);
77: (void) read(newsock, name, NAMELEN);
78: (void) read(newsock, Ttyname, NAMELEN);
79: # ifdef MONITOR
80: (void) read(newsock, (char *) &monitor, sizeof monitor);
81: # endif MONITOR
82:
83: if (reached_limit(machine)) {
84: socklen = 0;
85: (void) write(newsock, (char *) &socklen, sizeof socklen);
86: (void) close(newsock);
87: # ifdef OLDIPC
88: Fds_mask &= ~(1 << newsock);
89: # endif OLDIPC
90: return;
91: }
92:
93: # ifdef MONITOR
94: if (monitor)
95: if (End_monitor < &Monitor[MAXMON])
96: pp = End_monitor++;
97: else {
98: socklen = 0;
99: (void) write(newsock, (char *) &socklen,
100: sizeof socklen);
101: (void) close(newsock);
102: return;
103: }
104: else
105: # endif MONITOR
106: if (End_player < &Player[MAXPL])
107: pp = End_player++;
108: else {
109: socklen = 0;
110: (void) write(newsock, (char *) &socklen,
111: sizeof socklen);
112: (void) close(newsock);
113: return;
114: }
115:
116: pp->p_ident = get_ident(machine, uid, name);
117: pp->p_output = tmpfd;
118: pp->p_death[0] = '\0';
119: pp->p_fd = newsock;
120: pp->p_mask = (1 << pp->p_fd);
121: # ifndef OLDIPC
122: Fds_mask |= pp->p_mask;
123: if (pp->p_fd >= Num_fds)
124: Num_fds = pp->p_fd + 1;
125: # endif OLDIPC
126:
127: pp->p_y = 0;
128: pp->p_x = 0;
129:
130: # ifdef MONITOR
131: if (monitor)
132: stmonitor(pp);
133: else
134: # endif MONITOR
135: stplayer(pp);
136: }
137:
138: # ifdef MONITOR
139: stmonitor(pp)
140: register PLAYER *pp;
141: {
142: register int line;
143: register PLAYER *npp;
144:
145: bcopy((char *) Maze, (char *) pp->p_maze, sizeof Maze);
146:
147: drawmaze(pp);
148:
149: (void) sprintf(Buf, "%5.5s%c%-10.10s", " ", stat_char(pp),
150: pp->p_ident->i_name);
151: line = STAT_MON_ROW + 1 + (pp - Monitor);
152: for (npp = Player; npp < End_player; npp++) {
153: cgoto(npp, line, STAT_NAME_COL);
154: outstr(npp, Buf, STAT_NAME_LEN);
155: }
156: for (npp = Monitor; npp < End_monitor; npp++) {
157: cgoto(npp, line, STAT_NAME_COL);
158: outstr(npp, Buf, STAT_NAME_LEN);
159: }
160:
161: sendcom(pp, REFRESH);
162: sendcom(pp, READY, 0);
163: (void) fflush(pp->p_output);
164: }
165: # endif MONITOR
166:
167: stplayer(newpp)
168: register PLAYER *newpp;
169: {
170: register int x, y;
171: register PLAYER *pp;
172:
173: Nplayer++;
174:
175: for (y = 0; y < UBOUND; y++)
176: for (x = 0; x < WIDTH; x++)
177: newpp->p_maze[y][x] = Maze[y][x];
178: for ( ; y < DBOUND; y++) {
179: for (x = 0; x < LBOUND; x++)
180: newpp->p_maze[y][x] = Maze[y][x];
181: for ( ; x < RBOUND; x++)
182: newpp->p_maze[y][x] = SPACE;
183: for ( ; x < WIDTH; x++)
184: newpp->p_maze[y][x] = Maze[y][x];
185: }
186: for ( ; y < HEIGHT; y++)
187: for (x = 0; x < WIDTH; x++)
188: newpp->p_maze[y][x] = Maze[y][x];
189:
190: do {
191: x = rand_num(WIDTH - 1) + 1;
192: y = rand_num(HEIGHT - 1) + 1;
193: } while (Maze[y][x] != SPACE);
194: newpp->p_over = SPACE;
195: newpp->p_x = x;
196: newpp->p_y = y;
197: newpp->p_undershot = FALSE;
198:
199: # ifdef START_FLYING
200: /* This is only for debugging */
201: newpp->p_flying = rand_num(20);
202: newpp->p_flyx = 2 * rand_num(6) - 5;
203: newpp->p_flyy = 2 * rand_num(6) - 5;
204: newpp->p_face = FLYER;
205: # else START_FLYING
206: newpp->p_flying = -1;
207: rand_face(newpp);
208: # endif START_FLYING
209: newpp->p_damage = 0;
210: newpp->p_damcap = MAXDAM;
211: newpp->p_nchar = 0;
212: newpp->p_ncount = 0;
213: newpp->p_nexec = 0;
214: newpp->p_ammo = ISHOTS;
215: newpp->p_scan = -1;
216: newpp->p_cloak = CLOAKLEN;
217: newpp->p_ncshot = 0;
218:
219: do {
220: x = rand_num(WIDTH - 1) + 1;
221: y = rand_num(HEIGHT - 1) + 1;
222: } while (Maze[y][x] != SPACE);
223: Maze[y][x] = GMINE;
224: # ifdef MONITOR
225: for (pp = Monitor; pp < End_monitor; pp++)
226: check(pp, y, x);
227: # endif MONITOR
228:
229: do {
230: x = rand_num(WIDTH - 1) + 1;
231: y = rand_num(HEIGHT - 1) + 1;
232: } while (Maze[y][x] != SPACE);
233: Maze[y][x] = MINE;
234: # ifdef MONITOR
235: for (pp = Monitor; pp < End_monitor; pp++)
236: check(pp, y, x);
237: # endif MONITOR
238:
239: (void) sprintf(Buf, "%5.2f%c%-10.10s", newpp->p_ident->i_score,
240: stat_char(newpp), newpp->p_ident->i_name);
241: y = STAT_PLAY_ROW + 1 + (newpp - Player);
242: for (pp = Player; pp < End_player; pp++) {
243: if (pp != newpp) {
244: char smallbuf[10];
245:
246: pp->p_ammo += NSHOTS;
247: newpp->p_ammo += NSHOTS;
248: cgoto(pp, y, STAT_NAME_COL);
249: outstr(pp, Buf, STAT_NAME_LEN);
250: (void) sprintf(smallbuf, "%3d", pp->p_ammo);
251: cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL);
252: outstr(pp, smallbuf, 3);
253: }
254: }
255: # ifdef MONITOR
256: for (pp = Monitor; pp < End_monitor; pp++) {
257: cgoto(pp, y, STAT_NAME_COL);
258: outstr(pp, Buf, STAT_NAME_LEN);
259: }
260: # endif MONITOR
261:
262: drawmaze(newpp);
263: drawplayer(newpp, TRUE);
264: look(newpp);
265: # ifdef START_FLYING
266: /* Make sure that the position you enter in will be erased */
267: showexpl(newpp->p_y, newpp->p_x, FLYER);
268: # endif START_FLYING
269: sendcom(newpp, REFRESH);
270: sendcom(newpp, READY, 0);
271: (void) fflush(newpp->p_output);
272: }
273:
274: /*
275: * rand_face:
276: * Give the player a random facing direction
277: */
278: rand_face(pp)
279: register PLAYER *pp;
280: {
281: switch (rand_num(4)) {
282: case 0:
283: pp->p_face = LEFTS;
284: break;
285: case 1:
286: pp->p_face = RIGHT;
287: break;
288: case 2:
289: pp->p_face = BELOW;
290: break;
291: case 3:
292: pp->p_face = ABOVE;
293: break;
294: }
295: }
296:
297: /*
298: * get_ident:
299: * Get the score structure of a player
300: */
301: IDENT *
302: get_ident(machine, uid, name)
303: u_long machine;
304: u_long uid;
305: char *name;
306: {
307: register IDENT *ip;
308: static IDENT punt;
309:
310: for (ip = Scores; ip != NULL; ip = ip->i_next)
311: if (ip->i_machine == machine && ip->i_uid == uid &&
312: strncmp(ip->i_name, name, NAMELEN) == 0)
313: break;
314:
315: if (ip != NULL) {
316: ip->i_entries++;
317: ip->i_score = ip->i_kills / (double) ip->i_entries;
318: }
319: else {
320: ip = (IDENT *) malloc(sizeof (IDENT));
321: if (ip == NULL) {
322: /* Fourth down, time to punt */
323: ip = &punt;
324: }
325: ip->i_machine = machine;
326: ip->i_uid = uid;
327: strncpy(ip->i_name, name, NAMELEN);
328: ip->i_kills = 0;
329: ip->i_entries = 1;
330: ip->i_score = 0;
331: ip->i_next = Scores;
332: Scores = ip;
333: }
334:
335: return ip;
336: }
337:
338: /*
339: * reached_limit:
340: * Returns whether the limit of x persons per machine has been reached
341: */
342: reached_limit(machine)
343: u_long machine;
344: {
345: register PLAYER *pp;
346: register int count;
347:
348: count = 0;
349: for (pp = Player; pp < End_player; pp++)
350: if (pp->p_ident->i_machine == machine)
351: count++;
352: for (pp = Monitor; pp < End_monitor; pp++)
353: if (pp->p_ident->i_machine == machine)
354: count++;
355: return count >= MAXPERMACH;
356: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.