entry

package
v0.0.6-asynq Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 7, 2024 License: MIT Imports: 4 Imported by: 0

README

Entry Design

This repository contains the implementation of a matchmaking system designed to support different matching strategies and game modes. The project is organized into various components that facilitate the creation and management of player, group, team, and room entries using different matchmaking algorithms.

Directory Structure Demo

.
├── entry
│ ├── glicko2
│ │ ├── group.go
│ │ ├── player.go
│ │ ├── room.go
│ │ └── team.go
│ ├── goat_game
│ │ ├── group.go
│ │ ├── player.go
│ │ ├── room.go
│ │ └── team.go
│ ├── group.go
│ ├── player.go
│ ├── room.go
│ └── team.go
└── repository
  ├── group.go
  ├── player.go
  ├── room.go
  └── team.go

Components

the relastionship between entries

Root Directory

The entry root directory provides interfaces and base implementations for the four types of entries:

  • Interfaces:
    • Player
    • Group
    • Team
    • Room
  • Base Implementations:
    • PlayerBase
    • GroupBase
    • TeamBase
    • RoomBase

These interfaces define the core functionalities for different entities, while the bases provide foundational implementations that can be combinated.

Match Strategy (glicko2)

The glicko2 directory represents a specific match strategy based on the Glicko2 rating system. It includes implementations for the different types of entries, each combining the respective base class:

  • PlayerBaseGlicko2 (combines PlayerBase)
  • GroupBaseGlicko2 (combines GroupBase)
  • TeamBaseGlicko2 (combines TeamBase)
  • RoomBaseGlicko2 (combines RoomBase)
Game Mode (goat_game)

The goat_game directory represents a specific game mode. A game mode can support multiple match strategies. Here, it combines the Glicko2 strategy implementations to form its own entries:

  • goat_game.Player (combines PlayerBaseGlicko2, PlayerBaseGather)
  • goat_game.Group (combines GroupBaseGlicko2, GroupBaseGather)
  • goat_game.Team (combines TeamBaseGlicko2, TeamBaseGather)
  • goat_game.Room (combines RoomBaseGlicko2, RoomBaseGather)
Repository

In the repository directory, there are functions to create specific entry implementations based on provided parameters (game mode and match strategy). This allows for dynamic creation of entries like Player, Group, Team, and Room.

type PlayerMgr struct {
	*collection.Manager[string, entry.Player]
}

type GroupMgr struct {
	*collection.Manager[int64, entry.Group]
}

type TeamMgr struct {
	*collection.Manager[int64, entry.Team]
}

type RoomMgr struct {
	*collection.Manager[int64, entry.Room]
}

Factory Method

To use this matchmaking system, you can instantiate the desired base and strategy combinations using the factory method. Below is an example of how to create a player entry:

// repository/player.go
func (m *PlayerMgr) CreatePlayer(pInfo *pto.PlayerInfo) (p entry.Player, err error) {
	base := entry.NewPlayerBase(pInfo)

	switch base.GameMode {
	case constant.GameModeGoatGame:
		p, err = goat_game.CreatePlayer(base, pInfo)
	case constant.GameModeTest:
		p = base
	default:
		return nil, fmt.Errorf("unsupported game mode: %d", base.GameMode)
	}

	if err != nil {
		return nil, err
	}
	m.Add(p.UID(), p)
	return p, nil
}

// entry/goat_game/player.go
func CreatePlayer(base *entry.PlayerBase, pInfo *pto.PlayerInfo) (entry.Player, error) {
	p := &Player{}

	if err := p.withMatchStrategy(base, pInfo.Glicko2Info); err != nil {
		return nil, err
	}
	return p, nil
}
func (p *Player) withMatchStrategy(base *entry.PlayerBase, info *pto.Glicko2Info) error {
	switch base.MatchStrategy {
	case constant.MatchStrategyGlicko2:
		p.PlayerBaseGlicko2 = glicko2.CreatePlayerBase(base, info)
	default:
		return fmt.Errorf("unknown match strategy: %d", base.MatchStrategy)
	}
	return nil
}

Documentation

Index

Constants

View Source
const (
	InviteExpireSec = 60 * 5
)

Variables

This section is empty.

Functions

This section is empty.

Types

type Group

type Group interface {
	// ID returns the unique group id.
	ID() int64

	// Base returns the base information of the group.
	// Here we define a concrete struct `GroupBase`
	// to hold the common fields to avoid lots getter and setter method.
	Base() *GroupBase

	// IsFull checks if the group is full.
	IsFull() bool

	// SetCaptain sets the captain of the group.
	SetCaptain(Player)

	// GetCaptain returns the captain in the group.
	GetCaptain() Player

	// CanPlayTogether checks if the player can play with the group's players.
	CanPlayTogether(*pto.PlayerInfo) error

	// GetPlayerInfos 获取队伍用户信息
	GetPlayerInfos() pto.GroupUser

	// CanStartMatch checks if the group can start to match.
	CanStartMatch() bool
}

Group represents a group of players.

type GroupBase

type GroupBase struct {
	GroupID       int64
	GameMode      constant.GameMode
	ModeVersion   int64
	MatchStrategy constant.MatchStrategy

	// Do not do synchronization at this layer,
	// leave it to the caller to handle it uniformly,
	// to avoid deadlocks.
	sync.RWMutex

	// MatchID is a unique id to identify each match action.
	MatchID string

	// Settings holds the settings of the group.
	Settings GroupSettings

	// Configs holds the config of the group.
	Configs GroupConfig
	// contains filtered or unexported fields
}

GroupBase holds the common fields of a Group for all kinds of game mode and match strategy.

func NewGroupBase

func NewGroupBase(
	groupID int64, playerLimit int, playerBase *PlayerBase,
) *GroupBase

NewGroupBase creates a new GroupBase.

func (*GroupBase) AddInviteRecord

func (g *GroupBase) AddInviteRecord(inviteeUID string, nowUnix int64)

func (*GroupBase) AddPlayer

func (g *GroupBase) AddPlayer(p Player) error

func (*GroupBase) AllowNearbyJoin

func (g *GroupBase) AllowNearbyJoin() bool

func (*GroupBase) AllowRecentJoin

func (g *GroupBase) AllowRecentJoin() bool

func (*GroupBase) Base

func (g *GroupBase) Base() *GroupBase

func (*GroupBase) CanPlayTogether

func (g *GroupBase) CanPlayTogether(info *pto.PlayerInfo) error

func (*GroupBase) CanStartMatch

func (g *GroupBase) CanStartMatch() bool

func (*GroupBase) CheckState

func (g *GroupBase) CheckState(valids ...GroupState) error

func (*GroupBase) ClearPlayers

func (g *GroupBase) ClearPlayers()

func (*GroupBase) DelInviteRecord

func (g *GroupBase) DelInviteRecord(inviteeUID string)

func (*GroupBase) GetCaptain

func (g *GroupBase) GetCaptain() Player

func (*GroupBase) GetInviteExpireTimeStamp

func (g *GroupBase) GetInviteExpireTimeStamp(uid string) int64

func (*GroupBase) GetInviteRecords

func (g *GroupBase) GetInviteRecords() map[string]int64

func (*GroupBase) GetPlayerInfos

func (g *GroupBase) GetPlayerInfos() pto.GroupUser

func (*GroupBase) GetPlayers

func (g *GroupBase) GetPlayers() []Player

func (*GroupBase) GetState

func (g *GroupBase) GetState() GroupState

func (*GroupBase) GetStateWithLock

func (g *GroupBase) GetStateWithLock() GroupState

func (*GroupBase) ID

func (g *GroupBase) ID() int64

func (*GroupBase) IsFull

func (g *GroupBase) IsFull() bool

func (*GroupBase) IsInviteExpired

func (g *GroupBase) IsInviteExpired(uid string, nowUnix int64) bool

func (*GroupBase) PlayerExists

func (g *GroupBase) PlayerExists(uid string) bool

func (*GroupBase) PlayerLimit

func (g *GroupBase) PlayerLimit() int

func (*GroupBase) RemovePlayer

func (g *GroupBase) RemovePlayer(p Player) (empty bool)

func (*GroupBase) SetAllowNearbyJoin

func (g *GroupBase) SetAllowNearbyJoin(allow bool)

func (*GroupBase) SetAllowRecentJoin

func (g *GroupBase) SetAllowRecentJoin(allow bool)

func (*GroupBase) SetCaptain

func (g *GroupBase) SetCaptain(p Player)

func (*GroupBase) SetState

func (g *GroupBase) SetState(s GroupState)

func (*GroupBase) SetStateWithLock

func (g *GroupBase) SetStateWithLock(s GroupState)

func (*GroupBase) UIDs

func (g *GroupBase) UIDs() []string

type GroupConfig

type GroupConfig struct {
	PlayerLimit     int
	InviteExpireSec int64
}

type GroupRole

type GroupRole int8
const (
	GroupRoleMember  GroupRole = 0
	GroupRoleCaptain GroupRole = 1
)

type GroupSettings

type GroupSettings struct {
	// contains filtered or unexported fields
}

GroupSettings defines the settings of a group.

type GroupState

type GroupState int8
const (
	GroupStateInvite    GroupState = 0
	GroupStateMatch     GroupState = 1
	GroupStateGame      GroupState = 2
	GroupStateDissolved GroupState = 3
)

type Player

type Player interface {
	Base() *PlayerBase
	UID() string
	GetPlayerInfo() *pto.PlayerInfo
}

Player represents a player in a Group.

type PlayerBase

type PlayerBase struct {
	sync.RWMutex

	GroupID int64

	VoiceState PlayerVoiceState

	// TODO: other common attributes
	pto.PlayerInfo
	// contains filtered or unexported fields
}

PlayerBase holds the common fields of a Player for all kinds of game mode and match strategy.

func NewPlayerBase

func NewPlayerBase(info *pto.PlayerInfo) *PlayerBase

func (*PlayerBase) Base

func (p *PlayerBase) Base() *PlayerBase

func (*PlayerBase) CheckOnlineState

func (p *PlayerBase) CheckOnlineState(valids ...PlayerOnlineState) error

CheckOnlineState checks if the player is in a valid online state.

func (*PlayerBase) GetOnlineState

func (p *PlayerBase) GetOnlineState() PlayerOnlineState

func (*PlayerBase) GetOnlineStateWithLock

func (p *PlayerBase) GetOnlineStateWithLock() PlayerOnlineState

func (*PlayerBase) GetPlayerInfo

func (p *PlayerBase) GetPlayerInfo() *pto.PlayerInfo

func (*PlayerBase) GetVoiceState

func (p *PlayerBase) GetVoiceState() PlayerVoiceState

func (*PlayerBase) SetOnlineState

func (p *PlayerBase) SetOnlineState(s PlayerOnlineState)

func (*PlayerBase) SetOnlineStateWithLock

func (p *PlayerBase) SetOnlineStateWithLock(s PlayerOnlineState)

func (*PlayerBase) SetVoiceState

func (p *PlayerBase) SetVoiceState(s PlayerVoiceState)

func (*PlayerBase) UID

func (p *PlayerBase) UID() string

type PlayerOnlineState

type PlayerOnlineState int8

PlayerOnlineState is the state of a player. TODO: try to use state machine to manage player state.

const (
	PlayerOnlineStateOffline  PlayerOnlineState = 0
	PlayerOnlineStateOnline   PlayerOnlineState = 1
	PlayerOnlineStateInGroup  PlayerOnlineState = 2
	PlayerOnlineStateInMatch  PlayerOnlineState = 3
	PlayerOnlineStateInGame   PlayerOnlineState = 4
	PlayerOnlineStateInSettle PlayerOnlineState = 5
)

type PlayerVoiceState

type PlayerVoiceState int8

PlayerVoiceState is the voice state of a player.

const (
	PlayerVoiceStateMute   PlayerVoiceState = 0
	PlayerVoiceStateUnmute PlayerVoiceState = 1
)

type Room

type Room interface {
	Base() *RoomBase
	ID() int64
	GetMatchInfo() *pto.MatchInfo
}

type RoomBase

type RoomBase struct {
	sync.RWMutex

	GameMode      constant.GameMode
	MatchStrategy constant.MatchStrategy
	// contains filtered or unexported fields
}

func NewRoomBase

func NewRoomBase(id int64, t Team) *RoomBase

func (*RoomBase) AddTeam

func (r *RoomBase) AddTeam(t Team)

func (*RoomBase) Base

func (r *RoomBase) Base() *RoomBase

func (*RoomBase) GetMatchInfo

func (r *RoomBase) GetMatchInfo() *pto.MatchInfo

func (*RoomBase) GetTeams

func (r *RoomBase) GetTeams() []Team

func (*RoomBase) ID

func (r *RoomBase) ID() int64

func (*RoomBase) RemoveTeam

func (r *RoomBase) RemoveTeam(id int64)

type Team

type Team interface {
	Base() *TeamBase
	ID() int64
}

type TeamBase

type TeamBase struct {
	sync.RWMutex

	GameMode      constant.GameMode
	MatchStrategy constant.MatchStrategy
	// contains filtered or unexported fields
}

func NewTeamBase

func NewTeamBase(id int64, g Group) *TeamBase

func (*TeamBase) AddGroup

func (t *TeamBase) AddGroup(g Group)

func (*TeamBase) Base

func (t *TeamBase) Base() *TeamBase

func (*TeamBase) GetGroups

func (t *TeamBase) GetGroups() []Group

func (*TeamBase) ID

func (t *TeamBase) ID() int64

func (*TeamBase) RemoveGroup

func (t *TeamBase) RemoveGroup(id int64)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL