mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2024-12-30 10:26:58 +01:00
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:
parent
d12ed144ea
commit
b7a0f1489b
15 changed files with 206 additions and 27 deletions
|
@ -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);
|
||||||
|
|
|
@ -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()
|
||||||
{
|
{
|
||||||
|
|
|
@ -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 );
|
||||||
|
|
||||||
|
|
|
@ -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 )
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 );
|
||||||
|
|
|
@ -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))
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 =
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 );
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 );
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue