Advertisement
eniallator

mControl

Jul 14th, 2015
5,070
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 10.83 KB | None | 0 0
  1. -- This is eniallator's Control program.
  2. -- It works by trying to run commands sent by the remote computer.
  3. -- The remote program (the program that can run this) is http://pastebin.com/MY9HDL52 and runs like a command line.
  4. --
  5. -- ================================================================================
  6. --
  7. -- An on going project that im still working on.
  8. --
  9. -- ================================================================================
  10. --
  11. -- This program can use plugins!
  12. -- The reason i have made it able to use plugins is so that you can easily install multiple function packs/functions by simply downloading the pastebin into the plugin folder
  13. -- To create a plugin, follow the plugin template guide here: http://pastebin.com/YmmnaqXP
  14. --
  15. -- ================================================================================
  16. --
  17. -- To create a new function in this file do the following steps.
  18. -- In the helpTable table put the following value.
  19. --
  20. -- *insert your function name here* = "*insert your function's help here*"
  21. --
  22. -- To make your function just add a new key/value to the functionTable on line 66 where the key is how you are going to call your function in the remote command line. For example inputting "testFunc arg1 arg2" would call the function testfunc from the functionTable and in the function argument it would then pass the following arguments: ({"arg1","arg2"},*ID of remote computer thats connected*,*protocol thats being used*).
  23. --
  24. -- If you want to send an output to the remote program from your function then use the following rednet code:
  25. --
  26. -- rednet.send(connectID, "*insert string you want to send here*", mProt)
  27. --
  28. -- If you would like to modify the prefix of the remote's command line then instead of sending a string through to the remote, send the following table:
  29. --
  30. -- {"*insert output you want to send here*","*insert prefix you want to send here*"}
  31. --
  32. -- If you want people to be able to turn on/off your function then do the following step.
  33. --
  34. -- *insert your function name here* = 1
  35. --
  36. -- The program will automatically detect if theres a status key/value for your function so thats all you need to do.
  37.  
  38. version = "1.2.2.1"
  39. -- Version is used for the updater program i've made here: http://pastebin.com/jSWFQsA1
  40.  
  41. mProt = "masterRC"
  42. rednet.open("right")
  43. -- mProt is the protocol the computer will be using. You can also configure what side the wireless modem is on
  44.  
  45. pluginFolder = "mControlPlugins"
  46. -- Where the plugins for the program are read from. Plugins are easily installable functions for the control program
  47.  
  48. myFunction = "Default mControl program!"
  49. -- Called when the remote computer lists available computers it can connect with
  50.  
  51. -- ======================= Default function declaring below =======================
  52.  
  53. functions = {
  54.  
  55. status = {upload = 1, download = 1, filelist = 1, redstone = 1},
  56. -- Easily configure which programs you want running and which ones you don't by simply setting 1 for those you want running and 0 for those you don't want running.
  57.  
  58. helpTable = {
  59.   upload = "upload a file to connected computer",
  60.   download = "download a file from connected computer",
  61.   filelist = "list files on connected computer",
  62.   redstone = "control sides of connected computer to emit redstone on"
  63. },
  64. -- Default help messages for each program
  65.  
  66. functionTable = {
  67.  
  68. help = function()
  69.  
  70.   rednet.send(connectID,help,mProt)
  71. end,
  72.  
  73. upload = function (item)
  74.   if fs.exists(item[2]) == false then
  75.  
  76.     rednet.send(connectID, "send", mProt)
  77.     uselessID, downloadedFile = rednet.receive(mProt)
  78.     openFile = fs.open(item[2], 'w')
  79.     openFile.write(downloadedFile)
  80.     openFile.close()
  81.   else
  82.  
  83.     rednet.send(connectID, "File already exists on connected computer.", mProt)
  84.   end
  85.   -- Handles the upload function
  86. end,
  87.  
  88. download = function (item)
  89.   if fs.exists(item[1]) == true and fs.isDir(item[1]) == false then
  90.  
  91.     fileOpen = fs.open(item[1], 'r')
  92.     stringSend = fileOpen.readAll()
  93.     fileOpen.close()
  94.     tableSend = {stringSend, "Successfully downloaded file."}
  95.     rednet.send(connectID, tableSend, mProt)
  96.   else
  97.  
  98.     rednet.send(connectID, "File does not exist on connected computer.", mProt)
  99.   end
  100.   -- Handles the download function
  101. end,
  102.  
  103. filelist = function ()
  104.  
  105.   programList = fs.list("")
  106.   files = ""
  107.  
  108.   for i=1,#programList do
  109.     if fs.isDir(programList[i]) == false then
  110.       if files == "" then
  111.  
  112.         files = programList[i]
  113.       else
  114.  
  115.         files = files .. ", " .. programList[i]
  116.       end
  117.     end
  118.   end
  119.   -- Handles the fileList function by sending a list of files (not directories) through
  120.  
  121.   rednet.send(connectID, files, mProt)
  122. end,
  123.  
  124. redstone = function(item)
  125.   if item[1] == "top" or item[1] == "down" or item[1] == "back" or item[1] == "front" or item[1] == "left" or item[1] == "right" then
  126.     if item[2] == "on" then
  127.  
  128.       -- First checks to see if item[1] is a valid side then checks if item[2] is a valid state
  129.       redstone.setOutput(item[1], true)
  130.       rednet.send(connectID, "Set output " .. item[1] .. " to " .. item[2], mProt)
  131.       -- Turns the side in item[1] on
  132.  
  133.     elseif item[2] == "off" then
  134.  
  135.       redstone.setOutput(item[1], false)
  136.       rednet.send(connectID, "Set output " .. item[1] .. " to " .. item[2], mProt)
  137.       -- Turns the side in item[1] off
  138.     else
  139.  
  140.       rednet.send(connectID, 'Invalid syntax. Use "redstone [side] [on/off]"', mProt)
  141.     end
  142.   else
  143.  
  144.     rednet.send(connectID, 'Invalid side. Available sides are: top, down, back, front, left, right', mProt)
  145.   end
  146.   -- Error messages to catch every combination
  147. end
  148. }
  149. }
  150.  
  151. -- ============================ Plugin handling below =============================
  152.  
  153. local args = { ... }
  154.  
  155. if args[1] then
  156.  
  157. pluginFolder = args[1] .. "/" .. pluginFolder
  158. end
  159. -- Seeing if when running the program you have specified a folder in the arguments
  160.  
  161. tablesToMerge = {"status", "helpTable", "functionTable"}
  162. -- Defining what tables are okay to merge with the plugin's table
  163.  
  164. function mergeTable(mergeTab, tabName)
  165. for key, value in pairs(mergeTab) do
  166.   functions[tabName][key:lower()] = value
  167. end
  168. end
  169. -- Function for merging 2 tables
  170.  
  171. if not fs.exists(pluginFolder) then
  172. fs.makeDir(pluginFolder)
  173. end
  174. -- Checking if the plugin folder is a directory yet or not and if its not then it creates it
  175.  
  176. pluginFiles = fs.list(pluginFolder)
  177.  
  178. for i=1,#pluginFiles do
  179. if not fs.isDir(pluginFolder .. pluginFiles[i]) then
  180.  
  181.   os.loadAPI(pluginFolder .. "/" .. pluginFiles[i])
  182.  
  183.   for j=1,#tablesToMerge do
  184.     if _G[pluginFiles[i]][tablesToMerge[j]] then
  185.  
  186.       mergeTable(_G[pluginFiles[i]][tablesToMerge[j]], tablesToMerge[j])
  187.     end
  188.   end
  189. end
  190. end
  191. -- Merging the existing table with the plugin's table
  192.  
  193. -- ========================== Help string handling below ==========================
  194.  
  195. help = "exit - Disconnects from current connected computer\n"
  196.  
  197. for program, progHelp in pairs(functions.helpTable) do
  198. if functions.status[program] == 1 then
  199.   help = help .. program .. " - " .. progHelp .. "\n"
  200. end
  201. end
  202.  
  203. help = help:sub(1,string.len(help) - 1)
  204. -- Creates the help variable from the programs that are active
  205.  
  206. -- ====================== Putting everything together below =======================
  207.  
  208. function progRunning()
  209.  
  210. local terminate = false
  211. -- Declaring the terminate variable as false
  212.  
  213. repeat
  214.  
  215.   local ID, newMsg = rednet.receive(mProt)
  216.   -- Getting the connected computer's messages
  217.  
  218.   if ID == sendID and connected then
  219.   -- Checking if the computer that sent the message is the connected computer aswell as seeing if the connected variable is still true
  220.  
  221.     local newMsgIsWord = newMsg ~= ""
  222.     -- Checking if the incoming message is a word or not
  223.  
  224.     if newMsgIsWord and newMsg[1]:lower() == "terminate" then
  225.  
  226.       terminate = true
  227.       rednet.send(ID, "Terminated " .. funcToRun .. ".", mProt)
  228.       -- Seeing if the connected computer has sent "terminate" through and setting the terminate variable to true if they have
  229.     elseif newMsgIsWord and newMsg[1]:lower() == "exit" then
  230.  
  231.       connected = false
  232.       rednet.send(ID, "Disconnecting from current computer but continuing to run " .. funcToRun .. ".", mProt)
  233.       -- Still executing current function even if connected computer has exitted
  234.  
  235.     elseif newMsgIsWord and newMsg[1]:lower() == "fuel" and turtle then
  236.  
  237.       rednet.send(ID, "Fuel level currently at: " .. turtle.getFuelLevel(), mProt)
  238.       -- Sending the current fuel level through to the connected computer
  239.     else
  240.  
  241.       local sendMessage = "Currently executing " .. funcToRun .. ". Available commands are -\nterminate: terminate current function\nexit: continue to run function but disconnect."
  242.       -- Defining the message variable to send
  243.  
  244.       if turtle and turtle.getFuelLevel() ~= "unlimited" then
  245.         sendMessage = sendMessage .. "\nfuel: get the fuel level"
  246.       end
  247.       -- Adding fuel to the help if the connected computer is a turtle
  248.  
  249.       rednet.send(ID, sendMessage, mProt)
  250.       -- Responding to the user if they send a message
  251.     end
  252.   end
  253.  
  254. until terminate
  255. -- Runs until the terminate variable is true
  256. end
  257. -- Function to respond to the connected computer while the local computer is running a function
  258.  
  259. function callFunc()
  260.  
  261. functions.functionTable[funcToRun](msg, connectID, mProt)
  262. end
  263. -- Function for calling the correct function
  264.  
  265. while true do
  266. sendID, msg = rednet.receive(mProt)
  267.  
  268.   if msg == "list" then
  269.     rednet.send(sendID, myFunction, mProt)
  270.     -- Will respond to computers that are running list unless running connect
  271.  
  272.   elseif msg == "connect" then
  273.     rednet.send(sendID, {"Connected!",functions.status}, mProt)
  274.     -- Making the link from the mRemote program to the mControl program
  275.  
  276.     connected = true
  277.  
  278.     while connected do
  279.       invalid = true
  280.       connectID, msg = rednet.receive(mProt)
  281.       -- Getting the new message from the connected computer
  282.  
  283.       if connectID == sendID then
  284.         -- Comparing the connectID with the sendID to see if its the same id so no other computer can send messages
  285.         if msg[1] ~= nil then
  286.  
  287.           msg[1] = msg[1]:lower()
  288.         end
  289.  
  290.         if msg[1] == "exit" then
  291.  
  292.           rednet.send(connectID,"Disconnecting from current computer.",mProt)
  293.           invalid = false
  294.           connected = false
  295.           -- Exits the connect cycle so that it will respond to list and for other computers to connect to it
  296.         end
  297.  
  298.         for key,value in pairs(functions.functionTable) do
  299.           if key == msg[1] then
  300.  
  301.             invalid = false
  302.             table.remove(msg,1)
  303.             funcToRun = key
  304.             parallel.waitForAny(callFunc,progRunning)
  305.           end
  306.         end
  307.  
  308.         if invalid then
  309.  
  310.           rednet.send(connectID, 'Invalid command. Type "help" for options.', mProt)
  311.           -- Default path if msg[1] doesn't get caught by the for loop
  312.         end
  313.       end
  314.     end
  315.   end
  316. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement