Advertisement
NuAoA

Untitled

Apr 19th, 2013
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 213.98 KB | None | 0 0
  1. --[[
  2. RedOS
  3. Version: 0.3.5.90
  4. By: NuAoA
  5. Feel free to copy parts of the code (just let me know if you do somthing cool with it)
  6. pastebin get VekE809i startup
  7. ----------
  8. ----------
  9.  
  10. --0.3.6.0 --
  11. BugFixes:
  12. - Fixed tons of bugs caused by the CC rednet update.
  13. - Fixed the issue that caused computers to become copies of other terminals (I think)
  14. - Fixed a bug that allowed nil strings being accepted in userInput()
  15. - Fixed a bug in the signal selection window that caused a crash
  16. - Fixed custom UI's from staying 'highlighted' after selection
  17. - added some conditionals that should make checkLogic() run a bit faster, because why not.
  18. - Fixed a bug that caused refreshDisplay() to be called about ~3/sec. now its down to pretty much only when nessessary.
  19. - Fixed a small glitch in boxDrag() that erased the last created pixel
  20.  
  21. New Features:
  22. - Custom UI's can now toggle signals with a left click (or monitor touch) event.
  23. - Custom UI objects now display their off color even if they are not connected to a signal. So creating custom colors wont require you to hook the object to a signal before displaying.
  24. - Requested passwords are now replaced with **** when entered.
  25. - A locked terminal can't be 'terminated' anymore. restarting works fine, but will just boot into the locked screen. Attached monitors can still touched while locked.
  26. - Added the ability to check for updates (and download them).
  27. ----------
  28. ----------
  29. TODO:
  30.  
  31. 1) Figure out how to run custom scripts in parallel with the program on demand.
  32. 2) figure out how to make all logic update on the same tick.
  33. 3) add a transparent color to the custom UI
  34. 4) rewrite the "monitor_touch" event so that it works regardless of the screen the terminal is on.
  35. 4) make boxDrag() erase stuff while still dragging.
  36. --]]
  37.  
  38. ------Paste download------
  39. --------------------------
  40. local paste = "2jb4LRYJ" -- Public code
  41. --------------------------
  42.  
  43.  
  44. local DEBUG = true -- set to false to disable debug file and auto updates on boot.
  45. if DEBUG then
  46. paste = "qACY0ffj" -- Possibly unstable verson of redOS. (latest)
  47. local file = fs.open("debug","w")
  48. file.write("RedOS debug file \n")
  49. file:close()
  50. end
  51.  
  52. function Debug(text)
  53. if DEBUG then
  54. local file = fs.open("debug","r")
  55. local curr = file.readAll()
  56. file:close()
  57. file = fs.open("debug","w")
  58. file.write(curr.."\n"..tostring(text))
  59. file:close()
  60. end
  61. end
  62.  
  63. term.clear()
  64. local lastimage = {}
  65. local hexnums = { [10] = "a", [11] = "b", [12] = "c", [13] = "d", [14] = "e" , [15] = "f" }
  66. local comp_faces = {"Front","Back","Left","Right","Top","Bottom"}
  67. local sig_faces = {"Front","Back","Left","Right","Top","Bottom","Virtual"}
  68. local sig_names = {"White","Orange","Magenta","LightBlue","Yellow","Lime","Pink","Gray","LightGray","Cyan","Purple","Blue","Brown","Green","Red","Black"}
  69. local sig_values = {1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768}
  70. local HeaderNames = {"Options","View","Cable","Network"}
  71. local networkedIDs = {}
  72. local canRefresh = true -- Check if its ok to refresh the screen (prevents pulldowns from closing)
  73. local splashdone = false -- becomes true when the splash screen is finished, so that parallel code knows whats up.
  74. local monFace = nil -- current face of an attached monitor
  75. local mon = nil -- monitor "node"
  76. local networkNames = {} -- Will stay updated with the names of any computer on the network
  77. local UI_c,UI_t -- Color and text tables for the custom UI
  78. local header_c,header_t -- Color and text tables for the file menu
  79. local signal = {} -- This will store the current state of all redstone singals on the PC
  80. local logic = {} -- Stores all logic for the local terminal.
  81. local meta = {} -- Stores meta data, like computer name, password, ID, computers to boot into, etc.
  82. local tick = 0.1 -- the tick between redstone updates, increase this if you have problems with lag
  83. local global_tick = 1 -- counts up to infinity, used to pulse signals
  84. local ValidChars = {
  85. "\"","#","$","%","&","'","(",")","*","+",",","-",".","/","0","1","2","3",
  86. "4","5","6","7","8","9",":",";","<","=",">","?","@","A","B","C","D","E","F","G",
  87. "H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","[",
  88. "\\","]","^","_","`","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o",
  89. "p","q","r","s","t","u","v","w","x","y","z","{","}","~"," "
  90. }
  91. local CharToCode = {}
  92. local CodeToChar = {}
  93. for _, c in pairs(ValidChars) do
  94. local code = #CodeToChar+1
  95. CharToCode[c] = code
  96. CodeToChar[code] = c
  97. end
  98.  
  99. function meta_setup(...)
  100. local ID = os.getComputerID()
  101. if #arg>0 then
  102. ID = arg[1]
  103. end
  104. local c,t = emptyScreen(term)
  105. local tab = {}
  106. local ui_temp = {["table"] = c,["text"] =t }
  107. tab["computerName"] = "Computer "..ID
  108. tab["password"] = ""
  109. tab["ID"] = ID
  110. tab["isLocked"] = false --Locked
  111. tab["isRead"]= false --ReadOnly
  112. tab["showCustom"] = true
  113. tab["bootInto"] = ID
  114. tab["customUI"] = {[0] = ui_temp}
  115. return deepcopy(tab)
  116. end
  117.  
  118. --Temp default signal, will have to load a custom one on boot.
  119. function signal_setup(...)
  120. local sig = {}
  121. local sig2 = {}
  122. local ID = os.getComputerID()
  123. if #arg > 0 then
  124. ID = arg[1]
  125. end
  126. local sig_temp = {["isBundle"] = false,["value"] = false,["isRead"] = true,["hasScript"] = false,["hasUI"] = false}
  127. for i=1,#sig_faces do
  128. sig[sig_faces[i]] = deepcopy(sig_temp)
  129. if i == 7 then
  130. sig[sig_faces[i]]["isBundle"] = true
  131. sig[sig_faces[i]]["isRead"] = false
  132. sig[sig_faces[i]]["value"] = 0
  133. end
  134. end
  135.  
  136. sig2[ID] = deepcopy(sig)
  137. return deepcopy(sig2)
  138. end
  139.  
  140. function logic_setup()
  141. local sig = {}
  142. local sig_temp2 ={}
  143. local node = {["and"] = nil,["or"] = nil}
  144. local sig_temp = {["if"] = node,["else"] = false,["then"] = true,["toggle"] = false}
  145. for i=1,#sig_faces do
  146. sig_temp2[0] = sig_temp
  147. for j=1,#sig_values do
  148. sig_temp2[sig_values[j]] = sig_temp
  149. end
  150. sig[sig_faces[i]] = sig_temp2
  151. end
  152. return deepcopy(sig)
  153. end
  154.  
  155. ----------------------------------------------------------------
  156. -----------------------------[ Utility ]------------------------
  157. ----------------------------------------------------------------
  158. function checkUpdates(...)
  159. term.clear()
  160. term.setCursorPos(1,1)
  161. shell.run("pastebin get "..paste.." startup.temp")
  162. file = fs.open("startup.temp","r")
  163. local version = string.match(file.readAll(),"Version: %d+.%d+.%d+.%d+")
  164. local a,b,c,d = string.match(version,"Version: (%d+).%d+.%d+.%d+"),string.match(version,"Version: %d+.(%d+).%d+.%d+"),string.match(version,"Version: %d+.%d+.(%d+).%d+"),string.match(version,"Version: %d+.%d+.%d+.(%d+)")
  165. file:close()
  166. file = fs.open("startup","r")
  167. local version2 = string.match(file.readAll(),"Version: %d+.%d+.%d+.%d+")
  168. local a2,b2,c2,d2 = string.match(version2,"Version: (%d+).%d+.%d+.%d+"),string.match(version2,"Version: %d+.(%d+).%d+.%d+"),string.match(version2,"Version: %d+.%d+.(%d+).%d+"),string.match(version2,"Version: %d+.%d+.%d+.(%d+)")
  169. file:close()
  170. if tonumber(a)>tonumber(a2) or tonumber(b)>tonumber(b2) or tonumber(c)>tonumber(c2) or tonumber(d)>tonumber(d2) then
  171. if arg[1] or userInput("An update is available, would you like to update now? ("..string.match(version,"Version: (%d+.%d+.%d+.%d+)")..")",true) then
  172. fs.delete("startup")
  173. fs.copy("startup.temp","startup")
  174. fs.delete("startup.temp")
  175. os.reboot()
  176. end
  177. elseif not arg[1] then
  178. userInput("This version is up to date! ("..string.match(version,"Version: (%d+.%d+.%d+.%d+)")..")")
  179. end
  180. fs.delete("startup.temp")
  181. end
  182. -- Call to fully copy a table (table1=table2 will write changes to table1 back onto table2, deepcopy bypasses this)
  183. function deepcopy(orig)
  184. local orig_type = type(orig)
  185. local copy
  186. if orig_type == 'table' then
  187. copy = {}
  188. for orig_key, orig_value in next, orig, nil do
  189. copy[deepcopy(orig_key)] = deepcopy(orig_value)
  190. end
  191. setmetatable(copy, deepcopy(getmetatable(orig)))
  192. else -- number, string, boolean, etc
  193. copy = orig
  194. end
  195. return copy
  196. end
  197. --This function will copy everything in signal ignoring the values
  198. function deepcopySignal(sig)
  199. local sig_temp = deepcopy(sig)
  200. for i=1,#sig_faces do
  201. sig_temp[os.getComputerID()][sig_faces[i]]["value"] = signal[os.getComputerID()][sig_faces[i]]["value"]
  202. end
  203. return deepcopy(sig_temp)
  204. end
  205. function printTab(tab,...)
  206. local orig_type = type(tab)
  207. local copy
  208. if orig_type == 'table' then
  209. copy = {}
  210. for orig_key, orig_value in next, tab, nil do
  211. term.write(orig_key.." ")
  212. copy[deepcopy(orig_key)] = deepcopy(orig_value)
  213. end
  214. setmetatable(copy, deepcopy(getmetatable(orig)))
  215. else -- number, string, boolean, etc
  216. copy = orig
  217. term.write(orig)
  218. print()
  219. end
  220. if #arg>0 then
  221. io.read()
  222. else
  223. return copy
  224. end
  225. end
  226.  
  227. -- NOTHING TO SEE HERE TEST CODE PLEASE IGNORE :P
  228. function encrypt(msg, key)
  229. math.randomseed(key)
  230. local out = ""
  231. for i = 1,#msg do
  232. local c = msg:sub(i,i)
  233. local code = CharToCode[c]
  234. code = code + math.random(0,#ValidChars)
  235. if code > #ValidChars then
  236. code = code - #ValidChars
  237. end
  238. out = out..CodeToChar[code]
  239. end
  240. return out
  241. end
  242.  
  243. -- returns the string in its proper type, if no type found then returns the string.
  244. function toType(str)
  245. if str == nil then
  246. error("NIL string passed to function toType()",2)
  247. elseif tonumber(str) ~= nil then
  248. return tonumber(str)
  249. elseif string.lower(str) == "true" then
  250. return true
  251. elseif string.lower(str) == "false" then
  252. return false
  253. else
  254. return str
  255. end
  256. end
  257.  
  258. -- This function will simulate the shell on a comuter. I think it works for nearly everything
  259. function MYshell()
  260. screen = term
  261. screen.setBackgroundColor(colors.black)
  262. screen.clear()
  263. screen.setTextColor(colors.yellow)
  264. screen.setCursorPos(1,1)
  265. screen.write("RedOS is running in the background.")
  266. screen.setCursorPos(1,2)
  267. screen.write("Type 'redOS' to resume")
  268. local xsize,ysize = term.getSize()
  269. local pos = 3
  270. while true do
  271. screen.setCursorPos(1,pos)
  272. screen.setTextColor(colors.yellow)
  273. screen.write("> ")
  274. screen.setCursorPos(3,pos)
  275. screen.setTextColor(colors.white)
  276.  
  277. local command = io.read()
  278. pos = pos+1
  279. if pos>ysize then
  280. pos = ysize-1
  281. end
  282. if string.lower(command) == "redos" then
  283. break
  284. end
  285. local response = shell.run(command)
  286. if response == false then
  287. pos = pos+1
  288. elseif type(response) == "table" then
  289. for k,v in pairs(response) do
  290. print(v)
  291. end
  292. else
  293. local x,y = term.getCursorPos()
  294. pos = y
  295. --screen.clear()
  296. end
  297. end
  298. end
  299.  
  300. ----------------------------------------------------------------
  301. -----------------------------[ Save/Load ]----------------------
  302. ----------------------------------------------------------------
  303.  
  304. -- Saves the currently loaded tables to file, if arguments are passed (...) it will save those tables instead.
  305. -- It will broadcast the file if another computer wants it.
  306. function FSsave(filename,...)
  307. local logic_temp = logic_setup()
  308. local ID = tonumber(string.match(filename,"%d+"))
  309. local meta_temp = meta_setup(ID)
  310. local signal_temp = signal_setup(ID)
  311. local logic_curr = deepcopy(logic)
  312. local meta_curr = deepcopy(meta)
  313. local signal_curr = deepcopy(signal)
  314. networkedIDs = {}
  315. if attachModem() then
  316. rednet.broadcast("redOS metaID")
  317. end
  318. if #arg > 0 then
  319. logic_curr = deepcopy(arg[2])
  320. meta_curr = deepcopy(arg[3])
  321. signal_curr = deepcopy(arg[1])
  322. elseif meta["ID"] ~= os.getComputerID() then
  323. local s,l,m = FSload(filename)
  324. logic_curr = deepcopy(l)
  325. end
  326. local file = fs.open(filename,"w")
  327. file.write("RedOS data\n")
  328. if ID == os.getComputerID() and monFace ~= nil then
  329. file.write("monFace "..string.lower(monFace).."\n")
  330. end
  331. for i,v in pairs(meta_curr) do
  332. if i == "customUI" then
  333. for j,k in pairs(v) do
  334. for u,y in pairs(k) do
  335. if u == "table" or u == "text" then
  336. if scanTableFor(y) then
  337. for o,p in pairs(y) do
  338. file.write(u.." "..j.." "..o.." "..p)
  339. file.write("\n")
  340. end
  341. end
  342. else
  343. if meta_curr[i][j][u]~= nil then
  344. file.write("customUI "..j.." "..u.." "..tostring(meta_curr[i][j][u]))
  345. file.write("\n")
  346. end
  347. end
  348. end
  349. end
  350. elseif meta_temp[i] ~= meta_curr[i] or i == "ID" then
  351. if ID ~= meta_temp["ID"] or ID ~= meta_curr["ID"] then
  352. term.clear()
  353. error("Invalid ID is attempting to be saved: temp: "..meta_temp["ID"].." curr: "..meta_curr["ID"].." ID:"..ID,2)
  354. end
  355. file.write(i.." "..tostring(v))
  356. file.write("\n")
  357. end
  358. end
  359. for i=1,#sig_faces do
  360. for k,v in pairs(signal_curr[ID][sig_faces[i]]) do
  361. if k ~= "value" and signal_curr[ID][sig_faces[i]][k] ~= signal_temp[ID][sig_faces[i]][k] then
  362. file.write("signal "..sig_faces[i].." "..k.." "..tostring(v))
  363. file.write("\n")
  364. end
  365. end
  366. if signal_curr[ID][sig_faces[i]]["isBundle"] then
  367. for j=1,#sig_values do
  368. for k,v in pairs(logic_curr[sig_faces[i]][sig_values[j]]) do
  369. if k == "if" then
  370. for p,o in pairs(v) do
  371. if logic_curr[sig_faces[i]][sig_values[j]][k][p] ~= logic_temp[sig_faces[i]][sig_values[j]][k][p] then
  372. file.write("logic "..sig_faces[i].." "..sig_values[j].." "..p.." "..o)
  373. file.write("\n")
  374. end
  375. end
  376. else
  377. if logic_curr[sig_faces[i]][sig_values[j]][k] ~= logic_temp[sig_faces[i]][sig_values[j]][k] then
  378. file.write("logic "..sig_faces[i].." "..sig_values[j].." "..k.." "..tostring(v))
  379. file.write("\n")
  380. end
  381. end
  382. end
  383. end
  384. else
  385. for k,v in pairs(logic_curr[sig_faces[i]][0]) do
  386. if k == "if" then
  387. for p,o in pairs(v) do
  388. if logic_curr[sig_faces[i]][0][k][p] ~= logic_temp[sig_faces[i]][0][k][p] then
  389. file.write("logic "..sig_faces[i].." ".."0".." "..p.." "..o)
  390. file.write("\n")
  391. end
  392. end
  393. else
  394. if logic_curr[sig_faces[i]][0][k] ~= logic_temp[sig_faces[i]][0][k] then
  395. file.write("logic "..sig_faces[i].." ".."0".." "..k.." "..tostring(v))
  396. file.write("\n")
  397. end
  398. end
  399. end
  400. end
  401. end
  402. file.close()
  403. if ID ~= os.getComputerID() then
  404. broadcastFile(filename,ID)
  405. end
  406. sleep(0)
  407. for k,v in pairs(networkedIDs) do
  408. if v == meta_curr["ID"] then
  409. broadcastFile(filename,k)
  410. end
  411. end
  412. end
  413.  
  414. -- Will read a file, returning 3 tables corresponding to the signal, logic, and meta tables
  415. function FSload(filename)
  416. if fs.exists(filename) then
  417. local signal_temp = deepcopy(signal) --signal_setup()
  418. local logic_temp = logic_setup()
  419. local ID = tonumber(string.match(filename,"%d+"))
  420. local tmp_sig = signal_setup(ID)
  421. signal_temp[ID] = deepcopy(tmp_sig[ID])
  422. local meta_temp = meta_setup(ID)
  423. local efile = fs.open(filename,"r")
  424. if efile.readAll() ~= nil then
  425. efile:close()
  426. file = io.open(filename,"r")
  427. for line in file:lines() do
  428. local firstword = string.match(string.sub(line,0,8),"%S+")
  429. if firstword == "customUI" or firstword == "table" or firstword =="text" then
  430. local i = firstword
  431. if string.match(line,i.."%s%d+%s%d+") and (i=="table" or i=="text") then
  432. if type(meta_temp["customUI"][tonumber(string.match(line,i.."%s(%d+)%s%d+"))]) == "nil" then
  433. meta_temp["customUI"][tonumber(string.match(line,i.."%s(%d+)%s%d+"))] = {["table"] = {},["text"] = {}, ["signal"] = nil,["name"] = nil, ["onColor"] = colors.green, ["offColor"] = colors.red}
  434. end
  435. meta_temp["customUI"][tonumber(string.match(line,i.."%s(%d+)%s%d+"))][i][tonumber(string.match(line,i.."%s%d+%s(%d+)"))] = string.match(line,i.."%s%d+%s%d+%s(.+)")
  436. else
  437. if type(meta_temp["customUI"][tonumber(string.match(line,i.."%s(%d+)%s%S+"))]) == "nil" then
  438. meta_temp["customUI"][tonumber(string.match(line,i.."%s(%d+)%s%S+"))] = {["table"] = {},["text"] = {}, ["signal"] = nil,["name"] = nil, ["onColor"] = colors.green, ["offColor"] = colors.red}
  439. end
  440. meta_temp["customUI"][tonumber(string.match(line,i.."%s(%d+)%s%S+"))][string.match(line,i.."%s%d+%s(%S+)")] = toType(string.match(line,i.."%s%d+%s%S+%s(.+)"))
  441. end
  442. end
  443. if ID == os.getComputerID() and string.match(line,"monFace %S+") then
  444. monFace = string.match(line,"monFace (%S+)")
  445. end
  446. for i,v in pairs(meta_temp) do
  447. if i == "customUI" then
  448.  
  449. elseif string.match(string.sub(line,0,string.len(i)),i) then
  450. meta_temp[i] = toType(string.match(line,i.." (.+)"))
  451. end
  452. end
  453. if string.match(string.sub(line,0,5),"logic") then
  454. local op = string.match(line,"logic %S+%s%S+%s(%S+).+")
  455. if op == "and" or op == "or" then
  456. logic_temp[toType(string.match(line,"logic (%S+)%s%S+%s%S+%s.+"))][toType(string.match(line,"logic %S+%s(%S+)%s%S+%s.+"))]["if"][toType(string.match(line,"logic %S+%s%S+%s(%S+)%s.+"))] = toType(string.match(line,"logic %S+%s%S+%s%S+%s(.+)"))
  457. else
  458. logic_temp[toType(string.match(line,"logic (%S+)%s%S+%s%S+%s.+"))][toType(string.match(line,"logic %S+%s(%S+)%s%S+%s.+"))][toType(string.match(line,"logic %S+%s%S+%s(%S+)%s.+"))] = toType(string.match(line,"logic %S+%s%S+%s%S+%s(.+)"))
  459. end
  460. end
  461. if string.match(string.sub(line,0,6),"signal") then
  462. signal_temp[ID][toType(string.match(line,"signal (%S+)%s%S+%s.+"))][toType(string.match(line,"signal %S+%s(%S+)%s.+"))]= toType(string.match(line,"signal %S+%s%S+%s(.+)"))
  463. if string.match(line,"isBundle") then
  464. signal_temp[ID][string.match(line,"signal (%S+)")]["value"] = 0
  465. end
  466. end
  467. end
  468. file:close()
  469. networkNames[ID] = meta_temp["computerName"]
  470. return deepcopySignal(signal_temp),deepcopy(logic_temp),deepcopy(meta_temp)
  471. else
  472. efile.close()
  473. end
  474. else
  475. Debug(filename.." Does not exist!")
  476. end
  477. end
  478.  
  479. ----------------------------------------------------------------
  480. -----------------------------[ RedStone ]-----------------------
  481. ----------------------------------------------------------------
  482.  
  483. -- A little aid to change the type of input on a face. (probably never used)
  484. function setBundle(ID,face)
  485. signal[ID][face]["value"] = 0
  486. signal[ID][face]["isBundle"] = true
  487. end
  488. function setCable(ID,face)
  489. signal[ID][face]["value"] = false
  490. signal[ID][face]["isBundle"] = false
  491. end
  492.  
  493. -- Used to decode the format that signals are stored in the logic table
  494. --retuns, ID, Face, Sig_Value, state
  495. function decodeSignal(text)
  496. return tonumber(string.match(text,"(.+)|.+|.+|.+")),string.match(text,".+|(.+)|.+|.+"),tonumber(string.match(text,".+|.+|(.+)|.+")),toType(string.match(text,".+|.+|.+|(.+)"))
  497. end
  498.  
  499. --Recives a table at the cable node in the logic table, checks the current signal table for conditionals, and returns what to set the state to (true/false/pulse).
  500. -- node is logic[face]
  501. function isOn(tab,ID,face,sig_value)
  502. if type(tab[ID]) == "nil" then
  503. if attachModem() then
  504. rednet.send(ID,"redOS Boot")
  505. end
  506. if type(networkNames[ID]) == "nil" or type(signal[ID]) == "nil" then
  507. local sig_tmp = signal_setup(ID)
  508. signal[ID]=deepcopy(sig_tmp[ID])
  509. end
  510. sleep(0)
  511. tab = deepcopy(signal)
  512. Debug("Nil ID in isON, this should only happen around startup")
  513. end
  514. if tab[ID][face]["isBundle"] then
  515. return colors.test(tab[ID][face]["value"],sig_value)
  516. else
  517. return tab[ID][face]["value"]
  518. end
  519. end
  520.  
  521. --checks networkNames table and returns true if the ID exists in the table.
  522. function networked(ID)
  523. for k,v in pairs(networkNames) do
  524. if k == ID then
  525. return true
  526. end
  527. end
  528. return false
  529. end
  530.  
  531.  
  532. -- returns the state of a cable based on its logic and the current tick of the pulse timer. Will return t/f for a cable, or a value if its a bundle.
  533. function checkLogic(node,current_tick,curr_face)
  534. local ID = os.getComputerID()
  535. if signal[ID][curr_face]["isRead"] then
  536. return signal[ID][curr_face]["value"]
  537. end
  538. local i_s = 0
  539. local i_max = 0
  540. local pingedIDs = {}
  541. local needsave = false
  542. --local final_result = true
  543. local bund_val = 0
  544. if signal[ID][curr_face]["isBundle"] then
  545. i_s = 1
  546. i_max = 16
  547. end
  548.  
  549. for i_ = i_s,i_max do
  550. local value_fix
  551. if i_max >0 then
  552. value_fix = sig_values[i_]
  553. else
  554. value_fix = 0
  555. end
  556. local result = false
  557. local fail_and = false
  558. local pass_or = false
  559. local failedPing = false
  560. local skip = false
  561. if node[value_fix]["if"]["or"] == nil then --and node[i_]["if"]["and"] ~= nil then
  562. pass_or = true
  563. if node[value_fix]["if"]["and"] == nil then
  564. fail_and = true
  565. if node[value_fix]["else"] == false then -- theres literally no logic to be calculated
  566. skip = true
  567. end
  568. end
  569. end
  570. if not skip then
  571. for i,v in pairs(node[value_fix]["if"]) do
  572. for word in string.gmatch(v, "%S+") do
  573. local ID_,face,sig_value,state = decodeSignal(word)
  574. if ID_ ~= os.getComputerID() and not networked(ID_) then -- Check if computer is still connected every 4 seconds
  575. failedPing = true
  576. end
  577. if i == "and" then
  578. if state == false and not isOn(signal,ID_,face,sig_value) then
  579.  
  580. elseif state == true and isOn(signal,ID_,face,sig_value) then
  581.  
  582. else
  583. fail_and = true
  584. end
  585. elseif i == "or" then
  586. if state == false and not isOn(signal,ID_,face,sig_value) then
  587. pass_or = true
  588. break
  589. elseif state == true and isOn(signal,ID_,face,sig_value) then
  590. pass_or = true
  591. break
  592. else
  593. end
  594. end
  595. end
  596. end
  597. if pass_or and not fail_and and not failedPing then
  598. result = true
  599. else
  600. if logic[curr_face][value_fix]["toggle"] == true then
  601. --Toggle then/else
  602. logic[curr_face][value_fix]["toggle"] = false
  603. local temp = logic[curr_face][value_fix]["then"]
  604. logic[curr_face][value_fix]["then"] = logic[curr_face][value_fix]["else"]
  605. logic[curr_face][value_fix]["else"] = temp
  606. needsave = true
  607. end
  608. end
  609. if node[value_fix]["then"] == nil or node[value_fix]["else"] == nil then
  610. --No logic but we need to return something?
  611. error("All cables require logic")
  612. else
  613. local thenelse = "else"
  614. if result then
  615. thenelse = "then"
  616. end
  617. --print(isOn(signal,2,"Front",sig_values[i_]))
  618. --io.read()
  619. local TE_val = node[value_fix][thenelse]
  620. if string.match(tostring(TE_val),"toggle") then
  621. if thenelse == "then" then
  622. logic[curr_face][value_fix]["toggle"] = true
  623. end
  624. TE_val = toType(string.match(node[value_fix][thenelse],"toggle (.+)"))
  625. end
  626. if TE_val == true then
  627. if signal[ID][curr_face]["isBundle"] then
  628. bund_val = bund_val + sig_values[i_]
  629. else
  630. return true
  631. end
  632. elseif TE_val == false then
  633. if signal[ID][curr_face]["isBundle"] then
  634. --don't change the bundle value
  635. else
  636. return false
  637. end
  638. elseif type(TE_val) == "number" then
  639. if signal[ID][curr_face]["isBundle"] then
  640. if TE_val == 1 then
  641. if colors.test(signal[os.getComputerID()][curr_face]["value"],sig_values[i_]) then
  642.  
  643. else
  644. bund_val = bund_val + sig_values[i_]
  645. end
  646. elseif current_tick/TE_val == math.floor(current_tick/TE_val) then
  647. if not colors.test(signal[os.getComputerID()][curr_face]["value"],sig_values[i_]) then
  648. bund_val = bund_val + sig_values[i_]
  649. end
  650. else
  651. if colors.test(signal[os.getComputerID()][curr_face]["value"],sig_values[i_]) then
  652. --bund_val = bund_val + sig_values[i_]
  653. end
  654. end
  655. else
  656. if TE_val == 1 then
  657. return not signal[os.getComputerID()][curr_face]["value"]
  658. elseif current_tick/TE_val == math.floor(current_tick/TE_val) then
  659. return true
  660. else
  661. return false
  662. end
  663. end
  664. end
  665. end
  666. end
  667. if not signal[ID][curr_face]["isBundle"] then
  668. return false -- should only get here if the signal is a cable and it skip is true
  669. end
  670. end
  671. if needsave then
  672. if meta["ID"] ~= os.getComputerID() then
  673. local sig_t,log_t,meta_t = FSload(os.getComputerID()..".meta")
  674. FSsave(os.getComputerID()..".meta",sig_t,log_t,meta_t)
  675. else
  676. FSsave(os.getComputerID()..".meta")
  677. end
  678. end
  679. return bund_val
  680. end
  681.  
  682.  
  683. --Will return true if a signal has changed. If readredstone() then broadcast would be quite usefull.
  684. function readRedstone()
  685. --sleep(0)
  686. local change = false
  687. local ID = os.getComputerID()
  688. for i=1,#comp_faces do
  689. if signal[ID][comp_faces[i]]["isRead"] then
  690. local var
  691. if signal[ID][comp_faces[i]]["isBundle"] then
  692. var = rs.getBundledInput(string.lower(comp_faces[i]))
  693. else
  694. var = rs.getInput(string.lower(comp_faces[i]))
  695. end
  696. if signal[ID][comp_faces[i]]["value"] ~= var then
  697. change = true
  698. signal[ID][comp_faces[i]]["value"] = var
  699. end
  700. elseif signal[ID][comp_faces[i]]["isBundle"] and type(signal[ID][comp_faces[i]]["value"]) == "boolean" then
  701. Debug(type(signal[ID][comp_faces[i]]["value"]))
  702. signal[ID][comp_faces[i]]["value"] = 0
  703. end
  704. end
  705. return change
  706. end
  707.  
  708. function writeRedstone()
  709. local ID = os.getComputerID()
  710. for i=1,#comp_faces do
  711. if not signal[ID][comp_faces[i]]["isRead"] then
  712. if signal[ID][comp_faces[i]]["isBundle"] then
  713. rs.setBundledOutput(string.lower(comp_faces[i]),signal[ID][comp_faces[i]]["value"])
  714. else
  715. rs.setOutput(string.lower(comp_faces[i]),signal[ID][comp_faces[i]]["value"])
  716. end
  717. end
  718. end
  719. end
  720. function checkSignalChange(tab1,tab2)
  721. local ID = os.getComputerID()
  722. for i=1,#sig_faces do
  723. if tab2[ID][sig_faces[i]]["value"] ~= tab1[ID][sig_faces[i]]["value"] then
  724. return true
  725. end
  726. end
  727. return false
  728. end
  729.  
  730. function redstone()
  731. local ID = os.getComputerID()
  732. while true do
  733. local signal_temp = deepcopy(signal)
  734. readRedstone()
  735. global_tick = global_tick + 1
  736. for i=1,#sig_faces do
  737. signal[ID][sig_faces[i]]["value"] = checkLogic(logic[sig_faces[i]],global_tick,sig_faces[i])
  738. end
  739.  
  740. writeRedstone()
  741. if checkSignalChange(signal_temp,signal) then
  742. checkUIandUpdate()
  743. broadcastSignal()
  744. end
  745. sleep(tick)
  746. end
  747. end
  748. function checkUIandUpdate(...)
  749. local ret = false
  750. local ID = meta["ID"]
  751.  
  752. for k,v in pairs(meta["customUI"]) do
  753. if meta["customUI"][k]["signal"] ~= nil then
  754. local ID_,face_,sig_value,state = decodeSignal(meta["customUI"][k]["signal"])
  755. if updateUIcolor(k,v) then
  756. ret = true
  757. end
  758. end
  759. end
  760. if ret and #arg == 0 then refreshDisplay() end
  761. return ret
  762. end
  763.  
  764. function toggleBundle(ID,face)
  765. if signal[ID][face]["isBundle"] then
  766. signal[ID][face]["isBundle"] = false
  767. signal[ID][face]["value"] = false
  768. rs.setBundledOutput(string.lower(face),0)
  769. else
  770. signal[ID][face]["isBundle"] = true
  771. signal[ID][face]["value"] = 0
  772. rs.setOutput(string.lower(face),false)
  773. end
  774. end
  775. ----------------------------------------------------------------
  776. -----------------------------[ Network ]------------------------
  777. ----------------------------------------------------------------
  778. function attachModem()
  779. for i=1,#comp_faces do
  780. if peripheral.isPresent(string.lower(comp_faces[i])) and peripheral.getType(string.lower(comp_faces[i])) == "modem" then
  781. if rednet.isOpen(string.lower(comp_faces[i])) then
  782. return true
  783. else
  784. rednet.open(string.lower(comp_faces[i]))
  785. Debug("Opening side!")
  786. return true
  787. end
  788. end
  789. end
  790. return false
  791. end
  792. function broadcastSignal(...)
  793. local message = ""
  794. local ID = os.getComputerID()
  795. --for k,v in pairs(signal[ID]) do
  796. for i=1,#sig_faces do
  797. message = message..ID.." "..sig_faces[i].." "..tostring(signal[ID][sig_faces[i]]["value"])
  798. message = message.." "..tostring(signal[ID][sig_faces[i]]["isBundle"])
  799. message = message.." "..tostring(signal[ID][sig_faces[i]]["isRead"])
  800. message = message.." "..tostring(signal[ID][sig_faces[i]]["hasScript"]).."|"
  801. end
  802. --end
  803. if #arg >0 then
  804. if attachModem() then
  805. rednet.send(arg[1],"redOS signal|"..message)
  806.  
  807. end
  808. else
  809. if attachModem() then
  810. rednet.broadcast("redOS signal|"..message)
  811.  
  812. end
  813. end
  814. end
  815. function receiveSignal(message)
  816. for word in string.gmatch(message,"%d+%s%S+%s%S+%s%S+%s%S+%s%S+|") do
  817. local ID = tonumber(string.match(word,"(%d+)%s%S+%s%S+%s%S+%s%S+%s%S+|"))
  818. local face = string.match(word,"%d+%s(%S+)%s%S+%s%S+%s%S+%s%S+|")
  819. local tab = {}
  820. tab[1] = toType(string.match(word,"%d+%s%S+%s(%S+)%s%S+%s%S+%s%S+|"))
  821. tab[2] = toType(string.match(word,"%d+%s%S+%s%S+%s(%S+)%s%S+%s%S+|"))
  822. tab[3] = toType(string.match(word,"%d+%s%S+%s%S+%s%S+%s(%S+)%s%S+|"))
  823. tab[4] = toType(string.match(word,"%d+%s%S+%s%S+%s%S+%s%S+%s(%S+)|"))
  824. if ID == os.getComputerID() then
  825. --error("Can't recieve singal data from elsewhere, WTF mate?")
  826. -- Changed in the lastest version of CC, broadcast will now send the message to the PC being used.
  827. else
  828. if type(signal[ID]) == "nil" then
  829. local tab_temp = signal_setup(ID)
  830. signal[ID] = deepcopy(tab_temp[ID])
  831. end
  832. signal[ID][face]["value"] = tab[1]
  833. signal[ID][face]["isBundle"] = tab[2]
  834. signal[ID][face]["isRead"] = tab[3]
  835. signal[ID][face]["hasScript"] = tab[4]
  836. end
  837. end
  838. checkUIandUpdate()
  839. end
  840. function broadcastFile(filename,...)
  841. local file = fs.open(filename,"r")
  842. local str = file.readAll()
  843. if str ~= nil then
  844. if #arg >0 then
  845. if attachModem() then
  846. rednet.send(tonumber(arg[1]),"redOS "..filename.."| "..str)
  847. end
  848.  
  849. --else
  850. --userInput("Can't Locate network "..networkNames[arg[1]])
  851. --end
  852. else
  853. if attachModem() then
  854. rednet.broadcast("redOS "..filename.."| "..str)
  855. end
  856.  
  857. end
  858. else
  859. dubug("RedOSbroadcast FS read nil!")
  860. end
  861. file:close()
  862. return true
  863. end
  864.  
  865. function receiveFile(message)
  866. local text = string.match(message,"redOS %S+|(.+)")
  867. local filename = string.match(string.sub(message,0,20),"redOS (%S+)|")
  868. file = fs.open(filename,"w")
  869. file.write(text)
  870. file:close()
  871. if tonumber(string.match(filename,"%d+")) == os.getComputerID() then
  872. local sig_t,log_t,meta_t = FSload(filename)
  873. logic = deepcopy(log_t)
  874. if meta["ID"] == os.getComputerID() then
  875. signal = deepcopy(sig_t)
  876. meta = deepcopy(meta_t)
  877. FSsave(filename)
  878. checkUIandUpdate()
  879. end
  880.  
  881.  
  882. elseif tonumber(string.match(filename,"%d+")) == meta["ID"] then
  883. local s_temp,l_temp,m_temp = FSload(filename)
  884. meta = deepcopy(m_temp)
  885. signal[meta["ID"]] = deepcopy(s_temp[meta["ID"]])
  886. checkUIandUpdate()
  887. end
  888. end
  889. --ping ID, recives a unique response. arg[1] will display a message that the terminal can't be located.
  890.  
  891. function RedOSPing(ID_,...)
  892. if ID_ == nil then
  893. Debug("NIL ID in RedOSPing")
  894. return false
  895. end
  896. if tonumber(ID_) ~= os.getComputerID() then
  897. if attachModem() then
  898. rednet.send(tonumber(ID_),"redOS Ping")
  899. end
  900. local count = 0
  901. while true do
  902. local ID,message,dist = rednet.receive(0.1)
  903. if ID == nil then return false end
  904. if ID ~= ID_ and count >6 then
  905. return false --RedOSPing(ID_)
  906. end
  907. if message == nil then
  908. Debug("RedOSPing false "..ID)
  909. else
  910. if string.match(message, "redOS Pong") and ID_ == ID then
  911. return true
  912. elseif arg[1] and count >6 then
  913. userInput("Can't Locate network "..ID_)
  914. Debug("RedOSPing mishap "..ID)
  915. return false
  916. elseif count >6 then
  917. Debug("RedOSPing mishap "..ID)
  918. return false
  919. end
  920. end
  921. count = count+1
  922. end
  923. else
  924. return true
  925. end
  926. end
  927.  
  928. -- RSnetwork
  929. function RSnetwork()
  930. RSupdateNetwork()
  931. broadcastSignal()
  932. local function one()
  933. while true do
  934. local ID, message, dist = rednet.receive()
  935. if string.sub(message,0,13) == "redOS toggle|" then
  936. local a,b,c,d = decodeSignal(string.sub(message,14))
  937. if tonumber(a) == os.getComputerID() then
  938. local _else = logic[b][c]["else"]
  939. local _then = logic[b][c]["then"]
  940. local s,l,m = FSload(os.getComputerID()..".meta")
  941. logic[b][c]["else"] = _then
  942. logic[b][c]["then"] = _else
  943. FSsave(os.getComputerID()..".meta",s,logic,m)
  944. end
  945. message = nil
  946. end
  947. if ID ~= os.getComputerID() and message ~= nil then -- New CC is picking up local signals
  948. if message == "redOS Ping" then
  949. if attachModem() then
  950. rednet.send(ID,"redOS Pong")
  951. end
  952. elseif message == "redOS metaID" then
  953. if attachModem() then
  954. rednet.send(ID,"redOS metaID "..meta["ID"])
  955. end
  956. elseif message == "redOS 149634901231" then
  957. Debug("I SHOULD BE RESTARTING") -- WTF WHY DOESNT THIS WORK, IT DOES EVERYTHING PROPERLY BUT RECIEVE THE MESSAGE
  958. os.reboot()
  959. elseif string.match(string.sub(message,0,5),"redOS") and not string.match(string.sub(message,0,10),"redOS Pong") and message ~= "redOS Ping" then --we have a valid message
  960. if message == "redOS Request meta" then --A computer is requesting this computers meta data.
  961. broadcastFile(tostring(os.getComputerID())..".meta",ID)
  962. elseif message == "redOS Boot" then
  963. if attachModem() then
  964. rednet.send(ID,"redOS Info "..networkNames[os.getComputerID()])
  965. end
  966.  
  967. broadcastSignal(ID)
  968. if type(networkNames[ID]) == "nil" then
  969. if attachModem() then
  970. rednet.send(ID,"redOS Boot")
  971. end
  972.  
  973. end
  974. elseif string.match(string.sub(message,0,10),"redOS Info") then
  975. networkNames[tonumber(ID)] = string.match(message,"redOS Info (.+)")
  976. elseif string.match(string.sub(message,0,12),"redOS signal") then
  977. receiveSignal(message)
  978. elseif string.match(string.sub(message,0,25),"redOS %S+|") and not string.match(string.sub(message,0,12),"redOS signal") then
  979. receiveFile(message)
  980. elseif string.match(string.sub(message,0,25),"redOS metaID %d+") then
  981. if tonumber(string.match(string.sub(message,0,25),"redOS metaID (%d+)")) == meta["ID"] then
  982. networkedIDs[ID] = meta["ID"]
  983. end
  984. end
  985. end
  986. end
  987. end
  988. end
  989. local function two() --Updates the network every 5 seconds (this handles disconnected computers)
  990. while true do
  991. sleep(30)
  992. for k,v in pairs(deepcopy(networkNames)) do
  993. if not RedOSPing(k) then
  994. networkNames[k] = nil
  995. end
  996. end
  997. RSupdateNetwork()
  998. end
  999. end
  1000. parallel.waitForAll(one,two)
  1001. end
  1002.  
  1003. function RSupdateNetwork()
  1004. local thisname = networkNames[os.getComputerID()]
  1005. networkNames = {}
  1006. networkNames[os.getComputerID()] = thisname
  1007. if attachModem() then
  1008. rednet.broadcast("redOS Boot")
  1009. end
  1010. end
  1011. ----------------------------------------------------------------
  1012. -----------------------------[ Display API ]--------------------
  1013. ----------------------------------------------------------------
  1014. --Lots of credit to nPaintPro's author for the whole table -> display stuff. most of these functions are built off nPaintPro's format.
  1015. --Returns the color value of 'hex'
  1016. function getColourOf(hex)
  1017. local value = tonumber(hex, 16)
  1018. if not value then return nil end
  1019. value = math.pow(2,value)
  1020. return value
  1021. end
  1022.  
  1023. --Returns the hex string of 'colour'
  1024. local function getHexOf(colour)
  1025. if not colour or not tonumber(colour) then
  1026. return " "
  1027. end
  1028. local value = math.log(colour)/math.log(2)
  1029. if value > 9 then
  1030. value = hexnums[value]
  1031. end
  1032. return tostring(value)
  1033. end
  1034.  
  1035. -- Draws a picture as a image, arg[1] is a text overlay table. If arg[2] is true then we check the last used image&text for differences and only draw whats different (Does not support text color).
  1036. --Note, image and text have to be the same size
  1037. function drawPictureTable(mon, image, xinit, yinit, alpha,...)
  1038. if mon == nil then return end
  1039. if not alpha then alpha = 1 end
  1040. local text_tab = deepcopy(arg[1])
  1041. for y=1,#image do
  1042. for x=1,#image[y] do
  1043. local col = getColourOf(string.sub(image[y], x, x))
  1044. local tex = " "
  1045. local text_offset = 0
  1046. if not col then col = alpha end
  1047. if mon.isColor() then
  1048. mon.setBackgroundColour(col)
  1049. else
  1050. if string.sub(image[y], x, x) ~= " " then
  1051. mon.setBackgroundColour(colors.black)
  1052. else
  1053. mon.setBackgroundColour(colors.white)
  1054. end
  1055. end
  1056. if arg[1] ~= nil and text_tab[y] ~= nil then
  1057. tex = string.sub(text_tab[y],x,x)
  1058. if tex == "&" then
  1059. local txtclr = getColourOf(string.sub(text_tab[y],x+text_offset+1,x+text_offset+1))
  1060. if txtclr ~= nil then
  1061. if mon.isColor() then
  1062. mon.setTextColor(txtclr)
  1063. end
  1064. --text_offset = text_offset+1
  1065. text_tab[y] = string.sub(text_tab[y],3,string.len(text_tab[y]))
  1066. tex = string.sub(text_tab[y],x+text_offset,x+text_offset)
  1067. end
  1068. end
  1069. end
  1070. if string.len(tex) ~= 1 then
  1071. tex = " "
  1072. end
  1073. if arg[2] and (string.sub(image[y], x, x) ~= string.sub(lastimage["image"][y], x, x) or string.sub(text_tab[y], x, x) ~= string.sub(lastimage["text"][y], x, x)) then
  1074. mon.setCursorPos(xinit + x-1, yinit + y-1)
  1075. mon.write(tex)
  1076. elseif arg[2] == nil then
  1077. mon.setCursorPos(xinit + x-1, yinit + y-1)
  1078. mon.write(tex)
  1079. end
  1080. end
  1081. end
  1082. lastimage["image"] = image
  1083. lastimage["text"] = text_tab
  1084. mon.setTextColor(colors.white)
  1085. mon.setBackgroundColor(colors.black)
  1086. end
  1087. function splash()
  1088. local splashlogo = {
  1089. "444444444444444444 eeee eee eee 44 44 ";
  1090. "444444444444444444 e e e e e 4 4 4 ";
  1091. "44ffffffffffffff44 eeee ee e e 4 4 44 ";
  1092. "44f0ffffffffffff44 e e e e e 4 4 4 ";
  1093. "44ff0fffffffffff44 e e eee eee 44 44 ";
  1094. "44f0ff000fffffff44 ";
  1095. "44ffffffffffffff44 ";
  1096. "44ffffffffffffff44b8bbbbbb8bbbbbb8bbbbbb8bbb";
  1097. "44ffffffffffffff44bb8bbbbbb8bbbbbb8bbbbbb8bb";
  1098. "44ffffffffffffff4455585555558555555855555585";
  1099. "44ffffffffffffff4455558555555855555585555558";
  1100. "444444444444444444eeeee8eeeeee8eeeeee8eeeeee";
  1101. "444444444444444444eeeeee8eeeeee8eeeeee8eeeee";
  1102. "";
  1103. "";
  1104. }
  1105. canRefresh = false
  1106. if term.isColor() then
  1107. term.clear()
  1108. drawPictureTable(term, splashlogo, 4, 3, colors.black)
  1109. sleep(0.3)
  1110. drawPictureTable(term,{"44f0ffffffffffff44 ",""} , 4, 8, colors.black)
  1111. sleep(0.3)
  1112. drawPictureTable(term,{"44f0ff000fffffff44 ",""} , 4, 8, colors.black)
  1113. sleep(0.3)
  1114. drawPictureTable(term,{"44f0ffffffffffff44 ",""} , 4, 8, colors.black)
  1115. sleep(0.3)
  1116. drawPictureTable(term,{"44f0ff000fffffff44 ",""} , 4, 8, colors.black)
  1117. sleep(0.3)
  1118. term.clear()
  1119. end
  1120.  
  1121. splashdone = true
  1122. end
  1123.  
  1124. -- Generates empty tables.
  1125. function emptyScreen(mon,...)
  1126. local x_max,y_max = mon.getSize()
  1127. local tab = {}
  1128. if #arg >0 then
  1129. x_max = arg[1]
  1130. y_max = arg[2]
  1131. end
  1132. for y=1,y_max do
  1133. local str = " "
  1134. for x=1,x_max do
  1135. str = str.." "
  1136. end
  1137. tab[y] = str
  1138. end
  1139. return tab,deepcopy(tab)
  1140. end
  1141.  
  1142. --Will add color to a table at xpos,ypos. optional args are (table_text,text,text_color). It will overlap any existing colors.
  1143. -- addtoTables(xpos,ypos,table_color,bg_color,x_fin,y_fin)
  1144. function addColorToTable(table_color,xpos,ypos,bg_color,...)
  1145. local x_fin = arg[1]
  1146. local y_fin = arg[2]
  1147. if #arg <2 then
  1148. x_fin = xpos
  1149. y_fin = ypos
  1150. end
  1151. if ypos > #table_color then
  1152. error("index out of bounds ("..ypos..","..#table_color..")")
  1153. end
  1154. ypos = math.floor(ypos)
  1155. xpos = math.floor(xpos)
  1156. for y=ypos,y_fin do
  1157. for x=xpos,x_fin do
  1158. if tonumber(bg_color) == nil then
  1159. table_color[y] = string.sub(table_color[y],0,x-1).." "..string.sub(table_color[y],x+1)
  1160. else
  1161. table_color[y] = string.sub(table_color[y],0,x-1)..getHexOf(bg_color)..string.sub(table_color[y],x+1)
  1162. end
  1163. end
  1164. end
  1165. return table_color
  1166. end
  1167. --Shorthand for addColorToTable
  1168. function tc(...)
  1169. if #arg <6 then
  1170. return addColorToTable(arg[1],arg[2],arg[3],arg[4])
  1171. else
  1172. return addColorToTable(arg[1],arg[2],arg[3],arg[4],arg[5],arg[6])
  1173. end
  1174. end
  1175. -- Adds text to a table, optional args are text_color. I would not recomend trying to overwrite text to erase it, as forgotton color codes will literally become landmines. just replace the value with a new blank string.
  1176. function addTextToTable(table_text,xpos,ypos,text,...)
  1177. local text_color = arg[1]
  1178. local color_offset =0
  1179. local text_offset = 0
  1180. if arg[1] == nil then
  1181. text_color = colors.white
  1182. end
  1183. if ypos > #table_text then
  1184. error("index out of bounds ("..ypos..","..#table_text..")")
  1185. end
  1186. ypos = math.floor(ypos)
  1187. xpos = math.floor(xpos)
  1188.  
  1189. for i=1,string.len(table_text[ypos]) do
  1190. if string.sub(table_text[ypos],i,i)=="&" and i<xpos+color_offset then
  1191. color_offset = color_offset+2
  1192. end
  1193. end
  1194. --table_text[ypos] = string.sub(table_text[ypos],0,xpos+color_offset-1).." "..string.sub(table_text[ypos],xpos+color_offset)
  1195. if string.sub(table_text[ypos],color_offset+xpos,color_offset+xpos)=="&" then
  1196. if string.match(text,"&%S") then
  1197. table_text[ypos] = string.sub(table_text[ypos],0,xpos+color_offset-1)..text..string.sub(table_text[ypos],xpos+color_offset+string.len(text))
  1198. else
  1199. table_text[ypos] = string.sub(table_text[ypos],0,xpos+color_offset-1).."&"..getHexOf(text_color)..text..string.sub(table_text[ypos],xpos+color_offset+2+string.len(text))
  1200. end
  1201. else
  1202. --if text == nil then error("1000 ",2) end
  1203. table_text[ypos] = string.sub(table_text[ypos],0,xpos+color_offset-1).."&"..getHexOf(text_color)..text..string.sub(table_text[ypos],xpos+color_offset+string.len(text))
  1204. end
  1205.  
  1206. return deepcopy(table_text)
  1207. end
  1208. --Shorthand for addTextToTable
  1209. function tt(...)
  1210. if #arg <5 then
  1211. return addTextToTable(arg[1],arg[2],arg[3],arg[4])
  1212. elseif #arg == 5 then
  1213. return addTextToTable(arg[1],arg[2],arg[3],arg[4],arg[5])
  1214. end
  1215. end
  1216.  
  1217. -- Will create a pulldown at xpos,ypos, and return the users input. arg[1] (t/f) defines if the title bar should be the full width of the pulldown or not (usefull for file menus), arg[2-5] are colors.
  1218. function createPulldown(xpos,ypos,list,...)
  1219. local c_title = colors.green
  1220. local c_titletext = colors.white
  1221. local c_list = colors.cyan
  1222. local c_listtext = colors.white
  1223. local PDwidth = string.len(list[1])
  1224. local xsize,ysize = term.getSize()
  1225. local offset = 0
  1226. if #arg >= 5 then
  1227. c_title = arg[2]
  1228. c_titletext = arg[3]
  1229. c_list = arg[4]
  1230. c_listtext = arg[5]
  1231. end
  1232.  
  1233. for i=1,#list do
  1234. if string.len(list[i])>PDwidth then
  1235. PDwidth = string.len(list[i])
  1236. end
  1237. end
  1238. local t_bg,t_t = emptyScreen(term,PDwidth-1,#list)
  1239. --t_t = tt(t_t,1,1,list[1],c_titletext)
  1240. --t_bg = tc(t_bg,1,2,c_list,PDwidth,#list)
  1241. t_t[1] = "&"..getHexOf(c_titletext)..list[1]
  1242. if arg[1] then
  1243. t_bg = tc(t_bg,1,1,c_title,string.len(list[1]),1)
  1244. t_bg[1] = string.sub(t_bg[1],0,string.len(list[1]))
  1245. elseif not arg[1] then
  1246. t_bg = tc(t_bg,1,1,c_title,PDwidth,1)
  1247. end
  1248. for i=2,#list do
  1249. if string.match(string.sub(list[i],1,1),">") then
  1250. t_t = tt(t_t,1,i,string.sub(list[i],2,#list[i]),colors.lightGray)
  1251. c_list = colors.lightBlue
  1252. t_bg = tc(t_bg,1,i,c_list,PDwidth,i)
  1253. else
  1254. t_bg = tc(t_bg,1,i,c_list,PDwidth,i)
  1255. t_t = tt(t_t,1,i,list[i],c_listtext)
  1256. end
  1257. end
  1258. if xpos+PDwidth > xsize then
  1259. if arg[1] then
  1260. drawPictureTable(term,{t_bg[1],""}, xsize - PDwidth+1,ypos,colors.black,{t_t[1],""})
  1261. t_t[1] = ""
  1262. t_bg[1] = ""
  1263. end
  1264. xpos = xsize - PDwidth+1
  1265. end
  1266. if ypos+#list >ysize then
  1267. ypos = ysize-#list+1
  1268. end
  1269.  
  1270. drawPictureTable(term,t_bg,xpos,ypos,colors.black,t_t)
  1271. local event, button1, xPos2, yPos2 = os.pullEvent("mouse_click","monitor_touch")
  1272. if xPos2 >= xpos and xPos2 <= xpos+PDwidth and yPos2 >= ypos+1 and yPos2<=ypos+#list-1 and button1 == 1 and event == "mouse_click" then
  1273. return list[yPos2-ypos+1],xPos2,yPos2,button1,event
  1274. else
  1275. if arg[6] and xPos2 >= xpos and xPos2 <= xpos+PDwidth and yPos2 == ypos and button1 == 1 and event== "mouse_click" then
  1276. return list[yPos2-ypos+1],xPos2,yPos2,button1,event
  1277. end
  1278. return "exit",xPos2,yPos2,button1,event
  1279. end
  1280. end
  1281. --Used to make a pulldown within another pulldown
  1282. function pullsideways(list,xpos,ypos,gap)
  1283. local t_c = {"",""}
  1284. local t_t = {"",""}
  1285. local offset = gap+#list[1]
  1286. for i=1,offset do
  1287. t_c[1] = t_c[1]..getHexOf(colors.green)
  1288. t_t[1] = t_t[1].." "
  1289. end
  1290. t_t = tt(t_t,1,1,list[1])
  1291. local newlist = {}
  1292. for i=1, #list-2 do
  1293. newlist[i] = list[i+2]
  1294. end
  1295. local c_title = colors.cyan
  1296. local c_titletext = colors.white
  1297. local c_list = colors.cyan
  1298. local c_listtext = colors.white
  1299. drawPictureTable(term,t_c,xpos,ypos,colors.black,t_t)
  1300. --local result,xpos2,ypos2,button = createPulldown(xpos,ypos2,list,true)
  1301. return createPulldown(xpos+offset,ypos,newlist,false,c_title,c_titletext,c_list,c_listtext,true)
  1302. end
  1303. --if arg[1] is true then the dialog will be a yes/no dialog. Blank means just 'OK', "string" or "number" will prompt for a custom input of that type.
  1304. function userInput(text,...)
  1305. local screen = term
  1306. local x1,y1 = screen.getSize()
  1307. local t_bg,t_t = emptyScreen(screen,x1,y1)
  1308. local bg_color = colors.white
  1309. local fg_color = colors.lightBlue
  1310. local b_color = colors.yellow
  1311. local text_color = colors.white
  1312. local xpadding = 4
  1313. local text_start = math.floor(y1/2) -1
  1314. local lines = {}
  1315. if string.len(text) > x1-(2+xpadding*2) then
  1316. local newline = ""
  1317.  
  1318. local i = 1
  1319. for word in string.gmatch(text, "%S+") do
  1320. if string.len(newline.." "..word) > x1-10 then
  1321. lines[i] = newline
  1322. i=i+1
  1323. newline = word
  1324. else
  1325. newline = newline.." "..word
  1326. end
  1327. end
  1328. if newline ~= nil then
  1329. lines[#lines+1] = newline
  1330. end
  1331. text_start = math.floor(y1/2 - #lines/2 -1)
  1332. for i=1,#lines do
  1333. t_t = tt(t_t,math.floor((x1-string.len(lines[i]))/2),text_start+i,lines[i],text_color)
  1334. end
  1335. else --one line message
  1336. t_t = tt(t_t,math.floor((x1-string.len(text))/2),text_start,text,text_color)
  1337. end
  1338. t_bg = tc(t_bg,1,1,bg_color,x1,y1) --background
  1339. t_bg = tc(t_bg,xpadding,text_start-1,fg_color,x1-xpadding,text_start+4+#lines) --forground
  1340. if arg[1] == nil then
  1341. t_bg = tc(t_bg,math.floor(x1/2-1),text_start+#lines+3,b_color,math.floor(x1/2+2),text_start+#lines+3)
  1342. t_t = tt(t_t,math.floor(x1/2),text_start+#lines+3,"OK",colors.black)
  1343. elseif arg[1] == true then
  1344. t_bg = tc(t_bg,x1/2-9,text_start+#lines+3,b_color,x1/2-5,text_start+#lines+3)
  1345. t_bg = tc(t_bg,x1/2+5,text_start+#lines+3,b_color,x1/2+8,text_start+#lines+3)
  1346. t_t = tt(t_t,x1/2-8,text_start+#lines+3,"Yes",colors.black)
  1347. t_t = tt(t_t,x1/2+6,text_start+#lines+3,"No",colors.black)
  1348. elseif arg[1] == "string" or arg[1] == "number" then
  1349. t_t = tt(t_t,x1/2-12,text_start+#lines+2,">",text_color)
  1350. t_bg = tc(t_bg,x1/2-12,text_start+#lines+2,colors.black,x1/2+13,text_start+#lines+2)
  1351. end
  1352. drawPictureTable(screen, t_bg, 1, 1, colors.black,t_t)
  1353. if arg[1] == "string" or arg[1] == "number" then
  1354. while true do
  1355. drawPictureTable(screen, t_bg, 1, 1, colors.black,t_t)
  1356. screen.setCursorPos(x1/2-11,text_start+#lines+2)
  1357. local input
  1358. if arg[2] then
  1359. input = read("*")
  1360. else
  1361. input = io.read()
  1362. end
  1363. if arg[1] == "string" then
  1364. if input ~= "" and tostring(input) ~= nil then
  1365. return input
  1366. else
  1367. userInput("The input has to be a string")
  1368. end
  1369. elseif arg[1] == "number" then
  1370. if tonumber(input) ~= nil then
  1371. return tonumber(input)
  1372. else
  1373. userInput("The input has to be a number")
  1374. end
  1375. end
  1376. end
  1377. else
  1378. while true do
  1379. local event, button1, xpos2, ypos2 = os.pullEvent()
  1380. if arg[1] and (event == "mouse_click" or event == "key") then
  1381. if event == "key" and button1 == 28 then
  1382. return true
  1383. end
  1384. if xpos2>=x1/2-10 and xpos2<=x1/2-5 and ypos2 == text_start+#lines+3 then
  1385. return true
  1386. elseif xpos2>=x1/2+4 and xpos2<=x1/2+8 and ypos2 == text_start+#lines+3 then
  1387. return false
  1388. end
  1389. elseif not arg[1] then
  1390. if event =="key" then
  1391. return true
  1392. elseif event == "mouse_click" and xpos2>=x1/2-2 and xpos2<=x1/2+2 and ypos2 == text_start+#lines+3 then
  1393. return true
  1394. end
  1395. end
  1396. end
  1397. end
  1398. end
  1399. -- Overwrites table 1 with table 2.
  1400. function overwriteTable(tab1,tab2)
  1401. for i=1,#tab1 do
  1402. local line = ""
  1403. for j=1,#tab1[i] do
  1404. local tex1 = string.sub(tab1[i],j,j)
  1405. local tex2 = " "
  1406. if #tab2 >= i then
  1407. tex2= string.sub(tab2[i],j,j)
  1408. end
  1409. if tex1 == nil then
  1410. tex1 = " "
  1411. end
  1412. if tex2 == nil then
  1413. tex2 = " "
  1414. end
  1415. if tex2 == " " then
  1416. line = line..tex1
  1417. else
  1418. line = line..tex2
  1419. end
  1420. end
  1421. tab1[i] = line
  1422. end
  1423. return tab1
  1424. end
  1425.  
  1426. -- Will return the custom UI at position xpos,ypos. Otherwise will return nil
  1427. function findUIat(xpos,ypos)
  1428. local UItemp_c,UItemp_t = deepcopy(UI_c),deepcopy(UI_t)
  1429. local pairslist = {}
  1430. local iter =1
  1431. for k,v in pairs(meta["customUI"]) do
  1432. if k ~= 0 then
  1433. pairslist[iter] = k
  1434. iter = iter+1
  1435. end
  1436. end
  1437. for i=#pairslist,1,-1 do
  1438. if string.sub(meta["customUI"][pairslist[i]]["table"][ypos],xpos,xpos) ~= " " then
  1439. --found
  1440. return pairslist[i]
  1441. end
  1442. end
  1443. return nil -- [todo]
  1444. end
  1445. -- will allow the user to draw with dragable boxes until they are finished(key). left click create,rightclick erase. returns a table of what they drew.
  1446. function boxDrag(xpos,ypos)
  1447. local xsize,ysize = term.getSize()
  1448. local xmin,ymin = 1,2
  1449. local c_,t_ = emptyScreen(term)
  1450. local c2_,t2_ = emptyScreen(term)
  1451. while true do
  1452. local event, button, xpos2, ypos2 = os.pullEvent()
  1453. local x_,y_,x,y = xpos,ypos
  1454. local UI_c_t = deepcopy(UI_c)
  1455. if string.match(event,"mouse") then
  1456. x,y = xpos2,ypos2
  1457. if xpos>=xpos2 then
  1458. x_= xpos2
  1459. x = xpos
  1460. end
  1461. if ypos>=ypos2 then
  1462. y_ = ypos2
  1463. y = ypos
  1464. end
  1465. end
  1466.  
  1467. if event == "mouse_drag" and ypos2>1 then
  1468. c2_,t2_ = emptyScreen(term)
  1469. if button == 2 then
  1470. c2_ = tc(c2_,x_,y_-1,colors.black,x,y-1)
  1471. else
  1472. c2_ = tc(c2_,x_,y_-1,colors.white,x,y-1)
  1473. end
  1474. c_ = overwriteTable(deepcopy(c_),deepcopy(c2_))
  1475. drawPictureTable(term,overwriteTable(UI_c_t,overwriteTable(deepcopy(c_),deepcopy(c2_))),xmin,ymin,colors.black)
  1476. elseif event == "mouse_click"then
  1477. if ypos2>1 then
  1478.  
  1479. if button == 1 then
  1480. c_ = tc(c_,xpos2,ypos2-1,colors.white)
  1481. xpos = xpos2
  1482. ypos = ypos2
  1483. elseif button == 2 then
  1484. c_ = tc(c_,xpos2,ypos2-1,colors.black)
  1485. xpos = xpos2
  1486. ypos = ypos2
  1487. end
  1488. c_ = overwriteTable(deepcopy(c2_),deepcopy(c_))
  1489. drawPictureTable(term,overwriteTable(deepcopy(UI_c_t),deepcopy(c_)),xmin,ymin,colors.black)
  1490. else -- Menu Click
  1491. grabInput(xpos2,ypos2,button,event)
  1492. return replaceColorTable(replaceColorTable(c_,colors.white,colors.cyan),colors.black)
  1493. end
  1494. elseif event == "key" then
  1495. c_ = overwriteTable(c_,c2_)
  1496. return replaceColorTable(replaceColorTable(c_,colors.white,colors.cyan),colors.black)
  1497. end
  1498.  
  1499. --c2_ = deepcopy(c_)
  1500. end
  1501. end
  1502.  
  1503. --Will replace any color (or only arg[1]) in a table with " ", or whatever color arg[2] is. if arg[1] == true then every color will be replaced with arg[2] or " "
  1504. function replaceColorTable(tab,...)
  1505. local tex = " "
  1506. local color_hex = "%S"
  1507. if #arg > 0 then
  1508. if arg[1] ~= true then
  1509. color_hex = getHexOf(arg[1])
  1510. end
  1511. if #arg >1 then
  1512. tex = getHexOf(arg[2])
  1513. end
  1514. end
  1515. for i=1,#tab do
  1516. local line = ""
  1517. for j=1,#tab[i] do
  1518. if string.match(string.sub(tab[i],j,j),color_hex) then
  1519. line = line..tex
  1520. else
  1521. line = line..string.sub(tab[i],j,j)
  1522. end
  1523. end
  1524. tab[i] = line
  1525. end
  1526. return tab
  1527. end
  1528.  
  1529. --Will scan table tab for arg[1], returns true if found. if no args supplied will scan tab for any non-space character
  1530. function scanTableFor(tab,...)
  1531. local tex = " "
  1532. if #arg>0 then tex = getHexOf(arg[1]) end
  1533. for i=1,#tab do
  1534. for j=1,#tab[i] do
  1535. if #arg == 0 and string.sub(tab[i],j,j) ~= tex and string.sub(tab[i],j,j) ~= " " then
  1536. return true
  1537. elseif #arg >0 and string.sub(tab[i],j,j) == tex then
  1538. return true
  1539. end
  1540. end
  1541. end
  1542. return false
  1543. end
  1544.  
  1545. function addUI(tab)
  1546. if scanTableFor(tab) then
  1547. local newkey = #meta["customUI"] +1
  1548. meta["customUI"][newkey] = {["table"] = deepcopy(tab), ["signal"] = nil,["name"] = nil, ["onColor"] = colors.green, ["offColor"] = colors.cyan, ["state"] = false}
  1549. end
  1550. end
  1551.  
  1552. function colorsPullSideways(name,xpos,ypos,gap)
  1553. local t_c = {"",""}
  1554. local t_t = {"",""}
  1555. local xoff = 0
  1556. local yoff = 0
  1557. local xsize,ysize = term.getSize()
  1558. local offset = gap+string.len(name)
  1559. for i=1,offset do
  1560. t_c[1] = t_c[1]..getHexOf(colors.green)
  1561. t_t[1] = t_t[1].." "
  1562. end
  1563. t_t = tt(t_t,1,1,name)
  1564. local newlist = {}
  1565. local c_title = colors.cyan
  1566. local c_titletext = colors.white
  1567. local c_list = colors.cyan
  1568. local c_listtext = colors.white
  1569.  
  1570. local t_c2,t_t2 = emptyScreen(term,3,5)
  1571. t_c2 = tc(t_c2,1,1,colors.green,4,1)
  1572. local iter = 1
  1573. for i=1,4 do
  1574. for j=1,4 do
  1575. t_c2 = tc(t_c2,i,j+1,sig_values[iter])
  1576. iter = iter+1
  1577. end
  1578. end
  1579. if xpos+offset+4 >= xsize then
  1580. xoff = 3-(xsize-(xpos+offset))
  1581. end
  1582. if ypos+4>ysize then
  1583. yoff = 4-(ysize-ypos)
  1584. end
  1585. drawPictureTable(term,t_c,xpos,ypos,colors.black,t_t)
  1586. drawPictureTable(term,t_c2,xpos+offset-xoff,ypos-yoff,colors.black)
  1587. local event, button1, xpos2, ypos2 = os.pullEvent("mouse_click","monitor_touch")
  1588. if xpos2 >= xpos+offset-xoff and xpos2<=xpos+4+offset-xoff and ypos2>ypos-yoff and ypos2<=ypos+5-yoff and event == "mouse_click" then
  1589. iter=1
  1590. for i=1,4 do
  1591. for j=1,4 do
  1592. if xpos2-(offset+xpos-1)+xoff == i and ypos2-ypos+yoff ==j then
  1593. return sig_values[iter]
  1594. end
  1595. iter = iter+1
  1596. end
  1597. end
  1598. end
  1599. return nil
  1600. end
  1601. ----------------------------------------------------------------
  1602. -----------------------------[ Program ]--------------------
  1603. ----------------------------------------------------------------
  1604.  
  1605. function createHeader()
  1606. local t_c,t_t
  1607. local xsize,ysize = term.getSize()
  1608. local clr,txt = emptyScreen(term)
  1609. clr = tc(clr,1,1,colors.blue,xsize,1)
  1610. local pos_temp = 1
  1611. for i=1,#HeaderNames do
  1612. clr= tc(clr,pos_temp,1,colors.blue,pos_temp+string.len(HeaderNames[i])-1,1)
  1613. txt=tt(txt,pos_temp,1,HeaderNames[i],colors.lightGray)
  1614. pos_temp = pos_temp +2 +string.len(HeaderNames[i])
  1615. end
  1616. return {clr[1],""},{txt[1],""}
  1617. end
  1618.  
  1619. function grabInput(...)
  1620. local event, button, xPos, yPos
  1621. if #arg == 4 then
  1622. canRefresh = true
  1623. refreshDisplay()
  1624. xPos = arg[1]
  1625. yPos = arg[2]
  1626. button = arg[3]
  1627. event = arg[4]
  1628. elseif #arg == 1 then
  1629. while true do
  1630. event, button, xPos, yPos = grabEvents("locked")
  1631. if event ~= "monitor_touch" and event ~= "terminate" then
  1632. error("Wrong event type",2)
  1633. else
  1634. break
  1635. end
  1636. end
  1637. else
  1638. canRefresh = true
  1639. refreshDisplay()
  1640. while true do
  1641. event, button, xPos, yPos = grabEvents(true)
  1642. if event == "mouse_click" or event == "mouse_drag" or event == "monitor_touch" then
  1643. break
  1644. end
  1645. end
  1646. end
  1647. canRefresh = false
  1648. respondInput(xPos,yPos,button,event)
  1649. end
  1650.  
  1651. function userSignalSelection(text,...)
  1652. local showNetwork = true
  1653. local showFace = true
  1654. local showCable = true
  1655. local showState = true
  1656. if #arg>0 then
  1657. showNetwork = arg[1]
  1658. showFace = arg[2]
  1659. showCable = arg[3]
  1660. showState = arg[4]
  1661. end
  1662. local screen = term
  1663. local x1,y1 = screen.getSize()
  1664. local t_c,t_t = emptyScreen(screen,x1,y1)
  1665. local bg_color = colors.white
  1666. local fg_color = colors.lightBlue
  1667. local b_color = colors.yellow
  1668. local text_color = colors.white
  1669. local xpadding = 4
  1670. local text_start = math.floor(y1/2) -3
  1671. local lines = {}
  1672. local c_unselected = colors.orange
  1673. local c_pulldown = colors.lightGray
  1674. local my_signal = {["ID"] = os.getComputerID(),["face"] = nil,["cable"]=nil}
  1675.  
  1676. while true do
  1677. local t_c,t_t = nil,nil
  1678. t_c,t_t = emptyScreen(screen,x1,y1)
  1679. if string.len(text) > x1-(2+xpadding*2) then
  1680. local newline = ""
  1681. local ystartmod = 1
  1682. local i = 1
  1683. for word in string.gmatch(text, "%S+") do
  1684. if string.len(newline.." "..word) > x1-10 then
  1685. lines[i+1] = nil
  1686. lines[i] = newline
  1687. i=i+1
  1688. newline = word
  1689. else
  1690. newline = newline.." "..word
  1691. end
  1692. end
  1693. if newline ~= nil then
  1694. lines[#lines+1] = newline
  1695. end
  1696. if #lines > 3 then
  1697. ystartmod = 3
  1698. end
  1699. text_start = math.floor(y1/2 - #lines/2 -ystartmod)
  1700. for i=1,#lines do
  1701. t_t = tt(t_t,math.floor((x1-string.len(lines[i]))/2),text_start+i,lines[i],text_color)
  1702. end
  1703. else --one line message
  1704. t_t = tt(t_t,math.floor((x1-string.len(text))/2),text_start,text,text_color)
  1705. end
  1706. t_c = tc(t_c,1,1,bg_color,x1,y1) --background
  1707. t_c = tc(t_c,xpadding,text_start-1,fg_color,x1-xpadding,text_start+6+#lines) --forground
  1708. local menupos = text_start+3+#lines
  1709. if showNetwork then
  1710. if my_signal["ID"] == nil then
  1711. t_c = tc(t_c,6,menupos,c_unselected ,19,menupos)
  1712. t_t = tt(t_t,6,menupos,"Select Network",colors.black)
  1713. else
  1714. t_c = tc(t_c,6,menupos,c_pulldown,19,menupos)
  1715. t_t = tt(t_t,6,menupos,fstring(networkNames[my_signal["ID"]],14),colors.black)
  1716. end
  1717. end
  1718. if showFace then
  1719. if my_signal["face"] == nil then
  1720. t_c = tc(t_c,21,menupos,c_unselected,31,menupos)
  1721. t_t = tt(t_t,21,menupos,"Select Face",colors.black)
  1722. else
  1723. t_c = tc(t_c,21,menupos,c_pulldown,31,menupos)
  1724. t_t = tt(t_t,21,menupos,my_signal["face"],colors.black)
  1725. end
  1726. end
  1727. if showCable then
  1728. if my_signal["ID"] ~= nil and my_signal["face"] ~= nil and signal[my_signal["ID"]][my_signal["face"]]["isBundle"] then
  1729. if my_signal["cable"] == nil then
  1730. t_c = tc(t_c,33,menupos,c_unselected ,43,menupos)
  1731. t_t = tt(t_t,33,menupos,"Select Wire",colors.black)
  1732. else
  1733. t_c = tc(t_c,33,menupos,c_pulldown,33+string.len(my_signal["cable"]),menupos)
  1734. t_t = tt(t_t,33,menupos,my_signal["cable"],colors.black)
  1735. end
  1736. end
  1737. end
  1738. t_c = tc(t_c,x1/2-9,menupos+2,b_color,x1/2-6,menupos+2)
  1739. t_c = tc(t_c,x1/2+3,menupos+2,b_color,x1/2+10,menupos+2)
  1740. t_t = tt(t_t,x1/2-8,menupos+2,"OK",colors.black)
  1741. t_t = tt(t_t,x1/2+4,menupos+2,"Cancel",colors.black)
  1742. drawPictureTable(screen, t_c, 1, 1, colors.black,t_t)
  1743. local event, button, xpos, ypos = grabEvents()
  1744. if event == "mouse_click" then
  1745. if ypos == menupos then --signal selection.
  1746. if xpos>5 and xpos <= 19 and showNetwork then -- network pulldown
  1747. local iter = 3
  1748. local list = {}
  1749. list[1] = "Select Network"
  1750. list[2] = "Refresh Network"
  1751. for k,v in pairs(networkNames) do
  1752. list[iter] = v
  1753. if k ~= os.getComputerID() then
  1754. list[iter] = list[iter].." ("..k..")"
  1755. else
  1756. list[iter] = list[iter].." (Local)"
  1757. end
  1758. iter = iter+1
  1759. end
  1760. local result,xpos2,ypos2,button2,event2 = createPulldown(6,menupos,list,true)
  1761. if result ~= "exit" then
  1762. if result == list[2] then
  1763. RSupdateNetwork()
  1764. sleep(0)
  1765. else
  1766. for i=3,#list do
  1767. if result == list[i] then
  1768. local ID --os.getComputerID()
  1769. for k,v in pairs(networkNames) do
  1770. if list[i] == v.." ("..k..")" or list[i] ==v.." (Local)"then
  1771. ID = k
  1772. end
  1773. end
  1774. if ID == nil then error("Nil ID in networking") end
  1775. if ID == os.getComputerID() then
  1776. my_signal["ID"] = os.getComputerID()
  1777. local s_temp,l_temp,m_temp = FSload(ID..".meta")
  1778. my_signal["face"] = nil
  1779. my_signal["cable"] = nil
  1780. elseif RedOSPing(ID,true) and ID ~= os.getComputerID then
  1781. if attachModem() then
  1782. rednet.send(ID,"redOS Request meta")
  1783. end
  1784. sleep(0.1)
  1785. local s_temp,l_temp,m_temp = FSload(ID..".meta")
  1786. if m_temp["password"] ~= "" and m_temp["password"] ~= nil then
  1787. if encrypt(userInput("Please enter the password for terminal '"..m_temp["computerName"].."':","string",true),m_temp["ID"]) == m_temp["password"] then
  1788. my_signal["ID"] = ID
  1789. my_signal["face"] = nil
  1790. my_signal["cable"] = nil
  1791. else
  1792. userInput("Invalid Password for '"..m_temp["computerName"].."'")
  1793. end
  1794. else
  1795. my_signal["face"] = nil
  1796. my_signal["cable"] = nil
  1797. my_signal["ID"] = ID
  1798. end
  1799. end
  1800. end
  1801. end
  1802. end
  1803. else
  1804. -- [exit]
  1805. end
  1806. elseif xpos>20 and xpos<=31 and showFace then
  1807. local list = {}
  1808. list[1] = "Select Face"
  1809. for i=1,#sig_faces do
  1810. list[i+1] = sig_faces[i]
  1811. end
  1812. local result,xpos2,ypos2,button2,event2 = createPulldown(21,menupos,list,true)
  1813. if result ~= "exit" then
  1814. my_signal["cable"] = nil
  1815. my_signal["face"] = result
  1816. else
  1817. -- [exit]
  1818. end
  1819. elseif showCable and xpos >=33 and xpos<=43 and my_signal["ID"] ~= nil and my_signal["face"] ~= nil and signal[my_signal["ID"]][my_signal["face"]]["isBundle"] then
  1820. local list = {}
  1821. list[1] = "Select Wire"
  1822. for i=1,#sig_names do
  1823. list[i+1] = sig_names[i]
  1824. end
  1825. local result,xpos2,ypos2,button2,event2 = createPulldown(33,menupos,list,true)
  1826. if result ~= "exit" then
  1827. validSignal = false
  1828. my_signal["cable"] = result
  1829. for i=1,#sig_names do
  1830. if result == sig_names[i] then
  1831. my_signal["value"] = sig_values[i]
  1832. end
  1833. end
  1834. else
  1835. -- [exit]
  1836. end
  1837. end
  1838. elseif ypos == menupos+2 then
  1839. if xpos>=x1/2-10 and xpos<=x1/2-6 then
  1840. if (my_signal["ID"] ~= nil or not showNetwork) and (my_signal["face"] ~= nil or not showFace) and (not showCable or not signal[my_signal["ID"]][my_signal["face"]]["isBundle"] or my_signal["cable"] ~= nil) then
  1841. local val = 0
  1842. for i=1,#sig_names do
  1843. if my_signal["cable"] == sig_names[i] then
  1844. val = sig_values[i]
  1845. break
  1846. end
  1847. end
  1848. return my_signal["ID"],my_signal["face"],val
  1849. end
  1850. elseif xpos>=x1/2+2 and xpos<=x1/2+10 then
  1851. return nil,nil,nil
  1852. end
  1853. end
  1854. end
  1855.  
  1856. --os.reboot()
  1857. end
  1858. end
  1859.  
  1860. function respondInput(xpos,ypos,button,event)
  1861. if event == "mouse_click" or event == "monitor_touch" then
  1862. if button == 1 and event == "mouse_click" and ypos ==1 then
  1863. -- Header Pulldowns
  1864. if ypos == 1 then
  1865. local h = {[0]=1}
  1866. for i=1,#HeaderNames do
  1867. h[i] = h[i-1]+string.len(HeaderNames[i]) +2
  1868. if xpos >= h[i-1] and xpos<h[i]-2 then
  1869. headerPulldown(HeaderNames[i],h[i-1])
  1870. end
  1871. end
  1872. end
  1873. else
  1874.  
  1875. -- UI selection
  1876. local uiKey = nil
  1877. if event ~= "monitor_touch" then
  1878. uiKey = findUIat(xpos,ypos-1)
  1879. else
  1880. uiKey = findUIat(xpos,ypos)
  1881. end
  1882. if button ==2 and ypos >1 then
  1883. if uiKey ~= nil then
  1884. -- ValidUI
  1885. replaceColorTable(meta["customUI"][uiKey]["table"],true,colors.lime)
  1886. refreshDisplay(true)
  1887. local list = {"UI Options","Delete UI object","Disconnect Signal","Enable Click-to-Toggle","Set Off Color","Set On Color"}
  1888. if meta["customUI"][uiKey]["button"] == true then
  1889. list[4] = "Disable Click-to-Toggle"
  1890. end
  1891. if meta["customUI"][uiKey]["signal"] == nil then
  1892. list[3] = "Connect a Signal"
  1893. end
  1894. local result,xpos2,ypos2,button,event = createPulldown(xpos,ypos,list,true)
  1895. replaceColorTable(meta["customUI"][uiKey]["table"],true,colors.cyan)
  1896. if result ~= "exit" then
  1897. if result == "Delete UI object" then
  1898. meta["customUI"][uiKey] = nil
  1899. elseif result == list[4] then
  1900. if meta["customUI"][uiKey]["signal"] == nil then
  1901. userInput("This UI object needs to be connected to a signal first!")
  1902. else
  1903. meta["customUI"][uiKey]["button"] = not meta["customUI"][uiKey]["button"]
  1904. end
  1905. elseif result == list[3] then
  1906. if meta["customUI"][uiKey]["signal"] == nil then
  1907. local a,b,c =userSignalSelection("Please Select a signal. Note: If you plan on using this as a Click-to-Toggle signal, I highly recommend using a 'virtual' signal (unless you know what you are doing).")
  1908. if a ~= nil and b~= nil and c~= nil then
  1909. local str = a.."|"..b.."|"..c.."|".."true"
  1910. meta["customUI"][uiKey]["signal"] = str
  1911. checkUIandUpdate(true)
  1912. refreshDisplay(true)
  1913. end
  1914. else
  1915. meta["customUI"][uiKey]["signal"] = nil
  1916. end
  1917. elseif result == list[6] then
  1918. local new_c = colorsPullSideways(list[6].." ",xpos,ypos2,0)
  1919. if new_c ~= "nil" and new_c ~= nil then
  1920. meta["customUI"][uiKey]["onColor"] = new_c
  1921. checkUIandUpdate(true)
  1922. refreshDisplay(true)
  1923. end
  1924. elseif result == list[5] then
  1925. local new_c = colorsPullSideways(list[5].." ",xpos,ypos2,0)
  1926. if new_c ~= "nil" and new_c ~= nil then
  1927. meta["customUI"][uiKey]["offColor"] = new_c
  1928. replaceColorTable(meta["customUI"][uiKey]["table"],true,new_c)
  1929. checkUIandUpdate(true)
  1930. refreshDisplay(true)
  1931. end
  1932. end
  1933. else
  1934. checkUIandUpdate(true)
  1935. refreshDisplay(true)
  1936. end
  1937. end
  1938. elseif button == 1 or event == "monitor_touch" then
  1939. if uiKey ~= nil then
  1940. if meta["customUI"][uiKey]["signal"] ~= nil and meta["customUI"][uiKey]["button"] == true then
  1941. -- switch then/else
  1942. local a,b,c,d = decodeSignal(meta["customUI"][uiKey]["signal"])
  1943. rednet.send(a,"redOS toggle|"..meta["customUI"][uiKey]["signal"])
  1944. end
  1945. end
  1946. end
  1947. end
  1948. elseif event =="mouse_drag" then
  1949. if ypos>1 and meta["showCustom"] then
  1950. addUI(boxDrag(xpos,ypos))
  1951. end
  1952. else
  1953.  
  1954. end
  1955. end
  1956. --returns true if a password exists
  1957. function setupPassword(...)
  1958. if meta["password"] == nil or meta["password"] == "" then
  1959. if arg[1] then
  1960. if not userInput("No password found! You need to configure a password before you can continue. Continue?",true) then
  1961. return false
  1962. end
  1963. end
  1964. meta["password"] = encrypt(userInput("Please enter a password:","string"),meta["ID"])
  1965. if meta["password"] == "" or meta["password"] == nil then
  1966. userInput("Invalid Password")
  1967. return false
  1968. end
  1969. return true
  1970. end
  1971. return true
  1972. end
  1973. function lockTerminal()
  1974. if setupPassword(true) then
  1975. if not meta["isLocked"] then
  1976. meta["isLocked"] = true
  1977. end
  1978. FSsave(meta["ID"]..".meta")
  1979.  
  1980. local pullEvent = os.pullEvent
  1981. os.pullEvent = os.pullEventRaw
  1982. local function one()
  1983.  
  1984. while true do
  1985. local guess = userInput("This terminal has been locked. A password is required for access:","string",true)
  1986. if encrypt(guess,meta["ID"]) == meta["password"] then
  1987. meta["isLocked"] = false
  1988. userInput("This terminal has been unlocked")
  1989. FSsave(meta["ID"]..".meta")
  1990. break
  1991. else
  1992. sleep(0.5)
  1993. userInput("Incorrect Password")
  1994. end
  1995. end
  1996.  
  1997. end
  1998. local function two()
  1999. while true do
  2000. grabInput(true)
  2001. end
  2002. end
  2003. parallel.waitForAny(one,two)
  2004. os.pullEvent = pullEvent
  2005. end
  2006. end
  2007. --returns the string if its smaller than len, otherwise will trim and add ..
  2008. function fstring(str,len)
  2009. if str == nil or str == "" then
  2010. return "NIL STRING" -- debuging stuff
  2011. end
  2012. if string.len(str) > len then
  2013. return string.sub(str,0,len-2)..".."
  2014. else
  2015. return str
  2016. end
  2017. end
  2018.  
  2019. -- Required to pull more than 1 event from os.pullevent without having it trigged on network or redstone activity (apparently its just passing os.pullEvent() instantly)
  2020. function grabEvents(...)
  2021. local event, button, xpos, ypos
  2022. function one()
  2023. event, button, xpos, ypos = os.pullEvent("mouse_click")
  2024. end
  2025. function two()
  2026. event, button, xpos, ypos = os.pullEvent("key")
  2027. end
  2028. function three()
  2029. event, button, xpos, ypos = os.pullEvent("mouse_drag")
  2030. end
  2031. function four()
  2032. event, button, xpos, ypos = os.pullEvent("monitor_touch")
  2033. end
  2034. if #arg == 0 then
  2035. parallel.waitForAny(one,two,four)
  2036. elseif arg[1] ~= "locked" then
  2037. parallel.waitForAny(one,two,three,four)
  2038. elseif arg[1] == "locked" then
  2039. four()
  2040. end
  2041. return event, button, xpos, ypos
  2042. end
  2043. function logicScreen()
  2044.  
  2045. local xsize,ysize = term.getSize()
  2046. local c_bg = colors.lightBlue
  2047. local c_bord = colors.yellow
  2048. local c_pulldown = colors.lightGray
  2049. local c_pulldown_t = colors.white
  2050. local c_unselected = colors.orange
  2051. local saved = true
  2052. local validSignal = false
  2053. local my_logic = {} -- {["if"] = {["and"] = "",["or"] = ""},["then"]= true, ["else"] = false}
  2054. local my_signal = {["ID"] = os.getComputerID(), ["face"] = nil, ["cable"] = nil,["value"]=0, ["toggle"] = false, ["then"] = nil, ["else"] = nil}
  2055. local logic_temp = deepcopy(logic)
  2056. local my_trusted = {}
  2057. my_trusted[os.getComputerID()] = true
  2058. local function logicToString(l) --returns and,or
  2059. local andstr = ""
  2060. local orstr = ""
  2061. local iter = 1
  2062. for k,v in pairs(l) do
  2063. if l[k]["ID"] ~= nil and l[k]["face"] ~= nil and tonumber(l[k]["value"]) ~= nil and l[k]["state"] ~= nil then
  2064. if l[k]["isAnd"] then
  2065. andstr = andstr..l[k]["ID"].."|"..l[k]["face"].."|"..l[k]["value"].."|"..tostring(l[k]["state"]).." "
  2066. else
  2067. orstr = orstr..l[k]["ID"].."|"..l[k]["face"].."|"..l[k]["value"].."|"..tostring(l[k]["state"]).." "
  2068. end
  2069. end
  2070. iter = iter+1
  2071. end
  2072. if andstr == "" then
  2073. andstr = nil
  2074. end
  2075. if orstr == "" then
  2076. orstr = nil
  2077. end
  2078. return andstr,orstr
  2079. end
  2080. local function validSave()--l,s,l_temp)
  2081. local l = my_logic
  2082. local s = my_signal
  2083. local l_temp = logic_temp
  2084. local a,b = logicToString(l)
  2085. if a == nil then
  2086. a = ""
  2087. end
  2088. if b == nil then
  2089. b = ""
  2090. end
  2091. local l_temp2 = {["and"] = a,["or"] =b}
  2092. local pass = true
  2093. for k,v in pairs(l_temp[s["face"]][s["value"]]["if"]) do
  2094. local wordcount = 0
  2095. local word2count = 0
  2096. for word in string.gmatch(l_temp[s["face"]][s["value"]]["if"][k], "%S+") do
  2097. local check=false
  2098. wordcount = wordcount+1
  2099. word2count = 0
  2100. for word2 in string.gmatch(l_temp2[k],"%S+") do
  2101. word2count = word2count +1
  2102. if word ~= nil and word2 ~= nil and word == word2 then
  2103. check=true
  2104. break
  2105. end
  2106. end
  2107. if not check then
  2108. pass = false
  2109. break
  2110. end
  2111. end
  2112. if wordcount ~= word2count then
  2113. pass = false
  2114. end
  2115. end
  2116. if (a == "" and b == "") or (l_temp[s["face"]][s["value"]]["if"]["and"] == nil and l_temp[s["face"]][s["value"]]["if"]["or"] == nil) then
  2117. pass = false
  2118. if (a == "" and b == "") and (l_temp[s["face"]][s["value"]]["if"]["and"] == nil and l_temp[s["face"]][s["value"]]["if"]["or"] == nil) then
  2119. pass = true
  2120. end
  2121. end
  2122. return pass
  2123. end
  2124. local function save(s,l)
  2125. local a,b = logicToString(l)
  2126. local sig,log_,met = FSload(s["ID"]..".meta")
  2127. log_[s["face"]][s["value"]] = {["if"] = {["and"] = nil, ["or"] = nil},["then"] = nil,["else"] =nil}
  2128. log_[s["face"]][s["value"]]["if"]["and"] = a
  2129. log_[s["face"]][s["value"]]["if"]["or"] = b
  2130. if s["toggle"] then
  2131. log_[s["face"]][s["value"]]["then"] = "toggle "..tostring(s["then"])
  2132. log_[s["face"]][s["value"]]["else"] = "toggle "..tostring(s["else"])
  2133. else
  2134. log_[s["face"]][s["value"]]["then"] = s["then"]
  2135. log_[s["face"]][s["value"]]["else"] = s["else"]
  2136. end
  2137. if sig[s["ID"]][s["face"]]["isRead"] then
  2138. sig[s["ID"]][s["face"]]["isRead"] = not userInput("Warning!, The current face you are adding logic to is set to 'read'. In order to output a signal it needs to be set to 'write'. Would you like to set this face to 'write' now? (you won't be able to read in redstone from the "..s["face"].." face)",true)
  2139. end
  2140. FSsave(s["ID"]..".meta",sig,log_,met)
  2141. if s["ID"] == os.getComputerID() then
  2142. signal[os.getComputerID()][s["face"]]["isRead"] = sig[s["ID"]][s["face"]]["isRead"]
  2143. logic = deepcopy(log_)
  2144. else
  2145. if attachModem() then
  2146. rednet.send(s["ID"],"redOS Request meta")
  2147. end
  2148.  
  2149. end
  2150. end
  2151. while true do
  2152.  
  2153. local IFpos = 1
  2154. local t_c,t_t = emptyScreen(term)
  2155. local IF_c,IF_t = emptyScreen(term,33,ysize)
  2156.  
  2157. if validSignal then
  2158. t_c = tc(t_c,1,1,colors.gray,xsize,5)
  2159. t_c = tc(t_c,1,5,c_bg,xsize,ysize)
  2160. IF_c = tc(IF_c,1,1,c_bg,34,ysize)
  2161. if my_signal["then"] == logic_temp[my_signal["face"]][my_signal["value"]]["then"] or (my_signal["toggle"] and "toggle "..tostring(my_signal["then"]) == logic_temp[my_signal["face"]][my_signal["value"]]["then"]) then
  2162. t_c = tc(t_c,38,7,colors.lightGray,xsize-2,7)
  2163. else
  2164. t_c = tc(t_c,38,7,c_unselected,xsize-2,7)
  2165. saved = false
  2166. end
  2167. if my_signal["else"] == logic_temp[my_signal["face"]][my_signal["value"]]["else"] or (my_signal["toggle"] and "toggle "..tostring(my_signal["else"]) == logic_temp[my_signal["face"]][my_signal["value"]]["else"]) then
  2168. t_c = tc(t_c,38,11,colors.lightGray,xsize-2,11)
  2169. else
  2170. t_c = tc(t_c,38,11,c_unselected,xsize-2,11)
  2171. saved = false
  2172. end
  2173. local strthen
  2174. local strelse
  2175. if tostring(my_signal["then"]) == "true" then
  2176. strthen = "On "
  2177. elseif tostring(my_signal["then"]) == "false" then
  2178. strthen = "Off"
  2179. else --pulse
  2180. if type(my_signal["then"]) == "string" then
  2181. error("{"..my_signal["then"].."}")
  2182. end
  2183. strthen = string.sub("Pulse ("..tostring(my_signal["then"]/10)..")",0,12)
  2184. end
  2185. if tostring(my_signal["else"]) == "true" then
  2186. strelse = "On"
  2187. elseif tostring(my_signal["else"]) == "false" then
  2188. strelse= "Off"
  2189. else --pulse
  2190. strelse = string.sub("Pulse ("..tostring(my_signal["else"]/10)..")",0,12)
  2191. end
  2192. t_t = tt(t_t,38+(6-math.ceil(string.len(strthen)/2)),7,strthen,colors.black)
  2193. t_t = tt(t_t,38+(6-math.ceil(string.len(strelse)/2)),11,strelse,colors.black)
  2194. if my_signal["toggle"] then
  2195. local c_tog = colors.lightGray
  2196. if string.sub(tostring(logic_temp[my_signal["face"]][my_signal["value"]]["else"]),0,7) ~= "toggle " then
  2197. c_tog = c_unselected
  2198. saved = false
  2199. end
  2200. t_t = tt(t_t,41,15,"True",colors.black)
  2201. t_c = tc(t_c,41,15,c_tog,xsize-7,15)
  2202. else
  2203. local c_tog = c_unselected
  2204. if string.sub(tostring(logic_temp[my_signal["face"]][my_signal["value"]]["else"]),0,7) ~= "toggle " then
  2205. c_tog = colors.lightGray
  2206. else
  2207. saved = false
  2208. end
  2209. t_t = tt(t_t,41,15,"False",colors.black)
  2210. t_c = tc(t_c,41,15,c_tog,xsize-6,15)
  2211. end
  2212. IFpos = 1
  2213.  
  2214. for word,_ in pairs(my_logic) do
  2215. my_logic[word]["IFpos"] = IFpos
  2216. local andor = "Or"
  2217. local onoff = "Off"
  2218. local pdcolor = colors.orange
  2219. if my_logic[word]["saved"] then pdcolor = colors.lightGray else saved = false end
  2220. if my_logic[word]["isAnd"] then andor="And" end
  2221. if my_logic[word]["state"] then onoff="On" end
  2222. IF_t = tt(IF_t,1,IFpos,"-",colors.white)
  2223. IF_t = tt(IF_t,2,IFpos,andor,colors.black)
  2224. IF_t = tt(IF_t,6,IFpos,fstring(my_logic[word]["networkName"],8),colors.black)
  2225. IF_t = tt(IF_t,15,IFpos,my_logic[word]["face"],colors.black)
  2226. IF_t = tt(IF_t,22,IFpos,my_logic[word]["name"],colors.black)
  2227. IF_t = tt(IF_t,32,IFpos,onoff,colors.black)
  2228. IF_c = tc(IF_c,1,IFpos,colors.brown)
  2229. IF_c = tc(IF_c,2,IFpos,pdcolor,4,IFpos)
  2230. IF_c = tc(IF_c,6,IFpos,pdcolor,13,IFpos)
  2231. IF_c = tc(IF_c,15,IFpos,pdcolor,20,IFpos)
  2232. IF_c = tc(IF_c,22,IFpos,pdcolor,30,IFpos)
  2233. IF_c = tc(IF_c,32,IFpos,pdcolor,34,IFpos)
  2234. if type(word) == "string" then
  2235. my_logic[IFpos] = deepcopy(my_logic[word])
  2236. my_logic[word] = {}
  2237. end
  2238. IFpos = IFpos+1
  2239. end
  2240. IF_t = tt(IF_t,1,IFpos,"+Add Conditional",colors.black)
  2241. IF_c = tc(IF_c,1,IFpos,colors.green)
  2242. IF_c = tc(IF_c,2,IFpos,colors.lime,16,IFpos)
  2243. else
  2244. t_c = tc(t_c,1,1,c_bg,xsize,5)
  2245. t_c = tc(t_c,1,5,colors.gray,xsize,ysize)
  2246. IF_c = tc(IF_c,1,1,colors.gray,34,ysize)
  2247.  
  2248. end
  2249. IF_c = tc(IF_c,1,ysize-6,colors.yellow,34,ysize-6)
  2250. t_c = tc(t_c,1,1,c_bord,xsize,1)
  2251. t_c = tc(t_c,1,1,c_bord,1,ysize)
  2252. t_c = tc(t_c,xsize,1,c_bord,xsize,ysize)
  2253. t_c = tc(t_c,1,ysize,c_bord,xsize,ysize)
  2254. --t_c = tc(t_c,2,ysize-1,colors.lightGray,xsize-1,ysize-1)
  2255. t_t = tt(t_t,(xsize-string.len("Logic"))/2,1,"Logic",colors.black)
  2256.  
  2257. if saved then
  2258. t_c = tc(t_c,42,1,colors.lightGray,45,1)
  2259. else
  2260. t_c = tc(t_c,42,1,colors.lime,45,1)
  2261. end
  2262. t_t = tt(t_t,42,1,"Save",colors.black)
  2263. t_c = tc(t_c,47,1,colors.lightGray,50,1)
  2264. t_t = tt(t_t,47,1,"Exit",colors.black)
  2265. t_c = tc(t_c,1,5,colors.yellow,xsize,5)
  2266. t_c = tc(t_c,36,5,colors.yellow,36,ysize)
  2267. t_c = tc(t_c,36,9,colors.yellow,xsize,9)
  2268. t_t = tt(t_t,2,2,"Signal",colors.black)
  2269. t_c = tc(t_c,2,2,colors.yellow,7,2)
  2270. t_t = tt(t_t,2,6,"IF",colors.black)
  2271. t_c = tc(t_c,2,6,colors.yellow,3,6)
  2272. t_t = tt(t_t,37,6,"THEN",colors.black)
  2273. t_c = tc(t_c,37,6,colors.yellow,40,6)
  2274. t_t = tt(t_t,37,10,"ELSE",colors.black)
  2275. t_c = tc(t_c,37,10,colors.yellow,40,10)
  2276. t_t = tt(t_t,37,14,"Toggle",colors.black)
  2277. t_c = tc(t_c,37,14,colors.yellow,42,14)
  2278. t_c = tc(t_c,37,13,colors.yellow,xsize,13)
  2279. --------------------------------------------------onto dynamic stuff
  2280. if my_signal["ID"] == nil then
  2281. t_c = tc(t_c,4,3,c_unselected ,17,3)
  2282. t_t = tt(t_t,4,3,"Select Network",colors.black)
  2283. else
  2284. t_c = tc(t_c,4,3,c_pulldown,17,3)
  2285. t_t = tt(t_t,4,3,fstring(networkNames[my_signal["ID"]],14),colors.black)
  2286. end
  2287. if my_signal["face"] == nil then
  2288. t_c = tc(t_c,19,3,c_unselected,29,3)
  2289. t_t = tt(t_t,19,3,"Select Face",colors.black)
  2290. else
  2291. t_c = tc(t_c,19,3,c_pulldown,29,3)
  2292. t_t = tt(t_t,19,3,my_signal["face"],colors.black)
  2293. end
  2294. if my_signal["ID"] ~= nil and my_signal["face"] ~= nil and signal[my_signal["ID"]][my_signal["face"]]["isBundle"] then
  2295. if my_signal["cable"] == nil then
  2296. t_c = tc(t_c,31,3,c_unselected ,41,3)
  2297. t_t = tt(t_t,31,3,"Select Wire",colors.black)
  2298. else
  2299. t_c = tc(t_c,31,3,c_pulldown,31+string.len(my_signal["cable"]),3)
  2300. t_t = tt(t_t,31,3,my_signal["cable"],colors.black)
  2301. end
  2302. end
  2303.  
  2304. drawPictureTable(term, t_c, 1, 1, colors.black,t_t)
  2305. drawPictureTable(term, IF_c, 2, 7, colors.black,IF_t)
  2306. local event, button, xpos, ypos = grabEvents()
  2307. if event == "mouse_click" then
  2308. if ypos == 3 then --signal selection.
  2309. if (validSignal and not saved and xpos>3 and xpos<=41 and userInput("If you change the signal, all unsaved logic will be lost. Are you sure you want to continue?",true)) or not validSignal or saved then
  2310. drawPictureTable(term, t_c, 1, 1, colors.black,t_t)
  2311. if xpos>3 and xpos <= 17 then -- network pulldown
  2312. local iter = 3
  2313. local list = {}
  2314. list[1] = "Select Network"
  2315. list[2] = "Refresh Network"
  2316. for k,v in pairs(networkNames) do
  2317. list[iter] = v
  2318. if k ~= os.getComputerID() then
  2319. list[iter] = list[iter].." ("..k..")"
  2320. else
  2321. list[iter] = list[iter].." (Local)"
  2322. end
  2323. iter = iter+1
  2324. end
  2325. local result,xpos2,ypos2,button2,event2 = createPulldown(4,3,list,true)
  2326. if result ~= "exit" then
  2327. if result == list[2] then
  2328. RSupdateNetwork()
  2329. sleep(0)
  2330. else
  2331. for i=3,#list do
  2332. if result == list[i] then
  2333. local ID --os.getComputerID()
  2334. for k,v in pairs(networkNames) do
  2335. if list[i] == v.." ("..k..")" or list[i] ==v.." (Local)"then
  2336. ID = k
  2337. end
  2338. end
  2339. if ID == nil then error("Nil ID in networking") end
  2340. if ID == os.getComputerID() then
  2341. my_signal["ID"] = os.getComputerID()
  2342. local s_temp,l_temp,m_temp = FSload(ID..".meta")
  2343. logic_temp = deepcopy(l_temp)
  2344. validSignal = false
  2345. my_signal["face"] = nil
  2346. my_signal["cable"] = nil
  2347. my_signal["value"] = 0
  2348. elseif RedOSPing(ID,true) and ID ~= os.getComputerID then
  2349. if attachModem() then
  2350. rednet.send(ID,"redOS Request meta")
  2351. end
  2352. sleep(0)
  2353. local s_temp,l_temp,m_temp = FSload(ID..".meta")
  2354. if m_temp["password"] ~= "" and m_temp["password"] ~= nil and type(my_trusted[ID]) == "nil" then
  2355. if encrypt(userInput("Please enter the password for terminal '"..m_temp["computerName"].."':","string",true),m_temp["ID"]) == m_temp["password"] then
  2356. my_signal["ID"] = ID
  2357. logic_temp = deepcopy(l_temp)
  2358. validSignal = false
  2359. my_trusted[ID] = true
  2360. my_signal["face"] = nil
  2361. my_signal["cable"] = nil
  2362. my_signal["value"] = 0
  2363. else
  2364. userInput("Invalid Password for '"..m_temp["computerName"].."'")
  2365. end
  2366. else
  2367. my_signal["face"] = nil
  2368. my_signal["cable"] = nil
  2369. my_signal["value"] = 0
  2370. validSignal = false
  2371. my_signal["ID"] = ID
  2372. logic_temp = deepcopy(l_temp)
  2373. my_trusted[ID] = true
  2374. end
  2375.  
  2376. end
  2377. end
  2378. end
  2379. end
  2380. else
  2381. -- [exit]
  2382. end
  2383. elseif xpos>18 and xpos<=29 then
  2384. local list = {}
  2385. list[1] = "Select Face"
  2386. for i=1,#sig_faces do
  2387. list[i+1] = sig_faces[i]
  2388. end
  2389. local result,xpos2,ypos2,button2,event2 = createPulldown(19,3,list,true)
  2390. if result ~= "exit" then
  2391. validSignal = false
  2392.  
  2393. my_signal["cable"] = nil
  2394. my_signal["value"] = 0
  2395. my_signal["face"] = result
  2396. else
  2397. -- [exit]
  2398. end
  2399. elseif xpos >=31 and xpos<=41 and my_signal["ID"] ~= nil and my_signal["face"] ~= nil and signal[my_signal["ID"]][my_signal["face"]]["isBundle"] then
  2400. local list = {}
  2401. list[1] = "Select Wire"
  2402. for i=1,#sig_names do
  2403. list[i+1] = sig_names[i]
  2404. end
  2405. local result,xpos2,ypos2,button2,event2 = createPulldown(31,3,list,true)
  2406. if result ~= "exit" then
  2407. validSignal = false
  2408. my_signal["cable"] = result
  2409. for i=1,#sig_names do
  2410. if result == sig_names[i] then
  2411. my_signal["value"] = sig_values[i]
  2412. end
  2413. end
  2414. else
  2415. -- [exit]
  2416. end
  2417. end
  2418. end
  2419.  
  2420. elseif ypos > 6 and ypos <=IFpos+6 and xpos <36 then
  2421. for i=1,IFpos do
  2422. if ypos == i+6 then
  2423. -- we found the selected my_logic[i]
  2424.  
  2425. if xpos==2 and type(my_logic[i]) ~= "nil" then
  2426.  
  2427. local my_logic_temp = {}
  2428. local iter = 1
  2429. for ii=1,IFpos do
  2430. if type(my_logic[ii]) ~= "nil" and ii~= i then
  2431. my_logic_temp[iter] = my_logic[ii]
  2432. iter = iter+1
  2433. end
  2434. end
  2435. my_logic = deepcopy(my_logic_temp)
  2436. IFpos = IFpos-1
  2437. saved = false
  2438. elseif xpos >=2 and xpos <=16 and i == IFpos then
  2439. -- Add a new logic node
  2440. local sig_name = "Wire"
  2441. local sig_value = 0
  2442. if signal[os.getComputerID()]["Front"]["isBundle"] then
  2443. sig_name = "White"
  2444. sig_value = 1
  2445. end
  2446. my_logic[i] = {["networkName"] = "(local)",["ID"] = os.getComputerID(),["saved"] = false,["isAnd"] = true,["name"] = sig_name,["face"] = "Front",["value"] = sig_value,["state"] = true}
  2447. my_logic[i]["isBundle"] = signal[os.getComputerID()]["Front"]["isBundle"]
  2448.  
  2449. elseif i ~= IFpos then
  2450. -- Pulldowns mofo
  2451. if xpos>2 and xpos<6 then
  2452. my_logic[i]["isAnd"] = not my_logic[i]["isAnd"]
  2453. saved = false
  2454. my_logic[i]["saved"] = false
  2455. elseif xpos>6 and xpos <15 then
  2456. local list = {"Network "}
  2457. local iter = 2
  2458. for k,v in pairs(networkNames) do
  2459. list[iter] = v
  2460. if k ~= os.getComputerID() then
  2461. list[iter] = list[iter].." ("..k..")"
  2462. else
  2463. list[iter] = list[iter].." (Local)"
  2464. end
  2465. iter = iter+1
  2466. end
  2467. local result2,xpos2,ypos2,button2,event2 = createPulldown(7,ypos,list,true)
  2468. if result2 ~= "exit" then
  2469. saved = false
  2470. my_logic[i]["saved"] = false
  2471. for ii=2,#list do
  2472. if result2== list[ii] then
  2473. local ID --os.getComputerID()
  2474. for k,v in pairs(networkNames) do
  2475. if list[ii] == v.." ("..k..")" or list[ii] ==v.." (Local)"then
  2476. ID = k
  2477. end
  2478. end
  2479. if ID == os.getComputerID() then
  2480. my_logic[i]["networkName"] = "(local)"
  2481. else
  2482. my_logic[i]["networkName"] = networkNames[ID]
  2483. end
  2484. my_logic[i]["ID"] = ID
  2485. my_logic[i]["isBundle"] = signal[my_logic[i]["ID"]][my_logic[i]["face"]]["isBundle"]
  2486. if my_logic[i]["isBundle"] then
  2487. my_logic[i]["value"] = 1
  2488. my_logic[i]["Name"] = "White"
  2489. else
  2490. my_logic[i]["value"] = 0
  2491. my_logic[i]["Name"] = "Wire"
  2492. end
  2493. end
  2494. end
  2495. else
  2496. --[exit]
  2497. end
  2498. elseif xpos>15 and xpos<22 then
  2499. local list = {"Face "}
  2500. for ii=1,#sig_faces do
  2501. list[ii+1] = sig_faces[ii]
  2502. end
  2503. local result2,xpos2,ypos2,button2,event2 = createPulldown(16,ypos,list,true)
  2504. if result2 ~= "exit" then
  2505. saved = false
  2506. my_logic[i]["saved"] = false
  2507. my_logic[i]["face"] = result2
  2508. if signal[my_logic[i]["ID"]][result2]["isBundle"] then
  2509. my_logic[i]["isBundle"] = true
  2510. my_logic[i]["value"] = 1
  2511. my_logic[i]["name"] = "White"
  2512. else
  2513. my_logic[i]["isBundle"] = false
  2514. my_logic[i]["value"] = 0
  2515. my_logic[i]["name"] = "Wire"
  2516. end
  2517. else
  2518. -- [exit]
  2519. end
  2520. elseif xpos>22 and xpos<32 then
  2521. if my_logic[i]["isBundle"] then
  2522. local list = {"Cable ","Make Wire"}
  2523. for ii=1,#sig_names do
  2524. list[ii+2] = sig_names[ii]
  2525. end
  2526. local result2,xpos2,ypos2,button2,event2 = createPulldown(23,ypos,list,true)
  2527. if result2 ~= "exit" then
  2528. if result2 == "Make Wire" then
  2529. if userInput("Warning! If you change this face to a wire, it will no longer be able to read bundled cable. Any existing logic on this face will break. Continue?",true) then
  2530. if my_logic[i]["ID"] ~= os.getComputerID() then
  2531. if attachModem() then
  2532. rednet.send(my_logic[i]["ID"],"redOS Request meta")
  2533. end
  2534. sleep(0)
  2535. local s_,l_,m_ = FSload(my_logic[i]["ID"]..".meta")
  2536. if m_["password"] ~= nil and m_["password"] ~= "" and type(my_trusted[ID]) == "nil" then
  2537. if encrypt(userInput("In order to change the cable type you must enter the password for terminal '"..m_["computerName"].."':","string"),m_["ID"]) == m_["password"] then
  2538. s_[my_logic[i]["ID"]][my_logic[i]["face"]]["isBundle"] = false
  2539. signal[my_logic[i]["ID"]][my_logic[i]["face"]]["isBundle"] = false
  2540. FSsave(my_logic[i]["ID"]..".meta",s_,l_,m_)
  2541. my_trusted[my_logic[i]["ID"]] = true
  2542. saved = false
  2543. my_logic[i]["saved"] = false
  2544. my_logic[i]["isBundle"] =false
  2545. my_logic[i]["name"] = "Wire"
  2546. my_logic[i]["value"] = 0
  2547. else
  2548. userInput("Invalid Password for '"..m_["computerName"].."'. The cable type will remain a wire")
  2549. end
  2550. else
  2551. s_[my_logic[i]["ID"]][my_logic[i]["face"]]["isBundle"] = false
  2552. signal[my_logic[i]["ID"]][my_logic[i]["face"]]["isBundle"] = false
  2553. FSsave(my_logic[i]["ID"]..".meta",s_,l_,m_)
  2554. my_trusted[my_logic[i]["ID"]] = true
  2555. saved = false
  2556. my_logic[i]["saved"] = false
  2557. my_logic[i]["isBundle"] =false
  2558. my_logic[i]["name"] = "Wire"
  2559. my_logic[i]["value"] = 0
  2560. end
  2561. else
  2562. signal[my_logic[i]["ID"]][my_logic[i]["face"]]["isBundle"] = false
  2563. saved = false
  2564. my_logic[i]["saved"] = false
  2565. my_logic[i]["isBundle"] =false
  2566. my_logic[i]["name"] = "Wire"
  2567. my_logic[i]["value"] = 0
  2568. FSsave(my_logic[i]["ID"]..".meta")
  2569. end
  2570. for key,val in pairs(my_logic) do
  2571. if my_logic[i]["ID"] == my_logic[key]["ID"] and my_logic[key]["isBundle"] ~= signal[my_logic[i]["ID"]][my_logic[key]["face"]]["isBundle"] then
  2572. my_logic[key]["isBundle"] = signal[my_logic[i]["ID"]][my_logic[key]["face"]]["isBundle"]
  2573. if my_logic[key]["isBundle"] and my_logic[key]["value"] == 0 then
  2574. my_logic[key]["value"] = 1
  2575. my_logic[key]["name"] = "White"
  2576. elseif not my_logic[key]["isBundle"] and my_logic[key]["value"] ~= 0 then
  2577. my_logic[key]["value"] = 0
  2578. my_logic[key]["name"] = "Wire"
  2579. end
  2580. end
  2581. end
  2582. if my_logic[i]["ID"] == my_signal["ID"] and my_logic[i]["face"] == my_signal["face"] then
  2583. my_signal["cable"] = nil
  2584. validSignal = false
  2585. end
  2586. end
  2587. else
  2588. saved = false
  2589. my_logic[i]["saved"] = false
  2590. my_logic[i]["name"] = result2
  2591. for ii=1,#sig_names do
  2592. if result2 == sig_names[ii] then
  2593. my_logic[i]["value"] = sig_values[ii]
  2594. end
  2595. end
  2596. end
  2597. else
  2598. -- [exit]
  2599. end
  2600. else
  2601. local list = {"Wire ","Make Cable"}
  2602. local result2,xpos2,ypos2,button2,event2 = createPulldown(23,ypos,list,true)
  2603. if result2 ~= "exit" then
  2604. saved = false
  2605. my_logic[i]["saved"] = false
  2606. if result2 == "Make Cable" then
  2607. if userInput("Warning! If you change this face to a bundled cable, it will no longer be able to read normal redstone. Any existing logic on this face will break. Continue?",true) then
  2608. if my_logic[i]["ID"] ~= os.getComputerID() then
  2609. if attachModem() then
  2610. rednet.send(my_logic[i]["ID"],"redOS Request meta")
  2611.  
  2612. end
  2613. sleep(0)
  2614. local s_,l_,m_ = FSload(my_logic[i]["ID"]..".meta")
  2615. if m_["password"] ~= nil and m_["password"] ~= "" and type(my_trusted[ID]) == "nil" then
  2616. if encrypt(userInput("In order to change the cable type you must enter the password for terminal '"..m_["computerName"].."':","string"),m_["ID"]) == m_["password"] then
  2617. s_[my_logic[i]["ID"]][my_logic[i]["face"]]["isBundle"] = true
  2618. signal[my_logic[i]["ID"]][my_logic[i]["face"]]["isBundle"] = true
  2619. FSsave(my_logic[i]["ID"]..".meta",s_,l_,m_)
  2620. my_trusted[my_logic[i]["ID"]] = true
  2621. saved = false
  2622. my_logic[i]["saved"] = false
  2623. my_logic[i]["isBundle"] =true
  2624. my_logic[i]["name"] = "White"
  2625. my_logic[i]["value"] = 1
  2626. else
  2627. userInput("Invalid Password for '"..m_["computerName"].."'. The cable type will remain a wire")
  2628. end
  2629. else
  2630. s_[my_logic[i]["ID"]][my_logic[i]["face"]]["isBundle"] = true
  2631. signal[my_logic[i]["ID"]][my_logic[i]["face"]]["isBundle"] = true
  2632. FSsave(my_logic[i]["ID"]..".meta",s_,l_,m_)
  2633. my_trusted[my_logic[i]["ID"]] = true
  2634. saved = false
  2635. my_logic[i]["saved"] = false
  2636. my_logic[i]["isBundle"] =true
  2637. my_logic[i]["name"] = "White"
  2638. my_logic[i]["value"] = 1
  2639. end
  2640. else
  2641. signal[my_logic[i]["ID"]][my_logic[i]["face"]]["isBundle"] = true
  2642. saved = false
  2643. my_logic[i]["saved"] = false
  2644. my_logic[i]["isBundle"] =true
  2645. my_logic[i]["name"] = "White"
  2646. my_logic[i]["value"] = 1
  2647. FSsave(my_logic[i]["ID"]..".meta")
  2648. end
  2649. for key,val in pairs(my_logic) do
  2650. if my_logic[i]["ID"] == my_logic[key]["ID"] and my_logic[key]["isBundle"] ~= signal[my_logic[i]["ID"]][my_logic[key]["face"]]["isBundle"] then
  2651. my_logic[key]["isBundle"] = signal[my_logic[i]["ID"]][my_logic[key]["face"]]["isBundle"]
  2652. if my_logic[key]["isBundle"] and my_logic[key]["value"] == 0 then
  2653. my_logic[key]["value"] = 1
  2654. my_logic[key]["name"] = "White"
  2655. elseif not my_logic[key]["isBundle"] and my_logic[key]["value"] ~= 0 then
  2656. my_logic[key]["value"] = 0
  2657. my_logic[key]["name"] = "Wire"
  2658. end
  2659. end
  2660. end
  2661. if my_logic[i]["ID"] == my_signal["ID"] and my_logic[i]["face"] == my_signal["face"] then
  2662. my_signal["cable"] = nil
  2663. validSignal = false
  2664. end
  2665. end
  2666. end
  2667. else
  2668. -- [exit]
  2669. end
  2670. end
  2671. elseif xpos>32 and xpos<36 then
  2672. my_logic[i]["state"] = not my_logic[i]["state"]
  2673. saved = false
  2674. my_logic[i]["saved"] = false
  2675. else
  2676. -- [exit]
  2677.  
  2678. end
  2679. end
  2680. end
  2681. end
  2682. elseif xpos > 37 and ypos > 5 then
  2683. --We are in ELSE and THEN and toggle
  2684. if ypos == 7 and xpos < xsize-2 then
  2685. local list = {"Then ","On","Off","Pulse"}
  2686. local result2,xpos2,ypos2,button2,event2 = createPulldown(38,ypos,list,true)
  2687. if result2 ~= "exit" then
  2688. if result2 == list[2] then
  2689. my_signal["then"] = true
  2690. elseif result2 == list[3] then
  2691. my_signal["then"] = false
  2692. else
  2693. local val
  2694. while true do
  2695. val = userInput("Please enter a pulse timing in seconds","number")
  2696. if val >= 0.1 then
  2697. break
  2698. else
  2699. userInput("The timing must be greater than 0.1 seconds")
  2700. end
  2701. end
  2702. my_signal["then"] = math.ceil(val*10)
  2703. end
  2704. else
  2705. -- [exit]
  2706. end
  2707. elseif ypos == 11 and xpos < xsize-2 then
  2708. local list = {"else ","On","Off","Pulse"}
  2709. local result2,xpos2,ypos2,button2,event2 = createPulldown(38,ypos,list,true)
  2710. if result2 ~= "exit" then
  2711. if result2 == list[2] then
  2712. my_signal["else"] = true
  2713. elseif result2 == list[3] then
  2714. my_signal["else"] = false
  2715. else
  2716. local val
  2717. while true do
  2718. val = userInput("Please enter a pulse timing in seconds","number")
  2719. if val >= 0.1 then
  2720. break
  2721. else
  2722. userInput("The timing must be greater than 0.1 seconds")
  2723. end
  2724. end
  2725. my_signal["else"] = math.ceil(val*10)
  2726. end
  2727. else
  2728. -- [exit]
  2729. end
  2730. elseif ypos == 15 and xpos < xsize-5 and xpos>40 then
  2731. my_signal["toggle"] = not my_signal["toggle"]
  2732. end
  2733. elseif ypos == 1 and xpos>xsize-11 then
  2734. if not saved and xpos<xsize-6 and validSignal then
  2735. save(my_signal,my_logic)
  2736. sleep(0)
  2737. local _,logic_,_ = FSload(my_signal["ID"]..".meta")
  2738. logic_temp = {}
  2739. logic_temp = deepcopy(logic_)
  2740. saved = true
  2741. validSignal = false
  2742. elseif xpos>xsize-6 and xpos <xsize then
  2743. if not saved and validSignal then
  2744. if userInput("Are you sure you want to exit? all unsaved data will be lost",true) then
  2745. break
  2746. end
  2747. else
  2748. break
  2749. end
  2750. end
  2751. end
  2752. else
  2753. --os.reboot()
  2754. end
  2755. if not validSignal and my_signal["ID"] ~= nil and my_signal["face"] ~= nil and ((signal[my_signal["ID"]][my_signal["face"]]["isBundle"] and my_signal["cable"] ~= nil) or not signal[my_signal["ID"]][my_signal["face"]]["isBundle"]) then
  2756. validSignal = true
  2757. my_signal["then"] = logic_temp[my_signal["face"]][my_signal["value"]]["then"]
  2758. my_signal["else"] = logic_temp[my_signal["face"]][my_signal["value"]]["else"]
  2759. if string.match(string.sub(tostring(my_signal["then"]),0,6),"toggle") then
  2760. my_signal["toggle"] = true
  2761. my_signal["then"] = toType(string.sub(logic_temp[my_signal["face"]][my_signal["value"]]["then"],8))
  2762. my_signal["else"] = toType(string.sub(logic_temp[my_signal["face"]][my_signal["value"]]["else"],8))
  2763. else
  2764. my_signal["toggle"] = false
  2765. end
  2766. my_logic = {}
  2767. IFpos = 1
  2768. for k,v in pairs(logic_temp[my_signal["face"]][my_signal["value"]]["if"]) do
  2769. for word in string.gmatch(v, "%S+") do
  2770. if k=="and" or k=="or" then
  2771. local ID_,face,sig_value,state = decodeSignal(word)
  2772. local onoff = "On"
  2773. local sig_name = "Wire"
  2774. if not state then
  2775. onoff = "Off"
  2776. end
  2777. if type(networkNames[ID_]) == "nil" then
  2778. networkNames[ID_] = "Unknown "..ID_
  2779. local s_ = signal_setup(ID_)
  2780. signal[ID_] = deepcopy(s_[ID_])
  2781. end
  2782. if sig_value ~= 0 then
  2783. for kk,vv in pairs(sig_values) do
  2784. if sig_value == vv then
  2785. sig_name = sig_names[kk]
  2786. end
  2787. end
  2788. end
  2789. --my_logic[word] = {}
  2790. if os.getComputerID() == ID_ then networkName = "(Local)" else networkName = networkNames[ID_] end
  2791. my_logic[IFpos] = {["networkName"] = networkName,["ID"] = ID_,["saved"] = true,["isAnd"] = false,["name"] = sig_name,["face"] = face,["value"] = sig_value,["state"] = state}
  2792. if sig_value > 0 then
  2793. my_logic[IFpos]["isBundle"] = true
  2794. end
  2795. if k == "and" then
  2796. my_logic[IFpos]["isAnd"] = true
  2797. end
  2798. IFpos = IFpos +1
  2799. end
  2800. end
  2801. end
  2802. --end
  2803. elseif validSignal then
  2804. if not validSave() then--validSave(my_logic,my_signal,logic_temp) then
  2805. saved = false
  2806. else
  2807. saved = true
  2808. end
  2809.  
  2810. end
  2811. end
  2812. end
  2813.  
  2814.  
  2815. function configScreen()
  2816. local xsize,ysize = term.getSize()
  2817. local c_bg = colors.lightBlue
  2818. local c_bord = colors.yellow
  2819. local saved = true
  2820. local options = {"Computer Name:","Password:","Read Only:","Boot Into:","Trusted PCs:"}
  2821. local query = {
  2822. "This will assign a custom name to this PC. The name will be visible on all networks.";
  2823. "This is the password for the PC, it will be prompted when other users try to connect or when you lock the terminal";
  2824. "If this is set to true, other computers will not be able to edit anything on this PC. However, they will still be able to read its data (not working yet)";
  2825. "TODO";
  2826. "TODO";
  2827. }
  2828.  
  2829. local readonly = meta["isRead"]
  2830. local computerName = meta["computerName"]
  2831. local password = meta["password"]
  2832. local bootinto = meta["bootInto"]
  2833.  
  2834. while true do
  2835. local t_c,t_t = emptyScreen(term)
  2836. t_c = tc(t_c,1,1,c_bg,xsize,ysize)
  2837. t_c = tc(t_c,1,1,c_bord,xsize,1)
  2838. t_c = tc(t_c,1,1,c_bord,1,ysize)
  2839. t_c = tc(t_c,xsize,1,c_bord,xsize,ysize)
  2840. t_c = tc(t_c,1,ysize,c_bord,xsize,ysize)
  2841. for i=1,#options do
  2842. local xpos = 4
  2843. local ypos = i*2+3
  2844. --t_c = tc(t_c,xpos,ypos,c_bord,xpos+string.len("(EDIT)")-1,ypos)
  2845. --t_t = tt(t_t,xpos,ypos,"(EDIT)",colors.gray)
  2846. t_c = tc(t_c,xpos-1,ypos,colors.green)
  2847. t_t = tt(t_t,xpos-1,ypos,"?",colors.black)
  2848. t_t = tt(t_t,xpos+1,ypos,options[i],colors.black)
  2849. t_c = tc(t_c,xpos+1,ypos,colors.cyan,xpos+1+#options[i]-1,ypos)
  2850. local txtbg_c = colors.lightGray
  2851. if (i == 1 and computerName ~= meta["computerName"]) or (i == 2 and password ~= meta["password"]) or (i==3 and readonly ~= meta["isRead"]) or (i==4 and bootinto ~= meta["bootInto"] ) then
  2852. txtbg_c = colors.orange
  2853. saved = false
  2854. end
  2855. if i == 1 then
  2856. t_t = tt(t_t,xpos+2+string.len(options[i]),ypos,computerName,colors.black)
  2857. t_c = tc(t_c,xpos+2+string.len(options[i]),ypos,txtbg_c,xpos+1+#computerName+string.len(options[i]),ypos)
  2858. elseif i == 2 then
  2859. if password == nil or password == "" then
  2860. t_t = tt(t_t,xpos+2+string.len(options[i]),ypos,"Add Password",colors.black)
  2861. t_c = tc(t_c,xpos+2+string.len(options[i]),ypos,txtbg_c,xpos+13+string.len(options[i]),ypos)
  2862. else
  2863. t_t = tt(t_t,xpos+2+string.len(options[i]),ypos,"Edit Password",colors.black)
  2864. t_c = tc(t_c,xpos+2+string.len(options[i]),ypos,txtbg_c,xpos+14+string.len(options[i]),ypos)
  2865. t_t = tt(t_t,xpos+16+string.len(options[i]),ypos,"(Remove)",colors.black)
  2866. t_c = tc(t_c,xpos+16+string.len(options[i]),ypos,colors.yellow,xpos+23+string.len(options[i]),ypos)
  2867. end
  2868. elseif i==3 then
  2869. t_c = tc(t_c,xpos+2+#options[i],ypos,txtbg_c,xpos+1+#options[i]+string.len(tostring(readonly)),ypos)
  2870.  
  2871. t_t = tt(t_t,xpos+2+string.len(options[i]),ypos,tostring(readonly),colors.black)
  2872. elseif i==4 then
  2873. if bootinto ~= os.getComputerID() then
  2874. local networkname = networkNames[bootinto]
  2875. if networkNames[bootinto] == nil then
  2876. RSupdateNetwork()
  2877. sleep(0)
  2878. if networkNames[bootinto] == nil then
  2879. networkname= "Not Found"
  2880. else
  2881. networkname = networkNames[bootinto]
  2882. end
  2883. end
  2884. t_t = tt(t_t,xpos+2+string.len(options[i]),ypos,networkname,colors.black)
  2885. t_c = tc(t_c,xpos+2+string.len(options[i]),ypos,txtbg_c,xpos+1+string.len(networkNames[bootinto])+string.len(options[i]),ypos)
  2886. else
  2887. t_t = tt(t_t,xpos+2+string.len(options[i]),ypos,"(Local)",colors.black)
  2888. t_c = tc(t_c,xpos+2+string.len(options[i]),ypos,txtbg_c,xpos+8+string.len(options[i]),ypos)
  2889. end
  2890. end
  2891. end
  2892. t_c = tc(t_c,14,ysize-2,colors.yellow,19,ysize-2)
  2893. t_t = tt(t_t,15,ysize-2,"Save",colors.black)
  2894. t_t = tt(t_t,(xsize-string.len("Configuration"))/2,3,"Configuration",colors.black)
  2895. if meta["ID"] ~= os.getComputerID() then
  2896. t_t = tt(t_t,(xsize-string.len(networkNames[meta["ID"]]))/2,2,networkNames[meta["ID"]],colors.black)
  2897. else
  2898. t_t = tt(t_t,(xsize-string.len("(Local)"))/2,2,"(Local)",colors.black)
  2899. end
  2900. t_c = tc(t_c,(xsize-string.len("Configuration"))/2,3,colors.cyan,(xsize+string.len("Configuration"))/2-1,3)
  2901. t_c = tc(t_c,31,ysize-2,colors.yellow,36,ysize-2)
  2902. t_t = tt(t_t,32,ysize-2,"Exit",colors.black)
  2903. drawPictureTable(term, t_c, 1, 1, colors.black,t_t)
  2904. local event, button, xpos, ypos = grabEvents()
  2905. if event == "mouse_click" then
  2906. for i=1,#options do
  2907. if ypos == i*2+3 then
  2908. if xpos == 3 then --"?"
  2909. userInput(query[i])
  2910. elseif xpos > 5+#options[i] then
  2911. if i == 1 and xpos < 4+#options[i]+string.len(computerName)+2 then
  2912. t_c = tc(t_c,6+string.len(options[i]),ypos,colors.black,16+string.len(options[i]),ypos)
  2913. t_c = tc(t_c,16+string.len(options[i]),ypos,colors.lightBlue,xsize-1,ypos)
  2914. t_t = tt(t_t,6+string.len(options[i]),ypos," ",colors.black)
  2915. while true do
  2916. drawPictureTable(term, t_c, 1, 1, colors.black,t_t)
  2917. term.setCursorPos(6+string.len(options[i]),ypos)
  2918. local computerName_temp = io.read()
  2919. if computerName_temp ~= nil and computerName_temp ~= "" then
  2920. computerName = computerName_temp
  2921. break
  2922. end
  2923. end
  2924. elseif i==2 then
  2925. if xpos < 17+#options[i] then
  2926. if password == nil or password == "" then
  2927. while true do
  2928. password = encrypt(userInput("Please enter a new password:","string"),meta["ID"])
  2929. if password ~= nil and password ~= "" then
  2930. break
  2931. else
  2932. userInput("Invalid char")
  2933. end
  2934. end
  2935. else
  2936. if password == encrypt(userInput("Please enter the current password:","string"),meta["ID"]) then
  2937. while true do
  2938. password = encrypt(userInput("Please enter a new password:","string"),meta["ID"])
  2939. if password ~= nil and password ~= "" then
  2940. break
  2941. else
  2942. userInput("Invalid char")
  2943. end
  2944. end
  2945. else
  2946. userInput("Invalid Password")
  2947. end
  2948. end
  2949. elseif xpos > 17+#options[i] and xpos < 9+17+#options[i] then
  2950. if password == encrypt(userInput("Please enter the current password:","string"),meta["ID"]) then
  2951. password = ""
  2952. userInput("Password Removed")
  2953. else
  2954. userInput("Invalid Password")
  2955. end
  2956. end
  2957. elseif i ==3 and xpos <= 5+#options[i]+string.len(tostring(readonly)) then
  2958. readonly = not readonly
  2959. elseif i == 4 then
  2960. local a,b,c = userSignalSelection("Please select a network",true,false,false,false)
  2961. if a ~= nil then
  2962. bootinto = a
  2963. end
  2964. elseif i == 5 then
  2965.  
  2966. end
  2967. end
  2968. end
  2969. end
  2970. if ypos == ysize-2 then
  2971. if xpos >= 14 and xpos <= 20 then
  2972. meta["isRead"] = readonly
  2973. meta["computerName"] = computerName
  2974. meta["password"] = password
  2975. meta["bootInto"]= bootinto
  2976. networkNames[meta["ID"]] = computerName
  2977. saved = true
  2978. elseif xpos >= 31 and xpos <= 36 then
  2979. if saved then
  2980. break
  2981. else
  2982. if userInput("Are you sure you want to exit? All unsaved changes will be lost",true) then
  2983. break
  2984. end
  2985. end
  2986. end
  2987. end
  2988. elseif event =="key" and button == 28 then
  2989. if not saved then
  2990. meta["isRead"] = readonly
  2991. meta["computerName"] = computerName
  2992. meta["password"] = password
  2993. meta["bootInto"]= bootinto
  2994. networkNames[meta["ID"]] = computerName
  2995. saved = true
  2996. else
  2997. break
  2998. end
  2999. end
  3000. end
  3001. FSsave(meta["ID"]..".meta")
  3002. end
  3003. function headerPulldown(name,xpos)
  3004. if name == "Options" then
  3005. local list = {"Options","Lock Terminal","Config","Check for Updates","Command Line (Shell)","Restart","Reformat Terminal"}
  3006. local result,xpos2,ypos2,button,event = createPulldown(xpos,1,list,true)
  3007. if result == list[2] then
  3008. lockTerminal()
  3009. elseif result == list[3] then
  3010. configScreen()
  3011. elseif result == list[4] then
  3012. checkUpdates()
  3013. elseif result == list[5] then
  3014. MYshell()
  3015. elseif result == list[6] then
  3016. os.reboot()
  3017. elseif result == list[7] then
  3018. local warn_txt = networkNames[meta["ID"]]
  3019. if meta["ID"] == os.getComputerID() then
  3020. warn_txt = warn_txt.."(Local)"
  3021. else
  3022. warn_txt = warn_txt.."("..meta["ID"]..")"
  3023. end
  3024. local warning = "This will completely erase all custom logic/settings/UI's unique to the terminal "..warn_txt..". Are you sure you wish to continue? "
  3025. if userInput(warning,true) then
  3026. fs.delete(meta["ID"]..".meta")
  3027. --monFace = nil
  3028. FSsave(meta["ID"]..".meta",signal_setup(meta["ID"]),logic_setup(),meta_setup(meta["ID"]))
  3029. if meta["ID"] == os.getComputerID() then
  3030. signal,logic,meta = FSload(meta["ID"]..".meta")
  3031. os.reboot()
  3032. else
  3033. if attachModem() then
  3034. Debug(meta["ID"])
  3035. rednet.send(tonumber(meta["ID"]),"redOS 149634901231")
  3036. end
  3037. local sig,_,met = FSload(meta["ID"]..".meta")
  3038. meta = deepcopy(met)
  3039. signal = deepcopy(sig)
  3040. end
  3041. end
  3042. elseif result == "exit" then
  3043. grabInput(xpos2,ypos2,button,event)
  3044. end
  3045. elseif name == "View" then
  3046. local list = {"View","Erase custom UI","Push UI to monitor"}
  3047. local result,xpos2,ypos2,button,event = createPulldown(xpos,1,list,true)
  3048. if result == list[2] then
  3049. meta["customUI"] = {}
  3050. local c,t = emptyScreen(term)
  3051. meta["customUI"][0] = {["table"] = c,["text"] =t}
  3052. elseif result == list[3] then
  3053. list = {list[3],"Face:","Any","Front", "Back", "Left","Right","Top","Bottom"}
  3054. local result2,xpos3,ypos3,button1,event = pullsideways(list,xpos,3,0)
  3055. if result2 ~= "exit" then
  3056. local s,l,m = FSload(os.getComputerID()..".meta")
  3057. if result2 == list[3] then
  3058. for i=1,#comp_faces do
  3059. if peripheral.getType(string.lower(comp_faces[i])) == "monitor" then
  3060. monFace = string.lower(comp_faces[i])
  3061. mon = peripheral.wrap( string.lower(comp_faces[i]))
  3062. FSsave(os.getComputerID()..".meta",s,l,m)
  3063. end
  3064. end
  3065. elseif peripheral.isPresent(string.lower(result2)) and peripheral.getType(string.lower(result2)) =="monitor" then
  3066.  
  3067. mon = peripheral.wrap(string.lower(result2))
  3068. monFace = result2
  3069. FSsave(os.getComputerID()..".meta",s,l,m)
  3070. else
  3071. userInput("No monitor found on the "..string.lower(result2).." side of the terminal")
  3072. end
  3073. else
  3074. grabInput(xpos3,ypos3,button1,event)
  3075. end
  3076. elseif result == "exit" then
  3077. grabInput(xpos2,ypos2,button,event)
  3078. end
  3079.  
  3080. elseif name == "Cable" then
  3081. local list = {"Cable","Add Logic","Face Options"}
  3082. local result,xpos2,ypos2,button,event = createPulldown(xpos,1,list,true)
  3083. if result == list[2] then
  3084. logicScreen()
  3085. elseif result == list[3] then
  3086. list = {"Face Options","","Front","Back","Left","Right","Top","Bottom"}
  3087. local result2,xpos3,ypos3,button1,event = pullsideways(list,xpos,3,0)
  3088. if result2 ~= "exit" then
  3089. for i=2,#list do
  3090. if result2 == list[i] then
  3091. local var = {"Set as Bundle","Set to Read",list[i]}
  3092. if signal[meta["ID"]][list[i]]["isBundle"] then
  3093. var[1] = "Set as Wire"
  3094. end
  3095. if signal[meta["ID"]][list[i]]["isRead"] then
  3096. var[2] = "Set to Write"
  3097. end
  3098. for i=#list[i],5 do
  3099. var[3] = var[3].." "
  3100. end
  3101. local newlist = {var[3],"Toggle",var[1],var[2]}
  3102. local result3,xpos4,ypos4,button2,event = pullsideways(newlist,xpos+12,i,0)
  3103. if result3 ~= "exit" then
  3104. if result3 == newlist[3] then
  3105. if userInput("Warning! This will break any signals currently affecting the "..string.lower(list[i]).." face of the computer. Do you want to continue?",true) then
  3106. toggleBundle(meta["ID"],list[i])
  3107. end
  3108. else
  3109. if userInput("Warning! This will break any signals currently being set on the "..string.lower(list[i]).." face of the computer. Do you want to continue?",true) then
  3110. if not signal[meta["ID"]][list[i]]["isRead"] then
  3111. if signal[meta["ID"]][list[i]]["isBundle"] then
  3112. rs.setBundledOutput(string.lower(list[i]),0)
  3113. else
  3114. rs.setOutput(string.lower(list[i]),false)
  3115. end
  3116. end
  3117. signal[meta["ID"]][list[i]]["isRead"] = not signal[meta["ID"]][list[i]]["isRead"]
  3118. end
  3119. end
  3120. else
  3121. grabInput(xpos4,ypos4,button,event)
  3122. end
  3123. end
  3124. end
  3125. else
  3126. grabInput(xpos3,ypos3,button,event)
  3127. end
  3128. elseif result == "exit" then
  3129. grabInput(xpos2,ypos2,button,event)
  3130. end
  3131. elseif name == "Network" then
  3132. --RSupdateNetwork()
  3133. local list = {"Network","Refresh Network"}
  3134. num_networkNames = 0
  3135. for i,v in pairs(networkNames) do
  3136. num_networkNames = num_networkNames+1
  3137. end
  3138. if num_networkNames > 1 then
  3139. local iter = 4
  3140. for i,v in pairs(networkNames) do
  3141. if i ~= os.getComputerID() then
  3142. list[iter] = v.." ("..i..")"
  3143. else
  3144. list[3] = v.." (Local)"
  3145. iter = iter-1
  3146. end
  3147. iter = iter+1
  3148. end
  3149. end
  3150. local result,xpos2,ypos2,button,event = createPulldown(xpos,1,list,true)
  3151. if result == list[2] and list[2] == "Refresh Network" then
  3152. RSupdateNetwork()
  3153. sleep(0)
  3154. elseif result == "exit" then
  3155. grabInput(xpos2,ypos2,button,event)
  3156. else
  3157. for i=3,#list do
  3158. if result == list[i] then
  3159. local ID --os.getComputerID()
  3160. for k,v in pairs(networkNames) do
  3161. if list[i] == v.." ("..k..")" or list[i] ==v.." (Local)"then
  3162. ID = k
  3163. end
  3164. end
  3165. if ID == os.getComputerID() then
  3166. FSsave(meta["ID"]..".meta")
  3167. signal,_,meta = FSload(ID..".meta")
  3168. elseif RedOSPing(ID,true) and ID~= nil then
  3169.  
  3170. if fs.exists(ID..".meta") then fs.delete(ID..".meta") end
  3171. if attachModem() then
  3172. rednet.send(ID,"redOS Request meta")
  3173. end
  3174. while not fs.exists(ID..".meta") do
  3175. sleep(0.1)
  3176. end
  3177. local s_temp,l_temp,m_temp = FSload(ID..".meta")
  3178. if m_temp["password"] ~= "" and m_temp["password"] ~= nil then
  3179. if encrypt(userInput("Please enter the password for terminal '"..m_temp["computerName"].."':","string",true),m_temp["ID"]) == m_temp["password"] then
  3180. FSsave(meta["ID"]..".meta")
  3181. meta = deepcopy(m_temp)
  3182. signal[ID] = deepcopy(s_temp[ID])
  3183. else
  3184. userInput("Invalid Password, returning to terminal '"..meta["computerName"].."'")
  3185. end
  3186. else
  3187. FSsave(meta["ID"]..".meta")
  3188. signal[ID] = deepcopy(s_temp[ID])
  3189. meta = deepcopy(m_temp)
  3190. end
  3191.  
  3192. end
  3193. end
  3194. end
  3195. end
  3196. end
  3197. end
  3198. local refcnt = 0
  3199. function refreshDisplay(...)
  3200. refcnt = refcnt +1
  3201. local header_t_temp = deepcopy(header_t)
  3202. if networkNames[meta["ID"]] ~= nil then
  3203. local str = "("..string.sub(networkNames[meta["ID"]],0,19)..")"
  3204. if meta["ID"] == os.getComputerID() then
  3205. str = "(Local)"
  3206. end
  3207. if tonumber(string.match(str,"%d+")) ~= meta["ID"] then
  3208. str = str.." "..meta["ID"]
  3209. end
  3210.  
  3211. header_t_temp=tt(header_t_temp,52-string.len(str),1,str,colors.lightGray)
  3212. end
  3213.  
  3214. UI_c,UI_t = emptyScreen(term)
  3215. for k,v in pairs(meta["customUI"]) do
  3216. if k ~= 0 then
  3217. UI_c = overwriteTable(UI_c,v["table"])
  3218. end
  3219. end
  3220.  
  3221. if scanTableFor(meta["customUI"][0]["table"]) then
  3222. UI_c = overwriteTable(UI_c,meta["customUI"][0]["table"])
  3223. end
  3224. if term.isColor() then
  3225. if canRefresh or #arg>0 then
  3226. term.clear()
  3227. drawPictureTable(term, header_c, 1, 1, colors.black,header_t_temp)
  3228. drawPictureTable(term, UI_c, 1, 2, colors.black,UI_t)
  3229. end
  3230. else
  3231. term.clear()
  3232. term.setCursorPos(1,1)
  3233. print("RedOS Node")
  3234. print("Name: "..tostring(networkNames[os.getComputerID()]))
  3235. if type(networkNames[meta["ID"]]) ~= "nil" then
  3236. print("Connected to: "..networkNames[meta["ID"]])
  3237. end
  3238. for i=1,#comp_faces do
  3239. if peripheral.getType(string.lower(comp_faces[i])) == "monitor" then
  3240. monFace = string.lower(comp_faces[i])
  3241. end
  3242. end
  3243. end
  3244. if monFace ~= nil and peripheral.isPresent(string.lower(monFace)) and peripheral.getType(string.lower(monFace)) == "monitor" then
  3245. drawPictureTable(mon, UI_c, 1, 1, colors.black)
  3246. else
  3247. --someone broke the monitor
  3248. end
  3249.  
  3250. end
  3251.  
  3252.  
  3253. --Updates the colors of the UI to reflect the signal they are attached to.
  3254. function updateUIcolor(key,node)
  3255. if node["signal"] ~= nil then
  3256. local ID,face,sig_value,state = decodeSignal(node["signal"])
  3257. if isOn(signal,ID,face,sig_value) then
  3258. if scanTableFor(meta["customUI"][key]["table"],node["onColor"]) then
  3259. return false
  3260. end
  3261. replaceColorTable(meta["customUI"][key]["table"],true,node["onColor"])
  3262. return true
  3263. else
  3264. if scanTableFor(meta["customUI"][key]["table"],node["offColor"]) then
  3265. --Debug("OFF Looking for:"..getHexOf(node["onColor"]).." of key: "..key)
  3266. return false
  3267. end
  3268. replaceColorTable(meta["customUI"][key]["table"],true,node["offColor"])
  3269. return true
  3270. end
  3271. end
  3272.  
  3273. return false
  3274. end
  3275.  
  3276. function setupDisplay()
  3277. header_c,header_t = createHeader()
  3278. UI_c,UI_t = emptyScreen(term)
  3279. UI_c = tc(UI_c,2,2,colors.white,2,2)
  3280.  
  3281. end
  3282.  
  3283. signal = signal_setup()
  3284. logic = logic_setup()
  3285. meta = meta_setup()
  3286.  
  3287. if fs.exists(os.getComputerID()..".meta") then
  3288. signal,logic,meta = FSload(os.getComputerID()..".meta")
  3289. if monFace ~= nil then
  3290. mon = peripheral.wrap(monFace)
  3291. end
  3292. else
  3293.  
  3294. FSsave(os.getComputerID()..".meta")
  3295. end
  3296.  
  3297. setupDisplay()
  3298. networkNames[os.getComputerID()] = meta["computerName"]
  3299. function frontEnd()
  3300. if meta["bootInto"] ~= os.getComputerID() then
  3301. sleep(.5)
  3302. if RedOSPing(meta["bootInto"],true) then
  3303. if attachModem() then
  3304. rednet.send(meta["bootInto"],"redOS Request meta")
  3305. end
  3306.  
  3307. sleep(0.1)
  3308. local sig_,_,met_ = FSload(meta["bootInto"]..".meta")
  3309. signal[meta["bootInto"]] = deepcopy(sig_[meta["bootInto"]])
  3310. meta = deepcopy(met_)
  3311. end
  3312. end
  3313.  
  3314. while not splashdone do
  3315. sleep(0.1)
  3316. end
  3317.  
  3318. if meta["password"] ~= nil and meta["password"] ~= "" and meta["isLocked"] then
  3319. canRefresh = false
  3320. lockTerminal()
  3321. end
  3322. canRefresh = true
  3323. refreshDisplay()
  3324. while true do
  3325. grabInput()
  3326. FSsave(meta["ID"]..".meta")
  3327. local flist = fs.list("")
  3328. for i=1,#flist do
  3329. if string.match(flist[i],".meta") and flist[i] ~= meta["ID"]..".meta" and flist[i] ~= os.getComputerID()..".meta" then
  3330. fs.delete(flist[i])
  3331. end
  3332. end
  3333.  
  3334. end
  3335. end
  3336. function getTime()
  3337. http.request("http://alienmc.co/checkTPS.php")
  3338. local requesting = true
  3339. local valid = false
  3340. local respondedText = ""
  3341. while requesting do
  3342. local event, url, sourceText = os.pullEvent()
  3343. if event == "http_success" then
  3344. respondedText = sourceText.readAll()
  3345. valid = true
  3346. requesting = false
  3347. elseif event == "http_failure" then
  3348. requesting = false
  3349. end
  3350. end
  3351. local total = 0
  3352. for word in string.gmatch(respondedText,"%d+.%d+") do
  3353. total = total + tonumber(string.match(word,"(%d+).%d+")) + tonumber(string.match(word,"%d+.(%d+)"))/10
  3354. end
  3355. total = total/3
  3356. return total
  3357. end
  3358. function DebugScreen()
  3359. if DEBUG then
  3360. checkUpdates(true) -- forces a update
  3361. term.clear()
  3362. refreshDisplay()
  3363. local redcnt =0
  3364. local stncnt = 0
  3365. local allcnt = 0
  3366. local function countRednet()
  3367. while true do
  3368. --local event, _m,mess = os.pullEventRaw("rednet_message","modem_message")
  3369. redcnt = "DISABLED"
  3370. sleep(5)
  3371. --Debug(event.." Message: "..mess)
  3372. end
  3373. end
  3374. local function countstn()
  3375. while true do
  3376. sleep(5)
  3377. --os.pullEvent("redstone")
  3378. stncnt = "DISABLED"
  3379. end
  3380. end
  3381. local function allstn()
  3382. allcnt = "Disabled"
  3383. end
  3384. local function display()
  3385. while true do
  3386. sleep(0.5)
  3387. term.setCursorPos(1,19)
  3388. term.write("Refresh: "..refcnt)
  3389. term.setCursorPos(1,16)
  3390. --term.write("Redstone Events: "..stncnt)
  3391. term.setCursorPos(1,17)
  3392. --term.write("RedNet Events: "..redcnt)
  3393. term.setCursorPos(1,18)
  3394. --term.write("Total Events: "..allcnt)
  3395. end
  3396. end
  3397. --parallel.waitForAll(countRednet,countstn,allstn,display)
  3398. end
  3399. end
  3400.  
  3401.  
  3402. term.clear()
  3403.  
  3404. local Title = {
  3405. " 55 5 555 555 ";
  3406. "8585 85 8585 8585 ";
  3407. "85 85 85 5 5 85 85 55555 85 85 ";
  3408. "85 8585 85 85 855555 858885 855555 ";
  3409. "85 855 85 85 85888885 85 85 85888885 ";
  3410. "85 85 855555 85 85 855555 85 85 ";
  3411. "8 8 88888 8 8 88888 8 8 ";
  3412. "ffffffffffffffffffffffffffffffffffffffffffff ";
  3413. "ffffffffffffffffffffffffffffffffffffffffffff";
  3414. "";
  3415. "";
  3416. }
  3417. drawPictureTable(term, Title, 1, 1, colors.black)
  3418. mon = peripheral.wrap("back")
  3419. drawPictureTable(mon, Title, 1, 1, colors.black)
  3420. sleep(0.2)
  3421. drawPictureTable(mon, Title, 0, 3, colors.black)
  3422. while true do
  3423.  
  3424.  
  3425. sleep(0.2)
  3426. mon.clear()
  3427. drawPictureTable(mon, Title, -1, 3, colors.black)
  3428. sleep(0.2)
  3429. mon.clear()
  3430. drawPictureTable(mon, Title, 0, 3, colors.black)
  3431. sleep(0.2)
  3432. mon.clear()
  3433. drawPictureTable(mon, Title, 1, 3, colors.black)
  3434. for i=1,8 do
  3435. sleep(0.05)
  3436. mon.clear()
  3437. drawPictureTable(mon, Title, 0, 3+i, colors.black)
  3438. end
  3439. local currTick = getTime()
  3440.  
  3441. mon.clear()
  3442. mon.setTextScale(3)
  3443. mon.setTextColor(colors.white)
  3444. local x,y = mon.getSize()
  3445. mon.setCursorPos(1,y/2)
  3446. mon.write("The current TPS is: ")
  3447. mon.setCursorPos(x/2-1,y/2+1)
  3448. if currTick < 6 then
  3449. mon.setTextColor(colors.red)
  3450. elseif currTick >= 6 and currTick < 15 then
  3451. mon.setTextColor(colors.yellow)
  3452. else
  3453. mon.setTextColor(colors.green)
  3454. end
  3455. mon.write(currTick)
  3456. mon.setTextScale(1)
  3457. sleep(3)
  3458. for i=-7,3 do
  3459. sleep(0.05)
  3460. mon.clear()
  3461. drawPictureTable(mon, Title, 0, i, colors.black)
  3462. end
  3463. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement