game/common/baseroom/baseRoom.go

258 lines
6.3 KiB
Go
Raw Normal View History

2025-06-06 20:02:58 +08:00
package baseroom
import (
"fmt"
"game/common/proto/pb"
2025-06-07 11:57:56 +08:00
"github.com/fox/fox/ipb"
2025-06-06 20:02:58 +08:00
"github.com/fox/fox/log"
2025-06-07 11:57:56 +08:00
"github.com/fox/fox/processor"
"github.com/fox/fox/service"
2025-06-09 19:10:18 +08:00
"github.com/fox/fox/timer"
2025-06-06 20:02:58 +08:00
"github.com/golang/protobuf/proto"
"time"
)
type BaseRoom[Seat ISeat] struct {
2025-06-07 11:57:56 +08:00
id int
roomType int // 房间配置id 初级,中级,高级
playType int // 玩法配置id color玩法id
gameNo string
Seats []Seat
processor *processor.Processor
2025-06-09 19:10:18 +08:00
timeProcessor *processor.TimerProcessor
2025-06-06 20:02:58 +08:00
2025-06-09 19:10:18 +08:00
timeTypes map[timer.ITimeType]uint32
2025-06-07 11:57:56 +08:00
srv service.IService
2025-06-06 20:02:58 +08:00
}
2025-06-07 11:57:56 +08:00
func NewBaseRoom[Seat ISeat](id, roomType, playType int, srv service.IService) (*BaseRoom[Seat], pb.ErrCode) {
2025-06-06 20:02:58 +08:00
room := &BaseRoom[Seat]{
2025-06-07 11:57:56 +08:00
id: id,
roomType: roomType,
playType: playType,
gameNo: "",
2025-06-09 19:10:18 +08:00
timeTypes: make(map[timer.ITimeType]uint32),
2025-06-07 11:57:56 +08:00
srv: srv,
processor: processor.NewProcessor(),
2025-06-09 19:10:18 +08:00
timeProcessor: processor.NewTimerProcessor(),
2025-06-06 20:02:58 +08:00
}
return room, pb.ErrCode_OK
}
func (r *BaseRoom[Seat]) Id() int {
return r.id
}
func (r *BaseRoom[Seat]) RoomType() int {
return r.roomType
}
func (r *BaseRoom[Seat]) PlayType() int {
return r.playType
}
// 入座玩家数量(包含机器人)
func (r *BaseRoom[Seat]) SeatPlayerNum() int {
num := 0
for _, seat := range r.Seats {
if !seat.Empty() {
num++
}
}
return num
}
// 真实玩家数量
func (r *BaseRoom[Seat]) RealPlayerNum() int {
num := 0
for _, seat := range r.Seats {
if !seat.Empty() && seat.Player().Robot() == nil {
num++
}
}
return num
}
// 机器人数量
func (r *BaseRoom[Seat]) RobotPlayerNum() int {
num := 0
for _, seat := range r.Seats {
if !seat.Empty() && seat.Player().Robot() != nil {
num++
}
}
return num
}
func (r *BaseRoom[Seat]) HasEmptySeat() bool {
for _, seat := range r.Seats {
if seat.Empty() {
return true
}
}
return false
}
func (r *BaseRoom[Seat]) HasPlayer(uid int64) bool {
for _, seat := range r.Seats {
if !seat.Empty() && seat.Player().Id() == uid {
return true
}
}
return false
}
func (r *BaseRoom[Seat]) AddPlayer(player IPlayer, seat int) {
if seat < 0 || seat >= len(r.Seats) {
log.Error(r.SeatLog(r.Seats[seat], "out of range"))
return
}
r.Seats[seat].SetPlayer(player)
return
}
func (r *BaseRoom[Seat]) RemovePlayer(player IPlayer) {
for _, seat := range r.Seats {
if !seat.Empty() && seat.Player().Id() == player.Id() {
seat.SetPlayer(nil)
break
}
}
}
func (r *BaseRoom[Seat]) DebugSendMsg(user IPlayer, msgId pb.MsgId, msg proto.Message) {
log.Debug(r.UserLog(user.Id(), "send msg:%v %v", msgId, msg.String()))
}
func (r *BaseRoom[Seat]) SendMsg(user IPlayer, msgId pb.MsgId, msg proto.Message) {
r.DebugSendMsg(user, msgId, msg)
if user.Robot() != nil {
user.Robot().OnMessage(msgId, msg)
} else {
for _, seat := range r.Seats {
if !seat.Empty() && seat.Player().Id() == user.Id() {
2025-06-07 11:57:56 +08:00
iMsg := ipb.MakeMsgEx(r.srv.Name(), 0, user.Id(), int32(msgId), msg)
_ = r.srv.Send(user.GateTopicName(), iMsg)
2025-06-06 20:02:58 +08:00
break
}
}
}
}
func (r *BaseRoom[Seat]) Broadcast(msgId pb.MsgId, msg proto.Message, exclude ...IPlayer) {
for _, seat := range r.Seats {
if !seat.Empty() {
exist := false
for _, excludePlayer := range exclude {
if excludePlayer.Id() == seat.Player().Id() {
exist = true
break
}
}
if !exist {
r.SendMsg(seat.Player(), msgId, msg)
}
}
}
}
2025-06-09 19:10:18 +08:00
func (r *BaseRoom[Seat]) NewTimer(timerType timer.ITimeType, duration time.Duration, args ...any) {
2025-06-06 20:02:58 +08:00
if _, ok := r.timeTypes[timerType]; ok {
log.Error(r.Log("timer type:%v is exist.can not new timer", timerType.String()))
// if timerType == TtPlayerAct {
// log.Debug(r.Log(log.StackTrace()))
// }
return
}
2025-06-07 11:57:56 +08:00
tid := r.srv.NewTimer(duration+time.Duration(10)*time.Millisecond, func() {
2025-06-09 19:10:18 +08:00
if err := r.timeProcessor.Dispatch(timerType, args...); err != nil {
2025-06-07 11:57:56 +08:00
log.ErrorF(r.Log("timer dispatch err:%v", err))
}
2025-06-06 20:02:58 +08:00
}, true, r.Log("start type:%v timer", timerType.String()))
r.timeTypes[timerType] = tid
// log.Debug(r.Log("start type:%v timer", timerType.String()))
}
2025-06-09 19:10:18 +08:00
func (r *BaseRoom[Seat]) CancelTimer(timerType timer.ITimeType) {
2025-06-06 20:02:58 +08:00
if tid, ok := r.timeTypes[timerType]; ok {
2025-06-07 11:57:56 +08:00
r.srv.CancelTimer(tid)
2025-06-06 20:02:58 +08:00
delete(r.timeTypes, timerType)
// log.Debug(r.Log("stop type:%v timer, rest timer:%+v", timerType.String(), r.timeTypes))
}
}
func (r *BaseRoom[Seat]) CancelAllTimer() {
for _, tid := range r.timeTypes {
2025-06-07 11:57:56 +08:00
r.srv.CancelTimer(tid)
2025-06-06 20:02:58 +08:00
// log.Debug(r.Log("start type:%v timer", timerType.String()))
}
2025-06-09 19:10:18 +08:00
r.timeTypes = make(map[timer.ITimeType]uint32)
2025-06-06 20:02:58 +08:00
}
func (r *BaseRoom[Seat]) Log(format string, a ...any) string {
head := fmt.Sprintf("room:%v type:%v ", r.id, r.roomType)
return head + fmt.Sprintf(format, a...)
}
func (r *BaseRoom[Seat]) SeatLog(seat Seat, format string, a ...any) string {
head := ""
if seat.Player() != nil {
head = fmt.Sprintf("room:%v type:%v seat:%v user:%v robot:%v ", r.id, r.roomType, seat.No(), seat.Player().Id(), seat.Player().Robot() != nil)
} else {
head = fmt.Sprintf("room:%v type:%v seat:%v ", r.id, r.roomType, seat.No())
}
return head + fmt.Sprintf(format, a...)
}
func (r *BaseRoom[Seat]) UserLog(uid int64, format string, a ...any) string {
var seat Seat
exist := false
for _, st := range r.Seats {
if !st.Empty() && st.Player().Id() == uid {
seat = st
exist = true
break
}
}
if exist {
return r.SeatLog(seat, format, a...)
} else {
return r.Log(format, a...)
}
}
2025-06-07 11:57:56 +08:00
func (r *BaseRoom[Seat]) Unmarshal(cmd int32, data []byte) (any, error) {
return r.processor.Unmarshal(cmd, data)
}
func (r *BaseRoom[Seat]) Dispatch(user IPlayer, cmd int32, params ...any) error {
inp := make([]any, len(params)+1)
inp = append(inp, user)
inp = append(inp, params...)
return r.processor.Dispatch(cmd, inp...)
}
func (r *BaseRoom[Seat]) RegisterMessages(metas processor.RegisterMetas) {
r.processor.RegisterMessages(metas)
}
2025-06-09 19:10:18 +08:00
func (r *BaseRoom[Seat]) timerDispatch(user IPlayer, cmd timer.ITimeType, params ...any) error {
2025-06-07 11:57:56 +08:00
inp := make([]any, len(params)+1)
inp = append(inp, user)
inp = append(inp, params...)
return r.timeProcessor.Dispatch(cmd, inp...)
}
2025-06-06 20:02:58 +08:00
2025-06-07 11:57:56 +08:00
// 注册时间事件及处理
2025-06-09 19:10:18 +08:00
func (r *BaseRoom[Seat]) RegisterTimerMessages(metas processor.RegisterTimerMetas) {
2025-06-07 11:57:56 +08:00
r.timeProcessor.RegisterMessages(metas)
2025-06-06 20:02:58 +08:00
}
2025-06-07 11:57:56 +08:00
// 初始化房间
func (r *BaseRoom[Seat]) OnInit() {
2025-06-06 20:02:58 +08:00
}