Skip to content

Instantly share code, notes, and snippets.

@drucifer-sc
Last active November 6, 2025 11:49
Show Gist options
  • Select an option

  • Save drucifer-sc/6c2388a125092b8037e93e941ee8c21e to your computer and use it in GitHub Desktop.

Select an option

Save drucifer-sc/6c2388a125092b8037e93e941ee8c21e to your computer and use it in GitHub Desktop.
-- SPDX-FileCopyrightText: 2017 Daniel Ratcliffe
--
-- SPDX-License-Identifier: LicenseRef-CCPL
--
-- Patched to add Classic Peripherals' Radio Towers by Drucifer (Discord) 10/2025
-- Find modems and radio towers
local tModems, tTowers, bAntFound = {}, {}, false
for _, sModem in ipairs(peripheral.getNames()) do
if peripheral.getType(sModem) == "modem" then
table.insert(tModems, sModem)
end
if peripheral.getType(sModem) == "radio_tower" and peripheral.call(sModem,"isValid") then
local nHeight=peripheral.call(sModem,"getHeight")
if nHeight>1 then
table.insert(tTowers, sModem)
elseif nHeight==1 then
if not bAntFound then
peripheral.call(sModem,"setFrequency",rednet.CHANNEL_REPEAT)
bAntFound=true
end
end
end
end
if #tModems == 0 then
print("No modems found.")
return
elseif #tModems == 1 then
print("1 modem found.")
else
print(#tModems .. " modems found.")
end
local function open(nChannel)
for n = 1, #tModems do
local sModem = tModems[n]
peripheral.call(sModem, "open", nChannel)
end
end
local function close(nChannel)
for n = 1, #tModems do
local sModem = tModems[n]
peripheral.call(sModem, "close", nChannel)
end
end
-- Open channels
print("0 messages repeated.")
open(rednet.CHANNEL_REPEAT)
for _,sTower in ipairs(tTowers) do
peripheral.call(sTower,"setFrequency",rednet.CHANNEL_REPEAT)
end
-- Main loop (terminate to break)
local ok, error = pcall(function()
local tReceivedMessages = {}
local tReceivedMessageTimeouts = {}
local nTransmittedMessages = 0
while true do
local sEvent, sModem, nChannel, nReplyChannel, tMessage = os.pullEvent()
if sEvent == "modem_message" then
-- Got a modem message, rebroadcast it if it's a rednet thing
if nChannel == rednet.CHANNEL_REPEAT then
if type(tMessage) == "table" and tMessage.nMessageID and tMessage.nRecipient and type(tMessage.nRecipient) == "number" then
if not tReceivedMessages[tMessage.nMessageID] then
-- Ensure we only repeat a message once
tReceivedMessages[tMessage.nMessageID] = true
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
for n = 1, #tModems do
local sOtherModem = tModems[n]
peripheral.call(sOtherModem, "transmit", rednet.CHANNEL_REPEAT, nReplyChannel, tMessage)
peripheral.call(sOtherModem, "transmit", recipient_channel, nReplyChannel, tMessage)
end
for n = 1, #tTowers do
local sTower = tTowers[n]
peripheral.call(sTower, "broadcast", textutils.serialize({nChannel,nReplyChannel,tMessage}))
end
-- Log the event
nTransmittedMessages = nTransmittedMessages + 1
local _, y = term.getCursorPos()
term.setCursorPos(1, y - 1)
term.clearLine()
if nTransmittedMessages == 1 then
print(nTransmittedMessages .. " message repeated.")
else
print(nTransmittedMessages .. " messages repeated.")
end
end
end
end
elseif sEvent == "radio_message" then
local sPayload = nChannel --Move data to appropriately named variable
local tPayload = textutils.unserialize(sPayload)
local fDistance = nReplyChannel --Currently no use for this data
nChannel, nReplyChannel, tMessage = -1, -1, {}
-- Got a radio message, rebroadcast it if it's a rednet thing
if type(tPayload) == "table" and peripheral.call(sModem,"getFrequency") == rednet.CHANNEL_REPEAT then
nChannel, nReplyChannel, tMessage = table.unpack(tPayload)
if type(tMessage) == "table" and tMessage.nMessageID and tMessage.nRecipient and type(tMessage.nRecipient) == "number" then
if not tReceivedMessages[tMessage.nMessageID] then
-- Ensure we only repeat a message once
tReceivedMessages[tMessage.nMessageID] = true
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
for n = 1, #tModems do
local sOtherModem = tModems[n]
peripheral.call(sOtherModem, "transmit", rednet.CHANNEL_REPEAT, nReplyChannel, tMessage)
peripheral.call(sOtherModem, "transmit", recipient_channel, nReplyChannel, tMessage)
end
for n = 1, #tTowers do
local sTower = tTowers[n]
peripheral.call(sTower, "broadcast", sPayload)
end
-- Log the event
nTransmittedMessages = nTransmittedMessages + 1
local _, y = term.getCursorPos()
term.setCursorPos(1, y - 1)
term.clearLine()
if nTransmittedMessages == 1 then
print(nTransmittedMessages .. " message repeated.")
else
print(nTransmittedMessages .. " messages repeated.")
end
end
end
end
elseif sEvent == "timer" then
-- Got a timer event, use it to clear the message history
local nTimer = sModem
local nMessageID = tReceivedMessageTimeouts[nTimer]
if nMessageID then
tReceivedMessageTimeouts[nTimer] = nil
tReceivedMessages[nMessageID] = nil
end
end
end
end)
if not ok then
printError(error)
end
-- Close channels
close(rednet.CHANNEL_REPEAT)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment