package main import ( "encoding/json" "errors" "fmt" "net" ) const ( HandshakePacketID = 0x00 StatusRequestID = 0x00 StatusResponseID = 0x00 ) const ( SEGMENT_BITS = 0x7F CONTINUE_BIT = 0x80 ) type HandshakePacket struct { ProtocolVersion int ServerAddress string ServerPort uint16 NextState int } type StatusResponse struct { Version VersionInfo `json:"version"` Players PlayerInfo `json:"players"` Description Chat `json:"description"` } type VersionInfo struct { Name string `json:"name"` Protocol int `json:"protocol"` } type PlayerInfo struct { Max int `json:"max"` Online int `json:"online"` Sample []Player `json:"sample"` } type Player struct { Name string `json:"name"` ID string `json:"id"` } type Chat struct { Text string `json:"text"` } type Reader struct { data []byte cursor int } func main() { listener, err := net.Listen("tcp", "localhost:25565") if err != nil { fmt.Println("Error starting server:", err) return } defer listener.Close() fmt.Println("Server started on port 25565") for { conn, err := listener.Accept() if err != nil { fmt.Println("Error accepting connection:", err) continue } go handleConnection(conn) } } func handleConnection(conn net.Conn) { r := &Reader{data: make([]byte, 1024)} // Print the whole packet buf := make([]byte, 1024) n, _ := conn.Read(buf) r.data = buf[:n] fmt.Println("Packet: ", r.data) _, err := r.readVarInt() if err != nil { fmt.Println("Error reading first number:", err) return } packetID, err := r.readVarInt() if err != nil { fmt.Println("Error reading packet ID:", err) return } fmt.Println("Packet ID: ", packetID) switch packetID { case HandshakePacketID: handleHandshake(r) default: fmt.Println("Unknown packet ID:", packetID) } } func handleHandshake(r *Reader) { var handshake HandshakePacket if err := readHandshakePacket(r, &handshake); err != nil { fmt.Println("Error reading handshake packet:", err) return } if handshake.NextState == 1 { handleStatusRequest(r) } } func handleStatusRequest(r *Reader) { packetID, err := r.readVarInt() if err != nil { fmt.Println("Error reading packet ID:", err) return } if packetID == StatusRequestID { status := StatusResponse{ Version: VersionInfo{ Name: "1.17.1", Protocol: 756, }, Players: PlayerInfo{ Max: 100, Online: 5, Sample: []Player{}, }, Description: Chat{ Text: "A Minecraft Server", }, } response, err := json.Marshal(status) if err != nil { fmt.Println("Error marshaling status response:", err) return } w := &Writer{data: make([]byte, 1024)} if err := w.writeVarInt(StatusResponseID); err != nil { fmt.Println("Error writing response ID:", err) return } if err := w.writeVarInt(len(response)); err != nil { fmt.Println("Error writing response length:", err) return } if err := w.writeString(string(response)); err != nil { fmt.Println("Error writing response:", err) return } } } func (r *Reader) readByte() (byte, error) { if r.cursor >= len(r.data) { return 0, errors.New("EOF") } b := r.data[r.cursor] r.cursor++ return b, nil } func (r *Reader) readVarInt() (int, error) { value := 0 position := 0 for { currentByte, err := r.readByte() if err != nil { return 0, err } value |= int(currentByte&SEGMENT_BITS) << position if (currentByte & CONTINUE_BIT) == 0 { break } position += 7 if position >= 32 { return 0, errors.New("VarInt is too big") } } return value, nil } func (r *Reader) readString() (string, error) { length, err := r.readVarInt() if err != nil { return "", err } if r.cursor+length > len(r.data) { return "", errors.New("EOF: Reached String unexpectedly") } str := string(r.data[r.cursor : r.cursor+length]) r.cursor += length return str, nil } type Writer struct { data []byte cursor int } func (w *Writer) writeByte(b byte) error { if w.cursor >= len(w.data) { return errors.New("EOF") } w.data[w.cursor] = b w.cursor++ return nil } func (w *Writer) writeVarInt(value int) error { for { temp := byte(value & SEGMENT_BITS) value >>= 7 if value != 0 { temp |= CONTINUE_BIT } if err := w.writeByte(temp); err != nil { return err } if value == 0 { break } } return nil } func (w *Writer) writeString(s string) error { length := len(s) if err := w.writeVarInt(length); err != nil { return err } if w.cursor+length > len(w.data) { return errors.New("EOF") } copy(w.data[w.cursor:], s) w.cursor += length return nil } func writeByte(conn net.Conn, b byte) error { _, err := conn.Write([]byte{b}) return err } func writeVarInt(conn net.Conn, value int) error { var buf [5]byte n := 0 for { temp := byte(value & SEGMENT_BITS) value >>= 7 if value != 0 { temp |= CONTINUE_BIT } buf[n] = temp n++ if value == 0 { break } } _, err := conn.Write(buf[:n]) return err } func readHandshakePacket(r *Reader, packet *HandshakePacket) error { // Print the whole packet fmt.Println("Packet: ", r.data) fmt.Println("Works so far") var err error packet.ProtocolVersion, err = r.readVarInt() fmt.Println("version: ", packet.ProtocolVersion) if err != nil { return err } packet.ServerAddress, err = r.readString() fmt.Println(packet.ServerAddress) if err != nil { return err } port, err := r.readByte() if err != nil { return err } packet.ServerPort = uint16(port) packet.NextState, err = r.readVarInt() fmt.Println("Next state: ", packet.NextState) if err != nil { return err } return nil }