仅客户端模组

RecEx 的功能只在客户端存在。专用服务端会装上这个 mod(否则 acceptableRemoteVersions 无法满足连接校验),但只会在日志里打一条警告。

端代理结构

@Mod 类 RecipeExporterMod 用 @SidedProxy 绑定两个实现:

端 类
客户端 com.bigbass.recex.proxy.ClientProxy
服务端 com.bigbass.recex.proxy.ServerProxy

两者都继承空的 CommonProxy(其 preInit 与 init 都是空方法体)。

端差异

行为 客户端 服务端
preInit 调 super.preInit(空) log.warn("This is a clientside only mod!")
preInit 其余 注册 KeyInputEventHandler 到 FML 事件总线 无
init 调 super.init(空)+ KeyBindings.getInstance() 未覆写 → 空

即服务端把唯一的 preInit 槽位用来打那条警告;热键注册(ClientProxy.init)与按键事件监听(ClientProxy.preInit)都只发生在客户端。

服务端 ServerProxy 里的这条警告就是判断"你装了个只能在客户端用的 mod"的唯一信号。

客户端独有代码

@SideOnly(Side.CLIENT) 只标注在 gui/GuiMain.java 一个类上。客户端专属的引用还包括:

  • net.minecraft.client.settings.KeyBinding(KeyBindings.java)
  • net.minecraft.client.Minecraft、net.minecraft.client.gui.GuiScreen(listeners/KeyInputEventHandler.java)
  • org.lwjgl.opengl.GL11、Tessellator、OpenGlHelper(graphics/GraphicsRender.java)

这些类在服务端从未被加载,因为没有任何服务端代码路径会触及它们——ServerProxy.preInit 只打日志。

网络侧

没有任何自定义网络消息。grep -rn "SimpleNetworkWrapper\|IMessage\|NetworkRegistry\|sendToServer\|FMLEmbeddedChannel" src/main/java 零命中——没有自建 channel、没有客户端→服务端包、没有服务端→客户端包。

唯一的网络类使用是 GuiMain 里复用原版聊天包做本地反馈:

mc.getNetHandler().handleChat(new S02PacketChat(new ChatComponentText("Started export")));

S02PacketChat 是原版 net.minecraft.network.play.server 的类,通过 handleChat 直接塞进本地聊天栏显示,并不经过服务器。

联机规则

@Mod(modid = RecipeExporterMod.MODID,
     version = Tags.VERSION,
     acceptableRemoteVersions = "*")

acceptableRemoteVersions = "*" 表示接受任何远端版本——这是客户端专用 mod 在多人游戏里能连上服务器的前提:服务器若装着这个 mod 也不会因为版本差异拒绝连接,服务器若没装也不影响。

ServerProxy 打的警告不阻止服务器加载该 mod,只提示它无用。

README.md 强调导出必须在已加载的存档/服务器中进行(“the export process happens while in a loaded world/server”),也就是说多人游戏里由客户端本地执行导出,导出的是该客户端自己内存中的配方注册表。

相关条目