first of a set of changes to communicate to clients dictionary being

used by server.  Clients need to care if e.g. the server's disallowing
phonies based on its dict.  Can only be sent if client is of latest
version.  In that case, common code calls into new util function.  In
future changes, BoardActivity's implemention of the callback will need
to check if the server's choice of dict is available, and if not offer
to download it.  Once it's available, will want to install it.
This commit is contained in:
Eric House 2012-09-03 21:29:21 -07:00
parent d12ed144ea
commit b7a0f1489b
15 changed files with 206 additions and 27 deletions

View file

@ -268,6 +268,28 @@ and_util_informUndo( XW_UtilCtxt* uc )
UTIL_CBK_TAIL(); UTIL_CBK_TAIL();
} }
static void
and_util_informNetDict( XW_UtilCtxt* uc, const XP_UCHAR* oldName,
const XP_UCHAR* newName,
XWPhoniesChoice phoniesAction )
{
LOG_FUNC();
UTIL_CBK_HEADER( "informNetDict",
"(Ljava/lang/String;Ljava/lang/String;L"
PKG_PATH("jni/CurGameInfo$XWPhoniesChoice") ";)V" );
jstring jnew = (*env)->NewStringUTF( env, newName );
jstring jold = (*env)->NewStringUTF( env, oldName );
jobject jphon = intToJEnum( env, phoniesAction,
PKG_PATH("jni/CurGameInfo$XWPhoniesChoice") );
(*env)->CallVoidMethod( env, util->jutil, mid, jold, jnew, jphon );
(*env)->DeleteLocalRef( env, jnew );
(*env)->DeleteLocalRef( env, jold );
(*env)->DeleteLocalRef( env, jphon );
UTIL_CBK_TAIL();
}
static void static void
and_util_notifyGameOver( XW_UtilCtxt* uc ) and_util_notifyGameOver( XW_UtilCtxt* uc )
{ {
@ -585,6 +607,7 @@ makeUtil( MPFORMAL JNIEnv** envp, jobject jutil, CurGameInfo* gi,
#endif #endif
SET_PROC(informMove); SET_PROC(informMove);
SET_PROC(informUndo); SET_PROC(informUndo);
SET_PROC(informNetDict);
SET_PROC(notifyGameOver); SET_PROC(notifyGameOver);
SET_PROC(hiliteCell); SET_PROC(hiliteCell);
SET_PROC(engineProgressCallback); SET_PROC(engineProgressCallback);

View file

@ -1472,6 +1472,14 @@ public class BoardActivity extends XWActivity
nonBlockingDialog( DLG_OKONLY, getString( R.string.remote_undone ) ); nonBlockingDialog( DLG_OKONLY, getString( R.string.remote_undone ) );
} }
@Override
public void informNetDict( String oldName, String newName,
CurGameInfo.XWPhoniesChoice phonies )
{
DbgUtils.logf( "informNetDict(%s, %s, %s)", oldName, newName,
phonies.toString() );
}
@Override @Override
public void notifyGameOver() public void notifyGameOver()
{ {

View file

@ -116,6 +116,9 @@ public interface UtilCtxt {
void informMove( String expl, String words ); void informMove( String expl, String words );
void informUndo(); void informUndo();
void informNetDict( String oldName, String newName,
CurGameInfo.XWPhoniesChoice phonies );
void informMissing( boolean isServer, CommsAddrRec.CommsConnType connType, void informMissing( boolean isServer, CommsAddrRec.CommsConnType connType,
int nMissingPlayers ); int nMissingPlayers );

View file

@ -222,6 +222,12 @@ public class UtilCtxtImpl implements UtilCtxt {
subclassOverride( "informUndo" ); subclassOverride( "informUndo" );
} }
public void informNetDict( String oldName, String newName,
CurGameInfo.XWPhoniesChoice phonies )
{
subclassOverride( "informNetDict" );
}
public void informMissing( boolean isServer, public void informMissing( boolean isServer,
CommsAddrRec.CommsConnType connType, CommsAddrRec.CommsConnType connType,
int nMissingPlayers ) int nMissingPlayers )

View file

@ -47,6 +47,7 @@
#endif #endif
#define MAX_COLS MAX_ROWS #define MAX_COLS MAX_ROWS
#define STREAM_VERS_DICTNAME 0x15
#ifdef HASH_STREAM #ifdef HASH_STREAM
# define STREAM_VERS_HASHSTREAM 0x14 # define STREAM_VERS_HASHSTREAM 0x14
#endif #endif
@ -81,13 +82,7 @@
#define STREAM_VERS_41B4 0x02 #define STREAM_VERS_41B4 0x02
#define STREAM_VERS_405 0x01 #define STREAM_VERS_405 0x01
#ifdef STREAM_VERS_HASHSTREAM #define CUR_STREAM_VERS STREAM_VERS_DICTNAME
# define CUR_STREAM_VERS STREAM_VERS_HASHSTREAM
#elif MAX_COLS > 16
# define CUR_STREAM_VERS STREAM_VERS_BIGBOARD
#else
# define CUR_STREAM_VERS STREAM_VERS_BLUETOOTH2
#endif
typedef struct XP_Rect { typedef struct XP_Rect {
XP_S16 left; XP_S16 left;

View file

@ -1231,8 +1231,6 @@ client_readInitialMessage( ServerCtxt* server, XWStreamCtxt* stream )
gi_readFromStream( MPPARM(server->mpool) stream, &localGI ); gi_readFromStream( MPPARM(server->mpool) stream, &localGI );
localGI.serverRole = SERVER_ISCLIENT; localGI.serverRole = SERVER_ISCLIENT;
/* so it's not lost (HACK!). Without this, a client won't have a default
dict name when a new game is started. */
localGI.dictName = copyString( server->mpool, gi->dictName ); localGI.dictName = copyString( server->mpool, gi->dictName );
gi_copy( MPPARM(server->mpool) gi, &localGI ); gi_copy( MPPARM(server->mpool) gi, &localGI );
@ -1241,6 +1239,17 @@ client_readInitialMessage( ServerCtxt* server, XWStreamCtxt* stream )
newDict = util_makeEmptyDict( server->vol.util ); newDict = util_makeEmptyDict( server->vol.util );
dict_loadFromStream( newDict, stream ); dict_loadFromStream( newDict, stream );
#ifdef STREAM_VERS_BIGBOARD
if ( STREAM_VERS_DICTNAME <= streamVersion ) {
XP_UCHAR buf[128];
stringFromStreamHere( stream, buf, VSIZE(buf) );
if ( 0 != XP_STRCMP( buf, gi->dictName ) ) {
util_informNetDict( server->vol.util, gi->dictName, buf,
localGI.phoniesAction );
}
}
#endif
channelNo = stream_getAddress( stream ); channelNo = stream_getAddress( stream );
XP_ASSERT( channelNo != 0 ); XP_ASSERT( channelNo != 0 );
server->nv.addresses[0].channelNo = channelNo; server->nv.addresses[0].channelNo = channelNo;
@ -1373,7 +1382,11 @@ server_sendInitialMessage( ServerCtxt* server )
gi_writeToStream( stream, &localGI ); gi_writeToStream( stream, &localGI );
dict_writeToStream( dict, stream ); dict_writeToStream( dict, stream );
#ifdef STREAM_VERS_BIGBOARD
if ( STREAM_VERS_DICTNAME <= addr->streamVersion ) {
stringToStream( stream, dict_getShortName(dict) );
}
#endif
/* send tiles currently in tray */ /* send tiles currently in tray */
for ( ii = 0; ii < nPlayers; ++ii ) { for ( ii = 0; ii < nPlayers; ++ii ) {
model_trayToStream( model, ii, stream ); model_trayToStream( model, ii, stream );

View file

@ -129,6 +129,10 @@ typedef struct UtilVtable {
void (*m_util_informMove)( XW_UtilCtxt* uc, XWStreamCtxt* expl, void (*m_util_informMove)( XW_UtilCtxt* uc, XWStreamCtxt* expl,
XWStreamCtxt* words ); XWStreamCtxt* words );
void (*m_util_informUndo)( XW_UtilCtxt* uc ); void (*m_util_informUndo)( XW_UtilCtxt* uc );
void (*m_util_informNetDict)( XW_UtilCtxt* uc, const XP_UCHAR* oldName,
const XP_UCHAR* newName,
XWPhoniesChoice phoniesAction );
void (*m_util_notifyGameOver)( XW_UtilCtxt* uc ); void (*m_util_notifyGameOver)( XW_UtilCtxt* uc );
XP_Bool (*m_util_hiliteCell)( XW_UtilCtxt* uc, XP_U16 col, XP_U16 row ); XP_Bool (*m_util_hiliteCell)( XW_UtilCtxt* uc, XP_U16 col, XP_U16 row );
@ -244,6 +248,8 @@ struct XW_UtilCtxt {
(uc)->vtable->m_util_informMove( (uc),(e),(w)) (uc)->vtable->m_util_informMove( (uc),(e),(w))
#define util_informUndo(uc) \ #define util_informUndo(uc) \
(uc)->vtable->m_util_informUndo( (uc)) (uc)->vtable->m_util_informUndo( (uc))
#define util_informNetDict(uc, on, nn, pa ) \
(uc)->vtable->m_util_informNetDict( (uc), (on), (nn), (pa) )
#define util_notifyGameOver( uc ) \ #define util_notifyGameOver( uc ) \
(uc)->vtable->m_util_notifyGameOver((uc)) (uc)->vtable->m_util_notifyGameOver((uc))

View file

@ -394,6 +394,16 @@ curses_util_notifyGameOver( XW_UtilCtxt* uc )
} }
} /* curses_util_notifyGameOver */ } /* curses_util_notifyGameOver */
static void
curses_util_informNetDict( XW_UtilCtxt* uc, const XP_UCHAR* oldName,
const XP_UCHAR* newName,
XWPhoniesChoice phoniesAction )
{
XP_USE(uc);
XP_USE(phoniesAction);
XP_LOGF( "%s: %s => %s", __func__, oldName, newName );
}
static XP_Bool static XP_Bool
curses_util_hiliteCell( XW_UtilCtxt* uc, curses_util_hiliteCell( XW_UtilCtxt* uc,
XP_U16 XP_UNUSED(col), XP_U16 XP_UNUSED(row) ) XP_U16 XP_UNUSED(col), XP_U16 XP_UNUSED(row) )
@ -1516,6 +1526,7 @@ setupCursesUtilCallbacks( CursesAppGlobals* globals, XW_UtilCtxt* util )
util->vtable->m_util_informMove = curses_util_informMove; util->vtable->m_util_informMove = curses_util_informMove;
util->vtable->m_util_informUndo = curses_util_informUndo; util->vtable->m_util_informUndo = curses_util_informUndo;
util->vtable->m_util_notifyGameOver = curses_util_notifyGameOver; util->vtable->m_util_notifyGameOver = curses_util_notifyGameOver;
util->vtable->m_util_informNetDict = curses_util_informNetDict;
util->vtable->m_util_hiliteCell = curses_util_hiliteCell; util->vtable->m_util_hiliteCell = curses_util_hiliteCell;
util->vtable->m_util_engineProgressCallback = util->vtable->m_util_engineProgressCallback =
curses_util_engineProgressCallback; curses_util_engineProgressCallback;

View file

@ -1468,6 +1468,23 @@ gtk_util_notifyGameOver( XW_UtilCtxt* uc )
} }
} /* gtk_util_notifyGameOver */ } /* gtk_util_notifyGameOver */
static void
gtk_util_informNetDict( XW_UtilCtxt* uc, const XP_UCHAR* oldName,
const XP_UCHAR* newName,
XWPhoniesChoice phoniesAction )
{
GtkAppGlobals* globals = (GtkAppGlobals*)uc->closure;
gchar buf[512];
int offset = snprintf( buf, VSIZE(buf), "dict changing from %s to %s.",
oldName, newName );
if ( PHONIES_DISALLOW == phoniesAction ) {
snprintf( &buf[offset], VSIZE(buf)-offset, "%s",
"\nPHONIES_DISALLOW is set so this may lead to some surprises." );
}
(void)gtkask( globals->window, buf, GTK_BUTTONS_OK );
}
/* define this to prevent user events during debugging from stopping the engine */ /* define this to prevent user events during debugging from stopping the engine */
/* #define DONT_ABORT_ENGINE */ /* #define DONT_ABORT_ENGINE */
@ -1993,6 +2010,7 @@ setupGtkUtilCallbacks( GtkAppGlobals* globals, XW_UtilCtxt* util )
util->vtable->m_util_informMove = gtk_util_informMove; util->vtable->m_util_informMove = gtk_util_informMove;
util->vtable->m_util_informUndo = gtk_util_informUndo; util->vtable->m_util_informUndo = gtk_util_informUndo;
util->vtable->m_util_notifyGameOver = gtk_util_notifyGameOver; util->vtable->m_util_notifyGameOver = gtk_util_notifyGameOver;
util->vtable->m_util_informNetDict = gtk_util_informNetDict;
util->vtable->m_util_hiliteCell = gtk_util_hiliteCell; util->vtable->m_util_hiliteCell = gtk_util_hiliteCell;
util->vtable->m_util_altKeyDown = gtk_util_altKeyDown; util->vtable->m_util_altKeyDown = gtk_util_altKeyDown;
util->vtable->m_util_engineProgressCallback = util->vtable->m_util_engineProgressCallback =

View file

@ -49,6 +49,7 @@ typedef struct LinuxDictionaryCtxt {
/************************ Prototypes ***********************/ /************************ Prototypes ***********************/
static XP_Bool initFromDictFile( LinuxDictionaryCtxt* dctx, static XP_Bool initFromDictFile( LinuxDictionaryCtxt* dctx,
const LaunchParams* params,
const char* fileName ); const char* fileName );
static void linux_dictionary_destroy( DictionaryCtxt* dict ); static void linux_dictionary_destroy( DictionaryCtxt* dict );
static const XP_UCHAR* linux_dict_getShortName( const DictionaryCtxt* dict ); static const XP_UCHAR* linux_dict_getShortName( const DictionaryCtxt* dict );
@ -57,7 +58,8 @@ static const XP_UCHAR* linux_dict_getShortName( const DictionaryCtxt* dict );
* *
****************************************************************************/ ****************************************************************************/
DictionaryCtxt* DictionaryCtxt*
linux_dictionary_make( MPFORMAL const char* dictFileName, XP_Bool useMMap ) linux_dictionary_make( MPFORMAL const LaunchParams* params,
const char* dictFileName, XP_Bool useMMap )
{ {
LinuxDictionaryCtxt* result = LinuxDictionaryCtxt* result =
(LinuxDictionaryCtxt*)XP_MALLOC(mpool, sizeof(*result)); (LinuxDictionaryCtxt*)XP_MALLOC(mpool, sizeof(*result));
@ -69,7 +71,7 @@ linux_dictionary_make( MPFORMAL const char* dictFileName, XP_Bool useMMap )
result->useMMap = useMMap; result->useMMap = useMMap;
if ( !!dictFileName ) { if ( !!dictFileName ) {
XP_Bool success = initFromDictFile( result, dictFileName ); XP_Bool success = initFromDictFile( result, params, dictFileName );
if ( success ) { if ( success ) {
result->super.destructor = linux_dictionary_destroy; result->super.destructor = linux_dictionary_destroy;
result->super.func_dict_getShortName = linux_dict_getShortName; result->super.func_dict_getShortName = linux_dict_getShortName;
@ -205,7 +207,8 @@ dict_splitFaces( DictionaryCtxt* dict, const XP_U8* utf8,
} /* dict_splitFaces */ } /* dict_splitFaces */
static XP_Bool static XP_Bool
initFromDictFile( LinuxDictionaryCtxt* dctx, const char* fileName ) initFromDictFile( LinuxDictionaryCtxt* dctx, const LaunchParams* params,
const char* fileName )
{ {
XP_Bool formatOk = XP_TRUE; XP_Bool formatOk = XP_TRUE;
long curPos, dictLength; long curPos, dictLength;
@ -217,15 +220,20 @@ initFromDictFile( LinuxDictionaryCtxt* dctx, const char* fileName )
XP_Bool isUTF8 = XP_FALSE; XP_Bool isUTF8 = XP_FALSE;
XP_Bool hasHeader = XP_FALSE; XP_Bool hasHeader = XP_FALSE;
const XP_U8* ptr; const XP_U8* ptr;
char path[256];
if ( !getDictPath( params, fileName, path, VSIZE(path) ) ) {
XP_LOGF( "%s: path=%s", __func__, path );
goto closeAndExit;
}
struct stat statbuf; struct stat statbuf;
if ( 0 != stat( fileName, &statbuf ) || 0 == statbuf.st_size ) { if ( 0 != stat( path, &statbuf ) || 0 == statbuf.st_size ) {
goto closeAndExit; goto closeAndExit;
} }
dctx->dictLength = statbuf.st_size; dctx->dictLength = statbuf.st_size;
{ {
FILE* dictF = fopen( fileName, "r" ); FILE* dictF = fopen( path, "r" );
XP_ASSERT( !!dictF ); XP_ASSERT( !!dictF );
if ( dctx->useMMap ) { if ( dctx->useMMap ) {
dctx->dictBase = mmap( NULL, dctx->dictLength, PROT_READ, dctx->dictBase = mmap( NULL, dctx->dictLength, PROT_READ,

View file

@ -18,11 +18,13 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <getopt.h> #include <getopt.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <locale.h> #include <locale.h>
#include <string.h>
#include <netdb.h> /* gethostbyname */ #include <netdb.h> /* gethostbyname */
#include <errno.h> #include <errno.h>
@ -74,11 +76,12 @@
#define DEFAULT_LISTEN_PORT 4998 #define DEFAULT_LISTEN_PORT 4998
XP_Bool XP_Bool
file_exists( const char* fileName ) file_exists( const char* fileName )
{ {
struct stat statBuf; struct stat statBuf;
int statResult = stat( fileName, &statBuf ); int statResult = stat( fileName, &statBuf );
XP_LOGF( "%s(%s)=>%d", __func__, fileName, statResult == 0 );
return statResult == 0; return statResult == 0;
} /* file_exists */ } /* file_exists */
@ -454,6 +457,7 @@ typedef enum {
,CMD_TESTPRFX ,CMD_TESTPRFX
,CMD_TESTMINMAX ,CMD_TESTMINMAX
#endif #endif
,CMD_DICTDIR
,CMD_PLAYERDICT ,CMD_PLAYERDICT
,CMD_SEED ,CMD_SEED
,CMD_GAMESEED ,CMD_GAMESEED
@ -545,6 +549,7 @@ static CmdInfoRec CmdInfoRecs[] = {
,{ CMD_TESTPRFX, true, "test-prefix", "list first word starting with this" } ,{ CMD_TESTPRFX, true, "test-prefix", "list first word starting with this" }
,{ CMD_TESTMINMAX, true, "test-minmax", "M:M -- include only words whose len in range" } ,{ CMD_TESTMINMAX, true, "test-minmax", "M:M -- include only words whose len in range" }
#endif #endif
,{ CMD_DICTDIR, true, "dict-dir", "path to dir in which dicts will be sought" }
,{ CMD_PLAYERDICT, true, "player-dict", "dictionary name for player (in sequence)" } ,{ CMD_PLAYERDICT, true, "player-dict", "dictionary name for player (in sequence)" }
,{ CMD_SEED, true, "seed", "random seed" } ,{ CMD_SEED, true, "seed", "random seed" }
,{ CMD_GAMESEED, true, "game-seed", "game seed (for relay play)" } ,{ CMD_GAMESEED, true, "game-seed", "game seed (for relay play)" }
@ -1345,7 +1350,7 @@ walk_dict_test_all( const LaunchParams* params, GSList* testDicts,
for ( ii = 0; ii < count; ++ii ) { for ( ii = 0; ii < count; ++ii ) {
gchar* name = (gchar*)g_slist_nth_data( testDicts, ii ); gchar* name = (gchar*)g_slist_nth_data( testDicts, ii );
DictionaryCtxt* dict = DictionaryCtxt* dict =
linux_dictionary_make( MPPARM(params->util->mpool) name, linux_dictionary_make( MPPARM(params->util->mpool) params, name,
params->useMmap ); params->useMmap );
if ( NULL != dict ) { if ( NULL != dict ) {
XP_LOGF( "walk_dict_test(%s)", name ); XP_LOGF( "walk_dict_test(%s)", name );
@ -1356,6 +1361,55 @@ walk_dict_test_all( const LaunchParams* params, GSList* testDicts,
} }
#endif #endif
static void
trimDictPath( const char* input, char* buf, int bufsiz, char** path, char** dict )
{
struct stat statBuf;
int statResult = stat( input, &statBuf );
if ( 0 == statResult && S_ISLNK(statBuf.st_mode) ) {
ssize_t nWritten = readlink( input, buf, bufsiz );
buf[nWritten] = '\0';
} else {
snprintf( buf, bufsiz, "%s", input );
}
char* result = strrchr( buf, '/' );
if ( !!result ) { /* is is a full path */
*path = buf;
*result = '\0'; /* null-terminate it */
*dict = 1 + result;
} else {
*path = NULL;
*dict = buf;
}
char* dot = strrchr( *dict, '.' );
if ( !!dot && 0 == strcmp(dot, ".xwd") ) {
*dot = '\0';
}
XP_LOGF( "%s=> dict: %s; path: %s", __func__, *dict, *path );
}
XP_Bool
getDictPath( const LaunchParams *params, const char* name,
char* result, int resultLen )
{
XP_Bool success = XP_FALSE;
GSList* dictDirs;
result[0] = '\0';
for ( dictDirs = params->dictDirs; !!dictDirs; dictDirs = dictDirs->next ) {
const char* path = dictDirs->data;
char buf[256];
int len = snprintf( buf, VSIZE(buf), "%s/%s.xwd", path, name );
if ( len < VSIZE(buf) && file_exists( buf ) ) {
snprintf( result, resultLen, "%s", buf );
success = XP_TRUE;
break;
}
}
LOG_RETURNF( "%d", success );
return success;
}
int int
main( int argc, char** argv ) main( int argc, char** argv )
{ {
@ -1376,6 +1430,9 @@ main( int argc, char** argv )
GSList* testPrefixes = NULL; GSList* testPrefixes = NULL;
char* testMinMax = NULL; char* testMinMax = NULL;
#endif #endif
char dictbuf[256];
char* dict;
char* path;
/* install a no-op signal handler. Later curses- or gtk-specific code /* install a no-op signal handler. Later curses- or gtk-specific code
will install one that does the right thing in that context */ will install one that does the right thing in that context */
@ -1450,6 +1507,19 @@ main( int argc, char** argv )
mainParams.showRobotScores = XP_FALSE; mainParams.showRobotScores = XP_FALSE;
mainParams.useMmap = XP_TRUE; mainParams.useMmap = XP_TRUE;
char* envDictPath = getenv( "XW_DICTSPATH" );
if ( !!envDictPath ) {
char *saveptr;
for ( ; ; ) {
char* path = strtok_r( envDictPath, ":", &saveptr );
if ( !path ) {
break;
}
mainParams.dictDirs = g_slist_append( mainParams.dictDirs, path );
envDictPath = NULL;
}
}
/* serverName = mainParams.info.clientInfo.serverName = "localhost"; */ /* serverName = mainParams.info.clientInfo.serverName = "localhost"; */
#if defined PLATFORM_GTK #if defined PLATFORM_GTK
@ -1489,8 +1559,12 @@ main( int argc, char** argv )
conType = COMMS_CONN_IP_DIRECT; conType = COMMS_CONN_IP_DIRECT;
break; break;
case CMD_DICT: case CMD_DICT:
mainParams.gi.dictName = copyString( mainParams.util->mpool, trimDictPath( optarg, dictbuf, VSIZE(dictbuf), &path, &dict );
(XP_UCHAR*)optarg ); mainParams.gi.dictName = copyString( mainParams.util->mpool, dict );
if ( !path ) {
path = ".";
}
mainParams.dictDirs = g_slist_append( mainParams.dictDirs, path );
break; break;
#ifdef XWFEATURE_WALKDICT #ifdef XWFEATURE_WALKDICT
case CMD_TESTDICT: case CMD_TESTDICT:
@ -1503,8 +1577,16 @@ main( int argc, char** argv )
testMinMax = optarg; testMinMax = optarg;
break; break;
#endif #endif
case CMD_DICTDIR:
mainParams.dictDirs = g_slist_append( mainParams.dictDirs, optarg );
break;
case CMD_PLAYERDICT: case CMD_PLAYERDICT:
mainParams.playerDictNames[nPlayerDicts++] = optarg; trimDictPath( optarg, dictbuf, VSIZE(dictbuf), &path, &dict );
mainParams.playerDictNames[nPlayerDicts++] = dict;
if ( !path ) {
path = ".";
}
mainParams.dictDirs = g_slist_append( mainParams.dictDirs, path );
break; break;
case CMD_SEED: case CMD_SEED:
seed = atoi(optarg); seed = atoi(optarg);
@ -1757,9 +1839,11 @@ main( int argc, char** argv )
} }
if ( !!mainParams.gi.dictName ) { if ( !!mainParams.gi.dictName ) {
/* char path[256]; */
/* getDictPath( &mainParams, mainParams.gi.dictName, path, VSIZE(path) ); */
mainParams.dict = mainParams.dict =
linux_dictionary_make( MPPARM(mainParams.util->mpool) linux_dictionary_make( MPPARM(mainParams.util->mpool) &mainParams,
mainParams.gi.dictName, mainParams.gi.dictName,
mainParams.useMmap ); mainParams.useMmap );
XP_ASSERT( !!mainParams.dict ); XP_ASSERT( !!mainParams.dict );
mainParams.gi.dictLang = dict_getLangCode( mainParams.dict ); mainParams.gi.dictLang = dict_getLangCode( mainParams.dict );
@ -1787,8 +1871,8 @@ main( int argc, char** argv )
const XP_UCHAR* name = mainParams.playerDictNames[ii]; const XP_UCHAR* name = mainParams.playerDictNames[ii];
if ( !!name ) { if ( !!name ) {
mainParams.dicts.dicts[ii] = mainParams.dicts.dicts[ii] =
linux_dictionary_make( MPPARM(mainParams.util->mpool) name, linux_dictionary_make( MPPARM(mainParams.util->mpool)
mainParams.useMmap ); &mainParams, name, mainParams.useMmap );
} }
} }

View file

@ -66,6 +66,8 @@ XWStreamCtxt* streamFromFile( CommonGlobals* cGlobals, char* name,
void* closure ); void* closure );
XWStreamCtxt* streamFromDB( CommonGlobals* cGlobals, void* closure ); XWStreamCtxt* streamFromDB( CommonGlobals* cGlobals, void* closure );
void writeToFile( XWStreamCtxt* stream, void* closure ); void writeToFile( XWStreamCtxt* stream, void* closure );
XP_Bool getDictPath( const LaunchParams *params, const char* name,
char* result, int resultLen );
int blocking_read( int fd, unsigned char* buf, int len ); int blocking_read( int fd, unsigned char* buf, int len );

View file

@ -89,7 +89,7 @@ static DictionaryCtxt*
linux_util_makeEmptyDict( XW_UtilCtxt* XP_UNUSED_DBG(uctx) ) linux_util_makeEmptyDict( XW_UtilCtxt* XP_UNUSED_DBG(uctx) )
{ {
XP_DEBUGF( "linux_util_makeEmptyDict called" ); XP_DEBUGF( "linux_util_makeEmptyDict called" );
return linux_dictionary_make( MPPARM(uctx->mpool) NULL, XP_FALSE ); return linux_dictionary_make( MPPARM(uctx->mpool) NULL, NULL, XP_FALSE );
} /* linux_util_makeEmptyDict */ } /* linux_util_makeEmptyDict */
#define EM BONUS_NONE #define EM BONUS_NONE
@ -350,7 +350,6 @@ linux_util_vt_init( MPFORMAL XW_UtilCtxt* util )
util->vtable->m_util_getSquareBonus = linux_util_getSquareBonus; util->vtable->m_util_getSquareBonus = linux_util_getSquareBonus;
util->vtable->m_util_getCurSeconds = linux_util_getCurSeconds; util->vtable->m_util_getCurSeconds = linux_util_getCurSeconds;
util->vtable->m_util_getUserString = linux_util_getUserString; util->vtable->m_util_getUserString = linux_util_getUserString;
} }
void void

View file

@ -32,7 +32,9 @@ void linux_debugf(const char*, ...)
__attribute__ ((format (printf, 1, 2))); __attribute__ ((format (printf, 1, 2)));
#endif #endif
DictionaryCtxt* linux_dictionary_make( MPFORMAL const char* dictFileName, XP_Bool useMmap ); DictionaryCtxt* linux_dictionary_make( MPFORMAL const LaunchParams* mainParams,
const char* dictFileName, XP_Bool useMMap );
void linux_util_vt_init( MPFORMAL XW_UtilCtxt* util ); void linux_util_vt_init( MPFORMAL XW_UtilCtxt* util );
void linux_util_vt_destroy( XW_UtilCtxt* util ); void linux_util_vt_destroy( XW_UtilCtxt* util );

View file

@ -48,6 +48,7 @@ typedef struct LaunchParams {
DictionaryCtxt* dict; DictionaryCtxt* dict;
CurGameInfo gi; CurGameInfo gi;
PlayerDicts dicts; PlayerDicts dicts;
GSList* dictDirs;
char* fileName; char* fileName;
const XP_UCHAR* playerDictNames[MAX_NUM_PLAYERS]; const XP_UCHAR* playerDictNames[MAX_NUM_PLAYERS];
#ifdef USE_SQLITE #ifdef USE_SQLITE