Last active
November 6, 2025 11:49
-
-
Save drucifer-sc/6c2388a125092b8037e93e941ee8c21e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| -- 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