feat(map): 实现地图加载和玩家进入地图功能
- 在 Player 结构中添加 MapId 字段,用于记录当前所在地图 ID - 新增地图配置解析功能,支持从 XML 文件中读取地图信息 - 实现玩家进入地图的逻辑,包括设置玩家位置和广播通知 - 更新登录逻辑,在玩家登录时自动进入默认地图 - 重构地图相关的数据结构和接口,为后续地图功能扩展做准备
This commit is contained in:
@@ -14,6 +14,7 @@ type Player struct {
|
|||||||
UserID uint32 //用户ID
|
UserID uint32 //用户ID
|
||||||
IsLogin bool //是否登录
|
IsLogin bool //是否登录
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
|
MapId uint32 //当前所在的地图ID
|
||||||
|
|
||||||
loginChan chan struct{} // 登录完成通知通道
|
loginChan chan struct{} // 登录完成通知通道
|
||||||
context.Context
|
context.Context
|
||||||
|
|||||||
@@ -1 +1,123 @@
|
|||||||
package xml
|
package xml
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/ECUST-XX/xml"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Maps 根节点,对应<Maps>标签
|
||||||
|
type Maps struct {
|
||||||
|
XMLName xml.Name `xml:"Maps"`
|
||||||
|
Maps []Map `xml:"map"` // 包含所有地图配置
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map 单张地图配置,对应<map>标签
|
||||||
|
type Map struct {
|
||||||
|
ID int `xml:"id,attr"` // 地图ID
|
||||||
|
Name string `xml:"name,attr"` // 地图名称
|
||||||
|
X int `xml:"x,attr"` // 地图X坐标
|
||||||
|
Y int `xml:"y,attr"` // 地图Y坐标
|
||||||
|
Des string `xml:"des,attr,omitempty"` // 地图描述(可选)
|
||||||
|
Super int `xml:"super,attr,omitempty"` // 上级地图ID(可选)
|
||||||
|
IsFB int `xml:"isFB,attr,omitempty"` // 是否为副本(0/1,可选)
|
||||||
|
IsLocal int `xml:"isLocal,attr,omitempty"` // 是否为本地地图(0/1,可选)
|
||||||
|
Sound string `xml:"sound,attr,omitempty"` // 背景音乐(可选)
|
||||||
|
ReplaceMapID int `xml:"replaceMapId,attr,omitempty"` // 替换地图ID(可选)
|
||||||
|
FX int `xml:"fx,attr,omitempty"` // 道具地面X坐标(可选)
|
||||||
|
FY int `xml:"fy,attr,omitempty"` // 道具地面Y坐标(可选)
|
||||||
|
WX int `xml:"wx,attr,omitempty"` // 道具墙面X坐标(可选)
|
||||||
|
WY int `xml:"wy,attr,omitempty"` // 道具墙面Y坐标(可选)
|
||||||
|
HX int `xml:"hx,attr,omitempty"` // 总部主电脑X坐标(可选)
|
||||||
|
HY int `xml:"hy,attr,omitempty"` // 总部主电脑Y坐标(可选)
|
||||||
|
|
||||||
|
Entries Entries `xml:"Entries,omitempty"` // 进入点配置(可选)
|
||||||
|
ChangeMapComp ComponentList `xml:"changeMapComp,omitempty"` // 场景切换组件(可选)
|
||||||
|
FunComp ComponentList `xml:"funComp,omitempty"` // 点击触发组件(可选)
|
||||||
|
AutoComp ComponentList `xml:"autoComp,omitempty"` // 自动触发组件(可选)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Entries 进入点集合,对应<Entries>标签
|
||||||
|
type Entries struct {
|
||||||
|
Entries []Entry `xml:"Entry"` // 多个进入点
|
||||||
|
}
|
||||||
|
|
||||||
|
// Entry 单个进入点配置,对应<Entry>标签
|
||||||
|
type Entry struct {
|
||||||
|
FromMap int `xml:"FromMap,attr"` // 来源地图ID
|
||||||
|
PosX int `xml:"PosX,attr"` // 进入后X坐标
|
||||||
|
PosY int `xml:"PosY,attr"` // 进入后Y坐标
|
||||||
|
}
|
||||||
|
|
||||||
|
// ComponentList 组件集合(用于统一管理不同类型的组件列表)
|
||||||
|
type ComponentList struct {
|
||||||
|
Components []Component `xml:"component"` // 多个组件
|
||||||
|
}
|
||||||
|
|
||||||
|
// Component 单个功能组件配置,对应<component>标签
|
||||||
|
type Component struct {
|
||||||
|
Name string `xml:"name,attr,omitempty"` // 组件名称(可选)
|
||||||
|
Hit string `xml:"hit,attr,omitempty"` // 碰撞区域标识(可选)
|
||||||
|
TargetID int `xml:"targetID,attr,omitempty"` // 目标地图ID(可选)
|
||||||
|
Dir int `xml:"dir,attr,omitempty"` // 滚动方向(1-4,可选)
|
||||||
|
Fun string `xml:"fun,attr,omitempty"` // 触发函数名(可选)
|
||||||
|
Des string `xml:"des,attr,omitempty"` // 鼠标提示文本(可选)
|
||||||
|
IsStop int `xml:"isStop,attr,omitempty"` // 鼠标悬停是否跳帧(0/1,可选)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadHTTPFile 通过HTTP GET请求获取远程文件内容
|
||||||
|
// url: 远程文件的URL地址
|
||||||
|
// 返回文件内容字节流和可能的错误
|
||||||
|
func ReadHTTPFile(url string) ([]byte, error) {
|
||||||
|
// 创建HTTP客户端并设置超时时间(避免无限等待)
|
||||||
|
client := &http.Client{
|
||||||
|
Timeout: 30 * time.Second, // 30秒超时
|
||||||
|
}
|
||||||
|
|
||||||
|
// 发送GET请求
|
||||||
|
resp, err := client.Get(url)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("请求失败: %w", err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close() // 确保响应体被关闭
|
||||||
|
|
||||||
|
// 检查响应状态码
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
return nil, fmt.Errorf("请求返回非成功状态码: %d", resp.StatusCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 读取响应体内容
|
||||||
|
content, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("读取内容失败: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return content, nil
|
||||||
|
}
|
||||||
|
func getxml() ([]byte, error) {
|
||||||
|
|
||||||
|
// 读取整个文件内容,返回字节切片和错误
|
||||||
|
content, err := ReadHTTPFile("http://127.0.0.1:8080/assets/map_info.xml")
|
||||||
|
if err != nil {
|
||||||
|
// 处理错误(文件不存在、权限问题等)
|
||||||
|
log.Fatalf("无法读取文件: %v", err)
|
||||||
|
}
|
||||||
|
return content, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
func getMaps() Maps {
|
||||||
|
|
||||||
|
// 解析XML到结构体
|
||||||
|
var maps Maps
|
||||||
|
t1, _ := getxml()
|
||||||
|
xml.Unmarshal(t1, &maps)
|
||||||
|
|
||||||
|
return maps
|
||||||
|
}
|
||||||
|
|
||||||
|
// 全局函数配置
|
||||||
|
var MapConfig = getMaps()
|
||||||
|
|||||||
@@ -1,26 +0,0 @@
|
|||||||
package xml
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/ECUST-XX/xml"
|
|
||||||
)
|
|
||||||
|
|
||||||
type xmls struct {
|
|
||||||
Text string `xml:",chardata"`
|
|
||||||
Version string `xml:"comment"`
|
|
||||||
|
|
||||||
SuperMaps SuperMaps `xml:"superMaps"`
|
|
||||||
}
|
|
||||||
type SuperMaps struct {
|
|
||||||
XMLName xml.Name `xml:"superMaps"`
|
|
||||||
Text string `xml:",comment"`
|
|
||||||
Maps []Maps `xml:"maps"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Maps struct {
|
|
||||||
Text string `xml:",chardata"`
|
|
||||||
ID string `xml:"id,attr"`
|
|
||||||
Name string `xml:"name,attr"`
|
|
||||||
X string `xml:"x,attr"`
|
|
||||||
Y string `xml:"y,attr"`
|
|
||||||
// Galaxy string `xml:"galaxy,attr"`
|
|
||||||
}
|
|
||||||
@@ -48,25 +48,14 @@ var s = `
|
|||||||
</superMaps>`
|
</superMaps>`
|
||||||
|
|
||||||
func Test_main(t *testing.T) {
|
func Test_main(t *testing.T) {
|
||||||
tt := &SuperMaps{}
|
|
||||||
xml.Unmarshal([]byte(s), tt)
|
|
||||||
|
|
||||||
// tt.Maps = append(tt.Maps, Maps{
|
// 解析XML到结构体
|
||||||
// ID: "1",
|
var maps Maps
|
||||||
// Name: "传送舱",
|
t1, _ := getxml()
|
||||||
// // Galaxy: "1",
|
xml.Unmarshal(t1, &maps)
|
||||||
// X: "358",
|
|
||||||
// Y: "46",
|
//tf, _ := xml.MarshalIndentShortForm(tt, " ", " ")
|
||||||
// })
|
fmt.Println(maps)
|
||||||
// tt.Maps = append(tt.Maps, Maps{
|
|
||||||
// ID: "4",
|
|
||||||
// Name: "船长室",
|
|
||||||
// // Galaxy: "1",
|
|
||||||
// X: "358",
|
|
||||||
// Y: "46",
|
|
||||||
// })
|
|
||||||
tf, _ := xml.MarshalIndentShortForm(tt, " ", " ")
|
|
||||||
fmt.Println(string(tf))
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ func (h *Controller) Login(data *login.InInfo, c *entity.Conn) (result *login.Ou
|
|||||||
|
|
||||||
share.ShareManager.SetUserOnline(data.Head.UserID, h.Port) //设置用户登录服务器
|
share.ShareManager.SetUserOnline(data.Head.UserID, h.Port) //设置用户登录服务器
|
||||||
t.CompleteLogin() //通知客户端登录成功
|
t.CompleteLogin() //通知客户端登录成功
|
||||||
|
t.MapId = 1
|
||||||
|
|
||||||
//c.SendPack(data.Def())
|
//c.SendPack(data.Def())
|
||||||
result = login.NewOutInfo() //设置登录消息
|
result = login.NewOutInfo() //设置登录消息
|
||||||
|
|
||||||
|
|||||||
@@ -3,12 +3,16 @@ package controller
|
|||||||
import (
|
import (
|
||||||
"blazing/common/data/entity"
|
"blazing/common/data/entity"
|
||||||
"blazing/common/socket/errorcode"
|
"blazing/common/socket/errorcode"
|
||||||
|
"blazing/logic/service/maps"
|
||||||
"blazing/logic/service/mapin"
|
"blazing/logic/service/space"
|
||||||
)
|
)
|
||||||
|
|
||||||
// 处理命令: 1001
|
func (h *Controller) MapIn(data *maps.InInfo, c *entity.Player) (result *maps.OutInfo, err errorcode.ErrorCode) { //这个时候player应该是空的
|
||||||
func (h *Controller) InMap(data *mapin.InInfo, c *entity.Conn) (result *mapin.OutInfo, err errorcode.ErrorCode) { //这个时候player应该是空的
|
|
||||||
|
c.MapId = data.MapId //登录地图
|
||||||
|
space.GetPlanet(c.UserID).Set(c.UserID, c) //添加玩家
|
||||||
|
result = &maps.OutInfo{UserID: c.UserID} //设置广播信息
|
||||||
|
data.Broadcast(c.MapId, *result) //同步广播
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
12
logic/controller/mapout.go
Normal file
12
logic/controller/mapout.go
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
package controller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"blazing/common/data/entity"
|
||||||
|
"blazing/common/socket/errorcode"
|
||||||
|
"blazing/logic/service/maps"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (h *Controller) MapOut(data *maps.LeaveMapInboundInfo, c *entity.Player) (result *maps.LeaveMapOutboundInfo, err errorcode.ErrorCode) { //这个时候player应该是空的
|
||||||
|
result = &maps.LeaveMapOutboundInfo{UserID: c.GetUserID()}
|
||||||
|
return
|
||||||
|
}
|
||||||
@@ -3,14 +3,17 @@ package controller
|
|||||||
import (
|
import (
|
||||||
"blazing/common/data/entity"
|
"blazing/common/data/entity"
|
||||||
"blazing/common/socket/errorcode"
|
"blazing/common/socket/errorcode"
|
||||||
"blazing/logic/service/walk"
|
"blazing/logic/service/space"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (h Controller) Walk(data *walk.InInfo, c *entity.Player) (result *walk.OutInfo, err errorcode.ErrorCode) {
|
func (h Controller) Walk(data *space.InInfo, c *entity.Player) (result *space.OutInfo, err errorcode.ErrorCode) {
|
||||||
|
|
||||||
result = &walk.OutInfo{Flag: data.Flag,
|
result = &space.OutInfo{Flag: data.Flag,
|
||||||
UserID: c.GetUserID(),
|
UserID: c.GetUserID(),
|
||||||
Reserve2: data.Reverse2,
|
Reserve2: data.Reverse2,
|
||||||
Point: data.Point}
|
Point: data.Point}
|
||||||
|
|
||||||
|
data.Broadcast(c.MapId, *result) //走路的广播
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,11 +73,9 @@ func Start(serverid uint16) {
|
|||||||
|
|
||||||
// go func() {
|
// go func() {
|
||||||
t := rpc.StartClient(serverid, uint16(port), new(controller.LogicClient))
|
t := rpc.StartClient(serverid, uint16(port), new(controller.LogicClient))
|
||||||
//TODO 待实现掉线重新连接login
|
|
||||||
controller.Maincontroller.RPCClient = *t //将RPC赋值Start
|
controller.Maincontroller.RPCClient = *t //将RPC赋值Start
|
||||||
controller.Maincontroller.Port = uint16(port) //赋值服务器ID
|
controller.Maincontroller.Port = uint16(port) //赋值服务器ID
|
||||||
//}()
|
|
||||||
//go rpc.StartClient(uint16(serverid), &controller.Maincontroller)
|
|
||||||
|
|
||||||
service.NewLoginServiceService().SetServerID(serverid, gconv.Uint16(port), t)
|
service.NewLoginServiceService().SetServerID(serverid, gconv.Uint16(port), t)
|
||||||
socket.
|
socket.
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
package mapin
|
|
||||||
|
|
||||||
import (
|
|
||||||
"blazing/common/socket/handler"
|
|
||||||
"blazing/modules/blazing/model"
|
|
||||||
)
|
|
||||||
|
|
||||||
type InInfo struct {
|
|
||||||
Head handler.TomeeHeader `cmd:"2001" struc:"[0]pad"` //玩家登录
|
|
||||||
// 地图类型
|
|
||||||
mapType uint32
|
|
||||||
|
|
||||||
mapId uint32
|
|
||||||
// Point: 直接给坐标x,y
|
|
||||||
Point model.Pos `fieldDesc:"直接给坐标x,y"`
|
|
||||||
|
|
||||||
// Reverse2: 暂定 占位字符2
|
|
||||||
Reverse2 string `struc:"[2]byte"`
|
|
||||||
}
|
|
||||||
@@ -1,13 +1,41 @@
|
|||||||
package mapin
|
package maps
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"blazing/common/data/entity"
|
||||||
|
"blazing/common/socket/handler"
|
||||||
|
"blazing/logic/service/space"
|
||||||
"blazing/modules/blazing/model"
|
"blazing/modules/blazing/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type InInfo struct {
|
||||||
|
Head handler.TomeeHeader `cmd:"2001" struc:"[0]pad"` //切换地图
|
||||||
|
// 地图类型
|
||||||
|
MapType uint32
|
||||||
|
|
||||||
|
MapId uint32
|
||||||
|
// Point: 直接给坐标x,y
|
||||||
|
Point model.Pos `fieldDesc:"直接给坐标x,y"`
|
||||||
|
|
||||||
|
// Reverse2: 暂定 占位字符2
|
||||||
|
Reverse2 string `struc:"[2]byte"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *InInfo) Broadcast(mapid uint32, o OutInfo) {
|
||||||
|
|
||||||
|
space.GetPlanet(mapid).Range(func(playerID uint32, player *entity.Player) bool {
|
||||||
|
|
||||||
|
player.SendPack(t.Head.Pack(o))
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 这里存储星球的map
|
||||||
|
//var planetmap utils.SyncMap[] //= space.NewSyncMap()
|
||||||
|
|
||||||
// PeopleInfo 对应Java的PeopleInfo类,实现OutboundMessage接口
|
// PeopleInfo 对应Java的PeopleInfo类,实现OutboundMessage接口
|
||||||
type OutInfo struct {
|
type OutInfo struct {
|
||||||
// 系统时间
|
// 系统时间
|
||||||
SystemTime uint64 `struc:"uint64" fieldDesc:"系统时间" json:"system_time"`
|
SystemTime uint32 `struc:"uint32" fieldDesc:"系统时间" json:"system_time"`
|
||||||
|
|
||||||
// 米米号
|
// 米米号
|
||||||
UserID uint32 `struc:"uint32" fieldDesc:"米米号" json:"user_id"`
|
UserID uint32 `struc:"uint32" fieldDesc:"米米号" json:"user_id"`
|
||||||
12
logic/service/maps/mapout.go
Normal file
12
logic/service/maps/mapout.go
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
package maps
|
||||||
|
|
||||||
|
import "blazing/common/socket/handler"
|
||||||
|
|
||||||
|
type LeaveMapOutboundInfo struct {
|
||||||
|
// 米米号
|
||||||
|
UserID uint32 `struc:"uint32" fieldDesc:"米米号" json:"user_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type LeaveMapInboundInfo struct {
|
||||||
|
Head handler.TomeeHeader `cmd:"2002" struc:"[0]pad"` //切换地图
|
||||||
|
}
|
||||||
71
logic/service/space/space.go
Normal file
71
logic/service/space/space.go
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
package space
|
||||||
|
|
||||||
|
import (
|
||||||
|
"blazing/common/data/entity"
|
||||||
|
"blazing/modules/blazing/model"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Space 针对Player的并发安全map,键为uint32类型
|
||||||
|
type Space struct {
|
||||||
|
mu sync.RWMutex // 读写锁,读多写少场景更高效
|
||||||
|
data map[uint32]*entity.Player // 存储玩家数据的map,键为玩家ID
|
||||||
|
CanRefresh bool //是否能够刷怪
|
||||||
|
ID uint32 // 地图ID
|
||||||
|
Name string //地图名称
|
||||||
|
DefaultPos model.Pos //默认位置DefaultPos
|
||||||
|
Positions map[uint32]model.Pos //从上一个地图跳转后默认位置
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewSyncMap 创建一个新的玩家同步map
|
||||||
|
func NewSpace() *Space {
|
||||||
|
return &Space{
|
||||||
|
data: make(map[uint32]*entity.Player),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get 根据玩家ID获取玩家实例
|
||||||
|
// 读操作使用RLock,允许多个goroutine同时读取
|
||||||
|
func (m *Space) Get(playerID uint32) (*entity.Player, bool) {
|
||||||
|
m.mu.RLock()
|
||||||
|
defer m.mu.RUnlock()
|
||||||
|
val, exists := m.data[playerID]
|
||||||
|
return val, exists
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set 存储玩家实例(按ID)
|
||||||
|
// 写操作使用Lock,独占锁保证数据一致性
|
||||||
|
func (m *Space) Set(playerID uint32, player *entity.Player) {
|
||||||
|
m.mu.Lock()
|
||||||
|
defer m.mu.Unlock()
|
||||||
|
m.data[playerID] = player
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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,遍历过程中不会阻塞其他读操作
|
||||||
|
func (m *Space) Range(f func(playerID uint32, player *entity.Player) bool) {
|
||||||
|
m.mu.RLock()
|
||||||
|
defer m.mu.RUnlock()
|
||||||
|
for id, player := range m.data {
|
||||||
|
// 若回调返回false,则停止遍历
|
||||||
|
if !f(id, player) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
76
logic/service/space/walk.go
Normal file
76
logic/service/space/walk.go
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
package space
|
||||||
|
|
||||||
|
import (
|
||||||
|
"blazing/common/data/entity"
|
||||||
|
"blazing/common/data/xml"
|
||||||
|
"blazing/common/socket/handler"
|
||||||
|
"blazing/common/utils"
|
||||||
|
"blazing/modules/blazing/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 获取星球
|
||||||
|
func GetPlanet(id uint32) *Space {
|
||||||
|
planet, ok := planetmap.Load(id)
|
||||||
|
if ok {
|
||||||
|
return planet
|
||||||
|
}
|
||||||
|
|
||||||
|
//如果不ok,说明星球未创建,那就新建星球
|
||||||
|
|
||||||
|
for _, v := range xml.MapConfig.Maps {
|
||||||
|
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]{} //玩家数据
|
||||||
|
type InInfo struct {
|
||||||
|
Head handler.TomeeHeader `cmd:"2101" struc:"[0]pad"` //玩家登录
|
||||||
|
// Flag: 0为走,1为飞行模式,对应Java的@UInt long
|
||||||
|
Flag uint32
|
||||||
|
|
||||||
|
// Point: 直接给坐标x,y
|
||||||
|
Point model.Pos `fieldDesc:"直接给坐标x,y"`
|
||||||
|
|
||||||
|
// Reverse2: 暂定 占位字符2
|
||||||
|
Reverse2 string `struc:"[2]byte"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *InInfo) Broadcast(mapid uint32, o OutInfo) {
|
||||||
|
|
||||||
|
GetPlanet(mapid).Range(func(playerID uint32, player *entity.Player) bool {
|
||||||
|
|
||||||
|
player.SendPack(t.Head.Pack(o))
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// PeopleWalkOutboundInfo 对应Java的PeopleWalkOutboundInfo类,实现OutboundMessage接口
|
||||||
|
type OutInfo struct {
|
||||||
|
// Flag: 0为走,1为飞行模式
|
||||||
|
Flag uint32 `fieldDesc:"0为走,1为飞行模式" codec:"uint"`
|
||||||
|
|
||||||
|
// UserID: 走动的人的米米号
|
||||||
|
UserID uint32 `fieldDesc:"走动的人的米米号" codec:"uint"`
|
||||||
|
|
||||||
|
// Point: 直接给坐标x,y
|
||||||
|
Point model.Pos `fieldDesc:"直接给坐标x,y"`
|
||||||
|
|
||||||
|
// Reserve2: 这个字段同C2S_People_Walk中的reserve2
|
||||||
|
Reserve2 string `struc:"[2]byte"`
|
||||||
|
}
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
package walk
|
|
||||||
|
|
||||||
import (
|
|
||||||
"blazing/common/socket/handler"
|
|
||||||
"blazing/modules/blazing/model"
|
|
||||||
)
|
|
||||||
|
|
||||||
type InInfo struct {
|
|
||||||
Head handler.TomeeHeader `cmd:"2101" struc:"[0]pad"` //玩家登录
|
|
||||||
// Flag: 0为走,1为飞行模式,对应Java的@UInt long
|
|
||||||
Flag uint32
|
|
||||||
|
|
||||||
// Point: 直接给坐标x,y
|
|
||||||
Point model.Pos `fieldDesc:"直接给坐标x,y"`
|
|
||||||
|
|
||||||
// Reverse2: 暂定 占位字符2
|
|
||||||
Reverse2 string `struc:"[2]byte"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// PeopleWalkOutboundInfo 对应Java的PeopleWalkOutboundInfo类,实现OutboundMessage接口
|
|
||||||
type OutInfo struct {
|
|
||||||
// Flag: 0为走,1为飞行模式
|
|
||||||
Flag uint32 `fieldDesc:"0为走,1为飞行模式" codec:"uint"`
|
|
||||||
|
|
||||||
// UserID: 走动的人的米米号
|
|
||||||
UserID uint32 `fieldDesc:"走动的人的米米号" codec:"uint"`
|
|
||||||
|
|
||||||
// Point: 直接给坐标x,y
|
|
||||||
Point model.Pos `fieldDesc:"直接给坐标x,y"`
|
|
||||||
|
|
||||||
// Reserve2: 这个字段同C2S_People_Walk中的reserve2
|
|
||||||
Reserve2 string `struc:"[2]byte"`
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user