mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-02-15 08:47:56 +01:00
fix harvesting of known player names to not mismatch name/address
The buggy code assumed two arrays were in sync that weren't guaranteed to be so. So now I'm leveraging rematch code that already put addresses in player order.
This commit is contained in:
parent
daacc66ffe
commit
696c47ace4
12 changed files with 233 additions and 166 deletions
|
@ -237,7 +237,7 @@ mutex_init(CommsCtxt* comms)
|
|||
#define COMMS_MUTEX_UNLOCK COMMS_MUTEX_UNLOCK_RELEASE
|
||||
#endif
|
||||
|
||||
#define FLAG_HARVEST_DONE 1
|
||||
#define _FLAG_HARVEST_DONE 1 /* no longer used */
|
||||
#define FLAG_QUASHED 2
|
||||
|
||||
#define QUASHED(COMMS) (0 != ((COMMS)->flags & FLAG_QUASHED))
|
||||
|
@ -3397,31 +3397,6 @@ comms_setQuashed( CommsCtxt* comms, XWEnv xwe, XP_Bool quashed )
|
|||
return changed;
|
||||
}
|
||||
|
||||
#ifdef XWFEATURE_KNOWNPLAYERS
|
||||
void
|
||||
comms_gatherPlayers( CommsCtxt* comms, XWEnv xwe, XP_U32 created )
|
||||
{
|
||||
COMMS_MUTEX_LOCK(comms);
|
||||
if ( 0 == (comms->flags & FLAG_HARVEST_DONE) ) {
|
||||
CommsAddrRec addrs[4] = {{0}};
|
||||
XP_U16 nRecs = VSIZE(addrs);
|
||||
comms_getAddrs( comms, addrs, &nRecs );
|
||||
|
||||
const CurGameInfo* gi = comms->util->gameInfo;
|
||||
XP_ASSERT( 0 < gi->nPlayers );
|
||||
if ( kplr_addAddrs( comms->dutil, xwe, gi, addrs, nRecs, created ) ) {
|
||||
/* if ( 1 ) { */
|
||||
/* COMMS_LOGFF( "not setting flag :-)" ); */
|
||||
/* } else { */
|
||||
/* /\* Need a way to force/override this manually? *\/ */
|
||||
/* comms->flags |= FLAG_HARVEST_DONE; */
|
||||
/* } */
|
||||
}
|
||||
}
|
||||
COMMS_MUTEX_UNLOCK();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef RELAY_VIA_HTTP
|
||||
void
|
||||
comms_gameJoined( CommsCtxt* comms, XWEnv xwe, const XP_UCHAR* connname, XWHostID hid )
|
||||
|
|
|
@ -271,10 +271,6 @@ void types_rmType( XP_U16* conTypes, CommsConnType type );
|
|||
XP_Bool types_hasType( XP_U16 conTypes, CommsConnType type );
|
||||
XP_Bool types_iter( XP_U32 conTypes, CommsConnType* typp, XP_U32* state );
|
||||
|
||||
#ifdef XWFEATURE_KNOWNPLAYERS
|
||||
void comms_gatherPlayers( CommsCtxt* comms, XWEnv xwe, XP_U32 created );
|
||||
#endif
|
||||
|
||||
const char* ConnType2Str( CommsConnType typ );
|
||||
|
||||
# ifdef DEBUG
|
||||
|
|
|
@ -380,9 +380,9 @@ game_makeFromStream( MPFORMAL XWEnv xwe, XWStreamCtxt* stream,
|
|||
|
||||
#ifdef XWFEATURE_KNOWNPLAYERS
|
||||
const XP_U32 created = game->created;
|
||||
if ( 0 != created
|
||||
if ( !!game->comms && 0 != created
|
||||
&& server_getGameIsConnected( game->server ) ) {
|
||||
comms_gatherPlayers( game->comms, xwe, created );
|
||||
server_gatherPlayers( game->server, xwe, created );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -564,7 +564,7 @@ game_dispose( XWGame* game, XWEnv xwe )
|
|||
const XP_U32 created = game->created;
|
||||
if ( !!game->comms && 0 != created
|
||||
&& server_getGameIsConnected( game->server ) ) {
|
||||
comms_gatherPlayers( game->comms, xwe, created );
|
||||
server_gatherPlayers( game->server, xwe, created );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1072,6 +1072,7 @@ game_logGI( const CurGameInfo* gi, const char* msg, const char* func, int line )
|
|||
XP_LOGFF( "msg: %s from %s() line %d; gameID: %X", msg, func, line,
|
||||
!!gi ? gi->gameID:0 );
|
||||
if ( !!gi ) {
|
||||
XP_LOGF( " serverRole: %d", gi->serverRole );
|
||||
XP_LOGF( " nPlayers: %d", gi->nPlayers );
|
||||
for ( XP_U16 ii = 0; ii < gi->nPlayers; ++ii ) {
|
||||
const LocalPlayer* lp = &gi->players[ii];
|
||||
|
@ -1079,7 +1080,6 @@ game_logGI( const CurGameInfo* gi, const char* msg, const char* func, int line )
|
|||
boolToStr(lp->isLocal), lp->robotIQ, lp->name, lp->dictName, lp->password );
|
||||
}
|
||||
XP_LOGF( " forceChannel: %d", gi->forceChannel );
|
||||
XP_LOGF( " serverRole: %d", gi->serverRole );
|
||||
XP_LOGF( " dictName: %s", gi->dictName );
|
||||
XP_LOGF( " isoCode: %s", gi->isoCodeStr );
|
||||
XP_LOGF( " tradeSub7: %s", boolToStr(gi->tradeSub7) );
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
// #define ENABLE_LOGFFV 1
|
||||
#ifdef XWFEATURE_KNOWNPLAYERS
|
||||
|
||||
#include "knownplyr.h"
|
||||
#include "strutils.h"
|
||||
|
@ -26,8 +26,6 @@
|
|||
#include "dbgutil.h"
|
||||
#include "dllist.h"
|
||||
|
||||
#ifdef XWFEATURE_KNOWNPLAYERS
|
||||
|
||||
typedef struct _KnownPlayer {
|
||||
DLHead links;
|
||||
XP_U32 newestMod;
|
||||
|
@ -127,23 +125,6 @@ releaseState( XW_DUtilCtxt* dutil, XWEnv xwe, KPState* state )
|
|||
pthread_mutex_unlock( &dutil->kpMutex );
|
||||
}
|
||||
|
||||
static const XP_UCHAR*
|
||||
figureNameFor( XP_U16 posn, const CurGameInfo* gi )
|
||||
{
|
||||
const XP_UCHAR* result = NULL;
|
||||
for ( int ii = 0, nthRemote = 0;
|
||||
NULL == result && ii < gi->nPlayers;
|
||||
++ii ) {
|
||||
const LocalPlayer* lp = &gi->players[ii];
|
||||
if ( lp->isLocal ) {
|
||||
continue;
|
||||
} else if ( nthRemote++ == posn ) {
|
||||
result = lp->name;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
makeUniqueName( const KPState* state, const XP_UCHAR* name,
|
||||
XP_UCHAR newName[], XP_U16 len )
|
||||
|
@ -261,29 +242,15 @@ addPlayer( XW_DUtilCtxt* XP_UNUSED_DBG(dutil), KPState* state,
|
|||
}
|
||||
|
||||
XP_Bool
|
||||
kplr_addAddrs( XW_DUtilCtxt* dutil, XWEnv xwe, const CurGameInfo* gi,
|
||||
CommsAddrRec addrs[], XP_U16 nAddrs, XP_U32 modTime )
|
||||
kplr_addAddr( XW_DUtilCtxt* dutil, XWEnv xwe, const CommsAddrRec* addr,
|
||||
const XP_UCHAR* name, XP_U32 modTime )
|
||||
{
|
||||
XP_LOGFFV( "(nAddrs=%d)", nAddrs );
|
||||
XP_ASSERT( modTime );
|
||||
XP_Bool canUse = XP_TRUE;
|
||||
for ( int ii = 0; ii < nAddrs && canUse; ++ii ) {
|
||||
canUse = addr_hasType( &addrs[ii], COMMS_CONN_MQTT );
|
||||
if ( !canUse ) {
|
||||
XP_LOGFF( "addr %d has no mqqt id", ii );
|
||||
}
|
||||
}
|
||||
|
||||
XP_ASSERT( !!name );
|
||||
XP_Bool canUse = addr_hasType( addr, COMMS_CONN_MQTT );
|
||||
if ( canUse ) {
|
||||
KPState* state = loadState( dutil, xwe );
|
||||
for ( int ii = 0; ii < nAddrs && canUse; ++ii ) {
|
||||
const XP_UCHAR* name = figureNameFor( ii, gi );
|
||||
if ( !!name ) {
|
||||
addPlayer( dutil, state, name, &addrs[ii], modTime );
|
||||
} else {
|
||||
XP_LOGFF( "unable to find %dth name", ii );
|
||||
}
|
||||
}
|
||||
addPlayer( dutil, state, name, addr, modTime );
|
||||
releaseState( dutil, xwe, state );
|
||||
}
|
||||
|
||||
|
|
|
@ -52,8 +52,8 @@ KP_Rslt kplr_renamePlayer( XW_DUtilCtxt* dutil, XWEnv xwe, const XP_UCHAR* oldNa
|
|||
const XP_UCHAR* newName );
|
||||
KP_Rslt kplr_deletePlayer( XW_DUtilCtxt* dutil, XWEnv xwe, const XP_UCHAR* name );
|
||||
|
||||
XP_Bool kplr_addAddrs( XW_DUtilCtxt* dutil, XWEnv xwe, const CurGameInfo* gi,
|
||||
CommsAddrRec addrs[], XP_U16 nAddrs, XP_U32 modTime );
|
||||
XP_Bool kplr_addAddr( XW_DUtilCtxt* dutil, XWEnv xwe, const CommsAddrRec* addr,
|
||||
const XP_UCHAR* name, XP_U32 modTime );
|
||||
# else
|
||||
# define kplr_cleanup( dutil )
|
||||
# endif
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "device.h"
|
||||
#include "strutils.h"
|
||||
#include "dbgutil.h"
|
||||
#include "knownplyr.h"
|
||||
|
||||
#include "LocalizedStrIncludes.h"
|
||||
|
||||
|
@ -119,6 +120,7 @@ typedef struct ServerVolatiles {
|
|||
|
||||
#define MASK_IS_FROM_REMATCH (1<<0)
|
||||
#define MASK_HAVE_RIP_INFO (1<<1)
|
||||
#define FLAG_HARVEST_READY (1<<2)
|
||||
|
||||
typedef struct _ServerNonvolatiles {
|
||||
XP_U32 flags; /* */
|
||||
|
@ -287,6 +289,9 @@ static void writeProto( const ServerCtxt* server, XWStreamCtxt* stream,
|
|||
XW_Proto proto );
|
||||
static void readGuestAddrs( ServerCtxt* server, XWStreamCtxt* stream,
|
||||
XP_U8 streamVersion );
|
||||
static XP_Bool getRematchInfoImpl( const ServerCtxt* server,
|
||||
CurGameInfo* newGI, const NewOrder* nop,
|
||||
RematchInfo** ripp );
|
||||
|
||||
static void ri_fromStream( RematchInfo* rip, XWStreamCtxt* stream,
|
||||
const ServerCtxt* server );
|
||||
|
@ -2017,6 +2022,7 @@ server_do( ServerCtxt* server, XWEnv xwe )
|
|||
SETSTATE( server, XWSTATE_INTURN );
|
||||
setTurn( server, xwe, 0 );
|
||||
moreToDo = XP_TRUE;
|
||||
server->nv.flags |= FLAG_HARVEST_READY;
|
||||
break;
|
||||
|
||||
case XWSTATE_MOVE_CONFIRM_MUSTSEND:
|
||||
|
@ -2269,6 +2275,7 @@ client_readInitialMessage( ServerCtxt* server, XWEnv xwe, XWStreamCtxt* stream )
|
|||
XP_ASSERT( !localGI.dictName );
|
||||
localGI.dictName = copyString( server->mpool, gi->dictName );
|
||||
gi_copy( MPPARM(server->mpool) gi, &localGI );
|
||||
server->nv.flags |= FLAG_HARVEST_READY;
|
||||
|
||||
if ( streamVersion < STREAM_VERS_NOEMPTYDICT ) {
|
||||
SRVR_LOGFF( "loading and dropping empty dict" );
|
||||
|
@ -4266,9 +4273,7 @@ server_getRematchInfo( const ServerCtxt* server, XW_UtilCtxt* newUtil,
|
|||
XP_U32 gameID, const NewOrder* nop, RematchInfo** ripp )
|
||||
{
|
||||
XP_Bool success = server_canRematch( server, NULL );
|
||||
const CommsCtxt* comms = server->vol.comms;
|
||||
if ( success ) {
|
||||
RematchInfo ri = {0};
|
||||
CurGameInfo* newGI = newUtil->gameInfo;
|
||||
gi_disposePlayerInfo( MPPARM(newUtil->mpool) newGI );
|
||||
|
||||
|
@ -4280,102 +4285,114 @@ server_getRematchInfo( const ServerCtxt* server, XW_UtilCtxt* newUtil,
|
|||
}
|
||||
LOGGI( newUtil->gameInfo, "ready to invite" );
|
||||
|
||||
/* Now build the address list. Simple cases are STANDALONE, when I'm
|
||||
the host, or when there are only two devices/players. If I'm guest
|
||||
and there is another guest, I count on the host having sent rematch
|
||||
info, and *that* info has an old and a new format. Sheesh. */
|
||||
XP_Bool canOrder = XP_TRUE;
|
||||
if ( !comms ) {
|
||||
/* no addressing to do!! */
|
||||
} else if ( amHost( server ) || 2 == newGI->nPlayers ) {
|
||||
for ( int ii = 0; ii < newGI->nPlayers; ++ii ) {
|
||||
success = getRematchInfoImpl( server, newGI, nop, ripp );
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
static XP_Bool
|
||||
getRematchInfoImpl( const ServerCtxt* server, CurGameInfo* newGI,
|
||||
const NewOrder* nop, RematchInfo** ripp )
|
||||
{
|
||||
XP_Bool success = XP_TRUE;
|
||||
RematchInfo ri = {0};
|
||||
const CommsCtxt* comms = server->vol.comms;
|
||||
/* Now build the address list. Simple cases are STANDALONE, when I'm
|
||||
the host, or when there are only two devices/players. If I'm guest
|
||||
and there is another guest, I count on the host having sent rematch
|
||||
info, and *that* info has an old and a new format. Sheesh. */
|
||||
XP_Bool canOrder = XP_TRUE;
|
||||
if ( !comms ) {
|
||||
/* no addressing to do!! */
|
||||
} else if ( amHost( server ) || 2 == newGI->nPlayers ) {
|
||||
for ( int ii = 0; ii < newGI->nPlayers; ++ii ) {
|
||||
if ( newGI->players[ii].isLocal ) {
|
||||
ri_addLocal( &ri );
|
||||
} else {
|
||||
CommsAddrRec addr;
|
||||
if ( amHost(server) ) {
|
||||
XP_S8 deviceIndex = server->srvPlyrs[ii].deviceIndex;
|
||||
XP_ASSERT( deviceIndex != RIP_LOCAL_INDX );
|
||||
XP_PlayerAddr channelNo =
|
||||
server->nv.addresses[deviceIndex].channelNo;
|
||||
comms_getChannelAddr( comms, channelNo, &addr );
|
||||
} else {
|
||||
comms_getHostAddr( comms, &addr );
|
||||
}
|
||||
ri_addAddrAt( &ri, server, &addr, ii );
|
||||
}
|
||||
}
|
||||
} else if ( !!server->nv.rematch.addrs ) {
|
||||
XP_U16 streamVersion = server->nv.streamVersion;
|
||||
if ( STREAM_VERS_REMATCHORDER <= streamVersion ) {
|
||||
loadRemoteRI( server, newGI, &ri );
|
||||
|
||||
} else {
|
||||
/* I don't have complete info yet. So let's go through the gi,
|
||||
assigning an address to all non-local players. We'll use
|
||||
the host address first, then the rest we have. If we don't
|
||||
have the right number of everything, we fail. Note: we
|
||||
should not have given the user a choice in rematch ordering
|
||||
here!!!*/
|
||||
canOrder = newGI->nPlayers <= 2;
|
||||
XP_ASSERT( !canOrder );
|
||||
canOrder = XP_FALSE;
|
||||
|
||||
CommsAddrRec addrs[MAX_NUM_PLAYERS];
|
||||
int nAddrs = 0;
|
||||
comms_getHostAddr( comms, &addrs[nAddrs++] );
|
||||
|
||||
XWStreamCtxt* stream = mkServerStream( server,
|
||||
server->nv.streamVersion );
|
||||
stream_putBytes( stream, server->nv.rematch.addrs,
|
||||
server->nv.rematch.addrsLen );
|
||||
while ( 0 < stream_getSize( stream ) ) {
|
||||
XP_ASSERT( nAddrs < VSIZE(addrs) );
|
||||
addrFromStream( &addrs[nAddrs++], stream );
|
||||
}
|
||||
stream_destroy( stream );
|
||||
|
||||
int nextRemote = 0;
|
||||
for ( int ii = 0; success && ii < newGI->nPlayers; ++ii ) {
|
||||
if ( newGI->players[ii].isLocal ) {
|
||||
ri_addLocal( &ri );
|
||||
} else if ( nextRemote < nAddrs ) {
|
||||
ri_addAddrAt( &ri, server, &addrs[nextRemote++], ii );
|
||||
} else {
|
||||
CommsAddrRec addr;
|
||||
if ( amHost(server) ) {
|
||||
XP_S8 deviceIndex = server->srvPlyrs[ii].deviceIndex;
|
||||
XP_ASSERT( deviceIndex != RIP_LOCAL_INDX );
|
||||
XP_PlayerAddr channelNo =
|
||||
server->nv.addresses[deviceIndex].channelNo;
|
||||
comms_getChannelAddr( comms, channelNo, &addr );
|
||||
} else {
|
||||
comms_getHostAddr( comms, &addr );
|
||||
}
|
||||
ri_addAddrAt( &ri, server, &addr, ii );
|
||||
SRVR_LOGFF( "ERROR: not enough addresses for all"
|
||||
" remote players" );
|
||||
success = XP_FALSE;
|
||||
}
|
||||
}
|
||||
} else if ( !!server->nv.rematch.addrs ) {
|
||||
XP_U16 streamVersion = server->nv.streamVersion;
|
||||
if ( STREAM_VERS_REMATCHORDER <= streamVersion ) {
|
||||
loadRemoteRI( server, newGI, &ri );
|
||||
|
||||
} else {
|
||||
/* I don't have complete info yet. So let's go through the gi,
|
||||
assigning an address to all non-local players. We'll use
|
||||
the host address first, then the rest we have. If we don't
|
||||
have the right number of everything, we fail. Note: we
|
||||
should not have given the user a choice in rematch ordering
|
||||
here!!!*/
|
||||
canOrder = newGI->nPlayers <= 2;
|
||||
XP_ASSERT( !canOrder );
|
||||
canOrder = XP_FALSE;
|
||||
|
||||
CommsAddrRec addrs[MAX_NUM_PLAYERS];
|
||||
int nAddrs = 0;
|
||||
comms_getHostAddr( comms, &addrs[nAddrs++] );
|
||||
|
||||
XWStreamCtxt* stream = mkServerStream( server, server->nv.streamVersion );
|
||||
stream_putBytes( stream, server->nv.rematch.addrs,
|
||||
server->nv.rematch.addrsLen );
|
||||
while ( 0 < stream_getSize( stream ) ) {
|
||||
XP_ASSERT( nAddrs < VSIZE(addrs) );
|
||||
addrFromStream( &addrs[nAddrs++], stream );
|
||||
}
|
||||
stream_destroy( stream );
|
||||
|
||||
int nextRemote = 0;
|
||||
for ( int ii = 0; success && ii < newGI->nPlayers; ++ii ) {
|
||||
if ( newGI->players[ii].isLocal ) {
|
||||
ri_addLocal( &ri );
|
||||
} else if ( nextRemote < nAddrs ) {
|
||||
ri_addAddrAt( &ri, server, &addrs[nextRemote++], ii );
|
||||
} else {
|
||||
SRVR_LOGFF( "ERROR: not enough addresses for all remote players" );
|
||||
success = XP_FALSE;
|
||||
}
|
||||
}
|
||||
if ( success ) {
|
||||
success = nextRemote == nAddrs;
|
||||
}
|
||||
if ( success ) {
|
||||
success = nextRemote == nAddrs;
|
||||
}
|
||||
} else {
|
||||
XP_ASSERT( 0 ); /* should not have returned TRUE from server_canRematch(); */
|
||||
success = XP_FALSE;
|
||||
}
|
||||
|
||||
if ( success && canOrder ) {
|
||||
if ( !!comms ) {
|
||||
assertRI( &ri, newGI );
|
||||
}
|
||||
success = setPlayerOrder( server, nop, newGI, !!comms ? &ri : NULL );
|
||||
}
|
||||
|
||||
if ( success && !!comms ) {
|
||||
LOG_RI( &ri );
|
||||
assertRI( &ri, newGI );
|
||||
XP_ASSERT( success );
|
||||
*ripp = XP_MALLOC(server->mpool, sizeof(**ripp));
|
||||
**ripp = ri;
|
||||
} else {
|
||||
*ripp = NULL;
|
||||
}
|
||||
XP_ASSERT( success );
|
||||
} else {
|
||||
success = XP_FALSE;
|
||||
}
|
||||
|
||||
if ( success && canOrder ) {
|
||||
if ( !!comms ) {
|
||||
assertRI( &ri, newGI );
|
||||
}
|
||||
success = setPlayerOrder( server, nop, newGI, !!comms ? &ri : NULL );
|
||||
}
|
||||
|
||||
if ( success && !!comms ) {
|
||||
LOG_RI( &ri );
|
||||
assertRI( &ri, newGI );
|
||||
XP_ASSERT( success );
|
||||
*ripp = XP_MALLOC(server->mpool, sizeof(**ripp));
|
||||
**ripp = ri;
|
||||
} else {
|
||||
*ripp = NULL;
|
||||
}
|
||||
XP_ASSERT( success );
|
||||
|
||||
LOG_RETURNF( "%s", boolToStr(success) );
|
||||
return success;
|
||||
} /* server_getRematchInfo */
|
||||
} /* getRematchInfoImpl */
|
||||
|
||||
void
|
||||
server_disposeRematchInfo( ServerCtxt* XP_UNUSED_DBG(server), RematchInfo** ripp )
|
||||
|
@ -4464,6 +4481,42 @@ server_isFromRematch( const ServerCtxt* server )
|
|||
return 0 != (server->nv.flags & MASK_IS_FROM_REMATCH);
|
||||
}
|
||||
|
||||
#ifdef XWFEATURE_KNOWNPLAYERS
|
||||
void
|
||||
server_gatherPlayers( ServerCtxt* server, XWEnv xwe, XP_U32 created )
|
||||
{
|
||||
XP_Bool flagSet = 0 != (server->nv.flags & FLAG_HARVEST_READY);
|
||||
if ( flagSet ) {
|
||||
const CurGameInfo* gi = server->vol.gi;
|
||||
XW_DUtilCtxt* dutil = server->vol.dutil;
|
||||
|
||||
NewOrder no;
|
||||
server_figureOrder( server, RO_SAME, &no );
|
||||
|
||||
CurGameInfo tmpGi = *gi;
|
||||
RematchInfo* ripp;
|
||||
if ( getRematchInfoImpl( server, &tmpGi, &no, &ripp ) ) {
|
||||
for ( int ii = 0, nRemotes = 0; ii < gi->nPlayers; ++ii ) {
|
||||
const LocalPlayer* lp = &gi->players[ii];
|
||||
/* order unchanged? */
|
||||
XP_ASSERT( lp->name == gi->players[ii].name );
|
||||
if ( !lp->isLocal ) {
|
||||
CommsAddrRec addr;
|
||||
XP_U16 nPlayersH;
|
||||
if ( !server_ri_getAddr( ripp, nRemotes++, &addr, &nPlayersH ) ) {
|
||||
break;
|
||||
}
|
||||
XP_ASSERT( 1 == nPlayersH ); /* else fixme... */
|
||||
kplr_addAddr( dutil, xwe, &addr, lp->name, created );
|
||||
}
|
||||
}
|
||||
|
||||
server_disposeRematchInfo( server, &ripp );
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
static void
|
||||
log_ri( const ServerCtxt* server, const RematchInfo* rip,
|
||||
|
@ -4482,7 +4535,8 @@ log_ri( const ServerCtxt* server, const RematchInfo* rip,
|
|||
maxIndx = indx;
|
||||
}
|
||||
}
|
||||
SRVR_LOGFFV( "%d players (and %d addrs): [%s]", rip->nPlayers, rip->nAddrs, buf );
|
||||
SRVR_LOGFFV( "%d players (and %d addrs): [%s]", rip->nPlayers,
|
||||
rip->nAddrs, buf );
|
||||
|
||||
for ( int ii = 0; ii < rip->nAddrs; ++ii ) {
|
||||
XP_SNPRINTF( buf, VSIZE(buf), "[%d of %d]: %s from %s",
|
||||
|
|
|
@ -199,6 +199,10 @@ void server_setRematchOrder( ServerCtxt* server, const RematchInfo* ri );
|
|||
|
||||
XP_Bool server_isFromRematch( const ServerCtxt* server );
|
||||
|
||||
#ifdef XWFEATURE_KNOWNPLAYERS
|
||||
void server_gatherPlayers( ServerCtxt* server, XWEnv xwe, XP_U32 created );
|
||||
#endif
|
||||
|
||||
#ifdef CPLUS
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -447,8 +447,8 @@ disposeBoard( CursesBoardGlobals* bGlobals, XP_Bool rmFromList )
|
|||
cmenu_pop( bGlobals->cbState->menuState );
|
||||
}
|
||||
|
||||
gi_disposePlayerInfo( MPPARM(cGlobals->util->mpool) cGlobals->gi );
|
||||
game_dispose( &cGlobals->game, NULL_XWE );
|
||||
gi_disposePlayerInfo( MPPARM(cGlobals->util->mpool) cGlobals->gi );
|
||||
|
||||
disposeUtil( cGlobals );
|
||||
|
||||
|
|
|
@ -75,6 +75,7 @@
|
|||
#include "curgamlistwin.h"
|
||||
#include "gsrcwrap.h"
|
||||
#include "extcmds.h"
|
||||
#include "knownplyr.h"
|
||||
|
||||
#ifndef CURSES_CELL_HT
|
||||
# define CURSES_CELL_HT 1
|
||||
|
@ -1516,6 +1517,37 @@ resignWrapper( void* closure, XP_U32 gameID )
|
|||
return cb_resign( aGlobals->cbState, gameID );
|
||||
}
|
||||
|
||||
static cJSON*
|
||||
getKPsWrapper( void* closure )
|
||||
{
|
||||
CursesAppGlobals* aGlobals = (CursesAppGlobals*)closure;
|
||||
XW_DUtilCtxt* dutil = aGlobals->cag.params->dutil;
|
||||
|
||||
XP_U16 nFound = 0;
|
||||
kplr_getNames( dutil, NULL_XWE, XP_FALSE, NULL, &nFound );
|
||||
const XP_UCHAR* players[nFound];
|
||||
kplr_getNames( dutil, NULL_XWE, XP_FALSE, players, &nFound );
|
||||
|
||||
cJSON* result = cJSON_CreateArray();
|
||||
for ( int ii = 0; ii < nFound; ++ii ) {
|
||||
cJSON* entry = cJSON_CreateObject();
|
||||
cJSON_AddStringToObject( entry, "name", players[ii]);
|
||||
|
||||
CommsAddrRec addr;
|
||||
if ( kplr_getAddr( dutil, NULL_XWE, players[ii],
|
||||
&addr, NULL ) ) {
|
||||
|
||||
XP_UCHAR buf[17];
|
||||
formatMQTTDevID( &addr.u.mqtt.devID, buf, VSIZE(buf) );
|
||||
cJSON_AddStringToObject( entry, "devID", buf );
|
||||
}
|
||||
|
||||
cJSON_AddItemToArray( result, entry );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
cursesmain( XP_Bool XP_UNUSED(isServer), LaunchParams* params )
|
||||
{
|
||||
|
@ -1552,6 +1584,7 @@ cursesmain( XP_Bool XP_UNUSED(isServer), LaunchParams* params )
|
|||
.sendChat = sendChatWrapper,
|
||||
.undoMove = undoMoveWrapper,
|
||||
.resign = resignWrapper,
|
||||
.getKPs = getKPsWrapper,
|
||||
},
|
||||
};
|
||||
GSocketService* cmdService = cmds_addCmdListener( &wr );
|
||||
|
|
|
@ -153,6 +153,11 @@ resignFromArgs( CmdWrapper* wr, cJSON* args )
|
|||
XP_U32 gameID = gidFromObject( args );
|
||||
return (*wr->procs.resign)( wr->closure, gameID );
|
||||
}
|
||||
static cJSON*
|
||||
knwnPlyrs( CmdWrapper* wr )
|
||||
{
|
||||
return (*wr->procs.getKPs)( wr->closure );
|
||||
}
|
||||
|
||||
/* Return 'gid' of new game */
|
||||
static XP_U32
|
||||
|
@ -430,6 +435,12 @@ on_incoming_signal( GSocketService* XP_UNUSED(service),
|
|||
success = undoFromArgs( wr, args );
|
||||
} else if ( 0 == strcmp( cmdStr, "resign" ) ) {
|
||||
success = resignFromArgs( wr, args );
|
||||
} else if ( 0 == strcmp( cmdStr, "getKPs" ) ) {
|
||||
cJSON* result = knwnPlyrs( wr );
|
||||
success = !!result;
|
||||
if ( success ) {
|
||||
addObjectToObject( &response, "kps", result );
|
||||
}
|
||||
} else {
|
||||
success = XP_FALSE;
|
||||
XP_ASSERT(0);
|
||||
|
|
|
@ -37,6 +37,7 @@ typedef struct _CmdWrapper {
|
|||
XP_Bool (*sendChat)( void* closure, XP_U32 gameID, const char* msg );
|
||||
XP_Bool (*undoMove)( void* closure, XP_U32 gameID );
|
||||
XP_Bool (*resign)( void* closure, XP_U32 gameID );
|
||||
cJSON* (*getKPs)( void* closure );
|
||||
} procs;
|
||||
LaunchParams* params;
|
||||
void* closure;
|
||||
|
|
|
@ -198,6 +198,7 @@ class Device():
|
|||
_logdir = None
|
||||
_nSteps = 0
|
||||
_nextChatID = 0
|
||||
_kps = {}
|
||||
|
||||
@staticmethod
|
||||
def setup(logdir):
|
||||
|
@ -272,7 +273,10 @@ class Device():
|
|||
tryTrade = random.randint(0, 99) < self.args.TRADE_PCT
|
||||
response = self._sendWaitReply('moveIf', gid=gid, tryTrade=tryTrade)
|
||||
moved = response.get('success', False)
|
||||
if moved: break
|
||||
if moved:
|
||||
response = self._sendWaitReply('getKPs', gid=gid)
|
||||
self.checkKPs(response.get('kps'))
|
||||
break
|
||||
return moved
|
||||
|
||||
def sendChat(self):
|
||||
|
@ -280,7 +284,8 @@ class Device():
|
|||
if random.randint(0, 99) < self.args.CHAT_PCT:
|
||||
gid = self._pickGid()
|
||||
if gid:
|
||||
response = self._sendWaitReply('sendChat', gid=gid, msg=Device.nextChatMsg(self.host))
|
||||
response = self._sendWaitReply('sendChat', gid=gid,
|
||||
msg=Device.nextChatMsg(self.host))
|
||||
success = response.get('success', False)
|
||||
return success
|
||||
|
||||
|
@ -302,6 +307,19 @@ class Device():
|
|||
success = response.get('success', False)
|
||||
return success
|
||||
|
||||
def checkKPs(self, kps):
|
||||
if kps:
|
||||
for kp in kps:
|
||||
devID = kp.get('devID')
|
||||
if not devID in Device._kps: Device._kps[devID] = set()
|
||||
names = Device._kps[devID]
|
||||
|
||||
name = kp.get('name')
|
||||
if name not in names and len(names):
|
||||
print('adding {} to {} for {}' \
|
||||
.format(name, names, Device._kps.get(devID)))
|
||||
names.add(name)
|
||||
|
||||
def _pickGid(self):
|
||||
result = None
|
||||
gids = [game.gid for game in self._allGames()]
|
||||
|
@ -687,6 +705,12 @@ def countCores(args):
|
|||
count = len( glob.glob(args.CORE_PAT) )
|
||||
return count
|
||||
|
||||
def printKPs():
|
||||
kps = Device._kps
|
||||
for names in kps.values():
|
||||
assert 1 == len(names)
|
||||
print('Known players: {}'.format(kps))
|
||||
|
||||
def mainLoop(args, devs):
|
||||
startCount = len(devs)
|
||||
nCores = countCores(args)
|
||||
|
@ -936,6 +960,8 @@ def main():
|
|||
dev.quit()
|
||||
mainLoop(args, devs)
|
||||
|
||||
printKPs()
|
||||
|
||||
elapsed = datetime.datetime.now() - startTime
|
||||
print('played {} games in {}'.format(gGamesMade, elapsed))
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue