pkg

package
v0.0.1 Latest Latest
Warning

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

Go to latest
Published: Jun 1, 2021 License: MIT Imports: 16 Imported by: 0

Documentation

Index

Constants

View Source
const API_BASE = "https://calamityofsubterfuge.com"

API_BASE contains the base URL of the server instance.

View Source
const WEBSOCKET_ORIGIN = "https://calamityofsubterfuge.com"

WEBSOCKET_ORIGIN is the value of the Origin header on websockets. This is required or the server will reject the websocket, although it's mainly to protect against browsers starting websockets on different websites.

Variables

View Source
var CONN_READ_TIMEOUT = 20 * time.Second

CONN_READ_TIMEOUT is the amount of time we spend waiting for a read on the socket before we close the socket.

View Source
var CONN_WRITE_TIMEOUT = 20 * time.Second

CONN_WRITE_TIMEOUT is the amount of time we can spend waiting for a write to be acknowledged on the socket before we close the socket.

Functions

func ConnectGame

func ConnectGame(url string, jwt string) (*websocket.Conn, error)

ConnectGame will connect to the game server at the given url, authenticating with the given JWT.

func Play

func Play(cfg *Config, gameConstructor GameConstructor)

Play is an optional function to take over the majority of the boilerplate from the main function of your AI. It will use the given configuration and gameConstructor to connect to the lobby socket server and, when it receives a match from the lobby socket server it spawns a GameHub to manage the game using the given gameConstructor.

Essentially, this goes through all the boilerplate prior to having a Game initialized.

func QueueAI

func QueueAI(cfg *AIConfig, auth *AuthToken) (*websocket.Conn, map[string]interface{}, error)

QueueAI will register the AI with the lobby server and use the response to connect to the lobby socket server, returning the already authenticated websocket. The second result is the welcome message which should be stored for debugging errors with the server.

Types

type AIConfig

type AIConfig struct {
	// AIName is the name of our AI personality
	AIName string

	// AIUID is the unique identifier we assigned to our AI personality,
	// which is typically 23 random bytes encoded in some url safe format
	AIUID string

	// Version is a valid semantic identifier for our AI personality
	Version string

	// Role is the role this AI plays - economy, military, or science
	Role utils.Role

	// ClientAllowList are the UIDs of the users which are allowed to
	// select this AI Personality, unless this list is empty in which
	// case anyone can select this AI personality
	ClientAllowList []string

	// MaxConcurrentInstances is the maximum number of games which can
	// be played simultaneously by this machine.
	MaxConcurrentInstances int
}

AIConfig describes an AI that you are queueing and any additional parameters for the server.

type AuthToken

type AuthToken struct {
	// Token is an arbitrary secret that is provided by the calamity of subterfuge
	// website which we can pass to future requests as the bearer token. The format
	// of this token, if it's formatted at all, is not guarranteed. Hence this MUST
	// be treated as an opaque string.
	Token string

	// ExpiresAt is the time at which this AuthToken will stop working if no other
	// actions are taken. Note that this is just a hint from the server; the server
	// may decide to invalidate tokens at any time for any reason.
	ExpiresAt time.Time
}

AuthToken is the result of successfully logging in. It provides an arbitrary token and the time at which the token will stop working if the user does not logout sooner.

func Login

func Login(email, grantIden, secret string) (*AuthToken, error)

Login will login to the calamity of subterfuge account with the given email, using the given grant and secret. Note that this is not the same technique as humans use during the website, although it is the same endpoint. Any number of grant identifier and secret pairs can be created for an account after you signup via the website.

type Config

type Config struct {
	// Email of the calamity of subterfuge account to login with
	Email string

	// GrantIden identifies the non-human authentication method used for
	// the acount
	GrantIden string

	// Secret is the secret that allows the use of the grant
	Secret string

	// AIConfig is the configuration for the AI
	AIConfig *AIConfig
}

Config is the configuration used for the standard Play loop.

type Conn

type Conn struct {
	// UID is the identifier of this connection which is forwarded alongside all
	// messages to the receiving channel. This allows multiple connections to
	// use the same receive channel if it's desirable to do so. It may be left
	// blank if the receive channel only has a single connection and hence the
	// UID of the connection is superfluous.
	UID string

	// SendQueue is the channel which the Conn reads from in order to write to the
	// actual websocket.
	SendQueue chan interface{}
	// contains filtered or unexported fields
}

Conn is a convenience wrapper around a basic websocket connection which uses channels for send/receive of packets in the format expected by the calamity of subterfuge lobby socket and game socket protocols. The connection itself manages the required goroutines that read from the send queue and write to the receive queue, which can be canceled using Close.

func NewConn

func NewConn(conn *websocket.Conn, uid string, recvQueue chan ReceivedMessage, closedQueue chan string) *Conn

NewConn takes over management of the given websocket connection and returns the managed connection. It is not safe to use the websocket directly once this function is called.

The uid is used to distinguish messages from this connection if there are multiple connections using the same receive queue and closed queue. It may be left as a blank string if the receive and closed queues only have one connection and hence the uid is not required to distinguish the source.

A message is written to the receive queue whenever the server sends us a message. Our uid is written to the closedQueue exactly once when the underlying websocket connection is closed.

func (*Conn) Close

func (c *Conn) Close()

Close the connection if it's not already closed. If the socket is currently open, this will result in our uid being written to the closedQueue after a short delay.

type Game

type Game interface {
	// OnReceiveMessage should be called whenever the server sends
	// us a complete message which was successfully parsed.
	OnReceiveMessage(srvpkts.Packet)

	// OnDisconnected should be called if the websocket closed
	OnDisconnected()

	// Tick this game to account for the given amount of elapsed time,
	// called regularly
	Tick(time.Duration)
}

Game describes something which actually plays the game, i.e., controls the AI. When implementing a Game it can be helpful to use a world.State to handle the generic client state, but it is not required.

type GameConstructor

type GameConstructor func(sendQueue chan interface{}) Game

GameConstructor describes something which can initialize games from a sendQueue, where the sendQueue is a channel that client packets can be sent to be forwarded to the server.

type GameHub

type GameHub struct {
	UID string
	// contains filtered or unexported fields
}

GameHub manages a single server websocket connection in order to run a single game, notifying a particular channel upon completion and allowing cancellation

func NewGameHub

func NewGameHub(conn *websocket.Conn, uid string, finishNotifyQueue chan string, gameConstructor GameConstructor) *GameHub

NewGameHub takes over management of the given game server websocket to run a game initialized using the given GameConstructor. This does not start managing the game; that should be done in a dedicated goroutine by calling the long-running function Manage()

func (*GameHub) Close

func (h *GameHub) Close()

Closes this game hub if it is being managed right now. GameHubs cannot be reused.

func (*GameHub) Manage

func (h *GameHub) Manage()

Manage this game hub. Typically run on a dedicated goroutine, this will monitor the channels for this game hub in order to execute the game.

type Hub

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

Hub manages a lobby socket connection in order to detect and handle game notifications by connecting to the server and then initializing a game with a given GameConstructor, then managing the connection to use that Game.

func NewHub

func NewHub(lobbyConn *websocket.Conn, welcomeMsg map[string]interface{}, gameConstructor GameConstructor) *Hub

NewHub initializes a hub that will take over the given lobby socket connection. Upon a receiving a notification about a new game this will handle connecting to the server and managing the websocket in order to run the Game produced by the given GameConstructor. The welcomeMsg should be the first packet received on the lobby connection and is used exclusively for debugging.

func (*Hub) Cancel

func (h *Hub) Cancel()

Cancels the hub. This may be called from any goroutine and, if Manage is being run, it will stop and return ErrCanceled

func (*Hub) Manage

func (h *Hub) Manage() error

Manage the hub forever or until we are disconnected from the lobby or Cancel'd. This cannot be run in multiple routines simultaneously.

type HubError

type HubError int

HubError is an enum of errors that can cause the hub to stop managing. Unexpected errors will come with no HubError attached.

const (
	ErrConnectionGoingAway HubError = 1
	ErrCanceled            HubError = 2
)

func (HubError) Error

func (e HubError) Error() string

Error implements the error interface for HubError

type PreparablePacket

type PreparablePacket interface {
	// PrepareForMarshal is called prior to marshalling the packet which is to
	// be sent across the connection.
	PrepareForMarshal()
}

PreparablePacket can be implemented by packets to get a chance to initialize things prior to being marshaled and sent across the connection. This is most typically used for setting the Type field on the packet.

type ReceivedMessage

type ReceivedMessage struct {
	// ConnectionUID is the UID of the WebsocketChannelConn that this message
	// came from.
	ConnectionUID string

	// Message is the parsed message that was received. Note that this may have
	// been only part of the actual logical message frame, since the calamity of
	// subterfuge protocol allows multiple messages per message frame to reduce
	// overhead on small messages.
	Message map[string]interface{}
}

ReceivedMessage describes a message along with the connection it was received on.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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