test for duplicate initial client message and if so drop it; add const keyword; add assertion in addr comparion in attempt to learn why duplicates are getting through.

This commit is contained in:
ehouse 2007-12-31 20:00:13 +00:00
parent 4074417b33
commit 40f7295802
4 changed files with 110 additions and 99 deletions

View file

@ -1014,9 +1014,13 @@ preProcess( CommsCtxt* comms, XWStreamCtxt* stream,
static AddressRecord*
addrToRecord( CommsCtxt* comms, const CommsAddrRec* addr )
{
CommsConnType conType = addr->conType;
CommsConnType conType;
AddressRecord* rec;
XP_Bool matched = XP_FALSE;
XP_ASSERT( !!addr );
conType = addr->conType;
for ( rec = comms->recs; !!rec; rec = rec->next ) {
XP_ASSERT( conType == rec->addr.conType );
switch( conType ) {
@ -1039,7 +1043,9 @@ addrToRecord( CommsCtxt* comms, const CommsAddrRec* addr )
}
break;
case COMMS_CONN_IR: /* no way to test */
break;
default:
XP_ASSERT(0);
break;
}
if ( matched ) {

View file

@ -315,10 +315,10 @@ gi_disposePlayerInfo( MPFORMAL CurGameInfo* gi )
} /* gi_disposePlayerInfo */
void
gi_copy( MPFORMAL CurGameInfo* destGI, CurGameInfo* srcGI )
gi_copy( MPFORMAL CurGameInfo* destGI, const CurGameInfo* srcGI )
{
XP_U16 nPlayers, i;
LocalPlayer* srcPl;
const LocalPlayer* srcPl;
LocalPlayer* destPl;
replaceStringIfDifferent( mpool, &destGI->dictName,

View file

@ -99,7 +99,7 @@ void gi_initPlayerInfo( MPFORMAL CurGameInfo* gi,
void gi_disposePlayerInfo( MPFORMAL CurGameInfo* gi );
void gi_writeToStream( XWStreamCtxt* stream, const CurGameInfo* gi );
void gi_readFromStream( MPFORMAL XWStreamCtxt* stream, CurGameInfo* gi );
void gi_copy( MPFORMAL CurGameInfo* destGI, CurGameInfo* srcGi );
void gi_copy( MPFORMAL CurGameInfo* destGI, const CurGameInfo* srcGi );
XP_U16 gi_countLocalHumans( const CurGameInfo* gi );
XP_Bool player_hasPasswd( LocalPlayer* player );

View file

@ -940,103 +940,108 @@ clearLocalRobots( ServerCtxt* server )
static XP_Bool
client_readInitialMessage( ServerCtxt* server, XWStreamCtxt* stream )
{
DictionaryCtxt* newDict;
DictionaryCtxt* curDict;
XP_U16 nPlayers, nCols;
XP_PlayerAddr channelNo;
short i;
ModelCtxt* model = server->vol.model;
CurGameInfo* gi = server->vol.gi;
CurGameInfo localGI;
XP_U32 gameID;
PoolContext* pool;
XP_Bool accepted = 0 == server->nv.addresses[0].channelNo;
/* version */
XP_U8 streamVersion = stream_getU8( stream );
XP_ASSERT( streamVersion == STREAM_VERS_41B4 );
if ( streamVersion != STREAM_VERS_41B4 ) {
return XP_FALSE;
/* We should never get this message a second time, but very rarely we do.
Drop it in that case. */
XP_ASSERT( accepted );
if ( accepted ) {
DictionaryCtxt* newDict;
DictionaryCtxt* curDict;
XP_U16 nPlayers, nCols;
XP_PlayerAddr channelNo;
short i;
ModelCtxt* model = server->vol.model;
CurGameInfo* gi = server->vol.gi;
CurGameInfo localGI;
XP_U32 gameID;
PoolContext* pool;
/* version */
XP_U8 streamVersion = stream_getU8( stream );
XP_ASSERT( streamVersion == STREAM_VERS_41B4 );
if ( streamVersion != STREAM_VERS_41B4 ) {
return XP_FALSE;
}
stream_setVersion( stream, streamVersion );
gameID = stream_getU32( stream );
XP_STATUSF( "read gameID of %lx; calling comms_setConnID", gameID );
server->vol.gi->gameID = gameID;
comms_setConnID( server->vol.comms, gameID );
XP_MEMSET( &localGI, 0, sizeof(localGI) );
gi_readFromStream( MPPARM(server->mpool) stream, &localGI );
localGI.serverRole = SERVER_ISCLIENT;
/* so it's not lost (HACK!). Without this, a client won't have a default
dict name when a new game is started. */
localGI.dictName = copyString( server->mpool, gi->dictName );
gi_copy( MPPARM(server->mpool) gi, &localGI );
nCols = localGI.boardSize;
newDict = util_makeEmptyDict( server->vol.util );
dict_loadFromStream( newDict, stream );
channelNo = stream_getAddress( stream );
XP_ASSERT( channelNo != 0 );
server->nv.addresses[0].channelNo = channelNo;
/* PENDING init's a bit harsh for setting the size */
model_init( model, nCols, nCols );
nPlayers = localGI.nPlayers;
XP_STATUSF( "reading in %d players", localGI.nPlayers );
gi_disposePlayerInfo( MPPARM(server->mpool) &localGI );
gi->nPlayers = nPlayers;
model_setNPlayers( model, nPlayers );
curDict = model_getDictionary( model );
XP_ASSERT( !!newDict );
if ( curDict == NULL ) {
model_setDictionary( model, newDict );
} else if ( dict_tilesAreSame( newDict, curDict ) ) {
/* keep the dict the local user installed */
dict_destroy( newDict );
} else {
dict_destroy( curDict );
model_setDictionary( model, newDict );
util_userError( server->vol.util, ERR_SERVER_DICT_WINS );
clearLocalRobots( server );
}
XP_ASSERT( !server->pool );
pool = server->pool = pool_make( MPPARM_NOCOMMA(server->mpool) );
pool_initFromDict( server->pool, model_getDictionary(model));
/* now read the assigned tiles for each player from the stream, and remove
them from the newly-created local pool. */
for ( i = 0; i < nPlayers; ++i ) {
TrayTileSet tiles;
traySetFromStream( stream, &tiles );
XP_ASSERT( tiles.nTiles <= MAX_TRAY_TILES );
XP_STATUSF( "got %d tiles for player %d", tiles.nTiles, i );
model_assignPlayerTiles( model, i, &tiles );
/* remove what the server's assigned so we won't conflict later. */
pool_removeTiles( pool, &tiles );
}
SETSTATE( server, XWSTATE_INTURN );
/* Give board a chance to redraw self with the full compliment of known
players */
setTurn( server, 0 );
}
stream_setVersion( stream, streamVersion );
gameID = stream_getU32( stream );
XP_STATUSF( "read gameID of %lx; calling comms_setConnID", gameID );
server->vol.gi->gameID = gameID;
comms_setConnID( server->vol.comms, gameID );
XP_MEMSET( &localGI, 0, sizeof(localGI) );
gi_readFromStream( MPPARM(server->mpool) stream, &localGI );
localGI.serverRole = SERVER_ISCLIENT;
/* so it's not lost (HACK!). Without this, a client won't have a default
dict name when a new game is started. */
localGI.dictName = copyString( server->mpool, gi->dictName );
gi_copy( MPPARM(server->mpool) gi, &localGI );
nCols = localGI.boardSize;
newDict = util_makeEmptyDict( server->vol.util );
dict_loadFromStream( newDict, stream );
channelNo = stream_getAddress( stream );
XP_ASSERT( channelNo != 0 );
XP_ASSERT( server->nv.addresses[0].channelNo == 0 );
server->nv.addresses[0].channelNo = channelNo;
/* PENDING init's a bit harsh for setting the size */
model_init( model, nCols, nCols );
nPlayers = localGI.nPlayers;
XP_STATUSF( "reading in %d players", localGI.nPlayers );
gi_disposePlayerInfo( MPPARM(server->mpool) &localGI );
gi->nPlayers = nPlayers;
model_setNPlayers( model, nPlayers );
curDict = model_getDictionary( model );
XP_ASSERT( !!newDict );
if ( curDict == NULL ) {
model_setDictionary( model, newDict );
} else if ( dict_tilesAreSame( newDict, curDict ) ) {
/* keep the dict the local user installed */
dict_destroy( newDict );
} else {
dict_destroy( curDict );
model_setDictionary( model, newDict );
util_userError( server->vol.util, ERR_SERVER_DICT_WINS );
clearLocalRobots( server );
}
XP_ASSERT( !server->pool );
pool = server->pool = pool_make( MPPARM_NOCOMMA(server->mpool) );
pool_initFromDict( server->pool, model_getDictionary(model));
/* now read the assigned tiles for each player from the stream, and remove
them from the newly-created local pool. */
for ( i = 0; i < nPlayers; ++i ) {
TrayTileSet tiles;
traySetFromStream( stream, &tiles );
XP_ASSERT( tiles.nTiles <= MAX_TRAY_TILES );
XP_STATUSF( "got %d tiles for player %d", tiles.nTiles, i );
model_assignPlayerTiles( model, i, &tiles );
/* remove what the server's assigned so we won't conflict later. */
pool_removeTiles( pool, &tiles );
}
SETSTATE( server, XWSTATE_INTURN );
/* Give board a chance to redraw self with the full compliment of known
players */
setTurn( server, 0 );
return XP_TRUE;
return accepted;
} /* client_readInitialMessage */
#endif