143 lines
2.5 KiB
Lua
143 lines
2.5 KiB
Lua
local socket = require("socket")
|
|
|
|
local network = {}
|
|
|
|
local client
|
|
|
|
-- Packet IDs
|
|
network.MSG_KEY_PRESS = 1
|
|
network.MSG_GAMESTATE = 2
|
|
|
|
--------------------------------------------------
|
|
-- Packing
|
|
--------------------------------------------------
|
|
|
|
local function packU16(n)
|
|
return string.char(math.floor(n / 256) % 256, n % 256)
|
|
end
|
|
|
|
local function packU32(n)
|
|
return string.char(math.floor(n / 16777216) % 256, math.floor(n / 65536) % 256, math.floor(n / 256) % 256, n % 256)
|
|
end
|
|
|
|
local function unpackU16(s)
|
|
local b1, b2 = s:byte(1, 2)
|
|
return b1 * 256 + b2
|
|
end
|
|
|
|
local function unpackU32(s)
|
|
local b1, b2, b3, b4 = s:byte(1, 4)
|
|
|
|
return b1 * 16777216 + b2 * 65536 + b3 * 256 + b4
|
|
end
|
|
|
|
--------------------------------------------------
|
|
-- Connection
|
|
--------------------------------------------------
|
|
|
|
function network.connect(ip, port)
|
|
client = assert(socket.tcp())
|
|
|
|
client:settimeout(0)
|
|
|
|
local ok, err = client:connect(ip, port)
|
|
|
|
-- Non-blocking connect is expected
|
|
if not ok and err ~= "timeout" then
|
|
error(err)
|
|
end
|
|
|
|
print("Connecting...")
|
|
end
|
|
|
|
--------------------------------------------------
|
|
-- Sending
|
|
--------------------------------------------------
|
|
|
|
function network.sendPacket(id, payload)
|
|
if not client then
|
|
return
|
|
end
|
|
|
|
payload = payload or ""
|
|
|
|
local length = 2 + #payload
|
|
|
|
local packet = packU32(length) .. packU16(id) .. payload
|
|
|
|
client:send(packet)
|
|
end
|
|
|
|
function network.sendKey(key)
|
|
network.sendPacket(network.MSG_KEY_PRESS, key)
|
|
end
|
|
|
|
--------------------------------------------------
|
|
-- Packet handlers
|
|
--------------------------------------------------
|
|
|
|
network.handlers = {}
|
|
|
|
function network.on(id, callback)
|
|
network.handlers[id] = callback
|
|
end
|
|
|
|
--------------------------------------------------
|
|
-- Receiving
|
|
--------------------------------------------------
|
|
|
|
local function receivePacket()
|
|
local lenData, err = client:receive(4)
|
|
|
|
if not lenData then
|
|
return nil
|
|
end
|
|
|
|
local length = unpackU32(lenData)
|
|
|
|
local idData = client:receive(2)
|
|
if not idData then
|
|
return nil
|
|
end
|
|
|
|
local msgID = unpackU16(idData)
|
|
|
|
local payload = ""
|
|
|
|
if length > 2 then
|
|
payload = client:receive(length - 2)
|
|
|
|
if not payload then
|
|
return nil
|
|
end
|
|
end
|
|
|
|
return msgID, payload
|
|
end
|
|
|
|
--------------------------------------------------
|
|
-- Poll every frame
|
|
--------------------------------------------------
|
|
|
|
function network.update()
|
|
if not client then
|
|
return
|
|
end
|
|
|
|
while true do
|
|
local id, payload = receivePacket()
|
|
|
|
if not id then
|
|
break
|
|
end
|
|
|
|
local handler = network.handlers[id]
|
|
|
|
if handler then
|
|
handler(payload)
|
|
end
|
|
end
|
|
end
|
|
|
|
return network
|