From d1e0d7bf5b385511c674dffc19fed7f6fbb9f606 Mon Sep 17 00:00:00 2001 From: flswld Date: Sun, 2 Apr 2023 19:32:31 +0800 Subject: [PATCH] =?UTF-8?q?=E6=95=B4=E7=90=86=E5=9C=BA=E6=99=AF=E5=8D=8F?= =?UTF-8?q?=E8=AE=AE=E7=BB=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gdconf/gadget_data.go | 10 +- gdconf/scene_lua_config.go | 5 +- gs/game/game.go | 14 ++- gs/game/game_command_gm.go | 4 +- gs/game/game_tick_manager.go | 129 ++-------------------- gs/game/game_world_manager.go | 8 +- gs/game/game_world_scene.go | 6 +- gs/game/player_avatar.go | 6 +- gs/game/player_common.go | 120 +++++++++++++++++++++ gs/game/player_fight_sync.go | 83 +++++++++------ gs/game/player_gcg.go | 2 +- gs/game/player_login.go | 6 ++ gs/game/player_multiplayer.go | 147 +++++++++++++------------ gs/game/player_scene.go | 153 ++++++++++----------------- gs/game/player_stamina.go | 2 +- gs/game/player_world.go | 15 +-- gs/model/player.go | 3 +- protocol/cmd/cmd_id_proto_obj_map.go | 43 ++++++-- 18 files changed, 391 insertions(+), 365 deletions(-) diff --git a/gdconf/gadget_data.go b/gdconf/gadget_data.go index 4e6ec0f9..e8751726 100644 --- a/gdconf/gadget_data.go +++ b/gdconf/gadget_data.go @@ -6,9 +6,13 @@ import ( // GadgetData 物件配置表 type GadgetData struct { - GadgetId int32 `csv:"ID"` - Type int32 `csv:"类型,omitempty"` - DefaultCamp int32 `csv:"默认阵营,omitempty"` + GadgetId int32 `csv:"ID"` + Name string `csv:"名称$text_name_Name,omitempty"` + DefaultCamp int32 `csv:"默认阵营,omitempty"` + Type int32 `csv:"类型,omitempty"` + CanInteract int32 `csv:"能否交互,omitempty"` + VisionLevel int32 `csv:"视距等级,omitempty"` + ServerLuaScript string `csv:"服务器脚本,omitempty"` } func (g *GameDataConfig) loadGadgetData() { diff --git a/gdconf/scene_lua_config.go b/gdconf/scene_lua_config.go index 632d4836..c2ab8119 100644 --- a/gdconf/scene_lua_config.go +++ b/gdconf/scene_lua_config.go @@ -17,6 +17,7 @@ import ( const ( SceneGroupLoaderLimit = 4 // 加载文件的并发数 此操作很耗内存 调大之前请确保你的机器内存足够 + LuaStateLruKeepNum = 100 ) type SceneLuaConfig struct { @@ -406,10 +407,6 @@ func GetSceneGroup(groupId int32) *Group { return groupConfig } -const ( - LuaStateLruKeepNum = 10 -) - type LuaStateLru struct { GroupId int32 AccessTime int64 diff --git a/gs/game/game.go b/gs/game/game.go index 55ab9c68..fa63633e 100644 --- a/gs/game/game.go +++ b/gs/game/game.go @@ -389,8 +389,18 @@ func (g *Game) SendToWorldH(world *World, cmdId uint16, seq uint32, msg pb.Messa GAME.SendMsg(cmdId, world.GetOwner().PlayerID, seq, msg) } -func (g *Game) ReLoginPlayer(userId uint32) { - g.SendMsg(cmd.ClientReconnectNotify, userId, 0, new(proto.ClientReconnectNotify)) +func (g *Game) ReLoginPlayer(userId uint32, isQuitMp bool) { + reason := proto.ClientReconnectReason_CLIENT_RECONNNECT_NONE + if isQuitMp { + reason = proto.ClientReconnectReason_CLIENT_RECONNNECT_QUIT_MP + } + g.SendMsg(cmd.ClientReconnectNotify, userId, 0, &proto.ClientReconnectNotify{ + Reason: reason, + }) +} + +func (g *Game) LogoutPlayer(userId uint32) { + g.SendMsg(cmd.PlayerLogoutNotify, userId, 0, &proto.PlayerLogoutNotify{}) } func (g *Game) KickPlayer(userId uint32, reason uint32) { diff --git a/gs/game/game_command_gm.go b/gs/game/game_command_gm.go index 6e3a0513..85e3c5dd 100644 --- a/gs/game/game_command_gm.go +++ b/gs/game/game_command_gm.go @@ -25,7 +25,7 @@ func (g *GMCmd) GMTeleportPlayer(userId, sceneId, dungeonId uint32, posX, posY, logger.Error("player is nil, uid: %v", userId) return } - GAME.TeleportPlayer(player, uint16(proto.EnterReason_ENTER_REASON_GM), sceneId, &model.Vector{ + GAME.TeleportPlayer(player, proto.EnterReason_ENTER_REASON_GM, sceneId, &model.Vector{ X: posX, Y: posY, Z: posZ, @@ -141,6 +141,8 @@ func (g *GMCmd) GMAddUserAllEvery(userId, itemCount uint32) { g.GMAddUserAllCostume(userId) // 给予玩家所有风之翼 g.GMAddUserAllFlycloak(userId) + + GAME.LogoutPlayer(userId) } // GMAddQuest 添加任务 diff --git a/gs/game/game_tick_manager.go b/gs/game/game_tick_manager.go index da0312d0..b378126e 100644 --- a/gs/game/game_tick_manager.go +++ b/gs/game/game_tick_manager.go @@ -3,7 +3,6 @@ package game import ( "time" - "hk4e/common/constant" "hk4e/gdconf" "hk4e/pkg/logger" "hk4e/pkg/random" @@ -14,8 +13,8 @@ import ( // 游戏服务器定时帧管理器 const ( - ServerTickTime = 20 // 服务器全局tick最小间隔毫秒 - UserTickTime = 1000 // 玩家自身tick最小间隔毫秒 + ServerTickTime = 20 // 服务器全局tick最小间隔毫秒 + UserTickTime = 100 // 玩家自身tick最小间隔毫秒 ) type UserTimer struct { @@ -227,24 +226,8 @@ func (t *TickManager) onTickMinute(now int64) { func (t *TickManager) onTick10Second(now int64) { for _, world := range WORLD_MANAGER.GetAllWorld() { - for _, scene := range world.GetAllScene() { - for _, player := range scene.GetAllPlayer() { - - sceneTimeNotify := &proto.SceneTimeNotify{ - SceneId: player.SceneId, - SceneTime: uint64(scene.GetSceneTime()), - } - GAME.SendMsg(cmd.SceneTimeNotify, player.PlayerID, 0, sceneTimeNotify) - } - } - for _, player := range world.GetAllPlayer() { - playerTimeNotify := &proto.PlayerTimeNotify{ - IsPaused: player.Pause, - PlayerTime: uint64(player.TotalOnlineTime), - ServerTime: uint64(time.Now().UnixMilli()), - } - GAME.SendMsg(cmd.PlayerTimeNotify, player.PlayerID, 0, playerTimeNotify) - } + GAME.SceneTimeNotify(world) + GAME.PlayerTimeNotify(world) } } @@ -256,111 +239,15 @@ func (t *TickManager) onTick5Second(now int64) { } } // 多人世界其他玩家的坐标位置广播 - worldPlayerLocationNotify := &proto.WorldPlayerLocationNotify{ - PlayerWorldLocList: make([]*proto.PlayerWorldLocationInfo, 0), - } - for _, worldPlayer := range world.GetAllPlayer() { - playerWorldLocationInfo := &proto.PlayerWorldLocationInfo{ - SceneId: worldPlayer.SceneId, - PlayerLoc: &proto.PlayerLocationInfo{ - Uid: worldPlayer.PlayerID, - Pos: &proto.Vector{ - X: float32(worldPlayer.Pos.X), - Y: float32(worldPlayer.Pos.Y), - Z: float32(worldPlayer.Pos.Z), - }, - Rot: &proto.Vector{ - X: float32(worldPlayer.Rot.X), - Y: float32(worldPlayer.Rot.Y), - Z: float32(worldPlayer.Rot.Z), - }, - }, - } - worldPlayerLocationNotify.PlayerWorldLocList = append(worldPlayerLocationNotify.PlayerWorldLocList, playerWorldLocationInfo) - } - GAME.SendToWorldA(world, cmd.WorldPlayerLocationNotify, 0, worldPlayerLocationNotify) - - for _, scene := range world.GetAllScene() { - scenePlayerLocationNotify := &proto.ScenePlayerLocationNotify{ - SceneId: scene.id, - PlayerLocList: make([]*proto.PlayerLocationInfo, 0), - VehicleLocList: make([]*proto.VehicleLocationInfo, 0), - } - for _, scenePlayer := range scene.GetAllPlayer() { - // 玩家位置 - playerLocationInfo := &proto.PlayerLocationInfo{ - Uid: scenePlayer.PlayerID, - Pos: &proto.Vector{ - X: float32(scenePlayer.Pos.X), - Y: float32(scenePlayer.Pos.Y), - Z: float32(scenePlayer.Pos.Z), - }, - Rot: &proto.Vector{ - X: float32(scenePlayer.Rot.X), - Y: float32(scenePlayer.Rot.Y), - Z: float32(scenePlayer.Rot.Z), - }, - } - scenePlayerLocationNotify.PlayerLocList = append(scenePlayerLocationNotify.PlayerLocList, playerLocationInfo) - // 载具位置 - for _, entityId := range scenePlayer.VehicleInfo.LastCreateEntityIdMap { - entity := scene.GetEntity(entityId) - // 确保实体类型是否为载具 - if entity != nil && entity.GetEntityType() == constant.ENTITY_TYPE_GADGET && entity.gadgetEntity.gadgetVehicleEntity != nil { - vehicleLocationInfo := &proto.VehicleLocationInfo{ - Rot: &proto.Vector{ - X: float32(entity.rot.X), - Y: float32(entity.rot.Y), - Z: float32(entity.rot.Z), - }, - EntityId: entity.id, - CurHp: entity.fightProp[constant.FIGHT_PROP_CUR_HP], - OwnerUid: entity.gadgetEntity.gadgetVehicleEntity.owner.PlayerID, - Pos: &proto.Vector{ - X: float32(entity.pos.X), - Y: float32(entity.pos.Y), - Z: float32(entity.pos.Z), - }, - UidList: make([]uint32, 0, len(entity.gadgetEntity.gadgetVehicleEntity.memberMap)), - GadgetId: entity.gadgetEntity.gadgetVehicleEntity.vehicleId, - MaxHp: entity.fightProp[constant.FIGHT_PROP_MAX_HP], - } - for _, p := range entity.gadgetEntity.gadgetVehicleEntity.memberMap { - vehicleLocationInfo.UidList = append(vehicleLocationInfo.UidList, p.PlayerID) - } - scenePlayerLocationNotify.VehicleLocList = append(scenePlayerLocationNotify.VehicleLocList, vehicleLocationInfo) - } - } - } - GAME.SendToWorldA(world, cmd.ScenePlayerLocationNotify, 0, scenePlayerLocationNotify) - } + GAME.WorldPlayerLocationNotify(world) + GAME.ScenePlayerLocationNotify(world) } } func (t *TickManager) onTickSecond(now int64) { for _, world := range WORLD_MANAGER.GetAllWorld() { - for _, player := range world.GetAllPlayer() { - // 世界里所有玩家的网络延迟广播 - worldPlayerRTTNotify := &proto.WorldPlayerRTTNotify{ - PlayerRttList: make([]*proto.PlayerRTTInfo, 0), - } - for _, worldPlayer := range world.GetAllPlayer() { - playerRTTInfo := &proto.PlayerRTTInfo{Uid: worldPlayer.PlayerID, Rtt: worldPlayer.ClientRTT} - worldPlayerRTTNotify.PlayerRttList = append(worldPlayerRTTNotify.PlayerRttList, playerRTTInfo) - } - GAME.SendMsg(cmd.WorldPlayerRTTNotify, player.PlayerID, 0, worldPlayerRTTNotify) - // 玩家安全位置更新 - switch player.StaminaInfo.State { - case proto.MotionState_MOTION_DANGER_RUN, proto.MotionState_MOTION_RUN, - proto.MotionState_MOTION_DANGER_STANDBY_MOVE, proto.MotionState_MOTION_DANGER_STANDBY, proto.MotionState_MOTION_LADDER_TO_STANDBY, proto.MotionState_MOTION_STANDBY_MOVE, proto.MotionState_MOTION_STANDBY, - proto.MotionState_MOTION_DANGER_WALK, proto.MotionState_MOTION_WALK, - proto.MotionState_MOTION_DASH: - // 仅在陆地时更新玩家安全位置 - player.SafePos.X = player.Pos.X - player.SafePos.Y = player.Pos.Y - player.SafePos.Z = player.Pos.Z - } - } + // 世界里所有玩家的网络延迟广播 + GAME.WorldPlayerRTTNotify(world) } // // GCG游戏Tick // for _, game := range GCG_MANAGER.gameMap { diff --git a/gs/game/game_world_manager.go b/gs/game/game_world_manager.go index 89c41d58..d66e7ef3 100644 --- a/gs/game/game_world_manager.go +++ b/gs/game/game_world_manager.go @@ -193,10 +193,10 @@ func (w *WorldManager) GetMultiplayerWorldNum() uint32 { // EnterSceneContext 场景切换上下文数据结构 type EnterSceneContext struct { - OldSceneId uint32 - OldPos *model.Vector - OldRot *model.Vector - Uid uint32 + OldSceneId uint32 + OldPos *model.Vector + OldDungeonId uint32 + Uid uint32 } // World 世界数据结构 diff --git a/gs/game/game_world_scene.go b/gs/game/game_world_scene.go index 4262ec30..329dc653 100644 --- a/gs/game/game_world_scene.go +++ b/gs/game/game_world_scene.go @@ -458,9 +458,9 @@ func getTempFightPropMap() map[uint32]float32 { constant.FIGHT_PROP_CUR_ATTACK: float32(50.0), constant.FIGHT_PROP_BASE_DEFENSE: float32(500.0), constant.FIGHT_PROP_CUR_DEFENSE: float32(500.0), - constant.FIGHT_PROP_BASE_HP: float32(5000.0), - constant.FIGHT_PROP_CUR_HP: float32(5000.0), - constant.FIGHT_PROP_MAX_HP: float32(5000.0), + constant.FIGHT_PROP_BASE_HP: float32(50.0), + constant.FIGHT_PROP_CUR_HP: float32(50.0), + constant.FIGHT_PROP_MAX_HP: float32(50.0), constant.FIGHT_PROP_PHYSICAL_SUB_HURT: float32(0.1), constant.FIGHT_PROP_ICE_SUB_HURT: float32(0.1), constant.FIGHT_PROP_FIRE_SUB_HURT: float32(0.1), diff --git a/gs/game/player_avatar.go b/gs/game/player_avatar.go index 6f04b848..7cc69181 100644 --- a/gs/game/player_avatar.go +++ b/gs/game/player_avatar.go @@ -350,12 +350,8 @@ func (g *Game) AvatarChangeCostumeReq(player *model.Player, payloadMsg pb.Messag } func (g *Game) PacketAvatarInfo(avatar *model.Avatar) *proto.AvatarInfo { - isFocus := false - if avatar.AvatarId == 10000005 || avatar.AvatarId == 10000007 { - isFocus = true - } pbAvatar := &proto.AvatarInfo{ - IsFocus: isFocus, + IsFocus: false, AvatarId: avatar.AvatarId, Guid: avatar.Guid, PropMap: map[uint32]*proto.PropValue{ diff --git a/gs/game/player_common.go b/gs/game/player_common.go index 828ba126..f88f71b5 100644 --- a/gs/game/player_common.go +++ b/gs/game/player_common.go @@ -4,6 +4,7 @@ import ( "math" "time" + "hk4e/common/constant" "hk4e/gate/kcp" "hk4e/gs/model" "hk4e/pkg/logger" @@ -144,3 +145,122 @@ func (g *Game) ServerAppidBindNotify(userId uint32, anticheatAppId string, joinH player.SceneLoadState = model.SceneNone g.SendMsg(cmd.PlayerEnterSceneNotify, userId, player.ClientSeq, g.PacketPlayerEnterSceneNotifyLogin(player, proto.EnterType_ENTER_SELF)) } + +// WorldPlayerRTTNotify 世界里所有玩家的网络延迟广播 +func (g *Game) WorldPlayerRTTNotify(world *World) { + worldPlayerRTTNotify := &proto.WorldPlayerRTTNotify{ + PlayerRttList: make([]*proto.PlayerRTTInfo, 0), + } + for _, worldPlayer := range world.GetAllPlayer() { + playerRTTInfo := &proto.PlayerRTTInfo{Uid: worldPlayer.PlayerID, Rtt: worldPlayer.ClientRTT} + worldPlayerRTTNotify.PlayerRttList = append(worldPlayerRTTNotify.PlayerRttList, playerRTTInfo) + } + GAME.SendToWorldA(world, cmd.WorldPlayerRTTNotify, 0, worldPlayerRTTNotify) +} + +// WorldPlayerLocationNotify 多人世界其他玩家的坐标位置广播 +func (g *Game) WorldPlayerLocationNotify(world *World) { + worldPlayerLocationNotify := &proto.WorldPlayerLocationNotify{ + PlayerWorldLocList: make([]*proto.PlayerWorldLocationInfo, 0), + } + for _, worldPlayer := range world.GetAllPlayer() { + playerWorldLocationInfo := &proto.PlayerWorldLocationInfo{ + SceneId: worldPlayer.SceneId, + PlayerLoc: &proto.PlayerLocationInfo{ + Uid: worldPlayer.PlayerID, + Pos: &proto.Vector{ + X: float32(worldPlayer.Pos.X), + Y: float32(worldPlayer.Pos.Y), + Z: float32(worldPlayer.Pos.Z), + }, + Rot: &proto.Vector{ + X: float32(worldPlayer.Rot.X), + Y: float32(worldPlayer.Rot.Y), + Z: float32(worldPlayer.Rot.Z), + }, + }, + } + worldPlayerLocationNotify.PlayerWorldLocList = append(worldPlayerLocationNotify.PlayerWorldLocList, playerWorldLocationInfo) + } + GAME.SendToWorldA(world, cmd.WorldPlayerLocationNotify, 0, worldPlayerLocationNotify) +} + +func (g *Game) ScenePlayerLocationNotify(world *World) { + for _, scene := range world.GetAllScene() { + scenePlayerLocationNotify := &proto.ScenePlayerLocationNotify{ + SceneId: scene.id, + PlayerLocList: make([]*proto.PlayerLocationInfo, 0), + VehicleLocList: make([]*proto.VehicleLocationInfo, 0), + } + for _, scenePlayer := range scene.GetAllPlayer() { + // 玩家位置 + playerLocationInfo := &proto.PlayerLocationInfo{ + Uid: scenePlayer.PlayerID, + Pos: &proto.Vector{ + X: float32(scenePlayer.Pos.X), + Y: float32(scenePlayer.Pos.Y), + Z: float32(scenePlayer.Pos.Z), + }, + Rot: &proto.Vector{ + X: float32(scenePlayer.Rot.X), + Y: float32(scenePlayer.Rot.Y), + Z: float32(scenePlayer.Rot.Z), + }, + } + scenePlayerLocationNotify.PlayerLocList = append(scenePlayerLocationNotify.PlayerLocList, playerLocationInfo) + // 载具位置 + for _, entityId := range scenePlayer.VehicleInfo.LastCreateEntityIdMap { + entity := scene.GetEntity(entityId) + // 确保实体类型是否为载具 + if entity != nil && entity.GetEntityType() == constant.ENTITY_TYPE_GADGET && entity.gadgetEntity.gadgetVehicleEntity != nil { + vehicleLocationInfo := &proto.VehicleLocationInfo{ + Rot: &proto.Vector{ + X: float32(entity.rot.X), + Y: float32(entity.rot.Y), + Z: float32(entity.rot.Z), + }, + EntityId: entity.id, + CurHp: entity.fightProp[constant.FIGHT_PROP_CUR_HP], + OwnerUid: entity.gadgetEntity.gadgetVehicleEntity.owner.PlayerID, + Pos: &proto.Vector{ + X: float32(entity.pos.X), + Y: float32(entity.pos.Y), + Z: float32(entity.pos.Z), + }, + UidList: make([]uint32, 0, len(entity.gadgetEntity.gadgetVehicleEntity.memberMap)), + GadgetId: entity.gadgetEntity.gadgetVehicleEntity.vehicleId, + MaxHp: entity.fightProp[constant.FIGHT_PROP_MAX_HP], + } + for _, p := range entity.gadgetEntity.gadgetVehicleEntity.memberMap { + vehicleLocationInfo.UidList = append(vehicleLocationInfo.UidList, p.PlayerID) + } + scenePlayerLocationNotify.VehicleLocList = append(scenePlayerLocationNotify.VehicleLocList, vehicleLocationInfo) + } + } + } + GAME.SendToWorldA(world, cmd.ScenePlayerLocationNotify, 0, scenePlayerLocationNotify) + } +} + +func (g *Game) SceneTimeNotify(world *World) { + for _, scene := range world.GetAllScene() { + for _, player := range scene.GetAllPlayer() { + sceneTimeNotify := &proto.SceneTimeNotify{ + SceneId: player.SceneId, + SceneTime: uint64(scene.GetSceneTime()), + } + GAME.SendMsg(cmd.SceneTimeNotify, player.PlayerID, 0, sceneTimeNotify) + } + } +} + +func (g *Game) PlayerTimeNotify(world *World) { + for _, player := range world.GetAllPlayer() { + playerTimeNotify := &proto.PlayerTimeNotify{ + IsPaused: player.Pause, + PlayerTime: uint64(player.TotalOnlineTime), + ServerTime: uint64(time.Now().UnixMilli()), + } + GAME.SendMsg(cmd.PlayerTimeNotify, player.PlayerID, 0, playerTimeNotify) + } +} diff --git a/gs/game/player_fight_sync.go b/gs/game/player_fight_sync.go index aac42818..29b4bf27 100644 --- a/gs/game/player_fight_sync.go +++ b/gs/game/player_fight_sync.go @@ -1,7 +1,10 @@ package game import ( + "strings" + "hk4e/common/constant" + "hk4e/gdconf" "hk4e/gs/model" "hk4e/pkg/logger" "hk4e/pkg/reflection" @@ -90,11 +93,8 @@ func (g *Game) CombatInvocationsNotify(player *model.Player, payloadMsg pb.Messa return } scene := world.GetSceneById(player.SceneId) - if scene == nil { - logger.Error("scene is nil, sceneId: %v", player.SceneId) - return - } for _, entry := range req.InvokeList { + player.CombatInvokeHandler.AddEntry(entry.ForwardType, entry) switch entry.ArgumentType { case proto.CombatTypeArgument_COMBAT_EVT_BEING_HIT: evtBeingHitInfo := new(proto.EvtBeingHitInfo) @@ -114,30 +114,42 @@ func (g *Game) CombatInvocationsNotify(player *model.Player, payloadMsg pb.Messa logger.Error("could not found target, defense id: %v", attackResult.DefenseId) continue } - attackResult.Damage *= 100 - damage := attackResult.Damage - attackerId := attackResult.AttackerId - _ = attackerId - currHp := float32(0) fightProp := target.GetFightProp() - if fightProp != nil { - currHp = fightProp[constant.FIGHT_PROP_CUR_HP] - currHp -= damage - if currHp < 0 { - currHp = 0 - } - fightProp[constant.FIGHT_PROP_CUR_HP] = currHp + currHp := fightProp[constant.FIGHT_PROP_CUR_HP] + currHp -= attackResult.Damage + if currHp < 0 { + currHp = 0 } + fightProp[constant.FIGHT_PROP_CUR_HP] = currHp g.EntityFightPropUpdateNotifyBroadcast(world, target) - if currHp == 0 && target.GetEntityType() == constant.ENTITY_TYPE_MONSTER { - g.KillEntity(player, scene, target.GetId(), proto.PlayerDieType_PLAYER_DIE_GM) + switch target.GetEntityType() { + case constant.ENTITY_TYPE_AVATAR: + case constant.ENTITY_TYPE_MONSTER: + if currHp == 0 { + g.KillEntity(player, scene, target.GetId(), proto.PlayerDieType_PLAYER_DIE_GM) + } + case constant.ENTITY_TYPE_GADGET: + gadgetEntity := target.GetGadgetEntity() + gadgetDataConfig := gdconf.GetGadgetDataById(int32(gadgetEntity.GetGadgetId())) + if gadgetDataConfig == nil { + logger.Error("get gadget data config is nil, gadgetId: %v", gadgetEntity.GetGadgetId()) + continue + } + logger.Debug("[EvtBeingHit] GadgetData: %+v, uid: %v", gadgetDataConfig, player.PlayerID) + // TODO 临时的解决方案 + switch gadgetDataConfig.ServerLuaScript { + case "SubfieldDrop_WoodenObject_Broken": + g.KillEntity(player, scene, target.GetId(), proto.PlayerDieType_PLAYER_DIE_GM) + case "SetGadgetState": + g.ChangeGadgetState(player, target.GetId(), constant.GADGET_STATE_GEAR_START) + } + if strings.Contains(gadgetDataConfig.ServerLuaScript, "SubfieldDrop_Ore_") { + g.KillEntity(player, scene, target.GetId(), proto.PlayerDieType_PLAYER_DIE_GM) + } + if strings.Contains(gadgetDataConfig.ServerLuaScript, "Controller") { + g.ChangeGadgetState(player, target.GetId(), constant.GADGET_STATE_GEAR_START) + } } - combatData, err := pb.Marshal(evtBeingHitInfo) - if err != nil { - logger.Error("create combat invocations entity hit info error: %v", err) - } - entry.CombatData = combatData - player.CombatInvokeHandler.AddEntry(entry.ForwardType, entry) case proto.CombatTypeArgument_ENTITY_MOVE: entityMoveInfo := new(proto.EntityMoveInfo) err := pb.Unmarshal(entry.CombatData, entityMoveInfo) @@ -174,7 +186,23 @@ func (g *Game) CombatInvocationsNotify(player *model.Player, payloadMsg pb.Messa player.Rot.X = float64(motionInfo.Rot.X) player.Rot.Y = float64(motionInfo.Rot.Y) player.Rot.Z = float64(motionInfo.Rot.Z) - + // 玩家安全位置更新 + switch motionInfo.State { + case proto.MotionState_MOTION_DANGER_RUN, + proto.MotionState_MOTION_RUN, + proto.MotionState_MOTION_DANGER_STANDBY_MOVE, + proto.MotionState_MOTION_DANGER_STANDBY, + proto.MotionState_MOTION_LADDER_TO_STANDBY, + proto.MotionState_MOTION_STANDBY_MOVE, + proto.MotionState_MOTION_STANDBY, + proto.MotionState_MOTION_DANGER_WALK, + proto.MotionState_MOTION_WALK, + proto.MotionState_MOTION_DASH: + // 仅在陆地时更新玩家安全位置 + player.SafePos.X = player.Pos.X + player.SafePos.Y = player.Pos.Y + player.SafePos.Z = player.Pos.Z + } // 处理耐力消耗 g.ImmediateStamina(player, motionInfo.State) } else { @@ -207,7 +235,6 @@ func (g *Game) CombatInvocationsNotify(player *model.Player, payloadMsg pb.Messa // 只要转发了这两个包的其中之一 客户端的动画就会被打断 continue } - player.CombatInvokeHandler.AddEntry(entry.ForwardType, entry) case proto.CombatTypeArgument_COMBAT_ANIMATOR_PARAMETER_CHANGED: evtAnimatorParameterInfo := new(proto.EvtAnimatorParameterInfo) err := pb.Unmarshal(entry.CombatData, evtAnimatorParameterInfo) @@ -216,7 +243,6 @@ func (g *Game) CombatInvocationsNotify(player *model.Player, payloadMsg pb.Messa continue } // logger.Debug("EvtAnimatorParameterInfo: %v, ForwardType: %v", evtAnimatorParameterInfo, entry.ForwardType) - player.CombatInvokeHandler.AddEntry(entry.ForwardType, entry) case proto.CombatTypeArgument_COMBAT_ANIMATOR_STATE_CHANGED: evtAnimatorStateChangedInfo := new(proto.EvtAnimatorStateChangedInfo) err := pb.Unmarshal(entry.CombatData, evtAnimatorStateChangedInfo) @@ -225,9 +251,6 @@ func (g *Game) CombatInvocationsNotify(player *model.Player, payloadMsg pb.Messa continue } // logger.Debug("EvtAnimatorStateChangedInfo: %v, ForwardType: %v", evtAnimatorStateChangedInfo, entry.ForwardType) - player.CombatInvokeHandler.AddEntry(entry.ForwardType, entry) - default: - player.CombatInvokeHandler.AddEntry(entry.ForwardType, entry) } } } diff --git a/gs/game/player_gcg.go b/gs/game/player_gcg.go index ce00e6d5..4c86f6a4 100644 --- a/gs/game/player_gcg.go +++ b/gs/game/player_gcg.go @@ -63,7 +63,7 @@ func (g *Game) GCGStartChallenge(player *model.Player) { g.PacketGCGGameBriefDataNotify(player, proto.GCGGameBusinessType_GCG_GAME_GUIDE_GROUP, game)) // 玩家进入GCG界面 - g.TeleportPlayer(player, uint16(proto.EnterReason_ENTER_REASON_DUNGEON_ENTER), 79999, new(model.Vector), new(model.Vector), 2162) + g.TeleportPlayer(player, proto.EnterReason_ENTER_REASON_DUNGEON_ENTER, 79999, new(model.Vector), new(model.Vector), 2162) } // GCGAskDuelReq GCG决斗请求 diff --git a/gs/game/player_login.go b/gs/game/player_login.go index 72555f08..90f5125d 100644 --- a/gs/game/player_login.go +++ b/gs/game/player_login.go @@ -253,6 +253,12 @@ func (g *Game) LoginNotify(userId uint32, player *model.Player, clientSeq uint32 Birthday: "2000-01-01", } g.SendMsg(cmd.PlayerLoginRsp, userId, clientSeq, playerLoginRsp) + playerTimeNotify := &proto.PlayerTimeNotify{ + IsPaused: player.Pause, + PlayerTime: uint64(player.TotalOnlineTime), + ServerTime: uint64(time.Now().UnixMilli()), + } + g.SendMsg(cmd.PlayerTimeNotify, player.PlayerID, 0, playerTimeNotify) } func (g *Game) PacketPlayerDataNotify(player *model.Player) *proto.PlayerDataNotify { diff --git a/gs/game/player_multiplayer.go b/gs/game/player_multiplayer.go index c06c953e..dc5aae0c 100644 --- a/gs/game/player_multiplayer.go +++ b/gs/game/player_multiplayer.go @@ -87,7 +87,15 @@ func (g *Game) JoinOtherWorld(player *model.Player, hostPlayer *model.Player) { player.Rot.Z = hostPlayer.Rot.Z g.UserWorldAddPlayer(hostWorld, player) - playerEnterSceneNotify := g.PacketPlayerEnterSceneNotifyLogin(player, proto.EnterType_ENTER_OTHER) + playerEnterSceneNotify := g.PacketPlayerEnterSceneNotifyMp( + player, + hostPlayer, + proto.EnterType_ENTER_OTHER, + proto.EnterReason_ENTER_REASON_TEAM_JOIN, + 0, + new(model.Vector), + 0, + ) g.SendMsg(cmd.PlayerEnterSceneNotify, player.PlayerID, player.ClientSeq, playerEnterSceneNotify) } else { hostWorld.AddWaitPlayer(player.PlayerID) @@ -258,7 +266,7 @@ func (g *Game) UserDealEnterWorld(hostPlayer *model.Player, otherUid uint32, agr if !agree { return } - g.HostEnterMpWorld(hostPlayer, otherUid) + g.HostEnterMpWorld(hostPlayer) otherPlayer := USER_MANAGER.GetOnlineUser(otherUid) if otherPlayer == nil { @@ -308,7 +316,7 @@ func (g *Game) UserDealEnterWorld(hostPlayer *model.Player, otherUid uint32, agr g.SendMsg(cmd.PlayerApplyEnterMpResultNotify, otherPlayer.PlayerID, otherPlayer.ClientSeq, playerApplyEnterMpResultNotify) } -func (g *Game) HostEnterMpWorld(hostPlayer *model.Player, otherUid uint32) { +func (g *Game) HostEnterMpWorld(hostPlayer *model.Player) { world := WORLD_MANAGER.GetWorldByID(hostPlayer.WorldId) if world.GetMultiplayer() { return @@ -333,19 +341,13 @@ func (g *Game) HostEnterMpWorld(hostPlayer *model.Player, otherUid uint32) { hostPlayer, hostPlayer, proto.EnterType_ENTER_GOTO, - uint32(proto.EnterReason_ENTER_REASON_HOST_FROM_SINGLE_TO_MP), + proto.EnterReason_ENTER_REASON_HOST_FROM_SINGLE_TO_MP, hostPlayer.SceneId, hostPlayer.Pos, 0, ) g.SendMsg(cmd.PlayerEnterSceneNotify, hostPlayer.PlayerID, hostPlayer.ClientSeq, hostPlayerEnterSceneNotify) - guestBeginEnterSceneNotify := &proto.GuestBeginEnterSceneNotify{ - SceneId: hostPlayer.SceneId, - Uid: otherUid, - } - g.SendMsg(cmd.GuestBeginEnterSceneNotify, hostPlayer.PlayerID, hostPlayer.ClientSeq, guestBeginEnterSceneNotify) - // 仅仅把当前的场上角色的实体消失掉 activeAvatarId := world.GetPlayerActiveAvatarId(hostPlayer) g.RemoveSceneEntityNotifyToPlayer(hostPlayer, proto.VisionType_VISION_MISS, []uint32{world.GetPlayerWorldAvatarEntityId(hostPlayer, activeAvatarId)}) @@ -361,7 +363,7 @@ func (g *Game) UserLeaveWorld(player *model.Player) bool { return false } } - g.ReLoginPlayer(player.PlayerID) + g.ReLoginPlayer(player.PlayerID, true) return true } @@ -393,14 +395,12 @@ func (g *Game) UserWorldRemovePlayer(world *World, player *model.Player) { } } scene := world.GetSceneById(player.SceneId) - if scene == nil { - logger.Error("scene is nil, sceneId: %v", player.SceneId) - return - } - // 仅仅把当前的场上角色的实体消失掉 - activeAvatarId := world.GetPlayerActiveAvatarId(player) - g.RemoveSceneEntityNotifyToPlayer(player, proto.VisionType_VISION_MISS, []uint32{world.GetPlayerWorldAvatarEntityId(player, activeAvatarId)}) + entityIdList := make([]uint32, 0) + for _, entity := range scene.GetAllEntity() { + entityIdList = append(entityIdList, entity.GetId()) + } + g.RemoveSceneEntityNotifyToPlayer(player, proto.VisionType_VISION_MISS, entityIdList) delTeamEntityNotify := g.PacketDelTeamEntityNotify(scene, player) g.SendMsg(cmd.DelTeamEntityNotify, player.PlayerID, player.ClientSeq, delTeamEntityNotify) @@ -433,13 +433,6 @@ func (g *Game) UpdateWorldPlayerInfo(hostWorld *World, excludePlayer *model.Play continue } - playerPreEnterMpNotify := &proto.PlayerPreEnterMpNotify{ - State: proto.PlayerPreEnterMpNotify_START, - Uid: excludePlayer.PlayerID, - Nickname: excludePlayer.NickName, - } - g.SendMsg(cmd.PlayerPreEnterMpNotify, worldPlayer.PlayerID, worldPlayer.ClientSeq, playerPreEnterMpNotify) - worldPlayerInfoNotify := &proto.WorldPlayerInfoNotify{ PlayerInfoList: make([]*proto.OnlinePlayerInfo, 0), PlayerUidList: make([]uint32, 0), @@ -466,59 +459,63 @@ func (g *Game) UpdateWorldPlayerInfo(hostWorld *World, excludePlayer *model.Play } g.SendMsg(cmd.ServerTimeNotify, worldPlayer.PlayerID, worldPlayer.ClientSeq, serverTimeNotify) - scenePlayerInfoNotify := &proto.ScenePlayerInfoNotify{ - PlayerInfoList: make([]*proto.ScenePlayerInfo, 0), - } - for _, worldPlayer := range hostWorld.GetAllPlayer() { - onlinePlayerInfo := &proto.OnlinePlayerInfo{ - Uid: worldPlayer.PlayerID, - Nickname: worldPlayer.NickName, - PlayerLevel: worldPlayer.PropertiesMap[constant.PLAYER_PROP_PLAYER_LEVEL], - MpSettingType: proto.MpSettingType(worldPlayer.PropertiesMap[constant.PLAYER_PROP_PLAYER_MP_SETTING_TYPE]), - NameCardId: worldPlayer.NameCard, - Signature: worldPlayer.Signature, - ProfilePicture: &proto.ProfilePicture{AvatarId: worldPlayer.HeadImage}, - CurPlayerNumInWorld: uint32(hostWorld.GetWorldPlayerNum()), - } - scenePlayerInfoNotify.PlayerInfoList = append(scenePlayerInfoNotify.PlayerInfoList, &proto.ScenePlayerInfo{ - Uid: worldPlayer.PlayerID, - PeerId: hostWorld.GetPlayerPeerId(worldPlayer), - Name: worldPlayer.NickName, - SceneId: worldPlayer.SceneId, - OnlinePlayerInfo: onlinePlayerInfo, - }) - } - g.SendMsg(cmd.ScenePlayerInfoNotify, worldPlayer.PlayerID, worldPlayer.ClientSeq, scenePlayerInfoNotify) - - sceneTeamUpdateNotify := g.PacketSceneTeamUpdateNotify(hostWorld) - g.SendMsg(cmd.SceneTeamUpdateNotify, worldPlayer.PlayerID, worldPlayer.ClientSeq, sceneTeamUpdateNotify) - - syncTeamEntityNotify := &proto.SyncTeamEntityNotify{ - SceneId: worldPlayer.SceneId, - TeamEntityInfoList: make([]*proto.TeamEntityInfo, 0), - } - if hostWorld.GetMultiplayer() { - for _, worldPlayer := range hostWorld.GetAllPlayer() { - if worldPlayer.PlayerID == worldPlayer.PlayerID { - continue - } - teamEntityInfo := &proto.TeamEntityInfo{ - TeamEntityId: hostWorld.GetPlayerTeamEntityId(worldPlayer), - AuthorityPeerId: hostWorld.GetPlayerPeerId(worldPlayer), - TeamAbilityInfo: new(proto.AbilitySyncStateInfo), - } - syncTeamEntityNotify.TeamEntityInfoList = append(syncTeamEntityNotify.TeamEntityInfoList, teamEntityInfo) - } - } - g.SendMsg(cmd.SyncTeamEntityNotify, worldPlayer.PlayerID, worldPlayer.ClientSeq, syncTeamEntityNotify) - - syncScenePlayTeamEntityNotify := &proto.SyncScenePlayTeamEntityNotify{ - SceneId: worldPlayer.SceneId, - } - g.SendMsg(cmd.SyncScenePlayTeamEntityNotify, worldPlayer.PlayerID, worldPlayer.ClientSeq, syncScenePlayTeamEntityNotify) + g.UpdateWorldScenePlayerInfo(worldPlayer, hostWorld) } } +func (g *Game) UpdateWorldScenePlayerInfo(player *model.Player, world *World) { + scenePlayerInfoNotify := &proto.ScenePlayerInfoNotify{ + PlayerInfoList: make([]*proto.ScenePlayerInfo, 0), + } + for _, worldPlayer := range world.GetAllPlayer() { + onlinePlayerInfo := &proto.OnlinePlayerInfo{ + Uid: worldPlayer.PlayerID, + Nickname: worldPlayer.NickName, + PlayerLevel: worldPlayer.PropertiesMap[constant.PLAYER_PROP_PLAYER_LEVEL], + MpSettingType: proto.MpSettingType(worldPlayer.PropertiesMap[constant.PLAYER_PROP_PLAYER_MP_SETTING_TYPE]), + NameCardId: worldPlayer.NameCard, + Signature: worldPlayer.Signature, + ProfilePicture: &proto.ProfilePicture{AvatarId: worldPlayer.HeadImage}, + CurPlayerNumInWorld: uint32(world.GetWorldPlayerNum()), + } + scenePlayerInfoNotify.PlayerInfoList = append(scenePlayerInfoNotify.PlayerInfoList, &proto.ScenePlayerInfo{ + Uid: worldPlayer.PlayerID, + PeerId: world.GetPlayerPeerId(worldPlayer), + Name: worldPlayer.NickName, + SceneId: worldPlayer.SceneId, + OnlinePlayerInfo: onlinePlayerInfo, + }) + } + g.SendMsg(cmd.ScenePlayerInfoNotify, player.PlayerID, player.ClientSeq, scenePlayerInfoNotify) + + sceneTeamUpdateNotify := g.PacketSceneTeamUpdateNotify(world) + g.SendMsg(cmd.SceneTeamUpdateNotify, player.PlayerID, player.ClientSeq, sceneTeamUpdateNotify) + + syncTeamEntityNotify := &proto.SyncTeamEntityNotify{ + SceneId: player.SceneId, + TeamEntityInfoList: make([]*proto.TeamEntityInfo, 0), + } + if world.GetMultiplayer() { + for _, worldPlayer := range world.GetAllPlayer() { + if worldPlayer.PlayerID == player.PlayerID { + continue + } + teamEntityInfo := &proto.TeamEntityInfo{ + TeamEntityId: world.GetPlayerTeamEntityId(worldPlayer), + AuthorityPeerId: world.GetPlayerPeerId(worldPlayer), + TeamAbilityInfo: new(proto.AbilitySyncStateInfo), + } + syncTeamEntityNotify.TeamEntityInfoList = append(syncTeamEntityNotify.TeamEntityInfoList, teamEntityInfo) + } + } + g.SendMsg(cmd.SyncTeamEntityNotify, player.PlayerID, player.ClientSeq, syncTeamEntityNotify) + + syncScenePlayTeamEntityNotify := &proto.SyncScenePlayTeamEntityNotify{ + SceneId: player.SceneId, + } + g.SendMsg(cmd.SyncScenePlayTeamEntityNotify, player.PlayerID, player.ClientSeq, syncScenePlayTeamEntityNotify) +} + // 跨服玩家多人世界相关请求 func (g *Game) ServerUserMpReq(userMpInfo *mq.UserMpInfo, gsAppId string) { diff --git a/gs/game/player_scene.go b/gs/game/player_scene.go index 645a796e..976f8926 100644 --- a/gs/game/player_scene.go +++ b/gs/game/player_scene.go @@ -30,6 +30,21 @@ func (g *Game) EnterSceneReadyReq(player *model.Player, payloadMsg pb.Message) { logger.Debug("player enter scene ready, uid: %v", player.PlayerID) world := WORLD_MANAGER.GetWorldByID(player.WorldId) + if world.GetMultiplayer() && world.IsPlayerFirstEnter(player) { + guestBeginEnterSceneNotify := &proto.GuestBeginEnterSceneNotify{ + SceneId: player.SceneId, + Uid: player.PlayerID, + } + g.SendToWorldAEC(world, cmd.GuestBeginEnterSceneNotify, 0, guestBeginEnterSceneNotify, player.PlayerID) + + playerPreEnterMpNotify := &proto.PlayerPreEnterMpNotify{ + State: proto.PlayerPreEnterMpNotify_START, + Uid: player.PlayerID, + Nickname: player.NickName, + } + g.SendToWorldAEC(world, cmd.PlayerPreEnterMpNotify, 0, playerPreEnterMpNotify, player.PlayerID) + } + ctx := world.GetEnterSceneContextByToken(req.EnterSceneToken) if ctx == nil { logger.Error("get enter scene context is nil, uid: %v", player.PlayerID) @@ -155,20 +170,19 @@ func (g *Game) SceneInitFinishReq(player *model.Player, payloadMsg pb.Message) { } g.SendMsg(cmd.PlayerGameTimeNotify, player.PlayerID, player.ClientSeq, playerGameTimeNotify) - empty := new(proto.AbilitySyncStateInfo) activeAvatarId := world.GetPlayerActiveAvatarId(player) playerEnterSceneInfoNotify := &proto.PlayerEnterSceneInfoNotify{ CurAvatarEntityId: world.GetPlayerWorldAvatarEntityId(player, activeAvatarId), EnterSceneToken: req.EnterSceneToken, TeamEnterInfo: &proto.TeamEnterSceneInfo{ TeamEntityId: world.GetPlayerTeamEntityId(player), - TeamAbilityInfo: empty, + TeamAbilityInfo: new(proto.AbilitySyncStateInfo), AbilityControlBlock: new(proto.AbilityControlBlock), }, MpLevelEntityInfo: &proto.MPLevelEntityInfo{ - EntityId: WORLD_MANAGER.GetWorldByID(player.WorldId).GetMpLevelEntityId(), - AuthorityPeerId: world.GetPlayerPeerId(player), - AbilityInfo: empty, + EntityId: world.GetMpLevelEntityId(), + AuthorityPeerId: world.GetPlayerPeerId(world.GetOwner()), + AbilityInfo: new(proto.AbilitySyncStateInfo), }, AvatarEnterInfo: make([]*proto.AvatarEnterSceneInfo, 0), } @@ -188,7 +202,7 @@ func (g *Game) SceneInitFinishReq(player *model.Player, payloadMsg pb.Message) { MixinRecoverInfos: nil, SgvDynamicValueMap: nil, }, - WeaponAbilityInfo: empty, + WeaponAbilityInfo: new(proto.AbilitySyncStateInfo), } playerEnterSceneInfoNotify.AvatarEnterInfo = append(playerEnterSceneInfoNotify.AvatarEnterInfo, avatarEnterSceneInfo) } @@ -201,56 +215,7 @@ func (g *Game) SceneInitFinishReq(player *model.Player, payloadMsg pb.Message) { g.SendMsg(cmd.SceneAreaWeatherNotify, player.PlayerID, player.ClientSeq, sceneAreaWeatherNotify) } - scenePlayerInfoNotify := &proto.ScenePlayerInfoNotify{ - PlayerInfoList: make([]*proto.ScenePlayerInfo, 0), - } - for _, worldPlayer := range world.GetAllPlayer() { - onlinePlayerInfo := &proto.OnlinePlayerInfo{ - Uid: worldPlayer.PlayerID, - Nickname: worldPlayer.NickName, - PlayerLevel: worldPlayer.PropertiesMap[constant.PLAYER_PROP_PLAYER_LEVEL], - MpSettingType: proto.MpSettingType(worldPlayer.PropertiesMap[constant.PLAYER_PROP_PLAYER_MP_SETTING_TYPE]), - NameCardId: worldPlayer.NameCard, - Signature: worldPlayer.Signature, - ProfilePicture: &proto.ProfilePicture{AvatarId: worldPlayer.HeadImage}, - CurPlayerNumInWorld: uint32(world.GetWorldPlayerNum()), - } - scenePlayerInfoNotify.PlayerInfoList = append(scenePlayerInfoNotify.PlayerInfoList, &proto.ScenePlayerInfo{ - Uid: worldPlayer.PlayerID, - PeerId: world.GetPlayerPeerId(worldPlayer), - Name: worldPlayer.NickName, - SceneId: worldPlayer.SceneId, - OnlinePlayerInfo: onlinePlayerInfo, - }) - } - g.SendMsg(cmd.ScenePlayerInfoNotify, player.PlayerID, player.ClientSeq, scenePlayerInfoNotify) - - sceneTeamUpdateNotify := g.PacketSceneTeamUpdateNotify(world) - g.SendMsg(cmd.SceneTeamUpdateNotify, player.PlayerID, player.ClientSeq, sceneTeamUpdateNotify) - - syncTeamEntityNotify := &proto.SyncTeamEntityNotify{ - SceneId: player.SceneId, - TeamEntityInfoList: make([]*proto.TeamEntityInfo, 0), - } - if world.GetMultiplayer() { - for _, worldPlayer := range world.GetAllPlayer() { - if worldPlayer.PlayerID == player.PlayerID { - continue - } - teamEntityInfo := &proto.TeamEntityInfo{ - TeamEntityId: world.GetPlayerTeamEntityId(worldPlayer), - AuthorityPeerId: world.GetPlayerPeerId(worldPlayer), - TeamAbilityInfo: new(proto.AbilitySyncStateInfo), - } - syncTeamEntityNotify.TeamEntityInfoList = append(syncTeamEntityNotify.TeamEntityInfoList, teamEntityInfo) - } - } - g.SendMsg(cmd.SyncTeamEntityNotify, player.PlayerID, player.ClientSeq, syncTeamEntityNotify) - - syncScenePlayTeamEntityNotify := &proto.SyncScenePlayTeamEntityNotify{ - SceneId: player.SceneId, - } - g.SendMsg(cmd.SyncScenePlayTeamEntityNotify, player.PlayerID, player.ClientSeq, syncScenePlayTeamEntityNotify) + g.UpdateWorldScenePlayerInfo(player, world) g.GCGTavernInit(player) // GCG酒馆信息通知 @@ -270,27 +235,15 @@ func (g *Game) EnterSceneDoneReq(player *model.Player, payloadMsg pb.Message) { logger.Debug("player enter scene done, uid: %v", player.PlayerID) 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 world.GetMultiplayer() && world.IsPlayerFirstEnter(player) { - guestPostEnterSceneNotify := &proto.GuestPostEnterSceneNotify{ - SceneId: player.SceneId, - Uid: player.PlayerID, - } - g.SendMsg(cmd.GuestPostEnterSceneNotify, world.GetOwner().PlayerID, world.GetOwner().ClientSeq, guestPostEnterSceneNotify) - } var visionType = proto.VisionType_VISION_NONE - - activeAvatarId := world.GetPlayerActiveAvatarId(player) if player.SceneJump { visionType = proto.VisionType_VISION_BORN } else { visionType = proto.VisionType_VISION_TRANSPORT } + + activeAvatarId := world.GetPlayerActiveAvatarId(player) activeAvatarEntityId := world.GetPlayerWorldAvatarEntityId(player, activeAvatarId) g.AddSceneEntityNotify(player, visionType, []uint32{activeAvatarEntityId}, true, false) @@ -298,11 +251,6 @@ func (g *Game) EnterSceneDoneReq(player *model.Player, payloadMsg pb.Message) { for _, groupConfig := range g.GetNeighborGroup(scene.GetId(), player.Pos) { g.AddSceneGroup(player, scene, groupConfig) } - if player.SceneJump { - visionType = proto.VisionType_VISION_MEET - } else { - visionType = proto.VisionType_VISION_TRANSPORT - } // 同步客户端视野内的场景实体 entityIdList := make([]uint32, 0) visionEntityMap := g.GetVisionEntity(scene, player.Pos) @@ -343,6 +291,15 @@ func (g *Game) EnterSceneDoneReq(player *model.Player, payloadMsg pb.Message) { func (g *Game) PostEnterSceneReq(player *model.Player, payloadMsg pb.Message) { req := payloadMsg.(*proto.PostEnterSceneReq) logger.Debug("player post enter scene, uid: %v", player.PlayerID) + world := WORLD_MANAGER.GetWorldByID(player.WorldId) + + if world.GetMultiplayer() && world.IsPlayerFirstEnter(player) { + guestPostEnterSceneNotify := &proto.GuestPostEnterSceneNotify{ + SceneId: player.SceneId, + Uid: player.PlayerID, + } + g.SendToWorldAEC(world, cmd.GuestPostEnterSceneNotify, 0, guestPostEnterSceneNotify, player.PlayerID) + } postEnterSceneRsp := &proto.PostEnterSceneRsp{ EnterSceneToken: req.EnterSceneToken, @@ -805,29 +762,37 @@ func (g *Game) PacketPlayerEnterSceneNotifyLogin(player *model.Player, enterType func (g *Game) PacketPlayerEnterSceneNotifyTp( player *model.Player, enterType proto.EnterType, - enterReason uint32, + enterReason proto.EnterReason, prevSceneId uint32, prevPos *model.Vector, dungeonId uint32, ) *proto.PlayerEnterSceneNotify { - return g.PacketPlayerEnterSceneNotifyMp(player, player, enterType, enterReason, prevSceneId, prevPos, dungeonId) + return g.PacketPlayerEnterSceneNotifyCore(player, player, enterType, enterReason, prevSceneId, prevPos, dungeonId) } func (g *Game) PacketPlayerEnterSceneNotifyMp( player *model.Player, targetPlayer *model.Player, enterType proto.EnterType, - enterReason uint32, + enterReason proto.EnterReason, prevSceneId uint32, prevPos *model.Vector, dungeonId uint32, ) *proto.PlayerEnterSceneNotify { - world := WORLD_MANAGER.GetWorldByID(player.WorldId) - scene := world.GetSceneById(player.SceneId) - if scene == nil { - logger.Error("scene is nil, sceneId: %v", player.SceneId) - return new(proto.PlayerEnterSceneNotify) - } + return g.PacketPlayerEnterSceneNotifyCore(player, targetPlayer, enterType, enterReason, prevSceneId, prevPos, dungeonId) +} + +func (g *Game) PacketPlayerEnterSceneNotifyCore( + player *model.Player, + targetPlayer *model.Player, + enterType proto.EnterType, + enterReason proto.EnterReason, + prevSceneId uint32, + prevPos *model.Vector, + dungeonId uint32, +) *proto.PlayerEnterSceneNotify { + world := WORLD_MANAGER.GetWorldByID(targetPlayer.WorldId) + scene := world.GetSceneById(targetPlayer.SceneId) enterSceneToken := world.AddEnterSceneContext(&EnterSceneContext{ OldSceneId: prevSceneId, OldPos: &model.Vector{ @@ -835,35 +800,31 @@ func (g *Game) PacketPlayerEnterSceneNotifyMp( Y: prevPos.Y, Z: prevPos.Z, }, - OldRot: &model.Vector{ - X: 0, - Y: 0, - Z: 0, - }, - Uid: player.PlayerID, + OldDungeonId: dungeonId, + Uid: player.PlayerID, }) playerEnterSceneNotify := &proto.PlayerEnterSceneNotify{ PrevSceneId: prevSceneId, PrevPos: &proto.Vector{X: float32(prevPos.X), Y: float32(prevPos.Y), Z: float32(prevPos.Z)}, - SceneId: player.SceneId, - Pos: &proto.Vector{X: float32(player.Pos.X), Y: float32(player.Pos.Y), Z: float32(player.Pos.Z)}, + SceneId: targetPlayer.SceneId, + Pos: &proto.Vector{X: float32(targetPlayer.Pos.X), Y: float32(targetPlayer.Pos.Y), Z: float32(targetPlayer.Pos.Z)}, SceneBeginTime: uint64(scene.GetSceneCreateTime()), Type: enterType, TargetUid: targetPlayer.PlayerID, EnterSceneToken: enterSceneToken, WorldLevel: targetPlayer.PropertiesMap[constant.PLAYER_PROP_PLAYER_WORLD_LEVEL], - EnterReason: enterReason, + EnterReason: uint32(enterReason), WorldType: 1, DungeonId: dungeonId, SceneTagIdList: make([]uint32, 0), } SceneTransactionSeq++ - playerEnterSceneNotify.SceneTransaction = strconv.Itoa(int(player.SceneId)) + "-" + - strconv.Itoa(int(targetPlayer.PlayerID)) + "-" + + playerEnterSceneNotify.SceneTransaction = strconv.Itoa(int(targetPlayer.SceneId)) + "-" + + strconv.Itoa(int(player.PlayerID)) + "-" + strconv.Itoa(int(time.Now().Unix())) + "-" + strconv.Itoa(int(SceneTransactionSeq)) for _, sceneTagDataConfig := range gdconf.GetSceneTagDataMap() { - if uint32(sceneTagDataConfig.SceneId) == player.SceneId { + if uint32(sceneTagDataConfig.SceneId) == targetPlayer.SceneId { playerEnterSceneNotify.SceneTagIdList = append(playerEnterSceneNotify.SceneTagIdList, uint32(sceneTagDataConfig.SceneTagId)) } } diff --git a/gs/game/player_stamina.go b/gs/game/player_stamina.go index bca46b13..87b39a36 100644 --- a/gs/game/player_stamina.go +++ b/gs/game/player_stamina.go @@ -474,7 +474,7 @@ func (g *Game) DrownBackHandler(player *model.Player) { Z: player.SafePos.Z, } // 传送玩家至安全位置 - g.TeleportPlayer(player, uint16(proto.EnterReason_ENTER_REASON_REVIVAL), player.SceneId, pos, new(model.Vector), 0) + g.TeleportPlayer(player, proto.EnterReason_ENTER_REASON_REVIVAL, player.SceneId, pos, new(model.Vector), 0) } // 防止重置后又被修改 if player.StaminaInfo.DrownBackDelay != 0 { diff --git a/gs/game/player_world.go b/gs/game/player_world.go index 97a9654b..eba9dc1b 100644 --- a/gs/game/player_world.go +++ b/gs/game/player_world.go @@ -36,7 +36,7 @@ func (g *Game) SceneTransToPointReq(player *model.Player, payloadMsg pb.Message) } // 传送玩家 - g.TeleportPlayer(player, uint16(proto.EnterReason_ENTER_REASON_TRANS_POINT), req.SceneId, &model.Vector{ + g.TeleportPlayer(player, proto.EnterReason_ENTER_REASON_TRANS_POINT, req.SceneId, &model.Vector{ X: pointDataConfig.TranPos.X, Y: pointDataConfig.TranPos.Y, Z: pointDataConfig.TranPos.Z, @@ -124,7 +124,7 @@ func (g *Game) MarkMapReq(player *model.Player, payloadMsg pb.Message) { posYInt = 300 } // 传送玩家 - g.TeleportPlayer(player, uint16(proto.EnterReason_ENTER_REASON_GM), req.Mark.SceneId, &model.Vector{ + g.TeleportPlayer(player, proto.EnterReason_ENTER_REASON_GM, req.Mark.SceneId, &model.Vector{ X: float64(req.Mark.Pos.X), Y: float64(posYInt), Z: float64(req.Mark.Pos.Z), @@ -247,7 +247,7 @@ func (g *Game) PlayerEnterDungeonReq(player *model.Player, payloadMsg pb.Message 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{ + g.TeleportPlayer(player, 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), @@ -274,7 +274,7 @@ func (g *Game) PlayerQuitDungeonReq(player *model.Player, payloadMsg pb.Message) if ctx == nil { return } - g.TeleportPlayer(player, uint16(proto.EnterReason_ENTER_REASON_DUNGEON_QUIT), 3, &model.Vector{ + g.TeleportPlayer(player, proto.EnterReason_ENTER_REASON_DUNGEON_QUIT, 3, &model.Vector{ X: ctx.OldPos.X, Y: ctx.OldPos.Y, Z: ctx.OldPos.Z, @@ -309,6 +309,7 @@ func (g *Game) GadgetInteractReq(player *model.Player, payloadMsg pb.Message) { logger.Error("get gadget data config is nil, gadgetId: %v, uid: %v", gadgetEntity.GetGadgetId(), player.PlayerID) return } + logger.Debug("[GadgetInteractReq] GadgetData: %+v, uid: %v", gadgetDataConfig, player.PlayerID) interactType := proto.InteractType_INTERACT_NONE switch gadgetDataConfig.Type { case constant.GADGET_TYPE_GADGET: @@ -475,7 +476,7 @@ func (g *Game) doRandDropOnce(dropDataConfig *gdconf.DropData) map[int32]int32 { } // TeleportPlayer 传送玩家至地图上的某个位置 -func (g *Game) TeleportPlayer(player *model.Player, enterReason uint16, sceneId uint32, pos, rot *model.Vector, dungeonId uint32) { +func (g *Game) TeleportPlayer(player *model.Player, enterReason proto.EnterReason, sceneId uint32, pos, rot *model.Vector, dungeonId uint32) { // 传送玩家 newSceneId := sceneId oldSceneId := player.SceneId @@ -522,7 +523,7 @@ func (g *Game) TeleportPlayer(player *model.Player, enterReason uint16, sceneId 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) { + if enterReason == 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 } @@ -530,6 +531,6 @@ func (g *Game) TeleportPlayer(player *model.Player, enterReason uint16, sceneId 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) + playerEnterSceneNotify := g.PacketPlayerEnterSceneNotifyTp(player, enterType, enterReason, oldSceneId, oldPos, dungeonId) g.SendMsg(cmd.PlayerEnterSceneNotify, player.PlayerID, player.ClientSeq, playerEnterSceneNotify) } diff --git a/gs/model/player.go b/gs/model/player.go index 5740d853..f0085459 100644 --- a/gs/model/player.go +++ b/gs/model/player.go @@ -134,9 +134,10 @@ func (i *InvokeHandler[T]) AddEntry(forward proto.ForwardType, entry *T) { i.EntryListForwardAllExceptCur = append(i.EntryListForwardAllExceptCur, entry) case proto.ForwardType_FORWARD_TO_HOST: i.EntryListForwardHost = append(i.EntryListForwardHost, entry) + case proto.ForwardType_FORWARD_TO_PEER: + i.EntryListForwardAllExceptCur = append(i.EntryListForwardAllExceptCur, entry) case proto.ForwardType_FORWARD_ONLY_SERVER: i.EntryListForwardServer = append(i.EntryListForwardServer, entry) - // logger.Error("forward server entry: %v", entry) default: logger.Error("forward type: %v, entry: %v", forward, entry) } diff --git a/protocol/cmd/cmd_id_proto_obj_map.go b/protocol/cmd/cmd_id_proto_obj_map.go index 520b4fc7..ea4a9e52 100644 --- a/protocol/cmd/cmd_id_proto_obj_map.go +++ b/protocol/cmd/cmd_id_proto_obj_map.go @@ -42,8 +42,9 @@ func (c *CmdProtoMap) registerAllMessage() { c.regMsg(PlayerLoginRsp, func() any { return new(proto.PlayerLoginRsp) }) // 玩家登录响应 c.regMsg(PlayerForceExitReq, func() any { return new(proto.PlayerForceExitReq) }) // 退出游戏请求 c.regMsg(PlayerForceExitRsp, func() any { return new(proto.PlayerForceExitRsp) }) // 退出游戏响应 - c.regMsg(ServerDisconnectClientNotify, func() any { return new(proto.ServerDisconnectClientNotify) }) // 服务器断开连接通知 - c.regMsg(ClientReconnectNotify, func() any { return new(proto.ClientReconnectNotify) }) // 在线重连通知 + c.regMsg(ServerDisconnectClientNotify, func() any { return new(proto.ServerDisconnectClientNotify) }) // 断开连接通知 + c.regMsg(ClientReconnectNotify, func() any { return new(proto.ClientReconnectNotify) }) // 重连通知 + c.regMsg(PlayerLogoutNotify, func() any { return new(proto.PlayerLogoutNotify) }) // 退出登录通知 // 基础相关 c.regMsg(UnionCmdNotify, func() any { return new(proto.UnionCmdNotify) }) // 聚合消息 @@ -58,6 +59,8 @@ func (c *CmdProtoMap) registerAllMessage() { 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(TowerAllDataReq, func() any { return new(proto.TowerAllDataReq) }) // 深渊数据请求 + c.regMsg(TowerAllDataRsp, func() any { return new(proto.TowerAllDataRsp) }) // 深渊数据响应 // 场景 c.regMsg(PlayerSetPauseReq, func() any { return new(proto.PlayerSetPauseReq) }) // 玩家暂停请求 @@ -150,12 +153,12 @@ func (c *CmdProtoMap) registerAllMessage() { 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) }) // 更换角色请求 切人 @@ -340,9 +343,27 @@ func (c *CmdProtoMap) registerAllMessage() { c.regMsg(QuestProgressUpdateNotify, func() any { return new(proto.QuestProgressUpdateNotify) }) // 任务进度更新通知 c.regMsg(QuestGlobalVarNotify, func() any { return new(proto.QuestGlobalVarNotify) }) // 任务全局变量通知 - // 乱七八糟 - c.regMsg(TowerAllDataReq, func() any { return new(proto.TowerAllDataReq) }) // 深渊数据请求 - c.regMsg(TowerAllDataRsp, func() any { return new(proto.TowerAllDataRsp) }) // 深渊数据响应 + // 家园 + c.regMsg(GetPlayerHomeCompInfoReq, func() any { return new(proto.GetPlayerHomeCompInfoReq) }) // 请求 + c.regMsg(HomeGetBasicInfoReq, func() any { return new(proto.HomeGetBasicInfoReq) }) // 请求 + c.regMsg(GetHomeExchangeWoodInfoReq, func() any { return new(proto.GetHomeExchangeWoodInfoReq) }) // 请求 + c.regMsg(GetHomeExchangeWoodInfoRsp, func() any { return new(proto.GetHomeExchangeWoodInfoRsp) }) // 响应 + c.regMsg(HomeGetOnlineStatusReq, func() any { return new(proto.HomeGetOnlineStatusReq) }) // 请求 + c.regMsg(HomeGetOnlineStatusRsp, func() any { return new(proto.HomeGetOnlineStatusRsp) }) // 响应 + c.regMsg(TryEnterHomeReq, func() any { return new(proto.TryEnterHomeReq) }) // 请求 + c.regMsg(TryEnterHomeRsp, func() any { return new(proto.TryEnterHomeRsp) }) // 响应 + c.regMsg(HomeGetArrangementInfoReq, func() any { return new(proto.HomeGetArrangementInfoReq) }) // 请求 + c.regMsg(HomeGetArrangementInfoRsp, func() any { return new(proto.HomeGetArrangementInfoRsp) }) // 响应 + c.regMsg(HomeSceneInitFinishReq, func() any { return new(proto.HomeSceneInitFinishReq) }) // 请求 + c.regMsg(HomeSceneInitFinishRsp, func() any { return new(proto.HomeSceneInitFinishRsp) }) // 响应 + c.regMsg(HomeGetBlueprintSlotInfoReq, func() any { return new(proto.HomeGetBlueprintSlotInfoReq) }) // 请求 + c.regMsg(HomeGetBlueprintSlotInfoRsp, func() any { return new(proto.HomeGetBlueprintSlotInfoRsp) }) // 响应 + c.regMsg(HomeChangeEditModeReq, func() any { return new(proto.HomeChangeEditModeReq) }) // 请求 + c.regMsg(HomeChangeEditModeRsp, func() any { return new(proto.HomeChangeEditModeRsp) }) // 响应 + c.regMsg(HomeEnterEditModeFinishReq, func() any { return new(proto.HomeEnterEditModeFinishReq) }) // 请求 + c.regMsg(HomeEnterEditModeFinishRsp, func() any { return new(proto.HomeEnterEditModeFinishRsp) }) // 响应 + c.regMsg(HomeUpdateArrangementInfoReq, func() any { return new(proto.HomeUpdateArrangementInfoReq) }) // 请求 + c.regMsg(HomeUpdateArrangementInfoRsp, func() any { return new(proto.HomeUpdateArrangementInfoRsp) }) // 响应 } func (c *CmdProtoMap) regMsg(cmdId uint16, protoObjNewFunc func() any) {