Skip to content

Commit bc197c8

Browse files
authored
Merge pull request #45 from Quaver/test-env
Add testing environment
2 parents 6e196f5 + e2a92b8 commit bc197c8

File tree

8 files changed

+182
-1
lines changed

8 files changed

+182
-1
lines changed

cmd/server/server.go

+3
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ func (s *Server) Start() {
6565
utils.CloseConnection(conn)
6666
return
6767
}
68+
} else {
69+
_ = conn.Close()
70+
return
6871
}
6972

7073
// Handle various connection events

cmd/tests/client.go

+110
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
package tests
2+
3+
import (
4+
"encoding/base64"
5+
"encoding/json"
6+
"example.com/Quaver/Z/config"
7+
"example.com/Quaver/Z/db"
8+
"example.com/Quaver/Z/handlers"
9+
"fmt"
10+
"github.com/gorilla/websocket"
11+
"log"
12+
"net/url"
13+
"os"
14+
"os/signal"
15+
)
16+
17+
type Client struct {
18+
User *db.User
19+
Conn *websocket.Conn
20+
enableLogging bool
21+
}
22+
23+
func newClient(user *db.User) *Client {
24+
return &Client{User: user}
25+
}
26+
27+
func (client *Client) host() string {
28+
return fmt.Sprintf("localhost:%v", config.Instance.Server.Port)
29+
}
30+
31+
func (client *Client) loginData() handlers.LoginData {
32+
return handlers.LoginData{
33+
Id: client.User.SteamId,
34+
PTicket: "aGVsbG8=",
35+
PcbTicket: 0,
36+
Client: "1|2|3|4|5",
37+
}
38+
}
39+
40+
func (client *Client) loginDataEncoded() string {
41+
data := client.loginData()
42+
dataJson, _ := json.Marshal(data)
43+
44+
var encoded = make([]byte, base64.StdEncoding.EncodedLen(len(dataJson)))
45+
base64.StdEncoding.Encode(encoded, dataJson)
46+
47+
return string(encoded)
48+
}
49+
func (client *Client) login() {
50+
u := url.URL{
51+
Scheme: "ws",
52+
Host: client.host(),
53+
Path: "/",
54+
RawQuery: fmt.Sprintf("login=%v", client.loginDataEncoded()),
55+
}
56+
57+
var err error
58+
59+
client.Conn, _, err = websocket.DefaultDialer.Dial(u.String(), nil)
60+
61+
if err != nil {
62+
log.Fatal("dial:", err)
63+
}
64+
65+
defer client.Conn.Close()
66+
client.handleInterrupt(client.readMessages())
67+
}
68+
69+
func (client *Client) readMessages() chan struct{} {
70+
done := make(chan struct{})
71+
72+
go func() {
73+
defer close(done)
74+
75+
for {
76+
_, message, err := client.Conn.ReadMessage()
77+
78+
if err != nil {
79+
log.Println("read:", err)
80+
return
81+
}
82+
83+
if client.enableLogging {
84+
log.Printf("recv: %s", message)
85+
}
86+
}
87+
}()
88+
89+
return done
90+
}
91+
92+
func (client *Client) handleInterrupt(doneReadingChan chan struct{}) {
93+
interrupt := make(chan os.Signal, 1)
94+
signal.Notify(interrupt, os.Interrupt)
95+
96+
for {
97+
select {
98+
case <-doneReadingChan:
99+
return
100+
case <-interrupt:
101+
err := client.Conn.WriteMessage(websocket.CloseMessage,
102+
websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
103+
104+
if err != nil {
105+
log.Println("write close:", err)
106+
return
107+
}
108+
}
109+
}
110+
}

cmd/tests/stress_test.go

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package tests
2+
3+
import (
4+
"example.com/Quaver/Z/config"
5+
"example.com/Quaver/Z/db"
6+
"sync"
7+
"testing"
8+
)
9+
10+
// Tests a 100 users connecting to the server at one time
11+
func TestLogin100Clients(t *testing.T) {
12+
if err := config.Load("../../config.json"); err != nil {
13+
t.Fatal(err)
14+
}
15+
16+
db.InitializeSQL()
17+
18+
wg := sync.WaitGroup{}
19+
20+
for i := 3; i < 103; i++ {
21+
wg.Add(1)
22+
23+
i := i
24+
25+
go func() {
26+
defer wg.Done()
27+
28+
user, err := db.GetUserById(i)
29+
30+
if err != nil {
31+
t.Error(err)
32+
return
33+
}
34+
35+
client := newClient(user)
36+
client.login()
37+
}()
38+
}
39+
40+
wg.Wait()
41+
db.CloseSQLConnection()
42+
}

db/sql.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,13 @@ func InitializeSQL() {
3434
if err != nil {
3535
log.Fatalln(err)
3636
}
37-
37+
3838
SQL = db
39+
40+
SQL.DB.SetMaxOpenConns(100)
41+
SQL.DB.SetMaxIdleConns(10)
42+
SQL.DB.SetConnMaxLifetime(0)
43+
3944
log.Println("Successfully connected to SQL database")
4045
}
4146

db/users.go

+14
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,20 @@ func (u *User) GetProfileUrl() string {
2828
return fmt.Sprintf("https://quavergame.com/user/%v", u.Id)
2929
}
3030

31+
// GetUserById Retrieves a user from the database by their id
32+
func GetUserById(id int) (*User, error) {
33+
query := "SELECT id, steam_id, username, allowed, privileges, usergroups, mute_endtime, country, avatar_url, twitch_username FROM users WHERE id = ? LIMIT 1"
34+
35+
var user User
36+
err := SQL.Get(&user, query, id)
37+
38+
if err != nil {
39+
return nil, err
40+
}
41+
42+
return &user, nil
43+
}
44+
3145
// GetUserBySteamId Retrieves a user from the database by their Steam id
3246
func GetUserBySteamId(steamId string) (*User, error) {
3347
query := "SELECT id, steam_id, username, allowed, privileges, usergroups, mute_endtime, country, avatar_url, twitch_username FROM users WHERE steam_id = ? LIMIT 1"

go.mod

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ require (
2222
github.com/disgoorg/snowflake/v2 v2.0.1 // indirect
2323
github.com/gobwas/httphead v0.1.0 // indirect
2424
github.com/gobwas/pool v0.2.1 // indirect
25+
github.com/gorilla/websocket v1.5.3 // indirect
2526
github.com/sasha-s/go-csync v0.0.0-20210812194225-61421b77c44b // indirect
2627
golang.org/x/net v0.23.0 // indirect
2728
golang.org/x/sys v0.18.0 // indirect

go.sum

+2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og=
3131
github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
3232
github.com/gobwas/ws v1.2.0 h1:u0p9s3xLYpZCA1z5JgCkMeB34CKCMMQbM+G8Ii7YD0I=
3333
github.com/gobwas/ws v1.2.0/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY=
34+
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
35+
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
3436
github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g=
3537
github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ=
3638
github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0=

handlers/login.go

+4
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,10 @@ func canUserUseCustomGameBuild(user *db.User) bool {
345345

346346
// Sends webhook and disconnects a user for invalid client usage. Returns if the user is allowed to login
347347
func handleCustomGameBuildUsage(conn net.Conn, user *db.User, client string) bool {
348+
if config.Instance.BypassSteamLogin {
349+
return true
350+
}
351+
348352
clientStr := fmt.Sprintf("```json\n%v```", formatCustomGameBuild(client))
349353
webhooks.SendAntiCheat(user.Username, user.Id, user.GetProfileUrl(), user.AvatarUrl.String, "Invalid Game Build", clientStr)
350354

0 commit comments

Comments
 (0)