统一处理 OfflineDealer 离线事件(玩家在线与离线都必须生效),覆盖 _AOfflineDataDealer 的新增、改造与排查。用于离线奖励发放、出征/战斗结算、联盟申请与审批、订单回调、禁言状态变更等场景;当需求包含“玩家不在线也要处理”“OfflineRewardFunc.addPlayerOfflineReward”“_AOfflineDataDealer”时触发。
_AOfflineDataDealer 实现,避免漏处理、重复处理、漏注册。OfflineRewardFunc.addPlayerOfflineReward(...)。syncToClient() 决策:
true:落库并可客户端展示/领取。false:仅预处理,不入客户端领取链路。_preDeal(...) 只执行一次:由基类 preDeal 控制 hasPreDeal/markHasPreDeal。OfflineRewardFunc.addPlayerOfflineReward(...) 的上层不要再包 getLoaderMgr().safeCall(...),避免重复调度。addReward(...) + 离线手动写 PlayerOfflineRewardBO”分支时,默认收敛为 OfflineRewardFunc.addPlayerOfflineReward(...)。ByteBuffer(如 _rpc.req().get_buffer_xxx())时,优先使用 OfflineRewardFunc 的 重载,避免对象中转。ByteBuffersyncToClient=false;需要玩家领取用 syncToClient=true。.alpro(禁止改生成代码):
ServerProtocol/ProtocolScripts/Enum/OfflineRewardEnum.alproOfflineRewardObj 或 ServerObj 对应 .alproC_ 前缀protocol skill)OfflineDealer_XXX 继承 _AOfflineDataDealer,实现 getEnum/isValid/syncToClient/_preDeal。OfflineDataDealerMgr 构造中 regDealer(new OfflineDealer_XXX())。OfflineRewardFunc.addPlayerOfflineReward(...),不要直接调组件 addReward(...)。takeReward(...),通过 OfflineRewardTakeResult.setExtData(...) 返回。public class OfflineDealer_XXX extends _AOfflineDataDealer {
@Override
public EOfflineRewardEnum getEnum() {
return EOfflineRewardEnum.XXX;
}
@Override
public boolean isValid() {
return true;
}
@Override
public boolean syncToClient() {
return false;
}
@Override
protected void _preDeal(OfflineRewardInfo _info, NPPlayerContext _context) {
if (null == _info.getOfflineData()) {
return;
}
try {
// 1) readPackage 反序列化
// 2) 调用对应组件完成补偿/状态推进
} catch (Exception ex) {
USLog.error(_info.getUserData().getUSServer(), "OfflineDealer_XXX._preDeal - exception, cid={}", _info.getUserData().getCid(), ex);
}
}
}
.alpro 定义并重新生成协议。OfflineDataDealerMgr 已注册新 Dealer。_preDeal 空数据保护 + readPackage + 异常日志齐全。syncToClient 与需求一致(是否需要客户端领取)。OfflineRewardFunc.addPlayerOfflineReward(...),未绕开离线框架。C_ 枚举,导致展示链路不一致。_preDeal 做了非幂等副作用且无保护,重复登录时可能重复生效。takeReward,客户端拿不到展示扩展数据。.alpro、统一入口写离线、改动后需构建验证。