# -*- coding: utf-8 -*- """ ================================================================================ 客户端右键拦截系统(ClientFeatureDispatcher) ================================================================================ 【作用】 在客户端提前拦截"手持物品右键功能方块"的默认行为(吃/放置前摇), 消除服务端取消带来的"闪一下"视觉问题。与服务端 FeatureDispatcher 配合: 客户端先 cancel/ret, 再由服务端精确处理转换。 【监听事件】(全模组客户端唯一拦截点) 1. ClientItemUseOnEvent 手持白名单物品右键方块表面 -> ret=True 2. ClientItemTryUseEvent 手持直接吃物品(饭团/水煮蛋/豆腐) -> cancel=True 【注意】不拦 ClientBlockUseEvent(右键功能方块本体): 那会误拦"对炉灶放置 蒸笼/对空锅放置盘子"等合理放置。右键方块本体的转换由服务端 OnBlockUse 精确路由处理, 不在客户端提前 cancel。 【白名单来源】 共享数据 InterceptData.py (客户端/服务端同一份, 见其注释) ================================================================================ """ import mod.client.extraClientApi as clientApi ClientSystem = clientApi.GetClientSystemCls() clientComp = clientApi.GetEngineCompFactory() from ...BlueFoxTools.SpecialFunciton.BlueFoxSystem import BlueFoxClientSystem from .InterceptData import (ITEM_USE_ON_CANCEL, ITEM_USE_ON_CANCEL_BY_ITEM, SUSHI_BLOCKS, COATING_ITEMS) class ClientFeatureDispatcher(BlueFoxClientSystem): """客户端右键拦截: 白名单提前 cancel/ret, 消除闪烁""" def __init__(self, namespace, systemName): BlueFoxClientSystem.__init__(self, namespace, systemName) print "===== ClientFeatureDispatcher init =====" self.ListenForEvent(clientApi.GetEngineNamespace(), clientApi.GetEngineSystemName(), "ClientItemUseOnEvent", self, self.OnItemUseOn) self.ListenForEvent(clientApi.GetEngineNamespace(), clientApi.GetEngineSystemName(), "ClientItemTryUseEvent", self, self.OnItemTryUse) def Destroy(self): print "===== ClientFeatureDispatcher Destroy =====" self.UnListenForEvent(clientApi.GetEngineNamespace(), clientApi.GetEngineSystemName(), "ClientItemUseOnEvent", self, self.OnItemUseOn) self.UnListenForEvent(clientApi.GetEngineNamespace(), clientApi.GetEngineSystemName(), "ClientItemTryUseEvent", self, self.OnItemTryUse) # ============================================================================ # 入口1: 手持物品右键方块表面 -> 白名单组合才 ret (取消默认放置/吃) # ============================================================================ def OnItemUseOn(self, args): blockName = args.get("blockName") try: itemDict = args.get("itemDict") or {} itemName = itemDict.get("newItemName") or itemDict.get("itemName") except Exception: itemName = None if not itemName: return # 纯手持物品取消 (相邻放置/手持吃物品右键表面): 只看 item if itemName in ITEM_USE_ON_CANCEL_BY_ITEM: args["ret"] = True return if not blockName: return # 精确组合 (手持item, 被点block) pair = (itemName, blockName) if pair in ITEM_USE_ON_CANCEL: args["ret"] = True return # 寿司: 手持寿司方块物品 右键 自家寿司方块 -> 取消默认放置 if itemName in SUSHI_BLOCKS and blockName in SUSHI_BLOCKS: args["ret"] = True return # 裹粉: 手持生食材 右键 面粉块 -> 取消默认放置 if itemName in COATING_ITEMS and blockName == "rtdd:farineblock_3": args["ret"] = True # ============================================================================ # 入口3: 手持直接吃物品(长按/空中使用) -> cancel 默认吃 # ============================================================================ def OnItemTryUse(self, args): try: itemDict = args.get("itemDict") or {} itemName = itemDict.get("newItemName") or itemDict.get("itemName") except Exception: itemName = None # 饭团/水煮蛋/豆腐 在 ITEM_USE_ON_CANCEL_BY_ITEM 里(EAT_ITEMS) if itemName in ITEM_USE_ON_CANCEL_BY_ITEM: args["cancel"] = True # 注: 客户端系统需在客户端进程被实例化。modMain 只能在服务端 import 服务端 # 系统; 客户端系统由 BlueFox 框架自动注册其子类。为确保本类被加载, 需在 # modMain 客户端分支(IsInServer()==False)里 import 本模块。