diff --git a/.gitignore b/.gitignore index f819582af..03c114e34 100644 --- a/.gitignore +++ b/.gitignore @@ -25,5 +25,4 @@ docs/.vuepress/dist/ data/mysql/ data/redis/ go.work.sum -data/ __debug_* diff --git a/common/data/entity/Client.go b/common/data/entity/Client.go new file mode 100644 index 000000000..b501522d3 --- /dev/null +++ b/common/data/entity/Client.go @@ -0,0 +1,15 @@ +package entity + +type ClientData struct { + IsCrossDomain bool //是否跨域过 + player *player //客户实体 +} + +func NewClientData() *ClientData { + cd := &ClientData{ + IsCrossDomain: false, + player: nil, + } + return cd + +} diff --git a/common/data/entity/Server.go b/common/data/entity/Server.go new file mode 100644 index 000000000..1b42ff354 --- /dev/null +++ b/common/data/entity/Server.go @@ -0,0 +1,360 @@ +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/data/entity/player.go b/common/data/entity/player.go new file mode 100644 index 000000000..7048fc9dd --- /dev/null +++ b/common/data/entity/player.go @@ -0,0 +1,4 @@ +package entity + +type player struct { +}