samba/server/game/baseroom/roomMgr.go
2025-06-04 09:51:39 +08:00

240 lines
5.0 KiB
Go

package baseroom
import (
"fmt"
"samba/pkg/log"
pkgSrv "samba/pkg/service"
"samba/proto"
"samba/server/game/service"
"samba/util/config"
"samba/util/model"
"samba/util/state"
)
type ServiceStatus int
const (
SsWorking ServiceStatus = 0
SsWaitStop ServiceStatus = 1
SsStopped ServiceStatus = 2
)
var RoomMgr = newRoomMgr()
type roomMgr struct {
rooms map[int]IRoom
status ServiceStatus // 服务状态
no int
maxId int
minId int
}
func newRoomMgr() *roomMgr {
return &roomMgr{rooms: make(map[int]IRoom), status: SsWorking, no: 100000}
}
func (s *roomMgr) Count() int {
return len(s.rooms)
}
func (s *roomMgr) Init(sender pkgSrv.IService) {
s.no = config.Cmd.MinRoomId
s.maxId = config.Cmd.MaxRoomId
s.minId = config.Cmd.MinRoomId
SetService(sender)
}
func (s *roomMgr) Add(room IRoom) {
s.rooms[room.Id()] = room
}
func (s *roomMgr) DelEmptyRoom() {
var ids []IRoom
for _, room := range s.rooms {
if room.SeatPlayerNum() == 0 {
ids = append(ids, room)
}
}
msg := service.MakeMessage(proto.NtfMaintainId, &proto.NtfMaintain{Code: proto.Maintain}, 0, 0)
for _, room := range ids {
room.OnMessage(proto.NtfMaintainId, msg)
}
if len(s.rooms) == 0 && s.status == SsWaitStop {
s.status = SsStopped
}
}
func (s *roomMgr) NotifyStop() {
if s.status == SsWorking {
s.status = SsWaitStop
log.Info("service wait stop")
msg := service.MakeMessage(proto.NtfMaintainId, &proto.NtfMaintain{Code: proto.Maintain}, 0, 0)
for _, room := range s.rooms {
room.OnMessage(proto.NtfMaintainId, msg)
}
}
}
func (s *roomMgr) IsStopped() bool {
return s.status == SsStopped || len(s.rooms) == 0
}
// FindWaitRooms 获取所有未开始游戏的房间
func (s *roomMgr) FindWaitRooms() []IRoom {
rooms := make([]IRoom, 0)
for _, room := range s.rooms {
if room.Status() != state.RsWait {
continue
}
rooms = append(rooms, room)
}
return rooms
}
// 获取所有未开始或者准备中的游戏房间
func (s *roomMgr) FindWaitAndReadyRooms(roomType int) []IRoom {
rooms := make([]IRoom, 0)
for _, room := range s.rooms {
if room.Type() != roomType {
continue
}
if room.Status() != state.RsWait && room.Status() != state.RsReadyStart {
continue
}
rooms = append(rooms, room)
}
return rooms
}
func (s *roomMgr) Find(id int) IRoom {
return s.rooms[id]
}
func (s *roomMgr) FindPlayerRooms(uid int64) []IRoom {
rooms := make([]IRoom, 0)
for _, room := range s.rooms {
if room.HasPlayer(uid) {
rooms = append(rooms, room)
}
}
return rooms
}
func (s *roomMgr) FindClubRoomsByRoomType(roomType int, isClub bool) []IRoom {
rooms := make([]IRoom, 0)
for _, room := range s.rooms {
if room.Type() != roomType {
continue
}
if room.Status() == state.RsWait {
continue
}
if isClub && room.ClubId() > 0 && room.HasEmptySeat() {
rooms = append(rooms, room)
}
}
return rooms
}
func (s *roomMgr) FindPlayerCurrentRoom(uid int64) IRoom {
for _, room := range s.rooms {
if room.IsPlayerCurrentRoom(uid) {
return room
}
}
return nil
}
func (s *roomMgr) Del(id int) {
delete(s.rooms, id)
if len(s.rooms) == 0 && s.status == SsWaitStop {
s.status = SsStopped
}
}
func (s *roomMgr) makeRoomId() int {
for i := 0; i < s.maxId-s.minId; i++ {
s.no++
if s.no >= s.maxId {
s.no = s.minId
}
if _, ok := s.rooms[s.no]; !ok {
return s.no
}
}
log.Error(fmt.Sprintf("room mgr.room.MaxId:%d minId:%v", s.maxId, s.minId))
return -1
}
type CreateRoomFunc func(id, roomType, clubId int) (IRoom, proto.ErrorCode)
func (s *roomMgr) CreateRoom(roomType, clubId int, createRoom CreateRoomFunc) (room IRoom, code proto.ErrorCode) {
if s.status != SsWorking {
return nil, proto.Maintain
}
roomId := s.makeRoomId()
if roomId < 0 {
return nil, proto.Internal
}
room, code = createRoom(roomId, roomType, clubId)
if room != nil {
s.Add(room)
}
return room, code
}
// 删除俱乐部某个玩法下的空房间
func (s *roomMgr) DeleteClubRoom(clubId, roomType int) {
if clubId < 1 {
return
}
var dels []IRoom
for _, rm := range s.rooms {
if rm.ClubId() == clubId && rm.Type() == roomType && rm.Status() == state.RsWait {
dels = append(dels, rm)
}
}
for _, rm := range dels {
rm.ReleaseRoom()
}
return
}
// 俱乐部创建空房间
func (s *roomMgr) CreateClubRoom(clubId, roomType int, createRoom CreateRoomFunc) {
if s.status != SsWorking || clubId == 0 {
return
}
roomId := s.makeRoomId()
if roomId < 0 {
return
}
room, _ := createRoom(roomId, roomType, clubId)
if room != nil {
s.Add(room)
}
return
}
// 初始化时给所有俱乐部创建空房间
func (s *roomMgr) InitCreateClubRooms(createRoom CreateRoomFunc) {
if s.status != SsWorking || config.Cmd.IsClub == 0 {
return
}
clubs, err := model.NewClubInfoOp().LoadAll()
if err != nil {
log.Error(err.Error())
return
}
for _, club := range clubs {
if playInfos, err := model.NewClubPlayInfoOp().Load(club.ID); err == nil {
for _, playInfo := range playInfos {
if playInfo.State == 0 || playInfo.IsValid == 0 {
continue
}
s.CreateClubRoom(club.ID, playInfo.ID, createRoom)
}
}
}
}