This commit is contained in:
harper
2026-07-09 20:43:41 -07:00
parent bc14e946fc
commit c5cb04d760
5 changed files with 168 additions and 16 deletions
+126
View File
@@ -0,0 +1,126 @@
package server
import (
"encoding/binary"
"fmt"
"io"
"log"
"net"
"strconv"
)
const (
MsgKeyPress uint16 = 1
MsgGameState uint16 = 2
MSGServerStatus uint16 = 3
MSGOnConnect uint16 = 4
)
var num_clients int = 0
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
}
num_clients += 1
fmt.Println(toString(num_clients))
go SendPacket(conn, MSGOnConnect, []byte(string(num_clients)))
go handle(conn)
}
}
func toString(num int) {
return strconv.FormatInt(int64(num), 10)
}
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)
}
}
}
+2
View File
@@ -7,6 +7,8 @@ local client
-- Packet IDs
network.MSG_KEY_PRESS = 1
network.MSG_GAMESTATE = 2
network.MSG_SERVER_STATUS = 3
network.MSG_ON_CONNECT = 4
--------------------------------------------------
-- Packing
+2
View File
@@ -1,6 +1,7 @@
package main
import (
"fmt"
"grid-mmo-server/server"
)
@@ -13,4 +14,5 @@ type tile struct {
func main() {
server.Start()
fmt.Print()
}
+12 -3
View File
@@ -5,16 +5,25 @@ local player = {
y = 100,
}
local client_id = 0
function love.load()
network.connect("127.0.0.1", 9000)
network.on(network.MSG_ON_CONNECT, function(payload)
print("connected to server with id " .. payload)
if client_id == 0 then
client_id = payload
end
end)
network.on(network.MSG_GAMESTATE, function(payload)
print("Server:", payload)
print(payload)
end)
end
function love.keypressed(key)
network.sendKey(key)
network.sendPacket(network.MSG_KEY_PRESS, client_id .. "/pressed/" .. key)
end
function love.update()
@@ -22,7 +31,7 @@ function love.update()
end
function love.draw()
love.graphics.print("Connected", 20, 20)
love.graphics.print("Connected as id " .. client_id, 20, 20)
love.graphics.circle("fill", player.x, player.y, 10)
end
+20 -7
View File
@@ -6,13 +6,19 @@ import (
"io"
"log"
"net"
"strconv"
)
const (
MsgKeyPress uint16 = 1
MsgGameState uint16 = 2
MSGServerStatus uint16 = 3
MSGOnConnect uint16 = 4
)
var num_clients int = 0
var clients = map[int]net.Conn{}
func Start() {
listener, err := net.Listen("tcp", ":9000")
if err != nil {
@@ -28,13 +34,21 @@ func Start() {
continue
}
fmt.Println("Client connected")
num_clients += 1
client_id := strconv.Itoa(num_clients)
fmt.Println(client_id)
go SendPacket(MSGOnConnect, []byte(client_id))
addClient(conn, num_clients)
go handle(conn)
}
}
func SendPacket(conn net.Conn, msgID uint16, payload []byte) error {
func addClient(conn net.Conn, id int) {
clients[id] = conn
}
func SendPacket(msgID uint16, payload []byte) error {
// Length matches Lua: 2 (msgID) + payload size
length := uint32(2 + len(payload))
buf := make([]byte, 4+2+len(payload))
@@ -43,6 +57,7 @@ func SendPacket(conn net.Conn, msgID uint16, payload []byte) error {
binary.BigEndian.PutUint16(buf[4:6], msgID)
copy(buf[6:], payload)
for _, conn := range clients {
n, err := conn.Write(buf)
if err != nil {
return err
@@ -50,6 +65,7 @@ func SendPacket(conn net.Conn, msgID uint16, payload []byte) error {
if n != len(buf) {
return fmt.Errorf("short write: expected %d bytes, got %d", len(buf), n)
}
}
return nil
}
@@ -67,6 +83,7 @@ func handle(conn net.Conn) {
}
fmt.Println("Client disconnected")
num_clients -= 1
return
}
@@ -102,11 +119,7 @@ func handle(conn net.Conn) {
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
}
go SendPacket(MsgGameState, []byte(msg))
default:
fmt.Println("Unknown message:", msgID)