/* * file com_central.c - server answers to broadcasts by clients * * $Id: com_central.c,v 1.4 2004/06/26 03:20:15 iskywalker Exp $ * * Program XBLAST * (C) by Oliver Vogel (e-mail: m.vogel@ndh.net) * Added by Koen De Raedt for central support * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published * by the Free Software Foundation; either version 2; or (at your option) * any later version * * This program is distributed in the hope that it will be entertaining, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILTY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc. * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "com_central.h" #include "com_browse.h" #include "version.h" #include "str_util.h" #ifdef WMS #include "timeval.h" #endif #include "ini_file.h" /* * local types */ #define MAX_GAMES 256 #define DEAD_GAME_TIME 30 typedef struct { XBCommBrowse browse; unsigned short port; unsigned char serial; char *addrBroadcast; struct timeval tvSend; } XBCommCentral; typedef struct { unsigned short port; char game[48]; char host[32]; unsigned char version[3]; /* version numbers */ int gameID; int numLives; int numWins; int frameRate; time_t time; } XBCentralGames; XBCentralGames centralGames[MAX_GAMES]; XBBool isFree[MAX_GAMES]; XBBool isMess[MAX_GAMES]; int nextFreeSlot,usedSlots; int com_GetOpenGames() { return usedSlots; } void Central_MakeGameTextFile() { FILE *f; int i; f=fopen("games.html","w"); fprintf(f,""); for(i=0;i",centralGames[i].game); } else { fprintf(f,"", centralGames[i].game,centralGames[i].host,centralGames[i].port, centralGames[i].numLives,centralGames[i].numWins,centralGames[i].frameRate, centralGames[i].version[0],centralGames[i].version[1],centralGames[i].version[2]); } /* tele.port = centralGames[i].port; tele.version[0] = centralGames[i].version[0]; tele.version[1] = centralGames[i].version[1]; tele.version[2] = centralGames[i].version[2]; tele.numLives = centralGames[i].numLives; tele.numWins = centralGames[i].numWins; tele.frameRate = centralGames[i].frameRate; strncpy (tele.game, centralGames[i].game, sizeof (tele.game)); strncpy (tele.host, centralGames[i].host, sizeof (tele.host)); Dbg_Out("Inform client of game: %s %s:%i\n", centralGames[i].game, centralGames[i].host, centralGames[i].port); */ } } fprintf(f,"
%s
%s%s:%d%d%d%dV%u.%u.%u
"); fclose(f); } void Central_ClearOldGames() { int n=0,i; time_t now; now=time(NULL); for(i=0;iDEAD_GAME_TIME) { usedSlots--; isFree[i]=XBTrue; n++; } } } if(n>0) {Dbg_Out("%i dead game(s) removed\n",n);} Central_MakeGameTextFile(); } static void HandleQuery (XBCommCentral *rComm, const XBBrowseTeleQuery *query, const char *host, unsigned short port) { XBBrowseTeleReply tele; int i,n=0; memset (&tele, 0, sizeof (tele)); /* build central */ tele.any.type = XBBT_Reply; tele.any.serial = query->any.serial; for(i=0;ibrowse, host, port, XBFalse, &tele.any); n++; //break; } } /* --- */ Dbg_Out ("%i games send to client at %s:%hu\n", n,host, port); } /* HandleQuery */ static void HandleNewGame (XBCommCentral *rComm, const XBBrowseTeleNewGame *query, const char *host, unsigned short port) { XBBrowseTeleNewGameOK tele; int i,j; tele.any.type = XBBT_NewGameOK; tele.any.serial = query->any.serial; i=query->gameID; if(((i >=0) && isFree[i]) || i < 0) { for(i=nextFreeSlot, j=0; j<=MAX_GAMES; i=(i+1)%MAX_GAMES, j++) { if(isFree[i] && !isMess[i]) { usedSlots++; nextFreeSlot=i+1; break; } } if(j==MAX_GAMES) { i=-1; } } if(i>=0) { isFree[i]=XBFalse; centralGames[i].port=query->port; centralGames[i].version[0]=query->version[0]; centralGames[i].version[1]=query->version[1]; centralGames[i].version[2]=query->version[2]; centralGames[i].numLives=query->numLives; centralGames[i].numWins=query->numWins; centralGames[i].frameRate=query->frameRate; centralGames[i].time=time(NULL); sprintf(centralGames[i].host,"%s",host); sprintf(centralGames[i].game,"%s",query->game); Dbg_Out("New game %s at %s:%i\n", centralGames[i].game, centralGames[i].host, centralGames[i].port); } else { i=-1; Dbg_Out(" *** Games limit reached ***\n"); } tele.gameID=i; Browse_Send (&rComm->browse, host, port, XBFalse, &tele.any); /* --- */ Dbg_Out ("game id %i send to %s:%hu\n", i, host, port); Central_MakeGameTextFile(); } /* * Server starts or closes the game */ static void HandleCloseGame (XBCommCentral *rComm, const XBBrowseTeleNewGameOK *query, const char *host, unsigned short port) { int i=query->gameID; Dbg_Out("Game closed by server, game was %s\n", isFree[i] ? "not known" : "known"); if(!isFree[i]) { usedSlots--; if(usedSlots<0) usedSlots=0; isFree[i]=XBTrue; } } /* * receive central data */ static void ReceiveCentral (XBCommBrowse *bComm, const XBBrowseTele *tele, const char *host, unsigned short port) { assert (NULL != bComm); assert (NULL != tele); assert (NULL != host); switch (tele->type) { case XBBT_Query : HandleQuery ((XBCommCentral *) bComm, &tele->query, host, port); break; case XBBT_NewGame: HandleNewGame ((XBCommCentral *) bComm, &tele->newGame, host, port); break; case XBBT_NewGameOK: HandleCloseGame ((XBCommCentral *) bComm, &tele->newGameOK, host, port); break; default: break; } } /* ReceiveCentral */ /* * */ static XBCommResult DeleteCentral (XBComm *comm) { XBCommCentral *rComm = (XBCommCentral *) comm; /* */ assert (NULL != rComm); Browse_Finish (&rComm->browse); free (rComm); rComm = NULL; return XCR_OK; } /* DeleteCentral */ /* * create udp socket waiting for clients' queries */ XBComm* Central_CreateComm (unsigned short port) { XBSocket *pSocket; XBCommCentral *rComm; int i; /* DAYMESSAGE */ char s[1024],q[256]; int l[16],n; /* DAYMESSAGE */ /* create socket */ pSocket = Net_BindUdp (NULL, port); if (NULL == pSocket) { return NULL; } /* create communication data structure */ rComm = calloc (1, sizeof (*rComm)); assert (NULL != rComm); for(i=0;ibrowse, COMM_NewGameOK, pSocket, ReceiveCentral, DeleteCentral); /* that's all ? */ /* DAYMESSAGE */ for(i=0;ibrowse.comm; } /* Central_CreateComm */ /* * end of file com_central.c */