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>
50 lines
1.5 KiB
C#
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;
|
|
}
|
|
}
|