Advertisement
melzneni

universal_installer

Mar 23rd, 2020
221
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.62 KB | None | 0 0
  1. local argsSource = { ... }
  2.  
  3. function splitText(source, letters)
  4. local parts = {}
  5. local akt = "";
  6. local qM1 = 0; local qM2 = 0; local b1 = 0; local b2 = 0; local b3 = 0;
  7. for i = 1, #source do
  8. local z = string.sub(source, i, i)
  9. if z == "'" and qM2 == 0 then qM1 = 1 - qM1;
  10. elseif z == "\"" and qM1 == 0 then qM2 = 1 - qM2;
  11. elseif qM1 == 0 and qM2 == 0 then
  12. if z == "(" then b1 = b1 + 1
  13. elseif z == ")" then b1 = b1 - 1
  14. elseif z == "[" then b2 = b2 + 1
  15. elseif z == "]" then b2 = b2 - 1
  16. elseif z == "{" then b3 = b3 + 1
  17. elseif z == "}" then b3 = b3 - 1
  18. end
  19. end
  20. local split = false
  21. if b1 == 0 and b2 == 0 and b3 == 0 and qM1 == 0 and qM2 == 0 then
  22. for j = 1, #letters do
  23. if z == string.sub(letters, j, j) then
  24. split = true
  25. break
  26. end
  27. end
  28. end
  29. if split then
  30. if akt ~= "" then
  31. table.insert(parts, akt)
  32. akt = ""
  33. end
  34. else akt = akt .. z
  35. end
  36. end
  37. if akt ~= "" then table.insert(parts, akt) end
  38. return parts
  39. end
  40.  
  41. local args = {}
  42.  
  43. local TYPE_DECLARATION = 0
  44. local TYPE_TABLE = 1
  45. local TYPE_TABLE_MAP = 1
  46. local TYPE_TABLE_ARR = 2
  47. local TYPE_VALUE = 2
  48. local TYPE_CONSTANT = 3
  49. local TYPE_PASTEBIN = 4
  50.  
  51. if peripheral == nil then
  52. _G.os.reboot = function() print("fct: os.reboot()") end
  53. _G.os.setComputerLabel = function(label) print("fct: os.setComputerLabel(\""..label.."\")") end
  54. end
  55.  
  56. function getTypeName(t)
  57. if t == TYPE_DECLARATION then return "declaration"
  58. elseif t == TYPE_TABLE then return "table"
  59. elseif t == TYPE_VALUE then return "value"
  60. elseif t == TYPE_CONSTANT then return "constant"
  61. elseif t == TYPE_PASTEBIN then return "pastebin"
  62. else error("unknown type: " .. t)
  63. end
  64. end
  65.  
  66. function loadArgData(arg)
  67. local v = loadVar(arg)
  68. if v.type ~= TYPE_DECLARATION then
  69. error("every argument of this program needs to be of type 'declaration'")
  70. end
  71. return v
  72. end
  73.  
  74. function readFileText(file)
  75. local f = fs.open(file, "r")
  76. local text = f.readAll()
  77. f.close()
  78. return text
  79. end
  80.  
  81. function tryMatches(var, format, name)
  82. if not string.match(var, format) == var then error("invalid " .. name .. ": '" .. var .. "'") end
  83. end
  84.  
  85. function loadVar(source)
  86.  
  87. local pts = splitText(source, "=")
  88. if #pts > 1 then
  89. if #pts > 2 then error("only one '=' in declaration") end
  90. tryMatches(pts[1], "[A-Za-z_][A-Za-z0-9_]*", "dec-name")
  91. return { type = TYPE_DECLARATION, name = pts[1], value = loadVar(pts[2]) }
  92. end
  93.  
  94. if string.sub(source, 1, 1) == "{" and string.sub(source, #source) == "}" then
  95. local pts = splitText(string.sub(source, 2, #source - 1), ",")
  96. local values = {}
  97. for i, pt in pairs(pts) do
  98. local v = loadVar(pt)
  99. if v.type == TYPE_DECLARATION then
  100. values[v.name] = v.value
  101. else table.insert(values, v)
  102. end
  103. end
  104. return { type = TYPE_TABLE, values = values }
  105. elseif string.sub(source, 1, 1) == "<" and string.sub(source, #source) == ">" then
  106. source = string.sub(source, 2, #source - 1)
  107. local ind = string.find(source, ":")
  108. local action = string.sub(source, 1, ind - 1)
  109. tryMatches(action, "[A-Za-z_][A-Za-z0-9_]*", "action-name")
  110. if action == "pb" then
  111. local id = string.sub(source, ind + 1)
  112. tryMatches(id, "[A-Za-z_][A-Za-z0-9_]*", "pastebinId-name")
  113. return { type = TYPE_PASTEBIN, id = id }
  114. elseif action == "input" then
  115. local v = loadVar(string.sub(source, ind + 1))
  116. if v.type ~= TYPE_VALUE or type(v.value) ~= "string" then error("string value expected for function <input:''>") end
  117. io.write("input<" .. v.value .. ">: ")
  118. local data = io.read()
  119. return { type = TYPE_VALUE, value = data }
  120. elseif action == "inputNum" then
  121. local v = loadVar(string.sub(source, ind + 1))
  122. if v.type ~= TYPE_VALUE or type(v.value) ~= "string" then error("string value expected for function <input:''>") end
  123. io.write("inputNum<" .. v.value .. ">: ")
  124. local data = tonumber(io.read())
  125. return { type = TYPE_VALUE, value = data }
  126. else error("unknown action: '" .. action .. "'")
  127. end
  128. elseif string.sub(source, 1, 1) == "'" and string.sub(source, #source) == "'" then
  129. return { type = TYPE_VALUE, value = string.sub(source, 2, #source - 1) }
  130. elseif string.sub(source, 1, 1) == "$" and string.sub(source, #source) == "$" then
  131. local name = string.sub(source, 2, #source - 1)
  132. return { type = TYPE_CONSTANT, name = name }
  133. elseif source == "true" or source == "false" then
  134. return { type = TYPE_VALUE, value = source == "true" }
  135. elseif tonumber(source) ~= nil then
  136. return { type = TYPE_VALUE, value = tonumber(source) }
  137. else error("invalid source: '" .. source .. "'")
  138. end
  139. end
  140.  
  141. function checkType(name, value, t, t2)
  142. if value.type ~= t then
  143. error("value '" .. name .. "' needs to be of type '" .. getTypeName(t) .. "' (type '" .. getTypeName(value.type) .. "' given)")
  144. end
  145. if t2 ~= nil then
  146. if value.type == TYPE_TABLE then
  147. if t2 == TYPE_TABLE_MAP then
  148. for i, _ in pairs(value.values) do
  149. if type(i) == "number" then
  150. error("table '" .. name .. "' needs to be a map")
  151. end
  152. end
  153. elseif t2 == TYPE_TABLE_ARR then
  154. for i, _ in pairs(value.values) do
  155. if type(i) == "string" then
  156. error("table '" .. name .. "' needs to be an array")
  157. end
  158. end
  159. else error("unknown type2: '" .. t2 .. "'")
  160. end
  161. elseif value.type == TYPE_VALUE then
  162. if type(value.value) ~= t2 then error("value '" .. name .. "' needs to be of type '" .. t2 .. "' (type '" .. type(value.value .. "' given)")) end
  163. end
  164. end
  165. end
  166.  
  167. function writeToFile(fileName, data)
  168. local f = fs.open(fileName, "w")
  169. f.write(data)
  170. f.close()
  171. end
  172.  
  173. local startupBuildData = {
  174. files = {},
  175. cmds = {}
  176. }
  177.  
  178. local reboot = false
  179.  
  180. local functions = {
  181. startup = {
  182. delay = function(data)
  183. checkType("startup>delay", data, TYPE_VALUE, "number")
  184. startupBuildData.delay = data.value
  185. end,
  186. files = function(data)
  187. checkType("startup>files", data, TYPE_TABLE, TYPE_TABLE_MAP)
  188. for fileName, v in pairs(data.values) do
  189. checkType("startup>files>value", v, TYPE_PASTEBIN)
  190. table.insert(startupBuildData.files, { name = fileName, id = v.id })
  191. end
  192. end,
  193. cmds = function(data)
  194. checkType("startup>cmds", data, TYPE_TABLE, TYPE_TABLE_ARR)
  195. for i, cmd in pairs(data.values) do
  196. checkType("startup>cmds>cmd", cmd, TYPE_TABLE, TYPE_TABLE_ARR)
  197. table.insert(startupBuildData.cmds, cmd.values)
  198. end
  199. end
  200. },
  201. reboot = function(data)
  202. checkType("reboot", data, TYPE_VALUE, "boolean")
  203. reboot = data.value
  204. end,
  205. label = function(data)
  206. checkType("label", data, TYPE_VALUE, "string")
  207. os.setComputerLabel(data.value)
  208. end
  209. }
  210.  
  211. for i, v in pairs(argsSource) do
  212. table.insert(args, loadArgData(v))
  213. end
  214.  
  215. function printTable(tbl)
  216. printTableIndex(tbl, "", {})
  217. end
  218.  
  219. function printTableIndex(tbl, before, alreadyUsed)
  220. for i, v in pairs(tbl) do
  221. if type(v) == "table" then
  222. if tableContainsValue(alreadyUsed, v) then
  223. print(before .. i .. ":", "alreadyUsed");
  224. else
  225. print(before .. i .. ": [");
  226. table.insert(alreadyUsed, v)
  227. printTableIndex(v, before .. "\t", alreadyUsed)
  228. print(before .. "]")
  229. end
  230. else
  231. print(before .. i .. ":", v);
  232. end
  233. end
  234. end
  235.  
  236. function tableContainsValue(table, value)
  237. for i, v in pairs(table) do
  238. if v == value then return true end
  239. end
  240. return false
  241. end
  242.  
  243. function executeFunction(tName, name, data, functions)
  244. for n, fct in pairs(functions) do
  245. if name == n then
  246. if type(fct) == "table" then
  247. tName = tName .. "[" .. name .. "]"
  248. checkType(tName .. ".value", data, TYPE_TABLE, TYPE_TABLE_MAP)
  249. for n1, v in pairs(data.values) do
  250. executeFunction(tName, n1, v, fct)
  251. end
  252. else
  253. fct(data)
  254. end
  255. return
  256. end
  257. end
  258. error("function-name '" .. name .. "' isn't allowed for '" .. tName .. "'")
  259. end
  260.  
  261. function writeToFile(fileName, data)
  262. if fs == nil then
  263. local f = io.open(fileName, "w")
  264. io.output(f)
  265. io.write(data)
  266. io.close(f)
  267. else
  268. local f = fs.open(fileName, "w")
  269. f.write(data)
  270. f.close()
  271. end
  272. end
  273.  
  274. for i, v in pairs(args) do
  275. local tName = "level0-argument"
  276. executeFunction(tName, v.name, v.value, functions)
  277. --[[local fct = functions
  278. while type(fct) == "table" do
  279. for i,v1 in pairs(v.values) do
  280. checkType(tName, v, TYPE_DECLARATION)
  281.  
  282. local name = v.name
  283. local value = v.value
  284. local fct = functions[v.name]
  285. if fct == nil then error(tName .. " '" .. v.name .. "' isn't defined") end
  286. end
  287. end]]
  288. end
  289.  
  290. function replaceConstants(v, constants)
  291. if v.type == TYPE_CONSTANT then
  292. if constants[v.name] ~= nil then
  293. return { type = TYPE_VALUE, value = constants[v.name] }
  294. end
  295. elseif v.type == TYPE_TABLE then
  296. for i, v1 in pairs(v.values) do
  297. v.values[i] = replaceConstants(v1, constants)
  298. end
  299. elseif v.type ~= TYPE_VALUE then
  300. error("unsupported type: '" .. getTypeName(v.type) .. "'")
  301. end
  302. return v
  303. end
  304.  
  305. local txt = "local args={...}\n"
  306.  
  307. if startupBuildData.delay ~= nil then
  308. txt = txt .. "sleep(" .. startupBuildData.delay .. ")\n"
  309. end
  310.  
  311. for i, f in pairs(startupBuildData.files) do
  312. txt = txt .. "if fs.exists(\""..f.name.."\") then shell.run(\"delete\",\"" .. f.name .. "\") end\n"
  313. txt = txt .. "shell.run(\"pastebin\",\"get\",\"" .. f.id .. "\",\"" .. f.name .. "\")\n"
  314. end
  315.  
  316. for i, cmd in pairs(startupBuildData.cmds) do
  317. cmd = replaceConstants({ type = TYPE_TABLE, values = cmd }, { arg1 = "raw:args[1]", arg2 = "raw:args[2]" }).values
  318. for i, v in pairs(cmd) do
  319. checkType("cmds>cmd", v, TYPE_VALUE, "string")
  320. end
  321. txt = txt .. "shell.run("
  322. for i, v in pairs(cmd) do
  323. if i ~= 1 then txt = txt .. "," end
  324. if string.sub(v.value, 1, 4) == "raw:" then
  325. txt = txt .. string.sub(v.value, 5)
  326. else txt = txt .. "\"" .. v.value .. "\""
  327. end
  328. end
  329. txt = txt .. ")\n"
  330. end
  331.  
  332.  
  333. writeToFile("startup", txt)
  334.  
  335. if reboot then
  336. os.reboot()
  337. end
  338.  
  339. --[[
  340. local args = {}
  341. for i, v in pairs(argsSource) do
  342. if string.find(v, "=") ~= nil then
  343. local ind = string.find(v, "=")
  344. args[string.sub(v, 1, ind - 1)] = string.sub(v, ind + 1)
  345. else args[i] = v
  346. end
  347. end
  348.  
  349. local reboot = false
  350. local actions = {}
  351. for key, arg in pairs(args) do
  352. if type(key) == "number" then
  353. if arg == "reboot" then
  354. reboot = true
  355. else error("unknown argument: " .. arg)
  356. end
  357. else
  358. if key == "startup" then
  359. table.insert(actions, function()
  360. local f = fs.open("startup", "w")
  361. f.write("shell.run(\"delete\",\"unitHandler\")\n")
  362. f.write("shell.run(\"pastebin\",\"get\",\"" .. arg .. "\",\"unitHandler\")\n")
  363. f.write("shell.run(\"unitHandler\")\n")
  364. f.close()
  365. print("successfully set startup to '" .. arg .. "'")
  366. end)
  367. elseif key == "label" then
  368. table.insert(actions, function()
  369. os.setComputerLabel(arg)
  370. print("successfully set label to '" .. arg .. "'")
  371. end)
  372. else error("unknown argument-key: " .. key)
  373. end
  374. end
  375. end
  376.  
  377. for i = 1, #actions do
  378. actions[i]()
  379. end
  380.  
  381. if reboot then os.reboot() end
  382.  
  383.  
  384. ]]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement