You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

148 lines
3.7 KiB
Go

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)
}