-
Notifications
You must be signed in to change notification settings - Fork 0
/
Masters.go
72 lines (60 loc) · 1.63 KB
/
Masters.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
package darkstar_query_go
import (
"errors"
"fmt"
"net"
"github.com/StarsiegePlayers/darkstar-query-go/master"
"github.com/StarsiegePlayers/darkstar-query-go/protocol"
)
func Masters(options *protocol.Options) ([]*master.Master, map[string]*protocol.Server, []error) {
masters := options.Search
availableMasters := len(masters)
await := make(chan *master.Query)
output := make([]*master.Master, 0)
errorArray := make([]error, 0)
id := 0
for key, _ := range masters {
conn, err := net.Dial("udp", key)
if err != nil {
var dnsError *net.DNSError
if errors.As(err, &dnsError) {
errorArray = append(errorArray, fmt.Errorf("master: [%s]: no such host", dnsError.Name))
}
availableMasters--
continue
}
go masterQuery(conn, key, id, await, options)
id++
}
for i := 0; i < availableMasters; i++ {
result := <-await
if result.MasterData.Ping > 0 {
output = append(output, result.MasterData)
}
if result.Error != nil {
errorArray = append(errorArray, result.Error)
}
}
close(await)
games := dedupe(output)
return output, games, errorArray
}
func dedupe(servers []*master.Master) map[string]*protocol.Server {
output := make(map[string]*protocol.Server)
for _, server := range servers {
for k, v := range server.Servers {
if _, ok := output[k]; ok {
continue
}
output[k] = v
}
}
return output
}
func masterQuery(conn net.Conn, hostname string, id int, ret chan *master.Query, options *protocol.Options) {
query := new(master.Query)
query.MasterData = master.NewMaster()
query.MasterData.Address = hostname
query.Error = query.MasterData.Query(conn, id, options)
ret <- query
}