Mercurial > ~darius > hgwebdir.cgi > paradise_server
diff src/getentry.c @ 4:aa38447a4b21
First entry of Paradise Server 2.9 patch 10 Beta
author | darius |
---|---|
date | Sat, 06 Dec 1997 04:37:03 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/getentry.c Sat Dec 06 04:37:03 1997 +0000 @@ -0,0 +1,421 @@ +/*-------------------------------------------------------------------------- +NETREK II -- Paradise + +Permission to use, copy, modify, and distribute this software and its +documentation, or any derivative works thereof, for any NON-COMMERCIAL +purpose and without fee is hereby granted, provided that this copyright +notice appear in all copies. No representations are made about the +suitability of this software for any purpose. This software is provided +"as is" without express or implied warranty. + + Xtrek Copyright 1986 Chris Guthrie + Netrek (Xtrek II) Copyright 1989 Kevin P. Smith + Scott Silvey + Paradise II (Netrek II) Copyright 1993 Larry Denys + Kurt Olsen + Brandon Gillespie +--------------------------------------------------------------------------*/ + +#include "config.h" +#include <stdio.h> +#include <sys/types.h> +#include <sys/time.h> +#include "defs.h" +#include "struct.h" +#include "data.h" +#include "packets.h" +#include "shmem.h" + +extern int overload; /* 7/31/91 TC let overloaded join any team */ + +extern int updateShips(); +extern int sendMaskPacket(); +int tournamentMask(); +extern int briefUpdateClient(); +extern int flushSockBuf(); +extern int socketPause(); +extern int readFromClient(); +extern int isClientDead(); +extern int exitGame(); +#ifndef IRIX +extern int printf(); +#endif +extern int closeUdpConn(); +extern unsigned int sleep(); +extern int connectToClient(); +extern int updateSelf(); +extern int sendPickokPacket(); +extern int allowed_ship(); +extern int time_access(); +int deadTeam(); +int realNumShips(); + +#if 1 + +void +detourneyqueue() +{ + me->p_status = POUTFIT; + me->p_whydead = KPROVIDENCE; +} + +#endif + + +void +getEntry(team, stype) + int *team; + int *stype; +{ + + + int switching = -1; /* confirm switches 7/27/91 TC */ + inputMask = CP_OUTFIT; + for (;;) + { + /* updateShips so he knows how many players on each team */ + if (blk_flag) + updateShips(); + sendMaskPacket(tournamentMask(me->p_team)); + if (blk_flag) + briefUpdateClient(); + flushSockBuf(); + /* Have we been busted? */ + if (me->p_status == PFREE) + { + me->p_status = PDEAD; + me->p_explode = 600; + } + socketPause(); + readFromClient(); + if (isClientDead()) + { + int i; + + if (noressurect) + exitGame(); + printf("Ack! The client went away!\n"); + printf("I will attempt to resurrect him!\n"); + + /* UDP fail-safe */ + commMode = COMM_TCP; + if (udpSock >= 0) + closeUdpConn(); + + /* For next two minutes, we try to restore connection */ + shutdown(sock, 2); + sock = -1; + for (i = 0;; i++) + { + switch (me->p_status) + { + case PFREE: + me->p_status = PDEAD; + me->p_explode = 600; + break; + case PALIVE: + case POBSERVE: + me->p_ghostbuster = 0; + break; + case PDEAD: + me->p_explode = 600; + break; + default: + me->p_explode = 600; + me->p_ghostbuster = 0; + break; + } + sleep(5); + if (connectToClient(host, nextSocket)) + break; + if (i == 23) + { + printf("Oh well, maybe I'm getting rusty!\n"); + switch (me->p_status) + { + case PFREE: + break; + case PALIVE: + case POBSERVE: + me->p_ghostbuster = 100000; + break; + case PDEAD: + me->p_explode = 0; + break; + default: + me->p_explode = 0; + me->p_ghostbuster = 100000; + break; + } + exitGame(); + } + } + printf("A miracle! He's alive!\n"); + teamPick = -1; + updateSelf(); + updateShips(); + flushSockBuf(); + } + if (teamPick != -1) + { + if (teamPick < 0 || teamPick > 3) + { + warning("Get real!"); + sendPickokPacket(0); + teamPick = -1; + continue; + } +#if 1 + if (!(tournamentMask(me->p_team) & (1 << teamPick))) + { + warning("I cannot allow that. Pick another team"); + sendPickokPacket(0); + teamPick = -1; + continue; + } +#endif + + if (((1 << teamPick) != me->p_team) && + (me->p_team != ALLTEAM)) /* switching teams 7/27/91 TC */ + if ((switching != teamPick) + && (me->p_whydead != KGENOCIDE) +#ifdef LEAGUE_SUPPORT + && !status2->league +#endif + ) + { + switching = teamPick; + warning("Please confirm change of teams. Select the new team again."); + sendPickokPacket(0); + teamPick = -1; + continue; + } + /* His team choice is ok. */ + if (shipPick < 0 || shipPick >= NUM_TYPES) + { + warning("That is an illegal ship type. Try again."); + sendPickokPacket(0); + teamPick = -1; + continue; + } + if (!allowed_ship(1 << teamPick, mystats->st_rank, mystats->st_royal, shipPick)) + { + sendPickokPacket(0); + teamPick = -1; + continue; + } + if (shipvals[shipPick].s_nflags & SFNMASSPRODUCED) + { + warning("o)utpost, u)tility, or s)tandard?"); + sendPickokPacket(0); + tmpPick = shipPick; + continue; + } + break; + } +#if 1 + if (me->p_status == PTQUEUE) + { + if (status->tourn) + detourneyqueue(); + /* You don't time out on the tourney queue */ + me->p_ghostbuster = 0; + } +#endif + } + *team = teamPick; + if ((shipvals[tmpPick].s_nflags & SFNMASSPRODUCED) && + ((shipvals[shipPick].s_numports) || (shipPick == SCOUT))) + { + + *stype = tmpPick; + tmpPick = CRUISER; + } + else + { + *stype = shipPick; + tmpPick = CRUISER; + } + sendPickokPacket(1); + flushSockBuf(); +} + + + + +/*------------------------------TOURNAMENTMASK----------------------------*/ +/* + * This function takes the players current team and returns a mask of the + * teams that the player can join. + */ + +int +leaguemask(ishome, idx) + int ishome; /* team index */ + int idx; +{ +#ifdef LEAGUE_SUPPORT + if (status2->league == 1) + return idx_to_mask(ishome); + else +#endif + return idx_to_mask(idx); +} + +int +tournamentMask(team) + int team; /* players current team */ +{ + int i; /* looping var */ + int team1, team2; /* for getting two possible teams */ + int num1, num2; /* to hold num players on teams */ + + if (!blk_flag) /* not a paradise client */ + return (0); + if (status->gameup == 0) /* if game over, can join no team */ + return (0); + if (overload) /* if tester slot then can join */ + return (ALLTEAM); /* any team */ + if (mustexit) /* should we force player out */ + return (0); + if (!time_access()) /* if server closed then can join */ + return (0); /* no team */ + +#ifdef LEAGUE_SUPPORT + /* league stuff */ + if (status2->league) + { + if (me->p_homeaway == AWAY) + return leaguemask(1, status2->away.index); + else if (me->p_homeaway == HOME) + return leaguemask(0, status2->home.index); + else + { + warning("You have connected to a league server but aren't on a side."); + me->p_homeaway = (lrand48() & 1) + 1; /* dangerous int->enum cast */ + return 0; + } + /* NOTREACHED */ + } +#endif + if (me->p_homeaway != NEITHER) + { + warning("You have connected to a non-league server with a league ntserv."); + me->p_homeaway = NEITHER; + } + + if (!status->tourn) + { + return status2->nontteamlock; + } + + if (team != ALLTEAM && deadTeam(team)) /* if former team dead */ + team = ALLTEAM; /* then check all others */ + for (i = 0; i < NUMTEAM; i++) + { /* go through all teams and eliminate */ + if ((team & (1 << i)) && (deadTeam(1 << i))) /* from team var all + * teams */ + team &= ~(1 << i); /* that are dead */ + } + team1 = 0; /* no team in team 1 */ + num1 = 0; /* 0 players on team 1 */ + team2 = 0; /* no team in team 2 */ + num2 = 0; /* 0 players on team 2 */ + for (i = 0; i < NUMTEAM; i++) + { /* go through all teams */ + if (deadTeam(1 << i)) /* if team is dead then */ + continue; /* disregard it */ + if (realNumShips(1 << i) >= configvals->tournplayers) + { /* enough players */ + if (!team1) /* if no team in team1 yet */ + team1 = (1 << i); /* then this will be team 1 */ + else + { /* otherwise its team2 */ + team2 = (1 << i); + num1 = realNumShips(team1); /* get num players on two teams */ + num2 = realNumShips(team2); + if (num1 == num2) + { /* if teams same size then */ + if (team & (team1 | team2)) /* if player on one team */ + return (team & (team1 | team2)); /* let him join same team */ + return (team1 | team2); /* otherwise, he can join either */ + } + else if ((num1 > num2) && (team != team1)) + return (team2); /* if slight imabalance */ + else if ((num1 < num2) && (team != team2)) + return (team1); /* if slight imbalance */ + else + { + if (ABS(num1 - num2) < 2 || (((num1 > num2) && (team == team2)) || + (num2 > num1 && team == team1))) + return (team); + else + return (team1 | team2); + } + } + } + } /* end of for loop */ + return (team); /* just in case */ +} + + + + +/*--------------------------------REALNUMSHIPS-----------------------------*/ +/* + * Count the real number of ships on a team. This function returns a count + * of all the ships on a team that are not PFREE. + */ + +int +realNumShips(owner) + int owner; /* the team to check for */ +{ + int i; /* looping var */ + int num; /* to hold ship count */ + struct player *p; /* to point to players */ + + num = 0; /* initialize count */ + for (i = 0, p = players; i < MAXPLAYER; i++, p++) + { + if ((p->p_status != PFREE) && + !(p->p_flags & (PFSNAKE | PFBIRD)) && + (p->p_team == owner)) + { + num++; /* if ship not free and on our team */ + } + } + return (num); /* retun number of ships */ +} + + + + +/*----------------------------------DEADTEAM-------------------------------*/ +/* + * This function counts the number of planets that a team owns. It returns a + * 1 if the team has no planets, and a 0 if they have at least one planet. + */ + +int +deadTeam(owner) + int owner; /* team to check for */ +{ + int i; /* looping var */ + struct planet *p; /* to point to a planets */ + + for (i = 0, p = planets; i < NUMPLANETS; i++, p++) + { + if (p->pl_owner & owner) /* if planet owned by team then */ + return (0); /* found one planet owned by team */ + } + return (1); /* no planets found, team is dead */ +} + +/*-------------------------------------------------------------------------*/ + + + + + +/*---------END OF FILE--------*/