There's code on all platforms to force user to have dict prior to
opening a game or responding to an invitation. "Empty" dict play hasn't
made sense in a long time.
Create new class that owns the alert. Let it decide whether to post,
remove, etc. Seems to work, but I've removed some of the "reinvite"
options I'm not sure were helpful anyway. To be considered...
Got as far as having gtk client display list of previously harvested
known players to be invited. Their addresses, or at least mqtt ids are
saved. Next is to actually invite one.
If a configured-as-host game joined an existing game the relay would
make it a guest. The android util_ callback for that change was only
implemented in BoardDelegate and so the change was dropped unless the
game was open/visible. Because comms recorded the change, though, the
callback would never be called again and so the game never learned to
behave as a guest and never registered: permanent failure to join game!
Implemented with a new server state so initClientConnection can be
called from server_do() instead of inside comms while processing an
incoming packet.
To avoid inviteless relay games not having an mqtt channel (and so
yielding a crappy experience) pass the mqtt devid when device registers
and when server replies with all-here.
Some relay bug (I think) misroutes or duplicates packets. Don't assert
as that means test scripts fail to finish. Instead drop the
message. Scripts seem to recover ok with this change and I've never seen
the assert on a device so suspect it's test-world only
Add a basic regular expression engine to the dictiter, and to the UI add
the ability to filter for "starts with", "contains" and "ends with",
which translate into ANDed RE_*, _*RE_* and _*RE, respectively (with
_ standing for blank/wildcard). The engine's tightly integrated with the
next/prevWord() functions for greatest possible speed, but unless
there's no pattern does slow things down a bit (especially when "ENDS
WITH" is used.) The full engine is not exposed (users can't provide raw
REs), and while the parser will accept nesting (e.g. ([AB]_*[CD]){2,5}
to mean words from 2-5 tiles long starting with A or B and ending with C
or D) the engine can't handle it. Which is why filtering for word length
is handled separately from REs (but also tightly integrated.)
Users can enter strings that don't map to tiles. They now get an
error. It made sense for the error alert to have a "Show tiles"
button, so there's now a dialog listing all the tiles in a wordlist,
something the browser has needed all along.
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.
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.
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.
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.
With these changes the test script no longer produces games that don't
finish. I think they are recovering from the problems produced by one
device doing an undo while another is making a move, or other problems
produced by undo being allowed to happen on any device at any time, but
haven't analyzed the games beyond the test script's verifying that they
all finish with a Winner after all tiles are consumed.
There are still some stalls turning up when running the test script,
especially with more than two players in a game, but but it'll be
easier to do the final debugging off my pathetic travel-only
chromebook. And things are already much better. :-)
When something goes wrong with a move (typically because of undo), the
move stack and server's idea of whose turn it is get out of
sync. Since it being my turn means it's up to me to put the next move
on the stack, let the stack own "next turn". (Can probably eventually
get rid of the ServerCtxt variable that tracks it.)