Files
GaCy-GO/internal/gameserver/progression_sync.go
T

96 lines
2.2 KiB
Go

package gameserver
import (
"fmt"
"os"
"reflect"
"gac-hkrpg-go/internal/common"
goproto "gac-hkrpg-go/protocol/proto"
)
func syncPersistedExRanks(s *Session) error {
// Publish changes after battle settlement; do not replace actor progression
// while the client's combat scene is using its captured BattleInfo.
if _, active := CURRENT_BATTLE.Load(s.Token); active {
return nil
}
player := s.JSON()
if player == nil {
return nil
}
p, err := common.ReadPersistent()
if os.IsNotExist(err) {
return nil
}
if err != nil {
return err
}
changed := player.RefreshExRanks(p)
if s.pendingExRankSync == nil {
s.pendingExRankSync = make(map[uint32]bool)
}
for _, id := range changed {
s.pendingExRankSync[id] = true
}
if len(s.pendingExRankSync) == 0 {
return nil
}
changed = changed[:0]
for id := range s.pendingExRankSync {
changed = append(changed, id)
}
sortU32Slice(changed)
notify := &goproto.PlayerSyncScNotify{}
buildSync(player, notify, changed, nil, nil)
notify.MaterialList, err = eidolonMaterials(player)
if err != nil {
return err
}
if err := s.Send(notify); err != nil {
return err
}
Log(fmt.Sprintf("[EX-RANK SYNC] updated avatars=%v", changed))
s.pendingExRankSync = nil
return nil
}
// A rank-only edit does not require deleting/recreating inventory. Preserve the
// existing full-import path only when equipment, relics or avatar ownership change.
func reloadPlayerData(s *Session, next *common.FreesrData) error {
previous := s.JSON()
full := previous == nil
if !full {
full = !reflect.DeepEqual(previous.Lightcones, next.Lightcones) || !reflect.DeepEqual(previous.Relics, next.Relics) || len(previous.Avatars) != len(next.Avatars)
}
var changed []uint32
if !full {
for id, avatar := range next.Avatars {
old, exists := previous.Avatars[id]
if !exists {
full = true
break
}
if !reflect.DeepEqual(old, avatar) {
changed = append(changed, id)
}
}
}
s.SetJSON(next)
if full {
return s.SyncPlayer()
}
if len(changed) == 0 {
return nil
}
sortU32Slice(changed)
notify := &goproto.PlayerSyncScNotify{}
buildSync(next, notify, changed, nil, nil)
var err error
notify.MaterialList, err = eidolonMaterials(next)
if err != nil {
return err
}
return s.Send(notify)
}