...
1 package network
2
3 import (
4 "fmt"
5 "net"
6 "time"
7
8 "go.formulabun.club/srb2kart/network/info"
9 )
10
11
12
13 func GetServerInfo(adress string) (info.ServerInfoPacket, info.PlayerInfoPacket, error) {
14 udpAddr, err := net.ResolveUDPAddr("udp", adress)
15 if err != nil {
16 return info.ServerInfoPacket{}, info.PlayerInfoPacket{}, fmt.Errorf("failed to resolve udp address: %w", err)
17 }
18
19 conn, err := net.DialUDP("udp", nil, udpAddr)
20 if err != nil {
21 return info.ServerInfoPacket{}, info.PlayerInfoPacket{}, fmt.Errorf("failed to connect to server: %w", err)
22 }
23 defer conn.Close()
24
25 var serverInfoPacket info.ServerInfoPacket
26 var gotServerInfoPacket bool
27 var playerInfoPacket info.PlayerInfoPacket
28 var gotPlayerInfoPacket bool
29
30 conn.SetReadBuffer(2048)
31 conn.SetReadDeadline(time.Now().Add(1 * time.Second))
32 conn.Write(info.GetServerInfoPacket[:])
33 for !gotServerInfoPacket || !gotPlayerInfoPacket {
34 buffer := make([]byte, 2048)
35 _, _, err := conn.ReadFromUDP(buffer)
36 if err != nil {
37 return info.ServerInfoPacket{}, info.PlayerInfoPacket{}, fmt.Errorf("error getting information from server: %w", err)
38 }
39
40 packet, err := info.ParsePacket(buffer)
41 if err != nil {
42 return info.ServerInfoPacket{}, info.PlayerInfoPacket{}, fmt.Errorf("error reading packet: %w", err)
43 }
44
45 switch packetType := packet.GetPacketType(); packetType {
46 case info.PacketTypeServerInfo:
47 serverInfoPacket = packet.(info.ServerInfoPacket)
48 gotServerInfoPacket = true
49 case info.PacketTypePlayerInfo:
50 playerInfoPacket = packet.(info.PlayerInfoPacket)
51 gotPlayerInfoPacket = true
52 }
53 }
54
55
56 playersInGame := []info.PlayerInfoEntry{}
57 for _, player := range playerInfoPacket.PlayerInfo {
58 if player.Node != 255 {
59 playersInGame = append(playersInGame, player)
60 }
61 }
62 playerInfoPacket.PlayerInfo = playersInGame
63
64 if len(playerInfoPacket.PlayerInfo) != int(serverInfoPacket.NumberOfPlayer) {
65 return info.ServerInfoPacket{}, info.PlayerInfoPacket{}, fmt.Errorf("number of players in player info packet does not match number of players in server info packet: %w", err)
66 }
67
68 return serverInfoPacket, playerInfoPacket, nil
69 }
70
View as plain text