package controller import ( "blazing/logic/service/pet" "blazing/logic/service/player" "blazing/modules/player/model" ) type petListKind uint8 const ( petListKindMain petListKind = iota petListKindBackup ) type petListSlot struct { list *[]model.PetInfo index int info model.PetInfo kind petListKind } func (slot petListSlot) isValid() bool { return slot.list != nil && slot.index >= 0 && slot.index < len(*slot.list) } func (slot petListSlot) remove() { *slot.list = append((*slot.list)[:slot.index], (*slot.list)[slot.index+1:]...) } func buildPetShortInfo(info model.PetInfo) pet.PetShortInfo { return pet.PetShortInfo{ ID: info.ID, CatchTime: info.CatchTime, Level: info.Level, SkinID: info.SkinID, ShinyLen: info.ShinyLen, ShinyInfo: info.ShinyInfo, } } func buildPetListOutboundInfo(petList []model.PetInfo) *pet.GetPetListOutboundInfo { result := &pet.GetPetListOutboundInfo{ ShortInfoList: make([]pet.PetShortInfo, len(petList)), } for i := range petList { result.ShortInfoList[i] = buildPetShortInfo(petList[i]) } return result } func removePetByCatchTime(petList []model.PetInfo, catchTime uint32) []model.PetInfo { for i := range petList { if petList[i].CatchTime == catchTime { return append(petList[:i], petList[i+1:]...) } } return petList } func buildCatchTimeSet(petLists ...[]model.PetInfo) map[uint32]struct{} { total := 0 for _, petList := range petLists { total += len(petList) } catchTimes := make(map[uint32]struct{}, total) for _, petList := range petLists { for _, petInfo := range petList { catchTimes[petInfo.CatchTime] = struct{}{} } } return catchTimes } func buildPetInfoMap(petLists ...[]model.PetInfo) map[uint32]model.PetInfo { total := 0 for _, petList := range petLists { total += len(petList) } petMap := make(map[uint32]model.PetInfo, total) for _, petList := range petLists { for _, petInfo := range petList { petMap[petInfo.CatchTime] = petInfo } } return petMap } func buildWarehousePetList(player *player.Player) []model.PetInfo { allPets := player.Service.Pet.PetInfo(0) if len(allPets) == 0 { return make([]model.PetInfo, 0) } usedCatchTimes := buildCatchTimeSet(player.Info.PetList, player.Info.BackupPetList) result := make([]model.PetInfo, 0, len(allPets)) for i := range allPets { catchTime := allPets[i].Data.CatchTime if _, exists := usedCatchTimes[catchTime]; exists { continue } result = append(result, allPets[i].Data) } return result } func findBackupPet(player *player.Player, catchTime uint32) (int, *model.PetInfo, bool) { for i := range player.Info.BackupPetList { if player.Info.BackupPetList[i].CatchTime == catchTime { return i, &player.Info.BackupPetList[i], true } } return -1, nil, false } func findPetListSlot(player *player.Player, catchTime uint32) (petListSlot, bool) { if index, petInfo, ok := player.FindPet(catchTime); ok { return petListSlot{ list: &player.Info.PetList, index: index, info: *petInfo, kind: petListKindMain, }, true } if index, petInfo, ok := findBackupPet(player, catchTime); ok { return petListSlot{ list: &player.Info.BackupPetList, index: index, info: *petInfo, kind: petListKindBackup, }, true } return petListSlot{}, false } func syncBackupPetList(player *player.Player) { if player.Info.BackupPetList == nil { player.Info.BackupPetList = make([]model.PetInfo, 0) return } bagPets := player.Service.Pet.PetInfo(0) if len(bagPets) == 0 { player.Info.BackupPetList = make([]model.PetInfo, 0) return } bagCatchTimes := make(map[uint32]struct{}, len(bagPets)) for i := range bagPets { bagCatchTimes[bagPets[i].Data.CatchTime] = struct{}{} } mainPetCatchTimes := buildCatchTimeSet(player.Info.PetList) nextBackupList := make([]model.PetInfo, 0, len(player.Info.BackupPetList)) for _, petInfo := range player.Info.BackupPetList { if _, inBag := bagCatchTimes[petInfo.CatchTime]; !inBag { continue } if _, inMain := mainPetCatchTimes[petInfo.CatchTime]; inMain { continue } nextBackupList = append(nextBackupList, petInfo) } player.Info.BackupPetList = nextBackupList } func buildUserBagPetInfo(player *player.Player) *pet.GetUserBagPetInfoOutboundInfo { syncBackupPetList(player) result := &pet.GetUserBagPetInfoOutboundInfo{ PetList: make([]model.PetInfo, len(player.Info.PetList)), BackupPetList: make([]model.PetInfo, len(player.Info.BackupPetList)), } copy(result.PetList, player.Info.PetList) copy(result.BackupPetList, player.Info.BackupPetList) return result } func buildOrderedPetList( catchTimes []uint32, petMap map[uint32]model.PetInfo, used map[uint32]struct{}, ) ([]model.PetInfo, bool) { result := make([]model.PetInfo, 0, len(catchTimes)) for _, catchTime := range catchTimes { if catchTime == 0 { return nil, false } if _, exists := used[catchTime]; exists { return nil, false } petInfo, exists := petMap[catchTime] if !exists { return nil, false } used[catchTime] = struct{}{} result = append(result, petInfo) } return result, true } func buildPetShowOutboundInfo(userID, flag uint32, info *model.PetInfo) *pet.PetShowOutboundInfo { return &pet.PetShowOutboundInfo{ UserID: userID, CatchTime: info.CatchTime, ID: info.ID, Flag: flag, Dv: info.Dv, ShinyLen: info.ShinyLen, ShinyInfo: info.ShinyInfo, SkinID: info.SkinID, } }