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--------*/