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: }