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) }