1 package network
2
3 import (
4 "bufio"
5 "bytes"
6 "encoding/binary"
7 "fmt"
8 "net"
9 )
10
11 func AskInfo(address string) (ServerInfo, []PlayerInfo, error) {
12 conn, err := SendPacket(address, pt_askinfo, askInfo{0x0, 0x0})
13 if err != nil {
14 return ServerInfo{}, nil, fmt.Errorf("Could not ask for server info: %s", err)
15 }
16 defer conn.Close()
17
18
19 var server = ServerInfo{}
20 var buffer = make([]byte, binary.Size(server))
21 head, err := ReadHeader(conn, buffer)
22 if err != nil {
23 return server, nil, fmt.Errorf("Could not get server info response: %s", err)
24 }
25
26 buf := bytes.NewBuffer(buffer)
27 binary.Read(buf, binary.LittleEndian, &server)
28
29 if head.PacketType != pt_serverinfo {
30 panic("Expected server info packet to come first")
31 }
32
33
34 var players = make([]PlayerInfo, server.MaxPlayer)
35 buffer = make([]byte, binary.Size(players))
36 head, err = ReadHeader(conn, buffer)
37 if err != nil {
38 return server, players, fmt.Errorf("Could not get server info response: %s", err)
39 }
40
41 buf = bytes.NewBuffer(buffer)
42 binary.Read(buf, binary.LittleEndian, &players)
43
44 if head.PacketType != pt_playerinfo {
45 panic("Expected to receive packet info")
46 }
47
48 return server, players, nil
49 }
50
51 func TellAllFilesNeeded(address string) ([]string, error) {
52 conn, err := OpenConnection(address)
53 if err != nil {
54 fmt.Printf("Could not ask for needed files: %s", err)
55 }
56 defer conn.Close()
57
58 filesNeeded, files, err := tellFilesNeeded(conn, 0)
59 if err != nil {
60 return nil, fmt.Errorf("Could not request files: %s", err)
61 }
62 result := make([]string, 0, filesNeeded.Num)
63 for _, f := range files {
64 result = append(result, f.WadName)
65 }
66 for filesNeeded.More > 0 {
67 filesNeeded, files, err = tellFilesNeeded(conn, len(result))
68 if err != nil {
69 return nil, fmt.Errorf("Could not request files: %s", err)
70 }
71 for _, f := range files {
72 result = append(result, f.WadName)
73 }
74 }
75
76 return result, nil
77 }
78
79 func tellFilesNeeded(conn *net.UDPConn, from int) (FilesNeeded, []File, error) {
80 fmtErr := func(err error) (FilesNeeded, []File, error) {
81 return FilesNeeded{}, nil, fmt.Errorf("Could get needed files: %s", err)
82 }
83
84 err := SendPacketOnConnection(conn, pt_tellfilesneeded, FilesNeededNum(from))
85 if err != nil {
86 return fmtErr(err)
87 }
88
89 var response FilesNeeded
90 buffer := make([]byte, binary.Size(response))
91 head, err := ReadHeader(conn, buffer)
92 if err != nil {
93 return fmtErr(err)
94 }
95 if head.PacketType != pt_morefilesneeded {
96 return FilesNeeded{}, nil, fmt.Errorf("Unexpected packet response: %x instead of %x", head.PacketType, pt_morefilesneeded)
97 }
98
99 buff := bytes.NewBuffer(buffer)
100 err = binary.Read(buff, binary.LittleEndian, &response)
101 if err != nil {
102 return fmtErr(err)
103 }
104
105 files := make([]File, 0, response.Num)
106 fileScanner := bufio.NewScanner(bytes.NewBuffer(response.Files[:]))
107 fileScanner.Split(ScanFile)
108 for i := 0 ; i < int(response.Num); i++ {
109 if !fileScanner.Scan() {
110 return response, files, fmt.Errorf("Could not read the next file needed: %s", fileScanner.Err())
111 }
112 f, err := fileTokenToFile(fileScanner.Bytes())
113 if err != nil {
114 return response, files, fmt.Errorf("Could not read files needed: %s", err)
115 }
116 files = append(files, f)
117 }
118
119 return response, files, nil
120 }
121
View as plain text