mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-01-15 03:35:42 +00:00
Some bits of rednet cleanup
- Remove all the hungrarian notation in variables. Currently leaving the format of rednet messages for now, while I work out whether this counts as part of the public API or not. - Fix the "repeat" program failing with broadcast packets. This was introduced in #900, but I don't think anybody noticed. Will be more relevant when #955 is implemented though.
This commit is contained in:
parent
1cfad31a0d
commit
e16f66e128
@ -29,9 +29,9 @@ CHANNEL_REPEAT = 65533
|
|||||||
-- greater or equal to this limit wrap around to 0.
|
-- greater or equal to this limit wrap around to 0.
|
||||||
MAX_ID_CHANNELS = 65500
|
MAX_ID_CHANNELS = 65500
|
||||||
|
|
||||||
local tReceivedMessages = {}
|
local received_messages = {}
|
||||||
local tHostnames = {}
|
local hostnames = {}
|
||||||
local nClearTimer
|
local prune_received_timer
|
||||||
|
|
||||||
local function id_as_channel(id)
|
local function id_as_channel(id)
|
||||||
return (id or os.getComputerID()) % MAX_ID_CHANNELS
|
return (id or os.getComputerID()) % MAX_ID_CHANNELS
|
||||||
@ -115,10 +115,10 @@ be @{rednet.open|opened} before sending is possible.
|
|||||||
Assuming the target was in range and also had a correctly opened modem, it
|
Assuming the target was in range and also had a correctly opened modem, it
|
||||||
may then use @{rednet.receive} to collect the message.
|
may then use @{rednet.receive} to collect the message.
|
||||||
|
|
||||||
@tparam number nRecipient The ID of the receiving computer.
|
@tparam number recipient The ID of the receiving computer.
|
||||||
@param message The message to send. This should not contain coroutines or
|
@param message The message to send. This should not contain coroutines or
|
||||||
functions, as they will be converted to @{nil}.
|
functions, as they will be converted to @{nil}.
|
||||||
@tparam[opt] string sProtocol The "protocol" to send this message under. When
|
@tparam[opt] string protocol The "protocol" to send this message under. When
|
||||||
using @{rednet.receive} one can filter to only receive messages sent under a
|
using @{rednet.receive} one can filter to only receive messages sent under a
|
||||||
particular protocol.
|
particular protocol.
|
||||||
@treturn boolean If this message was successfully sent (i.e. if rednet is
|
@treturn boolean If this message was successfully sent (i.e. if rednet is
|
||||||
@ -131,41 +131,41 @@ actually _received_.
|
|||||||
|
|
||||||
rednet.send(2, "Hello from rednet!")
|
rednet.send(2, "Hello from rednet!")
|
||||||
]]
|
]]
|
||||||
function send(nRecipient, message, sProtocol)
|
function send(recipient, message, protocol)
|
||||||
expect(1, nRecipient, "number")
|
expect(1, recipient, "number")
|
||||||
expect(3, sProtocol, "string", "nil")
|
expect(3, protocol, "string", "nil")
|
||||||
-- Generate a (probably) unique message ID
|
-- Generate a (probably) unique message ID
|
||||||
-- We could do other things to guarantee uniqueness, but we really don't need to
|
-- 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
|
-- Store it to ensure we don't get our own messages back
|
||||||
local nMessageID = math.random(1, 2147483647)
|
local message_id = math.random(1, 2147483647)
|
||||||
tReceivedMessages[nMessageID] = os.clock() + 9.5
|
received_messages[message_id] = os.clock() + 9.5
|
||||||
if not nClearTimer then nClearTimer = os.startTimer(10) end
|
if not prune_received_timer then prune_received_timer = os.startTimer(10) end
|
||||||
|
|
||||||
-- Create the message
|
-- Create the message
|
||||||
local nReplyChannel = id_as_channel()
|
local reply_channel = id_as_channel()
|
||||||
local tMessage = {
|
local message_wrapper = {
|
||||||
nMessageID = nMessageID,
|
nMessageID = message_id,
|
||||||
nRecipient = nRecipient,
|
nRecipient = recipient,
|
||||||
nSender = os.getComputerID(),
|
nSender = os.getComputerID(),
|
||||||
message = message,
|
message = message,
|
||||||
sProtocol = sProtocol,
|
sProtocol = protocol,
|
||||||
}
|
}
|
||||||
|
|
||||||
local sent = false
|
local sent = false
|
||||||
if nRecipient == os.getComputerID() then
|
if recipient == os.getComputerID() then
|
||||||
-- Loopback to ourselves
|
-- Loopback to ourselves
|
||||||
os.queueEvent("rednet_message", os.getComputerID(), message, sProtocol)
|
os.queueEvent("rednet_message", os.getComputerID(), message_wrapper, protocol)
|
||||||
sent = true
|
sent = true
|
||||||
else
|
else
|
||||||
-- Send on all open modems, to the target and to repeaters
|
-- Send on all open modems, to the target and to repeaters
|
||||||
if nRecipient ~= CHANNEL_BROADCAST then
|
if recipient ~= CHANNEL_BROADCAST then
|
||||||
nRecipient = id_as_channel(nRecipient)
|
recipient = id_as_channel(recipient)
|
||||||
end
|
end
|
||||||
|
|
||||||
for _, sModem in ipairs(peripheral.getNames()) do
|
for _, modem in ipairs(peripheral.getNames()) do
|
||||||
if isOpen(sModem) then
|
if isOpen(modem) then
|
||||||
peripheral.call(sModem, "transmit", nRecipient, nReplyChannel, tMessage)
|
peripheral.call(modem, "transmit", recipient, reply_channel, message_wrapper)
|
||||||
peripheral.call(sModem, "transmit", CHANNEL_REPEAT, nReplyChannel, tMessage)
|
peripheral.call(modem, "transmit", CHANNEL_REPEAT, reply_channel, message_wrapper)
|
||||||
sent = true
|
sent = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -179,23 +179,23 @@ end
|
|||||||
--
|
--
|
||||||
-- @param message The message to send. This should not contain coroutines or
|
-- @param message The message to send. This should not contain coroutines or
|
||||||
-- functions, as they will be converted to @{nil}.
|
-- functions, as they will be converted to @{nil}.
|
||||||
-- @tparam[opt] string sProtocol The "protocol" to send this message under. When
|
-- @tparam[opt] string protocol The "protocol" to send this message under. When
|
||||||
-- using @{rednet.receive} one can filter to only receive messages sent under a
|
-- using @{rednet.receive} one can filter to only receive messages sent under a
|
||||||
-- particular protocol.
|
-- particular protocol.
|
||||||
-- @see rednet.receive
|
-- @see rednet.receive
|
||||||
-- @changed 1.6 Added protocol parameter.
|
-- @changed 1.6 Added protocol parameter.
|
||||||
function broadcast(message, sProtocol)
|
function broadcast(message, protocol)
|
||||||
expect(2, sProtocol, "string", "nil")
|
expect(2, protocol, "string", "nil")
|
||||||
send(CHANNEL_BROADCAST, message, sProtocol)
|
send(CHANNEL_BROADCAST, message, protocol)
|
||||||
end
|
end
|
||||||
|
|
||||||
--[[- Wait for a rednet message to be received, or until `nTimeout` seconds have
|
--[[- Wait for a rednet message to be received, or until `nTimeout` seconds have
|
||||||
elapsed.
|
elapsed.
|
||||||
|
|
||||||
@tparam[opt] string sProtocolFilter The protocol the received message must be
|
@tparam[opt] string protocol_filter The protocol the received message must be
|
||||||
sent with. If specified, any messages not sent under this protocol will be
|
sent with. If specified, any messages not sent under this protocol will be
|
||||||
discarded.
|
discarded.
|
||||||
@tparam[opt] number nTimeout The number of seconds to wait if no message is
|
@tparam[opt] number timeout The number of seconds to wait if no message is
|
||||||
received.
|
received.
|
||||||
@treturn[1] number The computer which sent this message
|
@treturn[1] number The computer which sent this message
|
||||||
@return[1] The received message
|
@return[1] The received message
|
||||||
@ -227,34 +227,34 @@ received.
|
|||||||
|
|
||||||
print(message)
|
print(message)
|
||||||
]]
|
]]
|
||||||
function receive(sProtocolFilter, nTimeout)
|
function receive(protocol_filter, timeout)
|
||||||
-- The parameters used to be ( nTimeout ), detect this case for backwards compatibility
|
-- The parameters used to be ( nTimeout ), detect this case for backwards compatibility
|
||||||
if type(sProtocolFilter) == "number" and nTimeout == nil then
|
if type(protocol_filter) == "number" and timeout == nil then
|
||||||
sProtocolFilter, nTimeout = nil, sProtocolFilter
|
protocol_filter, timeout = nil, protocol_filter
|
||||||
end
|
end
|
||||||
expect(1, sProtocolFilter, "string", "nil")
|
expect(1, protocol_filter, "string", "nil")
|
||||||
expect(2, nTimeout, "number", "nil")
|
expect(2, timeout, "number", "nil")
|
||||||
|
|
||||||
-- Start the timer
|
-- Start the timer
|
||||||
local timer = nil
|
local timer = nil
|
||||||
local sFilter = nil
|
local event_filter = nil
|
||||||
if nTimeout then
|
if timeout then
|
||||||
timer = os.startTimer(nTimeout)
|
timer = os.startTimer(timeout)
|
||||||
sFilter = nil
|
event_filter = nil
|
||||||
else
|
else
|
||||||
sFilter = "rednet_message"
|
event_filter = "rednet_message"
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Wait for events
|
-- Wait for events
|
||||||
while true do
|
while true do
|
||||||
local sEvent, p1, p2, p3 = os.pullEvent(sFilter)
|
local event, p1, p2, p3 = os.pullEvent(event_filter)
|
||||||
if sEvent == "rednet_message" then
|
if event == "rednet_message" then
|
||||||
-- Return the first matching rednet_message
|
-- Return the first matching rednet_message
|
||||||
local nSenderID, message, sProtocol = p1, p2, p3
|
local sender_id, message, protocol = p1, p2, p3
|
||||||
if sProtocolFilter == nil or sProtocol == sProtocolFilter then
|
if protocol_filter == nil or protocol == protocol_filter then
|
||||||
return nSenderID, message, sProtocol
|
return sender_id, message, protocol
|
||||||
end
|
end
|
||||||
elseif sEvent == "timer" then
|
elseif event == "timer" then
|
||||||
-- Return nil if we timeout
|
-- Return nil if we timeout
|
||||||
if p1 == timer then
|
if p1 == timer then
|
||||||
return nil
|
return nil
|
||||||
@ -276,34 +276,34 @@ end
|
|||||||
-- "registering" themselves before doing so (eg while offline or part of a
|
-- "registering" themselves before doing so (eg while offline or part of a
|
||||||
-- different network).
|
-- different network).
|
||||||
--
|
--
|
||||||
-- @tparam string sProtocol The protocol this computer provides.
|
-- @tparam string protocol The protocol this computer provides.
|
||||||
-- @tparam string sHostname The name this protocol exposes for the given protocol.
|
-- @tparam string hostname The name this protocol exposes for the given protocol.
|
||||||
-- @throws If trying to register a hostname which is reserved, or currently in use.
|
-- @throws If trying to register a hostname which is reserved, or currently in use.
|
||||||
-- @see rednet.unhost
|
-- @see rednet.unhost
|
||||||
-- @see rednet.lookup
|
-- @see rednet.lookup
|
||||||
-- @since 1.6
|
-- @since 1.6
|
||||||
function host(sProtocol, sHostname)
|
function host(protocol, hostname)
|
||||||
expect(1, sProtocol, "string")
|
expect(1, protocol, "string")
|
||||||
expect(2, sHostname, "string")
|
expect(2, hostname, "string")
|
||||||
if sHostname == "localhost" then
|
if hostname == "localhost" then
|
||||||
error("Reserved hostname", 2)
|
error("Reserved hostname", 2)
|
||||||
end
|
end
|
||||||
if tHostnames[sProtocol] ~= sHostname then
|
if hostnames[protocol] ~= hostname then
|
||||||
if lookup(sProtocol, sHostname) ~= nil then
|
if lookup(protocol, hostname) ~= nil then
|
||||||
error("Hostname in use", 2)
|
error("Hostname in use", 2)
|
||||||
end
|
end
|
||||||
tHostnames[sProtocol] = sHostname
|
hostnames[protocol] = hostname
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Stop @{rednet.host|hosting} a specific protocol, meaning it will no longer
|
--- Stop @{rednet.host|hosting} a specific protocol, meaning it will no longer
|
||||||
-- respond to @{rednet.lookup} requests.
|
-- respond to @{rednet.lookup} requests.
|
||||||
--
|
--
|
||||||
-- @tparam string sProtocol The protocol to unregister your self from.
|
-- @tparam string protocol The protocol to unregister your self from.
|
||||||
-- @since 1.6
|
-- @since 1.6
|
||||||
function unhost(sProtocol)
|
function unhost(protocol)
|
||||||
expect(1, sProtocol, "string")
|
expect(1, protocol, "string")
|
||||||
tHostnames[sProtocol] = nil
|
hostnames[protocol] = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Search the local rednet network for systems @{rednet.host|hosting} the
|
--- Search the local rednet network for systems @{rednet.host|hosting} the
|
||||||
@ -313,36 +313,36 @@ end
|
|||||||
-- If a hostname is specified, only one ID will be returned (assuming an exact
|
-- If a hostname is specified, only one ID will be returned (assuming an exact
|
||||||
-- match is found).
|
-- match is found).
|
||||||
--
|
--
|
||||||
-- @tparam string sProtocol The protocol to search for.
|
-- @tparam string protocol The protocol to search for.
|
||||||
-- @tparam[opt] string sHostname The hostname to search for.
|
-- @tparam[opt] string hostname The hostname to search for.
|
||||||
--
|
--
|
||||||
-- @treturn[1] { number }|nil A list of computer IDs hosting the given
|
-- @treturn[1] { number }|nil A list of computer IDs hosting the given
|
||||||
-- protocol, or @{nil} if none exist.
|
-- protocol, or @{nil} if none exist.
|
||||||
-- @treturn[2] number|nil The computer ID with the provided hostname and protocol,
|
-- @treturn[2] number|nil The computer ID with the provided hostname and protocol,
|
||||||
-- or @{nil} if none exists.
|
-- or @{nil} if none exists.
|
||||||
-- @since 1.6
|
-- @since 1.6
|
||||||
function lookup(sProtocol, sHostname)
|
function lookup(protocol, hostname)
|
||||||
expect(1, sProtocol, "string")
|
expect(1, protocol, "string")
|
||||||
expect(2, sHostname, "string", "nil")
|
expect(2, hostname, "string", "nil")
|
||||||
|
|
||||||
-- Build list of host IDs
|
-- Build list of host IDs
|
||||||
local tResults = nil
|
local results = nil
|
||||||
if sHostname == nil then
|
if hostname == nil then
|
||||||
tResults = {}
|
results = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Check localhost first
|
-- Check localhost first
|
||||||
if tHostnames[sProtocol] then
|
if hostnames[protocol] then
|
||||||
if sHostname == nil then
|
if hostname == nil then
|
||||||
table.insert(tResults, os.getComputerID())
|
table.insert(results, os.getComputerID())
|
||||||
elseif sHostname == "localhost" or sHostname == tHostnames[sProtocol] then
|
elseif hostname == "localhost" or hostname == hostnames[protocol] then
|
||||||
return os.getComputerID()
|
return os.getComputerID()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if not isOpen() then
|
if not isOpen() then
|
||||||
if tResults then
|
if results then
|
||||||
return table.unpack(tResults)
|
return table.unpack(results)
|
||||||
end
|
end
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
@ -350,8 +350,8 @@ function lookup(sProtocol, sHostname)
|
|||||||
-- Broadcast a lookup packet
|
-- Broadcast a lookup packet
|
||||||
broadcast({
|
broadcast({
|
||||||
sType = "lookup",
|
sType = "lookup",
|
||||||
sProtocol = sProtocol,
|
sProtocol = protocol,
|
||||||
sHostname = sHostname,
|
sHostname = hostname,
|
||||||
}, "dns")
|
}, "dns")
|
||||||
|
|
||||||
-- Start a timer
|
-- Start a timer
|
||||||
@ -362,30 +362,28 @@ function lookup(sProtocol, sHostname)
|
|||||||
local event, p1, p2, p3 = os.pullEvent()
|
local event, p1, p2, p3 = os.pullEvent()
|
||||||
if event == "rednet_message" then
|
if event == "rednet_message" then
|
||||||
-- Got a rednet message, check if it's the response to our request
|
-- Got a rednet message, check if it's the response to our request
|
||||||
local nSenderID, tMessage, sMessageProtocol = p1, p2, p3
|
local sender_id, message, message_protocol = p1, p2, p3
|
||||||
if sMessageProtocol == "dns" and type(tMessage) == "table" and tMessage.sType == "lookup response" then
|
if message_protocol == "dns" and type(message) == "table" and message.sType == "lookup response" then
|
||||||
if tMessage.sProtocol == sProtocol then
|
if message.sProtocol == protocol then
|
||||||
if sHostname == nil then
|
if hostname == nil then
|
||||||
table.insert(tResults, nSenderID)
|
table.insert(results, sender_id)
|
||||||
elseif tMessage.sHostname == sHostname then
|
elseif message.sHostname == hostname then
|
||||||
return nSenderID
|
return sender_id
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
elseif event == "timer" and p1 == timer then
|
||||||
-- Got a timer event, check it's the end of our timeout
|
-- Got a timer event, check it's the end of our timeout
|
||||||
if p1 == timer then
|
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
if results then
|
||||||
if tResults then
|
return table.unpack(results)
|
||||||
return table.unpack(tResults)
|
|
||||||
end
|
end
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
local bRunning = false
|
local started = false
|
||||||
|
|
||||||
--- Listen for modem messages and converts them into rednet messages, which may
|
--- Listen for modem messages and converts them into rednet messages, which may
|
||||||
-- then be @{receive|received}.
|
-- then be @{receive|received}.
|
||||||
@ -393,51 +391,51 @@ local bRunning = false
|
|||||||
-- This is automatically started in the background on computer startup, and
|
-- This is automatically started in the background on computer startup, and
|
||||||
-- should not be called manually.
|
-- should not be called manually.
|
||||||
function run()
|
function run()
|
||||||
if bRunning then
|
if started then
|
||||||
error("rednet is already running", 2)
|
error("rednet is already running", 2)
|
||||||
end
|
end
|
||||||
bRunning = true
|
started = true
|
||||||
|
|
||||||
while bRunning do
|
while true do
|
||||||
local sEvent, p1, p2, p3, p4 = os.pullEventRaw()
|
local event, p1, p2, p3, p4 = os.pullEventRaw()
|
||||||
if sEvent == "modem_message" then
|
if event == "modem_message" then
|
||||||
-- Got a modem message, process it and add it to the rednet event queue
|
-- Got a modem message, process it and add it to the rednet event queue
|
||||||
local sModem, nChannel, nReplyChannel, tMessage = p1, p2, p3, p4
|
local modem, channel, reply_channel, message = p1, p2, p3, p4
|
||||||
if nChannel == id_as_channel() or nChannel == CHANNEL_BROADCAST then
|
if channel == id_as_channel() or channel == CHANNEL_BROADCAST then
|
||||||
if type(tMessage) == "table" and type(tMessage.nMessageID) == "number"
|
if type(message) == "table" and type(message.nMessageID) == "number"
|
||||||
and tMessage.nMessageID == tMessage.nMessageID and not tReceivedMessages[tMessage.nMessageID]
|
and message.nMessageID == message.nMessageID and not received_messages[message.nMessageID]
|
||||||
and ((tMessage.nRecipient and tMessage.nRecipient == os.getComputerID()) or nChannel == CHANNEL_BROADCAST)
|
and ((message.nRecipient and message.nRecipient == os.getComputerID()) or channel == CHANNEL_BROADCAST)
|
||||||
and isOpen(sModem)
|
and isOpen(modem)
|
||||||
then
|
then
|
||||||
tReceivedMessages[tMessage.nMessageID] = os.clock() + 9.5
|
received_messages[message.nMessageID] = os.clock() + 9.5
|
||||||
if not nClearTimer then nClearTimer = os.startTimer(10) end
|
if not prune_received_timer then prune_received_timer = os.startTimer(10) end
|
||||||
os.queueEvent("rednet_message", tMessage.nSender or nReplyChannel, tMessage.message, tMessage.sProtocol)
|
os.queueEvent("rednet_message", message.nSender or reply_channel, message.message, message.sProtocol)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
elseif sEvent == "rednet_message" then
|
elseif event == "rednet_message" then
|
||||||
-- Got a rednet message (queued from above), respond to dns lookup
|
-- Got a rednet message (queued from above), respond to dns lookup
|
||||||
local nSenderID, tMessage, sProtocol = p1, p2, p3
|
local sender, message, protocol = p1, p2, p3
|
||||||
if sProtocol == "dns" and type(tMessage) == "table" and tMessage.sType == "lookup" then
|
if protocol == "dns" and type(message) == "table" and message.sType == "lookup" then
|
||||||
local sHostname = tHostnames[tMessage.sProtocol]
|
local hostname = hostnames[message.sProtocol]
|
||||||
if sHostname ~= nil and (tMessage.sHostname == nil or tMessage.sHostname == sHostname) then
|
if hostname ~= nil and (message.sHostname == nil or message.sHostname == hostname) then
|
||||||
rednet.send(nSenderID, {
|
send(sender, {
|
||||||
sType = "lookup response",
|
sType = "lookup response",
|
||||||
sHostname = sHostname,
|
sHostname = hostname,
|
||||||
sProtocol = tMessage.sProtocol,
|
sProtocol = message.sProtocol,
|
||||||
}, "dns")
|
}, "dns")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
elseif sEvent == "timer" and p1 == nClearTimer then
|
elseif event == "timer" and p1 == prune_received_timer then
|
||||||
-- Got a timer event, use it to clear the event queue
|
-- Got a timer event, use it to prune the set of received messages
|
||||||
nClearTimer = nil
|
prune_received_timer = nil
|
||||||
local nNow, bHasMore = os.clock(), nil
|
local now, has_more = os.clock(), nil
|
||||||
for nMessageID, nDeadline in pairs(tReceivedMessages) do
|
for message_id, deadline in pairs(received_messages) do
|
||||||
if nDeadline <= nNow then tReceivedMessages[nMessageID] = nil
|
if deadline <= now then received_messages[message_id] = nil
|
||||||
else bHasMore = true end
|
else has_more = true end
|
||||||
end
|
end
|
||||||
nClearTimer = bHasMore and os.startTimer(10)
|
prune_received_timer = has_more and os.startTimer(10)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -59,7 +59,8 @@ end
|
|||||||
-- @treturn Redirect The current terminal redirect
|
-- @treturn Redirect The current terminal redirect
|
||||||
-- @since 1.6
|
-- @since 1.6
|
||||||
-- @usage
|
-- @usage
|
||||||
-- Create a new @{window} which draws to the current redirect target
|
-- Create a new @{window} which draws to the current redirect target.
|
||||||
|
--
|
||||||
-- window.create(term.current(), 1, 1, 10, 10)
|
-- window.create(term.current(), 1, 1, 10, 10)
|
||||||
term.current = function()
|
term.current = function()
|
||||||
return redirectTarget
|
return redirectTarget
|
||||||
|
@ -14,10 +14,6 @@ else
|
|||||||
print(#tModems .. " modems found.")
|
print(#tModems .. " modems found.")
|
||||||
end
|
end
|
||||||
|
|
||||||
local function idAsChannel(id)
|
|
||||||
return (id or os.getComputerID()) % rednet.MAX_ID_CHANNELS
|
|
||||||
end
|
|
||||||
|
|
||||||
local function open(nChannel)
|
local function open(nChannel)
|
||||||
for n = 1, #tModems do
|
for n = 1, #tModems do
|
||||||
local sModem = tModems[n]
|
local sModem = tModems[n]
|
||||||
@ -53,11 +49,16 @@ local ok, error = pcall(function()
|
|||||||
tReceivedMessages[tMessage.nMessageID] = true
|
tReceivedMessages[tMessage.nMessageID] = true
|
||||||
tReceivedMessageTimeouts[os.startTimer(30)] = tMessage.nMessageID
|
tReceivedMessageTimeouts[os.startTimer(30)] = tMessage.nMessageID
|
||||||
|
|
||||||
|
local recipient_channel = tMessage.nRecipient
|
||||||
|
if tMessage.nRecipient ~= rednet.CHANNEL_BROADCAST then
|
||||||
|
recipient_channel = recipient_channel % rednet.MAX_ID_CHANNELS
|
||||||
|
end
|
||||||
|
|
||||||
-- Send on all other open modems, to the target and to other repeaters
|
-- Send on all other open modems, to the target and to other repeaters
|
||||||
for n = 1, #tModems do
|
for n = 1, #tModems do
|
||||||
local sOtherModem = tModems[n]
|
local sOtherModem = tModems[n]
|
||||||
peripheral.call(sOtherModem, "transmit", rednet.CHANNEL_REPEAT, nReplyChannel, tMessage)
|
peripheral.call(sOtherModem, "transmit", rednet.CHANNEL_REPEAT, nReplyChannel, tMessage)
|
||||||
peripheral.call(sOtherModem, "transmit", idAsChannel(tMessage.nRecipient), nReplyChannel, tMessage)
|
peripheral.call(sOtherModem, "transmit", recipient_channel, nReplyChannel, tMessage)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Log the event
|
-- Log the event
|
||||||
|
@ -88,6 +88,7 @@ describe("The rednet library", function()
|
|||||||
local fake_computer = require "support.fake_computer"
|
local fake_computer = require "support.fake_computer"
|
||||||
local debugx = require "support.debug_ext"
|
local debugx = require "support.debug_ext"
|
||||||
|
|
||||||
|
local function dawdle() while true do coroutine.yield() end end
|
||||||
local function computer_with_rednet(id, fn, options)
|
local function computer_with_rednet(id, fn, options)
|
||||||
local computer = fake_computer.make_computer(id, function(env)
|
local computer = fake_computer.make_computer(id, function(env)
|
||||||
local fns = { env.rednet.run }
|
local fns = { env.rednet.run }
|
||||||
@ -105,6 +106,10 @@ describe("The rednet library", function()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if options and options.host then
|
||||||
|
env.rednet.host("some_protocol", "host_" .. id)
|
||||||
|
end
|
||||||
|
|
||||||
return parallel.waitForAny(table.unpack(fns))
|
return parallel.waitForAny(table.unpack(fns))
|
||||||
end)
|
end)
|
||||||
local modem = fake_computer.add_modem(computer, "back")
|
local modem = fake_computer.add_modem(computer, "back")
|
||||||
@ -203,8 +208,8 @@ describe("The rednet library", function()
|
|||||||
env.sleep(10)
|
env.sleep(10)
|
||||||
|
|
||||||
-- Ensure our pending message store is empty. Bit ugly to prod internals, but there's no other way.
|
-- Ensure our pending message store is empty. Bit ugly to prod internals, but there's no other way.
|
||||||
expect(debugx.getupvalue(rednet.run, "tReceivedMessages")):same({})
|
expect(debugx.getupvalue(rednet.run, "received_messages")):same({})
|
||||||
expect(debugx.getupvalue(rednet.run, "nClearTimer")):eq(nil)
|
expect(debugx.getupvalue(rednet.run, "prune_received_timer")):eq(nil)
|
||||||
end, { open = true })
|
end, { open = true })
|
||||||
|
|
||||||
local computer_3, modem_3 = computer_with_rednet(3, nil, { open = true, rep = true })
|
local computer_3, modem_3 = computer_with_rednet(3, nil, { open = true, rep = true })
|
||||||
@ -222,5 +227,22 @@ describe("The rednet library", function()
|
|||||||
fake_computer.advance_all(computers, 10)
|
fake_computer.advance_all(computers, 10)
|
||||||
fake_computer.run_all(computers, { computer_1, computer_2 })
|
fake_computer.run_all(computers, { computer_1, computer_2 })
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it("handles lookups between computers with massive IDs", function()
|
||||||
|
local id_1, id_3 = 24283947, 93428798
|
||||||
|
local computer_1, modem_1 = computer_with_rednet(id_1, function(rednet)
|
||||||
|
local ids = { rednet.lookup("some_protocol") }
|
||||||
|
expect(ids):same { id_3 }
|
||||||
|
end, { open = true })
|
||||||
|
local computer_2, modem_2 = computer_with_rednet(2, nil, { open = true, rep = true })
|
||||||
|
local computer_3, modem_3 = computer_with_rednet(id_3, dawdle, { open = true, host = true })
|
||||||
|
fake_computer.add_modem_edge(modem_1, modem_2)
|
||||||
|
fake_computer.add_modem_edge(modem_2, modem_3)
|
||||||
|
|
||||||
|
local computers = { computer_1, computer_2, computer_3 }
|
||||||
|
fake_computer.run_all(computers, false)
|
||||||
|
fake_computer.advance_all(computers, 3)
|
||||||
|
fake_computer.run_all(computers, { computer_1 })
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
Loading…
Reference in New Issue
Block a user