diff --git a/main.go b/main.go index f2df281..ab5c606 100644 --- a/main.go +++ b/main.go @@ -56,6 +56,11 @@ type Reader struct { cursor int } +type ClientState struct { + conn net.Conn + nextState int +} + func main() { listener, err := net.Listen("tcp", "localhost:25565") if err != nil { @@ -73,99 +78,126 @@ func main() { continue } - go handleConnection(conn) + client := &ClientState{conn: conn, nextState: 0} + + go handleConnection(client) } } -func handleConnection(conn net.Conn) { - r := &Reader{data: make([]byte, 1024)} +func handleConnection(client *ClientState) { + defer client.conn.Close() + fmt.Println("New connection from:", client.conn.RemoteAddr()) + + r := &Reader{data: make([]byte, 0)} - // Print the whole packet buf := make([]byte, 1024) - n, _ := conn.Read(buf) - r.data = buf[:n] - fmt.Println("Packet: ", r.data) + for { + n, err := client.conn.Read(buf) + if err != nil { + fmt.Println("Error reading from connection or connection closed:", err) + break + } - _, err := r.readVarInt() - if err != nil { - fmt.Println("Error reading first number:", err) - return - } + // Append new data to the reader buffer + r.data = append(r.data, buf[:n]...) - packetID, err := r.readVarInt() - if err != nil { - fmt.Println("Error reading packet ID:", err) - return - } + // Process packets as long as there is data + for len(r.data) > 0 { + startCursor := r.cursor - fmt.Println("Packet ID: ", packetID) + packetLength, err := r.readVarInt() + if err != nil { + r.cursor = startCursor // Reset if incomplete packet + break + } - switch packetID { - case HandshakePacketID: - handleHandshake(r) - default: - fmt.Println("Unknown packet ID:", packetID) + if len(r.data[r.cursor:]) < packetLength { + r.cursor = startCursor // Reset if incomplete packet + break + } + + packetID, err := r.readVarInt() + if err != nil { + fmt.Println("Error reading packet ID:", err) + break + } + + fmt.Println("Packet ID:", packetID) + + if packetID == StatusRequestID && client.nextState == 1 { + handleStatusRequest(client.conn) + } else { + if packetID == HandshakePacketID { + handshake, err := handleHandshake(r) + if err != nil { + fmt.Println("Error processing handshake:", err) + return + } + client.nextState = handshake.NextState + } + } + + // Remove processed data + r.data = r.data[r.cursor:] + r.cursor = 0 + } } } -func handleHandshake(r *Reader) { +func handleHandshake(r *Reader) (HandshakePacket, error) { var handshake HandshakePacket if err := readHandshakePacket(r, &handshake); err != nil { fmt.Println("Error reading handshake packet:", err) - return + return handshake, err } - if handshake.NextState == 1 { - handleStatusRequest(r) - } + return handshake, nil } -func handleStatusRequest(r *Reader) { - packetID, err := r.readVarInt() +func handleStatusRequest(conn net.Conn) { + 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 reading packet ID:", err) + fmt.Println("Error marshaling status response:", 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", - }, - } + w := &Writer{data: make([]byte, 1024)} - response, err := json.Marshal(status) - if err != nil { - fmt.Println("Error marshaling status response:", err) - return - } + if err := w.writeVarInt(StatusResponseID); err != nil { + fmt.Println("Error writing response ID:", err) + return + } - w := &Writer{data: make([]byte, 1024)} + if err := w.writeVarInt(len(response)); err != nil { + fmt.Println("Error writing response length:", err) + return + } - if err := w.writeVarInt(StatusResponseID); err != nil { - fmt.Println("Error writing response ID:", err) - return - } + if err := w.writeString(string(response)); err != nil { + fmt.Println("Error writing response:", 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 - } + // Send response to client + _, err = conn.Write(w.data[:w.cursor]) + if err != nil { + fmt.Println("Error sending response:", err) } } @@ -218,6 +250,20 @@ func (r *Reader) readString() (string, error) { return str, nil } +func (r *Reader) readUnsignedShort() (uint16, error) { + b1, err := r.readByte() + if err != nil { + return 0, err + } + + b2, err := r.readByte() + if err != nil { + return 0, err + } + + return uint16(b1)<<8 | uint16(b2), nil +} + type Writer struct { data []byte cursor int @@ -304,11 +350,12 @@ func readHandshakePacket(r *Reader, packet *HandshakePacket) error { return err } - port, err := r.readByte() + port, err := r.readUnsignedShort() if err != nil { return err } - packet.ServerPort = uint16(port) + packet.ServerPort = port + fmt.Println("Port: ", packet.ServerPort) packet.NextState, err = r.readVarInt() fmt.Println("Next state: ", packet.NextState)