Skip to content
This repository has been archived by the owner on Jun 24, 2023. It is now read-only.

Commit

Permalink
Removed Gin and used my packet system library
Browse files Browse the repository at this point in the history
  • Loading branch information
jacobtread committed Mar 7, 2022
1 parent f8743f8 commit 9fa4724
Show file tree
Hide file tree
Showing 8 changed files with 65 additions and 305 deletions.
97 changes: 31 additions & 66 deletions backend/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,13 @@ import (
"backend/tools"
_ "embed"
"fmt"
"github.com/gin-gonic/gin"
"github.com/gorilla/websocket"
"github.com/jacobtread/gowsps"
"log"
"net/http"
)

const (
Version = "1.0.4"
Version = "1.0.5"
Intro = `
__ __ ___ __
/ \ | | | / | |__ |__)
Expand All @@ -35,87 +34,53 @@ var appIndex []byte
func main() {
address := tools.EnvOrDefault("QUIZLER_ADDRESS", "0.0.0.0") // Retrieve the address environment variable
port := tools.EnvOrDefault("QUIZLER_PORT", "8080") // Retrieve the port environment variable

// Create a host url from ADDRESS:PORT
host := fmt.Sprintf("%s:%s", address, port)
host := fmt.Sprintf("%s:%s", address, port) // Create a host url from ADDRESS:PORT

fmt.Printf(Intro, Version, port) // Print the intro message

gin.SetMode(gin.ReleaseMode) // Set Gin to "Release" mode (Not debug mode)
g := gin.New() // Create a new gin instance

g.Use(gin.Recovery()) // Recovery middleware to recover from panics and send 500 instead

g.GET("/ws", SocketConnect) // Create a new web socket endpoint

// Serve the index page if the websocket was not requested
g.NoRoute(func(context *gin.Context) {
// Serve the index.html file
context.Data(http.StatusOK, "text/html", appIndex)
// Create a handler for handling http requests
http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
if request.URL.Path == "/ws" { // If the user accessed the websocket endpoint
SocketConnect(writer, request) // Create a socket connection
} else {
writer.Header().Set("Content-Type", "text/html") // Set the Content-Type as HTML
_, _ = writer.Write(appIndex) // Write the index HTML body to the response
}
})

// Run the server
err := g.Run(host)
if err != nil {
log.Fatal("An error occurred", err)
err := http.ListenAndServe(host, nil) // Listen on the provided address
if err != nil { // If we encountered an error
log.Fatal("An error occurred", err) // Print out the error
}
}

// upgrader Used to upgrade HTTP requests to the WS protocol
var upgrader = websocket.Upgrader{CheckOrigin: func(r *http.Request) bool { return true }}

// SocketState A structure representing the state of a socket instance
type SocketState struct {
Hosted *game.Game // The hosted player
Game *game.Game // The active game
Player *game.Player // The active player

*Connection // The websocket connection
*gowsps.Connection // The websocket connection
}

//SocketConnect Creates a socket connection and upgrades the HTTP request to WS
func SocketConnect(c *gin.Context) {
// Try to upgrade the http connection to a web socket connection
ws, err := upgrader.Upgrade(c.Writer, c.Request, nil)
if err != nil { // If we failed to upgrade the connection
log.Fatal("Failed to upgrade connection", err)
}
// Deferred closing of the socket when we are done this will result
// in ws.Close being called after this function is finished executing
defer func(ws *websocket.Conn) { _ = ws.Close() }(ws)

var rawPacket = PacketRaw{} // The structure for packets to be decoded into as id and raw dat
conn := NewConnection(ws) // Create a new connection
var state = SocketState{Connection: conn} // Create a new state with the connection

for conn.Open { // As long as the connection is still open
// Read incoming packet into the raw packet map
err = ws.ReadJSON(&rawPacket)
if err != nil { // If packet parsing failed or the ID was missing
if conn.Open { // Ignore this message if the client is not connected any more
// Disconnect the client for sending invalid data
conn.Send(DisconnectPacket("Failed to decode packet"))
}
break
}
func SocketConnect(w http.ResponseWriter, r *http.Request) {
s := gowsps.NewPacketSystem()
var state = SocketState{} // Create a new state with the connection

// Add handlers for each of
gowsps.AddHandler(s, CCreateGame, state.onCreateGame)
gowsps.AddHandler(s, CCheckNameTaken, state.onCheckNameTaken)
gowsps.AddHandler(s, CRequestGameState, state.onRequestGameState)
gowsps.AddHandler(s, CRequestJoin, state.onRequestJoin)
gowsps.AddHandler(s, CStateChange, state.onStateChange)
gowsps.AddHandler(s, CAnswer, state.onAnswer)
gowsps.AddHandler(s, CKick, state.onKick)

s.UpgradeAndListen(w, r, func(conn *gowsps.Connection, err error) {
state.Connection = conn
})

switch rawPacket.Id {
case CCreateGame:
HandlePacket(rawPacket, state.onCreateGame)
case CCheckNameTaken:
HandlePacket(rawPacket, state.onCheckNameTaken)
case CRequestGameState:
HandlePacket(rawPacket, state.onRequestGameState)
case CRequestJoin:
HandlePacket(rawPacket, state.onRequestJoin)
case CStateChange:
HandlePacket(rawPacket, state.onStateChange)
case CAnswer:
HandlePacket(rawPacket, state.onAnswer)
case CKick:
HandlePacket(rawPacket, state.onKick)
}
}
state.Cleanup() // Cleanup the state
}

Expand Down
11 changes: 6 additions & 5 deletions backend/game/game.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package game
import (
"backend/net"
. "backend/tools"
. "github.com/jacobtread/gowsps"
"log"
"math"
"strings"
Expand All @@ -21,7 +22,7 @@ const (

// Game a structure representing the game itself
type Game struct {
Host *net.Connection // The connection to the game host
Host *Connection // The connection to the game host
Id Identifier // The unique identifier / game code for this game
Title string // The title / name of this game
Questions []QuestionData // An array of the questions for this game
Expand Down Expand Up @@ -73,7 +74,7 @@ func Get(identifier Identifier) *Game {
// New Creates a new game instance with the provided host, title, and questions.
// also starts a new goroutine for the games loop, adds it to Games and returns
// a reference to the game
func New(host *net.Connection, title string, questions []QuestionData) *Game {
func New(host *Connection, title string, questions []QuestionData) *Game {
id := CreateGameId() // Create a new unique game ID
game := Game{
Host: host,
Expand All @@ -94,7 +95,7 @@ func New(host *net.Connection, title string, questions []QuestionData) *Game {

// Join adds a new player to the game with the provided connection and name
// and returns a reference to the player
func (game *Game) Join(conn *net.Connection, name string) *Player {
func (game *Game) Join(conn *Connection, name string) *Player {
player := game.Players.Create(conn, name) // Create a new player
// Send the initial state of the game
player.Net.Send(net.GameStatePacket(game.State))
Expand All @@ -115,7 +116,7 @@ func (game *Game) IsNameTaken(name string) bool {
}

// Broadcast sends the provided packet to all the players in the game
func (game *Game) Broadcast(packet net.Packet, host bool) {
func (game *Game) Broadcast(packet Packet, host bool) {
// Iterate over all the players
game.Players.ForEach(func(id Identifier, player *Player) {
player.Net.Send(packet) // Send the packet to the player
Expand All @@ -129,7 +130,7 @@ func (game *Game) Broadcast(packet net.Packet, host bool) {
// BroadcastExcluding sends the provided packet to all the players in the game
// excluding any players that match the excluded id. The host parameter determines
// whether this packet will also be sent to the host of the game
func (game *Game) BroadcastExcluding(exclude Identifier, packet net.Packet, host bool) {
func (game *Game) BroadcastExcluding(exclude Identifier, packet Packet, host bool) {
// Iterate over all the players
game.Players.ForEach(func(id Identifier, player *Player) {
if id != exclude { // If the player id != the excluded id
Expand Down
5 changes: 3 additions & 2 deletions backend/game/player.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ package game
import (
"backend/net"
. "backend/tools"
"github.com/jacobtread/gowsps"
"sync"
"time"
)

type (
// Player A structure representing a player in the game
Player struct {
Net *net.Connection // The connection to the player socket
Net *gowsps.Connection // The connection to the player socket
Id Identifier // The unique ID of this player
Name string // The name of this player
Score uint32 // The score this player has
Expand Down Expand Up @@ -78,7 +79,7 @@ func (store *PlayerStore) CreatePlayerId() Identifier {
// Create a new player and add it to the PlayerStore. Sends the player
// data of all other players in the game to that player and adds them to
// player map. Returns a pointer to the created player
func (store *PlayerStore) Create(conn *net.Connection, name string) *Player {
func (store *PlayerStore) Create(conn *gowsps.Connection, name string) *Player {
id := store.CreatePlayerId() // Create a unique player ID
player := Player{
Net: conn, // Set the net connection
Expand Down
24 changes: 3 additions & 21 deletions backend/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,9 @@ module backend

go 1.18

require (
github.com/gin-gonic/gin v1.7.7
github.com/gorilla/websocket v1.4.2
github.com/mitchellh/mapstructure v1.4.3
)
require github.com/jacobtread/gowsps v0.0.0-20220307042916-78f2facec237

require (
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-playground/locales v0.14.0 // indirect
github.com/go-playground/universal-translator v0.18.0 // indirect
github.com/go-playground/validator/v10 v10.10.0 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/leodido/go-urn v1.2.1 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/ugorji/go/codec v1.2.6 // indirect
golang.org/x/crypto v0.0.0-20220213190939-1e6e3497d506 // indirect
golang.org/x/sys v0.0.0-20220209214540-3681064d5158 // indirect
golang.org/x/text v0.3.7 // indirect
google.golang.org/protobuf v1.27.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/mitchellh/mapstructure v1.4.3 // indirect
)
Loading

0 comments on commit 9fa4724

Please sign in to comment.