修复AOI的BUG问题

This commit is contained in:
flswld
2023-04-14 13:34:47 +08:00
parent e7c5723f98
commit ae5f2809bf
9 changed files with 74 additions and 83 deletions

View File

@@ -491,10 +491,21 @@ func (g *Game) ReLoginPlayer(userId uint32, isQuitMp bool) {
g.SendMsg(cmd.ClientReconnectNotify, userId, 0, &proto.ClientReconnectNotify{
Reason: reason,
})
player := USER_MANAGER.GetOnlineUser(userId)
if player == nil {
return
}
player.NetFreeze = true
}
func (g *Game) LogoutPlayer(userId uint32) {
g.SendMsg(cmd.PlayerLogoutNotify, userId, 0, &proto.PlayerLogoutNotify{})
player := USER_MANAGER.GetOnlineUser(userId)
if player == nil {
return
}
// 冻结掉服务器对该玩家的下行 避免大量发包对整个系统造成压力
player.NetFreeze = true
}
func (g *Game) KickPlayer(userId uint32, reason uint32) {
@@ -510,4 +521,5 @@ func (g *Game) KickPlayer(userId uint32, reason uint32) {
KickReason: reason,
},
})
player.NetFreeze = true
}

View File

@@ -86,7 +86,7 @@ func (g *GMCmd) GMAddUserFlycloak(userId, flycloakId uint32) {
// GMAddUserAllItem 给予玩家所有物品
func (g *GMCmd) GMAddUserAllItem(userId, itemCount uint32) {
g.GMHWOptLogoutPlayer(userId)
GAME.LogoutPlayer(userId)
itemList := make([]*ChangeItem, 0)
for itemId := range GAME.GetAllItemDataConfig() {
itemList = append(itemList, &ChangeItem{
@@ -106,7 +106,7 @@ func (g *GMCmd) GMAddUserAllWeapon(userId, itemCount uint32) {
// GMAddUserAllReliquary 给予玩家所有圣遗物
func (g *GMCmd) GMAddUserAllReliquary(userId, itemCount uint32) {
g.GMHWOptLogoutPlayer(userId)
GAME.LogoutPlayer(userId)
for itemId := range GAME.GetAllReliquaryDataConfig() {
g.GMAddUserReliquary(userId, uint32(itemId), itemCount)
}
@@ -135,7 +135,7 @@ func (g *GMCmd) GMAddUserAllFlycloak(userId uint32) {
// GMAddUserAllEvery 给予玩家所有内容
func (g *GMCmd) GMAddUserAllEvery(userId, itemCount uint32) {
g.GMHWOptLogoutPlayer(userId)
GAME.LogoutPlayer(userId)
// 给予玩家所有物品
g.GMAddUserAllItem(userId, itemCount)
// 给予玩家所有武器
@@ -150,18 +150,6 @@ func (g *GMCmd) GMAddUserAllEvery(userId, itemCount uint32) {
g.GMAddUserAllFlycloak(userId)
}
// GMHWOptLogoutPlayer GM重量级操作主动下线玩家
func (g *GMCmd) GMHWOptLogoutPlayer(userId uint32) {
GAME.LogoutPlayer(userId)
player := USER_MANAGER.GetOnlineUser(userId)
if player == nil {
logger.Error("player is nil, uid: %v", userId)
return
}
// 冻结掉服务器对该玩家的下行 避免大量发包对整个系统造成压力
player.NetFreeze = true
}
// GMAddQuest 添加任务
func (g *GMCmd) GMAddQuest(userId uint32, questId uint32) {
player := USER_MANAGER.GetOnlineUser(userId)

View File

@@ -2,6 +2,7 @@ package game
import (
"strings"
"time"
"hk4e/common/constant"
"hk4e/gdconf"
@@ -154,16 +155,13 @@ func (g *Game) CombatInvocationsNotify(player *model.Player, payloadMsg pb.Messa
// 玩家实体在移动
g.SceneBlockAoiPlayerMove(player, world, scene, player.Pos,
&model.Vector{X: float64(motionInfo.Pos.X), Y: float64(motionInfo.Pos.Y), Z: float64(motionInfo.Pos.Z)},
sceneEntity.GetId(),
)
if WORLD_MANAGER.IsBigWorld(world) {
g.BigWorldAoiPlayerMove(player, world, scene, player.Pos,
&model.Vector{X: float64(motionInfo.Pos.X), Y: float64(motionInfo.Pos.Y), Z: float64(motionInfo.Pos.Z)},
)
}
// 场景区域触发器检测
g.SceneRegionTriggerCheck(player, player.Pos,
&model.Vector{X: float64(motionInfo.Pos.X), Y: float64(motionInfo.Pos.Y), Z: float64(motionInfo.Pos.Z)},
sceneEntity.GetId())
// 更新玩家的位置信息
player.Pos.X, player.Pos.Y, player.Pos.Z = float64(motionInfo.Pos.X), float64(motionInfo.Pos.Y), float64(motionInfo.Pos.Z)
player.Rot.X, player.Rot.Y, player.Rot.Z = float64(motionInfo.Rot.X), float64(motionInfo.Rot.Y), float64(motionInfo.Rot.Z)
@@ -185,7 +183,7 @@ func (g *Game) CombatInvocationsNotify(player *model.Player, payloadMsg pb.Messa
// 处理耐力消耗
g.ImmediateStamina(player, motionInfo.State)
} else {
// 非玩家实体在移动
// 其他实体在移动
// 更新场景实体的位置信息
pos := sceneEntity.GetPos()
pos.X, pos.Y, pos.Z = float64(motionInfo.Pos.X), float64(motionInfo.Pos.Y), float64(motionInfo.Pos.Z)
@@ -231,7 +229,13 @@ func (g *Game) CombatInvocationsNotify(player *model.Player, payloadMsg pb.Messa
}
}
func (g *Game) SceneBlockAoiPlayerMove(player *model.Player, world *World, scene *Scene, oldPos *model.Vector, newPos *model.Vector) {
func (g *Game) SceneBlockAoiPlayerMove(player *model.Player, world *World, scene *Scene, oldPos *model.Vector, newPos *model.Vector, entityId uint32) {
// 服务器处理玩家移动场景区块aoi事件频率限制
now := uint64(time.Now().UnixMilli())
if now-player.LastSceneBlockAoiMoveTime < 200 {
return
}
player.LastSceneBlockAoiMoveTime = now
sceneBlockAoiMap := WORLD_MANAGER.GetSceneBlockAoiMap()
aoiManager, exist := sceneBlockAoiMap[player.SceneId]
if !exist {
@@ -304,6 +308,8 @@ func (g *Game) SceneBlockAoiPlayerMove(player *model.Player, world *World, scene
if len(addEntityIdList) > 0 {
g.AddSceneEntityNotify(player, proto.VisionType_VISION_MEET, addEntityIdList, false, false)
}
// 场景区域触发器检测
g.SceneRegionTriggerCheck(player, oldPos, newPos, entityId)
}
func (g *Game) BigWorldAoiPlayerMove(player *model.Player, world *World, scene *Scene, oldPos *model.Vector, newPos *model.Vector) {
@@ -346,10 +352,10 @@ func (g *Game) BigWorldAoiPlayerMove(player *model.Player, world *World, scene *
}
activeAvatarId := world.GetPlayerActiveAvatarId(player)
activeWorldAvatar := world.GetPlayerWorldAvatar(player, activeAvatarId)
// 老格子移除玩家
bigWorldAoi.RemoveObjectFromGrid(int64(player.PlayerID), oldGid)
// 处理消失的格子
for _, delGridId := range delGridIdList {
// 老格子移除玩家
bigWorldAoi.RemoveObjectFromGrid(int64(player.PlayerID), delGridId)
// 通知自己 老格子里的其它玩家消失
oldOtherWorldAvatarMap := bigWorldAoi.GetObjectListByGid(delGridId)
delEntityIdList := make([]uint32, 0)
@@ -392,9 +398,9 @@ func (g *Game) BigWorldAoiPlayerMove(player *model.Player, world *World, scene *
sceneEntityInfoAvatar := g.PacketSceneEntityInfoAvatar(scene, player, world.GetPlayerActiveAvatarId(player))
g.AddSceneEntityNotifyToPlayer(otherPlayer, proto.VisionType_VISION_MEET, []*proto.SceneEntityInfo{sceneEntityInfoAvatar})
}
// 新格子添加玩家
bigWorldAoi.AddObjectToGrid(int64(player.PlayerID), activeWorldAvatar, addGridId)
}
// 新格子添加玩家
bigWorldAoi.AddObjectToGrid(int64(player.PlayerID), activeWorldAvatar, newGid)
}
}

View File

@@ -157,9 +157,6 @@ func (g *Game) OnLogin(userId uint32, clientSeq uint32, gateAppId string, player
IsOnline: true,
},
})
if userId < PlayerBaseUid {
return
}
atomic.AddInt32(&ONLINE_PLAYER_NUM, 1)
SELF = nil
@@ -197,30 +194,19 @@ func (g *Game) CreatePlayer(userId uint32) *model.Player {
player.PropertiesMap[constant.PLAYER_PROP_PLAYER_MP_SETTING_TYPE] = 2
player.PropertiesMap[constant.PLAYER_PROP_IS_MP_MODE_AVAILABLE] = 1
player.SafePos = new(model.Vector)
player.Pos = new(model.Vector)
player.Rot = new(model.Vector)
sceneLuaConfig := gdconf.GetSceneLuaConfigById(int32(player.SceneId))
if sceneLuaConfig == nil {
if sceneLuaConfig != nil {
bornPos := sceneLuaConfig.SceneConfig.BornPos
bornRot := sceneLuaConfig.SceneConfig.BornRot
player.SafePos = &model.Vector{X: float64(bornPos.X), Y: float64(bornPos.Y), Z: float64(bornPos.Z)}
player.Pos = &model.Vector{X: float64(bornPos.X), Y: float64(bornPos.Y), Z: float64(bornPos.Z)}
player.Rot = &model.Vector{X: float64(bornRot.X), Y: float64(bornRot.Y), Z: float64(bornRot.Z)}
} else {
logger.Error("get scene lua config is nil, sceneId: %v, uid: %v", player.SceneId, player.PlayerID)
return player
player.SafePos = &model.Vector{X: 2747, Y: 194, Z: -1719}
player.Pos = &model.Vector{X: 2747, Y: 194, Z: -1719}
player.Rot = &model.Vector{X: 0, Y: 307, Z: 0}
}
player.SafePos = &model.Vector{
X: float64(sceneLuaConfig.SceneConfig.BornPos.X),
Y: float64(sceneLuaConfig.SceneConfig.BornPos.Y),
Z: float64(sceneLuaConfig.SceneConfig.BornPos.Z),
}
player.Pos = &model.Vector{
X: float64(sceneLuaConfig.SceneConfig.BornPos.X),
Y: float64(sceneLuaConfig.SceneConfig.BornPos.Y),
Z: float64(sceneLuaConfig.SceneConfig.BornPos.Z),
}
player.Rot = &model.Vector{
X: float64(sceneLuaConfig.SceneConfig.BornRot.X),
Y: float64(sceneLuaConfig.SceneConfig.BornRot.Y),
Z: float64(sceneLuaConfig.SceneConfig.BornRot.Z),
}
return player
}

View File

@@ -346,7 +346,7 @@ func (g *Game) HostEnterMpWorld(hostPlayer *model.Player) {
scene := world.GetSceneById(hostPlayer.SceneId)
entityIdList := make([]uint32, 0)
for _, entity := range scene.GetAllEntity() {
for _, entity := range g.GetVisionEntity(scene, hostPlayer.Pos) {
entityIdList = append(entityIdList, entity.GetId())
}
g.RemoveSceneEntityNotifyToPlayer(hostPlayer, proto.VisionType_VISION_MISS, entityIdList)
@@ -396,7 +396,7 @@ func (g *Game) UserWorldRemovePlayer(world *World, player *model.Player) {
scene := world.GetSceneById(player.SceneId)
entityIdList := make([]uint32, 0)
for _, entity := range scene.GetAllEntity() {
for _, entity := range g.GetVisionEntity(scene, player.Pos) {
entityIdList = append(entityIdList, entity.GetId())
}
g.RemoveSceneEntityNotifyToPlayer(player, proto.VisionType_VISION_MISS, entityIdList)

View File

@@ -438,9 +438,8 @@ func (g *Game) AddSceneEntityNotify(player *model.Player, visionType proto.Visio
}
entityList := make([]*proto.SceneEntityInfo, 0)
for _, entityId := range entityIdList[begin:end] {
entityMap := scene.GetAllEntity()
entity, exist := entityMap[entityId]
if !exist {
entity := scene.GetEntity(entityId)
if entity == nil {
logger.Error("get entity is nil, entityId: %v", entityId)
continue
}

View File

@@ -56,30 +56,31 @@ type Player struct {
DbQuest *DbQuest // 任务
DbWorld *DbWorld // 大世界
// 在线数据 请随意 记得加忽略字段的tag
LastSaveTime uint32 `bson:"-" msgpack:"-"` // 上一次存档保存时间
DbState int `bson:"-" msgpack:"-"` // 数据库存档状态
WorldId uint32 `bson:"-" msgpack:"-"` // 所在的世界id
GameObjectGuidCounter uint64 `bson:"-" msgpack:"-"` // 游戏对象guid计数器
LastKeepaliveTime uint32 `bson:"-" msgpack:"-"` // 上一次保持活跃时间
ClientTime uint32 `bson:"-" msgpack:"-"` // 客户端本地时钟
ClientRTT uint32 `bson:"-" msgpack:"-"` // 客户端网络往返时延
GameObjectGuidMap map[uint64]GameObject `bson:"-" msgpack:"-"` // 游戏对象guid映射表
Online bool `bson:"-" msgpack:"-"` // 在线状态
Pause bool `bson:"-" msgpack:"-"` // 暂停状态
SceneJump bool `bson:"-" msgpack:"-"` // 是否场景切换
SceneLoadState int `bson:"-" msgpack:"-"` // 场景加载状态
CoopApplyMap map[uint32]int64 `bson:"-" msgpack:"-"` // 敲门申请的玩家uid及时间
StaminaInfo *StaminaInfo `bson:"-" msgpack:"-"` // 耐力在线数据
VehicleInfo *VehicleInfo `bson:"-" msgpack:"-"` // 载具在线数据
ClientSeq uint32 `bson:"-" msgpack:"-"` // 客户端发包请求的序号
CombatInvokeHandler *InvokeHandler[proto.CombatInvokeEntry] `bson:"-" msgpack:"-"` // combat转发器
AbilityInvokeHandler *InvokeHandler[proto.AbilityInvokeEntry] `bson:"-" msgpack:"-"` // ability转发器
GateAppId string `bson:"-" msgpack:"-"` // 网关服务器的appid
AnticheatAppId string `bson:"-" msgpack:"-"` // 反作弊服务器的appid
GCGCurGameGuid uint32 `bson:"-" msgpack:"-"` // GCG玩家所在的游戏guid
GCGInfo *GCGInfo `bson:"-" msgpack:"-"` // 七圣召唤信息
XLuaDebug bool `bson:"-" msgpack:"-"` // 是否开启客户端XLUA调试
NetFreeze bool `bson:"-" msgpack:"-"` // 客户端网络上下行冻结状态
LastSaveTime uint32 `bson:"-" msgpack:"-"` // 上一次存档保存时间
DbState int `bson:"-" msgpack:"-"` // 数据库存档状态
WorldId uint32 `bson:"-" msgpack:"-"` // 所在的世界id
GameObjectGuidCounter uint64 `bson:"-" msgpack:"-"` // 游戏对象guid计数器
LastKeepaliveTime uint32 `bson:"-" msgpack:"-"` // 上一次保持活跃时间
ClientTime uint32 `bson:"-" msgpack:"-"` // 客户端本地时钟
ClientRTT uint32 `bson:"-" msgpack:"-"` // 客户端网络往返时延
GameObjectGuidMap map[uint64]GameObject `bson:"-" msgpack:"-"` // 游戏对象guid映射表
Online bool `bson:"-" msgpack:"-"` // 在线状态
Pause bool `bson:"-" msgpack:"-"` // 暂停状态
SceneJump bool `bson:"-" msgpack:"-"` // 是否场景切换
SceneLoadState int `bson:"-" msgpack:"-"` // 场景加载状态
CoopApplyMap map[uint32]int64 `bson:"-" msgpack:"-"` // 敲门申请的玩家uid及时间
StaminaInfo *StaminaInfo `bson:"-" msgpack:"-"` // 耐力在线数据
VehicleInfo *VehicleInfo `bson:"-" msgpack:"-"` // 载具在线数据
ClientSeq uint32 `bson:"-" msgpack:"-"` // 客户端发包请求的序号
CombatInvokeHandler *InvokeHandler[proto.CombatInvokeEntry] `bson:"-" msgpack:"-"` // combat转发器
AbilityInvokeHandler *InvokeHandler[proto.AbilityInvokeEntry] `bson:"-" msgpack:"-"` // ability转发器
GateAppId string `bson:"-" msgpack:"-"` // 网关服务器的appid
AnticheatAppId string `bson:"-" msgpack:"-"` // 反作弊服务器的appid
GCGCurGameGuid uint32 `bson:"-" msgpack:"-"` // GCG玩家所在的游戏guid
GCGInfo *GCGInfo `bson:"-" msgpack:"-"` // 七圣召唤信息
XLuaDebug bool `bson:"-" msgpack:"-"` // 是否开启客户端XLUA调试
NetFreeze bool `bson:"-" msgpack:"-"` // 客户端网络上下行冻结状态
LastSceneBlockAoiMoveTime uint64 `bson:"-" msgpack:"-"` // 上一次移动处理场景区块aoi的时间
// 特殊数据
ChatMsgMap map[uint32][]*ChatMsg `bson:"-" msgpack:"-"` // 聊天信息 数据量偏大 只从db读写 不保存到redis
}