OpenComputers Von Neumann Machine Programs
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

195 lines
4.8 KiB

local async = require("async")
local computer = require("computer")
local component = require("component")
local coroutine = require("coroutine")
local dns = require("dns")
local serial = require("serialization")
local table = require("table")
local string = require("string")
local modem = component.proxy(component.list("modem")())
local args = {...}
-- Take some existing modem functions and data
local net = {
addr = modem.address,
type = modem.type,
open = modem.open,
isOpen = modem.isOpen,
close = modem.close,
isWireless = modem.isWireless,
maxPacketSize = modem.maxPacketSize,
}
-- Used to determine if a string is a proper uuid
function isUUID(s)
local pattern = {8,4,4,4,12}
local t = split(s, "-")
for i, v in ipairs(t) do
if #v ~= pattern[i] or tonumber(v, 16) == nil then
return false
end
end
return true
end
-- Resolve addresses if they aren't UUIDs
function checkAddr(addr)
if not isUUID(addr) then
return dns.query(addr)
end
return addr
end
-- Close all ports
function net.closeAll()
for i = 1, 65535 do
net.close(i)
end
end
-- Strength getter and setter
function net.strength(n)
if n ~= nil then
modem.setStrength(n)
else
return modem.getStrength()
end
end
-- Wake mesage getter and setter
function net.wakeMsg(msg, fuzzy)
if msg ~= nil then
modem.setWakeMessage(msg, fuzzy)
else
return modem.getWakeMessage()
end
end
-- Send network packets
-- Auto serializes data for you
function net.send(addr, port, ...)
addr = checkAddr(addr)
local arg = table.pack(...)
for k, v in ipairs(arg) do
-- Only serialize tables
if type(v) == "table" then
arg[k] = serial.serialize(v)
end
end
modem.send(addr, port, table.unpack(arg))
end
-- Broadcast network packets
-- Auto serializes data for you
function net.broadcast(port, ...)
local arg = table.pack(...)
for k, v in ipairs(arg) do
-- Only serialize tables
if type(v) == "table" then
arg[k] = serial.serialize(v)
end
end
modem.broadcast(port, table.unpack(arg))
end
-- Custom function to receive network packets
-- Can specify a port and or address for simple filtering
-- Can also supply a filter function in addition to simple filtering
-- If port supplied, default action is to open the port for you
-- If nonblocking, uses coroutine.yield() do be prepared to handle that
function net.recv(t)
local pkt = {}
local tmp = {}
-- This allows default and keyword args
if t ~= nil then
setmetatable(t,{__index={
port = nil,
addr = nil,
fuzzy = false,
timeout = nil,
filter = nil,
open = true,
}})
local port, addr, timeout, filter, open =
t[1] or t.port,
t[2] or t.addr,
t[3] or t.timeout,
t[4] or t.filter,
t[5] or t.open
if addr ~= nil then
addr = checkAddr(addr)
end
-- Automatically open port to listen on
-- NOTE: Only works on a single port, if the filter function listens on
-- multiple you'll have to do that manually
if open and net ~= nil then net.open(port) end
----------------
-- Basic filter function used to call user defined filter functions
function f(name, ...)
-- Get rid of all non modem messages
if name ~= "modem_message" then return false end
local arg = {...}
local resAddress, resPort = arg[2], arg[3]
-- Check port is good
if port ~= nil and resPort ~= port then
return false
end
-- Check addr is good
if resAddr ~= nil and resAddr == addr then
return false
end
-- Do further filtering
if filter ~= nil then
return filter(name, ...)
else
return true
end
end
----------------
if timeout ~= nil then
tmp = {async.pullFiltered(timeout, f)}
else
tmp = {async.pullFiltered(f)}
end
end
-- Check for non-packets
if #tmp == 0 then
return nil, "timeout"
elseif tmp[1] == "interrupted" then
return nil, "interrupted"
end
-- Create basis of packet
pkt.laddr, pkt.raddr, pkt.port, pkt.distance, pkt.msg = tmp[2], tmp[3], tmp[4], tmp[5], tmp[6]
local data = {}
for i = 6, #tmp do
-- Unserialize any serialized data
if type(tmp[i]) == "string" then
status, res = pcall(serial.unserialize, tmp[i])
if status and res == nil then data[i-5] = tmp[i] else data[i-5] = res end
else
data[i-5] = tmp[i]
end
end
pkt.data = data
return pkt
end
-- wget -f http://localhost:8080/lib/net.lua /usr/lib/net.lua
-- wget -f http://mc.bashed.rocks:13699/lib/net.lua /usr/lib/net.lua
return net