diff --git a/build.cfg b/build.cfg index 74ab824..40b27bd 100755 --- a/build.cfg +++ b/build.cfg @@ -9,7 +9,8 @@ modules/drivers/vt52.lua modules/lib/print.lua modules/drivers/kbd.lua modules/lib/cdlib.lua -modules/net/copper.0.lua +modules/lib/relib.lua +modules/net/copper.lua modules/lib/readline.lua modules/lib/shutil.lua modules/lib/sha256.lua diff --git a/modules/lib/relib.lua b/modules/lib/relib.lua new file mode 100644 index 0000000..bec6d93 --- /dev/null +++ b/modules/lib/relib.lua @@ -0,0 +1,25 @@ +_G.relib = {} +function relib.encode(p) + p.port = p.port or 0 + local p2,p1 = p.port%256, math.floor(p.port/256) + p.pid = p.pid or string.char(math.random(255),math.random(255),math.random(255)) + p.at = p.at or 0 + p.pt = p.pt or 1 +-- local data = string.char(p1,p2)..string.char(math.random(255),math.random(255),math.random(255),at%256,pt%256)..msg:sub(1,1500) + local data = string.char(p1,p2)..p.pid..string.char(p.at%256,p.pt%256)..p.msg:sub(1,1500) + return data +end +function relib.decode(dat) + if type(dat) == "string" then + if dat:len() > 7 then + local p = {} + p.port = tonumber(string.format("%x%x",string.byte(dat:sub(1,1)),string.byte(dat:sub(2,2))),16) + p.pid = dat:sub(3,5) + p.at = string.byte(dat:sub(6,6)) + p.pt = string.byte(dat:sub(7,7)) + p.msg = dat:sub(8,1507) + return p + end + end + return false +end diff --git a/modules/net/copper.lua b/modules/net/copper.lua new file mode 100644 index 0000000..6f3a416 --- /dev/null +++ b/modules/net/copper.lua @@ -0,0 +1,80 @@ +net = {} +net.id = computer.address():sub(1,8) +net.np = 4957 +net.tm = {} +function net.send(id,po,msg) -- id, port, message + event.push("sendmsg",id,po,msg) +end +if cdlib and relib then +spawn("copperd",function() print(pcall(function () + local pt = {} + local ps = {} + for a,t in component.list("modem") do + table.insert(net.tm,component.proxy(a)) + component.proxy(a).open(net.np) + end + while true do + local ev = {event.pull()} + if ev[1] == "rsendmsg" then + dst,data = ev[2],ev[3] + for k,v in ipairs(net.tm) do + v.broadcast(net.np,"copper",cdlib.encode(0,net.id,dst,data)) + end + elseif ev[1] == "sendmsg" then + local p = {} + p.pid = string.char(math.random(255),math.random(255),math.random(255)) + p.nid = ev[2] + p.port = ev[3] + p.msg = ev[4] + p.at = 0 + p.lt = 0 + ps[p.pid] = p + elseif ev[1] == "modem_message" and ev[4] == net.np and ev[6] == "copper" then + local hops,src,dst,data = cdlib.decode(ev[7]) + if not pt[ev[7]:sub(2)] then + pt[ev[7]:sub(2)] = os.time() + if dst == net.id then + event.push("net_rmsg",src,data) + local pd = relib.decode(data) + if pd then + if pd.pt == 1 then + event.push("net_msg",src,pd.port,pd.msg) + pd.pt = 2 + pd.nid = src + pd.lt = 0 + ps[pd.pid] = pd + elseif pd.pt == 2 then + ps[pd.pid] = nil + end + end + else + for k,v in ipairs(net.tm) do + v.broadcast(net.np,"copper",cdlib.encode(hops+1,src,dst,data)) + end + end + end + end + for k,v in pairs(ps) do + if v.lt < os.time()-1 then + for l,m in ipairs(net.tm) do + m.broadcast(net.np,"copper",cdlib.encode(0,net.id,v.nid,relib.encode(v))) + end + v.at = v.at + 1 + v.lt = os.time() + if v.pt == 2 then ps[k] = nil end + end + if v.at > 255 then + ps[k] = nil + end + end + if #pt > 63 then + local cot = os.time() + for k,v in pairs(pt) do + if v < cot-16 then + pt[k] = nil + end + end + end + end +end)) end) +end