Files
bl/logic/service/space/boss_time.go
昔念 2ab7f59667 ```
feat(socket): 统一使用 glog.Info 替代 glog.Infof

将 ServerEvent.go 中的 glog.Infof 更改为 glog.Info,以统一日志输出方式并减少格式化开销。

feat(controller): 优化宠物经验设置逻辑与错误码返回

在 SetPetExp 方法中提前返回结果,并修正最终返回的错误码为 ErrSystemError。同时规范化注释格式。

feat(space): 支持天气地图判断与动态天气 BOSS 刷新

引入 lo 包用于查找
2025-12-13 18:35:17 +08:00

225 lines
6.7 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package space
import (
"blazing/cool"
"math/rand"
"strconv"
"strings"
"sync"
"sync/atomic"
"time"
)
// ========== 1. 定义TimeBoss的定时规则补全周四-周六,新增周日规则) ==========
// TimeBossRule 单个BOSS的定时规则
type TimeBossRule struct {
PetID uint32 // BOSS ID对应XML的petID="261"
Week int // 星期1=周一2=周二...7=周日)
ShowHours []int // 出现小时如12,17,18,24周日填0-23表示每小时
ShowMinute int // 出现分钟如35,0
LastTime int // 持续时间(分钟)
MapIDs []uint32 // 可选刷新地图ID列表随机选一个
}
// 全局261号BOSS的规则配置补全周四-周六,新增周日)
var timeBossRules = []TimeBossRule{
// 周一规则
{
PetID: 261,
Week: 1, // 周一
ShowHours: []int{12, 17, 18, 24}, // 12|17|18|24点35分
ShowMinute: 35, // 35分
LastTime: 40, // 持续40分钟
MapIDs: []uint32{15, 105, 54}, // 随机选一个地图
},
// 周二规则
{
PetID: 261,
Week: 2, // 周二
ShowHours: []int{17, 18, 24}, // 17|18|24点0分
ShowMinute: 0, // 0分
LastTime: 5, // 持续5分钟
MapIDs: []uint32{15, 105, 54},
},
// 周三规则
{
PetID: 261,
Week: 3, // 周三
ShowHours: []int{17, 18, 24}, // 17|18|24点0分
ShowMinute: 0, // 0分
LastTime: 5, // 持续5分钟
MapIDs: []uint32{15, 105, 54},
},
// 周四规则(和周一完全一致)
{
PetID: 261,
Week: 4, // 周四
ShowHours: []int{12, 17, 18, 24}, // 12|17|18|24点35分
ShowMinute: 35, // 35分
LastTime: 40, // 持续40分钟
MapIDs: []uint32{15, 105, 54},
},
// 周五规则(和周二完全一致)
{
PetID: 261,
Week: 5, // 周五
ShowHours: []int{17, 18, 24}, // 17|18|24点0分
ShowMinute: 0, // 0分
LastTime: 5, // 持续5分钟
MapIDs: []uint32{15, 105, 54},
},
// 周六规则(和周三完全一致)
{
PetID: 261,
Week: 6, // 周六
ShowHours: []int{17, 18, 24}, // 17|18|24点0分
ShowMinute: 0, // 0分
LastTime: 5, // 持续5分钟
MapIDs: []uint32{15, 105, 54},
},
// 周日规则特殊每小时刷新持续10分钟
{
PetID: 261,
Week: 7, // 周日
ShowHours: generateHourRange(0, 23), // 0-23点每小时
ShowMinute: 0, // 每小时0分触发
LastTime: 10, // 持续10分钟
MapIDs: []uint32{15, 105, 54}, // 随机选一个地图
},
}
// ========== 2. 全局变量(无修改,新增随机数生成器已存在) ==========
var (
registeredCronIDs = make(map[string]bool) // 记录已注册的Cron任务ID
cronMu sync.Mutex // 保护registeredCronIDs的互斥锁
randSource = rand.New(rand.NewSource(time.Now().UnixNano())) // 安全的随机数生成器
)
// ========== 3. 工具函数生成0-23小时数组适配周日每小时规则 ==========
// generateHourRange 生成从start到end的连续小时数组如0-23
func generateHourRange(start, end int) []int {
hours := make([]int, 0, end-start+1)
for i := start; i <= end; i++ {
hours = append(hours, i)
}
return hours
}
// ========== 4. 原有方法gettimeboss无修改自动适配新规则 ==========
func init() { // 忽略传入的mapid随机选地图
// 遍历所有TimeBoss规则包含周四-周六-周日)
for _, rule := range timeBossRules {
// 为该规则的每个小时生成Cron任务
for _, hour := range rule.ShowHours {
// 生成唯一Cron任务ID避免重复注册
cronID := genCronTaskID(rule.PetID, rule.Week, hour, rule.ShowMinute)
cronMu.Lock()
if registeredCronIDs[cronID] {
cronMu.Unlock()
continue // 已注册过,跳过
}
registeredCronIDs[cronID] = true
cronMu.Unlock()
// 转换规则为Cron表达式
cronExpr := genCronExpr(rule.Week, hour, rule.ShowMinute)
// 捕获当前循环的rule避免闭包引用同一变量
currentRule := rule
// 注册Cron定时任务
cool.Cron.AddFunc(cronExpr, func() {
// 1. 随机选一个地图ID
randomMapID := getRandomMapID(currentRule.MapIDs)
if randomMapID == 0 {
return // 无可用地图,跳过
}
sp := GetSpace(randomMapID)
if sp != nil {
// 2. 显示BOSS指定随机地图广播
sp.refushgaiya(true)
// 3. 启动定时器持续时间到后隐藏BOSS同样指定地图
time.AfterFunc(time.Duration(currentRule.LastTime)*time.Minute, func() {
sp.refushgaiya(false)
})
}
})
}
}
}
// ========== 5. 修改后的refushgaiya指定地图广播 ==========
func (s *Space) refushgaiya(vis bool) {
if !vis {
atomic.StoreUint32(&s.TimeBoss.Flag, 0)
} else {
atomic.StoreUint32(&s.TimeBoss.Flag, 1)
}
atomic.StoreUint32(&s.TimeBoss.ID, 261)
// 只向指定地图广播(核心:不再全局广播)
s.Broadcast(nil, 2022, &s.TimeBoss)
}
// ========== 6. 工具函数(无修改,自动适配周日规则) ==========
// getRandomMapID 从地图列表中随机选一个
func getRandomMapID(mapIDs []uint32) uint32 {
if len(mapIDs) == 0 {
return 0
}
return mapIDs[randSource.Intn(len(mapIDs))]
}
// genCronExpr 生成Cron表达式自动适配周日的0值
func genCronExpr(week, hour, minute int) string {
// 1. 处理小时24点转为0点Cron小时范围0-23
cronHour := hour
if cronHour == 24 {
cronHour = 0
}
// 2. 处理星期XML的7=周日 → Cron的0=周日,其余直接用
cronWeek := week
if cronWeek == 7 {
cronWeek = 0
}
// 3. 生成Cron表达式秒 分 时 日 月 周)
return strings.Join([]string{
"0", // 秒固定0整分触发
strconv.Itoa(minute), // 分
strconv.Itoa(cronHour), // 时
"?", // 日(不指定)
"*", // 月(每月)
strconv.Itoa(cronWeek), // 周
}, " ")
}
// genCronTaskID 生成唯一的Cron任务ID
func genCronTaskID(petID uint32, week, hour, minute int) string {
return strings.Join([]string{
strconv.FormatUint(uint64(petID), 10),
strconv.Itoa(week),
strconv.Itoa(hour),
strconv.Itoa(minute),
}, "_")
}
// containsMapID 检查mapid是否在列表中备用
func containsMapID(mapIDs []uint32, mapid uint32) bool {
for _, id := range mapIDs {
if id == mapid {
return true
}
}
return false
}