mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-01-30 08:34:16 +01:00
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:
parent
4074417b33
commit
40f7295802
4 changed files with 110 additions and 99 deletions
|
@ -1014,9 +1014,13 @@ preProcess( CommsCtxt* comms, XWStreamCtxt* stream,
|
||||||
static AddressRecord*
|
static AddressRecord*
|
||||||
addrToRecord( CommsCtxt* comms, const CommsAddrRec* addr )
|
addrToRecord( CommsCtxt* comms, const CommsAddrRec* addr )
|
||||||
{
|
{
|
||||||
CommsConnType conType = addr->conType;
|
CommsConnType conType;
|
||||||
AddressRecord* rec;
|
AddressRecord* rec;
|
||||||
XP_Bool matched = XP_FALSE;
|
XP_Bool matched = XP_FALSE;
|
||||||
|
|
||||||
|
XP_ASSERT( !!addr );
|
||||||
|
|
||||||
|
conType = addr->conType;
|
||||||
for ( rec = comms->recs; !!rec; rec = rec->next ) {
|
for ( rec = comms->recs; !!rec; rec = rec->next ) {
|
||||||
XP_ASSERT( conType == rec->addr.conType );
|
XP_ASSERT( conType == rec->addr.conType );
|
||||||
switch( conType ) {
|
switch( conType ) {
|
||||||
|
@ -1039,7 +1043,9 @@ addrToRecord( CommsCtxt* comms, const CommsAddrRec* addr )
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case COMMS_CONN_IR: /* no way to test */
|
case COMMS_CONN_IR: /* no way to test */
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
|
XP_ASSERT(0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ( matched ) {
|
if ( matched ) {
|
||||||
|
|
|
@ -315,10 +315,10 @@ gi_disposePlayerInfo( MPFORMAL CurGameInfo* gi )
|
||||||
} /* gi_disposePlayerInfo */
|
} /* gi_disposePlayerInfo */
|
||||||
|
|
||||||
void
|
void
|
||||||
gi_copy( MPFORMAL CurGameInfo* destGI, CurGameInfo* srcGI )
|
gi_copy( MPFORMAL CurGameInfo* destGI, const CurGameInfo* srcGI )
|
||||||
{
|
{
|
||||||
XP_U16 nPlayers, i;
|
XP_U16 nPlayers, i;
|
||||||
LocalPlayer* srcPl;
|
const LocalPlayer* srcPl;
|
||||||
LocalPlayer* destPl;
|
LocalPlayer* destPl;
|
||||||
|
|
||||||
replaceStringIfDifferent( mpool, &destGI->dictName,
|
replaceStringIfDifferent( mpool, &destGI->dictName,
|
||||||
|
|
|
@ -99,7 +99,7 @@ void gi_initPlayerInfo( MPFORMAL CurGameInfo* gi,
|
||||||
void gi_disposePlayerInfo( MPFORMAL CurGameInfo* gi );
|
void gi_disposePlayerInfo( MPFORMAL CurGameInfo* gi );
|
||||||
void gi_writeToStream( XWStreamCtxt* stream, const CurGameInfo* gi );
|
void gi_writeToStream( XWStreamCtxt* stream, const CurGameInfo* gi );
|
||||||
void gi_readFromStream( MPFORMAL XWStreamCtxt* stream, 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_U16 gi_countLocalHumans( const CurGameInfo* gi );
|
||||||
|
|
||||||
XP_Bool player_hasPasswd( LocalPlayer* player );
|
XP_Bool player_hasPasswd( LocalPlayer* player );
|
||||||
|
|
|
@ -940,103 +940,108 @@ clearLocalRobots( ServerCtxt* server )
|
||||||
static XP_Bool
|
static XP_Bool
|
||||||
client_readInitialMessage( ServerCtxt* server, XWStreamCtxt* stream )
|
client_readInitialMessage( ServerCtxt* server, XWStreamCtxt* stream )
|
||||||
{
|
{
|
||||||
DictionaryCtxt* newDict;
|
XP_Bool accepted = 0 == server->nv.addresses[0].channelNo;
|
||||||
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 */
|
/* We should never get this message a second time, but very rarely we do.
|
||||||
XP_U8 streamVersion = stream_getU8( stream );
|
Drop it in that case. */
|
||||||
XP_ASSERT( streamVersion == STREAM_VERS_41B4 );
|
XP_ASSERT( accepted );
|
||||||
if ( streamVersion != STREAM_VERS_41B4 ) {
|
if ( accepted ) {
|
||||||
return XP_FALSE;
|
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 );
|
return accepted;
|
||||||
|
|
||||||
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;
|
|
||||||
} /* client_readInitialMessage */
|
} /* client_readInitialMessage */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue