Advertisement
GravityScore

Firewolf 2.3.9

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