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 }