From 570f501a76bcc5fc6d3c3faaa747b703d60dd9c8 Mon Sep 17 00:00:00 2001 From: BuildTools Date: Fri, 12 Aug 2022 21:08:47 +0200 Subject: [PATCH] Initial commit --- command/commands.go | 58 +++++++++++++ command/public_ip.go | 22 +++++ config.json | 4 + data/server_manager.go | 54 ++++++++++++ data/session_manager.go | 45 ++++++++++ go.mod | 10 +++ go.sum | 48 +++++++++++ handlers/data/handler.go | 54 ++++++++++++ handlers/loader.go | 12 +++ handlers/user/handler.go | 172 +++++++++++++++++++++++++++++++++++++++ main.go | 20 +++++ objects/config.go | 22 +++++ objects/server.go | 46 +++++++++++ objects/session.go | 8 ++ server/server.go | 13 +++ server/websocket.go | 51 ++++++++++++ 16 files changed, 639 insertions(+) create mode 100755 command/commands.go create mode 100755 command/public_ip.go create mode 100755 config.json create mode 100755 data/server_manager.go create mode 100755 data/session_manager.go create mode 100755 go.mod create mode 100755 go.sum create mode 100755 handlers/data/handler.go create mode 100755 handlers/loader.go create mode 100755 handlers/user/handler.go create mode 100755 main.go create mode 100755 objects/config.go create mode 100755 objects/server.go create mode 100755 objects/session.go create mode 100755 server/server.go create mode 100755 server/websocket.go diff --git a/command/commands.go b/command/commands.go new file mode 100755 index 0000000..554e8ed --- /dev/null +++ b/command/commands.go @@ -0,0 +1,58 @@ +package command + +import ( + "bufio" + "fmt" + "github.com/ParadoxPixel/ThemePark-Websocket/server" + "os" + "strings" +) + +var commands = make(map[string]func([]string) bool) + +func ReadConsole() { + loadCommands() + reader := bufio.NewReader(os.Stdin) + + for { + text, _ := reader.ReadString('\n') + text = strings.Replace(text, "\n", "", -1) + + args := strings.Split(text, " ") + command := strings.ToLower(args[0]) + args = args[1:] + + b := handleCommand(command, args) + if b { + break + } + } +} + +func loadCommands() { + commands["exit"] = func(i []string) bool { + server.Stop() + return true + } + + commands["ip"] = func(i []string) bool { + ip, err := GetPublicIp() + if err != nil { + fmt.Println("Unable to get public IP") + } else { + fmt.Println("IP:", ip) + } + + return false + } +} + +func handleCommand(cmd string, args []string) bool { + f := commands[cmd] + if f == nil { + fmt.Println("Unknown command:", cmd) + return false + } + + return f(args) +} diff --git a/command/public_ip.go b/command/public_ip.go new file mode 100755 index 0000000..aff1521 --- /dev/null +++ b/command/public_ip.go @@ -0,0 +1,22 @@ +package command + +import ( + "io/ioutil" + "net/http" +) + +func GetPublicIp() (str string, err error) { + url := "https://api.ipify.org?format=text" + resp, err := http.Get(url) + if err != nil { + return "", err + } + + defer resp.Body.Close() + ip, err := ioutil.ReadAll(resp.Body) + if err != nil { + return "", err + } + + return string(ip), nil +} \ No newline at end of file diff --git a/config.json b/config.json new file mode 100755 index 0000000..2dd33b8 --- /dev/null +++ b/config.json @@ -0,0 +1,4 @@ +{ + "debug": true, + "address": ":1234" +} \ No newline at end of file diff --git a/data/server_manager.go b/data/server_manager.go new file mode 100755 index 0000000..5e341bc --- /dev/null +++ b/data/server_manager.go @@ -0,0 +1,54 @@ +package data + +import ( + "github.com/ParadoxPixel/ThemePark-Websocket/objects" + "sync" +) + +var serverMux sync.RWMutex +var servers = make(map[string]*objects.Server) + +func AddServer(server *objects.Server) { + serverMux.Lock() + if _,ok := servers[server.ID]; !ok { + servers[server.ID] = server + } + serverMux.Unlock() +} + +func CanServer(server string) bool { + if server == "" || server == "null" { + return false + } + + if ok, _ := HasServer(server); ok { + return false + } else { + return true + } +} + +func GetServer(server string) *objects.Server { + serverMux.Lock() + val,ok := servers[server] + serverMux.Unlock() + if ok { + return val + } else { + return nil + } +} + +func HasServer(publicKey string) (bool, *objects.Server) { + serverMux.Lock() + val,ok := servers[publicKey] + serverMux.Unlock() + + return ok, val +} + +func RemoveServer(session string) { + serverMux.Lock() + delete(servers, session) + serverMux.Unlock() +} \ No newline at end of file diff --git a/data/session_manager.go b/data/session_manager.go new file mode 100755 index 0000000..b714a1d --- /dev/null +++ b/data/session_manager.go @@ -0,0 +1,45 @@ +package data + +import ( + "github.com/ParadoxPixel/ThemePark-Websocket/objects" + "sync" +) + +var sessionMux sync.RWMutex +var sessions = make(map[string]*objects.Session) + +func AddSession(session *objects.Session) { + sessionMux.Lock() + sessions[session.Token] = session + sessionMux.Unlock() +} + +func GetSession(session string) *objects.Session { + sessionMux.Lock() + val := sessions[session] + sessionMux.Unlock() + + return val +} + +func HasSession(session string) bool { + sessionMux.Lock() + _,ok := sessions[session] + sessionMux.Unlock() + + return ok +} + +func CanSession(session string) bool { + if session == "" || session == "null" { + return false + } + + return !HasSession(session) +} + +func RemoveSession(session string) { + sessionMux.Lock() + delete(sessions, session) + sessionMux.Unlock() +} \ No newline at end of file diff --git a/go.mod b/go.mod new file mode 100755 index 0000000..f5d1db9 --- /dev/null +++ b/go.mod @@ -0,0 +1,10 @@ +module github.com/ParadoxPixel/ThemePark-Websocket + +go 1.15 + +require ( + github.com/Mindgamesnl/socketio v0.0.0-20201021200304-eb1420bb2fbc + github.com/sirupsen/logrus v1.7.0 // indirect + github.com/tinylib/msgp v1.1.5 // indirect + golang.org/x/sys v0.0.0-20201218084310-7d0127a74742 // indirect +) diff --git a/go.sum b/go.sum new file mode 100755 index 0000000..b3ac6ac --- /dev/null +++ b/go.sum @@ -0,0 +1,48 @@ +github.com/Mindgamesnl/socketio v0.0.0-20201021200304-eb1420bb2fbc h1:CNfD/YJm5Kygge0EG7wkMRaCZEFYSchlxLVSUMYjsgs= +github.com/Mindgamesnl/socketio v0.0.0-20201021200304-eb1420bb2fbc/go.mod h1:EcGORfC+Zg1qdWutPtZ4vskpH6M8A7wi4HIYgmq0no4= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/orcaman/concurrent-map v0.0.0-20190826125027-8c72a8bb44f6/go.mod h1:Lu3tH6HLW3feq74c2GC+jIMS/K2CFcDWnWD9XkenwhI= +github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= +github.com/philhofer/fwd v1.1.1 h1:GdGcTjf5RNAxwS4QLsiMzJYj5KEvPJD3Abr261yRQXQ= +github.com/philhofer/fwd v1.1.1/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/tinylib/msgp v1.1.1/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= +github.com/tinylib/msgp v1.1.5 h1:2gXmtWueD2HefZHQe1QOy9HVzmFrLOVvsXwXBQ0ayy0= +github.com/tinylib/msgp v1.1.5/go.mod h1:eQsjooMTnV42mHu917E26IogZ2930nFyBQdofk10Udg= +github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31/go.mod h1:onvgF043R+lC5RZ8IT9rBXDaEDnpnw/Cl+HFiw+v/7Q= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/zyxar/socketio v0.0.0-20200623153533-f514eff01dd3/go.mod h1:lMCBF9JFpkAwXs2Fhpu2iiVJAv/c1BwWAkH+3atGtY8= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201218084310-7d0127a74742 h1:+CBz4km/0KPU3RGTwARGh/noP3bEwtHcq+0YcBQM2JQ= +golang.org/x/sys v0.0.0-20201218084310-7d0127a74742/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20201022035929-9cf592e881e9/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/handlers/data/handler.go b/handlers/data/handler.go new file mode 100755 index 0000000..f45847c --- /dev/null +++ b/handlers/data/handler.go @@ -0,0 +1,54 @@ +package data + +import ( + "github.com/Mindgamesnl/socketio" + "github.com/ParadoxPixel/ThemePark-Websocket/data" + "github.com/ParadoxPixel/ThemePark-Websocket/objects" + "log" + "strings" +) + +func Load(namespace socketio.Namespace, debug bool) { + namespace.OnEvent("data", func(so socketio.Socket, msg string) { + clientType := so.GetQuery().Get("type") == "server" + var ok bool + var server *objects.Server + if !clientType { + ok, server = data.HasServer(so.GetQuery().Get("control_id")) + if !ok { + if debug { + log.Println( + "No server found with id:", + so.GetQuery().Get("control_id"), + "for client:", + so.GetQuery().Get("token"), + ) + } + return + } + + _ = server.Socket.Emit("data", msg) + return + } + + ok, server = data.HasServer(so.GetQuery().Get("id")) + if !strings.HasPrefix(msg, "{") { + args := strings.SplitN(msg, "@", 2) + ok, session := server.HasSession(args[0]) + if !ok { + if debug { + log.Println( + "Unable to send packet from server:", + server.ID, + "to client:", + args[0], + ) + } + return + } + + _ = session.Emit("data", args[1]) + return + } + }) +} diff --git a/handlers/loader.go b/handlers/loader.go new file mode 100755 index 0000000..2054264 --- /dev/null +++ b/handlers/loader.go @@ -0,0 +1,12 @@ +package handlers + +import ( + "github.com/Mindgamesnl/socketio" + "github.com/ParadoxPixel/ThemePark-Websocket/handlers/data" + "github.com/ParadoxPixel/ThemePark-Websocket/handlers/user" +) + +func Load(namespace socketio.Namespace, debug bool) { + user.Load(namespace, debug) + data.Load(namespace, debug) +} diff --git a/handlers/user/handler.go b/handlers/user/handler.go new file mode 100755 index 0000000..868addd --- /dev/null +++ b/handlers/user/handler.go @@ -0,0 +1,172 @@ +package user + +import ( + "fmt" + "github.com/Mindgamesnl/socketio" + "github.com/ParadoxPixel/ThemePark-Websocket/data" + "github.com/ParadoxPixel/ThemePark-Websocket/objects" + "log" +) + +var debug bool + +func Load(namespace socketio.Namespace, b bool) { + debug = b + namespace.OnConnect(func(so socketio.Socket) { + clientType := so.GetQuery().Get("type") + if clientType == "server" { + serverLogin(so) + return + } else if clientType == "client" { + clientLogin(so) + return + } else { + _ = so.Close() + } + }) + + namespace.OnDisconnect(func(so socketio.Socket) { + clientType := so.GetQuery().Get("type") + var session string + if clientType == "server" { + session = so.GetQuery().Get("id") + obj := data.GetServer(session) + if obj == nil { + return + } + + data.RemoveServer(session) + if debug { + log.Println( + "Server with id:", + so.GetQuery().Get("id"), + "disconnected", + ) + } + for _, user := range obj.Sessions { + _ = user.Emit("close", "SERVER_ERROR") + _ = user.Close() + } + } else if clientType == "client" { + session = so.GetQuery().Get("token") + obj := data.GetSession(session) + if obj == nil { + return + } + + ok, server := data.HasServer(obj.ID) + if !ok { + return + } + + if debug { + log.Println( + "Client disconnected to id:", + so.GetQuery().Get("control_id"), + "with token:", + so.GetQuery().Get("token"), + "to attraction:", + so.GetQuery().Get("attraction"), + ) + } + + data.RemoveSession(session) + server.RemoveSession(session, so.GetQuery().Get("attraction")) + _ = server.Socket.Emit("data", "{\"channel\":\"SERVER_IN_UNREGISTER_CLIENT\",\"data\":{\"payload\":{\"uuid\":\""+obj.UUID+"\"},\"type\":\"ClientDisconnectPayload\"}}") + } + }) + + namespace.OnError(func(so socketio.Socket, err ...interface{}) { + fmt.Println(err) + }) +} + +func serverLogin(so socketio.Socket) { + id := so.GetQuery().Get("id") + if !data.CanServer(id) { + if debug { + log.Println( + "Server with id:", + so.GetQuery().Get("id"), + "already connected", + ) + } + + _ = so.Close() + return + } + + data.AddServer(&objects.Server{ + ID: id, + Sessions: make(map[string]socketio.Socket), + Attraction: make(map[string]string), + Socket: so, + }) + if debug { + log.Println( + "Server with id:", + so.GetQuery().Get("id"), + "connected", + ) + } +} + +func clientLogin(so socketio.Socket) { + if !data.CanSession(so.GetQuery().Get("token")) { + _ = so.Close() + return + } + + ok, server := data.HasServer(so.GetQuery().Get("control_id")) + if !ok { + if debug { + log.Println( + "No server with id:", + so.GetQuery().Get("control_id"), + "for token:", + so.GetQuery().Get("token"), + ) + } + _ = so.Emit("close", "SERVER_ERROR") + _ = so.Close() + return + } + + ok = server.CanAttraction(so.GetQuery().Get("attraction")) + if !ok { + if debug { + log.Println( + "Server with id:", + so.GetQuery().Get("control_id"), + "already has operator for attraction:", + so.GetQuery().Get("attraction"), + ) + } + _ = so.Emit("close", "AUTHENTICATION_ERROR") + _ = so.Close() + return + } + + data.AddSession(&objects.Session{ + Token: so.GetQuery().Get("token"), + UUID: so.GetQuery().Get("uuid"), + ID: so.GetQuery().Get("control_id"), + Attraction: so.GetQuery().Get("attraction"), + }) + server.AddSession(so.GetQuery().Get("token"), so.GetQuery().Get("attraction"), so) + if debug { + log.Println( + "Client connected to id:", + so.GetQuery().Get("control_id"), + "with token:", + so.GetQuery().Get("token"), + "to attraction:", + so.GetQuery().Get("attraction"), + ) + } + + err := server.Socket.Emit("data", "{\"channel\":\"SERVER_IN_REGISTER_CLIENT\",\"data\":{\"payload\":{\"uuid\":\""+so.GetQuery().Get("uuid")+"\",\"token\":\""+so.GetQuery().Get("token")+"\",\"attraction_id\":\""+so.GetQuery().Get("attraction")+"\"},\"type\":\"ClientConnectPayload\"}}") + if err != nil { + log.Println(err) + } +} diff --git a/main.go b/main.go new file mode 100755 index 0000000..7946236 --- /dev/null +++ b/main.go @@ -0,0 +1,20 @@ +package main + +import ( + "fmt" + "github.com/ParadoxPixel/ThemePark-Websocket/command" + "github.com/ParadoxPixel/ThemePark-Websocket/objects" + "github.com/ParadoxPixel/ThemePark-Websocket/server" +) + +func main() { + config, err := objects.LoadConfiguration("config.json") + if err != nil { + fmt.Println(err) + return + } + + go server.Start("/", config.Address, config.Debug) + + command.ReadConsole() +} diff --git a/objects/config.go b/objects/config.go new file mode 100755 index 0000000..37bffa0 --- /dev/null +++ b/objects/config.go @@ -0,0 +1,22 @@ +package objects + +import ( + "encoding/json" + "io/ioutil" +) + +type Configuration struct { + Address string `json:"address"` + Debug bool `json:"debug"` +} + +func LoadConfiguration(file string) (Configuration, error) { + bytes, err := ioutil.ReadFile(file) + if err != nil { + return Configuration{}, err + } + + var config Configuration + err = json.Unmarshal(bytes, &config) + return config, err +} \ No newline at end of file diff --git a/objects/server.go b/objects/server.go new file mode 100755 index 0000000..8ab5338 --- /dev/null +++ b/objects/server.go @@ -0,0 +1,46 @@ +package objects + +import ( + "github.com/Mindgamesnl/socketio" + "sync" +) + +type Server struct { + Socket socketio.Socket + ID string + Sessions map[string]socketio.Socket + Attraction map[string]string + mux sync.RWMutex +} + +func (serv *Server) CanAttraction(attraction string) bool { + serv.mux.RLock() + defer serv.mux.RUnlock() + + _,b := serv.Attraction[attraction] + + return !b +} + +func (serv *Server) AddSession(session, attraction string, io socketio.Socket) { + serv.mux.Lock() + serv.Sessions[session] = io + serv.Attraction[attraction] = session + serv.mux.Unlock() +} + +func (serv *Server) HasSession(session string) (bool, socketio.Socket) { + serv.mux.RLock() + defer serv.mux.RUnlock() + + io, b := serv.Sessions[session] + + return b, io +} + +func (serv *Server) RemoveSession(session, attraction string) { + serv.mux.Lock() + delete(serv.Sessions, session) + delete(serv.Attraction, attraction) + serv.mux.Unlock() +} \ No newline at end of file diff --git a/objects/session.go b/objects/session.go new file mode 100755 index 0000000..f57e459 --- /dev/null +++ b/objects/session.go @@ -0,0 +1,8 @@ +package objects + +type Session struct { + Token string `json:"token"` + UUID string `json:"uuid"` + ID string `json:"id"` + Attraction string `json:"attraction"` +} \ No newline at end of file diff --git a/server/server.go b/server/server.go new file mode 100755 index 0000000..94cf57e --- /dev/null +++ b/server/server.go @@ -0,0 +1,13 @@ +package server + +import ( + "net/http" +) + +func CreateServer(addr string) *http.Server { + server := &http.Server{ + Addr: addr, + } + + return server +} diff --git a/server/websocket.go b/server/websocket.go new file mode 100755 index 0000000..f6c9ae4 --- /dev/null +++ b/server/websocket.go @@ -0,0 +1,51 @@ +package server + +import ( + "github.com/Mindgamesnl/socketio" + "github.com/ParadoxPixel/ThemePark-Websocket/handlers" + "log" + "net/http" + "strings" + "time" +) + +var runningServer *socketio.Server + +type WrappedServer struct { + OriginalHandler http.Handler +} + +func (wrapper WrappedServer) ServeHTTP(res http.ResponseWriter, req *http.Request) { + res.Header().Set("Access-Control-Allow-Origin", "*") + res.Header().Set("Access-Control-Allow-Methods", "GET, HEAD, POST, OPTIONS") + res.Header().Set("Access-Control-Allow-Headers", "Content-Type, Access-Control-Allow-Origin") + + if !strings.HasPrefix(req.URL.Path, "/socket.io/") { + _, _ = res.Write([]byte("{\"errors\":[{\"message\":\"something went wrong\",\"code\":\"BAD_REQUEST\"}],\"response\":{}}")) + return + } + + wrapper.OriginalHandler.ServeHTTP(res, req) +} + +func Start(namespace string, address string, debug bool) { + log.Println("Starting socket server") + server, _ := socketio.NewServer(time.Second*25, time.Second*5, socketio.DefaultParser) + runningServer = server + + handlers.Load(server.Namespace(namespace), debug) + + actualServer := CreateServer(address) + wrapper := WrappedServer{ + OriginalHandler: server, + } + actualServer.Handler = wrapper + + log.Println("Starting web server on ["+address+"]") + log.Fatal(actualServer.ListenAndServe()) +} + +func Stop() { + log.Println("Stopping web server") + _ = runningServer.Close() +}