connected remotegameprivate and backend
This commit is contained in:
6
.gitignore
vendored
6
.gitignore
vendored
@@ -4,6 +4,10 @@ remotegameplay
|
|||||||
room.json
|
room.json
|
||||||
laplace
|
laplace
|
||||||
scripts/
|
scripts/
|
||||||
server/
|
server/docker/
|
||||||
client/
|
client/
|
||||||
p2p/
|
p2p/
|
||||||
|
# Ignore SQLite database created
|
||||||
|
xplane11-webRTC.db
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ type Config struct {
|
|||||||
SSHPassword string
|
SSHPassword string
|
||||||
NATEscapeServerPort string
|
NATEscapeServerPort string
|
||||||
NATEscapeBarrierPort string
|
NATEscapeBarrierPort string
|
||||||
|
BackendURL string
|
||||||
|
Rate float64
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exists reports whether the named file or directory exists.
|
// Exists reports whether the named file or directory exists.
|
||||||
@@ -63,6 +65,8 @@ func SetDefaults() error {
|
|||||||
defaults["Rooms"] = defaultPath + "room.json"
|
defaults["Rooms"] = defaultPath + "room.json"
|
||||||
defaults["ScriptToExecute"] = ""
|
defaults["ScriptToExecute"] = ""
|
||||||
defaults["SSHPassword"] = ""
|
defaults["SSHPassword"] = ""
|
||||||
|
defaults["Rate"] = 0.0
|
||||||
|
defaults["BackendURL"] = "https://xplane-webrtc.akilan.io"
|
||||||
|
|
||||||
//Paths to search for config file
|
//Paths to search for config file
|
||||||
configPaths = append(configPaths, defaultPath)
|
configPaths = append(configPaths, defaultPath)
|
||||||
|
|||||||
129
core/core.go
Normal file
129
core/core.go
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
package core
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"github.com/Akilan1999/p2p-rendering-computation/server"
|
||||||
|
"github.com/Akilan1999/remotegameplay/config"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GameSession A single Game session. In the following implementation
|
||||||
|
// the server can have only 1 user occupying it por session.
|
||||||
|
type GameSession struct {
|
||||||
|
Link string `json:"LinkID"`
|
||||||
|
Rate float64 `json:"Rate"`
|
||||||
|
Server *server.SysInfo `json:"ServerInformation"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// BroadcastServerToBackend Broadcasts server information for the backend
|
||||||
|
func BroadcastServerToBackend() error {
|
||||||
|
// Get server specs
|
||||||
|
serverInfo := server.ServerInfo()
|
||||||
|
|
||||||
|
// Get information from the config file
|
||||||
|
config, err := config.ConfigInit()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var gameSession GameSession
|
||||||
|
|
||||||
|
respIpv4orIPv6 := Ip4or6(config.IPAddress)
|
||||||
|
|
||||||
|
// Adding game session information
|
||||||
|
respIpv4orIPv6 = "https://" + respIpv4orIPv6
|
||||||
|
|
||||||
|
// Get room information
|
||||||
|
_, err = ReadRoomsFile()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Game session url
|
||||||
|
//+ file.ID
|
||||||
|
gameSession.Link = respIpv4orIPv6 + ":" + config.NATEscapeServerPort + "/?id="
|
||||||
|
// Rate for the game session
|
||||||
|
gameSession.Rate = config.Rate
|
||||||
|
// Server specs to struct GameSession
|
||||||
|
// De-referencing server info
|
||||||
|
gameSession.Server = serverInfo
|
||||||
|
// convert Struct to JSON string
|
||||||
|
gameSessionString, err := StringPrettyPrint(gameSession)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Printing the entire game session string to ensure the session
|
||||||
|
// is running
|
||||||
|
fmt.Println(gameSessionString)
|
||||||
|
|
||||||
|
form := url.Values{}
|
||||||
|
form.Add("Link", gameSession.Link)
|
||||||
|
form.Add("Rate", strconv.FormatFloat(gameSession.Rate, 'E', -1, 64))
|
||||||
|
form.Add("HostName", gameSession.Server.Hostname)
|
||||||
|
form.Add("Platform", gameSession.Server.Platform)
|
||||||
|
form.Add("RAM", strconv.Itoa(int(gameSession.Server.RAM)))
|
||||||
|
form.Add("Disk", strconv.Itoa(int(gameSession.Server.Disk)))
|
||||||
|
form.Add("GPU", gameSession.Server.GPU.Gpu.GpuName)
|
||||||
|
form.Add("CPU", gameSession.Server.CPU)
|
||||||
|
|
||||||
|
req, err := http.NewRequest("POST", config.BackendURL+"AddGameSession", strings.NewReader(form.Encode()))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
|
||||||
|
|
||||||
|
// Sending request to the backend server
|
||||||
|
client := &http.Client{}
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
// Getting the response
|
||||||
|
response, err := ioutil.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// Checking if the response succeeded
|
||||||
|
if string(response) != "success" {
|
||||||
|
return errors.New(string(response))
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// StringPrettyPrint print the contents of the obj (
|
||||||
|
// Reference: https://stackoverflow.com/questions/24512112/how-to-print-struct-variables-in-console
|
||||||
|
func StringPrettyPrint(data interface{}) (string, error) {
|
||||||
|
var p []byte
|
||||||
|
// var err := error
|
||||||
|
p, err := json.MarshalIndent(data, "", "\t")
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%s \n", p), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ip4or6 Helper function to check if the IP address is IPV4 or
|
||||||
|
// IPV6 (https://socketloop.com/tutorials/golang-check-if-ip-address-is-version-4-or-6)
|
||||||
|
func Ip4or6(s string) string {
|
||||||
|
for i := 0; i < len(s); i++ {
|
||||||
|
switch s[i] {
|
||||||
|
case '.':
|
||||||
|
return s
|
||||||
|
case ':':
|
||||||
|
return "[" + s + "]"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "[" + s + "]"
|
||||||
|
|
||||||
|
}
|
||||||
6
go.mod
6
go.mod
@@ -7,7 +7,13 @@ replace github.com/Akilan1999/p2p-rendering-computation => /Users/akilan/Documen
|
|||||||
require (
|
require (
|
||||||
github.com/Akilan1999/p2p-rendering-computation v0.0.0-00010101000000-000000000000
|
github.com/Akilan1999/p2p-rendering-computation v0.0.0-00010101000000-000000000000
|
||||||
github.com/fatedier/frp v0.47.0 // indirect
|
github.com/fatedier/frp v0.47.0 // indirect
|
||||||
|
github.com/gin-gonic/gin v1.6.3
|
||||||
|
github.com/google/uuid v1.3.0
|
||||||
github.com/gorilla/websocket v1.5.0
|
github.com/gorilla/websocket v1.5.0
|
||||||
|
github.com/kataras/go-mailer v0.1.0
|
||||||
github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5 // indirect
|
github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5 // indirect
|
||||||
github.com/spf13/viper v1.8.1
|
github.com/spf13/viper v1.8.1
|
||||||
|
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||||
|
gorm.io/driver/sqlite v1.4.4
|
||||||
|
gorm.io/gorm v1.24.5
|
||||||
)
|
)
|
||||||
|
|||||||
21
go.sum
21
go.sum
@@ -116,7 +116,6 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF
|
|||||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
|
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
|
||||||
github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0=
|
github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0=
|
||||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
|
|
||||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
||||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||||
github.com/apenella/go-ansible v1.1.0/go.mod h1:tHqFBSwWXF9k2hkLQWfq6oxMQZHslySQqttkA2siyqE=
|
github.com/apenella/go-ansible v1.1.0/go.mod h1:tHqFBSwWXF9k2hkLQWfq6oxMQZHslySQqttkA2siyqE=
|
||||||
@@ -325,7 +324,6 @@ github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm
|
|||||||
github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14=
|
github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14=
|
||||||
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
|
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
|
||||||
github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
|
github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
|
||||||
github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0=
|
|
||||||
github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
|
github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
|
||||||
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
|
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
|
||||||
github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4=
|
github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4=
|
||||||
@@ -333,7 +331,6 @@ github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4u
|
|||||||
github.com/go-git/go-billy/v5 v5.2.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
|
github.com/go-git/go-billy/v5 v5.2.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
|
||||||
github.com/go-git/go-billy/v5 v5.3.1 h1:CPiOUAzKtMRvolEKw+bG1PLRpT7D3LIs3/3ey4Aiu34=
|
github.com/go-git/go-billy/v5 v5.3.1 h1:CPiOUAzKtMRvolEKw+bG1PLRpT7D3LIs3/3ey4Aiu34=
|
||||||
github.com/go-git/go-billy/v5 v5.3.1/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
|
github.com/go-git/go-billy/v5 v5.3.1/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
|
||||||
github.com/go-git/go-git-fixtures/v4 v4.2.1 h1:n9gGL1Ct/yIw+nfsfr8s4+sbhT+Ncu2SubfXjIWgci8=
|
|
||||||
github.com/go-git/go-git-fixtures/v4 v4.2.1/go.mod h1:K8zd3kDUAykwTdDCr+I0per6Y6vMiRR/nnVTBtavnB0=
|
github.com/go-git/go-git-fixtures/v4 v4.2.1/go.mod h1:K8zd3kDUAykwTdDCr+I0per6Y6vMiRR/nnVTBtavnB0=
|
||||||
github.com/go-git/go-git/v5 v5.4.2 h1:BXyZu9t0VkbiHtqrsvdq39UDhGJTl1h55VW6CSC4aY4=
|
github.com/go-git/go-git/v5 v5.4.2 h1:BXyZu9t0VkbiHtqrsvdq39UDhGJTl1h55VW6CSC4aY4=
|
||||||
github.com/go-git/go-git/v5 v5.4.2/go.mod h1:gQ1kArt6d+n+BGd+/B/I74HwRTLhth2+zti4ihgckDc=
|
github.com/go-git/go-git/v5 v5.4.2/go.mod h1:gQ1kArt6d+n+BGd+/B/I74HwRTLhth2+zti4ihgckDc=
|
||||||
@@ -556,6 +553,11 @@ github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOl
|
|||||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
|
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
|
||||||
github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU=
|
github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU=
|
||||||
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
|
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
|
||||||
|
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||||
|
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||||
|
github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||||
|
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||||
|
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||||
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||||
github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||||
@@ -573,6 +575,8 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X
|
|||||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||||
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
||||||
|
github.com/kataras/go-mailer v0.1.0 h1:KffyTZnKbaNzkRoyckaJZ4/jsUigvyUWxdrXXTTK7cY=
|
||||||
|
github.com/kataras/go-mailer v0.1.0/go.mod h1:+js8BH5a6EFHhufrz90OBaL9vSv2OFwWyPtJuP98mGk=
|
||||||
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hvgyYSX4TO5NpyC606/Z4SxnNYbT+WX27or6Ck=
|
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hvgyYSX4TO5NpyC606/Z4SxnNYbT+WX27or6Ck=
|
||||||
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
||||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||||
@@ -618,7 +622,6 @@ github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN
|
|||||||
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
|
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
|
||||||
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||||
github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho=
|
github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho=
|
||||||
github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A=
|
|
||||||
github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA=
|
github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA=
|
||||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||||
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||||
@@ -629,6 +632,8 @@ github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky
|
|||||||
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||||
github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
|
github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI=
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI=
|
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||||
@@ -937,6 +942,8 @@ github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijb
|
|||||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||||
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||||
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
|
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
|
||||||
|
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||||
|
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||||
github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU=
|
github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU=
|
||||||
github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM=
|
github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM=
|
||||||
github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
|
github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
|
||||||
@@ -1292,7 +1299,6 @@ golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/term v0.3.0 h1:qoo4akIqOcDME5bhc/NgxUdovd6BSS2uMsVjB56q1xI=
|
|
||||||
golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
|
golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
|
||||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
@@ -1628,6 +1634,11 @@ gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C
|
|||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
gorm.io/driver/sqlite v1.4.4 h1:gIufGoR0dQzjkyqDyYSCvsYR6fba1Gw5YKDqKeChxFc=
|
||||||
|
gorm.io/driver/sqlite v1.4.4/go.mod h1:0Aq3iPO+v9ZKbcdiz8gLWRw5VOPcBOPUQJFLq5e2ecI=
|
||||||
|
gorm.io/gorm v1.24.0/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
|
||||||
|
gorm.io/gorm v1.24.5 h1:g6OPREKqqlWq4kh/3MCQbZKImeB9e6Xgc4zD+JgNZGE=
|
||||||
|
gorm.io/gorm v1.24.5/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
|
||||||
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
||||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||||
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
|
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
|
||||||
|
|||||||
318
main.go
318
main.go
@@ -1,191 +1,219 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/Akilan1999/remotegameplay/config"
|
"github.com/Akilan1999/remotegameplay/config"
|
||||||
"github.com/Akilan1999/remotegameplay/core"
|
"github.com/Akilan1999/remotegameplay/core"
|
||||||
"log"
|
gameserver "github.com/Akilan1999/remotegameplay/server"
|
||||||
"math/rand"
|
"log"
|
||||||
"net/http"
|
"math/rand"
|
||||||
"os/exec"
|
"net/http"
|
||||||
"time"
|
"os/exec"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
addr := flag.String("addr", "localhost", "Listen address")
|
addr := flag.String("addr", "localhost", "Listen address")
|
||||||
port := flag.String("port", "8888", "port for running the server")
|
port := flag.String("port", "8888", "port for running the server")
|
||||||
tls := flag.Bool("tls", false, "Use TLS")
|
tls := flag.Bool("tls", false, "Use TLS")
|
||||||
//setconfig := flag.Bool("setconfig", false, "Generates a config file")
|
//setconfig := flag.Bool("setconfig", false, "Generates a config file")
|
||||||
certFile := flag.String("certFile", "files/server.crt", "TLS cert file")
|
certFile := flag.String("certFile", "files/server.crt", "TLS cert file")
|
||||||
keyFile := flag.String("keyFile", "files/server.key", "TLS key file")
|
keyFile := flag.String("keyFile", "files/server.key", "TLS key file")
|
||||||
headless := flag.Bool("headless", false, "Creating screenshare using headless mode")
|
headless := flag.Bool("headless", false, "Creating screenshare using headless mode")
|
||||||
roomInfo := flag.Bool("roomInfo", false, "Getting room id of headless server")
|
roomInfo := flag.Bool("roomInfo", false, "Getting room id of headless server")
|
||||||
killServer := flag.Bool("killServer", false, "Kills the laplace")
|
killServer := flag.Bool("killServer", false, "Kills the laplace")
|
||||||
killChromium := flag.Bool("killChromium", false, "Kills all chromuim")
|
killChromium := flag.Bool("killChromium", false, "Kills all chromuim")
|
||||||
BinaryToExcute := flag.String("BinaryToExecute", "", "Providing path (i.e Absolute path) of binary to execute")
|
BinaryToExcute := flag.String("BinaryToExecute", "", "Providing path (i.e Absolute path) of binary to execute")
|
||||||
|
GameServer := flag.Bool("GameServer", false, "Starts the game server by default")
|
||||||
|
Migrate := flag.Bool("Migrate", false, "Sets up the tables for the Sqlite database")
|
||||||
|
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
rand.Seed(time.Now().UnixNano())
|
rand.Seed(time.Now().UnixNano())
|
||||||
server := core.GetHttp()
|
server := core.GetHttp()
|
||||||
|
|
||||||
err := config.SetDefaults()
|
err := config.SetDefaults()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// running implementation to escape NAT
|
// Print out room information
|
||||||
Server, barrireKVM, err := core.EscapeNAT(*port)
|
if *roomInfo {
|
||||||
if err != nil {
|
room, err := core.ReadRoomsFile()
|
||||||
log.Fatalln(err)
|
if err != nil {
|
||||||
}
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
|
||||||
Config, err := config.ConfigInit()
|
PrettyPrint(room)
|
||||||
if err != nil {
|
return
|
||||||
log.Fatalln(err)
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Config.IPAddress = "64.227.168.102"
|
// Running in headless mode
|
||||||
Config.NATEscapeServerPort = Server
|
if *headless {
|
||||||
Config.NATEscapeBarrierPort = barrireKVM
|
Config, err := config.ConfigInit()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
|
||||||
fmt.Println(Config)
|
// Returns the URl address type
|
||||||
|
Addr := Ip4or6(Config.IPAddress)
|
||||||
|
|
||||||
err = Config.WriteConfig()
|
// If address is provided
|
||||||
if err != nil {
|
if *addr != "" {
|
||||||
log.Fatalln(err)
|
Addr = *addr
|
||||||
}
|
// Add brackets if the ip address is ipv6
|
||||||
|
Addr = Ip4or6(Addr)
|
||||||
|
}
|
||||||
|
|
||||||
// Print out room information
|
var TaskExecute string
|
||||||
if *roomInfo {
|
|
||||||
room, err := core.ReadRoomsFile()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalln(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
PrettyPrint(room)
|
if *BinaryToExcute != "" {
|
||||||
return
|
TaskExecute = *BinaryToExcute
|
||||||
}
|
} else {
|
||||||
|
// Read binary from config file
|
||||||
|
TaskExecute = Config.ScriptToExecute
|
||||||
|
}
|
||||||
|
|
||||||
// Running in headless mode
|
// Starting screen share headless
|
||||||
if *headless {
|
cmd := exec.Command("chromium-browser", "--no-sandbox", "--auto-select-desktop-capture-source=Entire screen", "--url", "https://"+Addr+":"+*port+"/?mode=headless", "--ignore-certificate-errors")
|
||||||
Config, err := config.ConfigInit()
|
if err := cmd.Start(); err != nil {
|
||||||
if err != nil {
|
log.Fatalln(err)
|
||||||
log.Fatalln(err)
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Returns the URl address type
|
// Makes program sleep for 2 seconds to allow chromium browser to open
|
||||||
Addr := Ip4or6(Config.IPAddress)
|
time.Sleep(3 * time.Second)
|
||||||
|
|
||||||
// If address is provided
|
// Task to be executed
|
||||||
if *addr != "" {
|
err = RunTask(TaskExecute)
|
||||||
Addr = *addr
|
if err != nil {
|
||||||
// Add brackets if the ip address is ipv6
|
fmt.Println(err)
|
||||||
Addr = Ip4or6(Addr)
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var TaskExecute string
|
return
|
||||||
|
|
||||||
if *BinaryToExcute != "" {
|
}
|
||||||
TaskExecute = *BinaryToExcute
|
|
||||||
} else {
|
|
||||||
// Read binary from config file
|
|
||||||
TaskExecute = Config.ScriptToExecute
|
|
||||||
}
|
|
||||||
|
|
||||||
// Starting screen share headless
|
// kills laplace server
|
||||||
cmd := exec.Command("chromium-browser", "--no-sandbox", "--auto-select-desktop-capture-source=Entire screen", "--url", "https://"+Addr+":"+*port+"/?mode=headless", "--ignore-certificate-errors")
|
if *killServer {
|
||||||
if err := cmd.Start(); err != nil {
|
cmd := exec.Command("pkill", "remotegameplay")
|
||||||
log.Fatalln(err)
|
if err := cmd.Run(); err != nil {
|
||||||
}
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// kills chromium server
|
||||||
|
if *killChromium {
|
||||||
|
cmd := exec.Command("pkill", "chromium")
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Makes program sleep for 2 seconds to allow chromium browser to open
|
if *Migrate {
|
||||||
time.Sleep(3 * time.Second)
|
// Connect to Sqlite
|
||||||
|
connect, err := gameserver.Connect()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
// Migrate table
|
||||||
|
session, err := gameserver.CreateTables(connect)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
session.Scan(gameserver.GameSession{})
|
||||||
|
|
||||||
// Task to be executed
|
return
|
||||||
err = RunTask(TaskExecute)
|
}
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
if *GameServer {
|
||||||
|
gameserver.Server(*port)
|
||||||
|
} else {
|
||||||
|
if *tls {
|
||||||
|
log.Println("Listening on TLS:", *addr+":"+*port)
|
||||||
|
if err := http.ListenAndServeTLS(*addr+":"+*port, *certFile, *keyFile, server); err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.Println("Listening:", *addr+":"+*port)
|
||||||
|
if err := http.ListenAndServe(*addr+":"+*port, server); err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
// running implementation to escape NAT
|
||||||
|
Server, barrireKVM, err := core.EscapeNAT(*port)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
|
||||||
// kills laplace server
|
Config, err := config.ConfigInit()
|
||||||
if *killServer {
|
if err != nil {
|
||||||
cmd := exec.Command("pkill", "remotegameplay")
|
log.Fatalln(err)
|
||||||
if err := cmd.Run(); err != nil {
|
}
|
||||||
fmt.Println(err)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// kills chromium server
|
|
||||||
if *killChromium {
|
|
||||||
cmd := exec.Command("pkill", "chromium")
|
|
||||||
if err := cmd.Run(); err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if *tls {
|
Config.IPAddress = "64.227.168.102"
|
||||||
log.Println("Listening on TLS:", *addr+":"+*port)
|
Config.NATEscapeServerPort = Server
|
||||||
if err := http.ListenAndServeTLS(*addr+":"+*port, *certFile, *keyFile, server); err != nil {
|
Config.NATEscapeBarrierPort = barrireKVM
|
||||||
log.Fatalln(err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log.Println("Listening:", *addr+":"+*port)
|
|
||||||
if err := http.ListenAndServe(*addr+":"+*port, server); err != nil {
|
|
||||||
log.Fatalln(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start P2PRC server
|
err = Config.WriteConfig()
|
||||||
//_, err = abstractions.Start()
|
if err != nil {
|
||||||
//if err != nil {
|
log.Fatalln(err)
|
||||||
// return
|
}
|
||||||
//}
|
|
||||||
|
err = core.BroadcastServerToBackend()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
} else {
|
||||||
|
fmt.Println("success broadcasting to game server")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start P2PRC server
|
||||||
|
//_, err = abstractions.Start()
|
||||||
|
//if err != nil {
|
||||||
|
// return
|
||||||
|
//}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// PrettyPrint print the contents of the obj (
|
// PrettyPrint print the contents of the obj (
|
||||||
// Reference: https://stackoverflow.com/questions/24512112/how-to-print-struct-variables-in-console
|
// Reference: https://stackoverflow.com/questions/24512112/how-to-print-struct-variables-in-console
|
||||||
func PrettyPrint(data interface{}) {
|
func PrettyPrint(data interface{}) {
|
||||||
var p []byte
|
var p []byte
|
||||||
// var err := error
|
// var err := error
|
||||||
p, err := json.MarshalIndent(data, "", "\t")
|
p, err := json.MarshalIndent(data, "", "\t")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
fmt.Printf("%s \n", p)
|
fmt.Printf("%s \n", p)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ip4or6 Helper function to check if the IP address is IPV4 or
|
// Ip4or6 Helper function to check if the IP address is IPV4 or
|
||||||
// IPV6 (https://socketloop.com/tutorials/golang-check-if-ip-address-is-version-4-or-6)
|
// IPV6 (https://socketloop.com/tutorials/golang-check-if-ip-address-is-version-4-or-6)
|
||||||
func Ip4or6(s string) string {
|
func Ip4or6(s string) string {
|
||||||
for i := 0; i < len(s); i++ {
|
for i := 0; i < len(s); i++ {
|
||||||
switch s[i] {
|
switch s[i] {
|
||||||
case '.':
|
case '.':
|
||||||
return s
|
return s
|
||||||
case ':':
|
case ':':
|
||||||
return "[" + s + "]"
|
return "[" + s + "]"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return "[" + s + "]"
|
return "[" + s + "]"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func RunTask(task string) error {
|
func RunTask(task string) error {
|
||||||
// Halts the process
|
// Halts the process
|
||||||
cmd := exec.Command("sh", task)
|
cmd := exec.Command("sh", task)
|
||||||
if err := cmd.Start(); err != nil {
|
if err := cmd.Start(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
16
server/auth/auth.go
Normal file
16
server/auth/auth.go
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package auth
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/sha256"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
// HashPassword Hash password passed through the
|
||||||
|
// parameter
|
||||||
|
func HashPassword(Password string) (string, error) {
|
||||||
|
data := []byte(Password)
|
||||||
|
hash := sha256.Sum256(data)
|
||||||
|
// returning hash as a string
|
||||||
|
return string(hash[:]), nil
|
||||||
|
}
|
||||||
|
|
||||||
17
server/auth/auth_test.go
Normal file
17
server/auth/auth_test.go
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
package auth
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Function to test if the password is hashed
|
||||||
|
func TestHashPassword(t *testing.T) {
|
||||||
|
Password, err := HashPassword("AKILAN1999")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
fmt.Println("Password Hash")
|
||||||
|
fmt.Println(Password)
|
||||||
|
}
|
||||||
15
server/connection.go
Normal file
15
server/connection.go
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"gorm.io/driver/sqlite"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Connect Connection to the Sqlite database
|
||||||
|
func Connect() (*gorm.DB, error) {
|
||||||
|
db, err := gorm.Open(sqlite.Open("xplane11-webRTC.db"), &gorm.Config{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return db, nil
|
||||||
|
}
|
||||||
16
server/connection_test.go
Normal file
16
server/connection_test.go
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Testing connection to the Database
|
||||||
|
func TestConnect(t *testing.T) {
|
||||||
|
// Connect to database created
|
||||||
|
_, err := Connect()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
}
|
||||||
26
server/login.go
Normal file
26
server/login.go
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"github.com/Akilan1999/remotegameplay/server/auth"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
func AuthLogin(db *gorm.DB, user *Users) (string, error) {
|
||||||
|
// Generate Hash from password
|
||||||
|
password, err := auth.HashPassword(user.Password)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
match, err := CheckIfEmailAndPasswordMatch(db, user.EmailID, password)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if match == "success" {
|
||||||
|
return "success", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", errors.New("Something is wrong with from our side. Email us: me@akilan.io to find out more. ")
|
||||||
|
}
|
||||||
44
server/mailServer.go
Normal file
44
server/mailServer.go
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
package server
|
||||||
|
|
||||||
|
// MailerSend This function sends an automated email to the
|
||||||
|
// person requesting it
|
||||||
|
func MailerSend(subject, email, message string) error {
|
||||||
|
// Load email credentials from the configuration file
|
||||||
|
//Config, err := config.ConfigInit()
|
||||||
|
//if err != nil {
|
||||||
|
// return err
|
||||||
|
//}
|
||||||
|
|
||||||
|
// sender configuration.
|
||||||
|
//config := mailer.Config{
|
||||||
|
// Host: Config.EmailHost,
|
||||||
|
// Username: Config.EmailID,
|
||||||
|
// Password: Config.EmailPassword,
|
||||||
|
// FromAddr: Config.EmailID,
|
||||||
|
// Port: Config.EmailPort,
|
||||||
|
// // Enable UseCommand to support sendmail unix command,
|
||||||
|
// // if this field is true then Host, Username, Password and Port are not required,
|
||||||
|
// // because this info already exists in your local sendmail configuration.
|
||||||
|
// //
|
||||||
|
// // Defaults to false.
|
||||||
|
// UseCommand: false,
|
||||||
|
//}
|
||||||
|
|
||||||
|
// initialize a new mail sender service.
|
||||||
|
//sender := mailer.New(config)
|
||||||
|
//
|
||||||
|
//// the rich message body.
|
||||||
|
//content := message
|
||||||
|
//
|
||||||
|
//// the recipient(s).
|
||||||
|
//to := []string{email}
|
||||||
|
//
|
||||||
|
//// send the e-mail.
|
||||||
|
//err = sender.Send(subject, content, to...)
|
||||||
|
//
|
||||||
|
//if err != nil {
|
||||||
|
// return err
|
||||||
|
//}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
14
server/mailServer_test.go
Normal file
14
server/mailServer_test.go
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestMailerSend(t *testing.T) {
|
||||||
|
err := MailerSend("Test", "akilanselva@hotmail.com", "Welcome from Xplane=WebRTC")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
}
|
||||||
341
server/models.go
Normal file
341
server/models.go
Normal file
@@ -0,0 +1,341 @@
|
|||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"github.com/Akilan1999/remotegameplay/server/auth"
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
//var users []User = []User{
|
||||||
|
// User{Username: "foobar", FirstName: "Foo", LastName: "Bar", Salary: 200},
|
||||||
|
// User{Username: "helloworld", FirstName: "Hello", LastName: "World", Salary: 200},
|
||||||
|
// User{Username: "john", FirstName: "John", Salary: 200},
|
||||||
|
//}
|
||||||
|
|
||||||
|
// LoginSession Storing information of the login session
|
||||||
|
type LoginSession struct {
|
||||||
|
SessionKey string `json:"SessionKey"`
|
||||||
|
UserID string `json:"UserID"`
|
||||||
|
User Users `gorm:"foreignKey:UserID;references:UserID" json:"Users"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Users This struct focuses on storing user
|
||||||
|
// information
|
||||||
|
type Users struct {
|
||||||
|
UserID string `json:"userID"`
|
||||||
|
Name string `form:"Name" json:"Name"`
|
||||||
|
Password string `form:"Password" binding:"required" json:"Password"`
|
||||||
|
EmailID string `form:"EmailID" binding:"required" json:"EmailID"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GameSession A single Game session. In the following implementation
|
||||||
|
// the server can have only 1 user occupying it por session.
|
||||||
|
type GameSession struct {
|
||||||
|
GameSessionID string `json:"GameSessionID"`
|
||||||
|
// Link of the stream started for gameplay
|
||||||
|
Link string `form:"Link" binding:"required" json:"LinkID"`
|
||||||
|
ServerID string `json:"ServerID"`
|
||||||
|
Rate float64 `form:"Rate" binding:"required" json:"Rate"`
|
||||||
|
Server ServerSpecs `gorm:"foreignKey:ID;references:ServerID" json:"ServerInformation"`
|
||||||
|
// State of the server if it's in use
|
||||||
|
// or free
|
||||||
|
State bool
|
||||||
|
UserID string `json:"UserID"`
|
||||||
|
User Users `gorm:"foreignKey:UserID;references:UserID" json:"ServerInformation"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServerSpecs Server specs information
|
||||||
|
type ServerSpecs struct {
|
||||||
|
ID string `bson: ID`
|
||||||
|
Hostname string `form:"Hostname" binding:"required" bson:hostname`
|
||||||
|
Platform string `form:"Platform" binding:"required" bson:platform`
|
||||||
|
CPU string `form:"CPU" binding:"required" bson:cpu`
|
||||||
|
RAM string `form:"RAM" binding:"required" bson:ram`
|
||||||
|
Disk string `form:"Disk" binding:"required" bson:disk`
|
||||||
|
GPU string `form:"GPU" binding:"required" bson:GPU`
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateTables CreateDB Add tables to the database
|
||||||
|
func CreateTables(db *gorm.DB) (*gorm.DB, error) {
|
||||||
|
// Creates table to store login sessions
|
||||||
|
db.AutoMigrate(LoginSession{})
|
||||||
|
// Creates table to store user information
|
||||||
|
db.AutoMigrate(Users{})
|
||||||
|
// Creates table of type GameSessions
|
||||||
|
db.AutoMigrate(GameSession{})
|
||||||
|
// Creates table of type ServerSpecs
|
||||||
|
db.AutoMigrate(ServerSpecs{})
|
||||||
|
// returns variable DB of type *gorm.DB and error
|
||||||
|
// which is nil at the current moment
|
||||||
|
return db, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveTableGameSession Removes table of type
|
||||||
|
func RemoveTableGameSession(db *gorm.DB) (*gorm.DB, error) {
|
||||||
|
var gameSession GameSession
|
||||||
|
// Creates table of type GameSessions
|
||||||
|
db.Delete(gameSession)
|
||||||
|
// returns variable DB of type *gorm.DB and error
|
||||||
|
// which is nil at the current moment
|
||||||
|
return db, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DisplayGameSessions Returns all the rows of all the game session information
|
||||||
|
// to display
|
||||||
|
func DisplayGameSessions(db *gorm.DB) ([]*GameSession, error) {
|
||||||
|
// select * from GameSessions
|
||||||
|
rows, err := db.Model(&GameSession{}).Rows()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
// Variable to store information of all game sessions
|
||||||
|
var GameSessions []*GameSession
|
||||||
|
|
||||||
|
// Iterates through all game session rows
|
||||||
|
for rows.Next() {
|
||||||
|
var gameSession GameSession
|
||||||
|
err := db.ScanRows(rows, &gameSession)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetServerSpecs based on ServerSpecs ID
|
||||||
|
// derived from the game session
|
||||||
|
specs, err := GetSeverSpecs(db, gameSession.ServerID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// Add server information to the struct Game session
|
||||||
|
gameSession.Server = *specs
|
||||||
|
|
||||||
|
// Append game result to the array
|
||||||
|
GameSessions = append(GameSessions, &gameSession)
|
||||||
|
}
|
||||||
|
|
||||||
|
return GameSessions, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSeverSpecs Get server specs information based on the ID provided
|
||||||
|
func GetSeverSpecs(db *gorm.DB, ID string) (*ServerSpecs, error) {
|
||||||
|
// query to get server specs to that game session
|
||||||
|
ServerSpecsRows, err := db.Model(&ServerSpecs{}).Where("ID = ?", ID).Rows()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer ServerSpecsRows.Close()
|
||||||
|
|
||||||
|
// Variable to store server specs
|
||||||
|
var serverSpecs ServerSpecs
|
||||||
|
|
||||||
|
// iterate thought the game session available in that server
|
||||||
|
for ServerSpecsRows.Next() {
|
||||||
|
err := db.ScanRows(ServerSpecsRows, &serverSpecs)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &serverSpecs, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddServerSpecs Add server specs
|
||||||
|
func AddServerSpecs(db *gorm.DB, gameSession *GameSession) error {
|
||||||
|
// Generate Random UUID for Game Session and server specs
|
||||||
|
gameSessionID, err := uuid.NewUUID()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
serverSpecsID, err := uuid.NewRandom()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// Create for entry for server specs because
|
||||||
|
// the game session foreign relies on the
|
||||||
|
// server specs primary key
|
||||||
|
gameSession.Server.ID = serverSpecsID.String()
|
||||||
|
|
||||||
|
// Adding the IDs for both the game session and
|
||||||
|
// the foreign key for server specs
|
||||||
|
gameSession.GameSessionID = gameSessionID.String()
|
||||||
|
gameSession.ServerID = serverSpecsID.String()
|
||||||
|
|
||||||
|
// Create Game Session
|
||||||
|
db.Create(gameSession)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckIfEmailExits Function to check if the username has been taken already or not
|
||||||
|
func CheckIfEmailExits(db *gorm.DB, Email string) error {
|
||||||
|
UserRows, err := db.Model(&Users{}).Where("email_id = ?", Email).Rows()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer UserRows.Close()
|
||||||
|
|
||||||
|
if UserRows.Next() {
|
||||||
|
return errors.New("Email already taken. ")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisterUser Function to insert new user information
|
||||||
|
func RegisterUser(db *gorm.DB, UserInformation *Users) error {
|
||||||
|
// Check if the username is already taken
|
||||||
|
err := CheckIfEmailExits(db, UserInformation.EmailID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate UserID using UUID
|
||||||
|
id := uuid.New()
|
||||||
|
UserInformation.UserID = id.String()
|
||||||
|
|
||||||
|
// Generate Hash for the plaintext password
|
||||||
|
password, err := auth.HashPassword(UserInformation.Password)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
UserInformation.Password = password
|
||||||
|
// Insert the record to the database
|
||||||
|
db.Create(UserInformation)
|
||||||
|
|
||||||
|
// Send email to the user that the user is successfully created
|
||||||
|
//err = MailerSend("Xplane 11 WebRTC", UserInformation.EmailID, `<h1>Welcome to Xplane 11 WebRTC ! `+UserInformation.Name+`</h1>`)
|
||||||
|
//if err != nil {
|
||||||
|
// return err
|
||||||
|
//}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckIfEmailAndPasswordMatch Check email and password information for login
|
||||||
|
func CheckIfEmailAndPasswordMatch(db *gorm.DB, emailID string, Password string) (string, error) {
|
||||||
|
UserRows, err := db.Model(&Users{}).Where("email_id = ? AND password = ?", emailID, Password).Rows()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
defer UserRows.Close()
|
||||||
|
|
||||||
|
if UserRows.Next() {
|
||||||
|
return "success", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", errors.New("Wrong login email or password ")
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetUserID Gets userID based on the EmailID
|
||||||
|
func GetUserID(db *gorm.DB, emailID string) (string, error) {
|
||||||
|
UserRows, err := db.Model(&Users{}).Where("email_id = ? ", emailID).Rows()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
defer UserRows.Close()
|
||||||
|
|
||||||
|
// Variable to store user information
|
||||||
|
var users Users
|
||||||
|
|
||||||
|
for UserRows.Next() {
|
||||||
|
err = db.ScanRows(UserRows, &users)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return users.UserID, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", errors.New("User not found. ")
|
||||||
|
}
|
||||||
|
|
||||||
|
// getUserInformation Gets user information based on the user ID provided
|
||||||
|
func getUserInformation(db *gorm.DB, ID string) (*Users, error) {
|
||||||
|
UserRows, err := db.Model(&Users{}).Where("user_id = ? ", ID).Rows()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer UserRows.Close()
|
||||||
|
|
||||||
|
// Variable to store user information
|
||||||
|
var users Users
|
||||||
|
|
||||||
|
for UserRows.Next() {
|
||||||
|
err = db.ScanRows(UserRows, &users)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &users, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, errors.New("User not found. ")
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateLoginSession function to create login session and setting expiry time
|
||||||
|
// for the login session
|
||||||
|
func CreateLoginSession(db *gorm.DB, user *Users) (*LoginSession, error) {
|
||||||
|
// Get userID to be added to the session
|
||||||
|
userID, err := GetUserID(db, user.EmailID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// Generating Session ID
|
||||||
|
newUUID, err := uuid.NewRandom()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create login session
|
||||||
|
var loginSession LoginSession
|
||||||
|
// Adding UUID key as session ID
|
||||||
|
loginSession.SessionKey = newUUID.String()
|
||||||
|
// Adding User ID to link to the user information
|
||||||
|
loginSession.UserID = userID
|
||||||
|
|
||||||
|
// Add session information to the table sessions
|
||||||
|
db.Create(loginSession)
|
||||||
|
|
||||||
|
return &loginSession, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveLoginSession Removes session from the database based on the session ID provided
|
||||||
|
func RemoveLoginSession(db *gorm.DB, SessionID string) error {
|
||||||
|
// Delete session from the database
|
||||||
|
err := db.Where("session_key = ?", SessionID).Delete(LoginSession{})
|
||||||
|
if err != nil {
|
||||||
|
return err.Error
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetUserInformation Gets the user information based on the session ID provided
|
||||||
|
func GetUserInformation(db *gorm.DB, SessionID string) (*Users, error) {
|
||||||
|
// Gets user ID from Session ID
|
||||||
|
// select * from LoginSessions where session_key = <session key>
|
||||||
|
rows, err := db.Model(&LoginSession{}).Where("session_key = ?", SessionID).Rows()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
// Iterates through all game session rows
|
||||||
|
for rows.Next() {
|
||||||
|
var loginSession LoginSession
|
||||||
|
err := db.ScanRows(rows, &loginSession)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get User information based on the User ID
|
||||||
|
user, err := getUserInformation(db, loginSession.UserID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// Ensure the password field is empty
|
||||||
|
user.Password = ""
|
||||||
|
// return struct user
|
||||||
|
return user, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, errors.New("Session not found. ")
|
||||||
|
}
|
||||||
209
server/models_test.go
Normal file
209
server/models_test.go
Normal file
@@ -0,0 +1,209 @@
|
|||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
// helper functions: These functions are designed
|
||||||
|
// to reduce repetitive steps
|
||||||
|
func CreateAndInsertData() (*gorm.DB,error) {
|
||||||
|
// Connect to database created
|
||||||
|
DB , err := Connect()
|
||||||
|
if err != nil {
|
||||||
|
return nil,err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the appropriate table
|
||||||
|
DB, err = CreateTables(DB)
|
||||||
|
if err != nil {
|
||||||
|
return nil,err
|
||||||
|
}
|
||||||
|
|
||||||
|
DB.Scan(&GameSession{})
|
||||||
|
|
||||||
|
// Setting dummy data for the game session
|
||||||
|
var Session GameSession
|
||||||
|
Session.Link = "Test"
|
||||||
|
Session.ServerID = "1"
|
||||||
|
Session.GameSessionID = "1"
|
||||||
|
|
||||||
|
Session.Server = ServerSpecs{ID: "1",Hostname : "Test",GPU: "Nvidia GTX1080ti"}
|
||||||
|
|
||||||
|
// Insert test rows
|
||||||
|
DB.Model(GameSession{}).Create(&Session)
|
||||||
|
|
||||||
|
res := DB.Scan(GameSession{})
|
||||||
|
fmt.Println(res.Error)
|
||||||
|
// prints row count
|
||||||
|
fmt.Println(res.RowsAffected)
|
||||||
|
|
||||||
|
return DB,nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrettyPrint print the contents of the obj (
|
||||||
|
// Reference: https://stackoverflow.com/questions/24512112/how-to-print-struct-variables-in-console
|
||||||
|
func PrettyPrint(data interface{}) {
|
||||||
|
var p []byte
|
||||||
|
// var err := error
|
||||||
|
p, err := json.MarshalIndent(data, "", "\t")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Printf("%s \n", p)
|
||||||
|
}
|
||||||
|
|
||||||
|
// To Ensure GameSession table is created
|
||||||
|
func TestCreateTableGameSession(t *testing.T) {
|
||||||
|
// Connect to database created
|
||||||
|
DB , err := Connect()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
DB, err = CreateTables(DB)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
DB.Scan(&GameSession{})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// To ensure the GameSession table is removed
|
||||||
|
func TestRemoveTableGameSession(t *testing.T) {
|
||||||
|
// Connect to database created
|
||||||
|
DB , err := Connect()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
DB, err = RemoveTableGameSession(DB)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
DB.Scan(&GameSession{})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Testing Insert rows
|
||||||
|
func TestInsertAndDeleteRows(t *testing.T) {
|
||||||
|
// Connect to database created
|
||||||
|
DB , err := Connect()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the appropriate table
|
||||||
|
DB, err = CreateTables(DB)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
DB.Scan(&GameSession{})
|
||||||
|
|
||||||
|
// Setting dummy data for the game session
|
||||||
|
var Session GameSession
|
||||||
|
Session.Link = "https://2.49.230.55:8888/?id=fervent_quizzical_whippet"
|
||||||
|
Session.ServerID = "1"
|
||||||
|
Session.GameSessionID = "1"
|
||||||
|
|
||||||
|
Session.Server = ServerSpecs{ID: "1",Hostname: "akilan-Swift-SF514-54GT",GPU: "NvidiaGT 775m", RAM: 8000, CPU: "Intel(R) Core(TM) i7-1065G7 CPU @ 1.30GHz" }
|
||||||
|
|
||||||
|
// Insert test rows
|
||||||
|
DB.Model(GameSession{}).Create(&Session)
|
||||||
|
|
||||||
|
res := DB.Scan(GameSession{})
|
||||||
|
fmt.Println(res.Error)
|
||||||
|
// prints row count
|
||||||
|
fmt.Println(res.RowsAffected)
|
||||||
|
|
||||||
|
// remove rows from the table created
|
||||||
|
// Delete the row from the server specs table
|
||||||
|
//DB.Delete(&ServerSpecs{}, 1)
|
||||||
|
// Delete table from GameSession Table
|
||||||
|
//DB.Delete(&GameSession{}, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test function to display all rows of the game
|
||||||
|
// session
|
||||||
|
func TestDisplayGameSessions(t *testing.T) {
|
||||||
|
// Creates a test game session table and
|
||||||
|
// inserts dummy data
|
||||||
|
DB, err := CreateAndInsertData()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
// Gets information about all the rows
|
||||||
|
Result , err := DisplayGameSessions(DB)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
PrettyPrint(Result)
|
||||||
|
|
||||||
|
//defer rows.Close()
|
||||||
|
|
||||||
|
//var gameSession GameSession
|
||||||
|
//
|
||||||
|
//// prints out the results
|
||||||
|
//for rows.Next() {
|
||||||
|
// DB.ScanRows(rows, &gameSession)
|
||||||
|
// fmt.Println(gameSession.ServerID)
|
||||||
|
//}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to check if the user information is
|
||||||
|
// getting successfully inserted into the database
|
||||||
|
func TestRegisterUser(t *testing.T) {
|
||||||
|
// Create a database connection
|
||||||
|
connect, err := Connect()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
// Setting test registration information
|
||||||
|
users := Users{Password: "Test123", EmailID: "akilanselva@hotmail.com"}
|
||||||
|
|
||||||
|
err = RegisterUser(connect, &users)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests to see the game session and server specs are
|
||||||
|
// added
|
||||||
|
func TestAddServerSpecs(t *testing.T) {
|
||||||
|
// Create a database connection
|
||||||
|
connect, err := Connect()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setting dummy data for the game session
|
||||||
|
var Session GameSession
|
||||||
|
Session.Link = "Test"
|
||||||
|
|
||||||
|
Session.Server = ServerSpecs{Hostname : "Test",GPU: "Nvidia GTX1080ti"}
|
||||||
|
|
||||||
|
// Calling server session
|
||||||
|
err = AddServerSpecs(connect, &Session)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
188
server/server.go
Normal file
188
server/server.go
Normal file
@@ -0,0 +1,188 @@
|
|||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Server Starts the server for the client side
|
||||||
|
func Server(port string) error {
|
||||||
|
|
||||||
|
r := gin.Default()
|
||||||
|
|
||||||
|
r.Static("/assets", "./templates/assets")
|
||||||
|
|
||||||
|
r.LoadHTMLGlob("./templates/*.html")
|
||||||
|
// htmlRender.TemplatesDir = "templates/" // default
|
||||||
|
// htmlRender.Ext = ".html" // default
|
||||||
|
|
||||||
|
// Tell gin to use our html render
|
||||||
|
|
||||||
|
// Initialise connection to Sqlite DB
|
||||||
|
connect, err := Connect()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gets default information about the game sessions
|
||||||
|
r.GET("/", func(c *gin.Context) {
|
||||||
|
// Get client session ID
|
||||||
|
session, err := c.Cookie("SessionID")
|
||||||
|
if err != nil {
|
||||||
|
c.Redirect(http.StatusFound, "/login")
|
||||||
|
}
|
||||||
|
|
||||||
|
// User information based on session ID
|
||||||
|
User, err := GetUserInformation(connect, session)
|
||||||
|
if err != nil {
|
||||||
|
c.Redirect(http.StatusFound, "/login")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get information of all game sessions available
|
||||||
|
GameSessions, err := DisplayGameSessions(connect)
|
||||||
|
if err != nil {
|
||||||
|
c.String(http.StatusOK, fmt.Sprint(err))
|
||||||
|
}
|
||||||
|
c.HTML(http.StatusOK, "index.html", gin.H{
|
||||||
|
"title": "Xplane11-WebRTC",
|
||||||
|
"GameSessions": GameSessions,
|
||||||
|
"User": User,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
// Opens the forgot password page
|
||||||
|
r.GET("/forgotpassword", func(c *gin.Context) {
|
||||||
|
c.HTML(http.StatusOK, "forgotpassword.html", gin.H{
|
||||||
|
"title": "Xplane11-WebRTC",
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
// Opens the login page
|
||||||
|
r.GET("/login", func(c *gin.Context) {
|
||||||
|
c.HTML(http.StatusOK, "login.html", gin.H{
|
||||||
|
"title": "Xplane11-WebRTC",
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
// Validate login information
|
||||||
|
r.POST("/login", func(c *gin.Context) {
|
||||||
|
// you can bind multipart form with explicit binding declaration:
|
||||||
|
// c.ShouldBindWith(&form, binding.Form)
|
||||||
|
// or you can simply use autobinding with ShouldBind method:
|
||||||
|
// source: https://github.com/gin-gonic/gin#multiparturlencoded-binding
|
||||||
|
var users Users
|
||||||
|
// in this case proper binding will be automatically selected
|
||||||
|
if err := c.ShouldBind(&users); err != nil {
|
||||||
|
c.String(http.StatusBadRequest, "bad request")
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := AuthLogin(connect, &users)
|
||||||
|
if err != nil {
|
||||||
|
c.String(http.StatusOK, fmt.Sprint(err))
|
||||||
|
} else {
|
||||||
|
if result == "success" {
|
||||||
|
// Create Login session
|
||||||
|
session, err := CreateLoginSession(connect, &users)
|
||||||
|
if err != nil {
|
||||||
|
c.String(http.StatusExpectationFailed, "error")
|
||||||
|
}
|
||||||
|
// TODO redirect to homepage
|
||||||
|
// Set client Cookie as Session ID
|
||||||
|
// To be changed when we use HTTPS
|
||||||
|
c.SetCookie("SessionID", session.SessionKey, 3600, "/", "localhost", false, true)
|
||||||
|
// redirects to the home page
|
||||||
|
//c.Redirect(http.StatusFound, "/")
|
||||||
|
|
||||||
|
// Sends message success. which then redirects back to the home page
|
||||||
|
c.String(http.StatusOK, "Success!")
|
||||||
|
} else {
|
||||||
|
c.String(http.StatusOK, "Something is wrong with from our side. Email us: me@akilan.io to find out more. ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// Route for logout
|
||||||
|
r.GET("/logout", func(c *gin.Context) {
|
||||||
|
// Get client session ID
|
||||||
|
session, err := c.Cookie("SessionID")
|
||||||
|
if err != nil {
|
||||||
|
c.Redirect(http.StatusFound, "/login")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove Session ID from the database
|
||||||
|
RemoveLoginSession(connect, session)
|
||||||
|
|
||||||
|
// redirect to the login page
|
||||||
|
c.Redirect(http.StatusFound, "/login")
|
||||||
|
})
|
||||||
|
|
||||||
|
// Opens the registration page
|
||||||
|
r.GET("/register", func(c *gin.Context) {
|
||||||
|
c.HTML(http.StatusOK, "registration.html", gin.H{
|
||||||
|
"title": "Xplane11-WebRTC",
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
// Register user information required
|
||||||
|
r.POST("/register", func(c *gin.Context) {
|
||||||
|
// you can bind multipart form with explicit binding declaration:
|
||||||
|
// c.ShouldBindWith(&form, binding.Form)
|
||||||
|
// or you can simply use autobinding with ShouldBind method:
|
||||||
|
// source: https://github.com/gin-gonic/gin#multiparturlencoded-binding
|
||||||
|
var users Users
|
||||||
|
// in this case proper binding will be automatically selected
|
||||||
|
if err := c.ShouldBind(&users); err != nil {
|
||||||
|
c.String(http.StatusBadRequest, "bad request")
|
||||||
|
}
|
||||||
|
|
||||||
|
err = RegisterUser(connect, &users)
|
||||||
|
if err != nil {
|
||||||
|
c.String(http.StatusOK, fmt.Sprint(err))
|
||||||
|
} else {
|
||||||
|
c.String(http.StatusOK, "Success! Head back to the login page")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// Add new server information
|
||||||
|
r.POST("/AddGameSession", func(c *gin.Context) {
|
||||||
|
|
||||||
|
// TODO: Binding
|
||||||
|
// you can bind multipart form with explicit binding declaration:
|
||||||
|
// c.ShouldBindWith(&form, binding.Form)
|
||||||
|
// or you can simply use autobinding with ShouldBind method:
|
||||||
|
// source: https://github.com/gin-gonic/gin#multiparturlencoded-binding
|
||||||
|
var gameSession GameSession
|
||||||
|
|
||||||
|
gameSession.Rate, _ = strconv.ParseFloat(c.PostForm("Rate"), 8)
|
||||||
|
gameSession.Server.GPU = c.PostForm("GPU")
|
||||||
|
gameSession.Link = c.PostForm("Link")
|
||||||
|
gameSession.Server.CPU = c.PostForm("CPU")
|
||||||
|
gameSession.Server.GPU = c.PostForm("GPU")
|
||||||
|
gameSession.Server.Platform = c.PostForm("Platform")
|
||||||
|
gameSession.Server.Hostname = c.PostForm("HostName")
|
||||||
|
gameSession.Server.RAM = c.PostForm("RAM")
|
||||||
|
gameSession.Server.Disk = c.PostForm("Disk")
|
||||||
|
|
||||||
|
// in this case proper binding will be automatically selected
|
||||||
|
//if err := c.ShouldBind(&gameSession); err != nil {
|
||||||
|
// c.String(http.StatusBadRequest, "bad request")
|
||||||
|
//}
|
||||||
|
|
||||||
|
err = AddServerSpecs(connect, &gameSession)
|
||||||
|
if err != nil {
|
||||||
|
c.String(http.StatusOK, fmt.Sprint(err))
|
||||||
|
} else {
|
||||||
|
c.String(http.StatusOK, "Success")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// Run gin server on the specified port
|
||||||
|
err = r.Run(":" + port)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
81
templates/addgamesession.html
Normal file
81
templates/addgamesession.html
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title>Admin - Free Bulma template</title>
|
||||||
|
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,700" rel="stylesheet">
|
||||||
|
<!-- Bulma Version 0.9.0-->
|
||||||
|
<link rel="stylesheet" href="https://unpkg.com/bulma@0.9.0/css/bulma.min.css" />
|
||||||
|
<link rel="stylesheet" type="text/css" href="assets/css/admin.css">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<!-- START NAV -->
|
||||||
|
<nav class="navbar is-white">
|
||||||
|
<div class="container">
|
||||||
|
<div class="navbar-brand">
|
||||||
|
<a class="navbar-item brand-text" href="index.html">
|
||||||
|
XPlane11-WebRTC
|
||||||
|
</a>
|
||||||
|
<div class="navbar-burger burger" data-target="navMenu">
|
||||||
|
<span></span>
|
||||||
|
<span></span>
|
||||||
|
<span></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="navMenu" class="navbar-menu">
|
||||||
|
<div class="navbar-start">
|
||||||
|
<a class="navbar-item" href="admin.html">
|
||||||
|
Home
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
<!-- END NAV -->
|
||||||
|
<div class="container">
|
||||||
|
<div class="">
|
||||||
|
<div class="">
|
||||||
|
<section class="hero is-info welcome is-small">
|
||||||
|
<div class="hero-body">
|
||||||
|
<div class="container">
|
||||||
|
<h1 class="title">
|
||||||
|
Hello, User.
|
||||||
|
</h1>
|
||||||
|
<h2 class="subtitle">
|
||||||
|
I hope you are having a great day!
|
||||||
|
</h2>
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section class="info-tiles">
|
||||||
|
<div class="tile is-ancestor has-text-centered row columns is-multiline">
|
||||||
|
{{ range .GameSessions }}
|
||||||
|
<div class="column is-4 tile is-parent">
|
||||||
|
<article class="tile is-child box">
|
||||||
|
<p class="title">{{ .Server.GPU }}</p>
|
||||||
|
<p style="color: #8F99A3; margin-top:-1.25rem; font-weight: 300; font-size: 1.25rem">RAM: {{ .Server.RAM }}</p>
|
||||||
|
<p style="color: #8F99A3; font-weight: 300; font-size: 1.25rem">Rate: 1$/hr </p>
|
||||||
|
<p style="color: #8F99A3; font-weight: 300; font-size: 1.25rem">CPU: {{ .Server.CPU }} </p>
|
||||||
|
<p style="color: #8F99A3; font-weight: 300; font-size: 1.25rem">Disk: {{ .Server.Disk }} </p>
|
||||||
|
<br>
|
||||||
|
<a href="{{ .Link }}" class="button is-block is-success is-fullwidth is-medium">Play</a>
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script async type="text/javascript" src="assets/js/bulma.js"></script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
82
templates/assets/css/admin.css
Normal file
82
templates/assets/css/admin.css
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
html, body {
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 1.5;
|
||||||
|
height: 100%;
|
||||||
|
background: #ECF0F3;
|
||||||
|
}
|
||||||
|
nav.navbar {
|
||||||
|
border-top: 4px solid #276cda;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
.navbar-item.brand-text {
|
||||||
|
font-weight: 300;
|
||||||
|
}
|
||||||
|
.navbar-item, .navbar-link {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
.columns {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
.menu-label {
|
||||||
|
color: #8F99A3;
|
||||||
|
letter-spacing: 1.3;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
.menu-list a {
|
||||||
|
color: #0F1D38;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
.menu-list a:hover {
|
||||||
|
background-color: transparent;
|
||||||
|
color: #276cda;
|
||||||
|
}
|
||||||
|
.menu-list a.is-active {
|
||||||
|
background-color: transparent;
|
||||||
|
color: #276cda;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
.card {
|
||||||
|
box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.18);
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
.card-header-title {
|
||||||
|
color: #8F99A3;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
.info-tiles {
|
||||||
|
margin: 1rem 0;
|
||||||
|
}
|
||||||
|
.info-tiles .subtitle {
|
||||||
|
font-weight: 300;
|
||||||
|
color: #8F99A3;
|
||||||
|
}
|
||||||
|
.hero.welcome.is-info {
|
||||||
|
background: #36D1DC;
|
||||||
|
background: -webkit-linear-gradient(to right, #5B86E5, #36D1DC);
|
||||||
|
background: linear-gradient(to right, #5B86E5, #36D1DC);
|
||||||
|
}
|
||||||
|
.hero.welcome .title, .hero.welcome .subtitle {
|
||||||
|
color: hsl(192, 17%, 99%);
|
||||||
|
}
|
||||||
|
.card .content {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
.card-footer-item {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #8F99A3;
|
||||||
|
}
|
||||||
|
.card-footer-item:hover {
|
||||||
|
}
|
||||||
|
.card-table .table {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
.events-card .card-table {
|
||||||
|
max-height: 250px;
|
||||||
|
overflow-y: scroll;
|
||||||
|
}
|
||||||
4
templates/assets/css/register.css
Normal file
4
templates/assets/css/register.css
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
.va {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
10
templates/assets/js/bulma.js
Normal file
10
templates/assets/js/bulma.js
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
// The following code is based off a toggle menu by @Bradcomp
|
||||||
|
// source: https://gist.github.com/Bradcomp/a9ef2ef322a8e8017443b626208999c1
|
||||||
|
(function() {
|
||||||
|
var burger = document.querySelector('.burger');
|
||||||
|
var menu = document.querySelector('#'+burger.dataset.target);
|
||||||
|
burger.addEventListener('click', function() {
|
||||||
|
burger.classList.toggle('is-active');
|
||||||
|
menu.classList.toggle('is-active');
|
||||||
|
});
|
||||||
|
})();
|
||||||
153
templates/forgotpassword.html
Normal file
153
templates/forgotpassword.html
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title>Register - Free Bulma template</title>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Nunito+Sans:wght@400;500;700&display=swap" rel="stylesheet">
|
||||||
|
<script src="https://kit.fontawesome.com/15181efa86.js" crossorigin="anonymous"></script>
|
||||||
|
<link rel="stylesheet" href="https://unpkg.com/bulma@0.9.0/css/bulma.min.css"/>
|
||||||
|
<link rel="stylesheet" type="text/css" href="assets/css/register.css">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<section class="container">
|
||||||
|
<div class="columns is-multiline">
|
||||||
|
<div class="column is-8 is-offset-2 register">
|
||||||
|
<div class="columns">
|
||||||
|
<div class="column left">
|
||||||
|
<h1 class="title is-1">Xplane 11 WebRTC</h1>
|
||||||
|
<br>
|
||||||
|
<h2 class="subtitle is-4">Enjoy the XPlane 11 gameplay performance without any setup</h2>
|
||||||
|
<p></p>
|
||||||
|
</div>
|
||||||
|
<div class="column right has-text-centered">
|
||||||
|
<h1 class="title is-4">Forgot password</h1>
|
||||||
|
<p class="description">We will send a reset password link to your email</p>
|
||||||
|
<form>
|
||||||
|
<div class="field">
|
||||||
|
<div class="control">
|
||||||
|
<input class="input is-medium" type="email" placeholder="Email">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button class="button is-block is-success is-fullwidth is-medium">Send reset password link</button>
|
||||||
|
<br>
|
||||||
|
<a href="/register" >Create a new account</a>
|
||||||
|
<br>
|
||||||
|
<a href="/login" >Already have an account ?</a>
|
||||||
|
<br/>
|
||||||
|
<small><em></em></small>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="column is-8 is-offset-2">
|
||||||
|
<br>
|
||||||
|
<nav class="level">
|
||||||
|
<div class="level-left">
|
||||||
|
<div class="level-item">
|
||||||
|
<span class="icon">
|
||||||
|
<i class="fab fa-github"></i>
|
||||||
|
</span>  
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="level-right">
|
||||||
|
<small class="level-item" style="color: var(--textLight)">
|
||||||
|
© Super Cool Website. All Rights Reserved.
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</body>
|
||||||
|
<style>
|
||||||
|
:root {
|
||||||
|
--brandColor: hsl(166, 67%, 51%);
|
||||||
|
--background: rgb(247, 247, 247);
|
||||||
|
--textDark: hsla(0, 0%, 0%, 0.66);
|
||||||
|
--textLight: hsla(0, 0%, 0%, 0.33);
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background: url('https://forums.x-plane.org/screenshots/monthly_2017_07/b738_21.png.5ba5bcaca689d85705396affb04473ce.png');
|
||||||
|
background-size: cover; /* <------ */
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center center;
|
||||||
|
height: 100vh;
|
||||||
|
color: var(--textDark);
|
||||||
|
}
|
||||||
|
|
||||||
|
.field:not(:last-child) {
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.register {
|
||||||
|
margin-top: 10rem;
|
||||||
|
background: white;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left,
|
||||||
|
.right {
|
||||||
|
padding: 4.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left {
|
||||||
|
border-right: 5px solid var(--background);
|
||||||
|
}
|
||||||
|
|
||||||
|
.left .title {
|
||||||
|
font-weight: 800;
|
||||||
|
letter-spacing: -2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left .colored {
|
||||||
|
color: var(--brandColor);
|
||||||
|
font-weight: 500;
|
||||||
|
margin-top: 1rem !important;
|
||||||
|
letter-spacing: -1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left p {
|
||||||
|
color: var(--textLight);
|
||||||
|
font-size: 1.15rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right .title {
|
||||||
|
font-weight: 800;
|
||||||
|
letter-spacing: -1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right .description {
|
||||||
|
margin-top: 1rem;
|
||||||
|
margin-bottom: 1rem !important;
|
||||||
|
color: var(--textLight);
|
||||||
|
font-size: 1.15rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right small {
|
||||||
|
color: var(--textLight);
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
input:focus {
|
||||||
|
border-color: var(--brandColor) !important;
|
||||||
|
box-shadow: 0 0 0 1px var(--brandColor) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fab,
|
||||||
|
.fas {
|
||||||
|
color: var(--textLight);
|
||||||
|
margin-right: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
</html>
|
||||||
85
templates/index.html
Normal file
85
templates/index.html
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title>Admin - Free Bulma template</title>
|
||||||
|
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,700" rel="stylesheet">
|
||||||
|
<!-- Bulma Version 0.9.0-->
|
||||||
|
<link rel="stylesheet" href="https://unpkg.com/bulma@0.9.0/css/bulma.min.css" />
|
||||||
|
<link rel="stylesheet" type="text/css" href="assets/css/admin.css">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<!-- START NAV -->
|
||||||
|
<nav class="navbar is-white">
|
||||||
|
<div class="container">
|
||||||
|
<div class="navbar-brand">
|
||||||
|
<a class="navbar-item brand-text" href="/">
|
||||||
|
XPlane11-WebRTC
|
||||||
|
</a>
|
||||||
|
<div class="navbar-burger burger" data-target="navMenu">
|
||||||
|
<span></span>
|
||||||
|
<span></span>
|
||||||
|
<span></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="navMenu" class="navbar-menu">
|
||||||
|
<div class="navbar-start">
|
||||||
|
<a class="navbar-item" href="/">
|
||||||
|
Home
|
||||||
|
</a>
|
||||||
|
<a class="navbar-item" href="/logout">
|
||||||
|
Logout
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
<!-- END NAV -->
|
||||||
|
<div class="container">
|
||||||
|
<div class="">
|
||||||
|
<div class="">
|
||||||
|
<section class="hero is-info welcome is-small">
|
||||||
|
<div class="hero-body">
|
||||||
|
<div class="container">
|
||||||
|
<h1 class="title">
|
||||||
|
Hello, {{ .User.Name }}
|
||||||
|
</h1>
|
||||||
|
<h2 class="subtitle">
|
||||||
|
I hope you are having a great day!
|
||||||
|
</h2>
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section class="info-tiles">
|
||||||
|
<div class="tile is-ancestor has-text-centered row columns is-multiline">
|
||||||
|
{{ range .GameSessions }}
|
||||||
|
<div class="column is-4 tile is-parent">
|
||||||
|
<article class="tile is-child box">
|
||||||
|
<p class="title">{{ .Server.GPU }}</p>
|
||||||
|
<p style="color: #8F99A3; margin-top:-1.25rem; font-weight: 300; font-size: 1.25rem">RAM: {{ .Server.RAM }} MB</p>
|
||||||
|
<p style="color: #8F99A3; font-weight: 300; font-size: 1.25rem">Rate: {{ .Rate }}$/hr </p>
|
||||||
|
<p style="color: #8F99A3; font-weight: 300; font-size: 1.25rem">CPU: {{ .Server.CPU }} </p>
|
||||||
|
<p style="color: #8F99A3; font-weight: 300; font-size: 1.25rem">Disk: {{ .Server.Disk }} MB</p>
|
||||||
|
<p style="color: #8F99A3; font-weight: 300; font-size: 1.25rem">Platform: {{ .Server.Platform }}</p>
|
||||||
|
<br>
|
||||||
|
<a href="{{ .Link }}" class="button is-block is-success is-fullwidth is-medium">Play</a>
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script async type="text/javascript" src="assets/js/bulma.js"></script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
218
templates/login.html
Normal file
218
templates/login.html
Normal file
@@ -0,0 +1,218 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title>Register - Free Bulma template</title>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Nunito+Sans:wght@400;500;700&display=swap" rel="stylesheet">
|
||||||
|
<script src="https://kit.fontawesome.com/15181efa86.js" crossorigin="anonymous"></script>
|
||||||
|
<link rel="stylesheet" href="https://unpkg.com/bulma@0.9.0/css/bulma.min.css"/>
|
||||||
|
<link rel="stylesheet" type="text/css" href="assets/css/register.css">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<section class="container">
|
||||||
|
<div class="columns is-multiline">
|
||||||
|
<div class="column is-8 is-offset-2 register">
|
||||||
|
<div class="columns">
|
||||||
|
<div class="column left">
|
||||||
|
<h1 class="title is-1">Xplane 11 WebRTC</h1>
|
||||||
|
<br>
|
||||||
|
<h2 class="subtitle is-4">Enjoy the XPlane 11 gameplay performance without any setup</h2>
|
||||||
|
<p></p>
|
||||||
|
</div>
|
||||||
|
<div class="column right has-text-centered">
|
||||||
|
<h1 class="title is-4">Login</h1>
|
||||||
|
<p class="description">We cool so long as your computer supports a browser</p>
|
||||||
|
<form>
|
||||||
|
<div class="field">
|
||||||
|
<div class="control">
|
||||||
|
<input class="input is-medium" type="email" placeholder="Email" id="EmailID">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field">
|
||||||
|
<div class="control">
|
||||||
|
<input class="input is-medium" type="password" placeholder="Password" id="Password">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field">
|
||||||
|
<div class="control">
|
||||||
|
<p id="EmailIDError"></p>
|
||||||
|
<p id="PasswordError"></p>
|
||||||
|
<p id="ResponseText"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button class="button is-block is-success is-fullwidth is-medium" onclick="LoginSubmit();return false;">Login</button>
|
||||||
|
<br>
|
||||||
|
<a href="/register" >Create a new account</a>
|
||||||
|
<br>
|
||||||
|
<a href="/forgotpassword">Forgot password ?</a>
|
||||||
|
<br/>
|
||||||
|
<small><em></em></small>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="column is-8 is-offset-2">
|
||||||
|
<br>
|
||||||
|
<nav class="level">
|
||||||
|
<div class="level-left">
|
||||||
|
<div class="level-item">
|
||||||
|
<span class="icon">
|
||||||
|
<i class="fab fa-github"></i>
|
||||||
|
</span>  
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="level-right">
|
||||||
|
<small class="level-item" style="color: var(--textLight)">
|
||||||
|
© Super Cool Website. All Rights Reserved.
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</body>
|
||||||
|
<script>
|
||||||
|
// The function is called on OnClick action
|
||||||
|
function LoginSubmit() {
|
||||||
|
// Getting element information of all the fields
|
||||||
|
// required for registration
|
||||||
|
var EmailID = document.getElementById("EmailID").value
|
||||||
|
var Password = document.getElementById("Password").value
|
||||||
|
|
||||||
|
|
||||||
|
// When EmailID is not entered
|
||||||
|
if (EmailID == "") {
|
||||||
|
document.getElementById("EmailIDError").innerHTML = "Enter EmailID"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// When EmailID is entered
|
||||||
|
if (EmailID != "") {
|
||||||
|
document.getElementById("EmailIDError").innerHTML = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// When password and confirm password don't match
|
||||||
|
if (Password != "") {
|
||||||
|
document.getElementById("PasswordError").innerHTML = ""
|
||||||
|
}
|
||||||
|
// When the password matches then clear the field
|
||||||
|
if (Password == "") {
|
||||||
|
document.getElementById("PasswordError").innerHTML = "Enter password"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// binding data to uri encoded string
|
||||||
|
uriencoded = "EmailID=" + EmailID + "&Password=" + Password
|
||||||
|
|
||||||
|
// Submitting the registration information
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open("POST", "/login", true);
|
||||||
|
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
|
||||||
|
xhr.send(uriencoded);
|
||||||
|
|
||||||
|
xhr.onload = function () {
|
||||||
|
console.log(xhr.responseText)
|
||||||
|
// Outputting response text
|
||||||
|
document.getElementById("ResponseText").innerHTML = xhr.responseText
|
||||||
|
// Create Sessions browser
|
||||||
|
// if response is success then redirect
|
||||||
|
if (xhr.responseText == "Success!") {
|
||||||
|
window.location.replace("/");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
:root {
|
||||||
|
--brandColor: hsl(166, 67%, 51%);
|
||||||
|
--background: rgb(247, 247, 247);
|
||||||
|
--textDark: hsla(0, 0%, 0%, 0.66);
|
||||||
|
--textLight: hsla(0, 0%, 0%, 0.33);
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background: url('https://forums.x-plane.org/screenshots/monthly_2017_07/b738_21.png.5ba5bcaca689d85705396affb04473ce.png');
|
||||||
|
background-size: cover; /* <------ */
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center center;
|
||||||
|
height: 100vh;
|
||||||
|
color: var(--textDark);
|
||||||
|
}
|
||||||
|
|
||||||
|
.field:not(:last-child) {
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.register {
|
||||||
|
margin-top: 10rem;
|
||||||
|
background: white;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left,
|
||||||
|
.right {
|
||||||
|
padding: 4.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left {
|
||||||
|
border-right: 5px solid var(--background);
|
||||||
|
}
|
||||||
|
|
||||||
|
.left .title {
|
||||||
|
font-weight: 800;
|
||||||
|
letter-spacing: -2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left .colored {
|
||||||
|
color: var(--brandColor);
|
||||||
|
font-weight: 500;
|
||||||
|
margin-top: 1rem !important;
|
||||||
|
letter-spacing: -1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left p {
|
||||||
|
color: var(--textLight);
|
||||||
|
font-size: 1.15rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right .title {
|
||||||
|
font-weight: 800;
|
||||||
|
letter-spacing: -1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right .description {
|
||||||
|
margin-top: 1rem;
|
||||||
|
margin-bottom: 1rem !important;
|
||||||
|
color: var(--textLight);
|
||||||
|
font-size: 1.15rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right small {
|
||||||
|
color: var(--textLight);
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
input:focus {
|
||||||
|
border-color: var(--brandColor) !important;
|
||||||
|
box-shadow: 0 0 0 1px var(--brandColor) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fab,
|
||||||
|
.fas {
|
||||||
|
color: var(--textLight);
|
||||||
|
margin-right: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
</html>
|
||||||
249
templates/registration.html
Normal file
249
templates/registration.html
Normal file
@@ -0,0 +1,249 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title>Register - Free Bulma template</title>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Nunito+Sans:wght@400;500;700&display=swap" rel="stylesheet">
|
||||||
|
<script src="https://kit.fontawesome.com/15181efa86.js" crossorigin="anonymous"></script>
|
||||||
|
<link rel="stylesheet" href="https://unpkg.com/bulma@0.9.0/css/bulma.min.css"/>
|
||||||
|
<link rel="stylesheet" type="text/css" href="assets/css/register.css">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<section class="container">
|
||||||
|
<div class="columns is-multiline">
|
||||||
|
<div class="column is-8 is-offset-2 register">
|
||||||
|
<div class="columns">
|
||||||
|
<div class="column left">
|
||||||
|
<h1 class="title is-1">Xplane 11 WebRTC</h1>
|
||||||
|
<br>
|
||||||
|
<h2 class="subtitle is-4">Enjoy the XPlane 11 gameplay performance without any setup</h2>
|
||||||
|
<p></p>
|
||||||
|
</div>
|
||||||
|
<div class="column right has-text-centered">
|
||||||
|
<h1 class="title is-4">Sign up today</h1>
|
||||||
|
<p class="description">We cool so long as your computer supports a browser</p>
|
||||||
|
<form>
|
||||||
|
<div class="field">
|
||||||
|
<div class="control">
|
||||||
|
<input class="input is-medium" type="text" id="Name" placeholder="Name" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field">
|
||||||
|
<div class="control">
|
||||||
|
<input class="input is-medium" type="email" id="EmailID" placeholder="Email" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field">
|
||||||
|
<div class="control">
|
||||||
|
<input class="input is-medium" type="password" id="Password" placeholder="Password" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field">
|
||||||
|
<div class="control">
|
||||||
|
<input class="input is-medium" type="password" id="ConfirmPassword" placeholder="Confirm password" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field">
|
||||||
|
<div class="control">
|
||||||
|
<p id="NameError"></p>
|
||||||
|
<p id="EmailIDError"></p>
|
||||||
|
<p id="ConfirmPasswordError"></p>
|
||||||
|
<p id="ResponseText"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button class="button is-block is-success is-fullwidth is-medium" onclick="RegisterSubmit();return false;">Submit</button>
|
||||||
|
<br>
|
||||||
|
<a href="/login" >Already have an account ?</a>
|
||||||
|
<br>
|
||||||
|
<a href="/forgotpassword">Forgot password ?</a>
|
||||||
|
<br/>
|
||||||
|
<br/>
|
||||||
|
<small><em></em></small>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="column is-8 is-offset-2">
|
||||||
|
<br>
|
||||||
|
<nav class="level">
|
||||||
|
<div class="level-left">
|
||||||
|
<div class="level-item">
|
||||||
|
<span class="icon">
|
||||||
|
<i class="fab fa-github"></i>
|
||||||
|
</span>  
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="level-right">
|
||||||
|
<small class="level-item" style="color: var(--textLight)">
|
||||||
|
© Super Cool Website. All Rights Reserved.
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</body>
|
||||||
|
<!-- The following script handles communicating with the server for registration -->
|
||||||
|
<script>
|
||||||
|
// The function is called on OnClick action
|
||||||
|
function RegisterSubmit() {
|
||||||
|
// Getting element information of all the fields
|
||||||
|
// required for registration
|
||||||
|
var EmailID = document.getElementById("EmailID").value
|
||||||
|
var Name = document.getElementById("Name").value
|
||||||
|
var Password = document.getElementById("Password").value
|
||||||
|
var ConfirmPassword = document.getElementById("ConfirmPassword").value
|
||||||
|
|
||||||
|
// When Name is not entered
|
||||||
|
if (Name == "") {
|
||||||
|
document.getElementById("Name").innerHTML = "Enter Name"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// When Name is entered
|
||||||
|
if (Name != "") {
|
||||||
|
document.getElementById("Name").innerHTML = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// When EmailID is not entered
|
||||||
|
if (EmailID == "") {
|
||||||
|
document.getElementById("EmailIDError").innerHTML = "Enter EmailID"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// When EmailID is entered
|
||||||
|
if (EmailID != "") {
|
||||||
|
document.getElementById("EmailIDError").innerHTML = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// When password and confirm password don't match
|
||||||
|
if (Password != ConfirmPassword) {
|
||||||
|
document.getElementById("ConfirmPasswordError").innerHTML = "Password and confirm password don't match"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// When the password matches then clear the field
|
||||||
|
if (Password == ConfirmPassword){
|
||||||
|
document.getElementById("ConfirmPasswordError").innerHTML = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// binding data to uri encoded string
|
||||||
|
uriencoded = "Name=" + Name + "&EmailID=" + EmailID + "&Password=" + Password
|
||||||
|
|
||||||
|
// Submitting the registration information
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open("POST", "/register", true);
|
||||||
|
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
|
||||||
|
xhr.send(uriencoded);
|
||||||
|
|
||||||
|
xhr.onload = function() {
|
||||||
|
// Outputting response text
|
||||||
|
document.getElementById("ResponseText").innerHTML = xhr.responseText
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// comparing strings
|
||||||
|
function strcmp(a, b)
|
||||||
|
{
|
||||||
|
return (a<b?-1:(a>b?1:0));
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
:root {
|
||||||
|
--brandColor: hsl(166, 67%, 51%);
|
||||||
|
--background: rgb(247, 247, 247);
|
||||||
|
--textDark: hsla(0, 0%, 0%, 0.66);
|
||||||
|
--textLight: hsla(0, 0%, 0%, 0.33);
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background: url('https://forums.x-plane.org/screenshots/monthly_2017_07/b738_21.png.5ba5bcaca689d85705396affb04473ce.png');
|
||||||
|
background-size: cover; /* <------ */
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center center;
|
||||||
|
height: 100vh;
|
||||||
|
color: var(--textDark);
|
||||||
|
}
|
||||||
|
|
||||||
|
.field:not(:last-child) {
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.register {
|
||||||
|
margin-top: 10rem;
|
||||||
|
background: white;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left,
|
||||||
|
.right {
|
||||||
|
padding: 4.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left {
|
||||||
|
border-right: 5px solid var(--background);
|
||||||
|
}
|
||||||
|
|
||||||
|
.left .title {
|
||||||
|
font-weight: 800;
|
||||||
|
letter-spacing: -2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left .colored {
|
||||||
|
color: var(--brandColor);
|
||||||
|
font-weight: 500;
|
||||||
|
margin-top: 1rem !important;
|
||||||
|
letter-spacing: -1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left p {
|
||||||
|
color: var(--textLight);
|
||||||
|
font-size: 1.15rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right .title {
|
||||||
|
font-weight: 800;
|
||||||
|
letter-spacing: -1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right .description {
|
||||||
|
margin-top: 1rem;
|
||||||
|
margin-bottom: 1rem !important;
|
||||||
|
color: var(--textLight);
|
||||||
|
font-size: 1.15rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right small {
|
||||||
|
color: var(--textLight);
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
input:focus {
|
||||||
|
border-color: var(--brandColor) !important;
|
||||||
|
box-shadow: 0 0 0 1px var(--brandColor) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fab,
|
||||||
|
.fas {
|
||||||
|
color: var(--textLight);
|
||||||
|
margin-right: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user