Documentation ¶
Index ¶
- Constants
- Variables
- func CreateLobby(playerName, chosenLanguage string, publicLobby bool, ...) (*Player, *Lobby, error)
- func GetRandomWords(wordCount int, lobby *Lobby) []string
- func SanitizeName(name string) string
- type EditableLobbySettings
- type Fill
- type FillEvent
- type GameEvent
- type GameOverEvent
- type KickVote
- type Line
- type LineEvent
- type Lobby
- func (lobby *Lobby) AppendFill(fill *FillEvent)
- func (lobby *Lobby) AppendLine(line *LineEvent)
- func (lobby *Lobby) CanIPConnect(address string) bool
- func (lobby *Lobby) ClearDrawing()
- func (lobby *Lobby) GetAvailableWordHints(player *Player) []*WordHint
- func (lobby *Lobby) GetConnectedPlayerCount() int
- func (lobby *Lobby) GetOccupiedPlayerSlots() int
- func (lobby *Lobby) GetPlayer(userSession string) *Player
- func (lobby *Lobby) GetPlayers() []*Player
- func (lobby *Lobby) HandleEvent(raw []byte, received *GameEvent, player *Player) error
- func (lobby *Lobby) HasConnectedPlayers() bool
- func (lobby *Lobby) HasFreePlayerSlot() bool
- func (lobby *Lobby) IsPublic() bool
- func (lobby *Lobby) JoinPlayer(playerName string) *Player
- func (lobby *Lobby) OnPlayerConnectUnsynchronized(player *Player)
- func (lobby *Lobby) OnPlayerDisconnect(player *Player)
- func (lobby *Lobby) Shutdown()
- func (lobby *Lobby) Synchronized(logic func())
- func (lobby *Lobby) TriggerUpdateEvent(eventType string, data interface{})
- type Message
- type NameChangeEvent
- type NextTurn
- type OwnerChangeEvent
- type Player
- func (player *Player) GetLastKnownAddress() string
- func (player *Player) GetUserSession() string
- func (player *Player) GetWebsocket() *websocket.Conn
- func (player *Player) GetWebsocketMutex() *sync.Mutex
- func (player *Player) SetLastKnownAddress(address string)
- func (player *Player) SetWebsocket(socket *websocket.Conn)
- type PlayerState
- type RGBColor
- type Ready
- type SettingBounds
- type WordHint
Constants ¶
const ( // Unstarted means the lobby has been opened but never started. Unstarted gameState = "unstarted" // Ongoing means the lobby has already been started. Ongoing gameState = "ongoing" // GameOver means that the lobby had been start, but the max round limit // has already been reached. GameOver gameState = "gameOver" )
const ( DrawingBoardBaseWidth = 1600 DrawingBoardBaseHeight = 900 MinBrushSize = 8 MaxBrushSize = 32 )
const MaxPlayerNameLength int = 30
MaxPlayerNameLength defines how long a string can be at max when used as the playername.
Variables ¶
var ( LobbySettingBounds = &SettingBounds{ MinDrawingTime: 60, MaxDrawingTime: 300, MinRounds: 1, MaxRounds: 20, MinMaxPlayers: 2, MaxMaxPlayers: 24, MinClientsPerIPLimit: 1, MaxClientsPerIPLimit: 24, } SupportedLanguages = map[string]string{ "english_gb": "English (GB)", "english": "English (US)", "italian": "Italian", "german": "German", "french": "French", "dutch": "Dutch", } )
Functions ¶
func CreateLobby ¶
func CreateLobby(playerName, chosenLanguage string, publicLobby bool, drawingTime, rounds, maxPlayers, customWordsChance, clientsPerIPLimit int, customWords []string, enableVotekick bool) (*Player, *Lobby, error)
CreateLobby creates a new lobby including the initial player (owner) and optionally returns an error, if any occurred during creation.
func GetRandomWords ¶
GetRandomWords gets a custom amount of random words for the passed Lobby. The words will be chosen from the custom words and the default dictionary, depending on the settings specified by the lobbies creator.
func SanitizeName ¶
SanitizeName removes invalid characters from the players name, resolves emoji codes, limits the name length and generates a new name if necessary.
Types ¶
type EditableLobbySettings ¶
type EditableLobbySettings struct { // MaxPlayers defines the maximum amount of players in a single lobby. MaxPlayers int `json:"maxPlayers"` // CustomWords are additional words that will be used in addition to the // predefined words. // Public defines whether the lobby is being broadcast to clients asking // for available lobbies. Public bool `json:"public"` // EnableVotekick decides whether players are allowed to kick eachother // by casting majority votes. EnableVotekick bool `json:"enableVotekick"` // CustomWordsChance determines the chance of each word being a custom // word on the next word prompt. This needs to be an integer between // 0 and 100. The value represents a percentage. CustomWordsChance int `json:"customWordsChance"` // ClientsPerIPLimit helps preventing griefing by reducing each player // to one tab per IP address. ClientsPerIPLimit int `json:"clientsPerIpLimit"` // DrawingTime is the amount of seconds that each player has available to // finish their drawing. DrawingTime int `json:"drawingTime"` // Rounds defines how many iterations a lobby does before the game ends. // One iteration means every participant does one drawing. Rounds int `json:"rounds"` }
EditableLobbySettings represents all lobby settings that are editable by the lobby owner after the lobby has already been opened.
type FillEvent ¶
FillEvent is basically the same as GameEvent, but with a specific Data type. We use this for reparsing as soon as we know that the type is right. It's a bit unperformant, but will do for now.
type GameEvent ¶
type GameEvent struct { Type string `json:"type"` Data interface{} `json:"data"` }
GameEvent contains an eventtype and optionally any data.
type GameOverEvent ¶
GameOverEvent is basically the ready event, but contains the last word. This is required in order to show the last player the word, in case they didn't manage to guess it in time. This is necessary since the last word is usually part of the "next-turn" event, which we don't send, since the game is over already.
type KickVote ¶
type KickVote struct { PlayerID string `json:"playerId"` PlayerName string `json:"playerName"` VoteCount int `json:"voteCount"` RequiredVoteCount int `json:"requiredVoteCount"` }
KickVote represents a players vote to kick another players. If the VoteCount is as great or greater than the RequiredVoteCount, the event indicates a successful kick vote. The voting is anonymous, meaning the voting player won't be exposed.
type Line ¶
type Line struct { FromX float32 `json:"fromX"` FromY float32 `json:"fromY"` ToX float32 `json:"toX"` ToY float32 `json:"toY"` Color RGBColor `json:"color"` LineWidth float32 `json:"lineWidth"` }
Line is the struct that a client send when drawing
type LineEvent ¶
LineEvent is basically the same as GameEvent, but with a specific Data type. We use this for reparsing as soon as we know that the type is right. It's a bit unperformant, but will do for now.
type Lobby ¶
type Lobby struct { // ID uniquely identified the Lobby. LobbyID string *EditableLobbySettings // DrawingTimeNew is the new value of the drawing time. If a round is // already ongoing, we can't simply change the drawing time, as it would // screw with the score calculation of the current turn. DrawingTimeNew int CustomWords []string // Whether the game has started, is ongoing or already over. State gameState // Owner references the Player that currently owns the lobby. // Meaning this player has rights to restart or change certain settings. Owner *Player // CurrentWord represents the word that was last selected. If no word has // been selected yet or the round is already over, this should be empty. CurrentWord string // Round is the round that the Lobby is currently in. This is a number // between 0 and Rounds. 0 indicates that it hasn't started yet. Round int Wordpack string // RoundEndTime represents the time at which the current round will end. // This is a UTC unix-timestamp in milliseconds. RoundEndTime int64 //LastPlayerDisconnectTime is used to know since when a lobby is empty, in case //it is empty. LastPlayerDisconnectTime *time.Time WriteJSON func(player *Player, object interface{}) error // contains filtered or unexported fields }
Lobby represents a game session. FIXME Field visibilities should be changed in case we ever serialize this.
func (*Lobby) AppendFill ¶
AppendFill adds a fill direction to the current drawing. This exists in order to prevent adding arbitrary elements to the drawing, as the backing array is an empty interface type.
func (*Lobby) AppendLine ¶
AppendLine adds a line direction to the current drawing. This exists in order to prevent adding arbitrary elements to the drawing, as the backing array is an empty interface type.
func (*Lobby) CanIPConnect ¶
CanIPConnect checks whether the IP is still allowed regarding the lobbies clients per IP address limit. This function should only be called for players that aren't already in the lobby.
func (*Lobby) ClearDrawing ¶
func (lobby *Lobby) ClearDrawing()
func (*Lobby) GetAvailableWordHints ¶
GetAvailableWordHints returns a WordHint array depending on the players game state, since people that are drawing or have already guessed correctly can see all hints.
func (*Lobby) GetConnectedPlayerCount ¶
GetConnectedPlayerCount returns the amount of player that have currently established a socket connection.
func (*Lobby) GetOccupiedPlayerSlots ¶
GetOccupiedPlayerSlots counts the available slots which can be taken by new players. Whether a slot is available is determined by the player count and whether a player is disconnect or furthermore how long they have been disconnected for. Therefore the result of this function will differ from Lobby.GetConnectedPlayerCount.
func (*Lobby) GetPlayers ¶
func (*Lobby) HandleEvent ¶
func (*Lobby) HasConnectedPlayers ¶
func (*Lobby) HasFreePlayerSlot ¶
HasFreePlayerSlot determines whether the lobby still has a slot for at least one more player. If a player has disconnected recently, the slot will be preserved for 5 minutes. This function should be used over Lobby.GetOccupiedPlayerSlots, as it is potentially faster.
func (*Lobby) JoinPlayer ¶
JoinPlayer creates a new player object using the given name and adds it to the lobbies playerlist. The new players is returned.
func (*Lobby) OnPlayerConnectUnsynchronized ¶
func (*Lobby) OnPlayerDisconnect ¶
func (*Lobby) Shutdown ¶
func (lobby *Lobby) Shutdown()
Shutdown sends all players an event, indicating that the lobby will be shut down. The caller of this function should take care of not allowing new connections. Clients should gracefully disconnect.
func (*Lobby) Synchronized ¶
func (lobby *Lobby) Synchronized(logic func())
Synchronized allows running a function while keeping the lobby locked via it's own mutex. This is useful in order to avoid having to relock a lobby multiple times, which might cause unexpected inconsistencies.
func (*Lobby) TriggerUpdateEvent ¶
type Message ¶
type Message struct { // Author is the player / thing that wrote the message Author string `json:"author"` // AuthorID is the unique identifier of the authors player object. AuthorID string `json:"authorId"` // Content is the actual message text. Content string `json:"content"` }
Message represents a message in the chatroom.
type NameChangeEvent ¶
type NextTurn ¶
type NextTurn struct { Round int `json:"round"` Players []*Player `json:"players"` RoundEndTime int `json:"roundEndTime"` //PreviousWord signals the last chosen word. If empty, no word has been //chosen. The client can now themselves whether there has been a previous //turn, by looking at the current gamestate. PreviousWord string `json:"previousWord"` }
NextTurn represents the data necessary for displaying the lobby state right after a new turn started. Meaning that no word has been chosen yet and therefore there are no wordhints and no current drawing instructions.
type OwnerChangeEvent ¶
type Player ¶
type Player struct { // ID uniquely identified the Player. ID string `json:"id"` // Name is the players displayed name Name string `json:"name"` // Score is the points that the player got in the current Lobby. Score int `json:"score"` // Connected defines whether the players websocket connection is currently // established. This has previously been in state but has been moved out // in order to avoid losing the state on refreshing the page. // While checking the websocket against nil would be enough, we still need // this field for sending it via the APIs. Connected bool `json:"connected"` // Rank is the current ranking of the player in his Lobby LastScore int `json:"lastScore"` Rank int `json:"rank"` State PlayerState `json:"state"` // contains filtered or unexported fields }
Player represents a participant in a Lobby.
func (*Player) GetLastKnownAddress ¶
GetLastKnownAddress returns the last known IP-Address used for an HTTP request.
func (*Player) GetUserSession ¶
GetUserSession returns the players current user session.
func (*Player) GetWebsocket ¶
GetWebsocket simply returns the players websocket connection. This method exists to encapsulate the websocket field and prevent accidental sending the websocket data via the network.
func (*Player) GetWebsocketMutex ¶
GetWebsocketMutex returns a mutex for locking the websocket connection. Since gorilla websockets shits it self when two calls happen at the same time, we need a mutex per player, since each player has their own socket. This getter extends to prevent accidentally sending the mutex via the network.
func (*Player) SetLastKnownAddress ¶
SetLastKnownAddress sets the last known IP-Address used for an HTTP request. Can be retrieved via GetLastKnownAddress().
func (*Player) SetWebsocket ¶
SetWebsocket sets the given connection as the players websocket connection.
type PlayerState ¶
type PlayerState string
const ( Guessing PlayerState = "guessing" Drawing PlayerState = "drawing" Standby PlayerState = "standby" )
type Ready ¶
type Ready struct { PlayerID string `json:"playerId"` PlayerName string `json:"playerName"` AllowDrawing bool `json:"allowDrawing"` VotekickEnabled bool `json:"votekickEnabled"` GameState gameState `json:"gameState"` OwnerID string `json:"ownerId"` Round int `json:"round"` Rounds int `json:"rounds"` RoundEndTime int `json:"roundEndTime"` DrawingTimeSetting int `json:"drawingTimeSetting"` WordHints []*WordHint `json:"wordHints"` Players []*Player `json:"players"` CurrentDrawing []interface{} `json:"currentDrawing"` }
Ready represents the initial state that a user needs upon connection. This includes all the necessary things for properly running a client without receiving any more data.
type SettingBounds ¶
type SettingBounds struct { MinDrawingTime int64 `json:"minDrawingTime"` MaxDrawingTime int64 `json:"maxDrawingTime"` MinRounds int64 `json:"minRounds"` MaxRounds int64 `json:"maxRounds"` MinMaxPlayers int64 `json:"minMaxPlayers"` MaxMaxPlayers int64 `json:"maxMaxPlayers"` MinClientsPerIPLimit int64 `json:"minClientsPerIpLimit"` MaxClientsPerIPLimit int64 `json:"maxClientsPerIpLimit"` }
SettingBounds defines the lower and upper bounds for the user-specified lobby creation input.