Rock/main.go

346 lines
7.7 KiB
Go
Raw Normal View History

2025-02-20 22:02:44 +01:00
package main
import (
2025-02-21 00:26:09 +01:00
"bytes"
"encoding/binary"
2025-02-20 22:13:51 +01:00
"encoding/json"
2025-02-20 23:18:43 +01:00
"errors"
2025-02-20 22:02:44 +01:00
"fmt"
"io"
2025-02-20 22:13:51 +01:00
"net"
2025-02-20 22:02:44 +01:00
)
2025-02-20 22:13:51 +01:00
const (
HandshakePacketID = 0x00
StatusRequestID = 0x00
StatusResponseID = 0x00
2025-02-21 00:26:09 +01:00
PingRequestID = 0x01
PongResponseID = 0x01
2025-02-20 23:18:43 +01:00
)
type PrefixedByteArray struct {
Length int
Data []byte
}
2025-02-20 22:13:51 +01:00
type HandshakePacket struct {
ProtocolVersion int
ServerAddress string
ServerPort uint16
NextState int
}
type LoginStartPacket struct {
SharedSecret PrefixedByteArray
VerifyToken PrefixedByteArray
}
2025-02-20 22:13:51 +01:00
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"`
}
2025-02-20 22:02:44 +01:00
2025-02-20 23:59:19 +01:00
type ClientState struct {
conn net.Conn
nextState int
}
2025-02-20 22:02:44 +01:00
func main() {
2025-02-20 23:18:43 +01:00
listener, err := net.Listen("tcp", "localhost:25565")
2025-02-20 22:13:51 +01:00
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
}
2025-02-20 23:59:19 +01:00
client := &ClientState{conn: conn, nextState: 0}
go handleConnection(client)
2025-02-20 22:13:51 +01:00
}
}
2025-02-20 23:59:19 +01:00
func handleConnection(client *ClientState) {
defer client.conn.Close()
fmt.Println("New connection from:", client.conn.RemoteAddr())
2025-02-20 23:18:43 +01:00
2025-02-20 23:59:19 +01:00
buf := make([]byte, 1024)
for {
n, err := client.conn.Read(buf)
if err != nil {
if err.Error() == "EOF" {
fmt.Println("Client disconnected:", client.conn.RemoteAddr())
} else {
fmt.Println("Error reading from client:", err)
}
2025-02-20 23:59:19 +01:00
break
}
2025-02-20 23:18:43 +01:00
2025-02-21 00:26:09 +01:00
reader := bytes.NewReader(buf[:n])
2025-02-20 23:59:19 +01:00
// Read packet length
2025-02-21 00:26:09 +01:00
packetLength, err := readVarInt(reader)
if err != nil {
fmt.Println("Error reading packet length:", err)
2025-02-21 00:26:09 +01:00
break
}
2025-02-20 23:59:19 +01:00
// Ensure full packet is read
packetData := make([]byte, packetLength)
if _, err := io.ReadFull(reader, packetData); err != nil {
fmt.Println("Error reading full packet data:", err)
break
}
packetReader := bytes.NewReader(packetData)
packetID, err := readVarInt(packetReader)
2025-02-21 00:26:09 +01:00
if err != nil {
fmt.Println("Error reading packet ID:", err)
break
}
2025-02-20 23:59:19 +01:00
2025-02-21 00:26:09 +01:00
fmt.Println("Packet ID:", packetID)
2025-02-20 23:59:19 +01:00
2025-02-21 00:26:09 +01:00
switch packetID {
case HandshakePacketID: // The same packet ID is used for the Status Request
2025-02-21 00:26:09 +01:00
if client.nextState == 1 {
handleStatusRequest(client)
} else if client.nextState == 2 {
fmt.Println("Received Login Start")
// Login Start
loginStart, err := handleLoginStart(packetReader)
if err != nil {
fmt.Println("Error processing login start:", err)
return
}
fmt.Println("Login Start:", loginStart)
// Send Encryption Request back
var packetData bytes.Buffer
writeVarInt(&packetData, 1) // Packet length: 1 byte for ID
packetData.WriteByte(0x01) // Encryption Request ID
// Server ID
writeString(&packetData, "JustAnotherServer")
// Public Key
writePrefixedByteArray(&packetData, PrefixedByteArray{Length: 0, Data: []byte{}})
// Verify Token
writePrefixedByteArray(&packetData, PrefixedByteArray{Length: 0, Data: []byte{}})
// Should authenticate (actually a boolean)
packetData.WriteByte(1)
if _, err := client.conn.Write(packetData.Bytes()); err != nil {
fmt.Println("Error sending encryption request:", err)
} else {
fmt.Println("Encryption request sent successfully")
}
} else if client.nextState == 3 {
// Transfer
fmt.Println("Received status request in the wrong state")
2025-02-21 00:26:09 +01:00
} else {
handshake, err := handleHandshake(packetReader)
2025-02-21 00:26:09 +01:00
if err != nil {
fmt.Println("Error processing handshake:", err)
return
}
client.nextState = handshake.NextState
}
case PingRequestID:
var timestamp int64
if err := binary.Read(packetReader, binary.BigEndian, &timestamp); err != nil {
2025-02-21 00:26:09 +01:00
fmt.Println("Error reading timestamp:", err)
2025-02-20 23:59:19 +01:00
break
}
2025-02-21 00:26:09 +01:00
var responsePacket bytes.Buffer
writeVarInt(&responsePacket, 9) // Packet length: 1 byte for ID + 8 bytes for timestamp
responsePacket.WriteByte(PongResponseID)
binary.Write(&responsePacket, binary.BigEndian, timestamp)
2025-02-20 23:59:19 +01:00
2025-02-21 00:26:09 +01:00
if _, err := client.conn.Write(responsePacket.Bytes()); err != nil {
fmt.Println("Error sending pong response:", err)
2025-02-20 23:59:19 +01:00
} else {
2025-02-21 00:26:09 +01:00
fmt.Println("Pong response sent successfully:", timestamp)
2025-02-20 23:59:19 +01:00
}
}
2025-02-20 22:13:51 +01:00
}
}
2025-02-21 00:26:09 +01:00
func handleHandshake(reader *bytes.Reader) (HandshakePacket, error) {
2025-02-20 22:13:51 +01:00
var handshake HandshakePacket
2025-02-21 00:26:09 +01:00
var err error
2025-02-20 23:59:19 +01:00
2025-02-21 00:26:09 +01:00
handshake.ProtocolVersion, err = readVarInt(reader)
2025-02-20 23:18:43 +01:00
if err != nil {
2025-02-21 00:26:09 +01:00
return handshake, err
2025-02-20 23:59:19 +01:00
}
2025-02-20 22:13:51 +01:00
2025-02-21 00:26:09 +01:00
handshake.ServerAddress, err = readString(reader)
2025-02-20 23:59:19 +01:00
if err != nil {
2025-02-21 00:26:09 +01:00
return handshake, err
2025-02-20 23:18:43 +01:00
}
2025-02-21 00:26:09 +01:00
if err := binary.Read(reader, binary.BigEndian, &handshake.ServerPort); err != nil {
return handshake, err
2025-02-20 23:18:43 +01:00
}
2025-02-21 00:26:09 +01:00
handshake.NextState, err = readVarInt(reader)
2025-02-20 22:13:51 +01:00
if err != nil {
2025-02-21 00:26:09 +01:00
return handshake, err
2025-02-20 23:18:43 +01:00
}
2025-02-21 00:26:09 +01:00
fmt.Printf("Handshake received: %+v\n", handshake)
return handshake, nil
2025-02-20 22:13:51 +01:00
}
func handleLoginStart(reader *bytes.Reader) (LoginStartPacket, error) {
var packet LoginStartPacket
var err error
packet.SharedSecret, err = readPrefixedByteArray(reader)
if err != nil {
return packet, err
}
packet.VerifyToken, err = readPrefixedByteArray(reader)
if err != nil {
return packet, err
}
fmt.Printf("Login Start received: %+v\n", packet)
return packet, nil
}
2025-02-21 00:26:09 +01:00
func handleStatusRequest(client *ClientState) {
status := StatusResponse{
Version: VersionInfo{"1.21.4", 769},
Players: PlayerInfo{Max: 100, Online: 5, Sample: []Player{}},
Description: Chat{Text: "A Minecraft Server"},
2025-02-20 23:59:19 +01:00
}
2025-02-21 00:26:09 +01:00
response, err := json.Marshal(status)
2025-02-20 23:59:19 +01:00
if err != nil {
2025-02-21 00:26:09 +01:00
fmt.Println("Error marshaling status response:", err)
return
2025-02-20 23:59:19 +01:00
}
2025-02-21 00:26:09 +01:00
var packetData bytes.Buffer
writeVarInt(&packetData, StatusResponseID)
2025-02-21 00:26:09 +01:00
writeVarInt(&packetData, len(response))
packetData.Write(response)
2025-02-20 23:59:19 +01:00
2025-02-21 00:26:09 +01:00
var responsePacket bytes.Buffer
writeVarInt(&responsePacket, packetData.Len())
responsePacket.Write(packetData.Bytes())
fmt.Println("Final Response Packet:", responsePacket.Bytes())
2025-02-20 22:13:51 +01:00
2025-02-21 00:26:09 +01:00
if _, err = client.conn.Write(responsePacket.Bytes()); err != nil {
fmt.Println("Error sending response:", err)
} else {
fmt.Println("Status response sent successfully")
2025-02-20 23:18:43 +01:00
}
}
2025-02-21 00:26:09 +01:00
func writeVarInt(buf *bytes.Buffer, value int) {
2025-02-20 22:13:51 +01:00
for {
2025-02-21 00:26:09 +01:00
temp := byte(value & 0x7F)
2025-02-20 22:13:51 +01:00
value >>= 7
2025-02-21 00:26:09 +01:00
if value > 0 {
temp |= 0x80
2025-02-20 22:13:51 +01:00
}
2025-02-21 00:26:09 +01:00
buf.WriteByte(temp)
2025-02-20 22:13:51 +01:00
if value == 0 {
break
}
}
2025-02-20 23:18:43 +01:00
}
func writeString(buf *bytes.Buffer, value string) {
writeVarInt(buf, len(value))
buf.WriteString(value)
}
func writePrefixedByteArray(buf *bytes.Buffer, value PrefixedByteArray) {
writeVarInt(buf, value.Length)
buf.Write(value.Data)
}
2025-02-21 00:26:09 +01:00
func readVarInt(reader *bytes.Reader) (int, error) {
value, position := 0, 0
2025-02-20 22:13:51 +01:00
for {
2025-02-21 00:26:09 +01:00
b, err := reader.ReadByte()
if err != nil {
return 0, err
2025-02-20 22:13:51 +01:00
}
2025-02-21 00:26:09 +01:00
value |= int(b&0x7F) << position
if (b & 0x80) == 0 {
2025-02-20 22:13:51 +01:00
break
}
2025-02-21 00:26:09 +01:00
position += 7
if position >= 32 {
return 0, errors.New("VarInt too big")
}
2025-02-20 22:13:51 +01:00
}
2025-02-21 00:26:09 +01:00
return value, nil
2025-02-20 22:13:51 +01:00
}
2025-02-21 00:26:09 +01:00
func readString(reader *bytes.Reader) (string, error) {
length, err := readVarInt(reader)
2025-02-20 23:18:43 +01:00
if err != nil {
2025-02-21 00:26:09 +01:00
return "", err
2025-02-20 23:18:43 +01:00
}
2025-02-21 00:26:09 +01:00
strBuf := make([]byte, length)
if _, err := reader.Read(strBuf); err != nil {
return "", err
2025-02-20 23:18:43 +01:00
}
2025-02-21 00:26:09 +01:00
return string(strBuf), nil
2025-02-20 22:02:44 +01:00
}
func readPrefixedByteArray(reader *bytes.Reader) (PrefixedByteArray, error) {
length, err := readVarInt(reader)
if err != nil {
return PrefixedByteArray{}, err
}
data := make([]byte, length)
if _, err := reader.Read(data); err != nil {
return PrefixedByteArray{}, err
}
return PrefixedByteArray{Length: length, Data: data}, nil
}