diff --git a/common/data/entity/Server.go b/common/data/entity/Server.go deleted file mode 100644 index 1b42ff35..00000000 --- a/common/data/entity/Server.go +++ /dev/null @@ -1,360 +0,0 @@ -package entity - -// import ( -// "context" -// "database/sql" -// "errors" -// "fmt" -// "log" -// "sync" -// "time" - -// ) - -// // Server 游戏服务器核心类,管理玩家、星球和游戏逻辑 -// type Server struct { -// players map[int64]*entity.Player -// planets map[int64]*planet.Planet -// mutex sync.RWMutex -// gameRepo repo.GameResourceRepo -// serverRepo repo.ServerRepo -// accountRepo repo.AccountRepo -// playerInfoRepo repo.PlayerInfoRepo -// playerItemRepo repo.PlayerItemInfoRepo -// petRepo repo.PetRepo -// } - -// // NewServer 创建新的游戏服务器实例 -// func NewServer( -// gameRepo repo.GameResourceRepo, -// serverRepo repo.ServerRepo, -// accountRepo repo.AccountRepo, -// playerInfoRepo repo.PlayerInfoRepo, -// playerItemRepo repo.PlayerItemInfoRepo, -// petRepo repo.PetRepo, -// ) *Server { -// s := &Server{ -// players: make(map[int64]*entity.Player), -// planets: make(map[int64]*planet.Planet), -// gameRepo: gameRepo, -// serverRepo: serverRepo, -// accountRepo: accountRepo, -// playerInfoRepo: playerInfoRepo, -// playerItemRepo: playerItemRepo, -// petRepo: petRepo, -// } -// s.initializePlanets() -// return s -// } - -// // initializePlanets 初始化所有星球 -// func (s *Server) initializePlanets() { -// maps := s.gameRepo.GetAllMaps() -// for _, config := range maps { -// planet := s.generatePlanet(config) -// s.planets[planet.GetId()] = planet -// } -// } - -// // generatePlanet 根据地图配置生成星球 -// func (s *Server) generatePlanet(config *mapInfo.MapXmlModel) *planet.Planet { -// entries := config.GetEntries() -// positions := make(map[int64]structs.Point) - -// if len(entries) == 0 { -// positions = make(map[int64]structs.Point) -// } else { -// for _, entry := range entries { -// positions[entry.GetFromMap()] = s.generatePoint(entry) -// } -// } - -// return planet.NewPlanet( -// s, -// int64(config.GetId()), -// config.GetName(), -// structs.Point{X: config.GetX(), Y: config.GetY()}, -// positions, -// s.gameRepo.CanMapRefresh(config.GetId()), -// ) -// } - -// // generatePoint 从入口配置生成点坐标 -// func (s *Server) generatePoint(xml *mapInfo.EntryXmlModel) structs.Point { -// return structs.Point{X: xml.GetPosX(), Y: xml.GetPosY()} -// } - -// // GetPlayer 获取玩家信息 -// func (s *Server) GetPlayer(accountID int64) (*entity.Player, error) { -// s.mutex.RLock() -// defer s.mutex.RUnlock() - -// player, exists := s.players[accountID] -// if !exists { -// return nil, errors.New("玩家不存在") -// } -// return player, nil -// } - -// // GetPlanet 获取星球信息 -// func (s *Server) GetPlanet(planetID int64) (*planet.Planet, error) { -// s.mutex.RLock() -// defer s.mutex.RUnlock() - -// planet, exists := s.planets[planetID] -// if !exists { -// return nil, errors.New("星球不存在") -// } -// return planet, nil -// } - -// // GetDefaultPlanet 获取默认星球 -// func (s *Server) GetDefaultPlanet() (*planet.Planet, error) { -// s.mutex.RLock() -// defer s.mutex.RUnlock() - -// planet, exists := s.planets[1] // 假设1是默认星球ID -// if !exists { -// return nil, errors.New("未找到默认星球") -// } -// return planet, nil -// } - -// // PlayerEnter 玩家加入服务器 -// func (s *Server) PlayerEnter(player *entity.Player) { -// s.mutex.Lock() -// defer s.mutex.Unlock() - -// s.players[player.GetAccountID()] = player -// } - -// // PlayerOffline 玩家离线处理 -// func (s *Server) PlayerOffline(player *entity.Player) { -// s.mutex.Lock() -// defer s.mutex.Unlock() - -// // 清理缓存会话数据 -// if err := s.accountRepo.RemoveSessionID(player.GetSessionID()); err != nil { -// log.Printf("清除会话ID失败: %v", err) -// } - -// // 清理登录绑定服务器 -// if err := s.serverRepo.CancelRecordAccount(player.GetAccountID()); err != nil { -// log.Printf("取消账号绑定失败: %v", err) -// } - -// // 从玩家列表中移除 -// delete(s.players, player.GetAccountID()) -// } - -// // BroadcastMessage 广播消息给所有在线玩家 -// func (s *Server) BroadcastMessage(message *net.OutboundMessage) { -// s.mutex.RLock() -// defer s.mutex.RUnlock() - -// for _, player := range s.players { -// if player.IsOnline() { -// player.SendMessage(message) -// } -// } -// } - -// // BroadcastMessageWithFilter 按条件广播消息给在线玩家 -// func (s *Server) BroadcastMessageWithFilter(message *net.OutboundMessage, filter func(*entity.Player) bool) { -// s.mutex.RLock() -// defer s.mutex.RUnlock() - -// for _, player := range s.players { -// if player.IsOnline() && filter(player) { -// player.SendMessage(message) -// } -// } -// } - -// // GeneratePetEntity 生成宠物实体 -// func (s *Server) GeneratePetEntity( -// playerID int64, -// petTypeID int, -// individualValue int16, -// nature int, -// abilityTypeEnum int, -// isShiny bool, -// level int, -// ) (*pet.PetEntity, error) { -// if level < 1 || level > 100 { -// return nil, fmt.Errorf("精灵等级必须在1到100之间, level: %d", level) -// } - -// petInfo, err := s.gameRepo.GetMonsterByID(petTypeID) -// if err != nil { -// return nil, fmt.Errorf("无效的精灵ID, pet_id: %d, 错误: %v", petTypeID, err) -// } - -// firstSkillInfo, err := s.gameRepo.GetPetFirstSkillID(petTypeID, level) -// if err != nil { -// return nil, fmt.Errorf("精灵没有初始技能, pet_id: %d, 错误: %v", petTypeID, err) -// } - -// zero := int16(0) - -// pet := pet.NewPetEntityBuilder() -// .WithAsset(petInfo) -// .WithLevelToExp(s.gameRepo.GetLevelToExp()) -// .WithPlayerID(playerID) -// .WithCapturePlayerID(playerID) -// .WithCaptureTime(time.Now().Unix()) -// .WithCaptureMap(0) // 假设0是默认地图ID -// .WithCaptureRect(0) // 假设0是默认区域 -// .WithCaptureLevel(level) -// .WithIndividualValue(individualValue) -// .WithNature(nature) -// .WithAbilityTypeEnum(abilityTypeEnum) -// .WithIsShiny(isShiny) -// .WithLevel(level) -// .WithCurrentExp(0) -// .WithEvHp(zero) -// .WithEvAttack(zero) -// .WithEvDefense(zero) -// .WithEvSpecialAttack(zero) -// .WithEvSpecialDefense(zero) -// .WithEvSpeed(zero) -// .WithSkill1ID(firstSkillInfo[0].GetId()) -// .WithSkill1Pp(firstSkillInfo[0].GetMaxPp()) -// .WithSkill2ID(firstSkillInfo[1].GetId()) -// .WithSkill2Pp(firstSkillInfo[1].GetMaxPp()) -// .WithSkill3ID(firstSkillInfo[2].GetId()) -// .WithSkill3Pp(firstSkillInfo[2].GetMaxPp()) -// .WithSkill4ID(firstSkillInfo[3].GetId()) -// .WithSkill4Pp(firstSkillInfo[3].GetMaxPp()) -// .WithIndividualGuarantee(0) -// .WithNatureGuarantee(0) -// .Build() - -// if err := s.CalculatePetPanel(pet); err != nil { -// return nil, err -// } - -// return pet, nil -// } - -// // CalculatePetPanel 计算宠物面板属性 -// func (s *Server) CalculatePetPanel(petEntity *pet.PetEntity) error { -// natureInfo, err := s.gameRepo.GetNatureInfoByID(petEntity.GetNature()) -// if err != nil { -// return fmt.Errorf("无效的性格ID, nature: %d, 错误: %v", petEntity.GetNature(), err) -// } - -// hp := util.CalculatePetHPPanelSize( -// petEntity.GetAsset().GetHp(), -// petEntity.GetIndividualValue(), -// petEntity.GetLevel(), -// petEntity.GetEvHp(), -// ) - -// attack := util.CalculatePetPanelSize( -// petEntity.GetAsset().GetAtk(), -// petEntity.GetIndividualValue(), -// petEntity.GetLevel(), -// petEntity.GetEvHp(), -// natureInfo.GetAttackCorrect(), -// ) - -// defense := util.CalculatePetPanelSize( -// petEntity.GetAsset().GetDef(), -// petEntity.GetIndividualValue(), -// petEntity.GetLevel(), -// petEntity.GetEvHp(), -// natureInfo.GetDefenseCorrect(), -// ) - -// specialAttack := util.CalculatePetPanelSize( -// petEntity.GetAsset().GetSpAtk(), -// petEntity.GetIndividualValue(), -// petEntity.GetLevel(), -// petEntity.GetEvHp(), -// natureInfo.GetSaCorrect(), -// ) - -// specialDefense := util.CalculatePetPanelSize( -// petEntity.GetAsset().GetSpDef(), -// petEntity.GetIndividualValue(), -// petEntity.GetLevel(), -// petEntity.GetEvHp(), -// natureInfo.GetSdCorrect(), -// ) - -// speed := util.CalculatePetPanelSize( -// petEntity.GetAsset().GetSpd(), -// petEntity.GetIndividualValue(), -// petEntity.GetLevel(), -// petEntity.GetEvHp(), -// natureInfo.GetSpeedCorrect(), -// ) - -// petEntity.SetMaxHp(hp) -// petEntity.SetCurrentHp(hp) -// petEntity.SetAttack(attack) -// petEntity.SetDefense(defense) -// petEntity.SetSpecialAttack(specialAttack) -// petEntity.SetSpecialDefense(specialDefense) -// petEntity.SetSpeed(speed) - -// return nil -// } - -// // SavePlayer 保存玩家信息到数据库 -// func (s *Server) SavePlayer(player *entity.Player) (bool, error) { -// ctx := context.Background() -// tx, err := s.playerInfoRepo.BeginTransaction(ctx) -// if err != nil { -// return false, fmt.Errorf("开始事务失败: %v", err) -// } -// defer func() { -// if r := recover(); r != nil { -// tx.Rollback() -// log.Printf("保存玩家时发生panic: %v", r) -// } else if err != nil { -// tx.Rollback() -// } else { -// tx.Commit() -// } -// }() - -// playerID := player.GetGameID() -// pets := player.GetPetBag().GetUsedPets() -// items := player.GetItemBag().GetItems() - -// // 保存玩家信息 -// if err := s.playerInfoRepo.Save(ctx, tx, player); err != nil { -// return false, fmt.Errorf("保存玩家信息失败: %v", err) -// } - -// // 保存精灵信息 -// if err := s.petRepo.SaveAll(ctx, tx, playerID, pets); err != nil { -// return false, fmt.Errorf("保存精灵信息失败: %v", err) -// } - -// // 保存玩家背包信息 -// if err := s.playerItemRepo.SaveAll(ctx, tx, playerID, items); err != nil { -// return false, fmt.Errorf("保存背包信息失败: %v", err) -// } - -// return true, nil -// } - -// // Destroy 销毁服务器,清理资源 -// func (s *Server) Destroy() error { -// // 保存所有玩家数据 -// s.mutex.RLock() -// for _, player := range s.players { -// go func(p *entity.Player) { -// if _, err := s.SavePlayer(p); err != nil { -// log.Printf("保存玩家 %d 数据失败: %v", p.GetAccountID(), err) -// } -// }(player) -// } -// s.mutex.RUnlock() - -// log.Println("Destroying server ...") -// return nil -// } diff --git a/common/socket/ServerEvent.go b/common/socket/ServerEvent.go index 0de04171..8cef8a35 100644 --- a/common/socket/ServerEvent.go +++ b/common/socket/ServerEvent.go @@ -50,6 +50,7 @@ func (s *Server) OnClose(c gnet.Conn, _ error) (action gnet.Action) { t := v.GetPlayer() if t != nil { glog.Debug(context.Background(), t.UserID, "断开连接") + t.IsLogin = false cool.Mainplayer.Delete(t.UserID) share.ShareManager.DeleteUserOnline(t.UserID) //设置用户登录服务器 } diff --git a/logic/controller/map.go b/logic/controller/map.go index 203f55dd..425ecbcb 100644 --- a/logic/controller/map.go +++ b/logic/controller/map.go @@ -42,7 +42,7 @@ func (h *Controller) MapEnter(data *maps.InInfo, c *entity.Player) (result *maps case <-ticker.C: // 刷新当前地图的怪物 if !c.IsFighting && c.MapId != 0 { - spawnMonsters(currentMap, c) + spawnMonsters(c) } } @@ -85,28 +85,58 @@ func (h *Controller) MapList(data *maps.ListMapPlayerInboundInfo, c *entity.Play } // 刷怪具体实现 -func spawnMonsters(mapID int, c *entity.Player) { +func spawnMonsters(c *entity.Player) { // 获取当前地图的怪物配置 - if mservice.NewMonsterService().GetId(c.MapId) == 0 { + if c == nil || mservice.NewMonsterService().GetId(c.MapId) == 0 { //用户离线 return } + if !c.IsLogin { + defer func() { + + if c.StopChan != nil { + close(c.StopChan) + c.StopChan = nil + } + }() + } // 创建数据包 tt := handler.NewTomeeHeader(2004, c.UserID) + t1 := genMonster(c.MapId) + c.SendPack(tt.Pack(&t1)) +} + +func genMonster(id uint32) maps.OgreInfo { // 设置怪物信息 t1 := maps.OgreInfo{} - //copy(t1.Data[:], monsterConfig) // 使用地图对应的怪物配置 + var localMenu = make([]int, 0) + for i := 7; i <= 448; i++ { + if bitsCount(i) == 3 { + localMenu = append(localMenu, i) + } + } + for i := 0; i < 3; i++ { ttt := maps.OgrePetInfo{} - ttt.Id = mservice.NewMonsterService().GetId(c.MapId) + ttt.Id = mservice.NewMonsterService().GetId(id) ttt.Shiny = uint32(i + 1) //t1.Data[i] = mservice.NewMonsterService().GetId(c.MapId) t1.Data[i] = ttt } - // 发送数据包 - c.SendPack(tt.Pack(&t1)) + + return t1 +} + +// 计算整数的二进制1的个数(对应Java的Integer.bitCount) +func bitsCount(n int) int { + count := 0 + for n > 0 { + count += n & 1 + n >>= 1 + } + return count }