mirror of
https://github.com/FlourishingWorld/hk4e.git
synced 2026-02-04 16:02:26 +08:00
fix panic
This commit is contained in:
15
README.md
15
README.md
@@ -4,9 +4,9 @@
|
||||
|
||||
#### 『原神』 Game Server But Golang Ver.
|
||||
|
||||
#### 代号hk4e中的hk起源于『Honkai Impact 3rd』
|
||||
#### 本项目的目标为构建一个高性能高可用的ARPG游戏服务端,并非以完整还原游戏内原本功能点为目的
|
||||
|
||||
#### 项目的客户端协议([360NENZ/teyvat-helper-hk4e-proto](https://github.com/360NENZ/teyvat-helper-hk4e-proto))、配置表([TomyJan/xudong](https://github.com/TomyJan/xudong))主要基于3.2版本修改而来,因此请尽量使用3.2版本的客户端,但不是必须的
|
||||
#### 项目的客户端协议、配置表主要基于3.2版本修改而来,因此请尽量使用3.2版本的客户端,但不是必须的
|
||||
|
||||
[3.2.0国际服客户端下载链接](https://autopatchhk.yuanshen.com/client_app/download/pc_zip/20221024103618_h2e3o3zijYKEqHnQ/GenshinImpact_3.2.0.zip)
|
||||
|
||||
@@ -16,12 +16,11 @@
|
||||
|
||||
## 特性
|
||||
|
||||
* 原生的高可用集群架构,任意节点宕机不会影响到整个系统,可大量水平扩展,支撑千万级DAU不是梦
|
||||
* 玩家级无状态游戏服务器,无锁单线程模型,开发省时省力,完善的玩家数据交换机制(内存-缓存-数据库)
|
||||
,拒绝同步阻塞的数据库访问,掌控每一纳秒的CPU时间不是梦
|
||||
* 新颖的玩家在线跨服无缝迁移功能,以多人世界之名,反复横跳于多个服务器进程之间不是梦
|
||||
* 独创的网关服务器侧客户端协议代理转换功能,拒绝因协议号消息号混淆而带来代码改动的烦恼,不同协议版本客户端同时在线联机不是梦
|
||||
* 完整的密钥交换机制实现,安全性++,拒绝一个写死的随机数种子和XOR密钥文件用到天荒地老,搭建一个属于自己的别具一格的聊天渠道不是梦
|
||||
* 原生的高可用集群架构,任意节点宕机不会影响到整个系统,可大量水平扩展
|
||||
* 玩家级无状态游戏服务器,无锁单线程模型,开发省时省力,完善的玩家数据交换机制(内存-缓存-数据库),拒绝同步阻塞的数据库访问
|
||||
* 新颖的玩家在线跨服无缝迁移功能
|
||||
* 独创的网关服务器侧客户端协议代理转换功能,拒绝因协议号消息号混淆而带来代码改动的烦恼
|
||||
* 完整的密钥交换机制实现,安全性++,拒绝一个写死的随机数种子和XOR密钥文件用到天荒地老
|
||||
|
||||
## 编译和运行环境
|
||||
|
||||
|
||||
@@ -321,6 +321,9 @@ func (g *GameManager) AoiPlayerMove(player *model.Player, oldPos *model.Vector,
|
||||
}
|
||||
// 旧有新没有的group即为消失的
|
||||
group := scene.GetGroupById(groupId)
|
||||
if group == nil {
|
||||
continue
|
||||
}
|
||||
for _, entity := range group.GetAllEntity() {
|
||||
delEntityIdList = append(delEntityIdList, entity.GetId())
|
||||
}
|
||||
|
||||
@@ -245,6 +245,7 @@ func (g *GameManager) SceneInitFinishReq(player *model.Player, payloadMsg pb.Mes
|
||||
func (g *GameManager) AddSceneGroup(scene *Scene, groupConfig *gdconf.Group) {
|
||||
initSuiteId := int(groupConfig.GroupInitConfig.Suite)
|
||||
if initSuiteId > len(groupConfig.SuiteList) {
|
||||
logger.Error("invalid init suite id: %v", initSuiteId)
|
||||
return
|
||||
}
|
||||
scene.AddGroupSuite(uint32(groupConfig.Id), uint8(initSuiteId))
|
||||
@@ -285,34 +286,41 @@ func (g *GameManager) EnterSceneDoneReq(player *model.Player, payloadMsg pb.Mess
|
||||
activeAvatarEntityId := world.GetPlayerWorldAvatarEntityId(player, activeAvatarId)
|
||||
g.AddSceneEntityNotify(player, visionType, []uint32{activeAvatarEntityId}, true, false)
|
||||
|
||||
// 加载附近的group
|
||||
aoiManager, exist := WORLD_MANAGER.GetSceneBlockAoiMap()[scene.GetId()]
|
||||
addEntityIdList := make([]uint32, 0)
|
||||
if exist {
|
||||
objectList := aoiManager.GetObjectListByPos(float32(player.Pos.X), 0.0, float32(player.Pos.Z))
|
||||
for _, groupAny := range objectList {
|
||||
group := groupAny.(*gdconf.Group)
|
||||
distance2D := math.Sqrt((player.Pos.X-float64(group.Pos.X))*(player.Pos.X-float64(group.Pos.X)) +
|
||||
(player.Pos.Z-float64(group.Pos.Z))*(player.Pos.Z-float64(group.Pos.Z)))
|
||||
groupConfig := groupAny.(*gdconf.Group)
|
||||
distance2D := math.Sqrt((player.Pos.X-float64(groupConfig.Pos.X))*(player.Pos.X-float64(groupConfig.Pos.X)) +
|
||||
(player.Pos.Z-float64(groupConfig.Pos.Z))*(player.Pos.Z-float64(groupConfig.Pos.Z)))
|
||||
if distance2D > ENTITY_LOD {
|
||||
continue
|
||||
}
|
||||
if group.DynamicLoad {
|
||||
if groupConfig.DynamicLoad {
|
||||
continue
|
||||
}
|
||||
g.AddSceneGroup(scene, group)
|
||||
g.AddSceneGroup(scene, groupConfig)
|
||||
group := scene.GetGroupById(uint32(groupConfig.Id))
|
||||
for _, entity := range group.GetAllEntity() {
|
||||
addEntityIdList = append(addEntityIdList, entity.GetId())
|
||||
}
|
||||
}
|
||||
}
|
||||
entityIdList := make([]uint32, 0)
|
||||
if player.SceneJump {
|
||||
visionType = proto.VisionType_VISION_MEET
|
||||
entityMap := scene.GetAllEntity()
|
||||
for _, entity := range entityMap {
|
||||
if entity.GetId() == activeAvatarEntityId {
|
||||
continue
|
||||
}
|
||||
entityIdList = append(entityIdList, entity.GetId())
|
||||
}
|
||||
} else {
|
||||
visionType = proto.VisionType_VISION_TRANSPORT
|
||||
}
|
||||
entityMap := scene.GetAllEntity()
|
||||
entityIdList := make([]uint32, 0)
|
||||
for _, entity := range entityMap {
|
||||
if entity.GetId() == activeAvatarEntityId {
|
||||
continue
|
||||
}
|
||||
entityIdList = append(entityIdList, entity.GetId())
|
||||
entityIdList = addEntityIdList
|
||||
}
|
||||
g.AddSceneEntityNotify(player, visionType, entityIdList, false, false)
|
||||
|
||||
|
||||
@@ -17,37 +17,11 @@ type Scene struct {
|
||||
id uint32
|
||||
world *World
|
||||
playerMap map[uint32]*model.Player
|
||||
entityMap map[uint32]*Entity
|
||||
groupMap map[uint32]*Group
|
||||
gameTime uint32 // 游戏内提瓦特大陆的时间
|
||||
createTime int64 // 场景创建时间
|
||||
meeoIndex uint32 // 客户端风元素染色同步协议的计数器
|
||||
}
|
||||
|
||||
type Group struct {
|
||||
suiteMap map[uint8]*Suite
|
||||
}
|
||||
|
||||
func (g *Group) GetAllSuite() map[uint8]*Suite {
|
||||
return g.suiteMap
|
||||
}
|
||||
|
||||
func (g *Group) GetAllEntity() map[uint32]*Entity {
|
||||
entityMap := make(map[uint32]*Entity)
|
||||
for _, suite := range g.suiteMap {
|
||||
for _, entity := range suite.entityMap {
|
||||
entityMap[entity.id] = entity
|
||||
}
|
||||
}
|
||||
return entityMap
|
||||
}
|
||||
|
||||
type Suite struct {
|
||||
entityMap map[uint32]*Entity
|
||||
}
|
||||
|
||||
func (s *Suite) GetAllEntity() map[uint32]*Entity {
|
||||
return s.entityMap
|
||||
entityMap map[uint32]*Entity // 场景中全部的实体
|
||||
groupMap map[uint32]*Group // 场景中按group->suite分类的实体
|
||||
gameTime uint32 // 游戏内提瓦特大陆的时间
|
||||
createTime int64 // 场景创建时间
|
||||
meeoIndex uint32 // 客户端风元素染色同步协议的计数器
|
||||
}
|
||||
|
||||
func (s *Scene) GetId() uint32 {
|
||||
@@ -420,6 +394,7 @@ func (s *Scene) GetEntity(entityId uint32) *Entity {
|
||||
func (s *Scene) AddGroupSuite(groupId uint32, suiteId uint8) {
|
||||
groupConfig := gdconf.GetSceneGroup(int32(groupId))
|
||||
if groupConfig == nil {
|
||||
logger.Error("get scene group config is nil, groupId: %v", groupId)
|
||||
return
|
||||
}
|
||||
suiteConfig := groupConfig.SuiteList[suiteId-1]
|
||||
@@ -429,6 +404,7 @@ func (s *Scene) AddGroupSuite(groupId uint32, suiteId uint8) {
|
||||
for _, monsterConfigId := range suiteConfig.MonsterConfigIdList {
|
||||
monster, exist := groupConfig.MonsterMap[monsterConfigId]
|
||||
if !exist {
|
||||
logger.Error("monster config not exist, monsterConfigId: %v", monsterConfigId)
|
||||
continue
|
||||
}
|
||||
entityId := s.createConfigEntity(uint32(groupConfig.Id), monster)
|
||||
@@ -438,6 +414,7 @@ func (s *Scene) AddGroupSuite(groupId uint32, suiteId uint8) {
|
||||
for _, gadgetConfigId := range suiteConfig.GadgetConfigIdList {
|
||||
gadget, exist := groupConfig.GadgetMap[gadgetConfigId]
|
||||
if !exist {
|
||||
logger.Error("gadget config not exist, gadgetConfigId: %v", gadgetConfigId)
|
||||
continue
|
||||
}
|
||||
entityId := s.createConfigEntity(uint32(groupConfig.Id), gadget)
|
||||
@@ -461,10 +438,12 @@ func (s *Scene) AddGroupSuite(groupId uint32, suiteId uint8) {
|
||||
func (s *Scene) RemoveGroupSuite(groupId uint32, suiteId uint8) {
|
||||
group := s.groupMap[groupId]
|
||||
if group == nil {
|
||||
logger.Error("group not exist, groupId: %v", groupId)
|
||||
return
|
||||
}
|
||||
suite := group.suiteMap[suiteId]
|
||||
if suite == nil {
|
||||
logger.Error("suite not exist, suiteId: %v", suiteId)
|
||||
return
|
||||
}
|
||||
for _, entity := range suite.entityMap {
|
||||
@@ -531,6 +510,7 @@ func (s *Scene) createConfigEntity(groupId uint32, entityConfig any) uint32 {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO 临时写死
|
||||
func getTempFightPropMap() map[uint32]float32 {
|
||||
fpm := map[uint32]float32{
|
||||
constant.FIGHT_PROP_CUR_HP: float32(72.91699),
|
||||
@@ -552,6 +532,40 @@ func getTempFightPropMap() map[uint32]float32 {
|
||||
return fpm
|
||||
}
|
||||
|
||||
type Group struct {
|
||||
suiteMap map[uint8]*Suite
|
||||
}
|
||||
|
||||
type Suite struct {
|
||||
entityMap map[uint32]*Entity
|
||||
}
|
||||
|
||||
func (g *Group) GetSuiteById(suiteId uint8) *Suite {
|
||||
return g.suiteMap[suiteId]
|
||||
}
|
||||
|
||||
func (g *Group) GetAllSuite() map[uint8]*Suite {
|
||||
return g.suiteMap
|
||||
}
|
||||
|
||||
func (g *Group) GetAllEntity() map[uint32]*Entity {
|
||||
entityMap := make(map[uint32]*Entity)
|
||||
for _, suite := range g.suiteMap {
|
||||
for _, entity := range suite.entityMap {
|
||||
entityMap[entity.id] = entity
|
||||
}
|
||||
}
|
||||
return entityMap
|
||||
}
|
||||
|
||||
func (s *Suite) GetEntityById(entityId uint32) *Entity {
|
||||
return s.entityMap[entityId]
|
||||
}
|
||||
|
||||
func (s *Suite) GetAllEntity() map[uint32]*Entity {
|
||||
return s.entityMap
|
||||
}
|
||||
|
||||
// Entity 场景实体数据结构
|
||||
type Entity struct {
|
||||
id uint32 // 实体id
|
||||
|
||||
Reference in New Issue
Block a user