v1.0.5: Console fetch fix rolled across all 6 builds

Console /rules now fetches from Discord async (was returning hardcoded
fallback without attempting fetch). DIAG logging kept for observability.
All 6 builds at 1.0.5. CHANGELOG.md, INSTALL.md, ACTIVE_CONTEXT.md updated.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Claude (Chronicler #83 - The Compiler)
2026-04-13 18:23:44 -05:00
parent 98f4f5b82a
commit e21a348b3b
56 changed files with 116 additions and 18 deletions

View File

@@ -14,12 +14,13 @@ Rules mod config bug — iterating fixes for Otherworld (NC1, 1.20.1 Forge).
- All 3 versions compiled (1.21.1 NeoForge on NC1, 1.20.1 + 1.16.5 Forge locally)
- CurseForge project page copy pending from Chronicler
### Rules Mod Config Bug — IN PROGRESS 🔧
### Rules Mod Config Bug — FIXED ✅
- v1.0.1: Added `ModConfigEvent.Loading` handler (symptom fix, not root cause)
- v1.0.2: Switched `ModConfig.Type.SERVER``COMMON` (config now persists across restarts ✅)
- v1.0.3: Fixed 1.20.1 event bus registration (config events were on wrong bus), added section header warnings to generated config
- v1.0.4: Diagnostic build (1.20.1 only) — INFO-level `[DIAG]` logs in RulesCommand + DiscordFetcher to trace where config-to-fetch pipeline breaks
- **Status:** Config loads correctly (Loading handler confirmed channel ID). `/rules` still returns defaults. Awaiting Chronicler's v1.0.4 diagnostic log output from Otherworld.
- v1.0.2: Switched `ModConfig.Type.SERVER``COMMON` (config persists ✅)
- v1.0.3: Fixed 1.20.1 event bus registration, added section header warnings
- v1.0.4: Diagnostic build — revealed DIAG logs never fired
- v1.0.5: **Root cause found** — console `/rules` hit early return, never fetched from Discord. Fixed: console path now fetches async. DIAG logging kept for observability.
- **Status:** WORKING on Otherworld. All 6 builds at v1.0.5. Ready for CurseForge submission.
### Bridge Queue — CLEAR ✅
- All REQs have matching RES files

View File

@@ -10,7 +10,7 @@ buildscript {
apply plugin: 'net.minecraftforge.gradle'
version = '1.0.3'
version = '1.0.5'
group = 'com.discordrules'
archivesBaseName = 'discordrules'

View File

@@ -15,8 +15,25 @@ public class RulesCommand {
public static void register(CommandDispatcher<CommandSource> dispatcher) {
dispatcher.register(Commands.literal("rules").executes(context -> {
CommandSource source = context.getSource();
LOGGER.info("[DIAG] /rules invoked. isPlayer={}, token length={}, channel={}, messageId={}, isValid={}",
source.getEntity() instanceof ServerPlayerEntity,
ServerRulesConfig.BOT_TOKEN.get().length(),
ServerRulesConfig.CHANNEL_ID.get(),
ServerRulesConfig.MESSAGE_ID.get(),
ServerRulesConfig.isMessageIdValid());
if (!(source.getEntity() instanceof ServerPlayerEntity)) {
source.sendSuccess(DiscordFormatter.formatRules(RulesCache.getRules()), false);
LOGGER.info("[DIAG] Console path — fetching from Discord");
DiscordFetcher.fetchRulesAsync().thenAccept(fetchedRules -> {
String rulesText;
if (fetchedRules != null) {
RulesCache.updateCache(fetchedRules);
rulesText = fetchedRules;
} else {
LOGGER.warn("Discord fetch failed. Using fallback rules.");
rulesText = RulesCache.getRules();
}
source.getServer().execute(() -> source.sendSuccess(DiscordFormatter.formatRules(rulesText), false));
});
return 1;
}
ServerPlayerEntity player = (ServerPlayerEntity) source.getEntity();

View File

@@ -10,7 +10,7 @@ buildscript {
apply plugin: 'net.minecraftforge.gradle'
version = '1.0.3'
version = '1.0.5'
group = 'com.discordrules'
archivesBaseName = 'discordrules'

View File

@@ -15,8 +15,25 @@ public class RulesCommand {
public static void register(CommandDispatcher<CommandSourceStack> dispatcher) {
dispatcher.register(Commands.literal("rules").executes(context -> {
CommandSourceStack source = context.getSource();
LOGGER.info("[DIAG] /rules invoked. isPlayer={}, token length={}, channel={}, messageId={}, isValid={}",
source.getEntity() instanceof ServerPlayer,
ServerRulesConfig.BOT_TOKEN.get().length(),
ServerRulesConfig.CHANNEL_ID.get(),
ServerRulesConfig.MESSAGE_ID.get(),
ServerRulesConfig.isMessageIdValid());
if (source.getEntity() == null || !(source.getEntity() instanceof ServerPlayer)) {
source.sendSystemMessage(DiscordFormatter.formatRules(RulesCache.getRules()));
LOGGER.info("[DIAG] Console path — fetching from Discord");
DiscordFetcher.fetchRulesAsync().thenAccept(fetchedRules -> {
String rulesText;
if (fetchedRules != null) {
RulesCache.updateCache(fetchedRules);
rulesText = fetchedRules;
} else {
LOGGER.warn("Discord fetch failed. Using fallback rules.");
rulesText = RulesCache.getRules();
}
source.getServer().execute(() -> source.sendSystemMessage(DiscordFormatter.formatRules(rulesText)));
});
return 1;
}
ServerPlayer player = (ServerPlayer) source.getEntity();

View File

@@ -6,5 +6,5 @@ neo_version=21.1.65
mod_id=discordrules
mod_name=Discord Rules
mod_version=1.0.3
mod_version=1.0.5
mod_group_id=com.discordrules

View File

@@ -15,8 +15,25 @@ public class RulesCommand {
public static void register(CommandDispatcher<CommandSourceStack> dispatcher) {
dispatcher.register(Commands.literal("rules").executes(context -> {
CommandSourceStack source = context.getSource();
LOGGER.info("[DIAG] /rules invoked. isPlayer={}, token length={}, channel={}, messageId={}, isValid={}",
source.isPlayer(),
ServerRulesConfig.BOT_TOKEN.get().length(),
ServerRulesConfig.CHANNEL_ID.get(),
ServerRulesConfig.MESSAGE_ID.get(),
ServerRulesConfig.isMessageIdValid());
if (!source.isPlayer()) {
source.sendSystemMessage(DiscordFormatter.formatRules(RulesCache.getRules()));
LOGGER.info("[DIAG] Console path — fetching from Discord");
DiscordFetcher.fetchRulesAsync().thenAccept(fetchedRules -> {
String rulesText;
if (fetchedRules != null) {
RulesCache.updateCache(fetchedRules);
rulesText = fetchedRules;
} else {
LOGGER.warn("Discord fetch failed. Using fallback rules.");
rulesText = RulesCache.getRules();
}
source.getServer().execute(() -> source.sendSystemMessage(DiscordFormatter.formatRules(rulesText)));
});
return 1;
}
ServerPlayer player = source.getPlayer();

View File

@@ -10,7 +10,7 @@ buildscript {
apply plugin: 'net.minecraftforge.gradle'
version = '1.0.3'
version = '1.0.5'
group = 'com.firefrostgaming.rules'
archivesBaseName = 'firefrostrules'

View File

@@ -15,8 +15,25 @@ public class RulesCommand {
public static void register(CommandDispatcher<CommandSource> dispatcher) {
dispatcher.register(Commands.literal("rules").executes(context -> {
CommandSource source = context.getSource();
LOGGER.info("[DIAG] /rules invoked. isPlayer={}, token length={}, channel={}, messageId={}, isValid={}",
source.getEntity() instanceof ServerPlayerEntity,
ServerRulesConfig.BOT_TOKEN.get().length(),
ServerRulesConfig.CHANNEL_ID.get(),
ServerRulesConfig.MESSAGE_ID.get(),
ServerRulesConfig.isMessageIdValid());
if (!(source.getEntity() instanceof ServerPlayerEntity)) {
source.sendSuccess(DiscordFormatter.formatRules(RulesCache.getRules()), false);
LOGGER.info("[DIAG] Console path — fetching from Discord");
DiscordFetcher.fetchRulesAsync().thenAccept(fetchedRules -> {
String rulesText;
if (fetchedRules != null) {
RulesCache.updateCache(fetchedRules);
rulesText = fetchedRules;
} else {
LOGGER.warn("Discord fetch failed. Using fallback rules.");
rulesText = RulesCache.getRules();
}
source.getServer().execute(() -> source.sendSuccess(DiscordFormatter.formatRules(rulesText), false));
});
return 1;
}
ServerPlayerEntity player = (ServerPlayerEntity) source.getEntity();

View File

@@ -6,5 +6,5 @@ neo_version=21.1.65
mod_id=firefrostrules
mod_name=Firefrost Rules
mod_version=1.0.3
mod_version=1.0.5
mod_group_id=com.firefrostgaming.rules

View File

@@ -15,8 +15,25 @@ public class RulesCommand {
public static void register(CommandDispatcher<CommandSourceStack> dispatcher) {
dispatcher.register(Commands.literal("rules").executes(context -> {
CommandSourceStack source = context.getSource();
LOGGER.info("[DIAG] /rules invoked. isPlayer={}, token length={}, channel={}, messageId={}, isValid={}",
source.isPlayer(),
ServerRulesConfig.BOT_TOKEN.get().length(),
ServerRulesConfig.CHANNEL_ID.get(),
ServerRulesConfig.MESSAGE_ID.get(),
ServerRulesConfig.isMessageIdValid());
if (!source.isPlayer()) {
source.sendSystemMessage(DiscordFormatter.formatRules(RulesCache.getRules()));
LOGGER.info("[DIAG] Console path — fetching from Discord");
DiscordFetcher.fetchRulesAsync().thenAccept(fetchedRules -> {
String rulesText;
if (fetchedRules != null) {
RulesCache.updateCache(fetchedRules);
rulesText = fetchedRules;
} else {
LOGGER.warn("Discord fetch failed. Using fallback rules.");
rulesText = RulesCache.getRules();
}
source.getServer().execute(() -> source.sendSystemMessage(DiscordFormatter.formatRules(rulesText)));
});
return 1;
}
ServerPlayer player = source.getPlayer();

View File

@@ -1,13 +1,17 @@
# Rules Mod Changelog
## [1.0.5] - 2026-04-13 *(diagnostic + fix — 1.20.1 only)*
## [1.0.5] - 2026-04-13
### Fixed
- **Console path never fetched from Discord** — `/rules` from server console hit early return that only read from cache/fallback, never triggered `DiscordFetcher`. Console now fetches async like the player path.
- **DIAG logs placed after early exit** — moved `[DIAG]` logging before the player/console branch so it fires on every invocation regardless of source
### Note
- Only `firefrostrules-1.0.5-1.20.1-forge.jar` was built. Other versions remain at 1.0.3.
### Added
- `[DIAG]` INFO-level logging on every `/rules` invocation: isPlayer, token length, channel, messageId, isValid
- INSTALL.md note about testing from console vs in-game
### Applies To
- All 6 builds at 1.0.5 (3 firefrostrules + 3 discordrules)
---

View File

@@ -30,6 +30,14 @@ Rules mod is using default config values! Edit config/firefrostrules-common.toml
The config lives at `config/firefrostrules-common.toml` (COMMON type).
This loads once at startup and persists reliably across restarts.
## Testing /rules
Both console and in-game `/rules` will fetch from Discord. However,
for the best test, have a player run `/rules` in-game. The console
path fetches async and displays the result, but the in-game path
also shows the "Fetching latest rules..." message and applies the
per-player cooldown.
## Upgrading from v1.0.0 or v1.0.1
Old versions used `world/serverconfig/firefrostrules-server.toml`.