fix(chat): grouped calculation of priority score for equal raw callsigns with different suffixes (also fixes #73)

This commit is contained in:
Marc Froehlich
2026-08-06 00:18:36 +02:00
parent eb38268be5
commit 084923366f
2 changed files with 28 additions and 29 deletions
@@ -227,12 +227,11 @@ public final class ScoreService {
ChatMember chosen = null; ChatMember chosen = null;
if (preferredCat != null) { if (preferredCat != null) {
for (ChatMember v : variants) { chosen = variants.stream()
if (v != null && v.getChatCategory() == preferredCat) { .filter(Objects::nonNull)
chosen = v; .filter(v -> isSameChatCategory(v.getChatCategory(), preferredCat))
break; .max(Comparator.comparingLong(ChatMember::getActivityTimeLastInEpoch))
} .orElse(null);
}
} }
if (chosen == null) { if (chosen == null) {
@@ -247,6 +246,14 @@ public final class ScoreService {
return representative; return representative;
} }
private static boolean isSameChatCategory(ChatCategory left, ChatCategory right) {
return left != null
&& right != null
&& left.getCategoryNumber() == right.getCategoryNumber();
}
/** /**
* Projects the immutable score snapshot back into ChatMember display fields so * Projects the immutable score snapshot back into ChatMember display fields so
* the normal station table can sort/filter by score without knowing the score * the normal station table can sort/filter by score without knowing the score
@@ -4291,32 +4291,24 @@ public class Kst4ContestApplication extends Application implements StatusUpdateL
} }
private ChatMember resolveChatMemberForTopCandidate(kst4contest.controller.ScoreService.TopCandidate c) { private ChatMember resolveChatMemberForTopCandidate(
kst4contest.controller.ScoreService.TopCandidate c
) {
String callRaw = c.getCallSignRaw(); if (c == null
ChatCategory preferredCategory = c.getPreferredChatCategory(); || c.getDisplayCallSign() == null
|| c.getPreferredChatCategory() == null) {
// 1) Prefer exact (callRaw + category) match return null;
synchronized (chatcontroller.getLst_chatMemberList()) {
for (ChatMember m : chatcontroller.getLst_chatMemberList()) {
if (m == null) continue;
if (m.getCallSignRaw() == null) continue;
if (!m.getCallSignRaw().equalsIgnoreCase(callRaw)) continue;
if (preferredCategory != null && preferredCategory.equals(m.getChatCategory())) {
return m;
}
}
// 2) Fallback: any variant with the same callsignRaw
for (ChatMember m : chatcontroller.getLst_chatMemberList()) {
if (m == null) continue;
if (m.getCallSignRaw() == null) continue;
if (m.getCallSignRaw().equalsIgnoreCase(callRaw)) return m;
}
} }
return null; /*
* Resolve the concrete active login by full callsign and category. Falling
* back to callSignRaw could select a different suffix in the same category.
*/
return chatcontroller.findActiveChatMember(
c.getDisplayCallSign(),
c.getPreferredChatCategory()
);
} }