mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-02-05 20:45:49 +01:00
download wordlists when needed for invitation
This commit is contained in:
parent
3c0edb3531
commit
4f524d0bb0
7 changed files with 153 additions and 33 deletions
|
@ -110,8 +110,21 @@ static void saveName( GameState* gs );
|
||||||
static bool isVisible( GameState* gs );
|
static bool isVisible( GameState* gs );
|
||||||
static int countDicts( Globals* globals );
|
static int countDicts( Globals* globals );
|
||||||
|
|
||||||
EM_JS(void, call_get_dict, (void* closure), {
|
typedef void (*GotDictProc)(void* closure, const char* lc, const char* name,
|
||||||
getDict(closure);
|
uint8_t* data, int len);
|
||||||
|
|
||||||
|
EM_JS(void, call_get_dict, (const char* lc, GotDictProc proc,
|
||||||
|
void* closure), {
|
||||||
|
let langs;
|
||||||
|
if (lc) {
|
||||||
|
langs = [UTF8ToString(lc)];
|
||||||
|
} else {
|
||||||
|
langs = [navigator.language.split('-')[0]];
|
||||||
|
if (langs[0] != 'en') {
|
||||||
|
langs.push('en');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
getDict(langs, proc, closure);
|
||||||
});
|
});
|
||||||
|
|
||||||
EM_JS(void, show_name, (const char* name), {
|
EM_JS(void, show_name, (const char* name), {
|
||||||
|
@ -315,7 +328,6 @@ sendInviteTo(GameState* gs, const MQTTDevID* remoteDevID)
|
||||||
nli_init( &nli, &gs->gi, &myAddr, 1, 1 );
|
nli_init( &nli, &gs->gi, &myAddr, 1, 1 );
|
||||||
nli_setGameName( &nli, gs->gameName );
|
nli_setGameName( &nli, gs->gameName );
|
||||||
|
|
||||||
|
|
||||||
XWStreamCtxt* stream = mem_stream_make_raw( MPPARM(globals->mpool)
|
XWStreamCtxt* stream = mem_stream_make_raw( MPPARM(globals->mpool)
|
||||||
globals->vtMgr );
|
globals->vtMgr );
|
||||||
dvc_makeMQTTInvite( globals->dutil, NULL, stream, &nli );
|
dvc_makeMQTTInvite( globals->dutil, NULL, stream, &nli );
|
||||||
|
@ -691,6 +703,15 @@ countDicts( Globals* globals )
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
haveDictFor(Globals* globals, const char* lc)
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
const XP_UCHAR* keys[] = {KEY_DICTS, lc, NULL};
|
||||||
|
dutil_forEach( globals->dutil, NULL, keys, upCounter, &count );
|
||||||
|
return 0 < count;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
updateDeviceButtons( Globals* globals )
|
updateDeviceButtons( Globals* globals )
|
||||||
{
|
{
|
||||||
|
@ -740,6 +761,31 @@ onMqttMsg(void* closure, const uint8_t* data, int len )
|
||||||
dvc_parseMQTTPacket( globals->dutil, NULL, data, len );
|
dvc_parseMQTTPacket( globals->dutil, NULL, data, len );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
storeAsDict(Globals* globals, const char* lc, const char* name,
|
||||||
|
uint8_t* data, int len )
|
||||||
|
{
|
||||||
|
char shortName[32];
|
||||||
|
sprintf( shortName, "%s", name );
|
||||||
|
char* dot = strstr(shortName, ".xwd");
|
||||||
|
if ( !!dot ) {
|
||||||
|
*dot = '\0';
|
||||||
|
}
|
||||||
|
XP_LOGFF("shortName: %s", shortName);
|
||||||
|
|
||||||
|
const XP_UCHAR* keys[] = {KEY_DICTS, lc, shortName, NULL};
|
||||||
|
dutil_storePtr( globals->dutil, NULL, keys, data, len );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
onGotDict( void* closure, const char* lc, const char* name,
|
||||||
|
uint8_t* data, int len)
|
||||||
|
{
|
||||||
|
CAST_GLOB(Globals*, globals, closure);
|
||||||
|
storeAsDict( globals, lc, name, data, len );
|
||||||
|
updateDeviceButtons( globals );
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
initDeviceGlobals( Globals* globals )
|
initDeviceGlobals( Globals* globals )
|
||||||
{
|
{
|
||||||
|
@ -771,7 +817,7 @@ initDeviceGlobals( Globals* globals )
|
||||||
call_setup( globals, buf, GITREV, now, onConflict, onFocussed, onMqttMsg );
|
call_setup( globals, buf, GITREV, now, onConflict, onFocussed, onMqttMsg );
|
||||||
|
|
||||||
if ( 0 == countDicts( globals ) ) {
|
if ( 0 == countDicts( globals ) ) {
|
||||||
call_get_dict( globals );
|
call_get_dict( NULL, onGotDict, globals );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -840,6 +886,40 @@ newFromInvite( Globals* globals, const NetLaunchInfo* invite )
|
||||||
return gs;
|
return gs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct _DictDownState {
|
||||||
|
Globals* globals;
|
||||||
|
NetLaunchInfo invite;
|
||||||
|
const char* lc;
|
||||||
|
} DictDownState;
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
onDictForInvite( void* closure, const char* lc, const char* name,
|
||||||
|
uint8_t* data, int len )
|
||||||
|
{
|
||||||
|
DictDownState* dds = (DictDownState*)closure;
|
||||||
|
if ( !!data && 0 < len ) {
|
||||||
|
storeAsDict( dds->globals, lc, name, data, len );
|
||||||
|
loadAndDraw( dds->globals, &dds->invite, NULL, NULL );
|
||||||
|
} else {
|
||||||
|
char msg[128];
|
||||||
|
sprintf( msg, "Unable to download %s worldlist for invitation", dds->lc );
|
||||||
|
call_alert( msg );
|
||||||
|
}
|
||||||
|
XP_FREE( dds->globals->mpool, dds );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
onDictConfirmed( void* closure, bool confirmed )
|
||||||
|
{
|
||||||
|
DictDownState* dds = (DictDownState*)closure;
|
||||||
|
if ( confirmed ) {
|
||||||
|
call_get_dict( dds->lc, onDictForInvite, dds );
|
||||||
|
} else {
|
||||||
|
XP_FREE( dds->globals->mpool, dds );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* If you launch a URL that encodes an invitation, you'll get here. If it's
|
/* If you launch a URL that encodes an invitation, you'll get here. If it's
|
||||||
* the first time (the game hasn't been created yet) you'll get a new game
|
* the first time (the game hasn't been created yet) you'll get a new game
|
||||||
* that connects to the host. If you've already created the game, you'll be
|
* that connects to the host. If you've already created the game, you'll be
|
||||||
|
@ -853,10 +933,19 @@ gameFromInvite( Globals* globals, const NetLaunchInfo* invite )
|
||||||
bool needsLoad = true;
|
bool needsLoad = true;
|
||||||
GameState* gs = getSavedGame( globals, invite->gameID );
|
GameState* gs = getSavedGame( globals, invite->gameID );
|
||||||
if ( !gs ) {
|
if ( !gs ) {
|
||||||
if ( invite->lang == 1 ) {
|
const char* lc = lcToLocale( invite->lang );
|
||||||
|
if ( haveDictFor(globals, lc) ) {
|
||||||
gs = newFromInvite( globals, invite );
|
gs = newFromInvite( globals, invite );
|
||||||
} else {
|
} else {
|
||||||
call_alert( "Invitations are only supported for play in English right now." );
|
char msg[128];
|
||||||
|
sprintf( msg, "Invitation requires a wordlist %s for "
|
||||||
|
"language %s; download now?", invite->dict, lc );
|
||||||
|
|
||||||
|
DictDownState* dds = XP_MALLOC( globals->mpool, sizeof(*dds) );
|
||||||
|
dds->globals = globals;
|
||||||
|
dds->invite = *invite;
|
||||||
|
dds->lc = lc;
|
||||||
|
call_confirm(globals, msg, onDictConfirmed, dds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return gs;
|
return gs;
|
||||||
|
@ -1674,16 +1763,11 @@ cbckString( StringProc proc, void* closure, const char* str )
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gotDictBinary( void* closure, const char* xwd, const char* lang,
|
gotDictBinary( GotDictProc proc, void* closure, const char* xwd,
|
||||||
const char* lc, int len, uint8_t* data )
|
const char* lc, uint8_t* data, int len )
|
||||||
{
|
{
|
||||||
XP_LOGFF( "xwd: %s; lang: %s, lc: %s, len: %d", xwd, lang, lc, len );
|
XP_LOGFF( "lc: %s, xwd: %s; len: %d", lc, xwd, len );
|
||||||
|
(*proc)(closure, lc, xwd, data, len);
|
||||||
CAST_GLOB(Globals*, globals, closure);
|
|
||||||
const XP_UCHAR* keys[] = {KEY_DICTS, lc, xwd, NULL};
|
|
||||||
dutil_storePtr( globals->dutil, NULL, keys, data, len );
|
|
||||||
|
|
||||||
updateDeviceButtons( globals );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -81,7 +81,7 @@ typedef struct Globals {
|
||||||
#define CAST_GS(typ, var, ptr) XP_ASSERT(((typ)(ptr))->_GUARD == GUARD_GS); typ var = (typ)(ptr)
|
#define CAST_GS(typ, var, ptr) XP_ASSERT(((typ)(ptr))->_GUARD == GUARD_GS); typ var = (typ)(ptr)
|
||||||
|
|
||||||
#define KEY_DICTS "dicts"
|
#define KEY_DICTS "dicts"
|
||||||
#define ROOT_PATH "/persisted"
|
#define ROOT_PATH "/persisted0.3"
|
||||||
|
|
||||||
void main_set_timer( GameState* gs, XWTimerReason why, XP_U16 when,
|
void main_set_timer( GameState* gs, XWTimerReason why, XP_U16 when,
|
||||||
XWTimerProc proc, void* closure );
|
XWTimerProc proc, void* closure );
|
||||||
|
|
|
@ -163,6 +163,16 @@ wasm_dictionary_destroy( DictionaryCtxt* dict, XWEnv xwe )
|
||||||
XP_FREE( dict->mpool, ctxt );
|
XP_FREE( dict->mpool, ctxt );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DictionaryCtxt*
|
||||||
|
wasm_dictionary_make_empty( Globals* globals )
|
||||||
|
{
|
||||||
|
WasmDictionaryCtxt* wdict = XP_CALLOC( globals->mpool, sizeof( *wdict ) );
|
||||||
|
dict_super_init( MPPARM(globals->mpool) (DictionaryCtxt*)wdict );
|
||||||
|
|
||||||
|
LOG_RETURNF( "%p", wdict );
|
||||||
|
return (DictionaryCtxt*)wdict;
|
||||||
|
}
|
||||||
|
|
||||||
DictionaryCtxt*
|
DictionaryCtxt*
|
||||||
wasm_dictionary_make( Globals* globals, XWEnv xwe,
|
wasm_dictionary_make( Globals* globals, XWEnv xwe,
|
||||||
const char* name, uint8_t* base, size_t len )
|
const char* name, uint8_t* base, size_t len )
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
|
|
||||||
DictionaryCtxt* wasm_dictionary_make( Globals* globals, XWEnv xwe,
|
DictionaryCtxt* wasm_dictionary_make( Globals* globals, XWEnv xwe,
|
||||||
const char* name, uint8_t* base, size_t len );
|
const char* name, uint8_t* base, size_t len );
|
||||||
|
DictionaryCtxt* wasm_dictionary_make_empty( Globals* globals );
|
||||||
void formatDictIndx( char buf[], size_t len, const char* lang, const char* name );
|
void formatDictIndx( char buf[], size_t len, const char* lang, const char* name );
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -410,6 +410,28 @@ wasm_dutil_md5sum( XW_DUtilCtxt* duc, XWEnv xwe, const XP_U8* ptr,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct _ForLangState {
|
||||||
|
XW_DUtilCtxt* duc;
|
||||||
|
XWEnv xwe;
|
||||||
|
uint8_t* ptr;
|
||||||
|
XP_U32 len;
|
||||||
|
} ForLangState;
|
||||||
|
|
||||||
|
static XP_Bool
|
||||||
|
gotForLang( void* closure, const XP_UCHAR* keys[] )
|
||||||
|
{
|
||||||
|
XP_LOGFF("name: %s", keys[2]);
|
||||||
|
ForLangState* fls = (ForLangState*)closure;
|
||||||
|
dutil_loadPtr( fls->duc, fls->xwe, keys, NULL, &fls->len );
|
||||||
|
if ( 0 < fls->len ) {
|
||||||
|
fls->ptr = XP_MALLOC( fls->duc->mpool, fls->len );
|
||||||
|
dutil_loadPtr( fls->duc, fls->xwe, keys, fls->ptr, &fls->len );
|
||||||
|
} else {
|
||||||
|
XP_LOGFF( "nothing for %s/%s", keys[1], keys[2] );
|
||||||
|
}
|
||||||
|
return NULL != fls->ptr;
|
||||||
|
}
|
||||||
|
|
||||||
static const DictionaryCtxt*
|
static const DictionaryCtxt*
|
||||||
wasm_dutil_getDict( XW_DUtilCtxt* duc, XWEnv xwe,
|
wasm_dutil_getDict( XW_DUtilCtxt* duc, XWEnv xwe,
|
||||||
XP_LangCode lang, const XP_UCHAR* dictName )
|
XP_LangCode lang, const XP_UCHAR* dictName )
|
||||||
|
@ -429,10 +451,22 @@ wasm_dutil_getDict( XW_DUtilCtxt* duc, XWEnv xwe,
|
||||||
dutil_loadPtr( duc, xwe, keys, ptr, &len );
|
dutil_loadPtr( duc, xwe, keys, ptr, &len );
|
||||||
result = wasm_dictionary_make( globals, xwe, dictName, ptr, len );
|
result = wasm_dictionary_make( globals, xwe, dictName, ptr, len );
|
||||||
dmgr_put( globals->dictMgr, xwe, dictName, result );
|
dmgr_put( globals->dictMgr, xwe, dictName, result );
|
||||||
|
} else {
|
||||||
|
/* Try another dict in same language */
|
||||||
|
XP_LOGFF( "trying for another %s dict", lc );
|
||||||
|
ForLangState fls = { .duc = duc,
|
||||||
|
.xwe = xwe,
|
||||||
|
};
|
||||||
|
const char* langKeys[] = {KEY_DICTS, lc, KEY_WILDCARD, NULL};
|
||||||
|
dutil_forEach( duc, xwe, langKeys, gotForLang, &fls );
|
||||||
|
if ( !!fls.ptr ) {
|
||||||
|
result = wasm_dictionary_make( globals, xwe, dictName, fls.ptr, fls.len );
|
||||||
|
dmgr_put( globals->dictMgr, xwe, dictName, result );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_RETURNF( "%p", result );
|
XP_LOGFF("(%s, %s)=>%p", lc, dictName, result );
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -410,11 +410,9 @@ wasm_util_altKeyDown( XW_UtilCtxt* uc, XWEnv xwe )
|
||||||
static DictionaryCtxt*
|
static DictionaryCtxt*
|
||||||
wasm_util_makeEmptyDict( XW_UtilCtxt* uc, XWEnv xwe )
|
wasm_util_makeEmptyDict( XW_UtilCtxt* uc, XWEnv xwe )
|
||||||
{
|
{
|
||||||
LOG_FUNC(); /* firing */
|
WasmUtilCtx* wuctxt = (WasmUtilCtx*)uc;
|
||||||
XP_ASSERT(0);
|
GameState* gs = wuctxt->closure;
|
||||||
/* return wasm_dictionary_make( MPPARM(uc->mpool) NULL, uc->closure, */
|
return wasm_dictionary_make_empty( gs->globals );
|
||||||
/* NULL, false, NULL ); */
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -45,18 +45,11 @@ function registerOnce(devid, gitrev, now) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDict(closure) {
|
function getDict(langs, proc, closure) {
|
||||||
// set these later
|
// set these later
|
||||||
let gots = {};
|
let gots = {};
|
||||||
|
|
||||||
let langs = 'en'; // navigator.language;
|
|
||||||
if (langs) {
|
|
||||||
langs = [langs.split('-')[0]];
|
|
||||||
}
|
|
||||||
console.log('langs: ' + langs + '; langs[0]: ' + langs[0]);
|
console.log('langs: ' + langs + '; langs[0]: ' + langs[0]);
|
||||||
if (langs[0] != 'en' ) {
|
|
||||||
langs.push('en');
|
|
||||||
}
|
|
||||||
let args = '?lc=' + langs.join('|');
|
let args = '?lc=' + langs.join('|');
|
||||||
console.log('args: ' + args);
|
console.log('args: ' + args);
|
||||||
fetch('/xw4/info.py/listDicts' + args, {
|
fetch('/xw4/info.py/listDicts' + args, {
|
||||||
|
@ -97,8 +90,8 @@ function getDict(closure) {
|
||||||
dataHeap.set( new Uint8Array(data) );
|
dataHeap.set( new Uint8Array(data) );
|
||||||
// console.log('made array?: ' + dataHeap);
|
// console.log('made array?: ' + dataHeap);
|
||||||
Module.ccall('gotDictBinary', null,
|
Module.ccall('gotDictBinary', null,
|
||||||
['number', 'string', 'string', 'string', 'number', 'array'],
|
['number', 'number', 'string', 'string', 'array', 'number'],
|
||||||
[closure, gots.xwd, gots.langName, gots.lc, len, dataHeap]);
|
[proc, closure, gots.xwd, gots.lc, dataHeap, len]);
|
||||||
Module._free(dataPtr);
|
Module._free(dataPtr);
|
||||||
});
|
});
|
||||||
console.log('getDict() done');
|
console.log('getDict() done');
|
||||||
|
|
Loading…
Add table
Reference in a new issue