samba/server/hall/handler/hallHandler.go

219 lines
6.0 KiB
Go
Raw Normal View History

2025-06-04 09:51:39 +08:00
package handler
import (
"fmt"
"github.com/golang-module/carbon/v2"
"github.com/rabbitmq/amqp091-go"
"samba/pkg/log"
"samba/pkg/xtime"
"samba/proto"
"samba/stub"
"samba/util/model"
"samba/util/routingKey"
"samba/util/util"
"strconv"
"time"
)
func onUserOnline(_ *amqp091.Delivery, msg map[string]interface{}) {
_, _, _, data := ParseMsg(msg)
req, err := util.MapToStructT[proto.UserOnline](data)
if err != nil {
log.Error(err.Error())
return
}
uid, _ := strconv.ParseInt(req.Uid, 10, 64)
log.Debug(fmt.Sprintf("玩家上线:%v", uid))
model.AddOnlineUser(uid)
SendMsgToGate(uid, proto.RspLoginSuccessId, &proto.RspLoginSuccess{})
model.RecordUserOnline(uid)
// 玩法服如需处理玩家上线消息自己单独监听该消息就OK
//gs := GameServerMgr.AllServer()
//for _, s := range gs {
// SendMsg(util.Direct(s.Type), s.RouterKey, "", uid, proto.NtfUserOnlineId, req)
//}
}
func onUserOffline(_ *amqp091.Delivery, msg map[string]interface{}) {
_, _, _, data := ParseMsg(msg)
req, err := util.MapToStructT[proto.UserOnline](data)
if err != nil {
log.Error(err.Error())
return
}
uid, _ := strconv.ParseInt(req.Uid, 10, 64)
log.Debug(fmt.Sprintf("玩家下线:%v", uid))
model.DelOnlineUser(uid)
model.RecordUserOffline(uid, MatchService)
}
func onUpdateService(_ *amqp091.Delivery, msg map[string]interface{}) {
_, _, _, data := ParseMsg(msg)
ntf, err := util.MapToStructT[proto.NtfNewService](data)
if err != nil {
log.Error(err.Error())
return
}
GameServerMgr.Update(ntf)
for _, gs := range GameServerMgr.gameServers {
if gs.Type == ntf.Type && gs.IsClub == ntf.IsClub {
SendMsg(util.Direct(gs.Type), gs.RouterKey, "", 0, proto.NtfNewServiceId, ntf)
}
}
log.Debug(fmt.Sprintf("更新服务:%+v", ntf))
}
func onUserReconnect(_ *amqp091.Delivery, msg map[string]interface{}) {
_, _, uid, data := ParseMsg(msg)
req, err := util.MapToStructT[proto.ReqReconnect](data)
if err != nil {
log.Error(err.Error())
return
}
gs := GameServerMgr.FindByRoomId(req.RoomId)
if gs != nil {
SendMsg(util.Direct(gs.Type), gs.RouterKey, "", uid, proto.ReqReconnectId, req)
}
}
// 重连主动进入房间
func onEnterRoom(_ *amqp091.Delivery, msg map[string]interface{}) {
_, _, uid, data := ParseMsg(msg)
req, err := util.MapToStructT[proto.ReqEnterRoom](data)
if err != nil {
log.Error(err.Error())
return
}
if gs := GameServerMgr.FindByRoomId(req.RoomId); gs != nil {
SendMsg(util.Direct(gs.Type), gs.RouterKey, "", uid, proto.ReqEnterRoomId, req)
}
}
func onLeaveRoom(_ *amqp091.Delivery, msg map[string]interface{}) {
_, _, uid, data := ParseMsg(msg)
req, err := util.MapToStructT[proto.ReqLeaveRoom](data)
if err != nil {
log.Error(err.Error())
return
}
if gs := GameServerMgr.FindByRoomId(req.RoomId); gs != nil {
SendMsg(util.Direct(gs.Type), gs.RouterKey, "", uid, proto.ReqLeaveRoomId, req)
}
}
func onDisbandRoom(_ *amqp091.Delivery, msg map[string]interface{}) {
_, _, uid, data := ParseMsg(msg)
req, err := util.MapToStructT[proto.ReqDisbandRoom](data)
if err != nil {
log.Error(err.Error())
return
}
if gs := GameServerMgr.FindByRoomId(req.RoomId); gs != nil {
SendMsg(util.Direct(gs.Type), gs.RouterKey, "", uid, proto.ReqDisbandRoomId, req)
}
}
func onUpdateConfig(_ *amqp091.Delivery, msg map[string]interface{}) {
_, _, uid, _ := ParseMsg(msg)
model.InitStub()
log.Debug("更新配置")
gs := GameServerMgr.AllServer()
for _, s := range gs {
SendMsg(util.Direct(s.Type), s.RouterKey, "", uid, proto.NtfUpdateConfigId, proto.NtfUpdateConfig{})
}
}
func onBankruptSubsidy(_ *amqp091.Delivery, msg map[string]interface{}) {
_, _, uid, _ := ParseMsg(msg)
rsp := &proto.RspBankruptSubsidy{}
// 不管成功与否都需要返回结果给客户端
defer SendMsgToGate(uid, proto.RspBankruptSubsidyId, rsp)
uInfo, err := model.NewUserInfoOp().Load(uid)
if err != nil {
rsp.Code = proto.Internal
log.Error(fmt.Sprintf("Load用户信息错误: %v", err))
return
}
brConf := stub.GetBankruptConf(model.GetVipLevelByUserId(uid))
if !xtime.IsTodayTimestamp(uInfo.BankruptTime) {
// 时间戳非当天
uInfo.Bankrupt = 0 // 重置为0
}
if uInfo.Bankrupt >= brConf.FreeCount {
// 领取次数达到限额
rsp.Code = proto.SubsidyNotEnough
return
}
SendMsgToDb(routingKey.DbKey(uInfo.UID), uInfo.UID, proto.ReqAddResourceId, &proto.ReqAddResource{
UserId: uInfo.UID,
ResValue: int64(brConf.Quota),
ResType: model.ResCoins,
Reason: model.ReasonSubsidy,
IsNotify: true,
})
err = model.NewUserInfoOp().UpdateBankruptCount(uInfo.UID, uInfo.Bankrupt+1)
if err != nil {
rsp.Code = proto.Internal
log.Error(fmt.Sprintf("Update破产信息错误: %v", err))
return
}
log.Debug(fmt.Sprintf("领取破产补助 uid: %d ", uInfo.UID))
}
func onPlayingNum(_ *amqp091.Delivery, msg map[string]interface{}) {
_, _, uid, _ := ParseMsg(msg)
rsp := &proto.RspPlayingNum{}
defer SendMsgToGate(uid, proto.RspPlayingNumId, rsp)
counts, err := model.GetAllRoomPlayingNum()
if err != nil {
log.Error(err.Error())
rsp.Code = proto.Internal
return
}
for k, v := range counts {
counts[k] = int(model.CalculateFakeCount(int64(v)))
}
rsp.Counts = counts
}
func onUserOnlineDurationTicker(lastTime carbon.Carbon, lastCount int) {
now := xtime.Now()
count := len(model.UserOnlineRepo)
defer func() {
MatchService.NewTimer(10*time.Second, func() {
onUserOnlineDurationTicker(now, count)
}, false)
}()
if count != lastCount {
// 人数有变动写入redis
err := model.NewUserOnlineOp().SetCurrent(int64(count))
if err != nil {
log.Error(err.Error())
}
}
if lastTime.Day() == now.Day() {
return
}
for uid, onlineTime := range model.UserOnlineRepo {
dur := model.UserOnlineDuration{
UID: uid,
OnlineTime: onlineTime.StdTime(),
Duration: onlineTime.DiffInSeconds(now),
RecordTime: lastTime.StdTime(), // 记录时间为昨天
}
if err := dur.Flush(MatchService); err != nil {
log.Error(fmt.Sprintf("failed to flush user uid=%d online duration %s", dur.UID, err))
}
}
}