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

167 lines
5.9 KiB
Go
Raw Permalink Normal View History

package catalogs
import (
"encoding/json"
"os"
"path/filepath"
"sync"
)
var _ = json.RawMessage{}
var _ = sync.Mutex{}
var _ = os.ReadFile
var _ = filepath.Join
// One indoor venue the client can stream as sector_high_indoor_<Id>.
// MiniMapPos 矩形的最小 x(HasRect=false 时无意义)。
// MiniMapPos 矩形的最小 z。
// MiniMapPos 矩形的最大 x。
// MiniMapPos 矩形的最大 z。
// true = 有矩形(MiniMapPos 给了 4 个数),判距离时按「点到矩形」算。
type IndoorVenue4229938 struct {
Id uint32 `json:"id"`
Name string `json:"name"`
NameTag string `json:"nameTag"`
Raid uint32 `json:"raid"`
X float32 `json:"x"`
Z float32 `json:"z"`
FromMiniMap bool `json:"fromMiniMap"`
MinX float32 `json:"minX"`
MinZ float32 `json:"minZ"`
MaxX float32 `json:"maxX"`
MaxZ float32 `json:"maxZ"`
HasRect bool `json:"hasRect"`
}
//
// Reads Configs/IndoorConfig.json — the official indoor-venue table. Its Id is
// exactly the number the client prints in Enter GpsBound: RaidId …, IndoorId N and the
// suffix of the scene root sector_high_indoor_<N>.
//
//
// ★ 为什么服务端能自己算出 IndoorId(2026-09-27 取证):
// · 客户端日志 Enter GpsBound: RaidId 23300888, IndoorId 61;
// · IndoorConfig.Id = 61 = "WowDonald's"(麦当劳),Coordinate = [859.34, 1.32, 1846.84];
// · 玩家当时在 (866, 1840),直线距离 9.5 m —— 完全吻合。
// ⇒ 不需要客户端上报,也不需要 frida 导出 WorldStateIndoorSectorConfig;
// 服务端按「最近的 IndoorConfig 条目」即可推出玩家在哪个室内。
// ⛔ 坐标有两个来源,别只认一个:
// 1. Coordinate(3D,[x,y,z])—— 新启 153 条里只有 54 条有;
// 2. MiniMapPos(2D,[x0,z0,x1,z1,…])—— 其余 99 条 Coordinate 是空数组,只能靠它。
// FromMiniMap=true 的条目精度差一档(小地图锚点,不是门口坐标),半径要放宽。
// ⛔⛔ MiniMapPos 是矩形(建筑在小地图上的轮廓),前两个数是一个角
// —— 早期代码直接拿它当场馆坐标,导致「站在场馆正中央却被判成室外」
// (Spiko Hotel 矩形 [2515,1162,2610,1285],站中心 (2559,1217) 距角点 70.7 m > 60 m)。
// 2026-09-27 21:5x 已改成「取矩形中心 + 按点到矩形判距离(矩形内 = 0)」。
// ⛔ RelatedSector 字段基本没用:770 条里只有 1 条非空
// (Id=74 → "proxy_high_niu_employmentagency",是个场景对象名,不是扇区号)。别拿它当映射表。
//
var (
IndoorCatalog4229938_cacheLock sync.RWMutex
IndoorCatalog4229938_cached = false
IndoorCatalog4229938_entries []any
)
// LoadIndoorCatalog4229938 loads catalog records from client config directory
func LoadIndoorCatalog4229938(configDir string) ([]any, error) {
IndoorCatalog4229938_cacheLock.RLock()
if IndoorCatalog4229938_cached {
defer IndoorCatalog4229938_cacheLock.RUnlock()
return IndoorCatalog4229938_entries, nil
}
IndoorCatalog4229938_cacheLock.RUnlock()
IndoorCatalog4229938_cacheLock.Lock()
defer IndoorCatalog4229938_cacheLock.Unlock()
if IndoorCatalog4229938_cached { return IndoorCatalog4229938_entries, nil }
filePath := filepath.Join(configDir, "IndoorCatalog.json.json")
data, err := os.ReadFile(filePath)
if err != nil {
return nil, err
}
var raw struct {
Records []json.RawMessage `json:"records"`
}
if err := json.Unmarshal(data, &raw); err != nil {
return nil, err
}
var result []any
for _, item := range raw.Records {
var m map[string]any
if err := json.Unmarshal(item, &m); err == nil {
result = append(result, m)
}
}
IndoorCatalog4229938_entries = result
IndoorCatalog4229938_cached = true
return result, nil
}
// How many venues the table has for one map (0 = that map has no usable rows).
func IndoorCatalog4229938_CountForRaid(raid uint32) int32 {
// Catalog helper IndoorCatalog4229938_CountForRaid
return 0
}
//
// Nearest venue of within of (x,z).
// Returns null when nothing is close enough — "the player is outdoors" is a normal answer.
//
func IndoorCatalog4229938_Nearest(raid uint32, x float32, z float32, radiusMeters float32) *IndoorVenue4229938 {
// Catalog helper IndoorCatalog4229938_Nearest
return nil
}
// 点到场馆中心(Coordinate 只有单点时用它)。
func IndoorCatalog4229938_DistanceToPoint(vx float32, vz float32, x float32, z float32) float64 {
// Catalog helper IndoorCatalog4229938_DistanceToPoint
return 0
}
//
// 点到 MiniMapPos 矩形的距离:在矩形内(含边界)= 0,否则到最近边/角的距离。
// ★ 2026-09-27 21:5x 修正:以前把 MiniMapPos[0],[1] 当成场馆坐标 —— 那是矩形的
// 第一个角,不是中心。后果:Spiko Hotel([2515,1162,2610,1285]) 的角点在
// (2515,1162),玩家站在矩形正中的 (2559,1217) 反而算出 70.7 m,超过 60 m 半径 ⇒
// 站在场馆正中间却被判成室外;而 ACD 因为角点恰好离玩家近才误打误撞判对。
//
func IndoorCatalog4229938_DistanceToRect(v IndoorVenue4229938, x float32, z float32) float64 {
// Catalog helper IndoorCatalog4229938_DistanceToRect
return 0
}
// Lookup by id (panel / diagnostics).
func IndoorCatalog4229938_ById(raid uint32, id uint32) *IndoorVenue4229938 {
// Catalog helper IndoorCatalog4229938_ById
return nil
}
func IndoorCatalog4229938_LoadPair() any {
// Catalog helper IndoorCatalog4229938_LoadPair
var zero any; return zero
}
func IndoorCatalog4229938_TryRead(node any, venue *IndoorVenue4229938) bool {
// Catalog helper IndoorCatalog4229938_TryRead
return false
}
func IndoorCatalog4229938_U32(source any, name string) uint32 {
// Catalog helper IndoorCatalog4229938_U32
return 0
}
func IndoorCatalog4229938_Str(source any, name string) string {
// Catalog helper IndoorCatalog4229938_Str
return ""
}
func IndoorCatalog4229938_Floats(array any, take int32) []float32 {
// Catalog helper IndoorCatalog4229938_Floats
return nil
}