diff --git a/gs/game/command_gm.go b/gs/game/command_gm.go index a21ad3d3..c0285728 100644 --- a/gs/game/command_gm.go +++ b/gs/game/command_gm.go @@ -143,6 +143,45 @@ func (g *GMCmd) GMAddUserAllEvery(userId, itemCount uint32) { g.GMAddUserAllFlycloak(userId) } +// GMAddQuest 添加任务 +func (g *GMCmd) GMAddQuest(userId uint32, questId uint32) { + player := USER_MANAGER.GetOnlineUser(userId) + if player == nil { + logger.Error("player is nil, uid: %v", userId) + return + } + dbQuest := player.GetDbQuest() + dbQuest.AddQuest(questId) + ntf := &proto.QuestListUpdateNotify{ + QuestList: make([]*proto.Quest, 0), + } + ntf.QuestList = append(ntf.QuestList, GAME_MANAGER.PacketQuest(player, questId)) + GAME_MANAGER.SendMsg(cmd.QuestListUpdateNotify, player.PlayerID, player.ClientSeq, ntf) +} + +// GMForceFinishAllQuest 强制完成当前所有任务 +func (g *GMCmd) GMForceFinishAllQuest(userId uint32) { + player := USER_MANAGER.GetOnlineUser(userId) + if player == nil { + logger.Error("player is nil, uid: %v", userId) + return + } + dbQuest := player.GetDbQuest() + ntf := &proto.QuestListUpdateNotify{ + QuestList: make([]*proto.Quest, 0), + } + for _, quest := range dbQuest.GetQuestMap() { + dbQuest.ForceFinishQuest(quest.QuestId) + pbQuest := GAME_MANAGER.PacketQuest(player, quest.QuestId) + if pbQuest == nil { + continue + } + ntf.QuestList = append(ntf.QuestList, pbQuest) + } + GAME_MANAGER.SendMsg(cmd.QuestListUpdateNotify, player.PlayerID, player.ClientSeq, ntf) + GAME_MANAGER.AcceptQuest(player, true) +} + // 系统级GM指令 func (g *GMCmd) ChangePlayerCmdPerm(userId uint32, cmdPerm uint8) { diff --git a/gs/game/player_fight_sync.go b/gs/game/player_fight_sync.go index 25e32a3f..ed3162de 100644 --- a/gs/game/player_fight_sync.go +++ b/gs/game/player_fight_sync.go @@ -112,7 +112,7 @@ func (g *GameManager) CombatInvocationsNotify(player *model.Player, payloadMsg p logger.Error("attackResult is nil") continue } - logger.Debug("run attack handler, attackResult: %v", attackResult) + // logger.Debug("run attack handler, attackResult: %v", attackResult) target := scene.GetEntity(attackResult.DefenseId) if target == nil { logger.Error("could not found target, defense id: %v", attackResult.DefenseId) @@ -221,7 +221,7 @@ func (g *GameManager) CombatInvocationsNotify(player *model.Player, payloadMsg p logger.Error("parse EvtAnimatorParameterInfo error: %v", err) continue } - logger.Debug("EvtAnimatorParameterInfo: %v, ForwardType: %v", evtAnimatorParameterInfo, entry.ForwardType) + // logger.Debug("EvtAnimatorParameterInfo: %v, ForwardType: %v", evtAnimatorParameterInfo, entry.ForwardType) // 这是否? evtAnimatorParameterInfo.IsServerCache = false newCombatData, err := pb.Marshal(evtAnimatorParameterInfo) @@ -242,7 +242,7 @@ func (g *GameManager) CombatInvocationsNotify(player *model.Player, payloadMsg p logger.Error("parse EvtAnimatorStateChangedInfo error: %v", err) continue } - logger.Debug("EvtAnimatorStateChangedInfo: %v, ForwardType: %v", evtAnimatorStateChangedInfo, entry.ForwardType) + // logger.Debug("EvtAnimatorStateChangedInfo: %v, ForwardType: %v", evtAnimatorStateChangedInfo, entry.ForwardType) // 试试看? evtAnimatorStateChangedInfo.HandleAnimatorStateImmediately = true evtAnimatorStateChangedInfo.ForceSync = true @@ -329,7 +329,7 @@ func (g *GameManager) AoiPlayerMove(player *model.Player, oldPos *model.Vector, } if !world.GetMultiplayer() { // 处理多人世界不同玩家不同位置的group卸载情况 - g.RemoveGroup(scene, groupConfig) + g.RemoveGroup(player, scene, groupConfig) } } // 出现的场景实体 @@ -340,7 +340,7 @@ func (g *GameManager) AoiPlayerMove(player *model.Player, oldPos *model.Vector, continue } // 新有旧没有的group即为出现的 - g.AddSceneGroup(scene, groupConfig) + g.AddSceneGroup(player, scene, groupConfig) group := scene.GetGroupById(groupId) if group == nil { continue @@ -350,8 +350,12 @@ func (g *GameManager) AoiPlayerMove(player *model.Player, oldPos *model.Vector, } } // 同步客户端消失和出现的场景实体 - g.RemoveSceneEntityNotifyToPlayer(player, proto.VisionType_VISION_MISS, delEntityIdList) - g.AddSceneEntityNotify(player, proto.VisionType_VISION_MEET, addEntityIdList, false, false) + if len(delEntityIdList) > 0 { + g.RemoveSceneEntityNotifyToPlayer(player, proto.VisionType_VISION_MISS, delEntityIdList) + } + if len(addEntityIdList) > 0 { + g.AddSceneEntityNotify(player, proto.VisionType_VISION_MEET, addEntityIdList, false, false) + } } // TriggerCheck 场景区域触发器检测 @@ -682,3 +686,23 @@ func (g *GameManager) EvtDestroyGadgetNotify(player *model.Player, payloadMsg pb scene.DestroyEntity(req.EntityId) g.RemoveSceneEntityNotifyBroadcast(scene, proto.VisionType_VISION_MISS, []uint32{req.EntityId}) } + +func (g *GameManager) EvtAiSyncSkillCdNotify(player *model.Player, payloadMsg pb.Message) { + req := payloadMsg.(*proto.EvtAiSyncSkillCdNotify) + _ = req +} + +func (g *GameManager) EvtAiSyncCombatThreatInfoNotify(player *model.Player, payloadMsg pb.Message) { + req := payloadMsg.(*proto.EvtAiSyncCombatThreatInfoNotify) + _ = req +} + +func (g *GameManager) EntityConfigHashNotify(player *model.Player, payloadMsg pb.Message) { + req := payloadMsg.(*proto.EntityConfigHashNotify) + _ = req +} + +func (g *GameManager) MonsterAIConfigHashNotify(player *model.Player, payloadMsg pb.Message) { + req := payloadMsg.(*proto.MonsterAIConfigHashNotify) + _ = req +} diff --git a/gs/game/player_scene.go b/gs/game/player_scene.go index c0718104..4d739e5a 100644 --- a/gs/game/player_scene.go +++ b/gs/game/player_scene.go @@ -18,7 +18,7 @@ import ( const ( ENTITY_MAX_BATCH_SEND_NUM = 1000 // 单次同步的最大实体数量 - ENTITY_LOD = 300 // 实体加载视野距离 + ENTITY_LOD = 100 // 实体加载视野距离 ) func (g *GameManager) EnterSceneReadyReq(player *model.Player, payloadMsg pb.Message) { @@ -27,37 +27,43 @@ func (g *GameManager) EnterSceneReadyReq(player *model.Player, payloadMsg pb.Mes world := WORLD_MANAGER.GetWorldByID(player.WorldId) enterSceneContext := world.GetEnterSceneContextByToken(req.EnterSceneToken) - aoiManager, exist := WORLD_MANAGER.GetSceneBlockAoiMap()[enterSceneContext.OldSceneId] - if !exist { - logger.Error("player scene not exist in aoi, sceneId: %v, uid: %v", enterSceneContext.OldSceneId, player.PlayerID) + if enterSceneContext == nil { + logger.Error("get enter scene context is nil, uid: %v", player.PlayerID) return } - objectList := aoiManager.GetObjectListByPos(float32(enterSceneContext.OldPos.X), 0.0, float32(enterSceneContext.OldPos.Z)) - delEntityIdList := make([]uint32, 0) - oldScene := world.GetSceneById(enterSceneContext.OldSceneId) - for _, groupAny := range objectList { - groupConfig := groupAny.(*gdconf.Group) - distance2D := math.Sqrt((player.Pos.X-float64(groupConfig.Pos.X))*(player.Pos.X-float64(groupConfig.Pos.X)) + - (player.Pos.Z-float64(groupConfig.Pos.Z))*(player.Pos.Z-float64(groupConfig.Pos.Z))) - if distance2D > ENTITY_LOD { - continue + if enterSceneContext.OldSceneId != 0 { + aoiManager, exist := WORLD_MANAGER.GetSceneBlockAoiMap()[enterSceneContext.OldSceneId] + if !exist { + logger.Error("player scene not exist in aoi, sceneId: %v, uid: %v", enterSceneContext.OldSceneId, player.PlayerID) + return } - if groupConfig.DynamicLoad { - continue - } - group := oldScene.GetGroupById(uint32(groupConfig.Id)) - if group == nil { - continue - } - for _, entity := range group.GetAllEntity() { - delEntityIdList = append(delEntityIdList, entity.GetId()) - } - if !world.GetMultiplayer() { - // 处理多人世界不同玩家不同位置的group卸载情况 - g.RemoveGroup(oldScene, groupConfig) + objectList := aoiManager.GetObjectListByPos(float32(enterSceneContext.OldPos.X), 0.0, float32(enterSceneContext.OldPos.Z)) + delEntityIdList := make([]uint32, 0) + oldScene := world.GetSceneById(enterSceneContext.OldSceneId) + for _, groupAny := range objectList { + groupConfig := groupAny.(*gdconf.Group) + distance2D := math.Sqrt((player.Pos.X-float64(groupConfig.Pos.X))*(player.Pos.X-float64(groupConfig.Pos.X)) + + (player.Pos.Z-float64(groupConfig.Pos.Z))*(player.Pos.Z-float64(groupConfig.Pos.Z))) + if distance2D > ENTITY_LOD { + continue + } + if groupConfig.DynamicLoad { + continue + } + group := oldScene.GetGroupById(uint32(groupConfig.Id)) + if group == nil { + continue + } + for _, entity := range group.GetAllEntity() { + delEntityIdList = append(delEntityIdList, entity.GetId()) + } + if !world.GetMultiplayer() { + // 处理多人世界不同玩家不同位置的group卸载情况 + g.RemoveGroup(player, oldScene, groupConfig) + } } + g.RemoveSceneEntityNotifyToPlayer(player, proto.VisionType_VISION_MISS, delEntityIdList) } - g.RemoveSceneEntityNotifyToPlayer(player, proto.VisionType_VISION_MISS, delEntityIdList) enterScenePeerNotify := &proto.EnterScenePeerNotify{ DestSceneId: player.SceneId, @@ -322,7 +328,7 @@ func (g *GameManager) EnterSceneDoneReq(player *model.Player, payloadMsg pb.Mess if groupConfig.DynamicLoad { continue } - g.AddSceneGroup(scene, groupConfig) + g.AddSceneGroup(player, scene, groupConfig) } if player.SceneJump { visionType = proto.VisionType_VISION_MEET @@ -423,7 +429,7 @@ func (g *GameManager) NpcTalkReq(player *model.Player, payloadMsg pb.Message) { NpcEntityId: req.NpcEntityId, EntityId: req.EntityId, } - g.SendMsg(cmd.EnterSceneReadyRsp, player.PlayerID, player.ClientSeq, rsp) + g.SendMsg(cmd.NpcTalkRsp, player.PlayerID, player.ClientSeq, rsp) } var SceneTransactionSeq uint32 = 0 @@ -435,13 +441,16 @@ func (g *GameManager) PacketPlayerEnterSceneNotifyLogin(player *model.Player, en logger.Error("scene is nil, sceneId: %v", player.SceneId) return new(proto.PlayerEnterSceneNotify) } + enterSceneToken := world.AddEnterSceneContext(&EnterSceneContext{ + OldSceneId: 0, + }) playerEnterSceneNotify := &proto.PlayerEnterSceneNotify{ SceneId: player.SceneId, Pos: &proto.Vector{X: float32(player.Pos.X), Y: float32(player.Pos.Y), Z: float32(player.Pos.Z)}, SceneBeginTime: uint64(scene.GetSceneCreateTime()), Type: enterType, TargetUid: player.PlayerID, - EnterSceneToken: world.enterSceneToken, + EnterSceneToken: enterSceneToken, WorldLevel: player.PropertiesMap[constant.PLAYER_PROP_PLAYER_WORLD_LEVEL], EnterReason: uint32(proto.EnterReason_ENTER_REASON_LOGIN), IsFirstLoginEnterScene: true, @@ -523,24 +532,34 @@ func (g *GameManager) PacketPlayerEnterSceneNotifyMp( return playerEnterSceneNotify } -func (g *GameManager) AddSceneGroup(scene *Scene, groupConfig *gdconf.Group) { +func (g *GameManager) AddSceneGroup(player *model.Player, scene *Scene, groupConfig *gdconf.Group) { initSuiteId := int(groupConfig.GroupInitConfig.Suite) if initSuiteId < 1 || initSuiteId > len(groupConfig.SuiteList) { - logger.Error("invalid init suite id: %v", initSuiteId) + logger.Error("invalid init suite id: %v, uid: %v", initSuiteId, player.PlayerID) return } scene.AddGroupSuite(uint32(groupConfig.Id), uint8(initSuiteId)) + ntf := &proto.GroupSuiteNotify{ + GroupMap: make(map[uint32]uint32), + } + ntf.GroupMap[uint32(groupConfig.Id)] = uint32(initSuiteId) + g.SendMsg(cmd.GroupSuiteNotify, player.PlayerID, player.ClientSeq, ntf) } -func (g *GameManager) RemoveGroup(scene *Scene, groupConfig *gdconf.Group) { +func (g *GameManager) RemoveGroup(player *model.Player, scene *Scene, groupConfig *gdconf.Group) { group := scene.GetGroupById(uint32(groupConfig.Id)) if group == nil { - logger.Error("group not exist, groupId: %v", groupConfig.Id) + logger.Error("group not exist, groupId: %v, uid: %v", groupConfig.Id, player.PlayerID) return } for suiteId := range group.GetAllSuite() { scene.RemoveGroupSuite(uint32(groupConfig.Id), suiteId) } + ntf := &proto.GroupUnloadNotify{ + GroupList: make([]uint32, 0), + } + ntf.GroupList = append(ntf.GroupList, uint32(groupConfig.Id)) + g.SendMsg(cmd.GroupUnloadNotify, player.PlayerID, player.ClientSeq, ntf) } func (g *GameManager) AddSceneEntityNotifyToPlayer(player *model.Player, visionType proto.VisionType, entityList []*proto.SceneEntityInfo) { diff --git a/gs/game/route_manager.go b/gs/game/route_manager.go index 962b9a3f..d6b52f68 100644 --- a/gs/game/route_manager.go +++ b/gs/game/route_manager.go @@ -141,6 +141,10 @@ func (r *RouteManager) initRoute() { r.registerRouter(cmd.TakeoffEquipReq, GAME_MANAGER.TakeoffEquipReq) r.registerRouter(cmd.AddQuestContentProgressReq, GAME_MANAGER.AddQuestContentProgressReq) r.registerRouter(cmd.NpcTalkReq, GAME_MANAGER.NpcTalkReq) + r.registerRouter(cmd.EvtAiSyncSkillCdNotify, GAME_MANAGER.EvtAiSyncSkillCdNotify) + r.registerRouter(cmd.EvtAiSyncCombatThreatInfoNotify, GAME_MANAGER.EvtAiSyncCombatThreatInfoNotify) + r.registerRouter(cmd.EntityConfigHashNotify, GAME_MANAGER.EntityConfigHashNotify) + r.registerRouter(cmd.MonsterAIConfigHashNotify, GAME_MANAGER.MonsterAIConfigHashNotify) } func (r *RouteManager) RouteHandle(netMsg *mq.NetMsg) { diff --git a/protocol/cmd/cmd_id_proto_obj_map.go b/protocol/cmd/cmd_id_proto_obj_map.go index eef53177..ae071526 100644 --- a/protocol/cmd/cmd_id_proto_obj_map.go +++ b/protocol/cmd/cmd_id_proto_obj_map.go @@ -118,6 +118,8 @@ func (c *CmdProtoMap) registerAllMessage() { c.regMsg(BeginCameraSceneLookNotify, func() any { return new(proto.BeginCameraSceneLookNotify) }) // 场景镜头注目通知 c.regMsg(NpcTalkReq, func() any { return new(proto.NpcTalkReq) }) // NPC对话请求 c.regMsg(NpcTalkRsp, func() any { return new(proto.NpcTalkRsp) }) // NPC对话响应 + c.regMsg(GroupSuiteNotify, func() any { return new(proto.GroupSuiteNotify) }) // 场景小组加载通知 + c.regMsg(GroupUnloadNotify, func() any { return new(proto.GroupUnloadNotify) }) // 场景组卸载通知 // 战斗与同步 c.regMsg(AvatarFightPropNotify, func() any { return new(proto.AvatarFightPropNotify) }) // 角色战斗属性通知 @@ -136,6 +138,10 @@ func (c *CmdProtoMap) registerAllMessage() { c.regMsg(EvtDestroyGadgetNotify, func() any { return new(proto.EvtDestroyGadgetNotify) }) // 销毁实体通知 c.regMsg(EvtAnimatorParameterNotify, func() any { return new(proto.EvtAnimatorParameterNotify) }) // 动画参数通知 c.regMsg(EvtAnimatorStateChangedNotify, func() any { return new(proto.EvtAnimatorStateChangedNotify) }) // 动画状态通知 + c.regMsg(EvtAiSyncSkillCdNotify, func() any { return new(proto.EvtAiSyncSkillCdNotify) }) + c.regMsg(EvtAiSyncCombatThreatInfoNotify, func() any { return new(proto.EvtAiSyncCombatThreatInfoNotify) }) + c.regMsg(EntityConfigHashNotify, func() any { return new(proto.EntityConfigHashNotify) }) + c.regMsg(MonsterAIConfigHashNotify, func() any { return new(proto.MonsterAIConfigHashNotify) }) // 队伍 c.regMsg(ChangeAvatarReq, func() any { return new(proto.ChangeAvatarReq) }) // 更换角色请求 切人 @@ -303,8 +309,7 @@ func (c *CmdProtoMap) registerAllMessage() { c.regMsg(GCGOperationReq, func() any { return new(proto.GCGOperationReq) }) // GCG游戏客户端操作请求 c.regMsg(GCGOperationRsp, func() any { return new(proto.GCGOperationRsp) }) // GCG游戏客户端操作响应 c.regMsg(GCGSkillPreviewNotify, func() any { return new(proto.GCGSkillPreviewNotify) }) // GCG游戏技能预览通知 - - // // TODO 客户端开始GCG游戏 + // TODO 客户端开始GCG游戏 c.regMsg(GCGStartChallengeByCheckRewardReq, func() any { return new(proto.GCGStartChallengeByCheckRewardReq) }) // GCG开始挑战来自检测奖励请求 c.regMsg(GCGStartChallengeByCheckRewardRsp, func() any { return new(proto.GCGStartChallengeByCheckRewardRsp) }) // GCG开始挑战来自检测奖励响应 c.regMsg(GCGStartChallengeReq, func() any { return new(proto.GCGStartChallengeReq) }) // GCG开始挑战请求 @@ -327,13 +332,6 @@ func (c *CmdProtoMap) registerAllMessage() { c.regMsg(TowerAllDataRsp, func() any { return new(proto.TowerAllDataRsp) }) // 深渊数据响应 c.regMsg(ServerAnnounceNotify, func() any { return new(proto.ServerAnnounceNotify) }) // 服务器公告通知 c.regMsg(ServerAnnounceRevokeNotify, func() any { return new(proto.ServerAnnounceRevokeNotify) }) // 服务器公告撤销通知 - - // TODO - c.regMsg(EvtAiSyncSkillCdNotify, func() any { return new(proto.EvtAiSyncSkillCdNotify) }) - c.regMsg(EvtAiSyncCombatThreatInfoNotify, func() any { return new(proto.EvtAiSyncCombatThreatInfoNotify) }) - c.regMsg(EntityConfigHashNotify, func() any { return new(proto.EntityConfigHashNotify) }) - c.regMsg(MonsterAIConfigHashNotify, func() any { return new(proto.MonsterAIConfigHashNotify) }) - c.regMsg(GetRegionSearchReq, func() any { return new(proto.GetRegionSearchReq) }) } func (c *CmdProtoMap) regMsg(cmdId uint16, protoObjNewFunc func() any) {