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

122 lines
5.2 KiB
Go
Raw Permalink Normal View History

package models
import (
"encoding/json"
"sync"
)
var _ = json.RawMessage{}
var _ = sync.Mutex{}
// 一件落地的物品。ConfigId 是配置行 id(9993xxxx),下发时才换成 ConsumableId。
type ExtractionShooterItem struct {
ConfigId uint32 `json:"configId"`
StackCount uint32 `json:"stackCount"`
CellX int32 `json:"cellX"`
CellY int32 `json:"cellY"`
IsRotated bool `json:"isRotated"`
IsLocked bool `json:"isLocked"`
BindPid uint64 `json:"bindPid"`
}
type ExtractionShooterGrid struct {
}
// 一个 bag 的服务端镜像:格数 + 占位图 + 物品清单。
type ExtractionShooterBagState struct {
BagId uint32 `json:"bagId"`
Meta ExtractionShooterBagMeta `json:"meta"`
Items []ExtractionShooterItem `json:"items"`
Grid ExtractionGrid4229938 `json:"grid"`
IsSlotGroup bool `json:"isSlotGroup"`
}
// 一个容器实例。实例 id 由客户端给出(8 字节),服务端只认这一份。
type ExtractionShooterContainerState struct {
InstanceId uint64 `json:"instanceId"`
CfgId uint32 `json:"cfgId"`
SizeX int32 `json:"sizeX"`
SizeY int32 `json:"sizeY"`
Items []ExtractionShooterItem `json:"items"`
Grid ExtractionGrid4229938 `json:"grid"`
// pid → 该玩家搜索完成的服务器秒数。空 = 未搜索 = 客户端隐藏图标。
SearchFinish map[uint64]uint32 `json:"searchFinish"`
//
// 已经把 SearchFinish 翻成过去的 pid。
// ⛑️ 这一位是「能不能看见东西」的开关:搜索刚发起时 SearchFinish 落在未来
// (客户端据此播读条),只有等时间到了、把它翻回过去,物品才会真正显示。
// 捐赠端 v1.7 的实机日志(09-24 17:07:04 → 17:07:05 → 17:07:06)逐帧证明了这个顺序:
// 推「未来」帧 → 隔 N 秒推「已揭晓」帧 → 玩家才取得到东西。
//
Revealed []uint64 `json:"revealed"`
// 整箱揭晓的基准延时:箱内最长的那件 SearchTime。
RevealDelaySeconds int32 `json:"revealDelaySeconds"`
}
//
// 每条连接的搜打撤状态,存 session.Items(与 GameRouter.SceneItemGrid 同套路)。
//
type ExtractionShooterSessionState struct {
SyncRoot any `json:"syncRoot"`
Bags map[uint32]ExtractionShooterBagState `json:"bags"`
Containers map[uint64]ExtractionShooterContainerState `json:"containers"`
UnlockedExpansions []uint32 `json:"unlockedExpansions"`
UnlockedBags []uint32 `json:"unlockedBags"`
TokenCount uint32 `json:"tokenCount"`
Seeded bool `json:"seeded"`
//
// 本局开始的时间戳(秒)—— 结算帧 SyncRaidSettlement 里的
// EnterRaidTime / BattleTime 就取它。
// Seed 每次重跑都会刷新(换局),Reset 不清它,
// 因为退图那一刀要用「退图时间 - 进图时间」算这一局打了多久。
//
EnterRaidSeconds uint32 `json:"enterRaidSeconds"`
}
//
// 搜打撤运行时:编目 → per-session 状态 → wire payload。
// 本轮覆盖:登录帧注入、进图、容器刷物与搜索、背包搬运 / 丢弃 / 锁定 / 排序 / 入仓、容器↔背包搬运。
// 不含武器实体化(轮盘 Tab 切枪)—— 那需要 CombatCatalogRepository 的实例 id
// 与 SyncSpiritWeaponDetail 整表,是第二轮的事。
// 三条容易漏的:
// 1. 下发 id 用 ConsumableId(ExtractionShooterCatalog4229938.WireIdFor),
// 配置行 id 只在服务端内部记。
// 2. 搜索时间戳必须落在未来:客户端 wait 秒数被钳负为 0 ⇒ 过去时间戳 = wait(0) 空转,
// 动画一帧不播。
// 3. 堆叠数量按服务端规则生成(StackCountForLocked)。写 1 会让客户端把角标
// 整个藏掉(showCountCtrl = StackCount <= 1),看起来像"子弹只有 1 发"。
//
type ExtractionShooterRuntime4229938 struct {
// ------------------------------------------------------------------ seeding
// 本局开放的包。取自 GamePlayTypeConfig 的 StorageSet / EquipSlotSet。
DefaultBagIds []uint32 `json:"defaultBagIds"`
//
// 轮盘里能放武器的格数(CellX 0..N-1)。
// WheelWeaponCfg(99952004)SlotCapacity{initial:8, max:8} —— 8 个槽位里有 1 个是私有武器槽
// (客户端 GetCellIndexBySlotIndex 把它扣掉了)⇒ 真正能放轮盘武器的是 7 格。
//
WheelSlotCells4229938 int32 `json:"wheelSlotCells4229938"`
//
// 轮盘物品要不要带 WeaponData 的运行时值。
// 面板改这个比改配置省事(不用改 json、不用重启),GM 面板那条 checkbox 走的就是这里的 setter。
// 没动过时 null ⇒ 回落到 world.content.extraction.wheelWeaponData,重启就恢复配置值。
// 关掉它专门用于回退验证:枪的 tooltip 会退化成普通物品描述,能一眼看出 tooltip 那条链路
// 到底走的是 ItemInfo.WeaponData 还是虚构出来的东西。
//
S_wheelWeaponDataOverride *bool `json:"s_wheelWeaponDataOverride"`
WheelWeaponDataEnabled bool `json:"wheelWeaponDataEnabled"`
}
const (
ExtractionShooterRuntime4229938_SessionKey string = "client4229938-extraction-shooter"
ExtractionShooterRuntime4229938_WheelHomeOffset4229938 int32 = 2
)
// 轮盘里的一件武器:格子 + 线上物品 id + SceneitemConfig 模板 + 账号军械实例 id。
type WheelWeapon struct {
CellX uint32 `json:"cellX"`
WireItemId uint32 `json:"wireItemId"`
SceneItemTemplateId uint32 `json:"sceneItemTemplateId"`
InstanceId uint64 `json:"instanceId"`
}