samba/server/truco/handler/msghandler.go

182 lines
5.8 KiB
Go
Raw Normal View History

2025-06-04 09:51:39 +08:00
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)
}