Resynchronize a log with the other stations, and rescore it

A station that was away — a laptop that lost the network, one that was
switched off — comes back missing whatever the others logged while it was
gone. N1MM fills that in by walking the log an hour at a time, and this is
that walk, on the same messages:

| Message | What it says |
|---|---|
| `CHECKSUM` | here is what I hold for your contacts in this hour, and the contest and callsign I am logging |
| `DELETEQS` | drop your copies of my contacts in that hour, I am sending them again |
| `RESYNCQSO` | one of those contacts |
| `CONFIRMED` | here is what the hour hashes to at my end — which also asks for the next hour |

Each station is the authority on the contacts it made, so an hour that
disagrees is replaced rather than merged. The answer to one block asks for
the next, and the walk ends when the block starts after the end of the
period. The Resynchronize tab counts the hours that agreed, the hours that
were sent again and the hours that still disagreed, which are N1MM's
columns.

**`LogChecksum`** is N1MM's: a CRC32 over the `DXLOG` columns of the block,
ordered by time and then callsign, leaving out what each station works out
for itself — points, the three multiplier flags, the country prefix, the
continent, the WPX prefix and `IsOriginal`. Two stations may disagree about
those and still hold the same log. A checksum that disagrees for any other
reason costs one block of traffic, which is what a resync is for.

**The link still holds no log.** It asks one through `ContactLog` for the
contacts of a computer in a block of time, and `SessionContactLog` answers
on the window thread, because that is where the log is touched.

**Every contact logged here now carries the computer that made it.** N1MM
stamps `NetBiosName` and `NetworkedCompNr` on every row and this program
did not, so its own contacts belonged to no station and a resync could not
ask for them.

**Rescore** writes the points and multiplier flags of a period back to the
database. The log in memory scores itself whenever it changes; the stored
rows do not, and N1MM reads them rather than working them out. A contact
that arrives from another station after the one that took a multiplier
leaves those columns behind. A station can also ask the others to rescore
when its resync finishes, which is the flag on the end of `CHECKSUM`.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PdAYHcdRktqKry7nk414TU
This commit is contained in:
2026-09-03 21:52:09 +00:00
co-authored by Claude Opus 5
parent 68b29d722a
commit 2a21c772ad
18 changed files with 1061 additions and 15 deletions
+41 -8
View File
@@ -393,13 +393,15 @@ burst of three does not read as thousands an hour. The five transmit-interlock
flags in the message are sent as false: this program does not block a
transmitter.
**The network status window** has N1MM's Stations, Actions and Messages tabs and
**The network status window** has N1MM's Stations, Actions, Resynchronize,
Rescore and Messages tabs and
its columns — Computer, IP Address, Pass, Run, 10, 100, Freq, Op, Msg, Send,
Receive, Band, R/M, Mode. Right-click a row to pass the contact being worked to
that station, to talk, or to close and open its connection; a connection closed
by hand stays closed until it is opened again, because the next beacon would
otherwise open it within ten seconds. Left out: N1MM's Resynchronize and Rescore
tabs, the transmit interlocks of its Options tab, the Master column and the
otherwise open it within ten seconds. The Resynchronize and Rescore tabs work
on a period — the contest, since a time, or the last few hours. Left out: the
transmit interlocks of N1MM's Options tab, the Master column and the
call-stacking target tab. There is nothing behind any of them here.
**The ten-minute rule.** `BandChangeRules` counts band changes and the stay on a
@@ -412,11 +414,42 @@ the changes per hour overrides `Contest.BandChangesFor`. N1MM's per-contest tabl
is not repeated: it is a few hundred cases in a decompiled hash switch, and the
contests this station enters are the ones worth reading out of it one at a time.
What the link does not do yet: N1MM's resync, where a station that has been
away asks another for the contacts it missed, and the log check that compares
two stations' logs row by row. Both are message types this program can already
frame; neither is written. There is also no guard against two stations taking
the same station number.
**Resync.** A station that was away asks the others for the hours it missed.
The walk is N1MM's, an hour at a time:
| Message | What it says |
|---|---|
| `CHECKSUM` | here is what I hold for your contacts in this hour, and the contest and callsign I am logging |
| `DELETEQS` | drop your copies of my contacts in that hour, I am sending them again |
| `RESYNCQSO` | one of those contacts |
| `CONFIRMED` | here is what the hour hashes to at my end — which also asks for the next hour |
Each station is the authority on the contacts it made, so the answer replaces
the block rather than merging into it. The walk ends when the block being asked
about starts after the end of the period.
`LogChecksum` is N1MM's: a CRC32 over the `DXLOG` columns of the block, ordered
by time and then callsign, leaving out the columns each station works out for
itself — points, the three multiplier flags, the country prefix, the continent,
the WPX prefix and `IsOriginal`. Two stations are allowed to disagree about
those and still hold the same log. A checksum that disagrees for any other
reason costs one block of traffic, which is what a resync is for.
Every contact logged here now carries the computer that made it —
`NetBiosName`, which N1MM stamps and this program did not — because that is what
a resync asks for a block of contacts by.
**Rescore** writes the points and multiplier flags of a period back to the
database. The log in memory scores itself whenever it changes, so this is for
the stored rows: N1MM reads those columns rather than working them out, and a
contact that arrives from another station after the one that took a multiplier
leaves them behind. A station can also ask the others to rescore when its resync
finishes, which is the flag on the end of `CHECKSUM`.
What the link does not do yet: the log check that compares two stations' logs
row by row. It is a message type this program can already frame; it is not
written. There is also no guard against two stations taking the same station
number.
**Voice keying.** `MessageSender` was written to cover a voice keyer playing a
recording, and nothing implements it. Each operator's recordings folder is