📄 driver.c
字号:
/* * Hunt * Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold * San Francisco, California */# include "hunt.h"# include <signal.h># include <errno.h># include <sys/ioctl.h># include <sys/time.h># ifndef pdp11# define RN (((Seed = Seed * 11109 + 13849) >> 16) & 0xffff)# else# define RN ((Seed = Seed * 11109 + 13849) & 0x7fff)# endifint Seed = 0;SOCKET Daemon;char *First_arg; /* pointer to argv[0] */char *Last_arg; /* pointer to end of argv/environ */# ifdef INTERNETint Test_socket; /* test socket to answer datagrams */FLAG inetd_spawned; /* invoked via inetd */FLAG standard_port = TRUE; /* true if listening on standard port */u_short sock_port; /* port # of tcp listen socket */u_short stat_port; /* port # of statistics tcp socket */# define DAEMON_SIZE (sizeof Daemon)# else# define DAEMON_SIZE (sizeof Daemon - 1)# endifextern SIGNAL_TYPE cleanup();/* * main: * The main program. */main(ac, av, ep)int ac;char **av, **ep;{ register PLAYER *pp; register int had_char;# ifdef INTERNET register long test_mask; u_short msg; short port_num, reply; int namelen; SOCKET test;# endif static long read_fds; static FLAG first = TRUE; static FLAG server = FALSE; extern int optind; extern char *optarg; int c; static struct timeval linger = { 90, 0 }; First_arg = av[0]; if (ep == NULL || *ep == NULL) ep = av + ac; while (*ep) ep++; Last_arg = ep[-1] + strlen(ep[-1]); while ((c = getopt(ac, av, "sp:")) != EOF) { switch (c) { case 's': server = TRUE; break;# ifdef INTERNET case 'p': standard_port = FALSE; Test_port = atoi(optarg); break;# endif default:erred: fprintf(stderr, "Usage: %s [-s] [-p port]\n", av[0]); exit(1); } } if (optind < ac) goto erred; init(); Sock_mask = (1 << Socket); Stat_mask = (1 << Status);# ifdef INTERNET test_mask = (1 << Test_socket);# endifagain: do { read_fds = Fds_mask; errno = 0; while (select(Num_fds, &read_fds, (int *) NULL, (int *) NULL, (struct timeval *) NULL) < 0) { if (errno != EINTR)# ifdef LOG syslog(LOG_WARNING, "select: %m");# else perror("select");# endif errno = 0; } Have_inp = read_fds;# ifdef INTERNET if (read_fds & test_mask) { namelen = DAEMON_SIZE; port_num = htons(sock_port); (void) recvfrom(Test_socket, (char *) &msg, sizeof msg, 0, (struct sockaddr *) &test, &namelen); switch (ntohs(msg)) { case C_MESSAGE: if (Nplayer <= 0) break; reply = htons((u_short) Nplayer); (void) sendto(Test_socket, (char *) &reply, sizeof reply, 0, (struct sockaddr *) &test, DAEMON_SIZE); break; case C_SCORES: reply = htons(stat_port); (void) sendto(Test_socket, (char *) &reply, sizeof reply, 0, (struct sockaddr *) &test, DAEMON_SIZE); break; case C_PLAYER: case C_MONITOR: if (msg == C_MONITOR && Nplayer <= 0) break; reply = htons(sock_port); (void) sendto(Test_socket, (char *) &reply, sizeof reply, 0, (struct sockaddr *) &test, DAEMON_SIZE); break; } }# endif for (;;) { had_char = FALSE; for (pp = Player; pp < End_player; pp++) if (havechar(pp)) { execute(pp); pp->p_nexec++; had_char++; }# ifdef MONITOR for (pp = Monitor; pp < End_monitor; pp++) if (havechar(pp)) { mon_execute(pp); pp->p_nexec++; had_char++; }# endif if (!had_char) break; moveshots(); for (pp = Player; pp < End_player; ) if (pp->p_death[0] != '\0') zap(pp, TRUE); else pp++;# ifdef MONITOR for (pp = Monitor; pp < End_monitor; ) if (pp->p_death[0] != '\0') zap(pp, FALSE); else pp++;# endif } if (read_fds & Sock_mask) if (answer()) {# ifdef INTERNET if (first && standard_port) faketalk();# endif first = FALSE; } if (read_fds & Stat_mask) send_stats(); for (pp = Player; pp < End_player; pp++) { if (read_fds & pp->p_mask) sendcom(pp, READY, pp->p_nexec); pp->p_nexec = 0; (void) fflush(pp->p_output); }# ifdef MONITOR for (pp = Monitor; pp < End_monitor; pp++) { if (read_fds & pp->p_mask) sendcom(pp, READY, pp->p_nexec); pp->p_nexec = 0; (void) fflush(pp->p_output); }# endif } while (Nplayer > 0); read_fds = Fds_mask; if (select(Num_fds, &read_fds, (int *) NULL, (int *) NULL, &linger) > 0) { goto again; } if (server) { clear_scores(); makemaze(); clearwalls();# ifdef BOOTS makeboots();# endif first = TRUE; goto again; }# ifdef MONITOR for (pp = Monitor; pp < End_monitor; ) zap(pp, FALSE);# endif cleanup(0);}/* * init: * Initialize the global parameters. */init(){ register int i;# ifdef INTERNET auto SOCKET test_port; auto int msg; auto int len;# endif# ifndef DEBUG# ifdef TIOCNOTTY (void) ioctl(fileno(stdout), TIOCNOTTY, NULL);# endif (void) setpgrp(getpid(), getpid()); (void) signal(SIGHUP, SIG_IGN); (void) signal(SIGINT, SIG_IGN); (void) signal(SIGQUIT, SIG_IGN); (void) signal(SIGTERM, cleanup);# endif (void) chdir("/usr/tmp"); /* just in case it core dumps */ (void) umask(0); /* No privacy at all! */ (void) signal(SIGPIPE, SIG_IGN);# ifdef LOG# ifdef SYSLOG_43 openlog("HUNT", LOG_PID, LOG_DAEMON);# endif# ifdef SYSLOG_42 openlog("HUNT", LOG_PID);# endif# endif /* * Initialize statistics socket */# ifdef INTERNET Daemon.sin_family = SOCK_FAMILY; Daemon.sin_addr.s_addr = INADDR_ANY; Daemon.sin_port = 0;# else Daemon.sun_family = SOCK_FAMILY; (void) strcpy(Daemon.sun_path, Stat_name);# endif Status = socket(SOCK_FAMILY, SOCK_STREAM, 0); if (bind(Status, (struct sockaddr *) &Daemon, DAEMON_SIZE) < 0) { if (errno == EADDRINUSE) exit(0); else {# ifdef LOG syslog(LOG_ERR, "bind: %m");# else perror("bind");# endif cleanup(1); } } (void) listen(Status, 5);# ifdef INTERNET len = sizeof (SOCKET); if (getsockname(Status, (struct sockaddr *) &Daemon, &len) < 0) {# ifdef LOG syslog(LOG_ERR, "getsockname: %m");# else perror("getsockname");# endif exit(1); } stat_port = ntohs(Daemon.sin_port);# endif /* * Initialize main socket */# ifdef INTERNET Daemon.sin_family = SOCK_FAMILY; Daemon.sin_addr.s_addr = INADDR_ANY; Daemon.sin_port = 0;# else Daemon.sun_family = SOCK_FAMILY; (void) strcpy(Daemon.sun_path, Sock_name);# endif Socket = socket(SOCK_FAMILY, SOCK_STREAM, 0);# if defined(INTERNET) msg = 1; if (setsockopt(Socket, SOL_SOCKET, SO_USELOOPBACK, &msg, sizeof msg)<0)# ifdef LOG syslog(LOG_WARNING, "setsockopt loopback %m");# else perror("setsockopt loopback");# endif# endif if (bind(Socket, (struct sockaddr *) &Daemon, DAEMON_SIZE) < 0) { if (errno == EADDRINUSE) exit(0); else {# ifdef LOG syslog(LOG_ERR, "bind: %m");# else perror("bind");# endif cleanup(1); } } (void) listen(Socket, 5);# ifdef INTERNET len = sizeof (SOCKET); if (getsockname(Socket, (struct sockaddr *) &Daemon, &len) < 0) {# ifdef LOG syslog(LOG_ERR, "getsockname: %m");# else perror("getsockname");# endif exit(1); } sock_port = ntohs(Daemon.sin_port);# endif /* * Initialize minimal select mask */ Fds_mask = (1 << Socket) | (1 << Status); Num_fds = ((Socket > Status) ? Socket : Status) + 1;# ifdef INTERNET len = sizeof (SOCKET); if (getsockname(0, (struct sockaddr *) &test_port, &len) >= 0 && test_port.sin_family == AF_INET) { inetd_spawned = TRUE; Test_socket = 0; if (test_port.sin_port != htons((u_short) Test_port)) { standard_port = FALSE; Test_port = ntohs(test_port.sin_port); } } else { test_port = Daemon; test_port.sin_port = htons((u_short) Test_port); Test_socket = socket(SOCK_FAMILY, SOCK_DGRAM, 0); if (bind(Test_socket, (struct sockaddr *) &test_port, DAEMON_SIZE) < 0) {# ifdef LOG syslog(LOG_ERR, "bind: %m");# else perror("bind");# endif exit(1); } (void) listen(Test_socket, 5); } Fds_mask |= (1 << Test_socket); if (Test_socket + 1 > Num_fds) Num_fds = Test_socket + 1;# endif Seed = getpid() + time((time_t *) NULL); makemaze();# ifdef BOOTS makeboots();# endif for (i = 0; i < NASCII; i++) See_over[i] = TRUE; See_over[DOOR] = FALSE; See_over[WALL1] = FALSE; See_over[WALL2] = FALSE; See_over[WALL3] = FALSE;# ifdef REFLECT See_over[WALL4] = FALSE; See_over[WALL5] = FALSE;# endif}# ifdef BOOTS/* * makeboots: * Put the boots in the maze */makeboots(){ register int x, y; register PLAYER *pp; do { x = rand_num(WIDTH - 1) + 1; y = rand_num(HEIGHT - 1) + 1; } while (Maze[y][x] != SPACE); Maze[y][x] = BOOT_PAIR; for (pp = Boot; pp < &Boot[NBOOTS]; pp++) pp->p_flying = -1;}# endif/* * checkdam: * Check the damage to the given player, and see if s/he is killed */checkdam(ouch, gotcha, credit, amt, shot_type)register PLAYER *ouch, *gotcha;register IDENT *credit;int amt;char shot_type;{ register char *cp; if (ouch->p_death[0] != '\0') return;# ifdef BOOTS if (shot_type == SLIME) switch (ouch->p_nboots) { default: break; case 1: amt = (amt + 1) / 2; break; case 2: if (gotcha != NULL) message(gotcha, "He has boots on!"); return; }# endif ouch->p_damage += amt; if (ouch->p_damage <= ouch->p_damcap) { (void) sprintf(Buf, "%2d", ouch->p_damage); cgoto(ouch, STAT_DAM_ROW, STAT_VALUE_COL); outstr(ouch, Buf, 2); return; } /* Someone DIED */ switch (shot_type) { default: cp = "Killed"; break;# ifdef FLY case FALL: cp = "Killed on impact"; break;# endif case KNIFE: cp = "Stabbed to death";
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -