Files
Nonemm/src/Nonemm.Spotting/Telnet/ClusterPrompts.cs
ericek111 8956c2fd22 Take the rest of what reading N1MM turned up
The call frame. Above the callsign box, N1MM writes which spotted station the
radio is sitting on, coloured like the bandmap colours it, or CQ-Frequency when
this is the frequency the last CQ went out on. Space with an empty callsign box
takes the call out of the frame and into the box, but only while searching:
TabPressed does that when the run box is unchecked, because a running station is
answering callers rather than chasing the one under its VFO. How close counts as
sitting on it is N1MM's tuning tolerance, 300 Hz, now a setting.

Sh/dx while unassisted. TelnetClient.Output refuses any command holding SH/DX
when the entry is not assisted, and the telnet window does the same now.
Whether an entry is assisted follows N1MM's own rule: assisted, multi-operator
or checklog may use spots, a single operator who did not say assisted may not.

The node's flavour. Click_LogonButton reads DXSpider, AR-Cluster, CC Cluster or
GoCluster out of the banner; ClusterClient reads the same words and the window
shows what it found. It changes nothing yet — the commands it would change are
ones this does not send — but the node says so and now we know.

CQ WW RTTY's state box. NextTab only stops on SectionText when the station is
US or Canadian, because nobody else sends a state, so a contest can now say a
box is not for this station and the walk steps over it. The box is still there
to type in.

The telnet button editor shows as many buttons as are defined, with an empty row
to write the next one in, rather than N1MM's twelve.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 10:23:30 +00:00

50 lines
1.5 KiB
C#

namespace Nonemm.Spotting.Telnet;
/// Reads what a cluster node is asking for at login. Every node asks in its own
/// words; these are the ones DXSpider, AR-Cluster, CC Cluster and DXNet use.
public static class ClusterPrompts
{
private static readonly string[] Callsign =
[
"login", "log in", "logon", "enter call", "enter your call",
"your call", "callsign", "call:", "user:",
];
private static readonly string[] Password = ["password"];
public static bool AsksForCallsign(string text) => Holds(text, Callsign);
public static bool AsksForPassword(string text) => Holds(text, Password);
/// Which cluster program said this, or `Unknown` when the text names none
/// of them. The words are the ones N1MM looks for in the banner.
public static ClusterKind KindOf(string text)
{
if (Holds(text, ["gocluster"]))
{
return ClusterKind.GoCluster;
}
if (Holds(text, ["ar-cluster"]))
{
return ClusterKind.ArCluster;
}
if (Holds(text, ["cc cluster", "cc-cluster"]))
{
return ClusterKind.CcCluster;
}
return Holds(text, ["dxspider", "dx spider"]) ? ClusterKind.DxSpider : ClusterKind.Unknown;
}
private static bool Holds(string text, IReadOnlyList<string> phrases)
{
foreach (string phrase in phrases)
{
if (text.Contains(phrase, StringComparison.OrdinalIgnoreCase))
{
return true;
}
}
return false;
}
}