Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[
- RedOS
- Version: 0.3.5.90
- By: NuAoA
- Feel free to copy parts of the code (just let me know if you do somthing cool with it)
- pastebin get VekE809i startup
- ----------
- ----------
- --0.3.6.0 --
- BugFixes:
- - Fixed tons of bugs caused by the CC rednet update.
- - Fixed the issue that caused computers to become copies of other terminals (I think)
- - Fixed a bug that allowed nil strings being accepted in userInput()
- - Fixed a bug in the signal selection window that caused a crash
- - Fixed custom UI's from staying 'highlighted' after selection
- - added some conditionals that should make checkLogic() run a bit faster, because why not.
- - Fixed a bug that caused refreshDisplay() to be called about ~3/sec. now its down to pretty much only when nessessary.
- - Fixed a small glitch in boxDrag() that erased the last created pixel
- New Features:
- - Custom UI's can now toggle signals with a left click (or monitor touch) event.
- - 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.
- - Requested passwords are now replaced with **** when entered.
- - 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.
- - Added the ability to check for updates (and download them).
- ----------
- ----------
- TODO:
- 1) Figure out how to run custom scripts in parallel with the program on demand.
- 2) figure out how to make all logic update on the same tick.
- 3) add a transparent color to the custom UI
- 4) rewrite the "monitor_touch" event so that it works regardless of the screen the terminal is on.
- 4) make boxDrag() erase stuff while still dragging.
- --]]
- ------Paste download------
- --------------------------
- local paste = "2jb4LRYJ" -- Public code
- --------------------------
- local DEBUG = true -- set to false to disable debug file and auto updates on boot.
- if DEBUG then
- paste = "qACY0ffj" -- Possibly unstable verson of redOS. (latest)
- local file = fs.open("debug","w")
- file.write("RedOS debug file \n")
- file:close()
- end
- function Debug(text)
- if DEBUG then
- local file = fs.open("debug","r")
- local curr = file.readAll()
- file:close()
- file = fs.open("debug","w")
- file.write(curr.."\n"..tostring(text))
- file:close()
- end
- end
- term.clear()
- local lastimage = {}
- local hexnums = { [10] = "a", [11] = "b", [12] = "c", [13] = "d", [14] = "e" , [15] = "f" }
- local comp_faces = {"Front","Back","Left","Right","Top","Bottom"}
- local sig_faces = {"Front","Back","Left","Right","Top","Bottom","Virtual"}
- local sig_names = {"White","Orange","Magenta","LightBlue","Yellow","Lime","Pink","Gray","LightGray","Cyan","Purple","Blue","Brown","Green","Red","Black"}
- local sig_values = {1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768}
- local HeaderNames = {"Options","View","Cable","Network"}
- local networkedIDs = {}
- local canRefresh = true -- Check if its ok to refresh the screen (prevents pulldowns from closing)
- local splashdone = false -- becomes true when the splash screen is finished, so that parallel code knows whats up.
- local monFace = nil -- current face of an attached monitor
- local mon = nil -- monitor "node"
- local networkNames = {} -- Will stay updated with the names of any computer on the network
- local UI_c,UI_t -- Color and text tables for the custom UI
- local header_c,header_t -- Color and text tables for the file menu
- local signal = {} -- This will store the current state of all redstone singals on the PC
- local logic = {} -- Stores all logic for the local terminal.
- local meta = {} -- Stores meta data, like computer name, password, ID, computers to boot into, etc.
- local tick = 0.1 -- the tick between redstone updates, increase this if you have problems with lag
- local global_tick = 1 -- counts up to infinity, used to pulse signals
- local ValidChars = {
- "\"","#","$","%","&","'","(",")","*","+",",","-",".","/","0","1","2","3",
- "4","5","6","7","8","9",":",";","<","=",">","?","@","A","B","C","D","E","F","G",
- "H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","[",
- "\\","]","^","_","`","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o",
- "p","q","r","s","t","u","v","w","x","y","z","{","}","~"," "
- }
- local CharToCode = {}
- local CodeToChar = {}
- for _, c in pairs(ValidChars) do
- local code = #CodeToChar+1
- CharToCode[c] = code
- CodeToChar[code] = c
- end
- function meta_setup(...)
- local ID = os.getComputerID()
- if #arg>0 then
- ID = arg[1]
- end
- local c,t = emptyScreen(term)
- local tab = {}
- local ui_temp = {["table"] = c,["text"] =t }
- tab["computerName"] = "Computer "..ID
- tab["password"] = ""
- tab["ID"] = ID
- tab["isLocked"] = false --Locked
- tab["isRead"]= false --ReadOnly
- tab["showCustom"] = true
- tab["bootInto"] = ID
- tab["customUI"] = {[0] = ui_temp}
- return deepcopy(tab)
- end
- --Temp default signal, will have to load a custom one on boot.
- function signal_setup(...)
- local sig = {}
- local sig2 = {}
- local ID = os.getComputerID()
- if #arg > 0 then
- ID = arg[1]
- end
- local sig_temp = {["isBundle"] = false,["value"] = false,["isRead"] = true,["hasScript"] = false,["hasUI"] = false}
- for i=1,#sig_faces do
- sig[sig_faces[i]] = deepcopy(sig_temp)
- if i == 7 then
- sig[sig_faces[i]]["isBundle"] = true
- sig[sig_faces[i]]["isRead"] = false
- sig[sig_faces[i]]["value"] = 0
- end
- end
- sig2[ID] = deepcopy(sig)
- return deepcopy(sig2)
- end
- function logic_setup()
- local sig = {}
- local sig_temp2 ={}
- local node = {["and"] = nil,["or"] = nil}
- local sig_temp = {["if"] = node,["else"] = false,["then"] = true,["toggle"] = false}
- for i=1,#sig_faces do
- sig_temp2[0] = sig_temp
- for j=1,#sig_values do
- sig_temp2[sig_values[j]] = sig_temp
- end
- sig[sig_faces[i]] = sig_temp2
- end
- return deepcopy(sig)
- end
- ----------------------------------------------------------------
- -----------------------------[ Utility ]------------------------
- ----------------------------------------------------------------
- function checkUpdates(...)
- term.clear()
- term.setCursorPos(1,1)
- shell.run("pastebin get "..paste.." startup.temp")
- file = fs.open("startup.temp","r")
- local version = string.match(file.readAll(),"Version: %d+.%d+.%d+.%d+")
- 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+)")
- file:close()
- file = fs.open("startup","r")
- local version2 = string.match(file.readAll(),"Version: %d+.%d+.%d+.%d+")
- 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+)")
- file:close()
- if tonumber(a)>tonumber(a2) or tonumber(b)>tonumber(b2) or tonumber(c)>tonumber(c2) or tonumber(d)>tonumber(d2) then
- 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
- fs.delete("startup")
- fs.copy("startup.temp","startup")
- fs.delete("startup.temp")
- os.reboot()
- end
- elseif not arg[1] then
- userInput("This version is up to date! ("..string.match(version,"Version: (%d+.%d+.%d+.%d+)")..")")
- end
- fs.delete("startup.temp")
- end
- -- Call to fully copy a table (table1=table2 will write changes to table1 back onto table2, deepcopy bypasses this)
- function deepcopy(orig)
- local orig_type = type(orig)
- local copy
- if orig_type == 'table' then
- copy = {}
- for orig_key, orig_value in next, orig, nil do
- copy[deepcopy(orig_key)] = deepcopy(orig_value)
- end
- setmetatable(copy, deepcopy(getmetatable(orig)))
- else -- number, string, boolean, etc
- copy = orig
- end
- return copy
- end
- --This function will copy everything in signal ignoring the values
- function deepcopySignal(sig)
- local sig_temp = deepcopy(sig)
- for i=1,#sig_faces do
- sig_temp[os.getComputerID()][sig_faces[i]]["value"] = signal[os.getComputerID()][sig_faces[i]]["value"]
- end
- return deepcopy(sig_temp)
- end
- function printTab(tab,...)
- local orig_type = type(tab)
- local copy
- if orig_type == 'table' then
- copy = {}
- for orig_key, orig_value in next, tab, nil do
- term.write(orig_key.." ")
- copy[deepcopy(orig_key)] = deepcopy(orig_value)
- end
- setmetatable(copy, deepcopy(getmetatable(orig)))
- else -- number, string, boolean, etc
- copy = orig
- term.write(orig)
- print()
- end
- if #arg>0 then
- io.read()
- else
- return copy
- end
- end
- -- NOTHING TO SEE HERE TEST CODE PLEASE IGNORE :P
- function encrypt(msg, key)
- math.randomseed(key)
- local out = ""
- for i = 1,#msg do
- local c = msg:sub(i,i)
- local code = CharToCode[c]
- code = code + math.random(0,#ValidChars)
- if code > #ValidChars then
- code = code - #ValidChars
- end
- out = out..CodeToChar[code]
- end
- return out
- end
- -- returns the string in its proper type, if no type found then returns the string.
- function toType(str)
- if str == nil then
- error("NIL string passed to function toType()",2)
- elseif tonumber(str) ~= nil then
- return tonumber(str)
- elseif string.lower(str) == "true" then
- return true
- elseif string.lower(str) == "false" then
- return false
- else
- return str
- end
- end
- -- This function will simulate the shell on a comuter. I think it works for nearly everything
- function MYshell()
- screen = term
- screen.setBackgroundColor(colors.black)
- screen.clear()
- screen.setTextColor(colors.yellow)
- screen.setCursorPos(1,1)
- screen.write("RedOS is running in the background.")
- screen.setCursorPos(1,2)
- screen.write("Type 'redOS' to resume")
- local xsize,ysize = term.getSize()
- local pos = 3
- while true do
- screen.setCursorPos(1,pos)
- screen.setTextColor(colors.yellow)
- screen.write("> ")
- screen.setCursorPos(3,pos)
- screen.setTextColor(colors.white)
- local command = io.read()
- pos = pos+1
- if pos>ysize then
- pos = ysize-1
- end
- if string.lower(command) == "redos" then
- break
- end
- local response = shell.run(command)
- if response == false then
- pos = pos+1
- elseif type(response) == "table" then
- for k,v in pairs(response) do
- print(v)
- end
- else
- local x,y = term.getCursorPos()
- pos = y
- --screen.clear()
- end
- end
- end
- ----------------------------------------------------------------
- -----------------------------[ Save/Load ]----------------------
- ----------------------------------------------------------------
- -- Saves the currently loaded tables to file, if arguments are passed (...) it will save those tables instead.
- -- It will broadcast the file if another computer wants it.
- function FSsave(filename,...)
- local logic_temp = logic_setup()
- local ID = tonumber(string.match(filename,"%d+"))
- local meta_temp = meta_setup(ID)
- local signal_temp = signal_setup(ID)
- local logic_curr = deepcopy(logic)
- local meta_curr = deepcopy(meta)
- local signal_curr = deepcopy(signal)
- networkedIDs = {}
- if attachModem() then
- rednet.broadcast("redOS metaID")
- end
- if #arg > 0 then
- logic_curr = deepcopy(arg[2])
- meta_curr = deepcopy(arg[3])
- signal_curr = deepcopy(arg[1])
- elseif meta["ID"] ~= os.getComputerID() then
- local s,l,m = FSload(filename)
- logic_curr = deepcopy(l)
- end
- local file = fs.open(filename,"w")
- file.write("RedOS data\n")
- if ID == os.getComputerID() and monFace ~= nil then
- file.write("monFace "..string.lower(monFace).."\n")
- end
- for i,v in pairs(meta_curr) do
- if i == "customUI" then
- for j,k in pairs(v) do
- for u,y in pairs(k) do
- if u == "table" or u == "text" then
- if scanTableFor(y) then
- for o,p in pairs(y) do
- file.write(u.." "..j.." "..o.." "..p)
- file.write("\n")
- end
- end
- else
- if meta_curr[i][j][u]~= nil then
- file.write("customUI "..j.." "..u.." "..tostring(meta_curr[i][j][u]))
- file.write("\n")
- end
- end
- end
- end
- elseif meta_temp[i] ~= meta_curr[i] or i == "ID" then
- if ID ~= meta_temp["ID"] or ID ~= meta_curr["ID"] then
- term.clear()
- error("Invalid ID is attempting to be saved: temp: "..meta_temp["ID"].." curr: "..meta_curr["ID"].." ID:"..ID,2)
- end
- file.write(i.." "..tostring(v))
- file.write("\n")
- end
- end
- for i=1,#sig_faces do
- for k,v in pairs(signal_curr[ID][sig_faces[i]]) do
- if k ~= "value" and signal_curr[ID][sig_faces[i]][k] ~= signal_temp[ID][sig_faces[i]][k] then
- file.write("signal "..sig_faces[i].." "..k.." "..tostring(v))
- file.write("\n")
- end
- end
- if signal_curr[ID][sig_faces[i]]["isBundle"] then
- for j=1,#sig_values do
- for k,v in pairs(logic_curr[sig_faces[i]][sig_values[j]]) do
- if k == "if" then
- for p,o in pairs(v) do
- if logic_curr[sig_faces[i]][sig_values[j]][k][p] ~= logic_temp[sig_faces[i]][sig_values[j]][k][p] then
- file.write("logic "..sig_faces[i].." "..sig_values[j].." "..p.." "..o)
- file.write("\n")
- end
- end
- else
- if logic_curr[sig_faces[i]][sig_values[j]][k] ~= logic_temp[sig_faces[i]][sig_values[j]][k] then
- file.write("logic "..sig_faces[i].." "..sig_values[j].." "..k.." "..tostring(v))
- file.write("\n")
- end
- end
- end
- end
- else
- for k,v in pairs(logic_curr[sig_faces[i]][0]) do
- if k == "if" then
- for p,o in pairs(v) do
- if logic_curr[sig_faces[i]][0][k][p] ~= logic_temp[sig_faces[i]][0][k][p] then
- file.write("logic "..sig_faces[i].." ".."0".." "..p.." "..o)
- file.write("\n")
- end
- end
- else
- if logic_curr[sig_faces[i]][0][k] ~= logic_temp[sig_faces[i]][0][k] then
- file.write("logic "..sig_faces[i].." ".."0".." "..k.." "..tostring(v))
- file.write("\n")
- end
- end
- end
- end
- end
- file.close()
- if ID ~= os.getComputerID() then
- broadcastFile(filename,ID)
- end
- sleep(0)
- for k,v in pairs(networkedIDs) do
- if v == meta_curr["ID"] then
- broadcastFile(filename,k)
- end
- end
- end
- -- Will read a file, returning 3 tables corresponding to the signal, logic, and meta tables
- function FSload(filename)
- if fs.exists(filename) then
- local signal_temp = deepcopy(signal) --signal_setup()
- local logic_temp = logic_setup()
- local ID = tonumber(string.match(filename,"%d+"))
- local tmp_sig = signal_setup(ID)
- signal_temp[ID] = deepcopy(tmp_sig[ID])
- local meta_temp = meta_setup(ID)
- local efile = fs.open(filename,"r")
- if efile.readAll() ~= nil then
- efile:close()
- file = io.open(filename,"r")
- for line in file:lines() do
- local firstword = string.match(string.sub(line,0,8),"%S+")
- if firstword == "customUI" or firstword == "table" or firstword =="text" then
- local i = firstword
- if string.match(line,i.."%s%d+%s%d+") and (i=="table" or i=="text") then
- if type(meta_temp["customUI"][tonumber(string.match(line,i.."%s(%d+)%s%d+"))]) == "nil" then
- meta_temp["customUI"][tonumber(string.match(line,i.."%s(%d+)%s%d+"))] = {["table"] = {},["text"] = {}, ["signal"] = nil,["name"] = nil, ["onColor"] = colors.green, ["offColor"] = colors.red}
- end
- 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(.+)")
- else
- if type(meta_temp["customUI"][tonumber(string.match(line,i.."%s(%d+)%s%S+"))]) == "nil" then
- meta_temp["customUI"][tonumber(string.match(line,i.."%s(%d+)%s%S+"))] = {["table"] = {},["text"] = {}, ["signal"] = nil,["name"] = nil, ["onColor"] = colors.green, ["offColor"] = colors.red}
- end
- 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(.+)"))
- end
- end
- if ID == os.getComputerID() and string.match(line,"monFace %S+") then
- monFace = string.match(line,"monFace (%S+)")
- end
- for i,v in pairs(meta_temp) do
- if i == "customUI" then
- elseif string.match(string.sub(line,0,string.len(i)),i) then
- meta_temp[i] = toType(string.match(line,i.." (.+)"))
- end
- end
- if string.match(string.sub(line,0,5),"logic") then
- local op = string.match(line,"logic %S+%s%S+%s(%S+).+")
- if op == "and" or op == "or" then
- 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(.+)"))
- else
- 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(.+)"))
- end
- end
- if string.match(string.sub(line,0,6),"signal") then
- 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(.+)"))
- if string.match(line,"isBundle") then
- signal_temp[ID][string.match(line,"signal (%S+)")]["value"] = 0
- end
- end
- end
- file:close()
- networkNames[ID] = meta_temp["computerName"]
- return deepcopySignal(signal_temp),deepcopy(logic_temp),deepcopy(meta_temp)
- else
- efile.close()
- end
- else
- Debug(filename.." Does not exist!")
- end
- end
- ----------------------------------------------------------------
- -----------------------------[ RedStone ]-----------------------
- ----------------------------------------------------------------
- -- A little aid to change the type of input on a face. (probably never used)
- function setBundle(ID,face)
- signal[ID][face]["value"] = 0
- signal[ID][face]["isBundle"] = true
- end
- function setCable(ID,face)
- signal[ID][face]["value"] = false
- signal[ID][face]["isBundle"] = false
- end
- -- Used to decode the format that signals are stored in the logic table
- --retuns, ID, Face, Sig_Value, state
- function decodeSignal(text)
- return tonumber(string.match(text,"(.+)|.+|.+|.+")),string.match(text,".+|(.+)|.+|.+"),tonumber(string.match(text,".+|.+|(.+)|.+")),toType(string.match(text,".+|.+|.+|(.+)"))
- end
- --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).
- -- node is logic[face]
- function isOn(tab,ID,face,sig_value)
- if type(tab[ID]) == "nil" then
- if attachModem() then
- rednet.send(ID,"redOS Boot")
- end
- if type(networkNames[ID]) == "nil" or type(signal[ID]) == "nil" then
- local sig_tmp = signal_setup(ID)
- signal[ID]=deepcopy(sig_tmp[ID])
- end
- sleep(0)
- tab = deepcopy(signal)
- Debug("Nil ID in isON, this should only happen around startup")
- end
- if tab[ID][face]["isBundle"] then
- return colors.test(tab[ID][face]["value"],sig_value)
- else
- return tab[ID][face]["value"]
- end
- end
- --checks networkNames table and returns true if the ID exists in the table.
- function networked(ID)
- for k,v in pairs(networkNames) do
- if k == ID then
- return true
- end
- end
- return false
- end
- -- 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.
- function checkLogic(node,current_tick,curr_face)
- local ID = os.getComputerID()
- if signal[ID][curr_face]["isRead"] then
- return signal[ID][curr_face]["value"]
- end
- local i_s = 0
- local i_max = 0
- local pingedIDs = {}
- local needsave = false
- --local final_result = true
- local bund_val = 0
- if signal[ID][curr_face]["isBundle"] then
- i_s = 1
- i_max = 16
- end
- for i_ = i_s,i_max do
- local value_fix
- if i_max >0 then
- value_fix = sig_values[i_]
- else
- value_fix = 0
- end
- local result = false
- local fail_and = false
- local pass_or = false
- local failedPing = false
- local skip = false
- if node[value_fix]["if"]["or"] == nil then --and node[i_]["if"]["and"] ~= nil then
- pass_or = true
- if node[value_fix]["if"]["and"] == nil then
- fail_and = true
- if node[value_fix]["else"] == false then -- theres literally no logic to be calculated
- skip = true
- end
- end
- end
- if not skip then
- for i,v in pairs(node[value_fix]["if"]) do
- for word in string.gmatch(v, "%S+") do
- local ID_,face,sig_value,state = decodeSignal(word)
- if ID_ ~= os.getComputerID() and not networked(ID_) then -- Check if computer is still connected every 4 seconds
- failedPing = true
- end
- if i == "and" then
- if state == false and not isOn(signal,ID_,face,sig_value) then
- elseif state == true and isOn(signal,ID_,face,sig_value) then
- else
- fail_and = true
- end
- elseif i == "or" then
- if state == false and not isOn(signal,ID_,face,sig_value) then
- pass_or = true
- break
- elseif state == true and isOn(signal,ID_,face,sig_value) then
- pass_or = true
- break
- else
- end
- end
- end
- end
- if pass_or and not fail_and and not failedPing then
- result = true
- else
- if logic[curr_face][value_fix]["toggle"] == true then
- --Toggle then/else
- logic[curr_face][value_fix]["toggle"] = false
- local temp = logic[curr_face][value_fix]["then"]
- logic[curr_face][value_fix]["then"] = logic[curr_face][value_fix]["else"]
- logic[curr_face][value_fix]["else"] = temp
- needsave = true
- end
- end
- if node[value_fix]["then"] == nil or node[value_fix]["else"] == nil then
- --No logic but we need to return something?
- error("All cables require logic")
- else
- local thenelse = "else"
- if result then
- thenelse = "then"
- end
- --print(isOn(signal,2,"Front",sig_values[i_]))
- --io.read()
- local TE_val = node[value_fix][thenelse]
- if string.match(tostring(TE_val),"toggle") then
- if thenelse == "then" then
- logic[curr_face][value_fix]["toggle"] = true
- end
- TE_val = toType(string.match(node[value_fix][thenelse],"toggle (.+)"))
- end
- if TE_val == true then
- if signal[ID][curr_face]["isBundle"] then
- bund_val = bund_val + sig_values[i_]
- else
- return true
- end
- elseif TE_val == false then
- if signal[ID][curr_face]["isBundle"] then
- --don't change the bundle value
- else
- return false
- end
- elseif type(TE_val) == "number" then
- if signal[ID][curr_face]["isBundle"] then
- if TE_val == 1 then
- if colors.test(signal[os.getComputerID()][curr_face]["value"],sig_values[i_]) then
- else
- bund_val = bund_val + sig_values[i_]
- end
- elseif current_tick/TE_val == math.floor(current_tick/TE_val) then
- if not colors.test(signal[os.getComputerID()][curr_face]["value"],sig_values[i_]) then
- bund_val = bund_val + sig_values[i_]
- end
- else
- if colors.test(signal[os.getComputerID()][curr_face]["value"],sig_values[i_]) then
- --bund_val = bund_val + sig_values[i_]
- end
- end
- else
- if TE_val == 1 then
- return not signal[os.getComputerID()][curr_face]["value"]
- elseif current_tick/TE_val == math.floor(current_tick/TE_val) then
- return true
- else
- return false
- end
- end
- end
- end
- end
- if not signal[ID][curr_face]["isBundle"] then
- return false -- should only get here if the signal is a cable and it skip is true
- end
- end
- if needsave then
- if meta["ID"] ~= os.getComputerID() then
- local sig_t,log_t,meta_t = FSload(os.getComputerID()..".meta")
- FSsave(os.getComputerID()..".meta",sig_t,log_t,meta_t)
- else
- FSsave(os.getComputerID()..".meta")
- end
- end
- return bund_val
- end
- --Will return true if a signal has changed. If readredstone() then broadcast would be quite usefull.
- function readRedstone()
- --sleep(0)
- local change = false
- local ID = os.getComputerID()
- for i=1,#comp_faces do
- if signal[ID][comp_faces[i]]["isRead"] then
- local var
- if signal[ID][comp_faces[i]]["isBundle"] then
- var = rs.getBundledInput(string.lower(comp_faces[i]))
- else
- var = rs.getInput(string.lower(comp_faces[i]))
- end
- if signal[ID][comp_faces[i]]["value"] ~= var then
- change = true
- signal[ID][comp_faces[i]]["value"] = var
- end
- elseif signal[ID][comp_faces[i]]["isBundle"] and type(signal[ID][comp_faces[i]]["value"]) == "boolean" then
- Debug(type(signal[ID][comp_faces[i]]["value"]))
- signal[ID][comp_faces[i]]["value"] = 0
- end
- end
- return change
- end
- function writeRedstone()
- local ID = os.getComputerID()
- for i=1,#comp_faces do
- if not signal[ID][comp_faces[i]]["isRead"] then
- if signal[ID][comp_faces[i]]["isBundle"] then
- rs.setBundledOutput(string.lower(comp_faces[i]),signal[ID][comp_faces[i]]["value"])
- else
- rs.setOutput(string.lower(comp_faces[i]),signal[ID][comp_faces[i]]["value"])
- end
- end
- end
- end
- function checkSignalChange(tab1,tab2)
- local ID = os.getComputerID()
- for i=1,#sig_faces do
- if tab2[ID][sig_faces[i]]["value"] ~= tab1[ID][sig_faces[i]]["value"] then
- return true
- end
- end
- return false
- end
- function redstone()
- local ID = os.getComputerID()
- while true do
- local signal_temp = deepcopy(signal)
- readRedstone()
- global_tick = global_tick + 1
- for i=1,#sig_faces do
- signal[ID][sig_faces[i]]["value"] = checkLogic(logic[sig_faces[i]],global_tick,sig_faces[i])
- end
- writeRedstone()
- if checkSignalChange(signal_temp,signal) then
- checkUIandUpdate()
- broadcastSignal()
- end
- sleep(tick)
- end
- end
- function checkUIandUpdate(...)
- local ret = false
- local ID = meta["ID"]
- for k,v in pairs(meta["customUI"]) do
- if meta["customUI"][k]["signal"] ~= nil then
- local ID_,face_,sig_value,state = decodeSignal(meta["customUI"][k]["signal"])
- if updateUIcolor(k,v) then
- ret = true
- end
- end
- end
- if ret and #arg == 0 then refreshDisplay() end
- return ret
- end
- function toggleBundle(ID,face)
- if signal[ID][face]["isBundle"] then
- signal[ID][face]["isBundle"] = false
- signal[ID][face]["value"] = false
- rs.setBundledOutput(string.lower(face),0)
- else
- signal[ID][face]["isBundle"] = true
- signal[ID][face]["value"] = 0
- rs.setOutput(string.lower(face),false)
- end
- end
- ----------------------------------------------------------------
- -----------------------------[ Network ]------------------------
- ----------------------------------------------------------------
- function attachModem()
- for i=1,#comp_faces do
- if peripheral.isPresent(string.lower(comp_faces[i])) and peripheral.getType(string.lower(comp_faces[i])) == "modem" then
- if rednet.isOpen(string.lower(comp_faces[i])) then
- return true
- else
- rednet.open(string.lower(comp_faces[i]))
- Debug("Opening side!")
- return true
- end
- end
- end
- return false
- end
- function broadcastSignal(...)
- local message = ""
- local ID = os.getComputerID()
- --for k,v in pairs(signal[ID]) do
- for i=1,#sig_faces do
- message = message..ID.." "..sig_faces[i].." "..tostring(signal[ID][sig_faces[i]]["value"])
- message = message.." "..tostring(signal[ID][sig_faces[i]]["isBundle"])
- message = message.." "..tostring(signal[ID][sig_faces[i]]["isRead"])
- message = message.." "..tostring(signal[ID][sig_faces[i]]["hasScript"]).."|"
- end
- --end
- if #arg >0 then
- if attachModem() then
- rednet.send(arg[1],"redOS signal|"..message)
- end
- else
- if attachModem() then
- rednet.broadcast("redOS signal|"..message)
- end
- end
- end
- function receiveSignal(message)
- for word in string.gmatch(message,"%d+%s%S+%s%S+%s%S+%s%S+%s%S+|") do
- local ID = tonumber(string.match(word,"(%d+)%s%S+%s%S+%s%S+%s%S+%s%S+|"))
- local face = string.match(word,"%d+%s(%S+)%s%S+%s%S+%s%S+%s%S+|")
- local tab = {}
- tab[1] = toType(string.match(word,"%d+%s%S+%s(%S+)%s%S+%s%S+%s%S+|"))
- tab[2] = toType(string.match(word,"%d+%s%S+%s%S+%s(%S+)%s%S+%s%S+|"))
- tab[3] = toType(string.match(word,"%d+%s%S+%s%S+%s%S+%s(%S+)%s%S+|"))
- tab[4] = toType(string.match(word,"%d+%s%S+%s%S+%s%S+%s%S+%s(%S+)|"))
- if ID == os.getComputerID() then
- --error("Can't recieve singal data from elsewhere, WTF mate?")
- -- Changed in the lastest version of CC, broadcast will now send the message to the PC being used.
- else
- if type(signal[ID]) == "nil" then
- local tab_temp = signal_setup(ID)
- signal[ID] = deepcopy(tab_temp[ID])
- end
- signal[ID][face]["value"] = tab[1]
- signal[ID][face]["isBundle"] = tab[2]
- signal[ID][face]["isRead"] = tab[3]
- signal[ID][face]["hasScript"] = tab[4]
- end
- end
- checkUIandUpdate()
- end
- function broadcastFile(filename,...)
- local file = fs.open(filename,"r")
- local str = file.readAll()
- if str ~= nil then
- if #arg >0 then
- if attachModem() then
- rednet.send(tonumber(arg[1]),"redOS "..filename.."| "..str)
- end
- --else
- --userInput("Can't Locate network "..networkNames[arg[1]])
- --end
- else
- if attachModem() then
- rednet.broadcast("redOS "..filename.."| "..str)
- end
- end
- else
- dubug("RedOSbroadcast FS read nil!")
- end
- file:close()
- return true
- end
- function receiveFile(message)
- local text = string.match(message,"redOS %S+|(.+)")
- local filename = string.match(string.sub(message,0,20),"redOS (%S+)|")
- file = fs.open(filename,"w")
- file.write(text)
- file:close()
- if tonumber(string.match(filename,"%d+")) == os.getComputerID() then
- local sig_t,log_t,meta_t = FSload(filename)
- logic = deepcopy(log_t)
- if meta["ID"] == os.getComputerID() then
- signal = deepcopy(sig_t)
- meta = deepcopy(meta_t)
- FSsave(filename)
- checkUIandUpdate()
- end
- elseif tonumber(string.match(filename,"%d+")) == meta["ID"] then
- local s_temp,l_temp,m_temp = FSload(filename)
- meta = deepcopy(m_temp)
- signal[meta["ID"]] = deepcopy(s_temp[meta["ID"]])
- checkUIandUpdate()
- end
- end
- --ping ID, recives a unique response. arg[1] will display a message that the terminal can't be located.
- function RedOSPing(ID_,...)
- if ID_ == nil then
- Debug("NIL ID in RedOSPing")
- return false
- end
- if tonumber(ID_) ~= os.getComputerID() then
- if attachModem() then
- rednet.send(tonumber(ID_),"redOS Ping")
- end
- local count = 0
- while true do
- local ID,message,dist = rednet.receive(0.1)
- if ID == nil then return false end
- if ID ~= ID_ and count >6 then
- return false --RedOSPing(ID_)
- end
- if message == nil then
- Debug("RedOSPing false "..ID)
- else
- if string.match(message, "redOS Pong") and ID_ == ID then
- return true
- elseif arg[1] and count >6 then
- userInput("Can't Locate network "..ID_)
- Debug("RedOSPing mishap "..ID)
- return false
- elseif count >6 then
- Debug("RedOSPing mishap "..ID)
- return false
- end
- end
- count = count+1
- end
- else
- return true
- end
- end
- -- RSnetwork
- function RSnetwork()
- RSupdateNetwork()
- broadcastSignal()
- local function one()
- while true do
- local ID, message, dist = rednet.receive()
- if string.sub(message,0,13) == "redOS toggle|" then
- local a,b,c,d = decodeSignal(string.sub(message,14))
- if tonumber(a) == os.getComputerID() then
- local _else = logic[b][c]["else"]
- local _then = logic[b][c]["then"]
- local s,l,m = FSload(os.getComputerID()..".meta")
- logic[b][c]["else"] = _then
- logic[b][c]["then"] = _else
- FSsave(os.getComputerID()..".meta",s,logic,m)
- end
- message = nil
- end
- if ID ~= os.getComputerID() and message ~= nil then -- New CC is picking up local signals
- if message == "redOS Ping" then
- if attachModem() then
- rednet.send(ID,"redOS Pong")
- end
- elseif message == "redOS metaID" then
- if attachModem() then
- rednet.send(ID,"redOS metaID "..meta["ID"])
- end
- elseif message == "redOS 149634901231" then
- Debug("I SHOULD BE RESTARTING") -- WTF WHY DOESNT THIS WORK, IT DOES EVERYTHING PROPERLY BUT RECIEVE THE MESSAGE
- os.reboot()
- 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
- if message == "redOS Request meta" then --A computer is requesting this computers meta data.
- broadcastFile(tostring(os.getComputerID())..".meta",ID)
- elseif message == "redOS Boot" then
- if attachModem() then
- rednet.send(ID,"redOS Info "..networkNames[os.getComputerID()])
- end
- broadcastSignal(ID)
- if type(networkNames[ID]) == "nil" then
- if attachModem() then
- rednet.send(ID,"redOS Boot")
- end
- end
- elseif string.match(string.sub(message,0,10),"redOS Info") then
- networkNames[tonumber(ID)] = string.match(message,"redOS Info (.+)")
- elseif string.match(string.sub(message,0,12),"redOS signal") then
- receiveSignal(message)
- elseif string.match(string.sub(message,0,25),"redOS %S+|") and not string.match(string.sub(message,0,12),"redOS signal") then
- receiveFile(message)
- elseif string.match(string.sub(message,0,25),"redOS metaID %d+") then
- if tonumber(string.match(string.sub(message,0,25),"redOS metaID (%d+)")) == meta["ID"] then
- networkedIDs[ID] = meta["ID"]
- end
- end
- end
- end
- end
- end
- local function two() --Updates the network every 5 seconds (this handles disconnected computers)
- while true do
- sleep(30)
- for k,v in pairs(deepcopy(networkNames)) do
- if not RedOSPing(k) then
- networkNames[k] = nil
- end
- end
- RSupdateNetwork()
- end
- end
- parallel.waitForAll(one,two)
- end
- function RSupdateNetwork()
- local thisname = networkNames[os.getComputerID()]
- networkNames = {}
- networkNames[os.getComputerID()] = thisname
- if attachModem() then
- rednet.broadcast("redOS Boot")
- end
- end
- ----------------------------------------------------------------
- -----------------------------[ Display API ]--------------------
- ----------------------------------------------------------------
- --Lots of credit to nPaintPro's author for the whole table -> display stuff. most of these functions are built off nPaintPro's format.
- --Returns the color value of 'hex'
- function getColourOf(hex)
- local value = tonumber(hex, 16)
- if not value then return nil end
- value = math.pow(2,value)
- return value
- end
- --Returns the hex string of 'colour'
- local function getHexOf(colour)
- if not colour or not tonumber(colour) then
- return " "
- end
- local value = math.log(colour)/math.log(2)
- if value > 9 then
- value = hexnums[value]
- end
- return tostring(value)
- end
- -- 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).
- --Note, image and text have to be the same size
- function drawPictureTable(mon, image, xinit, yinit, alpha,...)
- if mon == nil then return end
- if not alpha then alpha = 1 end
- local text_tab = deepcopy(arg[1])
- for y=1,#image do
- for x=1,#image[y] do
- local col = getColourOf(string.sub(image[y], x, x))
- local tex = " "
- local text_offset = 0
- if not col then col = alpha end
- if mon.isColor() then
- mon.setBackgroundColour(col)
- else
- if string.sub(image[y], x, x) ~= " " then
- mon.setBackgroundColour(colors.black)
- else
- mon.setBackgroundColour(colors.white)
- end
- end
- if arg[1] ~= nil and text_tab[y] ~= nil then
- tex = string.sub(text_tab[y],x,x)
- if tex == "&" then
- local txtclr = getColourOf(string.sub(text_tab[y],x+text_offset+1,x+text_offset+1))
- if txtclr ~= nil then
- if mon.isColor() then
- mon.setTextColor(txtclr)
- end
- --text_offset = text_offset+1
- text_tab[y] = string.sub(text_tab[y],3,string.len(text_tab[y]))
- tex = string.sub(text_tab[y],x+text_offset,x+text_offset)
- end
- end
- end
- if string.len(tex) ~= 1 then
- tex = " "
- end
- 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
- mon.setCursorPos(xinit + x-1, yinit + y-1)
- mon.write(tex)
- elseif arg[2] == nil then
- mon.setCursorPos(xinit + x-1, yinit + y-1)
- mon.write(tex)
- end
- end
- end
- lastimage["image"] = image
- lastimage["text"] = text_tab
- mon.setTextColor(colors.white)
- mon.setBackgroundColor(colors.black)
- end
- function splash()
- local splashlogo = {
- "444444444444444444 eeee eee eee 44 44 ";
- "444444444444444444 e e e e e 4 4 4 ";
- "44ffffffffffffff44 eeee ee e e 4 4 44 ";
- "44f0ffffffffffff44 e e e e e 4 4 4 ";
- "44ff0fffffffffff44 e e eee eee 44 44 ";
- "44f0ff000fffffff44 ";
- "44ffffffffffffff44 ";
- "44ffffffffffffff44b8bbbbbb8bbbbbb8bbbbbb8bbb";
- "44ffffffffffffff44bb8bbbbbb8bbbbbb8bbbbbb8bb";
- "44ffffffffffffff4455585555558555555855555585";
- "44ffffffffffffff4455558555555855555585555558";
- "444444444444444444eeeee8eeeeee8eeeeee8eeeeee";
- "444444444444444444eeeeee8eeeeee8eeeeee8eeeee";
- "";
- "";
- }
- canRefresh = false
- if term.isColor() then
- term.clear()
- drawPictureTable(term, splashlogo, 4, 3, colors.black)
- sleep(0.3)
- drawPictureTable(term,{"44f0ffffffffffff44 ",""} , 4, 8, colors.black)
- sleep(0.3)
- drawPictureTable(term,{"44f0ff000fffffff44 ",""} , 4, 8, colors.black)
- sleep(0.3)
- drawPictureTable(term,{"44f0ffffffffffff44 ",""} , 4, 8, colors.black)
- sleep(0.3)
- drawPictureTable(term,{"44f0ff000fffffff44 ",""} , 4, 8, colors.black)
- sleep(0.3)
- term.clear()
- end
- splashdone = true
- end
- -- Generates empty tables.
- function emptyScreen(mon,...)
- local x_max,y_max = mon.getSize()
- local tab = {}
- if #arg >0 then
- x_max = arg[1]
- y_max = arg[2]
- end
- for y=1,y_max do
- local str = " "
- for x=1,x_max do
- str = str.." "
- end
- tab[y] = str
- end
- return tab,deepcopy(tab)
- end
- --Will add color to a table at xpos,ypos. optional args are (table_text,text,text_color). It will overlap any existing colors.
- -- addtoTables(xpos,ypos,table_color,bg_color,x_fin,y_fin)
- function addColorToTable(table_color,xpos,ypos,bg_color,...)
- local x_fin = arg[1]
- local y_fin = arg[2]
- if #arg <2 then
- x_fin = xpos
- y_fin = ypos
- end
- if ypos > #table_color then
- error("index out of bounds ("..ypos..","..#table_color..")")
- end
- ypos = math.floor(ypos)
- xpos = math.floor(xpos)
- for y=ypos,y_fin do
- for x=xpos,x_fin do
- if tonumber(bg_color) == nil then
- table_color[y] = string.sub(table_color[y],0,x-1).." "..string.sub(table_color[y],x+1)
- else
- table_color[y] = string.sub(table_color[y],0,x-1)..getHexOf(bg_color)..string.sub(table_color[y],x+1)
- end
- end
- end
- return table_color
- end
- --Shorthand for addColorToTable
- function tc(...)
- if #arg <6 then
- return addColorToTable(arg[1],arg[2],arg[3],arg[4])
- else
- return addColorToTable(arg[1],arg[2],arg[3],arg[4],arg[5],arg[6])
- end
- end
- -- 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.
- function addTextToTable(table_text,xpos,ypos,text,...)
- local text_color = arg[1]
- local color_offset =0
- local text_offset = 0
- if arg[1] == nil then
- text_color = colors.white
- end
- if ypos > #table_text then
- error("index out of bounds ("..ypos..","..#table_text..")")
- end
- ypos = math.floor(ypos)
- xpos = math.floor(xpos)
- for i=1,string.len(table_text[ypos]) do
- if string.sub(table_text[ypos],i,i)=="&" and i<xpos+color_offset then
- color_offset = color_offset+2
- end
- end
- --table_text[ypos] = string.sub(table_text[ypos],0,xpos+color_offset-1).." "..string.sub(table_text[ypos],xpos+color_offset)
- if string.sub(table_text[ypos],color_offset+xpos,color_offset+xpos)=="&" then
- if string.match(text,"&%S") then
- 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))
- else
- 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))
- end
- else
- --if text == nil then error("1000 ",2) end
- 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))
- end
- return deepcopy(table_text)
- end
- --Shorthand for addTextToTable
- function tt(...)
- if #arg <5 then
- return addTextToTable(arg[1],arg[2],arg[3],arg[4])
- elseif #arg == 5 then
- return addTextToTable(arg[1],arg[2],arg[3],arg[4],arg[5])
- end
- end
- -- 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.
- function createPulldown(xpos,ypos,list,...)
- local c_title = colors.green
- local c_titletext = colors.white
- local c_list = colors.cyan
- local c_listtext = colors.white
- local PDwidth = string.len(list[1])
- local xsize,ysize = term.getSize()
- local offset = 0
- if #arg >= 5 then
- c_title = arg[2]
- c_titletext = arg[3]
- c_list = arg[4]
- c_listtext = arg[5]
- end
- for i=1,#list do
- if string.len(list[i])>PDwidth then
- PDwidth = string.len(list[i])
- end
- end
- local t_bg,t_t = emptyScreen(term,PDwidth-1,#list)
- --t_t = tt(t_t,1,1,list[1],c_titletext)
- --t_bg = tc(t_bg,1,2,c_list,PDwidth,#list)
- t_t[1] = "&"..getHexOf(c_titletext)..list[1]
- if arg[1] then
- t_bg = tc(t_bg,1,1,c_title,string.len(list[1]),1)
- t_bg[1] = string.sub(t_bg[1],0,string.len(list[1]))
- elseif not arg[1] then
- t_bg = tc(t_bg,1,1,c_title,PDwidth,1)
- end
- for i=2,#list do
- if string.match(string.sub(list[i],1,1),">") then
- t_t = tt(t_t,1,i,string.sub(list[i],2,#list[i]),colors.lightGray)
- c_list = colors.lightBlue
- t_bg = tc(t_bg,1,i,c_list,PDwidth,i)
- else
- t_bg = tc(t_bg,1,i,c_list,PDwidth,i)
- t_t = tt(t_t,1,i,list[i],c_listtext)
- end
- end
- if xpos+PDwidth > xsize then
- if arg[1] then
- drawPictureTable(term,{t_bg[1],""}, xsize - PDwidth+1,ypos,colors.black,{t_t[1],""})
- t_t[1] = ""
- t_bg[1] = ""
- end
- xpos = xsize - PDwidth+1
- end
- if ypos+#list >ysize then
- ypos = ysize-#list+1
- end
- drawPictureTable(term,t_bg,xpos,ypos,colors.black,t_t)
- local event, button1, xPos2, yPos2 = os.pullEvent("mouse_click","monitor_touch")
- if xPos2 >= xpos and xPos2 <= xpos+PDwidth and yPos2 >= ypos+1 and yPos2<=ypos+#list-1 and button1 == 1 and event == "mouse_click" then
- return list[yPos2-ypos+1],xPos2,yPos2,button1,event
- else
- if arg[6] and xPos2 >= xpos and xPos2 <= xpos+PDwidth and yPos2 == ypos and button1 == 1 and event== "mouse_click" then
- return list[yPos2-ypos+1],xPos2,yPos2,button1,event
- end
- return "exit",xPos2,yPos2,button1,event
- end
- end
- --Used to make a pulldown within another pulldown
- function pullsideways(list,xpos,ypos,gap)
- local t_c = {"",""}
- local t_t = {"",""}
- local offset = gap+#list[1]
- for i=1,offset do
- t_c[1] = t_c[1]..getHexOf(colors.green)
- t_t[1] = t_t[1].." "
- end
- t_t = tt(t_t,1,1,list[1])
- local newlist = {}
- for i=1, #list-2 do
- newlist[i] = list[i+2]
- end
- local c_title = colors.cyan
- local c_titletext = colors.white
- local c_list = colors.cyan
- local c_listtext = colors.white
- drawPictureTable(term,t_c,xpos,ypos,colors.black,t_t)
- --local result,xpos2,ypos2,button = createPulldown(xpos,ypos2,list,true)
- return createPulldown(xpos+offset,ypos,newlist,false,c_title,c_titletext,c_list,c_listtext,true)
- end
- --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.
- function userInput(text,...)
- local screen = term
- local x1,y1 = screen.getSize()
- local t_bg,t_t = emptyScreen(screen,x1,y1)
- local bg_color = colors.white
- local fg_color = colors.lightBlue
- local b_color = colors.yellow
- local text_color = colors.white
- local xpadding = 4
- local text_start = math.floor(y1/2) -1
- local lines = {}
- if string.len(text) > x1-(2+xpadding*2) then
- local newline = ""
- local i = 1
- for word in string.gmatch(text, "%S+") do
- if string.len(newline.." "..word) > x1-10 then
- lines[i] = newline
- i=i+1
- newline = word
- else
- newline = newline.." "..word
- end
- end
- if newline ~= nil then
- lines[#lines+1] = newline
- end
- text_start = math.floor(y1/2 - #lines/2 -1)
- for i=1,#lines do
- t_t = tt(t_t,math.floor((x1-string.len(lines[i]))/2),text_start+i,lines[i],text_color)
- end
- else --one line message
- t_t = tt(t_t,math.floor((x1-string.len(text))/2),text_start,text,text_color)
- end
- t_bg = tc(t_bg,1,1,bg_color,x1,y1) --background
- t_bg = tc(t_bg,xpadding,text_start-1,fg_color,x1-xpadding,text_start+4+#lines) --forground
- if arg[1] == nil then
- 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)
- t_t = tt(t_t,math.floor(x1/2),text_start+#lines+3,"OK",colors.black)
- elseif arg[1] == true then
- t_bg = tc(t_bg,x1/2-9,text_start+#lines+3,b_color,x1/2-5,text_start+#lines+3)
- t_bg = tc(t_bg,x1/2+5,text_start+#lines+3,b_color,x1/2+8,text_start+#lines+3)
- t_t = tt(t_t,x1/2-8,text_start+#lines+3,"Yes",colors.black)
- t_t = tt(t_t,x1/2+6,text_start+#lines+3,"No",colors.black)
- elseif arg[1] == "string" or arg[1] == "number" then
- t_t = tt(t_t,x1/2-12,text_start+#lines+2,">",text_color)
- t_bg = tc(t_bg,x1/2-12,text_start+#lines+2,colors.black,x1/2+13,text_start+#lines+2)
- end
- drawPictureTable(screen, t_bg, 1, 1, colors.black,t_t)
- if arg[1] == "string" or arg[1] == "number" then
- while true do
- drawPictureTable(screen, t_bg, 1, 1, colors.black,t_t)
- screen.setCursorPos(x1/2-11,text_start+#lines+2)
- local input
- if arg[2] then
- input = read("*")
- else
- input = io.read()
- end
- if arg[1] == "string" then
- if input ~= "" and tostring(input) ~= nil then
- return input
- else
- userInput("The input has to be a string")
- end
- elseif arg[1] == "number" then
- if tonumber(input) ~= nil then
- return tonumber(input)
- else
- userInput("The input has to be a number")
- end
- end
- end
- else
- while true do
- local event, button1, xpos2, ypos2 = os.pullEvent()
- if arg[1] and (event == "mouse_click" or event == "key") then
- if event == "key" and button1 == 28 then
- return true
- end
- if xpos2>=x1/2-10 and xpos2<=x1/2-5 and ypos2 == text_start+#lines+3 then
- return true
- elseif xpos2>=x1/2+4 and xpos2<=x1/2+8 and ypos2 == text_start+#lines+3 then
- return false
- end
- elseif not arg[1] then
- if event =="key" then
- return true
- elseif event == "mouse_click" and xpos2>=x1/2-2 and xpos2<=x1/2+2 and ypos2 == text_start+#lines+3 then
- return true
- end
- end
- end
- end
- end
- -- Overwrites table 1 with table 2.
- function overwriteTable(tab1,tab2)
- for i=1,#tab1 do
- local line = ""
- for j=1,#tab1[i] do
- local tex1 = string.sub(tab1[i],j,j)
- local tex2 = " "
- if #tab2 >= i then
- tex2= string.sub(tab2[i],j,j)
- end
- if tex1 == nil then
- tex1 = " "
- end
- if tex2 == nil then
- tex2 = " "
- end
- if tex2 == " " then
- line = line..tex1
- else
- line = line..tex2
- end
- end
- tab1[i] = line
- end
- return tab1
- end
- -- Will return the custom UI at position xpos,ypos. Otherwise will return nil
- function findUIat(xpos,ypos)
- local UItemp_c,UItemp_t = deepcopy(UI_c),deepcopy(UI_t)
- local pairslist = {}
- local iter =1
- for k,v in pairs(meta["customUI"]) do
- if k ~= 0 then
- pairslist[iter] = k
- iter = iter+1
- end
- end
- for i=#pairslist,1,-1 do
- if string.sub(meta["customUI"][pairslist[i]]["table"][ypos],xpos,xpos) ~= " " then
- --found
- return pairslist[i]
- end
- end
- return nil -- [todo]
- end
- -- 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.
- function boxDrag(xpos,ypos)
- local xsize,ysize = term.getSize()
- local xmin,ymin = 1,2
- local c_,t_ = emptyScreen(term)
- local c2_,t2_ = emptyScreen(term)
- while true do
- local event, button, xpos2, ypos2 = os.pullEvent()
- local x_,y_,x,y = xpos,ypos
- local UI_c_t = deepcopy(UI_c)
- if string.match(event,"mouse") then
- x,y = xpos2,ypos2
- if xpos>=xpos2 then
- x_= xpos2
- x = xpos
- end
- if ypos>=ypos2 then
- y_ = ypos2
- y = ypos
- end
- end
- if event == "mouse_drag" and ypos2>1 then
- c2_,t2_ = emptyScreen(term)
- if button == 2 then
- c2_ = tc(c2_,x_,y_-1,colors.black,x,y-1)
- else
- c2_ = tc(c2_,x_,y_-1,colors.white,x,y-1)
- end
- c_ = overwriteTable(deepcopy(c_),deepcopy(c2_))
- drawPictureTable(term,overwriteTable(UI_c_t,overwriteTable(deepcopy(c_),deepcopy(c2_))),xmin,ymin,colors.black)
- elseif event == "mouse_click"then
- if ypos2>1 then
- if button == 1 then
- c_ = tc(c_,xpos2,ypos2-1,colors.white)
- xpos = xpos2
- ypos = ypos2
- elseif button == 2 then
- c_ = tc(c_,xpos2,ypos2-1,colors.black)
- xpos = xpos2
- ypos = ypos2
- end
- c_ = overwriteTable(deepcopy(c2_),deepcopy(c_))
- drawPictureTable(term,overwriteTable(deepcopy(UI_c_t),deepcopy(c_)),xmin,ymin,colors.black)
- else -- Menu Click
- grabInput(xpos2,ypos2,button,event)
- return replaceColorTable(replaceColorTable(c_,colors.white,colors.cyan),colors.black)
- end
- elseif event == "key" then
- c_ = overwriteTable(c_,c2_)
- return replaceColorTable(replaceColorTable(c_,colors.white,colors.cyan),colors.black)
- end
- --c2_ = deepcopy(c_)
- end
- end
- --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 " "
- function replaceColorTable(tab,...)
- local tex = " "
- local color_hex = "%S"
- if #arg > 0 then
- if arg[1] ~= true then
- color_hex = getHexOf(arg[1])
- end
- if #arg >1 then
- tex = getHexOf(arg[2])
- end
- end
- for i=1,#tab do
- local line = ""
- for j=1,#tab[i] do
- if string.match(string.sub(tab[i],j,j),color_hex) then
- line = line..tex
- else
- line = line..string.sub(tab[i],j,j)
- end
- end
- tab[i] = line
- end
- return tab
- end
- --Will scan table tab for arg[1], returns true if found. if no args supplied will scan tab for any non-space character
- function scanTableFor(tab,...)
- local tex = " "
- if #arg>0 then tex = getHexOf(arg[1]) end
- for i=1,#tab do
- for j=1,#tab[i] do
- if #arg == 0 and string.sub(tab[i],j,j) ~= tex and string.sub(tab[i],j,j) ~= " " then
- return true
- elseif #arg >0 and string.sub(tab[i],j,j) == tex then
- return true
- end
- end
- end
- return false
- end
- function addUI(tab)
- if scanTableFor(tab) then
- local newkey = #meta["customUI"] +1
- meta["customUI"][newkey] = {["table"] = deepcopy(tab), ["signal"] = nil,["name"] = nil, ["onColor"] = colors.green, ["offColor"] = colors.cyan, ["state"] = false}
- end
- end
- function colorsPullSideways(name,xpos,ypos,gap)
- local t_c = {"",""}
- local t_t = {"",""}
- local xoff = 0
- local yoff = 0
- local xsize,ysize = term.getSize()
- local offset = gap+string.len(name)
- for i=1,offset do
- t_c[1] = t_c[1]..getHexOf(colors.green)
- t_t[1] = t_t[1].." "
- end
- t_t = tt(t_t,1,1,name)
- local newlist = {}
- local c_title = colors.cyan
- local c_titletext = colors.white
- local c_list = colors.cyan
- local c_listtext = colors.white
- local t_c2,t_t2 = emptyScreen(term,3,5)
- t_c2 = tc(t_c2,1,1,colors.green,4,1)
- local iter = 1
- for i=1,4 do
- for j=1,4 do
- t_c2 = tc(t_c2,i,j+1,sig_values[iter])
- iter = iter+1
- end
- end
- if xpos+offset+4 >= xsize then
- xoff = 3-(xsize-(xpos+offset))
- end
- if ypos+4>ysize then
- yoff = 4-(ysize-ypos)
- end
- drawPictureTable(term,t_c,xpos,ypos,colors.black,t_t)
- drawPictureTable(term,t_c2,xpos+offset-xoff,ypos-yoff,colors.black)
- local event, button1, xpos2, ypos2 = os.pullEvent("mouse_click","monitor_touch")
- 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
- iter=1
- for i=1,4 do
- for j=1,4 do
- if xpos2-(offset+xpos-1)+xoff == i and ypos2-ypos+yoff ==j then
- return sig_values[iter]
- end
- iter = iter+1
- end
- end
- end
- return nil
- end
- ----------------------------------------------------------------
- -----------------------------[ Program ]--------------------
- ----------------------------------------------------------------
- function createHeader()
- local t_c,t_t
- local xsize,ysize = term.getSize()
- local clr,txt = emptyScreen(term)
- clr = tc(clr,1,1,colors.blue,xsize,1)
- local pos_temp = 1
- for i=1,#HeaderNames do
- clr= tc(clr,pos_temp,1,colors.blue,pos_temp+string.len(HeaderNames[i])-1,1)
- txt=tt(txt,pos_temp,1,HeaderNames[i],colors.lightGray)
- pos_temp = pos_temp +2 +string.len(HeaderNames[i])
- end
- return {clr[1],""},{txt[1],""}
- end
- function grabInput(...)
- local event, button, xPos, yPos
- if #arg == 4 then
- canRefresh = true
- refreshDisplay()
- xPos = arg[1]
- yPos = arg[2]
- button = arg[3]
- event = arg[4]
- elseif #arg == 1 then
- while true do
- event, button, xPos, yPos = grabEvents("locked")
- if event ~= "monitor_touch" and event ~= "terminate" then
- error("Wrong event type",2)
- else
- break
- end
- end
- else
- canRefresh = true
- refreshDisplay()
- while true do
- event, button, xPos, yPos = grabEvents(true)
- if event == "mouse_click" or event == "mouse_drag" or event == "monitor_touch" then
- break
- end
- end
- end
- canRefresh = false
- respondInput(xPos,yPos,button,event)
- end
- function userSignalSelection(text,...)
- local showNetwork = true
- local showFace = true
- local showCable = true
- local showState = true
- if #arg>0 then
- showNetwork = arg[1]
- showFace = arg[2]
- showCable = arg[3]
- showState = arg[4]
- end
- local screen = term
- local x1,y1 = screen.getSize()
- local t_c,t_t = emptyScreen(screen,x1,y1)
- local bg_color = colors.white
- local fg_color = colors.lightBlue
- local b_color = colors.yellow
- local text_color = colors.white
- local xpadding = 4
- local text_start = math.floor(y1/2) -3
- local lines = {}
- local c_unselected = colors.orange
- local c_pulldown = colors.lightGray
- local my_signal = {["ID"] = os.getComputerID(),["face"] = nil,["cable"]=nil}
- while true do
- local t_c,t_t = nil,nil
- t_c,t_t = emptyScreen(screen,x1,y1)
- if string.len(text) > x1-(2+xpadding*2) then
- local newline = ""
- local ystartmod = 1
- local i = 1
- for word in string.gmatch(text, "%S+") do
- if string.len(newline.." "..word) > x1-10 then
- lines[i+1] = nil
- lines[i] = newline
- i=i+1
- newline = word
- else
- newline = newline.." "..word
- end
- end
- if newline ~= nil then
- lines[#lines+1] = newline
- end
- if #lines > 3 then
- ystartmod = 3
- end
- text_start = math.floor(y1/2 - #lines/2 -ystartmod)
- for i=1,#lines do
- t_t = tt(t_t,math.floor((x1-string.len(lines[i]))/2),text_start+i,lines[i],text_color)
- end
- else --one line message
- t_t = tt(t_t,math.floor((x1-string.len(text))/2),text_start,text,text_color)
- end
- t_c = tc(t_c,1,1,bg_color,x1,y1) --background
- t_c = tc(t_c,xpadding,text_start-1,fg_color,x1-xpadding,text_start+6+#lines) --forground
- local menupos = text_start+3+#lines
- if showNetwork then
- if my_signal["ID"] == nil then
- t_c = tc(t_c,6,menupos,c_unselected ,19,menupos)
- t_t = tt(t_t,6,menupos,"Select Network",colors.black)
- else
- t_c = tc(t_c,6,menupos,c_pulldown,19,menupos)
- t_t = tt(t_t,6,menupos,fstring(networkNames[my_signal["ID"]],14),colors.black)
- end
- end
- if showFace then
- if my_signal["face"] == nil then
- t_c = tc(t_c,21,menupos,c_unselected,31,menupos)
- t_t = tt(t_t,21,menupos,"Select Face",colors.black)
- else
- t_c = tc(t_c,21,menupos,c_pulldown,31,menupos)
- t_t = tt(t_t,21,menupos,my_signal["face"],colors.black)
- end
- end
- if showCable then
- if my_signal["ID"] ~= nil and my_signal["face"] ~= nil and signal[my_signal["ID"]][my_signal["face"]]["isBundle"] then
- if my_signal["cable"] == nil then
- t_c = tc(t_c,33,menupos,c_unselected ,43,menupos)
- t_t = tt(t_t,33,menupos,"Select Wire",colors.black)
- else
- t_c = tc(t_c,33,menupos,c_pulldown,33+string.len(my_signal["cable"]),menupos)
- t_t = tt(t_t,33,menupos,my_signal["cable"],colors.black)
- end
- end
- end
- t_c = tc(t_c,x1/2-9,menupos+2,b_color,x1/2-6,menupos+2)
- t_c = tc(t_c,x1/2+3,menupos+2,b_color,x1/2+10,menupos+2)
- t_t = tt(t_t,x1/2-8,menupos+2,"OK",colors.black)
- t_t = tt(t_t,x1/2+4,menupos+2,"Cancel",colors.black)
- drawPictureTable(screen, t_c, 1, 1, colors.black,t_t)
- local event, button, xpos, ypos = grabEvents()
- if event == "mouse_click" then
- if ypos == menupos then --signal selection.
- if xpos>5 and xpos <= 19 and showNetwork then -- network pulldown
- local iter = 3
- local list = {}
- list[1] = "Select Network"
- list[2] = "Refresh Network"
- for k,v in pairs(networkNames) do
- list[iter] = v
- if k ~= os.getComputerID() then
- list[iter] = list[iter].." ("..k..")"
- else
- list[iter] = list[iter].." (Local)"
- end
- iter = iter+1
- end
- local result,xpos2,ypos2,button2,event2 = createPulldown(6,menupos,list,true)
- if result ~= "exit" then
- if result == list[2] then
- RSupdateNetwork()
- sleep(0)
- else
- for i=3,#list do
- if result == list[i] then
- local ID --os.getComputerID()
- for k,v in pairs(networkNames) do
- if list[i] == v.." ("..k..")" or list[i] ==v.." (Local)"then
- ID = k
- end
- end
- if ID == nil then error("Nil ID in networking") end
- if ID == os.getComputerID() then
- my_signal["ID"] = os.getComputerID()
- local s_temp,l_temp,m_temp = FSload(ID..".meta")
- my_signal["face"] = nil
- my_signal["cable"] = nil
- elseif RedOSPing(ID,true) and ID ~= os.getComputerID then
- if attachModem() then
- rednet.send(ID,"redOS Request meta")
- end
- sleep(0.1)
- local s_temp,l_temp,m_temp = FSload(ID..".meta")
- if m_temp["password"] ~= "" and m_temp["password"] ~= nil then
- if encrypt(userInput("Please enter the password for terminal '"..m_temp["computerName"].."':","string",true),m_temp["ID"]) == m_temp["password"] then
- my_signal["ID"] = ID
- my_signal["face"] = nil
- my_signal["cable"] = nil
- else
- userInput("Invalid Password for '"..m_temp["computerName"].."'")
- end
- else
- my_signal["face"] = nil
- my_signal["cable"] = nil
- my_signal["ID"] = ID
- end
- end
- end
- end
- end
- else
- -- [exit]
- end
- elseif xpos>20 and xpos<=31 and showFace then
- local list = {}
- list[1] = "Select Face"
- for i=1,#sig_faces do
- list[i+1] = sig_faces[i]
- end
- local result,xpos2,ypos2,button2,event2 = createPulldown(21,menupos,list,true)
- if result ~= "exit" then
- my_signal["cable"] = nil
- my_signal["face"] = result
- else
- -- [exit]
- end
- 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
- local list = {}
- list[1] = "Select Wire"
- for i=1,#sig_names do
- list[i+1] = sig_names[i]
- end
- local result,xpos2,ypos2,button2,event2 = createPulldown(33,menupos,list,true)
- if result ~= "exit" then
- validSignal = false
- my_signal["cable"] = result
- for i=1,#sig_names do
- if result == sig_names[i] then
- my_signal["value"] = sig_values[i]
- end
- end
- else
- -- [exit]
- end
- end
- elseif ypos == menupos+2 then
- if xpos>=x1/2-10 and xpos<=x1/2-6 then
- 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
- local val = 0
- for i=1,#sig_names do
- if my_signal["cable"] == sig_names[i] then
- val = sig_values[i]
- break
- end
- end
- return my_signal["ID"],my_signal["face"],val
- end
- elseif xpos>=x1/2+2 and xpos<=x1/2+10 then
- return nil,nil,nil
- end
- end
- end
- --os.reboot()
- end
- end
- function respondInput(xpos,ypos,button,event)
- if event == "mouse_click" or event == "monitor_touch" then
- if button == 1 and event == "mouse_click" and ypos ==1 then
- -- Header Pulldowns
- if ypos == 1 then
- local h = {[0]=1}
- for i=1,#HeaderNames do
- h[i] = h[i-1]+string.len(HeaderNames[i]) +2
- if xpos >= h[i-1] and xpos<h[i]-2 then
- headerPulldown(HeaderNames[i],h[i-1])
- end
- end
- end
- else
- -- UI selection
- local uiKey = nil
- if event ~= "monitor_touch" then
- uiKey = findUIat(xpos,ypos-1)
- else
- uiKey = findUIat(xpos,ypos)
- end
- if button ==2 and ypos >1 then
- if uiKey ~= nil then
- -- ValidUI
- replaceColorTable(meta["customUI"][uiKey]["table"],true,colors.lime)
- refreshDisplay(true)
- local list = {"UI Options","Delete UI object","Disconnect Signal","Enable Click-to-Toggle","Set Off Color","Set On Color"}
- if meta["customUI"][uiKey]["button"] == true then
- list[4] = "Disable Click-to-Toggle"
- end
- if meta["customUI"][uiKey]["signal"] == nil then
- list[3] = "Connect a Signal"
- end
- local result,xpos2,ypos2,button,event = createPulldown(xpos,ypos,list,true)
- replaceColorTable(meta["customUI"][uiKey]["table"],true,colors.cyan)
- if result ~= "exit" then
- if result == "Delete UI object" then
- meta["customUI"][uiKey] = nil
- elseif result == list[4] then
- if meta["customUI"][uiKey]["signal"] == nil then
- userInput("This UI object needs to be connected to a signal first!")
- else
- meta["customUI"][uiKey]["button"] = not meta["customUI"][uiKey]["button"]
- end
- elseif result == list[3] then
- if meta["customUI"][uiKey]["signal"] == nil then
- 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).")
- if a ~= nil and b~= nil and c~= nil then
- local str = a.."|"..b.."|"..c.."|".."true"
- meta["customUI"][uiKey]["signal"] = str
- checkUIandUpdate(true)
- refreshDisplay(true)
- end
- else
- meta["customUI"][uiKey]["signal"] = nil
- end
- elseif result == list[6] then
- local new_c = colorsPullSideways(list[6].." ",xpos,ypos2,0)
- if new_c ~= "nil" and new_c ~= nil then
- meta["customUI"][uiKey]["onColor"] = new_c
- checkUIandUpdate(true)
- refreshDisplay(true)
- end
- elseif result == list[5] then
- local new_c = colorsPullSideways(list[5].." ",xpos,ypos2,0)
- if new_c ~= "nil" and new_c ~= nil then
- meta["customUI"][uiKey]["offColor"] = new_c
- replaceColorTable(meta["customUI"][uiKey]["table"],true,new_c)
- checkUIandUpdate(true)
- refreshDisplay(true)
- end
- end
- else
- checkUIandUpdate(true)
- refreshDisplay(true)
- end
- end
- elseif button == 1 or event == "monitor_touch" then
- if uiKey ~= nil then
- if meta["customUI"][uiKey]["signal"] ~= nil and meta["customUI"][uiKey]["button"] == true then
- -- switch then/else
- local a,b,c,d = decodeSignal(meta["customUI"][uiKey]["signal"])
- rednet.send(a,"redOS toggle|"..meta["customUI"][uiKey]["signal"])
- end
- end
- end
- end
- elseif event =="mouse_drag" then
- if ypos>1 and meta["showCustom"] then
- addUI(boxDrag(xpos,ypos))
- end
- else
- end
- end
- --returns true if a password exists
- function setupPassword(...)
- if meta["password"] == nil or meta["password"] == "" then
- if arg[1] then
- if not userInput("No password found! You need to configure a password before you can continue. Continue?",true) then
- return false
- end
- end
- meta["password"] = encrypt(userInput("Please enter a password:","string"),meta["ID"])
- if meta["password"] == "" or meta["password"] == nil then
- userInput("Invalid Password")
- return false
- end
- return true
- end
- return true
- end
- function lockTerminal()
- if setupPassword(true) then
- if not meta["isLocked"] then
- meta["isLocked"] = true
- end
- FSsave(meta["ID"]..".meta")
- local pullEvent = os.pullEvent
- os.pullEvent = os.pullEventRaw
- local function one()
- while true do
- local guess = userInput("This terminal has been locked. A password is required for access:","string",true)
- if encrypt(guess,meta["ID"]) == meta["password"] then
- meta["isLocked"] = false
- userInput("This terminal has been unlocked")
- FSsave(meta["ID"]..".meta")
- break
- else
- sleep(0.5)
- userInput("Incorrect Password")
- end
- end
- end
- local function two()
- while true do
- grabInput(true)
- end
- end
- parallel.waitForAny(one,two)
- os.pullEvent = pullEvent
- end
- end
- --returns the string if its smaller than len, otherwise will trim and add ..
- function fstring(str,len)
- if str == nil or str == "" then
- return "NIL STRING" -- debuging stuff
- end
- if string.len(str) > len then
- return string.sub(str,0,len-2)..".."
- else
- return str
- end
- end
- -- 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)
- function grabEvents(...)
- local event, button, xpos, ypos
- function one()
- event, button, xpos, ypos = os.pullEvent("mouse_click")
- end
- function two()
- event, button, xpos, ypos = os.pullEvent("key")
- end
- function three()
- event, button, xpos, ypos = os.pullEvent("mouse_drag")
- end
- function four()
- event, button, xpos, ypos = os.pullEvent("monitor_touch")
- end
- if #arg == 0 then
- parallel.waitForAny(one,two,four)
- elseif arg[1] ~= "locked" then
- parallel.waitForAny(one,two,three,four)
- elseif arg[1] == "locked" then
- four()
- end
- return event, button, xpos, ypos
- end
- function logicScreen()
- local xsize,ysize = term.getSize()
- local c_bg = colors.lightBlue
- local c_bord = colors.yellow
- local c_pulldown = colors.lightGray
- local c_pulldown_t = colors.white
- local c_unselected = colors.orange
- local saved = true
- local validSignal = false
- local my_logic = {} -- {["if"] = {["and"] = "",["or"] = ""},["then"]= true, ["else"] = false}
- local my_signal = {["ID"] = os.getComputerID(), ["face"] = nil, ["cable"] = nil,["value"]=0, ["toggle"] = false, ["then"] = nil, ["else"] = nil}
- local logic_temp = deepcopy(logic)
- local my_trusted = {}
- my_trusted[os.getComputerID()] = true
- local function logicToString(l) --returns and,or
- local andstr = ""
- local orstr = ""
- local iter = 1
- for k,v in pairs(l) do
- if l[k]["ID"] ~= nil and l[k]["face"] ~= nil and tonumber(l[k]["value"]) ~= nil and l[k]["state"] ~= nil then
- if l[k]["isAnd"] then
- andstr = andstr..l[k]["ID"].."|"..l[k]["face"].."|"..l[k]["value"].."|"..tostring(l[k]["state"]).." "
- else
- orstr = orstr..l[k]["ID"].."|"..l[k]["face"].."|"..l[k]["value"].."|"..tostring(l[k]["state"]).." "
- end
- end
- iter = iter+1
- end
- if andstr == "" then
- andstr = nil
- end
- if orstr == "" then
- orstr = nil
- end
- return andstr,orstr
- end
- local function validSave()--l,s,l_temp)
- local l = my_logic
- local s = my_signal
- local l_temp = logic_temp
- local a,b = logicToString(l)
- if a == nil then
- a = ""
- end
- if b == nil then
- b = ""
- end
- local l_temp2 = {["and"] = a,["or"] =b}
- local pass = true
- for k,v in pairs(l_temp[s["face"]][s["value"]]["if"]) do
- local wordcount = 0
- local word2count = 0
- for word in string.gmatch(l_temp[s["face"]][s["value"]]["if"][k], "%S+") do
- local check=false
- wordcount = wordcount+1
- word2count = 0
- for word2 in string.gmatch(l_temp2[k],"%S+") do
- word2count = word2count +1
- if word ~= nil and word2 ~= nil and word == word2 then
- check=true
- break
- end
- end
- if not check then
- pass = false
- break
- end
- end
- if wordcount ~= word2count then
- pass = false
- end
- end
- 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
- pass = false
- 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
- pass = true
- end
- end
- return pass
- end
- local function save(s,l)
- local a,b = logicToString(l)
- local sig,log_,met = FSload(s["ID"]..".meta")
- log_[s["face"]][s["value"]] = {["if"] = {["and"] = nil, ["or"] = nil},["then"] = nil,["else"] =nil}
- log_[s["face"]][s["value"]]["if"]["and"] = a
- log_[s["face"]][s["value"]]["if"]["or"] = b
- if s["toggle"] then
- log_[s["face"]][s["value"]]["then"] = "toggle "..tostring(s["then"])
- log_[s["face"]][s["value"]]["else"] = "toggle "..tostring(s["else"])
- else
- log_[s["face"]][s["value"]]["then"] = s["then"]
- log_[s["face"]][s["value"]]["else"] = s["else"]
- end
- if sig[s["ID"]][s["face"]]["isRead"] then
- 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)
- end
- FSsave(s["ID"]..".meta",sig,log_,met)
- if s["ID"] == os.getComputerID() then
- signal[os.getComputerID()][s["face"]]["isRead"] = sig[s["ID"]][s["face"]]["isRead"]
- logic = deepcopy(log_)
- else
- if attachModem() then
- rednet.send(s["ID"],"redOS Request meta")
- end
- end
- end
- while true do
- local IFpos = 1
- local t_c,t_t = emptyScreen(term)
- local IF_c,IF_t = emptyScreen(term,33,ysize)
- if validSignal then
- t_c = tc(t_c,1,1,colors.gray,xsize,5)
- t_c = tc(t_c,1,5,c_bg,xsize,ysize)
- IF_c = tc(IF_c,1,1,c_bg,34,ysize)
- 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
- t_c = tc(t_c,38,7,colors.lightGray,xsize-2,7)
- else
- t_c = tc(t_c,38,7,c_unselected,xsize-2,7)
- saved = false
- end
- 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
- t_c = tc(t_c,38,11,colors.lightGray,xsize-2,11)
- else
- t_c = tc(t_c,38,11,c_unselected,xsize-2,11)
- saved = false
- end
- local strthen
- local strelse
- if tostring(my_signal["then"]) == "true" then
- strthen = "On "
- elseif tostring(my_signal["then"]) == "false" then
- strthen = "Off"
- else --pulse
- if type(my_signal["then"]) == "string" then
- error("{"..my_signal["then"].."}")
- end
- strthen = string.sub("Pulse ("..tostring(my_signal["then"]/10)..")",0,12)
- end
- if tostring(my_signal["else"]) == "true" then
- strelse = "On"
- elseif tostring(my_signal["else"]) == "false" then
- strelse= "Off"
- else --pulse
- strelse = string.sub("Pulse ("..tostring(my_signal["else"]/10)..")",0,12)
- end
- t_t = tt(t_t,38+(6-math.ceil(string.len(strthen)/2)),7,strthen,colors.black)
- t_t = tt(t_t,38+(6-math.ceil(string.len(strelse)/2)),11,strelse,colors.black)
- if my_signal["toggle"] then
- local c_tog = colors.lightGray
- if string.sub(tostring(logic_temp[my_signal["face"]][my_signal["value"]]["else"]),0,7) ~= "toggle " then
- c_tog = c_unselected
- saved = false
- end
- t_t = tt(t_t,41,15,"True",colors.black)
- t_c = tc(t_c,41,15,c_tog,xsize-7,15)
- else
- local c_tog = c_unselected
- if string.sub(tostring(logic_temp[my_signal["face"]][my_signal["value"]]["else"]),0,7) ~= "toggle " then
- c_tog = colors.lightGray
- else
- saved = false
- end
- t_t = tt(t_t,41,15,"False",colors.black)
- t_c = tc(t_c,41,15,c_tog,xsize-6,15)
- end
- IFpos = 1
- for word,_ in pairs(my_logic) do
- my_logic[word]["IFpos"] = IFpos
- local andor = "Or"
- local onoff = "Off"
- local pdcolor = colors.orange
- if my_logic[word]["saved"] then pdcolor = colors.lightGray else saved = false end
- if my_logic[word]["isAnd"] then andor="And" end
- if my_logic[word]["state"] then onoff="On" end
- IF_t = tt(IF_t,1,IFpos,"-",colors.white)
- IF_t = tt(IF_t,2,IFpos,andor,colors.black)
- IF_t = tt(IF_t,6,IFpos,fstring(my_logic[word]["networkName"],8),colors.black)
- IF_t = tt(IF_t,15,IFpos,my_logic[word]["face"],colors.black)
- IF_t = tt(IF_t,22,IFpos,my_logic[word]["name"],colors.black)
- IF_t = tt(IF_t,32,IFpos,onoff,colors.black)
- IF_c = tc(IF_c,1,IFpos,colors.brown)
- IF_c = tc(IF_c,2,IFpos,pdcolor,4,IFpos)
- IF_c = tc(IF_c,6,IFpos,pdcolor,13,IFpos)
- IF_c = tc(IF_c,15,IFpos,pdcolor,20,IFpos)
- IF_c = tc(IF_c,22,IFpos,pdcolor,30,IFpos)
- IF_c = tc(IF_c,32,IFpos,pdcolor,34,IFpos)
- if type(word) == "string" then
- my_logic[IFpos] = deepcopy(my_logic[word])
- my_logic[word] = {}
- end
- IFpos = IFpos+1
- end
- IF_t = tt(IF_t,1,IFpos,"+Add Conditional",colors.black)
- IF_c = tc(IF_c,1,IFpos,colors.green)
- IF_c = tc(IF_c,2,IFpos,colors.lime,16,IFpos)
- else
- t_c = tc(t_c,1,1,c_bg,xsize,5)
- t_c = tc(t_c,1,5,colors.gray,xsize,ysize)
- IF_c = tc(IF_c,1,1,colors.gray,34,ysize)
- end
- IF_c = tc(IF_c,1,ysize-6,colors.yellow,34,ysize-6)
- t_c = tc(t_c,1,1,c_bord,xsize,1)
- t_c = tc(t_c,1,1,c_bord,1,ysize)
- t_c = tc(t_c,xsize,1,c_bord,xsize,ysize)
- t_c = tc(t_c,1,ysize,c_bord,xsize,ysize)
- --t_c = tc(t_c,2,ysize-1,colors.lightGray,xsize-1,ysize-1)
- t_t = tt(t_t,(xsize-string.len("Logic"))/2,1,"Logic",colors.black)
- if saved then
- t_c = tc(t_c,42,1,colors.lightGray,45,1)
- else
- t_c = tc(t_c,42,1,colors.lime,45,1)
- end
- t_t = tt(t_t,42,1,"Save",colors.black)
- t_c = tc(t_c,47,1,colors.lightGray,50,1)
- t_t = tt(t_t,47,1,"Exit",colors.black)
- t_c = tc(t_c,1,5,colors.yellow,xsize,5)
- t_c = tc(t_c,36,5,colors.yellow,36,ysize)
- t_c = tc(t_c,36,9,colors.yellow,xsize,9)
- t_t = tt(t_t,2,2,"Signal",colors.black)
- t_c = tc(t_c,2,2,colors.yellow,7,2)
- t_t = tt(t_t,2,6,"IF",colors.black)
- t_c = tc(t_c,2,6,colors.yellow,3,6)
- t_t = tt(t_t,37,6,"THEN",colors.black)
- t_c = tc(t_c,37,6,colors.yellow,40,6)
- t_t = tt(t_t,37,10,"ELSE",colors.black)
- t_c = tc(t_c,37,10,colors.yellow,40,10)
- t_t = tt(t_t,37,14,"Toggle",colors.black)
- t_c = tc(t_c,37,14,colors.yellow,42,14)
- t_c = tc(t_c,37,13,colors.yellow,xsize,13)
- --------------------------------------------------onto dynamic stuff
- if my_signal["ID"] == nil then
- t_c = tc(t_c,4,3,c_unselected ,17,3)
- t_t = tt(t_t,4,3,"Select Network",colors.black)
- else
- t_c = tc(t_c,4,3,c_pulldown,17,3)
- t_t = tt(t_t,4,3,fstring(networkNames[my_signal["ID"]],14),colors.black)
- end
- if my_signal["face"] == nil then
- t_c = tc(t_c,19,3,c_unselected,29,3)
- t_t = tt(t_t,19,3,"Select Face",colors.black)
- else
- t_c = tc(t_c,19,3,c_pulldown,29,3)
- t_t = tt(t_t,19,3,my_signal["face"],colors.black)
- end
- if my_signal["ID"] ~= nil and my_signal["face"] ~= nil and signal[my_signal["ID"]][my_signal["face"]]["isBundle"] then
- if my_signal["cable"] == nil then
- t_c = tc(t_c,31,3,c_unselected ,41,3)
- t_t = tt(t_t,31,3,"Select Wire",colors.black)
- else
- t_c = tc(t_c,31,3,c_pulldown,31+string.len(my_signal["cable"]),3)
- t_t = tt(t_t,31,3,my_signal["cable"],colors.black)
- end
- end
- drawPictureTable(term, t_c, 1, 1, colors.black,t_t)
- drawPictureTable(term, IF_c, 2, 7, colors.black,IF_t)
- local event, button, xpos, ypos = grabEvents()
- if event == "mouse_click" then
- if ypos == 3 then --signal selection.
- 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
- drawPictureTable(term, t_c, 1, 1, colors.black,t_t)
- if xpos>3 and xpos <= 17 then -- network pulldown
- local iter = 3
- local list = {}
- list[1] = "Select Network"
- list[2] = "Refresh Network"
- for k,v in pairs(networkNames) do
- list[iter] = v
- if k ~= os.getComputerID() then
- list[iter] = list[iter].." ("..k..")"
- else
- list[iter] = list[iter].." (Local)"
- end
- iter = iter+1
- end
- local result,xpos2,ypos2,button2,event2 = createPulldown(4,3,list,true)
- if result ~= "exit" then
- if result == list[2] then
- RSupdateNetwork()
- sleep(0)
- else
- for i=3,#list do
- if result == list[i] then
- local ID --os.getComputerID()
- for k,v in pairs(networkNames) do
- if list[i] == v.." ("..k..")" or list[i] ==v.." (Local)"then
- ID = k
- end
- end
- if ID == nil then error("Nil ID in networking") end
- if ID == os.getComputerID() then
- my_signal["ID"] = os.getComputerID()
- local s_temp,l_temp,m_temp = FSload(ID..".meta")
- logic_temp = deepcopy(l_temp)
- validSignal = false
- my_signal["face"] = nil
- my_signal["cable"] = nil
- my_signal["value"] = 0
- elseif RedOSPing(ID,true) and ID ~= os.getComputerID then
- if attachModem() then
- rednet.send(ID,"redOS Request meta")
- end
- sleep(0)
- local s_temp,l_temp,m_temp = FSload(ID..".meta")
- if m_temp["password"] ~= "" and m_temp["password"] ~= nil and type(my_trusted[ID]) == "nil" then
- if encrypt(userInput("Please enter the password for terminal '"..m_temp["computerName"].."':","string",true),m_temp["ID"]) == m_temp["password"] then
- my_signal["ID"] = ID
- logic_temp = deepcopy(l_temp)
- validSignal = false
- my_trusted[ID] = true
- my_signal["face"] = nil
- my_signal["cable"] = nil
- my_signal["value"] = 0
- else
- userInput("Invalid Password for '"..m_temp["computerName"].."'")
- end
- else
- my_signal["face"] = nil
- my_signal["cable"] = nil
- my_signal["value"] = 0
- validSignal = false
- my_signal["ID"] = ID
- logic_temp = deepcopy(l_temp)
- my_trusted[ID] = true
- end
- end
- end
- end
- end
- else
- -- [exit]
- end
- elseif xpos>18 and xpos<=29 then
- local list = {}
- list[1] = "Select Face"
- for i=1,#sig_faces do
- list[i+1] = sig_faces[i]
- end
- local result,xpos2,ypos2,button2,event2 = createPulldown(19,3,list,true)
- if result ~= "exit" then
- validSignal = false
- my_signal["cable"] = nil
- my_signal["value"] = 0
- my_signal["face"] = result
- else
- -- [exit]
- end
- 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
- local list = {}
- list[1] = "Select Wire"
- for i=1,#sig_names do
- list[i+1] = sig_names[i]
- end
- local result,xpos2,ypos2,button2,event2 = createPulldown(31,3,list,true)
- if result ~= "exit" then
- validSignal = false
- my_signal["cable"] = result
- for i=1,#sig_names do
- if result == sig_names[i] then
- my_signal["value"] = sig_values[i]
- end
- end
- else
- -- [exit]
- end
- end
- end
- elseif ypos > 6 and ypos <=IFpos+6 and xpos <36 then
- for i=1,IFpos do
- if ypos == i+6 then
- -- we found the selected my_logic[i]
- if xpos==2 and type(my_logic[i]) ~= "nil" then
- local my_logic_temp = {}
- local iter = 1
- for ii=1,IFpos do
- if type(my_logic[ii]) ~= "nil" and ii~= i then
- my_logic_temp[iter] = my_logic[ii]
- iter = iter+1
- end
- end
- my_logic = deepcopy(my_logic_temp)
- IFpos = IFpos-1
- saved = false
- elseif xpos >=2 and xpos <=16 and i == IFpos then
- -- Add a new logic node
- local sig_name = "Wire"
- local sig_value = 0
- if signal[os.getComputerID()]["Front"]["isBundle"] then
- sig_name = "White"
- sig_value = 1
- end
- my_logic[i] = {["networkName"] = "(local)",["ID"] = os.getComputerID(),["saved"] = false,["isAnd"] = true,["name"] = sig_name,["face"] = "Front",["value"] = sig_value,["state"] = true}
- my_logic[i]["isBundle"] = signal[os.getComputerID()]["Front"]["isBundle"]
- elseif i ~= IFpos then
- -- Pulldowns mofo
- if xpos>2 and xpos<6 then
- my_logic[i]["isAnd"] = not my_logic[i]["isAnd"]
- saved = false
- my_logic[i]["saved"] = false
- elseif xpos>6 and xpos <15 then
- local list = {"Network "}
- local iter = 2
- for k,v in pairs(networkNames) do
- list[iter] = v
- if k ~= os.getComputerID() then
- list[iter] = list[iter].." ("..k..")"
- else
- list[iter] = list[iter].." (Local)"
- end
- iter = iter+1
- end
- local result2,xpos2,ypos2,button2,event2 = createPulldown(7,ypos,list,true)
- if result2 ~= "exit" then
- saved = false
- my_logic[i]["saved"] = false
- for ii=2,#list do
- if result2== list[ii] then
- local ID --os.getComputerID()
- for k,v in pairs(networkNames) do
- if list[ii] == v.." ("..k..")" or list[ii] ==v.." (Local)"then
- ID = k
- end
- end
- if ID == os.getComputerID() then
- my_logic[i]["networkName"] = "(local)"
- else
- my_logic[i]["networkName"] = networkNames[ID]
- end
- my_logic[i]["ID"] = ID
- my_logic[i]["isBundle"] = signal[my_logic[i]["ID"]][my_logic[i]["face"]]["isBundle"]
- if my_logic[i]["isBundle"] then
- my_logic[i]["value"] = 1
- my_logic[i]["Name"] = "White"
- else
- my_logic[i]["value"] = 0
- my_logic[i]["Name"] = "Wire"
- end
- end
- end
- else
- --[exit]
- end
- elseif xpos>15 and xpos<22 then
- local list = {"Face "}
- for ii=1,#sig_faces do
- list[ii+1] = sig_faces[ii]
- end
- local result2,xpos2,ypos2,button2,event2 = createPulldown(16,ypos,list,true)
- if result2 ~= "exit" then
- saved = false
- my_logic[i]["saved"] = false
- my_logic[i]["face"] = result2
- if signal[my_logic[i]["ID"]][result2]["isBundle"] then
- my_logic[i]["isBundle"] = true
- my_logic[i]["value"] = 1
- my_logic[i]["name"] = "White"
- else
- my_logic[i]["isBundle"] = false
- my_logic[i]["value"] = 0
- my_logic[i]["name"] = "Wire"
- end
- else
- -- [exit]
- end
- elseif xpos>22 and xpos<32 then
- if my_logic[i]["isBundle"] then
- local list = {"Cable ","Make Wire"}
- for ii=1,#sig_names do
- list[ii+2] = sig_names[ii]
- end
- local result2,xpos2,ypos2,button2,event2 = createPulldown(23,ypos,list,true)
- if result2 ~= "exit" then
- if result2 == "Make Wire" then
- 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
- if my_logic[i]["ID"] ~= os.getComputerID() then
- if attachModem() then
- rednet.send(my_logic[i]["ID"],"redOS Request meta")
- end
- sleep(0)
- local s_,l_,m_ = FSload(my_logic[i]["ID"]..".meta")
- if m_["password"] ~= nil and m_["password"] ~= "" and type(my_trusted[ID]) == "nil" then
- 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
- s_[my_logic[i]["ID"]][my_logic[i]["face"]]["isBundle"] = false
- signal[my_logic[i]["ID"]][my_logic[i]["face"]]["isBundle"] = false
- FSsave(my_logic[i]["ID"]..".meta",s_,l_,m_)
- my_trusted[my_logic[i]["ID"]] = true
- saved = false
- my_logic[i]["saved"] = false
- my_logic[i]["isBundle"] =false
- my_logic[i]["name"] = "Wire"
- my_logic[i]["value"] = 0
- else
- userInput("Invalid Password for '"..m_["computerName"].."'. The cable type will remain a wire")
- end
- else
- s_[my_logic[i]["ID"]][my_logic[i]["face"]]["isBundle"] = false
- signal[my_logic[i]["ID"]][my_logic[i]["face"]]["isBundle"] = false
- FSsave(my_logic[i]["ID"]..".meta",s_,l_,m_)
- my_trusted[my_logic[i]["ID"]] = true
- saved = false
- my_logic[i]["saved"] = false
- my_logic[i]["isBundle"] =false
- my_logic[i]["name"] = "Wire"
- my_logic[i]["value"] = 0
- end
- else
- signal[my_logic[i]["ID"]][my_logic[i]["face"]]["isBundle"] = false
- saved = false
- my_logic[i]["saved"] = false
- my_logic[i]["isBundle"] =false
- my_logic[i]["name"] = "Wire"
- my_logic[i]["value"] = 0
- FSsave(my_logic[i]["ID"]..".meta")
- end
- for key,val in pairs(my_logic) do
- 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
- my_logic[key]["isBundle"] = signal[my_logic[i]["ID"]][my_logic[key]["face"]]["isBundle"]
- if my_logic[key]["isBundle"] and my_logic[key]["value"] == 0 then
- my_logic[key]["value"] = 1
- my_logic[key]["name"] = "White"
- elseif not my_logic[key]["isBundle"] and my_logic[key]["value"] ~= 0 then
- my_logic[key]["value"] = 0
- my_logic[key]["name"] = "Wire"
- end
- end
- end
- if my_logic[i]["ID"] == my_signal["ID"] and my_logic[i]["face"] == my_signal["face"] then
- my_signal["cable"] = nil
- validSignal = false
- end
- end
- else
- saved = false
- my_logic[i]["saved"] = false
- my_logic[i]["name"] = result2
- for ii=1,#sig_names do
- if result2 == sig_names[ii] then
- my_logic[i]["value"] = sig_values[ii]
- end
- end
- end
- else
- -- [exit]
- end
- else
- local list = {"Wire ","Make Cable"}
- local result2,xpos2,ypos2,button2,event2 = createPulldown(23,ypos,list,true)
- if result2 ~= "exit" then
- saved = false
- my_logic[i]["saved"] = false
- if result2 == "Make Cable" then
- 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
- if my_logic[i]["ID"] ~= os.getComputerID() then
- if attachModem() then
- rednet.send(my_logic[i]["ID"],"redOS Request meta")
- end
- sleep(0)
- local s_,l_,m_ = FSload(my_logic[i]["ID"]..".meta")
- if m_["password"] ~= nil and m_["password"] ~= "" and type(my_trusted[ID]) == "nil" then
- 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
- s_[my_logic[i]["ID"]][my_logic[i]["face"]]["isBundle"] = true
- signal[my_logic[i]["ID"]][my_logic[i]["face"]]["isBundle"] = true
- FSsave(my_logic[i]["ID"]..".meta",s_,l_,m_)
- my_trusted[my_logic[i]["ID"]] = true
- saved = false
- my_logic[i]["saved"] = false
- my_logic[i]["isBundle"] =true
- my_logic[i]["name"] = "White"
- my_logic[i]["value"] = 1
- else
- userInput("Invalid Password for '"..m_["computerName"].."'. The cable type will remain a wire")
- end
- else
- s_[my_logic[i]["ID"]][my_logic[i]["face"]]["isBundle"] = true
- signal[my_logic[i]["ID"]][my_logic[i]["face"]]["isBundle"] = true
- FSsave(my_logic[i]["ID"]..".meta",s_,l_,m_)
- my_trusted[my_logic[i]["ID"]] = true
- saved = false
- my_logic[i]["saved"] = false
- my_logic[i]["isBundle"] =true
- my_logic[i]["name"] = "White"
- my_logic[i]["value"] = 1
- end
- else
- signal[my_logic[i]["ID"]][my_logic[i]["face"]]["isBundle"] = true
- saved = false
- my_logic[i]["saved"] = false
- my_logic[i]["isBundle"] =true
- my_logic[i]["name"] = "White"
- my_logic[i]["value"] = 1
- FSsave(my_logic[i]["ID"]..".meta")
- end
- for key,val in pairs(my_logic) do
- 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
- my_logic[key]["isBundle"] = signal[my_logic[i]["ID"]][my_logic[key]["face"]]["isBundle"]
- if my_logic[key]["isBundle"] and my_logic[key]["value"] == 0 then
- my_logic[key]["value"] = 1
- my_logic[key]["name"] = "White"
- elseif not my_logic[key]["isBundle"] and my_logic[key]["value"] ~= 0 then
- my_logic[key]["value"] = 0
- my_logic[key]["name"] = "Wire"
- end
- end
- end
- if my_logic[i]["ID"] == my_signal["ID"] and my_logic[i]["face"] == my_signal["face"] then
- my_signal["cable"] = nil
- validSignal = false
- end
- end
- end
- else
- -- [exit]
- end
- end
- elseif xpos>32 and xpos<36 then
- my_logic[i]["state"] = not my_logic[i]["state"]
- saved = false
- my_logic[i]["saved"] = false
- else
- -- [exit]
- end
- end
- end
- end
- elseif xpos > 37 and ypos > 5 then
- --We are in ELSE and THEN and toggle
- if ypos == 7 and xpos < xsize-2 then
- local list = {"Then ","On","Off","Pulse"}
- local result2,xpos2,ypos2,button2,event2 = createPulldown(38,ypos,list,true)
- if result2 ~= "exit" then
- if result2 == list[2] then
- my_signal["then"] = true
- elseif result2 == list[3] then
- my_signal["then"] = false
- else
- local val
- while true do
- val = userInput("Please enter a pulse timing in seconds","number")
- if val >= 0.1 then
- break
- else
- userInput("The timing must be greater than 0.1 seconds")
- end
- end
- my_signal["then"] = math.ceil(val*10)
- end
- else
- -- [exit]
- end
- elseif ypos == 11 and xpos < xsize-2 then
- local list = {"else ","On","Off","Pulse"}
- local result2,xpos2,ypos2,button2,event2 = createPulldown(38,ypos,list,true)
- if result2 ~= "exit" then
- if result2 == list[2] then
- my_signal["else"] = true
- elseif result2 == list[3] then
- my_signal["else"] = false
- else
- local val
- while true do
- val = userInput("Please enter a pulse timing in seconds","number")
- if val >= 0.1 then
- break
- else
- userInput("The timing must be greater than 0.1 seconds")
- end
- end
- my_signal["else"] = math.ceil(val*10)
- end
- else
- -- [exit]
- end
- elseif ypos == 15 and xpos < xsize-5 and xpos>40 then
- my_signal["toggle"] = not my_signal["toggle"]
- end
- elseif ypos == 1 and xpos>xsize-11 then
- if not saved and xpos<xsize-6 and validSignal then
- save(my_signal,my_logic)
- sleep(0)
- local _,logic_,_ = FSload(my_signal["ID"]..".meta")
- logic_temp = {}
- logic_temp = deepcopy(logic_)
- saved = true
- validSignal = false
- elseif xpos>xsize-6 and xpos <xsize then
- if not saved and validSignal then
- if userInput("Are you sure you want to exit? all unsaved data will be lost",true) then
- break
- end
- else
- break
- end
- end
- end
- else
- --os.reboot()
- end
- 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
- validSignal = true
- my_signal["then"] = logic_temp[my_signal["face"]][my_signal["value"]]["then"]
- my_signal["else"] = logic_temp[my_signal["face"]][my_signal["value"]]["else"]
- if string.match(string.sub(tostring(my_signal["then"]),0,6),"toggle") then
- my_signal["toggle"] = true
- my_signal["then"] = toType(string.sub(logic_temp[my_signal["face"]][my_signal["value"]]["then"],8))
- my_signal["else"] = toType(string.sub(logic_temp[my_signal["face"]][my_signal["value"]]["else"],8))
- else
- my_signal["toggle"] = false
- end
- my_logic = {}
- IFpos = 1
- for k,v in pairs(logic_temp[my_signal["face"]][my_signal["value"]]["if"]) do
- for word in string.gmatch(v, "%S+") do
- if k=="and" or k=="or" then
- local ID_,face,sig_value,state = decodeSignal(word)
- local onoff = "On"
- local sig_name = "Wire"
- if not state then
- onoff = "Off"
- end
- if type(networkNames[ID_]) == "nil" then
- networkNames[ID_] = "Unknown "..ID_
- local s_ = signal_setup(ID_)
- signal[ID_] = deepcopy(s_[ID_])
- end
- if sig_value ~= 0 then
- for kk,vv in pairs(sig_values) do
- if sig_value == vv then
- sig_name = sig_names[kk]
- end
- end
- end
- --my_logic[word] = {}
- if os.getComputerID() == ID_ then networkName = "(Local)" else networkName = networkNames[ID_] end
- my_logic[IFpos] = {["networkName"] = networkName,["ID"] = ID_,["saved"] = true,["isAnd"] = false,["name"] = sig_name,["face"] = face,["value"] = sig_value,["state"] = state}
- if sig_value > 0 then
- my_logic[IFpos]["isBundle"] = true
- end
- if k == "and" then
- my_logic[IFpos]["isAnd"] = true
- end
- IFpos = IFpos +1
- end
- end
- end
- --end
- elseif validSignal then
- if not validSave() then--validSave(my_logic,my_signal,logic_temp) then
- saved = false
- else
- saved = true
- end
- end
- end
- end
- function configScreen()
- local xsize,ysize = term.getSize()
- local c_bg = colors.lightBlue
- local c_bord = colors.yellow
- local saved = true
- local options = {"Computer Name:","Password:","Read Only:","Boot Into:","Trusted PCs:"}
- local query = {
- "This will assign a custom name to this PC. The name will be visible on all networks.";
- "This is the password for the PC, it will be prompted when other users try to connect or when you lock the terminal";
- "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)";
- "TODO";
- "TODO";
- }
- local readonly = meta["isRead"]
- local computerName = meta["computerName"]
- local password = meta["password"]
- local bootinto = meta["bootInto"]
- while true do
- local t_c,t_t = emptyScreen(term)
- t_c = tc(t_c,1,1,c_bg,xsize,ysize)
- t_c = tc(t_c,1,1,c_bord,xsize,1)
- t_c = tc(t_c,1,1,c_bord,1,ysize)
- t_c = tc(t_c,xsize,1,c_bord,xsize,ysize)
- t_c = tc(t_c,1,ysize,c_bord,xsize,ysize)
- for i=1,#options do
- local xpos = 4
- local ypos = i*2+3
- --t_c = tc(t_c,xpos,ypos,c_bord,xpos+string.len("(EDIT)")-1,ypos)
- --t_t = tt(t_t,xpos,ypos,"(EDIT)",colors.gray)
- t_c = tc(t_c,xpos-1,ypos,colors.green)
- t_t = tt(t_t,xpos-1,ypos,"?",colors.black)
- t_t = tt(t_t,xpos+1,ypos,options[i],colors.black)
- t_c = tc(t_c,xpos+1,ypos,colors.cyan,xpos+1+#options[i]-1,ypos)
- local txtbg_c = colors.lightGray
- 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
- txtbg_c = colors.orange
- saved = false
- end
- if i == 1 then
- t_t = tt(t_t,xpos+2+string.len(options[i]),ypos,computerName,colors.black)
- t_c = tc(t_c,xpos+2+string.len(options[i]),ypos,txtbg_c,xpos+1+#computerName+string.len(options[i]),ypos)
- elseif i == 2 then
- if password == nil or password == "" then
- t_t = tt(t_t,xpos+2+string.len(options[i]),ypos,"Add Password",colors.black)
- t_c = tc(t_c,xpos+2+string.len(options[i]),ypos,txtbg_c,xpos+13+string.len(options[i]),ypos)
- else
- t_t = tt(t_t,xpos+2+string.len(options[i]),ypos,"Edit Password",colors.black)
- t_c = tc(t_c,xpos+2+string.len(options[i]),ypos,txtbg_c,xpos+14+string.len(options[i]),ypos)
- t_t = tt(t_t,xpos+16+string.len(options[i]),ypos,"(Remove)",colors.black)
- t_c = tc(t_c,xpos+16+string.len(options[i]),ypos,colors.yellow,xpos+23+string.len(options[i]),ypos)
- end
- elseif i==3 then
- t_c = tc(t_c,xpos+2+#options[i],ypos,txtbg_c,xpos+1+#options[i]+string.len(tostring(readonly)),ypos)
- t_t = tt(t_t,xpos+2+string.len(options[i]),ypos,tostring(readonly),colors.black)
- elseif i==4 then
- if bootinto ~= os.getComputerID() then
- local networkname = networkNames[bootinto]
- if networkNames[bootinto] == nil then
- RSupdateNetwork()
- sleep(0)
- if networkNames[bootinto] == nil then
- networkname= "Not Found"
- else
- networkname = networkNames[bootinto]
- end
- end
- t_t = tt(t_t,xpos+2+string.len(options[i]),ypos,networkname,colors.black)
- 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)
- else
- t_t = tt(t_t,xpos+2+string.len(options[i]),ypos,"(Local)",colors.black)
- t_c = tc(t_c,xpos+2+string.len(options[i]),ypos,txtbg_c,xpos+8+string.len(options[i]),ypos)
- end
- end
- end
- t_c = tc(t_c,14,ysize-2,colors.yellow,19,ysize-2)
- t_t = tt(t_t,15,ysize-2,"Save",colors.black)
- t_t = tt(t_t,(xsize-string.len("Configuration"))/2,3,"Configuration",colors.black)
- if meta["ID"] ~= os.getComputerID() then
- t_t = tt(t_t,(xsize-string.len(networkNames[meta["ID"]]))/2,2,networkNames[meta["ID"]],colors.black)
- else
- t_t = tt(t_t,(xsize-string.len("(Local)"))/2,2,"(Local)",colors.black)
- end
- t_c = tc(t_c,(xsize-string.len("Configuration"))/2,3,colors.cyan,(xsize+string.len("Configuration"))/2-1,3)
- t_c = tc(t_c,31,ysize-2,colors.yellow,36,ysize-2)
- t_t = tt(t_t,32,ysize-2,"Exit",colors.black)
- drawPictureTable(term, t_c, 1, 1, colors.black,t_t)
- local event, button, xpos, ypos = grabEvents()
- if event == "mouse_click" then
- for i=1,#options do
- if ypos == i*2+3 then
- if xpos == 3 then --"?"
- userInput(query[i])
- elseif xpos > 5+#options[i] then
- if i == 1 and xpos < 4+#options[i]+string.len(computerName)+2 then
- t_c = tc(t_c,6+string.len(options[i]),ypos,colors.black,16+string.len(options[i]),ypos)
- t_c = tc(t_c,16+string.len(options[i]),ypos,colors.lightBlue,xsize-1,ypos)
- t_t = tt(t_t,6+string.len(options[i]),ypos," ",colors.black)
- while true do
- drawPictureTable(term, t_c, 1, 1, colors.black,t_t)
- term.setCursorPos(6+string.len(options[i]),ypos)
- local computerName_temp = io.read()
- if computerName_temp ~= nil and computerName_temp ~= "" then
- computerName = computerName_temp
- break
- end
- end
- elseif i==2 then
- if xpos < 17+#options[i] then
- if password == nil or password == "" then
- while true do
- password = encrypt(userInput("Please enter a new password:","string"),meta["ID"])
- if password ~= nil and password ~= "" then
- break
- else
- userInput("Invalid char")
- end
- end
- else
- if password == encrypt(userInput("Please enter the current password:","string"),meta["ID"]) then
- while true do
- password = encrypt(userInput("Please enter a new password:","string"),meta["ID"])
- if password ~= nil and password ~= "" then
- break
- else
- userInput("Invalid char")
- end
- end
- else
- userInput("Invalid Password")
- end
- end
- elseif xpos > 17+#options[i] and xpos < 9+17+#options[i] then
- if password == encrypt(userInput("Please enter the current password:","string"),meta["ID"]) then
- password = ""
- userInput("Password Removed")
- else
- userInput("Invalid Password")
- end
- end
- elseif i ==3 and xpos <= 5+#options[i]+string.len(tostring(readonly)) then
- readonly = not readonly
- elseif i == 4 then
- local a,b,c = userSignalSelection("Please select a network",true,false,false,false)
- if a ~= nil then
- bootinto = a
- end
- elseif i == 5 then
- end
- end
- end
- end
- if ypos == ysize-2 then
- if xpos >= 14 and xpos <= 20 then
- meta["isRead"] = readonly
- meta["computerName"] = computerName
- meta["password"] = password
- meta["bootInto"]= bootinto
- networkNames[meta["ID"]] = computerName
- saved = true
- elseif xpos >= 31 and xpos <= 36 then
- if saved then
- break
- else
- if userInput("Are you sure you want to exit? All unsaved changes will be lost",true) then
- break
- end
- end
- end
- end
- elseif event =="key" and button == 28 then
- if not saved then
- meta["isRead"] = readonly
- meta["computerName"] = computerName
- meta["password"] = password
- meta["bootInto"]= bootinto
- networkNames[meta["ID"]] = computerName
- saved = true
- else
- break
- end
- end
- end
- FSsave(meta["ID"]..".meta")
- end
- function headerPulldown(name,xpos)
- if name == "Options" then
- local list = {"Options","Lock Terminal","Config","Check for Updates","Command Line (Shell)","Restart","Reformat Terminal"}
- local result,xpos2,ypos2,button,event = createPulldown(xpos,1,list,true)
- if result == list[2] then
- lockTerminal()
- elseif result == list[3] then
- configScreen()
- elseif result == list[4] then
- checkUpdates()
- elseif result == list[5] then
- MYshell()
- elseif result == list[6] then
- os.reboot()
- elseif result == list[7] then
- local warn_txt = networkNames[meta["ID"]]
- if meta["ID"] == os.getComputerID() then
- warn_txt = warn_txt.."(Local)"
- else
- warn_txt = warn_txt.."("..meta["ID"]..")"
- end
- 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? "
- if userInput(warning,true) then
- fs.delete(meta["ID"]..".meta")
- --monFace = nil
- FSsave(meta["ID"]..".meta",signal_setup(meta["ID"]),logic_setup(),meta_setup(meta["ID"]))
- if meta["ID"] == os.getComputerID() then
- signal,logic,meta = FSload(meta["ID"]..".meta")
- os.reboot()
- else
- if attachModem() then
- Debug(meta["ID"])
- rednet.send(tonumber(meta["ID"]),"redOS 149634901231")
- end
- local sig,_,met = FSload(meta["ID"]..".meta")
- meta = deepcopy(met)
- signal = deepcopy(sig)
- end
- end
- elseif result == "exit" then
- grabInput(xpos2,ypos2,button,event)
- end
- elseif name == "View" then
- local list = {"View","Erase custom UI","Push UI to monitor"}
- local result,xpos2,ypos2,button,event = createPulldown(xpos,1,list,true)
- if result == list[2] then
- meta["customUI"] = {}
- local c,t = emptyScreen(term)
- meta["customUI"][0] = {["table"] = c,["text"] =t}
- elseif result == list[3] then
- list = {list[3],"Face:","Any","Front", "Back", "Left","Right","Top","Bottom"}
- local result2,xpos3,ypos3,button1,event = pullsideways(list,xpos,3,0)
- if result2 ~= "exit" then
- local s,l,m = FSload(os.getComputerID()..".meta")
- if result2 == list[3] then
- for i=1,#comp_faces do
- if peripheral.getType(string.lower(comp_faces[i])) == "monitor" then
- monFace = string.lower(comp_faces[i])
- mon = peripheral.wrap( string.lower(comp_faces[i]))
- FSsave(os.getComputerID()..".meta",s,l,m)
- end
- end
- elseif peripheral.isPresent(string.lower(result2)) and peripheral.getType(string.lower(result2)) =="monitor" then
- mon = peripheral.wrap(string.lower(result2))
- monFace = result2
- FSsave(os.getComputerID()..".meta",s,l,m)
- else
- userInput("No monitor found on the "..string.lower(result2).." side of the terminal")
- end
- else
- grabInput(xpos3,ypos3,button1,event)
- end
- elseif result == "exit" then
- grabInput(xpos2,ypos2,button,event)
- end
- elseif name == "Cable" then
- local list = {"Cable","Add Logic","Face Options"}
- local result,xpos2,ypos2,button,event = createPulldown(xpos,1,list,true)
- if result == list[2] then
- logicScreen()
- elseif result == list[3] then
- list = {"Face Options","","Front","Back","Left","Right","Top","Bottom"}
- local result2,xpos3,ypos3,button1,event = pullsideways(list,xpos,3,0)
- if result2 ~= "exit" then
- for i=2,#list do
- if result2 == list[i] then
- local var = {"Set as Bundle","Set to Read",list[i]}
- if signal[meta["ID"]][list[i]]["isBundle"] then
- var[1] = "Set as Wire"
- end
- if signal[meta["ID"]][list[i]]["isRead"] then
- var[2] = "Set to Write"
- end
- for i=#list[i],5 do
- var[3] = var[3].." "
- end
- local newlist = {var[3],"Toggle",var[1],var[2]}
- local result3,xpos4,ypos4,button2,event = pullsideways(newlist,xpos+12,i,0)
- if result3 ~= "exit" then
- if result3 == newlist[3] then
- 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
- toggleBundle(meta["ID"],list[i])
- end
- else
- 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
- if not signal[meta["ID"]][list[i]]["isRead"] then
- if signal[meta["ID"]][list[i]]["isBundle"] then
- rs.setBundledOutput(string.lower(list[i]),0)
- else
- rs.setOutput(string.lower(list[i]),false)
- end
- end
- signal[meta["ID"]][list[i]]["isRead"] = not signal[meta["ID"]][list[i]]["isRead"]
- end
- end
- else
- grabInput(xpos4,ypos4,button,event)
- end
- end
- end
- else
- grabInput(xpos3,ypos3,button,event)
- end
- elseif result == "exit" then
- grabInput(xpos2,ypos2,button,event)
- end
- elseif name == "Network" then
- --RSupdateNetwork()
- local list = {"Network","Refresh Network"}
- num_networkNames = 0
- for i,v in pairs(networkNames) do
- num_networkNames = num_networkNames+1
- end
- if num_networkNames > 1 then
- local iter = 4
- for i,v in pairs(networkNames) do
- if i ~= os.getComputerID() then
- list[iter] = v.." ("..i..")"
- else
- list[3] = v.." (Local)"
- iter = iter-1
- end
- iter = iter+1
- end
- end
- local result,xpos2,ypos2,button,event = createPulldown(xpos,1,list,true)
- if result == list[2] and list[2] == "Refresh Network" then
- RSupdateNetwork()
- sleep(0)
- elseif result == "exit" then
- grabInput(xpos2,ypos2,button,event)
- else
- for i=3,#list do
- if result == list[i] then
- local ID --os.getComputerID()
- for k,v in pairs(networkNames) do
- if list[i] == v.." ("..k..")" or list[i] ==v.." (Local)"then
- ID = k
- end
- end
- if ID == os.getComputerID() then
- FSsave(meta["ID"]..".meta")
- signal,_,meta = FSload(ID..".meta")
- elseif RedOSPing(ID,true) and ID~= nil then
- if fs.exists(ID..".meta") then fs.delete(ID..".meta") end
- if attachModem() then
- rednet.send(ID,"redOS Request meta")
- end
- while not fs.exists(ID..".meta") do
- sleep(0.1)
- end
- local s_temp,l_temp,m_temp = FSload(ID..".meta")
- if m_temp["password"] ~= "" and m_temp["password"] ~= nil then
- if encrypt(userInput("Please enter the password for terminal '"..m_temp["computerName"].."':","string",true),m_temp["ID"]) == m_temp["password"] then
- FSsave(meta["ID"]..".meta")
- meta = deepcopy(m_temp)
- signal[ID] = deepcopy(s_temp[ID])
- else
- userInput("Invalid Password, returning to terminal '"..meta["computerName"].."'")
- end
- else
- FSsave(meta["ID"]..".meta")
- signal[ID] = deepcopy(s_temp[ID])
- meta = deepcopy(m_temp)
- end
- end
- end
- end
- end
- end
- end
- local refcnt = 0
- function refreshDisplay(...)
- refcnt = refcnt +1
- local header_t_temp = deepcopy(header_t)
- if networkNames[meta["ID"]] ~= nil then
- local str = "("..string.sub(networkNames[meta["ID"]],0,19)..")"
- if meta["ID"] == os.getComputerID() then
- str = "(Local)"
- end
- if tonumber(string.match(str,"%d+")) ~= meta["ID"] then
- str = str.." "..meta["ID"]
- end
- header_t_temp=tt(header_t_temp,52-string.len(str),1,str,colors.lightGray)
- end
- UI_c,UI_t = emptyScreen(term)
- for k,v in pairs(meta["customUI"]) do
- if k ~= 0 then
- UI_c = overwriteTable(UI_c,v["table"])
- end
- end
- if scanTableFor(meta["customUI"][0]["table"]) then
- UI_c = overwriteTable(UI_c,meta["customUI"][0]["table"])
- end
- if term.isColor() then
- if canRefresh or #arg>0 then
- term.clear()
- drawPictureTable(term, header_c, 1, 1, colors.black,header_t_temp)
- drawPictureTable(term, UI_c, 1, 2, colors.black,UI_t)
- end
- else
- term.clear()
- term.setCursorPos(1,1)
- print("RedOS Node")
- print("Name: "..tostring(networkNames[os.getComputerID()]))
- if type(networkNames[meta["ID"]]) ~= "nil" then
- print("Connected to: "..networkNames[meta["ID"]])
- end
- for i=1,#comp_faces do
- if peripheral.getType(string.lower(comp_faces[i])) == "monitor" then
- monFace = string.lower(comp_faces[i])
- end
- end
- end
- if monFace ~= nil and peripheral.isPresent(string.lower(monFace)) and peripheral.getType(string.lower(monFace)) == "monitor" then
- drawPictureTable(mon, UI_c, 1, 1, colors.black)
- else
- --someone broke the monitor
- end
- end
- --Updates the colors of the UI to reflect the signal they are attached to.
- function updateUIcolor(key,node)
- if node["signal"] ~= nil then
- local ID,face,sig_value,state = decodeSignal(node["signal"])
- if isOn(signal,ID,face,sig_value) then
- if scanTableFor(meta["customUI"][key]["table"],node["onColor"]) then
- return false
- end
- replaceColorTable(meta["customUI"][key]["table"],true,node["onColor"])
- return true
- else
- if scanTableFor(meta["customUI"][key]["table"],node["offColor"]) then
- --Debug("OFF Looking for:"..getHexOf(node["onColor"]).." of key: "..key)
- return false
- end
- replaceColorTable(meta["customUI"][key]["table"],true,node["offColor"])
- return true
- end
- end
- return false
- end
- function setupDisplay()
- header_c,header_t = createHeader()
- UI_c,UI_t = emptyScreen(term)
- UI_c = tc(UI_c,2,2,colors.white,2,2)
- end
- signal = signal_setup()
- logic = logic_setup()
- meta = meta_setup()
- if fs.exists(os.getComputerID()..".meta") then
- signal,logic,meta = FSload(os.getComputerID()..".meta")
- if monFace ~= nil then
- mon = peripheral.wrap(monFace)
- end
- else
- FSsave(os.getComputerID()..".meta")
- end
- setupDisplay()
- networkNames[os.getComputerID()] = meta["computerName"]
- function frontEnd()
- if meta["bootInto"] ~= os.getComputerID() then
- sleep(.5)
- if RedOSPing(meta["bootInto"],true) then
- if attachModem() then
- rednet.send(meta["bootInto"],"redOS Request meta")
- end
- sleep(0.1)
- local sig_,_,met_ = FSload(meta["bootInto"]..".meta")
- signal[meta["bootInto"]] = deepcopy(sig_[meta["bootInto"]])
- meta = deepcopy(met_)
- end
- end
- while not splashdone do
- sleep(0.1)
- end
- if meta["password"] ~= nil and meta["password"] ~= "" and meta["isLocked"] then
- canRefresh = false
- lockTerminal()
- end
- canRefresh = true
- refreshDisplay()
- while true do
- grabInput()
- FSsave(meta["ID"]..".meta")
- local flist = fs.list("")
- for i=1,#flist do
- if string.match(flist[i],".meta") and flist[i] ~= meta["ID"]..".meta" and flist[i] ~= os.getComputerID()..".meta" then
- fs.delete(flist[i])
- end
- end
- end
- end
- function getTime()
- http.request("http://alienmc.co/checkTPS.php")
- local requesting = true
- local valid = false
- local respondedText = ""
- while requesting do
- local event, url, sourceText = os.pullEvent()
- if event == "http_success" then
- respondedText = sourceText.readAll()
- valid = true
- requesting = false
- elseif event == "http_failure" then
- requesting = false
- end
- end
- local total = 0
- for word in string.gmatch(respondedText,"%d+.%d+") do
- total = total + tonumber(string.match(word,"(%d+).%d+")) + tonumber(string.match(word,"%d+.(%d+)"))/10
- end
- total = total/3
- return total
- end
- function DebugScreen()
- if DEBUG then
- checkUpdates(true) -- forces a update
- term.clear()
- refreshDisplay()
- local redcnt =0
- local stncnt = 0
- local allcnt = 0
- local function countRednet()
- while true do
- --local event, _m,mess = os.pullEventRaw("rednet_message","modem_message")
- redcnt = "DISABLED"
- sleep(5)
- --Debug(event.." Message: "..mess)
- end
- end
- local function countstn()
- while true do
- sleep(5)
- --os.pullEvent("redstone")
- stncnt = "DISABLED"
- end
- end
- local function allstn()
- allcnt = "Disabled"
- end
- local function display()
- while true do
- sleep(0.5)
- term.setCursorPos(1,19)
- term.write("Refresh: "..refcnt)
- term.setCursorPos(1,16)
- --term.write("Redstone Events: "..stncnt)
- term.setCursorPos(1,17)
- --term.write("RedNet Events: "..redcnt)
- term.setCursorPos(1,18)
- --term.write("Total Events: "..allcnt)
- end
- end
- --parallel.waitForAll(countRednet,countstn,allstn,display)
- end
- end
- term.clear()
- local Title = {
- " 55 5 555 555 ";
- "8585 85 8585 8585 ";
- "85 85 85 5 5 85 85 55555 85 85 ";
- "85 8585 85 85 855555 858885 855555 ";
- "85 855 85 85 85888885 85 85 85888885 ";
- "85 85 855555 85 85 855555 85 85 ";
- "8 8 88888 8 8 88888 8 8 ";
- "ffffffffffffffffffffffffffffffffffffffffffff ";
- "ffffffffffffffffffffffffffffffffffffffffffff";
- "";
- "";
- }
- drawPictureTable(term, Title, 1, 1, colors.black)
- mon = peripheral.wrap("back")
- drawPictureTable(mon, Title, 1, 1, colors.black)
- sleep(0.2)
- drawPictureTable(mon, Title, 0, 3, colors.black)
- while true do
- sleep(0.2)
- mon.clear()
- drawPictureTable(mon, Title, -1, 3, colors.black)
- sleep(0.2)
- mon.clear()
- drawPictureTable(mon, Title, 0, 3, colors.black)
- sleep(0.2)
- mon.clear()
- drawPictureTable(mon, Title, 1, 3, colors.black)
- for i=1,8 do
- sleep(0.05)
- mon.clear()
- drawPictureTable(mon, Title, 0, 3+i, colors.black)
- end
- local currTick = getTime()
- mon.clear()
- mon.setTextScale(3)
- mon.setTextColor(colors.white)
- local x,y = mon.getSize()
- mon.setCursorPos(1,y/2)
- mon.write("The current TPS is: ")
- mon.setCursorPos(x/2-1,y/2+1)
- if currTick < 6 then
- mon.setTextColor(colors.red)
- elseif currTick >= 6 and currTick < 15 then
- mon.setTextColor(colors.yellow)
- else
- mon.setTextColor(colors.green)
- end
- mon.write(currTick)
- mon.setTextScale(1)
- sleep(3)
- for i=-7,3 do
- sleep(0.05)
- mon.clear()
- drawPictureTable(mon, Title, 0, i, colors.black)
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement