1
0
mirror of https://github.com/ShadowKatStudios/OC-Minitel.git synced 2024-11-23 10:38:05 +11:00

hopefully made the bridge support arbitrary types and such

This commit is contained in:
Izaya 2018-04-05 17:27:36 +10:00
parent aa74d105ff
commit ce368627da
2 changed files with 71 additions and 44 deletions

View File

@ -3,13 +3,20 @@ local imt = require "interminitel"
local clients, coroutines, messages = {}, {}, {} local clients, coroutines, messages = {}, {}, {}
local function hasValidPacket(s) local function spawn(f)
local w, pi, pt, ds, sn, po, da = pcall(imt.decodePacket,s) coroutines[#coroutines+1] = coroutine.create(function()
if w and pi and pt and ds and sn and po and da then while true do
return true print(pcall(f))
end end
end)
end end
local function hasValidPacket(s)
local w, res = pcall(imt.decodePacket,s)
if res then return true end
end
hasValidPacket("")
function socketLoop() function socketLoop()
local server = socket.bind("*", 4096) local server = socket.bind("*", 4096)
server:settimeout(0) server:settimeout(0)
@ -17,27 +24,29 @@ function socketLoop()
local client,err = server:accept() local client,err = server:accept()
if client then if client then
client:settimeout(0) client:settimeout(0)
clients[#clients+1] = {["conn"]=client,last=os.time()} clients[#clients+1] = {["conn"]=client,last=os.time(),buffer=""}
print("Gained client: "..client:getsockname())
end end
coroutine.yield() coroutine.yield()
end end
end end
coroutines[#coroutines+1]=coroutine.create(socketLoop) spawn(socketLoop)
function clientLoop() function clientLoop()
while true do while true do
for _,client in pairs(clients) do for _,client in pairs(clients) do
local s=client.conn:receive(16384) local s=client.conn:receive()
if s then if s then
client.buffer = client.buffer .. s client.buffer = client.buffer .. s
print(s)
end end
end end
coroutine.yield() coroutine.yield()
end end
end end
coroutines[#coroutines+1]=coroutine.create(clientLoop) spawn(clientLoop)
function pushLoop() function pushLoop()
while true do while true do
@ -52,22 +61,23 @@ function pushLoop()
end end
end end
coroutines[#coroutines+1]=coroutine.create(pushLoop) spawn(pushLoop)
function bufferLoop() function bufferLoop()
while true do while true do
for _,client in pairs(clients) do for _,client in pairs(clients) do
if hasValidPacket(client.buffer) then if client.buffer:len() > 0 then
local tPacket = {imt.decodePacket(client.buffer)} if hasValidPacket(client.buffer) then
client.buffer = table.remove(tPacket,#tPacket) messages[#messages+1] = imt.encodePacket(imt.decodePacket(client.buffer))
messages[#messages+1] = imt.encodePacket(table.unpack(tPacket)) client.buffer = imt.getRemainder(client.buffer)
end
end end
end end
coroutine.yield() coroutine.yield()
end end
end end
coroutines[#coroutines+1]=coroutine.create(bufferLoop) spawn(bufferLoop)
while #coroutines > 0 do while #coroutines > 0 do
for k,v in pairs(coroutines) do for k,v in pairs(coroutines) do

View File

@ -1,5 +1,11 @@
local imt = {} local imt = {}
imt.ttypes = {}
imt.ttypes.string=1
imt.ttypes.number=2
imt.ftypes = {tostring,tonumber}
function imt.to16bn(n) function imt.to16bn(n)
return string.char(math.floor(n/256))..string.char(math.floor(n%256)) return string.char(math.floor(n/256))..string.char(math.floor(n%256))
end end
@ -7,38 +13,49 @@ function imt.from16bn(s)
return (string.byte(s,1,1)*256)+string.byte(s,2,2) return (string.byte(s,1,1)*256)+string.byte(s,2,2)
end end
function imt.encodePacket(packetID, packetType, destination, sender, port, data) function imt.encodePacket(...)
local rs = string.char(packetID:len()%256)..packetID..string.char(packetType) local tArgs = {...}
rs=rs..string.char(destination:len()%256)..destination local packet = string.char(#tArgs%256)
rs=rs..string.char(sender:len()%256)..sender for _,segment in ipairs(tArgs) do
rs=rs..to16bn(port) local segtype = type(segment)
rs=rs..to16bn(data:len())..data segment = tostring(segment)
return rs packet = packet .. imt.to16bn(segment:len()) .. string.char(imt.ttypes[segtype]) .. tostring(segment)
end
packet = imt.to16bn(packet:len()) .. packet
return packet
end end
function imt.decodePacket(s) function imt.decodePacket(s)
local pidlen, destlen, senderlen, datalen, packetID, packetType, destination, sender, port, data local function getfirst(n)
pidlen = string.byte(s:sub(1,1)) local ns = s:sub(1,n)
s=s:sub(2) s=s:sub(n+1)
packetID = s:sub(1,pidlen) return ns
s=s:sub(pidlen+1) end
packetType = string.byte(s:sub(pidlen+1)) local plen = imt.from16bn(getfirst(2))
s=s:sub(2) if s:len() < plen then return false end
destlen = string.byte(s:sub(1,1)) local nsegments = string.byte(getfirst(1))
s=s:sub(2) local tsegments = {}
destination = s:sub(1,destlen) for i = 1, nsegments do
s=s:sub(destlen+1) if s:len() < 1 then return false end
senderlen=string.byte(s:sub(1,1)) local seglen = imt.from16bn(getfirst(2))
s=s:sub(2) local segtype = string.byte(getfirst(1))
sender = s:sub(1,senderlen) local tempseg = getfirst(seglen)
s=s:sub(senderlen+1) tsegments[#tsegments+1] = imt.ftypes[segtype](tempseg)
port=from16bn(s:sub(1,2)) end
s=s:sub(3) return table.unpack(tsegments)
datalen=from16bn(s:sub(1,2)) end
s=s:sub(3) function imt.getRemainder(s)
data=s:sub(1,datalen) local function getfirst(n)
s=s:sub(datalen+1) local ns = s:sub(1,n)
return packetID, packetType, destination, sender, port, data, s s=s:sub(n+1)
return ns
end
local plen = imt.from16bn(getfirst(2))
if s:len() > plen then
getfirst(plen)
return s
end
return nil
end end
return imt return imt