master
1package main
2
3import (
4 "bytes"
5 "encoding/binary"
6 "encoding/json"
7 "fmt"
8 "net"
9 "strconv"
10 "time"
11)
12
13func main() {
14 serverAddress := "minecraft.trustme.click:25565" // Replace with the Minecraft server address
15 timeout := 5 * time.Second
16
17 playerCount, maxPlayers, err := getMinecraftPlayerCount(serverAddress, timeout)
18 if err != nil {
19 fmt.Printf("Error fetching player count: %v\n", err)
20 return
21 }
22
23 fmt.Printf("Active Players: %d/%d\n", playerCount, maxPlayers)
24}
25
26func getMinecraftPlayerCount(address string, timeout time.Duration) (int, int, error) {
27 conn, err := net.DialTimeout("tcp", address, timeout)
28 if err != nil {
29 return 0, 0, fmt.Errorf("failed to connect to server: %v", err)
30 }
31 defer conn.Close()
32
33 // Handshake Packet (0x00)
34 handshake := buildHandshakePacket(address)
35 if _, err := conn.Write(handshake); err != nil {
36 return 0, 0, fmt.Errorf("failed to send handshake packet: %v", err)
37 }
38
39 // Request Packet (0x00)
40 request := []byte{0x01, 0x00}
41 if _, err := conn.Write(request); err != nil {
42 return 0, 0, fmt.Errorf("failed to send request packet: %v", err)
43 }
44
45 // Read Response
46 conn.SetReadDeadline(time.Now().Add(timeout))
47 var response []byte
48 buffer := make([]byte, 4096)
49 for {
50 n, err := conn.Read(buffer)
51 if err != nil {
52 return 0, 0, fmt.Errorf("failed to read response: %v", err)
53 }
54 response = append(response, buffer[:n]...)
55 if len(response) >= 3 && response[0] == 0x00 { // Response packet starts with 0x00
56 break
57 }
58 }
59
60 // Parse JSON Response
61 jsonData := extractJSONFromResponse(response)
62 playerCount, maxPlayers, err := parsePlayerCountsFromJSON(jsonData)
63 if err != nil {
64 return 0, 0, fmt.Errorf("failed to parse player counts: %v", err)
65 }
66
67 return playerCount, maxPlayers, nil
68}
69
70func buildHandshakePacket(address string) []byte {
71 var buffer bytes.Buffer
72
73 host, port, _ := net.SplitHostPort(address)
74 portNum := parsePort(port)
75
76 writeVarInt(&buffer, 0) // Packet ID (0x00)
77 writeVarInt(&buffer, 757) // Protocol Version (1.18+ is 757)
78 writeVarInt(&buffer, len(host)) // Host length
79 buffer.WriteString(host) // Host
80 binary.Write(&buffer, binary.BigEndian, uint16(portNum)) // Port
81 writeVarInt(&buffer, 1) // Next state (status)
82
83 packet := buffer.Bytes()
84 return append(encodeLength(len(packet)), packet...)
85}
86
87func writeVarInt(buffer *bytes.Buffer, value int) {
88 for {
89 temp := byte(value & 0x7F)
90 value >>= 7
91 if value != 0 {
92 temp |= 0x80
93 }
94 buffer.WriteByte(temp)
95 if value == 0 {
96 break
97 }
98 }
99}
100
101func encodeLength(length int) []byte {
102 var buffer bytes.Buffer
103 writeVarInt(&buffer, length)
104 return buffer.Bytes()
105}
106
107func extractJSONFromResponse(response []byte) string {
108 length := decodeVarInt(bytes.NewReader(response[1:]))
109 return string(response[3 : 3+length])
110}
111
112func parsePlayerCountsFromJSON(jsonData string) (int, int, error) {
113 var response struct {
114 Players struct {
115 Online int `json:"online"`
116 Max int `json:"max"`
117 } `json:"players"`
118 }
119 if err := json.Unmarshal([]byte(jsonData), &response); err != nil {
120 return 0, 0, err
121 }
122 return response.Players.Online, response.Players.Max, nil
123}
124
125func decodeVarInt(reader *bytes.Reader) int {
126 var result int
127 var shift uint
128 for {
129 b, _ := reader.ReadByte()
130 result |= int(b&0x7F) << shift
131 if b&0x80 == 0 {
132 break
133 }
134 shift += 7
135 }
136 return result
137}
138
139func parsePort(port string) int {
140 portNum, err := strconv.Atoi(port)
141 if err != nil {
142 return 25565 // Default Minecraft port
143 }
144 return portNum
145}