mirror of
https://github.com/kevinbentley/Descent3.git
synced 2026-04-03 08:00:04 -04:00
433 lines
10 KiB
C++
433 lines
10 KiB
C++
/*
|
|
* $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 <windows.h>
|
|
#endif
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#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 <time.h>
|
|
|
|
#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<MAX_GAME_BUFFERS;i++)
|
|
{
|
|
if(GameBuffer[i].game_type==GT_UNUSED)
|
|
{
|
|
memset(&GameBuffer[i],0,sizeof(game_list));
|
|
memcpy(&GameBuffer[i],inpacket.data,len-GAME_HEADER_ONLY_SIZE);
|
|
i=MAX_GAME_BUFFERS+1;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
//mprintf ((0,"Sending ACK.\n"));
|
|
AckPacket(inpacket.sig);
|
|
}
|
|
}
|
|
|
|
void UpdateGameData(void *buffer)
|
|
{
|
|
if(GameType==GT_FREESPACE)
|
|
{
|
|
// memcpy(FreeSpaceTrackerGameData,buffer,sizeof(freespace_net_game_data));
|
|
}
|
|
else if(GameType==GT_DESCENT3)
|
|
{
|
|
memcpy(D3TrackerGameData,buffer,sizeof(d3_net_game_data_short));
|
|
}
|
|
else if(GameType==GT_D3TNG)
|
|
{
|
|
memcpy(D3TrackerGameData,buffer,sizeof(d3_net_game_data_tiny));
|
|
}
|
|
|
|
|
|
}
|
|
|
|
game_list gl;
|
|
|
|
game_list * GetGameList()
|
|
{
|
|
memset(&gl,0,sizeof(gl));
|
|
for(int i=0;i<MAX_GAME_BUFFERS;i++)
|
|
{
|
|
if(GameBuffer[i].game_type!=GT_UNUSED)
|
|
{
|
|
memcpy(&gl,&GameBuffer[i],sizeof(gl));
|
|
GameBuffer[i].game_type = GT_UNUSED;
|
|
return ≷
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void RequestGameList()
|
|
{
|
|
//Zero out all games
|
|
for(int i=0;i<MAX_GAME_BUFFERS;i++)
|
|
{
|
|
memset(&GameBuffer[i],0,sizeof(game_list));
|
|
}
|
|
|
|
int len = strlen(DLLPXO_hosted_lobby_name)+1;
|
|
memcpy(GameListReq.data,DLLPXO_hosted_lobby_name,len);
|
|
GameListReq.len = INTEL_INT(GAME_HEADER_ONLY_SIZE + len);
|
|
SendGameTrackerPacker(&GameListReq);
|
|
}
|
|
|
|
int SendGameOver()
|
|
{
|
|
IdleGameTracker();
|
|
|
|
if(SendingGameOver==3)
|
|
{
|
|
//Request timed out.
|
|
return 2;
|
|
}
|
|
if(SendingGameOver==2)
|
|
{
|
|
SendingGameOver = 0;
|
|
return 1;
|
|
}
|
|
if(SendingGameOver==1)
|
|
{
|
|
//Wait until it's sent.
|
|
return 0;
|
|
}
|
|
if(SendingGameOver==0)
|
|
{
|
|
LastGameOverPacket = DLLtimer_GetTime();
|
|
FirstGameOverPacket = DLLtimer_GetTime();
|
|
SendingGameOver = 1;
|
|
TrackerGameIsRunning = 0;
|
|
SendGameTrackerPacker(&GameOverPacket);
|
|
return 0;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
void AckPacket(int sig)
|
|
{
|
|
TrackAckPacket.sig = sig;
|
|
SendGameTrackerPacker(&TrackAckPacket);
|
|
}
|
|
|
|
void StartTrackerGame(void *buffer)
|
|
{
|
|
|
|
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 with a new game!\n",asctime(newtime)));
|
|
|
|
if(GameType==GT_FREESPACE)
|
|
{
|
|
// memcpy(FreeSpaceTrackerGameData,buffer,sizeof(freespace_net_game_data));
|
|
}
|
|
else if(GameType==GT_DESCENT3)
|
|
{
|
|
memcpy(D3TrackerGameData,buffer,sizeof(d3_net_game_data_short));
|
|
SendGameTrackerPacker(&TrackerGameData);
|
|
TrackerAckdUs = 0;
|
|
LastTrackerUpdate = DLLtimer_GetTime();
|
|
LastSentToTracker = DLLtimer_GetTime();
|
|
|
|
}
|
|
else if(GameType==GT_D3TNG)
|
|
{
|
|
memcpy(D3TrackerGameData,buffer,sizeof(d3_net_game_data_tiny));
|
|
SendGameTrackerPacker(&TrackerGameData);
|
|
TrackerAckdUs = 0;
|
|
LastTrackerUpdate = DLLtimer_GetTime();
|
|
LastSentToTracker = DLLtimer_GetTime();
|
|
}
|
|
TrackerGameIsRunning = 1;
|
|
//LastTrackerUpdate = 0;
|
|
} |