package main import ( "github.com/globalsign/mgo/bson" "math" "mongo.games.com/game/model" "mongo.games.com/game/proto" "mongo.games.com/game/protocol/message" "mongo.games.com/goserver/core/logger" "mongo.games.com/goserver/core/module" "strings" "time" ) // 0] "%s" // 5] "玩家 %s 在 %s 中获得了 %s元 ,进入游戏即可参与!" // 6] "玩家 在 %s 中获得了爆池奖励 %s元 ,进入游戏即可参与!" // 10] "恭喜 %s 在 %s 游戏内获得jackpot %s ,中奖金额【 %s】" // 11] "恭喜 %s 击杀 %s %s 获得 %s奖励" const ( //消息类型 0:标示消息内容为服务端拼装好的字符串 //1-99:根据客户端配置的编号格式化参数组成完整的消息内容(详见:HorseRaceLampMsgType) //100:弹幕跑马灯 HorseRaceLampType_ServerStr = 0 HorseRaceLampType_CoinNormal = 5 HorseRaceLampType_CoinReward = 6 HorseRaceLampType_CustomMsg = 100 ) var HorseRaceLampMgrSington = &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:跑马灯数据; 所有平台数据 HorseRaceLampGameList map[string][]*HorseRaceLamp // 平台:跑马灯 HorseRaceLampCastList map[string]*HorseRaceLampCastInfo // 平台:跑马灯 NextGameHorseRaceLamp map[string]int64 } type HorseRaceLamp struct { Key string Channel string Title string Content string Footer string StartTime int64 Interval int32 limitInterval int32 Count int32 // bo LastTime int64 Priority int32 CreateTime int64 MsgType int32 Platform string State int32 isRob bool Target []int32 StandSec 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 { msg := &HorseRaceLamp{ Key: value.Id.Hex(), Channel: value.Channel, Content: value.Content, StartTime: value.StartTime, Interval: value.Interval, Count: value.Count, MsgType: value.MsgType, Priority: value.Priority, CreateTime: value.CreateTime, Platform: value.Platform, State: value.State, Target: value.Target, StandSec: value.StandSec, limitInterval: int32(math.Floor(float64(len(value.Content))*0.3)) + 6, } this.HorseRaceLampMsgList[value.Id.Hex()] = msg this.insertToCastMsg(msg) } } } func (this *HorseRaceLampMgr) AddHorseRaceLampMsg(key, ch, p, title, content, footer string, startTime int64, interval, count, msgType, state, priority int32, createTime int64, target []int32, standSec int32) string { msg := &HorseRaceLamp{ Key: key, Channel: ch, Title: title, Content: content, Footer: footer, StartTime: startTime, Interval: interval, Count: count, MsgType: msgType, Priority: priority, CreateTime: createTime, Platform: p, State: state, Target: target, StandSec: standSec, } this.HorseRaceLampMsgList[key] = msg this.insertToCastMsg(msg) return key } 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{}, } } else { switch msg.MsgType { case HorseRaceLampType_CustomMsg: this.HorseRaceLampCastList[pKey].DealList = append(this.HorseRaceLampCastList[pKey].DealList, msg) default: this.HorseRaceLampCastList[pKey].DealQueue = append(this.HorseRaceLampCastList[pKey].DealQueue, msg) } } } 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 != HorseRaceLampType_CustomMsg { pInfo.CurTime = 0 pInfo.CurIndex = 0 } return true } 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) } func (this *HorseRaceLampMgr) PushGameHorseRaceLamp(ch, platform, content string, msgType int32, isRob bool, priority int32) bool { msg := &HorseRaceLamp{ Channel: ch, Content: content, Count: 1, MsgType: msgType, Platform: platform, Priority: priority, limitInterval: int32(math.Floor(float64(len(content))*0.3)) + 6, isRob: isRob, } 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 } 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) } } // ////////////////////////////////////////////////////////////////// // / Module Implement [HorseRaceLampMgr] // ////////////////////////////////////////////////////////////////// func (this *HorseRaceLampMgr) ModuleName() string { return "HorseRaceLampMgr" } func (this *HorseRaceLampMgr) Init() { } 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: "", Title: hrl.Title, Content: hrl.Content, Footer: hrl.Footer, 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.Target, StandSec: hrl.StandSec, }) } } func (this *HorseRaceLampMgr) Shutdown() { this.SaveHorseRaceLamp() module.UnregisteModule(this) } func (this *HorseRaceLampMgr) BroadcastHorseRaceLampMsg(horseRaceLamp *HorseRaceLamp) { if horseRaceLamp.MsgType == HorseRaceLampType_CustomMsg { logger.Logger.Infof(">>>>>>>弹幕>>>>>>>>(this *HorseRaceLampMgr) BroadcastHorseRaceLampMsg content:%v msgType:%v "+ "target:%v standSec:%v", horseRaceLamp.Content, horseRaceLamp.MsgType, horseRaceLamp.Target, 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.Target) == 0 { PlayerMgrSington.BroadcastMessageToPlatform(horseRaceLamp.Platform, int(message.MSGPacketID_PACKET_SC_NOTICE), rawpack) } else { PlayerMgrSington.BroadcastMessageToTarget(horseRaceLamp.Target, int(message.MSGPacketID_PACKET_SC_NOTICE), rawpack) } } func init() { module.RegisteModule(HorseRaceLampMgrSington, time.Second*3, 0) }