View difference between Paste ID: bALCJDvf and ss0BX2mM
SHOW: | | - or go back to the newest paste.
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")
42+
rednet.open("back")
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