ceshi 2 bug处理ok
This commit is contained in:
1 parent
b768ff1555
commit
faa3a22631
8 files changed
+314
-52
No files matched your search
+73
-9
@@ -32,6 +32,7 @@
|
||||
4. 在 modMain.py import 这些服务类即可(框架会自动实例化)
|
||||
================================================================================
|
||||
"""
|
||||
import time
|
||||
import mod.server.extraServerApi as serverApi
|
||||
|
||||
# ---- 网易API基础对象 ----
|
||||
@@ -57,6 +58,15 @@ GAI_FAN_EVENT = "GaifanRequest"
|
||||
# 相邻放置/厨具蘸油/寿司/裹粉/种水稻), 而非仅盖饭. ----
|
||||
ITEM_USE_ON_REQUEST = "ItemUseOnRequest"
|
||||
|
||||
# ---- 通用"手持物品右键功能方块"的 BlockUse 转换请求(与客户端 BLOCK_USE_REQUEST 一致).
|
||||
# 用于修复根因B: 手持可放置/可投掷物品(生肉/鱼/鸡蛋/胡萝卜/盘子/木条/寿司等)右键
|
||||
# 功能方块(支杆/挂肉钩/鸡窝/饲料槽/丸子机/石磨/炉灶/寿司方块)时, 原版先播放"放置/
|
||||
# 投掷"预览, 服务端 handleBlockUse 转换靠 ServerBlockUseEvent 触发, 但顺序不可保证,
|
||||
# 导致"想转换却放置/投掷了"。客户端对该(物品,功能方块)组合 ret 消闪后显式 Notify
|
||||
# 本事件, 服务端按被点方块 blockOwnerAll 路由到相应 handleBlockUse (与 TakeoutRequest
|
||||
# 同机制). ----
|
||||
BLOCK_USE_REQUEST = "BlockUseRequest"
|
||||
|
||||
# ---- 方块实体数据组件(计时持久化:记录开始时间戳,重启后继续计时) ----
|
||||
blockEntityDataComp = comp.CreateBlockEntityData(LevelId)
|
||||
|
||||
@@ -71,6 +81,15 @@ FACE_OFFSET = {
|
||||
5: (1, 0, 0),
|
||||
}
|
||||
|
||||
# ---- 右键转换成功后"取消同一右键配套的放置/吃"的时间窗口(秒) ----
|
||||
# 同一右键动作会同时触发 ServerBlockUseEvent(转换) 和 ServerItemUseOnEvent /
|
||||
# ServerItemTryUseEvent(手持方块物品的放置前摇 / 喝药吃食)。OnBlockUse 转换成功后
|
||||
# 会记录该玩家在此窗口内的后续 ItemUseOn/TryUse 应被取消(否则"转出了成品却又把
|
||||
# 手持方块放出来")。超过窗口即视为过期残留, pop 后直接放行, 避免"做完一个操作
|
||||
# 后任意位置放置都被吞"(统计: 空手右键只触发 BlockUse, 无配套 ItemUseOn 消费,
|
||||
# 若标记无时限会永久残留吞掉玩家下一次真实放置)。
|
||||
CANCEL_WINDOW = 0.5
|
||||
|
||||
|
||||
class FeatureDispatcher(BlueFoxServerSystem):
|
||||
"""
|
||||
@@ -225,6 +244,10 @@ class FeatureDispatcher(BlueFoxServerSystem):
|
||||
# (与 GaifanRequest 同机制, 统一覆盖全部 itemUseOn 转换)
|
||||
self.ListenForEvent(MOD_NAME, "ClientFeatureDispatcher",
|
||||
ITEM_USE_ON_REQUEST, self, self.OnItemUseOnRequest)
|
||||
# 10. BlockUseRequest —— 客户端拦截(手持可放置/可投掷物品, 功能方块)放置预览后,
|
||||
# 显式请求服务端执行对应 handleBlockUse(根因B: 防止"想转换却放置/投掷"了)。
|
||||
self.ListenForEvent(MOD_NAME, "ClientFeatureDispatcher",
|
||||
BLOCK_USE_REQUEST, self, self.OnBlockUseRequest)
|
||||
|
||||
def UnListenEvent(self):
|
||||
self.UnListenForEvent(serverApi.GetEngineNamespace(),
|
||||
@@ -251,6 +274,8 @@ class FeatureDispatcher(BlueFoxServerSystem):
|
||||
GAI_FAN_EVENT, self, self.OnGaifanRequest)
|
||||
self.UnListenForEvent(MOD_NAME, "ClientFeatureDispatcher",
|
||||
ITEM_USE_ON_REQUEST, self, self.OnItemUseOnRequest)
|
||||
self.UnListenForEvent(MOD_NAME, "ClientFeatureDispatcher",
|
||||
BLOCK_USE_REQUEST, self, self.OnBlockUseRequest)
|
||||
|
||||
# ============================================================================
|
||||
# 主入口1:玩家右键方块 → 按 blockOwner 路由到右键服务
|
||||
@@ -284,8 +309,9 @@ class FeatureDispatcher(BlueFoxServerSystem):
|
||||
handled = service.handleBlockUse(args)
|
||||
if handled:
|
||||
args['cancel'] = True
|
||||
self._cancelItemUse[playerId] = True
|
||||
print "[FD-BlockUse-DONE]", "player:", playerId, "hand:", _handItem, "block:", blockName, "svc:", service.__class__.__name__, "-> cancel=True, _cancelItemUse=True"
|
||||
# 记录时间戳(带窗口), 只取消同一右键配套的放置/吃; 过期残留自动放行
|
||||
self._cancelItemUse[playerId] = time.time()
|
||||
print "[FD-BlockUse-DONE]", "player:", playerId, "hand:", _handItem, "block:", blockName, "svc:", service.__class__.__name__, "-> cancel=True, _cancelItemUse=ts"
|
||||
return
|
||||
print "[FD-BlockUse-NOMATCH]", "player:", playerId, "hand:", _handItem, "block:", blockName, "-> 无匹配规则, 放行"
|
||||
|
||||
@@ -306,11 +332,12 @@ class FeatureDispatcher(BlueFoxServerSystem):
|
||||
"""
|
||||
playerId = args.get("playerId") or args.get("entityId")
|
||||
# 【关键】同一右键动作会同时触发 ServerBlockUseEvent(盛出/转换, 已由 OnBlockUse
|
||||
# 处理并设置 _cancelItemUse) 和 ServerItemUseOnEvent(手持方块物品的放置前摇)。
|
||||
# 若前一帧 OnBlockUse 已成功处理(盛出掉落/方块转换), 这里必须消费标记并
|
||||
# ret=True 取消放置, 否则"盛出了成品"却又"把手持的木碗/盘子放了出来"。
|
||||
# (与 OnItemTryUse 消费标记取消"吃/喝"是同一模式。)
|
||||
if self._cancelItemUse.pop(playerId, False):
|
||||
# 处理并设置 _cancelItemUse 时间戳) 和 ServerItemUseOnEvent(手持方块物品的放置前摇)。
|
||||
# 若在 CANCEL_WINDOW 窗口内, 这里必须消费标记并 ret=True 取消放置, 否则"盛出了成品"
|
||||
# 却又"把手持的木碗/盘子放了出来"。超窗口则视为过期残留, pop 后直接放行——绝不吞
|
||||
# 玩家之后的真实放置(日志: 空手右键完成后残留标记吞掉任意位置放置, 已修复)。
|
||||
_ts = self._cancelItemUse.pop(playerId, 0)
|
||||
if _ts and (time.time() - _ts) < CANCEL_WINDOW:
|
||||
args['ret'] = True
|
||||
print "[FD-ItemUseOn-CONSUME-CANCEL]", "player:", playerId, "item:", args.get("itemName"), "block:", args.get("blockName"), "-> ret=True 取消放置"
|
||||
return
|
||||
@@ -361,7 +388,8 @@ class FeatureDispatcher(BlueFoxServerSystem):
|
||||
handled = service.handleItemUseOn(args)
|
||||
if handled:
|
||||
args['ret'] = True
|
||||
self._cancelItemUse[playerId] = True
|
||||
# 时间戳(带窗口): itemUseOn 转换成功后, 同右手的后续 TryUse/放置也取消
|
||||
self._cancelItemUse[playerId] = time.time()
|
||||
return
|
||||
|
||||
# ============================================================================
|
||||
@@ -513,6 +541,39 @@ class FeatureDispatcher(BlueFoxServerSystem):
|
||||
return
|
||||
print "[FD-ItemUseOnRequest-NO-HANDLER]", itemName
|
||||
|
||||
def OnBlockUseRequest(self, args):
|
||||
"""
|
||||
客户端 ClientFeatureDispatcher 在拦截(手持可放置/可投掷物品, 功能方块)放置预览后,
|
||||
显式 NotifyToServer 发来的 BlockUse 转换请求(根因B). 因为客户端已 ret=True 把该
|
||||
组合的 ServerBlockUseEvent 吞掉(消闪), 服务端原本的 handleBlockUse 转换在这里补齐.
|
||||
|
||||
按被点方块名路由到 blockOwnerAll 里的服务(可能多个, 逐个 fallback, 第一个返回 True
|
||||
的处理成功, 与 OnBlockUse 相同). 各服务 handleBlockUse 内部自带 checkCooldown(同坐标/
|
||||
同物品), 即使与真实 ServerBlockUseEvent 重复触发, 冷却也会拦截第二次, 不双重消耗.
|
||||
"""
|
||||
playerId = args.get("playerId")
|
||||
x, y, z = args.get("x"), args.get("y"), args.get("z")
|
||||
blockName = args.get("blockName")
|
||||
if not (playerId and x is not None and y is not None and z is not None and blockName):
|
||||
return
|
||||
services = self.blockOwnerAll.get(blockName)
|
||||
if not services:
|
||||
print "[FD-BlockUseRequest-NO-SVC]", blockName
|
||||
return
|
||||
useArgs = {
|
||||
"blockName": blockName,
|
||||
"playerId": playerId,
|
||||
"entityId": playerId,
|
||||
"x": x, "y": y, "z": z,
|
||||
"face": args.get("face", 1),
|
||||
}
|
||||
for service in services:
|
||||
if hasattr(service, "handleBlockUse"):
|
||||
handled = service.handleBlockUse(useArgs)
|
||||
if handled:
|
||||
return
|
||||
print "[FD-BlockUseRequest-NO-HANDLER]", blockName
|
||||
|
||||
# ============================================================================
|
||||
# 主入口3:拦截物品使用(防止喝药水/吃食物等默认行为)
|
||||
# ============================================================================
|
||||
@@ -526,7 +587,10 @@ class FeatureDispatcher(BlueFoxServerSystem):
|
||||
"""
|
||||
playerId = args.get("playerId")
|
||||
print "[FD-ItemTryUse]", args.get("itemName"), "player", playerId
|
||||
if self._cancelItemUse.pop(playerId, False):
|
||||
# 仅在 CANCEL_WINDOW 窗口内消费(同一右键配套的吃/喝); 过期残留 pop 后放行,
|
||||
# 不吞玩家之后再吃/喝物品(根因A: 无时限标记残留会吞掉后续任意物品使用)。
|
||||
_ts = self._cancelItemUse.pop(playerId, 0)
|
||||
if _ts and (time.time() - _ts) < CANCEL_WINDOW:
|
||||
args['cancel'] = True
|
||||
return
|
||||
itemName = args.get("itemName")
|
||||
|
||||
Reference in new issue
Block a user