diff --git a/main.go b/main.go
index 19e1dbd..6ad1e1a 100644
--- a/main.go
+++ b/main.go
@@ -1,21 +1,194 @@
package main
import (
+ "encoding/json"
"fmt"
+ "net"
)
-//TIP
To run your code, right-click the code and select Run.
Alternatively, click
-// the icon in the gutter and select the Run menu item from here.
+const (
+ HandshakePacketID = 0x00
+ StatusRequestID = 0x00
+ StatusResponseID = 0x00
+)
+
+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"`
+}
func main() {
- //TIP Press when your caret is at the underlined text
- // to see how GoLand suggests fixing the warning.
Alternatively, if available, click the lightbulb to view possible fixes.
- s := "gopher"
- fmt.Println("Hello and welcome, %s!", s)
+ listener, err := net.Listen("tcp", ":25565")
+ if err != nil {
+ fmt.Println("Error starting server:", err)
+ return
+ }
+ defer listener.Close()
- for i := 1; i <= 5; i++ {
- //TIP To start your debugging session, right-click your code in the editor and select the Debug option.
We have set one breakpoint
- // for you, but you can always add more by pressing .
- fmt.Println("i =", 100/i)
+ 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) {
+ var packetID byte
+ if err := readByte(conn, &packetID); err != nil {
+ fmt.Println("Error reading packet ID:", err)
+ return
+ }
+
+ if packetID == HandshakePacketID {
+ handleHandshake(conn)
+ }
+}
+
+func handleHandshake(conn net.Conn) {
+ var handshake HandshakePacket
+ if err := readHandshakePacket(conn, &handshake); err != nil {
+ fmt.Println("Error reading handshake packet:", err)
+ return
+ }
+
+ if handshake.NextState == 1 {
+ handleStatusRequest(conn)
+ }
+}
+
+func handleStatusRequest(conn net.Conn) {
+ var packetID byte
+ if err := readByte(conn, &packetID); 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
+ }
+
+ if err := writeByte(conn, StatusResponseID); err != nil {
+ fmt.Println("Error writing response ID:", err)
+ return
+ }
+
+ if err := writeVarInt(conn, len(response)); err != nil {
+ fmt.Println("Error writing response length:", err)
+ return
+ }
+
+ if _, err := conn.Write(response); err != nil {
+ fmt.Println("Error writing response:", err)
+ return
+ }
+ }
+}
+
+func readByte(conn net.Conn, b *byte) error {
+ buf := make([]byte, 1)
+ _, err := conn.Read(buf)
+ if err != nil {
+ return err
+ }
+ *b = buf[0]
+ 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 {
+ for {
+ temp := byte(value & 0x7F)
+ value >>= 7
+ if value != 0 {
+ temp |= 0x80
+ }
+ if _, err := conn.Write([]byte{temp}); err != nil {
+ return err
+ }
+ if value == 0 {
+ break
+ }
+ }
+ return nil
+}
+
+func readVarInt(conn net.Conn, value *int) error {
+ var result int
+ var shift uint
+ for {
+ var b byte
+ if err := readByte(conn, &b); err != nil {
+ return err
+ }
+ result |= int(b&0x7F) << shift
+ shift += 7
+ if b&0x80 == 0 {
+ break
+ }
+ }
+ *value = result
+ return nil
+}
+
+func readHandshakePacket(conn net.Conn, packet *HandshakePacket) error {
+ if err := readVarInt(conn, &packet.ProtocolVersion); err != nil {
+
+ }
+ return nil
+}