pre cw with probe and a bunch script to read game behavior

This commit is contained in:
CAtlas0784 committed 2026-10-21 20:40:13 +07:00
1 parent 5120219ae2
commit da8a32f60d
310 files changed
+219693 -872

No files matched your search

+72 -1
View File
@@ -2,6 +2,7 @@ package gameserver
import (
"encoding/json"
"fmt"
"os"
"sort"
"sync"
@@ -26,8 +27,50 @@ type MissionUnlocks struct {
var (
missionUnlocksOnce sync.Once
missionUnlocks MissionUnlocks
missionCompatOnce sync.Once
missionCompatIDs map[uint32]struct{}
missionCompatErr error
)
type missionCompatibility struct {
UnsupportedSubMissions map[string][]uint32 `json:"unsupported_sub_mission_ids_by_client_version"`
}
func excludedSubMissionsForVersion(raw []byte, clientVersion string) (map[uint32]struct{}, error) {
var compatibility missionCompatibility
if err := json.Unmarshal(raw, &compatibility); err != nil {
return nil, fmt.Errorf("parse MissionCompatibility.json: %w", err)
}
excluded := make(map[uint32]struct{})
for _, id := range compatibility.UnsupportedSubMissions[clientVersion] {
if id == 0 {
return nil, fmt.Errorf("MissionCompatibility.json contains zero sub-mission ID for Client %s", clientVersion)
}
if _, exists := excluded[id]; exists {
return nil, fmt.Errorf("MissionCompatibility.json contains duplicate sub-mission ID %d for Client %s", id, clientVersion)
}
excluded[id] = struct{}{}
}
return excluded, nil
}
func excludedSubMissionsForConfiguredClient() (map[uint32]struct{}, error) {
missionCompatOnce.Do(func() {
cfg, err := common.LoadRuntimeConfig()
if err != nil {
missionCompatErr = err
return
}
raw, err := common.ReadResourceFile("resources/MissionCompatibility.json", "MissionCompatibility.json")
if err != nil {
missionCompatErr = err
return
}
missionCompatIDs, missionCompatErr = excludedSubMissionsForVersion(raw, cfg.ClientVersion)
})
return missionCompatIDs, missionCompatErr
}
func getMissionUnlocks() *MissionUnlocks {
missionUnlocksOnce.Do(func() {
raw, err := os.ReadFile("mission_unlocks.json")
@@ -115,7 +158,35 @@ func init() {
}
rsp.FinishedMainMissionIdList = finished
SceneDebugLog("GET_MISSION_DATA finished_sent=%d", len(rsp.FinishedMainMissionIdList))
// The Client's train unlock-data callback reads sub-mission rows from
// GetMissionData. Sending only MainMissionList leaves those lookups
// absent and can throw in TrainPartyModule while the train scene loads.
excludedSubMissions, err := excludedSubMissionsForConfiguredClient()
if err != nil {
return err
}
seenSubMissions := make(map[uint32]struct{}, len(unlocks.SubMissionIDs))
excludedCount := 0
for _, id := range unlocks.SubMissionIDs {
if id == 0 {
continue
}
if _, excluded := excludedSubMissions[id]; excluded {
excludedCount++
continue
}
if _, exists := seenSubMissions[id]; exists {
continue
}
seenSubMissions[id] = struct{}{}
rsp.MissionList = append(rsp.MissionList, &goproto.Mission{
Id: id,
Progress: 1,
Status: goproto.MissionStatus_MISSION_FINISH,
})
}
SceneDebugLog("GET_MISSION_DATA finished_main_sent=%d sub_missions_sent=%d sub_missions_excluded=%d", len(rsp.FinishedMainMissionIdList), len(rsp.MissionList), excludedCount)
return nil
})