net = {} net.id = computer.address():sub(1,8) net.delay = 2 net.np = 4957 net.cache = true net.cache_time = 16 net.log = false net.tm = {} if not component.list("ocemu")() then net.cache = true end function net.send(id,po,msg) -- id, port, message if id and po and msg then event.push("sendmsg",id,po,msg) else return false end end if cdlib and relib then spawn("copperd",function() print(xpcall(function () local pt = {} local ps = {} local fcache = {} local olog = log local function log(...) if net.log then olog(...) end end 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 pt[cdlib.encode(0,net.id,p.nid,relib.encode(p)):sub(2)] = computer.uptime() 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 hops and src and dst and data then if not fcache[src] then log("fcache["..tostring(src).."] = "..tostring(ev[3])) fcache[src] = {ev[2],ev[3],computer.uptime()} end if not pt[ev[7]:sub(2)] then pt[ev[7]:sub(2)] = computer.uptime() if dst == net.id then event.push("net_rmsg",src,data) local pd = relib.decode(data) if pd then if pd.port and pd.pid and pd.at and pd.pt then if pd.pt == 1 then event.push("net_msg",src,pd.port,pd.msg) pd.pt = 2 pd.nid = src pd.lt = 0 pd.msg = "" ps[pd.pid] = pd log("[copperd] sent ack to "..src) elseif pd.pt == 2 then log("[copperd] received ack from "..src.." for "..pd.pid) ps[pd.pid] = nil end end end else if hops < 255 then if fcache[dst] and net.cache then component.invoke(fcache[dst][1],"send",fcache[dst][2],net.np,"copper",cdlib.encode(hops+1,src,dst,data)) 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 end end end for k,v in pairs(ps) do if v.lt < computer.uptime()-net.delay then if fcache[v.nid] and net.cache then local lma = fcache[v.nid][1] local rma = fcache[v.nid][2] component.invoke(lma,"send",rma,net.np,"copper",cdlib.encode(0,net.id,v.nid,relib.encode(v))) else for l,m in ipairs(net.tm) do m.broadcast(net.np,"copper",cdlib.encode(0,net.id,v.nid,relib.encode(v))) end end v.at = v.at + 1 v.lt = computer.uptime() if v.pt == 2 then ps[k] = nil end end if v.at > 255 then ps[k] = nil end end local cot = computer.uptime() for k,v in pairs(pt) do if v < cot-16 then pt[k] = nil end end for k,v in pairs(fcache) do if v[3] < cot - net.cache_time then log(k.." derezzed") fcache[k] = nil end end end end)) end) end