Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Bugs :
- -- Confirmation functions dont work! This functions have something to do with confirmations :
- -- net.waitForConfirmation() -> never receives a confirmation. on each received rednet message a confirmation is sent back! so normally a confirmation should be received.
- -- net.sendConfirmation() -> i think that maybe here is the bug or the whole confirmation system is messed up -.-
- -- net.sendAndLetConfirm() -> uses both of the upper functions.
- -- net.rednet_messageEvent() -> sends for each received rednet message a confirmation back.
- -- It would be awesome if you help me :)
- rednet.open("back")
- -- In case that the user uses functions like read() or sleep() we have to eliminate the chance that this catches the terminate event
- os.pullEvent = os.pullEventRaw
- --------------------
- --[[ TOOL SECTION
- ]]
- --------------------
- --[[ Allowing Termination for the client program
- * Settingg <sys.bClientProgramAllowTermination> to <bAllowTermination>
- - Nothing.
- ]]
- function allowTermination(bAllowTermination)
- sys.bClientProgramAllowTermination = bAllowTermination
- return
- end
- --[[ Asking the user for a computername.
- * Setting the computerlabel to the input.
- - The entered computername <sComputerName>.
- ]]
- function askForComputerName()
- write("Please enter a computername : ")
- os.setComputerLabel(read())
- term.clear()
- term.setCursorPos(1,1)
- return os.getComputerLabel()
- end
- ------------------------
- --[[ SHARED VARIABLES
- ]]
- ------------------------
- -- In t_bLoopEventCheckingInstancesWorking the working status of each instance of loopEventChecking() is saved.
- t_bLoopEventCheckingInstancesWorking = {}
- -- In sys are two Variables for termination handling saved :
- sys = {}
- -- sys.bClientProgramAllowTermination saves the state of allowing termination of the client program.
- sys.bClientProgramAllowTermination = true
- -- sys.bClientProgramTerminate saves the state of terminating the client program.
- sys.bClientProgramTerminate = false
- -- comp saves variables about this computer
- comp = {}
- comp.nID = os.getComputerID()
- comp.sName = os.getComputerLabel() or askForComputerName()
- comp.bRednetOpen = true
- -----------------------------
- --[[ VARIABLE SUPPLY LEVEL
- ]]
- -----------------------------
- vars = {}
- -- vars.tVariables saves all Variables that are used for sharing variables between the event checking loop and the user program.
- vars.tVariables = {}
- --[[ Creating a variable section with the name <sName> in the shared variables.
- * Creating a table in <vars.tVariables> with the key <sName>.
- - <true> if the section was created; <false> if not.
- ]]
- function vars.createVariableSection(sName)
- if not vars.tVariables[sName] then
- vars.tVariables[sName] = {}
- return true
- end
- return false
- end
- --[[ Creating a variable with the name <sVariableName> in the section <sSectionName>.
- * Creating a table for the variable <sVariableName> in <vars.tVariables[sSectionName] with the key <sVariableName>.
- - <true> if the variable was created; <false> if not.
- ]]
- function vars.createVariable(sSectionName, sVariableName, vDefaultValue)
- if not vars.tVariables[sSectionName] then
- if not vars.createVariableSection(sSectionName) then
- return false
- end
- end
- if not vars.tVariables[sSectionName][sVariableName] then
- vars.tVariables[sSectionName][sVariableName] = {
- bChanged = false,
- vDefaultValue = vDefaultValue,
- vValue = vDefaultValue
- }
- return true
- end
- return false
- end
- --[[ Removing the variable section with the name <sSectionName> from the shared variables.
- * Removing the table with the key <sSectionName> in <vars.tVariables>.
- - <true> if the section was deleted; <false> if not.
- ]]
- function vars.removeVariableSection(sSectionName)
- if vars.tVariables[sSectionName] then
- vars.tVariables[sSectionName] = nil
- return true
- end
- return false
- end
- --[[ Removing the variable <sVariableName> from the section <sSectionName> from the shared variables.
- * Setting the variable <sVariableName> in the section <sSectionName> in the shared variables to <nil>.
- - <true> if variable could be removed; <false> if not.
- ]]
- function vars.removeVariable(sSectionName, sVariableName)
- if vars.tVariables[sSectionName] then
- if vars.tVariables[sSectionName][sVariableName] then
- vars.tVariables[sSectionName][sVariableName] = nil
- return true
- end
- end
- return false
- end
- --[[ Resetting the variable <sVariableName> in the section <sSectionName> to its default value.
- * Setting the <bChanged> of the variable to <true> and setting <vValue> of the variable to <vDefaultValue> from the variable.
- - <true> if the variable could be resetted; <false> if not.
- ]]
- function vars.resetVariable(sSectionName, sVariableName)
- if vars.tVariables[sSectionName] and vars.tVariables[sSectionName][sVariableName] then
- vars.tVariables[sSectionName][sVariableName].bChanged = false
- vars.tVariables[sSectionName][sVariableName].vValue = vars.tVariables[sSectionName][sVariableName].vDefaultValue
- return true
- end
- return false
- end
- --[[ Setting the existing variable <sVariableName> from the section <sSectionName> to <vValue>
- * Setting <vValue> from the variable <sVariableName> to <vValue>.
- - <true> if the variable could be set; <false> if not.
- ]]
- function vars.setVariable(sSectionName, sVariableName, vValue)
- if vars.tVariables[sSectionName] and vars.tVariables[sSectionName][sVariableName] then
- vars.tVariables[sSectionName][sVariableName].bChanged = true
- vars.tVariables[sSectionName][sVariableName].vValue = vValue
- return true
- end
- return false
- end
- --[[ Getting the variable <sVariableName> from the section <sSectionName>.
- * If <bLoopUntilChanged> is <true> the function will wait until <bChanged> of the variable is <true> and then return <vValue> of the variable.
- - The <vValue> of the variable : <vValue>
- ]]
- function vars.getVariable(sSectionName, sVariableName, bLoopUntilChanged)
- if bLoopUntilChanged then
- while not vars.tVariables[sSectionName][sVariableName].bChanged do
- os.sleep(0.1)
- end
- return vars.tVariables[sSectionName][sVariableName].vValue
- else
- return vars.tVariables[sSectionName][sVariableName].vValue
- end
- end
- --debug
- function show(var, ebene)
- local ebene = ebene or 1
- local str = ""
- for i = 1, ebene do
- str = str.." "
- end
- for k,v in pairs(var) do
- if type(v) == "table" then
- print(str..k..": table :")
- show(v, ebene + 1)
- print(str..k..": table end.")
- else
- print(str..k.." : "..tostring(v))
- end
- end
- end
- ---------------------
- --[[ EVENT SECTION
- The concept of this api :
- Base : Checks all the time for events.
- Net : A messaging API
- Shell : A normal shell, in that can be entered which program should be run.
- Program : All programs wihch path are entered in the shell can use the Base functions.
- ]]
- ---------------------
- -- In t_fEventHandler all EventHandler are saved.
- t_fEventHandler = {}
- --[[ Getting the working status for the instance <nInstance> of loopEventChecking()
- * Returning the value of the entry <nInstance> of the table <t_bLoopEventCheckingInstancesWorking>.
- - The working Status <bWorking>.
- ]]
- function getInstanceWorkingStatus(nInstance)
- return t_bLoopEventCheckingInstancesWorking[nInstance]
- end
- --[[ Checking in an endless loop for all events.
- * If an event occurs it checks if there is an EventHandler for it and if so it calls it with all parameters of the event.
- - Nothing.
- ]]
- function loopEventChecking()
- --var
- local nThisInstance = #t_bLoopEventCheckingInstancesWorking + 1
- local sEvent, par1, par2, par3 = "", nil, nil, nil
- --localfunc
- local function setInstanceWorkingStatus(nInstance, bWorking)
- t_bLoopEventCheckingInstancesWorking[nInstance] = bWorking
- return
- end
- local function callEventHandler()
- t_fEventHandler[sEvent](par1, par2, par3)
- while getInstanceWorkingStatus(nThisInstance + 1) do
- sleep(0.1)
- end
- end
- --begin
- setInstanceWorkingStatus(nThisInstance, false)
- while true do
- sEvent, par1, par2, par3 = os.pullEventRaw()
- if t_fEventHandler[sEvent] then
- setInstanceWorkingStatus(nThisInstance, true)
- parallel.waitForAny(loopEventChecking, callEventHandler)
- setInstanceWorkingStatus(nThisInstance, false)
- end
- end
- end
- -- EventHandler --
- --[[ terminate : - - -
- * Setting <sys.bClientProgramTerminate> if termination in <sys.bClientProgramAllowTermination> is allowed.
- ]]
- t_fEventHandler["terminate"] = function()
- if sys.bClientProgramAllowTermination then
- sys.bClientProgramTerminate = true
- end
- end
- --[[ timer : tTimerID - -
- * overgiving the timer identification to timer.timerEvent().
- ]]
- t_fEventHandler["timer"] = function(tTimerID)
- timer.timerEvent(tTimerID)
- end
- --[[ rednet_message : nSenderID sMessage nDistance
- * Overgiving <nSenderID>, <sMessage and <nDistance> to net.rednet_MessageEvent()
- ]]
- t_fEventHandler["rednet_message"] = function(nSenderID, sMessage, nDistance)
- net.rednet_messageEvent(nSenderID, sMessage, nDistance)
- end
- ---------------------
- --[[ TIMER SECTION
- ]]
- ---------------------
- timer = {}
- -- timer.t_fTimerFunctions saves all TimerFunctions
- timer.t_fTimerFunctions = {}
- -- Timer Function Tools --
- --[[ Adding the timerfunction <fTimerFunction> to the timerfunction list.
- * Adds the function <fTimerFunction> to <timer.t_fTimerFunctions> with the key <tTimerID>.
- - <true> if timerfunction could be added; <false> if not.
- ]]
- function timer.addTimerFunction(tTimerID, fTimerFunction)
- if not timer.t_fTimerFunctions[tTimerID] then
- timer.t_fTimerFunctions[tTimerID] = fTimerFunction
- return true
- end
- return false
- end
- --[[ Removing the timerfunction for the timerID <tTimerID> from the timerfunction list.
- * Removing the timerfunction with the key <tTimerID> from the timerfunction table <timer.t_fTimerFunctions>.
- - <true> if timerfunction could be removed; <false> if not.
- ]]
- function timer.removeTimerFunction(tTimerID)
- if timer.t_fTimerFunctions[tTimerID] then
- timer.t_fTimerFunctions[tTimerID] = nil
- return true
- end
- return false
- end
- --[[ Creating a timeout for the time of <nTimeout> secs. The function that is going to be called is <fTimeoutFunction>.
- * Adding the function <fTimeoutFunction> to the timerfunction list and starting a timer.
- - If the timer could be created the timerID <tTimerID>; <false> if not.
- ]]
- function timer.timeout(nTimeout, fTimeoutFunction)
- if nTimeout > 0 then
- local tTimerID = os.startTimer(nTimeout)
- timer.addTimerFunction(tTimerID, fTimeoutFunction)
- return tTimerID
- end
- return false
- end
- -- Timer Event Handling --
- --[[ Calling timerfunctions.
- * Checking if the timer with the ID <tTimerID> is in the timerfunction list, if so call the timerfunction.
- - Nothing.
- ]]
- function timer.timerEvent(tTimerID)
- if timer.t_fTimerFunctions[tTimerID] then
- timer.t_fTimerFunctions[tTimerID](tTimerID)
- timer.removeTimerFunction(tTimerID)
- end
- return
- end
- --------------------
- --[[ NET SECTIONS
- ]]
- --------------------
- net = {}
- -- net.t_fSocketFunctions saves all SocketFunctions
- net.t_fSocketFunctions = {}
- -- net.t_tComputerList saves the computers in reach.
- net.t_tComputerList = {}
- --net.t_tConnectionList saves all connections for this computer
- net.t_tConnectionList = {}
- --net.t_tForwardingList saves all forwardings for this
- net.t_tForwardingList = {}
- -- Socket Function Tools --
- --[[ Socketfunction adding.
- * Adds the function <fSocketFunction> for the socket <sSocket> to the SocketFunction table.
- - <true> if SocketFunction could be added; else <false>.
- ]]
- function net.addSocketFunction(sSocket, fSocketFunction)
- if not net.t_fSocketFunctions[sSocket] then
- net.t_fSocketFunctions[sSocket] = fSocketFunction
- return true
- end
- return false
- end
- --[[ Socketfunction removing.
- * Removes the Socketfunction for the socket <sSocket> from the SocketFunction table.
- - <true> if SocketFunction could be removed; else <false>.
- ]]
- function net.removeSocketFunction(sSocket)
- if net.t_fSocketFunctions[sSocket] then
- net.t_fSocketFunctions[sSocket] = nil
- return true
- end
- return false
- end
- -- Message Tools --
- --[[ Unzip a rednet message.
- * Returns the unpacked table that is created from ser.deserialize() with the raw rednet message <sRawMessage>
- - All Variables unpacked.
- ]]
- function net.processMessage(sRawMessage)
- return unpack(textutils.unserialize(sRawMessage))
- end
- --[[ Preparing a rednet message for normal sending.
- * Merging <sSocket>, <sRawMessage> and <tStations> with ser.serialize() in a string.
- - The prepared message <sMessage> that is ready for sending.
- ]]
- function net.prepareMessage(sSocket, sRawMessage, tStations)
- local tStations = tStations
- if not tStations then
- tStations = {}
- table.insert(tStations, {sName = comp.sName, nID = comp.nID})
- end
- return textutils.serialize({sSocket, sRawMessage, tStations})
- end
- --[[ Preparing a rednet message for forwarding.
- * Merging <nNextForwardingID>, <sRealSocket>, <sRealMessage> with ser.serialize() in a string.
- - The prepared message <sMessage> that is ready for sending.
- ]]
- function net.prepareForwardingMessage(nNextForwardingID, sRealSocket, sRealMessage)
- return textutils.serialize({nNextForwardingID, sRealSocket, sRealMessage})
- end
- -- Rednet Message Event Handling --
- --[[ Socketfunction calling.
- * Unzips received rednet messages. Adds this station. Calls the socketfunction if there is one.
- - Nothing.
- ]]
- function net.rednet_messageEvent(nSenderID, sRawMessage, nDistance)
- local sSocket, sMessage, tStations = net.processMessage(sRawMessage)
- table.insert(tStations, {["nID"] = comp.nID, ["sName"] = comp.sName, ["nDistanceFromLast"] = nDistance})
- if net.t_fSocketFunctions[sSocket] then
- net.sendConfirmation(tStations[#tStations - 1].nID, sSocket)
- net.t_fSocketFunctions[sSocket](sSocket, sMessage, tStations)
- end
- return
- end
- -- Listen function --
- --[[ Listening for the timeout <nTimeout> in secs on the socket <sSocket>.
- * Creating a timeout with timer.timeout() and create a socketfunction for the socket <sSocket>.
- - "timed out" if the timeout was reached; if message was received in the time <sSocket>, <sMessage>, <tStations>.
- ]]
- function net.listen(sSocket, nTimeout)
- -- local functions
- local function listenSocketFunction(sSocket, sMessage, tStations)
- vars.setVariable("net", "sStatus", "received")
- vars.setVariable("net", "sSocket", sSocket)
- vars.setVariable("net", "sMessage", sMessage)
- vars.setVariable("net", "tStations", tStations)
- net.removeSocketFunction(sSocket)
- return
- end
- local function listenTimeoutFunction()
- vars.setVariable("net", "sStatus", "timed out")
- net.removeSocketFunction(sSocket)
- return
- end
- -- begin
- if comp.bRednetOpen then
- if nTimeout > 0 then
- vars.createVariable("net", "sStatus", "waiting")
- vars.createVariable("net", "sSocket", "")
- vars.createVariable("net", "sMessage", "")
- vars.createVariable("net", "tStations", "")
- net.addSocketFunction(sSocket, listenSocketFunction)
- local tTimerID = timer.timeout(nTimeout, listenTimeoutFunction)
- local sStatus = vars.getVariable("net", "sStatus", true)
- local sSocket = vars.getVariable("net", "sSocket")
- local sMessage = vars.getVariable("net", "sMessage")
- local tStations = vars.getVariable("net", "tStations")
- vars.removeVariableSection("net")
- if sStatus == "timed out" then
- return "timed out", nil, nil
- else
- timer.removeTimerFunction(tTimerID)
- return sSocket, sMessage, tStations
- end
- end
- end
- return false
- end
- -- Raw Sendfunctions --
- --[[ Sending message <sMessage> to computer in reach with id <nTargetID> on the socket <sSocket>.
- - <true> if rednet is open; <false> if rednet isn't opened.
- ]]
- function net.sendRaw(nTargetID, sSocket, sMessage, tStations)
- local tStations = tStations or nil
- if comp.bRednetOpen then
- rednet.send(nTargetID, net.prepareMessage(sSocket, sMessage, tStations))
- return true
- end
- return false
- end
- --[[ Broadcasting message <sMessage> to all computers in reach on the socket <sSocket>.
- - <true> if rednet is open; <false> if rednet isn't opened.
- ]]
- function net.shoutRaw(sSocket, sMessage)
- if comp.bRednetOpen then
- rednet.broadcast(net.prepareMessage(sSocket, sMessage, false))
- return true
- end
- return false
- end
- --[[ send the message <sMessage> on socket <sSocket> to target <nTargetID> and wait for a confirmation.
- *
- - Nothing.
- ]]
- function net.sendAndLetConfirm(nTargetID, sSocket, sMessage, tStations)
- local tStations = tStations or nil
- if comp.bRednetOpen then
- net.sendRaw(nTargetID, sSocket, sMessage, tStations)
- if net.waitForConfirmation(sSocket, nTargetID, 1) then
- return true
- else
- --print("testie")
- net.sendRaw(nTargetID, sSocket, sMessage, tStations)
- if net.waitForConfirmation(sSocket, nTargetID, 1) then
- return true
- end
- end
- end
- return false
- end
- -- Confirmation Tools --
- --[[ Waiting for a confirmation for socket <sSocket> from the computer <nComputerID> for <nTrys> * 0.06 seconds.
- - <true> if a confirmation is received; <false> if not.
- ]]
- function net.waitForConfirmation(sSocket, nComputerID, nTrys)
- local nTrys = nTrys or 1
- local sSocket, sMessage, tStations = net.listen(sSocket..tostring(nComputerID), 0.06*nTrys)
- if sSocket ~= "timed out" then
- return true
- end
- return false
- end
- --[[ Sending a confirmation for socket <sSocket> to the computer <nTargetID>.
- - net.sendRaw()
- ]]
- function net.sendConfirmation(nTargetID, sSocket)
- return net.sendRaw(nTargetID, sSocket..tostring(comp.nID), "")
- end
- -- ComputerList Tools --
- --[[ Checking if <tStation> is in the computerlist.
- * Going through the computerlist <net.t_tComputerList> and comparing the names of the computers from the computerlist with the one from the station.
- - <true> if this station is in the computerlist; <false> if not.
- ]]
- function net.isInComputerList(tStation)
- for i,tComputer in ipairs(net.t_tComputerList) do
- if tComputer.sName == tStation.sName then
- return true
- end
- end
- return false
- end
- --[[ Adding station <tStation> to the computerlist.
- * Adding station <tStation> to the computerlist <t_tComputerList>.
- - Nothing.
- ]]
- function net.addToComputerList(tStation)
- table.insert(net.t_tComputerList, {nID = tStation.nID, sName = tStation.sName})
- return
- end
- --[[ Getting the ID from the computer with the name <sName> from the computerlist.
- * Going through the computerlist and comparing the names of all computers with <sName>.
- - <nID> if the computer is in the computerlist; <false> if not.
- ]]
- function net.getComputerIDFromComputerList(sName)
- for i,tComputer in ipairs(net.t_tComputerList) do
- if tComputer.sName == sName then
- return tComputer.nID
- end
- end
- return false
- end
- --[[ Refreshing the computerlist. Getting all computers in reach.
- * Broadcasting the request to refresh its computerlist.
- - net.shoutRaw().
- ]]
- function net.refreshComputerList()
- return net.shoutRaw("clr", "")
- end
- -- ConnectionList Tools --
- --[[ Adding a connection to the connectionList
- *
- - Nothing.
- ]]
- function net.addConnection(nRealTargetID, sRealTargetName, nStationCount, nNextTargetID, nNextForwardingID)
- local tConnection = {}
- tConnection.nRealTargetID = nRealTargetID
- tConnection.sRealTargetName = sRealTargetName
- tConnection.nStationCount = nStationCount or 1
- tConnection.nNextTargetID = nNextTargetID or 0
- tConnection.nNextForwardingID = nNextForwardingID or 0
- table.insert(net.t_tConnectionList, tConnection)
- return #net.t_tConnectionList
- end
- -- ForwadingList Tools
- --[[ Adding a forwarding to the forwardingList
- *
- - The forwardingID of the added forwarding.
- ]]
- function net.addForwarding(nStationCount, nNextTargetID, nNextForwardingID)
- local tForwarding = {}
- tForwarding.nStationCount = nStationCount
- tForwarding.nNextTargetID = nNextTargetID
- tForwarding.nNextForwardingID = nNextForwardingID
- table.insert(net.t_tForwardingList, tForwarding)
- return #net.t_tForwardingList
- end
- -- Open Function --
- --[[ Opening a connection to the target computer <sTargetName>.
- * Checking if the target computer is in the computerlist. If not all computers that are in the network are asked.
- - The new connection id <nConnectionID> if the connection could be built; <false> if not.
- ]]
- function net.open(sTargetName)
- if net.isInComputerList({sName = sTargetName}) then
- local nID = net.getComputerIDFromComputerList(sTargetName)
- return net.addConnection(nID, sTargetName)
- else
- --forwarding path finding
- end
- end
- -- Advanced Send Function --
- --[[ Sending message <sMessage> on the socket <sSocket> over the connection <nConnectionID>.
- * How to send depends on the need of forwarding for the connection.
- - <false>, "errordiscription" if a simple error occured;
- <false>, "errordiscription", <tStations> if an error occured during the forwarding;
- <true> if the message could be sent without any problems.
- ]]
- function net.send(nConnectionID, sSocket, sMessage)
- if not net.t_tConnectionList[nConnectionID] then
- return false
- end
- local tConnection = net.t_tConnectionList[nConnectionID]
- -- If message can be send directly :
- if tConnection.nStationCount == 1 then
- -- If message was confirmed :
- if net.sendAndLetConfirm(tConnection.nNextTargetID, sSocket, sMessage) then
- return true
- -- If message couldn't be confirmed :
- else
- return false, "couldn't reach first station"
- end
- -- If message needs more forwarding :
- else
- --Prepare the message :
- local sPreMessage = net.prepareForwardingMessage(tConnection.nNextForwardingID, sSocket, sMessage)
- -- If the next station couldn't confirm the message :
- if not sendAndLetConfirm(tConnection.nNextTargetID, "fwd", sPreMessage) then
- return false
- -- If the message was confirmed by the next station :
- else
- -- wait until info received
- local sFWDISocket, sFWDIMessage, tFWDIStations = net.listen("fwdi", 0.15 * tConnection.nStationCount)
- if sSocket == "success" then
- return true
- else
- return false, sSocket, tFWDIStations
- end
- end
- end
- end
- -- Networking Init --
- --[[ Networking init. Getting all computers in reach.
- - <false> if rednet isn't opened; <true> if rednet is open;
- ]]
- function net.init()
- if comp.bRednetOpen then
- return net.refreshComputerList()
- end
- return false
- end
- -- Socket Functions --
- --[[ Computer List Refresh
- -> Received when a computer wants to refresh its computerlist.
- * If the computer that sent the message isn't in the actual computers list, then send to it a message on socket "clra"
- ]]
- net.t_fSocketFunctions["clr"] = function(sSocket, sMessage, tStations)
- if not net.isInComputerList(tStations[1]) then
- net.addToComputerList(tStations[1])
- net.sendAndLetConfirm(tStations[1].nID, "clra", "")
- --print("testie11")
- end
- end
- --[[ Computer List Refresh Answer
- -> Received when this computer wanted to refresh its computerlist and other computers in reach answered.
- * Saves the computer to the computerlist.
- ]]
- net.t_fSocketFunctions["clra"] = function(sSocket, sMessage, tStations)
- if not net.isInComputerList(tStations[1]) then
- net.addToComputerList(tStations[1])
- end
- end
- --[[ Forwarding
- -> Received when this computer shall be used for forwarding.
- * Forwards a message.
- ]]
- net.t_fSocketFunctions["fwd"] = function(sSocket, sMessage, tStations)
- local nThisForwardingID, sRealSocket, sRealMessage = net.processMessage(sMessage)
- if not net.t_tForwardingList[nThisForwardingID] then
- return false
- end
- local tForwarding = net.t_tForwardingList[nThisForwardingID]
- print("Message \""..sRealMessage.."\" will be forwarded to "..tForwarding.nNextTargetID)
- -- If message can be send directly :
- if tForwarding.nStationCount == 1 then
- print("< directly forward! >")
- -- If message was confirmed :
- if net.sendAndLetConfirm(tForwarding.nNextTargetID, sRealSocket, sRealMessage, tStations) then
- --Send success back
- net.sendAndLetConfirm(tStations[#tStations - 1].nID, "fwdi", "success")
- -- If message couldn't be confirmed :
- else
- -- Send fail back.
- net.sendAndLetConfirm(tStations[#tStations - 1].nID, "fwdi", "nextTarget doesnt response : "..tForwarding.nNextTargetID)
- end
- -- If message needs more forwarding :
- else
- --Prepare the message :
- local sPreMessage = net.prepareForwardingMessage(tForwarding.nNextForwardingID, sRealSocket, sRealMessage)
- -- If the next station couldn't confirm the message :
- if not sendAndLetConfirm(tForwarding.nNextTargetID, "fwd", sPreMessage, tStations) then
- --send failure back
- net.sendAndLetConfirm(tStations[#tStations - 1].nID, "fwdi", "nextTarget doesnt response : "..tForwarding.nNextTargetID)
- -- If the message was confirmed by the next station :
- else
- -- wait until info received
- local sFWDISocket, sFWDIMessage, tFWDIStations = net.listen("fwdi", 0.15 * tForwarding.nStationCount)
- if sSocket == "timed out" then
- net.sendAndLetConfirm(tStations[#tStations - 1].nID, "fwdi", "info back sending timed out")
- else
- net.sendAndLetConfirm(tStations[#tStations - 1].nID, "fwdi", sFWDIMessage, tFWDIStations)
- end
- end
- end
- end
- ----------------------
- --[[ CLIENT SECTION
- ]]
- ----------------------
- --[[ Calling shell and after it the entered user program
- * Loading shell and after it the user program. Loop until the first eventLoopChecking() Instance is finished working.
- - Nothing.
- ]]
- function userFunction()
- --[[ Checking for the termination of the user program
- * Loop until the program shall terminate.
- - Nothing.
- ]]
- local function loopTerminateCheck()
- while not sys.bClientProgramTerminate do
- os.sleep(0.6)
- end
- term.clear()
- term.setCursorPos(1,1)
- return
- end
- --[[ load and call the shell
- * Load the shell from the shell program. Get the path entered by the user.
- - the program path <sProgramPath>.
- ]]
- local function shellExecute()
- -- get shell program in a function
- local sShellPath = "/rom/programs/shell2"
- local fShell, sErr = loadfile(sShellPath)
- local tEnv = {}
- if not fShell then
- print("Something went wrong loading the shell!")
- else
- if sErr and sErr ~= "" then
- term.clear()
- print(sErr)
- else
- --setmetatable(tEnv, {__index = getfenv(1)})
- setfenv(fShell, getfenv(1))
- vars.createVariable("shell", "sProgramPath", "")
- pcall(fShell)
- local sProgramPath = vars.getVariable("shell", "sProgramPath")
- --print("Path : "..sProgramPath)
- vars.removeVariableSection("shell")
- return sProgramPath
- end
- end
- return "Shell didn't execute"
- end
- --[[ load and call the user program
- * loading and calling the user program.
- - Nothing.
- ]]
- local function userProgramExecute(sProgramPath)
- -- get client program in a function
- local fUser, sErr = loadfile(sProgramPath)
- if not fUser then
- print("Something went wrong loading the client program!")
- else
- if sErr and sErr ~= "" then
- term.clear()
- print(sErr)
- else
- --print("client program will be executed")
- setfenv(fUser, getfenv(1))
- local bSuccess, sError = pcall(fUser)
- if not bSuccess then
- if sError then
- print("The clientprogram had an error, that wasn't specified!")
- else
- print("The clientprogram had an error : "..sError.."!")
- end
- end
- --print("client program is executed")
- end
- end
- end
- --[[ calling shellExecute() and after it userProgramExecute()
- * Executing first the shell and after it the user program entered in the shell.
- - Nothing.
- ]]
- local function shellAndUserProgramCall()
- allowTermination(true) -- will be false if debugging is done.
- local sProgramPath = shellExecute()
- allowTermination(true)
- userProgramExecute(sProgramPath)
- return
- end
- parallel.waitForAny(loopTerminateCheck, shellAndUserProgramCall)
- sys.bClientProgramTerminate = false
- while getInstanceWorkingStatus(1) do
- sleep(0.1)
- end
- return
- end
- ----------------------
- -----INITIALISING-----
- ----------------------
- per.init()
- net.init()
- -----------------
- --[[ LIFE LOOP
- ]]
- -----------------
- while true do
- t_bLoopEventCheckingInstancesWorking = {}
- local tEnv = getfenv(1)
- setmetatable(tEnv, {__index = _G})
- setfenv(loopEventChecking, tEnv)
- setfenv(userFunction, tEnv)
- parallel.waitForAny(loopEventChecking, userFunction)
- end
Advertisement
Add Comment
Please, Sign In to add comment