Advertisement
1lann

firewolf-offline

Jan 15th, 2013
149
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 121.47 KB | None | 0 0
  1.  
  2. --  
  3. --  Firewolf Website Browser
  4. --  Made by GravityScore and 1lann
  5. --  License found here: https://raw.github.com/1lann/Firewolf/master/LICENSE
  6. --
  7. --  Original Concept From RednetExplorer 2.4.1
  8. --  RednetExplorer Made by ComputerCraftFan11
  9. --  
  10.  
  11. --  
  12. --  Visit our website at:
  13. --  http://firewolf.webege.com/
  14. --  
  15.  
  16.  
  17. --  -------- Variables
  18.  
  19. -- Version
  20. local version = "2.3.8"
  21. local browserAgentTemplate = "Firewolf " .. version
  22. browserAgent = browserAgentTemplate
  23. local tArgs = {...}
  24.  
  25. -- Server Identification
  26. local serverID = "other"
  27. local serverList = {experimental = "Experimental", other = "Other"}
  28.  
  29. -- Updating
  30. local autoupdate = "true"
  31. local incognito = "false"
  32.  
  33. -- Geometry
  34. local w, h = term.getSize()
  35. local graphics = {}
  36.  
  37. -- Debugging
  38. local debugFile = nil
  39.  
  40. -- Environment
  41. local oldEnv = {}
  42. local env = {}
  43. local backupEnv = {}
  44. local api = {}
  45.  
  46. -- Themes
  47. local theme = {}
  48.  
  49. -- Databases
  50. local blacklist = {}
  51. local whitelist = {}
  52. local definitions = {}
  53. local verifiedDownloads = {}
  54. local dnsDatabase = {[1] = {}, [2] = {}}
  55.  
  56. -- Website loading
  57. local website = ""
  58. local homepage = ""
  59. local timeout = 0.08
  60. local openAddressBar = true
  61. local loadingRate = 0
  62. local curSites = {}
  63. local menuBarOpen = false
  64. local internalWebsite = false
  65. local serverWebsiteID = nil
  66.  
  67. -- Protocols
  68. local curProtocol = {}
  69. local protocols = {}
  70.  
  71. -- History
  72. local history = {}
  73. local addressBarHistory = {}
  74.  
  75. -- Events
  76. local event_loadWebsite = "firewolf_loadWebsiteEvent"
  77. local event_exitWebsite = "firewolf_exitWebsiteEvent"
  78. local event_openAddressBar = "firewolf_openAddressBarEvent"
  79. local event_exitApp = "firewolf_exitAppEvent"
  80. local event_redirect = "firewolf_redirectEvent"
  81.  
  82. -- Download URLs
  83. local firewolfURL = "https://raw.github.com/1lann/firewolf/master/entities/" .. serverID .. ".lua"
  84. local databaseURL = "https://raw.github.com/1lann/firewolf/master/databases/" .. serverID ..
  85.     "-database.txt"
  86. local serverURL = "https://raw.github.com/1lann/firewolf/master/server/server-release.lua"
  87. if serverID == "experimental" then
  88.     serverURL = "https://raw.github.com/1lann/firewolf/master/server/server-experimental.lua"
  89. end
  90. local availableThemesURL = "https://raw.github.com/1lann/firewolf/master/themes/available.txt"
  91.  
  92. -- Data Locations
  93. local rootFolder = "/.Firewolf_Data"
  94. local cacheFolder = rootFolder .. "/cache"
  95. local serverFolder = rootFolder .. "/servers"
  96. local themeLocation = rootFolder .. "/theme"
  97. local defaultThemeLocation = rootFolder .. "/default_theme"
  98. local availableThemesLocation = rootFolder .. "/available_themes"
  99. local serverSoftwareLocation = rootFolder .. "/server_software"
  100. local settingsLocation = rootFolder .. "/settings"
  101. local historyLocation = rootFolder .. "/history"
  102. local debugLogLocation = "/firewolf-log"
  103. local firewolfLocation = "/" .. shell.getRunningProgram()
  104.  
  105. local userBlacklist = rootFolder .. "/user_blacklist"
  106. local userWhitelist = rootFolder .. "/user_whitelist"
  107. local globalDatabase = rootFolder .. "/database"
  108.  
  109.  
  110. --  -------- Firewolf API
  111.  
  112. local function isAdvanced()
  113.     return term.isColor and term.isColor()
  114. end
  115.  
  116. api.clearPage = function(site, color, redraw, tcolor)
  117.     -- Site titles
  118.     local titles = {firewolf = "Firewolf Homepage", server = "Server Management",
  119.         history = "Firewolf History", help = "Help Page", downloads = "Downloads Center",
  120.         settings = "Firewolf Settings", credits = "Firewolf Credits", getinfo = "Website Information",
  121.         nomodem = "No Modem Attached!", crash = "Website Has Crashed!", overspeed = "Too Fast!",
  122.         incorrect = "Incorrect Website!"}
  123.     local title = titles[site]
  124.  
  125.     -- Clear
  126.     local c = color
  127.     if c == nil then c = colors.black end
  128.     term.setBackgroundColor(c)
  129.     term.setTextColor(colors[theme["address-bar-text"]])
  130.     if redraw ~= true then term.clear() end
  131.  
  132.     if not(menuBarOpen) then
  133.         -- URL bar
  134.         term.setCursorPos(2, 1)
  135.         term.setBackgroundColor(colors[theme["address-bar-background"]])
  136.         term.clearLine()
  137.         term.setCursorPos(2, 1)
  138.         local a = site
  139.         if a:len() > w - 9 then a = a:sub(1, 39) .. "..." end
  140.         write("rdnt://" .. a)
  141.         if title ~= nil then
  142.             term.setCursorPos(w - title:len() - 1, 1)
  143.             write(title)
  144.         end
  145.         term.setCursorPos(w, 1)
  146.         term.setBackgroundColor(colors[theme["top-box"]])
  147.         term.setTextColor(colors[theme["text-color"]])
  148.         write("<")
  149.         term.setBackgroundColor(c)
  150.         if tcolor then term.setTextColor(tcolor)
  151.         else term.setTextColor(colors.white) end
  152.         print("")
  153.     else
  154.         term.setCursorPos(1, 1)
  155.         term.setBackgroundColor(colors[theme["top-box"]])
  156.         term.setTextColor(colors[theme["text-color"]])
  157.         term.clearLine()
  158.         write("> [- Exit Firewolf -] [- Incorrect Website -]      ")
  159.         print("")
  160.     end
  161. end
  162.  
  163. api.centerPrint = function(text)
  164.     local w, h = term.getSize()
  165.     local x, y = term.getCursorPos()
  166.     term.setCursorPos(math.ceil((w + 1)/2 - text:len()/2), y)
  167.     print(text)
  168. end
  169.  
  170. api.centerWrite = function(text)
  171.     local w, h = term.getSize()
  172.     local x, y = term.getCursorPos()
  173.     term.setCursorPos(math.ceil((w + 1)/2 - text:len()/2), y)
  174.     write(text)
  175. end
  176.  
  177. api.leftPrint = function(text)
  178.     local x, y = term.getCursorPos()
  179.     term.setCursorPos(4, y)
  180.     print(text)
  181. end
  182.  
  183. api.leftWrite = function(text)
  184.     local x, y = term.getCursorPos()
  185.     term.setCursorPos(4, y)
  186.     write(text)
  187. end
  188.  
  189. api.rightPrint = function(text)
  190.     local x, y = term.getCursorPos()
  191.     local w, h = term.getSize()
  192.     term.setCursorPos(w - text:len() - 1, y)
  193.     print(text)
  194. end
  195.  
  196. api.rightWrite = function(text)
  197.     local x, y = term.getCursorPos()
  198.     local w, h = term.getSize()
  199.     term.setCursorPos(w - text:len() - 1, y)
  200.     write(text)
  201. end
  202.  
  203. api.redirect = function(url)
  204.     os.queueEvent(event_redirect, url:gsub("rdnt://", ""))
  205. end
  206.  
  207. api.prompt = function(list, dir)
  208.     if isAdvanced() then
  209.         for _, v in pairs(list) do
  210.             if v.bg then term.setBackgroundColor(v.bg) end
  211.             if v.tc then term.setTextColor(v.tc) end
  212.             if v[2] == -1 then v[2] = math.ceil((w + 1)/2 - (v[1]:len() + 6)/2) end
  213.  
  214.             term.setCursorPos(v[2], v[3])
  215.             write("[- " .. v[1])
  216.             term.setCursorPos(v[2] + v[1]:len() + 3, v[3])
  217.             write(" -]")
  218.         end
  219.  
  220.         while true do
  221.             local e, but, x, y = os.pullEvent()
  222.             if e == "mouse_click" then
  223.                 for _, v in pairs(list) do
  224.                     if x >= v[2] and x <= v[2] + v[1]:len() + 5 and y == v[3] then
  225.                         return v[1]
  226.                     end
  227.                 end
  228.             elseif e == event_exitWebsite then
  229.                 return nil
  230.             end
  231.         end
  232.     else
  233.         for _, v in pairs(list) do
  234.             term.setBackgroundColor(colors.black)
  235.             term.setTextColor(colors.white)
  236.             if v[2] == -1 then v[2] = math.ceil((w + 1)/2 - (v[1]:len() + 4)/2) end
  237.  
  238.             term.setCursorPos(v[2], v[3])
  239.             write("  " .. v[1])
  240.             term.setCursorPos(v[2] + v[1]:len() + 2, v[3])
  241.             write("  ")
  242.         end
  243.  
  244.         local key1 = 200
  245.         local key2 = 208
  246.         if dir == "horizontal" then
  247.             key1 = 203
  248.             key2 = 205
  249.         end
  250.  
  251.         local curSel = 1
  252.         term.setCursorPos(list[curSel][2], list[curSel][3])
  253.         write("[")
  254.         term.setCursorPos(list[curSel][2] + list[curSel][1]:len() + 3, list[curSel][3])
  255.         write("]")
  256.  
  257.         while true do
  258.             local e, key = os.pullEvent()
  259.             term.setCursorPos(list[curSel][2], list[curSel][3])
  260.             write(" ")
  261.             term.setCursorPos(list[curSel][2] + list[curSel][1]:len() + 3, list[curSel][3])
  262.             write(" ")
  263.             if e == "key" and key == key1 and curSel > 1 then
  264.                 curSel = curSel - 1
  265.             elseif e == "key" and key == key2 and curSel < #list then
  266.                 curSel = curSel + 1
  267.             elseif e == "key" and key == 28 then
  268.                 return list[curSel][1]
  269.             elseif e == event_exitWebsite then
  270.                 return nil
  271.             end
  272.             term.setCursorPos(list[curSel][2], list[curSel][3])
  273.             write("[")
  274.             term.setCursorPos(list[curSel][2] + list[curSel][1]:len() + 3, list[curSel][3])
  275.             write("]")
  276.         end
  277.     end
  278. end
  279.  
  280. api.scrollingPrompt = function(list, x, y, len, width)
  281.     local wid = width
  282.     if wid == nil then wid = w - 3 end
  283.  
  284.     local function updateDisplayList(items, loc, len)
  285.         local ret = {}
  286.         for i = 1, len do
  287.             local item = items[i + loc - 1]
  288.             if item ~= nil then table.insert(ret, item) end
  289.         end
  290.         return ret
  291.     end
  292.  
  293.     if isAdvanced() then
  294.         local function draw(a)
  295.             for i, v in ipairs(a) do
  296.                 term.setCursorPos(1, y + i - 1)
  297.                 api.centerWrite(string.rep(" ", wid + 2))
  298.                 term.setCursorPos(x, y + i - 1)
  299.                 write("[ " .. v:sub(1, wid - 5))
  300.                 term.setCursorPos(wid + x - 2, y + i - 1)
  301.                 write("  ]")
  302.             end
  303.         end
  304.  
  305.         local loc = 1
  306.         local disList = updateDisplayList(list, loc, len)
  307.         draw(disList)
  308.        
  309.         while true do
  310.             local e, but, clx, cly = os.pullEvent()
  311.             if e == "key" and but == 200 and loc > 1 then
  312.                 loc = loc - 1
  313.                 disList = updateDisplayList(list, loc, len)
  314.                 draw(disList)
  315.             elseif e == "key" and but == 208 and loc + len - 1 < #list then
  316.                 loc = loc + 1
  317.                 disList = updateDisplayList(list, loc, len)
  318.                 draw(disList)
  319.             elseif e == "mouse_scroll" and but > 0 and loc + len - 1 < #list then
  320.                 loc = loc + but
  321.                 disList = updateDisplayList(list, loc, len)
  322.                 draw(disList)
  323.             elseif e == "mouse_scroll" and but < 0 and loc > 1 then
  324.                 loc = loc + but
  325.                 disList = updateDisplayList(list, loc, len)
  326.                 draw(disList)
  327.             elseif e == "mouse_click" then
  328.                 for i, v in ipairs(disList) do
  329.                     if clx >= x and clx <= x + wid and cly == i + y - 1 then
  330.                         return v
  331.                     end
  332.                 end
  333.             elseif e == event_exitWebsite then
  334.                 return nil
  335.             end
  336.         end
  337.     else
  338.         local function draw(a)
  339.             for i, v in ipairs(a) do
  340.                 term.setCursorPos(1, y + i - 1)
  341.                 api.centerWrite(string.rep(" ", wid + 2))
  342.                 term.setCursorPos(x, y + i - 1)
  343.                 write("[ ] " .. v:sub(1, wid - 5))
  344.             end
  345.         end
  346.  
  347.         local loc = 1
  348.         local curSel = 1
  349.         local disList = updateDisplayList(list, loc, len)
  350.         draw(disList)
  351.         term.setCursorPos(x + 1, y + curSel - 1)
  352.         write("x")
  353.  
  354.         while true do
  355.             local e, key = os.pullEvent()
  356.             term.setCursorPos(x + 1, y + curSel - 1)
  357.             write(" ")
  358.             if e == "key" and key == 200 then
  359.                 if curSel > 1 then
  360.                     curSel = curSel - 1
  361.                 elseif loc > 1 then
  362.                     loc = loc - 1
  363.                     disList = updateDisplayList(list, loc, len)
  364.                     draw(disList)
  365.                 end
  366.             elseif e == "key" and key == 208 then
  367.                 if curSel < #disList then
  368.                     curSel = curSel + 1
  369.                 elseif loc + len - 1 < #list then
  370.                     loc = loc + 1
  371.                     disList = updateDisplayList(list, loc, len)
  372.                     draw(disList)
  373.                 end
  374.             elseif e == "key" and key == 28 then
  375.                 return list[curSel + loc - 1]
  376.             elseif e == event_exitWebsite then
  377.                 return nil
  378.             end
  379.             term.setCursorPos(x + 1, y + curSel - 1)
  380.             write("x")
  381.         end
  382.     end
  383. end
  384.  
  385. api.clearArea = function() api.clearPage(website) end
  386. api.cPrint = function(text) api.centerPrint(text) end
  387. api.cWrite = function(text) api.centerWrite(text) end
  388. api.lPrint = function(text) api.leftPrint(text) end
  389. api.lWrite = function(text) api.leftWrite(text) end
  390. api.rPrint = function(text) api.rightPrint(text) end
  391. api.rWrite = function(text) api.rightWrite(text) end
  392.  
  393. -- Set Environment
  394. for k, v in pairs(getfenv(0)) do env[k] = v end
  395. for k, v in pairs(getfenv(1)) do env[k] = v end
  396. for k, v in pairs(env) do oldEnv[k] = v end
  397. for k, v in pairs(api) do env[k] = v end
  398. for k, v in pairs(env) do backupEnv[k] = v end
  399. setfenv(1, env)
  400.  
  401.  
  402. --  -------- Utilities
  403.  
  404. local function debugLog(n, ...)
  405.     local lArgs = {...}
  406.     if debugFile then
  407.         if n == nil then n = "" end
  408.         debugFile:write("\n" .. tostring(n) .. " : ")
  409.         for k, v in pairs(lArgs) do
  410.             if type(v) == "string" or type(v) == "number" or type(v) == nil or
  411.                     type(v) == "boolean" then
  412.                 debugFile:write(tostring(v) .. ", ")
  413.             else debugFile:write("type-" .. type(v) .. ", ") end
  414.         end
  415.     end
  416. end
  417.  
  418. local function modRead(replaceChar, his, maxLen, stopAtMaxLen, liveUpdates, exitOnControl)
  419.     term.setCursorBlink(true)
  420.     local line = ""
  421.     local hisPos = nil
  422.     local pos = 0
  423.     if replaceChar then replaceChar = replaceChar:sub(1, 1) end
  424.     local w, h = term.getSize()
  425.     local sx, sy = term.getCursorPos()
  426.  
  427.     local function redraw(repl)
  428.         local scroll = 0
  429.         if line:len() >= maxLen then scroll = line:len() - maxLen end
  430.  
  431.         term.setCursorPos(sx, sy)
  432.         local a = repl or replaceChar
  433.         if a then term.write(string.rep(a, line:len() - scroll))
  434.         else term.write(line:sub(scroll + 1)) end
  435.         term.setCursorPos(sx + pos - scroll, sy)
  436.     end
  437.  
  438.     while true do
  439.         local e, but, x, y, p4, p5 = os.pullEvent()
  440.         if e == "char" and not(stopAtMaxLen == true and line:len() >= maxLen) then
  441.             line = line:sub(1, pos) .. but .. line:sub(pos + 1, -1)
  442.             pos = pos + 1
  443.             redraw()
  444.         elseif e == "key" then
  445.             if but == keys.enter then
  446.                 break
  447.             elseif but == keys.left then
  448.                 if pos > 0 then pos = pos - 1 redraw() end
  449.             elseif but == keys.right then
  450.                 if pos < line:len() then pos = pos + 1 redraw() end
  451.             elseif (but == keys.up or but == keys.down) and his then
  452.                 redraw(" ")
  453.                 if but == keys.up then
  454.                     if hisPos == nil and #his > 0 then hisPos = #his
  455.                     elseif hisPos > 1 then hisPos = hisPos - 1 end
  456.                 elseif but == keys.down then
  457.                     if hisPos == #his then hisPos = nil
  458.                     elseif hisPos ~= nil then hisPos = hisPos + 1 end
  459.                 end
  460.  
  461.                 if hisPos then
  462.                     line = his[hisPos]
  463.                     pos = line:len()
  464.                 else
  465.                     line = ""
  466.                     pos = 0
  467.                 end
  468.                 redraw()
  469.                 if liveUpdates then
  470.                     local a, data = liveUpdates(line, "update_history", nil, nil, nil, nil, nil)
  471.                     if a == true and data == nil then
  472.                         term.setCursorBlink(false)
  473.                         return line
  474.                     elseif a == true and data ~= nil then
  475.                         term.setCursorBlink(false)
  476.                         return data
  477.                     end
  478.                 end
  479.             elseif but == keys.backspace and pos > 0 then
  480.                 redraw(" ")
  481.                 line = line:sub(1, pos - 1) .. line:sub(pos + 1, -1)
  482.                 pos = pos - 1
  483.                 redraw()
  484.                 if liveUpdates then
  485.                     local a, data = liveUpdates(line, "delete", nil, nil, nil, nil, nil)
  486.                     if a == true and data == nil then
  487.                         term.setCursorBlink(false)
  488.                         return line
  489.                     elseif a == true and data ~= nil then
  490.                         term.setCursorBlink(false)
  491.                         return data
  492.                     end
  493.                 end
  494.             elseif but == keys.home then
  495.                 pos = 0
  496.                 redraw()
  497.             elseif but == keys.delete and pos < line:len() then
  498.                 redraw(" ")
  499.                 line = line:sub(1, pos) .. line:sub(pos + 2, -1)
  500.                 redraw()
  501.                 if liveUpdates then
  502.                     local a, data = liveUpdates(line, "delete", nil, nil, nil, nil, nil)
  503.                     if a == true and data == nil then
  504.                         term.setCursorBlink(false)
  505.                         return line
  506.                     elseif a == true and data ~= nil then
  507.                         term.setCursorBlink(false)
  508.                         return data
  509.                     end
  510.                 end
  511.             elseif but == keys["end"] then
  512.                 pos = line:len()
  513.                 redraw()
  514.             elseif (but == 29 or but == 157) and not(exitOnControl) then
  515.                 term.setCursorBlink(false)
  516.                 return nil
  517.             end
  518.         end if liveUpdates then
  519.             local a, data = liveUpdates(line, e, but, x, y, p4, p5)
  520.             if a == true and data == nil then
  521.                 term.setCursorBlink(false)
  522.                 return line
  523.             elseif a == true and data ~= nil then
  524.                 term.setCursorBlink(false)
  525.                 return data
  526.             end
  527.         end
  528.     end
  529.  
  530.     term.setCursorBlink(false)
  531.     if line ~= nil then line = line:gsub("^%s*(.-)%s*$", "%1") end
  532.     return line
  533. end
  534.  
  535.  
  536. --  -------- Graphics
  537.  
  538. graphics.githubImage = [[
  539. f       f  
  540. fffffffff  
  541. fffffffff  
  542. f4244424f  
  543. f4444444f  
  544. fffffefffe  
  545.    fffe e  
  546.  fffff e  
  547. ff f fe e  
  548.      e   e
  549.          
  550. ]]
  551.  
  552.  
  553. --  -------- Themes
  554.  
  555. local defaultTheme = {["address-bar-text"] = "white", ["address-bar-background"] = "gray",
  556.     ["address-bar-base"] = "lightGray", ["top-box"] = "red", ["bottom-box"] = "orange",
  557.     ["text-color"] = "white", ["background"] = "gray"}
  558. local originalTheme = {["address-bar-text"] = "white", ["address-bar-background"] = "black",
  559.     ["address-bar-base"] = "black", ["top-box"] = "black", ["bottom-box"] = "black",
  560.     ["text-color"] = "white", ["background"] = "black"}
  561.  
  562. local ownThemeFileContent = [[
  563. -- Text color of the address bar
  564. address-bar-text=
  565.  
  566. -- Background color of the address bar
  567. address-bar-background=
  568.  
  569. -- Color of separator bar when live searching
  570. address-bar-base=
  571.  
  572. -- Top box color
  573. top-box=
  574.  
  575. -- Bottom box color
  576. bottom-box=
  577.  
  578. -- Background color
  579. background=
  580.  
  581. -- Main text color
  582. text-color=
  583.  
  584. ]]
  585.  
  586. local function loadTheme(path)
  587.     if fs.exists(path) and not(fs.isDir(path)) then
  588.         local a = {}
  589.         local f = io.open(path, "r")
  590.         local l = f:read("*l")
  591.         while l ~= nil do
  592.             l = l:gsub("^%s*(.-)%s*$", "%1")
  593.             if l ~= "" and l ~= nil and l ~= "\n" and l:sub(1, 2) ~= "--" then
  594.                 local b = l:find("=")
  595.                 if a and b then
  596.                     local c = l:sub(1, b - 1)
  597.                     local d = l:sub(b + 1, -1)
  598.                     if c == "" or d == "" then return nil
  599.                     else a[c] = d end
  600.                 else return nil end
  601.             end
  602.             l = f:read("*l")
  603.         end
  604.         f:close()
  605.  
  606.         return a
  607.     else
  608.         return nil
  609.     end
  610. end
  611.  
  612. --  -------- Filesystem
  613.  
  614. local function download(url, path)
  615.     for i = 1, 3 do
  616.         local response = http.get(url)
  617.         if response then
  618.             local data = response.readAll()
  619.             response.close()
  620.             if path then
  621.                 local f = io.open(path, "w")
  622.                 f:write(data)
  623.                 f:close()
  624.             end
  625.             return true
  626.         end
  627.     end
  628.  
  629.     return false
  630. end
  631.  
  632. local function verifyGitHub()
  633.     local ret = false
  634.     http.request("https://raw.github.com")
  635.     local a = os.startTimer(10)
  636.     while true do
  637.         local e, url, source = os.pullEvent()
  638.         if e == "http_success" then
  639.             ret = true
  640.             break
  641.         elseif e == "http_failure" then
  642.             ret = false
  643.             break
  644.         elseif e == "timer" and url == a then
  645.             ret = false
  646.             break
  647.         end
  648.     end
  649.  
  650.     if not(ret) then
  651.         if isAdvanced() then
  652.             term.setTextColor(colors[theme["text-color"]])
  653.             term.setBackgroundColor(colors[theme["background"]])
  654.             term.clear()
  655.             local f = io.open(rootFolder .. "/temp_file", "w")
  656.             f:write(graphics.githubImage)
  657.             f:close()
  658.             local a = paintutils.loadImage(rootFolder .. "/temp_file")
  659.             paintutils.drawImage(a, 1, 3)
  660.             fs.delete(rootFolder .. "/temp_file")
  661.  
  662.             term.setCursorPos(19, 4)
  663.             term.setBackgroundColor(colors[theme["top-box"]])
  664.             write(string.rep(" ", 32))
  665.             term.setCursorPos(19, 5)
  666.             write("  Could Not Connect to GitHub!  ")
  667.             term.setCursorPos(19, 6)
  668.             write(string.rep(" ", 32))
  669.             term.setBackgroundColor(colors[theme["bottom-box"]])
  670.             term.setCursorPos(19, 8)
  671.             write(string.rep(" ", 32))
  672.             term.setCursorPos(19, 9)
  673.             write("    Sorry, Firewolf could not   ")
  674.             term.setCursorPos(19, 10)
  675.             write(" connect to GitHub to download  ")
  676.             term.setCursorPos(19, 11)
  677.             write(" necessary files. Please check: ")
  678.             term.setCursorPos(19, 12)
  679.             write("    http://status.github.com    ")
  680.             term.setCursorPos(19, 13)
  681.             write(string.rep(" ", 32))
  682.             term.setCursorPos(19, 14)
  683.             write("        Click to exit...        ")
  684.             term.setCursorPos(19, 15)
  685.             write(string.rep(" ", 32))
  686.             os.pullEvent("mouse_click")
  687.             return false
  688.         else
  689.             term.clear()
  690.             term.setCursorPos(1, 1)
  691.             term.setBackgroundColor(colors.black)
  692.             term.setTextColor(colors.white)
  693.             print("\n")
  694.             centerPrint("Could not connect to GitHub!")
  695.             print("")
  696.             centerPrint("Sorry, Firefox could not connect to")
  697.             centerPrint("GitHub to download necessary files.")
  698.             centerPrint("Please check:")
  699.             centerPrint("http://status.github.com")
  700.             print("")
  701.             centerPrint("Press any key to exit...")
  702.             os.pullEvent("key")
  703.             return false
  704.         end
  705.     end
  706.  
  707.     return true
  708. end
  709.  
  710. local function migrateFilesystem()
  711.     if fs.exists("/.Firefox_Data") then
  712.         fs.move("/.Firefox_Data", rootFolder)
  713.         fs.delete(serverSoftwareLocation)
  714.     end
  715. end
  716.  
  717. local function resetFilesystem()
  718.     -- Folders
  719.     if not(fs.exists(rootFolder)) then fs.makeDir(rootFolder)
  720.     elseif not(fs.isDir(rootFolder)) then fs.move(rootFolder, "/old-firewolf-data-file") end
  721.     if not(fs.exists(serverFolder)) then fs.makeDir(serverFolder) end
  722.     if not(fs.exists(cacheFolder)) then fs.makeDir(cacheFolder) end
  723.  
  724.     -- Settings
  725.     if not(fs.exists(settingsLocation)) then
  726.         local f = io.open(settingsLocation, "w")
  727.         f:write(textutils.serialize({auto = "true", incog = "false", home = "firewolf"}))
  728.         f:close()
  729.     end
  730.  
  731.     -- History
  732.     if not(fs.exists(historyLocation)) then
  733.         local f = io.open(historyLocation, "w")
  734.         f:write(textutils.serialize({}))
  735.         f:close()
  736.     end
  737.  
  738.     -- Server Software
  739.     if not(fs.exists(serverSoftwareLocation)) then
  740.         download(serverURL, serverSoftwareLocation)
  741.     end
  742.  
  743.     -- Themes
  744.     if isAdvanced() then
  745.         if autoupdate == "true" then
  746.             fs.delete(availableThemesLocation)
  747.             fs.delete(defaultThemeLocation)
  748.         end if not(fs.exists(availableThemesLocation)) then
  749.             download(availableThemesURL, availableThemesLocation)
  750.         end if not(fs.exists(defaultThemeLocation)) then
  751.             local f = io.open(availableThemesLocation, "r")
  752.             local a = f:read("*l")
  753.             f:close()
  754.             a = a:sub(1, a:find("| |") - 1)
  755.             download(a, defaultThemeLocation)
  756.         end if not(fs.exists(themeLocation)) then
  757.             fs.copy(defaultThemeLocation, themeLocation)
  758.         end
  759.     end
  760.  
  761.     -- Databases
  762.     fs.delete(globalDatabase)
  763.     for _, v in pairs({globalDatabase, userWhitelist, userBlacklist}) do
  764.         if not(fs.exists(v)) then
  765.             local f = io.open(v, "w")
  766.             f:write("")
  767.             f:close()
  768.         end
  769.     end
  770.  
  771.     -- Temp file
  772.     fs.delete(rootFolder .. "/temp_file")
  773.  
  774.     return nil
  775. end
  776.  
  777. local function updateClient()
  778.     local updateLocation = rootFolder .. "/update"
  779.     fs.delete(updateLocation)
  780.  
  781.     -- Update
  782.     download(firewolfURL, updateLocation)
  783.     local a = io.open(updateLocation, "r")
  784.     local b = io.open(firewolfLocation, "r")
  785.     local new = a:read("*a")
  786.     local cur = b:read("*a")
  787.     a:close()
  788.     b:close()
  789.  
  790.     if cur ~= new then
  791.         fs.delete(firewolfLocation)
  792.         fs.move(updateLocation, firewolfLocation)
  793.         shell.run(firewolfLocation)
  794.         return true
  795.     else
  796.         fs.delete(updateLocation)
  797.         return false
  798.     end
  799. end
  800.  
  801. local function appendToHistory(site)
  802.     if incognito == "false" then
  803.         if site == "home" or site == "homepage" then
  804.             site = homepage
  805.         end if site ~= "exit" and site ~= "" and site ~= "history" and site ~= history[1] then
  806.             table.insert(history, 1, site)
  807.             local f = io.open(historyLocation, "w")
  808.             f:write(textutils.serialize(history))
  809.             f:close()
  810.         end if site ~= addressBarHistory[#addressBarHistory] then
  811.             table.insert(addressBarHistory, site)
  812.         end
  813.     end
  814. end
  815.  
  816.  
  817. --  -------- Databases
  818.  
  819. local function loadDatabases()
  820.     -- Get
  821.     fs.delete(globalDatabase)
  822.     debugLog(download(databaseURL, globalDatabase))
  823.     local f = io.open(globalDatabase, "r")
  824.     local l = f:read("*l"):gsub("^%s*(.-)%s*$", "%1")
  825.  
  826.     -- Blacklist  ([id])
  827.     blacklist = {}
  828.     while l ~= "START-WHITELIST" do
  829.         l = f:read("*l"):gsub("^%s*(.-)%s*$", "%1")
  830.         if l ~= "" and l ~= "\n" and l ~= nil and l ~= "START-BLACKLIST" then
  831.             table.insert(blacklist, l)
  832.         end
  833.     end
  834.  
  835.     -- Whitelist ([site name]| |[id])
  836.     whitelist = {}
  837.     while l ~= "START-DOWNLOADS" do
  838.         l = f:read("*l"):gsub("^%s*(.-)%s*$", "%1")
  839.         if l ~= "" and l ~= "\n" and l ~= nil and l ~= "START-DOWNLOADS" then
  840.             local a, b = l:find("| |")
  841.             table.insert(whitelist, {l:sub(1, a - 1), l:sub(b + 1, -1)})
  842.         end
  843.     end
  844.  
  845.     -- Downloads ([url])
  846.     downloads = {}
  847.     while l ~= "START-DEFINITIONS" do
  848.         l = f:read("*l"):gsub("^%s*(.-)%s*$", "%1")
  849.         if l ~= "" and l ~= "\n" and l ~= nil and l ~= "START-DEFINITIONS" then
  850.             table.insert(downloads, l)
  851.         end
  852.     end
  853.  
  854.     -- Definitions ([definition]| |[offence name])
  855.     definitions = {}
  856.     while l ~= "END-DATABASE" do
  857.         l = f:read("*l"):gsub("^%s*(.-)%s*$", "%1")
  858.         if l ~= "" and l ~= "\n" and l ~= nil and l ~= "END-DATABASE" then
  859.             local a, b = l:find("| |")
  860.             --debugLog("add object!")
  861.             table.insert(definitions, {l:sub(1, a - 1), l:sub(b + 1, -1)})
  862.         end
  863.     end
  864.     f:close()
  865.  
  866.     -- User Blacklist
  867.     if not(fs.exists(userBlacklist)) then
  868.         local bf = fio.open(userBlacklist, "w")
  869.         bf:write("\n")
  870.         bf:close()
  871.     else
  872.         local bf = io.open(userBlacklist, "r")
  873.         local l = bf:read("*l")
  874.         while l ~= nil do
  875.             if l ~= nil and l ~= "" and l ~= "\n" then
  876.                 l = l:gsub("^%s*(.-)%s*$", "%1")
  877.                 table.insert(blacklist, l)
  878.             end
  879.             l = bf:read("*l")
  880.         end
  881.         bf:close()
  882.     end
  883.  
  884.     -- User Whitelist
  885.     if not(fs.exists(userWhitelist)) then
  886.         local wf = io.open(userWhitelist, "w")
  887.         wf:write("\n")
  888.         wf:close()
  889.     else
  890.         local wf = io.open(userWhitelist, "r")
  891.         local l = wf:read("*l")
  892.         while l ~= nil do
  893.             if l ~= nil and l ~= "" and l ~= "\n" then
  894.                 l = l:gsub("^%s*(.-)%s*$", "%1")
  895.                 local a, b = l:find("| |")
  896.                 table.insert(whitelist, {l:sub(1, a - 1), l:sub(b + 1, -1)})
  897.             end
  898.             l = wf:read("*l")
  899.         end
  900.         wf:close()
  901.     end
  902. end
  903.  
  904. local function verify(database, ...)
  905.     local args = {...}
  906.     if database == "blacklist" and #args >= 1 then
  907.         -- id
  908.         local found = false
  909.         for _, v in pairs(blacklist) do
  910.             if tostring(args[1]) == v then found = true end
  911.         end
  912.  
  913.         return found
  914.     elseif database == "whitelist" and #args >= 2 then
  915.         -- id, site
  916.         local found = false
  917.         for _, v in pairs(whitelist) do
  918.             if v[2] == tostring(args[1]) and v[1] == tostring(args[2]) then
  919.                 found = true
  920.             end
  921.         end
  922.  
  923.         return found
  924.     elseif database == "antivirus" and #args >= 1 then
  925.         -- content
  926.         local a = verify("antivirus offences", args[1])
  927.         if #a == 0 then return false
  928.         else return true end
  929.     elseif database == "antivirus offences" and #args >= 1 then
  930.         -- content
  931.         local c = args[1]:gsub(" ", ""):gsub("\n", ""):gsub("\t", "")
  932.         local a = {}
  933.         debugLog("start def")
  934.         for _, v in pairs(definitions) do
  935.             debugLog(definitions)
  936.             local b = false
  937.             for _, c in pairs(a) do
  938.                 if c == v[2] then b = true end
  939.             end
  940.  
  941.             if c:find(v[1], 1, true) and not(b) then
  942.                 table.insert(a, v[2])
  943.             end
  944.         end
  945.         table.sort(a)
  946.  
  947.         return a
  948.     else
  949.         return nil
  950.     end
  951. end
  952.  
  953.  
  954. --  -------- Protocols
  955.  
  956. protocols.http = {}
  957. protocols.rdnt = {}
  958.  
  959. protocols.rdnt.getSearchResults = function()
  960.     local resultIDs = {}
  961.     dnsDatabase = {[1] = {}, [2] = {}}
  962.  
  963.     rednet.broadcast("firewolf.broadcast.dns.list")
  964.     local startClock = os.clock()
  965.     while os.clock() - startClock < timeout do
  966.         local id, i = rednet.receive(timeout)
  967.         if id then
  968.             if i:sub(1, 14) == "firewolf-site:" then
  969.                 i = i:sub(15, -1)
  970.                 local bl, wl = verify("blacklist", id), verify("whitelist", id, i)
  971.                 if not(i:find(" ")) and i:len() < 40 and (not(bl) or (bl and wl)) then
  972.                     if not(resultIDs[tostring(id)]) then resultIDs[tostring(id)] = 1
  973.                     else resultIDs[tostring(id)] = resultIDs[tostring(id)] + 1
  974.                     end
  975.  
  976.                     local x = false
  977.                     for m,n in pairs(dnsDatabase[1]) do
  978.                         if n:lower() == i:lower() then x = true end
  979.                     end
  980.  
  981.                     if not(x) and resultIDs[tostring(id)] <= 3 then
  982.                         if not(i:find("rdnt://")) then i = ("rdnt://" .. i) end
  983.                         table.insert(dnsDatabase[1], i)
  984.                         table.insert(dnsDatabase[2], id)
  985.                     end
  986.                 end
  987.             end
  988.         else
  989.             break
  990.         end
  991.     end
  992.  
  993.     return dnsDatabase[1]
  994. end
  995.  
  996. protocols.rdnt.getWebsite = function(site)
  997.     local id, content, status = nil, nil, nil
  998.     local clock = os.clock()
  999.     local websiteID = nil
  1000.     for k, v in pairs(dnsDatabase[1]) do
  1001.         local web = site:gsub("rdnt://", "")
  1002.         if web:find("/") then
  1003.             web = web:sub(1, web:find("/") - 1)
  1004.         end
  1005.         if web == v:gsub("rdnt://", "") then
  1006.             websiteID = dnsDatabase[2][k]
  1007.             break
  1008.         end
  1009.         return nil, nil, nil
  1010.     end
  1011.     sleep(timeout)
  1012.     debugLog("Connect", site, websiteID)
  1013.     rednet.send(websiteID, site)
  1014.     clock = os.clock()
  1015.     while os.clock() - clock < timeout do
  1016.         id, content = rednet.receive(timeout)
  1017.         debugLog("received",id)
  1018.         if id then
  1019.             if id == websiteID then
  1020.                 local bl = verify("blacklist", id)
  1021.                 local av = verify("antivirus", content)
  1022.                 local wl = verify("whitelist", id, site)
  1023.                 status = nil
  1024.                 if (bl and not(wl)) or site == "" or site == "." or site == ".." then
  1025.                     -- Ignore
  1026.                 elseif av and not(wl) then
  1027.                     status = "antivirus"
  1028.                     break
  1029.                 else
  1030.                     status = "safe"
  1031.                     break
  1032.                 end
  1033.             end
  1034.         end
  1035.     end
  1036.  
  1037.     serverWebsiteID = id
  1038.     return id, content, status
  1039. end
  1040.  
  1041. protocols.http.getSearchResults = function(input)
  1042.     return {}
  1043. end
  1044.  
  1045. protocols.http.getWebsite = function(site)
  1046.     return nil
  1047. end
  1048.  
  1049.  
  1050. --  -------- Built-In Websites
  1051.  
  1052. local pages = {}
  1053. local errPages = {}
  1054.  
  1055. pages.firewolf = function(site)
  1056.     internalWebsite = true
  1057.     clearPage(site, colors[theme["background"]])
  1058.     print("")
  1059.     term.setTextColor(colors[theme["text-color"]])
  1060.     term.setBackgroundColor(colors[theme["top-box"]])
  1061.     centerPrint(string.rep(" ", 43))
  1062.     centerPrint([[         _,-='"-.__               /\_/\    ]])
  1063.     centerPrint([[          -.}        =._,.-==-._.,  @ @._, ]])
  1064.     centerPrint([[             -.__  __,-.   )       _,.-'   ]])
  1065.     centerPrint([[ Firewolf ]] .. version .. string.rep(" ", 8 - version:len()) ..
  1066.         [["     G..m-"^m m'        ]])
  1067.     centerPrint(string.rep(" ", 43))
  1068.     print("\n")
  1069.  
  1070.     term.setBackgroundColor(colors[theme["bottom-box"]])
  1071.     centerPrint(string.rep(" ", 43))
  1072.     centerPrint("  News:                       [- Sites -]  ")
  1073.     centerPrint("  - Version 2.3.8 has just been released!  ")
  1074.     centerPrint("    Check it out on the forums! It has     ")
  1075.     centerPrint("    a massive overhaul of all the systems  ")
  1076.     centerPrint("  - Version 2.3.7 has been released! It    ")
  1077.     centerPrint("    includes a new mini menu and help!     ")
  1078.     centerPrint(string.rep(" ", 43))
  1079.  
  1080.     while true do
  1081.         local e, but, x, y = os.pullEvent()
  1082.         if e == "mouse_click" and x >= 35 and x <= 45 and y == 12 then
  1083.             redirect("sites")
  1084.             return
  1085.         elseif e == event_exitWebsite then
  1086.             os.queueEvent(event_exitWebsite)
  1087.             return
  1088.         end
  1089.     end
  1090. end
  1091.  
  1092. pages.firefox = function(site)
  1093.     redirect("firewolf")
  1094. end
  1095.  
  1096. pages.sites = function(site)
  1097.     clearPage(site, colors[theme["background"]])
  1098.     term.setTextColor(colors[theme["text-color"]])
  1099.     term.setBackgroundColor(colors[theme["top-box"]])
  1100.     print("")
  1101.     centerPrint(string.rep(" ", 43))
  1102.     centerWrite(string.rep(" ", 43))
  1103.     centerPrint("Firewolf Built-In Sites")
  1104.     centerPrint(string.rep(" ", 43))
  1105.     print("")
  1106.  
  1107.     local sx = 8
  1108.     term.setBackgroundColor(colors[theme["bottom-box"]])
  1109.     term.setCursorPos(1, sx - 1)
  1110.     centerPrint(string.rep(" ", 43))
  1111.     centerPrint("  rdnt://firewolf                Homepage  ")
  1112.     centerPrint("  rdnt://history                  History  ")
  1113.     centerPrint("  rdnt://downloads       Downloads Center  ")
  1114.     centerPrint("  rdnt://server         Server Management  ")
  1115.     centerPrint("  rdnt://help                   Help Page  ")
  1116.     centerPrint("  rdnt://settings                Settings  ")
  1117.     centerPrint("  rdnt://sites             Built-In Sites  ")
  1118.     centerPrint("  rdnt://credits                  Credits  ")
  1119.     centerPrint("  rdnt://exit                        Exit  ")
  1120.     centerPrint(string.rep(" ", 43))
  1121.  
  1122.     local a = {"firewolf", "history", "downloads", "server", "help", "settings", "sites",
  1123.         "credits", "exit"}
  1124.     while true do
  1125.         local e, but, x, y = os.pullEvent()
  1126.         if e == "mouse_click" and x >= 7 and x <= 45 then
  1127.             for i, v in ipairs(a) do
  1128.                 if y == sx + i - 1 then
  1129.                     redirect(v)
  1130.                     return
  1131.                 end
  1132.             end
  1133.         elseif e == event_exitWebsite then
  1134.             os.queueEvent(event_exitWebsite)
  1135.             return
  1136.         end
  1137.     end
  1138. end
  1139.  
  1140. pages.history = function(site)
  1141.     clearPage(site, colors[theme["background"]])
  1142.     term.setTextColor(colors[theme["text-color"]])
  1143.     term.setBackgroundColor(colors[theme["top-box"]])
  1144.     print("")
  1145.     centerPrint(string.rep(" ", 47))
  1146.     centerWrite(string.rep(" ", 47))
  1147.     centerPrint("Firewolf History")
  1148.     centerPrint(string.rep(" ", 47))
  1149.     print("")
  1150.     term.setBackgroundColor(colors[theme["bottom-box"]])
  1151.  
  1152.     if #history > 0 then
  1153.         for i = 1, 12 do centerPrint(string.rep(" ", 47)) end
  1154.  
  1155.         local a = {"Clear History"}
  1156.         for i, v in ipairs(history) do table.insert(a, "rdnt://" .. v) end
  1157.         local opt = scrollingPrompt(a, 6, 8, 10, 40)
  1158.         if opt == "Clear History" then
  1159.             history = {}
  1160.             addressBarHistory = {}
  1161.             local f = io.open(historyLocation, "w")
  1162.             f:write(textutils.serialize(history))
  1163.             f:close()
  1164.  
  1165.             clearPage(site, colors[theme["background"]])
  1166.             term.setTextColor(colors[theme["text-color"]])
  1167.             term.setBackgroundColor(colors[theme["top-box"]])
  1168.             print("")
  1169.             centerPrint(string.rep(" ", 47))
  1170.             centerWrite(string.rep(" ", 47))
  1171.             centerPrint("Firewolf History")
  1172.             centerPrint(string.rep(" ", 47))
  1173.             print("\n")
  1174.             term.setBackgroundColor(colors[theme["bottom-box"]])
  1175.             centerPrint(string.rep(" ", 47))
  1176.             centerWrite(string.rep(" ", 47))
  1177.             centerPrint("Cleared history.")
  1178.             centerPrint(string.rep(" ", 47))
  1179.             openAddressBar = false
  1180.             sleep(1.3)
  1181.  
  1182.             openAddressBar = true
  1183.             redirect("history")
  1184.             return
  1185.         elseif opt then
  1186.             redirect(opt:gsub("rdnt://", ""))
  1187.             return
  1188.         elseif opt == nil then
  1189.             os.queueEvent(event_exitWebsite)
  1190.             return
  1191.         end
  1192.     else
  1193.         print("")
  1194.         centerPrint(string.rep(" ", 47))
  1195.         centerWrite(string.rep(" ", 47))
  1196.         centerPrint("No Items in History!")
  1197.         centerPrint(string.rep(" ", 47))
  1198.     end
  1199. end
  1200.  
  1201. pages.downloads = function(site)
  1202.     clearPage(site, colors[theme["background"]])
  1203.     term.setTextColor(colors[theme["text-color"]])
  1204.     term.setBackgroundColor(colors[theme["top-box"]])
  1205.     print("")
  1206.     centerPrint(string.rep(" ", 47))
  1207.     centerWrite(string.rep(" ", 47))
  1208.     centerPrint("Download Center")
  1209.     centerPrint(string.rep(" ", 47))
  1210.     print("")
  1211.  
  1212.     term.setBackgroundColor(colors[theme["bottom-box"]])
  1213.     for i = 1, 5 do
  1214.         centerPrint(string.rep(" ", 47))
  1215.     end
  1216.     local opt = prompt({{"Themes", 7, 8}, {"Plugins", 7, 10}}, "vertical")
  1217.     if opt == "Themes" and isAdvanced() then
  1218.         while true do
  1219.             local themes = {}
  1220.             local c = {"Make my Own", "Load my Own"}
  1221.             local f = io.open(availableThemesLocation, "r")
  1222.             local l = f:read("*l")
  1223.             while l ~= nil do
  1224.                 l = l:gsub("^%s*(.-)%s*$", "%1")
  1225.                 local a, b = l:find("| |")
  1226.                 table.insert(themes, {l:sub(1, a - 1), l:sub(b + 1, -1)})
  1227.                 table.insert(c, l:sub(b + 1, -1))
  1228.                 l = f:read("*l")
  1229.             end
  1230.             f:close()
  1231.             clearPage(site, colors[theme["background"]])
  1232.             term.setTextColor(colors[theme["text-color"]])
  1233.             term.setBackgroundColor(colors[theme["top-box"]])
  1234.             print("")
  1235.             centerPrint(string.rep(" ", 47))
  1236.             centerWrite(string.rep(" ", 47))
  1237.             centerPrint("Download Center - Themes")
  1238.             centerPrint(string.rep(" ", 47))
  1239.             print("")
  1240.             term.setBackgroundColor(colors[theme["bottom-box"]])
  1241.             for i = 1, 12 do centerPrint(string.rep(" ", 47)) end
  1242.             local t = scrollingPrompt(c, 4, 8, 10, 44)
  1243.             if t == nil then
  1244.                 os.queueEvent(event_exitWebsite)
  1245.                 return
  1246.             elseif t == "Make my Own" then
  1247.                 term.setCursorPos(6, 18)
  1248.                 write("Path: /")
  1249.                 local n = modRead(nil, nil, 35)
  1250.                 if n ~= "" and n ~= nil then
  1251.                     n = "/" .. n
  1252.                     local f = io.open(n, "w")
  1253.                     f:write(ownThemeFileContent)
  1254.                     f:close()
  1255.  
  1256.                     term.setCursorPos(1, 18)
  1257.                     centerWrite(string.rep(" ", 47))
  1258.                     term.setCursorPos(6, 18)
  1259.                     write("File Created!")
  1260.                     openAddressBar = false
  1261.                     sleep(1.1)
  1262.                     openAddressBar = true
  1263.                 elseif n == nil then
  1264.                     os.queueEvent(event_exitWebsite)
  1265.                     return
  1266.                 end
  1267.             elseif t == "Load my Own" then
  1268.                 term.setCursorPos(6, 18)
  1269.                 write("Path: /")
  1270.                 local n = modRead(nil, nil, 35)
  1271.                 if n ~= "" and n ~= nil then
  1272.                     n = "/" .. n
  1273.                     term.setCursorPos(1, 18)
  1274.                     centerWrite(string.rep(" ", 47))
  1275.                    
  1276.                     if fs.exists(n) and not(fs.isDir(n)) then
  1277.                         theme = loadTheme(n)
  1278.                         if theme ~= nil then
  1279.                             fs.delete(themeLocation)
  1280.                             fs.copy(n, themeLocation)
  1281.                             term.setCursorPos(6, 18)
  1282.                             write("Theme File Loaded! :D")
  1283.                         else
  1284.                             term.setCursorPos(6, 18)
  1285.                             write("Theme File is Corrupt! D:")
  1286.                             theme = loadTheme(themeLocation)
  1287.                         end
  1288.                         openAddressBar = false
  1289.                         sleep(1.1)
  1290.                         openAddressBar = true
  1291.                     elseif not(fs.exists(n)) then
  1292.                         term.setCursorPos(6, 18)
  1293.                         write("File does not exist!")
  1294.                         openAddressBar = false
  1295.                         sleep(1.1)
  1296.                         openAddressBar = true
  1297.                     elseif fs.isDir(n) then
  1298.                         term.setCursorPos(6, 18)
  1299.                         write("File is a directory!")
  1300.                         openAddressBar = false
  1301.                         sleep(1.1)
  1302.                         openAddressBar = true
  1303.                     end
  1304.                 elseif n == nil then
  1305.                     os.queueEvent(event_exitWebsite)
  1306.                     return
  1307.                 end
  1308.             else
  1309.                 local url = ""
  1310.                 for _, v in pairs(themes) do if v[2] == t then url = v[1] break end end
  1311.                 term.setCursorPos(1, 4)
  1312.                 term.setBackgroundColor(colors[theme["top-box"]])
  1313.                 centerWrite(string.rep(" ", 47))
  1314.                 centerWrite("Download Center - Downloading...")
  1315.                 fs.delete(rootFolder .. "/temp_theme")
  1316.                 download(url, rootFolder .. "/temp_theme")
  1317.                 theme = loadTheme(rootFolder .. "/temp_theme")
  1318.                 if theme == nil then
  1319.                     theme = loadTheme(themeLocation)
  1320.                     fs.delete(rootFolder .. "/temp_theme")
  1321.                     centerWrite(string.rep(" ", 47))
  1322.                     centerWrite("Download Center - Theme Is Corrupt! D:")
  1323.                     openAddressBar = false
  1324.                     sleep(1.1)
  1325.                     openAddressBar = true
  1326.                 else
  1327.                     fs.delete(themeLocation)
  1328.                     fs.copy(rootFolder .. "/temp_theme", themeLocation)
  1329.                     fs.delete(rootFolder .. "/temp_theme")
  1330.                     centerWrite(string.rep(" ", 47))
  1331.                     centerWrite("Download Center - Done! :D")
  1332.                     openAddressBar = false
  1333.                     sleep(1.1)
  1334.                     openAddressBar = true
  1335.                     redirect("home")
  1336.                     return
  1337.                 end
  1338.             end
  1339.         end
  1340.     elseif opt == "Themes" and not(isAdvanced()) then
  1341.         clearPage(site, colors[theme["background"]])
  1342.         term.setTextColor(colors[theme["text-color"]])
  1343.         term.setBackgroundColor(colors[theme["top-box"]])
  1344.         print("")
  1345.         centerPrint(string.rep(" ", 47))
  1346.         centerWrite(string.rep(" ", 47))
  1347.         centerPrint("Download Center")
  1348.         centerPrint(string.rep(" ", 47))
  1349.         print("\n")
  1350.  
  1351.         term.setBackgroundColor(colors[theme["bottom-box"]])
  1352.         centerPrint(string.rep(" ", 47))
  1353.         centerWrite(string.rep(" ", 47))
  1354.         centerPrint("Themes are not available on normal")
  1355.         centerWrite(string.rep(" ", 47))
  1356.         centerPrint("computers! :(")
  1357.         centerPrint(string.rep(" ", 47))
  1358.     elseif opt == "Plugins" then
  1359.         clearPage(site, colors[theme["background"]])
  1360.         term.setTextColor(colors[theme["text-color"]])
  1361.         term.setBackgroundColor(colors[theme["top-box"]])
  1362.         print("")
  1363.         centerPrint(string.rep(" ", 47))
  1364.         centerWrite(string.rep(" ", 47))
  1365.         centerPrint("Download Center - Plugins")
  1366.         centerPrint(string.rep(" ", 47))
  1367.         print("\n")
  1368.  
  1369.         term.setBackgroundColor(colors[theme["bottom-box"]])
  1370.         centerPrint(string.rep(" ", 47))
  1371.         centerWrite(string.rep(" ", 47))
  1372.         centerPrint("Comming Soon! (hopefully :P)")
  1373.         centerPrint(string.rep(" ", 47))
  1374.         centerPrint(string.rep(" ", 47))
  1375.         centerPrint(string.rep(" ", 47))
  1376.  
  1377.         local opt = prompt({{"Back", -1, 11}}, "vertical")
  1378.         if opt == nil then
  1379.             os.queueEvent(event_exitWebsite)
  1380.             return
  1381.         elseif opt == "Back" then
  1382.             redirect("downloads")
  1383.         end
  1384.     elseif opt == nil then
  1385.         os.queueEvent(event_exitWebsite)
  1386.         return
  1387.     end
  1388. end
  1389.  
  1390. pages.server = function(site)
  1391.     local function editPages(server)
  1392.         openAddressBar = false
  1393.         local oldLoc = shell.dir()
  1394.         local commandHis = {}
  1395.         local dir = serverFolder .. "/" .. server
  1396.         term.setBackgroundColor(colors.black)
  1397.         term.setTextColor(colors.white)
  1398.         term.clear()
  1399.         term.setCursorPos(1, 1)
  1400.         print("")
  1401.         print(" Server Shell Editing")
  1402.         print(" Type 'exit' to return to Firewolf.")
  1403.         print(" Note: The 'home' file is the index of your site.")
  1404.         print("")
  1405.  
  1406.         local allowed = {"cd", "move", "mv", "cp", "copy", "drive", "delete", "rm", "edit",
  1407.         "eject", "exit", "help", "id", "mkdir", "monitor", "rename", "alias", "clear",
  1408.         "paint", "firewolf", "lua", "redstone", "rs", "redprobe", "redpulse", "programs",
  1409.         "redset", "reboot", "hello", "label", "list", "ls", "easter", "pastebin", "dir"}
  1410.        
  1411.         while true do
  1412.             shell.setDir(serverFolder .. "/" .. server)
  1413.             term.setBackgroundColor(colors.black)
  1414.             if isAdvanced() then term.setTextColor(colors.yellow)
  1415.             else term.setTextColor(colors.white) end
  1416.             write("> ")
  1417.             term.setTextColor(colors.white)
  1418.             local line = read(nil, commandHis)
  1419.             table.insert(commandHis, line)
  1420.  
  1421.             local words = {}
  1422.             for m in string.gmatch(line, "[^ \t]+") do
  1423.                 local a = m:gsub("^%s*(.-)%s*$", "%1")
  1424.                 table.insert(words, a)
  1425.             end
  1426.  
  1427.             local com = words[1]
  1428.             if com == "exit" then
  1429.                 break
  1430.             elseif com then
  1431.                 local a = false
  1432.                 for _, v in pairs(allowed) do
  1433.                     if com == v then a = true break end
  1434.                 end
  1435.  
  1436.                 if a then
  1437.                     term.setBackgroundColor(colors.black)
  1438.                     term.setTextColor(colors.white)
  1439.                     shell.run(com, unpack(words, 2))
  1440.                 else
  1441.                     term.setTextColor(colors.red)
  1442.                     print("Program Not Allowed!")
  1443.                 end
  1444.             end
  1445.         end
  1446.         shell.setDir(oldLoc)
  1447.         openAddressBar = true
  1448.     end
  1449.  
  1450.     local function newServer()
  1451.         term.setBackgroundColor(colors[theme["background"]])
  1452.         for i = 1, 12 do
  1453.             term.setCursorPos(3, i + 6)
  1454.             write(string.rep(" ", 47))
  1455.         end
  1456.  
  1457.         term.setBackgroundColor(colors[theme["bottom-box"]])
  1458.         term.setCursorPos(1, 8)
  1459.         for i = 1, 8 do centerPrint(string.rep(" ", 47)) end
  1460.         term.setCursorPos(5, 9)
  1461.         write("Name: ")
  1462.         local name = modRead(nil, nil, 28, true)
  1463.         if name == nil then
  1464.             os.queueEvent(event_exitWebsite)
  1465.             return
  1466.         end
  1467.         term.setCursorPos(5, 11)
  1468.         write("URL:")
  1469.         term.setCursorPos(8, 12)
  1470.         write("rdnt://")
  1471.         local url = modRead(nil, nil, 33)
  1472.         if url == nil then
  1473.             os.queueEvent(event_exitWebsite)
  1474.             return
  1475.         end
  1476.         url = url:gsub(" ", "")
  1477.  
  1478.         local a = {"/", "| |", " ", "@", "!", "$", "#", "%", "^", "&", "*", "(", ")", "rdnt://",
  1479.             "[", "]", "{", "}", "\\", "\"", "'", ":", ";", "?", "<", ">", ",", "`", "-"}
  1480.         local b = false
  1481.         for k, v in pairs(a) do
  1482.             if url:find(v, 1, true) then
  1483.                 term.setCursorPos(5, 13)
  1484.                 write("URL Contains Illegal '" .. v .. "'!")
  1485.                 openAddressBar = false
  1486.                 sleep(1.1)
  1487.                 openAddressBar = true
  1488.                 b = true
  1489.                 break
  1490.             elseif name == "" or url == "" then
  1491.                 term.setCursorPos(5, 13)
  1492.                 write("URL or Name Is Empty!")
  1493.                 openAddressBar = false
  1494.                 sleep(1.1)
  1495.                 openAddressBar = true
  1496.                 b = true
  1497.                 break
  1498.             elseif fs.exists(serverFolder .. "/" .. url) then
  1499.                 term.setCursorPos(5, 13)
  1500.                 write("Server Already Exists!")
  1501.                 openAddressBar = false
  1502.                 sleep(1.1)
  1503.                 openAddressBar = true
  1504.                 b = true
  1505.                 break
  1506.             end
  1507.         end
  1508.  
  1509.         if not(b) then
  1510.             fs.makeDir(serverFolder .. "/" .. url)
  1511.             local f = io.open(serverFolder .. "/" .. url .. "/home", "w")
  1512.             f:write("print(\"\")\ncenterPrint(\"Welcome To " .. name .. "!\")\n")
  1513.             f:close()
  1514.  
  1515.             term.setCursorPos(5, 13)
  1516.             write("Successfully Created Server! :D")
  1517.         end
  1518.     end
  1519.  
  1520.     clearPage(site, colors[theme["background"]])
  1521.     term.setTextColor(colors[theme["text-color"]])
  1522.     term.setBackgroundColor(colors[theme["top-box"]])
  1523.     print("")
  1524.     centerPrint(string.rep(" ", 47))
  1525.     centerWrite(string.rep(" ", 47))
  1526.     centerPrint("Firewolf Server Management")
  1527.     centerPrint(string.rep(" ", 47))
  1528.     print("")
  1529.  
  1530.     local servers = {}
  1531.     for _, v in pairs(fs.list(serverFolder)) do
  1532.         if fs.isDir(serverFolder .. "/" .. v) then table.insert(servers, v) end
  1533.     end
  1534.  
  1535.     if isAdvanced() then
  1536.         term.setBackgroundColor(colors[theme["bottom-box"]])
  1537.         for i = 1, 12 do
  1538.             term.setCursorPos(3, i + 6)
  1539.             write(string.rep(" ", 24))
  1540.             term.setCursorPos(29, i + 6)
  1541.             write(string.rep(" ", 21))
  1542.         end
  1543.  
  1544.         local function draw(l, sel)
  1545.             term.setBackgroundColor(colors[theme["bottom-box"]])
  1546.             term.setCursorPos(4, 8)
  1547.             write("[- New Server -]")
  1548.             for i, v in ipairs(l) do
  1549.                 term.setCursorPos(3, i + 8)
  1550.                 write(string.rep(" ", 24))
  1551.                 term.setCursorPos(4, i + 8)
  1552.                 local nv = v
  1553.                 if nv:len() > 18 then nv = nv:sub(1, 15) .. "..." end
  1554.                 if i == sel then
  1555.                     write("[ " .. nv .. " ]")
  1556.                 else
  1557.                     write("  " .. nv)
  1558.                 end
  1559.             end
  1560.             if #l < 1 then
  1561.                 term.setCursorPos(4, 10)
  1562.                 write("A website is literally")
  1563.                 term.setCursorPos(4, 11)
  1564.                 write("just a lua script!")
  1565.                 term.setCursorPos(4, 12)
  1566.                 write("Go ahead and make one!")
  1567.                 term.setCursorPos(4, 14)
  1568.                 write("Also, be sure to check")
  1569.                 term.setCursorPos(4, 15)
  1570.                 write("out Firewolf's APIs to")
  1571.                 term.setCursorPos(4, 16)
  1572.                 write("help you make your")
  1573.                 term.setCursorPos(4, 17)
  1574.                 write("site, at rdnt://help")
  1575.             end
  1576.  
  1577.             term.setCursorPos(30, 8)
  1578.             write(string.rep(" ", 19))
  1579.             term.setCursorPos(30, 8)
  1580.             if l[sel] then
  1581.                 local nl = l[sel]
  1582.                 if nl:len() > 19 then nl = nl:sub(1, 16) .. "..." end
  1583.                 write(nl)
  1584.             else write("No Server Selected!") end
  1585.             term.setCursorPos(30, 10)
  1586.             write("[- Start -]")
  1587.             term.setCursorPos(30, 12)
  1588.             write("[- Edit -]")
  1589.             term.setCursorPos(30, 14)
  1590.             write("[- Run on Boot -]")
  1591.             term.setCursorPos(30, 16)
  1592.             write("[- Delete -]")
  1593.         end
  1594.  
  1595.         local function updateDisplayList(items, loc, len)
  1596.             local ret = {}
  1597.             for i = 1, len do
  1598.                 local item = items[i + loc - 1]
  1599.                 if item ~= nil then table.insert(ret, item) end
  1600.             end
  1601.             return ret
  1602.         end
  1603.  
  1604.         local sel = 1
  1605.         local loc = 1
  1606.         local len = 10
  1607.         local disList = updateDisplayList(servers, loc, len)
  1608.         draw(disList, sel)
  1609.  
  1610.         while true do
  1611.             local e, but, x, y = os.pullEvent()
  1612.             if e == "key" and but == 200 and #servers > 0 and loc > 1 then
  1613.                 -- Up
  1614.                 loc = loc - 1
  1615.                 disList = updateDisplayList(servers, loc, len)
  1616.                 draw(disList, sel)
  1617.             elseif e == "key" and but == 208 and #servers > 0 and loc + len - 1 < #servers then
  1618.                 -- Down
  1619.                 loc = loc + 1
  1620.                 disList = updateDisplayList(servers, loc, len)
  1621.                 draw(disList, sel)
  1622.             elseif e == "mouse_click" then
  1623.                 if x >= 4 and x <= 25 then
  1624.                     if y == 8 then
  1625.                         newServer()
  1626.                         redirect("server")
  1627.                         return
  1628.                     elseif #servers > 0 then
  1629.                         for i, v in ipairs(disList) do
  1630.                             if y == i + 8 then
  1631.                                 sel = i
  1632.                                 draw(disList, sel)
  1633.                             end
  1634.                         end
  1635.                     end
  1636.                 elseif x >= 30 and x <= 40 and y == 10 and #servers > 0 then
  1637.                     -- Start
  1638.                     term.clear()
  1639.                     term.setCursorPos(1, 1)
  1640.                     term.setBackgroundColor(colors.black)
  1641.                     term.setTextColor(colors.white)
  1642.                     openAddressBar = false
  1643.                     setfenv(1, oldEnv)
  1644.                     shell.run(serverSoftwareLocation, disList[sel], serverFolder .. "/" ..
  1645.                         disList[sel])
  1646.                     setfenv(1, env)
  1647.                     openAddressBar = true
  1648.                     errPages.checkForModem()
  1649.  
  1650.                     redirect("server")
  1651.                     return
  1652.                 elseif x >= 30 and x <= 39 and y == 12 and #servers > 0 then
  1653.                     editPages(disList[sel])
  1654.                     openAddressBar = true
  1655.                     redirect("server")
  1656.                     return
  1657.                 elseif x >= 30 and x <= 46 and y == 14 and #servers > 0 then
  1658.                     -- Startup
  1659.                     fs.delete("/old-startup")
  1660.                     if fs.exists("/startup") then fs.move("/startup", "/old-startup") end
  1661.                     local f = io.open("/startup", "w")
  1662.                     f:write("shell.run(\"" .. serverSoftwareLocation .. "\", \"" ..
  1663.                         disList[sel] .. "\", \"" .. serverFolder .. "/" .. disList[sel] .. "\")")
  1664.                     f:close()
  1665.  
  1666.                     term.setBackgroundColor(colors[theme["bottom-box"]])
  1667.                     term.setCursorPos(32, 15)
  1668.                     write("Will Run on Boot!")
  1669.                     openAddressBar = false
  1670.                     sleep(1.1)
  1671.                     openAddressBar = true
  1672.                     term.setCursorPos(32, 15)
  1673.                     write(string.rep(" ", 18))
  1674.                 elseif x >= 30 and x <= 41 and y == 16 and #servers > 0 then
  1675.                     fs.delete(serverFolder .. "/" .. disList[sel])
  1676.                     redirect("server")
  1677.                     return
  1678.                 end
  1679.             elseif e == event_exitWebsite then
  1680.                 os.queueEvent(event_exitWebsite)
  1681.                 return
  1682.             end
  1683.         end
  1684.     else
  1685.         local a = {"New Server"}
  1686.         for _, v in pairs(servers) do table.insert(a, v) end
  1687.         local server = scrollingPrompt(a, 4, 8, 10)
  1688.         if server == nil then
  1689.             os.queueEvent(event_exitWebsite)
  1690.             return
  1691.         elseif server == "New Server" then
  1692.             newServer()
  1693.         else
  1694.             term.setCursorPos(30, 8)
  1695.             write(server)
  1696.             local opt = prompt({{"Start", 30, 10}, {"Edit", 30, 12}, {"Run on Boot", 30, 13},
  1697.                 {"Delete", 30, 14}, {"Back", 30, 16}})
  1698.             if opt == "Start" then
  1699.                 -- Start
  1700.                 term.clear()
  1701.                 term.setCursorPos(1, 1)
  1702.                 term.setBackgroundColor(colors.black)
  1703.                 term.setTextColor(colors.white)
  1704.                 openAddressBar = false
  1705.                 setfenv(1, oldEnv)
  1706.                 shell.run(serverSoftwareLocation, server, serverFolder .. "/" .. server)
  1707.                 setfenv(1, env)
  1708.                 openAddressBar = true
  1709.                 errPages.checkForModem()
  1710.             elseif opt == "Edit" then
  1711.                 editPages(server)
  1712.                 openAddressBar = true
  1713.             elseif opt == "Run on Boot" then
  1714.                 fs.delete("/old-startup")
  1715.                 if fs.exists("/startup") then fs.move("/startup", "/old-startup") end
  1716.                 local f = io.open("/startup", "w")
  1717.                 f:write("shell.run(\"" .. serverSoftwareLocation .. "\", \"" ..
  1718.                     server .. "\", \"" .. serverFolder .. "/" .. server .. "\")")
  1719.                 f:close()
  1720.  
  1721.                 term.setCursorPos(32, 17)
  1722.                 write("Will Run on Boot!")
  1723.                 openAddressBar = false
  1724.                 sleep(1.1)
  1725.                 openAddressBar = true
  1726.             elseif opt == "Delete" then
  1727.                 fs.delete(serverFolder .. "/" .. server)
  1728.             elseif opt == "Back" then
  1729.                 -- Do nothing
  1730.             elseif opt == nil then
  1731.                 os.queueEvent(event_exitWebsite)
  1732.                 return
  1733.             end
  1734.         end
  1735.  
  1736.         redirect("server")
  1737.         return
  1738.     end
  1739. end
  1740.  
  1741. pages.help = function(site)
  1742.     clearPage(site, colors[theme["background"]])
  1743.     term.setTextColor(colors[theme["text-color"]])
  1744.     term.setBackgroundColor(colors[theme["top-box"]])
  1745.     print("\n")
  1746.     centerPrint(string.rep(" ", 47))
  1747.     centerWrite(string.rep(" ", 47))
  1748.     centerPrint("Firewolf Help")
  1749.     centerPrint(string.rep(" ", 47))
  1750.     print("")
  1751.  
  1752.     term.setBackgroundColor(colors[theme["bottom-box"]])
  1753.     for i = 1, 12 do centerPrint(string.rep(" ", 47)) end
  1754.     local opt = prompt({{"Getting Started", 7, 9}, {"Making a Theme", 7, 11},
  1755.         {"API Documentation", 7, 13}}, "vertical")
  1756.     term.setCursorPos(7, 15)
  1757.     write("View the full documentation here:")
  1758.     term.setCursorPos(7, 16)
  1759.     write("https://github.com/1lann/Firewolf/wiki")
  1760.     local pages = {}
  1761.     if opt == "Getting Started" then
  1762.         pages[1] = {title = "Getting Started - Intoduction", content = {
  1763.             "Hey there!",
  1764.             "",
  1765.             "Firewolf is an app that allows you to create",
  1766.             "and visit websites! Each site has name (the",
  1767.             "URL) which you can type into the address bar",
  1768.             "above, and then visit the site.",
  1769.         }} pages[2] = {title = "Getting Started - Searching", content = {
  1770.             "The address bar can be also be used to",
  1771.             "search for sites, by simply typing in the",
  1772.             "search term.",
  1773.             "",
  1774.             "To view all sites, just open it and hit",
  1775.             "enter (leave the field blank)."
  1776.         }} pages[3] = {title = "Getting Started - Built-In Websites", content = {
  1777.             "Firewolf has a set of built-in websites",
  1778.             "available for use:",
  1779.             "",
  1780.             "rdnt://firewolf   Normal hompage",
  1781.             "rdnt://history    Your history",
  1782.             "rdnt://downloads  Download themes and plugins",
  1783.             "rdnt://server     Create websites",
  1784.             "rdnt://help       Help and documentation"
  1785.         }} pages[4] = {title = "Getting Started - Built-In Websites", content = {
  1786.             "More built-in websites:",
  1787.             "",
  1788.             "rdnt://settings   Firewolf settings",
  1789.             "rdnt://update     Force update Firewolf",
  1790.             "rdnt://getinfo    Get website info",
  1791.             "rdnt://credits    View the credits",
  1792.             "rdnt://exit       Exit the app"
  1793.         }}
  1794.     elseif opt == "Making a Theme" then
  1795.         pages[1] = {title = "Making a Theme - Introduction", content = {
  1796.             "Firewolf themes are files that tell Firewolf",
  1797.             "to color things certain colors.",
  1798.             "Several themes can already be downloaded for",
  1799.             "Firewolf from the Download Center.",
  1800.             "",
  1801.             "You can also make your own theme, use it in",
  1802.             "your copy of Firewolf, and submit it to the",
  1803.             "Firewolf Download Center!"
  1804.         }} pages[2] = {title = "Making a Theme - Example", content = {
  1805.             "A theme file consists of several lines of",
  1806.             "text. Here is the default theme file:",
  1807.             "",
  1808.             "address-bar-text=white",
  1809.             "address-bar-background=gray",
  1810.             "top-box=red",
  1811.             "bottom-box=orange",
  1812.             "background=gray",
  1813.             "text-color=white"
  1814.         }} pages[3] = {title = "Making a Theme - Explanation", content = {
  1815.             "On each line of the example, something is",
  1816.             "given a color, like on the last line, the",
  1817.             "text of the page is told to be white.",
  1818.             "",
  1819.             "The color specified after the = is the same",
  1820.             "as when you call colors.[color name].",
  1821.             "For example, specifying red after the =",
  1822.             "colors that object red."
  1823.         }} pages[4] = {title = "Making a Theme - Have a Go", content = {
  1824.             "To make a theme, go to rdnt://downloads,",
  1825.             "click on the themes section, and click on",
  1826.             "'Create my Own'.",
  1827.             "",
  1828.             "Enter a theme name, then exit Firewolf and",
  1829.             "edit the newly create file in the root",
  1830.             "folder. Specify the colors for the keys,",
  1831.             "and return to the themes section of the",
  1832.             "downloads center. Click 'Load my Own'."
  1833.         }} pages[5] = {title = "Making a Theme - Submitting", content = {
  1834.             "To submit a theme to the Downloads Center,",
  1835.             "send GravityScore a message on the CCForums",
  1836.             "that contains your theme file and name.",
  1837.             "",
  1838.             "He will message you back saying whether your",
  1839.             "theme has been added, or if anything needs to",
  1840.             "be changed before it is added."
  1841.         }}
  1842.     elseif opt == "API Documentation" then
  1843.         pages[1] = {title = "API Documentation - 1", content = {
  1844.             "The Firewolf API is a bunch of global",
  1845.             "functions that aim to simplify your life when",
  1846.             "designing and coding websites.",
  1847.             "",
  1848.             "For a full documentation on these functions,",
  1849.             "visit the Firewolf Wiki Page here:",
  1850.             "https://github.com/1lann/Firewolf/wiki"
  1851.         }} pages[2] = {title = "API Documentation - 2", content = {
  1852.             "centerPrint(string text)",
  1853.             "cPrint(string text)",
  1854.             "centerWrite(string text)",
  1855.             "cWrite(string text)",
  1856.             "",
  1857.             "leftPrint(string text)",
  1858.             "lPrint(string text)",
  1859.         }} pages[3] = {title = "API Documentation - 3", content = {
  1860.             "leftWrite(string text)",
  1861.             "lWrite(string text)",
  1862.             "",
  1863.             "rightPrint(string text)",
  1864.             "rPrint(string text)",
  1865.             "rightWrite(string text)",
  1866.             "rWrite(string text)"
  1867.         }} pages[4] = {title = "API Documentation - 4", content = {
  1868.             "prompt(table list, string direction)",
  1869.             "scrollingPrompt(table list, integer x,",
  1870.             "   integer y, integer length[,",
  1871.             "   integer width])",
  1872.             "",
  1873.             "urlDownload(string url)",
  1874.             "pastebinDownload(string code)",
  1875.             "redirect(string site)",
  1876.         }} pages[5] = {title = "API Documentation - 5", content = {
  1877.             "loadImageFromServer(string imagePath)",
  1878.             "ioReadFileFromServer(string filePath)",
  1879.             "",
  1880.             "Full documentation can be found here:",
  1881.             "https://github.com/1lann/Firewolf/wiki"
  1882.         }}
  1883.     elseif opt == nil then
  1884.         os.queueEvent(event_exitWebsite)
  1885.         return
  1886.     end
  1887.  
  1888.     local function drawPage(page)
  1889.         clearPage(site, colors[theme["background"]])
  1890.         term.setTextColor(colors[theme["text-color"]])
  1891.         term.setBackgroundColor(colors[theme["top-box"]])
  1892.         print("")
  1893.         centerPrint(string.rep(" ", 47))
  1894.         centerWrite(string.rep(" ", 47))
  1895.         centerPrint(page.title)
  1896.         centerPrint(string.rep(" ", 47))
  1897.         print("")
  1898.  
  1899.         term.setBackgroundColor(colors[theme["bottom-box"]])
  1900.         for i = 1, 12 do centerPrint(string.rep(" ", 47)) end
  1901.         for i, v in ipairs(page.content) do
  1902.             term.setCursorPos(4, i + 7)
  1903.             write(v)
  1904.         end
  1905.     end
  1906.  
  1907.     local curPage = 1
  1908.     local a = {{"Prev", 26, 18}, {"Next", 38, 18}, {"Back",  14, 18}}
  1909.     drawPage(pages[curPage])
  1910.  
  1911.     while true do
  1912.         local b = {a[3]}
  1913.         if curPage == 1 then table.insert(b, a[2])
  1914.         elseif curPage == #pages then table.insert(b, a[1])
  1915.         else table.insert(b, a[1]) table.insert(b, a[2]) end
  1916.  
  1917.         local opt = prompt(b, "horizontal")
  1918.         if opt == "Prev" then
  1919.             curPage = curPage - 1
  1920.         elseif opt == "Next" then
  1921.             curPage = curPage + 1
  1922.         elseif opt == "Back" then
  1923.             break
  1924.         elseif opt == nil then
  1925.             os.queueEvent(event_exitWebsite)
  1926.             return
  1927.         end
  1928.  
  1929.         drawPage(pages[curPage])
  1930.     end
  1931.  
  1932.     redirect("help")
  1933. end
  1934.  
  1935. pages.settings = function(site)
  1936.     while true do
  1937.         clearPage(site, colors[theme["background"]])
  1938.         print("")
  1939.         term.setTextColor(colors[theme["text-color"]])
  1940.         term.setBackgroundColor(colors[theme["top-box"]])
  1941.         centerPrint(string.rep(" ", 43))
  1942.         centerWrite(string.rep(" ", 43))
  1943.         centerPrint("Firewolf Settings")
  1944.         centerWrite(string.rep(" ", 43))
  1945.         if fs.exists("/.bustedOs") then centerPrint("Designed For: BustedOS")
  1946.         else centerPrint("Designed For: " .. serverList[serverID]) end
  1947.         centerPrint(string.rep(" ", 43))
  1948.         print("")
  1949.  
  1950.         local a = "Automatic Updating - On"
  1951.         if autoupdate == "false" then a = "Automatic Updating - Off" end
  1952.         local b = "Record History - On"
  1953.         if incognito == "true" then b = "Record History - Off" end
  1954.         local c = "Homepage - rdnt://" .. homepage
  1955.  
  1956.         term.setBackgroundColor(colors[theme["bottom-box"]])
  1957.         for i = 1, 11 do centerPrint(string.rep(" ", 43)) end
  1958.         local opt = prompt({{a, 7, 9}, {b, 7, 11}, {c, 7, 13},
  1959.              {"Reset Firewolf", 7, 17}}, "vertical")
  1960.         if opt == a then
  1961.             if autoupdate == "true" then autoupdate = "false"
  1962.             elseif autoupdate == "false" then autoupdate = "true" end
  1963.         elseif opt == b then
  1964.             if incognito == "true" then incognito = "false"
  1965.             elseif incognito == "false" then incognito = "true" end
  1966.         elseif opt == c then
  1967.             term.setCursorPos(9, 15)
  1968.             write("rdnt://")
  1969.             local a = modRead(nil, nil, 30)
  1970.             if a == nil then
  1971.                 os.queueEvent(event_exitWebsite)
  1972.                 return
  1973.             end
  1974.             if a ~= "" then homepage = a end
  1975.         elseif opt == "Reset Firewolf" then
  1976.             clearPage(site, colors[theme["background"]])
  1977.             term.setTextColor(colors[theme["text-color"]])
  1978.             term.setBackgroundColor(colors[theme["top-box"]])
  1979.             print("")
  1980.             centerPrint(string.rep(" ", 43))
  1981.             centerWrite(string.rep(" ", 43))
  1982.             centerPrint("Reset Firewolf")
  1983.             centerPrint(string.rep(" ", 43))
  1984.             print("")
  1985.             term.setBackgroundColor(colors[theme["bottom-box"]])
  1986.             for i = 1, 12 do centerPrint(string.rep(" ", 43)) end
  1987.             local opt = prompt({{"Reset History", 7, 8}, {"Reset Servers", 7, 9},
  1988.                 {"Reset Theme", 7, 10}, {"Reset Cache", 7, 11}, {"Reset Databases", 7, 12},
  1989.                 {"Reset Settings", 7, 13}, {"Back", 7, 14}, {"Reset All", 7, 16}}, "vertical")
  1990.  
  1991.             openAddressBar = false
  1992.             if opt == "Reset All" then
  1993.                 fs.delete(rootFolder)
  1994.             elseif opt == "Reset History" then
  1995.                 fs.delete(historyLocation)
  1996.             elseif opt == "Reset Servers" then
  1997.                 fs.delete(serverFolder)
  1998.                 fs.delete(serverSoftwareLocation)
  1999.             elseif opt == "Reset Cache" then
  2000.                 fs.delete(cacheFolder)
  2001.             elseif opt == "Reset Databases" then
  2002.                 fs.delete(userWhitelist)
  2003.                 fs.delete(userBlacklist)
  2004.                 fs.delete(globalDatabase)
  2005.             elseif opt == "Reset Settings" then
  2006.                 fs.delete(settingsLocation)
  2007.             elseif opt == "Reset Theme" then
  2008.                 fs.delete(themeLocation)
  2009.                 fs.copy(defaultThemeLocation, themeLocation)
  2010.             elseif opt == "Back" then
  2011.                 openAddressBar = true
  2012.                 redirect("settings")
  2013.                 return
  2014.             elseif opt == nil then
  2015.                 openAddressBar = true
  2016.                 os.queueEvent(event_exitWebsite)
  2017.                 return
  2018.             end
  2019.  
  2020.             clearPage(site, colors[theme["background"]])
  2021.             term.setBackgroundColor(colors[theme["top-box"]])
  2022.             print("")
  2023.             centerPrint(string.rep(" ", 43))
  2024.             centerWrite(string.rep(" ", 43))
  2025.             centerPrint("Reset Firewolf")
  2026.             centerPrint(string.rep(" ", 43))
  2027.             print("")
  2028.             term.setCursorPos(1, 10)
  2029.             term.setBackgroundColor(colors[theme["bottom-box"]])
  2030.             centerPrint(string.rep(" ", 43))
  2031.             centerWrite(string.rep(" ", 43))
  2032.             centerPrint("Firewolf has been reset.")
  2033.             centerWrite(string.rep(" ", 43))
  2034.             if isAdvanced() then centerPrint("Click to exit...")
  2035.             else centerPrint("Press any key to exit...") end
  2036.             centerPrint(string.rep(" ", 43))
  2037.             while true do
  2038.                 local e = os.pullEvent()
  2039.                 if e == "mouse_click" or e == "key" then return true end
  2040.             end
  2041.         elseif opt == "Manage Blocked Servers" then
  2042.             openAddressBar = true
  2043.             clearPage(site, colors[theme["background"]])
  2044.             term.setTextColor(colors[theme["text-color"]])
  2045.             term.setBackgroundColor(colors[theme["top-box"]])
  2046.             print("")
  2047.             centerPrint(string.rep(" ", 43))
  2048.             centerWrite(string.rep(" ", 43))
  2049.             centerPrint("Manage Blocked Servers")
  2050.             centerPrint(string.rep(" ", 43))
  2051.             centerWrite(string.rep(" ", 43))
  2052.             centerPrint("Click on ID to remove server")
  2053.             centerPrint(string.rep(" ", 43))
  2054.             print("")
  2055.             for i = 1, 40 do
  2056.                 centerPrint(string.rep(" ", 43))
  2057.             end
  2058.             local rBlacklist = {}
  2059.             local f = io.open(userBlacklist, "r")
  2060.             for line in f:lines() do
  2061.                 if line ~= nil and line ~= "" and line ~= "\n" then
  2062.                 line = line:gsub("^%s*(.-)%s*$", "%1")
  2063.                 table.insert(rBlacklist, line)
  2064.             end
  2065.             end
  2066.             f:close()
  2067.             table.insert(rBlacklist, "Add Button Comming Soon!")
  2068.             while true do
  2069.                 local opt = scrollingPrompt(rBlacklist, 7, 8, 10, 38)
  2070.                 if opt == "Add Button Comming Soon!" then
  2071.                 elseif opt == nil then
  2072.                     return
  2073.                 else
  2074.                     table.remove(rBlacklist, opt)
  2075.                     table.remove(blacklist, opt)
  2076.                     local data = ""
  2077.                     f = io.open(userBlacklist, "w")
  2078.                     for k,v in pairs(rBlacklist) do
  2079.                         data = ("\n" .. v)
  2080.                     end
  2081.                     f:write(data)
  2082.                 end
  2083.             end
  2084.         elseif opt == nil then
  2085.             os.queueEvent(event_exitWebsite)
  2086.             return
  2087.         end
  2088.  
  2089.         -- Save
  2090.         local f = io.open(settingsLocation, "w")
  2091.         f:write(textutils.serialize({auto = autoupdate, incog = incognito, home = homepage}))
  2092.         f:close()
  2093.     end
  2094. end
  2095.  
  2096. pages.update = function(site)
  2097.     clearPage(site, colors[theme["background"]])
  2098.     print("\n")
  2099.     term.setTextColor(colors[theme["text-color"]])
  2100.     term.setBackgroundColor(colors[theme["top-box"]])
  2101.     centerPrint(string.rep(" ", 43))
  2102.     centerWrite(string.rep(" ", 43))
  2103.     centerPrint("Force Update Firewolf")
  2104.     centerPrint(string.rep(" ", 43))
  2105.  
  2106.     print("\n")
  2107.     term.setBackgroundColor(colors[theme["bottom-box"]])
  2108.     for i = 1, 3 do centerPrint(string.rep(" ", 43)) end
  2109.  
  2110.     local opt = prompt({{"Update", 7, 10}, {"Cancel", 34, 10}}, "horizontal")
  2111.     if opt == "Update" then
  2112.         openAddressBar = false
  2113.         term.setCursorPos(1, 10)
  2114.         centerWrite(string.rep(" ", 43))
  2115.         centerWrite("Updating...")
  2116.  
  2117.         local updateLocation = rootFolder .. "/update"
  2118.         fs.delete(updateLocation)
  2119.         download(firewolfURL, updateLocation)
  2120.         centerWrite(string.rep(" ", 43))
  2121.         centerPrint("Done!")
  2122.         centerWrite(string.rep(" ", 43))
  2123.         if term.isColor() then centerPrint("Click to exit...")
  2124.         else centerPrint("Press any key to exit...") end
  2125.         centerPrint(string.rep(" ", 43))
  2126.         sleep(1.3)
  2127.         fs.delete(firewolfLocation)
  2128.         fs.move(updateLocation, firewolfLocation)
  2129.         shell.run(firewolfLocation)
  2130.  
  2131.         return true
  2132.     elseif opt == "Cancel" then
  2133.         redirect("home")
  2134.         return
  2135.     elseif opt == nil then
  2136.         os.queueEvent(event_exitWebsite)
  2137.         return
  2138.     end
  2139. end
  2140.  
  2141. pages.credits = function(site)
  2142.     clearPage(site, colors[theme["background"]])
  2143.     print("\n")
  2144.     term.setTextColor(colors[theme["text-color"]])
  2145.     term.setBackgroundColor(colors[theme["top-box"]])
  2146.     centerPrint(string.rep(" ", 43))
  2147.     centerWrite(string.rep(" ", 43))
  2148.     centerPrint("Firewolf Credits")
  2149.     centerPrint(string.rep(" ", 43))
  2150.     print("\n")
  2151.     term.setBackgroundColor(colors[theme["bottom-box"]])
  2152.     centerPrint(string.rep(" ", 43))
  2153.     centerPrint("   Coded by:      GravityScore and 1lann   ")
  2154.     centerPrint("   Art by:                     lieudusty   ")
  2155.     centerPrint(string.rep(" ", 43))
  2156.     centerPrint("   Based off:       RednetExplorer 2.4.1   ")
  2157.     centerPrint("              Made by ComputerCraftFan11   ")
  2158.     centerPrint(string.rep(" ", 43))
  2159. end
  2160.  
  2161. pages.getinfo = function(site)
  2162.     local res = curSites
  2163.     table.insert(res, 1, "Type Website Address...")
  2164.     if #res > 0 then
  2165.         clearPage(site, colors[theme["background"]])
  2166.         print("")
  2167.         term.setTextColor(colors[theme["text-color"]])
  2168.         term.setBackgroundColor(colors[theme["top-box"]])
  2169.         centerPrint(string.rep(" ", 47))
  2170.         centerWrite(string.rep(" ", 47))
  2171.         centerPrint("Retrieve Website Information")
  2172.         centerPrint(string.rep(" ", 47))
  2173.         print("")
  2174.  
  2175.         term.setBackgroundColor(colors[theme["bottom-box"]])
  2176.         for i = 1, 12 do centerPrint(string.rep(" ", 47)) end
  2177.         local opt = scrollingPrompt(res, 4, 8, 10, 43)
  2178.         if opt == "Type Website Address..." then
  2179.             clearPage(site, colors[theme["background"]])
  2180.             print("")
  2181.             term.setTextColor(colors[theme["text-color"]])
  2182.             term.setBackgroundColor(colors[theme["top-box"]])
  2183.             centerPrint(string.rep(" ", 47))
  2184.             centerWrite(string.rep(" ", 47))
  2185.             centerPrint("Retrieve Website Information")
  2186.             centerPrint(string.rep(" ", 47))
  2187.             print("")
  2188.  
  2189.             term.setBackgroundColor(colors[theme["bottom-box"]])
  2190.             for i = 1, 3 do centerPrint(string.rep(" ", 47)) end
  2191.             term.setCursorPos(4, 8)
  2192.             write("rdnt://")
  2193.             opt = "rdnt://" .. modRead(nil, nil, 37)
  2194.         end if opt ~= nil then
  2195.             term.setTextColor(colors[theme["text-color"]])
  2196.             clearPage(site, colors[theme["background"]])
  2197.             print("\n\n")
  2198.             centerPrint("Connecting...")
  2199.  
  2200.             local id, content, status = curProtocol.getWebsite(opt:gsub("rdnt://", ""))
  2201.  
  2202.             if id ~= nil and status ~= nil then
  2203.                 clearPage(site, colors[theme["background"]])
  2204.                 print("")
  2205.                 term.setTextColor(colors[theme["text-color"]])
  2206.                 term.setBackgroundColor(colors[theme["top-box"]])
  2207.                 centerPrint(string.rep(" ", 47))
  2208.                 centerWrite(string.rep(" ", 47))
  2209.                 centerPrint("Retrieve Website Information")
  2210.                 centerWrite(string.rep(" ", 47))
  2211.                 centerPrint(opt)
  2212.                 centerPrint(string.rep(" ", 47))
  2213.                 print("")
  2214.  
  2215.                 term.setBackgroundColor(colors[theme["bottom-box"]])
  2216.                 for i = 1, 11 do centerPrint(string.rep(" ", 47)) end
  2217.                 local b = false
  2218.                 if verify("blacklist", id) then
  2219.                     term.setCursorPos(4, 9)
  2220.                     write("Website Triggers Blacklist")
  2221.                     b = true
  2222.                 end if verify("whitelist", id, site) then
  2223.                     term.setCursorPos(4, 10)
  2224.                     write("Website Triggers Whitelist")
  2225.                     b = true
  2226.                 end if verify("antivirus", content) then
  2227.                     term.setCursorPos(4, 11)
  2228.                     write("Website Triggers Antivirus")
  2229.                     b = true
  2230.                 end if not(b) then
  2231.                     term.setCursorPos(4, 10)
  2232.                     write("Website Did Not Trigger Anything!")
  2233.                 end
  2234.  
  2235.                 local c = prompt({{"Save Source", 4, 13}, {"Visit Site", 4, 15}}, "vertical")
  2236.                 if c == "Save Source" then
  2237.                     term.setCursorPos(7, 14)
  2238.                     write("Save As: /")
  2239.                     local a = "/" .. modRead(nil, nil, 32)
  2240.  
  2241.                     term.setCursorPos(1, 14)
  2242.                     centerWrite(string.rep(" ", 47))
  2243.                     term.setCursorPos(7, 14)
  2244.                     if fs.exists(a) then
  2245.                         write("File already exists!")
  2246.                     elseif fs.isReadOnly(a) then
  2247.                         write("Location is read only!")
  2248.                     else
  2249.                         write("Saved Successfully!")
  2250.                         local f = io.open(a, "w")
  2251.                         f:write(content)
  2252.                         f:close()
  2253.                     end
  2254.  
  2255.                     openAddressBar = false
  2256.                     sleep(1.3)
  2257.                     openAddressBar = true
  2258.                     redirect("getinfo")
  2259.                     return
  2260.                 elseif c == "Visit Site" then
  2261.                     redirect(opt:gsub("rdnt://", ""))
  2262.                     return
  2263.                 elseif c == nil then
  2264.                     os.queueEvent(event_exitWebsite)
  2265.                     return
  2266.                 end
  2267.             else
  2268.                 clearPage(site, colors[theme["background"]])
  2269.                 print("\n\n")
  2270.                 term.setTextColor(colors[theme["text-color"]])
  2271.                 term.setBackgroundColor(colors[theme["top-box"]])
  2272.                 centerPrint(string.rep(" ", 47))
  2273.                 centerWrite(string.rep(" ", 47))
  2274.                 centerPrint("Site Does Not Exist!")
  2275.                 centerPrint(string.rep(" ", 47))
  2276.             end
  2277.         elseif opt == nil then
  2278.             os.queueEvent(event_exitWebsite)
  2279.             return
  2280.         end
  2281.     else
  2282.         clearPage(site, colors[theme["background"]])
  2283.         print("\n\n")
  2284.         term.setTextColor(colors[theme["text-color"]])
  2285.         term.setBackgroundColor(colors[theme["top-box"]])
  2286.         centerPrint(string.rep(" ", 47))
  2287.         centerWrite(string.rep(" ", 47))
  2288.         centerPrint("No Websites are Currently Online! D:")
  2289.         centerPrint(string.rep(" ", 47))
  2290.     end
  2291. end
  2292.  
  2293. pages.kitteh = function(site)
  2294.     openAddressBar = false
  2295.     term.setTextColor(colors[theme["text-color"]])
  2296.     term.setBackgroundColor(colors[theme["background"]])
  2297.     term.clear()
  2298.     term.setCursorPos(1, 3)
  2299.     centerPrint([[       .__....._             _.....__,         ]])
  2300.     centerPrint([[         .": o :':         ;': o :".           ]])
  2301.     centerPrint([[         '. '-' .'.       .'. '-' .'           ]])
  2302.     centerPrint([[           '---'             '---'             ]])
  2303.     centerPrint([[                                               ]])
  2304.     centerPrint([[    _...----...    ...   ...    ...----..._    ]])
  2305.     centerPrint([[ .-'__..-""'----  '.  '"'  .'  ----'""-..__'-. ]])
  2306.     centerPrint([['.-'   _.--"""'     '-._.-'     '"""--._   '-.']])
  2307.     centerPrint([['  .-"'                :                '"-.  ']])
  2308.     centerPrint([[  '   '.            _.'"'._            .'   '  ]])
  2309.     centerPrint([[        '.     ,.-'"       "'-.,     .'        ]])
  2310.     centerPrint([[          '.                       .'          ]])
  2311.     centerPrint([[            '-._               _.-'            ]])
  2312.     centerPrint([[                '"'--.....--'"'                ]])
  2313.     print("")
  2314.     centerPrint("Firewolf Kitteh is Not Amused...")
  2315.     sleep(4)
  2316.     os.shutdown()
  2317. end
  2318.  
  2319. errPages.overspeed = function()
  2320.     website = "overspeed"
  2321.     clearPage("overspeed", colors[theme["background"]])
  2322.     print("\n")
  2323.     term.setTextColor(colors[theme["text-color"]])
  2324.     term.setBackgroundColor(colors[theme["top-box"]])
  2325.     centerPrint(string.rep(" ", 43))
  2326.     centerWrite(string.rep(" ", 43))
  2327.     centerPrint("Warning! D:")
  2328.     centerPrint(string.rep(" ", 43))
  2329.     print("")
  2330.  
  2331.     term.setBackgroundColor(colors[theme["bottom-box"]])
  2332.     centerPrint(string.rep(" ", 43))
  2333.     centerPrint("  Website browsing sleep limit reached!    ")
  2334.     centerPrint(string.rep(" ", 43))
  2335.     centerPrint("  To prevent Firewolf from spamming        ")
  2336.     centerPrint("  rednet, Firewolf has stopped loading     ")
  2337.     centerPrint("  the page.                                ")
  2338.     centerPrint(string.rep(" ", 43))
  2339.     centerPrint(string.rep(" ", 43))
  2340.     centerPrint(string.rep(" ", 43))
  2341.     openAddressBar = false
  2342.     for i = 1, 5 do
  2343.         term.setCursorPos(1, 14)
  2344.         centerWrite(string.rep(" ", 43))
  2345.         if 6 - i == 1 then centerWrite("Please wait 1 second...")
  2346.         else centerWrite("Please wait " .. tostring(6 - i) .. " seconds...") end
  2347.         sleep(1)
  2348.     end
  2349.     openAddressBar = true
  2350.  
  2351.     term.setCursorPos(1, 14)
  2352.     centerWrite(string.rep(" ", 43))
  2353.     centerWrite("You may now browse normally...")
  2354. end
  2355.  
  2356. errPages.crash = function(err)
  2357.     if err:find("Firewolf Antivirus: Unauthorized Function") then
  2358.         clearPage("crash", colors[theme["background"]])
  2359.         print("")
  2360.         term.setTextColor(colors[theme["text-color"]])
  2361.         term.setBackgroundColor(colors[theme["top-box"]])
  2362.         centerPrint(string.rep(" ", 43))
  2363.         centerWrite(string.rep(" ", 43))
  2364.         centerPrint("Website Aborted!")
  2365.         centerPrint(string.rep(" ", 43))
  2366.         print("")
  2367.         term.setBackgroundColor(colors[theme["bottom-box"]])
  2368.         centerPrint(string.rep(" ", 43))
  2369.         centerPrint("  The website has attempted to use a       ")
  2370.         centerPrint("  potentially malicious function that you  ")
  2371.         centerPrint("  did not authorize! This might also be    ")
  2372.         centerPrint("  a mistake.                               ")
  2373.         centerPrint(string.rep(" ", 43))
  2374.         centerPrint("  Please ask 1lann or GravityScore if you  ")
  2375.         centerPrint("  have any questions about this.           ")
  2376.         centerPrint(string.rep(" ", 43))
  2377.         centerWrite(string.rep(" ", 43))
  2378.         centerPrint("You may now browse normally!")
  2379.         centerWrite(string.rep(" ", 43))
  2380.     else
  2381.         clearPage("crash", colors[theme["background"]])
  2382.         print("")
  2383.         term.setTextColor(colors[theme["text-color"]])
  2384.         term.setBackgroundColor(colors[theme["top-box"]])
  2385.         centerPrint(string.rep(" ", 43))
  2386.         centerWrite(string.rep(" ", 43))
  2387.         centerPrint("The Website Has Crashed! D:")
  2388.         centerPrint(string.rep(" ", 43))
  2389.         print("")
  2390.  
  2391.         term.setBackgroundColor(colors[theme["bottom-box"]])
  2392.         centerPrint(string.rep(" ", 43))
  2393.         centerPrint("  It looks like the website has crashed!   ")
  2394.         centerPrint("  Report this error to the website owner:  ")
  2395.         centerPrint(string.rep(" ", 43))
  2396.         term.setBackgroundColor(colors[theme["background"]])
  2397.         print("")
  2398.         print("  " .. err)
  2399.         print("")
  2400.  
  2401.         term.setBackgroundColor(colors[theme["bottom-box"]])
  2402.         centerPrint(string.rep(" ", 43))
  2403.         centerWrite(string.rep(" ", 43))
  2404.         centerPrint("You may now browse normally!")
  2405.         centerPrint(string.rep(" ", 43))
  2406.     end
  2407. end
  2408.  
  2409. errPages.checkForModem = function()
  2410.     while true do
  2411.         local present = false
  2412.         for _, v in pairs(rs.getSides()) do
  2413.             if peripheral.getType(v) == "modem" then
  2414.                 rednet.open(v)
  2415.                 present = true
  2416.                 break
  2417.             end
  2418.         end
  2419.  
  2420.         if not(present) then
  2421.             website = "nomodem"
  2422.             clearPage("nomodem", colors[theme["background"]])
  2423.             print("")
  2424.             term.setTextColor(colors[theme["text-color"]])
  2425.             term.setBackgroundColor(colors[theme["top-box"]])
  2426.             centerPrint(string.rep(" ", 43))
  2427.             centerWrite(string.rep(" ", 43))
  2428.             centerPrint("No Modem Attached! D:")
  2429.             centerPrint(string.rep(" ", 43))
  2430.             print("")
  2431.  
  2432.             term.setBackgroundColor(colors[theme["bottom-box"]])
  2433.             centerPrint(string.rep(" ", 43))
  2434.             centerPrint("  No wireless modem was found on this      ")
  2435.             centerPrint("  computer, and Firewolf is not able to    ")
  2436.             centerPrint("  run without one!                         ")
  2437.             centerPrint(string.rep(" ", 43))
  2438.             centerWrite(string.rep(" ", 43))
  2439.             centerPrint("Waiting for a modem to be attached...")
  2440.             centerWrite(string.rep(" ", 43))
  2441.             if isAdvanced() then centerPrint("Click to exit...")
  2442.             else centerPrint("Press any key to exit...") end
  2443.             centerPrint(string.rep(" ", 43))
  2444.  
  2445.             while true do
  2446.                 local e, id = os.pullEvent()
  2447.                 if e == "key" or e == "mouse_click" then return false
  2448.                 elseif e == "peripheral" then break end
  2449.             end
  2450.         else
  2451.             return true
  2452.         end
  2453.     end
  2454. end
  2455.  
  2456. local function loadSite(site)
  2457.     local shellAllowed = false
  2458.     local function runSite(cacheLoc, antivirusEnv)
  2459.         -- Clear
  2460.         clearPage(site, colors.black)
  2461.         term.setBackgroundColor(colors.black)
  2462.         term.setTextColor(colors.white)
  2463.  
  2464.         -- Setup environment
  2465.         local cbc, ctc = colors.black, colors.white
  2466.         local nenv = antivirusEnv
  2467.         local safeFunc = true
  2468.         local unsafeFunc = {"os", "shell", "fs", "io", "loadstring", "loadfile", "dofile",
  2469.             "getfenv", "setfenv", "rawset"}
  2470.         for k, v in pairs(env) do
  2471.             safeFunc = true
  2472.             for ki, vi in pairs(unsafeFunc) do
  2473.                 if k == vi then safeFunc = false break end
  2474.             end
  2475.             if safeFunc then
  2476.                 if type(v) ~= "table" then nenv[k] = v
  2477.                 else
  2478.                     nenv[k] = {}
  2479.                     for i, d in pairs(v) do nenv[k][i] = d end
  2480.                 end
  2481.             end
  2482.         end
  2483.         nenv.term = {}
  2484.  
  2485.         local function ospullEvent(a)
  2486.             if a == "derp" then return true end
  2487.             while true do
  2488.                 local e, p1, p2, p3, p4, p5 = env.os.pullEventRaw()
  2489.                 if e == event_exitWebsite then
  2490.                     queueWebsiteExit = true
  2491.                     env.error(event_exitWebsite)
  2492.                 elseif e == "terminate" then
  2493.                     env.error()
  2494.                 end
  2495.  
  2496.                 if e ~= event_exitWebsite and e ~= event_redirect and e ~= event_exitApp
  2497.                         and e ~= event_loadWebsite then
  2498.                     if a then
  2499.                         if e == a then return e, p1, p2, p3, p4, p5 end
  2500.                     else return e, p1, p2, p3, p4, p5 end
  2501.                 end
  2502.             end
  2503.         end
  2504.  
  2505.         nenv.term.getSize = function()
  2506.             local wid, hei = env.term.getSize()
  2507.             return wid, hei - 1
  2508.         end
  2509.  
  2510.         nenv.term.setCursorPos = function(x, y)
  2511.             if not(y > 0) then y = 1 end
  2512.             return env.term.setCursorPos(x, y + 1)
  2513.         end
  2514.  
  2515.         nenv.term.getCursorPos = function()
  2516.             local x, y = env.term.getCursorPos()
  2517.             return x, y + 1
  2518.         end
  2519.  
  2520.         nenv.term.clear = function()
  2521.             local x, y = env.term.getCursorPos()
  2522.             api.clearPage(website, cbc, nil, ctc)
  2523.             env.term.setCursorPos(x, y)
  2524.         end
  2525.  
  2526.         nenv.term.setBackgroundColor = function(col)
  2527.             cbc = col
  2528.             return env.term.setBackgroundColor(col)
  2529.         end
  2530.  
  2531.         nenv.term.setBackgroundColour = function(col)
  2532.             cbc = col
  2533.             return env.term.setBackgroundColour(col)
  2534.         end
  2535.  
  2536.         nenv.term.getBackgroundColor = function()
  2537.             return cbc
  2538.         end
  2539.  
  2540.         nenv.term.getBackgroundColour = function()
  2541.             return cbc
  2542.         end
  2543.  
  2544.         nenv.term.setTextColor = function(col)
  2545.             ctc = col
  2546.             return env.term.setTextColor(col)
  2547.         end
  2548.  
  2549.         nenv.term.setTextColour = function(col)
  2550.             ctc = col
  2551.             return env.term.setTextColour(col)
  2552.         end
  2553.  
  2554.         nenv.term.getTextColour = function()
  2555.             return ctc
  2556.         end
  2557.  
  2558.         nenv.term.getTextColor = function()
  2559.             return ctc
  2560.         end
  2561.  
  2562.         nenv.term.write = function(text)
  2563.             return env.term.write(text)
  2564.         end
  2565.  
  2566.         nenv.term.setCursorBlink = function(bool)
  2567.             return env.term.setCursorBlink(bool)
  2568.         end
  2569.  
  2570.         nenv.write = function(text)
  2571.             return env.write(text)
  2572.         end
  2573.  
  2574.         nenv.print = function(...)
  2575.             return env.print(...)
  2576.         end
  2577.  
  2578.         nenv.term.isColor = function()
  2579.             return isAdvanced()
  2580.         end
  2581.  
  2582.         nenv.term.isColour = function()
  2583.             return isAdvanced()
  2584.         end
  2585.  
  2586.         local oldScroll = term.scroll
  2587.         term.scroll = function(n)
  2588.             local x, y = env.term.getCursorPos()
  2589.             oldScroll(n)
  2590.             clearPage(website, cbc, true)
  2591.             env.term.setCursorPos(x, y)
  2592.         end
  2593.  
  2594.         nenv.prompt = function(list, dir)
  2595.             local fixPrompt = function(list, dir)
  2596.                 if isAdvanced() then
  2597.                     for _, v in pairs(list) do
  2598.                         if v.bg then term.setBackgroundColor(v.bg) end
  2599.                         if v.tc then term.setTextColor(v.tc) end
  2600.                         if v[2] == -1 then v[2] = math.ceil((w + 1)/2 - (v[1]:len() + 6)/2) end
  2601.  
  2602.                         term.setCursorPos(v[2], v[3])
  2603.                         write("[- " .. v[1])
  2604.                         term.setCursorPos(v[2] + v[1]:len() + 3, v[3])
  2605.                         write(" -]")
  2606.                     end
  2607.  
  2608.                     while true do
  2609.                         local e, but, x, y = ospullEvent()
  2610.                         if e == "mouse_click" then
  2611.                             for _, v in pairs(list) do
  2612.                                 if x >= v[2] and x <= v[2] + v[1]:len() + 5 and y == v[3] then
  2613.                                     return v[1]
  2614.                                 end
  2615.                             end
  2616.                         elseif e == event_exitWebsite then
  2617.                             os.queueEvent(event_exitWebsite)
  2618.                             return nil
  2619.                         end
  2620.                     end
  2621.                 else
  2622.                     for _, v in pairs(list) do
  2623.                         term.setBackgroundColor(colors.black)
  2624.                         term.setTextColor(colors.white)
  2625.                         if v[2] == -1 then v[2] = math.ceil((w + 1)/2 - (v[1]:len() + 4)/2) end
  2626.  
  2627.                         term.setCursorPos(v[2], v[3])
  2628.                         write("  " .. v[1])
  2629.                         term.setCursorPos(v[2] + v[1]:len() + 2, v[3])
  2630.                         write("  ")
  2631.                     end
  2632.  
  2633.                     local key1 = 200
  2634.                     local key2 = 208
  2635.                     if dir == "horizontal" then
  2636.                         key1 = 203
  2637.                         key2 = 205
  2638.                     end
  2639.  
  2640.                     local curSel = 1
  2641.                     term.setCursorPos(list[curSel][2], list[curSel][3])
  2642.                     write("[")
  2643.                     term.setCursorPos(list[curSel][2] + list[curSel][1]:len() + 3,
  2644.                         list[curSel][3])
  2645.                     write("]")
  2646.  
  2647.                     while true do
  2648.                         local e, key = ospullEvent()
  2649.                         term.setCursorPos(list[curSel][2], list[curSel][3])
  2650.                         write(" ")
  2651.                         term.setCursorPos(list[curSel][2] + list[curSel][1]:len() + 3,
  2652.                             list[curSel][3])
  2653.                         write(" ")
  2654.                         if e == "key" and key == key1 and curSel > 1 then
  2655.                             curSel = curSel - 1
  2656.                         elseif e == "key" and key == key2 and curSel < #list then
  2657.                             curSel = curSel + 1
  2658.                         elseif e == "key" and key == 28 then
  2659.                             return list[curSel][1]
  2660.                         elseif e == event_exitWebsite then
  2661.                             os.queueEvent(event_exitWebsite)
  2662.                             return nil
  2663.                         end
  2664.                         term.setCursorPos(list[curSel][2], list[curSel][3])
  2665.                         write("[")
  2666.                         term.setCursorPos(list[curSel][2] + list[curSel][1]:len() + 3,
  2667.                             list[curSel][3])
  2668.                         write("]")
  2669.                     end
  2670.                 end
  2671.             end
  2672.  
  2673.             local a = {}
  2674.             for k, v in pairs(list) do
  2675.                 local b, t = v.b, v.t
  2676.                 if b == nil then b = cbg end
  2677.                 if t == nil then t = ctc end
  2678.                 table.insert(a, {v[1], v[2], v[3] + 1, bg = b, tc = t})
  2679.             end
  2680.  
  2681.             return fixPrompt(a, dir)
  2682.         end
  2683.  
  2684.         nenv.scrollingPrompt = function(list, x, y, len, width)
  2685.             local y = y + 1
  2686.             local wid = width
  2687.             if wid == nil then wid = w - 3 end
  2688.  
  2689.             local function updateDisplayList(items, loc, len)
  2690.                 local ret = {}
  2691.                 for i = 1, len do
  2692.                     local item = items[i + loc - 1]
  2693.                     if item ~= nil then table.insert(ret, item) end
  2694.                 end
  2695.                 return ret
  2696.             end
  2697.  
  2698.             if isAdvanced() then
  2699.                 local function draw(a)
  2700.                     for i, v in ipairs(a) do
  2701.                         term.setCursorPos(1, y + i - 1)
  2702.                         api.centerWrite(string.rep(" ", wid + 2))
  2703.                         term.setCursorPos(x, y + i - 1)
  2704.                         write("[ " .. v:sub(1, wid - 5))
  2705.                         term.setCursorPos(wid + x - 2, y + i - 1)
  2706.                         write("  ]")
  2707.                     end
  2708.                 end
  2709.  
  2710.                 local loc = 1
  2711.                 local disList = updateDisplayList(list, loc, len)
  2712.                 draw(disList)
  2713.                
  2714.                 while true do
  2715.                     local e, but, clx, cly = ospullEvent()
  2716.                     if e == "key" and but == 200 and loc > 1 then
  2717.                         loc = loc - 1
  2718.                         disList = updateDisplayList(list, loc, len)
  2719.                         draw(disList)
  2720.                     elseif e == "key" and but == 208 and loc + len - 1 < #list then
  2721.                         loc = loc + 1
  2722.                         disList = updateDisplayList(list, loc, len)
  2723.                         draw(disList)
  2724.                     elseif e == "mouse_scroll" and but > 0 and loc + len - 1 < #list then
  2725.                         loc = loc + but
  2726.                         disList = updateDisplayList(list, loc, len)
  2727.                         draw(disList)
  2728.                     elseif e == "mouse_scroll" and but < 0 and loc > 1 then
  2729.                         loc = loc + but
  2730.                         disList = updateDisplayList(list, loc, len)
  2731.                         draw(disList)
  2732.                     elseif e == "mouse_click" then
  2733.                         for i, v in ipairs(disList) do
  2734.                             if clx >= x and clx <= x + wid and cly == i + y - 1 then
  2735.                                 return v
  2736.                             end
  2737.                         end
  2738.                     elseif e == event_exitWebsite then
  2739.                         os.queueEvent(event_exitWebsite)
  2740.                         return nil
  2741.                     end
  2742.                 end
  2743.             else
  2744.                 local function draw(a)
  2745.                     for i, v in ipairs(a) do
  2746.                         term.setCursorPos(1, y + i - 1)
  2747.                         api.centerWrite(string.rep(" ", wid + 2))
  2748.                         term.setCursorPos(x, y + i - 1)
  2749.                         write("[ ] " .. v:sub(1, wid - 5))
  2750.                     end
  2751.                 end
  2752.  
  2753.                 local loc = 1
  2754.                 local curSel = 1
  2755.                 local disList = updateDisplayList(list, loc, len)
  2756.                 draw(disList)
  2757.                 term.setCursorPos(x + 1, y + curSel - 1)
  2758.                 write("x")
  2759.  
  2760.                 while true do
  2761.                     local e, key = ospullEvent()
  2762.                     term.setCursorPos(x + 1, y + curSel - 1)
  2763.                     write(" ")
  2764.                     if e == "key" and key == 200 then
  2765.                         if curSel > 1 then
  2766.                             curSel = curSel - 1
  2767.                         elseif loc > 1 then
  2768.                             loc = loc - 1
  2769.                             disList = updateDisplayList(list, loc, len)
  2770.                             draw(disList)
  2771.                         end
  2772.                     elseif e == "key" and key == 208 then
  2773.                         if curSel < #disList then
  2774.                             curSel = curSel + 1
  2775.                         elseif loc + len - 1 < #list then
  2776.                             loc = loc + 1
  2777.                             disList = updateDisplayList(list, loc, len)
  2778.                             draw(disList)
  2779.                         end
  2780.                     elseif e == "key" and key == 28 then
  2781.                         return list[curSel + loc - 1]
  2782.                     elseif e == event_exitWebsite then
  2783.                         os.queueEvent(event_exitWebsite)
  2784.                         return nil
  2785.                     end
  2786.                     term.setCursorPos(x + 1, y + curSel - 1)
  2787.                     write("x")
  2788.                 end
  2789.             end
  2790.         end
  2791.  
  2792.         nenv.loadImageFromServer = function(image)
  2793.             sleep(0.1)
  2794.             local mid, msgImage = curProtocol.getWebsite(site .. "/" .. image)
  2795.             if mid then
  2796.                 local f = env.io.open(rootFolder .. "/temp_file", "w")
  2797.                 f:write(msgImage)
  2798.                 f:close()
  2799.                 local rImage = env.paintutils.loadImage(rootFolder .. "/temp_file")
  2800.                 fs.delete(rootFolder .. "/temp_file")
  2801.                 return rImage
  2802.             end
  2803.             return nil
  2804.         end
  2805.  
  2806.         nenv.ioReadFileFromServer = function(file)
  2807.             sleep(0.1)
  2808.             local mid, msgFile = curProtocol.getWebsite(site .. "/" .. file)
  2809.             if mid then
  2810.                 local f = env.io.open(rootFolder .. "/temp_file", "w")
  2811.                 f:write(msgFile)
  2812.                 f:close()
  2813.                 local rFile = env.io.open(rootFolder .. "/temp_file", "r")
  2814.                 return rFile
  2815.             end
  2816.             return nil
  2817.         end
  2818.  
  2819.         --[[
  2820.         nenv.getCookie = function(cookieId)
  2821.             sleep(0.1)
  2822.             env.rednet.send(id, textutils.serialize({"getCookie", cookieId}))
  2823.             local startClock = os.clock()
  2824.             while os.clock() - startClock < timeout do
  2825.                 local mid, status = env.rednet.receive(timeout)
  2826.                 if mid == id then
  2827.                     if status == "[$notexist$]" then
  2828.                         return false
  2829.                     elseif env.string.find(status, "[$cookieData$]") then
  2830.                         return env.string.gsub(status, "[$cookieData$]", "")
  2831.                     end
  2832.                 end
  2833.             end
  2834.             return false
  2835.         end
  2836.  
  2837.         nenv.takeFromCookieJar = function(cookieId)
  2838.             nenv.getCookie(cookieId)
  2839.         end
  2840.  
  2841.         nenv.createCookie = function(cookieId)
  2842.             sleep(0.1)
  2843.             env.rednet.send(id, textutils.serialize({"createCookie", cookieId}))
  2844.             local startClock = os.clock()
  2845.             while os.clock() - startClock < timeout do
  2846.                 local mid, status = env.rednet.receive(timeout)
  2847.                 if mid == id then
  2848.                     if status == "[$notexist$]" then
  2849.                         return false
  2850.                     elseif env.string.find(status, "[$cookieData$]") then
  2851.                         return env.string.gsub(status, "[$cookieData$]", "")
  2852.                     end
  2853.                 end
  2854.             end
  2855.             return false
  2856.         end
  2857.  
  2858.         nenv.bakeCookie = function(cookieId)
  2859.             nenv.createCookie(cookieId)
  2860.         end
  2861.  
  2862.         nenv.deleteCookie = function(cookieId)
  2863.  
  2864.         end
  2865.  
  2866.         nenv.eatCookie = function(cookieId)
  2867.             nenv.deleteCookie(cookieId)
  2868.         end
  2869.         ]]--
  2870.  
  2871.         nenv.redirect = function(url)
  2872.             api.redirect(url)
  2873.             env.error()
  2874.         end
  2875.  
  2876.         if shellAllowed then
  2877.             nenv.shell.run = function(file, ...)
  2878.                 if file == "clear" then
  2879.                     api.clearPage(website, cbc)
  2880.                     env.term.setCursorPos(1, 2)
  2881.                 else
  2882.                     env.shell.run(file, ...)
  2883.                 end
  2884.             end
  2885.         end
  2886.  
  2887.         local queueWebsiteExit = false
  2888.         nenv.os.pullEvent = function(a)
  2889.             if a == "derp" then return true end
  2890.             while true do
  2891.                 local e, p1, p2, p3, p4, p5 = env.os.pullEventRaw()
  2892.                 if e == event_exitWebsite then
  2893.                     queueWebsiteExit = true
  2894.                     env.error(event_exitWebsite)
  2895.                 elseif e == "terminate" then
  2896.                     env.error()
  2897.                 end
  2898.  
  2899.                 if e ~= event_exitWebsite and e ~= event_redirect and e ~= event_exitApp
  2900.                         and e ~= event_loadWebsite then
  2901.                     if a then
  2902.                         if e == a then return e, p1, p2, p3, p4, p5 end
  2903.                     else return e, p1, p2, p3, p4, p5 end
  2904.                 end
  2905.             end
  2906.         end
  2907.  
  2908.         nenv.sleep = function(_nTime)
  2909.             local timer = os.startTimer(_nTime)
  2910.             repeat local _, param = ospullEvent("timer")
  2911.             until param == timer
  2912.         end
  2913.  
  2914.         nenv.read = function(_sReplaceChar, _tHistory)
  2915.             term.setCursorBlink(true)
  2916.  
  2917.             local sLine = ""
  2918.             local nHistoryPos = nil
  2919.             local nPos = 0
  2920.             if _sReplaceChar then
  2921.                 _sReplaceChar = string.sub(_sReplaceChar, 1, 1)
  2922.             end
  2923.            
  2924.             local w, h = term.getSize()
  2925.             local sx, sy = term.getCursorPos()
  2926.            
  2927.             local function redraw(_sCustomReplaceChar)
  2928.                 local nScroll = 0
  2929.                 if sx + nPos >= w then
  2930.                     nScroll = (sx + nPos) - w
  2931.                 end
  2932.                    
  2933.                 term.setCursorPos(sx, sy)
  2934.                 local sReplace = _sCustomReplaceChar or _sReplaceChar
  2935.                 if sReplace then
  2936.                     term.write(string.rep(sReplace, string.len(sLine) - nScroll))
  2937.                 else
  2938.                     term.write(string.sub(sLine, nScroll + 1))
  2939.                 end
  2940.                 term.setCursorPos(sx + nPos - nScroll, sy)
  2941.             end
  2942.            
  2943.             while true do
  2944.                 local sEvent, param = ospullEvent()
  2945.                 if sEvent == "char" then
  2946.                     sLine = string.sub(sLine, 1, nPos) .. param .. string.sub(sLine, nPos + 1)
  2947.                     nPos = nPos + 1
  2948.                     redraw()
  2949.                    
  2950.                 elseif sEvent == "key" then
  2951.                     if param == keys.enter then
  2952.                         break
  2953.                     elseif param == keys.left then
  2954.                         if nPos > 0 then
  2955.                             nPos = nPos - 1
  2956.                             redraw()
  2957.                         end
  2958.                     elseif param == keys.right then
  2959.                         if nPos < string.len(sLine) then
  2960.                             nPos = nPos + 1
  2961.                             redraw()
  2962.                         end
  2963.                     elseif param == keys.up or param == keys.down then
  2964.                         if _tHistory then
  2965.                             redraw(" ");
  2966.                             if param == keys.up then
  2967.                                 if nHistoryPos == nil then
  2968.                                     if #_tHistory > 0 then
  2969.                                         nHistoryPos = #_tHistory
  2970.                                     end
  2971.                                 elseif nHistoryPos > 1 then
  2972.                                     nHistoryPos = nHistoryPos - 1
  2973.                                 end
  2974.                             else
  2975.                                 if nHistoryPos == #_tHistory then
  2976.                                     nHistoryPos = nil
  2977.                                 elseif nHistoryPos ~= nil then
  2978.                                     nHistoryPos = nHistoryPos + 1
  2979.                                 end                    
  2980.                             end
  2981.                            
  2982.                             if nHistoryPos then
  2983.                                 sLine = _tHistory[nHistoryPos]
  2984.                                 nPos = string.len(sLine)
  2985.                             else
  2986.                                 sLine = ""
  2987.                                 nPos = 0
  2988.                             end
  2989.                             redraw()
  2990.                         end
  2991.                     elseif param == keys.backspace then
  2992.                         if nPos > 0 then
  2993.                             redraw(" ");
  2994.                             sLine = string.sub(sLine, 1, nPos - 1) .. string.sub(sLine, nPos + 1)
  2995.                             nPos = nPos - 1                
  2996.                             redraw()
  2997.                         end
  2998.                     elseif param == keys.home then
  2999.                         nPos = 0
  3000.                         redraw()       
  3001.                     elseif param == keys.delete then
  3002.                         if nPos < string.len(sLine) then
  3003.                             redraw(" ");
  3004.                             sLine = string.sub(sLine, 1, nPos) .. string.sub(sLine, nPos + 2)
  3005.                             redraw()
  3006.                         end
  3007.                     elseif param == keys["end"] then
  3008.                         nPos = string.len(sLine)
  3009.                         redraw()
  3010.                     end
  3011.                 end
  3012.             end
  3013.            
  3014.             term.setCursorBlink(false)
  3015.             term.setCursorPos(w + 1, sy)
  3016.             print()
  3017.            
  3018.             return sLine
  3019.         end
  3020.  
  3021.         -- Download API
  3022.         nenv.urlDownload = function(url)
  3023.             local function webmodRead(replaceChar, his, maxLen, stopAtMaxLen, liveUpdates,
  3024.                     exitOnControl)
  3025.                 term.setCursorBlink(true)
  3026.                 local line = ""
  3027.                 local hisPos = nil
  3028.                 local pos = 0
  3029.                 if replaceChar then replaceChar = replaceChar:sub(1, 1) end
  3030.                 local w, h = term.getSize()
  3031.                 local sx, sy = term.getCursorPos()
  3032.  
  3033.                 local function redraw(repl)
  3034.                     local scroll = 0
  3035.                     if line:len() >= maxLen then scroll = line:len() - maxLen end
  3036.  
  3037.                     term.setCursorPos(sx, sy)
  3038.                     local a = repl or replaceChar
  3039.                     if a then term.write(string.rep(a, line:len() - scroll))
  3040.                     else term.write(line:sub(scroll + 1)) end
  3041.                     term.setCursorPos(sx + pos - scroll, sy)
  3042.                 end
  3043.  
  3044.                 while true do
  3045.                     local e, but, x, y, p4, p5 = ospullEvent()
  3046.                     if e == "char" and not(stopAtMaxLen == true and line:len() >= maxLen) then
  3047.                         line = line:sub(1, pos) .. but .. line:sub(pos + 1, -1)
  3048.                         pos = pos + 1
  3049.                         redraw()
  3050.                     elseif e == "key" then
  3051.                         if but == keys.enter then
  3052.                             break
  3053.                         elseif but == keys.left then
  3054.                             if pos > 0 then pos = pos - 1 redraw() end
  3055.                         elseif but == keys.right then
  3056.                             if pos < line:len() then pos = pos + 1 redraw() end
  3057.                         elseif (but == keys.up or but == keys.down) and his then
  3058.                             redraw(" ")
  3059.                             if but == keys.up then
  3060.                                 if hisPos == nil and #his > 0 then hisPos = #his
  3061.                                 elseif hisPos > 1 then hisPos = hisPos - 1 end
  3062.                             elseif but == keys.down then
  3063.                                 if hisPos == #his then hisPos = nil
  3064.                                 elseif hisPos ~= nil then hisPos = hisPos + 1 end
  3065.                             end
  3066.  
  3067.                             if hisPos then
  3068.                                 line = his[hisPos]
  3069.                                 pos = line:len()
  3070.                             else
  3071.                                 line = ""
  3072.                                 pos = 0
  3073.                             end
  3074.                             redraw()
  3075.                             if liveUpdates then
  3076.                                 local a, data = liveUpdates(line, "update_history", nil, nil,
  3077.                                         nil, nil, nil)
  3078.                                 if a == true and data == nil then
  3079.                                     term.setCursorBlink(false)
  3080.                                     return line
  3081.                                 elseif a == true and data ~= nil then
  3082.                                     term.setCursorBlink(false)
  3083.                                     return data
  3084.                                 end
  3085.                             end
  3086.                         elseif but == keys.backspace and pos > 0 then
  3087.                             redraw(" ")
  3088.                             line = line:sub(1, pos - 1) .. line:sub(pos + 1, -1)
  3089.                             pos = pos - 1
  3090.                             redraw()
  3091.                             if liveUpdates then
  3092.                                 local a, data = liveUpdates(line, "delete", nil, nil, nil, nil, nil)
  3093.                                 if a == true and data == nil then
  3094.                                     term.setCursorBlink(false)
  3095.                                     return line
  3096.                                 elseif a == true and data ~= nil then
  3097.                                     term.setCursorBlink(false)
  3098.                                     return data
  3099.                                 end
  3100.                             end
  3101.                         elseif but == keys.home then
  3102.                             pos = 0
  3103.                             redraw()
  3104.                         elseif but == keys.delete and pos < line:len() then
  3105.                             redraw(" ")
  3106.                             line = line:sub(1, pos) .. line:sub(pos + 2, -1)
  3107.                             redraw()
  3108.                             if liveUpdates then
  3109.                                 local a, data = liveUpdates(line, "delete", nil, nil, nil, nil, nil)
  3110.                                 if a == true and data == nil then
  3111.                                     term.setCursorBlink(false)
  3112.                                     return line
  3113.                                 elseif a == true and data ~= nil then
  3114.                                     term.setCursorBlink(false)
  3115.                                     return data
  3116.                                 end
  3117.                             end
  3118.                         elseif but == keys["end"] then
  3119.                             pos = line:len()
  3120.                             redraw()
  3121.                         elseif (but == 29 or but == 157) and not(exitOnControl) then
  3122.                             term.setCursorBlink(false)
  3123.                             return nil
  3124.                         end
  3125.                     end if liveUpdates then
  3126.                         local a, data = liveUpdates(line, e, but, x, y, p4, p5)
  3127.                         if a == true and data == nil then
  3128.                             term.setCursorBlink(false)
  3129.                             return line
  3130.                         elseif a == true and data ~= nil then
  3131.                             term.setCursorBlink(false)
  3132.                             return data
  3133.                         end
  3134.                     end
  3135.                 end
  3136.  
  3137.                 term.setCursorBlink(false)
  3138.                 if line ~= nil then line = line:gsub("^%s*(.-)%s*$", "%1") end
  3139.                 return line
  3140.             end
  3141.  
  3142.             clearPage(website, colors[theme["background"]])
  3143.             print("\n\n")
  3144.             term.setTextColor(colors[theme["text-color"]])
  3145.             term.setBackgroundColor(colors[theme["top-box"]])
  3146.             centerPrint(string.rep(" ", 47))
  3147.             centerWrite(string.rep(" ", 47))
  3148.             centerPrint("Processing Download Request...")
  3149.             centerPrint(string.rep(" ", 47))
  3150.  
  3151.             openAddressBar = false
  3152.             local res = http.get(url)
  3153.             openAddressBar = true
  3154.             local data = nil
  3155.             if res then
  3156.                 data = res.readAll()
  3157.                 res.close()
  3158.             else
  3159.                 term.setCursorPos(1, 5)
  3160.                 centerPrint(string.rep(" ", 47))
  3161.                 centerWrite(string.rep(" ", 47))
  3162.                 centerPrint("Error: Download Failed!")
  3163.                 centerPrint(string.rep(" ", 47))
  3164.                 openAddressBar = false
  3165.                 sleep(3)
  3166.                 openAddressBar = true
  3167.  
  3168.                 clearPage(website, colors.black)
  3169.                 term.setCursorPos(1, 2)
  3170.                 return nil
  3171.             end
  3172.  
  3173.             clearPage(website, colors[theme["background"]])
  3174.             print("")
  3175.             term.setBackgroundColor(colors[theme["top-box"]])
  3176.             centerPrint(string.rep(" ", 47))
  3177.             centerWrite(string.rep(" ", 47))
  3178.             centerPrint("Download Files")
  3179.             centerPrint(string.rep(" ", 47))
  3180.             print("")
  3181.  
  3182.             local a = website
  3183.             if a:find("/") then a = a:sub(1, a:find("/") - 1) end
  3184.  
  3185.             term.setBackgroundColor(colors[theme["bottom-box"]])
  3186.             for i = 1, 10 do centerPrint(string.rep(" ", 47)) end
  3187.             term.setCursorPos(1, 8)
  3188.             centerPrint("  The website:                                 ")
  3189.             centerPrint("     rdnt://" .. a .. string.rep(" ", w - a:len() - 16))
  3190.             centerPrint("  Is attempting to download a file to this     ")
  3191.             centerPrint("  computer!                                    ")
  3192.  
  3193.             local opt = nenv.prompt({{"Download", 6, 14}, {"Cancel", w - 16, 14}}, "horizontal")
  3194.             if opt == "Download" then
  3195.                 clearPage(website, colors[theme["background"]])
  3196.                 print("")
  3197.                 term.setTextColor(colors[theme["text-color"]])
  3198.                 term.setBackgroundColor(colors[theme["top-box"]])
  3199.                 centerPrint(string.rep(" ", 47))
  3200.                 centerWrite(string.rep(" ", 47))
  3201.                 centerPrint("Download Files")
  3202.                 centerPrint(string.rep(" ", 47))
  3203.                 print("")
  3204.  
  3205.                 term.setBackgroundColor(colors[theme["bottom-box"]])
  3206.                 for i = 1, 10 do centerPrint(string.rep(" ", 47)) end
  3207.                 local a = tostring(math.random(1000, 9999))
  3208.                 term.setCursorPos(5, 8)
  3209.                 write("This is for security purposes: " .. a)
  3210.                 term.setCursorPos(5, 9)
  3211.                 write("Enter the 4 numbers above: ")
  3212.                 local b = webmodRead(nil, nil, 4, true)
  3213.                 if b == nil then
  3214.                     os.queueEvent(event_exitWebsite)
  3215.                     return
  3216.                 end
  3217.  
  3218.                 if b == a then
  3219.                     term.setCursorPos(5, 11)
  3220.                     write("Save As: /")
  3221.                     local c = webmodRead(nil, nil, w - 18, false)
  3222.                     if c ~= "" and c ~= nil then
  3223.                         c = "/" .. c
  3224.                         local f = io.open(c, "w")
  3225.                         f:write(data)
  3226.                         f:close()
  3227.                         term.setCursorPos(5, 13)
  3228.                         centerWrite("Download Successful! Continuing to Website...")
  3229.                         openAddressBar = false
  3230.                         sleep(1.1)
  3231.                         openAddressBar = true
  3232.  
  3233.                         clearPage(website, colors.black)
  3234.                         term.setCursorPos(1, 2)
  3235.                         return c
  3236.                     elseif c == nil then
  3237.                         os.queueEvent(event_exitWebsite)
  3238.                         return
  3239.                     end
  3240.                 else
  3241.                     term.setCursorPos(5, 13)
  3242.                     centerWrite("Incorrect! Cancelling Download...")
  3243.                     openAddressBar = false
  3244.                     sleep(1.1)
  3245.                     openAddressBar = true
  3246.                 end
  3247.             elseif opt == "Cancel" then
  3248.                 term.setCursorPos(1, 15)
  3249.                 centerWrite("Download Canceled!")
  3250.                 openAddressBar = false
  3251.                 sleep(1.1)
  3252.                 openAddressBar = true
  3253.             elseif opt == nil then
  3254.                 os.queueEvent(event_exitWebsite)
  3255.                 return
  3256.             end
  3257.  
  3258.             clearPage(website, colors.black)
  3259.             term.setCursorPos(1, 2)
  3260.             return nil
  3261.         end
  3262.  
  3263.         nenv.pastebinDownload = function(code)
  3264.             return nenv.urlDownload("http://pastebin.com/raw.php?i=" .. code)
  3265.         end
  3266.  
  3267.         -- Run
  3268.         local fn, err = env.loadfile(cacheLoc)
  3269.         if fn and not(err) then
  3270.             env.setfenv(fn, nenv)
  3271.             _, err = env.pcall(fn)
  3272.             env.setfenv(1, backupEnv)
  3273.         end
  3274.  
  3275.         -- Catch website error
  3276.         if err and not(err:find(event_exitWebsite)) then errPages.crash(err) end
  3277.         if queueWebsiteExit then os.queueEvent(event_exitWebsite) end
  3278.     end
  3279.  
  3280.     local function allowFunctions(offences)
  3281.         local function appendTable(tableData, addTable, tableName, ignore, overrideFunc)
  3282.             if not(tableData[tableName]) then tableData[tableName] = {} end
  3283.             for k, v in pairs(addTable) do
  3284.                 if ignore then
  3285.                     if ignore ~= k then
  3286.                         if overrideFunc then
  3287.                             tableData[tableName][k] = function()
  3288.                                 env.error("Firewolf Antivirus: Unauthorized Function") end
  3289.                         else
  3290.                             tableData[tableName][k] = v
  3291.                         end
  3292.                     end
  3293.                 else
  3294.                     if overrideFunc then
  3295.                         tableData[tableName][k] = function()
  3296.                             env.error("Firewolf Antivirus: Unauthorized Function") end
  3297.                     else
  3298.                         tableData[tableName][k] = v
  3299.                     end
  3300.                 end
  3301.             end
  3302.             return tableData
  3303.         end
  3304.  
  3305.         local returnTable = appendTable({}, os, "os", nil, true)
  3306.         returnTable = appendTable(returnTable, fs, "fs", nil, true)
  3307.         returnTable = appendTable(returnTable, io, "io", nil, true)
  3308.         returnTable = appendTable(returnTable, shell, "shell", nil, true)
  3309.         shellAllowed = false
  3310.         returnTable["loadfile"] = function()
  3311.                 env.error("Firewolf Antivirus: Unauthorized Function") end
  3312.         returnTable["loadstring"] = function()
  3313.                 env.error("Firewolf Antivirus: Unauthorized Function") end
  3314.         returnTable["dofile"] = function()
  3315.                 env.error("Firewolf Antivirus: Unauthorized Function") end
  3316.         returnTable["getfenv"] = function()
  3317.                 env.error("Firewolf Antivirus: Unauthorized Function") end
  3318.         returnTable["setfenv"] = function()
  3319.                 env.error("Firewolf Antivirus: Unauthorized Function") end
  3320.         returnTable["rawset"] = function()
  3321.                 env.error("Firewolf Antivirus: Unauthorized Function") end
  3322.  
  3323.         returnTable = appendTable(returnTable, os, "os", "run")
  3324.         for k, v in pairs(offences) do
  3325.             if v == "Modify Files" then
  3326.                 returnTable = appendTable(returnTable, io, "io")
  3327.                 returnTable = appendTable(returnTable, fs, "fs")
  3328.             elseif v == "Run Files" then
  3329.                 returnTable = appendTable(returnTable, os, "os")
  3330.                 returnTable = appendTable(returnTable, shell, "shell")
  3331.                 shellAllowed = true
  3332.                 returnTable["loadfile"] = loadfile
  3333.                 returnTable["dofile"] = dofile
  3334.             elseif v == "Execute Text" then
  3335.                 returnTable["loadstring"] = loadstring
  3336.             elseif v == "Modify Env" then
  3337.                 returnTable["getfenv"] = getfenv
  3338.                 returnTable["setfenv"] = setfenv
  3339.             elseif v == "Modify Anything" then
  3340.                 returnTable["rawset"] = rawset
  3341.             end
  3342.         end
  3343.  
  3344.         return returnTable
  3345.     end
  3346.  
  3347.     -- Draw
  3348.     openAddressBar = false
  3349.     clearPage(site, colors[theme["background"]])
  3350.     term.setTextColor(colors[theme["text-color"]])
  3351.     term.setBackgroundColor(colors[theme["background"]])
  3352.     print("\n\n")
  3353.     centerWrite("Getting DNS Listing...")
  3354.     internalWebsite = true
  3355.  
  3356.     -- Redirection bots
  3357.     loadingRate = loadingRate + 1
  3358.     term.clearLine()
  3359.     centerWrite("Getting Website...")
  3360.  
  3361.     -- Get website
  3362.     local id, content, status = curProtocol.getWebsite(site)
  3363.     term.clearLine()
  3364.     centerWrite("Processing Website...")
  3365.  
  3366.     -- Display website
  3367.     local cacheLoc = cacheFolder .. "/" .. site:gsub("/", "$slazh$")
  3368.     local antivirusProcessed = false
  3369.     local antivirusEnv = {}
  3370.     if id ~= nil and status ~= nil then
  3371.         openAddressBar = true
  3372.         if status == "antivirus" then
  3373.             local offences = verify("antivirus offences", content)
  3374.             if #offences > 0 then
  3375.                 antivirusProcessed = true
  3376.                 clearPage(site, colors[theme["background"]])
  3377.                 print("")
  3378.                 term.setTextColor(colors[theme["text-color"]])
  3379.                 term.setBackgroundColor(colors[theme["top-box"]])
  3380.                 centerPrint(string.rep(" ", 47))
  3381.                 centerWrite(string.rep(" ", 47))
  3382.                 centerPrint("Antivirus Triggered!")
  3383.                 centerPrint(string.rep(" ", 47))
  3384.                 print("")
  3385.  
  3386.                 term.setBackgroundColor(colors[theme["bottom-box"]])
  3387.                 centerPrint(string.rep(" ", 47))
  3388.                 centerPrint("  The antivirus has been triggered on this     ")
  3389.                 centerPrint("  website! Do you want to give this website    ")
  3390.                 centerPrint("  permissions to:                              ")
  3391.                 for i = 1, 8 do centerPrint(string.rep(" ", 47)) end
  3392.                 for i, v in ipairs(offences) do
  3393.                     if i > 3 then term.setCursorPos(w - 21, i + 8)
  3394.                     else term.setCursorPos(6, i + 11) end
  3395.                     write("[ " .. v)
  3396.                 end
  3397.                 while true do
  3398.                     local opt = prompt({{"Allow", 5, 17}, {"Cancel", 17, 17}, {"View Source", 31, 17}},
  3399.                             "horizontal")
  3400.                     if opt == "Allow" then
  3401.                         antivirusEnv = allowFunctions(offences)
  3402.                         status = "safe"
  3403.                         break
  3404.                     elseif opt == "Cancel" then
  3405.                         clearPage(site, colors[theme["background"]])
  3406.                         print("")
  3407.                         term.setTextColor(colors[theme["text-color"]])
  3408.                         term.setBackgroundColor(colors[theme["top-box"]])
  3409.                         centerPrint(string.rep(" ", 47))
  3410.                         centerWrite(string.rep(" ", 47))
  3411.                         centerPrint("O Noes!")
  3412.                         centerPrint(string.rep(" ", 47))
  3413.                         print("")
  3414.  
  3415.                         term.setBackgroundColor(colors[theme["bottom-box"]])
  3416.                         centerPrint(string.rep(" ", 47))
  3417.                         centerPrint("         ______                          __    ")
  3418.                         centerPrint("        / ____/_____ _____ ____   _____ / /    ")
  3419.                         centerPrint("       / __/  / ___// ___// __ \\ / ___// /     ")
  3420.                         centerPrint("      / /___ / /   / /   / /_/ // /   /_/      ")
  3421.                         centerPrint("     /_____//_/   /_/    \\____//_/   (_)       ")
  3422.                         centerPrint(string.rep(" ", 47))
  3423.                         centerPrint("  Could not connect to the website! The        ")
  3424.                         centerPrint("  website was not given enough permissions to  ")
  3425.                         centerPrint("  execute properly!                            ")
  3426.                         centerPrint(string.rep(" ", 47))
  3427.                         break
  3428.                     elseif opt == "View Source" then
  3429.                         local f = io.open(rootFolder .. "/temp-source", "w")
  3430.                         f:write(content)
  3431.                         f:close()
  3432.                         openAddressBar = false
  3433.                         shell.run("edit", rootFolder .. "/temp-source")
  3434.                         fs.delete(rootFolder .. "/temp-source")
  3435.                         clearPage(site, colors[theme["background"]])
  3436.                         print("")
  3437.                         term.setTextColor(colors[theme["text-color"]])
  3438.                         term.setBackgroundColor(colors[theme["top-box"]])
  3439.                         centerPrint(string.rep(" ", 47))
  3440.                         centerWrite(string.rep(" ", 47))
  3441.                         centerPrint("Antivirus Triggered!")
  3442.                         centerPrint(string.rep(" ", 47))
  3443.                         print("")
  3444.  
  3445.                         term.setBackgroundColor(colors[theme["bottom-box"]])
  3446.                         centerPrint(string.rep(" ", 47))
  3447.                         centerPrint("  The antivirus has been triggered on this     ")
  3448.                         centerPrint("  website! Do you want to give this website    ")
  3449.                         centerPrint("  permissions to:                              ")
  3450.                         for i = 1, 8 do centerPrint(string.rep(" ", 47)) end
  3451.                         for i, v in ipairs(offences) do
  3452.                             if i > 3 then term.setCursorPos(w - 21, i + 8)
  3453.                             else term.setCursorPos(6, i + 11) end
  3454.                             write("[ " .. v)
  3455.                         end
  3456.                         openAddressBar = true
  3457.                     elseif opt == nil then
  3458.                         os.queueEvent(event_exitWebsite)
  3459.                         return
  3460.                     end
  3461.                 end
  3462.             else
  3463.                 status = "safe"
  3464.             end
  3465.         end
  3466.  
  3467.         if status == "safe" and site ~= "" then
  3468.             if not(antivirusProcessed) then
  3469.                 antivirusEnv = allowFunctions({""})
  3470.             end
  3471.             internalWebsite = false
  3472.             local f = io.open(cacheLoc, "w")
  3473.             f:write(content)
  3474.             f:close()
  3475.             term.clearLine()
  3476.             centerWrite("Running Website...")
  3477.             runSite(cacheLoc, antivirusEnv)
  3478.             return
  3479.         end
  3480.     else
  3481.         if fs.exists(cacheLoc) and site ~= "" and site ~= "." and site ~= ".." and
  3482.                 not(verify("blacklist", site)) then
  3483.             openAddressBar = true
  3484.             clearPage(site, colors[theme["background"]])
  3485.             print("")
  3486.             term.setTextColor(colors[theme["text-color"]])
  3487.             term.setBackgroundColor(colors[theme["top-box"]])
  3488.             centerPrint(string.rep(" ", 47))
  3489.             centerWrite(string.rep(" ", 47))
  3490.             centerPrint("Cache Exists!")
  3491.             centerPrint(string.rep(" ", 47))
  3492.             print("")
  3493.  
  3494.             term.setBackgroundColor(colors[theme["bottom-box"]])
  3495.             centerPrint(string.rep(" ", 47))
  3496.             centerPrint("       ______              __            __    ")
  3497.             centerPrint("      / ____/____ _ _____ / /_   ___    / /    ")
  3498.             centerPrint("     / /    / __ '// ___// __ \\ / _ \\  / /     ")
  3499.             centerPrint("    / /___ / /_/ // /__ / / / //  __/ /_/      ")
  3500.             centerPrint("    \\____/ \\__,_/ \\___//_/ /_/ \\___/ (_)       ")
  3501.             centerPrint(string.rep(" ", 47))
  3502.             centerPrint("  Could not connect to the website! It may be  ")
  3503.             centerPrint("  down, or not exist! A cached version was     ")
  3504.             centerPrint("  found!                                       ")
  3505.             centerPrint(string.rep(" ", 47))
  3506.             centerPrint(string.rep(" ", 47))
  3507.  
  3508.             local opt = prompt({{"Load Cache", 6, 17}, {"Cancel", w - 16, 17}}, "horizontal")
  3509.             if opt == "Load Cache" then
  3510.                 internalWebsite = false
  3511.                 runSite(cacheLoc)
  3512.                 return
  3513.             elseif opt == "Cancel" then
  3514.                 clearPage(site, colors[theme["background"]])
  3515.                 print("\n")
  3516.                 term.setTextColor(colors[theme["text-color"]])
  3517.                 term.setBackgroundColor(colors[theme["top-box"]])
  3518.                 centerPrint(string.rep(" ", 47))
  3519.                 centerWrite(string.rep(" ", 47))
  3520.                 centerPrint("O Noes!")
  3521.                 centerPrint(string.rep(" ", 47))
  3522.                 print("")
  3523.  
  3524.                 term.setBackgroundColor(colors[theme["bottom-box"]])
  3525.                 centerPrint(string.rep(" ", 47))
  3526.                 centerPrint("         ______                          __    ")
  3527.                 centerPrint("        / ____/_____ _____ ____   _____ / /    ")
  3528.                 centerPrint("       / __/  / ___// ___// __ \\ / ___// /     ")
  3529.                 centerPrint("      / /___ / /   / /   / /_/ // /   /_/      ")
  3530.                 centerPrint("     /_____//_/   /_/    \\____//_/   (_)       ")
  3531.                 centerPrint(string.rep(" ", 47))
  3532.                 centerPrint("  Could not connect to the website! The        ")
  3533.                 centerPrint("  cached version was not loaded!               ")
  3534.                 centerPrint(string.rep(" ", 47))
  3535.             elseif opt == nil then
  3536.                 os.queueEvent(event_exitWebsite)
  3537.                 return
  3538.             end
  3539.         else
  3540.             openAddressBar = true
  3541.             local res = {}
  3542.             debugLog("Before",type(res))
  3543.             if site ~= "" then
  3544.                 for k, v in pairs(dnsDatabase[1]) do
  3545.                     if v:find(site:lower()) then
  3546.                         table.insert(res, v)
  3547.                     end
  3548.                 end
  3549.             else
  3550.                 for k,v in pairs(dnsDatabase[1]) do
  3551.                     table.insert(res, v)
  3552.                 end
  3553.             end
  3554.  
  3555.             if #res > 0 then
  3556.                 clearPage(site, colors[theme["background"]])
  3557.                 print("")
  3558.                 term.setTextColor(colors[theme["text-color"]])
  3559.                 term.setBackgroundColor(colors[theme["top-box"]])
  3560.                 centerPrint(string.rep(" ", 47))
  3561.                 centerWrite(string.rep(" ", 47))
  3562.                 if #res == 1 then centerPrint("1 Search Result")
  3563.                 else centerPrint(#res .. " Search Results") end
  3564.                 centerPrint(string.rep(" ", 47))
  3565.                 print("")
  3566.  
  3567.                 term.setBackgroundColor(colors[theme["bottom-box"]])
  3568.                 for i = 1, 12 do centerPrint(string.rep(" ", 47)) end
  3569.                 local opt = scrollingPrompt(res, 4, 8, 10, 43)
  3570.                 if opt then
  3571.                     redirect(opt:gsub("rdnt://", ""))
  3572.                     return
  3573.                 else
  3574.                     os.queueEvent(event_exitWebsite)
  3575.                     return
  3576.                 end
  3577.             elseif site == "" and #res == 0 then
  3578.                 clearPage(site, colors[theme["background"]])
  3579.                 print("\n\n")
  3580.                 term.setTextColor(colors[theme["text-color"]])
  3581.                 term.setBackgroundColor(colors[theme["top-box"]])
  3582.                 centerPrint(string.rep(" ", 47))
  3583.                 centerWrite(string.rep(" ", 47))
  3584.                 centerPrint("No Websites are Currently Online! D:")
  3585.                 centerWrite(string.rep(" ", 47))
  3586.                 centerPrint(string.rep(" ", 47))
  3587.                 centerWrite(string.rep(" ", 47))
  3588.                 centerPrint("Why not make one yourself?")
  3589.                 centerWrite(string.rep(" ", 47))
  3590.                 centerPrint("Visit rdnt://server!")
  3591.                 centerPrint(string.rep(" ", 47))
  3592.                 while true do
  3593.                     local e, p1, p2, p3 = os.pullEvent()
  3594.                     if e == "mouse_click" then
  3595.                         if p2 < 50 and p2 > 2 and p3 > 4 and p3 < 11 then
  3596.                             redirect("server")
  3597.                             break
  3598.                         end
  3599.                     elseif e == event_openAddressBar then
  3600.                         break
  3601.                     end
  3602.                 end
  3603.             else
  3604.                 clearPage(site, colors[theme["background"]])
  3605.                 print("\n")
  3606.                 term.setTextColor(colors[theme["text-color"]])
  3607.                 term.setBackgroundColor(colors[theme["top-box"]])
  3608.                 centerPrint(string.rep(" ", 47))
  3609.                 centerWrite(string.rep(" ", 47))
  3610.                 centerPrint("O Noes!")
  3611.                 centerPrint(string.rep(" ", 47))
  3612.                 print("")
  3613.                 term.setBackgroundColor(colors[theme["bottom-box"]])
  3614.                 centerPrint(string.rep(" ", 47))
  3615.                 centerPrint("         ______                          __    ")
  3616.                 centerPrint("        / ____/_____ _____ ____   _____ / /    ")
  3617.                 centerPrint("       / __/  / ___// ___// __ \\ / ___// /     ")
  3618.                 centerPrint("      / /___ / /   / /   / /_/ // /   /_/      ")
  3619.                 centerPrint("     /_____//_/   /_/    \\____//_/   (_)       ")
  3620.                 centerPrint(string.rep(" ", 47))
  3621.                 if verify("blacklist", id) then
  3622.                     centerPrint("  Could not connect to the website! It has     ")
  3623.                     centerPrint("  been blocked by a database admin!            ")
  3624.                 else
  3625.                     centerPrint("  Could not connect to the website! It may     ")
  3626.                     centerPrint("  be down, or not exist!                       ")
  3627.                 end
  3628.                 centerPrint(string.rep(" ", 47))
  3629.             end
  3630.         end
  3631.     end
  3632. end
  3633.  
  3634.  
  3635. --  -------- Websites
  3636.  
  3637. local function websiteMain()
  3638.     -- Variables
  3639.     local loadingClock = os.clock()
  3640.  
  3641.     -- Main loop
  3642.     while true do
  3643.         -- Reset
  3644.         setfenv(1, backupEnv)
  3645.         browserAgent = browserAgentTemplate
  3646.         clearPage(website)
  3647.         w, h = term.getSize()
  3648.         term.setBackgroundColor(colors.black)
  3649.         term.setTextColor(colors.white)
  3650.  
  3651.         -- Exit
  3652.         if website == "exit" then
  3653.             os.queueEvent(event_exitApp)
  3654.             return
  3655.         end
  3656.  
  3657.         -- Perform Checks
  3658.         local skip = false
  3659.         local oldWebsite = website
  3660.         if not(errPages.checkForModem()) then
  3661.             os.queueEvent(event_exitApp)
  3662.             return
  3663.         end
  3664.         website = oldWebsite
  3665.         if os.clock() - loadingClock > 5 then
  3666.             loadingRate = 0
  3667.             loadingClock = os.clock()
  3668.         elseif loadingRate >= 8 then
  3669.             errPages.overspeed()
  3670.             loadingClock = os.clock()
  3671.             loadingRate = 0
  3672.             skip = true
  3673.         end if not(skip) then
  3674.             -- Add to history
  3675.             appendToHistory(website)
  3676.  
  3677.             -- Render site
  3678.             clearPage(website)
  3679.             term.setBackgroundColor(colors.black)
  3680.             term.setTextColor(colors.white)
  3681.             if pages[website] then
  3682.                 local ex = pages[website](website)
  3683.                 if ex == true then
  3684.                     os.queueEvent(event_exitApp)
  3685.                     return
  3686.                 end
  3687.             else
  3688.                 loadSite(website)
  3689.             end
  3690.         end
  3691.  
  3692.         -- Wait
  3693.         os.pullEvent(event_loadWebsite)
  3694.     end
  3695. end
  3696.  
  3697.  
  3698. --  -------- Address Bar
  3699.  
  3700. local function retrieveSearchResults()
  3701.     curSites = curProtocol.getSearchResults()
  3702.     while true do
  3703.         local e = os.pullEvent()
  3704.         if website ~= "exit" and e == event_loadWebsite then
  3705.             curSites = curProtocol.getSearchResults()
  3706.         elseif e == event_exitApp then
  3707.             os.queueEvent(event_exitApp)
  3708.             return
  3709.         end
  3710.     end
  3711. end
  3712.  
  3713. local function addressBarRead()
  3714.     local len = 4
  3715.     local list = {}
  3716.  
  3717.     local function draw(l)
  3718.         local ox, oy = term.getCursorPos()
  3719.         for i = 1, len do
  3720.             term.setTextColor(colors[theme["address-bar-text"]])
  3721.             term.setBackgroundColor(colors[theme["address-bar-background"]])
  3722.             term.setCursorPos(1, i + 1)
  3723.             write(string.rep(" ", w))
  3724.         end
  3725.         if theme["address-bar-base"] then term.setBackgroundColor(colors[theme["address-bar-base"]])
  3726.         else term.setBackgroundColor(colors[theme["bottom-box"]]) end
  3727.         term.setCursorPos(1, len + 2)
  3728.         write(string.rep(" ", w))
  3729.         term.setBackgroundColor(colors[theme["address-bar-background"]])
  3730.  
  3731.         for i, v in ipairs(l) do
  3732.             term.setCursorPos(2, i + 1)
  3733.             write(v)
  3734.         end
  3735.         term.setCursorPos(ox, oy)
  3736.     end
  3737.  
  3738.     local function onLiveUpdate(cur, e, but, x, y, p4, p5)
  3739.         if e == "char" or e == "update_history" or e == "delete" then
  3740.             list = {}
  3741.             for _, v in pairs(curSites) do
  3742.                 if #list < len and v:gsub("rdnt://", ""):find(cur:lower(), 1, true) then
  3743.                     table.insert(list, v)
  3744.                 end
  3745.             end
  3746.             table.sort(list)
  3747.             table.sort(list, function(a, b)
  3748.                 local _, ac = a:gsub("rdnt://", ""):gsub(cur:lower(), "")
  3749.                 local _, bc = b:gsub("rdnt://", ""):gsub(cur:lower(), "")
  3750.                 return ac > bc
  3751.             end)
  3752.             draw(list)
  3753.             return false, nil
  3754.         elseif e == "mouse_click" then
  3755.             for i = 1, #list do
  3756.                 if y == i + 1 then
  3757.                     return true, list[i]:gsub("rdnt://", "")
  3758.                 end
  3759.             end
  3760.         end
  3761.     end
  3762.  
  3763.     onLiveUpdate("", "delete", nil, nil, nil, nil, nil)
  3764.     return modRead(nil, addressBarHistory, 41, false, onLiveUpdate)
  3765. end
  3766.  
  3767. local function addressBarMain()
  3768.     while true do
  3769.         local e, but, x, y = os.pullEvent()
  3770.         if (e == "key" and (but == 29 or but == 157)) or
  3771.                 (e == "mouse_click" and y == 1) then
  3772.             if openAddressBar then
  3773.                 if e == "key" then x = 45 end
  3774.                 if x == term.getSize() then
  3775.                     menuBarOpen = true
  3776.                     local list = nil
  3777.                     if not(internalWebsite) then
  3778.                         list = "> [- Exit Firewolf -] [- Incorrect Website -]      "
  3779.                     else
  3780.                         list = "> [- Exit Firewolf -]                              "
  3781.                     end
  3782.  
  3783.                     term.setBackgroundColor(colors[theme["top-box"]])
  3784.                     term.setTextColor(colors[theme["text-color"]])
  3785.                     term.setCursorPos(1, 1)
  3786.                     write(list)
  3787.                 elseif menuBarOpen and x == 1 then
  3788.                     menuBarOpen = false
  3789.                     clearPage(website, nil, true)
  3790.                 elseif x < 18 and x > 2 and menuBarOpen then
  3791.                     website = "exit"
  3792.                     menuBarOpen = false
  3793.                     os.queueEvent(event_openAddressBar)
  3794.                     os.queueEvent(event_exitWebsite)
  3795.                     sleep(0.0001)
  3796.                     website = "exit"
  3797.                     os.queueEvent(event_loadWebsite)
  3798.                 elseif x < 38 and x > 18 and not(internalWebsite) and menuBarOpen then
  3799.                     menuBarOpen = false
  3800.                     clearPage("incorrect", colors[theme["background"]])
  3801.                     print("")
  3802.                     term.setBackgroundColor(colors[theme["top-box"]])
  3803.                     term.setTextColor(colors[theme["text-color"]])
  3804.                     centerPrint(string.rep(" ", 47))
  3805.                     centerPrint(string.rep(" ", 47))
  3806.                     centerPrint(string.rep(" ", 47))
  3807.                     term.setCursorPos(1, 4)
  3808.                     centerPrint("Incorrect Website: ID Block")
  3809.                     term.setCursorPos(1, 7)
  3810.                     term.setBackgroundColor(colors[theme["bottom-box"]])
  3811.                     for i = 1, 12 do centerPrint(string.rep(" ", 47)) end
  3812.  
  3813.                     term.setCursorPos(1, 8)
  3814.                     centerPrint("This feature is used to block a server's ID")
  3815.                     centerPrint("if it's intercepting a website")
  3816.                     centerPrint("Ex. You got onto a website you didn't expect")
  3817.                     centerPrint("Managing comming soon!")
  3818.                     --centerPrint("Manage blocked servers at rdnt://settings")
  3819.                     centerPrint("")
  3820.                     centerPrint("You are about to block the server ID: " .. tostring(serverWebsiteID))
  3821.                     local opt = prompt({{"Block", 8, 15}, {"Don't Block", 28, 15}})
  3822.                     if opt == "Block" then
  3823.                         table.insert(blacklist, tostring(serverWebsiteID))
  3824.                         local f = io.open(userBlacklist,"a")
  3825.                         f:write(tostring(serverWebsiteID))
  3826.                         f:close()
  3827.                         centerPrint("")
  3828.                         centerPrint("Server Blocked!")
  3829.                         centerPrint("You may now browse normally!")
  3830.                     else
  3831.                         centerPrint("")
  3832.                         centerPrint("Server Not Blocked!")
  3833.                         centerPrint("You may now browse normally!")
  3834.                     end
  3835.                 elseif not(menuBarOpen) then
  3836.                     internalWebsite = true
  3837.  
  3838.                     -- Exit
  3839.                     os.queueEvent(event_openAddressBar)
  3840.                     os.queueEvent(event_exitWebsite)
  3841.  
  3842.                     -- Read
  3843.                     term.setBackgroundColor(colors[theme["address-bar-background"]])
  3844.                     term.setTextColor(colors[theme["address-bar-text"]])
  3845.                     term.setCursorPos(2, 1)
  3846.                     term.clearLine()
  3847.                     write("rdnt://")
  3848.                     local oldWebsite = website
  3849.                     website = addressBarRead()
  3850.                     if website == nil then
  3851.                         website = oldWebsite
  3852.                     elseif website == "home" or website == "homepage" then
  3853.                         website = homepage
  3854.                     end
  3855.  
  3856.                     -- Load
  3857.                     os.queueEvent(event_loadWebsite)
  3858.                 end
  3859.             end
  3860.         elseif e == event_redirect then
  3861.             if openAddressBar then
  3862.                 -- Redirect
  3863.                 os.queueEvent(event_exitWebsite)
  3864.                 if but == "home" or but == "homepage" then website = homepage
  3865.                 else website = but end
  3866.                 os.queueEvent(event_loadWebsite)
  3867.             end
  3868.         elseif e == event_exitApp then
  3869.             os.queueEvent(event_exitApp)
  3870.             break
  3871.         end
  3872.     end
  3873. end
  3874.  
  3875.  
  3876. --  -------- Main
  3877.  
  3878. local function main()
  3879.     -- Logo
  3880.     term.setBackgroundColor(colors[theme["background"]])
  3881.     term.setTextColor(colors[theme["text-color"]])
  3882.     term.clear()
  3883.     term.setCursorPos(1, 2)
  3884.     term.setBackgroundColor(colors[theme["top-box"]])
  3885.     centerPrint(string.rep(" ", 47))
  3886.     centerPrint([[          ______ ____ ____   ______            ]])
  3887.     centerPrint([[ ------- / ____//  _// __ \ / ____/            ]])
  3888.     centerPrint([[ ------ / /_    / / / /_/ // __/               ]])
  3889.     centerPrint([[ ----- / __/  _/ / / _  _// /___               ]])
  3890.     centerPrint([[ ---- / /    /___//_/ |_|/_____/               ]])
  3891.     centerPrint([[ --- / /       _       __ ____   __     ______ ]])
  3892.     centerPrint([[ -- /_/       | |     / // __ \ / /    / ____/ ]])
  3893.     centerPrint([[              | | /| / // / / // /    / /_     ]])
  3894.     centerPrint([[              | |/ |/ // /_/ // /___ / __/     ]])
  3895.     centerPrint([[              |__/|__/ \____//_____//_/        ]])
  3896.     centerPrint(string.rep(" ", 47))
  3897.     print("\n")
  3898.     term.setBackgroundColor(colors[theme["bottom-box"]])
  3899.  
  3900.     -- Download Files
  3901.     centerPrint(string.rep(" ", 47))
  3902.     centerWrite(string.rep(" ", 47))
  3903.     centerPrint("Downloading Required Files...")
  3904.     centerWrite(string.rep(" ", 47))
  3905.     --if not(verifyGitHub()) then return false end
  3906.     migrateFilesystem()
  3907.     resetFilesystem()
  3908.  
  3909.     -- Download Databases
  3910.     local x, y = term.getCursorPos()
  3911.     term.setCursorPos(1, y - 1)
  3912.     centerWrite(string.rep(" ", 47))
  3913.     centerWrite("Downloading Databases...")
  3914.     --loadDatabases()
  3915.  
  3916.     -- Load Settings
  3917.     centerWrite(string.rep(" ", 47))
  3918.     centerWrite("Loading Data...")
  3919.     local f = io.open(settingsLocation, "r")
  3920.     local a = textutils.unserialize(f:read("*l"))
  3921.     autoupdate = a.auto
  3922.     incognito = a.incog
  3923.     homepage = a.home
  3924.     curProtocol = protocols.rdnt
  3925.     f:close()
  3926.  
  3927.     -- Load history
  3928.     local b = io.open(historyLocation, "r")
  3929.     history = textutils.unserialize(b:read("*l"))
  3930.     b:close()
  3931.  
  3932.     -- Update
  3933.     centerWrite(string.rep(" ", 47))
  3934.     centerWrite("Checking For Updates...")
  3935.     --if autoupdate == "true" then if updateClient() then return false end end
  3936.  
  3937.     -- Modem
  3938.     if not(errPages.checkForModem()) then return false end
  3939.     website = homepage
  3940.  
  3941.     -- Run
  3942.     parallel.waitForAll(websiteMain, addressBarMain, retrieveSearchResults)
  3943.  
  3944.     return false
  3945. end
  3946.  
  3947. local skipExit = false
  3948. local function startup()
  3949.     -- HTTP API
  3950.     if not(http) then
  3951.         term.setTextColor(colors[theme["text-color"]])
  3952.         term.setBackgroundColor(colors[theme["background"]])
  3953.         term.clear()
  3954.         term.setCursorPos(1, 2)
  3955.         term.setBackgroundColor(colors[theme["top-box"]])
  3956.         api.centerPrint(string.rep(" ", 47))
  3957.         api.centerWrite(string.rep(" ", 47))
  3958.         api.centerPrint("HTTP API Not Enabled! D:")
  3959.         api.centerPrint(string.rep(" ", 47))
  3960.         print("")
  3961.  
  3962.         term.setBackgroundColor(colors[theme["bottom-box"]])
  3963.         api.centerPrint(string.rep(" ", 47))
  3964.         api.centerPrint("  Firewolf is unable to run without the HTTP   ")
  3965.         api.centerPrint("  API Enabled! Please enable it in the CC      ")
  3966.         api.centerPrint("  Config!                                      ")
  3967.         api.centerPrint(string.rep(" ", 47))
  3968.  
  3969.         api.centerPrint(string.rep(" ", 47))
  3970.         api.centerWrite(string.rep(" ", 47))
  3971.         if isAdvanced() then api.centerPrint("Click to exit...")
  3972.         else api.centerPrint("Press any key to exit...") end
  3973.         api.centerPrint(string.rep(" ", 47))
  3974.  
  3975.         while true do
  3976.             local e, but, x, y = os.pullEvent()
  3977.             if e == "mouse_click" or e == "key" then break end
  3978.         end
  3979.  
  3980.         return false
  3981.     end
  3982.  
  3983.     -- Turtle
  3984.     if turtle then
  3985.         term.clear()
  3986.         term.setCursorPos(1, 2)
  3987.         api.centerPrint("Advanced Comptuer Required!")
  3988.         print("\n")
  3989.         api.centerPrint("  This version of Firewolf requires  ")
  3990.         api.centerPrint("  an Advanced Comptuer to run!       ")
  3991.         print("")
  3992.         api.centerPrint("  Turtles may not be used to run     ")
  3993.         api.centerPrint("  Firewolf! :(                       ")
  3994.         print("")
  3995.         api.centerPrint("Press any key to exit...")
  3996.  
  3997.         os.pullEvent("key")
  3998.         return false
  3999.     end
  4000.  
  4001.     -- Run
  4002.     local _, err = pcall(function() skipExit = main() end)
  4003.     if err ~= nil then
  4004.         term.setTextColor(colors[theme["text-color"]])
  4005.         term.setBackgroundColor(colors[theme["background"]])
  4006.         term.clear()
  4007.         term.setCursorPos(1, 2)
  4008.         term.setCursorBlink(false)
  4009.         term.setBackgroundColor(colors[theme["top-box"]])
  4010.         api.centerPrint(string.rep(" ", 47))
  4011.         api.centerWrite(string.rep(" ", 47))
  4012.         api.centerPrint("Firewolf has Crashed! D:")
  4013.         api.centerPrint(string.rep(" ", 47))
  4014.         print("")
  4015.         term.setBackgroundColor(colors[theme["background"]])
  4016.         print("")
  4017.         print("  " .. err)
  4018.         print("")
  4019.  
  4020.         term.setBackgroundColor(colors[theme["bottom-box"]])
  4021.         api.centerPrint(string.rep(" ", 47))
  4022.         if autoupdate == "true" then
  4023.             api.centerPrint("  Please report this error to 1lann or         ")
  4024.             api.centerPrint("  GravityScore so we are able to fix it!       ")
  4025.             api.centerPrint("  If this problem persists, try deleting       ")
  4026.             api.centerPrint("  " .. rootFolder .. "                              ")
  4027.         else
  4028.             api.centerPrint("  Automatic updating is off! A new version     ")
  4029.             api.centerPrint("  may have have been released, which could     ")
  4030.             api.centerPrint("  fix this problem!                            ")
  4031.             api.centerPrint("  If you didn't intend to turn auto-updating   ")
  4032.             api.centerPrint("  off, delete " .. rootFolder .. "                  ")
  4033.         end
  4034.         api.centerPrint(string.rep(" ", 47))
  4035.         api.centerWrite(string.rep(" ", 47))
  4036.         if isAdvanced() then api.centerPrint("Click to exit...")
  4037.         else api.centerPrint("Press any key to exit...") end
  4038.         api.centerPrint(string.rep(" ", 47))
  4039.  
  4040.         while true do
  4041.             local e, but, x, y = os.pullEvent()
  4042.             if e == "mouse_click" or e == "key" then break end
  4043.         end
  4044.  
  4045.         return false
  4046.     end
  4047.  
  4048.     return true
  4049. end
  4050.  
  4051. -- Theme
  4052. if not(isAdvanced()) then
  4053.     theme = originalTheme
  4054. else
  4055.     theme = loadTheme(themeLocation)
  4056.     if theme == nil then theme = defaultTheme end
  4057. end
  4058.  
  4059. -- Debugging
  4060. if #tArgs > 0 and tArgs[1] == "debug" then
  4061.     term.setTextColor(colors[theme["text-color"]])
  4062.     term.setBackgroundColor(colors[theme["background"]])
  4063.     term.clear()
  4064.     term.setCursorPos(1, 4)
  4065.     api.centerPrint(string.rep(" ", 43))
  4066.     api.centerWrite(string.rep(" ", 43))
  4067.     api.centerPrint("Debug Mode Enabled...")
  4068.     api.centerPrint(string.rep(" ", 43))
  4069.  
  4070.     if fs.exists(debugLogLocation) then debugFile = io.open(debugLogLocation, "a")
  4071.     else debugFile = io.open(debugLogLocation, "w") end
  4072.     debugFile:write("\n-- [" .. textutils.formatTime(os.time()) .. "] New Log --")
  4073.     sleep(1.3)
  4074. end
  4075.  
  4076. -- Start
  4077. startup()
  4078.  
  4079. -- Exit Message
  4080. if isAdvanced() then
  4081.     term.setBackgroundColor(colors.black)
  4082.     term.setTextColor(colors.white)
  4083. end
  4084. term.setCursorBlink(false)
  4085. term.clear()
  4086. term.setCursorPos(1, 1)
  4087.  
  4088. if fs.exists("/.bustedOs") and not(skipExit) then
  4089.     term.setBackgroundColor(colors[theme["background"]])
  4090.     term.setTextColor(colors[theme["text-color"]])
  4091.     term.clear()
  4092.     term.setCursorPos(1, 5)
  4093.     term.setBackgroundColor(colors[theme["top-box"]])
  4094.     api.centerPrint(string.rep(" ", 43))
  4095.     api.centerWrite(string.rep(" ", 43))
  4096.     api.centerPrint("Thank You for Using Firewolf " .. version)
  4097.     api.centerWrite(string.rep(" ", 43))
  4098.     api.centerPrint("Made by 1lann and GravityScore")
  4099.     api.centerPrint(string.rep(" ", 43))
  4100.     api.centerWrite(string.rep(" ", 43))
  4101.     if isAdvanced() then api.centerPrint("Click to exit...")
  4102.     else api.centerPrint("Press any key to exit...") end
  4103.     api.centerPrint(string.rep(" ", 43))
  4104.  
  4105.     while true do
  4106.         local e = os.pullEvent()
  4107.         if e == "mouse_click" or e == "key" then break end
  4108.     end
  4109.  
  4110.     term.setTextColor(colors.white)
  4111.     term.setBackgroundColor(colors.black)
  4112.     term.clear()
  4113.     term.setCursorPos(1, 1)
  4114. elseif not(skipExit) then
  4115.     api.centerPrint("Thank You for Using Firewolf " .. version)
  4116.     api.centerPrint("Made by 1lann and GravityScore")
  4117.     term.setCursorPos(1, 3)
  4118. end
  4119.  
  4120. -- Closes
  4121. for _, v in pairs(rs.getSides()) do rednet.close(v) end
  4122. if debugFile then debugFile:close() end
  4123.  
  4124. -- Reset Environment
  4125. setfenv(1, oldEnv)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement