improve comms address tracking (breaks android for now)

Remove legacy relay-inspired logic around comms addressing. Now when a
device creates a game it's required to provide its "self address," and
if it's a client, the address of the host (which it presumably got
through the invitation in response to which the game is being
created.) Then as registration messages come in from clients, the host
gathers their addresses as always.
This commit is contained in:
Eric House 2022-09-03 18:47:04 -07:00
parent ad8b81baf5
commit 4996d3fe89
14 changed files with 311 additions and 551 deletions

View file

@ -1,6 +1,6 @@
/* -*- compile-command: "cd ../linux && make MEMDEBUG=TRUE -j3"; -*- */
/*
* Copyright 2001 - 2021 by Eric House (xwords@eehouse.org). All rights
* Copyright 2001 - 2022 by Eric House (xwords@eehouse.org). All rights
* reserved.
*
* This program is free software; you can redistribute it and/or
@ -251,6 +251,9 @@ static void putDevID( const CommsCtxt* comms, XWEnv xwe, XWStreamCtxt* stream );
#endif
#ifdef DEBUG
static void assertAddrOk( const CommsAddrRec* addr );
#define ASSERT_ADDR_OK(addr) assertAddrOk( addr )
# ifdef XWFEATURE_RELAY
static const char* relayCmdToStr( XWRELAY_Cmd cmd );
# endif
@ -261,6 +264,7 @@ static void logAddrs( const CommsCtxt* comms, XWEnv xwe,
const char* caller );
#else
#define ASSERT_ADDR_OK(addr)
#define printQueue( comms )
#define logAddr( comms, xwe, addr, caller)
#define logAddrs( comms, caller )
@ -380,6 +384,7 @@ init_relay( CommsCtxt* comms, XWEnv xwe, XP_U16 nPlayersHere, XP_U16 nPlayersTot
CommsCtxt*
comms_make( MPFORMAL XWEnv xwe, XW_UtilCtxt* util, XP_Bool isServer,
const CommsAddrRec* selfAddr, const CommsAddrRec* hostAddr,
#ifdef XWFEATURE_RELAY
XP_U16 nPlayersHere, XP_U16 nPlayersTotal,
#endif
@ -422,6 +427,22 @@ comms_make( MPFORMAL XWEnv xwe, XW_UtilCtxt* util, XP_Bool isServer,
comms->channelSeed = gameSeed;
# endif
#endif
if ( !!selfAddr ) {
logAddr( comms, xwe, selfAddr, __func__ );
comms_augmentHostAddr( comms, xwe, selfAddr );
}
if ( !!hostAddr ) {
XP_ASSERT( !isServer );
logAddr( comms, xwe, hostAddr, __func__ );
XP_PlayerAddr channelNo = comms_getChannelSeed( comms );
#ifdef DEBUG
AddressRecord* rec =
#endif
rememberChannelAddress( comms, xwe, channelNo, 0, hostAddr,0 );
XP_ASSERT( rec == getRecordFor( comms, xwe, hostAddr, channelNo, XP_TRUE ) );
}
return comms;
} /* comms_make */
@ -697,6 +718,7 @@ addrFromStream( CommsAddrRec* addrP, XWStreamCtxt* stream )
for ( XP_U32 st = 0; addr_iter( addrP, &typ, &st ); ) {
addrFromStreamOne( addrP, stream, typ );
}
ASSERT_ADDR_OK( addrP );
}
/* Return TRUE if there are no addresses left that include relay */
@ -756,7 +778,7 @@ comms_makeFromStream( MPFORMAL XWEnv xwe, XWStreamCtxt* stream,
nPlayersHere = 0;
nPlayersTotal = 0;
}
CommsCtxt* comms = comms_make( MPPARM(mpool) xwe, util, isServer,
CommsCtxt* comms = comms_make( MPPARM(mpool) xwe, util, isServer, NULL, NULL,
#ifdef XWFEATURE_RELAY
nPlayersHere, nPlayersTotal,
#endif
@ -961,7 +983,8 @@ sendConnect( CommsCtxt* comms, XWEnv xwe
} /* sendConnect */
static void
addrToStreamOne( XWStreamCtxt* stream, CommsConnType typ, const CommsAddrRec* addrP )
addrToStreamOne( XWStreamCtxt* stream, CommsConnType typ,
const CommsAddrRec* addrP )
{
switch( typ ) {
case COMMS_CONN_NONE:
@ -998,6 +1021,7 @@ addrToStreamOne( XWStreamCtxt* stream, CommsConnType typ, const CommsAddrRec* ad
case COMMS_CONN_NFC:
break;
case COMMS_CONN_MQTT:
XP_ASSERT( 0 != addrP->u.mqtt.devID );
stream_putBytes( stream, &addrP->u.mqtt.devID, sizeof(addrP->u.mqtt.devID) );
break;
default:
@ -1057,9 +1081,9 @@ comms_writeToStream( CommsCtxt* comms, XWEnv XP_UNUSED_DBG(xwe),
#endif
for ( rec = comms->recs; !!rec; rec = rec->next ) {
CommsAddrRec* addr = &rec->addr;
addrToStream( stream, addr );
const CommsAddrRec* addr = &rec->addr;
logAddr( comms, xwe, addr, __func__ );
addrToStream( stream, addr );
stream_putU32VL( stream, rec->nextMsgID );
stream_putU32VL( stream, rec->lastMsgRcd );
@ -1069,7 +1093,7 @@ comms_writeToStream( CommsCtxt* comms, XWEnv XP_UNUSED_DBG(xwe),
#endif
stream_putU16( stream, (XP_U16)rec->lastMsgAckd );
stream_putU16( stream, rec->channelNo );
if ( addr_hasType( &rec->addr, COMMS_CONN_RELAY ) ) {
if ( addr_hasType( addr, COMMS_CONN_RELAY ) ) {
stream_putU8( stream, rec->rr.hostID ); /* unneeded unless RELAY */
}
}
@ -1174,15 +1198,20 @@ comms_addMQTTDevID( CommsCtxt* comms, XP_PlayerAddr channelNo,
if ( found ) {
if ( addr_hasType( &rec->addr, COMMS_CONN_MQTT ) ) {
XP_ASSERT( *devID == rec->addr.u.mqtt.devID );
} else {
CommsAddrRec tmp = {0};
addr_setType( &tmp, COMMS_CONN_MQTT );
tmp.u.mqtt.devID = *devID;
ASSERT_ADDR_OK( &tmp );
augmentAddrIntrnl( comms, &rec->addr, &tmp, XP_TRUE );
ASSERT_ADDR_OK( &rec->addr );
}
CommsAddrRec addr = {0};
addr_setType( &addr, COMMS_CONN_MQTT );
addr.u.mqtt.devID = *devID;
augmentAddrIntrnl( comms, &rec->addr, &addr, XP_TRUE );
}
}
if ( !found ) {
XP_LOGFF( "unable to augment address!!" );
XP_ASSERT(0);
}
#endif
}
@ -1260,55 +1289,6 @@ formatMsgNo( const CommsCtxt* comms, const MsgQueueElem* elem,
XP_SNPRINTF( buf, len, "%d:%d", comms->rr.myHostID, elem->msgID );
}
void
comms_getInitialAddr( CommsAddrRec* addr
#ifdef XWFEATURE_RELAY
, const XP_UCHAR* relayName
, XP_U16 relayPort
#endif
)
{
XP_MEMSET( addr, 0, sizeof(*addr) );
#if defined XWFEATURE_RELAY
addr_setType( addr, COMMS_CONN_RELAY ); /* for temporary ease in debugging */
addr->u.ip_relay.ipAddr = 0L; /* force 'em to set it */
addr->u.ip_relay.port = relayPort;
{
const char* name = relayName;
char* room = RELAY_ROOM_DEFAULT;
XP_MEMCPY( addr->u.ip_relay.hostName, name, XP_STRLEN(name)+1 );
XP_MEMCPY( addr->u.ip_relay.invite, room, XP_STRLEN(room)+1 );
}
addr->u.ip_relay.seeksPublicRoom = XP_FALSE;
addr->u.ip_relay.advertiseRoom = XP_FALSE;
#elif defined PLATFORM_PALM
/* default values; default is still IR where there's a choice, at least on
Palm... */
addr->conType = COMMS_CONN_IR;
#endif
addr_setType( addr, COMMS_CONN_MQTT );
} /* comms_getInitialAddr */
XP_Bool
comms_checkAddr( XWEnv xwe, DeviceRole role, const CommsAddrRec* addr,
XW_UtilCtxt* util )
{
XP_Bool ok = XP_TRUE;
/* make sure the user's given us enough information to make a connection */
if ( role == SERVER_ISCLIENT ) {
if ( addr_hasType( addr, COMMS_CONN_BT ) ) {
XP_U32 empty = 0L; /* check four bytes to save some code */
if ( !XP_MEMCMP( &empty, &addr->u.bt.btAddr, sizeof(empty) ) ) {
ok = XP_FALSE;
if ( !!util ) {
util_userError( util, xwe, STR_NEED_BT_HOST_ADDR );
}
}
}
}
return ok;
} /* comms_checkAddr */
CommsConnTypes
comms_getConTypes( const CommsCtxt* comms )
{
@ -1326,6 +1306,7 @@ void
comms_dropHostAddr( CommsCtxt* comms, CommsConnType typ )
{
addr_rmType( &comms->addr, typ );
ASSERT_ADDR_OK( &comms->addr );
}
XP_Bool
@ -1540,6 +1521,25 @@ assertQueueOk( const CommsCtxt* comms )
XP_LOGFF( "queueLen unexpectedly high: %d", count );
}
}
static void
assertAddrOk( const CommsAddrRec* addr )
{
CommsConnType typ;
for ( XP_U32 st = 0; addr_iter( addr, &typ, &st ); ) {
switch ( typ ) {
case COMMS_CONN_MQTT:
XP_ASSERT( 0 != addr->u.mqtt.devID );
break;
case COMMS_CONN_SMS:
XP_ASSERT( 0 != addr->u.sms.phone[0] );
break;
default:
XP_ASSERT(0);
break;
}
}
}
#endif
static XP_Bool
@ -1654,105 +1654,112 @@ sendMsg( CommsCtxt* comms, XWEnv xwe, MsgQueueElem* elem, const CommsConnType fi
cbuf, elem->msgID, elem->len, elem->checksum );
#endif
CommsAddrRec addr;
const CommsAddrRec* addrP;
(void)channelToAddress( comms, xwe, channelNo, &addrP );
if ( NULL == addrP ) {
XP_LOGFF( TAGFMT() "no addr for channel so using comms'", TAGPRMS );
comms_getAddr( comms, &addr );
logAddr( comms, xwe, &addr, "default case" );
if ( comms->isServer ) {
(void)channelToAddress( comms, xwe, channelNo, &addrP );
} else {
addr = *addrP;
/* guest has only one peer, but old code might save several */
XP_ASSERT( !!comms->recs && !comms->recs->next );
if ( !!comms->recs ) {
addrP = &comms->recs->addr;
}
}
if ( NULL == addrP ) {
XP_LOGFF( TAGFMT() "no addr for channel %x; dropping!'", TAGPRMS, channelNo );
XP_ASSERT(0);
} else {
CommsAddrRec addr = *addrP;
if ( addr_hasType( &comms->addr, COMMS_CONN_NFC ) ) {
addr_addType( &addr, COMMS_CONN_NFC );
}
}
CommsConnType typ;
for ( XP_U32 st = 0; addr_iter( &addr, &typ, &st ); ) {
XP_S16 nSent = -1;
if ( comms_getAddrDisabled( comms, typ, XP_TRUE ) ) {
XP_LOGFF( "dropping message because %s disabled",
ConnType2Str( typ ) );
} else if ( COMMS_CONN_NONE != filter && filter != typ ) {
XP_LOGFF( "dropping message because not of type %s",
ConnType2Str( filter ) );
} else {
CommsConnType typ;
for ( XP_U32 st = 0; addr_iter( &addr, &typ, &st ); ) {
XP_S16 nSent = -1;
if ( comms_getAddrDisabled( comms, typ, XP_TRUE ) ) {
XP_LOGFF( "dropping message because %s disabled",
ConnType2Str( typ ) );
} else if ( COMMS_CONN_NONE != filter && filter != typ ) {
XP_LOGFF( "dropping message because not of type %s",
ConnType2Str( filter ) );
} else {
#ifdef COMMS_CHECKSUM
XP_LOGFF( TAGFMT() "sending msg with sum %s using typ %s", TAGPRMS,
elem->checksum, ConnType2Str(typ) );
XP_LOGFF( TAGFMT() "sending msg with sum %s using typ %s", TAGPRMS,
elem->checksum, ConnType2Str(typ) );
#endif
switch ( typ ) {
switch ( typ ) {
#ifdef XWFEATURE_RELAY
case COMMS_CONN_RELAY: {
XWHostID destID = getDestID( comms, xwe, channelNo );
if ( HOST_ID_NONE == destID ) {
XP_LOGFF( TAGFMT() "skipping message via relay: no destID yet", TAGPRMS );
} else if ( haveRelayID( comms ) && sendNoConn( comms, xwe, elem, destID ) ) {
/* do nothing */
nSent = elem->len;
} else if ( comms->rr.relayState >= COMMS_RELAYSTATE_CONNECTED ) {
XP_UCHAR msgNo[16];
formatMsgNo( comms, elem, msgNo, sizeof(msgNo) );
if ( send_via_relay( comms, xwe, XWRELAY_MSG_TORELAY, destID,
elem->msg, elem->len, msgNo ) ) {
case COMMS_CONN_RELAY: {
XWHostID destID = getDestID( comms, xwe, channelNo );
if ( HOST_ID_NONE == destID ) {
XP_LOGFF( TAGFMT() "skipping message via relay: no destID yet", TAGPRMS );
} else if ( haveRelayID( comms ) && sendNoConn( comms, xwe, elem, destID ) ) {
/* do nothing */
nSent = elem->len;
} else if ( comms->rr.relayState >= COMMS_RELAYSTATE_CONNECTED ) {
XP_UCHAR msgNo[16];
formatMsgNo( comms, elem, msgNo, sizeof(msgNo) );
if ( send_via_relay( comms, xwe, XWRELAY_MSG_TORELAY, destID,
elem->msg, elem->len, msgNo ) ) {
nSent = elem->len;
}
} else {
XP_LOGFF( "skipping message: not connected to relay" );
}
} else {
XP_LOGFF( "skipping message: not connected to relay" );
}
break;
}
#endif
#if defined XWFEATURE_IP_DIRECT
case COMMS_CONN_BT:
case COMMS_CONN_IP_DIRECT:
nSent = send_via_ip( comms, BTIPMSG_DATA, channelNo,
elem->msg, elem->len );
#ifdef COMMS_HEARTBEAT
setHeartbeatTimer( comms );
#endif
break;
#endif
default: {
XP_ASSERT( addr_hasType( &addr, typ ) );
/* A more general check that the address type has the settings
it needs would be better here.... */
if ( typ == COMMS_CONN_MQTT && 0 == addr.u.mqtt.devID ) {
XP_LOGFF( "not sending: MQTT address NULL" );
break;
}
XP_ASSERT( !!comms->procs.send );
XP_U32 gameid = gameID( comms );
logAddr( comms, xwe, &addr, __func__ );
XP_UCHAR msgNo[16];
formatMsgNo( comms, elem, msgNo, sizeof(msgNo) );
nSent = (*comms->procs.send)( xwe, elem->msg, elem->len, msgNo,
elem->createdStamp, &addr,
typ, gameid, comms->procs.closure );
break;
}
} /* switch */
}
XP_LOGFF( TAGFMT() "sent %d bytes using typ %s", TAGPRMS, nSent,
ConnType2Str(typ) );
if ( nSent > result ) {
result = nSent;
}
}
if ( result == elem->len ) {
#ifdef DEBUG
++elem->sendCount;
#endif
XP_LOGFF( "elem's sendCount since load: %d",
elem->sendCount );
#if defined XWFEATURE_IP_DIRECT
case COMMS_CONN_BT:
case COMMS_CONN_IP_DIRECT:
nSent = send_via_ip( comms, BTIPMSG_DATA, channelNo,
elem->msg, elem->len );
#ifdef COMMS_HEARTBEAT
setHeartbeatTimer( comms );
#endif
break;
#endif
default: {
XP_ASSERT( addr_hasType( &addr, typ ) );
/* A more general check that the address type has the settings
it needs would be better here.... */
if ( typ == COMMS_CONN_MQTT && 0 == addr.u.mqtt.devID ) {
XP_LOGFF( "not sending: MQTT address NULL" );
XP_ASSERT(0);
break;
}
XP_ASSERT( !!comms->procs.send );
XP_U32 gameid = gameID( comms );
logAddr( comms, xwe, &addr, __func__ );
XP_UCHAR msgNo[16];
formatMsgNo( comms, elem, msgNo, sizeof(msgNo) );
nSent = (*comms->procs.send)( xwe, elem->msg, elem->len, msgNo,
elem->createdStamp, &addr,
typ, gameid, comms->procs.closure );
break;
}
} /* switch */
}
XP_LOGFF( TAGFMT() "sent %d bytes using typ %s", TAGPRMS, nSent,
ConnType2Str(typ) );
if ( nSent > result ) {
result = nSent;
}
}
if ( result == elem->len ) {
#ifdef DEBUG
++elem->sendCount;
#endif
XP_LOGFF( "elem's sendCount since load: %d",
elem->sendCount );
}
CNO_FMT( cbuf1, elem->channelNo );
XP_LOGFF( "(%s; msgID=" XP_LD ", len=%d)=>%d", cbuf1, elem->msgID,
elem->len, result );
}
CNO_FMT( cbuf1, elem->channelNo );
XP_LOGFF( "(%s; msgID=" XP_LD ", len=%d)=>%d", cbuf1, elem->msgID,
elem->len, result );
XP_ASSERT( result < 0 || elem->len == result );
return result;
} /* sendMsg */
@ -2318,8 +2325,7 @@ getRecordFor( CommsCtxt* comms, XWEnv xwe, const CommsAddrRec* addr,
}
}
XP_LOGFF( "(%s, maskChannel=%s) => %p", cbuf,
maskChannel? "true":"false", rec );
XP_LOGFF( "(%s, maskChannel=%s) => %p", cbuf, boolToStr(maskChannel), rec );
return rec;
} /* getRecordFor */
@ -2402,7 +2408,8 @@ validateInitialMessage( CommsCtxt* comms, XWEnv xwe,
XP_LOGFF( TAGFMT() "ORd channel onto channelNo: now %s", TAGPRMS, cbuf1 );
XP_ASSERT( comms->nextChannelNo <= CHANNEL_MASK );
}
rec = rememberChannelAddress( comms, xwe, *channelNo, senderID, addr, flags );
rec = rememberChannelAddress( comms, xwe, *channelNo, senderID, addr,
flags );
if ( hasPayload ) {
rec->initialSeen = XP_TRUE;
} else {
@ -2416,9 +2423,18 @@ validateInitialMessage( CommsCtxt* comms, XWEnv xwe,
rec = getRecordFor( comms, xwe, addr, *channelNo, XP_TRUE );
if ( !!rec ) {
augmentChannelAddr( comms, rec, addr, senderID );
/* Used to be that the initial message was where the channel
record got created, but now the client creates an address for
the host on startup (comms_make()) */
if ( comms->isServer ) {
XP_LOGFF( TAGFMT() "rejecting duplicate INIT message", TAGPRMS );
rec = NULL;
} else {
XP_LOGFF( "accepting duplicate (?) msg" );
}
/* reject: we've already seen init message on channel */
XP_LOGFF( TAGFMT() "rejecting duplicate INIT message", TAGPRMS );
rec = NULL;
// XP_ASSERT(0);
} else {
if ( comms->isServer ) {
if ( checkChannelNo( comms, channelNo ) ) {
@ -3172,7 +3188,6 @@ augmentChannelAddr( CommsCtxt* comms, AddressRecord* const rec,
for ( XP_U32 st = 0; addr_iter( addr, &typ, &st ); ) {
if ( !addr_hasType( &comms->addr, typ ) ) {
XP_LOGFF( "main addr missing type %s", ConnType2Str(typ) );
XP_ASSERT(0); /* firing */
}
}
#endif
@ -3182,6 +3197,7 @@ static XP_Bool
augmentAddrIntrnl( CommsCtxt* comms, CommsAddrRec* destAddr,
const CommsAddrRec* srcAddr, XP_Bool isNewer )
{
ASSERT_ADDR_OK( srcAddr );
XP_Bool changed = XP_FALSE;
const CommsAddrRec empty = {0};
if ( !!srcAddr ) {
@ -3194,12 +3210,14 @@ augmentAddrIntrnl( CommsCtxt* comms, CommsAddrRec* destAddr,
/* If an address is getting added to a channel, the top-level
address should also include the type. The specifics of the
address don't make sense to copy, however. */
address don't make sense to copy, however.
NO -- not any more. I have the addresses my user gives me
*/
if ( !!comms && ! addr_hasType( &comms->addr, typ ) ) {
/* we just added it, so can't be comms->addr */
XP_ASSERT( destAddr != &comms->addr );
XP_LOGFF( "adding %s to comms->addr", ConnType2Str(typ) );
addr_addType( &comms->addr, typ );
XP_LOGFF( "NOT adding %s to comms->addr", ConnType2Str(typ) );
// addr_addType( &comms->addr, typ );
}
}
@ -3236,6 +3254,7 @@ augmentAddrIntrnl( CommsCtxt* comms, CommsAddrRec* destAddr,
case COMMS_CONN_NFC:
break;
case COMMS_CONN_MQTT:
XP_ASSERT( 0 != srcAddr->u.mqtt.devID );
dest = &destAddr->u.mqtt;
src = &srcAddr->u.mqtt;
siz = sizeof(destAddr->u.mqtt);
@ -3360,6 +3379,13 @@ types_addType( XP_U16* conTypes, CommsConnType type )
*conTypes |= 1 << (type - 1);
}
void
types_rmType( XP_U16* conTypes, CommsConnType type )
{
XP_ASSERT( COMMS_CONN_NONE != type );
*conTypes &= ~(1 << (type - 1));
}
void
addr_addType( CommsAddrRec* addr, CommsConnType type )
{
@ -3371,7 +3397,7 @@ addr_rmType( CommsAddrRec* addr, CommsConnType type )
{
XP_ASSERT( COMMS_CONN_NONE != type );
// XP_LOGF( "%s(%s)", __func__, ConnType2Str(type) );
addr->_conTypes &= ~(1 << (type - 1));
types_rmType( &addr->_conTypes, type );
}
/* Overwrites anything that might already be there. Use addr_addType() to add

View file

@ -1,6 +1,6 @@
/* -*- compile-command: "cd ../linux && make MEMDEBUG=TRUE -j3"; -*- */
/*
* Copyright 2001 - 2014 by Eric House (xwords@eehouse.org). All rights
* Copyright 2001 - 2022 by Eric House (xwords@eehouse.org). All rights
* reserved.
*
* This program is free software; you can redistribute it and/or
@ -138,6 +138,8 @@ typedef struct _TransportProcs {
CommsCtxt* comms_make( MPFORMAL XWEnv xwe, XW_UtilCtxt* util,
XP_Bool isServer,
const CommsAddrRec* selfAddr,
const CommsAddrRec* hostAddr,
#ifdef XWFEATURE_RELAY
XP_U16 nPlayersHere, XP_U16 nPlayersTotal,
#endif
@ -165,16 +167,6 @@ void comms_destroy( CommsCtxt* comms, XWEnv xwe );
void comms_setConnID( CommsCtxt* comms, XP_U32 connID );
/* "static" methods work when no comms present */
void comms_getInitialAddr( CommsAddrRec* addr
#ifdef XWFEATURE_RELAY
, const XP_UCHAR* relayName
, XP_U16 relayPort
#endif
);
XP_Bool comms_checkAddr( XWEnv xwe, DeviceRole role, const CommsAddrRec* addr,
XW_UtilCtxt* util );
void comms_getAddr( const CommsCtxt* comms, CommsAddrRec* addr );
void comms_augmentHostAddr( CommsCtxt* comms, XWEnv xwe, const CommsAddrRec* addr );
void comms_addMQTTDevID( CommsCtxt* comms, XP_PlayerAddr channelNo,
@ -261,12 +253,13 @@ XP_Bool augmentAddr( CommsAddrRec* addr, const CommsAddrRec* newer,
CommsConnType addr_getType( const CommsAddrRec* addr );
void addr_setType( CommsAddrRec* addr, CommsConnType type );
void addr_addType( CommsAddrRec* addr, CommsConnType type );
void types_addType( XP_U16* conTypes, CommsConnType type );
void addr_rmType( CommsAddrRec* addr, CommsConnType type );
XP_Bool addr_hasType( const CommsAddrRec* addr, CommsConnType type );
XP_Bool types_hasType( XP_U16 conTypes, CommsConnType type );
XP_Bool addr_iter( const CommsAddrRec* addr, CommsConnType* typp,
XP_U32* state );
void types_addType( XP_U16* conTypes, CommsConnType type );
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

View file

@ -155,8 +155,10 @@ unrefDicts( XWEnv xwe, const DictionaryCtxt* dict, PlayerDicts* playerDicts )
XP_Bool
game_makeNewGame( MPFORMAL XWEnv xwe, XWGame* game, CurGameInfo* gi,
XW_UtilCtxt* util, DrawCtx* draw,
const CommonPrefs* cp, const TransportProcs* procs
const CommsAddrRec* selfAddr, const CommsAddrRec* hostAddr,
XW_UtilCtxt* util,
DrawCtx* draw, const CommonPrefs* cp,
const TransportProcs* procs
#ifdef SET_GAMESEED
,XP_U16 gameSeed
#endif
@ -192,6 +194,7 @@ game_makeNewGame( MPFORMAL XWEnv xwe, XWGame* game, CurGameInfo* gi,
if ( gi->serverRole != SERVER_STANDALONE ) {
game->comms = comms_make( MPPARM(mpool) xwe, util,
gi->serverRole != SERVER_ISCLIENT,
selfAddr, hostAddr,
#ifdef XWFEATURE_RELAY
nPlayersHere, nPlayersTotal,
#endif
@ -228,7 +231,9 @@ game_makeNewGame( MPFORMAL XWEnv xwe, XWGame* game, CurGameInfo* gi,
} /* game_makeNewGame */
XP_Bool
game_reset( MPFORMAL XWGame* game, XWEnv xwe, CurGameInfo* gi, XW_UtilCtxt* util,
game_reset( MPFORMAL XWGame* game, XWEnv xwe, CurGameInfo* gi,
const CommsAddrRec* selfAddr, const CommsAddrRec* hostAddr,
XW_UtilCtxt* util,
CommonPrefs* cp, const TransportProcs* procs )
{
XP_ASSERT( util == game->util );
@ -262,6 +267,7 @@ game_reset( MPFORMAL XWGame* game, XWEnv xwe, CurGameInfo* gi, XW_UtilCtxt* util
} else if ( gi->serverRole != SERVER_STANDALONE ) {
game->comms = comms_make( MPPARM(mpool) xwe, util,
gi->serverRole != SERVER_ISCLIENT,
selfAddr, hostAddr,
#ifdef XWFEATURE_RELAY
nPlayersHere, nPlayersTotal,
#endif
@ -409,8 +415,8 @@ game_makeFromStream( MPFORMAL XWEnv xwe, XWStreamCtxt* stream,
XP_Bool
game_makeFromInvite( MPFORMAL XWEnv xwe, const NetLaunchInfo* nli,
XWGame* game, CurGameInfo* gi, const XP_UCHAR* plyrName,
XW_UtilCtxt* util, DrawCtx* draw,
XWGame* game, CurGameInfo* gi, const CommsAddrRec* selfAddr,
const XP_UCHAR* plyrName, XW_UtilCtxt* util, DrawCtx* draw,
CommonPrefs* cp, const TransportProcs* procs )
{
gi_setNPlayers( gi, nli->nPlayersT, nli->nPlayersH );
@ -425,7 +431,10 @@ game_makeFromInvite( MPFORMAL XWEnv xwe, const NetLaunchInfo* nli,
replaceStringIfDifferent( mpool, &gi->players[0].name, plyrName );
replaceStringIfDifferent( mpool, &gi->dictName, nli->dict );
XP_Bool success = game_makeNewGame( MPPARM(mpool) xwe, game, gi, util, draw, cp, procs );
CommsAddrRec hostAddr;
nli_makeAddrRec( nli, &hostAddr );
XP_Bool success = game_makeNewGame( MPPARM(mpool) xwe, game, gi, selfAddr,
&hostAddr, util, draw, cp, procs );
if ( success ) {
CommsAddrRec returnAddr;
nli_makeAddrRec( nli, &returnAddr );
@ -434,28 +443,6 @@ game_makeFromInvite( MPFORMAL XWEnv xwe, const NetLaunchInfo* nli,
return success;
}
void
game_saveNewGame( MPFORMAL XWEnv xwe, const CurGameInfo* gi, XW_UtilCtxt* util,
const CommonPrefs* cp, XWStreamCtxt* out )
{
XWGame newGame = {0};
CurGameInfo newGI = {0};
gi_copy( MPPARM(mpool) &newGI, gi );
game_makeNewGame( MPPARM(mpool) xwe, &newGame, &newGI, util,
NULL, /* DrawCtx*, */
cp, NULL /* TransportProcs* procs */
#ifdef SET_GAMESEED
,0
#endif
);
game_saveToStream( &newGame, xwe, &newGI, out, 1 );
game_saveSucceeded( &newGame, xwe, 1 );
game_dispose( &newGame, xwe );
gi_disposePlayerInfo( MPPARM(mpool) &newGI );
}
void
game_saveToStream( const XWGame* game, XWEnv xwe, const CurGameInfo* gi,
XWStreamCtxt* stream, XP_U16 saveToken )

View file

@ -76,13 +76,15 @@ typedef struct _XWGame {
} XWGame;
XP_Bool game_makeNewGame( MPFORMAL XWEnv xwe, XWGame* game, CurGameInfo* gi,
XW_UtilCtxt* util, DrawCtx* draw,
const CommonPrefs* cp, const TransportProcs* procs
const CommsAddrRec* selfAddr, const CommsAddrRec* hostAddr,
XW_UtilCtxt* util, DrawCtx* draw, const CommonPrefs* cp,
const TransportProcs* procs
#ifdef SET_GAMESEED
,XP_U16 gameSeed
#endif
);
XP_Bool game_reset( MPFORMAL XWGame* game, XWEnv xwe, CurGameInfo* gi,
const CommsAddrRec* selfAddr, const CommsAddrRec* hostAddr,
XW_UtilCtxt* util, CommonPrefs* cp,
const TransportProcs* procs );
void game_changeDict( MPFORMAL XWGame* game, XWEnv xwe, CurGameInfo* gi,
@ -94,8 +96,8 @@ XP_Bool game_makeFromStream( MPFORMAL XWEnv xwe, XWStreamCtxt* stream,
CommonPrefs* cp, const TransportProcs* procs );
XP_Bool game_makeFromInvite( MPFORMAL XWEnv xwe, const NetLaunchInfo* nli,
XWGame* game, CurGameInfo* gi, const XP_UCHAR* plyrName,
XW_UtilCtxt* util, DrawCtx* draw,
XWGame* game, CurGameInfo* gi, const CommsAddrRec* selfAddr,
const XP_UCHAR* plyrName, XW_UtilCtxt* util, DrawCtx* draw,
CommonPrefs* cp, const TransportProcs* procs );
void game_saveNewGame( MPFORMAL XWEnv xwe, const CurGameInfo* gi, XW_UtilCtxt* util,

View file

@ -47,7 +47,6 @@ static void getPlayersImpl( const KPState* state, const XP_UCHAR** players,
static void
loadFromStream( XW_DUtilCtxt* dutil, KPState* state, XWStreamCtxt* stream )
{
LOG_FUNC();
while ( 0 < stream_getSize( stream ) ) {
XP_U32 newestMod = stream_getU32( stream );
XP_UCHAR buf[64];

View file

@ -50,6 +50,7 @@ nli_init( NetLaunchInfo* nli, const CurGameInfo* gi, const CommsAddrRec* addr,
break;
case COMMS_CONN_SMS:
XP_STRCAT( nli->phone, addr->u.sms.phone );
XP_ASSERT( 1 == addr->u.sms.port );
// nli->port = addr->u.sms.port; <-- I wish
break;
case COMMS_CONN_MQTT:
@ -278,11 +279,23 @@ logNLI( const NetLaunchInfo* nli, const char* callerFunc, const int callerLine )
offset += XP_SNPRINTF( &conTypes[offset], sizeof(conTypes)-offset, "%s,", asstr );
}
XP_UCHAR buf[256+128];
XP_UCHAR buf[1024];
XP_SNPRINTF( buf, VSIZE(buf), "{ctyps: [%s], nPlayersT: %d, nPlayersH: %d, "
"isoCode: '%s', gameID: %d, inviteID: %s, mqttid: %s}", conTypes,
nli->nPlayersT, nli->nPlayersH, nli->isoCodeStr, nli->gameID,
nli->inviteID, nli->mqttDevID );
"isoCode: '%s', gameID: %d",
conTypes, nli->nPlayersT, nli->nPlayersH, nli->isoCodeStr,
nli->gameID );
if ( types_hasType( nli->_conTypes, COMMS_CONN_MQTT ) ) {
XP_UCHAR smallBuf[128];
XP_SNPRINTF( smallBuf, VSIZE(smallBuf), ", mqttid: %s", nli->mqttDevID );
XP_STRCAT( buf, smallBuf );
}
if ( types_hasType( nli->_conTypes, COMMS_CONN_SMS ) ) {
XP_UCHAR smallBuf[128];
XP_SNPRINTF( smallBuf, VSIZE(smallBuf), ", phone: %s",
nli->phone );
XP_STRCAT( buf, smallBuf );
}
XP_STRCAT( buf, "}" );
XP_LOGF( "%s", buf );
}
# endif

View file

@ -287,7 +287,7 @@ static XP_Bool
inDuplicateMode( const ServerCtxt* server )
{
XP_Bool result = server->vol.gi->inDuplicateMode;
// LOG_RETURNF( "%d", result );
// LOG_RETURNF( "%s", boolToStr(result) );
return result;
}
@ -423,7 +423,7 @@ getNV( XWStreamCtxt* stream, ServerNonvolatiles* nv, XP_U16 nPlayers )
if ( version >= STREAM_VERS_DUPLICATE ) {
for ( ii = 0; ii < nPlayers; ++ii ) {
nv->dupTurnsMade[ii] = stream_getBits( stream, 1 );
XP_LOGFF( "dupTurnsMade[%d]: %d", ii, nv->dupTurnsMade[ii] );
// XP_LOGFF( "dupTurnsMade[%d]: %d", ii, nv->dupTurnsMade[ii] );
nv->dupTurnsForced[ii] = stream_getBits( stream, 1 );
}
nv->dupTurnsSent = stream_getBits( stream, 1 );
@ -2413,14 +2413,14 @@ server_askPickTiles( ServerCtxt* server, XWEnv xwe, XP_U16 turn,
return asked;
}
/* dupe_trayAllowsMoves()
/* trayAllowsMoves()
*
* Assuming a model with a turn loaded (but maybe not committed), build the
* tile set containing the current model tray tiles PLUS the new set we're
* considering, and see if the engine can find moves.
*/
static XP_Bool
dupe_trayAllowsMoves( ServerCtxt* server, XWEnv xwe, XP_U16 turn,
trayAllowsMoves( ServerCtxt* server, XWEnv xwe, XP_U16 turn,
const Tile* tiles, XP_U16 nTiles )
{
ModelCtxt* model = server->vol.model;
@ -2552,8 +2552,8 @@ fetchTiles( ServerCtxt* server, XWEnv xwe, XP_U16 playerNum, XP_U16 nToFetch,
if ( !inDuplicateMode( server ) && !forceCanPlay ) {
break;
} else if ( dupe_trayAllowsMoves( server, xwe, playerNum, &resultTiles->tiles[0],
nSoFar + nLeft )
} else if ( trayAllowsMoves( server, xwe, playerNum, &resultTiles->tiles[0],
nSoFar + nLeft )
|| ++nBadTrays >= 5 ) {
break;
}

View file

@ -357,51 +357,6 @@ curses_socket_acceptor( int listener, Acceptor func, CommonGlobals* cGlobals,
}
}
static void
copyParmsAddr( CommonGlobals* cGlobals )
{
LaunchParams* params = cGlobals->params;
CommsAddrRec* addr = &cGlobals->addr;
CommsConnType typ;
for ( XP_U32 st = 0; addr_iter( &params->addr, &typ, &st ); ) {
addr_addType( addr, typ );
switch( typ ) {
#ifdef XWFEATURE_RELAY
case COMMS_CONN_RELAY:
addr->u.ip_relay.ipAddr = 0; /* ??? */
addr->u.ip_relay.port = params->connInfo.relay.defaultSendPort;
addr->u.ip_relay.seeksPublicRoom =
params->connInfo.relay.seeksPublicRoom;
addr->u.ip_relay.advertiseRoom = params->connInfo.relay.advertiseRoom;
XP_STRNCPY( addr->u.ip_relay.hostName,
params->connInfo.relay.relayName,
sizeof(addr->u.ip_relay.hostName) - 1 );
XP_STRNCPY( addr->u.ip_relay.invite, params->connInfo.relay.invite,
sizeof(addr->u.ip_relay.invite) - 1 );
break;
#endif
#ifdef XWFEATURE_SMS
case COMMS_CONN_SMS:
XP_STRNCPY( addr->u.sms.phone, params->connInfo.sms.myPhone,
sizeof(addr->u.sms.phone) - 1 );
addr->u.sms.port = params->connInfo.sms.port;
break;
#endif
#ifdef XWFEATURE_BLUETOOTH
case COMMS_CONN_BT:
XP_ASSERT( sizeof(addr->u.bt.btAddr)
>= sizeof(params->connInfo.bt.hostAddr));
XP_MEMCPY( &addr->u.bt.btAddr, &params->connInfo.bt.hostAddr,
sizeof(params->connInfo.bt.hostAddr) );
break;
#endif
default:
break;
}
}
}
static CursesBoardGlobals*
commonInit( CursesBoardState* cbState, sqlite3_int64 rowid,
const CurGameInfo* gip )
@ -442,7 +397,7 @@ commonInit( CursesBoardState* cbState, sqlite3_int64 rowid,
bGlobals->procs.requestJoin = relay_requestJoin_curses;
#endif
copyParmsAddr( cGlobals );
makeSelfAddress( &cGlobals->selfAddr, params );
setOneSecondTimer( cGlobals );
return bGlobals;
@ -575,6 +530,10 @@ initNoDraw( CursesBoardState* cbState, sqlite3_int64 rowid,
CommonGlobals* cGlobals = &result->cGlobals;
LaunchParams* params = cGlobals->params;
if ( !!returnAddr ) {
cGlobals->hostAddr = *returnAddr;
}
cGlobals->cp.showBoardArrow = XP_TRUE;
cGlobals->cp.showRobotScores = params->showRobotScores;
cGlobals->cp.hideTileValues = params->hideValues;
@ -592,7 +551,7 @@ initNoDraw( CursesBoardState* cbState, sqlite3_int64 rowid,
cGlobals->cp.makePhonyPct = params->makePhonyPct;
#endif
if ( linuxOpenGame( cGlobals, &result->procs, returnAddr ) ) {
if ( linuxOpenGame( cGlobals, &result->procs ) ) {
result = ref( result );
} else {
disposeBoard( result );

View file

@ -618,8 +618,7 @@ createOrLoadObjects( GtkGameGlobals* globals )
TransportProcs procs;
setTransportProcs( &procs, globals );
if ( linuxOpenGame( cGlobals, &procs, &cGlobals->addr ) ) {
if ( linuxOpenGame( cGlobals, &procs ) ) {
if ( !params->fileName && !!params->dbName ) {
XP_UCHAR buf[64];
snprintf( buf, sizeof(buf), "%s / %lld", params->dbName,
@ -861,23 +860,14 @@ new_game_impl( GtkGameGlobals* globals, XP_Bool fireConnDlg )
{
XP_Bool success = XP_FALSE;
CommonGlobals* cGlobals = &globals->cGlobals;
CommsAddrRec addr;
if ( !!cGlobals->game.comms ) {
comms_getAddr( cGlobals->game.comms, &addr );
} else {
comms_getInitialAddr( &addr
#ifdef XWFEATURE_RELAY
, RELAY_NAME_DEFAULT, RELAY_PORT_DEFAULT
#endif
);
}
CurGameInfo* gi = cGlobals->gi;
CommsAddrRec addr;
success = gtkNewGameDialog( globals, gi, &addr, XP_TRUE, fireConnDlg );
if ( success ) {
#ifndef XWFEATURE_STANDALONE_ONLY
XP_Bool isClient = gi->serverRole == SERVER_ISCLIENT;
XP_ASSERT( !isClient ); /* Doesn't make sense! Send invitation. */
#endif
TransportProcs procs = {
.closure = globals,
@ -887,20 +877,10 @@ new_game_impl( GtkGameGlobals* globals, XP_Bool fireConnDlg )
#endif
};
(void)game_reset( MEMPOOL &cGlobals->game, NULL_XWE, gi, cGlobals->util,
(void)game_reset( MEMPOOL &cGlobals->game, NULL_XWE, gi,
&cGlobals->selfAddr, NULL, cGlobals->util,
&cGlobals->cp, &procs );
#ifndef XWFEATURE_STANDALONE_ONLY
if ( !!cGlobals->game.comms ) {
comms_augmentHostAddr( cGlobals->game.comms, NULL_XWE, &addr );
} else if ( gi->serverRole != SERVER_STANDALONE ) {
XP_ASSERT(0);
}
if ( isClient ) {
tryConnectToServer( cGlobals );
}
#endif
(void)server_do( cGlobals->game.server, NULL_XWE ); /* assign tiles, etc. */
board_invalAll( cGlobals->game.board );
board_draw( cGlobals->game.board, NULL_XWE );
@ -2507,6 +2487,8 @@ initGlobalsNoDraw( GtkGameGlobals* globals, LaunchParams* params,
setupUtil( cGlobals );
setupGtkUtilCallbacks( globals, cGlobals->util );
makeSelfAddress( &cGlobals->selfAddr, params );
}
/* This gets called all the time, e.g. when the mouse moves across
@ -2736,27 +2718,8 @@ XP_Bool
makeNewGame( GtkGameGlobals* globals )
{
CommonGlobals* cGlobals = &globals->cGlobals;
if ( !!cGlobals->game.comms ) {
comms_getAddr( cGlobals->game.comms, &cGlobals->addr );
} else {
#ifdef XWFEATURE_RELAY
LaunchParams* params = cGlobals->params;
const XP_UCHAR* relayName = params->connInfo.relay.relayName;
if ( !relayName ) {
relayName = RELAY_NAME_DEFAULT;
}
XP_U16 relayPort = params->connInfo.relay.defaultSendPort;
if ( 0 == relayPort ) {
relayPort = RELAY_PORT_DEFAULT;
}
comms_getInitialAddr( &cGlobals->addr , relayName, relayPort );
#else
comms_getInitialAddr( &cGlobals->addr );
#endif
}
CurGameInfo* gi = cGlobals->gi;
XP_Bool success = gtkNewGameDialog( globals, gi, &cGlobals->addr,
XP_Bool success = gtkNewGameDialog( globals, cGlobals->gi,
&cGlobals->selfAddr,
XP_TRUE, XP_FALSE );
LOG_RETURNF( "%s", boolToStr(success) );
return success;

View file

@ -351,63 +351,10 @@ handle_open_button( GtkWidget* XP_UNUSED(widget), void* closure )
}
void
make_rematch( GtkAppGlobals* apg, const CommonGlobals* cGlobals )
make_rematch( GtkAppGlobals* XP_UNUSED(apg),
const CommonGlobals* XP_UNUSED(cGlobals) )
{
LaunchParams* params = apg->cag.params;
XP_ASSERT( params == cGlobals->params );
XWStreamCtxt* stream = mem_stream_make_raw( MPPARM(cGlobals->util->mpool)
params->vtMgr );
/* Create new game. But has no addressing info, so need to set that
aside for later. */
const CommsCtxt* comms = cGlobals->game.comms;
CurGameInfo gi = {0};
gi_copy( MPPARM(cGlobals->util->mpool) &gi, cGlobals->gi );
gi.gameID = 0; /* clear so will get generated */
if ( !!comms ) {
gi.serverRole = SERVER_ISSERVER;
gi.forceChannel = 0;
}
game_saveNewGame( MPPARM(cGlobals->util->mpool) NULL_XWE, &gi,
cGlobals->util, &cGlobals->cp, stream );
sqlite3_int64 rowID = gdb_writeNewGame( stream, params->pDb );
stream_destroy( stream, NULL_XWE );
gi_disposePlayerInfo( MPPARM(cGlobals->util->mpool) &gi );
/* If it's a multi-device game, save enough information with it than when
opened it can invite the other device[s] join the rematch. */
if ( !!comms ) {
XWStreamCtxt* stream = mem_stream_make_raw( MPPARM(cGlobals->util->mpool)
params->vtMgr );
CommsAddrRec addr;
comms_getAddr( comms, &addr );
addrToStream( stream, &addr );
CommsAddrRec addrs[4];
XP_U16 nRecs = VSIZE(addrs);
comms_getAddrs( comms, NULL_XWE, addrs, &nRecs );
stream_putU8( stream, nRecs );
for ( int ii = 0; ii < nRecs; ++ii ) {
XP_LOGFF( "MQTT rematch not implemented" );
XP_ASSERT(0); /* REWRITE TO USE MQTT */
/* XP_UCHAR relayID[32]; */
/* XP_U16 len = sizeof(relayID); */
/* comms_formatRelayID( comms, ii, relayID, &len ); */
/* XP_LOGF( "%s: adding relayID: %s", __func__, relayID ); */
/* stringToStream( stream, relayID ); */
/* if ( addr_hasType( &addrs[ii], COMMS_CONN_RELAY ) ) { */
/* /\* copy over room name *\/ */
/* XP_STRCAT( addrs[ii].u.ip_relay.invite, addr.u.ip_relay.invite ); */
/* } */
/* addrToStream( stream, &addrs[ii] ); */
}
gdb_saveInviteAddrs( stream, params->pDb, rowID );
stream_destroy( stream, NULL_XWE );
}
open_row( apg, rowID, XP_TRUE );
XP_ASSERT(0);
} /* make_rematch */
static void
@ -740,7 +687,7 @@ feedBufferGTK( GtkAppGlobals* apg, sqlite3_int64 rowid,
/* Stuff common to receiving invitations */
static void
gameFromInvite( GtkAppGlobals* apg, const NetLaunchInfo* invite,
const CommsAddrRec* returnAddr )
const CommsAddrRec* XP_UNUSED(returnAddr) )
{
LaunchParams* params = apg->cag.params;
CurGameInfo gi = {0};
@ -757,17 +704,13 @@ gameFromInvite( GtkAppGlobals* apg, const NetLaunchInfo* invite,
replaceStringIfDifferent( params->mpool, &gi.dictName, invite->dict );
GtkGameGlobals* globals = malloc( sizeof(*globals) );
CommonGlobals* cGlobals = &globals->cGlobals;
params->needsNewGame = XP_FALSE;
initBoardGlobalsGtk( globals, params, &gi );
if ( !!returnAddr ) {
globals->cGlobals.addr = *returnAddr;
} else {
nli_makeAddrRec( invite, &globals->cGlobals.addr );
}
nli_makeAddrRec( invite, &cGlobals->hostAddr );
GtkWidget* gameWindow = globals->window;
globals->cGlobals.rowid = -1;
cGlobals->rowid = -1;
recordOpened( apg, globals );
gtk_widget_show( gameWindow );

View file

@ -61,6 +61,7 @@
#include "relaycon.h"
#include "mqttcon.h"
#include "smsproto.h"
#include "device.h"
#ifdef PLATFORM_NCURSES
# include "cursesmain.h"
#endif
@ -147,10 +148,8 @@ ensureLocalPlayerNames( LaunchParams* XP_UNUSED_DBG(params), CurGameInfo* gi )
}
bool
linuxOpenGame( CommonGlobals* cGlobals, const TransportProcs* procs,
const CommsAddrRec* returnAddrP )
linuxOpenGame( CommonGlobals* cGlobals, const TransportProcs* procs )
{
LOG_FUNC();
XWStreamCtxt* stream = NULL;
XP_Bool opened = XP_FALSE;
@ -163,6 +162,7 @@ linuxOpenGame( CommonGlobals* cGlobals, const TransportProcs* procs,
XP_SNPRINTF( buf, sizeof(buf), "%d", params->dbFileID );
mpool_setTag( MEMPOOL buf );
stream = streamFromDB( cGlobals );
XP_ASSERT(0);
#endif
} else if ( !!params->pDb && 0 <= cGlobals->rowid ) {
stream = mem_stream_make_raw( MPPARM(cGlobals->util->mpool)
@ -184,10 +184,13 @@ linuxOpenGame( CommonGlobals* cGlobals, const TransportProcs* procs,
if ( !opened /* && canMakeFromGI( cGlobals->gi )*/ ) {
opened = XP_TRUE;
CommsAddrRec* hostAddr = NULL;
if ( cGlobals->gi->serverRole == SERVER_ISCLIENT ) {
hostAddr = &cGlobals->hostAddr;
}
game_makeNewGame( MEMPOOL NULL_XWE, &cGlobals->game, cGlobals->gi,
cGlobals->util, cGlobals->draw,
&cGlobals->cp, procs
&cGlobals->selfAddr, hostAddr, cGlobals->util,
cGlobals->draw, &cGlobals->cp, procs
#ifdef SET_GAMESEED
, params->gameSeed
#endif
@ -195,60 +198,6 @@ linuxOpenGame( CommonGlobals* cGlobals, const TransportProcs* procs,
#ifdef XWFEATURE_RELAY
bool savedGame = false;
#endif
CommsAddrRec returnAddr = {0};
if ( !!returnAddrP ) {
returnAddr = *returnAddrP;
CommsConnType typ;
for ( XP_U32 st = 0; addr_iter( &returnAddr, &typ, &st ); ) {
if ( params->commsDisableds[typ][0] ) {
comms_setAddrDisabled( cGlobals->game.comms, typ, XP_FALSE, XP_TRUE );
}
if ( params->commsDisableds[typ][1] ) {
comms_setAddrDisabled( cGlobals->game.comms, typ, XP_TRUE, XP_TRUE );
}
switch( typ ) {
#ifdef XWFEATURE_RELAY
case COMMS_CONN_RELAY:
/* addr.u.ip_relay.ipAddr = 0; */
/* addr.u.ip_relay.port = params->connInfo.relay.defaultSendPort; */
/* addr.u.ip_relay.seeksPublicRoom = params->connInfo.relay.seeksPublicRoom; */
/* addr.u.ip_relay.advertiseRoom = params->connInfo.relay.advertiseRoom; */
/* XP_STRNCPY( addr.u.ip_relay.hostName, params->connInfo.relay.relayName, */
/* sizeof(addr.u.ip_relay.hostName) - 1 ); */
/* XP_STRNCPY( addr.u.ip_relay.invite, params->connInfo.relay.invite, */
/* sizeof(addr.u.ip_relay.invite) - 1 ); */
break;
#endif
#ifdef XWFEATURE_BLUETOOTH
case COMMS_CONN_BT:
XP_ASSERT( sizeof(returnAddr.u.bt.btAddr)
>= sizeof(params->connInfo.bt.hostAddr));
XP_MEMCPY( &returnAddr.u.bt.btAddr, &params->connInfo.bt.hostAddr,
sizeof(params->connInfo.bt.hostAddr) );
break;
#endif
#ifdef XWFEATURE_IP_DIRECT
case COMMS_CONN_IP_DIRECT:
XP_STRNCPY( returnAddr.u.ip.hostName_ip, params->connInfo.ip.hostName,
sizeof(addr.u.ip.hostName_ip) - 1 );
returnAddr.u.ip.port_ip = params->connInfo.ip.port;
break;
#endif
#ifdef XWFEATURE_SMS
case COMMS_CONN_SMS:
XP_LOGF( "%s(): SMS is on at least", __func__ );
/* No! Don't overwrite what may be a return address with local
stuff */
/* XP_STRNCPY( addr.u.sms.phone, params->connInfo.sms.phone, */
/* sizeof(addr.u.sms.phone) - 1 ); */
/* addr.u.sms.port = params->connInfo.sms.port; */
break;
#endif
default:
break;
}
}
}
/* Need to save in order to have a valid selRow for the first send */
linuxSaveGame( cGlobals );
@ -256,57 +205,9 @@ linuxOpenGame( CommonGlobals* cGlobals, const TransportProcs* procs,
savedGame = true;
#endif
#ifndef XWFEATURE_STANDALONE_ONLY
/* If this is to be a relay connected game, tell it so. Otherwise
let the invitation process and receipt of messages populate
comms' addressbook */
if ( cGlobals->gi->serverRole != SERVER_STANDALONE ) {
#ifdef XWFEATURE_RELAY
if ( addr_hasType( &params->addr, COMMS_CONN_RELAY ) ) {
if ( ! savedGame ) {
linuxSaveGame( cGlobals );
savedGame = true;
}
CommsAddrRec addr = {0};
comms_getInitialAddr( &addr, params->connInfo.relay.relayName,
params->connInfo.relay.defaultSendPort );
XP_MEMCPY( addr.u.ip_relay.invite, params->connInfo.relay.invite,
1 + XP_STRLEN(params->connInfo.relay.invite) );
addr.u.ip_relay.seeksPublicRoom = params->connInfo.relay.seeksPublicRoom;
addr.u.ip_relay.advertiseRoom = params->connInfo.relay.advertiseRoom;
comms_augmentHostAddr( cGlobals->game.comms, NULL_XWE, &addr ); /* sends stuff */
}
#endif
if ( addr_hasType( &params->addr, COMMS_CONN_SMS ) ) {
CommsAddrRec addr = {0};
addr_addType( &addr, COMMS_CONN_SMS );
XP_STRCAT( addr.u.sms.phone, params->connInfo.sms.myPhone );
addr.u.sms.port = params->connInfo.sms.port;
comms_augmentHostAddr( cGlobals->game.comms, NULL_XWE, &addr );
}
if ( addr_hasType( &params->addr, COMMS_CONN_MQTT ) ) {
CommsAddrRec addr = {0};
addr_addType( &addr, COMMS_CONN_MQTT );
addr.u.mqtt.devID = *mqttc_getDevID( params );
comms_augmentHostAddr( cGlobals->game.comms, NULL_XWE, &addr );
}
}
if ( !!returnAddrP ) {
/* This may trigger network activity */
CommsCtxt* comms = cGlobals->game.comms;
if ( !!comms ) {
comms_augmentHostAddr( cGlobals->game.comms, NULL_XWE, &returnAddr );
}
}
#endif
#ifdef XWFEATURE_SEARCHLIMIT
cGlobals->gi->allowHintRect = params->allowHintRect;
#endif
if ( params->needsNewGame && !opened ) {
XP_ASSERT(0);
// new_game_impl( globals, XP_FALSE );
@ -330,6 +231,7 @@ linuxOpenGame( CommonGlobals* cGlobals, const TransportProcs* procs,
server_do( cGlobals->game.server, NULL_XWE );
linuxSaveGame( cGlobals ); /* again, to include address etc. */
}
LOG_RETURNF( "%s", boolToStr(opened) );
return opened;
} /* linuxOpenGame */
@ -849,7 +751,7 @@ typedef enum {
,CMD_INVITEE_SMSNUMBER
,CMD_SMSPORT
#endif
,CMD_WITHMQTT
,CMD_WITHOUT_MQTT
,CMD_MQTTHOST
,CMD_MQTTPORT
@ -1002,7 +904,7 @@ static CmdInfoRec CmdInfoRecs[] = {
,{ CMD_INVITEE_SMSNUMBER, true, "invitee-sms-number", "number to send any invitation to" }
,{ CMD_SMSPORT, true, "sms-port", "this devices's sms port" }
#endif
,{ CMD_WITHMQTT, false, "with-mqtt", "enable connecting via mqtt" }
,{ CMD_WITHOUT_MQTT, false, "without-mqtt", "disable connecting via mqtt (which is on by default)" }
,{ CMD_MQTTHOST, true, "mqtt-host", "server mosquitto is running on" }
,{ CMD_MQTTPORT, true, "mqtt-port", "port mosquitto is listening on" }
,{ CMD_INVITEE_MQTTDEVID, true, "invitee-mqtt-devid", "upper-case hex devID to send any invitation to" }
@ -2626,6 +2528,32 @@ testOneString( const LaunchParams* params, GSList* testDicts )
}
#endif
void
makeSelfAddress( CommsAddrRec* selfAddr, const LaunchParams* params )
{
XP_MEMSET( selfAddr, 0, sizeof(*selfAddr) );
CommsConnType typ;
for ( XP_U32 state = 0; types_iter( params->conTypes, &typ, &state ); ) {
XP_LOGFF( "got type: %s", ConnType2Str(typ) );
addr_addType( selfAddr, typ );
switch ( typ ) {
case COMMS_CONN_MQTT:
dvc_getMQTTDevID( params->dutil, NULL_XWE, &selfAddr->u.mqtt.devID );
XP_ASSERT( 0 != selfAddr->u.mqtt.devID );
break;
case COMMS_CONN_SMS:
XP_ASSERT( !!params->connInfo.sms.myPhone[0] );
XP_STRCAT( selfAddr->u.sms.phone, params->connInfo.sms.myPhone );
XP_ASSERT( 1 == params->connInfo.sms.port ); /* It's ignored, but keep it 1 */
selfAddr->u.sms.port = params->connInfo.sms.port;
break;
default:
XP_ASSERT(0);
}
}
}
int
main( int argc, char** argv )
{
@ -2660,9 +2588,6 @@ main( int argc, char** argv )
#ifdef XWFEATURE_SMS
// char* phone = NULL;
#endif
#ifdef XWFEATURE_BLUETOOTH
const char* btaddr = NULL;
#endif
setlocale(LC_ALL, "");
@ -2724,6 +2649,7 @@ main( int argc, char** argv )
mainParams.useUdp = true;
mainParams.dbName = "xwgames.sqldb";
mainParams.cursesListWinHt = 5;
types_addType( &mainParams.conTypes, COMMS_CONN_MQTT );
if ( file_exists( "./dict.xwd" ) ) {
trimDictPath( "./dict.xwd", dictbuf, VSIZE(dictbuf), &path, &dict );
@ -2780,15 +2706,15 @@ main( int argc, char** argv )
#endif
case CMD_HOSTIP:
mainParams.connInfo.ip.hostName = optarg;
addr_addType( &mainParams.addr, COMMS_CONN_IP_DIRECT );
types_addType( &mainParams.conTypes, COMMS_CONN_IP_DIRECT );
break;
case CMD_HOSTPORT:
mainParams.connInfo.ip.hostPort = atoi(optarg);
addr_addType( &mainParams.addr, COMMS_CONN_IP_DIRECT );
types_addType( &mainParams.conTypes, COMMS_CONN_IP_DIRECT );
break;
case CMD_MYPORT:
mainParams.connInfo.ip.myPort = atoi(optarg);
addr_addType( &mainParams.addr, COMMS_CONN_IP_DIRECT );
types_addType( &mainParams.conTypes, COMMS_CONN_IP_DIRECT );
break;
case CMD_DICT:
trimDictPath( optarg, dictbuf, VSIZE(dictbuf), &path, &dict );
@ -2909,12 +2835,12 @@ main( int argc, char** argv )
#ifdef XWFEATURE_SMS
case CMD_SMSNUMBER: /* SMS phone number */
mainParams.connInfo.sms.myPhone = optarg;
addr_addType( &mainParams.addr, COMMS_CONN_SMS );
types_addType( &mainParams.conTypes, COMMS_CONN_SMS );
break;
case CMD_INVITEE_SMSNUMBER:
mainParams.connInfo.sms.inviteePhones =
g_slist_append( mainParams.connInfo.sms.inviteePhones, optarg );
addr_addType( &mainParams.addr, COMMS_CONN_SMS );
types_addType( &mainParams.conTypes, COMMS_CONN_SMS );
break;
case CMD_INVITEE_COUNTS: {
gchar** strs = g_strsplit( optarg, ":", -1 );
@ -2928,11 +2854,11 @@ main( int argc, char** argv )
break;
case CMD_SMSPORT:
mainParams.connInfo.sms.port = atoi(optarg);
addr_addType( &mainParams.addr, COMMS_CONN_SMS );
types_addType( &mainParams.conTypes, COMMS_CONN_SMS );
break;
#endif
case CMD_WITHMQTT:
addr_addType( &mainParams.addr, COMMS_CONN_MQTT );
case CMD_WITHOUT_MQTT:
types_rmType( &mainParams.conTypes, COMMS_CONN_MQTT );
break;
case CMD_MQTTHOST:
mainParams.connInfo.mqtt.hostName = optarg;
@ -2943,7 +2869,7 @@ main( int argc, char** argv )
case CMD_INVITEE_MQTTDEVID:
mainParams.connInfo.mqtt.inviteeDevIDs =
g_slist_append( mainParams.connInfo.mqtt.inviteeDevIDs, optarg );
addr_addType( &mainParams.addr, COMMS_CONN_MQTT );
types_addType( &mainParams.conTypes, COMMS_CONN_MQTT );
break;
case CMD_DUPPACKETS:
mainParams.duplicatePackets = XP_TRUE;
@ -3072,8 +2998,8 @@ main( int argc, char** argv )
break;
#ifdef XWFEATURE_BLUETOOTH
case CMD_BTADDR:
addr_addType( &mainParams.addr, COMMS_CONN_BT );
btaddr = optarg;
types_addType( &mainParams.conTypes, COMMS_CONN_BT );
mainParams.connInfo.bt.btaddr = optarg;
break;
#endif
case CMD_HIDEVALUES:
@ -3286,6 +3212,7 @@ main( int argc, char** argv )
given. It's an error to give too many, or not to give enough if
there's no game-dict */
if ( 0 < nPlayerDicts ) {
XP_ASSERT(0); /* fix me */
/* XP_U16 nextDict = 0; */
/* for ( ii = 0; ii < mainParams.gi.nPlayers; ++ii ) { */
/* if ( mainParams.gi.players[ii].isLocal ) { */
@ -3302,71 +3229,14 @@ main( int argc, char** argv )
/* } */
}
/* if ( !isServer ) { */
/* if ( mainParams.info.serverInfo.nRemotePlayers > 0 ) { */
/* mainParams.needsNewGame = XP_TRUE; */
/* } */
/* } */
#ifdef XWFEATURE_WALKDICT
if ( !!testDicts ) {
walk_dict_test_all( MPPARM(mainParams.mpool) &mainParams, testDicts, testPrefixes );
exit( 0 );
}
#endif
CommsConnType typ;
for ( XP_U32 st = 0; addr_iter( &mainParams.addr, &typ, &st ); ) {
switch ( typ ) {
#ifdef XWFEATURE_BLUETOOTH
case COMMS_CONN_BT: {
bdaddr_t ba;
XP_Bool success;
XP_ASSERT( btaddr );
if ( isServer ) {
success = XP_TRUE;
/* any format is ok */
} else if ( btaddr[1] == ':' ) {
success = XP_FALSE;
if ( btaddr[0] == 'n' ) {
if ( !nameToBtAddr( btaddr+2, &ba ) ) {
fprintf( stderr, "fatal error: unable to find device %s\n",
btaddr + 2 );
exit(0);
}
success = XP_TRUE;
} else if ( btaddr[0] == 'a' ) {
success = 0 == str2ba( &btaddr[2], &ba );
XP_ASSERT( success );
}
}
if ( !success ) {
usage( argv[0], "bad format for -B param" );
}
XP_MEMCPY( &mainParams.connInfo.bt.hostAddr, &ba,
sizeof(mainParams.connInfo.bt.hostAddr) );
}
break;
#endif
/* #ifdef XWFEATURE_SMS */
/* case COMMS_CONN_SMS: */
/* XP_MEMCPY( &mainParams.connInfo.sms.myPhone, sms-phone */
/* const char* serverPhone; */
/* int port; */
/* break; */
/* #endif */
default:
break;
}
}
// addr_setType( &mainParams.addr, conType );
/* mainParams.pipe = linuxCommPipeCtxtMake( isServer ); */
/* mainParams.util->vtable->m_util_makeStreamFromAddr = */
/* linux_util_makeStreamFromAddr; */
// mainParams.util->gameInfo = &mainParams.pgi;
srandom( seed ); /* init linux random number generator */
XP_LOGFF( "seeded srandom with %d", seed );

View file

@ -112,9 +112,10 @@ void linux_doInitialReg( LaunchParams* params, XP_Bool idIsNew );
XP_Bool linux_setupDevidParams( LaunchParams* params );
XP_Bool parseSMSParams( LaunchParams* params, gchar** myPhone, XP_U16* myPort );
void makeSelfAddress( CommsAddrRec* selfAddr, const LaunchParams* params );
unsigned int makeRandomInt();
bool linuxOpenGame( CommonGlobals* cGlobals, const TransportProcs* procs,
const CommsAddrRec* addrP );
bool linuxOpenGame( CommonGlobals* cGlobals, const TransportProcs* procs );
void tryConnectToServer( CommonGlobals* cGlobals );
void ensureLocalPlayerNames( LaunchParams* params, CurGameInfo* gi );
void cancelTimers( CommonGlobals* cGlobals );

View file

@ -153,7 +153,7 @@ typedef struct _LaunchParams {
const XP_UCHAR* iterTestPatStr;
#endif
CommsAddrRec addr;
XP_U16 conTypes;
struct {
XP_U16 inviteeCounts[MAX_NUM_PLAYERS];
#ifdef XWFEATURE_RELAY
@ -169,6 +169,7 @@ typedef struct _LaunchParams {
#ifdef XWFEATURE_BLUETOOTH
struct {
bdaddr_t hostAddr; /* unused if a host */
const char* btaddr;
} bt;
#endif
#if defined XWFEATURE_IP_DIRECT || defined XWFEATURE_DIRECTIP
@ -229,7 +230,8 @@ struct CommonGlobals {
XWGame game;
DrawCtx* draw;
CurGameInfo* gi;
CommsAddrRec addr;
CommsAddrRec selfAddr; /* set e.g. by new game dialog */
CommsAddrRec hostAddr; /* used by client only: addr of invite sender */
XP_U16 lastNTilesToUse;
XP_U16 lastStreamSize;
XP_U16 nMissing;

View file

@ -476,6 +476,8 @@ def build_cmds(args):
PARAMS += [ '--with-mqtt' ]
if DEV == 1:
PARAMS += [ '--force-invite' ]
else:
PARAMS += [ '--without-mqtt' ]
if args.UNDO_PCT > 0:
PARAMS += ['--undo-pct', args.UNDO_PCT]