2025-08-15 22:44:28 +08:00
|
|
|
|
package space
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
2025-08-30 00:36:08 +08:00
|
|
|
|
"blazing/common/data/xmlres"
|
2025-08-16 03:36:13 +00:00
|
|
|
|
"blazing/common/utils"
|
2025-09-14 01:35:16 +08:00
|
|
|
|
|
|
|
|
|
|
"blazing/logic/service/common"
|
2025-09-04 02:00:57 +08:00
|
|
|
|
|
2025-08-15 22:44:28 +08:00
|
|
|
|
"blazing/modules/blazing/model"
|
|
|
|
|
|
"sync"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
// Space 针对Player的并发安全map,键为uint32类型
|
|
|
|
|
|
type Space struct {
|
2025-09-14 01:35:16 +08:00
|
|
|
|
mu sync.RWMutex // 读写锁,读多写少场景更高效
|
|
|
|
|
|
data map[uint32]common.PlayerI // 存储玩家数据的map,键为玩家ID
|
|
|
|
|
|
CanRefresh bool //是否能够刷怪
|
|
|
|
|
|
ID uint32 // 地图ID
|
|
|
|
|
|
Name string //地图名称
|
|
|
|
|
|
DefaultPos model.Pos //默认位置DefaultPos
|
|
|
|
|
|
Positions map[uint32]model.Pos //从上一个地图跳转后默认位置
|
2025-08-15 22:44:28 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// NewSyncMap 创建一个新的玩家同步map
|
|
|
|
|
|
func NewSpace() *Space {
|
|
|
|
|
|
return &Space{
|
2025-09-14 01:35:16 +08:00
|
|
|
|
data: make(map[uint32]common.PlayerI),
|
2025-08-15 22:44:28 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Get 根据玩家ID获取玩家实例
|
|
|
|
|
|
// 读操作使用RLock,允许多个goroutine同时读取
|
2025-09-14 01:35:16 +08:00
|
|
|
|
func (m *Space) Get(playerID uint32) (common.PlayerI, bool) {
|
2025-08-15 22:44:28 +08:00
|
|
|
|
m.mu.RLock()
|
|
|
|
|
|
defer m.mu.RUnlock()
|
|
|
|
|
|
val, exists := m.data[playerID]
|
|
|
|
|
|
return val, exists
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Set 存储玩家实例(按ID)
|
|
|
|
|
|
// 写操作使用Lock,独占锁保证数据一致性
|
2025-09-14 01:35:16 +08:00
|
|
|
|
func (m *Space) Set(playerID uint32, player common.PlayerI) *Space {
|
2025-08-15 22:44:28 +08:00
|
|
|
|
m.mu.Lock()
|
|
|
|
|
|
defer m.mu.Unlock()
|
|
|
|
|
|
m.data[playerID] = player
|
2025-08-28 21:35:56 +00:00
|
|
|
|
|
|
|
|
|
|
return m
|
2025-08-15 22:44:28 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Delete 根据玩家ID删除玩家实例
|
|
|
|
|
|
// 写操作使用Lock
|
|
|
|
|
|
func (m *Space) Delete(playerID uint32) {
|
|
|
|
|
|
m.mu.Lock()
|
|
|
|
|
|
defer m.mu.Unlock()
|
|
|
|
|
|
delete(m.data, playerID)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Len 获取当前玩家数量
|
|
|
|
|
|
// 读操作使用RLock
|
|
|
|
|
|
func (m *Space) Len() int {
|
|
|
|
|
|
m.mu.RLock()
|
|
|
|
|
|
defer m.mu.RUnlock()
|
|
|
|
|
|
return len(m.data)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Range 遍历所有玩家并执行回调函数
|
|
|
|
|
|
// 读操作使用RLock,遍历过程中不会阻塞其他读操作
|
2025-09-14 01:35:16 +08:00
|
|
|
|
func (m *Space) Range(f func(playerID uint32, player common.PlayerI) bool) {
|
2025-08-15 22:44:28 +08:00
|
|
|
|
m.mu.RLock()
|
|
|
|
|
|
defer m.mu.RUnlock()
|
|
|
|
|
|
for id, player := range m.data {
|
|
|
|
|
|
// 若回调返回false,则停止遍历
|
|
|
|
|
|
if !f(id, player) {
|
|
|
|
|
|
break
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-08-16 03:36:13 +00:00
|
|
|
|
|
|
|
|
|
|
// 获取星球
|
|
|
|
|
|
func GetSpace(id uint32) *Space {
|
|
|
|
|
|
|
|
|
|
|
|
planet, ok := planetmap.Load(id)
|
|
|
|
|
|
if ok {
|
|
|
|
|
|
return planet
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-20 22:34:45 +08:00
|
|
|
|
if id > 10000 { //说明是玩家地图GetSpace
|
|
|
|
|
|
|
|
|
|
|
|
t := NewSpace()
|
|
|
|
|
|
planetmap.Store(id, t)
|
|
|
|
|
|
return t
|
|
|
|
|
|
}
|
2025-08-16 03:36:13 +00:00
|
|
|
|
//如果不ok,说明星球未创建,那就新建星球
|
|
|
|
|
|
|
2025-08-30 00:36:08 +08:00
|
|
|
|
for _, v := range xmlres.MapConfig.Maps {
|
2025-08-16 03:36:13 +00:00
|
|
|
|
if v.ID == int(id) { //找到这个地图
|
|
|
|
|
|
t := NewSpace()
|
|
|
|
|
|
t.DefaultPos = model.Pos{X: uint32(v.X), Y: uint32(v.Y)}
|
|
|
|
|
|
t.ID = uint32(v.ID)
|
|
|
|
|
|
t.Name = v.Name
|
|
|
|
|
|
t.Positions = make(map[uint32]model.Pos)
|
|
|
|
|
|
for _, v := range v.Entries.Entries { //添加地图入口
|
|
|
|
|
|
t.Positions[uint32(v.FromMap)] = model.Pos{X: uint32(v.PosX), Y: uint32(v.PosY)}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
planetmap.Store(id, t)
|
|
|
|
|
|
return t
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var planetmap = &utils.SyncMap[uint32, *Space]{} //玩家数据
|
2025-09-14 01:35:16 +08:00
|
|
|
|
type LeaveMapOutboundInfo struct {
|
|
|
|
|
|
// 米米号
|
|
|
|
|
|
UserID uint32 `struc:"uint32" fieldDesc:"米米号" json:"user_id"`
|
|
|
|
|
|
}
|