/* * AutoStore 模组客户端主入口(Fabric ClientModInitializer)。 * 负责初始化配置、启动领土数据服务、注册 tick 事件与聊天监听、注册命令。 * *
通过单例 {@link #instance()} 向其他模块提供访问入口。 */ package autostore.client; import autostore.client.command.AutoStoreCommands; import autostore.client.config.ConfigStore; import autostore.client.config.ExpansionConfig; import autostore.client.controller.ExpansionController; import autostore.client.gui.AutoStoreGui; import autostore.client.monitor.SubtitleChatMonitor; import autostore.client.territory.TerritoryDataService; import com.mojang.brigadier.CommandDispatcher; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents; import net.minecraft.text.Text; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.option.KeyBinding; import net.minecraft.client.MinecraftClient; import net.minecraft.client.util.InputUtil; @Environment(value=EnvType.CLIENT) /** * 客户端主入口(Fabric ClientModInitializer): * 负责初始化配置、启动领土数据服务、注册 tick 事件与聊天监听、注册命令。 * *
通过单例 {@link #instance()} 向其他模块提供访问入口。 */ public class AutoStoreModClient implements ClientModInitializer { /** 全局单例实例 */ private static AutoStoreModClient instance; /** 配置存储(读写 JSON 配置文件) */ private final ConfigStore configStore = new ConfigStore(); /** 领土数据服务(定时拉取邦国地图) */ private final TerritoryDataService dataService = new TerritoryDataService(); /** 自动扩地控制器 */ private final ExpansionController controller = new ExpansionController(this.dataService); /** 当前生效的扩地配置 */ private ExpansionConfig config; /** GUI 打开请求标记(在下一帧安全地打开界面) */ private boolean openGuiRequested; /** 一键唤出 GUI 的快捷键(默认 Ctrl+R,可在控制设置中修改) */ private KeyBinding guiKey; /** GLFW 键码:R 键 */ private static final int KEY_R = 82; /** GLFW 键码:左/右 Ctrl */ private static final int KEY_LEFT_CTRL = 341; private static final int KEY_RIGHT_CTRL = 345; /** * 客户端初始化入口: * 加载配置、以 60 秒间隔启动领土数据刷新、 * 注册每帧 tick(驱动控制器 + 延迟打开 GUI)、 * 注册聊天/游戏消息监听(转发给扩地监听器)、注册 /autostore 命令。 */ public void onInitializeClient() { instance = this; this.config = this.configStore.load(); this.dataService.start(Math.max(10L, this.config.refreshIntervalSeconds)); // 注册一键唤出 GUI 的快捷键(默认 Ctrl+R,可在"控制"设置中重新绑定) this.guiKey = KeyBindingHelper.registerKeyBinding(new KeyBinding("key.autostore.open", KEY_R, "category.autostore")); ClientTickEvents.END_CLIENT_TICK.register(client -> { block3: { this.controller.tick(); // Ctrl+R 组合键按下时请求打开 GUI(与 /autostore gui 命令走同一安全路径) while (this.guiKey.wasPressed()) { if (this.isCtrlDown(client)) { this.openGui(); } } if (this.openGuiRequested) { this.openGuiRequested = false; try { client.setScreenAndRender(new AutoStoreGui(this)); } catch (Throwable throwable) { if (client.player == null) break block3; client.player.sendMessage(Text.literal(("AutoStore GUI \u6253\u5f00\u5931\u8d25: " + String.valueOf(throwable))), false); } } } }); ClientReceiveMessageEvents.GAME.register((message, overlay) -> this.controller.monitor().onChat(message.getString())); ClientReceiveMessageEvents.CHAT.register((message, signed, profile, params, instant) -> this.controller.monitor().onChat(message.getString())); ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> AutoStoreCommands.register(dispatcher, this)); } /** 返回全局单例实例 */ public static AutoStoreModClient instance() { return instance; } /** 返回自动扩地控制器 */ public ExpansionController controller() { return this.controller; } /** 返回领土数据服务 */ public TerritoryDataService dataService() { return this.dataService; } /** 返回配置存储 */ public ConfigStore configStore() { return this.configStore; } /** 返回当前生效的扩地配置 */ public ExpansionConfig config() { return this.config; } /** 保存当前配置到磁盘 */ public void saveConfig() { this.configStore.save(this.config); } /** 返回扩地消息监听器 */ public SubtitleChatMonitor monitor() { return this.controller.monitor(); } /** 请求打开扩地 GUI(下一帧安全执行) */ public void openGui() { this.openGuiRequested = true; } /** 检查是否按下了 Ctrl 键(左或右) */ private boolean isCtrlDown(MinecraftClient client) { long handle = client.getWindow().getHandle(); return InputUtil.isKeyPressed(handle, KEY_LEFT_CTRL) || InputUtil.isKeyPressed(handle, KEY_RIGHT_CTRL); } }