From 1f844396bc315920089dd0a14e2bbe9cac1e963c Mon Sep 17 00:00:00 2001 From: Good627 <193092356+Good627@users.noreply.github.com> Date: Mon, 19 Oct 2026 00:44:47 +0300 Subject: [PATCH] fix(ally): return error when unable to fetch ally info in /eden ally view --- src/tel/eden/mod/EdenModClient.java | 12 +++++++++++- src/tel/eden/mod/chat/DiscordChatFormatter.java | 4 ++-- test/tel/eden/mod/chat/DiscordChatFormatterTest.java | 8 ++++++++ 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/tel/eden/mod/EdenModClient.java b/src/tel/eden/mod/EdenModClient.java index 443ca7b..567ad47 100644 --- a/src/tel/eden/mod/EdenModClient.java +++ b/src/tel/eden/mod/EdenModClient.java @@ -161,6 +161,8 @@ public final class EdenModClient implements ClientModInitializer { // Invalidates delayed party commands when the client changes server/world, so invites // queued for one session can never be delivered to the next connection. private final java.util.concurrent.atomic.AtomicInteger partyCommandGeneration = new java.util.concurrent.atomic.AtomicInteger(); + private final java.util.concurrent.atomic.AtomicLong allyViewRequestId = new java.util.concurrent.atomic.AtomicLong(); + private final java.util.concurrent.atomic.AtomicLong allyViewPendingId = new java.util.concurrent.atomic.AtomicLong(); // Deterministic per-occurrence index so rapid identical bank events stay distinct. // Short window: only the current burst counts, so stale earlier deposits can't // make different clients assign divergent seqs (which duplicated Discord posts). @@ -1124,6 +1126,7 @@ public void onGameFeedback(String message, String color) { @Override public void onAllyActivity(java.util.List entries) { + allyViewPendingId.set(0); boolean canManage = isChiefOwnerOrStrategist(); display(() -> DiscordChatFormatter.allyActivity(entries, canManage)); } @@ -1363,10 +1366,17 @@ private LiteralArgumentBuilder buildAllyCommand() { private void requestAllyView(FabricClientCommandSource source) { BridgeWebSocketClient current = socket; if (current == null) { - source.sendFeedback(notConnected()); + source.sendFeedback(DiscordChatFormatter.systemLine("Unable to fetch ally info, try again later.", ChatFormatting.RED)); return; } + long id = allyViewRequestId.incrementAndGet(); + allyViewPendingId.set(id); current.sendAllyActivityRequest(); + partyCommandExecutor.schedule(() -> { + if (allyViewPendingId.compareAndSet(id, 0)) { + display(() -> DiscordChatFormatter.systemLine("Unable to fetch ally info, try again later.", ChatFormatting.RED)); + } + }, 5, TimeUnit.SECONDS); } private CompletableFuture suggestMembers(CommandContext context, SuggestionsBuilder builder) { diff --git a/src/tel/eden/mod/chat/DiscordChatFormatter.java b/src/tel/eden/mod/chat/DiscordChatFormatter.java index da8b989..d85ef26 100644 --- a/src/tel/eden/mod/chat/DiscordChatFormatter.java +++ b/src/tel/eden/mod/chat/DiscordChatFormatter.java @@ -151,8 +151,8 @@ public static Component warCounts(int days, java.util.List entries, boolean canManage) { MutableComponent out = Component.empty().append(prefix(SHIELD)); - if (entries.isEmpty()) { - return out.append(Component.literal("No guild allies currently found.").withStyle(ChatFormatting.GOLD)); + if (entries == null || entries.isEmpty()) { + return out.append(Component.literal("Unable to fetch ally info, try again later.").withStyle(ChatFormatting.RED)); } out.append(Component.literal("Guild Allies (by inactivity):").withStyle(ChatFormatting.GREEN)); for (tel.eden.mod.net.AllyActivityEntry entry : entries) { diff --git a/test/tel/eden/mod/chat/DiscordChatFormatterTest.java b/test/tel/eden/mod/chat/DiscordChatFormatterTest.java index a645e51..e23d0f2 100644 --- a/test/tel/eden/mod/chat/DiscordChatFormatterTest.java +++ b/test/tel/eden/mod/chat/DiscordChatFormatterTest.java @@ -86,4 +86,12 @@ void allyActivityFormatsCleanlyWhenTagUnknown() { org.junit.jupiter.api.Assertions.assertTrue(text.contains("Unknown Guild — 10m ago")); } + + @Test + void allyActivityReturnsErrorWhenEmpty() { + Component component = DiscordChatFormatter.allyActivity(List.of(), false); + String text = component.getString(); + + org.junit.jupiter.api.Assertions.assertTrue(text.contains("Unable to fetch ally info, try again later.")); + } }