diff --git a/common/mq/nats.go b/common/mq/nats.go index d785938e..1cd449f2 100644 --- a/common/mq/nats.go +++ b/common/mq/nats.go @@ -399,7 +399,7 @@ func (m *MessageQueue) gateTcpMqConn(gateServerConnAddrMap map[string]bool) { } func (m *MessageQueue) gateTcpMqRecvHandle(inst *GateTcpMqInst) { - dataBuf := make([]byte, 0, 1500) + dataBuf := make([]byte, 0, 1024) recvBuf := make([]byte, 1024*1024) for { recvLen, err := inst.conn.Read(recvBuf) @@ -421,11 +421,10 @@ func (m *MessageQueue) gateTcpMqRecvHandleLoop(data []byte, dataBuf *[]byte) { if len(*dataBuf) != 0 { // 取出之前的缓冲区数据 data = append(*dataBuf, data...) - *dataBuf = make([]byte, 0, 1500) + *dataBuf = make([]byte, 0, 1024) } // 长度太短 if len(data) < 4 { - logger.Debug("packet len less 4 byte, data: %v", data) *dataBuf = append(*dataBuf, data...) return } diff --git a/gdconf/scene_lua_config.go b/gdconf/scene_lua_config.go index 25cc085c..a2780f90 100644 --- a/gdconf/scene_lua_config.go +++ b/gdconf/scene_lua_config.go @@ -16,8 +16,8 @@ import ( // 场景详情配置数据 const ( - SceneGroupLoaderLimit = 4 // 加载文件的并发数 此操作很耗内存 调大之前请确保你的机器内存足够 - LuaStateLruKeepNum = 100 + SceneGroupLoaderLimit = 4 // 加载文件的并发数 此操作很耗内存 调大之前请确保你的机器内存足够 + LuaStateLruKeepNum = 1000 // 内存常驻LUA虚拟机实例数量上限 ) type SceneLuaConfig struct { diff --git a/gs/game/game.go b/gs/game/game.go index 4201df0b..79bff2d3 100644 --- a/gs/game/game.go +++ b/gs/game/game.go @@ -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 } diff --git a/gs/game/game_command_gm.go b/gs/game/game_command_gm.go index 17e92db1..07ee3b00 100644 --- a/gs/game/game_command_gm.go +++ b/gs/game/game_command_gm.go @@ -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) diff --git a/gs/game/player_fight_sync.go b/gs/game/player_fight_sync.go index 6d342f7d..c1a33ed3 100644 --- a/gs/game/player_fight_sync.go +++ b/gs/game/player_fight_sync.go @@ -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) } } diff --git a/gs/game/player_login.go b/gs/game/player_login.go index 9d96ff72..80d2b9bc 100644 --- a/gs/game/player_login.go +++ b/gs/game/player_login.go @@ -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 } diff --git a/gs/game/player_multiplayer.go b/gs/game/player_multiplayer.go index 13c13a96..2458fa4c 100644 --- a/gs/game/player_multiplayer.go +++ b/gs/game/player_multiplayer.go @@ -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) diff --git a/gs/game/player_scene.go b/gs/game/player_scene.go index 26149dd7..f48f0560 100644 --- a/gs/game/player_scene.go +++ b/gs/game/player_scene.go @@ -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 } diff --git a/gs/model/player.go b/gs/model/player.go index 7e16c454..437283d4 100644 --- a/gs/model/player.go +++ b/gs/model/player.go @@ -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 }