sync
This commit is contained in:
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,6 +7,8 @@ local client
|
|||||||
-- Packet IDs
|
-- Packet IDs
|
||||||
network.MSG_KEY_PRESS = 1
|
network.MSG_KEY_PRESS = 1
|
||||||
network.MSG_GAMESTATE = 2
|
network.MSG_GAMESTATE = 2
|
||||||
|
network.MSG_SERVER_STATUS = 3
|
||||||
|
network.MSG_ON_CONNECT = 4
|
||||||
|
|
||||||
--------------------------------------------------
|
--------------------------------------------------
|
||||||
-- Packing
|
-- Packing
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"grid-mmo-server/server"
|
"grid-mmo-server/server"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -13,4 +14,5 @@ type tile struct {
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
server.Start()
|
server.Start()
|
||||||
|
fmt.Print()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,16 +5,25 @@ local player = {
|
|||||||
y = 100,
|
y = 100,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
local client_id = 0
|
||||||
|
|
||||||
function love.load()
|
function love.load()
|
||||||
network.connect("127.0.0.1", 9000)
|
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)
|
network.on(network.MSG_GAMESTATE, function(payload)
|
||||||
print("Server:", payload)
|
print(payload)
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
function love.keypressed(key)
|
function love.keypressed(key)
|
||||||
network.sendKey(key)
|
network.sendPacket(network.MSG_KEY_PRESS, client_id .. "/pressed/" .. key)
|
||||||
end
|
end
|
||||||
|
|
||||||
function love.update()
|
function love.update()
|
||||||
@@ -22,7 +31,7 @@ function love.update()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function love.draw()
|
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)
|
love.graphics.circle("fill", player.x, player.y, 10)
|
||||||
end
|
end
|
||||||
|
|||||||
+20
-7
@@ -6,13 +6,19 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
MsgKeyPress uint16 = 1
|
MsgKeyPress uint16 = 1
|
||||||
MsgGameState uint16 = 2
|
MsgGameState uint16 = 2
|
||||||
|
MSGServerStatus uint16 = 3
|
||||||
|
MSGOnConnect uint16 = 4
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var num_clients int = 0
|
||||||
|
var clients = map[int]net.Conn{}
|
||||||
|
|
||||||
func Start() {
|
func Start() {
|
||||||
listener, err := net.Listen("tcp", ":9000")
|
listener, err := net.Listen("tcp", ":9000")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -28,13 +34,21 @@ func Start() {
|
|||||||
continue
|
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)
|
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 matches Lua: 2 (msgID) + payload size
|
||||||
length := uint32(2 + len(payload))
|
length := uint32(2 + len(payload))
|
||||||
buf := make([]byte, 4+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)
|
binary.BigEndian.PutUint16(buf[4:6], msgID)
|
||||||
copy(buf[6:], payload)
|
copy(buf[6:], payload)
|
||||||
|
|
||||||
|
for _, conn := range clients {
|
||||||
n, err := conn.Write(buf)
|
n, err := conn.Write(buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -50,6 +65,7 @@ func SendPacket(conn net.Conn, msgID uint16, payload []byte) error {
|
|||||||
if n != len(buf) {
|
if n != len(buf) {
|
||||||
return fmt.Errorf("short write: expected %d bytes, got %d", len(buf), n)
|
return fmt.Errorf("short write: expected %d bytes, got %d", len(buf), n)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,6 +83,7 @@ func handle(conn net.Conn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("Client disconnected")
|
fmt.Println("Client disconnected")
|
||||||
|
num_clients -= 1
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,11 +119,7 @@ func handle(conn net.Conn) {
|
|||||||
fmt.Println(msg)
|
fmt.Println(msg)
|
||||||
|
|
||||||
// Send something back to the client
|
// Send something back to the client
|
||||||
err := SendPacket(conn, MsgGameState, []byte("received key press: "+msg))
|
go SendPacket(MsgGameState, []byte(msg))
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Send error:", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fmt.Println("Unknown message:", msgID)
|
fmt.Println("Unknown message:", msgID)
|
||||||
|
|||||||
Reference in New Issue
Block a user