gameplay

package
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Sep 5, 2024 License: AGPL-3.0 Imports: 31 Imported by: 0

Documentation

Overview

Package gameplay should know nothing about protocols or databases. It is mostly a pass-through interface to a Macondo game, but also implements a timer and other related logic. This is a use-case in the clean architecture hierarchy.

Index

Constants

View Source
const (
	// Per player, per game.
	MaxAllowedAbortRequests = 1
	MaxAllowedNudges        = 2
	// Disallow abort after this many turns.
	// XXX: This is purposefully somewhat high to account for people playing
	// in a club or legacy tournament oblivious to the fact that they should
	// be cancelling. We can make it lower as our chat implementation becomes
	// more obvious.
	AbortDisallowTurns = 7

	// If receiver has this many milliseconds on their clock or fewer, we don't allow
	// sending them requests.
	DisallowMsecsRemaining = 30 * 1000

	AbortTimeout = time.Second * 60
	NudgeTimeout = time.Second * 120
)
View Source
const (
	IdentificationAuthority = "io.woogles"
)

Variables

View Source
var (
	ErrTooManyAborts = errors.New("you have made too many cancel requests in this game")
	ErrTooManyNudges = errors.New("you have made too many nudges in this game")

	ErrNoMatchingEvent              = errors.New("no matching request to respond to")
	ErrTooManyTurns                 = errors.New("it is too late to cancel")
	ErrPleaseWaitToEnd              = errors.New("this game is almost over; request not sent")
	ErrMetaEventExpirationIncorrect = errors.New("meta event did not expire")
	ErrAlreadyOutstandingRequest    = errors.New("you already have an outstanding request")
	ErrOutstandingRequestExists     = errors.New("please respond to existing request")
	// generic not allowed error; the front-end should disallow anything that can
	// return this error:
	ErrNotAllowed            = errors.New("that action is not allowed")
	ErrCannotAcceptOwnEvents = errors.New("you cannot accept your own requests")
)

Functions

func AbortGame

func AbortGame(ctx context.Context, stores *stores.Stores,
	g *entity.Game, gameEndReason pb.GameEndReason) error

AbortGame aborts a game. This should be done for games that never started, or games that were aborted by mutual consent. It will send events to the correct places, and takes in a locked game.

func CancelSoughtGame

func CancelSoughtGame(ctx context.Context, gameStore SoughtGameStore, id string) error

func ComputeGameStats

func ComputeGameStats(ctx context.Context, history *macondopb.GameHistory, req *pb.GameRequest,
	variantKey entity.VariantKey, evt *pb.GameEndedEvent, stores *stores.Stores) (*entity.Stats, error)

func HandleEvent

func HandleEvent(ctx context.Context, stores *stores.Stores, userID string, cge *pb.ClientGameplayEvent) (*entity.Game, error)

HandleEvent handles a gameplay event from the socket

func HandleMetaEvent

func HandleMetaEvent(ctx context.Context, evt *pb.GameMetaEvent, eventChan chan<- *entity.EventWrapper,
	stores *stores.Stores) error

HandleMetaEvent processes a passed-in Meta Event, returning an error if it is not applicable.

func InstantiateNewGame

func InstantiateNewGame(ctx context.Context, gameStore GameStore, cfg *config.Config,
	users [2]*entity.User, req *pb.GameRequest, tdata *entity.TournamentData) (*entity.Game, error)

InstantiateNewGame instantiates a game and returns it. Users must be in order of who goes first.

func NewSoughtGame

func NewSoughtGame(ctx context.Context, gameStore SoughtGameStore,
	req *pb.SeekRequest) (*entity.SoughtGame, error)

func PlayMove

func PlayMove(ctx context.Context,
	entGame *entity.Game,
	stores *stores.Stores,
	userID string, onTurn,
	timeRemaining int,
	m *move.Move) error

func Rate

func Rate(ctx context.Context, scores map[string]int32, g *entity.Game,
	winner string, userStore user.Store, now int64) (map[string][2]int32, error)

func StartGame

func StartGame(ctx context.Context, stores *stores.Stores, eventChan chan<- *entity.EventWrapper,
	entGame *entity.Game) error

func TimedOut

func TimedOut(ctx context.Context, stores *stores.Stores, timedout string, gameID string) error

TimedOut gets called when the client thinks the user's time ran out. We verify that that is actually the case.

Types

type GameService

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

GameService is a service that contains functions relevant to a game's metadata, stats, etc. All real-time functionality is handled in gameplay/game.go and related files.

func NewGameService

func NewGameService(u user.Store, gs GameStore, gds *stores.GameDocumentStore,
	cfg *config.Config) *GameService

NewGameService creates a GameService

func (*GameService) GetGCG

GetGCG downloads a GCG for a full native game, or a partial GCG for an annotated game.

func (*GameService) GetGameDocument

XXX: GetGameDocument should be moved to omgwords service eventually, once we get rid of GameHistory and game entities etc.

func (*GameService) GetGameHistory

func (*GameService) GetMetadata

GetMetadata gets metadata for the given game.

func (*GameService) GetRecentGames

GetRecentGames gets quickdata for the numGames most recent games of the player

offset by offset.

func (*GameService) GetRematchStreak

GetRematchStreak gets quickdata for the given rematch streak.

type GameStore

type GameStore interface {
	Get(ctx context.Context, id string) (*entity.Game, error)
	GetMetadata(ctx context.Context, id string) (*pb.GameInfoResponse, error)
	GetRematchStreak(ctx context.Context, originalRequestId string) (*gs.StreakInfoResponse, error)
	GetRecentGames(ctx context.Context, username string, numGames int, offset int) (*pb.GameInfoResponses, error)
	GetRecentTourneyGames(ctx context.Context, tourneyID string, numGames int, offset int) (*pb.GameInfoResponses, error)
	Set(context.Context, *entity.Game) error
	Create(context.Context, *entity.Game) error
	CreateRaw(context.Context, *entity.Game, pb.GameType) error
	Exists(ctx context.Context, id string) (bool, error)
	ListActive(context.Context, string, bool) (*pb.GameInfoResponses, error)
	Count(ctx context.Context) (int64, error)
	CachedCount(ctx context.Context) int
	GameEventChan() chan<- *entity.EventWrapper
	SetGameEventChan(c chan<- *entity.EventWrapper)
	Unload(context.Context, string)
	SetReady(ctx context.Context, gid string, pidx int) (int, error)
	GetHistory(ctx context.Context, id string) (*macondopb.GameHistory, error)
}

GameStore is an interface for getting a full game.

type SoughtGameStore

type SoughtGameStore interface {
	Get(ctx context.Context, id string) (*entity.SoughtGame, error)
	GetBySeekerConnID(ctx context.Context, connID string) (*entity.SoughtGame, error)
	New(context.Context, *entity.SoughtGame) error
	Delete(ctx context.Context, id string) error
	ListOpenSeeks(ctx context.Context, receiverID, tourneyID string) ([]*entity.SoughtGame, error)
	ExistsForUser(ctx context.Context, userID string) (bool, error)
	DeleteForUser(ctx context.Context, userID string) (*entity.SoughtGame, error)
	UpdateForReceiver(ctx context.Context, userID string) (*entity.SoughtGame, error)
	DeleteForSeekerConnID(ctx context.Context, connID string) (*entity.SoughtGame, error)
	UpdateForReceiverConnID(ctx context.Context, connID string) (*entity.SoughtGame, error)
	UserMatchedBy(ctx context.Context, userID, matcher string) (bool, error)
	ExpireOld(ctx context.Context) error
}

SoughtGameStore is an interface for getting a sought game.

Jump to

Keyboard shortcuts

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