mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-01-07 05:24:46 +01:00
202 lines
6 KiB
C
202 lines
6 KiB
C
|
/* -*- compile-command: "cd ../linux && make MEMDEBUG=TRUE -j3"; -*- */
|
||
|
/*
|
||
|
* Copyright 2001 - 2020 by Eric House (xwords@eehouse.org). All rights
|
||
|
* reserved.
|
||
|
*
|
||
|
* This program is free software; you can redistribute it and/or
|
||
|
* modify it under the terms of the GNU General Public License
|
||
|
* as published by the Free Software Foundation; either version 2
|
||
|
* of the License, or (at your option) any later version.
|
||
|
*
|
||
|
* This program is distributed in the hope that it will be useful,
|
||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
* GNU General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU General Public License
|
||
|
* along with this program; if not, write to the Free Software
|
||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||
|
*/
|
||
|
|
||
|
#include "knownplyr.h"
|
||
|
#include "strutils.h"
|
||
|
#include "comms.h"
|
||
|
#include "dbgutil.h"
|
||
|
|
||
|
typedef struct _KnownPlayer {
|
||
|
struct _KnownPlayer* next;
|
||
|
XP_UCHAR* name;
|
||
|
CommsAddrRec addr;
|
||
|
} KnownPlayer;
|
||
|
|
||
|
typedef struct _KPState {
|
||
|
KnownPlayer* players;
|
||
|
XP_U16 nPlayers;
|
||
|
XP_Bool dirty;
|
||
|
} KPState;
|
||
|
|
||
|
/* enum { STREAM_VERSION_KP_1, /\* initial *\/ */
|
||
|
/* }; */
|
||
|
|
||
|
static void
|
||
|
addPlayer( XW_DUtilCtxt* dutil, KPState* state,
|
||
|
const XP_UCHAR* name, const CommsAddrRec* addr );
|
||
|
|
||
|
static void
|
||
|
loadFromStream( XW_DUtilCtxt* dutil, KPState* state, XWStreamCtxt* stream )
|
||
|
{
|
||
|
LOG_FUNC();
|
||
|
while ( 0 < stream_getSize( stream ) ) {
|
||
|
XP_UCHAR buf[64];
|
||
|
stringFromStreamHere( stream, buf, VSIZE(buf) );
|
||
|
|
||
|
CommsAddrRec addr = {0};
|
||
|
addrFromStream( &addr, stream );
|
||
|
|
||
|
addPlayer( dutil, state, buf, &addr );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static KPState*
|
||
|
loadState( XW_DUtilCtxt* dutil, XWEnv xwe )
|
||
|
{
|
||
|
LOG_FUNC();
|
||
|
KPState* state = (KPState*)dutil->kpCtxt;
|
||
|
if ( NULL == state ) {
|
||
|
dutil->kpCtxt = state = XP_CALLOC( dutil->mpool, sizeof(*state) );
|
||
|
XWStreamCtxt* stream = mem_stream_make_raw( MPPARM(dutil->mpool)
|
||
|
dutil_getVTManager(dutil) );
|
||
|
dutil_loadStream( dutil, xwe, KNOWN_PLAYERS_KEY, NULL, stream );
|
||
|
if ( 0 < stream_getSize( stream ) ) {
|
||
|
XP_U8 vers = stream_getU8( stream );
|
||
|
stream_setVersion( stream, vers );
|
||
|
loadFromStream( dutil, state, stream );
|
||
|
}
|
||
|
|
||
|
stream_destroy( stream, xwe );
|
||
|
}
|
||
|
return state;
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
saveState( XW_DUtilCtxt* dutil, XWEnv xwe, KPState* state )
|
||
|
{
|
||
|
if ( state->dirty ) {
|
||
|
XWStreamCtxt* stream = mem_stream_make_raw( MPPARM(dutil->mpool)
|
||
|
dutil_getVTManager(dutil) );
|
||
|
stream_putU8( stream, CUR_STREAM_VERS );
|
||
|
for ( KnownPlayer* kp = state->players; !!kp; kp = kp->next ) {
|
||
|
stringToStream( stream, kp->name );
|
||
|
addrToStream( stream, &kp->addr );
|
||
|
}
|
||
|
dutil_storeStream( dutil, xwe, KNOWN_PLAYERS_KEY, stream );
|
||
|
stream_destroy( stream, xwe );
|
||
|
state->dirty = XP_FALSE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static const XP_UCHAR*
|
||
|
figureNameFor( XP_U16 posn, const CurGameInfo* gi )
|
||
|
{
|
||
|
const XP_UCHAR* result = NULL;
|
||
|
// int nthRemote = 0;
|
||
|
for ( int ii = 0, nthRemote = 0;
|
||
|
NULL == result && ii < gi->nPlayers;
|
||
|
++ii ) {
|
||
|
const LocalPlayer* lp = &gi->players[ii];
|
||
|
if ( lp->isLocal ) {
|
||
|
continue;
|
||
|
} else if ( nthRemote++ == posn ) {
|
||
|
result = lp->name;
|
||
|
}
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
addPlayer( XW_DUtilCtxt* dutil, KPState* state,
|
||
|
const XP_UCHAR* name, const CommsAddrRec* addr )
|
||
|
{
|
||
|
XP_LOGFF( "(name=%s)", name );
|
||
|
XP_Bool exists = XP_FALSE;
|
||
|
for ( KnownPlayer* kp = state->players; !!kp && !exists; kp = kp->next ) {
|
||
|
exists = 0 == XP_STRCMP( kp->name, name );
|
||
|
}
|
||
|
if ( !exists ) {
|
||
|
XP_LOGFF( "adding new player!" );
|
||
|
KnownPlayer* newPlayer = XP_CALLOC( dutil->mpool, sizeof(*newPlayer) );
|
||
|
newPlayer->name = copyString( dutil->mpool, name );
|
||
|
newPlayer->addr = *addr;
|
||
|
newPlayer->next = state->players;
|
||
|
state->players = newPlayer;
|
||
|
state->dirty = XP_TRUE;
|
||
|
++state->nPlayers;
|
||
|
}
|
||
|
XP_LOGFF( "nPlayers now: %d", state->nPlayers );
|
||
|
}
|
||
|
|
||
|
XP_Bool
|
||
|
kplr_addAddrs( XW_DUtilCtxt* dutil, XWEnv xwe, const CurGameInfo* gi,
|
||
|
CommsAddrRec addrs[], XP_U16 nAddrs )
|
||
|
{
|
||
|
LOG_FUNC();
|
||
|
XP_Bool canUse = XP_TRUE;
|
||
|
for ( int ii = 0; ii < nAddrs && canUse; ++ii ) {
|
||
|
canUse = addr_hasType( &addrs[ii], COMMS_CONN_MQTT );
|
||
|
if ( !canUse ) {
|
||
|
XP_LOGFF( "addr %d has no mqqt id", ii );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( canUse ) {
|
||
|
KPState* state = loadState( dutil, xwe );
|
||
|
for ( int ii = 0; ii < nAddrs && canUse; ++ii ) {
|
||
|
const XP_UCHAR* name = figureNameFor( ii, gi );
|
||
|
if ( !!name ) {
|
||
|
addPlayer( dutil, state, name, &addrs[ii] );
|
||
|
} else {
|
||
|
XP_LOGFF( "unable to find %dth name", ii );
|
||
|
}
|
||
|
}
|
||
|
saveState( dutil, xwe, state );
|
||
|
}
|
||
|
|
||
|
return canUse;
|
||
|
}
|
||
|
|
||
|
XP_Bool
|
||
|
kplr_havePlayers( XW_DUtilCtxt* dutil, XWEnv xwe )
|
||
|
{
|
||
|
KPState* state = loadState( dutil, xwe );
|
||
|
XP_Bool result = 0 < state->nPlayers;
|
||
|
LOG_RETURNF( "%s", boolToStr(result) );
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
kplr_getPlayers( XW_DUtilCtxt* dutil, XWEnv xwe,
|
||
|
const XP_UCHAR** players, XP_U16* nFound )
|
||
|
{
|
||
|
KPState* state = loadState( dutil, xwe );
|
||
|
if ( state->nPlayers <= *nFound && !!players ) {
|
||
|
XP_U16 ii = 0;
|
||
|
for ( KnownPlayer* kp = state->players; !!kp; kp = kp->next ) {
|
||
|
players[ii++] = kp->name;
|
||
|
}
|
||
|
}
|
||
|
*nFound = state->nPlayers;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
kplr_cleanup( XW_DUtilCtxt* dutil )
|
||
|
{
|
||
|
KPState** state = (KPState**)&dutil->kpCtxt;
|
||
|
if ( !!*state ) {
|
||
|
for ( KnownPlayer* kp = (*state)->players; !!kp; kp = kp->next ) {
|
||
|
XP_FREEP( dutil->mpool, &kp->name );
|
||
|
XP_FREE( dutil->mpool, kp );
|
||
|
}
|
||
|
XP_FREEP( dutil->mpool, state );
|
||
|
}
|
||
|
}
|