Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/simple-game-server-go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ jobs:
with:
go-version: '1.20'
- name: Lint
uses: golangci/golangci-lint-action@v2
uses: golangci/golangci-lint-action@v8
with:
version: v1.52.2
working-directory: './simple-game-server-go'
skip-go-installation: true
only-new-issues: true
- name: Build
uses: goreleaser/goreleaser-action@v2
if: startsWith(github.ref, 'refs/tags/') == false
Expand Down
1 change: 1 addition & 0 deletions go.work.sum
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r
github.com/centrifugal/centrifuge v0.21.1/go.mod h1:uAFqaz85mlIw995eZblWzfuMj1Ok4jWNGZUMYbpQfbE=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/gomodule/redigo v1.8.5/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/igm/sockjs-go/v3 v3.0.2/go.mod h1:UqchsOjeagIBFHvd+RZpLaVRbCwGilEC08EDHsD1jYE=
github.com/klauspost/cpuid/v2 v2.0.6 h1:dQ5ueTiftKxp0gyjKSx5+8BtPWkyQbd95m8Gys/RarI=
Expand Down
66 changes: 39 additions & 27 deletions simple-game-server-go/.golangci.yml
Original file line number Diff line number Diff line change
@@ -1,42 +1,54 @@
version: "2"
run:
concurrency: 4
deadline: 5m

linters-settings:
cyclop:
max-complexity: 20
gocyclo:
min-complexity: 20

linters:
enable-all: true
default: all
disable:
- depguard
- exhaustive
- exhaustruct
- exhaustivestruct
- forcetypeassert
- funlen
- gochecknoglobals
- godox
- gomoddirectives
- interfacer
- maligned
- gomnd
- ireturn
- lll
- mnd
- nestif
- nlreturn
- paralleltest
- scopelint
- tagliatelle
- testpackage
- tparallel
- varnamelen
- wrapcheck
- wsl
- godox
- forcetypeassert
- nlreturn
- tagliatelle
- varnamelen
- ireturn
- varcheck
- deadcode
- golint
- ifshort
- structcheck
- nosnakecase
- lll
settings:
cyclop:
max-complexity: 20
gocyclo:
min-complexity: 20
exclusions:
generated: lax
presets:
- comments
- common-false-positives
- legacy
- std-error-handling
paths:
- builtin$
- examples$
- third_party$
formatters:
enable:
- gci
- gofmt
- gofumpt
- goimports
exclusions:
generated: lax
paths:
- builtin$
- examples$
- third_party$
4 changes: 0 additions & 4 deletions simple-game-server-go/go.sum
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
github.com/FZambia/eagle v0.0.2 h1:35qHDuXSQevZ4w9A51k4wU7OE/tPHTEWXoywA93hvkY=
github.com/FZambia/sentinel v1.1.0 h1:qrCBfxc8SvJihYNjBWgwUI93ZCvFe/PJIPTHKmlp8a8=
github.com/Unity-Technologies/unity-gaming-services-go-sdk v0.3.1 h1:piV2hAtoc5ke3ywkIvUs82J+CphjWXoN3219isDmY00=
github.com/Unity-Technologies/unity-gaming-services-go-sdk v0.3.1/go.mod h1:WgDwSafd4alCs+HdK0z+7htBVZIe+LUrLQgM738WDd0=
github.com/Unity-Technologies/unity-gaming-services-go-sdk v0.5.0 h1:nH2XUCCx1BAV6hXhjSaIA+rOrzX2CRPz4/Yx/sZ26Do=
github.com/Unity-Technologies/unity-gaming-services-go-sdk v0.5.0/go.mod h1:WgDwSafd4alCs+HdK0z+7htBVZIe+LUrLQgM738WDd0=
github.com/Unity-Technologies/unity-gaming-services-go-sdk v0.5.4 h1:2KQYKCx44tEurLU5TlhmPhvKyvXo5QyBiTEfFqiC25g=
github.com/Unity-Technologies/unity-gaming-services-go-sdk v0.5.4/go.mod h1:WgDwSafd4alCs+HdK0z+7htBVZIe+LUrLQgM738WDd0=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
Expand Down
12 changes: 6 additions & 6 deletions simple-game-server-go/internal/game/allocated.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ func (g *Game) allocated(allocationID string) {
maxPlayers = defaultMaxPlayers
}

g.Server.SetMaxPlayers(int32(maxPlayers))
g.Server.SetServerName(fmt.Sprintf("simple-game-server-go - %s", c.AllocatedUUID))
g.Server.SetGameType(c.Extra["gameType"])
g.Server.SetGameMap(c.Extra["map"])
g.SetMaxPlayers(int32(maxPlayers))
g.SetServerName("simple-game-server-go - " + c.AllocatedUUID)
g.SetGameType(c.Extra["gameType"])
g.SetGameMap(c.Extra["map"])

// Set a random metric, if using SQP.
if c.QueryType == server.QueryProtocolSQP {
Expand Down Expand Up @@ -95,7 +95,7 @@ func (g *Game) acceptClient(server *net.TCPListener) (*net.TCPConn, error) {
}

g.clients.Store(client.RemoteAddr(), client)
currentPlayers := g.Server.PlayerJoined()
currentPlayers := g.PlayerJoined()
g.logger.WithFields(logrus.Fields{
"client_ip": client.RemoteAddr().String(),
"current_players": currentPlayers,
Expand All @@ -108,7 +108,7 @@ func (g *Game) acceptClient(server *net.TCPListener) (*net.TCPConn, error) {
func (g *Game) handleClient(client *net.TCPConn) {
defer func() {
g.clients.Delete(client.RemoteAddr())
currentPlayers := g.Server.PlayerLeft()
currentPlayers := g.PlayerLeft()
g.logger.WithFields(logrus.Fields{
"client_ip": client.RemoteAddr().String(),
"current_players": currentPlayers,
Expand Down
2 changes: 1 addition & 1 deletion simple-game-server-go/internal/game/deallocated.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func (g *Game) deallocated() {

// disconnectAllClients disconnects all remaining clients connected to the game server.
func (g *Game) disconnectAllClients() {
g.clients.Range(func(key interface{}, value interface{}) bool {
g.clients.Range(func(_, value any) bool {
client, ok := value.(*net.TCPConn)
if !ok {
return true
Expand Down
2 changes: 1 addition & 1 deletion simple-game-server-go/internal/game/game.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ func (g *Game) Start() error {
g.logger.Info("stopped")
}()

return g.Server.WaitUntilTerminated()
return g.WaitUntilTerminated()
}

// processEvents handles processing events for the operation of the
Expand Down
97 changes: 73 additions & 24 deletions simple-game-server-go/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

import (
"flag"
"io"
"os"
"path/filepath"
"runtime/debug"
"strings"

"github.com/Unity-Technologies/multiplay-examples/simple-game-server-go/internal/game"
"github.com/sirupsen/logrus"
Expand All @@ -15,29 +17,89 @@
dir, _ := os.UserHomeDir()
f := flag.NewFlagSet("simple-game-server-go", flag.ContinueOnError)

var log, logFile, tracebackLevel string
f.StringVar(&log, "log", filepath.Join(dir, "logs"), "path to the log directory to write to")
var logTargets, logFile, tracebackLevel string
f.StringVar(&logTargets, "log", "stdout,"+filepath.Join(dir, "logs"), "comma-separated log targets: 'stdout', file path, or directory")
f.StringVar(&logFile, "logFile", "", "path to the log file to write to")
f.StringVar(
&tracebackLevel,
"tracebackLevel",
"",
"the amount of detail printed by the runtime prints before exiting due to an unrecovered panic",
)
f.StringVar(&tracebackLevel, "tracebackLevel", "none", "the amount of detail printed by the runtime prints before exiting due to an unrecovered panic")

// Flags which are not used, but must be present to satisfy the default parameters in the Unity Dashboard.
var port, queryPort uint
f.UintVar(&port, "port", 8000, "port for the game server to bind to")
f.UintVar(&queryPort, "queryport", 8001, "port for the query endpoint to bind to")

return log, logFile, tracebackLevel, f.Parse(args)
return logTargets, logFile, tracebackLevel, f.Parse(args)
}

// logWritersFromTargets creates a multi-writer from the specified log targets and log file.
// If no valid targets are provided, it defaults to writing to stdout.
func logWritersFromTargets(logTargets string, logFile string, logger *logrus.Logger) io.Writer {
targets := make([]io.Writer, 0)
for _, t := range splitAndTrim(logTargets) {

Check failure on line 37 in simple-game-server-go/main.go

View workflow job for this annotation

GitHub Actions / goreleaser

missing whitespace above this line (no shared variables above range) (wsl_v5)
switch t {
case "stdout":
targets = append(targets, os.Stdout)
case "stderr":
targets = append(targets, os.Stderr)
default:
// If it's a directory, use server.log inside it
info, err := os.Stat(t)
if err == nil && info.IsDir() {
t = filepath.Join(t, "server.log")
}
f, err := os.OpenFile(t, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0o666)

Check failure on line 49 in simple-game-server-go/main.go

View workflow job for this annotation

GitHub Actions / goreleaser

missing whitespace above this line (invalid statement above assign) (wsl_v5)
if err != nil {
logger.WithError(err).Warningf("could not open log target %s for writing", t)
continue
}
targets = append(targets, f)

Check failure on line 54 in simple-game-server-go/main.go

View workflow job for this annotation

GitHub Actions / goreleaser

missing whitespace above this line (invalid statement above assign) (wsl_v5)
}
}
// logFile takes precedence
if logFile != "" {
f, err := os.OpenFile(logFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0o666)
if err == nil {
targets = append(targets, f)
} else {
logger.WithError(err).Warning("could not open log file for writing")
}
}
if len(targets) == 0 {

Check failure on line 66 in simple-game-server-go/main.go

View workflow job for this annotation

GitHub Actions / goreleaser

missing whitespace above this line (invalid statement above if) (wsl_v5)
return os.Stdout
}
return io.MultiWriter(targets...)

Check failure on line 69 in simple-game-server-go/main.go

View workflow job for this annotation

GitHub Actions / goreleaser

missing whitespace above this line (too many lines above return) (wsl_v5)
}

// splitAndTrim splits a string by the OS-specific path list separator and trims each part.
func splitAndTrim(s string) []string {
parts := make([]string, 0)
for _, p := range filepath.SplitList(s) {

Check failure on line 75 in simple-game-server-go/main.go

View workflow job for this annotation

GitHub Actions / goreleaser

missing whitespace above this line (no shared variables above range) (wsl_v5)
for _, t := range splitComma(p) {
trimmed := filepath.Clean(t)
if trimmed != "" && trimmed != "." {
parts = append(parts, trimmed)
}
}
}
return parts

Check failure on line 83 in simple-game-server-go/main.go

View workflow job for this annotation

GitHub Actions / goreleaser

missing whitespace above this line (too many lines above return) (wsl_v5)
}

// splitComma splits a string by commas and trims each part, returning a slice of non-empty strings.
func splitComma(s string) []string {
res := make([]string, 0)
for _, t := range strings.Split(s, ",") {

Check failure on line 89 in simple-game-server-go/main.go

View workflow job for this annotation

GitHub Actions / goreleaser

missing whitespace above this line (no shared variables above range) (wsl_v5)
trimmed := strings.TrimSpace(t)
if trimmed != "" && trimmed != "." {
res = append(res, trimmed)
}
}
return res

Check failure on line 95 in simple-game-server-go/main.go

View workflow job for this annotation

GitHub Actions / goreleaser

missing whitespace above this line (too many lines above return) (wsl_v5)
}

func main() {
logger := logrus.New()
logger.SetFormatter(&logrus.JSONFormatter{})

log, logFile, tracebackLevel, err := parseFlags(os.Args[1:])
logTargets, logFile, tracebackLevel, err := parseFlags(os.Args[1:])
if err != nil {
logger.WithError(err).Fatal("error parsing flags")
}
Expand All @@ -47,20 +109,7 @@
debug.SetTraceback(tracebackLevel)
}

// Let -logFile take precedence over -log
if logFile == "" && log != "" {
logFile = filepath.Join(log, "server.log")
}

if logFile != "" {
f, err := os.OpenFile(logFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0o666)
if err == nil {
defer f.Close()
logger.Out = f
} else {
logger.WithError(err).Warning("could not open log file for writing")
}
}
logger.Out = logWritersFromTargets(logTargets, logFile, logger)

g, err := game.New(logger)
if err != nil {
Expand Down
Loading
Loading