mirror of
https://github.com/FlourishingWorld/hk4e.git
synced 2026-03-01 00:35:36 +08:00
场景group分suite加载、读取掉落表
This commit is contained in:
@@ -5,9 +5,9 @@ import (
|
||||
"sort"
|
||||
"strconv"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"hk4e/common/config"
|
||||
"hk4e/pkg/logger"
|
||||
|
||||
lua "github.com/yuin/gopher-lua"
|
||||
@@ -19,8 +19,6 @@ const (
|
||||
SceneGroupLoaderLimit = 4 // 加载文件的并发数 此操作很耗内存 调大之前请确保你的机器内存足够
|
||||
)
|
||||
|
||||
var OBJECT_ID_COUNTER uint64
|
||||
|
||||
type SceneLuaConfig struct {
|
||||
Id int32
|
||||
SceneConfig *SceneConfig // 地图配置
|
||||
@@ -55,77 +53,27 @@ type BlockRange struct {
|
||||
}
|
||||
|
||||
type Group struct {
|
||||
Id int32 `json:"id"`
|
||||
RefreshId int32 `json:"refresh_id"`
|
||||
Area int32 `json:"area"`
|
||||
Pos *Vector `json:"pos"`
|
||||
DynamicLoad bool `json:"dynamic_load"`
|
||||
IsReplaceable *Replaceable `json:"is_replaceable"`
|
||||
MonsterList []*Monster `json:"monsters"` // 怪物
|
||||
NpcList []*Npc `json:"npcs"` // NPC
|
||||
GadgetList []*Gadget `json:"gadgets"` // 物件
|
||||
RegionList []*Region `json:"regions"`
|
||||
TriggerList []*Trigger `json:"triggers"`
|
||||
LuaStr string `json:"-"`
|
||||
LuaState *lua.LState `json:"-"`
|
||||
Id int32 `json:"id"`
|
||||
RefreshId int32 `json:"refresh_id"`
|
||||
Area int32 `json:"area"`
|
||||
Pos *Vector `json:"pos"`
|
||||
DynamicLoad bool `json:"dynamic_load"`
|
||||
IsReplaceable *Replaceable `json:"is_replaceable"`
|
||||
MonsterMap map[int32]*Monster `json:"-"` // 怪物
|
||||
NpcMap map[int32]*Npc `json:"-"` // NPC
|
||||
GadgetMap map[int32]*Gadget `json:"-"` // 物件
|
||||
RegionMap map[int32]*Region `json:"-"` // 区域
|
||||
TriggerMap map[string]*Trigger `json:"-"` // 触发器
|
||||
GroupInitConfig *GroupInitConfig `json:"-"` // 初始化配置
|
||||
SuiteList []*Suite `json:"-"` // 小组配置
|
||||
LuaStr string `json:"-"` // LUA原始字符串缓存
|
||||
LuaState *lua.LState `json:"-"` // LUA虚拟机实例
|
||||
}
|
||||
|
||||
const (
|
||||
LuaStateLruKeepNum = 1000
|
||||
)
|
||||
|
||||
type LuaStateLru struct {
|
||||
GroupId int32
|
||||
AccessTime int64
|
||||
}
|
||||
|
||||
type LuaStateLruList []*LuaStateLru
|
||||
|
||||
func (l LuaStateLruList) Len() int {
|
||||
return len(l)
|
||||
}
|
||||
|
||||
func (l LuaStateLruList) Less(i, j int) bool {
|
||||
return l[i].AccessTime < l[j].AccessTime
|
||||
}
|
||||
|
||||
func (l LuaStateLruList) Swap(i, j int) {
|
||||
l[i], l[j] = l[j], l[i]
|
||||
}
|
||||
|
||||
func LuaStateLruRemove() {
|
||||
removeNum := len(CONF.LuaStateLruMap) - LuaStateLruKeepNum
|
||||
if removeNum <= 0 {
|
||||
return
|
||||
}
|
||||
luaStateLruList := make(LuaStateLruList, 0)
|
||||
for _, luaStateLru := range CONF.LuaStateLruMap {
|
||||
luaStateLruList = append(luaStateLruList, luaStateLru)
|
||||
}
|
||||
sort.Stable(luaStateLruList)
|
||||
for i := 0; i < removeNum; i++ {
|
||||
luaStateLru := luaStateLruList[i]
|
||||
group := GetSceneGroup(luaStateLru.GroupId)
|
||||
group.LuaState = nil
|
||||
delete(CONF.LuaStateLruMap, luaStateLru.GroupId)
|
||||
}
|
||||
logger.Info("lua state lru remove finish, remove num: %v", removeNum)
|
||||
}
|
||||
|
||||
func (g *Group) GetLuaState() *lua.LState {
|
||||
CONF.LuaStateLruMap[g.Id] = &LuaStateLru{
|
||||
GroupId: g.Id,
|
||||
AccessTime: time.Now().UnixMilli(),
|
||||
}
|
||||
if g.LuaState == nil {
|
||||
g.LuaState = newLuaState(g.LuaStr)
|
||||
scriptLib := g.LuaState.NewTable()
|
||||
g.LuaState.SetGlobal("ScriptLib", scriptLib)
|
||||
for _, scriptLibFunc := range SCRIPT_LIB_FUNC_LIST {
|
||||
g.LuaState.SetField(scriptLib, scriptLibFunc.fnName, g.LuaState.NewFunction(scriptLibFunc.fn))
|
||||
}
|
||||
}
|
||||
return g.LuaState
|
||||
type GroupInitConfig struct {
|
||||
Suite int32 `json:"suite"`
|
||||
EndSuite int32 `json:"end_suite"`
|
||||
RandSuite bool `json:"rand_suite"`
|
||||
}
|
||||
|
||||
type Replaceable struct {
|
||||
@@ -141,7 +89,7 @@ type Monster struct {
|
||||
Rot *Vector `json:"rot"`
|
||||
Level int32 `json:"level"`
|
||||
AreaId int32 `json:"area_id"`
|
||||
ObjectId uint64 `json:"-"`
|
||||
DropTag string `json:"drop_tag"` // 关联MonsterDropData表
|
||||
}
|
||||
|
||||
type Npc struct {
|
||||
@@ -150,18 +98,19 @@ type Npc struct {
|
||||
Pos *Vector `json:"pos"`
|
||||
Rot *Vector `json:"rot"`
|
||||
AreaId int32 `json:"area_id"`
|
||||
ObjectId uint64 `json:"-"`
|
||||
}
|
||||
|
||||
type Gadget struct {
|
||||
ConfigId int32 `json:"config_id"`
|
||||
GadgetId int32 `json:"gadget_id"`
|
||||
Pos *Vector `json:"pos"`
|
||||
Rot *Vector `json:"rot"`
|
||||
Level int32 `json:"level"`
|
||||
AreaId int32 `json:"area_id"`
|
||||
PointType int32 `json:"point_type"` // 关联GatherData表
|
||||
ObjectId uint64 `json:"-"`
|
||||
ConfigId int32 `json:"config_id"`
|
||||
GadgetId int32 `json:"gadget_id"`
|
||||
Pos *Vector `json:"pos"`
|
||||
Rot *Vector `json:"rot"`
|
||||
Level int32 `json:"level"`
|
||||
AreaId int32 `json:"area_id"`
|
||||
PointType int32 `json:"point_type"` // 关联GatherData表
|
||||
State int32 `json:"state"`
|
||||
VisionLevel int32 `json:"vision_level"`
|
||||
DropTag string `json:"drop_tag"`
|
||||
}
|
||||
|
||||
type Region struct {
|
||||
@@ -185,6 +134,22 @@ type Trigger struct {
|
||||
TriggerCount int32 `json:"trigger_count"`
|
||||
}
|
||||
|
||||
type SuiteLuaTable struct {
|
||||
MonsterConfigIdList any `json:"monsters"` // 怪物
|
||||
GadgetConfigIdList any `json:"gadgets"` // 物件
|
||||
RegionConfigIdList any `json:"regions"` // 区域
|
||||
TriggerNameList any `json:"triggers"` // 触发器
|
||||
RandWeight int32 `json:"rand_weight"`
|
||||
}
|
||||
|
||||
type Suite struct {
|
||||
MonsterConfigIdList []int32
|
||||
GadgetConfigIdList []int32
|
||||
RegionConfigIdList []int32
|
||||
TriggerNameList []string
|
||||
RandWeight int32
|
||||
}
|
||||
|
||||
func (g *GameDataConfig) loadGroup(group *Group, block *Block, sceneId int32, blockId int32) {
|
||||
sceneLuaPrefix := g.luaPrefix + "scene/"
|
||||
sceneIdStr := strconv.Itoa(int(sceneId))
|
||||
@@ -197,55 +162,120 @@ func (g *GameDataConfig) loadGroup(group *Group, block *Block, sceneId int32, bl
|
||||
}
|
||||
group.LuaStr = string(groupLuaData)
|
||||
luaState := newLuaState(group.LuaStr)
|
||||
// init_config
|
||||
group.GroupInitConfig = new(GroupInitConfig)
|
||||
ok := getSceneLuaConfigTable[*GroupInitConfig](luaState, "init_config", group.GroupInitConfig)
|
||||
if !ok {
|
||||
logger.Error("get init_config object error, sceneId: %v, blockId: %v, groupId: %v", sceneId, blockId, groupId)
|
||||
luaState.Close()
|
||||
return
|
||||
}
|
||||
// monsters
|
||||
group.MonsterList = make([]*Monster, 0)
|
||||
ok := getSceneLuaConfigTable[*[]*Monster](luaState, "monsters", &group.MonsterList)
|
||||
monsterList := make([]*Monster, 0)
|
||||
ok = getSceneLuaConfigTable[*[]*Monster](luaState, "monsters", &monsterList)
|
||||
if !ok {
|
||||
logger.Error("get monsters object error, sceneId: %v, blockId: %v, groupId: %v", sceneId, blockId, groupId)
|
||||
luaState.Close()
|
||||
return
|
||||
}
|
||||
for _, monster := range group.MonsterList {
|
||||
monster.ObjectId = atomic.AddUint64(&OBJECT_ID_COUNTER, 1)
|
||||
group.MonsterMap = make(map[int32]*Monster)
|
||||
for _, monster := range monsterList {
|
||||
group.MonsterMap[monster.ConfigId] = monster
|
||||
}
|
||||
// npcs
|
||||
group.NpcList = make([]*Npc, 0)
|
||||
ok = getSceneLuaConfigTable[*[]*Npc](luaState, "npcs", &group.NpcList)
|
||||
npcList := make([]*Npc, 0)
|
||||
ok = getSceneLuaConfigTable[*[]*Npc](luaState, "npcs", &npcList)
|
||||
if !ok {
|
||||
logger.Error("get npcs object error, sceneId: %v, blockId: %v, groupId: %v", sceneId, blockId, groupId)
|
||||
luaState.Close()
|
||||
return
|
||||
}
|
||||
for _, npc := range group.NpcList {
|
||||
npc.ObjectId = atomic.AddUint64(&OBJECT_ID_COUNTER, 1)
|
||||
group.NpcMap = make(map[int32]*Npc)
|
||||
for _, npc := range npcList {
|
||||
group.NpcMap[npc.ConfigId] = npc
|
||||
}
|
||||
// gadgets
|
||||
group.GadgetList = make([]*Gadget, 0)
|
||||
ok = getSceneLuaConfigTable[*[]*Gadget](luaState, "gadgets", &group.GadgetList)
|
||||
gadgetList := make([]*Gadget, 0)
|
||||
ok = getSceneLuaConfigTable[*[]*Gadget](luaState, "gadgets", &gadgetList)
|
||||
if !ok {
|
||||
logger.Error("get gadgets object error, sceneId: %v, blockId: %v, groupId: %v", sceneId, blockId, groupId)
|
||||
luaState.Close()
|
||||
return
|
||||
}
|
||||
for _, gadget := range group.GadgetList {
|
||||
gadget.ObjectId = atomic.AddUint64(&OBJECT_ID_COUNTER, 1)
|
||||
group.GadgetMap = make(map[int32]*Gadget)
|
||||
for _, gadget := range gadgetList {
|
||||
group.GadgetMap[gadget.ConfigId] = gadget
|
||||
}
|
||||
// regions
|
||||
group.RegionList = make([]*Region, 0)
|
||||
ok = getSceneLuaConfigTable[*[]*Region](luaState, "regions", &group.RegionList)
|
||||
regionList := make([]*Region, 0)
|
||||
ok = getSceneLuaConfigTable[*[]*Region](luaState, "regions", ®ionList)
|
||||
if !ok {
|
||||
logger.Error("get regions object error, sceneId: %v, blockId: %v, groupId: %v", sceneId, blockId, groupId)
|
||||
luaState.Close()
|
||||
return
|
||||
}
|
||||
group.RegionMap = make(map[int32]*Region)
|
||||
for _, region := range regionList {
|
||||
group.RegionMap[region.ConfigId] = region
|
||||
}
|
||||
// triggers
|
||||
group.TriggerList = make([]*Trigger, 0)
|
||||
ok = getSceneLuaConfigTable[*[]*Trigger](luaState, "triggers", &group.TriggerList)
|
||||
triggerList := make([]*Trigger, 0)
|
||||
ok = getSceneLuaConfigTable[*[]*Trigger](luaState, "triggers", &triggerList)
|
||||
if !ok {
|
||||
logger.Error("get triggers object error, sceneId: %v, blockId: %v, groupId: %v", sceneId, blockId, groupId)
|
||||
luaState.Close()
|
||||
return
|
||||
}
|
||||
group.TriggerMap = make(map[string]*Trigger)
|
||||
for _, trigger := range triggerList {
|
||||
group.TriggerMap[trigger.Name] = trigger
|
||||
}
|
||||
// suites
|
||||
suiteLuaTableList := make([]*SuiteLuaTable, 0)
|
||||
ok = getSceneLuaConfigTable[*[]*SuiteLuaTable](luaState, "suites", &suiteLuaTableList)
|
||||
if !ok {
|
||||
logger.Error("get suites object error, sceneId: %v, blockId: %v, groupId: %v", sceneId, blockId, groupId)
|
||||
luaState.Close()
|
||||
return
|
||||
}
|
||||
if len(suiteLuaTableList) == 0 {
|
||||
logger.Info("get suites object is nil, sceneId: %v, blockId: %v, groupId: %v", sceneId, blockId, groupId)
|
||||
}
|
||||
group.SuiteList = make([]*Suite, 0)
|
||||
for _, suiteLuaTable := range suiteLuaTableList {
|
||||
suite := &Suite{
|
||||
MonsterConfigIdList: make([]int32, 0),
|
||||
GadgetConfigIdList: make([]int32, 0),
|
||||
RegionConfigIdList: make([]int32, 0),
|
||||
TriggerNameList: make([]string, 0),
|
||||
RandWeight: suiteLuaTable.RandWeight,
|
||||
}
|
||||
idAnyList, ok := suiteLuaTable.MonsterConfigIdList.([]any)
|
||||
if ok {
|
||||
for _, idAny := range idAnyList {
|
||||
suite.MonsterConfigIdList = append(suite.MonsterConfigIdList, int32(idAny.(float64)))
|
||||
}
|
||||
}
|
||||
idAnyList, ok = suiteLuaTable.GadgetConfigIdList.([]any)
|
||||
if ok {
|
||||
for _, idAny := range idAnyList {
|
||||
suite.GadgetConfigIdList = append(suite.GadgetConfigIdList, int32(idAny.(float64)))
|
||||
}
|
||||
}
|
||||
idAnyList, ok = suiteLuaTable.RegionConfigIdList.([]any)
|
||||
if ok {
|
||||
for _, idAny := range idAnyList {
|
||||
suite.RegionConfigIdList = append(suite.RegionConfigIdList, int32(idAny.(float64)))
|
||||
}
|
||||
}
|
||||
nameAnyList, ok := suiteLuaTable.TriggerNameList.([]any)
|
||||
if ok {
|
||||
for _, nameAny := range nameAnyList {
|
||||
suite.TriggerNameList = append(suite.TriggerNameList, nameAny.(string))
|
||||
}
|
||||
}
|
||||
group.SuiteList = append(group.SuiteList, suite)
|
||||
}
|
||||
luaState.Close()
|
||||
block.groupMapLoadLock.Lock()
|
||||
block.GroupMap[group.Id] = group
|
||||
@@ -253,10 +283,12 @@ func (g *GameDataConfig) loadGroup(group *Group, block *Block, sceneId int32, bl
|
||||
}
|
||||
|
||||
func (g *GameDataConfig) loadSceneLuaConfig() {
|
||||
OBJECT_ID_COUNTER = 0
|
||||
g.SceneLuaConfigMap = make(map[int32]*SceneLuaConfig)
|
||||
g.GroupMap = make(map[int32]*Group)
|
||||
g.LuaStateLruMap = make(map[int32]*LuaStateLru)
|
||||
if !config.GetConfig().Hk4e.LoadSceneLuaConfig {
|
||||
return
|
||||
}
|
||||
sceneLuaPrefix := g.luaPrefix + "scene/"
|
||||
for _, sceneData := range g.SceneDataMap {
|
||||
sceneId := sceneData.SceneId
|
||||
@@ -345,9 +377,9 @@ func (g *GameDataConfig) loadSceneLuaConfig() {
|
||||
for _, scene := range g.SceneLuaConfigMap {
|
||||
for _, block := range scene.BlockMap {
|
||||
for _, group := range block.GroupMap {
|
||||
monsterCount += len(group.MonsterList)
|
||||
npcCount += len(group.NpcList)
|
||||
gadgetCount += len(group.GadgetList)
|
||||
monsterCount += len(group.MonsterMap)
|
||||
npcCount += len(group.NpcMap)
|
||||
gadgetCount += len(group.GadgetMap)
|
||||
groupCount++
|
||||
}
|
||||
blockCount++
|
||||
@@ -373,3 +405,61 @@ func GetSceneGroup(groupId int32) *Group {
|
||||
}
|
||||
return groupConfig
|
||||
}
|
||||
|
||||
const (
|
||||
LuaStateLruKeepNum = 10
|
||||
)
|
||||
|
||||
type LuaStateLru struct {
|
||||
GroupId int32
|
||||
AccessTime int64
|
||||
}
|
||||
|
||||
type LuaStateLruList []*LuaStateLru
|
||||
|
||||
func (l LuaStateLruList) Len() int {
|
||||
return len(l)
|
||||
}
|
||||
|
||||
func (l LuaStateLruList) Less(i, j int) bool {
|
||||
return l[i].AccessTime < l[j].AccessTime
|
||||
}
|
||||
|
||||
func (l LuaStateLruList) Swap(i, j int) {
|
||||
l[i], l[j] = l[j], l[i]
|
||||
}
|
||||
|
||||
func LuaStateLruRemove() {
|
||||
removeNum := len(CONF.LuaStateLruMap) - LuaStateLruKeepNum
|
||||
if removeNum <= 0 {
|
||||
return
|
||||
}
|
||||
luaStateLruList := make(LuaStateLruList, 0)
|
||||
for _, luaStateLru := range CONF.LuaStateLruMap {
|
||||
luaStateLruList = append(luaStateLruList, luaStateLru)
|
||||
}
|
||||
sort.Stable(luaStateLruList)
|
||||
for i := 0; i < removeNum; i++ {
|
||||
luaStateLru := luaStateLruList[i]
|
||||
group := GetSceneGroup(luaStateLru.GroupId)
|
||||
group.LuaState = nil
|
||||
delete(CONF.LuaStateLruMap, luaStateLru.GroupId)
|
||||
}
|
||||
logger.Info("lua state lru remove finish, remove num: %v", removeNum)
|
||||
}
|
||||
|
||||
func (g *Group) GetLuaState() *lua.LState {
|
||||
CONF.LuaStateLruMap[g.Id] = &LuaStateLru{
|
||||
GroupId: g.Id,
|
||||
AccessTime: time.Now().UnixMilli(),
|
||||
}
|
||||
if g.LuaState == nil {
|
||||
g.LuaState = newLuaState(g.LuaStr)
|
||||
scriptLib := g.LuaState.NewTable()
|
||||
g.LuaState.SetGlobal("ScriptLib", scriptLib)
|
||||
for _, scriptLibFunc := range SCRIPT_LIB_FUNC_LIST {
|
||||
g.LuaState.SetField(scriptLib, scriptLibFunc.fnName, g.LuaState.NewFunction(scriptLibFunc.fn))
|
||||
}
|
||||
}
|
||||
return g.LuaState
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user