Implemented basic server

This commit is contained in:
Verox001 2025-02-20 22:13:51 +01:00
parent aa2c60013c
commit aeb8f642d6

193
main.go
View File

@ -1,21 +1,194 @@
package main
import (
"encoding/json"
"fmt"
"net"
)
//TIP <p>To run your code, right-click the code and select <b>Run</b>.</p> <p>Alternatively, click
// the <icon src="AllIcons.Actions.Execute"/> icon in the gutter and select the <b>Run</b> menu item from here.</p>
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 <p>Press <shortcut actionId="ShowIntentionActions"/> when your caret is at the underlined text
// to see how GoLand suggests fixing the warning.</p><p>Alternatively, if available, click the lightbulb to view possible fixes.</p>
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 <p>To start your debugging session, right-click your code in the editor and select the Debug option.</p> <p>We have set one <icon src="AllIcons.Debugger.Db_set_breakpoint"/> breakpoint
// for you, but you can always add more by pressing <shortcut actionId="ToggleLineBreakpoint"/>.</p>
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
}