feat: expand gameplay and state persistence

- add character imprint, awakening, and equipment refinement

- add equipment ticket gacha and persistent progression fields

- add request-scoped account transactions with crash recovery

- persist age confirmation and isolate client plugin patches

- separate one-off save repair tools from shipped tooling
This commit is contained in:
2026-09-23 00:55:36 +08:00
parent f55a71ac52
commit 113e941bef
57 changed files with 4377 additions and 1314 deletions
+26
View File
@@ -46,6 +46,10 @@ type HopePowderProvider interface {
HopePowderBalance() uint64
}
type EquipmentMileageProvider interface {
EquipmentMileageBalances() (mileage, exchangeGage uint64)
}
func (s *LoginSeed) AttachCurrencies(provider CurrencyProvider) error {
if provider == nil {
return errors.New("account: nil currency provider")
@@ -96,6 +100,19 @@ func (s *LoginSeed) SeedHopePowder() (uint64, error) {
return value, nil
}
func (s *LoginSeed) SeedEquipmentMileage() (mileage, exchangeGage uint64, err error) {
if err = s.Validate(); err != nil {
return 0, 0, err
}
if mileage, _, err = wire.Varint(s.UserInfo, 67); err != nil {
return 0, 0, err
}
if exchangeGage, _, err = wire.Varint(s.UserInfo, 68); err != nil {
return 0, 0, err
}
return mileage, exchangeGage, nil
}
type diskSeed struct {
Version string `json:"version"`
PacketCode int `json:"packet_code"`
@@ -239,6 +256,15 @@ func (s *LoginSeed) Login(request, sessionKey []byte) ([]byte, error) {
return nil, fmt.Errorf("account: replace hope powder: %w", err)
}
}
if provider, ok := s.currencies.(EquipmentMileageProvider); ok {
equipMileage, exchangeGage := provider.EquipmentMileageBalances()
if user, _, err = wire.ReplaceVarint(user, 67, equipMileage); err != nil {
return nil, fmt.Errorf("account: replace equipment mileage: %w", err)
}
if user, _, err = wire.ReplaceVarint(user, 68, exchangeGage); err != nil {
return nil, fmt.Errorf("account: replace equipment mileage exchange gauge: %w", err)
}
}
}
if s.firstGacha != nil {
value := uint64(0)