mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-02-05 20:45:49 +01:00
add test for rematch (once for now)
This commit is contained in:
parent
be9159fc35
commit
d021bb4029
4 changed files with 199 additions and 40 deletions
|
@ -135,6 +135,7 @@ static void relay_requestJoin_curses( void* closure, const XP_UCHAR* devID,
|
||||||
XP_U16 nPlayersTotal, XP_U16 seed, XP_U16 lang );
|
XP_U16 nPlayersTotal, XP_U16 seed, XP_U16 lang );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static XP_Bool rematch_and_save( CursesBoardGlobals* bGlobals, XP_U32* newGameID );
|
||||||
static void disposeBoard( CursesBoardGlobals* bGlobals );
|
static void disposeBoard( CursesBoardGlobals* bGlobals );
|
||||||
static void initCP( CommonGlobals* cGlobals );
|
static void initCP( CommonGlobals* cGlobals );
|
||||||
static CursesBoardGlobals* commonInit( CursesBoardState* cbState,
|
static CursesBoardGlobals* commonInit( CursesBoardState* cbState,
|
||||||
|
@ -595,6 +596,20 @@ enableDraw( CursesBoardGlobals* bGlobals, const cb_dims* dims )
|
||||||
setupBoard( bGlobals );
|
setupBoard( bGlobals );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static CursesBoardGlobals*
|
||||||
|
findOrOpenForGameID( CursesBoardState* cbState, XP_U32 gameID,
|
||||||
|
const CurGameInfo* gi, const CommsAddrRec* returnAddr )
|
||||||
|
{
|
||||||
|
CursesBoardGlobals* result = NULL;
|
||||||
|
sqlite3_int64 rowids[1];
|
||||||
|
int nRowIDs = VSIZE(rowids);
|
||||||
|
gdb_getRowsForGameID( cbState->params->pDb, gameID, rowids, &nRowIDs );
|
||||||
|
if ( 1 == nRowIDs ) {
|
||||||
|
result = findOrOpen( cbState, rowids[0], gi, returnAddr );
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
static CursesBoardGlobals*
|
static CursesBoardGlobals*
|
||||||
findOrOpen( CursesBoardState* cbState, sqlite3_int64 rowid,
|
findOrOpen( CursesBoardState* cbState, sqlite3_int64 rowid,
|
||||||
const CurGameInfo* gi, const CommsAddrRec* returnAddr )
|
const CurGameInfo* gi, const CommsAddrRec* returnAddr )
|
||||||
|
@ -657,12 +672,7 @@ void
|
||||||
cb_addInvite( CursesBoardState* cbState, XP_U32 gameID, XP_U16 forceChannel,
|
cb_addInvite( CursesBoardState* cbState, XP_U32 gameID, XP_U16 forceChannel,
|
||||||
const CommsAddrRec* destAddr )
|
const CommsAddrRec* destAddr )
|
||||||
{
|
{
|
||||||
sqlite3_int64 rowids[1];
|
CursesBoardGlobals* bGlobals = findOrOpenForGameID( cbState, gameID, NULL, NULL );
|
||||||
int nRowIDs = VSIZE(rowids);
|
|
||||||
gdb_getRowsForGameID( cbState->params->pDb, gameID, rowids, &nRowIDs );
|
|
||||||
XP_ASSERT( 1 == nRowIDs );
|
|
||||||
|
|
||||||
CursesBoardGlobals* bGlobals = findOrOpen( cbState, rowids[0], NULL, NULL );
|
|
||||||
CommonGlobals* cGlobals = &bGlobals->cGlobals;
|
CommonGlobals* cGlobals = &bGlobals->cGlobals;
|
||||||
CommsCtxt* comms = cGlobals->game.comms;
|
CommsCtxt* comms = cGlobals->game.comms;
|
||||||
|
|
||||||
|
@ -676,6 +686,40 @@ cb_addInvite( CursesBoardState* cbState, XP_U32 gameID, XP_U16 forceChannel,
|
||||||
comms_invite( comms, NULL_XWE, &nli, destAddr, XP_TRUE );
|
comms_invite( comms, NULL_XWE, &nli, destAddr, XP_TRUE );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XP_Bool
|
||||||
|
cb_makeRematch( CursesBoardState* cbState, XP_U32 gameID, XP_U32* newGameID )
|
||||||
|
{
|
||||||
|
CursesBoardGlobals* bGlobals = findOrOpenForGameID( cbState, gameID, NULL, NULL );
|
||||||
|
XP_Bool success = rematch_and_save( bGlobals, newGameID );
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
XP_Bool
|
||||||
|
cb_makeMoveIf( CursesBoardState* cbState, XP_U32 gameID )
|
||||||
|
{
|
||||||
|
CursesBoardGlobals* bGlobals =
|
||||||
|
findOrOpenForGameID( cbState, gameID, NULL, NULL );
|
||||||
|
XP_Bool success = !!bGlobals;
|
||||||
|
if ( success ) {
|
||||||
|
CommonGlobals* cGlobals = &bGlobals->cGlobals;
|
||||||
|
BoardCtxt* board = cGlobals->game.board;
|
||||||
|
success = board_canHint( board );
|
||||||
|
if ( success ) {
|
||||||
|
XP_Bool ignored;
|
||||||
|
success = board_requestHint( cGlobals->game.board, NULL_XWE,
|
||||||
|
#ifdef XWFEATURE_SEARCHLIMIT
|
||||||
|
XP_FALSE,
|
||||||
|
#endif
|
||||||
|
XP_FALSE, &ignored );
|
||||||
|
if ( success ) {
|
||||||
|
success = board_commitTurn( board, NULL_XWE, XP_TRUE, XP_TRUE, NULL );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOG_RETURNF( "%s", boolToStr(success) );
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
kill_board( gpointer data )
|
kill_board( gpointer data )
|
||||||
{
|
{
|
||||||
|
@ -938,7 +982,6 @@ rematch_and_save_once( CursesBoardGlobals* bGlobals )
|
||||||
{
|
{
|
||||||
LOG_FUNC();
|
LOG_FUNC();
|
||||||
CommonGlobals* cGlobals = &bGlobals->cGlobals;
|
CommonGlobals* cGlobals = &bGlobals->cGlobals;
|
||||||
CursesBoardState* cbState = bGlobals->cbState;
|
|
||||||
|
|
||||||
int32_t alreadyDone;
|
int32_t alreadyDone;
|
||||||
gchar key[128];
|
gchar key[128];
|
||||||
|
@ -947,21 +990,37 @@ rematch_and_save_once( CursesBoardGlobals* bGlobals )
|
||||||
&& 0 != alreadyDone ) {
|
&& 0 != alreadyDone ) {
|
||||||
XP_LOGFF( "already rematched game %X", cGlobals->gi->gameID );
|
XP_LOGFF( "already rematched game %X", cGlobals->gi->gameID );
|
||||||
} else {
|
} else {
|
||||||
CursesBoardGlobals* bGlobalsNew = commonInit( cbState, -1, NULL );
|
if ( rematch_and_save( bGlobals, NULL ) ) {
|
||||||
|
|
||||||
XP_Bool success = game_makeRematch( &bGlobals->cGlobals.game, NULL_XWE,
|
|
||||||
bGlobalsNew->cGlobals.util,
|
|
||||||
&cGlobals->cp, &bGlobalsNew->cGlobals.procs,
|
|
||||||
&bGlobalsNew->cGlobals.game, "newName" );
|
|
||||||
if ( success ) {
|
|
||||||
linuxSaveGame( &bGlobalsNew->cGlobals );
|
|
||||||
gdb_storeInt( cGlobals->params->pDb, key, 1 );
|
gdb_storeInt( cGlobals->params->pDb, key, 1 );
|
||||||
}
|
}
|
||||||
disposeBoard( bGlobalsNew );
|
|
||||||
}
|
}
|
||||||
LOG_RETURN_VOID();
|
LOG_RETURN_VOID();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static XP_Bool
|
||||||
|
rematch_and_save( CursesBoardGlobals* bGlobals, XP_U32* newGameID )
|
||||||
|
{
|
||||||
|
LOG_FUNC();
|
||||||
|
CommonGlobals* cGlobals = &bGlobals->cGlobals;
|
||||||
|
CursesBoardState* cbState = bGlobals->cbState;
|
||||||
|
|
||||||
|
CursesBoardGlobals* bGlobalsNew = commonInit( cbState, -1, NULL );
|
||||||
|
|
||||||
|
XP_Bool success = game_makeRematch( &bGlobals->cGlobals.game, NULL_XWE,
|
||||||
|
bGlobalsNew->cGlobals.util,
|
||||||
|
&cGlobals->cp, &bGlobalsNew->cGlobals.procs,
|
||||||
|
&bGlobalsNew->cGlobals.game, "newName" );
|
||||||
|
if ( success ) {
|
||||||
|
if ( !!newGameID ) {
|
||||||
|
*newGameID = bGlobalsNew->cGlobals.gi->gameID;
|
||||||
|
}
|
||||||
|
linuxSaveGame( &bGlobalsNew->cGlobals );
|
||||||
|
}
|
||||||
|
disposeBoard( bGlobalsNew );
|
||||||
|
LOG_RETURNF( "%s", boolToStr(success) );
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
curses_util_notifyGameOver( XW_UtilCtxt* uc, XWEnv XP_UNUSED(xwe), XP_S16 quitter )
|
curses_util_notifyGameOver( XW_UtilCtxt* uc, XWEnv XP_UNUSED(xwe), XP_S16 quitter )
|
||||||
{
|
{
|
||||||
|
|
|
@ -52,6 +52,9 @@ void cb_feedGame( CursesBoardState* cbState, XP_U32 gameID,
|
||||||
const XP_U8* buf, XP_U16 len, const CommsAddrRec* from );
|
const XP_U8* buf, XP_U16 len, const CommsAddrRec* from );
|
||||||
void cb_addInvite( CursesBoardState* cbState, XP_U32 gameID, XP_U16 forceChannel,
|
void cb_addInvite( CursesBoardState* cbState, XP_U32 gameID, XP_U16 forceChannel,
|
||||||
const CommsAddrRec* destAddr );
|
const CommsAddrRec* destAddr );
|
||||||
|
XP_Bool cb_makeRematch( CursesBoardState* cbState, XP_U32 gameID, XP_U32* newGameID );
|
||||||
|
XP_Bool cb_makeMoveIf( CursesBoardState* cbState, XP_U32 gameID );
|
||||||
|
|
||||||
void cb_closeAll( CursesBoardState* cbState );
|
void cb_closeAll( CursesBoardState* cbState );
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1447,6 +1447,30 @@ onGameSaved( CursesAppGlobals* aGlobals, sqlite3_int64 rowid, bool isNew )
|
||||||
cgl_refreshOne( aGlobals->gameList, rowid, isNew );
|
cgl_refreshOne( aGlobals->gameList, rowid, isNew );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static XP_U32
|
||||||
|
castGid( cJSON* obj )
|
||||||
|
{
|
||||||
|
XP_U32 gameID;
|
||||||
|
sscanf( obj->valuestring, "%X", &gameID );
|
||||||
|
return gameID;
|
||||||
|
}
|
||||||
|
|
||||||
|
static XP_U32
|
||||||
|
gidFromObject( cJSON* obj )
|
||||||
|
{
|
||||||
|
cJSON* tmp = cJSON_GetObjectItem( obj, "gid" );
|
||||||
|
XP_ASSERT( !!tmp );
|
||||||
|
return castGid( tmp );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
addGIDToObject( cJSON* obj, XP_U32 gid, const char* key )
|
||||||
|
{
|
||||||
|
char buf[16];
|
||||||
|
sprintf( buf, "%08X", gid );
|
||||||
|
cJSON_AddStringToObject( obj, key, buf );
|
||||||
|
}
|
||||||
|
|
||||||
static XP_Bool
|
static XP_Bool
|
||||||
makeGameFromArgs( CursesAppGlobals* aGlobals, cJSON* args )
|
makeGameFromArgs( CursesAppGlobals* aGlobals, cJSON* args )
|
||||||
{
|
{
|
||||||
|
@ -1457,11 +1481,9 @@ makeGameFromArgs( CursesAppGlobals* aGlobals, cJSON* args )
|
||||||
gi.boardSize = 15;
|
gi.boardSize = 15;
|
||||||
gi.traySize = 7;
|
gi.traySize = 7;
|
||||||
|
|
||||||
cJSON* tmp = cJSON_GetObjectItem( args, "gid" );
|
gi.gameID = gidFromObject( args );
|
||||||
XP_ASSERT( !!tmp );
|
|
||||||
sscanf( tmp->valuestring, "%X", &gi.gameID );
|
|
||||||
|
|
||||||
tmp = cJSON_GetObjectItem( args, "nPlayers" );
|
cJSON* tmp = cJSON_GetObjectItem( args, "nPlayers" );
|
||||||
XP_ASSERT( !!tmp );
|
XP_ASSERT( !!tmp );
|
||||||
gi.nPlayers = tmp->valueint;
|
gi.nPlayers = tmp->valueint;
|
||||||
|
|
||||||
|
@ -1506,18 +1528,13 @@ inviteFromArgs( CursesAppGlobals* aGlobals, cJSON* args )
|
||||||
/* XP_LOGFF( "(%s)", buf ); */
|
/* XP_LOGFF( "(%s)", buf ); */
|
||||||
/* } */
|
/* } */
|
||||||
|
|
||||||
XP_U32 gameID;
|
XP_U32 gameID = gidFromObject( args );
|
||||||
cJSON* tmp = cJSON_GetObjectItem( args, "gid" );
|
|
||||||
XP_ASSERT( !!tmp );
|
|
||||||
sscanf( tmp->valuestring, "%X", &gameID );
|
|
||||||
|
|
||||||
tmp = cJSON_GetObjectItem( args, "channel" );
|
cJSON* tmp = cJSON_GetObjectItem( args, "channel" );
|
||||||
XP_ASSERT( !!tmp );
|
XP_ASSERT( !!tmp );
|
||||||
XP_U16 channel = tmp->valueint;
|
XP_U16 channel = tmp->valueint;
|
||||||
XP_LOGFF( "read channel: %X", channel );
|
XP_LOGFF( "read channel: %X", channel );
|
||||||
|
|
||||||
/* CursesBoardState* cbState, XP_U32 gameID, XP_U16 forceChannel, */
|
|
||||||
/* const CommsAddrRec* destAddr */
|
|
||||||
CommsAddrRec destAddr = {0};
|
CommsAddrRec destAddr = {0};
|
||||||
cJSON* addr = cJSON_GetObjectItem( args, "addr" );
|
cJSON* addr = cJSON_GetObjectItem( args, "addr" );
|
||||||
XP_ASSERT( !!addr );
|
XP_ASSERT( !!addr );
|
||||||
|
@ -1541,6 +1558,28 @@ inviteFromArgs( CursesAppGlobals* aGlobals, cJSON* args )
|
||||||
return XP_TRUE;
|
return XP_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static XP_Bool
|
||||||
|
moveifFromArgs( CursesAppGlobals* aGlobals, cJSON* args )
|
||||||
|
{
|
||||||
|
XP_U32 gameID = gidFromObject( args );
|
||||||
|
return cb_makeMoveIf( aGlobals->cbState, gameID );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return 'gid' of new game */
|
||||||
|
static XP_U32
|
||||||
|
rematchFromArgs( CursesAppGlobals* aGlobals, cJSON* args )
|
||||||
|
{
|
||||||
|
XP_U32 result = 0;
|
||||||
|
|
||||||
|
XP_U32 gameID = gidFromObject( args );
|
||||||
|
|
||||||
|
XP_U32 newGameID = 0;
|
||||||
|
if ( cb_makeRematch( aGlobals->cbState, gameID, &newGameID ) ) {
|
||||||
|
result = newGameID;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
static cJSON*
|
static cJSON*
|
||||||
getGamesStateForArgs( CursesAppGlobals* aGlobals, cJSON* args )
|
getGamesStateForArgs( CursesAppGlobals* aGlobals, cJSON* args )
|
||||||
{
|
{
|
||||||
|
@ -1549,14 +1588,12 @@ getGamesStateForArgs( CursesAppGlobals* aGlobals, cJSON* args )
|
||||||
LaunchParams* params = aGlobals->cag.params;
|
LaunchParams* params = aGlobals->cag.params;
|
||||||
cJSON* gids = cJSON_GetObjectItem(args, "gids" );
|
cJSON* gids = cJSON_GetObjectItem(args, "gids" );
|
||||||
for ( int ii = 0 ; ii < cJSON_GetArraySize(gids) ; ++ii ) {
|
for ( int ii = 0 ; ii < cJSON_GetArraySize(gids) ; ++ii ) {
|
||||||
XP_U32 gameID;
|
XP_U32 gameID = castGid( cJSON_GetArrayItem( gids, ii ) );
|
||||||
cJSON* gid = cJSON_GetArrayItem( gids, ii );
|
|
||||||
sscanf( gid->valuestring, "%X", &gameID );
|
|
||||||
|
|
||||||
GameInfo gib;
|
GameInfo gib;
|
||||||
if ( gdb_getGameInfoForGID( params->pDb, gameID, &gib ) ) {
|
if ( gdb_getGameInfoForGID( params->pDb, gameID, &gib ) ) {
|
||||||
cJSON* item = cJSON_CreateObject();
|
cJSON* item = cJSON_CreateObject();
|
||||||
cJSON_AddStringToObject( item, "gid", gid->valuestring );
|
addGIDToObject( item, gameID, "gid" );
|
||||||
cJSON_AddBoolToObject( item, "gameOver", gib.gameOver );
|
cJSON_AddBoolToObject( item, "gameOver", gib.gameOver );
|
||||||
cJSON_AddNumberToObject( item, "nPending", gib.nPending );
|
cJSON_AddNumberToObject( item, "nPending", gib.nPending );
|
||||||
cJSON_AddNumberToObject( item, "nMoves", gib.nMoves );
|
cJSON_AddNumberToObject( item, "nMoves", gib.nMoves );
|
||||||
|
@ -1631,6 +1668,15 @@ on_incoming_signal( GSocketService* XP_UNUSED(service),
|
||||||
} else if ( 0 == strcmp( cmdStr, "invite" ) ) {
|
} else if ( 0 == strcmp( cmdStr, "invite" ) ) {
|
||||||
XP_Bool success = inviteFromArgs( aGlobals, args );
|
XP_Bool success = inviteFromArgs( aGlobals, args );
|
||||||
response = makeBoolObj( "success", success );
|
response = makeBoolObj( "success", success );
|
||||||
|
} else if ( 0 == strcmp( cmdStr, "moveIf" ) ) {
|
||||||
|
XP_Bool success = moveifFromArgs( aGlobals, args );
|
||||||
|
response = makeBoolObj( "success", success );
|
||||||
|
} else if ( 0 == strcmp( cmdStr, "rematch" ) ) {
|
||||||
|
XP_U32 newGameID = rematchFromArgs( aGlobals, args );
|
||||||
|
if ( 0 != newGameID ) {
|
||||||
|
response = cJSON_CreateObject();
|
||||||
|
addGIDToObject( response, newGameID, "newGid" );
|
||||||
|
}
|
||||||
} else if ( 0 == strcmp( cmdStr, "gamesState" ) ) {
|
} else if ( 0 == strcmp( cmdStr, "gamesState" ) ) {
|
||||||
response = getGamesStateForArgs( aGlobals, args );
|
response = getGamesStateForArgs( aGlobals, args );
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -37,10 +37,11 @@ class GuestGameInfo():
|
||||||
|
|
||||||
# Should be subclass of GuestGameInfo
|
# Should be subclass of GuestGameInfo
|
||||||
class HostedInfo():
|
class HostedInfo():
|
||||||
def __init__(self, guests):
|
def __init__(self, guests, gid=None, invitesSent=False):
|
||||||
self.guestNames = guests
|
self.guestNames = guests
|
||||||
self.gid = '{:08X}'.format(random.randint(0, 0x7FFFFFFF))
|
self.gid = gid and gid or '{:08X}'.format(random.randint(1, 0x7FFFFFFF))
|
||||||
self.invitesSent = False
|
assert len(self.gid) == 8
|
||||||
|
self.invitesSent = invitesSent
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return 'gid: {}, guests: {}'.format(self.gid, self.guestNames)
|
return 'gid: {}, guests: {}'.format(self.gid, self.guestNames)
|
||||||
|
@ -165,6 +166,16 @@ class Device():
|
||||||
while not self.endTime or not os.path.exists(self.cmdSocketName):
|
while not self.endTime or not os.path.exists(self.cmdSocketName):
|
||||||
time.sleep(0.2)
|
time.sleep(0.2)
|
||||||
|
|
||||||
|
def moveOne(self):
|
||||||
|
moved = False
|
||||||
|
gids = [game.gid for game in self._allGames() if not self.gameOver(game.gid)]
|
||||||
|
random.shuffle(gids)
|
||||||
|
for gid in gids:
|
||||||
|
response = self._sendWaitReply('moveIf', gid=gid)
|
||||||
|
moved = response.get('success', False)
|
||||||
|
if moved: break
|
||||||
|
return moved
|
||||||
|
|
||||||
def _sendWaitReply(self, cmd, **kwargs):
|
def _sendWaitReply(self, cmd, **kwargs):
|
||||||
self.launchIfNot()
|
self.launchIfNot()
|
||||||
|
|
||||||
|
@ -229,15 +240,28 @@ class Device():
|
||||||
if not stepped:
|
if not stepped:
|
||||||
if not self.endTime:
|
if not self.endTime:
|
||||||
self.launchIfNot()
|
self.launchIfNot()
|
||||||
|
elif datetime.datetime.now() > self.endTime:
|
||||||
|
self.quit()
|
||||||
|
elif self.moveOne():
|
||||||
|
pass
|
||||||
else:
|
else:
|
||||||
now = datetime.datetime.now()
|
# self._log('sleeping with {} to go'.format(self.endTime-now))
|
||||||
if now > self.endTime:
|
time.sleep(0.5)
|
||||||
self.quit()
|
|
||||||
else:
|
|
||||||
# self._log('sleeping with {} to go'.format(self.endTime-now))
|
|
||||||
time.sleep(0.5)
|
|
||||||
stepped = True;
|
stepped = True;
|
||||||
|
|
||||||
|
# I may be a guest or a host in this game. Rematch works either
|
||||||
|
# way. But how I figure out the other players differs.
|
||||||
|
def rematch(self, gid):
|
||||||
|
newGid = self._sendWaitReply('rematch', gid=gid).get('newGid')
|
||||||
|
if newGid:
|
||||||
|
guests = Device.playersIn(gid)
|
||||||
|
guests.remove(self.host)
|
||||||
|
self._log('rematch: new host: {}; new guest[s]: {}, gid: {}'.format(self.host, guests, newGid))
|
||||||
|
|
||||||
|
self.hostedGames.append(HostedInfo(guests, newGid, True))
|
||||||
|
for guest in guests:
|
||||||
|
Device.getFor(guest).expectInvite(newGid)
|
||||||
|
|
||||||
def invite(self, game):
|
def invite(self, game):
|
||||||
failed = False
|
failed = False
|
||||||
for ii in range(len(game.guestNames)):
|
for ii in range(len(game.guestNames)):
|
||||||
|
@ -365,6 +389,10 @@ class Device():
|
||||||
Device._devs[host] = dev
|
Device._devs[host] = dev
|
||||||
return dev
|
return dev
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def playersIn(gid):
|
||||||
|
return [dev.host for dev in Device.devsWith(gid)]
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
# return all devices (up to 4 of them) that are host or guest in a
|
# return all devices (up to 4 of them) that are host or guest in a
|
||||||
# game with <gid>"""
|
# game with <gid>"""
|
||||||
|
@ -376,6 +404,16 @@ class Device():
|
||||||
def getAll():
|
def getAll():
|
||||||
return [dev for dev in Device._devs.values()]
|
return [dev for dev in Device._devs.values()]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def getFor(player):
|
||||||
|
result = None
|
||||||
|
for dev in Device.getAll():
|
||||||
|
if dev.host == player:
|
||||||
|
result = dev
|
||||||
|
break;
|
||||||
|
assert result
|
||||||
|
return result
|
||||||
|
|
||||||
def addGameWith(self, guests):
|
def addGameWith(self, guests):
|
||||||
# self._log('addGameWith({})'.format(guests))
|
# self._log('addGameWith({})'.format(guests))
|
||||||
hosted = HostedInfo(guests)
|
hosted = HostedInfo(guests)
|
||||||
|
@ -407,11 +445,22 @@ def openOnExit(args):
|
||||||
subprocess.Popen([str(arg) for arg in appargs], stdout = subprocess.DEVNULL,
|
subprocess.Popen([str(arg) for arg in appargs], stdout = subprocess.DEVNULL,
|
||||||
stderr = subprocess.DEVNULL, universal_newlines = True)
|
stderr = subprocess.DEVNULL, universal_newlines = True)
|
||||||
|
|
||||||
|
# Pick a game that's joined -- all invites accepted -- and call
|
||||||
|
# rematch on it. Return True if successful
|
||||||
|
def testRematch():
|
||||||
|
for dev in Device.getAll():
|
||||||
|
for gid, status in dev.gameStates.items():
|
||||||
|
if 2 < status.get('nMoves', 0):
|
||||||
|
dev.rematch(gid)
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
def mainLoop(args, devs):
|
def mainLoop(args, devs):
|
||||||
startCount = len(devs)
|
startCount = len(devs)
|
||||||
|
|
||||||
startTime = datetime.datetime.now()
|
startTime = datetime.datetime.now()
|
||||||
nextStallCheck = startTime + datetime.timedelta(seconds = 20)
|
nextStallCheck = startTime + datetime.timedelta(seconds = 20)
|
||||||
|
rematchTested = False
|
||||||
|
|
||||||
while 0 < len(devs):
|
while 0 < len(devs):
|
||||||
if gDone:
|
if gDone:
|
||||||
|
@ -424,6 +473,8 @@ def mainLoop(args, devs):
|
||||||
devs.remove(dev)
|
devs.remove(dev)
|
||||||
log(args, 'removed dev for {}; {} devs left'.format(dev.host, len(devs)))
|
log(args, 'removed dev for {}; {} devs left'.format(dev.host, len(devs)))
|
||||||
|
|
||||||
|
if not rematchTested: rematchTested = testRematch()
|
||||||
|
|
||||||
now = datetime.datetime.now()
|
now = datetime.datetime.now()
|
||||||
if devs and now > nextStallCheck:
|
if devs and now > nextStallCheck:
|
||||||
nextStallCheck = now + datetime.timedelta(seconds = 10)
|
nextStallCheck = now + datetime.timedelta(seconds = 10)
|
||||||
|
|
Loading…
Add table
Reference in a new issue