diff --git a/common/data/xml/map.go b/common/data/xml/map/map.go similarity index 100% rename from common/data/xml/map.go rename to common/data/xml/map/map.go diff --git a/common/data/xml/monster_refresh_test.go b/common/data/xml/map/monster_refresh_test.go similarity index 100% rename from common/data/xml/monster_refresh_test.go rename to common/data/xml/map/monster_refresh_test.go diff --git a/common/data/xml/talk/monster_refresh_test.go b/common/data/xml/talk/monster_refresh_test.go new file mode 100644 index 000000000..8fbc3850a --- /dev/null +++ b/common/data/xml/talk/monster_refresh_test.go @@ -0,0 +1,58 @@ +package xml + +import ( + "fmt" + "testing" + + "github.com/ECUST-XX/xml" +) + +var s = ` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +` + +func Test_main(t *testing.T) { + + // 解析XML到结构体 + var maps TalkCount + t1, _ := getxml() + xml.Unmarshal(t1, &maps) + + //tf, _ := xml.MarshalIndentShortForm(tt, " ", " ") + fmt.Println(maps) + +} diff --git a/common/data/xml/talk/talk.go b/common/data/xml/talk/talk.go new file mode 100644 index 000000000..725ac1942 --- /dev/null +++ b/common/data/xml/talk/talk.go @@ -0,0 +1,89 @@ +package xml + +import ( + "fmt" + "io" + "log" + "net/http" + "time" + + "github.com/ECUST-XX/xml" // 注意:需确保该xml库与示例中使用的一致 +) + +func getxml() ([]byte, error) { + + // 读取整个文件内容,返回字节切片和错误 + content, err := ReadHTTPFile("http://127.0.0.1:8080/assets/talk_count.xml") + if err != nil { + // 处理错误(文件不存在、权限问题等) + log.Fatalf("无法读取文件: %v", err) + } + return content, nil + +} + +// TalkCount 根节点,对应标签 +// 注意:xml.Name需指定命名空间,与XML中的xmlns保持一致 +type TalkCount struct { + XMLName xml.Name `xml:"nieo.seer.org.talk-count talk_count"` + Entries []Entry `xml:"entry"` // 包含所有entry节点 +} + +// Entry 单个条目配置,对应标签 +type Entry struct { + ID int `xml:"id,attr"` // 条目ID + ItemID int `xml:"item_id,attr"` // 物品ID + ItemMinCount int `xml:"item_min_count,attr"` // 物品最小数量 + ItemMaxCount int `xml:"item_max_count,attr"` // 物品最大数量 + Desc string `xml:"desc,attr"` // 描述信息 + Count int `xml:"count,attr"` // 计数 + Policy string `xml:"policy,attr,omitempty"` // 策略(可选,如week) +} + +// 复用示例中的ReadHTTPFile函数(读取远程文件) +func ReadHTTPFile(url string) ([]byte, error) { + client := &http.Client{ + Timeout: 30 * time.Second, + } + + 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 +} + +// 获取XML内容(可根据实际URL修改) +func getTalkCountXML() ([]byte, error) { + // 注意:此处URL需替换为实际的talk_count.xml文件地址 + content, err := ReadHTTPFile("http://127.0.0.1:8080/assets/talk_count.xml") + if err != nil { + log.Fatalf("无法读取文件: %v", err) + } + return content, nil +} + +// 解析XML到结构体 +func getTalkCount() TalkCount { + var talkCount TalkCount + content, _ := getTalkCountXML() + // 解析XML时需注意命名空间匹配 + if err := xml.Unmarshal(content, &talkCount); err != nil { + log.Fatalf("XML解析失败: %v", err) + } + return talkCount +} + +// 全局配置变量,用于存储解析后的结果 +var TalkCountConfig = getTalkCount() diff --git a/logic/service/space/walk.go b/logic/service/space/walk.go index 89b408b4f..e32a6e46d 100644 --- a/logic/service/space/walk.go +++ b/logic/service/space/walk.go @@ -2,7 +2,7 @@ package space import ( "blazing/common/data/entity" - "blazing/common/data/xml" + xml "blazing/common/data/xml/map" "blazing/common/socket/handler" "blazing/common/utils" "blazing/modules/blazing/model" diff --git a/modules/blazing/model/boss.go b/modules/blazing/model/boss.go new file mode 100644 index 000000000..0b9ff2b42 --- /dev/null +++ b/modules/blazing/model/boss.go @@ -0,0 +1,192 @@ +package model + +import ( + "blazing/cool" + "encoding/json" +) + +// ------------------------------ +// 1. BOSS主表结构(核心ID与关联) +// ------------------------------ + +const TableNameBoss = "boss" + +// Boss 主表仅存储核心索引和JSON数据 +type Boss struct { + *cool.Model + PlanetID int32 `gorm:"not null;index:idx_boss_planet;comment:'所属星球/地图ID'" json:"planet_id"` + BossID int32 `gorm:"not null;comment:'BOSS序号(同星球内唯一)'" json:"boss_id"` + Data string `gorm:"type:text;not null;comment:'BOSS详细数据(JSON格式)'" json:"data"` + Galaxy string `gorm:"type:varchar(50);comment:'所属星系(如帕诺星系)'" json:"galaxy"` +} + +// 联合唯一索引:确保星球+BOSS序号唯一 +func (b *Boss) Indexes() map[string]string { + return map[string]string{ + "idx_planet_boss_unique": "planet_id,boss_id", + } +} + +// TableName 定义表名 +func (*Boss) TableName() string { + return TableNameBoss +} + +// GroupName 定义分组名 +func (*Boss) GroupName() string { + return "default" +} + +// NewBoss 创建新的BOSS主表实例 +func NewBoss() *Boss { + return &Boss{ + Model: cool.NewModel(), + } +} + +// ------------------------------ +// 2. BOSS详细数据结构(JSON存储) +// ------------------------------ + +// BossData 封装BOSS所有详细属性,用于JSON序列化 +type BossData struct { + // 基础信息 + EncyclopediaID int32 `json:"encyclopedia_id"` // BOSS图鉴ID + Desc string `json:"desc"` // BOSS名称描述 + Level int32 `json:"level"` // 等级 + Capturable bool `json:"capturable"` // 是否可捕捉 + + // 战斗属性 + MaxHP int32 `json:"max_hp"` // 最大血量(-1使用默认公式) + Attack int32 `json:"attack"` // 攻击属性 + Defense int32 `json:"defense"` // 防御属性 + SpecialAttack int32 `json:"special_attack"` // 特攻属性 + SpecialDefense int32 `json:"special_defense"` // 特防属性 + Speed int32 `json:"speed"` // 速度属性 + Definitely int32 `json:"definitely"` // 必定命中率(默认5) + Dodge int32 `json:"dodge"` // 闪避率(默认5) + Stat string `json:"stat"` // 开局属性变化(攻击,特攻,防御,特防,速度,命中) + + // 技能列表 + Skills []BossSkill `json:"skills"` + + // 免疫效果 + ImmunityEffectIDs []int32 `json:"immunity_effect_ids"` // 免疫效果ID列表 + ImmunityBuffNames []string `json:"immunity_buff_names"` // 免疫Buff名称列表 + + // 特殊Buff + SpecialBuffs []SpecialBuff `json:"special_buffs"` +} + +// BossSkill 技能详情结构 +type BossSkill struct { + ID int32 `json:"id"` // 技能ID + Desc string `json:"desc"` // 技能描述 + InfinityPP bool `json:"infinity_pp"` // 是否PP无限 +} + +// SpecialBuff 特殊Buff结构 +type SpecialBuff struct { + Value string `json:"value"` // Buff标识(如boss://map314-boss0) + Params string `json:"params"` // 附加参数(空格分隔) +} + +// ------------------------------ +// 3. JSON序列化/反序列化工具方法 +// ------------------------------ + +// ToJSON 将BossData转为JSON字符串 +func (d *BossData) ToJSON() (string, error) { + data, err := json.Marshal(d) + if err != nil { + return "", err + } + return string(data), nil +} + +// ParseBossData 从JSON字符串解析BossData +func ParseBossData(jsonStr string) (*BossData, error) { + var data BossData + if err := json.Unmarshal([]byte(jsonStr), &data); err != nil { + return nil, err + } + return &data, nil +} + +// ------------------------------ +// 4. 表初始化 +// ------------------------------ + +func init() { + // 创建BOSS主表 + cool.CreateTable(&Boss{}) +} + +// ------------------------------ +// 5. 使用示例 +// ------------------------------ + +/* +// 存储BOSS数据示例 +func ExampleSaveBoss() { + // 1. 构建详细数据 + skills := []BossSkill{ + {ID: 10001, Desc: "撞击", InfinityPP: true}, + {ID: 20020, Desc: "毒粉", InfinityPP: true}, + } + + immunityEffects := []int32{7, 36} + immunityBuffs := []string{"condition://brun", "condition://poison"} + + specialBuffs := []SpecialBuff{ + {Value: "boss://map59-boss0", Params: ""}, + } + + bossData := &BossData{ + EncyclopediaID: 347, + Desc: "远古鱼龙", + Level: 100, + Capturable: false, + MaxHP: 3000, + Attack: 280, + SpecialAttack: 417, + Defense: 350, + SpecialDefense: 317, + Speed: 264, + Definitely: 45, + Stat: "0 0 0 0 0 0", + Skills: skills, + ImmunityEffectIDs: immunityEffects, + ImmunityBuffNames: immunityBuffs, + SpecialBuffs: specialBuffs, + } + + // 2. 序列化为JSON + dataJSON, _ := bossData.ToJSON() + + // 3. 存储到主表 + boss := NewBoss() + boss.PlanetID = 59 + boss.BossID = 0 + boss.Galaxy = "卡兰星系" + boss.Data = dataJSON + + // 实际项目中使用GORM保存 + // db.Create(boss) +} + +// 查询BOSS数据示例 +func ExampleGetBoss() { + // 1. 从数据库查询主表 + var boss Boss + // db.Where("planet_id = ? AND boss_id = ?", 59, 0).First(&boss) + + // 2. 解析JSON数据 + bossData, _ := ParseBossData(boss.Data) + + // 3. 使用数据 + println("BOSS名称:", bossData.Desc) + println("等级:", bossData.Level) + println("技能数量:", len(bossData.Skills)) +} +*/ diff --git a/modules/blazing/model/monster_refresh.go b/modules/blazing/model/monster_refresh.go new file mode 100644 index 000000000..43c85f323 --- /dev/null +++ b/modules/blazing/model/monster_refresh.go @@ -0,0 +1,47 @@ +package model + +import ( + "blazing/cool" +) + +const ( + TableNameMonsterRefresh = "monster_refresh" // 怪物刷新规则表 + +) + +// MonsterRefresh 怪物刷新规则模型(对应XML中的标签) +type MonsterRefresh struct { + *cool.Model + MapID int32 `gorm:"not null;index:idx_refresh_by_map_id;comment:'所属地图ID'" json:"map_id"` + MonsterID int32 `gorm:"not null;comment:'怪物唯一编号'" json:"monster_id"` + Desc string `gorm:"type:varchar(100);not null;comment:'怪物名称(如皮皮)'" json:"desc"` + MinLevel int32 `gorm:"not null;comment:'最低等级'" json:"min_level"` + MaxLevel int32 `gorm:"not null;comment:'最高等级'" json:"max_level"` + Capturable bool `gorm:"not null;comment:'是否可捕捉'" json:"capturable"` + Rate float64 `gorm:"not null;comment:'刷新概率(百分比)'" json:"rate"` //未设置概率的就是默认刷新 + Value string `gorm:"type:text;not null;comment:'限制值(如19:00-24:00)'" json:"value"` //这里是js文本,暂定传入时间 +} + +// TableName MonsterRefresh's table name +func (*MonsterRefresh) TableName() string { + return TableNameMonsterRefresh +} + +// GroupName MonsterRefresh's table group +func (*MonsterRefresh) GroupName() string { + return "default" +} + +// NewMonsterRefresh create a new MonsterRefresh +func NewMonsterRefresh() *MonsterRefresh { + return &MonsterRefresh{ + Model: cool.NewModel(), + } +} + +// 初始化表结构 +func init() { + + cool.CreateTable(&MonsterRefresh{}) + +} diff --git a/modules/blazing/model/player.go b/modules/blazing/model/player.go index fbc5cd3cf..187f09997 100644 --- a/modules/blazing/model/player.go +++ b/modules/blazing/model/player.go @@ -18,7 +18,7 @@ type Pos struct { // PeopleItemInfo 穿戴装备信息结构(对应Java的PeopleItemInfo) type PeopleItemInfo struct { - ID uint32 `struc:"uint32"` // 装备id(对应Java的@UInt long) + ID uint32 `struc:"uint32"` // 装备id Level uint32 `struc:"uint32" default:"1"` // 未知字段(默认值1,对应Java的@Builder.Default) } diff --git a/modules/blazing/model/task.go b/modules/blazing/model/task.go new file mode 100644 index 000000000..0c3b4f2ff --- /dev/null +++ b/modules/blazing/model/task.go @@ -0,0 +1 @@ +package model \ No newline at end of file