diff --git a/programs.info b/programs.info index 476f8f4..441c14b 100644 --- a/programs.info +++ b/programs.info @@ -58,6 +58,13 @@ "libgpu","libevent","simple_data_structure" } }, + ["shrink"]={ + title="Shrink", + info="Shrink string by removing useless spaces.", + files={ + "shrink.lua" + } + }, ["drone"]={ title="Drone", info="Drone console and bios", @@ -65,10 +72,12 @@ contact="1362050620@qq.com", files={ ["programs/drone/drone_bios.lua"]="drone_bios.lua", - ["programs/drone/drone_console.lua"]="drone_console.lua" + ["programs/drone/drone_console.lua"]="drone_console.lua", + ["programs/drone/drone_radar.lua"]="drone_radar.lua", + ["programs/drone/drone_flash.lua"]="drone_flash.lua" }, requires={ - "libevent" + "libevent", "shrink" } }, ["smartstorage"]={ diff --git a/programs/drone/drone_bios.lua b/programs/drone/drone_bios.lua index 0a96ba2..94018bd 100644 --- a/programs/drone/drone_bios.lua +++ b/programs/drone/drone_bios.lua @@ -1,6 +1,6 @@ +drone_version="Drone v3.3b" drone=component.proxy(component.list("drone")()) modem=component.proxy(component.list("modem")()) -drone_version="Drone v3.2" drone.setStatusText(drone_version .. '\n' .. modem.address) modem.open(98) handlers={} @@ -8,39 +8,67 @@ timers={} wake_list={} handlers["_anything"]={} handle_event=function(e) - if(handlers[e[1]]) then for i,tb in pairs(handlers[e[1]]) do coroutine.resume(tb.co,i,e) end end - for i,tb in pairs(handlers["_anything"]) do coroutine.resume(tb.co,i,e) end + if(handlers[e[1]]) then + for i,tb in pairs(handlers[e[1]]) do + coroutine.resume(tb.co,i,e) + end + end + for i,tb in pairs(handlers["_anything"]) do + coroutine.resume(tb.co,i,e) + end end sleep=function(sec) - local this,flag=coroutine.running() - table.insert(wake_list,{id=0,tm=computer.uptime()+sec,co=this}) - local this_id=coroutine.yield() - table.remove(wake_list,this_id) + table.insert(wake_list,{id=0,tm=computer.uptime()+sec,co=coroutine.running()}) + table.remove(wake_list,coroutine.yield()) end -cancel=function(id) - if(timers[id]) then for i,t in ipairs(wake_list) do if(t.id==id) then table.remove(wake_list,i) break end end timers[id]=nil return true - else return false end +cancel=function(id,wid) + if(wid) then + table.remove(wake_list,wid) + else + for i,t in ipairs(wake_list) do + if(t.id==id) then + table.remove(wake_list,i) + break + end + end + end + if(timers[id]) then + timers[id]=nil + return true + else + return false + end end timer=function(sec,fn,times) - local next=computer.uptime()+sec - local id=table.insert(timers,{cb=fn,intv=sec,times=times}) - table.insert(wake_list,{tm=next,id=id,co=coroutine.create(function(this_id) + table.insert(timers,{cb=fn,intv=sec,times=times}) + local id=#timers + table.insert(wake_list,{tm=computer.uptime()+sec,id=id,co=coroutine.create(function(wid) while true do - pcall(fn) - local this_tb=timers[this.id] - if(this_tb.times>0) then this_tb.times=this_tb.times-1 - if(this_tb.times<1) then timer[wake_list[this_id].id]=nil table.remove(wake_list,this_id) return - else this.tm=computer.uptime()+this_tb.intv this_id=coroutine.yield() end + pcall(fn) + local tb=timers[id] + if(tb.times<0 or tb.times>1) then + tb.times,tb.tm=tb.times-1,computer.uptime()+tb.intv + wid=coroutine.yield() + else + cancel(id,wid) + return end end end)}) return id end ignore=function(name,id) - handlers[name][id]=nil + if(handlers[name][id]) then + handlers[name][id]=nil + return true + else + return false + end end listen=function(name,cb) - if(handlers[name]==nil) then handlers[name]={} end + if(handlers[name]==nil) then + handlers[name]={} + end table.insert(handlers[name],{co=coroutine.create(function(i,e) while true do local ok,res=pcall(cb,e) @@ -54,28 +82,27 @@ listen=function(name,cb) return #handlers[name] end wait=function(sec,name) - if(sec==nil and name==nil) then sec=-1 - elseif(sec==nil and name~=nil) then sec=-1 - elseif(sec~=nil and name==nil) then if(type(sec)=="string") then name=sec sec=-1 end end - local this,flag=coroutine.running() - if(sec>=0) then - table.insert(wake_list,{id=0,tm=computer.uptime()+sec,co=this}) - else - table.insert(wake_list,{id=0,tm=math.huge,co=this}) - end - local id - if(name~=nil) then - id=listen(name,function(e) if(e[1]==name) then coroutine.resume(this,-1,e) return false end end) - else - id=listen("_anything",function(e) coroutine.resume(this,-1,e) return false end) - end - local this_id,e=coroutine.yield() - if(this_id==-1) then - for idx,t in ipairs(wake_list) do if(t.co==this) then table.remove(wake_list,idx) end end + if(name==nil and type(sec)=="string") then name=sec sec=nil end + sec=sec and computer.uptime()+sec or math.huge + local this=coroutine.running() + table.insert(wake_list,{id=0,tm=sec,co=this}) + name=name or "_anything" + local id=listen(name,function(e) + coroutine.resume(this,-1,e) + return false + end) + local wid,e=coroutine.yield() + ignore(name,id) + if(wid==-1) then + for i,t in ipairs(wake_list) do + if(t.co==this) then + table.remove(wake_list,i) + break + end + end return e else - ignore(id) - table.remove(wake_list,this_id) + table.remove(wake_list,wid) return nil end end @@ -83,25 +110,26 @@ listen("modem_message",function(e) local snd=e[3] local tag=e[6] local cmd=e[7] - if(tag~=nil and cmd~=nil and tag=='execute_command') then - local ok,err=pcall(function() - local f=load(cmd) - local cmdok,cmdresult=pcall(f) - if(not cmdok) then - modem.send(snd,99,"Failed to execute: " .. cmdresult) + if(tag and tag=='execute_command' and cmd) then + local f,err=load(cmd) + if(f) then + local ok,err=pcall(f) + if(not ok) then + modem.send(snd,99,"CallError: " .. res) else - modem.send(snd,99,cmdresult) + modem.send(snd,99,res) end - end) - if(not ok) then - modem.send(snd,99,"Command Execute Failed: " .. err) + else + modem.send(snd,99,"SyntaxError: " .. err) end end end) while true do local max_wait,max_id=math.huge,0 for i,v in ipairs(wake_list) do - if(v.tm1 do sleep(t) end + end return drone_lib_version .. " successfully installed." ]==] function helper.install_step2() @@ -135,7 +139,7 @@ function helper.install_step2() SetResponse("[Local] Install step 2: About to perform installation on " .. helper.target_drone) os.sleep(1) SetResponse("[Local] Install step 2: Sending data to " .. helper.target_drone) - modem.send(helper.target_drone,98,helper.drone_lib) + modem.send(helper.target_drone,98,"execute_command",helper.drone_lib) end end diff --git a/programs/drone/drone_flash.lua b/programs/drone/drone_flash.lua new file mode 100644 index 0000000..9c2ea84 --- /dev/null +++ b/programs/drone/drone_flash.lua @@ -0,0 +1,44 @@ +-- Drone Flash +-- Created by Kiritow +local component=require('component') +local shrink=require('shrink') +require('libevent') +print("Please insert new eeprom. (Or press Ctrl+C if the eeprom is already inserted.)") +while true do + local e=WaitMultipleEvent("interrupted","component_added") + if(e.event=="interrupted" or (e.event=="component_added" and e.componentType=="eeprom")) then + break + end +end +print("[Working] Reading drone bios from disk...") +local f=io.open("drone_bios.lua","r") +if(not f) then + print("[Error] Unable to open drone_bios.lua.") + return +end +local data=f:read("a") +f:close() +print("Original data size: " .. string.len(data)) +print("[Working] Syntax checking...") +local xt={} +local fn,err=load(data,"DroneBios","t",xt) +if(not fn) then + print("Found syntax error: " .. err) + return +end +print("[Working] Getting DroneBios version...") +pcall(fn) +local drone_bios_version=xt['drone_version'] +if(not drone_bios_version) then + print("[Error] Unable to get version tag.") + return +end +print("Version tag: " .. drone_bios_version) +print("[Working] Shrinking...") +data=shrink(data) +print("Shrank data size: " .. string.len(data)) +print("[Working] Writing to eeprom...") +component.eeprom.set(data) +print("[Working] Setting eeprom label...") +component.eeprom.setLabel(drone_bios_version) +print("[Done] Remember to insert the original eeprom!") \ No newline at end of file diff --git a/programs/drone/drone_radar.lua b/programs/drone/drone_radar.lua new file mode 100644 index 0000000..5605871 --- /dev/null +++ b/programs/drone/drone_radar.lua @@ -0,0 +1,105 @@ +-- Drone Radar +-- Created by Kiritow. +local component=require('component') +local computer=require('computer') +local term=require('term') +local text=require('text') + +require("libevent") + +local radar_version="Drone Radar v0.1.3" +local modem=component.modem +local gpu=term.gpu() + +local function status(msg) + local w,h=gpu.getResolution() + gpu.set(1,h,"Status: " .. msg) +end + +term.clear() +print("Drone Radar") +print("Checking hardware...") +if(modem==nil) then + print("This program requires a modem component to work") + return +end +print("Opening modem port...") +if(not modem.open(99)) then + if(modem.isOpen(99)) then + print("Port 99 is already opened.") + else + print("Unable to open port 99.") + return + end +end +print("Adding timer...") +local broadcast_intv=8 +local timer=AddTimer(broadcast_intv,function() + modem.broadcast(98,"execute_command","modem.send('" .. modem.address .. "',99,'radar_info',drone.getOffset(),computer.energy())") +end,-1) +print("Adding listener...") +local tb_drone={} +local listener=AddEventListener("modem_message",function(e) + if(e.port==99 and e.data[1]=='radar_info') then + tb_drone[e.senderAddress]={ + distance=e.distance, + offset=e.data[2], + energy=e.data[3], + update=computer.uptime() + } + PushEvent("radar_gui_update") + end +end) + +local function show_tb(tb) + local maxLen={} + for idx,v in ipairs(tb) do + for nidx,val in ipairs(v) do + if(not maxLen[nidx] or maxLen[nidx]broadcast_intv*2.5) then + tb_drone[addr]=nil + end + end + show_tb(show) + local e=WaitMultipleEvent("interrupted","radar_gui_update") + if(e.event=="interrupted") then break end +end + +term.clear() +print("Stopping listener...") +RemoveEventListener(listener) +print("Stopping timer...") +RemoveTimer(timer) +print("Closing port...") +modem.close(99) \ No newline at end of file