pre cw with probe and a bunch script to read game behavior
This commit is contained in:
1 parent
5120219ae2
commit
da8a32f60d
310 files changed
+219693
-872
No files matched your search
@@ -0,0 +1,97 @@
|
||||
package gameserver
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"gac-hkrpg-go/internal/common"
|
||||
goproto "gac-hkrpg-go/protocol/proto"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
// Shared read path for entry and GetData. It never adopts a revision into a
|
||||
// session or writes persistent; callers choose when a validated view becomes
|
||||
// their current session revision.
|
||||
func readCurrencyWarsData(catalog *common.CurrencyWarsCatalog) (*goproto.GridFightGetDataScRsp, uint64, error) {
|
||||
if catalog == nil {
|
||||
return nil, 0, fmt.Errorf("CW catalog is missing")
|
||||
}
|
||||
cfg, err := common.LoadRuntimeConfig()
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
snapshot, err := common.ReadCurrencyWarsSnapshot(cfg.PlayerUID, catalog.ClientVersion, catalog.Provenance.GameAssemblySHA256)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
if snapshot == nil {
|
||||
return nil, 0, nil
|
||||
}
|
||||
var saved goproto.GridFightGetDataScRsp
|
||||
if err := proto.Unmarshal(snapshot.WireData, &saved); err != nil {
|
||||
return nil, 0, fmt.Errorf("decode saved CW protocol: %w", err)
|
||||
}
|
||||
if err := validateCurrencyWarsSavedData(&saved, catalog); err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
return &saved, snapshot.Revision, nil
|
||||
}
|
||||
|
||||
// Validate known metadata prerequisites before restoring a saved response.
|
||||
// Full run validation belongs to the gameplay state machine, which is still
|
||||
// being implemented. Entry and captured initial-choice handlers commit only
|
||||
// their validated phases; this is not full gameplay/resume validation.
|
||||
func validateCurrencyWarsSavedData(data *goproto.GridFightGetDataScRsp, catalog *common.CurrencyWarsCatalog) error {
|
||||
if data == nil || catalog == nil || data.Retcode != 0 || data.LFLCDNGALME == nil {
|
||||
return fmt.Errorf("saved CW response is missing metadata or contains an error")
|
||||
}
|
||||
meta := data.LFLCDNGALME
|
||||
if meta.PKELAIPIHMF == nil || meta.PKELAIPIHMF.MHFHLBHFIBC == nil || meta.HFPEJIDDDJG == nil {
|
||||
return fmt.Errorf("saved CW permanent/season state is incomplete")
|
||||
}
|
||||
season := meta.HFPEJIDDDJG
|
||||
if season.ADFEKPNIFOJ != catalog.ActiveSeasonID || season.GEGMHOMNBDG != catalog.ActiveSubSeasonID || season.Exp == nil || season.MHFHLBHFIBC == nil || season.NLENPEPIHAC == nil {
|
||||
return fmt.Errorf("saved CW season state differs from captured active season")
|
||||
}
|
||||
division, ok := catalog.Division(season.DivisionId)
|
||||
if !ok || division.SeasonID != catalog.ActiveSeasonID {
|
||||
return fmt.Errorf("saved CW division is not in active season")
|
||||
}
|
||||
book := season.NLENPEPIHAC
|
||||
if book.DNEGDNEBJMB == nil || book.NIOAIKLPACM == nil || book.EECJFCNKKMB == nil || book.KJIJEGAHLGB == nil || book.NNIJIFGJJJA == nil || book.JLFANEOAHOC == nil || book.EJHDGLHCNLH == nil || book.PJBIPMKACOF == nil {
|
||||
return fmt.Errorf("saved CW handbook containers are incomplete")
|
||||
}
|
||||
if run := data.DHFOFLFCLAH; run != nil {
|
||||
// Native Start/GetData captures establish LJNGPCKPJLF as Season.
|
||||
// MPJPLKKJNGE is not a required season identity; it can be zero.
|
||||
if run.UniqueId == 0 || run.LJNGPCKPJLF != catalog.ActiveSeasonID || run.DivisionId == 0 {
|
||||
return fmt.Errorf("saved CW active run identity is incomplete")
|
||||
}
|
||||
if d, ok := catalog.Division(run.DivisionId); !ok || d.SeasonID != run.LJNGPCKPJLF {
|
||||
return fmt.Errorf("saved CW run division differs from its season")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// saveCurrencyWarsData must be called only after a validated CW state-machine
|
||||
// transition, under the session state lock. It does not alter adventure data.
|
||||
func (s *Session) saveCurrencyWarsData(data *goproto.GridFightGetDataScRsp, catalog *common.CurrencyWarsCatalog) error {
|
||||
if err := validateCurrencyWarsSavedData(data, catalog); err != nil {
|
||||
return err
|
||||
}
|
||||
cfg, err := common.LoadRuntimeConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
wire, err := proto.Marshal(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
next := common.NewCurrencyWarsSnapshot(cfg.PlayerUID, catalog.ClientVersion, catalog.Provenance.GameAssemblySHA256, wire)
|
||||
revision, err := common.CommitCurrencyWarsSnapshot(s.currencyWarsRevision, next)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.currencyWarsRevision = revision
|
||||
return nil
|
||||
}
|
||||
Reference in new issue
Block a user