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/game/srvdata" "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 ) const ( MAX_GAMENOTICE_PER_PLATFORM = 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 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 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) WordCheck(content string) string { // has := srvdata.HasSensitiveWord([]rune(content)) // if has { // content = string(srvdata.ReplaceSensitiveWord([]rune(content))[:]) // } // return content //} func (this *HorseRaceLampMgr) IsSensitiveWord(content string) bool { return srvdata.HasSensitiveWord([]rune(content)) } 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.Platform, horseRaceLamp.Target, int(message.MSGPacketID_PACKET_SC_NOTICE), rawpack) } } func init() { module.RegisteModule(HorseRaceLampMgrSington, time.Second*3, 0) RegisterParallelLoadFunc("平台通知", func() error { HorseRaceLampMgrSington.InitHorseRaceLamp() return nil }) }