Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[encryption]]--
- local chars = {}
- for i=0,9 do
- table.insert(chars,48+i)
- end
- for i=0,25 do
- table.insert(chars,65+i)
- table.insert(chars,97+i)
- end
- local key = {}
- if fs.exists("rn.key") and not fs.isDir("rn.key") then
- local f = fs.open("rn.key","r")
- f = f.readAll(),f.close()
- for c in f:gmatch(".") do
- table.insert(key,c:byte())
- end
- else
- for i=1,128 do
- table.insert(key,chars[math.random(#chars)])
- end
- local f = fs.open("rn.key","w")
- for k,v in pairs(key) do
- f.write(string.char(v))
- end f.close()
- end
- local function r()
- local res = {}
- for i=1,math.random(5,10) do
- table.insert(res,string.char(chars[math.random(#chars)]))
- end return table.concat(res)
- end
- local hex = {[0]=0,1,2,3,4,5,6,7,8,9,"A","B","C","D","E","F"}
- local floor = math.floor
- function encrypt(str)
- local i = 1
- str = r().."\1\2\3"..str
- return str:gsub(".",function(c)
- c = (c:byte() + key[i])%256
- i = i % #key + 1
- return hex[floor(c/16)]..hex[c%16]
- end)
- end
- local dec = {
- A=10,B=11,C=12,D=13,E=14,F=15
- }
- for i=0,10 do
- dec[tostring(i)] = i
- end
- function decrypt(str)
- local i = 1
- local pre,msg = str:gsub("(.)(.)",function(a,b)
- if not dec[a] then print("ERR: ",a," ",a:byte()) return end
- if not dec[b] then print("ERR: ",b," ",b:byte()) return end
- return string.char(dec[a]*16+dec[b])
- end):gsub(".",function(c)
- c = c:byte() - key[i]
- i = i % #key + 1
- return string.char(c%256)
- end):match("^(%w+)\1\2\3(.*)$")
- if not pre then return nil end
- if #pre < 5 or #pre > 10 then
- return nil
- end return msg
- end
- --[[reddernet]]--
- local rednet = rednet
- if rednet.reddernet then
- error("RedderNet already ran")
- end
- pcall(os.loadAPI,"encryption")
- local encryption = encryption
- reddernet = getfenv()
- CHANNEL_BROADCAST = rednet.CHANNEL_BROADCAST
- CHANNEL_REPEAT = rednet.CHANNEL_REPEAT
- local tReceivedMessages = {}
- local tReceivedMessageTimeouts = {}
- local tHostnames = {}
- function open( sModem )
- if type( sModem ) ~= "string" then
- error( "expected string", 2 )
- end
- if peripheral.getType( sModem ) ~= "modem" then
- error( "No such modem: "..sModem, 2 )
- end
- peripheral.call( sModem, "open", os.getComputerID() )
- peripheral.call( sModem, "open", CHANNEL_BROADCAST )
- end
- function close( sModem )
- if sModem then
- -- Close a specific modem
- if type( sModem ) ~= "string" then
- error( "expected string", 2 )
- end
- if peripheral.getType( sModem ) ~= "modem" then
- error( "No such modem: "..sModem, 2 )
- end
- peripheral.call( sModem, "close", os.getComputerID() )
- peripheral.call( sModem, "close", CHANNEL_BROADCAST )
- else
- -- Close all modems
- for n,sModem in ipairs( peripheral.getNames() ) do
- if isOpen( sModem ) then
- close( sModem )
- end
- end
- end
- end
- function isOpen( sModem )
- if sModem then
- -- Check if a specific modem is open
- if type( sModem ) ~= "string" then
- error( "expected string", 2 )
- end
- if peripheral.getType( sModem ) == "modem" then
- return peripheral.call( sModem, "isOpen", os.getComputerID() ) and peripheral.call( sModem, "isOpen", CHANNEL_BROADCAST )
- end
- else
- -- Check if any modem is open
- for n,sModem in ipairs( peripheral.getNames() ) do
- if isOpen( sModem ) then
- return true
- end
- end
- end
- return false
- end
- local encrypted = true
- function setEncrypted(bool)
- encrypted = bool
- end
- function send( nRecipient, message, sProtocol )
- -- Generate a (probably) unique message ID
- -- We could do other things to guarantee uniqueness, but we really don't need to
- -- Store it to ensure we don't get our own messages back
- local nMessageID = math.random( 1, 2147483647 )
- tReceivedMessages[ nMessageID ] = true
- tReceivedMessageTimeouts[ os.startTimer( 30 ) ] = nMessageID
- -- Create the message
- local nReplyChannel = os.getComputerID()
- local tMessage = {
- nMessageID = nMessageID,
- nRecipient = nRecipient,
- message = encrypted and encryption.encrypt(message) or message,
- sProtocol = sProtocol,
- reddernet = true,
- encrypted = encrypted
- }
- if nRecipient == os.getComputerID() then
- -- Loopback to ourselves
- os.queueEvent( "rednet_message", nReplyChannel, message, sProtocol )
- else
- -- Send on all open modems, to the target and to repeaters
- local sent = false
- for n,sModem in ipairs( peripheral.getNames() ) do
- if isOpen( sModem ) then
- peripheral.call( sModem, "transmit", nRecipient, nReplyChannel, tMessage );
- peripheral.call( sModem, "transmit", CHANNEL_REPEAT, nReplyChannel, tMessage );
- sent = true
- end
- end
- end
- end
- function broadcast( message, sProtocol )
- send( CHANNEL_BROADCAST, message, sProtocol )
- end
- function receive( sProtocolFilter, nTimeout )
- -- The parameters used to be ( nTimeout ), detect this case for backwards compatibility
- if type(sProtocolFilter) == "number" and nTimeout == nil then
- sProtocolFilter, nTimeout = nil, sProtocolFilter
- end
- -- Start the timer
- local timer = nil
- local sFilter = nil
- if nTimeout then
- timer = os.startTimer( nTimeout )
- sFilter = nil
- else
- sFilter = "rednet_message"
- end
- -- Wait for events
- while true do
- local sEvent, p1, p2, p3 = os.pullEvent( sFilter )
- if sEvent == "rednet_message" then
- -- Return the first matching rednet_message
- local nSenderID, message, sProtocol = p1, p2, p3
- if sProtocolFilter == nil or sProtocol == sProtocolFilter then
- return nSenderID, message, sProtocol
- end
- elseif sEvent == "timer" then
- -- Return nil if we timeout
- if p1 == timer then
- return nil
- end
- end
- end
- end
- function host( sProtocol, sHostname )
- if type( sProtocol ) ~= "string" or type( sHostname ) ~= "string" then
- error( "expected string, string", 2 )
- end
- if sHostname == "localhost" then
- error( "Reserved hostname", 2 )
- end
- if tHostnames[ sProtocol ] ~= sHostname then
- if lookup( sProtocol, sHostname ) ~= nil then
- error( "Hostname in use", 2 )
- end
- tHostnames[ sProtocol ] = sHostname
- end
- end
- function unhost( sProtocol )
- if type( sProtocol ) ~= "string" then
- error( "expected string", 2 )
- end
- tHostnames[ sProtocol ] = nil
- end
- function lookup( sProtocol, sHostname )
- if type( sProtocol ) ~= "string" then
- error( "expected string", 2 )
- end
- -- Build list of host IDs
- local tResults = nil
- if sHostname == nil then
- tResults = {}
- end
- -- Check localhost first
- if tHostnames[ sProtocol ] then
- if sHostname == nil then
- table.insert( tResults, os.getComputerID() )
- elseif sHostname == "localhost" or sHostname == tHostnames[ sProtocol ] then
- return os.getComputerID()
- end
- end
- if not isOpen() then
- if tResults then
- return table.unpack( tResults )
- end
- return nil
- end
- -- Broadcast a lookup packet
- broadcast( {
- sType = "lookup",
- sProtocol = sProtocol,
- sHostname = sHostname,
- }, "dns" )
- -- Start a timer
- local timer = os.startTimer( 2 )
- -- Wait for events
- while true do
- local event, p1, p2, p3 = os.pullEvent()
- if event == "rednet_message" then
- -- Got a rednet message, check if it's the response to our request
- local nSenderID, tMessage, sMessageProtocol = p1, p2, p3
- if sMessageProtocol == "dns" and tMessage.sType == "lookup response" then
- if tMessage.sProtocol == sProtocol then
- if sHostname == nil then
- table.insert( tResults, nSenderID )
- elseif tMessage.sHostname == sHostname then
- return nSenderID
- end
- end
- end
- else
- -- Got a timer event, check it's the end of our timeout
- if p1 == timer then
- break
- end
- end
- end
- if tResults then
- return table.unpack( tResults )
- end
- return nil
- end
- local function clean(str)
- if type(str) ~= "string" then return str end
- return str:gsub("[^a-zA-Z0-9]","?")
- end
- local done = setmetatable({},{__mode="k"})
- local pullRaw = coroutine.yield
- local function pull(filter)
- local hmm = {pullRaw(filter)}
- local ev = hmm[1]
- if ev == "modem_message" then
- local msg = hmm[5]
- if type(msg) == "table" and msg.reddernet and msg.encrypted then
- if done[msg] then return hmm end
- local m = msg.message
- local txt = encryption.decrypt(m)
- if not txt then return end
- msg.encryptedMessage = m
- msg.encrypted = false
- msg.message = txt
- end
- end return hmm
- end
- function os.pullEventRaw(filter)
- while true do
- local res = pull(filter)
- if res then
- return unpack(res)
- end
- end
- end
- local bRunning = false
- local function run()
- if bRunning then
- error( "reddernet is already running", 2 )
- end bRunning = true
- while bRunning do
- local sEvent, p1, p2, p3, p4 = os.pullEventRaw()
- if sEvent == "modem_message" then
- -- Got a modem message, process it and add it to the rednet event queue
- local sModem, nChannel, nReplyChannel, tMessage = p1, p2, p3, p4
- if isOpen( sModem ) and ( nChannel == os.getComputerID() or nChannel == CHANNEL_BROADCAST ) then
- if type( tMessage ) == "table" and tMessage.nMessageID then
- if not tReceivedMessages[ tMessage.nMessageID ] then
- tReceivedMessages[ tMessage.nMessageID ] = true
- tReceivedMessageTimeouts[ os.startTimer( 30 ) ] = nMessageID
- os.queueEvent( "rednet_message", nReplyChannel, tMessage.message, tMessage.sProtocol )
- end
- end
- end
- elseif sEvent == "rednet_message" then
- -- Got a rednet message (queued from above), respond to dns lookup
- local nSenderID, tMessage, sProtocol = p1, p2, p3
- if sProtocol == "dns" and tMessage.sType == "lookup" then
- local sHostname = tHostnames[ tMessage.sProtocol ]
- if sHostname and (tMessage.sHostname == nil or tMessage.sHostname == sHostname) then
- rednet.send( nSenderID, {
- sType = "lookup response",
- sHostname = sHostname,
- sProtocol = tMessage.sProtocol,
- }, "dns" )
- end
- end
- elseif sEvent == "timer" then
- -- Got a timer event, use it to clear the event queue
- local nTimer = p1
- local nMessage = tReceivedMessageTimeouts[ nTimer ]
- if nMessage then
- tReceivedMessageTimeouts[ nTimer ] = nil
- tReceivedMessages[ nMessage ] = nil
- end
- end
- end
- end
- do -- Take over rednet!
- local raw = os.pullEventRaw
- function os.pullEventRaw(ev)
- local s,e = xpcall(function()
- error("banana",4)
- end,function(e) return e end)
- if e:match("^rednet:%d+: banana$") then
- os.pullEventRaw = raw
- _G.DONE = true run()
- end return raw(ev)
- end os.queueEvent("")
- end
- for k,v in pairs(reddernet) do
- rednet[k] = v
- end
- --[[networking]]--
- --[[ Notes
- Address format: 24 bit
- -> 6 hexadecimal characters
- 16 bits 8 bits
- ABCD : EF
- Network Host
- #Networks: 65536
- #Hosts: 16777216
- #Hosts/Network: 256
- (Should definitly be plenty)
- Notations:
- Normal: 00AB:0C
- Shortened: AB:C
- Long: 00AB0C
- Simplified Long: AB0C
- (Always hexadecimal)
- --]]
- local function writeBits(tab,s,num)
- local _,bits = math.frexp(num)
- s = s - 1
- for i=bits,1,-1 do
- local v = num%2
- tab[i+s] = v
- num = (num-v)/2
- end return tab
- end
- local function fillBits(tab,n)
- for i=1,n-#tab do
- table.insert(tab,1,0)
- end return tab
- end
- local function opAnd(a,b)
- local res = {}
- for i=1,#a do
- res[i] = a[i] + b[i] == 2 and 1 or 0
- end return res
- end
- local function opOr(a,b)
- local res = {}
- for i=1,#a do
- res[i] = a[i] + b[i] > 0 and 1 or 0
- end return res
- end
- address = {
- toBit = function(str)
- local net,host = str:match("(%x+):(%x+)")
- if not net then return nil end
- net = tonumber(net,16)
- host = tonumber(host,16)
- local res = writeBits({},1,net)
- for i=1,16-#res do
- table.insert(res,1,0)
- end
- print(table.concat(res))
- writeBits(res,17,host)
- for i=1,24-#res do
- table.insert(res,17,0)
- end return res
- end;
- applyMask = function(a,b,mask)
- -- Resulting bitlist contains the
- -- bits of a where mask[i]==1 and
- -- the bits of b where mask[i]==0
- local res = {}
- for i=1,#mask do
- res[i] = a[i]
- end
- for i=#mask+1,#a do
- res[i] = b[i]
- end
- end;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement