void parsemeta() /* Read and Parse the metaserver information, either from the metaservers * by UDP (1), from a single metaserver by TCP (3), or from the cache (2). */ { statusLevel = intDefault("metaStatusLevel", defaultStatLevel); if (statusLevel < 0) statusLevel = 0; else if (statusLevel >= statusNull) statusLevel = statusNull - 1; ReadMetasSend(); LoadMetasCache(); metaHeight = 2 + N_OVERHEAD; }
static int ReadMetasSend() { char *metaservers; /* our copy of the metaserver host names */ char *token; /* current metaserver host name */ struct sockaddr_in address; /* the address of the metaservers */ static char *req; /* the request packet for the metaserver */ static int reqlen; /* the length of the request packet */ last = time(NULL); /* host names of metaservers, default in data.c, comma delimited */ if ((getdefault("metaserver")) != NULL) metaserver = getdefault("metaserver"); /* port number of metaservers, unlikely to change, not a list */ metaport = intDefault("metaport", metaport); /* whether to report everything that happens */ verbose = booleanDefault("metaverbose", verbose); /* create the socket */ if (msock < 0) { msock = socket(AF_INET, SOCK_DGRAM, 0); if (msock < 0) { perror("ReadMetasSend: socket"); return 0; } /* bind the socket to any address */ address.sin_addr.s_addr = INADDR_ANY; address.sin_family = AF_INET; address.sin_port = 0; if (bind(msock,(struct sockaddr *)&address, sizeof(address)) < 0) { perror("ReadMetasSend: bind"); close(msock); return 0; } req = malloc(80); snprintf(req, 80, "?version=netrek-client-cow-%s.%d", mvers, PATCHLEVEL); reqlen = strlen(req); } /* send request to a multicast metaserver on local area network */ address.sin_family = AF_INET; address.sin_port = htons(metaport); address.sin_addr.s_addr = inet_addr("224.0.0.1"); if (verbose) fprintf(stderr, "requesting player list from nearby servers on %s\n", inet_ntoa(address.sin_addr)); if (sendto(msock, req, reqlen, 0, (struct sockaddr *)&address, sizeof(address)) < 0) { perror("ReadMetasSend: sendto"); } else { sent++; } /* try each of the comma delimited metaserver host names */ metaservers = strdup(metaserver); token = strtok(metaservers,","); while (token != NULL) { /* compose the address structure */ address.sin_family = AF_INET; address.sin_port = htons(metaport); /* skip any blanks */ while (*token == ' ') token++; /* attempt numeric translation first */ if ((address.sin_addr.s_addr = inet_addr(token)) == -1) { struct hostent *hp; /* then translation by name */ if ((hp = gethostbyname(token)) == NULL) { /* if it didn't work, return failure and warning */ fprintf(stderr, "cannot resolve host %s, check for DNS problems?\n", token); } else { int i; /* resolution worked, send a query to every metaserver listed */ for(i=0;;i++) { /* check for end of list of addresses */ if (hp->h_addr_list[i] == NULL) break; address.sin_addr.s_addr = *(long *) hp->h_addr_list[i]; if (verbose) fprintf(stderr, "requesting player list from metaserver %s at %s\n", token, inet_ntoa(address.sin_addr)); if (sendto(msock, req, reqlen, 0, (struct sockaddr *)&address, sizeof(address)) < 0) { perror("ReadMetasSend: sendto"); } else { sent++; } } } } else { /* call to inet_addr() worked, host name is in IP address form */ if (verbose) fprintf(stderr, "requesting player list from metaserver %s\n", inet_ntoa(address.sin_addr)); if (sendto(msock, req, reqlen, 0, (struct sockaddr *)&address, sizeof(address)) < 0) { perror("ReadMetasSend: sendto"); } else { sent++; } } /* look for next host name in list */ token = strtok(NULL,","); } /* while (token != NULL) */ metaWindowName = "Netrek Server List"; return sent; }
int main(int argc, char **argv) { int team, s_type; char *dpyname = NULL; int usage = 0; int err = 0; char *name, *ptr, *cp; struct passwd *pwent; int passive = 0; int xpmopt = 1; int useORopt = 0; int useCookieOpt = 0; int dontUseCookieOpt = 0; /* char *defaultsFile=NULL;*/ pseudo[0] = defpasswd[0] = '\0'; name = *argv++; argc--; if ((ptr = strrchr(name, '/')) != NULL) name = ptr + 1; while (*argv) { if (**argv != '-') { serverName = *argv; /* don't abort argument processing */ argv++; argc--; } else { ++*argv; argc--; ptr = *argv++; while (*ptr) { switch (*ptr) { case 'C': /* character name */ (void) strncpy(pseudo, *argv, sizeof(pseudo)); argv++; argc--; break; case 'P': /* authorization password */ (void) strncpy(defpasswd, *argv, sizeof(defpasswd)); { int i; for (i = 0; (*argv)[i]; i++) (*argv)[i] = 0; } argv++; argc--; break; case 'u': usage++; break; case 's': if (*argv) { xtrekPort = atoi(*argv); passive = 1; argv++; argc--; } break; case 'p': if (*argv) { xtrekPort = atoi(*argv); argv++; argc--; } break; case 'd': dpyname = *argv; argc--; argv++; break; case 'm': usemeta = 1; break; case 'h': serverName = *argv; argc--; argv++; break; case 't': title = *argv; argc--; argv++; break; case 'r': defaultsFile = *argv; argv++; argc--; break; #ifdef AUTHORIZE case 'o': RSA_Client = -1; break; case 'R': RSA_Client = -2; break; #else case 'o': case 'R': printf("This client does not have binary authorization.\n"); break; #endif case 'e': #ifdef AUTHORIZE checkExpire(1); #else printf("This client does not RSA verify and will not expire.\n"); #endif exit(0); break; case 'f': /* list ftp sites */ fprintf(stderr, "\n\ The newest version of the Paradise client can be found at:\n\ ftp.netrek.org in /pub/netrek/paradise/bin/\n"); exit(0); case 'G': if (*argv) { ghoststart++; ghost_pno = atoi(*argv); printf("Emergency restart being attempted...\n"); argv++; argc--; } break; case '2': /* force paradise */ paradise = 1; break; case 'F': /* File playback */ if (*argv) { playFile = strdup(*argv); playback = 1; argv++; argc--; } break; case 'x': xpmopt = 0; break; case 'k': /* cookie mode [BDyess] */ useCookieOpt = 1; break; case 'K': /* no-cookies :( [BDyess] */ dontUseCookieOpt = 1; break; case 'v': verbose_image_loading = 1; break; case 'O': /* turn on GXor image drawing [BDyess]*/ useORopt = 1; break; case 'c': /* dump .paradiserc defaults [BDyess] */ dump_defaults = 1; break; default: fprintf(stderr, "%s: unknown option '%c'\n", name, *ptr); err++; break; } ptr++; } } } inittrigtables(); initStars(); /* moved from redraw.c at KAO\'s suggestion */ if (usage || err) { printUsage(name); #ifdef AUTHORIZE checkExpire(1); #endif exit(0); /* exit(err); Exits from checkExpire */ } defaultsFile = initDefaults(defaultsFile); if(xpmopt) xpm = 1; else xpm = booleanDefault("xpm",xpm); if(xpm) printf("XPM mode enabled.\n"); /* command line option overrides .paradiserc value [BDyess] */ if(useORopt) useOR = 1; else useOR = booleanDefault("useOR",useOR); if(useOR) printf("OR mode enabled.\n"); if(useOR || !xpm) cookie = 0; /* default no-cookies unless in XPM mode w/out OR [BDyess] */ /* note: need a milk mode :) */ if(useCookieOpt) cookie = 1; else if(dontUseCookieOpt) cookie = 0; else cookie = booleanDefault("cookie",cookie); if(cookie) printf("Cookie mode enabled.\n"); #ifdef AUTHORIZE if (RSA_Client != -1) checkExpire(0); #endif /* compatability */ if (argc > 0) serverName = argv[0]; srandom(getpid() + time((long *) 0)); if(playback || booleanDefault("playback",0)) { defNickName = "playback"; usemeta=0; serverName = "playback"; } else { if (serverName) { char temp[80], *s; sprintf(temp, "server.%s", serverName); if ((s = stringDefault(temp,NULL))) { printf("Using nickname \"%s\" for server %s\n", serverName, s); defNickName = serverName; serverName = s; defFlavor = stringDefault("flavor",NULL); } } if (!serverName) { serverName = stringDefault("server",NULL); } if (!serverName && !passive) { serverName = DEFAULT_SERVER; usemeta = 1; /* no server specified, show the menu */ } if (passive) serverName = "passive"; /* newwin gets a wrong title otherwise */ if (xtrekPort < 0) xtrekPort = intDefault("port", -1); if (xtrekPort < 0) xtrekPort = DEFAULT_PORT; } /* playback */ build_default_configuration(); metaserverAddress = stringDefault("metaserver", "metaserver.netrek.org"); if (usemeta) openmeta(); W_Initialize(dpyname); metaFork = booleanDefault("metaFork", metaFork); /* do the metawindow thang */ if (usemeta) { metawindow(); metainput(); if (metaFork) W_Initialize(dpyname); newwin(dpyname, name); } else /* this creates the necessary x windows for the game */ newwin(dpyname, name); /* open memory...? */ openmem(); if (!startPlayback()) { if (!passive) { serverName = callServer(xtrekPort, serverName); } else { connectToServer(xtrekPort); } } sendFeature("FEATURE_PACKETS", 'S', 1, 0, 0); timeStart = time(NULL); findslot(); /* sets all the settings from defaults file (.xtrekrc probably) */ resetDefaults(); #ifdef UNIX_SOUND init_sound(); play_sound(SND_PARADISE); #endif mapAll(); /* signal(SIGINT, SIG_IGN);*/ signal(SIGCHLD, reaper); /* Get login name */ if ((pwent = getpwuid(getuid())) != NULL) (void) strncpy(login, pwent->pw_name, sizeof(login)); else (void) strncpy(login, "Bozo", sizeof(login)); login[sizeof(login) - 1] = '\0'; if (pseudo[0] == '\0') { char *freeme; strncpy(pseudo, freeme = stringDefault("name",login), sizeof(pseudo)); free(freeme); } pseudo[sizeof(pseudo) - 1] = '\0'; if (defpasswd[0] == '\0') { char buf[100]; /* added password by character name -JR */ sprintf(buf,"password.%s",pseudo); if((cp = stringDefault(buf,NULL)) || (cp = stringDefault("password",NULL))) (void) strncpy(defpasswd, cp, sizeof(defpasswd)); } defpasswd[sizeof(defpasswd) - 1] = '\0'; /* sendLoginReq("Gray Lensman", "hh", "sfd", 0); loginAccept = -1; while (loginAccept == -1) { socketPause(1,0); readFromServer(); } */ getname(pseudo, defpasswd); loggedIn = 1; /* Set p_hostile to hostile, so if keeppeace is on, the guy starts off hating everyone (like a good fighter should) */ me->p_hostile = (1 << number_of_teams) - 1; redrawTstats(); me->p_planets = 0; me->p_genoplanets = 0; me->p_armsbomb = 0; me->p_genoarmsbomb = 0; /* Set up a reasonable default */ me->p_whydead = KNOREASON; me->p_teami = -1; s_type = defaultShip(CRUISER); /* from rlb7h 11/15/91 TC */ if (booleanDefault("netStats", 1)) startPing(); /* tell the server that we support pings */ /* hack to make galaxy class ships work. This could be more elegant, but the configuration code would have to be modified quite a bit, since the client doesn't know if it's on a paradise server until after it connects, and it needs the configuration info before it connects. */ init_galaxy_class(); initkeymap(-1); /* needs to have ship types initialized -JR */ setjmp(env); /* Reentry point of game */ if (ghoststart) { int i; ghoststart = 0; for (i = -1; i < 5; i++) if (teaminfo[i].letter == me->p_mapchars[0]) break; me->p_teami = i; if (me->p_damage > me->p_ship->s_maxdamage) { me->p_status = POUTFIT; } else me->p_status = PALIVE; } else me->p_status = POUTFIT; while (1) { switch (me->p_status) { case POUTFIT: case PTQUEUE: /* give the player the motd and find out which team he wants */ new_entrywindow(&team, &s_type); allowPlayerlist = 1; if (W_IsMapped(playerw)) playerlist(); if (!playback) if (team == -1) { W_DestroyWindow(w); sendByeReq(); sleep(1); printf("OK, bye!\n"); EXIT(0); } sendVersion(); myship = getship(myship->s_type); currentship = myship->s_type; /* sendOptionsPacket(); this would totally blast any flags you had on the server */ redrawall = 1; enter(); calibrate_stats(); W_ClearWindow(w); /* for (i = 0; i < NSIG; i++) { signal(i, SIG_IGN); } */ me->p_status = PALIVE; /* Put player in game */ #ifdef UNIX_SOUND kill_sound (); #endif hockeyInit(); if (showStats) /* Default showstats are on. */ W_MapWindow(statwin); if (showNewStats) /* default showNewStats are off. [BDyess] */ W_MapWindow(newstatwin); if (tryUdp && commMode != COMM_UDP) { sendUdpReq(COMM_UDP); } if (tryShort) { sendShortReq(SPK_VON); tryShort = 0; /* only try it once */ } /* Send request for a full update */ if (askforUpdate) { if(recv_short) sendShortReq(SPK_SALL); else sendUdpReq(COMM_UPDATE); } sendUpdatePacket(1000000 / updateSpeed); W_Deiconify(baseWin); break; case PALIVE: case PEXPLODE: case PDEAD: case POBSERVE: /* Get input until the player quits or dies */ input(); W_ClearWindow(mapw); break; default: printf("client has p_status=%d. how strange\n", me->p_status); me->p_status = POUTFIT; } } /* NOTREACHED */ }