package live_logic import ( "dcg/game/manager" "dcg/game/pb" pbCommon "dcg/game/pb/common" pbMq "dcg/game/pb/mq" "dcg/pkg/cmd" ) type ( // liveLogic 直播游戏逻辑 // 处理指令 // 处理礼物 liveLogic struct { gameType string // 游戏类型 preDanmakuHandler PreDanmakuHandlerFunc // 弹幕前置处理 cmdParser *cmd.Parser // 命令解析 cmdHandlerMapper map[string]CMDHandlerFunc // 具体命令处理(同类型) giftHandlers []GiftHandler // 礼物处理 nobilityHandler NobilityHandlerFunc // 贵族购买处理 } ) func NewLiveGameLogic(opts ...LogicOption) LiveLogic { resp := &liveLogic{ cmdHandlerMapper: make(map[string]CMDHandlerFunc), preDanmakuHandler: DefaultPreDanmakuHandlerFunc, giftHandlers: make([]GiftHandler, 0), } for _, opt := range opts { opt(resp) } return resp } func (l *liveLogic) SetGameType(gameType string) { l.gameType = gameType } func (l *liveLogic) SetPreDanmakuHandler(h PreDanmakuHandlerFunc) { l.preDanmakuHandler = h } func (l *liveLogic) SetCmdParser(parser *cmd.Parser) { l.cmdParser = parser } func (l *liveLogic) GameType() string { return l.gameType } func (l *liveLogic) RegisterCMDHandler(h CMDHandlerFunc, cmd string, alias ...string) { if _, ok := l.cmdHandlerMapper[cmd]; ok { return } l.cmdHandlerMapper[cmd] = h // alias for _, s := range alias { if _, ok := l.cmdHandlerMapper[s]; ok { continue } l.cmdHandlerMapper[s] = h } } func (l *liveLogic) RegisterGiftHandler(h GiftHandler) { l.giftHandlers = append(l.giftHandlers, h) } func (l *liveLogic) RegisterNobilityHandler(h NobilityHandlerFunc) { l.nobilityHandler = h } // HandleDanmaku 弹幕数据处理 // pushCommonMsg 非弹幕数据是否转发 func (l *liveLogic) HandleDanmaku(liveRoom *LiveRoom, user *pbCommon.PbUser, dm *pbMq.MqDanmaku) { preResp := PreDanmakuHandlerResp{ PushDanmaku: true, Parsing: true, } if l.preDanmakuHandler != nil { preResp = l.preDanmakuHandler(liveRoom, user, dm) } if l.cmdParser != nil { cmdStruct := l.cmdParser.Parse(dm.Msg) if cmdStruct.IsCMD && preResp.Parsing { for _, m := range cmdStruct.Matches { l.handleCMD(liveRoom, m.Prefix, m.Content, user) } } else if preResp.PushDanmaku { l.pushDanmaku(liveRoom, user, dm.Msg) } } else if preResp.PushDanmaku { l.pushDanmaku(liveRoom, user, dm.Msg) } } func (l *liveLogic) handleCMD(liveRoom *LiveRoom, prefix string, content []rune, user *pbCommon.PbUser) { if h, ok := l.cmdHandlerMapper[prefix]; ok { h(liveRoom, prefix, content, user) } } func (l *liveLogic) pushDanmaku(liveRoom *LiveRoom, user *pbCommon.PbUser, msg string) { room, err := manager.GameManager.RoomByLiveRoom(liveRoom.RoomId, liveRoom.Platform) if err != nil { return } room.Broadcast(pb.PushDanmaku, &pbCommon.DanmakuMsg{ User: user, Content: msg, }) } func (l *liveLogic) HandleGift(liveRoom *LiveRoom, user *pbCommon.PbUser, gift *pbMq.MqGift) { if len(l.giftHandlers) == 0 { return } wrapped := l.wrapGiftHandler(nil, l.giftHandlers) wrapped(liveRoom, user, gift) } // wrapGiftHandler wraps handler and middlewares into a right order call stack. // like: // var wrapped GiftHandlerFunc = m1(m2(m3(handle))) func (l *liveLogic) wrapGiftHandler(handler GiftHandlerFunc, middles []GiftHandler) (wrapped GiftHandlerFunc) { if handler == nil { handler = EmptyGiftHandlerFunc } wrapped = handler for i := len(middles) - 1; i >= 0; i-- { m := middles[i] wrapped = m(wrapped) } return } func (l *liveLogic) HandleNobility(liveRoom *LiveRoom, user *pbCommon.PbUser, msg *pbMq.MqNobilityBuy) { if l.nobilityHandler == nil { return } l.nobilityHandler(liveRoom, user, msg) }