diff --git a/programs.info b/programs.info index c7b1aae..cc21ecf 100644 --- a/programs.info +++ b/programs.info @@ -176,5 +176,15 @@ requires={ "libevent" } + }, + ["mcnet-exp"]={ + title="MC Network (Experimental)", + experimental=true, + info="MC Network based on modem networks.", + files={ + ["programs/mcnet/mcnet_core.lua"]="__lib__/", + ["programs/mcnet/libmcnet.lua"]="__lib__/", + ["programs/mcnet/mcnetd.lua"]="__bin__", + } } } \ No newline at end of file diff --git a/programs/mcnet/libmcnet.lua b/programs/mcnet/libmcnet.lua new file mode 100644 index 0000000..2964945 --- /dev/null +++ b/programs/mcnet/libmcnet.lua @@ -0,0 +1,47 @@ +-- LibMCNet +local component=require('component') +local core=require('mcnet_core') + +local mcnetd_version=1 +local default_ttl=5 + +local function NetSendEx(modem,dest,port,...) + local t={} + t.ver=mcnetd_version + t.ttl=default_ttl + t.src=modem.address + t.dest=dest + t.port=port + t.data=table.pack(...) + core.send(t) +end + +-- NetSend(component.modem,"dest-uuid",80,"GET / Hello.World") +-- NetSend("dest-uuid",80,"GET / Hello.World") +local function NetSend(a,b,c,...) + if(not a or type(a)=="table") then + NetSendEx(a or component.modem,b,c,...) + else + NetSendEx(component.modem,a,b,c,...) + end +end + +local function NetBroadcast(port,...) + local t={} + t.ver=mcnetd_version + t.ttl=default_ttl + t.src=component.modem.address + t.port=port + t.data=table.pack(...) + core.broadcast(t) +end + +local function SetTTL(ttl) + default_ttl=ttl +end + +return { + send=NetSend, + broadcast=NetBroadcast, + setttl=SetTTL +} \ No newline at end of file diff --git a/programs/mcnet/mcnet_core.lua b/programs/mcnet/mcnet_core.lua new file mode 100644 index 0000000..6b71ea0 --- /dev/null +++ b/programs/mcnet/mcnet_core.lua @@ -0,0 +1,90 @@ +-- MCNet Core +local component=require('component') +local event=require('event') +local serialization=require('serialization') + +local config={} +config.mcnetd_version=1 +config.port=53 +config.itvl=60 +config.modem=component.list("modem")() +if(config.modem) then + config.modem=component.proxy(config.modem) +else + config.modem={ + send=function() end, + broadcast=function() end + } +end + +local dns_table={} + +local function RBroadcast(t) + config.modem.broadcast(config.port,serialization.serialize(t)) +end + +local function RSend(dest,t) + config.modem.send(dest,config.port,serialization.serialize(t)) +end + +local function GSend(t) + t.dest=dns_table[t.dest] or t.dest + RBroadcast(t) +end + +local function GBroadcast(t) + RBroadcast(t) +end + +local function GEventCallback(ename,receiver,sender,port,distance,dtb) + if(config.modem.address==receiver and port==config.port and receiver~=sender) then + local t=serialization.unserialize(dtb) + if(type(t)=="table" and type(t.ver)=="number" and t.ver==config.mcnetd_version) then + if(not t.flag) then + if(not t.dest or t.dest==receiver) then + event.push("modem_message",receiver,t.src,t.port,0,table.unpack(t.data)) + elseif(t.ttl>1) then + t.ttl=t.ttl-1 + GSend(t) + end + elseif(t.flag==0) then + local t={} + t.ttl=1 + t.ver=config.mcnetd_version + t.flag=1 + t.data=dns_table + RSend(sender,t) + elseif(t.flag==1) then + for k,v in pairs(t.data) do + if(not dns_table[k]) then + dns_table[k]=v + end + end + end + end + end +end + +local function KflushDNS() + local t={} + t.ttl=1 + t.ver=config.mcnetd_version + t.flag=0 -- DNS Sync request + RBroadcast(t) +end + +local function GTimer() + KflushDNS() +end + +return { + send=GSend, + broadcast=GBroadcast, + + internal={ + evcb=GEventCallback, + tmcb=GTimer, + config=config, + dns=dns_table + } +} \ No newline at end of file diff --git a/programs/mcnet/mcnetd.lua b/programs/mcnet/mcnetd.lua new file mode 100644 index 0000000..add9167 --- /dev/null +++ b/programs/mcnet/mcnetd.lua @@ -0,0 +1,31 @@ +-- mcnet daemon +local component=require('component') +local event=require('event') +local core=require('mcnet_code') + +local xprint=function(...) + io.write("[mcnetd] ") + print(...) +end + +local modem=component.list("modem")() +if(not modem) then + xprint("No modem card found. Exiting mcnetd...") + return +else + modem=component.proxy(modem) + xprint("Found modem: " .. modem) +end + +if(not modem.open(core.internal.config.port)) then + xprint("Failed to open mcnetd port.") + return +end + +xprint("Starting mcnetd " .. core.mcnetd_version .. " on port " .. core.internal.config.port) +core.internal.config.modem=modem +local lid=event.listen("modem_message",core.internal.evcb) +local tid=event.timer(core.internal.config.itvl,core.internal.tmcb,math.huge) +core.internal.listenerid=lid +core.internal.timerid=tid +xprint("mcnetd started with listener id: " .. lid .. ", timer id: " .. tid)