manual: updated sniffer settings description + source: changed sniffing to callsignraw and avoid dupe entries

This commit is contained in:
Marc Froehlich
2026-08-16 03:40:54 +02:00
parent 8fa5360752
commit 720dd2560b
3 changed files with 129 additions and 35 deletions
@@ -3981,42 +3981,96 @@ private ObservableList<String>
} }
/** /**
* decides if a message in the in-queue is directed to me or if its directed to another station and sniffed * Checks whether a message belongs to a monitored base callsign.
* @param chatMessage *
* @return * <p>QSO monitoring intentionally combines all visible ON4KST variants of
* the same station. An entry for DN9APW therefore also matches DN9APW-2,
* DN9APW-70 and other suffixes. This affects monitoring only; message
* routing continues to use the complete callsign and chat category.</p>
*
* @param chatMessage message to examine
* @return true if sender or receiver belongs to a monitored base callsign
*/ */
public boolean isSniffedMessage(ChatMessage chatMessage) { public boolean isSniffedMessage(ChatMessage chatMessage) {
if (chatMessage == null || chatMessage.getSender() == null || chatMessage.getReceiver() == null) {
if (chatMessage == null
|| chatMessage.getSender() == null
|| chatMessage.getReceiver() == null) {
return false; return false;
} }
String senderCall = chatMessage.getSender().getCallSign(); String senderCall =
String receiverCall = chatMessage.getReceiver().getCallSign(); chatMessage.getSender().getCallSign();
String receiverCall =
chatMessage.getReceiver().getCallSign();
if (senderCall == null || receiverCall == null) { if (senderCall == null || receiverCall == null) {
return false; return false;
} }
if (lstNotify_QSOSniffer_sniffedCallSignList == null || lstNotify_QSOSniffer_sniffedCallSignList.isEmpty()) { if (lstNotify_QSOSniffer_sniffedCallSignList == null
|| lstNotify_QSOSniffer_sniffedCallSignList.isEmpty()) {
return false; return false;
} }
String senderBaseCall =
ChatMember.normalizeCallSignToBaseCallSign(
senderCall
);
String receiverBaseCall =
ChatMember.normalizeCallSignToBaseCallSign(
receiverCall
);
boolean observedCall = boolean observedCall =
lstNotify_QSOSniffer_sniffedCallSignList.contains(senderCall) lstNotify_QSOSniffer_sniffedCallSignList
|| lstNotify_QSOSniffer_sniffedCallSignList.contains(receiverCall); .stream()
.anyMatch(
monitoredCall -> {
String monitoredBaseCall =
ChatMember
.normalizeCallSignToBaseCallSign(
monitoredCall
);
return monitoredBaseCall != null
&& (
monitoredBaseCall
.equalsIgnoreCase(
senderBaseCall
)
|| monitoredBaseCall
.equalsIgnoreCase(
receiverBaseCall
)
);
}
);
if (!observedCall) { if (!observedCall) {
return false; return false;
} }
String myCall = getChatPreferences() != null ? getChatPreferences().getStn_loginCallSign() : null; String myCall =
String myRawCall = getChatPreferences() != null ? getChatPreferences().getStn_loginCallSignRaw() : null; getChatPreferences() != null
? getChatPreferences().getStn_loginCallSign()
: null;
String myRawCall =
getChatPreferences() != null
? getChatPreferences().getStn_loginCallSignRaw()
: null;
/* /*
* Sniffed messages should appear in the private table only if they are not * Messages which are already addressed directly to the local station
* already direct messages to my own callsign. * belong in the PM table without an additional Sniffed marker.
*/ */
return !receiverCall.equals(myCall) && !receiverCall.equals(myRawCall); boolean directedToOwnCall =
(myCall != null
&& receiverCall.equalsIgnoreCase(myCall))
|| (myRawCall != null
&& receiverCall.equalsIgnoreCase(myRawCall));
return !directedToOwnCall;
} }
/** /**
@@ -2631,10 +2631,15 @@ public class ChatPreferences {
if (callSign != null if (callSign != null
&& !callSign.isBlank()) { && !callSign.isBlank()) {
/*
* Older preference files may still contain complete KST callsigns
* such as DN9APW-2. Monitoring is stored by base callsign so that
* every suffix of the same station is covered by one entry.
*/
String normalizedCallSign = String normalizedCallSign =
callSign ChatMember.normalizeCallSignToBaseCallSign(
.trim() callSign
.toUpperCase(); );
if (!lstNotify_QSOSniffer_sniffedCallSignList if (!lstNotify_QSOSniffer_sniffedCallSignList
.contains(normalizedCallSign)) { .contains(normalizedCallSign)) {
@@ -2660,12 +2665,28 @@ public class ChatPreferences {
for (int i = 0; i < children.getLength(); i++) { for (int i = 0; i < children.getLength(); i++) {
Node child = children.item(i); Node child = children.item(i);
if (child.getNodeType() == Node.ELEMENT_NODE) { if (child.getNodeType() == Node.ELEMENT_NODE) {
String word = child.getTextContent(); String callSign = child.getTextContent();
if (word != null) {
word = word.trim(); if (callSign != null
} && !callSign.isBlank()) {
if (word != null && !word.isEmpty()) {
lstNotify_QSOSniffer_sniffedWordsList.add(word); /*
* Older preference files may contain complete KST callsigns
* such as DN9APW-2. QSO monitoring is stored by base callsign,
* so one entry covers every suffix of the same station.
*/
String normalizedCallSign =
ChatMember.normalizeCallSignToBaseCallSign(
callSign
);
if (normalizedCallSign != null
&& !normalizedCallSign.isBlank()
&& !lstNotify_QSOSniffer_sniffedCallSignList
.contains(normalizedCallSign)) {
lstNotify_QSOSniffer_sniffedCallSignList
.add(normalizedCallSign);
}
} }
} }
} }
@@ -4775,21 +4775,31 @@ public class Kst4ContestApplication extends Application implements StatusUpdateL
callSignColumn.setOnEditCommit(event -> { callSignColumn.setOnEditCommit(event -> {
int row = event.getTablePosition().getRow(); int row = event.getTablePosition().getRow();
String newValue = String enteredCallSign =
event.getNewValue() == null event.getNewValue() == null
? "" ? ""
: event.getNewValue() : event.getNewValue()
.trim() .trim()
.toUpperCase(Locale.ROOT); .toUpperCase(Locale.ROOT);
if (newValue.isBlank()) { if (enteredCallSign.isBlank()) {
event.getTableView() event.getTableView()
.getItems() .getItems()
.remove(row); .remove(row);
return; return;
} }
if (!GuiUtils.isCallSignSyntax(newValue)) { /*
* QSO monitoring intentionally works with the base callsign.
* Entering DN9APW, DN9APW-2 or DN9APW-70 therefore produces
* the same monitoring entry: DN9APW.
*/
String monitoredBaseCall =
ChatMember.normalizeCallSignToBaseCallSign(
enteredCallSign
);
if (!GuiUtils.isCallSignSyntax(monitoredBaseCall)) {
alertWindowEvent( alertWindowEvent(
"Please enter a valid callsign." "Please enter a valid callsign."
); );
@@ -4813,7 +4823,9 @@ public class Kst4ContestApplication extends Application implements StatusUpdateL
.get(i); .get(i);
if (existing != null if (existing != null
&& existing.equalsIgnoreCase(newValue)) { && existing.equalsIgnoreCase(
monitoredBaseCall
)) {
duplicate = true; duplicate = true;
break; break;
} }
@@ -4821,7 +4833,7 @@ public class Kst4ContestApplication extends Application implements StatusUpdateL
if (duplicate) { if (duplicate) {
alertWindowEvent( alertWindowEvent(
"This callsign is already " "This base callsign is already "
+ "in the monitoring list." + "in the monitoring list."
); );
event.getTableView().refresh(); event.getTableView().refresh();
@@ -4830,7 +4842,7 @@ public class Kst4ContestApplication extends Application implements StatusUpdateL
event.getTableView() event.getTableView()
.getItems() .getItems()
.set(row, newValue); .set(row, monitoredBaseCall);
}); });
table.getColumns().add(callSignColumn); table.getColumns().add(callSignColumn);
@@ -10915,15 +10927,21 @@ public class Kst4ContestApplication extends Application implements StatusUpdateL
dialog.showAndWait().ifPresent( dialog.showAndWait().ifPresent(
input -> { input -> {
String callSign = String enteredCallSign =
input input
.trim() .trim()
.toUpperCase( .toUpperCase(
Locale.ROOT Locale.ROOT
); );
String monitoredBaseCall =
ChatMember
.normalizeCallSignToBaseCallSign(
enteredCallSign
);
if (!GuiUtils.isCallSignSyntax( if (!GuiUtils.isCallSignSyntax(
callSign monitoredBaseCall
)) { )) {
alertWindowEvent( alertWindowEvent(
"Please enter " "Please enter "
@@ -10938,15 +10956,16 @@ public class Kst4ContestApplication extends Application implements StatusUpdateL
.stream() .stream()
.anyMatch( .anyMatch(
existing -> existing ->
existing existing != null
&& existing
.equalsIgnoreCase( .equalsIgnoreCase(
callSign monitoredBaseCall
) )
); );
if (duplicate) { if (duplicate) {
alertWindowEvent( alertWindowEvent(
"This callsign is already " "This base callsign is already "
+ "in the monitoring list." + "in the monitoring list."
); );
return; return;
@@ -10954,7 +10973,7 @@ public class Kst4ContestApplication extends Application implements StatusUpdateL
chatcontroller chatcontroller
.getLstNotify_QSOSniffer_sniffedCallSignList() .getLstNotify_QSOSniffer_sniffedCallSignList()
.add(callSign); .add(monitoredBaseCall);
} }
); );
} }