master
Raw Download raw file
  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}