From b6164f3b9e33fa06a522c20c5d1c4ff9ce10836a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=98=94=E5=BF=B5?= <1@72wo.cn> Date: Sat, 23 Aug 2025 17:44:12 +0800 Subject: [PATCH] =?UTF-8?q?feat(logic):=20=E5=AE=9E=E7=8E=B0=E5=9C=B0?= =?UTF-8?q?=E5=9B=BE=E5=88=B7=E6=80=AA=E5=8A=9F=E8=83=BD=E5=B9=B6=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E6=95=B0=E6=8D=AE=E5=BA=93=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在玩家结构中添加 StopChan 通道,用于停止刷怪协程 - 优化 MapEnter 和 MapLeave 函数,支持刷怪功能 - 新增 spawnMonsters 函数实现具体刷怪逻辑 - 优化多个模块的数据库查询语句,提高查询效率 - 调整 PlayerService 中的 Reg 函数,优化数据插入操作 --- common/data/entity/player.go | 1 + logic/controller/map.go | 66 +++++++++++++++---- modules/base/base.go | 1 + modules/base/model/base_sys_menu.go | 2 +- modules/base/service/base_sys_department.go | 2 +- modules/base/service/base_sys_menu.go | 4 +- modules/base/service/base_sys_user.go | 2 +- .../controller/admin/monster_refresh.go | 22 +++++++ modules/blazing/model/monster_refresh.go | 11 ++-- modules/blazing/service/isreg.go | 5 +- modules/blazing/service/monster_refresh.go | 41 ++++++++++++ 11 files changed, 131 insertions(+), 26 deletions(-) create mode 100644 modules/blazing/controller/admin/monster_refresh.go create mode 100644 modules/blazing/service/monster_refresh.go diff --git a/common/data/entity/player.go b/common/data/entity/player.go index 2c9c382d7..142f4cbdc 100644 --- a/common/data/entity/player.go +++ b/common/data/entity/player.go @@ -18,6 +18,7 @@ type Player struct { loginChan chan struct{} // 登录完成通知通道 Nick string //昵称 + StopChan chan struct{} //停止刷怪协程 context.Context } diff --git a/logic/controller/map.go b/logic/controller/map.go index 1e7e70419..209551681 100644 --- a/logic/controller/map.go +++ b/logic/controller/map.go @@ -7,6 +7,7 @@ import ( "blazing/logic/service/maphot" "blazing/logic/service/maps" "blazing/logic/service/space" + mservice "blazing/modules/blazing/service" "time" ) @@ -19,24 +20,31 @@ func (h *Controller) MapEnter(data *maps.InInfo, c *entity.Player) (result *maps tt.Nick = c.Nick tt.Pos = data.Point data.Broadcast(c.MapId, *tt) //同步广播 - go func() { //测试刷怪 + // 如果是无怪地图,直接返回 + + if mservice.NewMonsterService().GetId(c.MapId) == 0 { + return nil, -1 + } + + // 创建新的停止通道 + c.StopChan = make(chan struct{}) + + // 启动刷怪协程 + go func(stopChan chan struct{}, currentMap int) { + ticker := time.NewTicker(5 * time.Second) + defer ticker.Stop() for { - tt := handler.NewTomeeHeader() - tt.CMD = 2004 - tt.Result = 0 - tt.UserID = c.UserID - t1 := maps.OgreInfo{} - for i := 0; i < 9; i++ { - t1.Data[i] = 1 + select { + case <-stopChan: + // 收到停止信号,退出协程 + return + case <-ticker.C: + // 刷新当前地图的怪物 + spawnMonsters(currentMap, c) } - - c.SendPack(tt.Pack(&t1)) - <-time.After(10000 * time.Millisecond) - } - - }() + }(c.StopChan, int(c.MapId)) return nil, -1 } func (h Controller) MapHot(data *maphot.InInfo, c *entity.Player) (result *maphot.OutInfo, err errorcode.ErrorCode) { @@ -52,6 +60,12 @@ func (h *Controller) MapLeave(data *maps.LeaveMapInboundInfo, c *entity.Player) //result = &maps.LeaveMapOutboundInfo{UserID: c.GetUserID()} data.Broadcast(c.MapId, maps.LeaveMapOutboundInfo{UserID: c.GetUserID()}) //同步广播 space.GetSpace(c.MapId).Delete(c.UserID) + // 如果有正在运行的刷怪协程,发送停止信号 + if c.StopChan != nil { + close(c.StopChan) + c.StopChan = nil + } + c.MapId = 0 // 重置当前地图 return nil, -1 } func (h *Controller) MapList(data *maps.ListMapPlayerInboundInfo, c *entity.Player) (result *maps.ListMapPlayerOutboundInfo, err errorcode.ErrorCode) { //这个时候player应该是空的 @@ -66,3 +80,27 @@ func (h *Controller) MapList(data *maps.ListMapPlayerInboundInfo, c *entity.Play result.Player = append(result.Player, *result1) return } + +// 刷怪具体实现 +func spawnMonsters(mapID int, c *entity.Player) { + // 获取当前地图的怪物配置 + + if mservice.NewMonsterService().GetId(c.MapId) == 0 { + return + } + + // 创建数据包 + tt := handler.NewTomeeHeader() + tt.CMD = 2004 + tt.Result = 0 + tt.UserID = c.UserID + + // 设置怪物信息 + t1 := maps.OgreInfo{} + //copy(t1.Data[:], monsterConfig) // 使用地图对应的怪物配置 + for i := 0; i < 9; i++ { + t1.Data[i] = mservice.NewMonsterService().GetId(c.MapId) + } + // 发送数据包 + c.SendPack(tt.Pack(&t1)) +} diff --git a/modules/base/base.go b/modules/base/base.go index f5f59f4bb..13818b3fe 100644 --- a/modules/base/base.go +++ b/modules/base/base.go @@ -32,6 +32,7 @@ func init() { ctx = gctx.GetInitCtx() ) cool.Loger.Debug(ctx, "module base init start ...") + var t bool cool.FillInitData(ctx, "base", &model.BaseSysMenu{}, &t) diff --git a/modules/base/model/base_sys_menu.go b/modules/base/model/base_sys_menu.go index 822ebe9ee..46bc1aff8 100644 --- a/modules/base/model/base_sys_menu.go +++ b/modules/base/model/base_sys_menu.go @@ -10,7 +10,7 @@ type BaseSysMenu struct { ParentID uint `gorm:"column:parentId;type:bigint" json:"parentId"` // 父菜单ID Name string `gorm:"column:name;type:varchar(255);not null" json:"name"` // 菜单名称 Router *string `gorm:"column:router;type:varchar(255)" json:"router"` // 菜单地址 - Perms *string `gorm:"column:perms;type:varchar(255)" json:"perms"` // 权限标识 + Perms *string `gorm:"column:perms;type:text" json:"perms"` // 权限标识 Type int32 `gorm:"column:type;not null" json:"type"` // 类型 0:目录 1:菜单 2:按钮 Icon *string `gorm:"column:icon;type:varchar(255)" json:"icon"` // 图标 OrderNum int32 `gorm:"column:orderNum;type:int;not null;default:0" json:"orderNum"` // 排序 diff --git a/modules/base/service/base_sys_department.go b/modules/base/service/base_sys_department.go index 52639f849..eba851ff3 100644 --- a/modules/base/service/base_sys_department.go +++ b/modules/base/service/base_sys_department.go @@ -33,7 +33,7 @@ func (s *BaseSysDepartmentService) GetByRoleIds(roleIds []string, isAdmin bool) } } else { // 如果不是超级管理员,则返回角色所在部门 - result, _ = cool.DBM(BaseSysRoleDepartment).Where("roleId IN (?)", roleIds).Fields("departmentId").All() + result, _ = cool.DBM(BaseSysRoleDepartment).Where(`"roleId" IN (?)`, roleIds).Fields("departmentId").All() for _, v := range result { vmap := v.Map() if vmap["departmentId"] != nil { diff --git a/modules/base/service/base_sys_menu.go b/modules/base/service/base_sys_menu.go index 890bd875b..64ba7b749 100644 --- a/modules/base/service/base_sys_menu.go +++ b/modules/base/service/base_sys_menu.go @@ -30,7 +30,7 @@ func (s *BaseSysMenuService) GetPerms(roleIds []string) []string { if garray.NewIntArrayFrom(gconv.Ints(roleIds)).Contains(1) { result, _ = m.Fields("a.perms").All() } else { - result, _ = m.InnerJoin("base_sys_role_menu b", "a.id=b.menuId").InnerJoin("base_sys_role c", "b.roleId=c.id").Where("c.id IN (?)", roleIds).Fields("a.perms").All() + result, _ = m.InnerJoin("base_sys_role_menu b", `a.id=b."menuId"`).InnerJoin("base_sys_role c", `b."roleId"=c.id`).Where("c.id IN (?)", roleIds).Fields("a.perms").All() } for _, v := range result { vmap := v.Map() @@ -51,7 +51,7 @@ func (s *BaseSysMenuService) GetMenus(roleIds []string, isAdmin bool) (result gd result, err = m.Group("a.id").Order("a.orderNum", "asc").All() fmt.Println(err) } else { - result, _ = m.InnerJoin("base_sys_role_menu b", "a.id=b.menuId").Where("b.roleId IN (?)", roleIds).Group("a.id").Order("a.orderNum asc").All() + result, _ = m.InnerJoin("base_sys_role_menu b", `a.id=b."menuId"`).Where(`b."roleId" IN (?)`, roleIds).Group("a.id").Order("a.orderNum asc").All() } return diff --git a/modules/base/service/base_sys_user.go b/modules/base/service/base_sys_user.go index fec893acb..66b90ffd5 100644 --- a/modules/base/service/base_sys_user.go +++ b/modules/base/service/base_sys_user.go @@ -204,7 +204,7 @@ func (s *BaseSysUserService) Move(ctx g.Ctx) (err error) { departmentId := request.Get("departmentId").Int() userIds := request.Get("userIds").Slice() - _, err = cool.DBM(s.Model).Where("`id` IN(?)", userIds).Data(g.Map{"departmentId": departmentId}).Update() + _, err = cool.DBM(s.Model).Where("id IN(?)", userIds).Data(g.Map{"departmentId": departmentId}).Update() return } diff --git a/modules/blazing/controller/admin/monster_refresh.go b/modules/blazing/controller/admin/monster_refresh.go new file mode 100644 index 000000000..d3c0b6e42 --- /dev/null +++ b/modules/blazing/controller/admin/monster_refresh.go @@ -0,0 +1,22 @@ +package admin + +import ( + "blazing/cool" + "blazing/modules/blazing/service" +) + +type TaskInfoController struct { + *cool.Controller +} + +func init() { + var task_info_controller = &TaskInfoController{ + &cool.Controller{ + Prefix: "/admin/monster/refresh", + Api: []string{"Add", "Delete", "Update", "Info", "List", "Page"}, + Service: service.NewMonsterService(), + }, + } + // 注册路由 + cool.RegisterController(task_info_controller) +} diff --git a/modules/blazing/model/monster_refresh.go b/modules/blazing/model/monster_refresh.go index 8354bd4e7..6e6604149 100644 --- a/modules/blazing/model/monster_refresh.go +++ b/modules/blazing/model/monster_refresh.go @@ -15,11 +15,12 @@ type MonsterRefresh struct { 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文本,暂定传入时间 + 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 diff --git a/modules/blazing/service/isreg.go b/modules/blazing/service/isreg.go index 0171a281d..3d936c100 100644 --- a/modules/blazing/service/isreg.go +++ b/modules/blazing/service/isreg.go @@ -40,7 +40,7 @@ func (s *PlayerService) IsReg(accountID uint) bool { // 实现注册,id+昵称+颜色 func (s *PlayerService) Reg(accountID uint, nick string, color uint32) { - nick = strings.TrimSpace(nick) + nick = strings.Trim(nick, "\x00") t := model.NewPlayer() t.PlayerID = uint64(accountID) @@ -54,8 +54,9 @@ func (s *PlayerService) Reg(accountID uint, nick string, color uint32) { if err != nil { return } + t.Data = string(t22) - _, err = cool.DBM(s.Model).Data(t).Insert() + _, err = cool.DBM(s.Model).Data(t).FieldsEx("id").Insert() if err != nil { glog.Error(context.Background(), err) return diff --git a/modules/blazing/service/monster_refresh.go b/modules/blazing/service/monster_refresh.go new file mode 100644 index 000000000..1cd9c5981 --- /dev/null +++ b/modules/blazing/service/monster_refresh.go @@ -0,0 +1,41 @@ +package service + +import ( + "blazing/cool" + "blazing/modules/blazing/model" +) + +type MonsterService struct { + *cool.Service +} + +func NewMonsterService() *MonsterService { + return &MonsterService{ + &cool.Service{ + Model: model.NewMonsterRefresh(), + PageQueryOp: &cool.QueryOp{ + FieldEQ: []string{"status", "type"}, + }, + UniqueKey: map[string]string{ + "name": "任务名称不能重复", + }, + }, + } +} +func (s *MonsterService) GetId(mapid uint32) uint32 { + + m := cool.DBM(s.Model).Where("map_id", mapid) + var tt []model.MonsterRefresh + m.Scan(&tt) + + for _, v := range tt { + + if v.MapID == int32(mapid) { + return uint32(v.MonsterID) + + } + + } + return 0 + +}