From c5cb04d760ad31704290abc3c486451bf742e2a2 Mon Sep 17 00:00:00 2001 From: harper Date: Thu, 9 Jul 2026 20:43:41 -0700 Subject: [PATCH] sync --- ] | 126 +++++++++++++++++++++++++++++++++++++++++++++++ client/init.lua | 2 + main.go | 2 + main.lua | 15 ++++-- server/server.go | 39 ++++++++++----- 5 files changed, 168 insertions(+), 16 deletions(-) create mode 100644 ] diff --git a/] b/] new file mode 100644 index 0000000..cfdf130 --- /dev/null +++ b/] @@ -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) + } + } +} diff --git a/client/init.lua b/client/init.lua index 3cc50e6..ca237f2 100644 --- a/client/init.lua +++ b/client/init.lua @@ -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 diff --git a/main.go b/main.go index 14a6c94..a3028ff 100644 --- a/main.go +++ b/main.go @@ -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() } diff --git a/main.lua b/main.lua index 766bd63..721f875 100644 --- a/main.lua +++ b/main.lua @@ -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 diff --git a/server/server.go b/server/server.go index a1b3dea..2114a24 100644 --- a/server/server.go +++ b/server/server.go @@ -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,12 +57,14 @@ func SendPacket(conn net.Conn, msgID uint16, payload []byte) error { 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) + for _, conn := range clients { + 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 } @@ -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)