refactor: room 包移除大量 error 返回,增加易于房间操作 Helper 数据结构,可通过 Manager.GetHelper 和 room.NewHelper 获取
This commit is contained in:
parent
930fe159bf
commit
3dec4075d5
|
@ -195,6 +195,7 @@ func (slf *event[PID, P, R]) RegPlayerSeatChangeEvent(handle PlayerSeatChangeEve
|
|||
}
|
||||
|
||||
// RegPlayerSeatChangeEventWithRoom 玩家座位改变时将立即执行被注册的事件处理函数
|
||||
// - 当玩家之前没有座位时,oldSeat 为 NoSeat
|
||||
func (slf *event[PID, P, R]) RegPlayerSeatChangeEventWithRoom(room R, handle PlayerSeatChangeEventHandle[PID, P, R]) {
|
||||
slf.playerSeatChangeEventRoomHandles[room.GetGuid()] = append(slf.playerSeatChangeEventRoomHandles[room.GetGuid()], handle)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,127 @@
|
|||
package room
|
||||
|
||||
import (
|
||||
"github.com/kercylan98/minotaur/game"
|
||||
"github.com/kercylan98/minotaur/utils/hash"
|
||||
)
|
||||
|
||||
// NewHelper 创建房间助手
|
||||
func NewHelper[PID comparable, P game.Player[PID], R Room](manager *Manager[PID, P, R], room R) *Helper[PID, P, R] {
|
||||
return &Helper[PID, P, R]{
|
||||
m: manager,
|
||||
room: room,
|
||||
Seat: manager.GetSeatInfo(room.GetGuid()),
|
||||
}
|
||||
}
|
||||
|
||||
// Helper 易于快捷使用的房间助手
|
||||
type Helper[PID comparable, P game.Player[PID], R Room] struct {
|
||||
m *Manager[PID, P, R]
|
||||
*Seat[PID, P, R]
|
||||
room R
|
||||
}
|
||||
|
||||
// Room 获取房间
|
||||
func (slf *Helper[PID, P, R]) Room() R {
|
||||
return slf.room
|
||||
}
|
||||
|
||||
// GetPlayer 获取玩家
|
||||
func (slf *Helper[PID, P, R]) GetPlayer(playerId PID) P {
|
||||
return slf.m.GetRoomPlayer(slf.room.GetGuid(), playerId)
|
||||
}
|
||||
|
||||
// GetPlayers 获取房间中的所有玩家
|
||||
func (slf *Helper[PID, P, R]) GetPlayers() map[PID]P {
|
||||
return slf.m.GetRoomPlayers(slf.room.GetGuid())
|
||||
}
|
||||
|
||||
// GetPlayerCount 获取房间中的玩家数量
|
||||
func (slf *Helper[PID, P, R]) GetPlayerCount() int {
|
||||
return slf.m.GetRoomPlayerCount(slf.room.GetGuid())
|
||||
}
|
||||
|
||||
// GetPlayerLimit 获取房间中的玩家数量上限
|
||||
func (slf *Helper[PID, P, R]) GetPlayerLimit() int {
|
||||
return slf.m.GetRoomPlayerLimit(slf.room.GetGuid())
|
||||
}
|
||||
|
||||
// GetPlayerRooms 获取玩家所在的所有房间
|
||||
func (slf *Helper[PID, P, R]) GetPlayerRooms(playerId PID) map[int64]R {
|
||||
return slf.m.GetPlayerRooms(playerId)
|
||||
}
|
||||
|
||||
// GetPlayerRoomHelpers 获取玩家所在的所有房间助手
|
||||
func (slf *Helper[PID, P, R]) GetPlayerRoomHelpers(playerId PID) map[int64]*Helper[PID, P, R] {
|
||||
return slf.m.GetPlayerRoomHelpers(playerId)
|
||||
}
|
||||
|
||||
// SetPlayerLimit 设置房间中的玩家数量上限
|
||||
func (slf *Helper[PID, P, R]) SetPlayerLimit(limit int) {
|
||||
slf.m.SetPlayerLimit(slf.room.GetGuid(), limit)
|
||||
}
|
||||
|
||||
// GetPlayerIDs 获取房间中的所有玩家ID
|
||||
func (slf *Helper[PID, P, R]) GetPlayerIDs() []PID {
|
||||
return hash.KeyToSlice(slf.GetPlayers())
|
||||
}
|
||||
|
||||
// SetOwner 设置房主
|
||||
func (slf *Helper[PID, P, R]) SetOwner(playerId PID) {
|
||||
slf.m.SetOwner(slf.room.GetGuid(), playerId)
|
||||
}
|
||||
|
||||
// CancelOwner 取消房主
|
||||
func (slf *Helper[PID, P, R]) CancelOwner() {
|
||||
slf.manager.CancelOwner(slf.room.GetGuid())
|
||||
}
|
||||
|
||||
// HasPlayer 是否有玩家
|
||||
func (slf *Helper[PID, P, R]) HasPlayer(playerId PID) bool {
|
||||
return slf.m.InRoom(slf.room.GetGuid(), playerId)
|
||||
}
|
||||
|
||||
// IsFull 房间是否已满
|
||||
func (slf *Helper[PID, P, R]) IsFull() bool {
|
||||
return slf.GetPlayerCount() == slf.GetPlayerLimit()
|
||||
}
|
||||
|
||||
// IsEmpty 房间是否为空
|
||||
func (slf *Helper[PID, P, R]) IsEmpty() bool {
|
||||
return slf.GetPlayerCount() == 0
|
||||
}
|
||||
|
||||
// GetRemainder 获取房间还可以容纳多少玩家
|
||||
func (slf *Helper[PID, P, R]) GetRemainder() int {
|
||||
return slf.GetPlayerLimit() - slf.GetPlayerCount()
|
||||
}
|
||||
|
||||
// IsOwner 是否是房主
|
||||
func (slf *Helper[PID, P, R]) IsOwner(playerId PID) bool {
|
||||
return slf.m.IsOwner(slf.room.GetGuid(), playerId)
|
||||
}
|
||||
|
||||
// HasOwner 是否有房主
|
||||
func (slf *Helper[PID, P, R]) HasOwner() bool {
|
||||
return slf.m.HasOwner(slf.room.GetGuid())
|
||||
}
|
||||
|
||||
// GetOwner 获取房主
|
||||
func (slf *Helper[PID, P, R]) GetOwner() P {
|
||||
return slf.m.GetOwner(slf.room.GetGuid())
|
||||
}
|
||||
|
||||
// Join 加入房间
|
||||
func (slf *Helper[PID, P, R]) Join(player P) error {
|
||||
return slf.m.Join(slf.room.GetGuid(), player)
|
||||
}
|
||||
|
||||
// Leave 离开房间
|
||||
func (slf *Helper[PID, P, R]) Leave(player P) {
|
||||
slf.m.Leave(slf.room.GetGuid(), player)
|
||||
}
|
||||
|
||||
// KickOut 踢出房间
|
||||
func (slf *Helper[PID, P, R]) KickOut(executor, kicked PID, reason string) error {
|
||||
return slf.m.KickOut(slf.room.GetGuid(), executor, kicked, reason)
|
||||
}
|
|
@ -2,7 +2,7 @@ package room
|
|||
|
||||
import "github.com/kercylan98/minotaur/game"
|
||||
|
||||
type info[PlayerID comparable, P game.Player[PlayerID], R Room] struct {
|
||||
type Info[PlayerID comparable, P game.Player[PlayerID], R Room] struct {
|
||||
room R
|
||||
playerLimit int // 玩家人数上限, <= 0 表示无限制
|
||||
owner *PlayerID // 房主
|
||||
|
|
|
@ -10,10 +10,11 @@ import (
|
|||
func NewManager[PID comparable, P game.Player[PID], R Room]() *Manager[PID, P, R] {
|
||||
manager := &Manager[PID, P, R]{
|
||||
event: newEvent[PID, P, R](),
|
||||
rooms: concurrent.NewBalanceMap[int64, *info[PID, P, R]](),
|
||||
rooms: concurrent.NewBalanceMap[int64, *Info[PID, P, R]](),
|
||||
players: concurrent.NewBalanceMap[PID, P](),
|
||||
pr: concurrent.NewBalanceMap[PID, map[int64]struct{}](),
|
||||
rp: concurrent.NewBalanceMap[int64, map[PID]struct{}](),
|
||||
helpers: concurrent.NewBalanceMap[int64, *Helper[PID, P, R]](),
|
||||
}
|
||||
|
||||
return manager
|
||||
|
@ -22,19 +23,33 @@ func NewManager[PID comparable, P game.Player[PID], R Room]() *Manager[PID, P, R
|
|||
// Manager 房间管理器
|
||||
type Manager[PID comparable, P game.Player[PID], R Room] struct {
|
||||
*event[PID, P, R]
|
||||
rooms *concurrent.BalanceMap[int64, *info[PID, P, R]] // 所有房间
|
||||
players *concurrent.BalanceMap[PID, P] // 所有加入房间的玩家
|
||||
pr *concurrent.BalanceMap[PID, map[int64]struct{}] // 玩家所在房间
|
||||
rp *concurrent.BalanceMap[int64, map[PID]struct{}] // 房间中的玩家
|
||||
rooms *concurrent.BalanceMap[int64, *Info[PID, P, R]] // 所有房间
|
||||
players *concurrent.BalanceMap[PID, P] // 所有加入房间的玩家
|
||||
pr *concurrent.BalanceMap[PID, map[int64]struct{}] // 玩家所在房间
|
||||
rp *concurrent.BalanceMap[int64, map[PID]struct{}] // 房间中的玩家
|
||||
helpers *concurrent.BalanceMap[int64, *Helper[PID, P, R]] // 房间助手
|
||||
}
|
||||
|
||||
// GetHelper 获取房间助手
|
||||
func (slf *Manager[PID, P, R]) GetHelper(room R) *Helper[PID, P, R] {
|
||||
helper, exist := slf.helpers.GetExist(room.GetGuid())
|
||||
if exist {
|
||||
return helper
|
||||
}
|
||||
helper = NewHelper[PID, P, R](slf, room)
|
||||
slf.helpers.Set(room.GetGuid(), helper)
|
||||
return helper
|
||||
}
|
||||
|
||||
// CreateRoom 创建房间
|
||||
func (slf *Manager[PID, P, R]) CreateRoom(room R) {
|
||||
roomInfo := &info[PID, P, R]{
|
||||
func (slf *Manager[PID, P, R]) CreateRoom(room R, options ...Option[PID, P, R]) {
|
||||
roomInfo := &Info[PID, P, R]{
|
||||
room: room,
|
||||
seat: newSeat[PID, P, R](slf, room, slf.event),
|
||||
}
|
||||
for _, option := range options {
|
||||
option(roomInfo)
|
||||
}
|
||||
slf.rooms.Set(room.GetGuid(), roomInfo)
|
||||
}
|
||||
|
||||
|
@ -42,6 +57,16 @@ func (slf *Manager[PID, P, R]) CreateRoom(room R) {
|
|||
func (slf *Manager[PID, P, R]) ReleaseRoom(guid int64) {
|
||||
slf.unReg(guid)
|
||||
slf.rooms.Delete(guid)
|
||||
slf.helpers.Delete(guid)
|
||||
slf.rp.Atom(func(m map[int64]map[PID]struct{}) {
|
||||
players := m[guid]
|
||||
slf.pr.Atom(func(m map[PID]map[int64]struct{}) {
|
||||
for playerId := range players {
|
||||
delete(m[playerId], guid)
|
||||
}
|
||||
})
|
||||
})
|
||||
slf.rp.Delete(guid)
|
||||
}
|
||||
|
||||
// SetPlayerLimit 设置房间人数上限
|
||||
|
@ -51,7 +76,7 @@ func (slf *Manager[PID, P, R]) SetPlayerLimit(roomId int64, limit int) {
|
|||
}
|
||||
var room R
|
||||
var oldLimit int
|
||||
slf.rooms.Atom(func(m map[int64]*info[PID, P, R]) {
|
||||
slf.rooms.Atom(func(m map[int64]*Info[PID, P, R]) {
|
||||
info, ok := m[roomId]
|
||||
if !ok {
|
||||
return
|
||||
|
@ -69,7 +94,7 @@ func (slf *Manager[PID, P, R]) SetPlayerLimit(roomId int64, limit int) {
|
|||
func (slf *Manager[PID, P, R]) CancelOwner(roomId int64) {
|
||||
var room R
|
||||
var oldOwner P
|
||||
slf.rooms.Atom(func(m map[int64]*info[PID, P, R]) {
|
||||
slf.rooms.Atom(func(m map[int64]*Info[PID, P, R]) {
|
||||
info, ok := m[roomId]
|
||||
if !ok {
|
||||
return
|
||||
|
@ -85,15 +110,81 @@ func (slf *Manager[PID, P, R]) CancelOwner(roomId int64) {
|
|||
}
|
||||
}
|
||||
|
||||
// SetOwner 设置房主
|
||||
func (slf *Manager[PID, P, R]) SetOwner(roomId int64, owner PID) error {
|
||||
var err error
|
||||
var oldOwner, newOwner P
|
||||
var room R
|
||||
slf.rooms.Atom(func(m map[int64]*info[PID, P, R]) {
|
||||
// GetPlayerRooms 获取玩家所在的房间
|
||||
func (slf *Manager[PID, P, R]) GetPlayerRooms(playerId PID) (rooms map[int64]R) {
|
||||
rooms = map[int64]R{}
|
||||
slf.pr.Atom(func(m map[PID]map[int64]struct{}) {
|
||||
for roomId := range m[playerId] {
|
||||
room, ok := slf.rooms.GetExist(roomId)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
rooms[roomId] = room.room
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// GetPlayerRoomHelpers 获取玩家所在的房间助手
|
||||
func (slf *Manager[PID, P, R]) GetPlayerRoomHelpers(playerId PID) (helpers map[int64]*Helper[PID, P, R]) {
|
||||
helpers = map[int64]*Helper[PID, P, R]{}
|
||||
slf.pr.Atom(func(m map[PID]map[int64]struct{}) {
|
||||
for roomId := range m[playerId] {
|
||||
room, ok := slf.rooms.GetExist(roomId)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
helpers[roomId] = slf.GetHelper(room.room)
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// IsOwner 检查玩家是否是房主
|
||||
func (slf *Manager[PID, P, R]) IsOwner(roomId int64, playerId PID) bool {
|
||||
var isOwner bool
|
||||
slf.rooms.Atom(func(m map[int64]*Info[PID, P, R]) {
|
||||
info, ok := m[roomId]
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
isOwner = info.owner != nil && *info.owner == playerId
|
||||
})
|
||||
return isOwner
|
||||
}
|
||||
|
||||
// HasOwner 检查房间是否有房主
|
||||
func (slf *Manager[PID, P, R]) HasOwner(roomId int64) bool {
|
||||
var hasOwner bool
|
||||
slf.rooms.Atom(func(m map[int64]*Info[PID, P, R]) {
|
||||
info, ok := m[roomId]
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
hasOwner = info.owner != nil
|
||||
})
|
||||
return hasOwner
|
||||
}
|
||||
|
||||
// GetOwner 获取房主
|
||||
func (slf *Manager[PID, P, R]) GetOwner(roomId int64) (player P) {
|
||||
slf.rooms.Atom(func(m map[int64]*Info[PID, P, R]) {
|
||||
info, ok := m[roomId]
|
||||
if !ok || info.owner == nil {
|
||||
return
|
||||
}
|
||||
player = slf.GetRoomPlayer(roomId, *info.owner)
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// SetOwner 设置房主
|
||||
func (slf *Manager[PID, P, R]) SetOwner(roomId int64, owner PID) {
|
||||
var oldOwner, newOwner P
|
||||
var room R
|
||||
slf.rooms.Atom(func(m map[int64]*Info[PID, P, R]) {
|
||||
info, ok := m[roomId]
|
||||
if !ok {
|
||||
err = ErrRoomNotExist
|
||||
return
|
||||
}
|
||||
room = info.room
|
||||
|
@ -102,13 +193,14 @@ func (slf *Manager[PID, P, R]) SetOwner(roomId int64, owner PID) error {
|
|||
}
|
||||
newOwner = slf.GetRoomPlayer(roomId, owner)
|
||||
if generic.IsNil(newOwner) {
|
||||
err = ErrRoomOrPlayerNotExist
|
||||
return
|
||||
}
|
||||
info.owner = &owner
|
||||
})
|
||||
if generic.IsNil(newOwner) {
|
||||
return
|
||||
}
|
||||
slf.OnPlayerUpgradeOwnerEvent(room, oldOwner, newOwner)
|
||||
return err
|
||||
}
|
||||
|
||||
// GetRoom 获取房间
|
||||
|
@ -124,7 +216,7 @@ func (slf *Manager[PID, P, R]) Exist(guid int64) bool {
|
|||
// GetRooms 获取所有房间
|
||||
func (slf *Manager[PID, P, R]) GetRooms() map[int64]R {
|
||||
var rooms = make(map[int64]R)
|
||||
slf.rooms.Atom(func(m map[int64]*info[PID, P, R]) {
|
||||
slf.rooms.Atom(func(m map[int64]*Info[PID, P, R]) {
|
||||
for id, info := range m {
|
||||
rooms[id] = info.room
|
||||
}
|
||||
|
@ -152,7 +244,7 @@ func (slf *Manager[PID, P, R]) ExistPlayer(id PID) bool {
|
|||
}
|
||||
|
||||
// InRoom 检查玩家是否在指定房间内
|
||||
func (slf *Manager[PID, P, R]) InRoom(id PID, guid int64) bool {
|
||||
func (slf *Manager[PID, P, R]) InRoom(guid int64, id PID) bool {
|
||||
var in bool
|
||||
slf.pr.Atom(func(m map[PID]map[int64]struct{}) {
|
||||
rooms, exist := m[id]
|
||||
|
@ -242,8 +334,8 @@ func (slf *Manager[PID, P, R]) GetRoomPlayerLimit(guid int64) int {
|
|||
|
||||
// Leave 使玩家离开房间
|
||||
func (slf *Manager[PID, P, R]) Leave(roomId int64, player P) {
|
||||
var roomInfo *info[PID, P, R]
|
||||
slf.rooms.Atom(func(m map[int64]*info[PID, P, R]) {
|
||||
var roomInfo *Info[PID, P, R]
|
||||
slf.rooms.Atom(func(m map[int64]*Info[PID, P, R]) {
|
||||
room, exist := m[roomId]
|
||||
if !exist {
|
||||
return
|
||||
|
@ -254,7 +346,11 @@ func (slf *Manager[PID, P, R]) Leave(roomId int64, player P) {
|
|||
return
|
||||
}
|
||||
slf.OnPlayerLeaveRoomEvent(roomInfo.room, player)
|
||||
roomInfo.seat.removePlayerSeat(player.GetID())
|
||||
seat := roomInfo.seat.GetSeat(player.GetID())
|
||||
if seat != NoSeat && slf.IsOwner(roomId, player.GetID()) && slf.GetPlayerCount() > 1 {
|
||||
slf.SetOwner(roomId, roomInfo.seat.GetPlayerIDWithSeat(roomInfo.seat.GetNextSeat(seat)))
|
||||
}
|
||||
roomInfo.seat.RemoveSeat(player.GetID())
|
||||
slf.pr.Atom(func(m map[PID]map[int64]struct{}) {
|
||||
rooms, exist := m[player.GetID()]
|
||||
if !exist {
|
||||
|
@ -274,8 +370,8 @@ func (slf *Manager[PID, P, R]) Leave(roomId int64, player P) {
|
|||
// Join 使玩家加入房间
|
||||
func (slf *Manager[PID, P, R]) Join(roomId int64, player P) error {
|
||||
var err error
|
||||
var roomInfo *info[PID, P, R]
|
||||
slf.rooms.Atom(func(m map[int64]*info[PID, P, R]) {
|
||||
var roomInfo *Info[PID, P, R]
|
||||
slf.rooms.Atom(func(m map[int64]*Info[PID, P, R]) {
|
||||
room, exist := m[roomId]
|
||||
if !exist {
|
||||
err = ErrRoomNotExist
|
||||
|
@ -304,7 +400,9 @@ func (slf *Manager[PID, P, R]) Join(roomId int64, player P) error {
|
|||
slf.players.Set(player.GetID(), player)
|
||||
roomInfo = room
|
||||
})
|
||||
roomInfo.seat.addSeat(player.GetID())
|
||||
if roomInfo.seat.autoSitDown {
|
||||
roomInfo.seat.AddSeat(player.GetID())
|
||||
}
|
||||
slf.OnPlayerJoinRoomEvent(roomInfo.room, player)
|
||||
return err
|
||||
}
|
||||
|
@ -336,16 +434,14 @@ func (slf *Manager[PID, P, R]) KickOut(roomId int64, executor, kicked PID, reaso
|
|||
}
|
||||
|
||||
// GetSeatInfo 获取座位信息
|
||||
func (slf *Manager[PID, P, R]) GetSeatInfo(roomId int64) (*Seat[PID, P, R], error) {
|
||||
func (slf *Manager[PID, P, R]) GetSeatInfo(roomId int64) *Seat[PID, P, R] {
|
||||
var result *Seat[PID, P, R]
|
||||
var err error
|
||||
slf.rooms.Atom(func(m map[int64]*info[PID, P, R]) {
|
||||
slf.rooms.Atom(func(m map[int64]*Info[PID, P, R]) {
|
||||
room, exist := m[roomId]
|
||||
if !exist {
|
||||
err = ErrRoomNotExist
|
||||
return
|
||||
}
|
||||
result = room.seat
|
||||
})
|
||||
return result, err
|
||||
return result
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package room
|
||||
|
||||
// Room 房间类似于简版的游戏世界(World),不过没有游戏实体
|
||||
// Room 游戏房间接口
|
||||
type Room interface {
|
||||
// GetGuid 获取房间的唯一标识符
|
||||
GetGuid() int64
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
package room
|
||||
|
||||
import "github.com/kercylan98/minotaur/game"
|
||||
|
||||
type Option[PID comparable, P game.Player[PID], R Room] func(info *Info[PID, P, R])
|
||||
|
||||
// WithPlayerLimit 设置房间人数上限
|
||||
func WithPlayerLimit[PID comparable, P game.Player[PID], R Room](limit int) Option[PID, P, R] {
|
||||
return func(info *Info[PID, P, R]) {
|
||||
info.playerLimit = limit
|
||||
}
|
||||
}
|
||||
|
||||
// WithNotAutoJoinSeat 设置不自动加入座位
|
||||
func WithNotAutoJoinSeat[PID comparable, P game.Player[PID], R Room]() Option[PID, P, R] {
|
||||
return func(info *Info[PID, P, R]) {
|
||||
info.seat.autoSitDown = false
|
||||
}
|
||||
}
|
|
@ -7,12 +7,17 @@ import (
|
|||
"sync"
|
||||
)
|
||||
|
||||
const (
|
||||
NoSeat = -1 // 无座位
|
||||
)
|
||||
|
||||
func newSeat[PlayerID comparable, P game.Player[PlayerID], R Room](manager *Manager[PlayerID, P, R], room R, event *event[PlayerID, P, R]) *Seat[PlayerID, P, R] {
|
||||
roomSeat := &Seat[PlayerID, P, R]{
|
||||
manager: manager,
|
||||
room: room,
|
||||
event: event,
|
||||
seatPS: concurrent.NewBalanceMap[PlayerID, int](),
|
||||
manager: manager,
|
||||
room: room,
|
||||
event: event,
|
||||
seatPS: concurrent.NewBalanceMap[PlayerID, int](),
|
||||
autoSitDown: true,
|
||||
}
|
||||
return roomSeat
|
||||
}
|
||||
|
@ -27,12 +32,12 @@ type Seat[PlayerID comparable, P game.Player[PlayerID], R Room] struct {
|
|||
seatPS *concurrent.BalanceMap[PlayerID, int]
|
||||
seatSP []*PlayerID
|
||||
duplicateLock bool
|
||||
autoMode sync.Once
|
||||
autoSitDown bool
|
||||
}
|
||||
|
||||
// addSeat 为特定玩家添加座位
|
||||
// AddSeat 为特定玩家添加座位
|
||||
// - 当座位存在空缺的时候,玩家将会优先在空缺位置坐下,否则将会在末位追加
|
||||
func (slf *Seat[PlayerID, P, R]) addSeat(id PlayerID) {
|
||||
func (slf *Seat[PlayerID, P, R]) AddSeat(id PlayerID) {
|
||||
if slf.seatPS.Exist(id) {
|
||||
return
|
||||
}
|
||||
|
@ -52,8 +57,8 @@ func (slf *Seat[PlayerID, P, R]) addSeat(id PlayerID) {
|
|||
slf.event.OnPlayerSeatSetEvent(slf.room, slf.manager.GetPlayer(id), seat)
|
||||
}
|
||||
|
||||
// removePlayerSeat 删除玩家座位
|
||||
func (slf *Seat[PlayerID, P, R]) removePlayerSeat(id PlayerID) {
|
||||
// RemoveSeat 删除玩家座位
|
||||
func (slf *Seat[PlayerID, P, R]) RemoveSeat(id PlayerID) {
|
||||
if !slf.seatPS.Exist(id) {
|
||||
return
|
||||
}
|
||||
|
@ -64,36 +69,38 @@ func (slf *Seat[PlayerID, P, R]) removePlayerSeat(id PlayerID) {
|
|||
slf.seatSP[seat] = nil
|
||||
}
|
||||
|
||||
// SetSeat 设置玩家的座位号
|
||||
// - 如果玩家没有预先添加过座位将会返回错误
|
||||
// - 如果位置已经有玩家,将会与其进行更换
|
||||
func (slf *Seat[PlayerID, P, R]) SetSeat(id PlayerID, seat int) error {
|
||||
oldSeat, err := slf.setSeat(id, seat)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
slf.event.OnPlayerSeatChangeEvent(slf.room, slf.manager.GetPlayer(id), oldSeat, seat)
|
||||
return nil
|
||||
// HasSeat 判断玩家是否有座位
|
||||
func (slf *Seat[PlayerID, P, R]) HasSeat(id PlayerID) bool {
|
||||
return slf.seatPS.Exist(id)
|
||||
}
|
||||
|
||||
func (slf *Seat[PlayerID, P, R]) setSeat(id PlayerID, seat int) (int, error) {
|
||||
// SetSeat 设置玩家的座位号
|
||||
// - 如果位置已经有玩家,将会与其进行更换
|
||||
func (slf *Seat[PlayerID, P, R]) SetSeat(id PlayerID, seat int) int {
|
||||
slf.mutex.Lock()
|
||||
slf.duplicateLock = true
|
||||
defer func() {
|
||||
slf.mutex.Unlock()
|
||||
slf.duplicateLock = false
|
||||
}()
|
||||
oldSeat, err := slf.GetSeat(id)
|
||||
if err != nil {
|
||||
return oldSeat, err
|
||||
}
|
||||
playerId, err := slf.GetPlayerIDWithSeat(seat)
|
||||
if err != nil {
|
||||
ov := slf.seatSP[oldSeat]
|
||||
slf.seatSP[oldSeat] = slf.seatSP[seat]
|
||||
slf.seatSP[seat] = ov
|
||||
slf.seatPS.Set(id, seat)
|
||||
slf.seatPS.Set(playerId, oldSeat)
|
||||
oldSeat := slf.GetSeat(id)
|
||||
player := slf.GetPlayerWithSeat(seat)
|
||||
if player != nil {
|
||||
if oldSeat == NoSeat {
|
||||
maxSeat := len(slf.seatSP) - 1
|
||||
if seat > maxSeat {
|
||||
count := seat - maxSeat
|
||||
slf.seatSP = append(slf.seatSP, make([]*PlayerID, count)...)
|
||||
}
|
||||
slf.seatSP[seat] = &id
|
||||
slf.seatPS.Set(id, seat)
|
||||
} else {
|
||||
ov := slf.seatSP[oldSeat]
|
||||
slf.seatSP[oldSeat] = slf.seatSP[seat]
|
||||
slf.seatSP[seat] = ov
|
||||
slf.seatPS.Set(id, seat)
|
||||
slf.seatPS.Set(player.GetID(), oldSeat)
|
||||
}
|
||||
} else {
|
||||
maxSeat := len(slf.seatSP) - 1
|
||||
if seat > maxSeat {
|
||||
|
@ -104,32 +111,55 @@ func (slf *Seat[PlayerID, P, R]) setSeat(id PlayerID, seat int) (int, error) {
|
|||
slf.seatSP[oldSeat] = nil
|
||||
slf.seatPS.Set(id, seat)
|
||||
}
|
||||
return oldSeat, nil
|
||||
slf.event.OnPlayerSeatChangeEvent(slf.room, slf.manager.GetPlayer(id), oldSeat, seat)
|
||||
return oldSeat
|
||||
}
|
||||
|
||||
// IsNoSeat 判断玩家是否没有座位
|
||||
func (slf *Seat[PlayerID, P, R]) IsNoSeat(id PlayerID) bool {
|
||||
return slf.GetSeat(id) == NoSeat
|
||||
}
|
||||
|
||||
// GetSeat 获取玩家座位号
|
||||
func (slf *Seat[PlayerID, P, R]) GetSeat(id PlayerID) (int, error) {
|
||||
// - 如果玩家没有座位,将会返回 NoSeat
|
||||
func (slf *Seat[PlayerID, P, R]) GetSeat(id PlayerID) int {
|
||||
seat, exist := slf.seatPS.GetExist(id)
|
||||
if !exist {
|
||||
return 0, ErrPlayerNotInRoom
|
||||
return NoSeat
|
||||
}
|
||||
return seat, nil
|
||||
return seat
|
||||
}
|
||||
|
||||
// GetPlayerIDWithSeat 获取特定座位号的玩家
|
||||
func (slf *Seat[PlayerID, P, R]) GetPlayerIDWithSeat(seat int) (playerId PlayerID, err error) {
|
||||
// GetPlayerIDWithSeat 获取特定座位号的玩家ID
|
||||
func (slf *Seat[PlayerID, P, R]) GetPlayerIDWithSeat(seat int) (id PlayerID) {
|
||||
if !slf.duplicateLock {
|
||||
slf.mutex.RLock()
|
||||
defer slf.mutex.RUnlock()
|
||||
}
|
||||
if seat > len(slf.seatSP)-1 {
|
||||
return playerId, ErrPlayerNotInRoom
|
||||
if seat >= len(slf.seatSP) || seat < 0 {
|
||||
return id
|
||||
}
|
||||
playerId := slf.seatSP[seat]
|
||||
if playerId == nil {
|
||||
return id
|
||||
}
|
||||
return *playerId
|
||||
}
|
||||
|
||||
// GetPlayerWithSeat 获取特定座位号的玩家
|
||||
func (slf *Seat[PlayerID, P, R]) GetPlayerWithSeat(seat int) (player P) {
|
||||
if !slf.duplicateLock {
|
||||
slf.mutex.RLock()
|
||||
defer slf.mutex.RUnlock()
|
||||
}
|
||||
if seat >= len(slf.seatSP) || seat < 0 {
|
||||
return player
|
||||
}
|
||||
id := slf.seatSP[seat]
|
||||
if id == nil {
|
||||
return playerId, ErrPlayerNotInRoom
|
||||
return player
|
||||
}
|
||||
return *id, nil
|
||||
return slf.manager.GetRoomPlayer(slf.room.GetGuid(), *id)
|
||||
}
|
||||
|
||||
// GetSeatInfo 获取所有座位号
|
||||
|
@ -169,20 +199,21 @@ func (slf *Seat[PlayerID, P, R]) GetSeatInfoWithPlayerIDMap() map[PlayerID]int {
|
|||
}
|
||||
|
||||
// GetFirstSeat 获取第一个未缺席的座位号
|
||||
// - 如果没有,将会返回 NoSeat
|
||||
func (slf *Seat[PlayerID, P, R]) GetFirstSeat() int {
|
||||
for seat, playerId := range slf.seatSP {
|
||||
if playerId != nil {
|
||||
return seat
|
||||
}
|
||||
}
|
||||
return -1
|
||||
return NoSeat
|
||||
}
|
||||
|
||||
// GetNextSeat 获取特定座位号下一个未缺席的座位号
|
||||
func (slf *Seat[PlayerID, P, R]) GetNextSeat(seat int) int {
|
||||
l := len(slf.seatSP)
|
||||
if l == 0 || seat >= l || seat < 0 {
|
||||
return -1
|
||||
return NoSeat
|
||||
}
|
||||
var target = seat
|
||||
for {
|
||||
|
@ -204,7 +235,7 @@ func (slf *Seat[PlayerID, P, R]) GetNextSeat(seat int) int {
|
|||
func (slf *Seat[PlayerID, P, R]) GetNextSeatVacancy(seat int) int {
|
||||
l := len(slf.seatSP)
|
||||
if l == 0 || seat >= l || seat < 0 {
|
||||
return -1
|
||||
return NoSeat
|
||||
}
|
||||
seat++
|
||||
if seat >= l {
|
||||
|
@ -217,7 +248,7 @@ func (slf *Seat[PlayerID, P, R]) GetNextSeatVacancy(seat int) int {
|
|||
func (slf *Seat[PlayerID, P, R]) GetPrevSeat(seat int) int {
|
||||
l := len(slf.seatSP)
|
||||
if l == 0 || seat >= l || seat < 0 {
|
||||
return -1
|
||||
return NoSeat
|
||||
}
|
||||
var target = seat
|
||||
for {
|
||||
|
@ -239,7 +270,7 @@ func (slf *Seat[PlayerID, P, R]) GetPrevSeat(seat int) int {
|
|||
func (slf *Seat[PlayerID, P, R]) GetPrevSeatVacancy(seat int) int {
|
||||
l := len(slf.seatSP)
|
||||
if l == 0 || seat >= l || seat < 0 {
|
||||
return -1
|
||||
return NoSeat
|
||||
}
|
||||
seat--
|
||||
if seat < 0 {
|
||||
|
|
|
@ -19,19 +19,19 @@ func NewManager(senders ...Sender) *Manager {
|
|||
case <-manager.closeChannel:
|
||||
close(manager.closeChannel)
|
||||
close(manager.notifyChannel)
|
||||
log.Info("Manager", log.String("state", "release"))
|
||||
log.Info("m", log.String("state", "release"))
|
||||
return
|
||||
case notify := <-manager.notifyChannel:
|
||||
for _, sender := range manager.senders {
|
||||
if err := sender.Push(notify); err != nil {
|
||||
log.Error("Manager", log.String("sender", reflect.TypeOf(sender).String()), log.Err(err))
|
||||
log.Error("m", log.String("sender", reflect.TypeOf(sender).String()), log.Err(err))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
log.Info("Manager", log.String("state", "running"))
|
||||
log.Info("m", log.String("state", "running"))
|
||||
return manager
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue