116 lines
2.0 KiB
Go
116 lines
2.0 KiB
Go
package server
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"fmt"
|
|
"io"
|
|
"log"
|
|
"net"
|
|
)
|
|
|
|
const (
|
|
MsgKeyPress uint16 = 1
|
|
MsgGameState uint16 = 2
|
|
)
|
|
|
|
func Start() {
|
|
listener, err := net.Listen("tcp", ":9000")
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
fmt.Println("Server listening on port 9000")
|
|
|
|
for {
|
|
conn, err := listener.Accept()
|
|
if err != nil {
|
|
fmt.Println("Accept error:", err)
|
|
continue
|
|
}
|
|
|
|
fmt.Println("Client connected")
|
|
|
|
go handle(conn)
|
|
}
|
|
}
|
|
|
|
func SendPacket(conn net.Conn, msgID uint16, payload []byte) error {
|
|
// Length matches Lua: 2 (msgID) + payload size
|
|
length := uint32(2 + len(payload))
|
|
buf := make([]byte, 4+2+len(payload))
|
|
|
|
binary.BigEndian.PutUint32(buf[0:4], length)
|
|
binary.BigEndian.PutUint16(buf[4:6], msgID)
|
|
copy(buf[6:], payload)
|
|
|
|
n, err := conn.Write(buf)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if n != len(buf) {
|
|
return fmt.Errorf("short write: expected %d bytes, got %d", len(buf), n)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func handle(conn net.Conn) {
|
|
defer conn.Close()
|
|
|
|
for {
|
|
// Read packet length
|
|
var length uint32
|
|
|
|
err := binary.Read(conn, binary.BigEndian, &length)
|
|
if err != nil {
|
|
if err != io.EOF {
|
|
fmt.Println("Read length error:", err)
|
|
}
|
|
|
|
fmt.Println("Client disconnected")
|
|
return
|
|
}
|
|
|
|
// Prevent invalid packets
|
|
if length < 2 {
|
|
fmt.Println("Invalid packet length:", length)
|
|
return
|
|
}
|
|
|
|
// Read message ID
|
|
var msgID uint16
|
|
|
|
err = binary.Read(conn, binary.BigEndian, &msgID)
|
|
if err != nil {
|
|
fmt.Println("Read message ID error:", err)
|
|
return
|
|
}
|
|
|
|
// Read payload
|
|
payload := make([]byte, length-2)
|
|
|
|
_, err = io.ReadFull(conn, payload)
|
|
if err != nil {
|
|
fmt.Println("Read payload error:", err)
|
|
return
|
|
}
|
|
|
|
switch msgID {
|
|
|
|
case MsgKeyPress:
|
|
msg := string(payload)
|
|
|
|
fmt.Println(msg)
|
|
|
|
// Send something back to the client
|
|
err := SendPacket(conn, MsgGameState, []byte("received key press: "+msg))
|
|
if err != nil {
|
|
fmt.Println("Send error:", err)
|
|
return
|
|
}
|
|
|
|
default:
|
|
fmt.Println("Unknown message:", msgID)
|
|
}
|
|
}
|
|
}
|