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
- Variables
- func AbortGame(ctx context.Context, stores *stores.Stores, g *entity.Game, ...) error
- func CancelSoughtGame(ctx context.Context, gameStore SoughtGameStore, id string) error
- func ComputeGameStats(ctx context.Context, history *macondopb.GameHistory, req *pb.GameRequest, ...) (*entity.Stats, error)
- func HandleEvent(ctx context.Context, stores *stores.Stores, userID string, ...) (*entity.Game, error)
- func HandleMetaEvent(ctx context.Context, evt *pb.GameMetaEvent, ...) error
- func InstantiateNewGame(ctx context.Context, gameStore GameStore, cfg *config.Config, ...) (*entity.Game, error)
- func NewSoughtGame(ctx context.Context, gameStore SoughtGameStore, req *pb.SeekRequest) (*entity.SoughtGame, error)
- func PlayMove(ctx context.Context, entGame *entity.Game, stores *stores.Stores, ...) error
- func Rate(ctx context.Context, scores map[string]int32, g *entity.Game, winner string, ...) (map[string][2]int32, error)
- func StartGame(ctx context.Context, stores *stores.Stores, ...) error
- func TimedOut(ctx context.Context, stores *stores.Stores, timedout string, gameID string) error
- type GameService
- func (gs *GameService) GetGCG(ctx context.Context, req *connect.Request[pb.GCGRequest]) (*connect.Response[pb.GCGResponse], error)
- func (gs *GameService) GetGameDocument(ctx context.Context, req *connect.Request[pb.GameDocumentRequest]) (*connect.Response[pb.GameDocumentResponse], error)
- func (gs *GameService) GetGameHistory(ctx context.Context, req *connect.Request[pb.GameHistoryRequest]) (*connect.Response[pb.GameHistoryResponse], error)
- func (gs *GameService) GetMetadata(ctx context.Context, req *connect.Request[pb.GameInfoRequest]) (*connect.Response[ipc.GameInfoResponse], error)
- func (gs *GameService) GetRecentGames(ctx context.Context, req *connect.Request[pb.RecentGamesRequest]) (*connect.Response[ipc.GameInfoResponses], error)
- func (gs *GameService) GetRematchStreak(ctx context.Context, req *connect.Request[pb.RematchStreakRequest]) (*connect.Response[pb.StreakInfoResponse], error)
- type GameStore
- type SoughtGameStore
Constants ¶
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 )
const (
IdentificationAuthority = "io.woogles"
)
Variables ¶
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)
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 ¶
func (gs *GameService) GetGCG(ctx context.Context, req *connect.Request[pb.GCGRequest], ) (*connect.Response[pb.GCGResponse], error)
GetGCG downloads a GCG for a full native game, or a partial GCG for an annotated game.
func (*GameService) GetGameDocument ¶
func (gs *GameService) GetGameDocument(ctx context.Context, req *connect.Request[pb.GameDocumentRequest], ) (*connect.Response[pb.GameDocumentResponse], error)
XXX: GetGameDocument should be moved to omgwords service eventually, once we get rid of GameHistory and game entities etc.
func (*GameService) GetGameHistory ¶
func (gs *GameService) GetGameHistory(ctx context.Context, req *connect.Request[pb.GameHistoryRequest], ) (*connect.Response[pb.GameHistoryResponse], error)
func (*GameService) GetMetadata ¶
func (gs *GameService) GetMetadata(ctx context.Context, req *connect.Request[pb.GameInfoRequest], ) (*connect.Response[ipc.GameInfoResponse], error)
GetMetadata gets metadata for the given game.
func (*GameService) GetRecentGames ¶
func (gs *GameService) GetRecentGames(ctx context.Context, req *connect.Request[pb.RecentGamesRequest], ) (*connect.Response[ipc.GameInfoResponses], error)
GetRecentGames gets quickdata for the numGames most recent games of the player
offset by offset.
func (*GameService) GetRematchStreak ¶
func (gs *GameService) GetRematchStreak(ctx context.Context, req *connect.Request[pb.RematchStreakRequest], ) (*connect.Response[pb.StreakInfoResponse], error)
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.