* Remove message type MSG_PLAYER_DATA as it sends/receives void* data chuncks which is __not__ endian safe (not to mention struct padding)

* Don't maintain player stats in lib/netplay/netplay.c; instead maintain them in src/multistat.c
 * Add a new net message type (NET_PLAYER_STATS) to exchange player stats


git-svn-id: svn+ssh://svn.gna.org/svn/warzone/trunk@3661 4a71c877-e1ca-e34f-864e-861f7616d084
master
Giel van Schijndel 2008-02-03 14:39:31 +00:00
parent 4354be1e75
commit 0c7ade394d
6 changed files with 59 additions and 166 deletions

View File

@ -48,7 +48,6 @@ enum
MSG_JOIN = 90, // needs to start at 90 MSG_JOIN = 90, // needs to start at 90
MSG_ACCEPTED, MSG_ACCEPTED,
MSG_PLAYER_INFO, MSG_PLAYER_INFO,
MSG_PLAYER_DATA,
MSG_PLAYER_JOINED, MSG_PLAYER_JOINED,
MSG_PLAYER_LEFT, MSG_PLAYER_LEFT,
MSG_GAME_FLAGS, MSG_GAME_FLAGS,
@ -111,8 +110,6 @@ NETPLAY NetPlay;
static BOOL allow_joining = FALSE; static BOOL allow_joining = FALSE;
static GAMESTRUCT game; static GAMESTRUCT game;
static NET_PLAYER_DATA local_player_data[MAX_CONNECTED_PLAYERS] = { { 0, NULL, 0 } };
static NET_PLAYER_DATA global_player_data[MAX_CONNECTED_PLAYERS] = { { 0, NULL, 0 } };
static TCPsocket tcp_socket = NULL; static TCPsocket tcp_socket = NULL;
static NETBUFSOCKET* bsocket = NULL; static NETBUFSOCKET* bsocket = NULL;
static NETBUFSOCKET* connected_bsocket[MAX_CONNECTED_PLAYERS] = { NULL }; static NETBUFSOCKET* connected_bsocket[MAX_CONNECTED_PLAYERS] = { NULL };
@ -367,110 +364,6 @@ BOOL NETchangePlayerName(UDWORD dpid, char *newName)
return TRUE; return TRUE;
} }
static void resize_local_player_data(unsigned int i, unsigned int size)
{
if (local_player_data[i].buffer_size < size)
{
if (local_player_data[i].data != NULL)
{
free(local_player_data[i].data);
}
local_player_data[i].data = malloc(size);
local_player_data[i].buffer_size = size;
}
}
static void resize_global_player_data(unsigned int i, size_t size)
{
void* new_buffer;
if (size == 0)
{
free(global_player_data[i].data);
global_player_data[i].data = NULL;
global_player_data[i].buffer_size = 0;
return;
}
new_buffer = realloc(global_player_data[i].data, size);
if (new_buffer == NULL)
{
debug(LOG_ERROR, "resize_global_player_data: Out of memory!");
abort();
return;
}
global_player_data[i].data = new_buffer;
global_player_data[i].buffer_size = size;
}
// ////////////////////////////////////////////////////////////////////////
BOOL NETgetLocalPlayerData(UDWORD dpid, void *pData)
{
memcpy(pData, local_player_data[dpid].data, local_player_data[dpid].size);
return TRUE;
}
// ////////////////////////////////////////////////////////////////////////
BOOL NETgetGlobalPlayerData(UDWORD dpid, void *pData)
{
if(!NetPlay.bComms)
{
memcpy(pData, local_player_data[dpid].data, local_player_data[dpid].size);
return TRUE;
}
memcpy(pData, global_player_data[dpid].data, global_player_data[dpid].size);
return TRUE;
}
// ////////////////////////////////////////////////////////////////////////
BOOL NETsetLocalPlayerData(UDWORD dpid,void *pData, SDWORD size)
{
debug(LOG_NET, "NETsetLocalPlayerData(%u, %p, %d)", dpid, pData, size);
local_player_data[dpid].size = size;
resize_local_player_data(dpid, size);
memcpy(local_player_data[dpid].data, pData, size);
return TRUE;
}
static void NETsendGlobalPlayerData(uint32_t dpid)
{
NETbeginEncode(MSG_PLAYER_DATA, NET_ALL_PLAYERS);
{
char* data = (char*)global_player_data[dpid].data;
uint16_t size = global_player_data[dpid].size;
NETuint32_t(&dpid);
NETuint16_t(&size);
NETbin(data, size);
}
NETend();
}
// ////////////////////////////////////////////////////////////////////////
BOOL NETsetGlobalPlayerData(uint32_t dpid, void *pData, uint16_t size)
{
debug(LOG_NET, "NETsetGlobalPlayerData(%u, %p, %d)", dpid, pData, size);
if(!NetPlay.bComms)
{
local_player_data[dpid].size = size;
resize_local_player_data(dpid, size);
memcpy(local_player_data[dpid].data, pData, size);
return TRUE;
}
global_player_data[dpid].size = size;
resize_global_player_data(dpid, size);
memcpy(global_player_data[dpid].data, pData, size);
// broadcast player data
NETsendGlobalPlayerData(dpid);
NETBroadcastPlayerInfo(dpid);
return TRUE;
}
// //////////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////////////
// return one of the four user flags in the current sessiondescription. // return one of the four user flags in the current sessiondescription.
SDWORD NETgetGameFlags(UDWORD flag) SDWORD NETgetGameFlags(UDWORD flag)
@ -567,17 +460,8 @@ BOOL NETinit(BOOL bFirstCall)
// SHUTDOWN THE CONNECTION. // SHUTDOWN THE CONNECTION.
BOOL NETshutdown(void) BOOL NETshutdown(void)
{ {
unsigned int i;
debug( LOG_NET, "NETshutdown" ); debug( LOG_NET, "NETshutdown" );
for( i = 0; i < MAX_CONNECTED_PLAYERS; i++ )
{
if( local_player_data[i].data != NULL )
{
free( local_player_data[i].data );
}
}
NETstopLogging(); NETstopLogging();
SDLNet_Quit(); SDLNet_Quit();
return 0; return 0;
@ -851,32 +735,6 @@ BOOL NETprocessSystemMessage(NETMSG * pMsg)
} }
break; break;
} }
case MSG_PLAYER_DATA:
{
uint32_t dpid;
NETbeginDecode();
{
uint16_t size;
NETuint32_t(&dpid);
debug(LOG_NET, "NETprocessSystemMessage: Receiving MSG_PLAYER_DATA for player %u", (unsigned int)dpid);
// Retrieve required buffer size, and resize buffer
NETuint16_t(&size);
resize_global_player_data(dpid, size);
global_player_data[dpid].size = size;
// Retrieve data
NETbin((char*)global_player_data[dpid].data, size);
}
NETend();
if (is_server)
{
NETsendGlobalPlayerData(dpid);
}
break;
}
case MSG_PLAYER_JOINED: case MSG_PLAYER_JOINED:
{ {
uint8_t dpid; uint8_t dpid;

View File

@ -150,10 +150,6 @@ extern BOOL NEThostGame(const char* SessionName, const char* PlayerName,// host
//from netusers.c //from netusers.c
extern UDWORD NETplayerInfo(void); // count players in this game. extern UDWORD NETplayerInfo(void); // count players in this game.
extern BOOL NETchangePlayerName(UDWORD dpid, char *newName);// change a players name. extern BOOL NETchangePlayerName(UDWORD dpid, char *newName);// change a players name.
extern BOOL NETgetLocalPlayerData(UDWORD dpid, void *pData);
extern BOOL NETgetGlobalPlayerData(UDWORD dpid, void *pData);
extern BOOL NETsetLocalPlayerData(UDWORD dpid, void *pData, SDWORD size);
extern BOOL NETsetGlobalPlayerData(uint32_t dpid, void *pData, uint16_t size);
extern void NETsetPacketDir(PACKETDIR dir); extern void NETsetPacketDir(PACKETDIR dir);
extern PACKETDIR NETgetPacketDir(void); extern PACKETDIR NETgetPacketDir(void);

View File

@ -791,6 +791,9 @@ BOOL recvMessage(void)
case NET_RESEARCHSTATUS: case NET_RESEARCHSTATUS:
recvResearchStatus(); recvResearchStatus();
break; break;
case NET_PLAYER_STATS:
recvMultiStats();
break;
default: default:
break; break;
} }

View File

@ -43,7 +43,7 @@ typedef enum _msgtype
NET_CHECK_DROID, //9 check & update bot position and damage. NET_CHECK_DROID, //9 check & update bot position and damage.
NET_CHECK_STRUCT, //10 check & update struct damage. NET_CHECK_STRUCT, //10 check & update struct damage.
NET_CHECK_POWER, //11 power levels for a player. NET_CHECK_POWER, //11 power levels for a player.
__DEPRECATED__NET_VERSION__, //12 was VERSION data; is unused now; but some code depends on this enum having these numbers (BAD!!!) NET_PLAYER_STATS, //12 player stats
NET_BUILD, //13 build a new structure NET_BUILD, //13 build a new structure
NET_STRUCTDEST, //14 specify a strucutre to destroy NET_STRUCTDEST, //14 specify a strucutre to destroy
NET_BUILDFINISHED, //15 a building is complete. NET_BUILDFINISHED, //15 a building is complete.

View File

@ -49,24 +49,17 @@ extern char MultiPlayersPath[PATH_MAX];
// //////////////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////////////////
// STATS STUFF // STATS STUFF
// //////////////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////////////////
static PLAYERSTATS playerStats[MAX_PLAYERS];
// //////////////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////////////////
// Get Player's stats // Get Player's stats
PLAYERSTATS getMultiStats(UDWORD player,BOOL bLocal) PLAYERSTATS getMultiStats(UDWORD player,BOOL bLocal)
{ {
static PLAYERSTATS stat; static PLAYERSTATS stat;
UDWORD playerDPID; uint32_t playerDPID = player2dpid[player];
playerDPID = player2dpid[player]; // Copy over the data from our local array
memcpy(&stat, &playerStats[playerDPID], sizeof(stat));
if(bLocal)
{
NETgetLocalPlayerData(playerDPID, &stat);
}
else
{
NETgetGlobalPlayerData(playerDPID, &stat);
}
return stat; return stat;
} }
@ -75,19 +68,56 @@ PLAYERSTATS getMultiStats(UDWORD player,BOOL bLocal)
// Set Player's stats // Set Player's stats
BOOL setMultiStats(SDWORD dp, PLAYERSTATS plStats, BOOL bLocal) BOOL setMultiStats(SDWORD dp, PLAYERSTATS plStats, BOOL bLocal)
{ {
UDWORD playerDPID = (UDWORD) dp; uint32_t playerDPID = (uint32_t)dp;
if(bLocal) // First copy over the data into our local array
memcpy(&playerStats[playerDPID], &plStats, sizeof(plStats));
if (!bLocal)
{ {
NETsetLocalPlayerData(playerDPID,&plStats,sizeof(PLAYERSTATS)); // Now send it to all other players
} NETbeginEncode(NET_PLAYER_STATS, NET_ALL_PLAYERS);
else // Send the ID of the player's stats we're updating
{ NETuint32_t(&playerDPID);
NETsetGlobalPlayerData(playerDPID,&plStats,sizeof(PLAYERSTATS));
// Send over the actual stats
NETuint32_t(&playerStats[playerDPID].played);
NETuint32_t(&playerStats[playerDPID].wins);
NETuint32_t(&playerStats[playerDPID].losses);
NETuint32_t(&playerStats[playerDPID].totalKills);
NETuint32_t(&playerStats[playerDPID].totalScore);
NETuint32_t(&playerStats[playerDPID].recentKills);
NETuint32_t(&playerStats[playerDPID].recentScore);
NETuint32_t(&playerStats[playerDPID].killsToAdd);
NETuint32_t(&playerStats[playerDPID].scoreToAdd);
NETend();
} }
return TRUE; return TRUE;
} }
void recvMultiStats()
{
uint32_t playerDPID;
NETbeginDecode();
// Retrieve the ID number of the player for which we need to
// update the stats
NETuint32_t(&playerDPID);
// Retrieve the actual stats
NETuint32_t(&playerStats[playerDPID].played);
NETuint32_t(&playerStats[playerDPID].wins);
NETuint32_t(&playerStats[playerDPID].losses);
NETuint32_t(&playerStats[playerDPID].totalKills);
NETuint32_t(&playerStats[playerDPID].totalScore);
NETuint32_t(&playerStats[playerDPID].recentKills);
NETuint32_t(&playerStats[playerDPID].recentScore);
NETuint32_t(&playerStats[playerDPID].killsToAdd);
NETuint32_t(&playerStats[playerDPID].scoreToAdd);
NETend();
}
// //////////////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////////////////
// Load Player Stats // Load Player Stats
BOOL loadMultiStats(char *sPlayerName, PLAYERSTATS *st) BOOL loadMultiStats(char *sPlayerName, PLAYERSTATS *st)

View File

@ -27,6 +27,9 @@
* Also Definitions for saved Arena Forces to enable teams to be saved to disk * Also Definitions for saved Arena Forces to enable teams to be saved to disk
*/ */
#ifndef __INCLUDED_SRC_MULTISTATS_H__
#define __INCLUDED_SRC_MULTISTATS_H__
typedef struct typedef struct
{ {
uint32_t played; /// propogated stats. uint32_t played; /// propogated stats.
@ -40,7 +43,6 @@ typedef struct
uint32_t killsToAdd; // things to add next time score is updated. uint32_t killsToAdd; // things to add next time score is updated.
uint32_t scoreToAdd; uint32_t scoreToAdd;
} PLAYERSTATS; } PLAYERSTATS;
// stat defs // stat defs
@ -53,3 +55,7 @@ extern void updateMultiStatsGames (void);
extern void updateMultiStatsWins (void); extern void updateMultiStatsWins (void);
extern void updateMultiStatsLoses (void); extern void updateMultiStatsLoses (void);
extern void updateMultiStatsKills (BASE_OBJECT *psKilled,UDWORD player); extern void updateMultiStatsKills (BASE_OBJECT *psKilled,UDWORD player);
extern void recvMultiStats(void);
#endif // __INCLUDED_SRC_MULTISTATS_H__