Implemented basic server
This commit is contained in:
parent
aa2c60013c
commit
aeb8f642d6
193
main.go
193
main.go
@ -1,21 +1,194 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net"
|
||||||
)
|
)
|
||||||
|
|
||||||
//TIP <p>To run your code, right-click the code and select <b>Run</b>.</p> <p>Alternatively, click
|
const (
|
||||||
// the <icon src="AllIcons.Actions.Execute"/> icon in the gutter and select the <b>Run</b> menu item from here.</p>
|
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() {
|
func main() {
|
||||||
//TIP <p>Press <shortcut actionId="ShowIntentionActions"/> when your caret is at the underlined text
|
listener, err := net.Listen("tcp", ":25565")
|
||||||
// to see how GoLand suggests fixing the warning.</p><p>Alternatively, if available, click the lightbulb to view possible fixes.</p>
|
if err != nil {
|
||||||
s := "gopher"
|
fmt.Println("Error starting server:", err)
|
||||||
fmt.Println("Hello and welcome, %s!", s)
|
return
|
||||||
|
}
|
||||||
|
defer listener.Close()
|
||||||
|
|
||||||
for i := 1; i <= 5; i++ {
|
fmt.Println("Server started on port 25565")
|
||||||
//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>
|
for {
|
||||||
fmt.Println("i =", 100/i)
|
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
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user