This repository has been archived on 2026-10-31. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files

99 lines
5.0 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package routers
import (
"context"
"sync"
)
var _ = sync.Mutex{}
var _ = context.Background
//
// 巡卫官(里希 / 15021021)盘查链路的最后一步 —— 开罚单出结果。
// <code>
// 客户端 PoliceExamineManager.lua:1163 gPoliceJobManager.cs:AskPoliceFine(pid, fineIdList)
// ⇒ C2S AskPoliceFineNpc(63548238)
// ⇒ 服务端必须回 S2C ShowReceiveRewardDetail(64145515) 且 Reason == ItemReason.PoliceFine(180001)
// ⇒ GameToClientImpl.lua:266 gPoliceJobManager:OnDropPoliceJobExp(msg.Reward)
// ⇒ PoliceExamineManager.lua:618 填 fineMoney / JobExpInfo
// ⇒ PoliceExamineManager.lua:601 ShowFineResult(罚款结果面板)
// </code>
// ⛑⛑ 为什么之前"开罚单没结果":AskPoliceFineNpc 既没进
// Enabled4229938MethodIds(硬规则 94)也没 handler ⇒ 客户端 await 卡死,
// 服务端从来没回过掉落帧 ⇒ needShowFineResult=true 但 OnDropPoliceJobExp
// 永远不触发 ⇒ ShowFineResult 一次都没被调用。
// ⛑ 反编译陷阱(又是同一条,见已作废结论):
// GameToClientImpl.lua:266 里写的是 if msg.Reason ~= ItemReason.PoliceFine then,
// 字面读是"非罚款才回调",但同一函数里 if msg.Reason ~= Mall or msg.Reason ~= MallBundle
// 恒为真会无条件 return ⇒ 字面读整段逻辑自相矛盾 ⇒ 反编译器把 == 翻成了 ~=。
// 真意:Reason == PoliceFine 时才走 OnDropPoliceJobExp。
// ItemReason.PoliceFine = 180001(dump.cs:1737137,enum ItemReason TypeDefIndex:32206)。
// 回滚 = 删本文件 + 从 GameRouter.cs 白名单删掉 MethodId.AskPoliceFineNpc。
//
// =================================================================================
// ① C2S AskPoliceFineNpc(63548238)
// =================================================================================
//
// 玩家在盘查面板里选完罪名、点「开罚单」时由 C# 侧发出来的那条。
// 形状:AskPoliceFine(ulong pid, object data)(dump.cs:673124),data 是 int[]。
// 极性 CSharpOnly ⇒ lua 没有 writer 可抄、count 编码不确定 ⇒ 不硬解析,
// 只把前 8 字节当 u64 pid 记日志,其余原样打 hex 留作取证。
// ⛑ 用 HandlerPacketKind.Both:INVOKE / NOTIFY 都不能漏。
// INVOKE 不回执 ⇒ 客户端 await 到超时(硬规则 94 的同一类坑)。
//
func GameRouter_PoliceFine_AskPoliceFineNpc(ctx context.Context, conn any, msg any) any {
// Router implementation for GameRouter_PoliceFine_AskPoliceFineNpc
var zero any; return zero
}
// =================================================================================
// ② S2C ShowReceiveRewardDetail(64145515) —— 手搓字节
// =================================================================================
//
// 推一帧 ShowReceiveRewardDetail(64145515, LuaOnly),Reason = PoliceFine(180001)。
// 载荷(照 Auto.Reader[308] / Auto.Reader[500],RPCDeserializeAuto.lua:37641 / 37521):
// <code>
// int32 Reason = 180001
// uint32 RewardTemplate = 0
// list FirstItemInfo = FF + int32 count + uint32* (空)
// cplx ExtraInfo = 00(null —— 必须 null!DropManager.lua:126 见 ExtraInfo 非空
// 就会拿 ExtraInfo.Pos 判"掉落物在地上"并 return,罚款结果就没了)
// dict Reward = FF + int32 count + { byte key, cplx RewardDetail }
// </code>
// RewardDetail(Reader[500])28 个字段全按声明顺序写,空的集合一律 FF + int32 0
// (Serializer.ReadList / ReadDict = peek byte FF + 原始 int32 count,不带 +1 偏置;
// 只有 ReadList7Bit / ReadDict7Bit 才走 Int7 +1 偏置)。
// SpiritTalentExpInfo 是 ReadComplex ⇒ 写 00。
// ⛑⛑ 关键判据(PoliceExamineManager.lua:618):
// <code>
// fineMoney = Σ RewardDetail.Money
// if RewardDetail.JobExpInfo[Police] then JobExpInfo = RewardDetail.JobExpInfo end
// if JobExpInfo or fineMoney &lt;= 0 then ShowFineResult() end
// </code>
// ⇒ JobExpInfo 里必须命中 Police(11300003),否则 money&gt;0 时永远不弹。
// 所以这里 money 与 exp 都给,双保险。
//
func GameRouter_PoliceFine_PushFineRewardAsync(ctx context.Context, session *GameSession, money float64, jobExp uint32, token context.Context) any {
// Router implementation for GameRouter_PoliceFine_PushFineRewardAsync
var zero any; return zero
}
// 照 Auto.Reader[308] / Auto.Reader[500] 手搓 ShowReceiveRewardDetail。
func GameRouter_PoliceFine_BuildFineRewardWire(ctx context.Context, money float64, jobExp uint32) []byte {
// Router implementation for GameRouter_PoliceFine_BuildFineRewardWire
return nil
}
// Serializer.ReadList 的空集合:peek FF + 原始 int32 count = 0。
func GameRouter_PoliceFine_EmptyList(ctx context.Context, w any) any {
// Router implementation for GameRouter_PoliceFine_EmptyList
var zero any; return zero
}
// Serializer.ReadDict 的空字典:peek FF + 原始 int32 count = 0。
func GameRouter_PoliceFine_EmptyDict(ctx context.Context, w any) any {
// Router implementation for GameRouter_PoliceFine_EmptyDict
var zero any; return zero
}