From 7bd1e13660103234084a2a891f4d5698d92814c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20M=C3=BCller?= Date: Wed, 14 Oct 2026 17:16:13 +0200 Subject: [PATCH] reworked household and exemption dialogs --- .../tooling/banEvasion/BanEvasionDialogs.java | 88 ++++++++++++++----- 1 file changed, 65 insertions(+), 23 deletions(-) diff --git a/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/tooling/banEvasion/BanEvasionDialogs.java b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/tooling/banEvasion/BanEvasionDialogs.java index 8b22ce7..ce80a87 100644 --- a/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/tooling/banEvasion/BanEvasionDialogs.java +++ b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/tooling/banEvasion/BanEvasionDialogs.java @@ -51,7 +51,7 @@ final class BanEvasionDialogs { private record CaseView(BanEvasionRepository.CaseDetails details, Map banStates, Map households) { } - private record LinksView(String name, List links, List networks) { + private record LinksView(String name, List links, List networks, @Nullable Long household) { } private final BanEvasion appliance; @@ -120,15 +120,19 @@ final class BanEvasionDialogs { this.appliance.loadFor(admin, () -> this.appliance.query(connection -> new LinksView( this.appliance.repository().nameOf(connection, uuid), this.appliance.repository().linksOf(connection, uuid, LINK_LIMIT), - this.appliance.repository().recentNetworks(connection, uuid, RECENT_NETWORKS) + this.appliance.repository().recentNetworks(connection, uuid, RECENT_NETWORKS), + this.appliance.repository().householdsOf(connection, List.of(uuid)).get(uuid) )), view -> { List lines = new ArrayList<>(); + if(view.household() != null) lines.add(Component.text(view.name() + " gehört zu Haushalt #" + view.household() + ".")); if(view.links().isEmpty()) lines.add(Component.text("Kein anderer Account hat je einen Anschluss mit " + view.name() + " geteilt.")); view.links().forEach(link -> lines.add(Component.text(String.format("%s – %d Einträge an gemeinsamen Anschlüssen, %s bis %s%s", link.name(), link.sharedAttempts(), TIME.format(link.firstAt()), TIME.format(link.lastAt()), link.caseId() == null ? "" : " · Fall #" + link.caseId())))); List buttons = new ArrayList<>(); + if(view.household() != null) + buttons.add(button("Haushalt #" + view.household(), player -> this.openHousehold(player, view.household()))); view.links().stream() .filter(link -> link.caseId() != null) .forEach(link -> buttons.add(button("Fall #" + link.caseId() + ": " + link.name(), player -> this.openCase(player, link.caseId(), false)))); @@ -160,34 +164,72 @@ final class BanEvasionDialogs { void openExemptions(Player admin) { Instant now = Instant.now(); this.appliance.loadFor(admin, () -> this.appliance.query(connection -> this.appliance.repository().activeExemptions(connection, now)), exemptions -> { - List lines = new ArrayList<>(); - if(exemptions.isEmpty()) lines.add(Component.text("Keine aktiven IP-Ausnahmen.")); - exemptions.forEach(exemption -> lines.add(Component.text(String.format("%s · %s bis %s · %s%s", - exemption.network(), TIME.format(exemption.validFrom()), TIME.format(exemption.validUntil()), - exemption.createdByName() == null ? "?" : exemption.createdByName(), - exemption.note() == null ? "" : " · " + exemption.note())))); - + Component body = Component.text(exemptions.isEmpty() + ? "Keine aktiven IP-Ausnahmen." + : exemptions.size() + " aktive IP-Ausnahmen, zuerst endende oben."); List buttons = new ArrayList<>(); - exemptions.forEach(exemption -> buttons.add(button("Beenden: " + exemption.network(), player -> this.endExemption(player, exemption)))); + exemptions.forEach(exemption -> buttons.add(button( + String.format("%s bis %s%s", Networks.mask(exemption.network()), TIME.format(exemption.validUntil()), + exemption.note() == null ? "" : " · " + exemption.note()), + player -> this.openExemption(player, exemption)))); buttons.add(button("Zur Fallliste", player -> this.openList(player, CaseStatus.OPEN))); - show(admin, "IP-Ausnahmen", lines(lines), List.of(), buttons); + show(admin, "IP-Ausnahmen", body, List.of(), buttons); }); } + private void openExemption(Player admin, BanEvasionRepository.Exemption exemption) { + Component body = lines(List.of( + Component.text("Anschluss: " + exemption.network()), + Component.text("Gültig: " + TIME.format(exemption.validFrom()) + " bis " + TIME.format(exemption.validUntil())), + Component.text("Angelegt von: " + (exemption.createdByName() == null ? "?" : exemption.createdByName())), + Component.text("Notiz: " + (exemption.note() == null ? "–" : exemption.note())) + )); + show(admin, "IP-Ausnahme", body, List.of(), List.of( + button("Jetzt beenden", player -> this.endExemption(player, exemption)), + button("Zurück", this::openExemptions) + )); + } + void openHouseholds(Player admin) { this.appliance.loadFor(admin, () -> this.appliance.query(this.appliance.repository()::listHouseholds), households -> { + String text = households.isEmpty() ? "Keine Haushalte." : households.size() + " Haushalte, neueste zuerst."; + if(households.size() > LIST_LIMIT) + text += " Gezeigt werden die neuesten " + LIST_LIMIT + " – ältere über /accountLinks finden."; + List buttons = new ArrayList<>(); + households.stream().limit(LIST_LIMIT).forEach(household -> buttons.add(button( + "#" + household.id() + ": " + household.members().stream().map(BanEvasionRepository.Member::name).collect(Collectors.joining(", ")), + player -> this.openHousehold(player, household.id())))); + buttons.add(button("Zur Fallliste", player -> this.openList(player, CaseStatus.OPEN))); + show(admin, "Haushalte", Component.text(text), List.of(), buttons); + }); + } + + private record HouseholdView(BanEvasionRepository.Household household, Map banStates) { + } + + void openHousehold(Player admin, long householdId) { + this.appliance.loadFor(admin, () -> { + BanEvasionRepository.Household household = this.appliance.query(connection -> this.appliance.repository().household(connection, householdId)); + if(household == null) return null; + return new HouseholdView(household, this.appliance.banStates(household.members().stream().map(BanEvasionRepository.Member::uuid).toList())); + }, view -> { + if(view == null) { + admin.sendMessage(Component.text("Haushalt #" + householdId + " gibt es nicht (mehr).", NamedTextColor.GRAY)); + this.openHouseholds(admin); + return; + } + BanEvasionRepository.Household household = view.household(); List lines = new ArrayList<>(); - if(households.isEmpty()) lines.add(Component.text("Keine Haushalte.")); - households.forEach(household -> lines.add(Component.text(String.format("#%d: %s%s", - household.id(), - household.members().stream().map(BanEvasionRepository.Member::name).collect(Collectors.joining(", ")), - household.note() == null ? "" : " · " + household.note())))); + lines.add(Component.text("Angelegt " + TIME.format(household.createdAt()) + " von " + + (household.createdByName() == null ? "?" : household.createdByName()))); + lines.add(Component.text("Notiz: " + (household.note() == null ? "–" : household.note()))); + lines.add(Component.empty()); + household.members().forEach(member -> lines.add(accountLine(member.name(), view.banStates().get(member.uuid()), null))); List buttons = new ArrayList<>(); - households.forEach(household -> household.members().forEach(member -> - buttons.add(button("Aus #" + household.id() + " entfernen: " + member.name(), player -> this.removeMember(player, member))))); - buttons.add(button("Zur Fallliste", player -> this.openList(player, CaseStatus.OPEN))); - show(admin, "Haushalte", lines(lines), List.of(), buttons); + household.members().forEach(member -> buttons.add(button("Entfernen: " + member.name(), player -> this.removeMember(player, householdId, member)))); + buttons.add(button("Zurück", this::openHouseholds)); + show(admin, "Haushalt #" + householdId, lines(lines), List.of(), buttons); }); } @@ -290,13 +332,13 @@ final class BanEvasionDialogs { }); } - private void removeMember(Player admin, BanEvasionRepository.Member member) { + private void removeMember(Player admin, long householdId, BanEvasionRepository.Member member) { this.appliance.loadFor(admin, () -> this.appliance.query(connection -> { this.appliance.repository().removeFromHousehold(connection, member.uuid()); return true; }), done -> { - Main.logger().info(String.format("BanEvasion: %s removed from household by %s", member.name(), admin.getName())); - this.openHouseholds(admin); + Main.logger().info(String.format("BanEvasion: %s removed from household #%d by %s", member.name(), householdId, admin.getName())); + this.openHousehold(admin, householdId); }); }