legaliceit

EventHandling & Rednet API

Oct 27th, 2012
114
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 28.41 KB | None | 0 0
  1. -- Bugs :
  2. --  Confirmation functions dont work! This functions have something to do with confirmations :
  3. --   net.waitForConfirmation()  -> never receives a confirmation. on each received rednet  message a confirmation is sent back! so normally a confirmation should be received.
  4. --   net.sendConfirmation()     -> i think that maybe here is the bug or the whole confirmation system is messed up -.-
  5. --   net.sendAndLetConfirm()    -> uses both of the upper functions.
  6. --   net.rednet_messageEvent()  -> sends for each received rednet message a confirmation back.
  7.  
  8. --              It would be awesome if you help me :)
  9.  
  10. rednet.open("back")
  11.  
  12. -- In case that the user uses functions like read() or sleep() we have to eliminate the chance that this catches the terminate event
  13. os.pullEvent = os.pullEventRaw
  14.  
  15. --------------------
  16. --[[    TOOL SECTION
  17. ]]
  18. --------------------
  19.  
  20. --[[ Allowing Termination for the client program
  21.     * Settingg <sys.bClientProgramAllowTermination> to <bAllowTermination>
  22.     - Nothing.
  23. ]]
  24. function allowTermination(bAllowTermination)
  25.     sys.bClientProgramAllowTermination = bAllowTermination
  26.     return
  27. end
  28.  
  29. --[[ Asking the user for a computername.
  30.     * Setting the computerlabel to the input.
  31.     - The entered computername <sComputerName>.
  32. ]]
  33. function askForComputerName()
  34.     write("Please enter a computername : ")
  35.     os.setComputerLabel(read())
  36.     term.clear()
  37.     term.setCursorPos(1,1)
  38.     return os.getComputerLabel()
  39. end
  40.  
  41.  
  42.  
  43. ------------------------
  44. --[[    SHARED VARIABLES
  45. ]]
  46. ------------------------
  47.  
  48. -- In t_bLoopEventCheckingInstancesWorking the working status of each instance of loopEventChecking() is saved.
  49. t_bLoopEventCheckingInstancesWorking = {}
  50.  
  51. -- In sys are two Variables for termination handling saved :
  52. sys = {}
  53. -- sys.bClientProgramAllowTermination saves the state of allowing termination of the client program.
  54. sys.bClientProgramAllowTermination = true
  55. -- sys.bClientProgramTerminate saves the state of terminating the client program.
  56. sys.bClientProgramTerminate = false
  57.  
  58.  
  59. -- comp saves variables about this computer
  60. comp = {}
  61. comp.nID = os.getComputerID()
  62. comp.sName = os.getComputerLabel() or askForComputerName()
  63. comp.bRednetOpen = true
  64.  
  65.  
  66. -----------------------------
  67. --[[    VARIABLE SUPPLY LEVEL
  68. ]]
  69. -----------------------------
  70. vars = {}
  71.  
  72. -- vars.tVariables saves all Variables that are used for sharing variables between the event checking loop and the user program.
  73. vars.tVariables = {}
  74.  
  75. --[[ Creating a variable section with the name <sName> in the shared variables.
  76.     * Creating a table in <vars.tVariables> with the key <sName>.
  77.     - <true> if the section was created; <false> if not.
  78. ]]
  79. function vars.createVariableSection(sName)
  80.     if not vars.tVariables[sName] then
  81.         vars.tVariables[sName] = {}
  82.         return true
  83.     end
  84.     return false
  85. end
  86.  
  87. --[[ Creating a variable with the name <sVariableName> in the section <sSectionName>.
  88.     * Creating a table for the variable <sVariableName> in <vars.tVariables[sSectionName] with the key <sVariableName>.
  89.     - <true> if the variable was created; <false> if not.
  90. ]]
  91. function vars.createVariable(sSectionName, sVariableName, vDefaultValue)
  92.     if not vars.tVariables[sSectionName] then
  93.         if not vars.createVariableSection(sSectionName) then
  94.             return false
  95.         end
  96.     end
  97.     if not vars.tVariables[sSectionName][sVariableName] then
  98.         vars.tVariables[sSectionName][sVariableName] = {
  99.             bChanged = false,
  100.             vDefaultValue = vDefaultValue,
  101.             vValue = vDefaultValue
  102.         }
  103.         return true
  104.     end
  105.     return false
  106. end
  107.  
  108. --[[ Removing the variable section with the name <sSectionName> from the shared variables.
  109.     * Removing the table with the key <sSectionName> in <vars.tVariables>.
  110.     - <true> if the section was deleted; <false> if not.
  111. ]]
  112. function vars.removeVariableSection(sSectionName)
  113.     if vars.tVariables[sSectionName] then
  114.         vars.tVariables[sSectionName] = nil
  115.         return true
  116.     end
  117.     return false
  118. end
  119.  
  120. --[[ Removing the variable <sVariableName> from the section <sSectionName> from the shared variables.
  121.     * Setting the variable <sVariableName> in the section <sSectionName> in the shared variables to <nil>.
  122.     - <true> if variable could be removed; <false> if not.
  123. ]]
  124. function vars.removeVariable(sSectionName, sVariableName)
  125.     if vars.tVariables[sSectionName] then
  126.         if vars.tVariables[sSectionName][sVariableName] then
  127.             vars.tVariables[sSectionName][sVariableName] = nil
  128.             return true
  129.         end
  130.     end
  131.     return false
  132. end
  133.  
  134. --[[ Resetting the variable <sVariableName> in the section <sSectionName> to its default value.
  135.     * Setting the <bChanged> of the variable to <true> and setting <vValue> of the variable to <vDefaultValue> from the variable.
  136.     - <true> if the variable could be resetted; <false> if not.
  137. ]]
  138. function vars.resetVariable(sSectionName, sVariableName)
  139.     if vars.tVariables[sSectionName] and vars.tVariables[sSectionName][sVariableName] then
  140.         vars.tVariables[sSectionName][sVariableName].bChanged = false
  141.         vars.tVariables[sSectionName][sVariableName].vValue = vars.tVariables[sSectionName][sVariableName].vDefaultValue
  142.         return true
  143.     end
  144.     return false
  145. end
  146.  
  147.  
  148. --[[ Setting the existing variable <sVariableName> from the section <sSectionName> to <vValue>
  149.     * Setting <vValue> from the variable <sVariableName> to <vValue>.
  150.     - <true> if the variable could be set; <false> if not.
  151. ]]
  152. function vars.setVariable(sSectionName, sVariableName, vValue)
  153.     if vars.tVariables[sSectionName] and vars.tVariables[sSectionName][sVariableName] then
  154.         vars.tVariables[sSectionName][sVariableName].bChanged = true
  155.         vars.tVariables[sSectionName][sVariableName].vValue = vValue
  156.         return true
  157.     end
  158.     return false
  159. end
  160.  
  161. --[[ Getting the variable <sVariableName> from the section <sSectionName>.
  162.     * If <bLoopUntilChanged> is <true> the function will wait until <bChanged> of the variable is <true> and then return <vValue> of the variable.
  163.     - The <vValue> of the variable : <vValue>
  164. ]]
  165. function vars.getVariable(sSectionName, sVariableName, bLoopUntilChanged)
  166.     if bLoopUntilChanged then
  167.         while not vars.tVariables[sSectionName][sVariableName].bChanged do
  168.             os.sleep(0.1)
  169.         end
  170.         return vars.tVariables[sSectionName][sVariableName].vValue
  171.     else
  172.         return vars.tVariables[sSectionName][sVariableName].vValue
  173.     end
  174. end
  175.  
  176.  
  177. --debug
  178. function show(var, ebene)
  179.     local ebene = ebene or 1
  180.     local str = ""
  181.     for i = 1, ebene do
  182.         str = str.."  "
  183.     end
  184.     for k,v in pairs(var) do
  185.         if type(v) == "table" then
  186.             print(str..k..": table :")
  187.             show(v, ebene + 1)
  188.             print(str..k..": table end.")
  189.         else
  190.             print(str..k.." : "..tostring(v))
  191.         end
  192.     end
  193. end
  194.  
  195.  
  196.  
  197. ---------------------
  198. --[[    EVENT SECTION
  199.     The concept of this api :
  200.         Base : Checks all the time for events.
  201.             Net : A messaging API
  202.         Shell : A normal shell, in that can be entered which program should be run.
  203.         Program : All programs wihch path are entered in the shell can use the Base functions.
  204. ]]
  205. ---------------------
  206.  
  207. -- In t_fEventHandler all EventHandler are saved.
  208. t_fEventHandler = {}
  209.  
  210. --[[ Getting the working status for the instance <nInstance> of loopEventChecking()
  211.     * Returning the value of the entry <nInstance> of the table <t_bLoopEventCheckingInstancesWorking>.
  212.     - The working Status <bWorking>.
  213. ]]
  214. function getInstanceWorkingStatus(nInstance)
  215.     return t_bLoopEventCheckingInstancesWorking[nInstance]
  216. end
  217.  
  218. --[[ Checking in an endless loop for all events.
  219.     * 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.
  220.     - Nothing.
  221. ]]
  222. function loopEventChecking()
  223.     --var
  224.     local nThisInstance = #t_bLoopEventCheckingInstancesWorking + 1
  225.     local sEvent, par1, par2, par3 = "", nil, nil, nil
  226.    
  227.     --localfunc
  228.     local function setInstanceWorkingStatus(nInstance, bWorking)
  229.         t_bLoopEventCheckingInstancesWorking[nInstance] = bWorking
  230.         return
  231.     end
  232.     local function callEventHandler()
  233.         t_fEventHandler[sEvent](par1, par2, par3)
  234.        
  235.         while getInstanceWorkingStatus(nThisInstance + 1) do
  236.             sleep(0.1)
  237.         end
  238.     end
  239.    
  240.     --begin
  241.     setInstanceWorkingStatus(nThisInstance, false)
  242.    
  243.     while true do
  244.         sEvent, par1, par2, par3 = os.pullEventRaw()
  245.        
  246.         if t_fEventHandler[sEvent] then
  247.             setInstanceWorkingStatus(nThisInstance, true)
  248.            
  249.             parallel.waitForAny(loopEventChecking, callEventHandler)
  250.            
  251.             setInstanceWorkingStatus(nThisInstance, false)
  252.         end
  253.     end
  254. end
  255.  
  256.  
  257. --          EventHandler        --
  258.  
  259. --[[ terminate :    -   -   -
  260.     * Setting <sys.bClientProgramTerminate> if termination in <sys.bClientProgramAllowTermination> is allowed.
  261. ]]
  262. t_fEventHandler["terminate"] = function()
  263.     if sys.bClientProgramAllowTermination then
  264.         sys.bClientProgramTerminate = true
  265.     end
  266. end
  267.  
  268. --[[ timer :    tTimerID    -   -
  269.     * overgiving the timer identification to timer.timerEvent().
  270. ]]
  271. t_fEventHandler["timer"] = function(tTimerID)
  272.     timer.timerEvent(tTimerID)
  273. end
  274.  
  275. --[[ rednet_message :   nSenderID   sMessage    nDistance
  276.     * Overgiving <nSenderID>, <sMessage and <nDistance> to net.rednet_MessageEvent()
  277. ]]
  278. t_fEventHandler["rednet_message"] = function(nSenderID, sMessage, nDistance)
  279.     net.rednet_messageEvent(nSenderID, sMessage, nDistance)
  280. end
  281.  
  282.  
  283. ---------------------
  284. --[[    TIMER SECTION
  285. ]]
  286. ---------------------
  287.  
  288. timer = {}
  289. -- timer.t_fTimerFunctions saves all TimerFunctions
  290. timer.t_fTimerFunctions = {}
  291.  
  292.  
  293. --          Timer Function Tools        --
  294.  
  295. --[[ Adding the timerfunction <fTimerFunction> to the timerfunction list.
  296.     * Adds the function <fTimerFunction> to <timer.t_fTimerFunctions> with the key <tTimerID>.
  297.     - <true> if timerfunction could be added; <false> if not.
  298. ]]
  299. function timer.addTimerFunction(tTimerID, fTimerFunction)
  300.     if not timer.t_fTimerFunctions[tTimerID] then
  301.         timer.t_fTimerFunctions[tTimerID] = fTimerFunction
  302.         return true
  303.     end
  304.     return false
  305. end
  306. --[[ Removing the timerfunction for the timerID <tTimerID> from the timerfunction list.
  307.     * Removing the timerfunction with the key <tTimerID> from the timerfunction table <timer.t_fTimerFunctions>.
  308.     - <true> if timerfunction could be removed; <false> if not.
  309. ]]
  310. function timer.removeTimerFunction(tTimerID)
  311.     if timer.t_fTimerFunctions[tTimerID] then
  312.         timer.t_fTimerFunctions[tTimerID] = nil
  313.         return true
  314.     end
  315.     return false
  316. end
  317.  
  318. --[[ Creating a timeout for the time of <nTimeout> secs. The function that is going to be called is <fTimeoutFunction>.
  319.     * Adding the function <fTimeoutFunction> to the timerfunction list and starting a timer.
  320.     - If the timer could be created the timerID <tTimerID>; <false> if not.
  321. ]]
  322. function timer.timeout(nTimeout, fTimeoutFunction)
  323.     if nTimeout > 0 then
  324.         local tTimerID = os.startTimer(nTimeout)
  325.         timer.addTimerFunction(tTimerID, fTimeoutFunction)
  326.         return tTimerID
  327.     end
  328.     return false
  329. end
  330.  
  331.  
  332. --      Timer Event Handling        --
  333.  
  334. --[[ Calling timerfunctions.
  335.     * Checking if the timer with the ID <tTimerID> is in the timerfunction list, if so call the timerfunction.
  336.     - Nothing.
  337. ]]
  338. function timer.timerEvent(tTimerID)
  339.     if timer.t_fTimerFunctions[tTimerID] then
  340.         timer.t_fTimerFunctions[tTimerID](tTimerID)
  341.         timer.removeTimerFunction(tTimerID)
  342.     end
  343.     return
  344. end
  345.  
  346.  
  347.  
  348. --------------------
  349. --[[    NET SECTIONS
  350. ]]
  351. --------------------
  352.  
  353. net = {}
  354. -- net.t_fSocketFunctions saves all SocketFunctions
  355. net.t_fSocketFunctions = {}
  356. -- net.t_tComputerList saves the computers in reach.
  357. net.t_tComputerList = {}
  358.  
  359. --net.t_tConnectionList saves all connections for this computer
  360. net.t_tConnectionList = {}
  361.  
  362. --net.t_tForwardingList saves all forwardings for this
  363. net.t_tForwardingList = {}
  364.  
  365.  
  366. --      Socket Function Tools       --
  367.  
  368. --[[ Socketfunction adding.
  369.     * Adds the function <fSocketFunction> for the socket <sSocket> to the SocketFunction table.
  370.     - <true> if SocketFunction could be added; else <false>.
  371. ]]
  372. function net.addSocketFunction(sSocket, fSocketFunction)
  373.     if not net.t_fSocketFunctions[sSocket] then
  374.         net.t_fSocketFunctions[sSocket] = fSocketFunction
  375.         return true
  376.     end
  377.     return false
  378. end
  379. --[[ Socketfunction removing.
  380.     * Removes the Socketfunction for the socket <sSocket> from the SocketFunction table.
  381.     - <true> if SocketFunction could be removed; else <false>.
  382. ]]
  383. function net.removeSocketFunction(sSocket)
  384.     if net.t_fSocketFunctions[sSocket] then
  385.         net.t_fSocketFunctions[sSocket] = nil
  386.         return true
  387.     end
  388.     return false
  389. end
  390.  
  391.  
  392. --          Message Tools           --
  393.  
  394. --[[ Unzip a rednet message.
  395.     * Returns the unpacked table that is created from ser.deserialize() with the raw rednet message <sRawMessage>
  396.     - All Variables unpacked.
  397. ]]
  398. function net.processMessage(sRawMessage)
  399.     return unpack(textutils.unserialize(sRawMessage))
  400. end
  401.  
  402. --[[ Preparing a rednet message for normal sending.
  403.     * Merging <sSocket>, <sRawMessage> and <tStations> with ser.serialize() in a string.
  404.     - The prepared message <sMessage> that is ready for sending.
  405. ]]
  406. function net.prepareMessage(sSocket, sRawMessage, tStations)
  407.     local tStations = tStations
  408.     if not tStations then
  409.         tStations = {}
  410.         table.insert(tStations, {sName = comp.sName, nID = comp.nID})
  411.     end
  412.     return textutils.serialize({sSocket, sRawMessage, tStations})
  413. end
  414.  
  415. --[[ Preparing a rednet message for forwarding.
  416.     * Merging <nNextForwardingID>, <sRealSocket>, <sRealMessage> with ser.serialize() in a string.
  417.     - The prepared message <sMessage> that is ready for sending.
  418. ]]
  419. function net.prepareForwardingMessage(nNextForwardingID, sRealSocket, sRealMessage)
  420.     return textutils.serialize({nNextForwardingID, sRealSocket, sRealMessage})
  421. end
  422.  
  423. --        Rednet Message Event Handling        --
  424.  
  425. --[[ Socketfunction calling.
  426.     * Unzips received rednet messages. Adds this station. Calls the socketfunction if there is one.
  427.     - Nothing.
  428. ]]
  429. function net.rednet_messageEvent(nSenderID, sRawMessage, nDistance)
  430.     local sSocket, sMessage, tStations = net.processMessage(sRawMessage)
  431.    
  432.     table.insert(tStations, {["nID"] = comp.nID, ["sName"] = comp.sName, ["nDistanceFromLast"] = nDistance})
  433.    
  434.     if net.t_fSocketFunctions[sSocket] then
  435.        
  436.         net.sendConfirmation(tStations[#tStations - 1].nID, sSocket)
  437.        
  438.         net.t_fSocketFunctions[sSocket](sSocket, sMessage, tStations)
  439.     end
  440.    
  441.     return
  442. end
  443.  
  444.  
  445. --          Listen function             --
  446.  
  447. --[[ Listening for the timeout <nTimeout> in secs on the socket <sSocket>.
  448.     * Creating a timeout with timer.timeout() and create a socketfunction for the socket <sSocket>.
  449.     - "timed out" if the timeout was reached; if message was received in the time <sSocket>, <sMessage>, <tStations>.
  450. ]]
  451. function net.listen(sSocket, nTimeout)
  452.     -- local functions
  453.     local function listenSocketFunction(sSocket, sMessage, tStations)
  454.         vars.setVariable("net", "sStatus", "received")
  455.         vars.setVariable("net", "sSocket", sSocket)
  456.         vars.setVariable("net", "sMessage", sMessage)
  457.         vars.setVariable("net", "tStations", tStations)
  458.        
  459.         net.removeSocketFunction(sSocket)
  460.        
  461.         return
  462.     end
  463.     local function listenTimeoutFunction()
  464.         vars.setVariable("net", "sStatus", "timed out")
  465.        
  466.         net.removeSocketFunction(sSocket)
  467.        
  468.         return
  469.     end
  470.    
  471.     -- begin
  472.     if comp.bRednetOpen then
  473.         if nTimeout > 0 then
  474.        
  475.             vars.createVariable("net", "sStatus", "waiting")
  476.             vars.createVariable("net", "sSocket", "")
  477.             vars.createVariable("net", "sMessage", "")
  478.             vars.createVariable("net", "tStations", "")
  479.        
  480.             net.addSocketFunction(sSocket, listenSocketFunction)
  481.             local tTimerID = timer.timeout(nTimeout, listenTimeoutFunction)
  482.            
  483.             local sStatus = vars.getVariable("net", "sStatus", true)
  484.            
  485.             local sSocket = vars.getVariable("net", "sSocket")
  486.             local sMessage = vars.getVariable("net", "sMessage")
  487.             local tStations = vars.getVariable("net", "tStations")
  488.            
  489.            
  490.             vars.removeVariableSection("net")
  491.            
  492.             if sStatus == "timed out" then
  493.                 return "timed out", nil, nil
  494.             else
  495.                 timer.removeTimerFunction(tTimerID)
  496.                 return sSocket, sMessage, tStations
  497.             end
  498.         end
  499.     end
  500.     return false
  501. end
  502.  
  503.  
  504. --          Raw Sendfunctions       --
  505.  
  506. --[[ Sending message <sMessage> to computer in reach with id <nTargetID> on the socket <sSocket>.
  507.     - <true> if rednet is open; <false> if rednet isn't opened.
  508. ]]
  509. function net.sendRaw(nTargetID, sSocket, sMessage, tStations)
  510.     local tStations = tStations or nil
  511.     if comp.bRednetOpen then
  512.         rednet.send(nTargetID, net.prepareMessage(sSocket, sMessage, tStations))
  513.         return true
  514.     end
  515.     return false
  516. end
  517. --[[ Broadcasting message <sMessage> to all computers in reach on the socket <sSocket>.
  518.     - <true> if rednet is open; <false> if rednet isn't opened.
  519. ]]
  520. function net.shoutRaw(sSocket, sMessage)
  521.     if comp.bRednetOpen then
  522.         rednet.broadcast(net.prepareMessage(sSocket, sMessage, false))
  523.         return true
  524.     end
  525.     return false
  526. end
  527.  
  528. --[[ send the message <sMessage> on socket <sSocket> to target <nTargetID> and wait for a confirmation.
  529.     *
  530.     - Nothing.
  531. ]]
  532. function net.sendAndLetConfirm(nTargetID, sSocket, sMessage, tStations)
  533.     local tStations = tStations or nil
  534.     if comp.bRednetOpen then
  535.         net.sendRaw(nTargetID, sSocket, sMessage, tStations)
  536.         if net.waitForConfirmation(sSocket, nTargetID, 1) then
  537.             return true
  538.         else
  539.             --print("testie")
  540.             net.sendRaw(nTargetID, sSocket, sMessage, tStations)
  541.             if net.waitForConfirmation(sSocket, nTargetID, 1) then
  542.                 return true
  543.             end
  544.         end
  545.     end
  546.     return false
  547. end
  548.  
  549.  
  550. --      Confirmation Tools      --
  551.  
  552. --[[ Waiting for a confirmation for socket <sSocket> from the computer <nComputerID> for <nTrys> * 0.06 seconds.
  553.     - <true> if a confirmation is received; <false> if not.
  554. ]]
  555. function net.waitForConfirmation(sSocket, nComputerID, nTrys)
  556.     local nTrys = nTrys or 1
  557.    
  558.     local sSocket, sMessage, tStations = net.listen(sSocket..tostring(nComputerID), 0.06*nTrys)
  559.     if sSocket ~= "timed out" then
  560.         return true
  561.     end
  562.     return false
  563. end
  564. --[[ Sending a confirmation for socket <sSocket> to the computer <nTargetID>.
  565.     - net.sendRaw()
  566. ]]
  567. function net.sendConfirmation(nTargetID, sSocket)
  568.     return net.sendRaw(nTargetID, sSocket..tostring(comp.nID), "")
  569. end
  570.  
  571.  
  572. --      ComputerList Tools      --
  573.  
  574. --[[ Checking if <tStation> is in the computerlist.
  575.     * Going through the computerlist <net.t_tComputerList> and comparing the names of the computers from the computerlist with the one from the station.
  576.     - <true> if this station is in the computerlist; <false> if not.
  577. ]]
  578. function net.isInComputerList(tStation)
  579.     for i,tComputer in ipairs(net.t_tComputerList) do
  580.         if tComputer.sName == tStation.sName then
  581.             return true
  582.         end
  583.     end
  584.     return false
  585. end
  586. --[[ Adding station <tStation> to the computerlist.
  587.     * Adding station <tStation> to the computerlist <t_tComputerList>.
  588.     - Nothing.
  589. ]]
  590. function net.addToComputerList(tStation)
  591.     table.insert(net.t_tComputerList, {nID = tStation.nID, sName = tStation.sName})
  592.     return
  593. end
  594.  
  595. --[[ Getting the ID from the computer with the name <sName> from the computerlist.
  596.     * Going through the computerlist and comparing the names of all computers with <sName>.
  597.     - <nID> if the computer is in the computerlist; <false> if not.
  598. ]]
  599. function net.getComputerIDFromComputerList(sName)
  600.     for i,tComputer in ipairs(net.t_tComputerList) do
  601.         if tComputer.sName == sName then
  602.             return tComputer.nID
  603.         end
  604.     end
  605.     return false
  606. end
  607.  
  608. --[[ Refreshing the computerlist. Getting all computers in reach.
  609.     * Broadcasting the request to refresh its computerlist.
  610.     - net.shoutRaw().
  611. ]]
  612. function net.refreshComputerList()
  613.     return net.shoutRaw("clr", "")
  614. end
  615.  
  616.  
  617. --      ConnectionList Tools    --
  618.  
  619. --[[ Adding a connection to the connectionList
  620.     *
  621.     - Nothing.
  622. ]]
  623. function net.addConnection(nRealTargetID, sRealTargetName, nStationCount, nNextTargetID, nNextForwardingID)
  624.     local tConnection = {}
  625.     tConnection.nRealTargetID = nRealTargetID
  626.     tConnection.sRealTargetName = sRealTargetName
  627.     tConnection.nStationCount = nStationCount or 1
  628.     tConnection.nNextTargetID = nNextTargetID or 0
  629.     tConnection.nNextForwardingID = nNextForwardingID or 0
  630.     table.insert(net.t_tConnectionList, tConnection)
  631.     return #net.t_tConnectionList
  632. end
  633.  
  634.  
  635. --      ForwadingList Tools
  636.  
  637. --[[ Adding a forwarding to the forwardingList
  638.     *
  639.     - The forwardingID of the added forwarding.
  640. ]]
  641. function net.addForwarding(nStationCount, nNextTargetID, nNextForwardingID)
  642.     local tForwarding = {}
  643.     tForwarding.nStationCount = nStationCount
  644.     tForwarding.nNextTargetID = nNextTargetID
  645.     tForwarding.nNextForwardingID = nNextForwardingID
  646.     table.insert(net.t_tForwardingList, tForwarding)
  647.     return #net.t_tForwardingList
  648. end
  649.  
  650.  
  651. --      Open Function       --
  652.  
  653. --[[ Opening a connection to the target computer <sTargetName>.
  654.     * Checking if the target computer is in the computerlist. If not all computers that are in the network are asked.
  655.     - The new connection id <nConnectionID> if the connection could be built; <false> if not.
  656. ]]
  657. function net.open(sTargetName)
  658.     if net.isInComputerList({sName = sTargetName}) then
  659.         local nID = net.getComputerIDFromComputerList(sTargetName)
  660.         return net.addConnection(nID, sTargetName)
  661.     else
  662.         --forwarding path finding
  663.     end
  664. end
  665.  
  666.  
  667. --      Advanced Send Function      --
  668.  
  669. --[[ Sending message <sMessage> on the socket <sSocket> over the connection <nConnectionID>.
  670.     * How to send depends on the need of forwarding for the connection.
  671.     - <false>, "errordiscription" if a simple error occured;
  672.       <false>, "errordiscription", <tStations> if an error occured during the forwarding;
  673.       <true> if the message could be sent without any problems.
  674. ]]
  675. function net.send(nConnectionID, sSocket, sMessage)
  676.     if not net.t_tConnectionList[nConnectionID] then
  677.         return false
  678.     end
  679.    
  680.     local tConnection = net.t_tConnectionList[nConnectionID]
  681.    
  682.     -- If message can be send directly :
  683.     if tConnection.nStationCount == 1 then
  684.    
  685.         -- If message was confirmed :
  686.         if net.sendAndLetConfirm(tConnection.nNextTargetID, sSocket, sMessage) then
  687.             return true
  688.         -- If message couldn't be confirmed :
  689.         else
  690.             return false, "couldn't reach first station"
  691.         end
  692.    
  693.     -- If message needs more forwarding :
  694.     else
  695.    
  696.         --Prepare the message :
  697.         local sPreMessage = net.prepareForwardingMessage(tConnection.nNextForwardingID, sSocket, sMessage)
  698.        
  699.         -- If the next station couldn't confirm the message :
  700.         if not sendAndLetConfirm(tConnection.nNextTargetID, "fwd", sPreMessage) then
  701.            
  702.             return false
  703.            
  704.         -- If the message was confirmed by the next station :
  705.         else
  706.            
  707.             -- wait until info received
  708.             local sFWDISocket, sFWDIMessage, tFWDIStations = net.listen("fwdi", 0.15 * tConnection.nStationCount)
  709.            
  710.             if sSocket == "success" then
  711.                 return true
  712.             else
  713.                 return false, sSocket, tFWDIStations
  714.             end
  715.            
  716.         end
  717.    
  718.     end
  719.    
  720. end
  721.  
  722.  
  723. --      Networking Init     --
  724.  
  725. --[[ Networking init. Getting all computers in reach.
  726.     - <false> if rednet isn't opened; <true> if rednet is open;
  727. ]]
  728. function net.init()
  729.     if comp.bRednetOpen then
  730.         return net.refreshComputerList()
  731.     end
  732.     return false
  733. end
  734.  
  735.  
  736. --      Socket Functions        --
  737.  
  738. --[[ Computer List Refresh
  739.     -> Received when a computer wants to refresh its computerlist.
  740.     * If the computer that sent the message isn't in the actual computers list, then send to it a message on socket "clra"
  741. ]]
  742. net.t_fSocketFunctions["clr"] = function(sSocket, sMessage, tStations)
  743.     if not net.isInComputerList(tStations[1]) then
  744.         net.addToComputerList(tStations[1])
  745.         net.sendAndLetConfirm(tStations[1].nID, "clra", "")
  746.         --print("testie11")
  747.     end
  748. end
  749.  
  750. --[[ Computer List Refresh Answer
  751.     -> Received when this computer wanted to refresh its computerlist and other computers in reach answered.
  752.     * Saves the computer to the computerlist.
  753. ]]
  754. net.t_fSocketFunctions["clra"] = function(sSocket, sMessage, tStations)
  755.     if not net.isInComputerList(tStations[1]) then
  756.         net.addToComputerList(tStations[1])
  757.     end
  758. end
  759.  
  760. --[[ Forwarding
  761.     -> Received when this computer shall be used for forwarding.
  762.     * Forwards a message.
  763. ]]
  764. net.t_fSocketFunctions["fwd"] = function(sSocket, sMessage, tStations)
  765.     local nThisForwardingID, sRealSocket, sRealMessage = net.processMessage(sMessage)
  766.    
  767.     if not net.t_tForwardingList[nThisForwardingID] then
  768.         return false
  769.     end
  770.    
  771.     local tForwarding = net.t_tForwardingList[nThisForwardingID]
  772.    
  773.     print("Message \""..sRealMessage.."\" will be forwarded to "..tForwarding.nNextTargetID)
  774.     -- If message can be send directly :
  775.     if tForwarding.nStationCount == 1 then
  776.         print("< directly forward! >")
  777.         -- If message was confirmed :
  778.         if net.sendAndLetConfirm(tForwarding.nNextTargetID, sRealSocket, sRealMessage, tStations) then
  779.            
  780.             --Send success back
  781.             net.sendAndLetConfirm(tStations[#tStations - 1].nID, "fwdi", "success")
  782.            
  783.         -- If message couldn't be confirmed :
  784.         else
  785.             -- Send fail back.
  786.             net.sendAndLetConfirm(tStations[#tStations - 1].nID, "fwdi", "nextTarget doesnt response : "..tForwarding.nNextTargetID)
  787.         end
  788.    
  789.     -- If message needs more forwarding :
  790.     else
  791.    
  792.         --Prepare the message :
  793.         local sPreMessage = net.prepareForwardingMessage(tForwarding.nNextForwardingID, sRealSocket, sRealMessage)
  794.        
  795.         -- If the next station couldn't confirm the message :
  796.         if not sendAndLetConfirm(tForwarding.nNextTargetID, "fwd", sPreMessage, tStations) then
  797.            
  798.             --send failure back
  799.             net.sendAndLetConfirm(tStations[#tStations - 1].nID, "fwdi", "nextTarget doesnt response : "..tForwarding.nNextTargetID)
  800.            
  801.         -- If the message was confirmed by the next station :
  802.         else
  803.            
  804.             -- wait until info received
  805.             local sFWDISocket, sFWDIMessage, tFWDIStations = net.listen("fwdi", 0.15 * tForwarding.nStationCount)
  806.            
  807.             if sSocket == "timed out" then
  808.                 net.sendAndLetConfirm(tStations[#tStations - 1].nID, "fwdi", "info back sending timed out")
  809.             else
  810.                 net.sendAndLetConfirm(tStations[#tStations - 1].nID, "fwdi", sFWDIMessage, tFWDIStations)
  811.             end
  812.            
  813.         end
  814.    
  815.     end
  816. end
  817.  
  818. ----------------------
  819. --[[    CLIENT SECTION
  820. ]]
  821. ----------------------
  822.  
  823. --[[ Calling shell and after it the entered user program
  824.     * Loading shell and after it the user program. Loop until the first eventLoopChecking() Instance is finished working.
  825.     - Nothing.
  826. ]]
  827. function userFunction()
  828.  
  829.     --[[ Checking for the termination of the user program
  830.         * Loop until the program shall terminate.
  831.         - Nothing.
  832.     ]]
  833.     local function loopTerminateCheck()
  834.         while not sys.bClientProgramTerminate do
  835.             os.sleep(0.6)
  836.         end
  837.         term.clear()
  838.         term.setCursorPos(1,1)
  839.         return
  840.     end
  841.     --[[ load and call the shell
  842.         * Load the shell from the shell program. Get the path entered by the user.
  843.         - the program path <sProgramPath>.
  844.     ]]
  845.     local function shellExecute()
  846.         -- get shell program in a function
  847.         local sShellPath = "/rom/programs/shell2"
  848.         local fShell, sErr = loadfile(sShellPath)
  849.         local tEnv = {}
  850.         if not fShell then
  851.             print("Something went wrong loading the shell!")
  852.         else
  853.             if sErr and sErr ~= "" then
  854.                 term.clear()
  855.                 print(sErr)
  856.             else
  857.                 --setmetatable(tEnv, {__index = getfenv(1)})
  858.                 setfenv(fShell, getfenv(1))
  859.                
  860.                 vars.createVariable("shell", "sProgramPath", "")
  861.                
  862.                 pcall(fShell)
  863.                
  864.                 local sProgramPath = vars.getVariable("shell", "sProgramPath")
  865.                 --print("Path : "..sProgramPath)
  866.                 vars.removeVariableSection("shell")
  867.                
  868.                 return sProgramPath
  869.             end
  870.         end
  871.         return "Shell didn't execute"
  872.     end
  873.     --[[ load and call the user program
  874.         * loading and calling the user program.
  875.         - Nothing.
  876.     ]]
  877.     local function userProgramExecute(sProgramPath)
  878.         -- get client program in a function
  879.         local fUser, sErr = loadfile(sProgramPath)
  880.         if not fUser then
  881.             print("Something went wrong loading the client program!")
  882.         else
  883.             if sErr and sErr ~= "" then
  884.                 term.clear()
  885.                 print(sErr)
  886.             else
  887.                 --print("client program will be executed")
  888.                 setfenv(fUser, getfenv(1))
  889.                 local bSuccess, sError = pcall(fUser)
  890.                 if not bSuccess then
  891.                     if sError then
  892.                         print("The clientprogram had an error, that wasn't specified!")
  893.                     else
  894.                         print("The clientprogram had an error : "..sError.."!")
  895.                     end
  896.                 end
  897.                 --print("client program is executed")
  898.             end
  899.         end
  900.     end
  901.     --[[ calling shellExecute() and after it userProgramExecute()
  902.         * Executing first the shell and after it the user program entered in the shell.
  903.         - Nothing.
  904.     ]]
  905.     local function shellAndUserProgramCall()
  906.         allowTermination(true)  -- will be false if debugging is done.
  907.         local sProgramPath = shellExecute()
  908.         allowTermination(true)
  909.         userProgramExecute(sProgramPath)
  910.        
  911.         return
  912.     end
  913.    
  914.     parallel.waitForAny(loopTerminateCheck, shellAndUserProgramCall)
  915.     sys.bClientProgramTerminate = false
  916.    
  917.     while getInstanceWorkingStatus(1) do
  918.         sleep(0.1)
  919.     end
  920.    
  921.     return
  922. end
  923.  
  924.  
  925. ----------------------
  926. -----INITIALISING-----
  927. ----------------------
  928. per.init()
  929. net.init()
  930.  
  931. -----------------
  932. --[[    LIFE LOOP
  933. ]]
  934. -----------------
  935. while true do
  936.     t_bLoopEventCheckingInstancesWorking = {}
  937.    
  938.     local tEnv = getfenv(1)
  939.     setmetatable(tEnv, {__index = _G})
  940.    
  941.     setfenv(loopEventChecking, tEnv)
  942.     setfenv(userFunction, tEnv)
  943.    
  944.     parallel.waitForAny(loopEventChecking, userFunction)
  945. end
Advertisement
Add Comment
Please, Sign In to add comment