This is a read-only snapshot of the ComputerCraft forums,
taken in April 2020.
Wireless Towers
Started by johnnic, 11 December 2013 - 09:38 PMPosted 11 December 2013 - 10:38 PM
I would like to suggest adding a wireless tower which would listen for all wireless signals within the wireless modem range. It would transmit the signal to all other wireless towers that are possibly using the same ID or are linked. It could be a standalone block, or a peripheral.
Posted 11 December 2013 - 10:41 PM
…or you could code it yourself. This is already possible to create in-game with some clever programming.
Posted 11 December 2013 - 11:27 PM
Yep. Here is some very minimalistic code to get your ideas flowing (done with Rednet - you could do this with the Modem API as well)
log = fs.open("file name for a running log", "a")
rednet.open("side i think you know how to do this")
local _, m = rednet.receive()
rednet.broadcast(m) --# You could also rednet.send() to certain towers, or with a for loop to a list of other towers.
log.write(m)
log.flush
Note that I'm not great on my syntax - I'm feeling a little lazy. So don't guarantee that working - it's just a basic idea.Edited on 11 December 2013 - 10:28 PM
Posted 12 December 2013 - 12:56 AM
You'd want to rebroadcast the message in a specific way so two towers don't simply repeat messages between each other, but yeah this should be possible with some smart programming.
Edit: Oh, and you'll need the receiver to ignore repeated messages as multiple towers in range repeat the message.
Edit: Oh, and you'll need the receiver to ignore repeated messages as multiple towers in range repeat the message.
Edited on 11 December 2013 - 11:58 PM
Posted 12 December 2013 - 01:20 AM
As distantcam stated you'll want to avoid message propagation. I'd say that the easiest method for this would be to implement a UUID (for example computer id and some incremental number) in the message which is stored in a table at each node. This is then checked and if present it does not relay the message.
Assuming the latest version of ComputerCraft you could do the following (making use of Rednet API for simplicity of code examples, Modem API could also be used)
As you can see from very simple examples above this task is not a difficult one to complete! And if you're running an older version of ComputerCraft requires a few extra steps of serialising and unserialising the rednet messages (as they were needed to be strings in older versions)
Assuming the latest version of ComputerCraft you could do the following (making use of Rednet API for simplicity of code examples, Modem API could also be used)
Sender Code
rednet.open("left")
local nextId = 0
local compId = os.getComputerID()
local function sendMessage(message)
local uuid = string.format("%d:%d", compId, nextId)
rednet.broadcast({uuid = uuid; content = message})
nextId = nextId + 1
end
sendMessage("Hello World!")
Repeater Code
rednet.open("left")
local prevMessages = {}
local function rebroadcast(msg)
--# check that the message was a table and it has the uuid field
if type(msg) ~= "table" or not msg.uuid then
return false --# it didn't lets just ignore the message
end
--# check if the message has been handled before
if not prevMessages[msg.uuid] then
prevMessages[msg.uuid] = true --# mark it as received
rednet.broadcast(msg)
return true --# it was handled this time!
end
return false
end
while true do
local _, msg = rednet.receive()
rebroadcast(msg)
end
Receiver Code
rednet.open("left")
local prevMessages = {}
local function processMessage(msg)
--# make sure that it is a valid message that we just received
if type(msg) == "table" and msg.uuid and not prevMessages[msg.uuid] then
prevMessages[msg.uuid] = true
--# perform whatever else you want to on the message here, you've not seen this message before
end
end
while true do
local _, msg = rednet.receive()
processMessage(msg)
end
As you can see from very simple examples above this task is not a difficult one to complete! And if you're running an older version of ComputerCraft requires a few extra steps of serialising and unserialising the rednet messages (as they were needed to be strings in older versions)
Edited on 12 December 2013 - 01:30 AM
Posted 12 December 2013 - 02:24 AM
--# check that the message was a table and it has the uuid field if type(msg) ~= "table" and not msg.uuid then
I think you want an "or" there, not an "and". Didn't quite De Morgan properly.
Posted 12 December 2013 - 02:30 AM
Whoops, yeh thanks. It was originally a different statement, forgot to swap it.I think you want an "or" there, not an "and". Didn't quite De Morgan properly.
Posted 12 December 2013 - 07:16 PM
You'd want to rebroadcast the message in a specific way so two towers don't simply repeat messages between each other, but yeah this should be possible with some smart programming.
Edit: Oh, and you'll need the receiver to ignore repeated messages as multiple towers in range repeat the message.
As distantcam stated you'll want to avoid message propagation. I'd say that the easiest method for this would be to implement a UUID (for example computer id and some incremental number) in the message which is stored in a table at each node. This is then checked and if present it does not relay the message.
Assuming the latest version of ComputerCraft you could do the following (making use of Rednet API for simplicity of code examples, Modem API could also be used)Sender Code
rednet.open("left") local nextId = 0 local compId = os.getComputerID() local function sendMessage(message) local uuid = string.format("%d:%d", compId, nextId) rednet.broadcast({uuid = uuid; content = message}) nextId = nextId + 1 end sendMessage("Hello World!")
Repeater Code
rednet.open("left") local prevMessages = {} local function rebroadcast(msg) --# check that the message was a table and it has the uuid field if type(msg) ~= "table" or not msg.uuid then return false --# it didn't lets just ignore the message end --# check if the message has been handled before if not prevMessages[msg.uuid] then prevMessages[msg.uuid] = true --# mark it as received rednet.broadcast(msg) return true --# it was handled this time! end return false end while true do local _, msg = rednet.receive() rebroadcast(msg) end
Receiver Code
rednet.open("left") local prevMessages = {} local function processMessage(msg) --# make sure that it is a valid message that we just received if type(msg) == "table" and msg.uuid and not prevMessages[msg.uuid] then prevMessages[msg.uuid] = true --# perform whatever else you want to on the message here, you've not seen this message before end end while true do local _, msg = rednet.receive() processMessage(msg) end
As you can see from very simple examples above this task is not a difficult one to complete! And if you're running an older version of ComputerCraft requires a few extra steps of serialising and unserialising the rednet messages (as they were needed to be strings in older versions)
I did include a comment in my code for this purpose.
Posted 12 December 2013 - 07:42 PM
I did include a comment in my code for this purpose.
Yeah, but a hard-coded whitelist would mean the code is not reusable, and a pain to set up on lots of towers.
Posted 12 December 2013 - 07:43 PM
It wasn't stated explicitly enough. You stated that rednet.send could be used, but not the benefit of doing so, also using that method would be annoying 'cause you'd need to do 1 of 2 things:I did include a comment in my code for this purpose.
- have a different program for each tower due to the different towers it has in range (it would also need to know where to send each message based on the target, this is a lot of manual work)
- have the same program for each tower but write a very complicated program that includes node discovery, rolling updates of RIBs, and an implementation of a routing protocol such as OSPF.
Edited on 12 December 2013 - 06:44 PM
Posted 12 December 2013 - 11:33 PM
Um, I said "Get your ideas flowing". So mine is meant to be a few-line example. Yours is still better, but it is a lot longer.