Advertisement
ladyDia

Network TIOS Turtle

Dec 8th, 2024 (edited)
141
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 17.88 KB | None | 0 0
  1. --[[
  2.     Turtle Input Output System (Working name)
  3.     Takes in a string of basic commands and executes them
  4.     All commands are two characters long
  5.     On command start up
  6.     Max command string length of 256?
  7.     Max instruction length of 99 (jump instructions)
  8.     Keeps list of blocks in inventory
  9.     Slot 1 is reserved for onboard fuel
  10.     Keeps list of functions in this script
  11.     Turns command string into function ID and number in a list
  12.     -example-
  13.         command string
  14.             "CFMF10TR1DF1" or "cfmf10tr1df1"
  15.         function ID and number list
  16.             1 {cf,-1}
  17.             2 {mf, 10}
  18.             3 {tr, 1}
  19.             4 {df, 1}
  20.     Calling a variable followed by a number x will set the variable to that number
  21.     -example-
  22.         "L110" will set variable N1 to 10
  23.        
  24.    
  25.     Command IDs (x represents number input (Min 0, Max 99), v represents an variable)
  26.     In format of Command String - Description
  27.     --Movement--
  28.     MF   - Move forward
  29.     MU   - Move upward
  30.     MD   - Move downward  
  31.     MB   - Move backward
  32.     TR   - Turn right
  33.     TL   - Turn left
  34.     --Digging--
  35.     DU   - Dig up
  36.     DD   - Dig down
  37.     DF   - Dig forward
  38.     DA   - Dig down, forward, and up
  39.     --Inspecting blocks--
  40.     IUvx - Detect up, if something found then set v to x
  41.     IIvx - Detect forward, if something found then set v to x (IF is reserved by lua)
  42.     IDvx - Detect down, if something found then set v to x
  43.     IAvx - Detect all, if something found then set v to x
  44.     --Compairing blocks--
  45.     CUvx - Compare up, if block matches selected block then set v to x
  46.     CFvx - Compare forward, if block matches selected block then set v to x
  47.     CDvx - Compare down, if block matches selected block then set v to x
  48.     CAvx - Compare all, if any block matches selected block then set v to x
  49.     --Placing blocks--
  50.     PF   - Place selected block forward
  51.     PU   - Place block upward
  52.     PD   - Place block downward
  53.     --Dropping items--
  54.     TF   - Drop forward items from selected slot
  55.     TU   - Drop upward items from selected slot
  56.     TD   - Drop downward items from selected slot
  57.     --Status packets (Not implimented yet)--
  58.     SI   - Send a packet back to a server with the current inventory
  59.     SF   - Send a packet back to a server with current fuel level
  60.     SG   - Send a packet back to a server with current GPS location and facing
  61.     SE   - Send a packet back to a server saying instructions completed (Maybe do automatically)
  62.     --Misc--
  63.     ED   - Add current instruction to the call stack
  64.     HT   - Halt instruction, ends program
  65.     RT   - Go to instuction at top of callstack, pop callstack
  66.     RF   - Refuel the turtle using fuel in current slot
  67.     TI   - Takes inventory of current blocks and items and updates inventory list
  68.     SSx  - Selects the slot with ID of x
  69.     WTx  - Waits for x number of seconds
  70.     FAx  - Adds x to top of function stack (used to load in function)
  71.     INv  - If v is 0 then set to 1, otherwise set to 0
  72.     CSvx - Checks slot x for items, if items exist then set v to 1 otherwise set v to 0
  73.     --Jump instructions--
  74.     JIx  - Jump to instruction x
  75.     FJx  - Jump to instruction stored in function array at index x, add current instruction + 1 to call stack
  76.     LJvx - Jump to instruction on top of stack unless v is x, also reduces v by 1 when jumping
  77.     BJvx - Jump to instruction on top of stack unless v is false/0
  78.     --Maths--
  79.     SUvx - Subtract x from v
  80.     ADvx - Add x to v
  81.     --Variables--
  82.     E1   - Number of spaces left in inventory
  83.     I1   - current instruction
  84.     B1-9 - Boolean value, 0 for false and 1 for true
  85.     A1   - Array of numbers, used to store a set of data to return as a packet later
  86.     N1-9 - Holds a number from 0 to 99
  87. --]]
  88.  
  89. --[[
  90.     All data packets have a set structure made of four sections
  91.     First Section - IP Address of target system
  92.     Second Section - IP Address of sending system
  93.     Third Section - Type of packet being sent (what protocol does packet follow)
  94.     Fourth Section - The main data the packet is transporting
  95.  
  96.     For testing, the IP address will be the same as the device ID.
  97.     In the future this will be changed to allow for proper routing and
  98.     security measures.
  99.  
  100.     The protocol the packet follows is a string in all caps
  101.     (CDP,ERP,DRP,UPP,etc) to allow for universal understanding (and style)
  102.  
  103.     An IP address of 0 for the target system means that the packet is for
  104.     the router to work with. Trying to assign a different device this IP will fail
  105.     as the router will intercept all packets with that IP.
  106. --]]
  107.  
  108.  
  109.  
  110.  
  111.  
  112. --Variables
  113. local networkDeviceSide = "left" --Change this to where network device is
  114. deviceType = "turtle"
  115. tIOSversion = "2.3.2"
  116. ipAddress = {-1,-1,-1}
  117. routerID = -1 --The computer ID of the router, allowing for responses to be returned
  118. message = {}
  119. packet = {}
  120. localFunctions = {}
  121. local instructionCount = 1
  122. local turtleInventory = {}
  123. local serverIP = {-1,-1,-1}
  124.  
  125. local callStack = {}
  126. local functionStack = {}
  127.  
  128. local variablesList = {
  129.     e1 = 0,
  130.     i1 = 0,
  131.     b1 = 0,
  132.     b2 = 0,
  133.     b3 = 0,
  134.     b4 = 0,
  135.     b5 = 0,
  136.     b6 = 0,
  137.     b7 = 0,
  138.     b8 = 0,
  139.     b9 = 0,
  140.     a1 = {},
  141.     n1 = 0,
  142.     n2 = 0,
  143.     n3 = 0,
  144.     n4 = 0,
  145.     n5 = 0,
  146.     n6 = 0,
  147.     n7 = 0,
  148.     n8 = 0,
  149.     n9 = 0
  150. }
  151.  
  152. local function sendPacket (
  153.         targetIP, --Table
  154.         protocol, --String
  155.         data --Any
  156. )
  157.     --[[
  158.         This function sends a packet to an IP address in the network.
  159.         Each packet needs to follow the rules of packet construction.
  160.         If the target IP is 0 then the packet will be sent to the default router.
  161.         If the sending IP is -1 then that means the IP hasn't been set yet
  162.         and will need to be to recieve packets from devices other than the router.
  163.     --]]
  164.     --Checking if there is a default router to send packet to, otherwise skip all code
  165.     if routerID == -1 then
  166.         print("Default router not set")
  167.         goto skip
  168.     end
  169.     --Checking if packet components have the right data types, otherwise skip all code
  170.     if not (type(targetIP) == "table") or not (type(protocol) == "string") then
  171.         print("Improperly formatted packet")
  172.         goto skip
  173.     end
  174.     --Packet construction
  175.     local packet = {
  176.         targetIP,
  177.         ipAddress,
  178.         protocol,
  179.         data
  180.     }
  181.     --Sending packet
  182.     print(targetIP[1].."."..targetIP[2].."."..targetIP[3] .. " " .. ipAddress[1].."."..ipAddress[2].."."..ipAddress[3] .. " " .. protocol .. " " .. type(data))
  183.     rednet.send(routerID,packet)
  184.     ::skip::
  185. end
  186.  
  187. local function digAll()
  188.     turtle.digDown()
  189.     turtle.dig()
  190.     turtle.digUp()
  191. end
  192.  
  193. local function takeInventory ()
  194.     variablesList["e1"] = 0
  195.     turtleInventory = {}
  196.     local itemInfo = {}
  197.     for i = 1, 16, 1 do
  198.         itemInfo = turtle.getItemDetail(i,true)
  199.         table.insert(turtleInventory,itemInfo)
  200.         if(itemInfo == nil) then
  201.             variablesList["e1"] = variablesList["e1"] + 1
  202.         end    
  203.     end
  204. end
  205.  
  206. local function addToCallStack ()
  207.     table.insert(callStack,instructionCount)
  208. end
  209.  
  210. local function returnTo()
  211.     instructionCount = callStack[#callStack]
  212.     table.remove(callStack,#callStack)
  213. end
  214.  
  215. local function sendInventory()
  216.     sendPacket(serverIP,"DP",{"inventory",turtleInventory})
  217. end
  218.  
  219. local function sendFuelLevel()
  220.     sendPacket(serverIP,"DP",{"fuel",turtle.getFuelLevel()})
  221. end
  222.  
  223. local function sendGPS()
  224.     sendPacket(serverIP,"DP",{"gps",gps.locate()})
  225. end
  226.  
  227. local function sendIntructionComplete()
  228.     sendPacket(serverIP,"DP",{"intruction","Completed"})
  229. end
  230.  
  231. local function jumpTo(count)
  232.     instructionCount = count
  233. end
  234.  
  235. local function functionJump(count)
  236.     table.insert(callStack,instructionCount+1)
  237.     instructionCount = functionStack[count]
  238. end
  239.  
  240. local function functionAdd(count)
  241.     table.insert(functionStack,count)
  242. end
  243.  
  244. local function loopJump(varName,count)
  245.     if variablesList[varName] > count and #callStack > 0 then
  246.         instructionCount = callStack[#callStack]
  247.         variablesList[varName] = variablesList[varName] - 1
  248.     elseif #callStack > 0 then
  249.         table.remove(callStack,#callStack)
  250.     end
  251. end
  252.  
  253. local function boolJump(varName,count)
  254.     if variablesList[varName] > 0 then
  255.         instructionCount = callStack[#callStack]
  256.     else
  257.         table.remove(callStack,#callStack)
  258.     end
  259. end
  260.  
  261. local function detectUp(varName,count)
  262.     if turtle.detectUp() then
  263.         variablesList[varName] = count
  264.     end
  265. end
  266.  
  267. local function detectFront(varName,count)
  268.     if turtle.detect() then
  269.         variablesList[varName] = count
  270.     end
  271. end
  272.  
  273. local function detectDown(varName,count)
  274.     if turtle.detectDown() then
  275.         variablesList[varName] = count
  276.     end
  277. end
  278.  
  279. local function detectAll(varName,count)
  280.     if (turtle.detectUp() or turtle.detect() or turtle.detectDown()) then
  281.         variablesList[varName] = count
  282.     end
  283. end
  284.  
  285.    
  286. local function compareUp(varName,count)
  287.     if turtle.compareUp() then
  288.         variablesList[varName] = count
  289.     end
  290. end
  291.  
  292. local function compareFront(varName,count)
  293.     if turtle.compare() then
  294.         variablesList[varName] = count
  295.     end
  296. end
  297.  
  298. local function compareDown(varName,count)
  299.     if turtle.compareDown() then
  300.         variablesList[varName] = count
  301.     end
  302. end
  303.  
  304. local function compareAll(varName,count)
  305.     if (turtle.compareUp() or turtle.compare() or turtle.compareDown()) then
  306.         variablesList[varName] = count
  307.     end
  308. end
  309.  
  310. local function addTo(varName,count)
  311.     varName = varName + count
  312. end
  313.  
  314. local function subFrom(varName,count)
  315.     varName = varName - count
  316. end
  317.  
  318. local function checkSlot(varName,count)
  319.     inventoryInfo = turtle.getItemDetail(count)
  320.     if inventoryInfo == nil then
  321.         varName = 0
  322.     else
  323.         varName = 1
  324.     end
  325. end
  326.  
  327. --Holds all of the basic turtle functions we may need
  328. local basicInstructionsDict = {
  329.     mf = turtle.forward,
  330.     mu = turtle.up,
  331.     md = turtle.down,
  332.     mb = turtle.back,
  333.     tr = turtle.turnRight,
  334.     tl = turtle.turnLeft,
  335.     du = turtle.digUp,
  336.     dd = turtle.digDown,
  337.     df = turtle.dig,
  338.     da = digAll,
  339.     pf = turtle.place,
  340.     pu = turtle.placeUp,
  341.     pd = turtle.placeDown,
  342.     tf = turtle.drop,
  343.     tu = turtle.dropUp,
  344.     td = turtle.dropDown,
  345.     rf = turtle.refuel,
  346.     ti = takeInventory,
  347.     ed = addToCallStack,
  348.     rt = returnTo,
  349.     si = sendInventory,
  350.     sf = sendFuelLevel,
  351.     sg = sendGPS,
  352.     se = sendIntructionComplete
  353. }
  354. --One Argument Instructions
  355. local advancedInstructionsDict = {
  356.     --si = , Uses networking functions combine with existing network code
  357.     --sf = ,
  358.     --sg = ,
  359.     --se = ,
  360.     ss = turtle.select,
  361.     wt = sleep,
  362.     fj = functionJump,
  363.     ji = jumpTo,
  364.     pp = print,
  365.     fa = functionAdd
  366. }
  367. --Two Argument Instructions
  368. local veryAdvancedInstructionsDict = {
  369.     lj = loopJump,
  370.     bj = boolJump,
  371.     iu = detectUp,
  372.     ii = detectFront,
  373.     id = detectDown,
  374.     ia = detectAll,
  375.     cu = compareUp,
  376.     cf = compareFront,
  377.     cd = compareDown,
  378.     ca = compareAll,
  379.     su = addTo,
  380.     ad = subFrom,
  381.     cs = checkSlot
  382. }
  383.  
  384. local function instructionExecuter(instructionSet)
  385.     instructionCount = 1
  386.     while instructionCount <= #instructionSet do
  387.     --for instructionCount = 1, #instructionSet, 1 do
  388.         local instruction = instructionSet[instructionCount]
  389.         --Checking for halt instruction
  390.         if instruction == "ht" then
  391.             goto breaking
  392.         end
  393.         --Checking functions
  394.         if basicInstructionsDict[instruction] then
  395.             --If instruction is basic then run it
  396.             basicInstructionsDict[instruction]()                   
  397.         elseif advancedInstructionsDict[instruction] then
  398.             --If instruction is advanced then run it, the next instruction should be an argument
  399.             --Index instructionCount one more time to account for argument
  400.             instructionCount = instructionCount + 1
  401.             if variablesList[instructionSet[instructionCount]] then
  402.                 advancedInstructionsDict[instruction](variablesList[instructionSet[instructionCount]])
  403.             else
  404.                 advancedInstructionsDict[instruction](tonumber(instructionSet[instructionCount]))
  405.             end    
  406.         elseif veryAdvancedInstructionsDict[instruction] then
  407.             --If instruction is very advanced then run it, the next two instructions should be arguments
  408.             instructionCount = instructionCount + 2
  409.             if variablesList[instructionSet[instructionCount]] then                
  410.                 veryAdvancedInstructionsDict[instruction](
  411.                     instructionSet[instructionCount-1],
  412.                     variablesList[instructionSet[instructionCount]]
  413.                 )
  414.             else
  415.                 veryAdvancedInstructionsDict[instruction](
  416.                     instructionSet[instructionCount-1],
  417.                     tonumber(instructionSet[instructionCount])
  418.                 )
  419.             end
  420.            
  421.            
  422.         elseif variablesList[instruction] then
  423.             --Checking variables
  424.             --If variable then set variable equal to next argument
  425.             instructionCount = instructionCount + 1
  426.             if variablesList[instructionSet[instructionCount]] then
  427.                 variablesList[instruction] = variablesList[instructionSet[instructionCount]]
  428.             else
  429.                 variablesList[instruction] = tonumber(instructionSet[instructionCount])
  430.             end    
  431.            
  432.         end
  433.         instructionCount = instructionCount + 1
  434.         variablesList["i1"] = instructionCount
  435.     end
  436.     ::breaking::
  437.     --Resetting the variables back to 0
  438.     local variablesList = {
  439.         e1 = 0,
  440.         i1 = 0,
  441.         b1 = 0,
  442.         b2 = 0,
  443.         b3 = 0,
  444.         b4 = 0,
  445.         b5 = 0,
  446.         b6 = 0,
  447.         b7 = 0,
  448.         b8 = 0,
  449.         b9 = 0,
  450.         a1 = {},
  451.         n1 = 0,
  452.         n2 = 0,
  453.         n3 = 0,
  454.         n4 = 0,
  455.         n5 = 0,
  456.         n6 = 0,
  457.         n7 = 0,
  458.         n8 = 0,
  459.         n9 = 0
  460.     }
  461. end
  462.  
  463. local function commandStringParser(commandString)
  464.     local tempString = ""
  465.     local instructionSet = {}
  466.     for i = 1, #commandString, 1 do
  467.         tempString = tempString .. string.sub(commandString,i,i)
  468.         if math.fmod(i,2) == 0 then
  469.             table.insert(instructionSet,tempString)
  470.             --print(tempString)
  471.             tempString = ""
  472.         end
  473.     end
  474.     return instructionSet
  475. end
  476.  
  477.  local function responseRDP ()
  478.     --[[
  479.     Router Discovery Protocol
  480.     Used by a router to discover other routers and build up a internetwork routing table.
  481.     After recieving a routing table, start adding it to router routing table
  482.     Routing table info:
  483.     1 - IP of router
  484.     2 - ID of next hop
  485.     3 - IP of next hop? (for future tracert)
  486.     4 - Number of hops to IP (To find shortest route)
  487.    
  488.     Routers will not have themselves on their own routing tables
  489.     --]]
  490. end
  491.  
  492. local function responseCDP ()
  493.     --[[
  494.     Computer Discovery Protocol
  495.     Used by a router to discover devices on the network then assign them IP addresses
  496.     and set itself as the device's default router. Devices already with an IP and
  497.     default router do not respond to CDP packets to avoid confusion on the side of
  498.     the router.
  499.     --]]
  500.     --If the device already has an IP and assigned Router then skip all code
  501.     if not (ipAddress == -1)  and not (routerID == -1) then goto skip end
  502.     --Sets the device's default router to the device ID that sent the packet
  503.     routerID = message[1]
  504.     --Send CDP packet to router (IP 0) with the ID of the device
  505.     sendPacket({0,0,0},"CDP",os.getComputerID())
  506.     --An IP packet should be sent in the near future to this device to assign IP
  507.     ::skip::
  508. end
  509.  
  510. local function responseERP ()
  511.     --[[
  512.         Echo Request Protocol is used to see if an IP address is responding.
  513.         Sending an ERP packet will cause the device to send a return packet back to the
  514.         source device.
  515.     --]]
  516.     if packet[4] == "Ping" then
  517.         sendPacket(packet[2],"ERP","pong")
  518.     end
  519. end
  520.  
  521. local function responseDRP ()
  522.     --Device Request Protocol
  523.     sendPacket(packet[2],"DRP",deviceType)
  524. end
  525.  
  526. local function responseUPP ()
  527.     --Unknown Packet Protocol
  528. end
  529.  
  530. local function responseIP ()
  531.     --[[
  532.     Internet Protocol
  533.     Used by router to give a device an IP address. Will only be accepted if the
  534.     router is the default router the device knows. If the default router is
  535.     unassigned then the IP packet is dropped. The data on the packet should
  536.     be a number.
  537.     --]]
  538.     --Checking if routerID is assigned
  539.     print(routerID)
  540.     if routerID == -1 then goto skip end
  541.     --Checking if routerID is the same as the message sender
  542.     if not (routerID == message[1]) then goto skip end
  543.     --Setting the IP of the device to the one sent by the router
  544.     ipAddress = packet[4]
  545.    
  546.     --Sending IP packet with the device type to the router
  547.     sendPacket({0,0,0},"IP",deviceType)
  548.     ::skip::
  549. end
  550.  
  551. local function responseDP ()
  552.     --Data  Packet (How to respond to generic data packets)
  553.     print("Instruct: " .. packet[4])
  554.     serverIP = packet[2]
  555.     instructionExecuter(commandStringParser(packet[4]))
  556. end
  557.  
  558. local function responseAP ()
  559.     --Acknowledgement Packet
  560. end
  561.  
  562.  
  563.  
  564. function mainLoop ()
  565.     --This function runs continuously and allows the device to respond to requests and packets
  566.     while true do
  567.         print("Ready to recieve message")
  568.         --Wait until rednet message recieved
  569.         message = {rednet.receive()}
  570.         --Pulling out the packet inside of the message
  571.         packet = (message[2])
  572.        
  573.         --Checking if packet is properly formatted, if it is not then drop packet and continue loop
  574.         if #packet < 4 then goto continue end
  575.         if not (packet[3] == "CDP") then
  576.             print("Packet Type: " .. packet[3])
  577.         end
  578.         if localFunctions["response"..packet[3]] then
  579.             --If protocol exists
  580.             if not (packet[3] == "CDP") then
  581.                 print("Running response "..packet[3])
  582.             end
  583.             localFunctions["response"..packet[3]]()
  584.             --table.insert(dataQueue,packet)
  585.         else  
  586.             --Send UPP packet to source device if protocol is unknown
  587.             print("Unknown")
  588.             sendPacket(packet[1],"UPP","Unknown Packet Type: "..packet[3])
  589.         end
  590.         --]]
  591.         ::continue::
  592.         --End of cycle upkeep
  593.         --Resetting last received message and packet back to their default states
  594.         message = {}
  595.         packet = {}
  596.     end
  597. end
  598.  
  599. --Finding all of the local functions and storing them
  600. index = 1
  601. while true do
  602.     key, data = debug.getlocal(1,index)
  603.     if not key then break end
  604.     --print(key)
  605.     if type(data) == "function" then
  606.         if debug.getinfo(data, "S").what == "Lua" then
  607.             localFunctions[key] = data
  608.         end
  609.     end
  610.     index = index + 1
  611. end
  612.  
  613. --Turning on the network capabilities of the device
  614. peripheralNames = peripheral.getNames()
  615. for i = 1, #peripheralNames, 1 do
  616.     if peripheral.hasType(peripheralNames[i],"modem") then
  617.         rednet.open(peripheralNames[i])
  618.     end
  619. end
  620. --Calling the mainLoop to start program
  621. print("tIOS version: v"..tIOSversion)
  622. print("Starting mainLoop")
  623. mainLoop()
  624.  
  625.  
  626.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement