diff --git a/gdconf/dungeon_data.go b/gdconf/dungeon_data.go new file mode 100644 index 00000000..b2b617e5 --- /dev/null +++ b/gdconf/dungeon_data.go @@ -0,0 +1,29 @@ +package gdconf + +import ( + "hk4e/pkg/logger" +) + +// DungeonData 地牢配置表 +type DungeonData struct { + DungeonId int32 `csv:"ID"` + SceneId int32 `csv:"场景ID,omitempty"` +} + +func (g *GameDataConfig) loadDungeonData() { + g.DungeonDataMap = make(map[int32]*DungeonData) + dungeonDataList := make([]*DungeonData, 0) + readTable[DungeonData](g.txtPrefix+"DungeonData.txt", &dungeonDataList) + for _, dungeonData := range dungeonDataList { + g.DungeonDataMap[dungeonData.DungeonId] = dungeonData + } + logger.Info("DungeonData count: %v", len(g.DungeonDataMap)) +} + +func GetDungeonDataById(dungeonId int32) *DungeonData { + return CONF.DungeonDataMap[dungeonId] +} + +func GetDungeonDataMap() map[int32]*DungeonData { + return CONF.DungeonDataMap +} diff --git a/gdconf/game_data_config.go b/gdconf/game_data_config.go index e48c136d..d7f879b8 100644 --- a/gdconf/game_data_config.go +++ b/gdconf/game_data_config.go @@ -62,6 +62,7 @@ type GameDataConfig struct { DropDataMap map[int32]*DropData // 掉落 MonsterDropDataMap map[string]map[int32]*MonsterDropData // 怪物掉落 ChestDropDataMap map[string]map[int32]*ChestDropData // 宝箱掉落 + DungeonDataMap map[int32]*DungeonData // 地牢 GCGCharDataMap map[int32]*GCGCharData // 七圣召唤角色卡牌 GCGSkillDataMap map[int32]*GCGSkillData // 七圣召唤卡牌技能 GachaDropGroupDataMap map[int32]*GachaDropGroupData // 卡池掉落组 临时的 @@ -160,6 +161,7 @@ func (g *GameDataConfig) load() { g.loadDropData() // 掉落 g.loadMonsterDropData() // 怪物掉落 g.loadChestDropData() // 宝箱掉落 + g.loadDungeonData() // 地牢 g.loadGCGCharData() // 七圣召唤角色卡牌 g.loadGCGSkillData() // 七圣召唤卡牌技能 g.loadGachaDropGroupData() // 卡池掉落组 临时的 diff --git a/gs/game/command_controller.go b/gs/game/command_controller.go index b3dc0d40..b5954090 100644 --- a/gs/game/command_controller.go +++ b/gs/game/command_controller.go @@ -160,13 +160,13 @@ func (c *CommandManager) TeleportCommand(cmd *CommandMessage) { c.SendMessage(cmd.Executor, "已将玩家 UID:%v 请求加入目标玩家 UID:%v 的世界。", player.PlayerID, targetUid) } else { // 传送玩家至目标玩家的位置 - c.gmCmd.GMTeleportPlayer(player.PlayerID, target.SceneId, target.Pos.X, target.Pos.Y, target.Pos.Z) + c.gmCmd.GMTeleportPlayer(player.PlayerID, target.SceneId, 0, target.Pos.X, target.Pos.Y, target.Pos.Z) // 发送消息给执行者 c.SendMessage(cmd.Executor, "已将玩家 UID:%v 传送至 目标玩家 UID:%v。", player.PlayerID, targetUid) } } else { // 传送玩家至指定的位置 - c.gmCmd.GMTeleportPlayer(player.PlayerID, sceneId, pos.X, pos.Y, pos.Z) + c.gmCmd.GMTeleportPlayer(player.PlayerID, sceneId, 0, pos.X, pos.Y, pos.Z) // 发送消息给执行者 c.SendMessage(cmd.Executor, "已将玩家 UID:%v 传送至 场景:%v, X:%.2f, Y:%.2f, Z:%.2f。", player.PlayerID, sceneId, pos.X, pos.Y, pos.Z) } diff --git a/gs/game/command_gm.go b/gs/game/command_gm.go index c0285728..3d116919 100644 --- a/gs/game/command_gm.go +++ b/gs/game/command_gm.go @@ -19,7 +19,7 @@ type GMCmd struct { // 玩家通用GM指令 // GMTeleportPlayer 传送玩家 -func (g *GMCmd) GMTeleportPlayer(userId, sceneId uint32, posX, posY, posZ float64) { +func (g *GMCmd) GMTeleportPlayer(userId, sceneId, dungeonId uint32, posX, posY, posZ float64) { player := USER_MANAGER.GetOnlineUser(userId) if player == nil { logger.Error("player is nil, uid: %v", userId) @@ -29,7 +29,7 @@ func (g *GMCmd) GMTeleportPlayer(userId, sceneId uint32, posX, posY, posZ float6 X: posX, Y: posY, Z: posZ, - }, new(model.Vector), 0) + }, new(model.Vector), dungeonId) } // GMAddUserItem 给予玩家物品 diff --git a/gs/game/player_login.go b/gs/game/player_login.go index 0ae6ac3b..9843d61c 100644 --- a/gs/game/player_login.go +++ b/gs/game/player_login.go @@ -187,7 +187,7 @@ func (g *GameManager) CreatePlayer(userId uint32, nickName string, mainCharAvata sceneLuaConfig := gdconf.GetSceneLuaConfigById(int32(player.SceneId)) if sceneLuaConfig == nil { - logger.Error("get scene lua config is nil, sceneId: %v", player.SceneId) + logger.Error("get scene lua config is nil, sceneId: %v, uid: %v", player.SceneId, player.PlayerID) return nil } player.SafePos = &model.Vector{ diff --git a/gs/game/player_scene.go b/gs/game/player_scene.go index 4d739e5a..e0c8402c 100644 --- a/gs/game/player_scene.go +++ b/gs/game/player_scene.go @@ -16,6 +16,8 @@ import ( pb "google.golang.org/protobuf/proto" ) +// 场景模块 场景组 小组 实体 管理相关 + const ( ENTITY_MAX_BATCH_SEND_NUM = 1000 // 单次同步的最大实体数量 ENTITY_LOD = 100 // 实体加载视野距离 @@ -381,31 +383,6 @@ func (g *GameManager) PostEnterSceneReq(player *model.Player, payloadMsg pb.Mess g.SendMsg(cmd.PostEnterSceneRsp, player.PlayerID, player.ClientSeq, postEnterSceneRsp) } -func (g *GameManager) ChangeGameTimeReq(player *model.Player, payloadMsg pb.Message) { - req := payloadMsg.(*proto.ChangeGameTimeReq) - gameTime := req.GameTime - world := WORLD_MANAGER.GetWorldByID(player.WorldId) - scene := world.GetSceneById(player.SceneId) - if scene == nil { - logger.Error("scene is nil, sceneId: %v", player.SceneId) - return - } - scene.ChangeGameTime(gameTime) - - for _, scenePlayer := range scene.GetAllPlayer() { - playerGameTimeNotify := &proto.PlayerGameTimeNotify{ - GameTime: scene.GetGameTime(), - Uid: scenePlayer.PlayerID, - } - g.SendMsg(cmd.PlayerGameTimeNotify, scenePlayer.PlayerID, scenePlayer.ClientSeq, playerGameTimeNotify) - } - - changeGameTimeRsp := &proto.ChangeGameTimeRsp{ - CurGameTime: scene.GetGameTime(), - } - g.SendMsg(cmd.ChangeGameTimeRsp, player.PlayerID, player.ClientSeq, changeGameTimeRsp) -} - func (g *GameManager) SceneEntityDrownReq(player *model.Player, payloadMsg pb.Message) { req := payloadMsg.(*proto.SceneEntityDrownReq) @@ -414,7 +391,8 @@ func (g *GameManager) SceneEntityDrownReq(player *model.Player, payloadMsg pb.Me return } scene := world.GetSceneById(player.SceneId) - scene.DestroyEntity(req.EntityId) + entity := scene.GetEntity(req.EntityId) + scene.SetEntityLifeState(entity, constant.LIFE_STATE_DEAD, proto.PlayerDieType_PLAYER_DIE_DRAWN) sceneEntityDrownRsp := &proto.SceneEntityDrownRsp{ EntityId: req.EntityId, @@ -422,16 +400,6 @@ func (g *GameManager) SceneEntityDrownReq(player *model.Player, payloadMsg pb.Me g.SendMsg(cmd.SceneEntityDrownRsp, player.PlayerID, player.ClientSeq, sceneEntityDrownRsp) } -func (g *GameManager) NpcTalkReq(player *model.Player, payloadMsg pb.Message) { - req := payloadMsg.(*proto.NpcTalkReq) - rsp := &proto.NpcTalkRsp{ - CurTalkId: req.TalkId, - NpcEntityId: req.NpcEntityId, - EntityId: req.EntityId, - } - g.SendMsg(cmd.NpcTalkRsp, player.PlayerID, player.ClientSeq, rsp) -} - var SceneTransactionSeq uint32 = 0 func (g *GameManager) PacketPlayerEnterSceneNotifyLogin(player *model.Player, enterType proto.EnterType) *proto.PlayerEnterSceneNotify { @@ -443,6 +411,7 @@ func (g *GameManager) PacketPlayerEnterSceneNotifyLogin(player *model.Player, en } enterSceneToken := world.AddEnterSceneContext(&EnterSceneContext{ OldSceneId: 0, + Uid: player.PlayerID, }) playerEnterSceneNotify := &proto.PlayerEnterSceneNotify{ SceneId: player.SceneId, @@ -503,6 +472,12 @@ func (g *GameManager) PacketPlayerEnterSceneNotifyMp( Y: prevPos.Y, Z: prevPos.Z, }, + OldRot: &model.Vector{ + X: 0, + Y: 0, + Z: 0, + }, + Uid: player.PlayerID, }) playerEnterSceneNotify := &proto.PlayerEnterSceneNotify{ PrevSceneId: prevSceneId, diff --git a/gs/game/player_stamina.go b/gs/game/player_stamina.go index 94e95ca0..a483bee9 100644 --- a/gs/game/player_stamina.go +++ b/gs/game/player_stamina.go @@ -277,18 +277,15 @@ func (g *GameManager) SkillStartStamina(player *model.Player, casterId uint32, s // VehicleRestoreStaminaHandler 处理载具持续回复耐力 func (g *GameManager) VehicleRestoreStaminaHandler(player *model.Player) { - world := WORLD_MANAGER.GetWorldByID(player.WorldId) - scene := world.GetSceneById(player.SceneId) - if scene == nil { - logger.Error("scene is nil, sceneId: %v", player.SceneId) - return - } - // 玩家暂停状态不更新耐力 if player.Pause { return } - + world := WORLD_MANAGER.GetWorldByID(player.WorldId) + if world == nil { + return + } + scene := world.GetSceneById(player.SceneId) // 获取玩家创建的载具实体 entity := scene.GetEntity(player.VehicleInfo.InVehicleEntityId) if entity == nil { @@ -311,16 +308,15 @@ func (g *GameManager) VehicleRestoreStaminaHandler(player *model.Player) { // SustainStaminaHandler 处理持续耐力消耗 func (g *GameManager) SustainStaminaHandler(player *model.Player) { - world := WORLD_MANAGER.GetWorldByID(player.WorldId) - scene := world.GetSceneById(player.SceneId) - if scene == nil { - logger.Error("scene is nil, sceneId: %v", player.SceneId) - return - } // 玩家暂停状态不更新耐力 if player.Pause { return } + world := WORLD_MANAGER.GetWorldByID(player.WorldId) + if world == nil { + return + } + scene := world.GetSceneById(player.SceneId) // 获取玩家处于的载具实体 entity := scene.GetEntity(player.VehicleInfo.InVehicleEntityId) if entity == nil { @@ -453,11 +449,10 @@ func (g *GameManager) DrownBackHandler(player *model.Player) { } world := WORLD_MANAGER.GetWorldByID(player.WorldId) - scene := world.GetSceneById(player.SceneId) - if scene == nil { - logger.Error("scene is nil, sceneId: %v", player.SceneId) + if world == nil { return } + scene := world.GetSceneById(player.SceneId) activeAvatar := world.GetPlayerWorldAvatar(player, world.GetPlayerActiveAvatarId(player)) avatarEntity := scene.GetEntity(activeAvatar.GetAvatarEntityId()) if avatarEntity == nil { @@ -489,22 +484,6 @@ func (g *GameManager) DrownBackHandler(player *model.Player) { Y: player.SafePos.Y, Z: player.SafePos.Z, } - // 获取最近角色实体的锚点 - // TODO 阻塞优化 16ms我感觉有点慢 - // for _, entry := range gdc.CONF.ScenePointEntries { - // if entry.PointData == nil || entry.PointData.TranPos == nil { - // continue - // } - // pointPos := &model.Vector{ - // X: entry.PointData.TranPos.X, - // Y: entry.PointData.TranPos.Y, - // Z: entry.PointData.TranPos.Z, - // } - // // 该坐标距离小于之前的则赋值 - // if player.SafePos.Distance(pointPos) < player.SafePos.Distance(pos) { - // pos = pointPos - // } - // } // 传送玩家至安全位置 g.TeleportPlayer(player, uint16(proto.EnterReason_ENTER_REASON_REVIVAL), player.SceneId, pos, new(model.Vector), 0) } diff --git a/gs/game/player_world.go b/gs/game/player_world.go index db1e4b4b..f5248296 100644 --- a/gs/game/player_world.go +++ b/gs/game/player_world.go @@ -13,9 +13,10 @@ import ( pb "google.golang.org/protobuf/proto" ) +// 大地图模块 大世界相关的所有逻辑 + func (g *GameManager) SceneTransToPointReq(player *model.Player, payloadMsg pb.Message) { req := payloadMsg.(*proto.SceneTransToPointReq) - dbWorld := player.GetDbWorld() dbScene := dbWorld.GetSceneById(req.SceneId) if dbScene == nil { @@ -32,9 +33,9 @@ func (g *GameManager) SceneTransToPointReq(player *model.Player, payloadMsg pb.M g.SendError(cmd.SceneTransToPointRsp, player, &proto.SceneTransToPointRsp{}, proto.Retcode_RET_POINT_NOT_UNLOCKED) return } + // 传送玩家 - sceneId := req.SceneId - g.TeleportPlayer(player, uint16(proto.EnterReason_ENTER_REASON_TRANS_POINT), sceneId, &model.Vector{ + g.TeleportPlayer(player, uint16(proto.EnterReason_ENTER_REASON_TRANS_POINT), req.SceneId, &model.Vector{ X: pointDataConfig.TranPos.X, Y: pointDataConfig.TranPos.Y, Z: pointDataConfig.TranPos.Z, @@ -112,9 +113,9 @@ func (g *GameManager) GetScenePointReq(player *model.Player, payloadMsg pb.Messa func (g *GameManager) MarkMapReq(player *model.Player, payloadMsg pb.Message) { req := payloadMsg.(*proto.MarkMapReq) - operation := req.Op - if operation == proto.MarkMapReq_ADD { + if req.Op == proto.MarkMapReq_ADD { logger.Debug("user mark type: %v", req.Mark.PointType) + // 地图标点传送 if req.Mark.PointType == proto.MapMarkPointType_NPC { posYInt, err := strconv.ParseInt(req.Mark.Name, 10, 64) if err != nil { @@ -129,6 +130,7 @@ func (g *GameManager) MarkMapReq(player *model.Player, payloadMsg pb.Message) { }, new(model.Vector), 0) } } + g.SendMsg(cmd.MarkMapRsp, player.PlayerID, player.ClientSeq, &proto.MarkMapRsp{}) } func (g *GameManager) GetSceneAreaReq(player *model.Player, payloadMsg pb.Message) { @@ -176,6 +178,112 @@ func (g *GameManager) EnterWorldAreaReq(player *model.Player, payloadMsg pb.Mess g.SendMsg(cmd.EnterWorldAreaRsp, player.PlayerID, player.ClientSeq, enterWorldAreaRsp) } +func (g *GameManager) ChangeGameTimeReq(player *model.Player, payloadMsg pb.Message) { + req := payloadMsg.(*proto.ChangeGameTimeReq) + gameTime := req.GameTime + world := WORLD_MANAGER.GetWorldByID(player.WorldId) + scene := world.GetSceneById(player.SceneId) + if scene == nil { + logger.Error("scene is nil, sceneId: %v", player.SceneId) + return + } + scene.ChangeGameTime(gameTime) + + for _, scenePlayer := range scene.GetAllPlayer() { + playerGameTimeNotify := &proto.PlayerGameTimeNotify{ + GameTime: scene.GetGameTime(), + Uid: scenePlayer.PlayerID, + } + g.SendMsg(cmd.PlayerGameTimeNotify, scenePlayer.PlayerID, scenePlayer.ClientSeq, playerGameTimeNotify) + } + + changeGameTimeRsp := &proto.ChangeGameTimeRsp{ + CurGameTime: scene.GetGameTime(), + } + g.SendMsg(cmd.ChangeGameTimeRsp, player.PlayerID, player.ClientSeq, changeGameTimeRsp) +} + +func (g *GameManager) NpcTalkReq(player *model.Player, payloadMsg pb.Message) { + req := payloadMsg.(*proto.NpcTalkReq) + rsp := &proto.NpcTalkRsp{ + CurTalkId: req.TalkId, + NpcEntityId: req.NpcEntityId, + EntityId: req.EntityId, + } + g.SendMsg(cmd.NpcTalkRsp, player.PlayerID, player.ClientSeq, rsp) +} + +func (g *GameManager) DungeonEntryInfoReq(player *model.Player, payloadMsg pb.Message) { + req := payloadMsg.(*proto.DungeonEntryInfoReq) + pointDataConfig := gdconf.GetScenePointBySceneIdAndPointId(int32(req.SceneId), int32(req.PointId)) + if pointDataConfig == nil { + g.SendError(cmd.DungeonEntryInfoRsp, player, &proto.DungeonEntryInfoRsp{}) + return + } + + rsp := &proto.DungeonEntryInfoRsp{ + DungeonEntryList: make([]*proto.DungeonEntryInfo, 0), + PointId: req.PointId, + } + for _, dungeonId := range pointDataConfig.DungeonIds { + rsp.DungeonEntryList = append(rsp.DungeonEntryList, &proto.DungeonEntryInfo{ + DungeonId: uint32(dungeonId), + }) + } + g.SendMsg(cmd.DungeonEntryInfoRsp, player.PlayerID, player.ClientSeq, rsp) +} + +func (g *GameManager) PlayerEnterDungeonReq(player *model.Player, payloadMsg pb.Message) { + req := payloadMsg.(*proto.PlayerEnterDungeonReq) + dungeonDataConfig := gdconf.GetDungeonDataById(int32(req.DungeonId)) + if dungeonDataConfig == nil { + logger.Error("get dungeon data config is nil, dungeonId: %v, uid: %v", req.DungeonId, player.PlayerID) + return + } + sceneLuaConfig := gdconf.GetSceneLuaConfigById(dungeonDataConfig.SceneId) + if sceneLuaConfig == nil { + logger.Error("get scene lua config is nil, sceneId: %v, uid: %v", dungeonDataConfig.SceneId, player.PlayerID) + return + } + g.TeleportPlayer(player, uint16(proto.EnterReason_ENTER_REASON_DUNGEON_ENTER), uint32(dungeonDataConfig.SceneId), &model.Vector{ + X: float64(sceneLuaConfig.SceneConfig.BornPos.X), + Y: float64(sceneLuaConfig.SceneConfig.BornPos.Y), + Z: float64(sceneLuaConfig.SceneConfig.BornPos.Z), + }, &model.Vector{ + X: float64(sceneLuaConfig.SceneConfig.BornRot.X), + Y: float64(sceneLuaConfig.SceneConfig.BornRot.Y), + Z: float64(sceneLuaConfig.SceneConfig.BornRot.Z), + }, req.DungeonId) + + rsp := &proto.PlayerEnterDungeonRsp{ + DungeonId: req.DungeonId, + PointId: req.PointId, + } + g.SendMsg(cmd.PlayerEnterDungeonRsp, player.PlayerID, player.ClientSeq, rsp) +} + +func (g *GameManager) PlayerQuitDungeonReq(player *model.Player, payloadMsg pb.Message) { + req := payloadMsg.(*proto.PlayerQuitDungeonReq) + world := WORLD_MANAGER.GetWorldByID(player.WorldId) + if world == nil { + return + } + ctx := world.GetLastEnterSceneContextBySceneIdAndUid(3, player.PlayerID) + if ctx == nil { + return + } + g.TeleportPlayer(player, uint16(proto.EnterReason_ENTER_REASON_DUNGEON_QUIT), 3, &model.Vector{ + X: ctx.OldPos.X, + Y: ctx.OldPos.Y, + Z: ctx.OldPos.Z, + }, new(model.Vector), 0) + + rsp := &proto.PlayerQuitDungeonRsp{ + PointId: req.PointId, + } + g.SendMsg(cmd.PlayerQuitDungeonRsp, player.PlayerID, player.ClientSeq, rsp) +} + // TeleportPlayer 传送玩家至地图上的某个位置 func (g *GameManager) TeleportPlayer(player *model.Player, enterReason uint16, sceneId uint32, pos, rot *model.Vector, dungeonId uint32) { // 传送玩家 @@ -221,18 +329,16 @@ func (g *GameManager) TeleportPlayer(player *model.Player, enterReason uint16, s player.Rot.Z = rot.Z var enterType proto.EnterType - switch enterReason { - case uint16(proto.EnterReason_ENTER_REASON_DUNGEON_ENTER): - logger.Debug("player tp to dungeon scene, sceneId: %v, pos: %v", player.SceneId, player.Pos) - enterType = proto.EnterType_ENTER_DUNGEON - default: - if jumpScene { - logger.Debug("player jump scene, scene: %v, pos: %v", player.SceneId, player.Pos) - enterType = proto.EnterType_ENTER_JUMP - } else { - logger.Debug("player goto scene, scene: %v, pos: %v", player.SceneId, player.Pos) - enterType = proto.EnterType_ENTER_GOTO + if jumpScene { + logger.Debug("player jump scene, scene: %v, pos: %v", player.SceneId, player.Pos) + enterType = proto.EnterType_ENTER_JUMP + if enterReason == uint16(proto.EnterReason_ENTER_REASON_DUNGEON_ENTER) { + logger.Debug("player tp to dungeon scene, sceneId: %v, pos: %v", player.SceneId, player.Pos) + enterType = proto.EnterType_ENTER_DUNGEON } + } else { + logger.Debug("player goto scene, scene: %v, pos: %v", player.SceneId, player.Pos) + enterType = proto.EnterType_ENTER_GOTO } playerEnterSceneNotify := g.PacketPlayerEnterSceneNotifyTp(player, enterType, uint32(enterReason), oldSceneId, oldPos, dungeonId) g.SendMsg(cmd.PlayerEnterSceneNotify, player.PlayerID, player.ClientSeq, playerEnterSceneNotify) diff --git a/gs/game/route_manager.go b/gs/game/route_manager.go index d6b52f68..df3cd91a 100644 --- a/gs/game/route_manager.go +++ b/gs/game/route_manager.go @@ -145,6 +145,9 @@ func (r *RouteManager) initRoute() { r.registerRouter(cmd.EvtAiSyncCombatThreatInfoNotify, GAME_MANAGER.EvtAiSyncCombatThreatInfoNotify) r.registerRouter(cmd.EntityConfigHashNotify, GAME_MANAGER.EntityConfigHashNotify) r.registerRouter(cmd.MonsterAIConfigHashNotify, GAME_MANAGER.MonsterAIConfigHashNotify) + r.registerRouter(cmd.DungeonEntryInfoReq, GAME_MANAGER.DungeonEntryInfoReq) + r.registerRouter(cmd.PlayerEnterDungeonReq, GAME_MANAGER.PlayerEnterDungeonReq) + r.registerRouter(cmd.PlayerQuitDungeonReq, GAME_MANAGER.PlayerQuitDungeonReq) } func (r *RouteManager) RouteHandle(netMsg *mq.NetMsg) { diff --git a/gs/game/world_manager.go b/gs/game/world_manager.go index 81c2befb..8f30575f 100644 --- a/gs/game/world_manager.go +++ b/gs/game/world_manager.go @@ -207,6 +207,8 @@ func (w *WorldManager) GetMultiplayerWorldNum() uint32 { type EnterSceneContext struct { OldSceneId uint32 OldPos *model.Vector + OldRot *model.Vector + Uid uint32 } // World 世界数据结构 @@ -258,6 +260,23 @@ func (w *World) AddEnterSceneContext(ctx *EnterSceneContext) uint32 { return w.enterSceneToken } +func (w *World) GetLastEnterSceneContextBySceneIdAndUid(sceneId uint32, uid uint32) *EnterSceneContext { + for token := w.enterSceneToken; token >= 5000; token -= 100 { + ctx, exist := w.enterSceneContextMap[token] + if !exist { + continue + } + if ctx.OldSceneId != sceneId { + continue + } + if ctx.Uid != uid { + continue + } + return ctx + } + return nil +} + func (w *World) GetWorldLevel() uint8 { return w.worldLevel } diff --git a/protocol/cmd/cmd_id_proto_obj_map.go b/protocol/cmd/cmd_id_proto_obj_map.go index ae071526..b0a56f70 100644 --- a/protocol/cmd/cmd_id_proto_obj_map.go +++ b/protocol/cmd/cmd_id_proto_obj_map.go @@ -46,16 +46,18 @@ func (c *CmdProtoMap) registerAllMessage() { c.regMsg(ClientReconnectNotify, func() any { return new(proto.ClientReconnectNotify) }) // 在线重连通知 // 基础相关 - c.regMsg(UnionCmdNotify, func() any { return new(proto.UnionCmdNotify) }) // 聚合消息 - c.regMsg(PingReq, func() any { return new(proto.PingReq) }) // ping请求 - c.regMsg(PingRsp, func() any { return new(proto.PingRsp) }) // ping响应 - c.regMsg(WorldPlayerRTTNotify, func() any { return new(proto.WorldPlayerRTTNotify) }) // 世界玩家RTT时延 - c.regMsg(PlayerDataNotify, func() any { return new(proto.PlayerDataNotify) }) // 玩家信息通知 昵称、属性表等 - c.regMsg(PlayerPropNotify, func() any { return new(proto.PlayerPropNotify) }) // 玩家属性表通知 - c.regMsg(OpenStateUpdateNotify, func() any { return new(proto.OpenStateUpdateNotify) }) // 游戏功能模块开放状态更新通知 - c.regMsg(PlayerTimeNotify, func() any { return new(proto.PlayerTimeNotify) }) // 玩家累计在线时长通知 - c.regMsg(ServerTimeNotify, func() any { return new(proto.ServerTimeNotify) }) // 服务器时间通知 - c.regMsg(WindSeedClientNotify, func() any { return new(proto.WindSeedClientNotify) }) // 客户端XLUA调试通知 + c.regMsg(UnionCmdNotify, func() any { return new(proto.UnionCmdNotify) }) // 聚合消息 + c.regMsg(PingReq, func() any { return new(proto.PingReq) }) // ping请求 + c.regMsg(PingRsp, func() any { return new(proto.PingRsp) }) // ping响应 + c.regMsg(WorldPlayerRTTNotify, func() any { return new(proto.WorldPlayerRTTNotify) }) // 世界玩家RTT时延 + c.regMsg(PlayerDataNotify, func() any { return new(proto.PlayerDataNotify) }) // 玩家信息通知 昵称、属性表等 + c.regMsg(PlayerPropNotify, func() any { return new(proto.PlayerPropNotify) }) // 玩家属性表通知 + c.regMsg(OpenStateUpdateNotify, func() any { return new(proto.OpenStateUpdateNotify) }) // 游戏功能模块开放状态更新通知 + c.regMsg(PlayerTimeNotify, func() any { return new(proto.PlayerTimeNotify) }) // 玩家累计在线时长通知 + c.regMsg(ServerTimeNotify, func() any { return new(proto.ServerTimeNotify) }) // 服务器时间通知 + c.regMsg(WindSeedClientNotify, func() any { return new(proto.WindSeedClientNotify) }) // 客户端XLUA调试通知 + c.regMsg(ServerAnnounceNotify, func() any { return new(proto.ServerAnnounceNotify) }) // 服务器公告通知 + c.regMsg(ServerAnnounceRevokeNotify, func() any { return new(proto.ServerAnnounceRevokeNotify) }) // 服务器公告撤销通知 // 场景 c.regMsg(PlayerSetPauseReq, func() any { return new(proto.PlayerSetPauseReq) }) // 玩家暂停请求 @@ -75,6 +77,8 @@ func (c *CmdProtoMap) registerAllMessage() { c.regMsg(UnlockTransPointReq, func() any { return new(proto.UnlockTransPointReq) }) // 解锁场景传送点请求 c.regMsg(UnlockTransPointRsp, func() any { return new(proto.UnlockTransPointRsp) }) // 解锁场景传送点响应 c.regMsg(ScenePointUnlockNotify, func() any { return new(proto.ScenePointUnlockNotify) }) // 场景传送点解锁通知 + c.regMsg(MarkMapReq, func() any { return new(proto.MarkMapReq) }) // 标记地图请求 + c.regMsg(MarkMapRsp, func() any { return new(proto.MarkMapRsp) }) // 标记地图响应 c.regMsg(QueryPathReq, func() any { return new(proto.QueryPathReq) }) // 寻路请求 c.regMsg(QueryPathRsp, func() any { return new(proto.QueryPathRsp) }) // 寻路响应 c.regMsg(GetScenePointReq, func() any { return new(proto.GetScenePointReq) }) // 获取场景传送点请求 @@ -112,36 +116,42 @@ func (c *CmdProtoMap) registerAllMessage() { c.regMsg(SceneEntityDrownReq, func() any { return new(proto.SceneEntityDrownReq) }) // 场景实体溺水请求 c.regMsg(SceneEntityDrownRsp, func() any { return new(proto.SceneEntityDrownRsp) }) // 场景实体溺水响应 c.regMsg(ObstacleModifyNotify, func() any { return new(proto.ObstacleModifyNotify) }) // 寻路阻挡变动通知 - c.regMsg(DungeonWayPointNotify, func() any { return new(proto.DungeonWayPointNotify) }) // 地牢副本相关 - c.regMsg(DungeonDataNotify, func() any { return new(proto.DungeonDataNotify) }) // 地牢副本相关 c.regMsg(SceneAudioNotify, func() any { return new(proto.SceneAudioNotify) }) // 场景风物之琴音乐同步通知 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(DungeonEntryInfoReq, func() any { return new(proto.DungeonEntryInfoReq) }) // 地牢信息请求 + c.regMsg(DungeonEntryInfoRsp, func() any { return new(proto.DungeonEntryInfoRsp) }) // 地牢信息响应 + c.regMsg(PlayerEnterDungeonReq, func() any { return new(proto.PlayerEnterDungeonReq) }) // 进入地牢请求 + c.regMsg(PlayerEnterDungeonRsp, func() any { return new(proto.PlayerEnterDungeonRsp) }) // 进入地牢响应 + c.regMsg(PlayerQuitDungeonReq, func() any { return new(proto.PlayerQuitDungeonReq) }) // 退出地牢请求 + c.regMsg(PlayerQuitDungeonRsp, func() any { return new(proto.PlayerQuitDungeonRsp) }) // 退出地牢响应 + c.regMsg(DungeonDataNotify, func() any { return new(proto.DungeonDataNotify) }) // 地牢数据通知 + c.regMsg(DungeonWayPointNotify, func() any { return new(proto.DungeonWayPointNotify) }) // 地牢路点通知 // 战斗与同步 c.regMsg(AvatarFightPropNotify, func() any { return new(proto.AvatarFightPropNotify) }) // 角色战斗属性通知 c.regMsg(EntityFightPropUpdateNotify, func() any { return new(proto.EntityFightPropUpdateNotify) }) // 实体战斗属性更新通知 - c.regMsg(CombatInvocationsNotify, func() any { return new(proto.CombatInvocationsNotify) }) // 战斗通知 包含场景中实体的移动数据和伤害数据,多人游戏服务器转发 - c.regMsg(AbilityInvocationsNotify, func() any { return new(proto.AbilityInvocationsNotify) }) // 技能通知 多人游戏服务器转发 - c.regMsg(ClientAbilityInitFinishNotify, func() any { return new(proto.ClientAbilityInitFinishNotify) }) // 客户端技能初始化完成通知 多人游戏服务器转发 - c.regMsg(EvtDoSkillSuccNotify, func() any { return new(proto.EvtDoSkillSuccNotify) }) // 释放技能成功事件通知 - c.regMsg(ClientAbilityChangeNotify, func() any { return new(proto.ClientAbilityChangeNotify) }) // 客户端技能改变通知 - c.regMsg(MassiveEntityElementOpBatchNotify, func() any { return new(proto.MassiveEntityElementOpBatchNotify) }) // 风元素染色相关通知 - c.regMsg(EvtAvatarEnterFocusNotify, func() any { return new(proto.EvtAvatarEnterFocusNotify) }) // 进入弓箭蓄力瞄准状态通知 - c.regMsg(EvtAvatarUpdateFocusNotify, func() any { return new(proto.EvtAvatarUpdateFocusNotify) }) // 弓箭蓄力瞄准状态移动通知 - c.regMsg(EvtAvatarExitFocusNotify, func() any { return new(proto.EvtAvatarExitFocusNotify) }) // 退出弓箭蓄力瞄准状态通知 - c.regMsg(EvtEntityRenderersChangedNotify, func() any { return new(proto.EvtEntityRenderersChangedNotify) }) // 实体可视状态改变通知 + c.regMsg(CombatInvocationsNotify, func() any { return new(proto.CombatInvocationsNotify) }) // 客户端combat通知 服务器转发 + c.regMsg(AbilityInvocationsNotify, func() any { return new(proto.AbilityInvocationsNotify) }) // 客户端ability通知 服务器转发 + c.regMsg(ClientAbilityInitFinishNotify, func() any { return new(proto.ClientAbilityInitFinishNotify) }) // 客户端ability初始化完成通知 服务器转发 + c.regMsg(EvtDoSkillSuccNotify, func() any { return new(proto.EvtDoSkillSuccNotify) }) // 释放技能成功通知 + c.regMsg(ClientAbilityChangeNotify, func() any { return new(proto.ClientAbilityChangeNotify) }) // 客户端ability变更通知 服务器转发 + c.regMsg(MassiveEntityElementOpBatchNotify, func() any { return new(proto.MassiveEntityElementOpBatchNotify) }) // 风元素染色相关通知 服务器转发 + c.regMsg(EvtAvatarEnterFocusNotify, func() any { return new(proto.EvtAvatarEnterFocusNotify) }) // 进入弓箭蓄力瞄准状态通知 服务器转发 + c.regMsg(EvtAvatarUpdateFocusNotify, func() any { return new(proto.EvtAvatarUpdateFocusNotify) }) // 弓箭蓄力瞄准状态移动通知 服务器转发 + c.regMsg(EvtAvatarExitFocusNotify, func() any { return new(proto.EvtAvatarExitFocusNotify) }) // 退出弓箭蓄力瞄准状态通知 服务器转发 + c.regMsg(EvtEntityRenderersChangedNotify, func() any { return new(proto.EvtEntityRenderersChangedNotify) }) // 实体可视状态改变通知 服务器转发 c.regMsg(EvtCreateGadgetNotify, func() any { return new(proto.EvtCreateGadgetNotify) }) // 创建实体通知 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(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) }) // 更换角色请求 切人 @@ -327,11 +337,8 @@ func (c *CmdProtoMap) registerAllMessage() { c.regMsg(QuestGlobalVarNotify, func() any { return new(proto.QuestGlobalVarNotify) }) // 任务全局变量通知 // 乱七八糟 - c.regMsg(MarkMapReq, func() any { return new(proto.MarkMapReq) }) // 标记地图请求 - c.regMsg(TowerAllDataReq, func() any { return new(proto.TowerAllDataReq) }) // 深渊数据请求 - 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) }) // 服务器公告撤销通知 + c.regMsg(TowerAllDataReq, func() any { return new(proto.TowerAllDataReq) }) // 深渊数据请求 + c.regMsg(TowerAllDataRsp, func() any { return new(proto.TowerAllDataRsp) }) // 深渊数据响应 } func (c *CmdProtoMap) regMsg(cmdId uint16, protoObjNewFunc func() any) {