415 lines
12 KiB
Go
415 lines
12 KiB
Go
package main
|
||
|
||
import (
|
||
"math"
|
||
"strings"
|
||
"time"
|
||
|
||
"github.com/globalsign/mgo/bson"
|
||
"mongo.games.com/goserver/core/logger"
|
||
|
||
"mongo.games.com/game/model"
|
||
"mongo.games.com/game/proto"
|
||
"mongo.games.com/game/protocol/message"
|
||
)
|
||
|
||
const (
|
||
HorseRaceLampTypeServer = iota
|
||
HorseRaceLampTypeLottery // 竞技馆抽奖活动中奖消息
|
||
|
||
HorseRaceLampTypeBatch = 100 // 弹幕跑马灯
|
||
)
|
||
|
||
var HorseRaceLampMgrSingleton = &HorseRaceLampMgr{
|
||
HorseRaceLampMsgList: make(map[string]*HorseRaceLamp),
|
||
HorseRaceLampGameList: make(map[string][]*HorseRaceLamp),
|
||
HorseRaceLampCastList: make(map[string]*HorseRaceLampCastInfo),
|
||
NextGameHorseRaceLamp: make(map[string]int64),
|
||
}
|
||
|
||
type HorseRaceLampMgr struct {
|
||
HorseRaceLampMsgList map[string]*HorseRaceLamp // _id:所有平台跑马灯数据
|
||
HorseRaceLampCastList map[string]*HorseRaceLampCastInfo // 平台:跑马灯(队列跑马灯+弹幕跑马灯)
|
||
HorseRaceLampGameList map[string][]*HorseRaceLamp // 平台:游戏跑马灯,只播一次,播完删除
|
||
NextGameHorseRaceLamp map[string]int64 // 平台:下次游戏跑马灯播放时间
|
||
}
|
||
|
||
type HorseRaceLamp struct {
|
||
Platform string // 平台
|
||
Key string // _id
|
||
Channel string // 包渠道
|
||
Title string // 标题
|
||
Content string // 内容
|
||
StartTime int64 // 开始播放的时间
|
||
Interval int32 // 播放间隔
|
||
Count int32 // 播放次数
|
||
LastTime int64 // 上次播放时间
|
||
Priority int32 // 播放优先级
|
||
CreateTime int64 // 创建时间
|
||
MsgType int32 // 消息类型
|
||
State int32 // 状态 0.启用;1.关闭
|
||
Players []int32 // 玩家
|
||
StandSec int32 // 保持时间
|
||
|
||
isRob bool // 是否是机器人
|
||
limitInterval int32 // 播放需要的时间
|
||
}
|
||
|
||
type HorseRaceLampCastInfo struct {
|
||
CurIndex int // 队列跑马灯当前索引
|
||
CurTime int64 // 队列跑马灯当下次检测时间(时间间隔是上一个跑马灯播放需要的时间)
|
||
DealQueue []*HorseRaceLamp // 队列跑马灯,按顺序播放
|
||
DealList []*HorseRaceLamp // 弹幕跑马灯列表
|
||
}
|
||
|
||
func (this *HorseRaceLampMgr) InitHorseRaceLamp() {
|
||
for _, p := range PlatformMgrSingleton.GetPlatforms() {
|
||
noticeList, err := model.GetAllHorseRaceLamp(p.IdStr)
|
||
if err != nil {
|
||
logger.Logger.Error("InitHorseRaceLamp count failed:", err, noticeList)
|
||
}
|
||
|
||
for _, value := range noticeList {
|
||
this.AddHorseRaceLampMsg(&HorseRaceLampParam{
|
||
Platform: value.Platform,
|
||
Key: value.Id.Hex(),
|
||
AppChannel: value.Channel,
|
||
Title: value.Title,
|
||
Content: value.Content,
|
||
StartTime: value.StartTime,
|
||
Interval: value.Interval,
|
||
Count: value.Count,
|
||
MsgType: value.MsgType,
|
||
State: value.State,
|
||
Priority: value.Priority,
|
||
Players: value.Target,
|
||
StandSec: value.StandSec,
|
||
})
|
||
}
|
||
}
|
||
}
|
||
|
||
func (this *HorseRaceLampMgr) insertToCastMsg(msg *HorseRaceLamp) {
|
||
pKey := msg.Platform
|
||
if this.HorseRaceLampCastList[pKey] == nil {
|
||
this.HorseRaceLampCastList[pKey] = &HorseRaceLampCastInfo{
|
||
CurIndex: 0,
|
||
CurTime: 0,
|
||
DealQueue: []*HorseRaceLamp{},
|
||
DealList: []*HorseRaceLamp{},
|
||
}
|
||
}
|
||
|
||
switch msg.MsgType {
|
||
case HorseRaceLampTypeBatch:
|
||
this.HorseRaceLampCastList[pKey].DealList = append(this.HorseRaceLampCastList[pKey].DealList, msg)
|
||
default:
|
||
this.HorseRaceLampCastList[pKey].DealQueue = append(this.HorseRaceLampCastList[pKey].DealQueue, msg)
|
||
}
|
||
}
|
||
|
||
type HorseRaceLampParam struct {
|
||
Platform string
|
||
Key string
|
||
AppChannel string
|
||
Title string
|
||
Content string
|
||
StartTime int64 // 开始时间
|
||
Interval int32 // 播放间隔,秒
|
||
Count int32 // 播放次数
|
||
MsgType int32 // 消息类型
|
||
State int32 // 状态 0.启用;1.关闭
|
||
Priority int32 // 优先级
|
||
Players []int32 // 玩家
|
||
StandSec int32 // 保持时间
|
||
}
|
||
|
||
// AddHorseRaceLampMsg 添加跑马灯
|
||
func (this *HorseRaceLampMgr) AddHorseRaceLampMsg(param *HorseRaceLampParam) string {
|
||
msg := &HorseRaceLamp{
|
||
Key: param.Key,
|
||
Channel: param.AppChannel,
|
||
Title: param.Title,
|
||
Content: param.Content,
|
||
StartTime: param.StartTime,
|
||
Interval: param.Interval,
|
||
Count: param.Count,
|
||
MsgType: param.MsgType,
|
||
Priority: param.Priority,
|
||
CreateTime: time.Now().Unix(),
|
||
Platform: param.Platform,
|
||
State: param.State,
|
||
Players: param.Players,
|
||
StandSec: param.StandSec,
|
||
limitInterval: int32(math.Floor(float64(len(param.Content))*0.3)) + 6,
|
||
}
|
||
this.HorseRaceLampMsgList[param.Key] = msg
|
||
this.insertToCastMsg(msg)
|
||
return param.Key
|
||
}
|
||
|
||
// EditHorseRaceLampMsg 修改跑马灯
|
||
func (this *HorseRaceLampMgr) EditHorseRaceLampMsg(hrl *HorseRaceLamp) bool {
|
||
if _, ok := this.HorseRaceLampMsgList[hrl.Key]; !ok {
|
||
return false
|
||
}
|
||
hrl.limitInterval = int32(math.Floor(float64(len(hrl.Content))*0.3)) + 6
|
||
this.HorseRaceLampMsgList[hrl.Key] = hrl
|
||
|
||
if pInfo, ok := this.HorseRaceLampCastList[hrl.Platform]; ok && hrl.MsgType != HorseRaceLampTypeBatch {
|
||
pInfo.CurTime = 0
|
||
pInfo.CurIndex = 0
|
||
}
|
||
return true
|
||
}
|
||
|
||
// DelHorseRaceLampMsg 删除跑马灯
|
||
func (this *HorseRaceLampMgr) DelHorseRaceLampMsg(key string) {
|
||
if needDel, ok := this.HorseRaceLampMsgList[key]; ok {
|
||
if pInfo, ok := this.HorseRaceLampCastList[needDel.Platform]; ok {
|
||
pInfo.CurTime = 0
|
||
pInfo.CurIndex = 0
|
||
for index := range pInfo.DealQueue {
|
||
if pInfo.DealQueue[index] == needDel {
|
||
pInfo.DealQueue = append(pInfo.DealQueue[:index], pInfo.DealQueue[index+1:]...)
|
||
break
|
||
}
|
||
}
|
||
for index := range pInfo.DealList {
|
||
if pInfo.DealList[index] == needDel {
|
||
pInfo.DealList = append(pInfo.DealList[:index], pInfo.DealList[index+1:]...)
|
||
break
|
||
}
|
||
}
|
||
}
|
||
}
|
||
delete(this.HorseRaceLampMsgList, key)
|
||
}
|
||
|
||
type GameHorseRaceLampParam struct {
|
||
Platform string // 平台
|
||
AppChannel string // 包渠道
|
||
Content string // 内容
|
||
MsgType int32 // 消息类型
|
||
IsRobot bool // 是否是机器人消息
|
||
Priority int32 // 优先级
|
||
}
|
||
|
||
// PushGameHorseRaceLamp 推送游戏跑马灯
|
||
func (this *HorseRaceLampMgr) PushGameHorseRaceLamp(param *GameHorseRaceLampParam) bool {
|
||
msg := &HorseRaceLamp{
|
||
Platform: param.Platform,
|
||
Content: param.Content,
|
||
Count: 1,
|
||
MsgType: param.MsgType,
|
||
Priority: param.Priority,
|
||
limitInterval: int32(math.Floor(float64(len(param.Content))*0.3)) + 6,
|
||
isRob: param.IsRobot,
|
||
}
|
||
|
||
platform := param.Platform
|
||
isRob := param.IsRobot
|
||
priority := param.Priority
|
||
|
||
if pool, exist := this.HorseRaceLampGameList[platform]; exist {
|
||
if len(pool) >= model.GameParamData.BacklogGameHorseRaceLamp && len(pool) > 0 {
|
||
minRobPriority := priority
|
||
minPlayerPriority := priority
|
||
bestRobIdx := -1
|
||
bestPlayerIdx := -1
|
||
for k, v := range pool {
|
||
if !isRob {
|
||
if v.isRob { //优先替换机器人的跑马灯
|
||
if v.Priority <= minRobPriority {
|
||
bestRobIdx = k
|
||
minRobPriority = v.Priority
|
||
}
|
||
} else { //其次替换真实玩家的跑马灯
|
||
if v.Priority < minPlayerPriority {
|
||
bestPlayerIdx = k
|
||
minPlayerPriority = v.Priority
|
||
}
|
||
}
|
||
} else {
|
||
if v.isRob {
|
||
if v.Priority < minRobPriority {
|
||
bestRobIdx = k
|
||
minRobPriority = v.Priority
|
||
}
|
||
}
|
||
}
|
||
}
|
||
if bestRobIdx != -1 { //优先替换机器人的跑马灯
|
||
pool = append(pool[:bestRobIdx], pool[bestRobIdx+1:]...)
|
||
} else if bestPlayerIdx != -1 { //其次替换玩家的跑马灯
|
||
pool = append(pool[:bestPlayerIdx], pool[bestPlayerIdx+1:]...)
|
||
} else { //没找到要替换的,直接丢弃自己的
|
||
return false
|
||
}
|
||
}
|
||
|
||
if !isRob {
|
||
// 替换一个机器人的消息,没有机器人则追加
|
||
isFindRob := false
|
||
if len(pool) > 0 {
|
||
for k, v := range pool {
|
||
if v.isRob {
|
||
pool[k] = msg
|
||
isFindRob = true
|
||
break
|
||
}
|
||
}
|
||
}
|
||
if isFindRob {
|
||
this.HorseRaceLampGameList[platform] = pool
|
||
} else {
|
||
this.HorseRaceLampGameList[platform] = append(pool, msg)
|
||
}
|
||
} else {
|
||
// 是机器人直接追加
|
||
this.HorseRaceLampGameList[platform] = append(pool, msg)
|
||
}
|
||
} else {
|
||
this.HorseRaceLampGameList[platform] = []*HorseRaceLamp{msg}
|
||
}
|
||
return true
|
||
}
|
||
|
||
// DealHorseRaceLamp 广播跑马灯
|
||
func (this *HorseRaceLampMgr) DealHorseRaceLamp(uTime int64, value *HorseRaceLamp) {
|
||
if value.Count > 0 { // 播放次数
|
||
this.BroadcastHorseRaceLampMsg(value)
|
||
value.Count = value.Count - 1
|
||
value.LastTime = uTime
|
||
value.StartTime = value.LastTime + int64(value.Interval)
|
||
if value.Count <= 0 {
|
||
this.DelHorseRaceLampMsg(value.Key)
|
||
model.RemoveHorseRaceLamp(value.Key, value.Platform)
|
||
}
|
||
} else {
|
||
this.BroadcastHorseRaceLampMsg(value)
|
||
value.LastTime = uTime
|
||
value.StartTime = value.LastTime + int64(value.Interval)
|
||
}
|
||
}
|
||
|
||
func (this *HorseRaceLampMgr) ModuleName() string {
|
||
return "HorseRaceLampMgr"
|
||
}
|
||
|
||
func (this *HorseRaceLampMgr) Init() {
|
||
//this.InitHorseRaceLamp()
|
||
}
|
||
|
||
func (this *HorseRaceLampMgr) Update() {
|
||
uTime := time.Now().Unix()
|
||
// 队列跑马灯
|
||
for _, v := range this.HorseRaceLampCastList {
|
||
if uTime > v.CurTime {
|
||
if v.CurIndex < len(v.DealQueue) {
|
||
value := v.DealQueue[v.CurIndex]
|
||
//需要跳过
|
||
if value.State != 0 {
|
||
v.CurIndex += 1
|
||
if v.CurIndex >= len(v.DealQueue) {
|
||
v.CurIndex = 0
|
||
}
|
||
} else if uTime > value.StartTime && value.State == 0 {
|
||
this.DealHorseRaceLamp(uTime, value)
|
||
v.CurIndex += 1
|
||
if v.CurIndex >= len(v.DealQueue) {
|
||
v.CurIndex = 0
|
||
}
|
||
v.CurTime = uTime + int64(value.limitInterval)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
// 弹幕跑马灯
|
||
for _, nc := range this.HorseRaceLampCastList {
|
||
for _, value := range nc.DealList {
|
||
if uTime > value.StartTime && value.State == 0 {
|
||
this.DealHorseRaceLamp(uTime, value)
|
||
}
|
||
}
|
||
}
|
||
// 游戏跑马灯,只播一次
|
||
for name, pool := range this.HorseRaceLampGameList {
|
||
if len(pool) > 0 {
|
||
msg := pool[0]
|
||
nextTs := this.NextGameHorseRaceLamp[name]
|
||
if uTime >= nextTs {
|
||
this.HorseRaceLampGameList[name] = pool[1:]
|
||
if msg != nil {
|
||
this.BroadcastHorseRaceLampMsg(msg)
|
||
this.NextGameHorseRaceLamp[name] = uTime + int64(msg.limitInterval)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
func (this *HorseRaceLampMgr) SaveHorseRaceLamp() {
|
||
for _, hrl := range this.HorseRaceLampMsgList {
|
||
model.EditHorseRaceLamp(&model.HorseRaceLamp{
|
||
Id: bson.ObjectIdHex(hrl.Key),
|
||
Channel: hrl.Channel,
|
||
Title: hrl.Title,
|
||
Content: hrl.Content,
|
||
StartTime: hrl.StartTime,
|
||
Interval: hrl.Interval,
|
||
Count: hrl.Count,
|
||
CreateTime: hrl.CreateTime,
|
||
Priority: hrl.Priority,
|
||
MsgType: hrl.MsgType,
|
||
Platform: hrl.Platform,
|
||
State: hrl.State,
|
||
Target: hrl.Players,
|
||
StandSec: hrl.StandSec,
|
||
})
|
||
}
|
||
}
|
||
|
||
func (this *HorseRaceLampMgr) Shutdown() {
|
||
//this.SaveHorseRaceLamp()
|
||
//module.UnregisteModule(this)
|
||
}
|
||
|
||
func (this *HorseRaceLampMgr) BroadcastHorseRaceLampMsg(horseRaceLamp *HorseRaceLamp) {
|
||
if horseRaceLamp.MsgType == HorseRaceLampTypeBatch {
|
||
logger.Logger.Infof(">>>>>>>弹幕>>>>>>>>(this *HorseRaceLampMgr) BroadcastHorseRaceLampMsg content:%v msgType:%v "+
|
||
"players:%v standSec:%v", horseRaceLamp.Content, horseRaceLamp.MsgType, horseRaceLamp.Players, horseRaceLamp.StandSec)
|
||
}
|
||
var rawpack = &message.SCNotice{
|
||
Count: proto.Int(1),
|
||
MsgType: proto.Int32(horseRaceLamp.MsgType),
|
||
Ts: proto.Int64(time.Now().Unix()), //发送时间
|
||
ChannelId: proto.String(horseRaceLamp.Channel),
|
||
Platform: proto.String(horseRaceLamp.Platform),
|
||
StandSec: proto.Int32(horseRaceLamp.StandSec),
|
||
}
|
||
if horseRaceLamp.MsgType == 0 {
|
||
rawpack.Params = append(rawpack.Params, &message.NoticeParam{StrParam: proto.String(horseRaceLamp.Content)})
|
||
} else if horseRaceLamp.MsgType > 0 && horseRaceLamp.MsgType < 100 {
|
||
strArr := strings.Split(horseRaceLamp.Content, "|")
|
||
for _, value := range strArr {
|
||
rawpack.Params = append(rawpack.Params, &message.NoticeParam{StrParam: proto.String(value)})
|
||
}
|
||
} else if horseRaceLamp.MsgType == 100 {
|
||
rawpack.Params = append(rawpack.Params, &message.NoticeParam{StrParam: proto.String(horseRaceLamp.Title)})
|
||
rawpack.Params = append(rawpack.Params, &message.NoticeParam{StrParam: proto.String(horseRaceLamp.Content)})
|
||
//rawpack.Params = append(rawpack.Params, &message.NoticeParam{StrParam: proto.String(horseRaceLamp.Footer)})
|
||
}
|
||
|
||
proto.SetDefaults(rawpack)
|
||
if len(horseRaceLamp.Players) == 0 {
|
||
PlayerMgrSington.BroadcastMessageToPlatform(horseRaceLamp.Platform, int(message.MSGPacketID_PACKET_SC_NOTICE), rawpack)
|
||
} else {
|
||
PlayerMgrSington.BroadcastMessageToTarget(horseRaceLamp.Players, int(message.MSGPacketID_PACKET_SC_NOTICE), rawpack)
|
||
}
|
||
}
|
||
|
||
func init() {
|
||
//module.RegisteModule(HorseRaceLampMgrSingleton, time.Second*3, 0)
|
||
}
|