-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
serverstat.go
113 lines (87 loc) · 2.27 KB
/
serverstat.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package serverstat
import (
"errors"
"sort"
"sync"
"github.com/vikpe/serverstat/qserver"
"github.com/vikpe/serverstat/qserver/commands/status87"
"github.com/vikpe/serverstat/qserver/geo"
"github.com/vikpe/serverstat/qserver/mvdsv"
"github.com/vikpe/serverstat/qserver/mvdsv/qtvstream"
"github.com/vikpe/serverstat/qserver/qversion"
"github.com/vikpe/serverstat/qutil"
"github.com/vikpe/udpclient"
)
type Client struct {
geoProvider geo.Provider
}
func NewClient() *Client {
return &Client{
geoProvider: geo.NewDefaultProvider(),
}
}
func (c *Client) GetInfo(address string) (qserver.GenericServer, error) {
server, err := getServerInfo(address)
if err == nil {
server.Geo = c.geoProvider.ByAddress(server.Address)
}
return server, err
}
func getServerInfo(address string) (qserver.GenericServer, error) {
if !qutil.IsValidServerAddress(address) {
return qserver.GenericServer{}, errors.New("invalid server address")
}
settings, clients, err := status87.ParseResponse(
udpclient.New().SendCommand(address, status87.Command),
)
if err != nil {
return qserver.GenericServer{}, err
}
if settings.Has("hostname") {
settings["hostname_parsed"] = qserver.ParseHostname(address, settings.Get("hostname", ""))
}
server := qserver.GenericServer{
Address: address,
Version: qversion.New(settings.Get("*version", "")),
Clients: clients,
Settings: settings,
}
if server.Version.IsMvdsv() {
stream, _ := mvdsv.GetQtvStream(address)
server.ExtraInfo.QtvStream = stream
} else {
server.ExtraInfo.QtvStream = qtvstream.New()
}
return server, nil
}
func (c *Client) GetInfoFromMany(addresses []string) []qserver.GenericServer {
var (
wg sync.WaitGroup
mutex sync.Mutex
)
servers := make([]qserver.GenericServer, 0)
for _, address := range addresses {
wg.Add(1)
go func(address string) {
defer wg.Done()
server, err := getServerInfo(address)
if err != nil {
return
}
mutex.Lock()
servers = append(servers, server)
mutex.Unlock()
}(address)
}
wg.Wait()
if len(servers) == 0 {
return servers
}
for index, server := range servers {
servers[index].Geo = c.geoProvider.ByAddress(server.Address)
}
sort.Slice(servers, func(i, j int) bool {
return servers[i].Address < servers[j].Address
})
return servers
}