```
feat(xml): 更新任务配置结构以支持新能量节点解析 将原先的 TalkCount 和 TalkEntry 结构替换为 TalkRoot 和 Energy, 以适配新的 XML 配置格式。同时更新了相关引用代码以确保类型一致性。 refactor(item): 优化物品添加方法支持可变参数传入 调整 ItemAdd 方法签名,从接收数组改为接收可变参数, 提升调用灵活性,并同步修改控制器中对物品添加逻辑的处理方式。 feat(login): 修复每日重置逻辑并引入 gtime 时间管理 修正登录时每日任务重置区间错误(400~100 改为 400~500), 并改用 gtime.Now().Time 提供更准确的时间戳记录与比较, 同时增强挖矿次数等
This commit is contained in:
@@ -38,7 +38,7 @@ var (
|
||||
MapConfig Maps //地图配置
|
||||
ItemsConfig Items //物品配置
|
||||
EffectArgsConfig EffectArg //arg参数
|
||||
TalkConfig TalkCount //任务配置
|
||||
TalkConfig TalkRoot //任务配置
|
||||
//Monster MonsterRoot //野怪配置
|
||||
MonsterMap map[int]TMapConfig
|
||||
//Skill MovesTbl //技能配置
|
||||
@@ -67,7 +67,7 @@ func initfile() {
|
||||
|
||||
})
|
||||
|
||||
TalkConfig = getXml[TalkCount](path + "talk.xml")
|
||||
TalkConfig = getXml[TalkRoot](path + "talk.xml")
|
||||
|
||||
Monster := getXml[MonsterRoot](path + "地图配置野怪.xml")
|
||||
|
||||
|
||||
@@ -4,20 +4,21 @@ import (
|
||||
"github.com/ECUST-XX/xml" // 注意:需确保该xml库与示例中使用的一致
|
||||
)
|
||||
|
||||
// TalkCount 根节点,对应<talk_count>标签
|
||||
// 注意:xml.Name需指定命名空间,与XML中的xmlns保持一致
|
||||
type TalkCount struct {
|
||||
XMLName xml.Name `xml:"nieo.seer.org.talk-count talk_count"`
|
||||
Entries []TalkEntry `xml:"entry"` // 包含所有entry节点
|
||||
// 定义XML根节点对应的结构体
|
||||
// 根节点<root>包含多个<energy>子节点,用切片接收
|
||||
type TalkRoot struct {
|
||||
XMLName xml.Name `xml:"root"` // 指定根节点名称为root
|
||||
Energies []Energy `xml:"energy"` // 子节点<energy>映射为切片,标签对应节点名
|
||||
}
|
||||
|
||||
// Entry 单个条目配置,对应<entry>标签
|
||||
type TalkEntry 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)
|
||||
// 定义<energy>节点对应的结构体
|
||||
// 每个字段对应<energy>的属性,用`xml:"属性名,attr"`标签标识
|
||||
type Energy struct {
|
||||
Type uint64 `xml:"type,attr"` // 类别ID(服务器规定),属性type
|
||||
MapID uint64 `xml:"mapID,attr"` // 矿产所在地图ID,属性mapID
|
||||
Name string `xml:"name,attr"` // 矿产名字,属性name
|
||||
CollectType string `xml:"collectType,attr"` // 操作类型(挖掘/采集/采摘),属性collectType
|
||||
CollectCnt uint64 `xml:"collectCnt,attr"` // 每天采集次数,属性collectCnt
|
||||
Unit string `xml:"unit,attr"` // 单位(块/罐/个),属性unit
|
||||
Dir uint64 `xml:"dir,attr"` // 人模朝向方向,属性dir
|
||||
}
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"blazing/common/data/xmlres"
|
||||
"blazing/common/socket/errorcode"
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
"blazing/logic/service/common"
|
||||
"blazing/logic/service/item"
|
||||
"blazing/logic/service/player"
|
||||
"blazing/logic/service/space"
|
||||
"blazing/modules/blazing/model"
|
||||
)
|
||||
|
||||
@@ -38,3 +43,95 @@ func (h Controller) PlayerExp(data *item.ExpTotalRemainInboundInfo, c *player.Pl
|
||||
TotalExp: uint32(c.Info.ExpPool),
|
||||
}, 0
|
||||
}
|
||||
|
||||
func (h Controller) BuyItem(data *item.BuyInboundInfo, c *player.Player) (result *item.BuyOutboundInfo, err errorcode.ErrorCode) {
|
||||
tt, ok := xmlres.ItemsMAP[int(data.ItemId)]
|
||||
if ok {
|
||||
c.Info.Coins -= data.Count * uint32(tt.Price)
|
||||
|
||||
c.ItemAdd(model.SingleItemInfo{ItemId: data.ItemId, ItemCnt: data.Count})
|
||||
return &item.BuyOutboundInfo{
|
||||
ItemId: data.ItemId,
|
||||
Level: 1,
|
||||
Count: data.Count,
|
||||
Coins: c.Info.Coins,
|
||||
}, 0
|
||||
}
|
||||
|
||||
return &item.BuyOutboundInfo{
|
||||
|
||||
Coins: c.Info.Coins,
|
||||
}, 0
|
||||
}
|
||||
func (h Controller) ChangePlayerCloth(data *item.ChangePlayerClothInboundInfo, c *player.Player) (result *item.ChangePlayerClothOutboundInfo, err errorcode.ErrorCode) {
|
||||
|
||||
result = &item.ChangePlayerClothOutboundInfo{
|
||||
UserID: c.Info.UserID,
|
||||
ClothList: make([]model.PeopleItemInfo, 0),
|
||||
}
|
||||
|
||||
for _, v := range data.ClothList {
|
||||
result.ClothList = append(result.ClothList, model.PeopleItemInfo{ID: v, Level: 1})
|
||||
}
|
||||
c.Info.Clothes = result.ClothList
|
||||
defer space.GetSpace(c.Info.MapID).User.IterCb(func(playerID uint32, player common.PlayerI) {
|
||||
// fmt.Println("ChangePlayerCloth", playerID, data.Head.Pack(result))
|
||||
player.SendPack(data.Head.Pack(result))
|
||||
|
||||
})
|
||||
return nil, -1
|
||||
}
|
||||
func (h Controller) Talk(data *item.TalkCountInboundInfo, c *player.Player) (result *item.TalkCountOutboundInfo, err errorcode.ErrorCode) {
|
||||
result = &item.TalkCountOutboundInfo{}
|
||||
c.Service.Talk(func(t map[uint32]uint32) bool {
|
||||
|
||||
tt, ok := t[data.ID]
|
||||
if ok {
|
||||
result.GiftCount = tt
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
return result, 0
|
||||
}
|
||||
|
||||
var talkcacche = make(map[string]uint32)
|
||||
|
||||
func (h Controller) TalkCate(data *item.TalkCateInboundInfo, c *player.Player) (result *item.DayTalkInfo, err errorcode.ErrorCode) {
|
||||
result = &item.DayTalkInfo{}
|
||||
result.OutList = make([]item.CateInfo, 0)
|
||||
for _, te := range xmlres.TalkConfig.Energies {
|
||||
if te.MapID == uint64(c.Info.MapID) && te.Type == uint64(data.ID) { //
|
||||
|
||||
c.Service.Talk(func(t map[uint32]uint32) bool {
|
||||
_, ok := t[data.ID]
|
||||
if ok {
|
||||
t[data.ID] += 1
|
||||
}
|
||||
|
||||
return true
|
||||
})
|
||||
_, ok := talkcacche[te.Name]
|
||||
if !ok {
|
||||
for _, v := range xmlres.ItemsMAP {
|
||||
if v.Name == te.Name {
|
||||
talkcacche[te.Name] = uint32(v.ID)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
rand.Seed(time.Now().UnixNano()) // UnixNano 精度更高,避免短时间内种子重复
|
||||
|
||||
// 2. 生成 1-10 的随机数:rand.Intn(10) → 0-9,+1 后范围变为 1-10
|
||||
randomNum := rand.Intn(10) + 1
|
||||
result.OutList = append(result.OutList, item.CateInfo{ID: uint32(talkcacche[te.Name]), Count: uint32(randomNum)})
|
||||
c.ItemAdd(model.SingleItemInfo{ItemId: uint32(talkcacche[te.Name]), ItemCnt: uint32(randomNum)})
|
||||
break
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return result, 0
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/v2/os/glog"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"github.com/jinzhu/copier"
|
||||
"github.com/panjf2000/gnet/v2"
|
||||
)
|
||||
@@ -54,23 +55,26 @@ func (h *Controller) Login(data *user.MAIN_LOGIN_IN, c gnet.Conn) (result *user.
|
||||
t.Info.UserID = data.Head.UserID
|
||||
t.Onlinetime = uint32(time.Now().Unix()) //保存时间戳
|
||||
t.Changemap = true
|
||||
|
||||
cool.Loger.Info(context.Background(), "用户上次重置日期", t.Info.LastResetTime.String())
|
||||
if !IsToday(t.Info.LastResetTime) { //判断是否是今天
|
||||
t.Info.LastResetTime = time.Now()
|
||||
t.Info.LastResetTime = gtime.Now().Time
|
||||
//每天login时候检查重置时间,然后把电池,任务,挖矿重置
|
||||
//挖矿需要单独存,因为防止多开挖矿
|
||||
t.Info.TimeToday = 0 //重置电池
|
||||
|
||||
for i := 400; i < 100; i++ { //每日任务区段
|
||||
for i := 400; i < 500; i++ { //每日任务区段
|
||||
|
||||
if xmlres.TaskMap[i].Type == 1 { //日常任务
|
||||
t.Info.TaskList[i-1] = 0 //重置每日任务
|
||||
t.Service.Task(uint32(i), func(t *model.TaskEX) bool {
|
||||
t.Data = []uint32{}
|
||||
tttL, ok := xmlres.TaskMap[i]
|
||||
if ok {
|
||||
if tttL.Type == 1 { //日常任务
|
||||
t.Info.TaskList[i-1] = 0 //重置每日任务
|
||||
t.Service.Task(uint32(i), func(t *model.TaskEX) bool {
|
||||
t.Data = []uint32{}
|
||||
|
||||
return true
|
||||
return true
|
||||
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -78,8 +82,8 @@ func (h *Controller) Login(data *user.MAIN_LOGIN_IN, c gnet.Conn) (result *user.
|
||||
t.Info.DailyResArr[i] = 0 //重置每日任务
|
||||
|
||||
}
|
||||
t.Service.Talk(func(m *map[uint32]uint32) bool { //挖矿
|
||||
m = &map[uint32]uint32{}
|
||||
t.Service.Talk(func(m map[uint32]uint32) bool { //挖矿
|
||||
m = map[uint32]uint32{}
|
||||
return true
|
||||
})
|
||||
|
||||
|
||||
@@ -542,7 +542,7 @@ func (h Controller) Complete_Task(data *task.CompleteTaskInboundInfo, c *player.
|
||||
for _, v := range result.ItemList {
|
||||
ttt = append(ttt, model.SingleItemInfo{ItemId: v.ItemId, ItemCnt: v.ItemCount})
|
||||
}
|
||||
c.ItemAdd(ttt)
|
||||
c.ItemAdd(ttt...)
|
||||
return result, 0
|
||||
}
|
||||
|
||||
|
||||
@@ -50,3 +50,18 @@ func (h Controller) Aimat(data *user.AimatInboundInfo, c *player.Player) (result
|
||||
|
||||
return ret, -1
|
||||
}
|
||||
func (h Controller) Chat(data *user.ChatInboundInfo, c *player.Player) (result *user.ChatOutboundInfo, err errorcode.ErrorCode) {
|
||||
result = &user.ChatOutboundInfo{
|
||||
|
||||
Message: data.Message,
|
||||
SenderNickname: c.Info.Nick,
|
||||
SenderId: c.Info.UserID,
|
||||
}
|
||||
|
||||
defer space.GetSpace(c.Info.MapID).User.IterCb(func(playerID uint32, v common.PlayerI) {
|
||||
|
||||
v.SendPack(data.Head.Pack(result))
|
||||
})
|
||||
|
||||
return nil, -1
|
||||
}
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
package chat
|
||||
|
||||
import "blazing/logic/service/player"
|
||||
|
||||
type ChatInboundInfo struct {
|
||||
|
||||
|
||||
Head player.TomeeHeader `cmd:"2102" struc:"[0]pad"`
|
||||
Reserve uint32 `json:"reserve" fieldDescription:"填充 默认值为0" uint:"true"` // @UInt long reserve,无符号长整数
|
||||
Message string `json:"message" fieldDescription:"消息内容, 结束符为utf-8的数字0"` // 消息内容,包含utf-8空字符('\x00')作为结束符
|
||||
}
|
||||
21
logic/service/item/buy.go
Normal file
21
logic/service/item/buy.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package item
|
||||
|
||||
import "blazing/logic/service/player"
|
||||
|
||||
type BuyInboundInfo struct {
|
||||
Head player.TomeeHeader `cmd:"2601" struc:"[0]pad"`
|
||||
//物品ID
|
||||
ItemId uint32
|
||||
//物品数量
|
||||
Count uint32
|
||||
}
|
||||
type BuyOutboundInfo struct {
|
||||
//剩余的数量
|
||||
Coins uint32
|
||||
//购买的物品ID
|
||||
ItemId uint32
|
||||
//购买数量
|
||||
Count uint32
|
||||
//购买的物品等级
|
||||
Level uint32
|
||||
}
|
||||
17
logic/service/item/cloth.go
Normal file
17
logic/service/item/cloth.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package item
|
||||
|
||||
import (
|
||||
"blazing/logic/service/player"
|
||||
"blazing/modules/blazing/model"
|
||||
)
|
||||
|
||||
type ChangePlayerClothOutboundInfo struct {
|
||||
UserID uint32 `description:"玩家id" codec:"uint"`
|
||||
ClothesLen uint32 `struc:"sizeof=ClothList" fieldDesc:"穿戴装备的信息" json:"clothes_len"`
|
||||
ClothList []model.PeopleItemInfo `description:"玩家装备列表" codec:"list"` // List<PeopleItemInfo> -> 指针切片
|
||||
}
|
||||
type ChangePlayerClothInboundInfo struct {
|
||||
Head player.TomeeHeader `cmd:"2604" struc:"[0]pad"`
|
||||
ClothesLen uint32 `struc:"sizeof=ClothList" fieldDesc:"穿戴装备的信息" json:"clothes_len"`
|
||||
ClothList []uint32 `description:"玩家装备列表" codec:"list"`
|
||||
}
|
||||
25
logic/service/item/talk.go
Normal file
25
logic/service/item/talk.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package item
|
||||
|
||||
import "blazing/logic/service/player"
|
||||
|
||||
type TalkCountInboundInfo struct {
|
||||
Head player.TomeeHeader `cmd:"2701" struc:"[0]pad"`
|
||||
ID uint32 `description:"奖品的Type, 即ID" codec:"uint"` // @UInt long -> uint64,字段描述对应@FieldDescription
|
||||
}
|
||||
type TalkCountOutboundInfo struct {
|
||||
GiftCount uint32 `description:"已领取奖励的次数" codec:"uint"` // @UInt long -> uint64,字段描述对应@FieldDescription
|
||||
}
|
||||
type TalkCateInboundInfo struct {
|
||||
Head player.TomeeHeader `cmd:"2702" struc:"[0]pad"`
|
||||
ID uint32 `description:"奖品的Type, 即ID" codec:"uint"` // @UInt long -> uint64,字段描述对应@FieldDescription
|
||||
}
|
||||
type DayTalkInfo struct {
|
||||
CateList uint32 `description:"要序列list数量字段 只序列数量 结构体数据给null"` // 对应Java的cateList
|
||||
OutListLen uint32 `struc:"sizeof=OutList"`
|
||||
OutList []CateInfo `description:"实际发放奖励使用的是outlist"` // 对应Java的outList
|
||||
}
|
||||
type CateInfo struct {
|
||||
// 示例字段,需替换为实际定义
|
||||
ID uint32
|
||||
Count uint32
|
||||
}
|
||||
@@ -212,7 +212,7 @@ func replaceOneNumber(original [3]int) ([3]int, int, int) {
|
||||
}
|
||||
|
||||
// 添加物品
|
||||
func (p *Player) ItemAdd(t []model.SingleItemInfo) {
|
||||
func (p *Player) ItemAdd(t ...model.SingleItemInfo) {
|
||||
var ttt []model.SingleItemInfo
|
||||
for _, v := range t {
|
||||
|
||||
|
||||
17
logic/service/user/chat.go
Normal file
17
logic/service/user/chat.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package user
|
||||
|
||||
import "blazing/logic/service/player"
|
||||
|
||||
type ChatInboundInfo struct {
|
||||
Head player.TomeeHeader `cmd:"2102" struc:"[0]pad"`
|
||||
Reserve uint32 `json:"reserve" fieldDescription:"填充 默认值为0" uint:"true"` // @UInt long reserve,无符号长整数
|
||||
MessageLen uint32 `struc:"sizeof=Message"`
|
||||
Message string `json:"message" fieldDescription:"消息内容, 结束符为utf-8的数字0"` // 消息内容,包含utf-8空字符('\x00')作为结束符
|
||||
}
|
||||
type ChatOutboundInfo struct {
|
||||
SenderId uint32 `description:"发送人的米米号" codec:"uint"` // @UInt long -> uint64
|
||||
SenderNickname string `struc:"[16]byte" default:"seer" json:"nick"` // 固定16字节的字符串,对应@ArraySerialize注解
|
||||
ToId uint32 `description:"可能是私聊用的 公屏发送时为0" codec:"uint"` // @UInt long -> uint64
|
||||
MessageLen uint32 `struc:"sizeof=Message"`
|
||||
Message string `description:"这里的内容没有结束符" codec:"string"` // String -> string
|
||||
}
|
||||
@@ -6,14 +6,14 @@ import (
|
||||
|
||||
// TalkCheck 获取玩家当前的Talk数据
|
||||
// todo 待实现xml解析判断是否溢出
|
||||
func (s *UserService) Talk(t func(*map[uint32]uint32) bool) {
|
||||
func (s *UserService) Talk(t func(map[uint32]uint32) bool) {
|
||||
|
||||
m1 := s.Model(s.talk.Model)
|
||||
|
||||
var talks model.TalkEX
|
||||
m1.Scan(&talks)
|
||||
|
||||
ok := t(&talks.Data)
|
||||
ok := t(talks.Data)
|
||||
if ok {
|
||||
m1.Update(talks)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user