diff --git a/gs/game/game_manager.go b/gs/game/game_manager.go index 94ae46ea..b4392268 100644 --- a/gs/game/game_manager.go +++ b/gs/game/game_manager.go @@ -5,8 +5,10 @@ import ( "hk4e/gate/entity/gm" "hk4e/gate/kcp" "hk4e/gs/dao" + "hk4e/gs/model" "hk4e/pkg/alg" "hk4e/pkg/logger" + "hk4e/pkg/reflection" "hk4e/protocol/cmd" "hk4e/protocol/proto" ) @@ -35,7 +37,7 @@ func NewGameManager(dao *dao.Dao, netMsgInput chan *cmd.NetMsg, netMsgOutput cha GAME_MANAGER = r LOCAL_EVENT_MANAGER = NewLocalEventManager() ROUTE_MANAGER = NewRouteManager() - USER_MANAGER = NewUserManager(dao, LOCAL_EVENT_MANAGER.localEventChan) + USER_MANAGER = NewUserManager(dao) WORLD_MANAGER = NewWorldManager(r.snowflake) TICK_MANAGER = NewTickManager() COMMAND_MANAGER = NewCommandManager() @@ -92,6 +94,27 @@ func (g *GameManager) SendMsg(cmdId uint16, userId uint32, clientSeq uint32, pay g.netMsgInput <- netMsg } +// CommonRetError 通用返回错误码 +func (g *GameManager) CommonRetError(cmdId uint16, player *model.Player, rsp pb.Message, retCode ...proto.Retcode) { + if rsp == nil { + return + } + ret := int32(proto.Retcode_RET_FAIL) + if len(retCode) == 0 { + ret = int32(proto.Retcode_RET_SVR_ERROR) + } else if len(retCode) == 1 { + ret = int32(retCode[0]) + } else { + return + } + ok := reflection.SetStructFieldValue(rsp, "Retcode", ret) + if !ok { + return + } + logger.LOG.Debug("send common error: %v", rsp) + g.SendMsg(cmdId, player.PlayerID, player.ClientSeq, rsp) +} + func (g *GameManager) ReconnectPlayer(userId uint32) { g.SendMsg(cmd.ClientReconnectNotify, userId, 0, new(proto.ClientReconnectNotify)) } diff --git a/gs/game/tick_manager.go b/gs/game/tick_manager.go index fcdf2fd2..f58afb70 100644 --- a/gs/game/tick_manager.go +++ b/gs/game/tick_manager.go @@ -150,11 +150,7 @@ func (t *TickManager) onTick10Second(now int64) { for _, player := range world.playerMap { if world.multiplayer || !world.owner.Pause { // 改面板 - team := player.TeamConfig.GetActiveTeam() - for _, avatarId := range team.AvatarIdList { - if avatarId == 0 { - break - } + for _, avatarId := range world.GetPlayerAvatarIdList(player) { avatar := player.AvatarMap[avatarId] avatar.FightPropMap[uint32(constant.FightPropertyConst.FIGHT_PROP_CUR_ATTACK)] = 1000000 avatar.FightPropMap[uint32(constant.FightPropertyConst.FIGHT_PROP_CRITICAL)] = 1.0 diff --git a/gs/game/user_avatar.go b/gs/game/user_avatar.go index 1e10e6ba..5434a377 100644 --- a/gs/game/user_avatar.go +++ b/gs/game/user_avatar.go @@ -89,7 +89,6 @@ func (g *GameManager) WearUserAvatarEquip(userId uint32, avatarId uint32, weapon world := WORLD_MANAGER.GetWorldByID(player.WorldId) scene := world.GetSceneById(player.SceneId) playerTeamEntity := scene.GetPlayerTeamEntity(player.PlayerID) - team := player.TeamConfig.GetActiveTeam() if weapon.AvatarId != 0 { // 武器在别的角色身上 @@ -105,10 +104,7 @@ func (g *GameManager) WearUserAvatarEquip(userId uint32, avatarId uint32, weapon weakAvatar := player.AvatarMap[weakAvatarId] weakWeapon := player.WeaponMap[weakAvatar.EquipWeapon.WeaponId] - for _, aid := range team.AvatarIdList { - if aid == 0 { - break - } + for _, aid := range world.GetPlayerAvatarIdList(player) { if aid == weakAvatar.AvatarId { playerTeamEntity.weaponEntityMap[weakWeapon.WeaponId] = scene.CreateEntityWeapon() } @@ -125,10 +121,7 @@ func (g *GameManager) WearUserAvatarEquip(userId uint32, avatarId uint32, weapon player.WearWeapon(avatarId, weaponId) } - for _, aid := range team.AvatarIdList { - if aid == 0 { - break - } + for _, aid := range world.GetPlayerAvatarIdList(player) { if aid == avatarId { playerTeamEntity.weaponEntityMap[weaponId] = scene.CreateEntityWeapon() } diff --git a/gs/game/user_combat.go b/gs/game/user_combat.go index 524f5706..09527687 100644 --- a/gs/game/user_combat.go +++ b/gs/game/user_combat.go @@ -148,7 +148,7 @@ func (g *GameManager) CombatInvocationsNotify(player *model.Player, payloadMsg p if motionInfo.Pos == nil || motionInfo.Rot == nil { continue } - activeAvatarId := player.TeamConfig.GetActiveAvatarId() + activeAvatarId := world.GetPlayerActiveAvatarId(player) playerTeamEntity := scene.GetPlayerTeamEntity(player.PlayerID) playerActiveAvatarEntityId := playerTeamEntity.avatarEntityMap[activeAvatarId] if entityMoveInfo.EntityId == playerActiveAvatarEntityId { @@ -232,8 +232,7 @@ func (g *GameManager) CombatInvocationsNotify(player *model.Player, payloadMsg p } } // 把队伍中的其他非活跃角色也同步进行移动 - team := player.TeamConfig.GetActiveTeam() - for _, avatarId := range team.AvatarIdList { + for _, avatarId := range world.GetPlayerAvatarIdList(player) { // 跳过当前的活跃角色 if avatarId == activeAvatarId { continue diff --git a/gs/game/user_login.go b/gs/game/user_login.go index 006ba2dd..17a6878a 100644 --- a/gs/game/user_login.go +++ b/gs/game/user_login.go @@ -33,7 +33,7 @@ func (g *GameManager) OnLoginOk(userId uint32, player *model.Player, clientSeq u player.InitAll() player.TeamConfig.UpdateTeam() // 创建世界 - world := WORLD_MANAGER.CreateWorld(player, false) + world := WORLD_MANAGER.CreateWorld(player) world.AddPlayer(player, player.SceneId) player.WorldId = world.id @@ -107,7 +107,7 @@ func (g *GameManager) OnUserOffline(userId uint32) { player.OfflineTime = uint32(time.Now().Unix()) player.Online = false player.TotalOnlineTime += uint32(time.Now().UnixMilli()) - player.OnlineTime - USER_MANAGER.OfflineUser(player) + USER_MANAGER.DeleteUser(player) } func (g *GameManager) LoginNotify(userId uint32, player *model.Player, clientSeq uint32) { @@ -258,10 +258,7 @@ func (g *GameManager) PacketAvatarDataNotify(player *model.Player) *proto.Avatar } for teamIndex, team := range player.TeamConfig.TeamList { var teamAvatarGuidList []uint64 = nil - for _, avatarId := range team.AvatarIdList { - if avatarId == 0 { - break - } + for _, avatarId := range team.GetAvatarIdList() { teamAvatarGuidList = append(teamAvatarGuidList, player.AvatarMap[avatarId].Guid) } avatarDataNotify.AvatarTeamMap[uint32(teamIndex)+1] = &proto.AvatarTeam{ @@ -375,7 +372,7 @@ func (g *GameManager) CreatePlayer(userId uint32, nickName string, mainCharAvata player.WearWeapon(mainCharAvatarId, weaponId) player.TeamConfig = model.NewTeamInfo() - player.TeamConfig.AddAvatarToTeam(mainCharAvatarId, 0) + player.TeamConfig.SetTeamAvatar(0, []uint32{mainCharAvatarId}) return player } diff --git a/gs/game/user_manager.go b/gs/game/user_manager.go index 694e560e..e6d0b4da 100644 --- a/gs/game/user_manager.go +++ b/gs/game/user_manager.go @@ -1,7 +1,6 @@ package game import ( - "encoding/json" "sync" "time" @@ -12,24 +11,20 @@ import ( ) type UserManager struct { - dao *dao.Dao - playerMap map[uint32]*model.Player - playerMapLock sync.RWMutex - localEventChan chan *LocalEvent + dao *dao.Dao + playerMap map[uint32]*model.Player + playerMapLock sync.RWMutex } -func NewUserManager(dao *dao.Dao, localEventChan chan *LocalEvent) (r *UserManager) { +func NewUserManager(dao *dao.Dao) (r *UserManager) { r = new(UserManager) r.dao = dao r.playerMap = make(map[uint32]*model.Player) - r.localEventChan = localEventChan return r } func (u *UserManager) GetUserOnlineState(userId uint32) bool { - u.playerMapLock.RLock() player, exist := u.playerMap[userId] - u.playerMapLock.RUnlock() if !exist { return false } else { @@ -38,9 +33,7 @@ func (u *UserManager) GetUserOnlineState(userId uint32) bool { } func (u *UserManager) GetOnlineUser(userId uint32) *model.Player { - u.playerMapLock.RLock() player, exist := u.playerMap[userId] - u.playerMapLock.RUnlock() if !exist { return nil } else { @@ -54,14 +47,12 @@ func (u *UserManager) GetOnlineUser(userId uint32) *model.Player { func (u *UserManager) GetAllOnlineUserList() map[uint32]*model.Player { onlinePlayerMap := make(map[uint32]*model.Player) - u.playerMapLock.RLock() for userId, player := range u.playerMap { if player.Online == false { continue } onlinePlayerMap[userId] = player } - u.playerMapLock.RUnlock() return onlinePlayerMap } @@ -73,9 +64,7 @@ type PlayerRegInfo struct { } func (u *UserManager) CheckUserExistOnReg(userId uint32, req *proto.SetPlayerBornDataReq, clientSeq uint32) (exist bool, asyncWait bool) { - u.playerMapLock.RLock() _, exist = u.playerMap[userId] - u.playerMapLock.RUnlock() if exist { return true, false } else { @@ -85,7 +74,7 @@ func (u *UserManager) CheckUserExistOnReg(userId uint32, req *proto.SetPlayerBor if player != nil { exist = true } - u.localEventChan <- &LocalEvent{ + LOCAL_EVENT_MANAGER.localEventChan <- &LocalEvent{ EventId: CheckUserExistOnRegFromDbFinish, Msg: &PlayerRegInfo{ Exist: exist, @@ -100,9 +89,7 @@ func (u *UserManager) CheckUserExistOnReg(userId uint32, req *proto.SetPlayerBor } func (u *UserManager) LoadTempOfflineUserSync(userId uint32) *model.Player { - u.playerMapLock.RLock() player, exist := u.playerMap[userId] - u.playerMapLock.RUnlock() if exist { return player } else { @@ -110,10 +97,7 @@ func (u *UserManager) LoadTempOfflineUserSync(userId uint32) *model.Player { if player == nil { return nil } - player.DbState = model.DbOffline - u.playerMapLock.Lock() u.playerMap[player.PlayerID] = player - u.playerMapLock.Unlock() return player } } @@ -132,9 +116,7 @@ func (u *UserManager) AddUser(player *model.Player) { return } u.ChangeUserDbState(player, model.DbInsert) - u.playerMapLock.Lock() u.playerMap[player.PlayerID] = player - u.playerMapLock.Unlock() } func (u *UserManager) DeleteUser(player *model.Player) { @@ -142,19 +124,7 @@ func (u *UserManager) DeleteUser(player *model.Player) { return } u.ChangeUserDbState(player, model.DbDelete) - u.playerMapLock.Lock() u.playerMap[player.PlayerID] = player - u.playerMapLock.Unlock() -} - -func (u *UserManager) UpdateUser(player *model.Player) { - if player == nil { - return - } - u.ChangeUserDbState(player, model.DbUpdate) - u.playerMapLock.Lock() - u.playerMap[player.PlayerID] = player - u.playerMapLock.Unlock() } type PlayerLoginInfo struct { @@ -164,9 +134,7 @@ type PlayerLoginInfo struct { } func (u *UserManager) OnlineUser(userId uint32, clientSeq uint32) (*model.Player, bool) { - u.playerMapLock.RLock() player, exist := u.playerMap[userId] - u.playerMapLock.RUnlock() if exist { u.ChangeUserDbState(player, model.DbNormal) return player, false @@ -179,7 +147,7 @@ func (u *UserManager) OnlineUser(userId uint32, clientSeq uint32) (*model.Player u.playerMap[player.PlayerID] = player u.playerMapLock.Unlock() } - u.localEventChan <- &LocalEvent{ + LOCAL_EVENT_MANAGER.localEventChan <- &LocalEvent{ EventId: LoadLoginUserFromDbFinish, Msg: &PlayerLoginInfo{ UserId: userId, @@ -192,53 +160,27 @@ func (u *UserManager) OnlineUser(userId uint32, clientSeq uint32) (*model.Player } } -func (u *UserManager) OfflineUser(player *model.Player) { - if player == nil { - return - } - u.ChangeUserDbState(player, model.DbOffline) - u.playerMapLock.Lock() - u.playerMap[player.PlayerID] = player - u.playerMapLock.Unlock() -} - func (u *UserManager) ChangeUserDbState(player *model.Player, state int) { if player == nil { return } switch player.DbState { case model.DbInsert: - if state == model.DbDelete { - player.DbState = model.DbDelete - } + break case model.DbDelete: - case model.DbUpdate: - if state == model.DbDelete { - player.DbState = model.DbDelete - } else if state == model.DbOffline { - player.DbState = model.DbOffline + if state == model.DbNormal { + player.DbState = model.DbNormal } case model.DbNormal: if state == model.DbDelete { player.DbState = model.DbDelete - } else if state == model.DbUpdate { - player.DbState = model.DbUpdate - } else if state == model.DbOffline { - player.DbState = model.DbOffline - } - case model.DbOffline: - if state == model.DbDelete { - player.DbState = model.DbDelete - } else if state == model.DbUpdate { - player.DbState = model.DbUpdate - } else if state == model.DbNormal { - player.DbState = model.DbNormal } } } +// 用户数据库定时同步协程 + func (u *UserManager) StartAutoSaveUser() { - // 用户数据库定时同步协程 go func() { ticker := time.NewTicker(time.Minute * 5) for { @@ -249,57 +191,44 @@ func (u *UserManager) StartAutoSaveUser() { } func (u *UserManager) SaveUser() { - logger.LOG.Info("auto save user start") - playerMapTemp := make(map[uint32]*model.Player) + playerMapSave := make(map[uint32]*model.Player, len(u.playerMap)) u.playerMapLock.RLock() for k, v := range u.playerMap { - playerMapTemp[k] = v + playerMapSave[k] = v } u.playerMapLock.RUnlock() - logger.LOG.Info("copyLocalTeamToWorld user map finish") insertList := make([]*model.Player, 0) - deleteList := make([]uint32, 0) updateList := make([]*model.Player, 0) - for k, v := range playerMapTemp { - switch v.DbState { - case model.DbInsert: - insertList = append(insertList, v) - playerMapTemp[k].DbState = model.DbNormal - case model.DbDelete: - deleteList = append(deleteList, v.PlayerID) - delete(playerMapTemp, k) - case model.DbUpdate: - updateList = append(updateList, v) - playerMapTemp[k].DbState = model.DbNormal - case model.DbNormal: + for uid, player := range playerMapSave { + if uid < 100000000 { continue - case model.DbOffline: - updateList = append(updateList, v) - delete(playerMapTemp, k) + } + switch player.DbState { + case model.DbInsert: + insertList = append(insertList, player) + playerMapSave[uid].DbState = model.DbNormal + case model.DbDelete: + updateList = append(updateList, player) + delete(playerMapSave, uid) + case model.DbNormal: + updateList = append(updateList, player) + } + if !player.Online { + delete(playerMapSave, uid) } } - insertListJson, err := json.Marshal(insertList) - logger.LOG.Debug("insertList: %v", string(insertListJson)) - deleteListJson, err := json.Marshal(deleteList) - logger.LOG.Debug("deleteList: %v", string(deleteListJson)) - updateListJson, err := json.Marshal(updateList) - logger.LOG.Debug("updateList: %v", string(updateListJson)) - logger.LOG.Info("db state init finish") - err = u.dao.InsertPlayerList(insertList) + err := u.dao.InsertPlayerList(insertList) if err != nil { logger.LOG.Error("insert player list error: %v", err) - } - err = u.dao.DeletePlayerList(deleteList) - if err != nil { - logger.LOG.Error("delete player error: %v", err) + return } err = u.dao.UpdatePlayerList(updateList) if err != nil { - logger.LOG.Error("update player error: %v", err) + logger.LOG.Error("update player list error: %v", err) + return } - logger.LOG.Info("db write finish") u.playerMapLock.Lock() - u.playerMap = playerMapTemp + u.playerMap = playerMapSave u.playerMapLock.Unlock() - logger.LOG.Info("auto save user finish") + logger.LOG.Info("save user finish, insert user count: %v, update user count: %v", len(insertList), len(updateList)) } diff --git a/gs/game/user_map.go b/gs/game/user_map.go index d41c30a8..bc5a9c7b 100644 --- a/gs/game/user_map.go +++ b/gs/game/user_map.go @@ -84,7 +84,7 @@ func (g *GameManager) TeleportPlayer(player *model.Player, sceneId uint32, pos * } world := WORLD_MANAGER.GetWorldByID(player.WorldId) oldScene := world.GetSceneById(oldSceneId) - activeAvatarId := player.TeamConfig.GetActiveAvatarId() + activeAvatarId := world.GetPlayerActiveAvatarId(player) playerTeamEntity := oldScene.GetPlayerTeamEntity(player.PlayerID) g.RemoveSceneEntityNotifyBroadcast(oldScene, proto.VisionType_VISION_TYPE_REMOVE, []uint32{playerTeamEntity.avatarEntityMap[activeAvatarId]}) if jumpScene { diff --git a/gs/game/user_multiplayer.go b/gs/game/user_multiplayer.go index 81730484..77f66f69 100644 --- a/gs/game/user_multiplayer.go +++ b/gs/game/user_multiplayer.go @@ -269,7 +269,7 @@ func (g *GameManager) UserDealEnterWorld(hostPlayer *model.Player, otherUid uint // 仅仅把当前的场上角色的实体消失掉 scene := world.GetSceneById(hostPlayer.SceneId) playerTeamEntity := scene.GetPlayerTeamEntity(hostPlayer.PlayerID) - activeAvatarId := hostPlayer.TeamConfig.GetActiveAvatarId() + activeAvatarId := world.GetPlayerActiveAvatarId(hostPlayer) g.RemoveSceneEntityNotifyToPlayer(hostPlayer, proto.VisionType_VISION_TYPE_MISS, []uint32{playerTeamEntity.avatarEntityMap[activeAvatarId]}) } @@ -295,7 +295,7 @@ func (g *GameManager) UserWorldAddPlayer(world *World, player *model.Player) { } world.AddPlayer(player, player.SceneId) player.WorldId = world.id - if len(world.playerMap) > 1 { + if world.GetWorldPlayerNum() > 1 { g.UpdateWorldPlayerInfo(world, player) } } @@ -316,7 +316,7 @@ func (g *GameManager) UserWorldRemovePlayer(world *World, player *model.Player) // 仅仅把当前的场上角色的实体消失掉 playerTeamEntity := scene.GetPlayerTeamEntity(player.PlayerID) - activeAvatarId := player.TeamConfig.GetActiveAvatarId() + activeAvatarId := world.GetPlayerActiveAvatarId(player) g.RemoveSceneEntityNotifyToPlayer(player, proto.VisionType_VISION_TYPE_MISS, []uint32{playerTeamEntity.avatarEntityMap[activeAvatarId]}) delTeamEntityNotify := g.PacketDelTeamEntityNotify(scene, player) @@ -328,14 +328,14 @@ func (g *GameManager) UserWorldRemovePlayer(world *World, player *model.Player) } g.SendMsg(cmd.PlayerQuitFromMpNotify, player.PlayerID, player.ClientSeq, playerQuitFromMpNotify) - activeAvatarId := player.TeamConfig.GetActiveAvatarId() + activeAvatarId := world.GetPlayerActiveAvatarId(player) playerTeamEntity := scene.GetPlayerTeamEntity(player.PlayerID) g.RemoveSceneEntityNotifyBroadcast(scene, proto.VisionType_VISION_TYPE_REMOVE, []uint32{playerTeamEntity.avatarEntityMap[activeAvatarId]}) } world.RemovePlayer(player) player.WorldId = 0 - if world.multiplayer && len(world.playerMap) > 0 { + if world.multiplayer && world.GetWorldPlayerNum() > 0 { g.UpdateWorldPlayerInfo(world, player) } if world.owner.PlayerID == player.PlayerID { @@ -370,7 +370,7 @@ func (g *GameManager) UpdateWorldPlayerInfo(hostWorld *World, excludePlayer *mod NameCardId: subWorldPlayer.NameCard, Signature: subWorldPlayer.Signature, ProfilePicture: &proto.ProfilePicture{AvatarId: subWorldPlayer.HeadImage}, - CurPlayerNumInWorld: uint32(len(hostWorld.playerMap)), + CurPlayerNumInWorld: uint32(hostWorld.GetWorldPlayerNum()), } worldPlayerInfoNotify.PlayerInfoList = append(worldPlayerInfoNotify.PlayerInfoList, onlinePlayerInfo) @@ -395,7 +395,7 @@ func (g *GameManager) UpdateWorldPlayerInfo(hostWorld *World, excludePlayer *mod NameCardId: worldPlayer.NameCard, Signature: worldPlayer.Signature, ProfilePicture: &proto.ProfilePicture{AvatarId: worldPlayer.HeadImage}, - CurPlayerNumInWorld: uint32(len(hostWorld.playerMap)), + CurPlayerNumInWorld: uint32(hostWorld.GetWorldPlayerNum()), } scenePlayerInfoNotify.PlayerInfoList = append(scenePlayerInfoNotify.PlayerInfoList, &proto.ScenePlayerInfo{ Uid: worldPlayer.PlayerID, @@ -407,7 +407,7 @@ func (g *GameManager) UpdateWorldPlayerInfo(hostWorld *World, excludePlayer *mod } g.SendMsg(cmd.ScenePlayerInfoNotify, worldPlayer.PlayerID, worldPlayer.ClientSeq, scenePlayerInfoNotify) - sceneTeamUpdateNotify := g.PacketSceneTeamUpdateNotifyMp(hostWorld) + sceneTeamUpdateNotify := g.PacketSceneTeamUpdateNotify(hostWorld) g.SendMsg(cmd.SceneTeamUpdateNotify, worldPlayer.PlayerID, worldPlayer.ClientSeq, sceneTeamUpdateNotify) syncTeamEntityNotify := &proto.SyncTeamEntityNotify{ diff --git a/gs/game/user_scene.go b/gs/game/user_scene.go index 295255f1..eebdbc73 100644 --- a/gs/game/user_scene.go +++ b/gs/game/user_scene.go @@ -58,7 +58,7 @@ func (g *GameManager) SceneInitFinishReq(player *model.Player, payloadMsg pb.Mes NameCardId: worldPlayer.NameCard, Signature: worldPlayer.Signature, ProfilePicture: &proto.ProfilePicture{AvatarId: worldPlayer.HeadImage}, - CurPlayerNumInWorld: uint32(len(world.playerMap)), + CurPlayerNumInWorld: uint32(world.GetWorldPlayerNum()), } worldPlayerInfoNotify.PlayerInfoList = append(worldPlayerInfoNotify.PlayerInfoList, onlinePlayerInfo) worldPlayerInfoNotify.PlayerUidList = append(worldPlayerInfoNotify.PlayerUidList, worldPlayer.PlayerID) @@ -116,7 +116,7 @@ func (g *GameManager) SceneInitFinishReq(player *model.Player, payloadMsg pb.Mes g.SendMsg(cmd.PlayerGameTimeNotify, player.PlayerID, player.ClientSeq, playerGameTimeNotify) empty := new(proto.AbilitySyncStateInfo) - activeAvatarId := player.TeamConfig.GetActiveAvatarId() + activeAvatarId := world.GetPlayerActiveAvatarId(player) playerTeamEntity := scene.GetPlayerTeamEntity(player.PlayerID) playerEnterSceneInfoNotify := &proto.PlayerEnterSceneInfoNotify{ CurAvatarEntityId: playerTeamEntity.avatarEntityMap[activeAvatarId], @@ -133,11 +133,7 @@ func (g *GameManager) SceneInitFinishReq(player *model.Player, payloadMsg pb.Mes }, AvatarEnterInfo: make([]*proto.AvatarEnterSceneInfo, 0), } - activeTeam := player.TeamConfig.GetActiveTeam() - for _, avatarId := range activeTeam.AvatarIdList { - if avatarId == 0 { - break - } + for _, avatarId := range world.GetPlayerAvatarIdList(player) { avatar := player.AvatarMap[avatarId] avatarEnterSceneInfo := &proto.AvatarEnterSceneInfo{ AvatarGuid: avatar.Guid, @@ -170,7 +166,7 @@ func (g *GameManager) SceneInitFinishReq(player *model.Player, payloadMsg pb.Mes NameCardId: worldPlayer.NameCard, Signature: worldPlayer.Signature, ProfilePicture: &proto.ProfilePicture{AvatarId: worldPlayer.HeadImage}, - CurPlayerNumInWorld: uint32(len(world.playerMap)), + CurPlayerNumInWorld: uint32(world.GetWorldPlayerNum()), } scenePlayerInfoNotify.PlayerInfoList = append(scenePlayerInfoNotify.PlayerInfoList, &proto.ScenePlayerInfo{ Uid: worldPlayer.PlayerID, @@ -182,12 +178,7 @@ func (g *GameManager) SceneInitFinishReq(player *model.Player, payloadMsg pb.Mes } g.SendMsg(cmd.ScenePlayerInfoNotify, player.PlayerID, player.ClientSeq, scenePlayerInfoNotify) - var sceneTeamUpdateNotify *proto.SceneTeamUpdateNotify = nil - if world.multiplayer { - sceneTeamUpdateNotify = g.PacketSceneTeamUpdateNotifyMp(world) - } else { - sceneTeamUpdateNotify = g.PacketSceneTeamUpdateNotify(world) - } + sceneTeamUpdateNotify := g.PacketSceneTeamUpdateNotify(world) g.SendMsg(cmd.SceneTeamUpdateNotify, player.PlayerID, player.ClientSeq, sceneTeamUpdateNotify) syncTeamEntityNotify := &proto.SyncTeamEntityNotify{ @@ -240,7 +231,7 @@ func (g *GameManager) EnterSceneDoneReq(player *model.Player, payloadMsg pb.Mess var visionType = proto.VisionType_VISION_TYPE_TRANSPORT playerTeamEntity := scene.GetPlayerTeamEntity(player.PlayerID) - activeAvatarId := player.TeamConfig.GetActiveAvatarId() + activeAvatarId := world.GetPlayerActiveAvatarId(player) if world.IsPlayerFirstEnter(player) { visionType = proto.VisionType_VISION_TYPE_BORN } @@ -463,10 +454,10 @@ func (g *GameManager) AddSceneEntityNotify(player *model.Player, visionType prot logger.LOG.Error("get scene player is nil, world id: %v, scene id: %v", world.id, scene.id) continue } - if entity.avatarEntity.avatarId != scenePlayer.TeamConfig.GetActiveAvatarId() { + if entity.avatarEntity.avatarId != world.GetPlayerActiveAvatarId(scenePlayer) { continue } - sceneEntityInfoAvatar := g.PacketSceneEntityInfoAvatar(scene, scenePlayer, scenePlayer.TeamConfig.GetActiveAvatarId()) + sceneEntityInfoAvatar := g.PacketSceneEntityInfoAvatar(scene, scenePlayer, world.GetPlayerActiveAvatarId(scenePlayer)) entityList = append(entityList, sceneEntityInfoAvatar) case uint32(proto.ProtEntityType_PROT_ENTITY_TYPE_WEAPON): case uint32(proto.ProtEntityType_PROT_ENTITY_TYPE_MONSTER): @@ -707,9 +698,9 @@ func (g *GameManager) PacketSceneAvatarInfo(scene *Scene, player *model.Player, BornTime: uint32(player.AvatarMap[avatarId].BornTime), TeamResonanceList: make([]uint32, 0), } - for id := range player.TeamConfig.TeamResonances { - sceneAvatarInfo.TeamResonanceList = append(sceneAvatarInfo.TeamResonanceList, uint32(id)) - } + //for id := range player.TeamConfig.TeamResonances { + // sceneAvatarInfo.TeamResonanceList = append(sceneAvatarInfo.TeamResonanceList, uint32(id)) + //} return sceneAvatarInfo } diff --git a/gs/game/user_social.go b/gs/game/user_social.go index 007b71f2..30a98051 100644 --- a/gs/game/user_social.go +++ b/gs/game/user_social.go @@ -49,6 +49,7 @@ func (g *GameManager) SetPlayerBirthdayReq(player *model.Player, payloadMsg pb.M logger.LOG.Debug("user set birthday, uid: %v", player.PlayerID) req := payloadMsg.(*proto.SetPlayerBirthdayReq) _ = req + g.CommonRetError(cmd.SetPlayerBirthdayRsp, player, &proto.SetPlayerBirthdayRsp{}) } func (g *GameManager) SetNameCardReq(player *model.Player, payloadMsg pb.Message) { @@ -336,7 +337,7 @@ func (g *GameManager) PacketOnlinePlayerInfo(player *model.Player) *proto.Online } world := WORLD_MANAGER.GetWorldByID(player.WorldId) if world != nil && world.playerMap != nil { - onlinePlayerInfo.CurPlayerNumInWorld = uint32(len(world.playerMap)) + onlinePlayerInfo.CurPlayerNumInWorld = uint32(world.GetWorldPlayerNum()) } return onlinePlayerInfo } diff --git a/gs/game/user_stamina.go b/gs/game/user_stamina.go index f360af3e..9263d2f5 100644 --- a/gs/game/user_stamina.go +++ b/gs/game/user_stamina.go @@ -27,7 +27,12 @@ func (g *GameManager) SceneAvatarStaminaStepReq(player *model.Player, payloadMsg } else if req.Rot.X > 270 && req.Rot.X < 360 { angleRevise = int32(req.Rot.X - 360.0) } else { - logger.LOG.Error("invalid rot x angle: %v", req.Rot.X) + logger.LOG.Error("invalid rot x angle: %v, uid: %v", req.Rot.X, player.PlayerID) + sceneAvatarStaminaStepRsp := &proto.SceneAvatarStaminaStepRsp{ + Retcode: int32(proto.Retcode_RET_FAIL), + } + g.SendMsg(cmd.SceneAvatarStaminaStepRsp, player.PlayerID, player.ClientSeq, sceneAvatarStaminaStepRsp) + return } // 攀爬耐力修正曲线 // angle >= 0 cost = -x + 10 @@ -49,12 +54,6 @@ func (g *GameManager) SceneAvatarStaminaStepReq(player *model.Player, payloadMsg // PacketSceneAvatarStaminaStepRsp sceneAvatarStaminaStepRsp := new(proto.SceneAvatarStaminaStepRsp) - // 角度超过范围返回值为错误 - if (req.Rot.X >= 0 && req.Rot.X < 90) || (req.Rot.X > 270 && req.Rot.X < 360) { - sceneAvatarStaminaStepRsp.Retcode = int32(proto.Retcode_RET_SUCC) - } else { - sceneAvatarStaminaStepRsp.Retcode = int32(proto.Retcode_RET_FAIL) - } sceneAvatarStaminaStepRsp.UseClientRot = true sceneAvatarStaminaStepRsp.Rot = req.Rot g.SendMsg(cmd.SceneAvatarStaminaStepRsp, player.PlayerID, player.ClientSeq, sceneAvatarStaminaStepRsp) @@ -62,6 +61,10 @@ func (g *GameManager) SceneAvatarStaminaStepReq(player *model.Player, payloadMsg // HandleStamina 处理即时耐力消耗 func (g *GameManager) HandleStamina(player *model.Player, motionState proto.MotionState) { + // 玩家暂停状态不更新耐力 + if player.Pause { + return + } staminaInfo := player.StaminaInfo //logger.LOG.Debug("stamina handle, uid: %v, motionState: %v", player.PlayerID, motionState) @@ -129,6 +132,10 @@ func (g *GameManager) HandleSkillStartStamina(player *model.Player, skillId uint // StaminaHandler 处理持续耐力消耗 func (g *GameManager) StaminaHandler(player *model.Player) { + // 玩家暂停状态不更新耐力 + if player.Pause { + return + } staminaInfo := player.StaminaInfo // 添加的耐力大于0为恢复 @@ -222,12 +229,13 @@ func (g *GameManager) UpdateStamina(player *model.Player, staminaCost int32) { // SetStamina 设置玩家的耐力 func (g *GameManager) SetStamina(player *model.Player, stamina uint32) { prop := constant.PlayerPropertyConst.PROP_CUR_PERSIST_STAMINA + // 设置玩家的耐力prop + player.PropertiesMap[prop] = stamina + //logger.LOG.Debug("player curr stamina: %v", stamina) // 当前无变动不要频繁发包 if player.PropertiesMap[constant.PlayerPropertyConst.PROP_MAX_STAMINA] == player.PropertiesMap[constant.PlayerPropertyConst.PROP_CUR_PERSIST_STAMINA] { return } - // 设置玩家的耐力prop - player.PropertiesMap[prop] = stamina // PacketPlayerPropNotify playerPropNotify := new(proto.PlayerPropNotify) diff --git a/gs/game/user_team.go b/gs/game/user_team.go index 3794d6d0..8c56316f 100644 --- a/gs/game/user_team.go +++ b/gs/game/user_team.go @@ -21,18 +21,14 @@ func (g *GameManager) ChangeAvatarReq(player *model.Player, payloadMsg pb.Messag scene := world.GetSceneById(player.SceneId) playerTeamEntity := scene.GetPlayerTeamEntity(player.PlayerID) - oldAvatarId := player.TeamConfig.GetActiveAvatarId() + oldAvatarId := world.GetPlayerActiveAvatarId(player) oldAvatar := player.AvatarMap[oldAvatarId] if oldAvatar.Guid == targetAvatarGuid { logger.LOG.Error("can not change to the same avatar, uid: %v, oldAvatarId: %v, oldAvatarGuid: %v", player.PlayerID, oldAvatarId, oldAvatar.Guid) return } - activeTeam := player.TeamConfig.GetActiveTeam() index := -1 - for avatarIndex, avatarId := range activeTeam.AvatarIdList { - if avatarId == 0 { - break - } + for avatarIndex, avatarId := range world.GetPlayerAvatarIdList(player) { if targetAvatarGuid == player.AvatarMap[avatarId].Guid { index = avatarIndex } @@ -42,6 +38,7 @@ func (g *GameManager) ChangeAvatarReq(player *model.Player, payloadMsg pb.Messag return } player.TeamConfig.CurrAvatarIndex = uint8(index) + world.SetPlayerLocalAvatarIndex(player, index) entity := scene.GetEntity(playerTeamEntity.avatarEntityMap[oldAvatarId]) if entity == nil { @@ -57,10 +54,12 @@ func (g *GameManager) ChangeAvatarReq(player *model.Player, payloadMsg pb.Messag g.SendMsg(cmd.SceneEntityDisappearNotify, scenePlayer.PlayerID, scenePlayer.ClientSeq, sceneEntityDisappearNotify) } + newAvatarId := world.GetPlayerActiveAvatarId(player) + newAvatarEntity := g.PacketSceneEntityInfoAvatar(scene, player, newAvatarId) sceneEntityAppearNotify := &proto.SceneEntityAppearNotify{ AppearType: proto.VisionType_VISION_TYPE_REPLACE, Param: playerTeamEntity.avatarEntityMap[oldAvatarId], - EntityList: []*proto.SceneEntityInfo{g.PacketSceneEntityInfoAvatar(scene, player, player.TeamConfig.GetActiveAvatarId())}, + EntityList: []*proto.SceneEntityInfo{newAvatarEntity}, } for _, scenePlayer := range scene.playerMap { g.SendMsg(cmd.SceneEntityAppearNotify, scenePlayer.PlayerID, scenePlayer.ClientSeq, sceneEntityAppearNotify) @@ -74,25 +73,22 @@ func (g *GameManager) ChangeAvatarReq(player *model.Player, payloadMsg pb.Messag } func (g *GameManager) SetUpAvatarTeamReq(player *model.Player, payloadMsg pb.Message) { - logger.LOG.Debug("user change team, uid: %v", player.PlayerID) + logger.LOG.Debug("user change team avatar, uid: %v", player.PlayerID) req := payloadMsg.(*proto.SetUpAvatarTeamReq) - + world := WORLD_MANAGER.GetWorldByID(player.WorldId) + if world.multiplayer { + g.CommonRetError(cmd.SetUpAvatarTeamRsp, player, &proto.SetUpAvatarTeamRsp{}) + return + } teamId := req.TeamId if teamId <= 0 || teamId >= 5 { - setUpAvatarTeamRsp := &proto.SetUpAvatarTeamRsp{ - Retcode: int32(proto.Retcode_RET_SVR_ERROR), - } - g.SendMsg(cmd.SetUpAvatarTeamRsp, player.PlayerID, player.ClientSeq, setUpAvatarTeamRsp) + g.CommonRetError(cmd.SetUpAvatarTeamRsp, player, &proto.SetUpAvatarTeamRsp{}) return } avatarGuidList := req.AvatarTeamGuidList - world := WORLD_MANAGER.GetWorldByID(player.WorldId) selfTeam := teamId == uint32(player.TeamConfig.GetActiveTeamId()) - if (selfTeam && len(avatarGuidList) == 0) || len(avatarGuidList) > 4 || world.multiplayer { - setUpAvatarTeamRsp := &proto.SetUpAvatarTeamRsp{ - Retcode: int32(proto.Retcode_RET_SVR_ERROR), - } - g.SendMsg(cmd.SetUpAvatarTeamRsp, player.PlayerID, player.ClientSeq, setUpAvatarTeamRsp) + if (selfTeam && len(avatarGuidList) == 0) || len(avatarGuidList) > 4 { + g.CommonRetError(cmd.SetUpAvatarTeamRsp, player, &proto.SetUpAvatarTeamRsp{}) return } avatarIdList := make([]uint32, 0) @@ -104,17 +100,7 @@ func (g *GameManager) SetUpAvatarTeamReq(player *model.Player, payloadMsg pb.Mes } } player.TeamConfig.ClearTeamAvatar(uint8(teamId - 1)) - for _, avatarId := range avatarIdList { - player.TeamConfig.AddAvatarToTeam(avatarId, uint8(teamId-1)) - } - - if world.multiplayer { - setUpAvatarTeamRsp := &proto.SetUpAvatarTeamRsp{ - Retcode: int32(proto.Retcode_RET_SVR_ERROR), - } - g.SendMsg(cmd.SetUpAvatarTeamRsp, player.PlayerID, player.ClientSeq, setUpAvatarTeamRsp) - return - } + player.TeamConfig.SetTeamAvatar(uint8(teamId-1), avatarIdList) avatarTeamUpdateNotify := &proto.AvatarTeamUpdateNotify{ AvatarTeamMap: make(map[uint32]*proto.AvatarTeam), @@ -124,10 +110,7 @@ func (g *GameManager) SetUpAvatarTeamReq(player *model.Player, payloadMsg pb.Mes TeamName: team.Name, AvatarGuidList: make([]uint64, 0), } - for _, avatarId := range team.AvatarIdList { - if avatarId == 0 { - break - } + for _, avatarId := range team.GetAvatarIdList() { avatarTeam.AvatarGuidList = append(avatarTeam.AvatarGuidList, player.AvatarMap[avatarId].Guid) } avatarTeamUpdateNotify.AvatarTeamMap[uint32(teamIndex)+1] = avatarTeam @@ -137,40 +120,27 @@ func (g *GameManager) SetUpAvatarTeamReq(player *model.Player, payloadMsg pb.Mes if selfTeam { player.TeamConfig.CurrAvatarIndex = 0 player.TeamConfig.UpdateTeam() + world.SetPlayerLocalAvatarIndex(player, 0) + world.SetPlayerLocalTeam(player, avatarIdList) + world.UpdateMultiplayerTeam() scene := world.GetSceneById(player.SceneId) scene.UpdatePlayerTeamEntity(player) sceneTeamUpdateNotify := g.PacketSceneTeamUpdateNotify(world) g.SendMsg(cmd.SceneTeamUpdateNotify, player.PlayerID, player.ClientSeq, sceneTeamUpdateNotify) - - setUpAvatarTeamRsp := &proto.SetUpAvatarTeamRsp{ - TeamId: teamId, - CurAvatarGuid: player.AvatarMap[player.TeamConfig.GetActiveAvatarId()].Guid, - AvatarTeamGuidList: make([]uint64, 0), - } - team := player.TeamConfig.GetTeamByIndex(uint8(teamId - 1)) - for _, avatarId := range team.AvatarIdList { - if avatarId == 0 { - break - } - setUpAvatarTeamRsp.AvatarTeamGuidList = append(setUpAvatarTeamRsp.AvatarTeamGuidList, player.AvatarMap[avatarId].Guid) - } - g.SendMsg(cmd.SetUpAvatarTeamRsp, player.PlayerID, player.ClientSeq, setUpAvatarTeamRsp) - } else { - setUpAvatarTeamRsp := &proto.SetUpAvatarTeamRsp{ - TeamId: teamId, - CurAvatarGuid: player.AvatarMap[player.TeamConfig.GetActiveAvatarId()].Guid, - AvatarTeamGuidList: make([]uint64, 0), - } - team := player.TeamConfig.GetTeamByIndex(uint8(teamId - 1)) - for _, avatarId := range team.AvatarIdList { - if avatarId == 0 { - break - } - setUpAvatarTeamRsp.AvatarTeamGuidList = append(setUpAvatarTeamRsp.AvatarTeamGuidList, player.AvatarMap[avatarId].Guid) - } - g.SendMsg(cmd.SetUpAvatarTeamRsp, player.PlayerID, player.ClientSeq, setUpAvatarTeamRsp) } + + activeAvatarId := world.GetPlayerActiveAvatarId(player) + setUpAvatarTeamRsp := &proto.SetUpAvatarTeamRsp{ + TeamId: teamId, + CurAvatarGuid: player.AvatarMap[activeAvatarId].Guid, + AvatarTeamGuidList: make([]uint64, 0), + } + team := player.TeamConfig.GetTeamByIndex(uint8(teamId - 1)) + for _, avatarId := range team.GetAvatarIdList() { + setUpAvatarTeamRsp.AvatarTeamGuidList = append(setUpAvatarTeamRsp.AvatarTeamGuidList, player.AvatarMap[avatarId].Guid) + } + g.SendMsg(cmd.SetUpAvatarTeamRsp, player.PlayerID, player.ClientSeq, setUpAvatarTeamRsp) } func (g *GameManager) ChooseCurAvatarTeamReq(player *model.Player, payloadMsg pb.Message) { @@ -179,15 +149,19 @@ func (g *GameManager) ChooseCurAvatarTeamReq(player *model.Player, payloadMsg pb teamId := req.TeamId world := WORLD_MANAGER.GetWorldByID(player.WorldId) if world.multiplayer { + g.CommonRetError(cmd.ChooseCurAvatarTeamRsp, player, &proto.ChooseCurAvatarTeamRsp{}) return } team := player.TeamConfig.GetTeamByIndex(uint8(teamId) - 1) - if team == nil || len(team.AvatarIdList) == 0 { + if team == nil || len(team.GetAvatarIdList()) == 0 { return } player.TeamConfig.CurrTeamIndex = uint8(teamId) - 1 player.TeamConfig.CurrAvatarIndex = 0 player.TeamConfig.UpdateTeam() + world.SetPlayerLocalAvatarIndex(player, 0) + world.SetPlayerLocalTeam(player, team.GetAvatarIdList()) + world.UpdateMultiplayerTeam() scene := world.GetSceneById(player.SceneId) scene.UpdatePlayerTeamEntity(player) @@ -201,17 +175,13 @@ func (g *GameManager) ChooseCurAvatarTeamReq(player *model.Player, payloadMsg pb } func (g *GameManager) ChangeMpTeamAvatarReq(player *model.Player, payloadMsg pb.Message) { - logger.LOG.Debug("user change mp team, uid: %v", player.PlayerID) + logger.LOG.Debug("user change mp team avatar, uid: %v", player.PlayerID) req := payloadMsg.(*proto.ChangeMpTeamAvatarReq) - currAvatarGuid := req.CurAvatarGuid avatarGuidList := req.AvatarGuidList world := WORLD_MANAGER.GetWorldByID(player.WorldId) - if len(avatarGuidList) == 0 || len(avatarGuidList) > 4 || !world.multiplayer { - changeMpTeamAvatarRsp := &proto.ChangeMpTeamAvatarRsp{ - Retcode: int32(proto.Retcode_RET_SVR_ERROR), - } - g.SendMsg(cmd.ChangeMpTeamAvatarRsp, player.PlayerID, player.ClientSeq, changeMpTeamAvatarRsp) + if !world.multiplayer || len(avatarGuidList) == 0 || len(avatarGuidList) > 4 { + g.CommonRetError(cmd.ChangeMpTeamAvatarRsp, player, &proto.ChangeMpTeamAvatarRsp{}) return } @@ -221,26 +191,14 @@ func (g *GameManager) ChangeMpTeamAvatarReq(player *model.Player, payloadMsg pb. avatarIdList = append(avatarIdList, avatarId) } world.SetPlayerLocalTeam(player, avatarIdList) - - currAvatarId := player.GetAvatarIdByGuid(currAvatarGuid) - localTeam := world.multiplayerTeam.localTeamMap[player.PlayerID] - avatarIndex := 0 - for index, worldTeamAvatar := range localTeam { - if worldTeamAvatar.avatarId == 0 { - continue - } - if worldTeamAvatar.avatarId == currAvatarId { - avatarIndex = index - } - } - world.SetPlayerLocalAvatarIndex(player, avatarIndex) + world.SetPlayerLocalAvatarIndex(player, 0) world.UpdateMultiplayerTeam() scene := world.GetSceneById(player.SceneId) scene.UpdatePlayerTeamEntity(player) for _, worldPlayer := range world.playerMap { - sceneTeamUpdateNotify := g.PacketSceneTeamUpdateNotifyMp(world) + sceneTeamUpdateNotify := g.PacketSceneTeamUpdateNotify(world) g.SendMsg(cmd.SceneTeamUpdateNotify, worldPlayer.PlayerID, worldPlayer.ClientSeq, sceneTeamUpdateNotify) } @@ -259,113 +217,7 @@ func (g *GameManager) PacketSceneTeamUpdateNotify(world *World) *proto.SceneTeam IsInMp: world.multiplayer, } empty := new(proto.AbilitySyncStateInfo) - for _, worldPlayer := range world.playerMap { - worldPlayerScene := world.GetSceneById(worldPlayer.SceneId) - worldPlayerTeamEntity := worldPlayerScene.GetPlayerTeamEntity(worldPlayer.PlayerID) - team := worldPlayer.TeamConfig.GetActiveTeam() - for _, avatarId := range team.AvatarIdList { - if avatarId == 0 { - break - } - worldPlayerAvatar := worldPlayer.AvatarMap[avatarId] - equipIdList := make([]uint32, 0) - weapon := worldPlayerAvatar.EquipWeapon - equipIdList = append(equipIdList, weapon.ItemId) - for _, reliquary := range worldPlayerAvatar.EquipReliquaryList { - equipIdList = append(equipIdList, reliquary.ItemId) - } - sceneTeamAvatar := &proto.SceneTeamAvatar{ - PlayerUid: worldPlayer.PlayerID, - AvatarGuid: worldPlayerAvatar.Guid, - SceneId: worldPlayer.SceneId, - EntityId: worldPlayerTeamEntity.avatarEntityMap[avatarId], - SceneEntityInfo: g.PacketSceneEntityInfoAvatar(worldPlayerScene, worldPlayer, avatarId), - WeaponGuid: worldPlayerAvatar.EquipWeapon.Guid, - WeaponEntityId: worldPlayerTeamEntity.weaponEntityMap[worldPlayerAvatar.EquipWeapon.WeaponId], - IsPlayerCurAvatar: worldPlayer.TeamConfig.GetActiveAvatarId() == avatarId, - IsOnScene: worldPlayer.TeamConfig.GetActiveAvatarId() == avatarId, - AvatarAbilityInfo: empty, - WeaponAbilityInfo: empty, - AbilityControlBlock: new(proto.AbilityControlBlock), - } - if world.multiplayer { - sceneTeamAvatar.AvatarInfo = g.PacketAvatarInfo(worldPlayerAvatar) - sceneTeamAvatar.SceneAvatarInfo = g.PacketSceneAvatarInfo(worldPlayerScene, worldPlayer, avatarId) - } - // add AbilityControlBlock - avatarDataConfig := gdc.CONF.AvatarDataMap[int32(avatarId)] - acb := sceneTeamAvatar.AbilityControlBlock - embryoId := 0 - // add avatar abilities - if avatarDataConfig != nil { - for _, abilityId := range avatarDataConfig.Abilities { - embryoId++ - emb := &proto.AbilityEmbryo{ - AbilityId: uint32(embryoId), - AbilityNameHash: uint32(abilityId), - AbilityOverrideNameHash: uint32(constant.GameConstantConst.DEFAULT_ABILITY_NAME), - } - acb.AbilityEmbryoList = append(acb.AbilityEmbryoList, emb) - } - } - // add default abilities - for _, abilityId := range constant.GameConstantConst.DEFAULT_ABILITY_HASHES { - embryoId++ - emb := &proto.AbilityEmbryo{ - AbilityId: uint32(embryoId), - AbilityNameHash: uint32(abilityId), - AbilityOverrideNameHash: uint32(constant.GameConstantConst.DEFAULT_ABILITY_NAME), - } - acb.AbilityEmbryoList = append(acb.AbilityEmbryoList, emb) - } - // add team resonances - for id := range worldPlayer.TeamConfig.TeamResonancesConfig { - embryoId++ - emb := &proto.AbilityEmbryo{ - AbilityId: uint32(embryoId), - AbilityNameHash: uint32(id), - AbilityOverrideNameHash: uint32(constant.GameConstantConst.DEFAULT_ABILITY_NAME), - } - acb.AbilityEmbryoList = append(acb.AbilityEmbryoList, emb) - } - // add skill depot abilities - skillDepot := gdc.CONF.AvatarSkillDepotDataMap[int32(worldPlayerAvatar.SkillDepotId)] - if skillDepot != nil && len(skillDepot.Abilities) != 0 { - for _, id := range skillDepot.Abilities { - embryoId++ - emb := &proto.AbilityEmbryo{ - AbilityId: uint32(embryoId), - AbilityNameHash: uint32(id), - AbilityOverrideNameHash: uint32(constant.GameConstantConst.DEFAULT_ABILITY_NAME), - } - acb.AbilityEmbryoList = append(acb.AbilityEmbryoList, emb) - } - } - // add equip abilities - for skill := range worldPlayerAvatar.ExtraAbilityEmbryos { - embryoId++ - emb := &proto.AbilityEmbryo{ - AbilityId: uint32(embryoId), - AbilityNameHash: uint32(endec.Hk4eAbilityHashCode(skill)), - AbilityOverrideNameHash: uint32(constant.GameConstantConst.DEFAULT_ABILITY_NAME), - } - acb.AbilityEmbryoList = append(acb.AbilityEmbryoList, emb) - } - sceneTeamUpdateNotify.SceneTeamAvatarList = append(sceneTeamUpdateNotify.SceneTeamAvatarList, sceneTeamAvatar) - } - } - return sceneTeamUpdateNotify -} - -func (g *GameManager) PacketSceneTeamUpdateNotifyMp(world *World) *proto.SceneTeamUpdateNotify { - sceneTeamUpdateNotify := &proto.SceneTeamUpdateNotify{ - IsInMp: world.multiplayer, - } - empty := new(proto.AbilitySyncStateInfo) - for _, worldTeamAvatar := range world.multiplayerTeam.worldTeam { - if worldTeamAvatar.avatarId == 0 { - continue - } + for _, worldTeamAvatar := range world.GetWorldTeamAvatarList() { worldPlayer := USER_MANAGER.GetOnlineUser(worldTeamAvatar.uid) worldPlayerScene := world.GetSceneById(worldPlayer.SceneId) worldPlayerTeamEntity := worldPlayerScene.GetPlayerTeamEntity(worldPlayer.PlayerID) @@ -420,16 +272,16 @@ func (g *GameManager) PacketSceneTeamUpdateNotifyMp(world *World) *proto.SceneTe } acb.AbilityEmbryoList = append(acb.AbilityEmbryoList, emb) } - // add team resonances - for id := range worldPlayer.TeamConfig.TeamResonancesConfig { - embryoId++ - emb := &proto.AbilityEmbryo{ - AbilityId: uint32(embryoId), - AbilityNameHash: uint32(id), - AbilityOverrideNameHash: uint32(constant.GameConstantConst.DEFAULT_ABILITY_NAME), - } - acb.AbilityEmbryoList = append(acb.AbilityEmbryoList, emb) - } + //// add team resonances + //for id := range worldPlayer.TeamConfig.TeamResonancesConfig { + // embryoId++ + // emb := &proto.AbilityEmbryo{ + // AbilityId: uint32(embryoId), + // AbilityNameHash: uint32(id), + // AbilityOverrideNameHash: uint32(constant.GameConstantConst.DEFAULT_ABILITY_NAME), + // } + // acb.AbilityEmbryoList = append(acb.AbilityEmbryoList, emb) + //} // add skill depot abilities skillDepot := gdc.CONF.AvatarSkillDepotDataMap[int32(worldPlayerAvatar.SkillDepotId)] if skillDepot != nil && len(skillDepot.Abilities) != 0 { diff --git a/gs/game/world_manager.go b/gs/game/world_manager.go index 6b085452..10f8b62e 100644 --- a/gs/game/world_manager.go +++ b/gs/game/world_manager.go @@ -43,7 +43,7 @@ func (w *WorldManager) GetWorldMap() map[uint32]*World { return w.worldMap } -func (w *WorldManager) CreateWorld(owner *model.Player, multiplayer bool) *World { +func (w *WorldManager) CreateWorld(owner *model.Player) *World { worldId := uint32(w.snowflake.GenId()) world := &World{ id: worldId, @@ -52,7 +52,7 @@ func (w *WorldManager) CreateWorld(owner *model.Player, multiplayer bool) *World sceneMap: make(map[uint32]*Scene), entityIdCounter: 0, worldLevel: 0, - multiplayer: multiplayer, + multiplayer: false, mpLevelEntityId: 0, chatMsgList: make([]*proto.ChatInfo, 0), // aoi划分 @@ -88,38 +88,22 @@ func (w *WorldManager) DestroyWorld(worldId uint32) { delete(w.worldMap, worldId) } +// GetBigWorld 获取本服务器的AI世界 func (w *WorldManager) GetBigWorld() *World { return w.bigWorld } -// InitBigWorld 初始化大世界 +// InitBigWorld 初始化AI世界 func (w *WorldManager) InitBigWorld(owner *model.Player) { w.bigWorld = w.GetWorldByID(owner.WorldId) w.bigWorld.ChangeToMultiplayer() } -// WorldTeamAvatar 通用世界队伍角色项 -type WorldTeamAvatar struct { - uid uint32 - avatarId uint32 +func (w *World) IsBigWorld() bool { + return w.owner.PlayerID == 1 } -type MultiplayerTeam struct { - // key:uid value:玩家的本地队伍 - localTeamMap map[uint32][]*WorldTeamAvatar - // key:uid value:玩家当前角色索引 - localAvatarIndexMap map[uint32]int - // 最终的世界队伍 - worldTeam []*WorldTeamAvatar -} - -func CreateMultiplayerTeam() (r *MultiplayerTeam) { - r = new(MultiplayerTeam) - r.localTeamMap = make(map[uint32][]*WorldTeamAvatar) - r.localAvatarIndexMap = make(map[uint32]int) - r.worldTeam = make([]*WorldTeamAvatar, 0) - return r -} +// 世界数据结构 type World struct { id uint32 @@ -144,6 +128,7 @@ func (w *World) GetNextWorldEntityId(entityType uint16) uint32 { return ret } +// GetPlayerPeerId 获取当前玩家世界内编号 func (w *World) GetPlayerPeerId(player *model.Player) uint32 { for peerId, worldPlayer := range w.peerMap { if worldPlayer.PlayerID == player.PlayerID { @@ -153,10 +138,12 @@ func (w *World) GetPlayerPeerId(player *model.Player) uint32 { return 0 } +// GetNextPeerId 获取下一个世界内玩家编号 func (w *World) GetNextPeerId() uint32 { return uint32(len(w.playerMap) + 1) } +// GetWorldPlayerNum 获取世界中玩家的数量 func (w *World) GetWorldPlayerNum() int { return len(w.playerMap) } @@ -166,7 +153,14 @@ func (w *World) AddPlayer(player *model.Player, sceneId uint32) { w.playerMap[player.PlayerID] = player // 将玩家自身当前的队伍角色信息复制到世界的玩家本地队伍 team := player.TeamConfig.GetActiveTeam() - w.SetPlayerLocalTeam(player, team.AvatarIdList) + if player.PlayerID == w.owner.PlayerID { + w.SetPlayerLocalTeam(player, team.AvatarIdList) + w.SetPlayerLocalAvatarIndex(player, int(player.TeamConfig.CurrAvatarIndex)) + } else { + // 非房主最多复制前两个角色 + w.SetPlayerLocalTeam(player, team.AvatarIdList[0:2]) + w.SetPlayerLocalAvatarIndex(player, 0) + } w.UpdateMultiplayerTeam() scene := w.GetSceneById(sceneId) scene.AddPlayer(player) @@ -183,17 +177,44 @@ func (w *World) RemovePlayer(player *model.Player) { w.UpdateMultiplayerTeam() } +// WorldAvatar 通用世界角色 +type WorldAvatar struct { + uid uint32 + avatarId uint32 +} + +type MultiplayerTeam struct { + // key:uid value:玩家的本地队伍 + localTeamMap map[uint32][]*WorldAvatar + // key:uid value:玩家当前角色索引 + localAvatarIndexMap map[uint32]int + // 最终的世界队伍 + worldTeam []*WorldAvatar +} + +func CreateMultiplayerTeam() (r *MultiplayerTeam) { + r = new(MultiplayerTeam) + r.localTeamMap = make(map[uint32][]*WorldAvatar) + r.localAvatarIndexMap = make(map[uint32]int) + r.worldTeam = make([]*WorldAvatar, 0) + return r +} + +func (w *World) GetPlayerLocalTeam(player *model.Player) []*WorldAvatar { + return w.multiplayerTeam.localTeamMap[player.PlayerID] +} + func (w *World) SetPlayerLocalTeam(player *model.Player, avatarIdList []uint32) { - localTeam := make([]*WorldTeamAvatar, 4) + localTeam := make([]*WorldAvatar, 4) for index := 0; index < 4; index++ { if index > len(avatarIdList)-1 { - localTeam[index] = &WorldTeamAvatar{ + localTeam[index] = &WorldAvatar{ uid: 0, avatarId: 0, } } else { avatarId := avatarIdList[index] - localTeam[index] = &WorldTeamAvatar{ + localTeam[index] = &WorldAvatar{ uid: player.PlayerID, avatarId: avatarId, } @@ -202,12 +223,16 @@ func (w *World) SetPlayerLocalTeam(player *model.Player, avatarIdList []uint32) w.multiplayerTeam.localTeamMap[player.PlayerID] = localTeam } +func (w *World) ClearPlayerLocalTeam(player *model.Player) { + w.multiplayerTeam.localTeamMap[player.PlayerID] = make([]*WorldAvatar, 4) +} + func (w *World) GetPlayerLocalAvatarIndex(player *model.Player) int { return w.multiplayerTeam.localAvatarIndexMap[player.PlayerID] } func (w *World) SetPlayerLocalAvatarIndex(player *model.Player, index int) { - if index > len(w.multiplayerTeam.localTeamMap[player.PlayerID])-1 { + if index > len(w.GetPlayerLocalTeam(player))-1 { return } w.multiplayerTeam.localAvatarIndexMap[player.PlayerID] = index @@ -215,16 +240,39 @@ func (w *World) SetPlayerLocalAvatarIndex(player *model.Player, index int) { func (w *World) GetPlayerActiveAvatarId(player *model.Player) uint32 { avatarIndex := w.GetPlayerLocalAvatarIndex(player) - localTeam := w.multiplayerTeam.localTeamMap[player.PlayerID] + localTeam := w.GetPlayerLocalTeam(player) worldTeamAvatar := localTeam[avatarIndex] return worldTeamAvatar.avatarId } +func (w *World) GetPlayerAvatarIdList(player *model.Player) []uint32 { + localTeam := w.GetPlayerLocalTeam(player) + avatarIdList := make([]uint32, 0) + for _, worldAvatar := range localTeam { + if worldAvatar.avatarId == 0 { + continue + } + avatarIdList = append(avatarIdList, worldAvatar.avatarId) + } + return avatarIdList +} + +func (w *World) GetWorldTeamAvatarList() []*WorldAvatar { + worldAvatarList := make([]*WorldAvatar, 0) + for _, worldAvatar := range w.multiplayerTeam.worldTeam { + if worldAvatar.avatarId == 0 { + continue + } + worldAvatarList = append(worldAvatarList, worldAvatar) + } + return worldAvatarList +} + func (w *World) copyLocalTeamToWorld(start int, end int, peerId uint32) { localTeamIndex := 0 for index := start; index <= end; index++ { player := w.peerMap[peerId] - localTeam := w.multiplayerTeam.localTeamMap[player.PlayerID] + localTeam := w.GetPlayerLocalTeam(player) w.multiplayerTeam.worldTeam[index] = localTeam[localTeamIndex] localTeamIndex++ } @@ -232,7 +280,7 @@ func (w *World) copyLocalTeamToWorld(start int, end int, peerId uint32) { // UpdateMultiplayerTeam 整合所有玩家的本地队伍计算出世界队伍 func (w *World) UpdateMultiplayerTeam() { - w.multiplayerTeam.worldTeam = make([]*WorldTeamAvatar, 4) + w.multiplayerTeam.worldTeam = make([]*WorldAvatar, 4) switch w.GetWorldPlayerNum() { case 1: // 1P*4 @@ -257,6 +305,35 @@ func (w *World) UpdateMultiplayerTeam() { } } +// 世界聊天 + +func (w *World) AddChat(chatInfo *proto.ChatInfo) { + w.chatMsgList = append(w.chatMsgList, chatInfo) +} + +func (w *World) GetChatList() []*proto.ChatInfo { + return w.chatMsgList +} + +// ChangeToMultiplayer 转换为多人世界 +func (w *World) ChangeToMultiplayer() { + w.multiplayer = true +} + +// IsPlayerFirstEnter 获取玩家是否首次加入本世界 +func (w *World) IsPlayerFirstEnter(player *model.Player) bool { + _, exist := w.playerFirstEnterMap[player.PlayerID] + if !exist { + return true + } else { + return false + } +} + +func (w *World) PlayerEnter(player *model.Player) { + w.playerFirstEnterMap[player.PlayerID] = time.Now().UnixMilli() +} + func (w *World) CreateScene(sceneId uint32) *Scene { scene := &Scene{ id: sceneId, @@ -281,34 +358,7 @@ func (w *World) GetSceneById(sceneId uint32) *Scene { return scene } -func (w *World) AddChat(chatInfo *proto.ChatInfo) { - w.chatMsgList = append(w.chatMsgList, chatInfo) -} - -func (w *World) GetChatList() []*proto.ChatInfo { - return w.chatMsgList -} - -func (w *World) IsBigWorld() bool { - return w.owner.PlayerID == 1 -} - -func (w *World) ChangeToMultiplayer() { - w.multiplayer = true -} - -func (w *World) IsPlayerFirstEnter(player *model.Player) bool { - _, exist := w.playerFirstEnterMap[player.PlayerID] - if !exist { - return true - } else { - return false - } -} - -func (w *World) PlayerEnter(player *model.Player) { - w.playerFirstEnterMap[player.PlayerID] = time.Now().UnixMilli() -} +// 场景数据结构 type Scene struct { id uint32 @@ -334,6 +384,8 @@ type GadgetEntity struct { gatherId uint32 } +// 场景实体数据结构 + type Entity struct { id uint32 scene *Scene @@ -388,34 +440,9 @@ func (s *Scene) CreatePlayerTeamEntity(player *model.Player) { } func (s *Scene) UpdatePlayerTeamEntity(player *model.Player) { - if s.world.multiplayer { - s.UpdatePlayerTeamEntityMp(player) - return - } - team := player.TeamConfig.GetActiveTeam() playerTeamEntity := s.playerTeamEntityMap[player.PlayerID] - for _, avatarId := range team.AvatarIdList { - if avatarId == 0 { - break - } - avatar := player.AvatarMap[avatarId] - avatarEntityId, exist := playerTeamEntity.avatarEntityMap[avatarId] - if exist { - s.DestroyEntity(avatarEntityId) - } - playerTeamEntity.avatarEntityMap[avatarId] = s.CreateEntityAvatar(player, avatarId) - weaponEntityId, exist := playerTeamEntity.weaponEntityMap[avatar.EquipWeapon.WeaponId] - if exist { - s.DestroyEntity(weaponEntityId) - } - playerTeamEntity.weaponEntityMap[avatar.EquipWeapon.WeaponId] = s.CreateEntityWeapon() - } -} - -func (s *Scene) UpdatePlayerTeamEntityMp(player *model.Player) { - playerTeamEntity := s.playerTeamEntityMap[player.PlayerID] - for _, worldTeamAvatar := range s.world.multiplayerTeam.worldTeam { - if worldTeamAvatar.uid != player.PlayerID || worldTeamAvatar.avatarId == 0 { + for _, worldTeamAvatar := range s.world.GetWorldTeamAvatarList() { + if worldTeamAvatar.uid != player.PlayerID { continue } avatar := player.AvatarMap[worldTeamAvatar.avatarId] @@ -469,7 +496,7 @@ func (s *Scene) CreateEntityAvatar(player *model.Player, avatarId uint32) uint32 }, } s.entityMap[entity.id] = entity - if avatarId == player.TeamConfig.GetActiveAvatarId() { + if avatarId == s.world.GetPlayerActiveAvatarId(player) { s.world.aoiManager.AddEntityIdToGridByPos(entity.id, float32(entity.pos.X), float32(entity.pos.Y), float32(entity.pos.Z)) } return entity.id diff --git a/gs/model/invoke_handler.go b/gs/model/invoke_handler.go index 1edf94ed..1585f3fc 100644 --- a/gs/model/invoke_handler.go +++ b/gs/model/invoke_handler.go @@ -43,9 +43,9 @@ func (i *InvokeHandler[T]) AddEntry(forward proto.ForwardType, entry *T) { i.EntryListForwardHost = append(i.EntryListForwardHost, entry) case proto.ForwardType_FORWARD_TYPE_ONLY_SERVER: i.EntryListForwardServer = append(i.EntryListForwardServer, entry) - logger.LOG.Error("fwd server entry: %v", entry) + //logger.LOG.Error("forward server entry: %v", entry) default: - logger.LOG.Error("forward: %v, entry: %v", forward, entry) + logger.LOG.Error("forward type: %v, entry: %v", forward, entry) } } diff --git a/gs/model/player.go b/gs/model/player.go index 7b13b877..4bd745c6 100644 --- a/gs/model/player.go +++ b/gs/model/player.go @@ -6,11 +6,9 @@ import ( ) const ( - DbInsert = iota + DbNormal = iota + DbInsert DbDelete - DbUpdate - DbNormal - DbOffline ) const ( diff --git a/gs/model/team.go b/gs/model/team.go index 997cdde3..2e5cd550 100644 --- a/gs/model/team.go +++ b/gs/model/team.go @@ -10,6 +10,17 @@ type Team struct { AvatarIdList []uint32 `bson:"avatarIdList"` } +func (t *Team) GetAvatarIdList() []uint32 { + avatarIdList := make([]uint32, 0) + for _, avatarId := range t.AvatarIdList { + if avatarId == 0 { + continue + } + avatarIdList = append(avatarIdList, avatarId) + } + return avatarIdList +} + type TeamInfo struct { TeamList []*Team `bson:"teamList"` CurrTeamIndex uint8 `bson:"currTeamIndex"` @@ -39,10 +50,7 @@ func (t *TeamInfo) UpdateTeam() { t.TeamResonancesConfig = make(map[int32]bool) teamElementTypeCountMap := make(map[uint16]uint8) avatarSkillDepotDataMapConfig := gdc.CONF.AvatarSkillDepotDataMap - for _, avatarId := range activeTeam.AvatarIdList { - if avatarId == 0 { - break - } + for _, avatarId := range activeTeam.GetAvatarIdList() { skillData := avatarSkillDepotDataMapConfig[int32(avatarId)] if skillData != nil { teamElementTypeCountMap[skillData.ElementType.Value] += 1 @@ -90,26 +98,10 @@ func (t *TeamInfo) ClearTeamAvatar(teamIndex uint8) { team.AvatarIdList = make([]uint32, 4) } -func (t *TeamInfo) AddAvatarToTeam(avatarId uint32, teamIndex uint8) { +func (t *TeamInfo) SetTeamAvatar(teamIndex uint8, avatarIdList []uint32) { team := t.GetTeamByIndex(teamIndex) if team == nil { return } - for i, v := range team.AvatarIdList { - if v == 0 { - team.AvatarIdList[i] = avatarId - break - } - } -} - -func (t *TeamInfo) GetActiveAvatarId() uint32 { - activeTeam := t.GetActiveTeam() - if activeTeam == nil { - return 0 - } - if t.CurrAvatarIndex >= uint8(len(activeTeam.AvatarIdList)) { - return 0 - } - return activeTeam.AvatarIdList[t.CurrAvatarIndex] + team.AvatarIdList = avatarIdList } diff --git a/pkg/reflection/struct.go b/pkg/reflection/struct.go index bf6eee54..13c0c770 100644 --- a/pkg/reflection/struct.go +++ b/pkg/reflection/struct.go @@ -25,3 +25,25 @@ func ConvStructToMap(value any) map[string]any { } return result } + +func SetStructFieldValue(structPointer any, fieldName string, value any) bool { + refType := reflect.TypeOf(structPointer) + if refType.Kind() != reflect.Ptr { + return false + } + refType = refType.Elem() + if refType.Kind() != reflect.Struct { + return false + } + refValue := reflect.ValueOf(structPointer) + if refValue.Kind() != reflect.Ptr { + return false + } + refValue = refValue.Elem() + field := refValue.FieldByName(fieldName) + if field.Type() != reflect.TypeOf(value) { + return false + } + field.Set(reflect.ValueOf(value)) + return true +}