samba/server/truco/handler/msghandler.go
2025-06-04 09:51:39 +08:00

182 lines
5.8 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 handler
import (
"encoding/json"
"fmt"
"github.com/rabbitmq/amqp091-go"
"os"
"samba/pkg/ksync"
"samba/pkg/log"
"samba/pkg/rmq"
"samba/pkg/servername"
"samba/pkg/service"
"samba/proto"
. "samba/server/game/baseroom"
"samba/server/truco/room"
. "samba/server/truco/service"
"samba/util/config"
"samba/util/playtype"
"samba/util/routingKey"
"samba/util/util"
"time"
)
var MsgHandler = map[string]MessageHandler{
proto.ReqReconnectId: onReconnect,
proto.NtfUserOfflineId: onUserOffline,
proto.ReqMatchRoomId: onMatchRoom,
proto.ReqCancelMatchRoomId: onCancelMatchRoom,
proto.ReqLeaveRoomId: onLeaveRoom,
proto.ReqEnterRoomId: onEnterRoom,
proto.ReqSetPokersId: onSetPokers,
proto.NtfUpdateConfigId: onUpdateConfig,
proto.NtfNewServiceId: onUpdateService,
proto.ReqMatchClubRoomId: onMatchClubRoom,
proto.ReqCancelMatchClubRoomId: onCancelMatchClubRoom,
proto.ReqDisbandRoomId: onDisbandRoom,
proto.ReqUserDisbandRoomId: onUserDisbandRoom,
proto.ReqEnterClubRoomId: onEnterClubRoom,
proto.ReqQuickEnterClubRoomId: onQuickEnterClubRoom,
proto.RspCreatePlayGameId: onCreatePlayGame,
proto.RspDeletePlayGameId: onDelPlayGame,
proto.RspUpdatePlayGameId: onUpdatePlayGame,
proto.RspSetPlayGameValidId: onSetPlayGameValid,
}
type MessageHandler func(d *amqp091.Delivery, msg map[string]interface{})
func RegisterMsgHandler(s service.IService) bool {
//if err := s.QueueBind(QueueName(), routingKey.UserOnline, util.Topic(servername.User)); err != nil {
// log.Error(err.Error())
// return false
//}
if err := s.QueueBind(QueueName(), routingKey.UserOffline, util.Topic(servername.User)); err != nil {
log.Error(err.Error())
return false
}
if err := s.QueueBind(QueueName(), routingKey.CreateClubPlayType, util.Topic(servername.Club)); err != nil {
log.Error(err.Error())
return false
}
//if err := s.QueueBind(QueueName(), routingKey.SystemPublish, util.Topic(servername.User)); err != nil {
// log.Error(err.Error())
// return false
//}
if err := s.QueueBind(QueueName(), routingKey.Truco, util.Direct(servername.Truco)); err != nil {
log.Error(err.Error())
return false
}
if err := s.QueueBind(QueueName(), QueueName(), util.Direct(servername.Truco)); err != nil {
log.Error(err.Error())
return false
}
return true
}
func handlerMessage(_ service.IService, d *amqp091.Delivery) {
var msg map[string]interface{}
if err := json.Unmarshal(d.Body, &msg); err != nil {
log.Error(fmt.Sprintf("consume message error: %v.body:%v", err, string(d.Body)))
return
}
msgId, roomId, uid, _ := ParseMsg(msg)
if fn, ok := MsgHandler[msgId]; ok && fn != nil {
fn(d, msg)
} else {
rm := RoomMgr.Find(roomId)
if rm != nil {
log.Debug(fmt.Sprintf("player:%v recv msgId:%v msg:%v", uid, msgId, string(d.Body)))
rm.OnMessage(msgId, msg)
} else {
log.Error(fmt.Sprintf("room id:%v not exist.msgId:%v", roomId, msgId))
}
}
}
func InitService() {
opts := []service.Option{
service.SetOnInit(func(s service.IService) bool {
if err := s.ExchangeDeclare(util.Direct(servername.Truco), rmq.ExchangeDirect); err != nil {
log.Error(err.Error())
return false
}
if err := s.ExchangeDeclare(util.Topic(servername.Truco), rmq.ExchangeTopic); err != nil {
log.Error(err.Error())
return false
}
if err := s.QueueDeclare(QueueName()); err != nil {
log.Error(err.Error())
}
if !RegisterMsgHandler(s) {
return false
}
if err := s.Consume(QueueName()); err != nil {
log.Error(err.Error())
return false
}
log.Info(fmt.Sprintf("service:%v init.is club:%v", s.Name(), config.Cmd.IsClub > 0))
return true
}),
service.SetOnNotifyStop(func(s service.IService) {
RoomMgr.NotifyStop()
}),
service.SetCanStop(func(s service.IService) bool {
//log.Info(fmt.Sprintf("room count is zero:%v", RoomMgr.IsStopped()))
return RoomMgr.IsStopped()
}),
service.SetOnStop(func(s service.IService) {
if err := s.ConsumeDelete(); err != nil {
log.Error(err.Error())
} else {
log.Info(fmt.Sprintf("delete consume channle"))
}
if err := s.QueueDelete(QueueName()); err != nil {
log.Error(err.Error())
} else {
log.Info(fmt.Sprintf("delete queue:%v", QueueName()))
}
log.Info(fmt.Sprintf("service:%v stop", s.Name()))
}),
}
TrucoService.IService = service.NewService(servername.Truco, QueueName(), config.RabbitmqUrl(), handlerMessage, opts...)
RoomMgr.Init(TrucoService)
RoomMgr.InitCreateClubRooms(room.NewTrucoRoom)
room.GMatchQueue.Matching()
room.GMatchClubQueue.Matching()
room.ClubMatchQueue{}.Matching()
cfg := &config.Cmd
newServiceNtf := &proto.NtfNewService{Type: TrucoService.Type(), RouterKey: QueueName(),
RoomMaxId: cfg.MaxRoomId, RoomMinId: cfg.MinRoomId, IsClub: cfg.IsClub > 0}
newServiceNtf.PlayType = append(newServiceNtf.PlayType, int(playtype.PtPaulistaClean))
newServiceNtf.PlayType = append(newServiceNtf.PlayType, int(playtype.PtPaulistaDirty))
newServiceNtf.PlayType = append(newServiceNtf.PlayType, int(playtype.PtMineiroClean))
newServiceNtf.PlayType = append(newServiceNtf.PlayType, int(playtype.PtMineiroDirty))
SendMsg(util.Direct(servername.Hall), routingKey.Hall, 0, "", 0, proto.NtfNewServiceId, newServiceNtf)
logCurrentRoomCount(TrucoService)
}
func StopService() {
TrucoService.NotifyStop()
TrucoService.WaitStop()
}
func logCurrentRoomCount(s service.IService) {
log.Info(fmt.Sprintf("current room num:%v", RoomMgr.Count()))
if TrucoService.AutoWaitStop {
RoomMgr.DelEmptyRoom()
}
if TrucoService.AutoWaitStop && RoomMgr.Count() == 0 {
log.Info("旧服务且房间数为0自动关闭")
ksync.GoSafe(func() {
StopService()
log.Info("auto exit, initiating shutdown...")
os.Exit(0)
}, nil)
}
s.NewTimer(5*time.Minute, func() { logCurrentRoomCount(s) }, false)
}