/* * $Logfile: /DescentIII/Main/mtclient/mtgametrack.cpp $ * $Revision: 1.1.1.1 $ * $Date: 2003-08-26 03:58:40 $ * $Author: kevinb $ * * Game Tracker client code * * $Log: not supported by cvs2svn $ * * 17 10/03/01 12:44a Kevin * Smaller version of pxo packets * * 16 9/02/99 3:16p Kevin * Macintosh byte ordering fixes * * 15 8/25/99 2:38p Samir * added byteswap.h for INTEL_INT. * * 14 8/24/99 5:47p Kevin * Macintosh crap * * 13 7/06/99 5:52p Kevin * PXO & multiplayer fixes for the patch * * 12 5/05/99 5:23p Kevin * fixed some bugs on the gamelist * * 11 5/04/99 7:29p Kevin * Fixed bug that caused the server to send his game info twice whenever * the level starts. * * 10 5/04/99 5:39p Kevin * connection dll & pxo game tracking improvements (added server type to * list) * * 9 4/19/99 8:35p Jeff * Compile under Linux * * 8 3/25/99 3:26p Kevin * Made PXO games be based on your chat channel * * 7 1/07/99 11:51a Kevin * Added support for joining servers on alternate ports and hosting behind * a proxy/firewall * * 6 12/30/98 12:16p Kevin * Auto Mission Download system * * 5 12/23/98 6:38p Kevin * All UDP data (except gamespy) now uses one (registered) port number * * 4 10/19/98 9:50a Kevin * Added nettest application * * 3 7/27/98 5:31p Kevin * Sound/Bitmap exchange system * * 2 6/01/98 10:10a Kevin * Added DLL connection interface and auto update DLL * * 1 5/21/98 11:08a Kevin * * 6 5/14/98 11:07a Kevin * Made gameover packet to the tracker reliable * * 5 5/04/98 12:53p Kevin * Fixed mastertracker resend stuff * * 4 4/30/98 3:49p Kevin * Mastertracker pilot stats * * 3 4/24/98 3:50p Kevin * Added mastertracker game tracking support * * 2 4/23/98 4:49p Kevin * Added Master tracker Game tracker support * * 1 4/23/98 3:26p Kevin * Initial version * * $NoKeywords: $ */ /* InitGameTracker(int game_type); //D3 or Freespace //Call periodically so we can send our update, and make sure it is received IdleGameTracker(); StartTrackerGame(void *buffer) //Call with a freespace_net_game_data or d3_net_game_data structure //Call with a freespace_net_game_data or d3_net_game_data structure //Updates our memory so when it is time, we send the latest game data UpdateGameData(gamedata); //Call to signify end of game RequestGameList();//Sends a GNT_GAMELIST_REQ packet to the server. game_list * GetGameList();//returns a pointer to a game_list struct */ #ifdef WIN32 #include #endif #include #include #include "game.h" #include "ddio.h" #include "descent.h" #include "pstypes.h" #include "pserror.h" #include "mem.h" #include "mono.h" #include "networking.h" #include "mtgametrack.h" #include "byteswap.h" #include #include "mt_net.h" //extern float DLLtimer_GetTime(void); typedef float( *timer_GetTime_fp) (void); extern timer_GetTime_fp DLLtimer_GetTime; typedef int (*nw_RegisterCallback_fp) (void * nfp, ubyte id); extern nw_RegisterCallback_fp DLLnw_RegisterCallback; typedef int (*nw_DoReceiveCallbacks_fp)(void); extern nw_DoReceiveCallbacks_fp DLLnw_DoReceiveCallbacks; #if ( defined(MONO) && (!defined(RELEASE)) ) #define DLLmprintf(args) DLLDebug_ConsolePrintf args #else #define DLLmprintf(args) #endif typedef void( *Debug_ConsolePrintf_fp ) (int n, char *format, ... ); extern Debug_ConsolePrintf_fp DLLDebug_ConsolePrintf; //Variables game_list GameBuffer[MAX_GAME_BUFFERS]; int GameType;//d3 or fs float LastTrackerUpdate; float LastSentToTracker; float LastGameOverPacket; float FirstGameOverPacket; int SendingGameOver; unsigned int TrackerAckdUs; unsigned int TrackerGameIsRunning; game_packet_header TrackerGameData; game_packet_header GameListReq; game_packet_header TrackAckPacket; game_packet_header GameOverPacket; game_packet_header inpacket; d3_net_game_data_tiny *D3TrackerGameData; extern int DLLnw_ListenPort; extern ushort DLLPXOPort; extern char *DLLPXO_hosted_lobby_name; int InitGameTrackerClient(int gametype) { GameType = gametype; LastTrackerUpdate = 0; switch(gametype) { case GT_FREESPACE: // TrackerGameData.len = GAME_HEADER_ONLY_SIZE+sizeof(freespace_net_game_data); break; case GT_DESCENT3: TrackerGameData.len = INTEL_INT(GAME_HEADER_ONLY_SIZE+sizeof(d3_net_game_data_short)); break; case GT_D3TNG: TrackerGameData.len = INTEL_INT(GAME_HEADER_ONLY_SIZE+sizeof(d3_net_game_data_tiny)); break; } TrackerGameData.game_type = gametype; //1==freespace (GT_FREESPACE), 2==D3, 3==tuberacer, etc. TrackerGameData.type = INTEL_INT(GNT_GAMEUPDATE_TINY); //Used to specify what to do ie. Add a new net game (GNT_GAMESTARTED), remove a net game (game over), etc. D3TrackerGameData = (d3_net_game_data_tiny *)&TrackerGameData.data; if(DLLPXOPort) { D3TrackerGameData->options = 1; D3TrackerGameData->arg1 = DLLPXOPort; } GameListReq.game_type = gametype; GameListReq.type = INTEL_INT(GNT_GAMELIST_LITE_FILTER_REQ); GameListReq.len = INTEL_INT(GAME_HEADER_ONLY_SIZE); TrackAckPacket.game_type = gametype; TrackAckPacket.len = INTEL_INT(GAME_HEADER_ONLY_SIZE); TrackAckPacket.type = INTEL_INT(GNT_CLIENT_ACK); GameOverPacket.game_type = gametype; GameOverPacket.len = INTEL_INT(GAME_HEADER_ONLY_SIZE); GameOverPacket.type = INTEL_INT(GNT_GAMEOVER); SendingGameOver = 0; DLLnw_RegisterCallback(HandleGamePacket,PXO_NETID_GAME_TRACKER); return 1; } void IdleGameTracker() { DLLnw_DoReceiveCallbacks(); //unsigned int bytesin; //mprintf ((0,"IdleGameTracker() entered.\n")); if((TrackerGameIsRunning)&&((DLLtimer_GetTime()-LastTrackerUpdate)>TRACKER_UPDATE_INTERVAL)) { struct tm *newtime; time_t aclock; time( &aclock ); /* Get time in seconds */ newtime = localtime( &aclock ); //Time to update the tracker again DLLmprintf((0,"[%.24s] Updating the PXO game tracker!\n",asctime(newtime))); SendGameTrackerPacker(&TrackerGameData); // sendto(gamesock,(const char *)&TrackerGameData,TrackerGameData.len,0,(SOCKADDR *)>rackaddr,sizeof(SOCKADDR_IN)); TrackerAckdUs = 0; LastTrackerUpdate = DLLtimer_GetTime(); LastSentToTracker = DLLtimer_GetTime(); } else if((TrackerGameIsRunning)&&(!TrackerAckdUs)&&((DLLtimer_GetTime()-LastSentToTracker)>TRACKER_RESEND_TIME)) { //We still haven't been acked by the last packet and it's time to resend. struct tm *newtime; time_t aclock; time( &aclock ); /* Get time in seconds */ newtime = localtime( &aclock ); //Time to update the tracker again DLLmprintf((0,"[%.24s] (Resending) Updating the PXO game tracker!\n",asctime(newtime))); SendGameTrackerPacker(&TrackerGameData); TrackerAckdUs = 0; LastTrackerUpdate = DLLtimer_GetTime(); LastSentToTracker = DLLtimer_GetTime(); } if(SendingGameOver) { if((DLLtimer_GetTime()-LastGameOverPacket)>TRACKER_RESEND_TIME) { //resend LastGameOverPacket = DLLtimer_GetTime(); SendGameTrackerPacker(&GameOverPacket); } else if((DLLtimer_GetTime()-FirstGameOverPacket)>TRACKER_TIMEOUT) { //Giving up, it timed out. SendingGameOver = 3; } } } void HandleGamePacket(ubyte *data,int len, network_address *from) { memcpy(&inpacket,data,sizeof(inpacket)); //Check to make sure the packets ok if(len) { switch(INTEL_INT(inpacket.type)) { case GNT_SERVER_ACK: //The server got our packet so we can stop sending now TrackerAckdUs = 1; if(SendingGameOver) { SendingGameOver = 2; } break; case GNT_GAMELIST_LITE_DATA: if(len < (GAME_HEADER_ONLY_SIZE + sizeof(game_list))) { DLLmprintf((0,"(%d) packet is too small!\n",len)); } //Woohoo! Game data! put it in the buffer (if one's free) //DLLmprintf ((0,"GNT_GAMELIST_LITE_DATA received.\n")); for(int i=0;i