|
|
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.