跳到正文
烈焰甘蔗Wiki

MessageMarketClosed(关闭市场 GUI)

事实基准:harvestcraft-1.3.14-GTNH.jar(MC 1.7.10 / Forge 10.13.4.1614)CFR 0.152 反编译源码。

基本信息

属性 值 来源
类 com.pam.harvestcraft.MessageMarketClosed MessageMarketClosed.java:14
实现接口 IMessage、IMessageHandler<MessageMarketClosed, IMessage>(自处理) MessageMarketClosed.java:15-16
判别器 2 PacketHandler.java:19
通道 harvestcraft(SimpleNetworkWrapper) PacketHandler.java:14
目标侧 Side.SERVER PacketHandler.java:19
方向 客户端 → 服务端 发送点在 GuiMarket.func_146281_b()
发送点 GuiMarket.java:93(func_146281_b,即 GUI 被关闭的回调) PacketHandler.INSTANCE.sendToServer(...)

承载的数据

toBytes / fromBytes(MessageMarketClosed.java:30-40)共 3 个 int,共 12 字节:

顺序 字段 类型 字节 语义
1 x int 4 市场方块 X
2 y int 4 市场方块 Y
3 z int 4 市场方块 Z

没有 itemNum,也没有 shouldClear —— 本包只做"退出交易态"这一件事。

坐标同样取自 tileEntityMarket.field_145851_c / field_145848_d / field_145849_e(SRG 名 → 未解析,语义佐证见 MessageMarketBuy)。

有一个无参构造器(MessageMarketClosed.java:21-22)供服务端反序列化使用。

服务端处理(onMessage,MessageMarketClosed.java:42-55)

  1. 取 EntityPlayerMP:ctx.getServerHandler().field_147369_b(SRG → 未解析)。

  2. 按坐标取方块实体,仅当 instanceof TileEntityMarket 时继续(MessageMarketClosed.java:44-45)。

  3. 退还槽 0 的物品(MessageMarketClosed.java:47-50):

    if (tileEntityMarket.func_70301_a(0) != null) {
        player.func_70099_a(tileEntityMarket.func_70301_a(0), 1.0f);
        tileEntityMarket.func_70299_a(0, null);
    }
    
    • func_70301_a(int) = TileEntity.getStackInSlot(int)(SRG → 未解析;语义佐证:被当作可空 ItemStack 用,且 != null 判空)。
    • player.func_70099_a(ItemStack, float) = EntityPlayerMP.dropItemAsItem(ItemStack, float)(SRG → 未解析;语义佐证:第二参数是 float,1.0f 表示不随机偏移)。
    • func_70299_a(int, ItemStack) = TileEntity.setInventorySlotContents(int, ItemStack)(SRG → 未解析;语义佐证:第二参数被置为 null,即清空槽)。

    即:槽 0 里的东西(客户付入的货币/待结算物)掉回地面,然后槽被置空。

  4. tileEntityMarket.setTrading(false)(TileEntityMarket.java:99)复位交易标志(MessageMarketClosed.java:51)。

  5. 无条件 player.field_70170_p.func_147471_g(x, y, z) 刷新方块(MessageMarketClosed.java:53)。

  6. return null(MessageMarketClosed.java:54):无应答包。

调用点

GuiMarket.func_146281_b()(GuiMarket.java:92-95):

public void func_146281_b() {
    PacketHandler.INSTANCE.sendToServer((IMessage)new MessageMarketClosed(
        this.tileEntityMarket.field_145851_c,
        this.tileEntityMarket.field_145848_d,
        this.tileEntityMarket.field_145849_e));
    super.func_146281_b();
}
  • func_146281_b 是 GuiContainer 的关闭回调(SRG → 未解析;语义佐证:super.func_146281_b() 同名调用,且方法体只做"通知服务端 + 调父类")。
  • 发送发生在 super 调用之前。
  • GuiMarket 是客户端 GUI,因此这是纯客户端 → 服务端的一次单向通知。

源码缺陷 / 观察

  • 本包是三个已注册包里唯一无条件可达且带状态清理副作用的包:它会真正丢弃/退回槽 0 内容。若因某种原因该包未送达(例如客户端在发送后立刻断线),槽内物品会滞留——但这属于原版关服清理路径,本条目未在游戏中验证。
  • 槽位检查硬编码为 0,没有遍历其它槽位;TileEntityMarket 的槽 0 是货币槽(takeEmeraldFromSlot / clearInventory 也只针对槽 0),语义一致。
  • 与 MessageMarketBuy 一样,服务端不校验坐标处的方块是否为玩家正在交互的市场,只用 instanceof TileEntityMarket 过滤。

相关条目

浏览全部模组