game_sync/worldsrv/horseracelamp.go

415 lines
12 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 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)
}