local api = {} local storage local save local PROTOCOL = "TURTI_DIMENSION_PROTOCOL" local RESPONSE_EVENT = PROTOCOL .. "_RESPONSE_EVENT" local RESPONSE_TIMEOUT = 3 local function openRednet() local side peripheral.find("modem", function(name, modem) if modem.isWireless() then side = name end end) if not rednet.isOpen(side) then rednet.open(side) end end local function listenerThread() openRednet() while true do local _, _, _, replyChannel, message, distance = os.pullEvent("modem_message") if type(message) == "table" and message["sProtocol"] == PROTOCOL and message["message"] then local msg = getTableFromSaveText(message["message"]) if msg.type == "dimensionRequest" then if storage.dimension and distance then rednet.send(replyChannel, getTableSaveText({ type = "dimensionResponse", dimension = storage.dimension, callId = msg.callId }), PROTOCOL) end elseif msg.type == "dimensionResponse" then storage.responses[msg.callId] = msg.dimension save() os.queueEvent(RESPONSE_EVENT) end end end end function api.hostDimension(dimension) storage.dimension = dimension save() end local function tryGetDimension() local callId = storage.currentCallId storage.currentCallId = storage.currentCallId + 1 save() rednet.broadcast(getTableSaveText({ type = "dimensionRequest", callId = callId }), PROTOCOL) local timer = os.startTimer(RESPONSE_TIMEOUT) while true do local event, arg = os.pullEvent() if event == RESPONSE_EVENT then local dimension = storage.responses[callId] storage.responses[callId] = nil save() return dimension elseif event == "timer" then if arg == timer then return nil end end end end function api.getDimension() while true do local dimension = tryGetDimension() if dimension then return dimension end end end return { name = "dimension", onSetup = function() ThreadManager.startThread( listenerThread, "dimension listener" ) end, onInitStorage = function(_storage, _save) storage = _storage save = _save if not storage.responses then storage.responses = {} storage.currentCallId = 0 end end, api = api }