Was dropping invitations that were posted before I connected to the
remote broker. Now they're kept, and sent until the broker says
publish succeeded. Better would be to have comms resend when mqtt
connects, but I'm not set up for that.
Server needs to not rematch if any device has more than one
player (for now, as I'm too lazy to fix this rare condition.) I'm
moving toward having the linux client write status to a unix socket on
exit rather than having the test script parse the log file for
status. GameOver is there now. Tile counts should follow.
Because only the host/inviter knows the addresses of all the devices
in a game it's hard for guests to rematch (unless it's a 2-device
game, as they know the host's address.) So now, as part of telling
guests the game is ready to play, include the addresses of other
guests. It's usually only 9 bytes per device, and only happens when
more than two devices are in a game.
No point in sending the old-topic-format MQTT messages to clients that
know about the new one, and in fact it's harmful. Devices in a game
already agree on the stream version to use and communicate it, so pass
that into comms once it's known and from there on to the device code
that builds mqtt messages.
This is probably a temporary fix for Linux not being aggressive enough
about calling comms_resendAll() when opening a game. For now, though,
test scripts fail without it.
To prevent deleted games' ghost invitations from remaining as
persisted on a topic and so being received over and over, have
recipient of invitation send an empty message on the same topic to
remove them. Any message sent once the game start would have replaced
the invitation, but sometimes if the sender is deleted at the right
time there's none.
MQTT must create the same header for each message, so having it set
the current timestamp is bad. I actually think it belongs in the comms
header, not in each transport.
Rematch against self didn't work, and is useful for testing. So in
dutil method hasGame(), check if games with the same gameID are also
for the same channel. And when creating a new game for rematch, make
sure it's channel is 0.
Creating an address record without having heard from the remote is
new, and setting it to an old version was preventing using new msg
format. So set to new by default. Not sure how it'll get downgraded
facing an old client, but a 100-game upgrade test passes.....
Looks like invitations become unsendable before they're deleted
sometimes and so block sending real messages. This fixes device
accepting invitation but never hearing back from host.
This should complete sending to multiple topics (for backwards
compatibility) and supporting combined messages in the future (sending
them is hard; receiving not so much.)
I didn't understand MQTT at all. Per the docs anyway it only keeps a
message around if its "persist" flag is set, and then it only keeps
the most recent per topic. I expected that when a device connected,
messages would be waiting for it, but that's apparently not true (some
evidence to the contrary.) But having all games on a device share the
same topic means only one message can be waiting. So switch to
including gameID in the topic, subscribing to a wildcard topic and
sending to a different one per game. For now, for legacy purposes,
we'll keep sending to the old per-device topic.
Engine shouldn't be so stupid as to play a blank for 0 points. So when
comparing two moves, sort first on score, then use number of blanks
used to break any ties.
Duplicate messages early on, which happened only in the test script
but could have anywhere, broke connectivity. So don't kill address
records when a duplicate shows up. Dupes only escape message ID
checking early (before channel is established). I used to remove
address records when a message was rejected, but don't understand why
so removed that, though asserts show it's not mattering except for
those early messages.
Add dutil proc haveGame() and use it to detect duplicate
invitations. I'm passing, but ignoring on android, the channel, which
means that for now you can't invite yourself and on-device testing
requires having CrossWords and CrossDbg or a second user.