fix relay game failure to change roles

If a configured-as-host game joined an existing game the relay would
make it a guest. The android util_ callback for that change was only
implemented in BoardDelegate and so the change was dropped unless the
game was open/visible. Because comms recorded the change, though, the
callback would never be called again and so the game never learned to
behave as a guest and never registered: permanent failure to join game!
Implemented with a new server state so initClientConnection can be
called from server_do() instead of inside comms while processing an
incoming packet.
This commit is contained in:
Eric House 2020-08-25 14:47:56 -07:00
parent 15fde8044f
commit b0f7176b6c
14 changed files with 85 additions and 89 deletions

View file

@ -1828,22 +1828,6 @@ public class BoardDelegate extends DelegateBase
} }
} }
@Override
public void setIsServer( boolean isServer )
{
Log.d( TAG, "setIsServer(isServer=%b)", isServer );
DeviceRole newRole = isServer? DeviceRole.SERVER_ISSERVER
: DeviceRole.SERVER_ISCLIENT;
if ( newRole != m_gi.serverRole ) {
m_gi.serverRole = newRole;
if ( !isServer ) {
handleViaThread( JNICmd.CMD_SWITCHCLIENT );
}
} else {
Log.d( TAG, "setIsServer(): no change" );
}
}
@Override @Override
public void bonusSquareHeld( int bonus ) public void bonusSquareHeld( int bonus )
{ {

View file

@ -60,7 +60,6 @@ public class JNIThread extends Thread implements AutoCloseable {
CMD_INVALALL, CMD_INVALALL,
CMD_LAYOUT, CMD_LAYOUT,
CMD_START, CMD_START,
CMD_SWITCHCLIENT,
CMD_RESET, CMD_RESET,
CMD_SAVE, CMD_SAVE,
CMD_DO, CMD_DO,
@ -524,12 +523,6 @@ public class JNIThread extends Thread implements AutoCloseable {
draw = tryConnect( m_jniGamePtr, m_gi ); draw = tryConnect( m_jniGamePtr, m_gi );
break; break;
case CMD_SWITCHCLIENT:
XwJNI.server_reset( m_jniGamePtr );
XwJNI.server_initClientConnection( m_jniGamePtr );
draw = XwJNI.server_do( m_jniGamePtr );
break;
case CMD_DO: case CMD_DO:
if ( nextSame( JNICmd.CMD_DO ) ) { if ( nextSame( JNICmd.CMD_DO ) ) {
continue; continue;

View file

@ -61,7 +61,6 @@ public interface UtilCtxt {
void requestTime(); void requestTime();
void remSelected(); void remSelected();
void timerSelected( boolean inDuplicateMode, boolean canPause ); void timerSelected( boolean inDuplicateMode, boolean canPause );
void setIsServer( boolean isServer );
void informWordsBlocked( int nWords, String words, String dict ); void informWordsBlocked( int nWords, String words, String dict );
void bonusSquareHeld( int bonus ); void bonusSquareHeld( int bonus );

View file

@ -79,12 +79,14 @@ public class UtilCtxtImpl implements UtilCtxt {
@Override @Override
public void setTimer( int why, int when, int handle ) public void setTimer( int why, int when, int handle )
{ {
Log.e( TAG, "setTimer(%d) not doing anything...", why );
subclassOverride( "setTimer" ); subclassOverride( "setTimer" );
} }
@Override @Override
public void clearTimer( int why ) public void clearTimer( int why )
{ {
Log.e( TAG, "setTimer(%d) not doing anything...", why );
subclassOverride( "clearTimer" ); subclassOverride( "clearTimer" );
} }
@ -100,13 +102,6 @@ public class UtilCtxtImpl implements UtilCtxt {
subclassOverride( "timerSelected" ); subclassOverride( "timerSelected" );
} }
@Override
public void setIsServer( boolean isServer )
{
subclassOverride( "setIsServer" );
Assert.failDbg();
}
@Override @Override
public void informWordsBlocked( int nWords, String words, String dict ) public void informWordsBlocked( int nWords, String words, String dict )
{ {

View file

@ -703,16 +703,6 @@ and_util_addrChange( XW_UtilCtxt* uc, XWEnv xwe,
// LOG_FUNC(); // LOG_FUNC();
} }
static void
and_util_setIsServer( XW_UtilCtxt* uc, XWEnv xwe, XP_Bool isServer )
{
/* Change both the C and Java structs, which need to stay in sync */
uc->gameInfo->serverRole = isServer? SERVER_ISSERVER : SERVER_ISCLIENT;
UTIL_CBK_HEADER( "setIsServer", "(Z)V" );
(*env)->CallVoidMethod( env, util->jutil, mid, isServer );
UTIL_CBK_TAIL();
}
static void static void
and_util_informWordsBlocked( XW_UtilCtxt* uc, XWEnv xwe, XP_U16 nBadWords, and_util_informWordsBlocked( XW_UtilCtxt* uc, XWEnv xwe, XP_U16 nBadWords,
XWStreamCtxt* words, const XP_UCHAR* dict ) XWStreamCtxt* words, const XP_UCHAR* dict )
@ -975,7 +965,6 @@ makeUtil( MPFORMAL JNIEnv* env,
#ifndef XWFEATURE_STANDALONE_ONLY #ifndef XWFEATURE_STANDALONE_ONLY
SET_PROC(informMissing); SET_PROC(informMissing);
SET_PROC(addrChange); SET_PROC(addrChange);
SET_PROC(setIsServer);
#endif #endif
#ifdef XWFEATURE_SEARCHLIMIT #ifdef XWFEATURE_SEARCHLIMIT
SET_PROC(getTraySearchLimits); SET_PROC(getTraySearchLimits);

View file

@ -1221,6 +1221,7 @@ struct _JNIState {
#define XWJNI_START_GLOBALS() \ #define XWJNI_START_GLOBALS() \
XWJNI_START() \ XWJNI_START() \
AndGameGlobals* globals = &state->globals; \ AndGameGlobals* globals = &state->globals; \
XP_USE(globals); /*no warnings */ \
#define XWJNI_END() \ #define XWJNI_END() \
} \ } \

View file

@ -110,6 +110,10 @@ struct CommsCtxt {
AddressRecord* recs; /* return addresses */ AddressRecord* recs; /* return addresses */
TransportProcs procs; TransportProcs procs;
RoleChangeProc rcProc;
void* rcClosure;
XP_U32 xportFlags; XP_U32 xportFlags;
#ifdef COMMS_HEARTBEAT #ifdef COMMS_HEARTBEAT
XP_U32 lastMsgRcd; XP_U32 lastMsgRcd;
@ -355,7 +359,9 @@ CommsCtxt*
comms_make( MPFORMAL XWEnv xwe, XW_UtilCtxt* util, XP_Bool isServer, comms_make( MPFORMAL XWEnv xwe, XW_UtilCtxt* util, XP_Bool isServer,
XP_U16 XP_UNUSED_RELAY(nPlayersHere), XP_U16 XP_UNUSED_RELAY(nPlayersHere),
XP_U16 XP_UNUSED_RELAY(nPlayersTotal), XP_U16 XP_UNUSED_RELAY(nPlayersTotal),
const TransportProcs* procs, XP_U16 forceChannel const TransportProcs* procs,
RoleChangeProc rcp, void* rcClosure,
XP_U16 forceChannel
#ifdef SET_GAMESEED #ifdef SET_GAMESEED
, XP_U16 gameSeed , XP_U16 gameSeed
#endif #endif
@ -379,6 +385,10 @@ comms_make( MPFORMAL XWEnv xwe, XW_UtilCtxt* util, XP_Bool isServer,
comms->xportFlags = comms->procs.flags; comms->xportFlags = comms->procs.flags;
#endif #endif
} }
XP_ASSERT( rcp );
comms->rcProc = rcp;
comms->rcClosure = rcClosure;
comms->dutil = util_getDevUtilCtxt( util, xwe ); comms->dutil = util_getDevUtilCtxt( util, xwe );
comms->util = util; comms->util = util;
comms->dutil = util_getDevUtilCtxt( util, xwe ); comms->dutil = util_getDevUtilCtxt( util, xwe );
@ -648,8 +658,11 @@ addrFromStream( CommsAddrRec* addrP, XWStreamCtxt* stream )
} }
CommsCtxt* CommsCtxt*
comms_makeFromStream( MPFORMAL XWEnv xwe, XWStreamCtxt* stream, XW_UtilCtxt* util, comms_makeFromStream( MPFORMAL XWEnv xwe, XWStreamCtxt* stream,
const TransportProcs* procs, XP_U16 forceChannel ) XW_UtilCtxt* util,
const TransportProcs* procs,
RoleChangeProc rcp, void* rcClosure,
XP_U16 forceChannel )
{ {
XP_U16 nPlayersHere, nPlayersTotal; XP_U16 nPlayersHere, nPlayersTotal;
AddressRecord** prevsAddrNext; AddressRecord** prevsAddrNext;
@ -670,8 +683,8 @@ comms_makeFromStream( MPFORMAL XWEnv xwe, XWStreamCtxt* stream, XW_UtilCtxt* uti
nPlayersTotal = 0; nPlayersTotal = 0;
} }
CommsCtxt* comms = comms_make( MPPARM(mpool) xwe, util, isServer, CommsCtxt* comms = comms_make( MPPARM(mpool) xwe, util, isServer,
nPlayersHere, nPlayersTotal, procs, nPlayersHere, nPlayersTotal, procs,
forceChannel rcp, rcClosure, forceChannel
#ifdef SET_GAMESEED #ifdef SET_GAMESEED
, 0 , 0
#endif #endif
@ -1768,8 +1781,11 @@ got_connect_cmd( CommsCtxt* comms, XWEnv xwe, XWStreamCtxt* stream,
if ( isServer != comms->isServer ) { if ( isServer != comms->isServer ) {
XP_LOGFF( "becoming%s a server", isServer ? "" : " NOT" ); XP_LOGFF( "becoming%s a server", isServer ? "" : " NOT" );
comms->isServer = isServer; comms->isServer = isServer;
util_setIsServer( comms->util, xwe, comms->isServer ); #ifdef DEBUG
XP_U16 queueLen = comms->queueLen;
#endif
(*comms->rcProc)( xwe, comms->rcClosure, !isServer );
XP_ASSERT( queueLen == comms->queueLen ); /* callback should not send!!! */
reset_internal( comms, xwe, isServer, comms->rr.nPlayersHere, reset_internal( comms, xwe, isServer, comms->rr.nPlayersHere,
comms->rr.nPlayersTotal, XP_FALSE ); comms->rr.nPlayersTotal, XP_FALSE );
} }
@ -2732,7 +2748,8 @@ comms_getStats( CommsCtxt* comms, XWStreamCtxt* stream )
} }
XP_SNPRINTF( (XP_UCHAR*)buf, sizeof(buf), XP_SNPRINTF( (XP_UCHAR*)buf, sizeof(buf),
(XP_UCHAR*)"msg queue len: %d; have %d channels\n", (XP_UCHAR*)"role: %s; msg queue len: %d; have %d channels\n",
comms->isServer ? "host" : "guest",
comms->queueLen, nChannels ); comms->queueLen, nChannels );
stream_catString( stream, buf ); stream_catString( stream, buf );

View file

@ -102,6 +102,7 @@ typedef void (*RelayRequestJoinProc)( XWEnv xwe, void* closure, const XP_UCHAR*
#endif #endif
typedef void (*MsgCountChange)( XWEnv xwe, void* closure, XP_U16 msgCount ); typedef void (*MsgCountChange)( XWEnv xwe, void* closure, XP_U16 msgCount );
typedef void (*RoleChangeProc)( XWEnv xwe, void* closure, XP_Bool amNowGuest );
typedef enum { typedef enum {
COMMS_XPORT_FLAGS_NONE = 0 COMMS_XPORT_FLAGS_NONE = 0
@ -138,7 +139,9 @@ typedef struct _TransportProcs {
CommsCtxt* comms_make( MPFORMAL XWEnv xwe, XW_UtilCtxt* util, CommsCtxt* comms_make( MPFORMAL XWEnv xwe, XW_UtilCtxt* util,
XP_Bool isServer, XP_Bool isServer,
XP_U16 nPlayersHere, XP_U16 nPlayersTotal, XP_U16 nPlayersHere, XP_U16 nPlayersTotal,
const TransportProcs* procs, XP_U16 forceChannel const TransportProcs* procs,
RoleChangeProc rcp, void* rcClosure,
XP_U16 forceChannel
#ifdef SET_GAMESEED #ifdef SET_GAMESEED
,XP_U16 gameSeed ,XP_U16 gameSeed
#endif #endif
@ -187,6 +190,7 @@ XP_Bool comms_getIsServer( const CommsCtxt* comms );
CommsCtxt* comms_makeFromStream( MPFORMAL XWEnv xwe, XWStreamCtxt* stream, CommsCtxt* comms_makeFromStream( MPFORMAL XWEnv xwe, XWStreamCtxt* stream,
XW_UtilCtxt* util, XW_UtilCtxt* util,
const TransportProcs* procs, const TransportProcs* procs,
RoleChangeProc rcp, void* rcClosure,
XP_U16 forceChannel ); XP_U16 forceChannel );
void comms_start( CommsCtxt* comms, XWEnv xwe ); void comms_start( CommsCtxt* comms, XWEnv xwe );
void comms_stop( CommsCtxt* comms, XWEnv xwe ); void comms_stop( CommsCtxt* comms, XWEnv xwe );

View file

@ -98,6 +98,14 @@ timerChangeListener( XWEnv xwe, void* data, const XP_U32 gameID,
gameID, oldVal, newVal ); gameID, oldVal, newVal );
} }
static void
onRoleChanged( XWEnv xwe, void* closure, XP_Bool amNowGuest )
{
XP_ASSERT( amNowGuest );
XWGame* game = (XWGame*)closure;
server_onRoleChanged( game->server, xwe, amNowGuest );
}
static void static void
setListeners( XWGame* game, const CommonPrefs* cp ) setListeners( XWGame* game, const CommonPrefs* cp )
{ {
@ -136,7 +144,8 @@ game_makeNewGame( MPFORMAL XWEnv xwe, XWGame* game, CurGameInfo* gi,
game->comms = comms_make( MPPARM(mpool) xwe, util, game->comms = comms_make( MPPARM(mpool) xwe, util,
gi->serverRole != SERVER_ISCLIENT, gi->serverRole != SERVER_ISCLIENT,
nPlayersHere, nPlayersTotal, nPlayersHere, nPlayersTotal,
procs, gi->forceChannel procs, onRoleChanged, game,
gi->forceChannel
#ifdef SET_GAMESEED #ifdef SET_GAMESEED
, gameSeed , gameSeed
#endif #endif
@ -191,6 +200,7 @@ game_reset( MPFORMAL XWGame* game, XWEnv xwe, CurGameInfo* gi, XW_UtilCtxt* util
game->comms = comms_make( MPPARM(mpool) xwe, util, game->comms = comms_make( MPPARM(mpool) xwe, util,
gi->serverRole != SERVER_ISCLIENT, gi->serverRole != SERVER_ISCLIENT,
nPlayersHere, nPlayersTotal, procs, nPlayersHere, nPlayersTotal, procs,
onRoleChanged, game,
gi->forceChannel gi->forceChannel
#ifdef SET_GAMESEED #ifdef SET_GAMESEED
, 0 , 0
@ -281,7 +291,8 @@ game_makeFromStream( MPFORMAL XWEnv xwe, XWStreamCtxt* stream, XWGame* game,
if ( hasComms ) { if ( hasComms ) {
game->comms = comms_makeFromStream( MPPARM(mpool) xwe, stream, util, game->comms = comms_makeFromStream( MPPARM(mpool) xwe, stream, util,
procs, gi->forceChannel ); procs, onRoleChanged, game,
gi->forceChannel );
} else { } else {
game->comms = NULL; game->comms = NULL;
} }
@ -301,6 +312,11 @@ game_makeFromStream( MPFORMAL XWEnv xwe, XWStreamCtxt* stream, XWGame* game,
success = XP_TRUE; success = XP_TRUE;
} while( XP_FALSE ); } while( XP_FALSE );
} }
if ( success && !!game && !!game->comms ) {
XP_ASSERT( comms_getIsServer(game->comms) == server_getIsServer(game->server) );
}
return success; return success;
} /* game_makeFromStream */ } /* game_makeFromStream */

View file

@ -217,6 +217,7 @@ getStateStr( XW_State st )
switch( st ) { switch( st ) {
CASESTR(XWSTATE_NONE); CASESTR(XWSTATE_NONE);
CASESTR(XWSTATE_BEGIN); CASESTR(XWSTATE_BEGIN);
CASESTR(XWSTATE_NEWCLIENT);
CASESTR(XWSTATE_NEED_SHOWSCORE); CASESTR(XWSTATE_NEED_SHOWSCORE);
CASESTR(XWSTATE_RECEIVED_ALL_REG); CASESTR(XWSTATE_RECEIVED_ALL_REG);
CASESTR(XWSTATE_NEEDSEND_BADWORD_INFO); CASESTR(XWSTATE_NEEDSEND_BADWORD_INFO);
@ -226,6 +227,7 @@ getStateStr( XW_State st )
CASESTR(XWSTATE_INTURN); CASESTR(XWSTATE_INTURN);
CASESTR(XWSTATE_GAMEOVER); CASESTR(XWSTATE_GAMEOVER);
default: default:
XP_ASSERT(0);
return "unknown"; return "unknown";
} }
# undef CASESTR # undef CASESTR
@ -289,6 +291,10 @@ amServer( const ServerCtxt* server )
return result; return result;
} }
#ifdef DEBUG
XP_Bool server_getIsServer( const ServerCtxt* server ) { return amServer(server); }
#endif
static void static void
initServer( ServerCtxt* server, XWEnv xwe ) initServer( ServerCtxt* server, XWEnv xwe )
{ {
@ -558,6 +564,21 @@ server_writeToStream( const ServerCtxt* server, XWStreamCtxt* stream )
writeStreamIf( stream, server->nv.prevWordsStream ); writeStreamIf( stream, server->nv.prevWordsStream );
} /* server_writeToStream */ } /* server_writeToStream */
void
server_onRoleChanged( ServerCtxt* server, XWEnv xwe, XP_Bool amNowGuest )
{
if ( amNowGuest == amServer(server) ) { /* do I need to change */
XP_ASSERT ( amNowGuest );
if ( amNowGuest ) {
server->vol.gi->serverRole = SERVER_ISCLIENT;
server_reset( server, xwe, server->vol.comms );
SETSTATE( server, XWSTATE_NEWCLIENT );
util_requestTime( server->vol.util, xwe );
}
}
}
static void static void
cleanupServer( ServerCtxt* server, XWEnv xwe ) cleanupServer( ServerCtxt* server, XWEnv xwe )
{ {
@ -1630,6 +1651,12 @@ server_do( ServerCtxt* server, XWEnv xwe )
} }
break; break;
case XWSTATE_NEWCLIENT:
XP_ASSERT( !amServer( server ) );
SETSTATE( server, XWSTATE_NONE ); /* server_initClientConnection expects this */
server_initClientConnection( server, xwe );
break;
case XWSTATE_NEEDSEND_BADWORD_INFO: case XWSTATE_NEEDSEND_BADWORD_INFO:
XP_ASSERT( server->vol.gi->serverRole == SERVER_ISSERVER ); XP_ASSERT( server->vol.gi->serverRole == SERVER_ISSERVER );
badWordMoveUndoAndTellUser( server, xwe, &server->illegalWordInfo ); badWordMoveUndoAndTellUser( server, xwe, &server->illegalWordInfo );

View file

@ -43,6 +43,7 @@ void server_reset( ServerCtxt* server, XWEnv xwe, CommsCtxt* comms );
void server_destroy( ServerCtxt* server, XWEnv xwe ); void server_destroy( ServerCtxt* server, XWEnv xwe );
void server_prefsChanged( ServerCtxt* server, const CommonPrefs* cp ); void server_prefsChanged( ServerCtxt* server, const CommonPrefs* cp );
void server_onRoleChanged( ServerCtxt* server, XWEnv xwe, XP_Bool amNowGuest );
typedef void (*TurnChangeListener)( XWEnv xwe, void* data ); typedef void (*TurnChangeListener)( XWEnv xwe, void* data );
void server_setTurnChangeListener( ServerCtxt* server, TurnChangeListener tl, void server_setTurnChangeListener( ServerCtxt* server, TurnChangeListener tl,
@ -134,6 +135,10 @@ void server_writeFinalScores( ServerCtxt* server, XWEnv xwe, XWStreamCtxt* strea
XP_U16 server_figureFinishBonus( const ServerCtxt* server, XP_U16 turn ); XP_U16 server_figureFinishBonus( const ServerCtxt* server, XP_U16 turn );
#endif #endif
#ifdef DEBUG
XP_Bool server_getIsServer( const ServerCtxt* server );
#endif
#ifdef CPLUS #ifdef CPLUS
} }
#endif #endif

View file

@ -23,7 +23,7 @@
enum { enum {
XWSTATE_NONE, /* 0 */ XWSTATE_NONE, /* 0 */
XWSTATE_BEGIN, /* 1 */ XWSTATE_BEGIN, /* 1 */
__UNUSED1, /* was XWSTATE_POOL_INITED */ XWSTATE_NEWCLIENT, /* was a host, now a reset client */
XWSTATE_NEED_SHOWSCORE, /* client-only */ XWSTATE_NEED_SHOWSCORE, /* client-only */
__XWSTATE_WAITING_ALL_REG, /* 4 (unused) */ __XWSTATE_WAITING_ALL_REG, /* 4 (unused) */
XWSTATE_RECEIVED_ALL_REG, /* includes waiting for dict from server */ XWSTATE_RECEIVED_ALL_REG, /* includes waiting for dict from server */
@ -34,7 +34,7 @@ enum {
XWSTATE_INTURN, /* 10 */ XWSTATE_INTURN, /* 10 */
XWSTATE_GAMEOVER, /* 11 */ XWSTATE_GAMEOVER, /* 11 */
XWSTATE_LAST /* for asserts only :-) */ XWSTATE_LAST, /* for asserts only :-) */
}; };
typedef XP_U8 XW_State; typedef XP_U8 XW_State;
#define XWSTATE_NBITS 4 #define XWSTATE_NBITS 4

View file

@ -171,7 +171,6 @@ typedef struct UtilVtable {
XP_U16 nMissing ); XP_U16 nMissing );
void (*m_util_addrChange)( XW_UtilCtxt* uc, XWEnv xwe, const CommsAddrRec* oldAddr, void (*m_util_addrChange)( XW_UtilCtxt* uc, XWEnv xwe, const CommsAddrRec* oldAddr,
const CommsAddrRec* newAddr ); const CommsAddrRec* newAddr );
void (*m_util_setIsServer)(XW_UtilCtxt* uc, XWEnv xwe, XP_Bool isServer );
#endif #endif
void (*m_util_informWordsBlocked)( XW_UtilCtxt* uc, XWEnv xwe, XP_U16 nBadWords, void (*m_util_informWordsBlocked)( XW_UtilCtxt* uc, XWEnv xwe, XP_U16 nBadWords,
@ -306,8 +305,6 @@ struct XW_UtilCtxt {
(uc)->vtable->m_util_informMissing((uc), (e), (is), (ct), (nd), (nm) ) (uc)->vtable->m_util_informMissing((uc), (e), (is), (ct), (nd), (nm) )
# define util_addrChange( uc,e, addro, addrn ) \ # define util_addrChange( uc,e, addro, addrn ) \
(uc)->vtable->m_util_addrChange((uc), (e), (addro), (addrn)) (uc)->vtable->m_util_addrChange((uc), (e), (addro), (addrn))
# define util_setIsServer( uc,e, is ) \
(uc)->vtable->m_util_setIsServer((uc), (e), (is))
# else # else
# define util_addrChange( uc,e, addro, addrn ) # define util_addrChange( uc,e, addro, addrn )
#endif #endif

View file

@ -1865,36 +1865,6 @@ linux_util_addrChange( XW_UtilCtxt* uc, XWEnv XP_UNUSED(xwe),
} }
} }
static gint
changeRolesIdle( gpointer data )
{
CommonGlobals* cGlobals = (CommonGlobals*)data;
ServerCtxt* server = cGlobals->game.server;
server_reset( server, NULL_XWE, cGlobals->game.comms );
if ( SERVER_ISCLIENT == cGlobals->gi->serverRole ) {
XWStreamCtxt* stream =
mem_stream_make( MPPARM(cGlobals->util->mpool) cGlobals->params->vtMgr,
cGlobals, CHANNEL_NONE, sendOnClose );
(void)server_initClientConnection( server, NULL_XWE, stream );
}
(void)server_do( server, NULL_XWE );
return 0;
}
static void
linux_util_setIsServer( XW_UtilCtxt* uc, XWEnv XP_UNUSED(xwe),XP_Bool isServer )
{
XP_LOGF( "%s(isServer=%d)", __func__, isServer );
CommonGlobals* cGlobals = (CommonGlobals*)uc->closure;
DeviceRole newRole = isServer? SERVER_ISSERVER : SERVER_ISCLIENT;
cGlobals->params->serverRole = newRole;
cGlobals->gi->serverRole = newRole;
(void)ADD_ONETIME_IDLE( changeRolesIdle, cGlobals );
XP_ASSERT( isServer == game_getIsServer( &cGlobals->game ) );
}
#endif #endif
unsigned int unsigned int
@ -2552,7 +2522,6 @@ setupLinuxUtilCallbacks( XW_UtilCtxt* util )
#ifndef XWFEATURE_STANDALONE_ONLY #ifndef XWFEATURE_STANDALONE_ONLY
SET_PROC(informMissing); SET_PROC(informMissing);
SET_PROC(addrChange); SET_PROC(addrChange);
SET_PROC(setIsServer);
#endif #endif
SET_PROC(formatPauseHistory); SET_PROC(formatPauseHistory);
SET_PROC(setTimer); SET_PROC(setTimer);