Files
ft/CodexOutput/upserver/阶段4B2字段与模块加载合同-正式版-2026-09-23.md

25 KiB
Raw Blame History

阶段4B2字段与模块加载合同(正式版)

日期:2026-09-23。状态:已审设计合同,供检查点2继续实施;不代表已实现或验收。正文合并修订2附件与D1/D2差异修订,依据差异裁决生效。后续实施首读本正式版;原受审附件及其hash保留供历史核对,不再作为D1/D2的当前规则。其余合同沿用修订2方案及原实施批准。本清单限定于当前PlayerData.LoadPlayerData/LoadPlayerDataNew同步消费链和登录标记,不等于全项目玩法存档盘点。其余按需玩法读取由4B3/4C另审,受控入口不启动那些流程。

1. 统一规则

  • 所有适配器为本次epoch产生独立的加载状态;不与原快照、上次账号、静态默认字典或其他模块共享可变集合。
  • D<K,V>为JSON对象解码到相应字典,L<T>为JSON数组,T为现有保存DTO的序列化字段形状。必须先检查token类型、重复属性、null、数值溢出与有限浮点数;禁止靠Json.NET字符串/浮点到整数的宽松转换判合法。键转为整数/枚举后重复也拒绝。
  • 原保存DTO有构造副作用时用新文件中的同形状纯数据结构解码,不能在Decode里Resolve服务;应用时仅传已解码字段。不得反射复制真实模块全部字段,配置/服务/订阅不属于存档。
  • 已存在的可选键坏值也使整个加载Malformed。缺失才生成下面列明的空态。JSON文字null不是缺失;集合可以为空但不能为null,活动对象缺失由Missing状态表达,不向旧loader传"null"。
  • 未识别顶层键保留原快照、计数为Unconsumed,不送给总入口或参与主档判定。注释掉的MonthCardData、ChallengeData、TargetEventPackData、PokerScoreData、EventPartnerData、EventBreak/EventCan不算当前消费键。
  • 配置引用只验证该加载步骤会解引用的表项;0作为尚未激活/未选择的明确哨兵保留,不统一要求所有活动ID都为正。活动已失效但载荷可解析时保持Dormant,不启动活动、不自动清档/写回。
  • 数字紧凑串按InvariantCulture且无千位分隔解析;时间兼容按O(RoundtripKind)优先,之后仅允许本次捕获的CurrentCulture与InvariantCulture的TryParse;若两者成功却得到不同日期,返回UnsupportedSchema,不猜测。newData中日期含分隔逗号导致槽数不是19同样拒绝。既有文化存档的不兼容必须明确报错,未来迁移另审,不改PF解析规则。

2. 主档格式:完整核心字段,不再使用“任一特征键命中”

支持两种已知布局:

  1. 现代格式:顶层NewPlayerDataDic为D<string,string>,其newData恰好19个逗号槽;每槽必须可解析。只有NewPlayerDataDic而没有完整newData,不推断为新档。
  2. 完整旧格式:下表的19个顶层键全部存在且合法。不支持用部分旧键加部分新槽拼出主档。NewPlayerDataDic内的旧散键只作一致性校验,不单独授权完整档;缺核心时返回MissingCore,要求显式迁移,不造默认资产。

两格式同时完整存在时逐字段比较规范值,任意不同返回ConflictingRepresentations。现代格式存在但损坏,不回落旧格式。现存非完整旧格式只要包含与现代格式重叠的字段,也逐字段检查一致;不能让残余冲突值被静默覆盖。

槽 顶层旧键 NewPlayerDataDic旧散键 类型/主档规则
0 Lv lv Int32,>=1
1 Gold gold UInt64
2 vipAllScore vipS Int32,>=0
3 Energy energy Int32,>=0,坏/负值拒绝而非改0
4 Diamond pearl Int32,>=0;源码PlayerData.Pearl常量实际是Diamond
5 Magnification mag Int32,>=0
6 EquipRodID rodID Int32,必须在固定TbRodData存在,不以默认杆掩盖坏档
7 LastEnergyRecoveryTime EnergyTime 时间,按§1解析规则
8 RewardNewMap rewardNewMap Int32原始位集;保持有符号位表示,不按普通计数限制
9 EnergyRM energyRM Int32,>=0
10 GoldRM goldRM UInt64
11 DiamondTrue diamond Int32,>=0;不能错认成Diamond
12 CurrentMapId cMapID Int32;0为原入口哨兵,非0须存在于TbMapData
13 LastMapId lMapID 同上
14 FishingFrequency FF Int32,>=0
15 AllFishingFrequency AFF Int32,>=0
16 HeistGameCount HGC Int32,>=0
17 BombGameCount BGC Int32,>=0
18 FishHuntGameCount FHGC Int32,>=0

这是一项比原PF加载更严格的KV准入提案,不声称所有历史PF档都兼容;不使用正式账号猜测规则。本阶段只用合成完整档/残档验证。凡不符合支持布局的真实档将来必须走单独迁移,不自动建档。

3. 全部当前消费键登记及优先级

表中的模块编号也用于产物诊断。主档19键及NewPlayerDataDic由M01/M02消费;其余顶层键如下,均可缺失但不可损坏。

模块 顶层键/模式 格式合同
M01 玩家附加 NewRodList、SeasonId、IsOpenAppraise、InfiniteBuildingData L、Int32、存在标记(任意非null字符串,仅存在性转true)、原始字符串(加载期不解释建筑载荷)
M03 鱼/杆/地图 RodData、RodLevelData、FishSwimToMap、FishSwimToMapCount、MapProgress、HonorLevelData D<Int32,Int32>;整型负哨兵按原类型保留,不误把所有键看成表ID
M03 鱼/杆/地图 InitRodAccessoriesData、Map_5_{mapId}、Map_{mapId}、LuckDataDic RodGSAData形状;D<Int32,string>每项鱼紧凑串;旧D<Int32,FishWeightData>;D<string,float>
M04 商店 ShopPackBuyCount、ShopAllPackBuyCount、ShopGiftBuyCount D<string,Int32>、D<Int32,Int32>、D<Int32,Int32>
M04 商店 Voucher、ChainPackDataNew、VIPAdPackData、TurntableAdData、BuyData、AdvertAllCount Int32、DailySignEvent、AdvertData、DailySignEvent、L、D<Int32,Int32>
M04 商店 DiamondShopRefreshCount、DiamondShopRefreshTime、DiamondShopItemRecords、BlackFridayCouponDate Int32、时间、D<Int32,ItemShopRecord>、优惠券紧凑格式
M05 活动基础 LimitedTimeEventDic、FixedTimeEventDic、ETDropAfterDropDic、RankTargetCount、WheelLevelCount D<Int32,LimitedTimeEvent>、D<Int32,FixedTimeEvent>、后三者D<Int32,Int32>
M05 活动基础 TurntableRoll、WheelOperateCount、AllWheelOperateCount、WheelLevelFreeCount、PVPToken Int32
M06 增益 BuffDataList、TargetBuffDataList、FishDailyBuff、GlobalBuffDataList D<Int32,FishBuffTimeData>、L、FishBuffTimeData、D<Int32,FishBuffTimeData>
M07 营地 IsFix、IsOpenSkyscraper、CampDataDic bool、精确0/1字符串、D<string,Int32>;不能调用SetIsFix默认isSave=true
M08 成就 AchievementData D<ConditionType,AchievementData>
M09 钓鱼箱 FishingBoxData 原FishingBoxData的序列化形状,实际加载FishingBoxOpenNum;FishingNewBoxs按§5重置
M10 引导 GuideSaveData、GuideSaveDataNew D<string,GuideSaveData>;新格式`group
M11 战令 BattlePassRecordTask、BattlePassRecord、BattleTask 新组合紧凑格式;旧BattlePassRecord/旧BattleTask JSON形状
M12 签到 MonthlySignEvent MonthlySignEvent形状;dailySignEvent不允许null
M13 触发礼包 TriggerPackDataList、GiftVIPDData、FixedTimeShopDic L、D<string,GiftVIPDData>、D<Int32,FixedTimeEvent>
M14 公会加载态 ClubSignin、LureDonateData、IsOpenClubRed 时间或空字符串(无签到)、LureDonateData形状、存在标记(非null字符串→false)
M15 挑战 FishingChallengeData 现有InitChallengeData(string)的DTO形状,仅数据解码,不启动挑战
M16 宝箱链礼包 OfferChainsChestData TOfferChainsData
M17 Disco礼包 OfferDiscoPartyManager TOfferDiscoPartyData
M18 伙伴 EventPartnerGatherData EventPartnerGatherData,不能调用带Save的ClearData
M19 消块 EventCubeMeltData EventCubeMeltData
M20 活动礼包 EventPackData 现有LoadEventPackData的数据形状;配置派生仅在Apply前解码计算
M21 储蓄罐 PiggyBankPackData PiggyBankPackData.Data;旧兼容redirectID=0规范为4055001并检查配置存在,不写回
M22 砍价礼包 GeneralEventPackData GeneralEventPackData;redirectID须存在且PackType=3才可交BargainPackData,否则UnsupportedSchema,不能静默丢弃
M23 足迹 FootPrint UInt64位集,完整值由新增私有ulong受控字段保存;现有Int32枚举仅提供低32位视图,不代表全部64位;不调用UploadData,不拒未声明高位
M24 靶场 EventShootingRangeData EventShootingRangeData.RawData
M25 药水 epdk EventPotionData
M26 弹珠 epbdk EventPinballData
M27 刮刮卡 estdk EventScratchTicketData
M28 节日礼包 ThanksGivingPackData、ThanksGivingPackMigrationData 各自4个Int32逗号槽:EventId,RedirectId,TokenProgress,ChainProgress
M29 Pinata EventPinataPackData EventPinataPackData;仅SetData对应数据赋值,不GetFreshPinataPackData
M30 挖矿加载壳 无 InitServerData当前忽略字典,仅在_dataModel为空时new;KV必须替换成新未启动模型,不能复用旧实例
M31 登录附属 MMTest、hwGoogle、hwFacebook、Apple、EAccoutUrl、TapJoy_Diamond MMTest规则见主方案;渠道精确0/1;D<string,string>;Int32余额。额外当前非游客渠道名只允许来自测试身份枚举,不能任意字符串入意图

3.1 NewPlayerDataDic的附属键

键 解析及覆盖语义
vipL Int32,Int32记录以`
ld 恰好3个有限float,以`
ad `ConditionType:value1
bd Int32,Int32记录以;连接;替换FishingBoxOpenNum,空串为空字典
ct、rt Int32:Int32记录以,连接;分别替换ETDropAfterDropDic、RankTargetCount,空串为空字典
LDD 旧JSON格式同LuckDataDic;与ld共存时先分别严格解码,规范值必须一致,否则冲突
AD 旧JSON为D<ConditionType,string>,每个字符串恰好Id|Target|day三槽,按Int32/UInt64/Int32、InvariantCulture严格解析;不同于顶层AchievementData的对象值。键须为已定义ConditionType,归一化后重复键拒绝。与ad/顶层共存时全部先独立严格解码,共有字段冲突则ConflictingRepresentations;一致按ad > AD > 顶层AchievementData选择并整字典替换,不合并旧账号条目

NewPlayerDataDic中的其余旧散键为§2的19项,全部校验。其它内部键保留为Unconsumed,不能参与初始化。

同义表示同时出现时不依赖Dictionary迭代顺序:核心先作一致性检查;其余 Map_5_x与Map_x、GuideSaveDataNew与GuideSaveData、BattlePassRecordTask与旧战令、ld/LDD/LuckDataDic、ad/AD/AchievementData、bd/FishingBoxData、ct/ETDropAfterDropDic、rt/RankTargetCount全部先分别严格解码,共有字段不同则Conflict;一致时选新格式,缺新则选旧。新引导替换整个字典,不把未出现在新格式的旧组静默合并。

3.2 紧凑格式与动态键边界

  • Map动态后缀必须正整数且在固定TbMapData内;同一数值的非规范十进制后缀拒绝。只匹配Map_5_数字与Map_数字,其它前缀属于Unconsumed。鱼记录支持源码现存5/9槽两种:5槽Level/MaxG/TotalCard/TotalNum/NewFish;9槽采用0/1/5/6/7这五个位置,其余兼容槽必须保留但不作为当前字段。所有被消费槽严格解析。
  • BattlePassRecordTask恰好两个#分段(即一个分隔符);第一段按现存BattlePassRecord 7个|字段解析(ID、Level、Exp、BuyVipToastIndex、IsUnlockVip、两份逗号ID列表),第二段按BattleTask 5个|字段(两份key:value逗号字典、loginDays逗号列表、两个截止ticks)。空集合串允许,记录字段数量不符拒绝;ticks须在DateTime范围内。以受审源码SerializeObject顺序为准,不能改存档格式。
  • BlackFridayCouponDate支持7槽旧格式或9槽新格式,6个日期分量必须组成合法DateTime;旧格式RedirectId=0/IsBought=false,新格式末位只允许0/1;8槽或多余槽拒绝。
  • ThanksGiving两种键都严格4槽;不能复用原Data.Deserialize的“错误时打印原值并返回零对象”容错。
  • 所有分隔集合末尾空记录按当前保存器的Join格式:空整体表示空集合,非空整体中的空记录/重复key为Malformed。不得日志输出被拒绝的原字符串。

4. 无副作用加载路径及写点裁决

修订2不再调用旧LoadPlayerData/LoadPlayerDataNew总入口,以下旧路径仅为提取数据规则的依据。

旧同步链/风险点 KV路径明确处置
CompareDatas的PF×PlayerPrefs合并与写回 完全不调用;只有4B1不可变快照和独立解码状态
InitData MMTest缺失/旧格式两处写+SetMMTestValue写 内存规范化及本epoch意图;不运行GEvent统计
Agg InitData补渠道、AvatarToPF写EAccoutUrl 受控仅纯标记合并;不运行真实SDK和Login返回后的头像/邀请链
Camp.SetIsFix(isSave:false) 原路径本次抽查安全,但KV直接赋私有字段,禁止误调用默认true
PlayerData.energy相关setter、体力恢复、SavePlayerData 直接给energy/_lastEnergyRecoveryTime等赋值,不调用SetEnergy/恢复/保存或事件发布
PlayerFishData InitData中的GEvent、地图派生调用 纯decode后整组替换;不统计、不发解锁提示
FishingEventData Init/SetEvent/目标/排名恢复 不调用;只替换数据和置空运行派生对象;LimitedTime按冻结时钟做纯过滤
Potion/Pinball/Scratch GetDataFromServer→Init 不调用;只解析并替换原始数据,运行配置状态未激活
Pinata.LoadData→GetFreshPinataPackData 不调用刷新;只替换纯数据,奖励、红点不启动
Bargain.LoadData→AddGiftFaceUIForce 不调用旧函数;只替换_data
Partner.ClearData→SaveData、Cube.ClearData、活动默认建档 不借这些函数Reset;新增纯空态替换
Shop.Init、BattlePass刷新任务/领奖、Signin刷新 不调用;加载不等于功能激活
Digging.InitServerData之后的模型InitServerData异步服务 本阶段只new空模型;禁止调用异步业务初始化
所有旧LoadData带ELog/Debug输出原JSON、TryParse吞错 新KV纯入口只用结构化诊断;不能借用其日志和容错路径
PlayFabMgr定时/暂停/销毁/普通/立即写 主方案guard前置拦截;违反计数导致受控加载失败

因此无需声称未经读取的所有玩法保存调用都被4B2重构。受控路径只允许运行附件的纯适配器;未来新调用/活动激活属于范围变化,先补方案再审。

5. 每模块空态、替换职责和精确文件清单

以下路径相对Client/Assets/Scripts/。每行都要实现/测试 DecodeForKVLoad(纯)、ResetForKVLoad、ReplaceFromKVDecoded;同一类可合并方法但不能遗漏状态。固定配置/注入服务引用保留;旧账号的已加载数据和从它派生的缓存必须清除。无玩法运行时的订阅/计时器要求为零,非零拒绝准入,不在此模块中擅自扩展玩法退出。

ID 文件(白名单) 缺键/撤销时的明确空态与替换集合
M01 DataCenter/DataCenter.PlayerData.cs NewPlayerDataDic/vipScoreDic/newRodList新空集合;19核心字段置为不可发布空态(数值0、时间MinValue),合法Apply后全部由核心档替换;seasonId=0、IsOpenAppraise=false、InfiniteBuildingData=null;vip/vipLastScore/PriceLv=0、priceLevel=null,地图缓存0。空态仅用于未就绪,不允许作为新档进入玩法
M02 DataCenter/DataCenter.SmallGame.cs 三个游戏次数=0;加载派生的对手/预选缓存空、当前对手null;不触发取对手或网络
M03 DataCenter/DataCenter.PlayerFishData.cs;DataCenter/PlayerFishDataRod.cs mapFishData/mapProgress/fishData/fishCardData/rodData/rodLevelData/fishSwimToMap/fishSwimToMapCount/LuckDataDic/_honorlevel全新空集合;rodAccessoriesData=null;InitBotLuck/InitFishLuck/BotCount=0;所有地图/杆加载派生开关false、选择0。缺配件不调用默认建档方法
M04 DataCenter/DataCenter.PlayerShopData.cs;UI/Shop/BlackFridayCouponData.cs 购买/广告/钻石商店字典和buyData空,Voucher=0,ChainPackData/VIPAdPackData/TurntableAdData=null,刷新计数0/时间MinValue;CouponData原对象中账号字段归零/MinValue/false;SKU及配置引用不替换,不触发IAP查询
M05 DataCenter/DataCenter.FishingEventData.cs;DataCenter/FishingEvent_PVPData.cs 限时/固定/目标/排名/WheelLevelCount全新空集合;TurntableCoupon取固定表InitWheelTicket,WheelOperateCount/AllWheelOperateCount/freecount/PVPToken=0;目标队列、rankInit/rankTarget、wheelInit/wheelLevel和活动实例引用null;解锁集合空。缺活动是未激活,不启动Init
M06 DataCenter/BuffDataCenter.cs map/target/global buffs和showFishBuffIds空,fishDailyBuff=null
M07 Camp/CampDataMM.cs CampDataDic空,_isFix=false、_isOpenSkyscraper="0";_id=101、PreID/AreaIndex/AreaStep/AreaId/AreaStepCount/TimelineId=0;当前场景/StepInfo/AreaList派生引用清空,不加载建筑/资源
M08 DataCenter/AchievementDataManager.cs _achievementDatas整字典替换;空态空字典,不继续合并旧条目
M09 DataCenter/FishingBoxData.cs FishingNewBoxs/FishingBoxOpenNum新空字典,不领取、生成箱子或发布奖励
M10 DataCenter/DataCenter.GuideData.cs GuideSaveDataDic空、curSaveData/curDefine/curGroupDefine/popupPanelNode=null;配置指引定义保留,不启动引导
M11 DataCenter/BattlePassData.cs BattlePassRecord新构造态(ID/Exp/BuyVipToastIndex/IsUnlockVip/InflationRate=0,Level=1,三份奖励列表空),BattleTask新零态且集合显式空;不Refresh/Save/领奖
M12 DataCenter/DataCenter.SignupData.cs _monthlySignEvent=null;存在时替换,不读取会刷新日期/保存的dailySignEvent getter
M13 DataCenter/DataCenter.TriggerPackData.cs triggerPackList/giftVIPDData/fixedTimeShopDic新空;不Init、不注册条件事件
M14 Services/ClubService.cs signTime=null、lureDonateData新零态、IsOpenClubRed=true;只处理三项加载态,不登录公会/取网络成员信息
M15 DataCenter/FishingChallengeManager.cs 原始挑战存档对象null,挑战运行态未激活;有数据直接替换,不调用无参InitChallengeData
M16 DataCenter/OfferChainsChestManager.cs OfferChainsData=null;ValidIds空、活动派生引用null,不进场、不改FirstOpen
M17 DataCenter/OfferDiscoPartyManager.cs OfferDiscoPartyData=null、ValidIds空、活动派生引用null;FreeTime回构造值1
M18 DataCenter/EventPartnerGatherManager.cs GatherData=null、_isEventDataChanged=false、当前伙伴运行引用null;PartnerInfoManager/RobotInvitationSystem替换为空的新实例,不调用含Save的ClearData
M19 EventCubeMelt/Data/EventCubeMeltManager.cs EventData=null、_isInit=false、活动运行引用null;不调用Init/ClearData
M20 DataCenter/EventPackData.cs _data是单个Data结构,空态四字段currentEventID/purchaseCount/VIPLvlWhenEventActivate/redirectID全0;存在时整体替换,活动有效且redirectID=0时沿用4054001的旧兼容映射并校验表,不TriggerEventPack、不发布红点
M21 DataCenter/PiggyBankPackData.cs _data=null,存在时用严格解码后的对象替换;不UpdateData
M22 DataCenter/BargainPackData.cs _data=null,存在时直接赋对象,不经会触发FaceUI的LoadData
M23 Services/FootPrintService.cs 新增私有ulong完整KV位集及internal只读验证访问;Reset完整字段和_footPrint同时归零,Replace完整保留UInt64并用显式unchecked低32位投影到_footPrint(注释说明视图位宽)。公开EFootPrint : int、IFootPrintService及旧LoadData/UpdateFootPrint/UploadData不改;受控范围禁止旧保存,完整值的4B3消费另审,不承诺退出受控后可玩
M24 UI/ShootingRange/ShootingRangeData.cs _data显式Missing/null,存在时替换RawData;未就绪不得读会解引用_data的游戏getter
M25 DataCenter/EventPotionDataManager.cs m_PotionData=null,运行关卡/表缓存回未激活;存在只装载原始数据,不调用Init
M26 DataCenter/EventPinballDataManager.cs m_PinballData=null,运行关卡/表缓存回未激活;同上
M27 DataCenter/EventScratchTicketDataManager.cs m_ScratchTicketData=null,运行关卡/表缓存回未激活;同上
M28 UI/Shop/ThanksGivingPackData.cs;UI/Shop/ChainPackWithProgressData.cs 两个实例的_data各自Missing/null,无共享可变对象;不做礼包迁移/领奖
M29 UI/PinataPack/EventPinataPackDataManager.cs 同一容器的EventPinataPackData实例直接将EventID/PinataMainID/PurchasedCount三个自动属性全置0,然后由已解码状态全量赋值;不调用AddPurchasedCount或GetFreshPinataPackData,不替换容器注册、不反射。Decode不得new该数据类(其字段初始化会Resolve表),用纯三整数DTO
M30 SandDig/DiggingGameManager.cs _dataModel替换全新未初始化实例、_broadLogic=null、游戏状态Normal;已有玩法资源/音频/board时拒绝受控准入,不在此释放活跃玩法资源
M31 Services/UserService.cs及其新增KV partial;Services/AggUserService.cs 本次副本/意图/绑定集合独立,MMTest=0、EAccoutUrl空、TapJoy余额0;真实SDK集合不作跨账号复用;PF公开身份默认不因受控加载而变成已授权

上表的“回未激活/派生引用”限定为相应loader能够写入或由该存档直接缓存的状态,不授权全面重构模块。实现需将各行定义映射到字段并在测试中显式断言,不能只测一个代表字段。若源码出现清单外的同步消费或状态写入,视为设计差异先补审,不能自动扩白名单。

固定Apply顺序:M01基础核心→M02→M03→M04→M05→M06→M07→M08→M09→M10→M11→M12→M13→M14→M15…M30→M31通知。全部Reset先执行,再开始任何Replace;物化DTO之间的引用由本次状态创建,配置引用只能来自同一只读快照。

6. 附件验收与证据口径

  • 每行至少:存在合法值、完全缺失、存在坏值;A有数据/B缺数据在同对象上检查整组字段;所有三类用例不能只靠字典已清空来冒充实际模块状态。
  • 每个现代/旧表示同时出现的组合验证一致与冲突;动态地图多ID、缺某地图、旧地图不会残留;同一模块多个可选键只缺其中一项也须清空该项。
  • 数据类型测试覆盖两种货币键别名、19槽精确长度、时间文化歧义、负位掩码与非负计数区别、null/重复属性/未知表项;无正式账号值。
  • 零副作用计数同时覆盖写入、SDK/网络调用、PlayerPrefs、事件、UI及计时器;任何非白名单调用导致失败,不能用最终数据库没变化代替。
  • 本附件为已审设计约束与待验清单,没有声称31模块已经实测通过,也没有声称现有业务支持重载;主会话须在代码交付后逐行填入实测证据。

7. D1/D2补审合并的边界与必验项

D1:空对象和空紧凑整体表示空集合。JSON null、对象值冒充旧AD字符串、缺槽/多槽、空记录、溢出、重复属性、枚举归一化后重复和未定义枚举均为Malformed;不尝试另一值类型解码、不回落合法新表示掩盖坏旧表示。分别验证三种成就表示的合法/缺失/坏值、AD字符串正例/对象值反例、Target超UInt64、重复枚举别名、三者共存一致/冲突、坏AD与合法ad共存仍失败。M08在同对象A→B缺失时为空,零保存/事件。

D2:明确投影表达式例如unchecked((EFootPrint)(int)(uint)completeBits),注释视图仅含低32位、完整值保留在ulong字段;不依赖默认溢出检查设置。验证0、低位组合、2^31、2^32、UInt64.MaxValue的完整值与投影视图,拒负值/溢出,A高位→B缺失时两个字段一起归零。必须在Unity真实对象上验证,离线算术不能替代;旧PF原方法及公开面保持,既定PF行为回归仍执行。guard禁止受控范围内UploadData写入,未来4B3完整值消费另审。

P2-α迁移盘点输入新增:旧PF成就加载器曾静默跳过的AD坏槽条目。当前受控KV按严格合同整体Malformed;未来真实档方案必须覆盖识别、备份、修复或人工退出,并经独立评审及用户产品确认。此次不读取或迁移真实档,不授权自动跳过/清档/默认建档。

版本历史:原附件SHA256为9E1A49E389CD6E9B38FA2CB55E5839ED5356E915AECCD4787FFE6F8276340745,保持不变。本正式版仅合并已审D1/D2及三条P3落地,未增加业务文件白名单;4B2实施完成仍需独立实施复核,检查点1不重做,检查点2–4顺序不变。