Moving logic into the timer itself. There's always meant to be one
running, set from between 10 seconds and 23 hours from now. Code
receiving messages (mqtt or relay) resets the backoff when a message is
received, so when there's activity the timer should stay short. Somebody
with no games at all will have attempts made to connect to the relay and
mosquitto once/day, which is when invitations via that method would be
received. Devices with FCM should see lower latency of course.
Didn't handle the case where a game included NFC or BT. I should
probably be stripping those on receipt as I think the android side does
when the devices doesn't support 'em. And that in turn should be common/
code. So just fix it for now so testing can continue.
There were ways of leaving multiple instances running, I think fighting
for resources and keeping each other from connecting. Now I think there
can only be one. And lots of logging will help find future problems.
This is meant to replace the relay eventually, but for now it's a new
option, like BT or SMS, to be chosen. Protocol is handled in common/
code for the first time, meaning that linux and android interact without
the need to keep two platforms in sync. Linux uses lib-mosquitto, and
Android uses eclipse's Paho client (the generic java version, not the
one that uses four-year-old Service patterns and so crashes for SDK >=
26.)
Hungarian is unique (so far) in having two-letter tiles that can be
spelled with one-letter tiles AND in allowing words to be spelled both
ways. This crashed search based on strings because there were
duplicates. So now search is done by tile arrays. Strings are first
converted, and then IFF there is more than one tile array result AND the
wordlist has the new flag indicating that duplicates are possible, THEN
the user is asked to choose among the possible tile spellings of the
search string.
Strictly speaking I think a subset is ok. I need to fix my build scripts
OR figure out how to enable the checking Weblate claims to have. The
string I modified is isn't used AFAIK so it's not urgent.
Linux and Android duplicated all the code to parse a wordlist file --
and shared a bug that needed fixing. So now most of that is in a common/
function both call, and the bug -- failing to mask out flag bits I don't
care about -- is fixed.
For some reason the header and dawg data in Spanish wordlist don't
agree. Until I fix this, remove the assertion from the (dev-use-only)
script that dumps wordlist since it breaks it for other uses.
Find-prefix feature in current code crashes on Hungarian because it
allows duplicates (words that occur spelled with the same letters but
different tile combinations.) Modify Makefile to exclude those (as it
does for all other multi-letter-tile languages). And to pull the git
source of the wordlist on demand.
I'm getting crashes and don't want to think about it. It may be time to
remove this, though it's needed for logging-storage to work from jni.
To be revisited....
Separated the refcounting and ptr-as-long wrapping aspects of GamePtr
into a superclass that others might later inherit from. Cleaned up
dict_iter entrypoints, and added sanity checks to both structs so I'll
quickly notice if I get the ptr management wrong.
Fixing a problem with languages (like Hungarian) where it's legal to use
a two-letter tile or two single-letter tiles to play the same word. When
words are seen, or searched for, as char-arrays, there are
duplicates. Current code crashes, but there's also risk the user gets
unexpected behavior. Crash is fixed, and foundation laid for better UX,
by doing all searches for tile arrays. If a search string translates to
more than one tile array the user must choose. For that choice to make
sense it's now possible to translate tile[] to char[] with a delimiter
between the tile strings.
I'm keeping it AND asserting at every possible location that the env
passed all the way in is the same as what the mapping produces. If in
months I haven't seen a single crash then I can evaluate which way of
passing the env around is better. (It'd be code size vs. performance,
as the passing of env is noticably faster. Code size could be fixed by
turning 'XWEnv xwe,' into a macro that goes away on some builds.)
I was getting an occasional crash using a stale env to delete a dict's
resources because the dict was cacheing the env that created it. Dumb!
Using the thread->env mapping stuff worked, but that felt risky and so I
tried just passing it in. It's safe, and involves an amount of change I
can tolerate. So likely going that way.
For Hungarian, there are "duplicate" words because e.g. the string CS
can be spelled with two tiles or one. If a delimiter is printed at tile
boundaries the duplication goes away.
Add Makefile filters to create a wordlist with about 42K words derived
from a github project (thanks to pointers from an informant. :-) Per
him, and contrary to how Catalan does it, double-letter-tile words
also appear in single-letter variants if the tiles allow.
Duplicate games get lots of crashes when mixed with phonies code. Will
need to fix that before enabling duplicate mode. In general there are
lots of assertion failures mixing trades and undos and phonies and
running dozens of games at once. I don't think that's new so will ship
now and fix later.
Turns out the host, when inviting a remote device, needs to know how
many players are on it (since more than one is supported and the script
currently generates that case.) So pass to --server devices an array,
one per remote -- but don't bother when all entries are "1";
Bad programmer. And because the raw bytes form was so large it always
caused the fake sms stuff to send immediately rather than waiting for a
timer to expire -- which never happened when run by the test script. So
I'm not allowing any timer for invitation-sends only.
(Another problem is that there's no mechanism in the xplat code to retry
invitation sends. That needs fixing.)
If slow network traffic has given a guest time to move tiles to the
board while the host decides its last move must be rejected, those tiles
must be removed before the rejected turn can be undone.
With reject-phonies set this will trigger the reject path.
Also init CommonPrefs in jni land since its makePhonyPct, left unitialized,
causes the robot to deliberately reverse every turn, firing an assertion that the
robot's moves are legal.
Currently detects the same as tiles not in a line and calls out to a new
util method that's currently parameter-less. On Android the option only
appears in d variants.
When a guest sends a move to the server it's not the next player's turn
until the server checks the move and rejects or accepts it. It was
possible still to manipulate the board, playing new tiles, and even to
attempt to commit them. And if the move came back rejected, the bogus
committed one would be that was cleared. Bad. So I'm just setting the
turn to -1, which disables board etc., and letting nextTurn() assigne it
after the confirmation comes back.
On each open, increment a counter. And if we're able to close without a
crash intervening, decrement. Once we're trying to open with a non-0
counter we have a bad game. Open only after warning the user.
Yikes. I used to assert, in nextTurn(), that you were in the right
state. On release builds that went away, and you were moved into the
right state regardless. The bug happened when I changed that to exit
nextTurn() without changing the state, meaning that for PHONIES_DISALLOW
the host filled up its message queue trying to communicate that the
latest move was ok, never getting out of the state that required sending
that message. The fix is simply to change the state after sending and,
guest-side, after receiving, that message.
The lock was leaking when sometimes the OS would call onStop() without
isFinishing() being true, then never use the fragment again. And never
call onDestroy(). Releasing the lock in onStop and regetting it in
onResume seems to fix, but this needs some testing and time.
The problem appears to be that the new <vector/> .xml drawable has a
greater height for purposes of layout. Specifying dimensions seems to be
the way to go, though devices may vary.
I don't know why, but in my tests the relay seems to be delivering
messages to the wrong device. The linux device detects this. It used to
assert, but now just drops the message. If this is happening on Android
it might be why I'm seeing crashes...
The problem appears to be that the new <vector/> .xml drawable has a
greater height for purposes of layout. Specifying dimensions seems to be
the way to go, though devices may vary.
reverse change in 19fa3fce05 (April 4
2019) making MainActivity singleTask, which caused starting the app to
launch the gamesList screen rather than the game that had been open when
it was moved to background. Now it's "standard," and I have to hope that
doesn't produce new problems. As I wrote back then, we'll see. More
quickly I hope.
Required redoing how I invoke the NDK. The limititations I had to hack
around before seem fixed, so this is probably better. But there will be
glitches. :-)
The common code truncates to 255 *bytes*, not chars, so this isn't even
right, but at least for ascii users it'll make it less likely that
what's typed doesn't all get sent. The right fix is to change the format
to not limit sent str len to 255 bytes. See commit 512a8e1af.
Len byte was limited to 255, but would get clipped (masked with 0xFF)
then all the string data would get written. So on receipt, the clipped
length was taken to be that of the string data, with the rest of the
string to be interpreted as something else. An array index, in this
case.
The common code truncates to 255 *bytes*, not chars, so this isn't even
right, but at least for ascii users it'll make it less likely that
what's typed doesn't all get sent. The right fix is to change the format
to not limit sent str len to 255 bytes. See commit 512a8e1af.
Len byte was limited to 255, but would get clipped (masked with 0xFF)
then all the string data would get written. So on receipt, the clipped
length was taken to be that of the string data, with the rest of the
string to be interpreted as something else. An array index, in this
case.