mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-02-15 08:47:56 +01:00
add to test ability to invite using known players
This commit is contained in:
parent
31d0547a60
commit
2d9cb93ae6
9 changed files with 144 additions and 71 deletions
|
@ -1666,8 +1666,8 @@ pickChannel( const CommsCtxt* comms, const NetLaunchInfo* nli,
|
|||
/* First, do we already have an invitation for this address */
|
||||
for ( AddressRecord* rec = comms->recs; !!rec; rec = rec->next ) {
|
||||
if ( addrsAreSame( destAddr, &rec->addr ) ) {
|
||||
result = rec->channelNo;
|
||||
XP_LOGFF( "addrs match; reusing channel" );
|
||||
result = rec->channelNo & CHANNEL_MASK;
|
||||
XP_LOGFF( "addrs match; reusing channel %d", result );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1685,7 +1685,7 @@ pickChannel( const CommsCtxt* comms, const NetLaunchInfo* nli,
|
|||
for ( XP_PlayerAddr chan = 1; chan <= CHANNEL_MASK; ++chan ) {
|
||||
if ( 0 == (gicd.hasInvitesMask & (1 << chan)) ) {
|
||||
result = chan;
|
||||
XP_LOGFF( "using unused channel" );
|
||||
XP_LOGFF( "using unused channel %d", result );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1696,14 +1696,14 @@ pickChannel( const CommsCtxt* comms, const NetLaunchInfo* nli,
|
|||
for ( XP_PlayerAddr chan = 1; chan <= CHANNEL_MASK; ++chan ) {
|
||||
if ( 0 == (gicd.hasNonInvitesMask & (1 << chan)) ) {
|
||||
result = chan;
|
||||
XP_LOGFF( "recycling channel" );
|
||||
XP_LOGFF( "recycling channel: %d", result );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LOG_RETURNF( "%d", result );
|
||||
COMMS_LOGFF( "=> 0X%X", result );
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1716,7 +1716,7 @@ comms_invite( CommsCtxt* comms, XWEnv xwe, const NetLaunchInfo* nli,
|
|||
WITH_MUTEX(&comms->mutex);
|
||||
XP_PlayerAddr forceChannel = pickChannel( comms, nli, destAddr );
|
||||
XP_LOGFF( "forceChannel: %d", forceChannel );
|
||||
XP_ASSERT( 0 < forceChannel && (forceChannel & CHANNEL_MASK) == forceChannel );
|
||||
XP_ASSERT( 0 < forceChannel );
|
||||
if ( 0 < forceChannel ) {
|
||||
XP_ASSERT( (forceChannel & CHANNEL_MASK) == forceChannel );
|
||||
if ( !haveRealChannel( comms, forceChannel ) ) {
|
||||
|
@ -2872,7 +2872,7 @@ checkChannelNo( CommsCtxt* comms, const CommsAddrRec* retAddr, XP_PlayerAddr* ch
|
|||
comms->nextChannelNo = channelNo;
|
||||
}
|
||||
*channelNoP = channelNo;
|
||||
LOG_RETURNF( "%s", boolToStr(success) );
|
||||
COMMS_LOGFF( "=> %s", boolToStr(success) );
|
||||
return success;
|
||||
}
|
||||
|
||||
|
|
|
@ -367,7 +367,7 @@ kplr_getAddr( XW_DUtilCtxt* dutil, XWEnv xwe, const XP_UCHAR* name,
|
|||
}
|
||||
releaseStateLocked( dutil, xwe, state );
|
||||
END_WITH_MUTEX();
|
||||
LOG_RETURNF( "%s", boolToStr(found) );
|
||||
XP_LOGFF( "(%s) => %s", name, boolToStr(found) );
|
||||
return found;
|
||||
}
|
||||
|
||||
|
|
|
@ -149,6 +149,13 @@ nli_setMQTTDevID( NetLaunchInfo* nli, const MQTTDevID* mqttDevID )
|
|||
formatMQTTDevID( mqttDevID, nli->mqttDevID, VSIZE(nli->mqttDevID) );
|
||||
}
|
||||
|
||||
void
|
||||
nli_setPhone( NetLaunchInfo* nli, const XP_UCHAR* phone )
|
||||
{
|
||||
types_addType( &nli->_conTypes, COMMS_CONN_SMS );
|
||||
XP_STRNCPY( nli->phone, phone, VSIZE(nli->phone) );
|
||||
}
|
||||
|
||||
void
|
||||
nli_saveToStream( const NetLaunchInfo* nli, XWStreamCtxt* stream )
|
||||
{
|
||||
|
|
|
@ -49,6 +49,7 @@ void nli_setDevID( NetLaunchInfo* nli, XP_U32 devID );
|
|||
void nli_setInviteID( NetLaunchInfo* nli, const XP_UCHAR* inviteID );
|
||||
void nli_setGameName( NetLaunchInfo* nli, const XP_UCHAR* gameName );
|
||||
void nli_setMQTTDevID( NetLaunchInfo* nli, const MQTTDevID* mqttDevID );
|
||||
void nli_setPhone( NetLaunchInfo* nli, const XP_UCHAR* phone );
|
||||
|
||||
#ifdef XWFEATURE_NLI_FROM_ARGV
|
||||
XP_Bool nli_fromArgv( MPFORMAL NetLaunchInfo* nlip, int argc, const char** argv );
|
||||
|
|
|
@ -2145,6 +2145,7 @@ findOrderedSlot( ServerCtxt* server, XWStreamCtxt* stream,
|
|||
|
||||
for ( int ii = 0; !success && ii < gi->nPlayers; ++ii ) {
|
||||
ServerPlayer* sp = &server->srvPlyrs[ii];
|
||||
SRVR_LOGFFV( "ii: %d; deviceIndex: %d", ii, sp->deviceIndex );
|
||||
if ( UNKNOWN_DEVICE == sp->deviceIndex ) {
|
||||
int addrIndx = rip->addrIndices[ii];
|
||||
if ( addrsAreSame( &guestAddr, &rip->addrs[addrIndx] ) ) {
|
||||
|
@ -2156,7 +2157,7 @@ findOrderedSlot( ServerCtxt* server, XWStreamCtxt* stream,
|
|||
}
|
||||
}
|
||||
|
||||
LOG_RETURNF( "%s", boolToStr(success) );
|
||||
SRVR_LOGFFV( "()=>%s", boolToStr(success) );
|
||||
return success;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "gamesdb.h"
|
||||
#include "dbgutil.h"
|
||||
#include "stats.h"
|
||||
#include "knownplyr.h"
|
||||
|
||||
static XP_U32
|
||||
castGid( cJSON* obj )
|
||||
|
@ -82,29 +83,42 @@ gidFromObject( const cJSON* obj )
|
|||
return castGid( tmp );
|
||||
}
|
||||
|
||||
|
||||
/* Invite can be via a known player or via */
|
||||
static XP_Bool
|
||||
inviteFromArgs( CmdWrapper* wr, cJSON* args )
|
||||
{
|
||||
XW_DUtilCtxt* dutil = wr->params->dutil;
|
||||
XP_U32 gameID = gidFromObject( args );
|
||||
|
||||
XP_Bool viaKnowns = XP_FALSE;
|
||||
cJSON* remotes = cJSON_GetObjectItem( args, "remotes" );
|
||||
if ( !remotes ) {
|
||||
remotes = cJSON_GetObjectItem( args, "kps" );
|
||||
viaKnowns = !!remotes;
|
||||
}
|
||||
|
||||
int nRemotes = cJSON_GetArraySize(remotes);
|
||||
CommsAddrRec destAddrs[nRemotes];
|
||||
XP_MEMSET( destAddrs, 0, sizeof(destAddrs) );
|
||||
|
||||
for ( int ii = 0; ii < nRemotes; ++ii ) {
|
||||
XP_Bool success = XP_TRUE;
|
||||
for ( int ii = 0; success && ii < nRemotes; ++ii ) {
|
||||
cJSON* item = cJSON_GetArrayItem( remotes, ii );
|
||||
|
||||
if ( viaKnowns ) {
|
||||
/* item is just a name */
|
||||
XP_LOGFF( "found kplyr name: %s", item->valuestring );
|
||||
success = kplr_getAddr( dutil, NULL_XWE, item->valuestring,
|
||||
&destAddrs[ii], NULL );
|
||||
} else {
|
||||
cJSON* addr = cJSON_GetObjectItem( item, "addr" );
|
||||
XP_ASSERT( !!addr );
|
||||
cJSON* tmp = cJSON_GetObjectItem( addr, "mqtt" );
|
||||
if ( !!tmp ) {
|
||||
XP_LOGFF( "parsing mqtt: %s", tmp->valuestring );
|
||||
addr_addType( &destAddrs[ii], COMMS_CONN_MQTT );
|
||||
#ifdef DEBUG
|
||||
XP_Bool success =
|
||||
#endif
|
||||
success =
|
||||
strToMQTTCDevID( tmp->valuestring, &destAddrs[ii].u.mqtt.devID );
|
||||
XP_ASSERT( success );
|
||||
}
|
||||
|
@ -116,11 +130,14 @@ inviteFromArgs( CmdWrapper* wr, cJSON* args )
|
|||
destAddrs[ii].u.sms.port = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( success ) {
|
||||
(*wr->procs.addInvites)( wr->closure, gameID, nRemotes, destAddrs );
|
||||
}
|
||||
|
||||
LOG_RETURN_VOID();
|
||||
return XP_TRUE;
|
||||
LOG_RETURNF( "%s", boolToStr(success) );
|
||||
return success;
|
||||
}
|
||||
|
||||
static XP_Bool
|
||||
|
|
|
@ -1406,6 +1406,9 @@ send_invites( CommonGlobals* cGlobals, XP_U16 nPlayers,
|
|||
const MQTTDevID* devid = mqttc_getDevID( cGlobals->params );
|
||||
nli_setMQTTDevID( &nli, devid );
|
||||
}
|
||||
if ( addr_hasType( &myAddr, COMMS_CONN_SMS ) ) {
|
||||
nli_setPhone( &nli, myAddr.u.sms.phone );
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
{
|
||||
|
|
|
@ -179,11 +179,10 @@ linux_addInvites( CommonGlobals* cGlobals, XP_U16 nRemotes,
|
|||
|
||||
CommsAddrRec selfAddr;
|
||||
comms_getSelfAddr( comms, &selfAddr );
|
||||
|
||||
for ( int ii = 0; ii < nRemotes; ++ii ) {
|
||||
NetLaunchInfo nli;
|
||||
nli_init( &nli, cGlobals->gi, &selfAddr, 1, 0 );
|
||||
|
||||
for ( int ii = 0; ii < nRemotes; ++ii ) {
|
||||
comms_invite( comms, NULL_XWE, &nli, &destAddrs[ii], XP_TRUE );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import argparse, datetime, glob, json, os, random, shutil, signal, \
|
|||
socket, struct, subprocess, sys, threading, time
|
||||
|
||||
g_ROOT_NAMES = ['Brynn', 'Ariela', 'Kati', 'Eric']
|
||||
g_INVITE_HOWS = ['Out-of-App', 'Internal', 'KnownPlayer']
|
||||
# These must correspond to what the linux app is looking for in roFromStr()
|
||||
g_ROS = ['same', 'low_score_first', 'high_score_first', 'juggle',]
|
||||
gDone = False
|
||||
|
@ -472,15 +473,45 @@ class Device():
|
|||
Device.getForPlayer(guest) \
|
||||
.expectInvite(newGid, rematchLevel, gid, rematchOrder)
|
||||
|
||||
# Randomly choose from g_INVITE_HOWS based on the ratio expressed
|
||||
# in INVITE_PCTS, without requiring e.g. that they sum to 100%
|
||||
def _inviteHow(self):
|
||||
count = len(g_INVITE_HOWS)
|
||||
# multiply by len to ensure the ratios work without errors
|
||||
asInts = [count * int(one) for one in self.args.INVITE_PCTS.split(':')]
|
||||
assert count == len(asInts)
|
||||
total = sum(asInts)
|
||||
assert 0 == total % count
|
||||
choice = random.randrange(0, total)
|
||||
for indx in range(count):
|
||||
target = asInts[indx]
|
||||
if choice < target:
|
||||
result = g_INVITE_HOWS[indx]
|
||||
break
|
||||
choice -= target
|
||||
return result
|
||||
|
||||
# inviting means either causing host to send an in-game invitation
|
||||
# (the way rematch works) or causing guest to register (as happens
|
||||
# when email or SMS is used for invitations.)
|
||||
def invite(self, game):
|
||||
doOOB = random.randint(0, 99) < self.args.OOB_PCT
|
||||
if doOOB: self.inviteOutOfBand(game)
|
||||
else: self.inviteInBand(game)
|
||||
test = { key: 0 for key in g_INVITE_HOWS }
|
||||
|
||||
def inviteOutOfBand(self, game):
|
||||
how = self._inviteHow()
|
||||
if how == 'Out-of-App':
|
||||
success = self.inviteOutOfApp(game)
|
||||
elif how == 'Internal':
|
||||
success = self.inviteInApp(game)
|
||||
elif how == 'KnownPlayer':
|
||||
success = self.inviteKP(game)
|
||||
else: assert False
|
||||
|
||||
return success
|
||||
# doOOB = random.randint(0, 99) < self.args.OOB_PCT
|
||||
# if doOOB: self.inviteOutOfBand(game)
|
||||
# else: self.inviteInBand(game)
|
||||
|
||||
def inviteOutOfApp(self, game):
|
||||
# For each invitee, we need to make sure it exists, launch it,
|
||||
# and then send it the equivalent of an emailed invitation.
|
||||
|
||||
|
@ -499,8 +530,7 @@ class Device():
|
|||
|
||||
game.needsInvite = False
|
||||
|
||||
|
||||
def inviteInBand(self, game):
|
||||
def inviteInApp(self, game):
|
||||
remotes = []
|
||||
guestDevs = []
|
||||
useRandomDevID = random.randint(0, 100) < self.args.BAD_INVITE_PCT
|
||||
|
@ -519,6 +549,14 @@ class Device():
|
|||
guestDev.expectInvite(game.gid, game.rematchLevel)
|
||||
game.needsInvite = useRandomDevID
|
||||
|
||||
def inviteKP(self, game):
|
||||
response = self._sendWaitReply('invite', gid=game.gid,
|
||||
kps=game.guestNames)
|
||||
if response['success']:
|
||||
for name in game.guestNames:
|
||||
Device.getForPlayer(name).expectInvite(game.gid, game.rematchLevel)
|
||||
game.needsInvite = False
|
||||
|
||||
def _mkAddr(self, dev, useRandomDevID=False):
|
||||
addr = {}
|
||||
if self.args.WITH_MQTT:
|
||||
|
@ -644,7 +682,7 @@ class Device():
|
|||
|
||||
def _checkScript(self):
|
||||
assert os.path.exists(self.args.APP_NEW)
|
||||
if not os.path.exists(self.script):
|
||||
|
||||
scriptArgs = ['exec'] # without exec means terminate() won't work
|
||||
if self.args.VALGRIND:
|
||||
scriptArgs += ['valgrind']
|
||||
|
@ -954,15 +992,22 @@ def mkParser():
|
|||
|
||||
parser.add_argument('--bad-invite-pct', dest = 'BAD_INVITE_PCT', default = 0, type=int,
|
||||
help='What pct (0..99) of MQTT invitations will be to non-existant devices')
|
||||
parser.add_argument('--oob-invite-pct', dest = 'OOB_PCT', default = 50, type=int,
|
||||
help='What pct (0..99) of guests will "emailed" rather than comms-invited')
|
||||
|
||||
# Inviting to new games is done in one of three ways. New games
|
||||
# with new players involve an out-of-app process like sending an
|
||||
# email with a URL. After that, once a remote player is "known",
|
||||
# known-player invitation uses info in the KnownPlayer
|
||||
# data. Finally, rematches work with the information in the
|
||||
# current game's addressing.
|
||||
parser.add_argument('--invite-pcts', dest = 'INVITE_PCTS', default = '33:33:33',
|
||||
help='Odds of inviting each of 3 ways: {}'.format(':'.join(g_INVITE_HOWS)))
|
||||
|
||||
parser.add_argument('--timer-seconds', dest='TIMER_SECS', default=10, type=int,
|
||||
help='Enable game timer with game this many seconds long')
|
||||
parser.add_argument('--min-app-life', dest='MIN_APP_LIFE', default=15, type=int,
|
||||
help='Minimum number of seconds app will run after each launch')
|
||||
|
||||
parser.add_argument('--with-sms', dest = 'WITH_SMS', action = 'store_true')
|
||||
parser.add_argument('--with-sms', dest = 'WITH_SMS', action = 'store_true', default=False)
|
||||
parser.add_argument('--without-sms', dest = 'WITH_SMS', default=False, action='store_false')
|
||||
# parser.add_argument('--sms-fail-pct', dest = 'SMS_FAIL_PCT', default = 0, type = int)
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue