dannysmc95

Discover Store (V6.0)

Sep 15th, 2015
1,771
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 190.74 KB | None | 0 0
  1. --[[
  2.     Name: Discover App Store
  3.     Author: DannySMc (dannysmc95)
  4.     Requirements: HTTP, Colour, Whitelist dannysmc.com/ in the HTTP config.
  5. ]]
  6.  
  7. -- Set variables
  8. tArgs = { ... }
  9. os.getEvent = os.pullEvent
  10. os.pullEvent = os.pullEventRaw
  11.  
  12. system = {
  13.     ["name"] = "Discover Store";
  14.     ["auth"] = "DannySMc (dannysmc95)";
  15.     ["paths"] = {
  16.         ["config"] = ".DiscoverConfig";
  17.         ["plugins"] = "/DPlugins/";
  18.     };
  19.     ["plugins"] = true;
  20.     ["storeconfig"] = true;
  21.     ["lock_program"] = false;
  22.     ["storeuser"] = true;
  23. }
  24.  
  25. -- Used for applications to send data between each other
  26. temp = {}
  27.  
  28. local side_scroll = 0
  29. local viewapps = {}
  30.  
  31. -- Create Discover Object
  32. discover = {
  33.     data = {
  34.         username = nil;
  35.         password = nil;
  36.         authkey = nil;
  37.         errormsg = nil;
  38.         cmessage = nil;
  39.         loggedin = false;
  40.         urls = {
  41.             user = "http://api.dannysmc.com/user.php";
  42.             store = "http://api.dannysmc.com/store.php";
  43.             projects = "http://api.dannysmc.com/projects.php";
  44.         };
  45.         apps = {};
  46.         versions = {};
  47.         categories = {};
  48.         snippets = {};
  49.         snippets_user = {};
  50.         notifications = {};
  51.         version = "6.0";
  52.         build = "332";
  53.         version_api = "5.1.8:311";
  54.         newupdate = nil;
  55.         mail = {};
  56.         feed = {};
  57.     };
  58.     -- Project Check
  59.     get_update = function( self )
  60.         local uniqueid = "db613a9197c76e8f0fd61cd67547920a3805ee380aabee241298d3379c7c0dcddc0b5c411ee393615f142f750e8bfdc349720782a4d07cde4e083147a4149d20"
  61.         local query = "command=check_update&uniqueid="..textutils.urlEncode(tostring(uniqueid)).."&version="..textutils.urlEncode(tostring(self.data.version))
  62.         local req = http.post(self.data.urls.projects, query)
  63.         req = textutils.unserialize(req.readAll())
  64.         if req.status then
  65.             local url = req.url
  66.  
  67.             local dat = http.get(url)
  68.             self.data.newupdate = dat.readAll()
  69.             return true
  70.         else
  71.             return false
  72.         end
  73.     end;
  74.     -- Set Username and Password
  75.     set = function( self, username, password )
  76.         self.data.username = username
  77.         self.data.password = base.crypto.sha256(password)
  78.         return true
  79.     end;
  80.     -- Get function to return a certain bit of information
  81.     get = function ( self, name )
  82.         return self.data[name]
  83.     end;
  84.     report = function( self, data )
  85.         local query = "cmd=report_bug&data=" .. tostring(textutils.serialize(data))
  86.         local req = http.post(self.data.urls.store, query)
  87.         req = textutils.unserialize(req.readAll())
  88.         if req.status then
  89.             return true
  90.         else
  91.             return unpack({false, req.error})
  92.         end
  93.     end;
  94.     -- Main login function to get authkey
  95.     login = function( self, username, password )
  96.         if username then
  97.             self.data.username = username
  98.         end
  99.         if password then
  100.             self.data.password = password
  101.         end
  102.         if self.data.username and self.data.password then
  103.             local query = "cmd=login&username="..textutils.urlEncode(tostring(self.data.username)).."&password="..textutils.urlEncode(tostring(self.data.password))
  104.             local res = http.post(self.data.urls.user, query)
  105.             res = textutils.unserialize(res.readAll())
  106.             if res.status == true then
  107.                 self.data.authkey = res.authkey
  108.                 self.data.loggedin = true;
  109.                 return true
  110.             elseif res.status == false then
  111.                 self.data.errormsg = res.error
  112.                 return false
  113.             end
  114.         else
  115.             return false
  116.         end
  117.     end;
  118.     -- Registration
  119.     register = function( self, username, password, email )
  120.         if username and password and email then
  121.             local query = "cmd=register&username="..textutils.urlEncode(tostring(username)).."&password="..textutils.urlEncode(tostring(password)).."&email="..textutils.urlEncode(tostring(email))
  122.             local req = http.post(self.data.urls.user, query)
  123.             req = textutils.unserialize(req.readAll())
  124.             if req.status then
  125.                 self.data.cmessage = tostring(req.message)
  126.                 return true
  127.             else
  128.                 self.data.errormsg = req.error
  129.                 return false
  130.             end
  131.         else
  132.             self.data.errormsg = "Please supply a username, password and email!"
  133.             return false
  134.         end
  135.     end;
  136.     -- Log out user
  137.     logout = function( self )
  138.         local req = http.post(self.data.urls.user, "cmd=logout&authkey="..textutils.urlEncode(tostring(self.data.authkey)))
  139.         req = textutils.unserialize(req.readAll())
  140.         if req.status then
  141.             discover.data.loggedin = false
  142.             discover.data.username = nil
  143.             discover.data.password = nil
  144.             discover.data.authkey = nil
  145.             self.data.cmessage = req.message
  146.             return true
  147.         else
  148.             self.data.errormsg = req.error
  149.             return false
  150.         end
  151.     end;
  152.     -- Check if a authkey is still valid
  153.     validate = function( self )
  154.         if self.data.authkey then
  155.             local query = "cmd=validate&authkey="..textutils.urlEncode(tostring(self.data.authkey))
  156.             local res = http.post(self.data.urls.user, query)
  157.             res = textutils.unserialize(res.readAll())
  158.             if res.status == true then
  159.                 self.data.cmessage = res.message
  160.                 self.data.loggedin = true;
  161.                 return true
  162.             elseif res.status == false then
  163.                 self.data.errormsg = res.error
  164.                 return false
  165.             end
  166.         else
  167.             return false
  168.         end
  169.     end;
  170.     store_init = function( self )
  171.         local ret = http.post(self.data.urls.store, "cmd=list_apps")
  172.         ret = textutils.unserialize(ret.readAll())
  173.         if ret.status == true then
  174.             self.data.apps = ret.data
  175.         else
  176.             return false
  177.         end
  178.  
  179.         local ret = http.post(self.data.urls.store, "cmd=list_categories")
  180.         ret = textutils.unserialize(ret.readAll())
  181.         if ret.status == true then
  182.             self.data.categories = ret.data
  183.         else
  184.             return false
  185.         end
  186.  
  187.         local ret = http.post(self.data.urls.store, "cmd=list_versions")
  188.         ret = textutils.unserialize(ret.readAll())
  189.         if ret.status == true then
  190.             self.data.versions = ret.data
  191.         else
  192.             return false
  193.         end
  194.  
  195.         if self.data.loggedin then
  196.             if not discover:view_n() then
  197.                 return unpack({false, "Could not obtain notifications"})
  198.             end
  199.         end
  200.  
  201.         local ret = http.post(self.data.urls.store, "cmd=list_versions")
  202.         ret = textutils.unserialize(ret.readAll())
  203.         if ret.status == true then
  204.             self.data.versions = ret.data
  205.         else
  206.             return false
  207.         end
  208.    
  209.         return true
  210.     end;
  211.     store_comments_get = function( self, appid )
  212.         local query = "cmd=view_comments&appid="..textutils.urlEncode(tostring(appid))
  213.         local req = http.post(self.data.urls.store, query)
  214.         req = textutils.unserialize(req.readAll())
  215.         if req.status == true then
  216.             discover.data.cmessage = "Successful"
  217.             discover.data.comments = req.data
  218.             return true
  219.         else
  220.             discover.data.errormsg = req.error
  221.             return false
  222.         end
  223.     end;
  224.     store_comments_set = function( self, appid, comment )
  225.         local query = "cmd=add_comment&appid="..textutils.urlEncode(tostring(appid)).."&comment="..textutils.urlEncode(tostring(comment)).."&authkey="..textutils.urlEncode(tostring(self.data.authkey))
  226.         local req = http.post(self.data.urls.store, query)
  227.         req = textutils.unserialize(req.readAll())
  228.         if req.status then
  229.             self.data.cmessage = req.message
  230.             return true
  231.         else
  232.             self.data.errormsg = req.error
  233.             return false
  234.         end
  235.     end;
  236.     store_download = function( self, appid )
  237.         local query = "cmd=download&appid="..textutils.urlEncode(tostring(appid))
  238.         local req = http.post(self.data.urls.store, query)
  239.         return req
  240.     end;
  241.     store_upload = function ( self, appname, appdesc, appcate, appvers, appstat, appdata )
  242.         local query = "cmd=upload&authkey="..textutils.urlEncode(tostring(self.data.authkey)).."&name="..textutils.urlEncode(tostring(appname)).."&desc="..textutils.urlEncode(tostring(appdesc)).."&vers="..textutils.urlEncode(tostring(appvers)).."&cate="..textutils.urlEncode(tostring(appcate)).."&status="..textutils.urlEncode(tostring(appstat)).."&data="..textutils.urlEncode(tostring(appdata))
  243.         local req = http.post(self.data.urls.store, query)
  244.         req = textutils.unserialize(req.readAll())
  245.         if req.status then
  246.             self.data.cmessage = req.message
  247.             return true
  248.         else
  249.             self.data.errormsg = req.error
  250.             return false
  251.         end
  252.     end;
  253.     store_update = function( self, appid, vers, stat, data )
  254.         if appid and vers and stat and data then
  255.             local query = "cmd=update&authkey="..textutils.urlEncode(tostring(self.data.authkey)).."&appid="..textutils.urlEncode(tostring(appid)).."&vers="..textutils.urlEncode(tostring(vers)).."&status="..textutils.urlEncode(tostring(stat)).."&data="..textutils.urlEncode(tostring(data))
  256.             local req = http.post(self.data.urls.store, query)
  257.             req = textutils.unserialize(req.readAll())
  258.             if req.status then
  259.                 self.data.cmessage = tostring(req.message)
  260.                 return true
  261.             else
  262.                 self.data.errormsg = tostring(req.error)
  263.                 return false
  264.             end
  265.         else
  266.             self.data.errormsg = "Please fill in all fields"
  267.             return false
  268.         end
  269.     end;
  270.     store_apps_user = function( self, username )
  271.         if not username then
  272.             query = "cmd=list_apps_user&authkey="..textutils.urlEncode(tostring(self.data.authkey))
  273.         else
  274.             query = "cmd=list_apps_user&authkey="..textutils.urlEncode(tostring(self.data.authkey)).."&username="..textutils.urlEncode(tostring(username))
  275.         end
  276.         local req = http.post(self.data.urls.store, query)
  277.         req = textutils.unserialize(req.readAll())
  278.         if req.status then
  279.             discover.data.appsuser = req.data
  280.             return true
  281.         else
  282.             discover.data.errormsg = req.error
  283.             return false
  284.         end
  285.     end;
  286.     store_edit = function( self, appid, name, desc, cate, stat )
  287.         if appid and name and desc and stat and cate then
  288.             local query = "cmd=edit&authkey="..textutils.urlEncode(tostring(self.data.authkey)).."&appid="..textutils.urlEncode(tostring(appid)).."&status="..textutils.urlEncode(tostring(stat)).."&name="..textutils.urlEncode(tostring(name)).."&desc="..textutils.urlEncode(tostring(desc)).."&category="..textutils.urlEncode(tostring(cate))
  289.             local req = http.post(self.data.urls.store, query)
  290.             req = textutils.unserialize(req.readAll())
  291.             if req.status then
  292.                 self.data.cmessage = tostring(req.message)
  293.                 return true
  294.             else
  295.                 self.data.errormsg = req.error
  296.                 return false
  297.             end
  298.         else
  299.             self.data.errormsg = "Please fill in all fields"
  300.             return false
  301.         end
  302.     end;
  303.     store_delete = function( self, appid )
  304.         if appid then
  305.             local query = "cmd=delete&authkey="..textutils.urlEncode(tostring(self.data.authkey)).."&appid="..textutils.urlEncode(tostring(appid))
  306.             local req = http.post(self.data.urls.store, query)
  307.             req = textutils.unserialize(req.readAll())
  308.             if req.status then
  309.                 self.data.cmessage = tostring(req.message)
  310.                 return true
  311.             else
  312.                 self.data.errormsg = req.error
  313.                 return false
  314.             end
  315.         else
  316.             self.data.errormsg = "Please fill in all fields"
  317.             return false
  318.         end
  319.     end;
  320.     snippets_list = function( self )
  321.         local query = "cmd=snippets_view"
  322.         local req = http.post(self.data.urls.store, query)
  323.         req = textutils.unserialize(req.readAll())
  324.         if req.status then
  325.             self.data.cmessage = tostring(req.message)
  326.             self.data.snippets = req.data
  327.             return true
  328.         else
  329.             self.data.errormsg = req.error
  330.             return false
  331.         end
  332.     end;
  333.     snippets_download = function( self, snipid )
  334.         local query = "cmd=snippets_download&id="..textutils.urlEncode(tostring(snipid))
  335.         local req = http.post(self.data.urls.store, query)
  336.         req = req.readAll()
  337.         return req
  338.     end;
  339.     snippets_list_user = function( self )
  340.         self.data.snippets_user = nil
  341.         local query = "cmd=snippets_list_user&key="..textutils.urlEncode(tostring(discover.data.authkey))
  342.         local req = http.post(self.data.urls.store, query)
  343.         req = textutils.unserialize(req.readAll())
  344.         if req.status then
  345.             self.data.cmessage = tostring(req.message)
  346.             self.data.snippets_user = req.data
  347.             return true
  348.         else
  349.             self.data.errormsg = req.error
  350.             return false
  351.         end
  352.     end;
  353.     snippets_delete = function( self, id )
  354.         local query = "cmd=snippets_delete&id="..textutils.urlEncode(tostring(id)).."&key="..textutils.urlEncode(tostring(self.data.authkey))
  355.         local req = http.post(self.data.urls.store, query)
  356.         req = textutils.unserialize(req.readAll())
  357.         if req.status then
  358.             self.data.cmessage = tostring(req.message)
  359.             return true
  360.         else
  361.             self.data.errormsg = req.error
  362.             return false
  363.         end
  364.     end;
  365.     snippets_upload = function( self, name, desc, vers, stat, path )
  366.         local f = fs.open(path, "r")
  367.         tdata = f.readAll()
  368.         f.close()
  369.         local query = "cmd=snippets_upload&auth="..textutils.urlEncode(tostring(self.data.authkey)).."&name="..textutils.urlEncode(tostring(name)).."&desc="..textutils.urlEncode(tostring(vers)).."&vers="..textutils.urlEncode(tostring(vers)).."&stat="..textutils.urlEncode(tostring(stat)).."&data="..textutils.urlEncode(tostring(tdata))
  370.         local req = http.post(self.data.urls.store, query)
  371.         req = textutils.unserialize(req.readAll())
  372.         if req.status then
  373.             self.data.cmessage = tostring(req.message)
  374.             return true
  375.         else
  376.             self.data.errormsg = req.error
  377.             return false
  378.         end
  379.     end;
  380.     view_n = function( self )
  381.         local query = "cmd=notifications_view&key="..textutils.urlEncode(tostring(discover.data.authkey))
  382.         local req = http.post(self.data.urls.store, query)
  383.         req = textutils.unserialize(req.readAll())
  384.         if req.status then
  385.             self.data.cmessage = tostring(req.message)
  386.             self.data.notifications = req.data
  387.             return true
  388.         else
  389.             self.data.errormsg = req.error
  390.             return false
  391.         end
  392.     end;
  393.     delete_n = function( self, id )
  394.         if not id then
  395.             return false
  396.         end
  397.         local query = "cmd=notifications_delete&id="..textutils.urlEncode(tostring(id)).."&key="..textutils.urlEncode(tostring(discover.data.authkey))
  398.         local req = http.post(self.data.urls.store, query)
  399.         req = textutils.unserialize(req.readAll())
  400.         if req.status then
  401.             self.data.cmessage = tostring(req.message)
  402.             return true
  403.         else
  404.             self.data.errormsg = req.error
  405.             return false
  406.         end
  407.     end;
  408.     get_stats = function( self )
  409.         local query = "cmd=get_stats&key="..textutils.urlEncode(tostring(discover.data.authkey))
  410.         local req = http.post(self.data.urls.store, query)
  411.         req = textutils.unserialize(req.readAll())
  412.         if req.status then
  413.             self.data.cmessage = tostring(req.message)
  414.             return req.data
  415.         else
  416.             self.data.errormsg = req.error
  417.             return false
  418.         end
  419.     end;
  420.     cloud_get = function( self )
  421.         local query = "cmd=cloud_get&key="..textutils.urlEncode(tostring(discover.data.authkey))
  422.         local req = http.post(self.data.urls.store, query)
  423.         req = textutils.unserialize(req.readAll())
  424.         if req.status then
  425.             return req.data
  426.         else
  427.             self.data.errormsg = req.error
  428.             return false
  429.         end
  430.     end;
  431.     cloud_delete = function( self, id )
  432.         local query = "cmd=cloud_delete&id="..textutils.urlEncode(tostring(id)).."&key="..textutils.urlEncode(tostring(self.data.authkey))
  433.         local req = http.post(self.data.urls.store, query)
  434.         req = textutils.unserialize(req.readAll())
  435.         if req.status then
  436.             self.data.cmessage = tostring(req.message)
  437.             return true
  438.         else
  439.             self.data.errormsg = req.error
  440.             return false
  441.         end
  442.     end;
  443.     cloud_upload = function( self, filepath )
  444.         if filepath then
  445.             if not fs.exists(filepath) then
  446.                 self.data.errormsg = "File: "..filepath.." was not found"
  447.                 return false
  448.             end
  449.             local filename = filepath
  450.             local f = fs.open(filepath, "r")
  451.             filedata = f.readAll()
  452.             f.close()
  453.             filedata = base.base64.encode(filedata)
  454.             local query = "cmd=cloud_upload&filename="..textutils.urlEncode(tostring(filename)).."&filedata="..textutils.urlEncode(tostring(filedata)).."&key="..textutils.urlEncode(tostring(self.data.authkey))
  455.             local req = http.post(self.data.urls.store, query)
  456.             req = textutils.unserialize(req.readAll())
  457.             if req.status then
  458.                 self.data.cmessage = tostring(req.message)
  459.                 return true
  460.             else
  461.                 self.data.errormsg = req.error
  462.                 return false
  463.             end
  464.         else
  465.             self.data.errormsg = "Please supply all fields"
  466.             return false
  467.         end
  468.     end;
  469.     cloud_rename = function( self, id, name )
  470.         local query = "cmd=cloud_rename&id="..textutils.urlEncode(tostring(id)).."&key="..textutils.urlEncode(tostring(self.data.authkey)).."&newname="..textutils.urlEncode(tostring(name))
  471.         local req = http.post(self.data.urls.store, query)
  472.         req = textutils.unserialize(req.readAll())
  473.         if req.status then
  474.             self.data.cmessage = tostring(req.message)
  475.             return true
  476.         else
  477.             self.data.errormsg = req.error
  478.             return false
  479.         end
  480.     end;
  481.     mail_get = function( self )
  482.         local query = "cmd=mail_view_received&key=" ..textutils.urlEncode(tostring(self.data.authkey))
  483.         local req = http.post(self.data.urls.store, query)
  484.         req = textutils.unserialize(req.readAll())
  485.         if req.status then
  486.             self.data.mail = req.data
  487.             return true
  488.         else
  489.             return false
  490.         end
  491.     end;
  492.     mail_send = function( self, recipient, subject, message, attachments )
  493.         local query = "cmd=mail_send&key=" ..textutils.urlEncode(tostring(self.data.authkey)) .. "&recipient=" ..textutils.urlEncode(tostring(recipient)) .. "&subject=" ..textutils.urlEncode(tostring(subject)) .. "&message=" ..textutils.urlEncode(tostring(message)) .. "&attachments=" ..textutils.urlEncode(tostring(attachments))
  494.         local req = http.post(self.data.urls.store, query)
  495.         req = textutils.unserialize(req.readAll())
  496.         if req.status then
  497.             return true
  498.         else
  499.             self.data.errormsg = req.error;
  500.             return false
  501.         end
  502.     end;
  503.     mail_get_own = function( self )
  504.         local query = "cmd=mail_view_sent&key=" ..textutils.urlEncode(tostring(self.data.authkey))
  505.         local req = http.post(self.data.urls.store, query)
  506.         req = textutils.unserialize(req.readAll())
  507.         if req.status then
  508.             self.data.mail = req.data
  509.             return true
  510.         else
  511.             return false
  512.         end
  513.     end;
  514.     mail_delete = function( self, mailid )
  515.         local query = "cmd=mail_delete&key=" ..textutils.urlEncode(tostring(self.data.authkey)) .. "&id=" ..textutils.urlEncode(tostring(mailid))
  516.         local req = http.post(self.data.urls.store, query)
  517.         req = textutils.unserialize(req.readAll())
  518.         if req.status then
  519.             return true
  520.         else
  521.             self.data.errormsg = req.error;
  522.             return false
  523.         end
  524.     end;
  525.     mail_view = function( self, mailid )
  526.         local query = "cmd=mail_view&key=" ..textutils.urlEncode(tostring(self.data.authkey)) .. "&id=" ..textutils.urlEncode(tostring(mailid))
  527.         local req = http.post(self.data.urls.store, query)
  528.         req = textutils.unserialize(req.readAll())
  529.         if req.status then
  530.             return true
  531.         else
  532.             return false
  533.         end
  534.         return true;
  535.     end;
  536.     feed_view = function( self )
  537.         local query = "cmd=feed_view&key=" ..textutils.urlEncode(tostring(self.data.authkey))
  538.         local req = http.post(self.data.urls.store, query)
  539.         req = textutils.unserialize(req.readAll())
  540.         if req.status then
  541.             self.data.feed = req.data
  542.             return true
  543.         else
  544.             return false
  545.         end
  546.     end;
  547.     feed_new = function( self, message )
  548.         local query = "cmd=feed_send&key=" ..textutils.urlEncode(tostring(self.data.authkey)) .. "&message=" .. textutils.urlEncode(tostring(message))
  549.         local req = http.post(self.data.urls.store, query)
  550.         req = textutils.unserialize(req.readAll())
  551.         if req.status then
  552.             return true
  553.         else
  554.             self.data.errormsg = req.error;
  555.             return false
  556.         end
  557.     end;
  558. }
  559.  
  560.     -- Get Store API
  561. if (#tArgs == 0) then
  562.     downloadapi = false
  563.     local nTries = 0
  564.     while not downloadapi do
  565.         local ok, err = pcall( function()
  566.             if http then
  567.                 aa = aa or {}
  568.                 local a = http.get("http://api.dannysmc.com/files/apis/baseapi.lua")
  569.                 a = a.readAll()
  570.                 local env = {}
  571.                 a = loadstring(a)
  572.                 local env = getfenv()
  573.                 setfenv(a,env)
  574.                 local status, err = pcall(a, unpack(aa))
  575.                 if (not status) and err then
  576.                     printError("Error loading api")
  577.                     return false
  578.                 end
  579.                 local returned = err
  580.                 env = env
  581.                 _G["progutils"] = env
  582.             end
  583.         end)
  584.         if not ok then
  585.             term.clear()
  586.             term.setCursorPos(1,1)
  587.             print("Download API (Attempt: "..nTries.."/".."5)")
  588.             if nTries >= 5 then
  589.                 shell.run("shell")
  590.             end
  591.         else
  592.             downloadapi = true
  593.         end
  594.     end
  595. end
  596.  
  597. -- Set Object Methods (Better naming convention)
  598. store = {}
  599. store.__index = store
  600.  
  601. store.account = {}
  602. store.account.__index = store.account
  603.  
  604. store.apps = {}
  605. store.apps.__index = store.apps
  606.  
  607. store.draw = {}
  608. store.draw.__index = store.draw
  609.  
  610. store.cloud = {}
  611. store.cloud.__index = store.cloud
  612.  
  613. store.snippets = {}
  614. store.snippets.__index = store.snippets
  615.  
  616. store.social = {}
  617. store.social.__index = store.social
  618.  
  619. -- Discover Store Main Code:
  620. function store.draw.menu(screen)
  621.     base.draw.box(1, 51, 1, 2, " ", "grey", "grey")
  622.     base.draw.texta("Discover:", 1, 1, false, "cyan", "grey")
  623.     if screen then
  624.         base.draw.texta(screen, 10, 1, false, "white", "grey")
  625.     end
  626.     if #discover.data.notifications > 0 then
  627.         base.draw.texta("N", 43, 1, false, "red", "grey")
  628.     else
  629.         base.draw.texta("N", 43, 1, false, "lightGrey", "grey")
  630.     end
  631.     base.draw.textr(base.time.current(), 1, false, "lime", "grey")
  632.     chars = {2, 12, 22, 32, 42}
  633.     for i=1, #chars do
  634.         coun = i + side_scroll
  635.         if coun > #threads then
  636.             break
  637.         end
  638.         if threads[coun].name == currentThread.name then
  639.             base.draw.texta("  "..threads[coun].name:sub(1, 8).." ", chars[i], 2, false, "blue", "grey")
  640.             base.draw.texta("x", chars[i], 2, false, "red", "grey")
  641.         else
  642.             base.draw.texta(" "..threads[coun].name:sub(1,8).." ", chars[i], 2, false, "orange", "grey")
  643.         end
  644.     end
  645.     base.draw.texta(tostring(#threads), 45, 1, false, "lightBlue", "grey")
  646.     if side_scroll == 0 then
  647.         base.draw.texta("<", 1, 2, false, "lightGrey", "grey")
  648.     else
  649.         base.draw.texta("<", 1, 2, false, "lightBlue", "grey")
  650.     end
  651.     if side_scroll + 5 >= #threads then
  652.         base.draw.texta(">", 51, 2, false, "lightGrey", "grey")
  653.     else
  654.         base.draw.texta(">", 51, 2, false, "lightBlue", "grey")
  655.     end
  656. end
  657.  
  658. function store.draw.menu_input(screen, intx, inty)
  659.     discover:view_n()
  660.     if inty == 1 then
  661.         -- Check top layer buttons
  662.         if intx == 43 then
  663.             if not base.thread.find("Notifications") then
  664.                 base.thread.create("Notifications", store.account.notifications)
  665.             end
  666.             base.thread.switch("Notifications")
  667.         end
  668.     elseif inty == 2 then
  669.         -- Check Task Deletion First
  670.         if intx == 2 then
  671.             if #threads >= side_scroll + 1 then
  672.                 if threads[1+side_scroll].name == currentThread.name then
  673.                     -- Remove Thread
  674.                     base.thread.remove(threads[1+side_scroll].name)
  675.                     if not base.thread.find("Home") then
  676.                         base.thread.create("Home", store.home)
  677.                     end
  678.                     base.thread.switch("Home")
  679.                     return true
  680.                 end
  681.             end
  682.         elseif intx == 12 then
  683.             if #threads >= side_scroll + 2 then
  684.                 if threads[2+side_scroll].name == currentThread.name then
  685.                     -- Remove Thread
  686.                     base.thread.remove(threads[2+side_scroll].name)
  687.                     if not base.thread.find("Home") then
  688.                         base.thread.create("Home", store.home)
  689.                     end
  690.                     base.thread.switch("Home")                 
  691.                     return true
  692.                 end
  693.             end
  694.         elseif intx == 22 then
  695.             if #threads >= side_scroll + 3 then
  696.                 if threads[3+side_scroll].name == currentThread.name then
  697.                     -- Remove Thread
  698.                     base.thread.remove(threads[3+side_scroll].name)
  699.                     if not base.thread.find("Home") then
  700.                         base.thread.create("Home", store.home)
  701.                     end
  702.                     base.thread.switch("Home")                 
  703.                     return true
  704.                 end
  705.             end
  706.         elseif intx == 32 then
  707.             if #threads >= side_scroll + 4 then
  708.                 if threads[4+side_scroll].name == currentThread.name then
  709.                     -- Remove Thread
  710.                     base.thread.remove(threads[4+side_scroll].name)
  711.                     if not base.thread.find("Home") then
  712.                         base.thread.create("Home", store.home)
  713.                     end
  714.                     base.thread.switch("Home")                 
  715.                     return true
  716.                 end
  717.             end
  718.         elseif intx == 42 then
  719.             if #threads >= side_scroll + 5 then
  720.                 if threads[5+side_scroll].name == currentThread.name then
  721.                     -- Remove Thread
  722.                     base.thread.remove(threads[5+side_scroll].name)
  723.                     if not base.thread.find("Home") then
  724.                         base.thread.create("Home", store.home)
  725.                     end
  726.                     base.thread.switch("Home")                 
  727.                     return true
  728.                 end
  729.             end
  730.         end
  731.  
  732.         -- Task Switching
  733.         if intx >= 2 and intx <= 10 then
  734.             if #threads >= side_scroll + 1 then
  735.                 base.thread.switch(threads[1+side_scroll].name)
  736.                 store.draw.menu(screen)
  737.             end
  738.         elseif intx >= 12 and intx <= 20 then
  739.             if #threads >= side_scroll + 2 then
  740.                 base.thread.switch(threads[2+side_scroll].name)
  741.                 store.draw.menu(screen)
  742.             end    
  743.         elseif intx >= 22 and intx <= 30 then
  744.             if #threads >= side_scroll + 3 then
  745.                 base.thread.switch(threads[3+side_scroll].name)
  746.                 store.draw.menu(screen)
  747.             end
  748.         elseif intx >= 32 and intx <= 40 then
  749.             if #threads >= side_scroll + 4 then
  750.                 base.thread.switch(threads[4+side_scroll].name)
  751.                 store.draw.menu(screen)
  752.             end
  753.         elseif intx >= 42 and intx <= 50 then
  754.             if #threads >= side_scroll + 5 then
  755.                 base.thread.switch(threads[5+side_scroll].name)
  756.                 store.draw.menu(screen)
  757.             end
  758.         elseif intx == 1 then
  759.             if side_scroll > 0 then
  760.                 side_scroll = side_scroll - 1
  761.                 store.draw.menu(screen)
  762.             end
  763.         elseif intx == 51 then
  764.             if (side_scroll + 5) < #threads then
  765.                 side_scroll = side_scroll + 1
  766.                 store.draw.menu(screen)
  767.             end
  768.         end
  769.     end
  770. end
  771.  
  772. function store.draw.logo(intx, inty)
  773.     local text = "Welcome to the Discover App Store. If you have notifications, the N in the menu bar will go red! A * following a button means you need to be logged in!"
  774.     for k,v in ipairs(base.data.wordwrap(text, 41)) do
  775.         base.draw.textc(v, k+3, false, "grey", "white")
  776.     end
  777.  
  778.     if discover.data.loggedin then
  779.         base.draw.box(2, 24, 9, 1, false, "red", "red")
  780.         base.draw.texta("Log out", 3, 9, false, "white", "red")
  781.     else
  782.         base.draw.box(2, 24, 9, 1, false, "cyan", "cyan")
  783.         base.draw.texta("Log In", 3, 9, false, "white", "cyan")
  784.     end
  785.     base.draw.box(2, 24, 11, 1, false, "cyan", "cyan")
  786.     base.draw.box(2, 24, 13, 1, false, "cyan", "cyan")
  787.     base.draw.box(2, 24, 15, 1, false, "cyan", "cyan")
  788.     base.draw.box(2, 24, 17, 1, false, "cyan", "cyan")
  789.     base.draw.box(27, 24, 9, 1, false, "cyan", "cyan")
  790.     base.draw.box(27, 24, 11, 1, false, "cyan", "cyan")
  791.     base.draw.box(27, 24, 13, 1, false, "cyan", "cyan")
  792.     base.draw.box(27, 24, 15, 1, false, "cyan", "cyan")
  793.     base.draw.box(27, 24, 17, 1, false, "cyan", "cyan")
  794.     base.draw.texta("Apps List", 3, 11, false, "white", "cyan")
  795.     base.draw.texta("Snippets", 3, 13, false, "white", "cyan")
  796.     base.draw.texta("Discover Cloud*", 3, 15, false, "white", "cyan")
  797.     base.draw.texta("Social Network*", 3, 17, false, "white", "cyan")
  798.     base.draw.texta("My Account*", 28, 9, false, "white", "cyan")
  799.     base.draw.texta("Help / FAQ", 28, 11, false, "white", "cyan")
  800.     base.draw.texta("Update Log", 28, 13, false, "white", "cyan")
  801.     base.draw.texta("Settings", 28, 15, false, "white", "cyan")
  802.     base.draw.texta("Credits", 28, 17, false, "white", "cyan")
  803.  
  804.  
  805.     base.draw.box(1, 51, 19, 1, " ", "grey", "grey")
  806.     base.draw.textr("Exit ", 19, false, "orange", "grey")
  807.     base.draw.textl(" Search", 19, false, "lightBlue", "grey")
  808. end
  809.  
  810. function store.init()
  811.     base.screen.colour("lightGrey")
  812.     base.draw.textc("--------------------------", 2, false, "grey", "lightGrey")
  813.     base.draw.textc("    Discover App Store    ", 3, false, "black", "lightGrey")
  814.     base.draw.textc("--------------------------", 4, false, "grey", "lightGrey")
  815.     base.draw.textc("--< Created By DannySMc >--", 19, false, "lightBlue", "lightGrey")
  816.     base.draw.box(8, 37, 15, 1, " ", "white", "white")
  817.     base.draw.box(8, 1, 15, 1, " ", "lime", "lime")
  818.     sleep(0.15)
  819.  
  820.     base.draw.box(1, 51, 10, 1, " ", "lightGrey", "lightGrey")
  821.     base.draw.textc("Loading Configurations...", 10, false, "red", "lightGrey")
  822.     base.draw.box(8, 3, 15, 1, " ", "lime", "lime")
  823.  
  824.     -- Load Configurations
  825.     if fs.exists(system.paths.config) then
  826.         local f = fs.open(system.paths.config, "r")
  827.         local dat = base.base64.decode( f.readAll() )
  828.         local c = textutils.unserialize( dat )
  829.         system.storeconfig = c.storeconfig
  830.         system.plugins = c.plugins
  831.         if (c.lock) then
  832.             system.lock = c.lock
  833.         end
  834.         if (c.username) then
  835.             discover.data.username = c.username
  836.             discover.data.password = c.password
  837.             discover.data.authkey = c.authkey
  838.         end
  839.         f.close()
  840.         base.draw.box(8, 5, 15, 1, " ", "lime", "lime"); sleep(0.15);
  841.     end
  842.    
  843.     -- Check for Update
  844.     base.draw.box(1, 51, 10, 1, " ", "lightGrey", "lightGrey")
  845.     base.draw.textc("Checking for update...", 10, false, "red", "lightGrey")
  846.     base.draw.box(8, 9, 15, 1, " ", "lime", "lime")
  847.     local status = discover:get_update()
  848.     if status then
  849.         base.draw.box(1, 51, 10, 1, " ", "lightGrey", "lightGrey")
  850.         base.draw.textc("Update found, please wait...", 10, false, "red", "lightGrey")
  851.         sleep(1.5)
  852.         local name = shell.getRunningProgram()
  853.         local f = fs.open(name, "w")
  854.         f.write(discover.data.newupdate)
  855.         f.close()
  856.         shell.run(shell.getRunningProgram())
  857.         base.draw.box(8, 12, 15, 1, " ", "lime", "lime"); sleep(0.15);
  858.     else
  859.         base.draw.box(1, 51, 10, 1, " ", "lightGrey", "lightGrey")
  860.         base.draw.textc("You are currently running the latest version", 10, false, "red", "lightGrey")
  861.         base.draw.box(8, 12, 15, 1, " ", "lime", "lime"); sleep(0.15);
  862.     end
  863.  
  864.     -- Loading User Settings / Login
  865.     base.draw.box(8, 14, 15, 1, " ", "lime", "lime")
  866.     if system.storeconfig then
  867.         if fs.exists(".DiscoverConfig") then
  868.             base.draw.box(1, 51, 10, 1, " ", "lightGrey", "lightGrey")
  869.             base.draw.textc("Attempting to Login...", 10, false, "red", "lightGrey")
  870.             local ok = discover:login(discover.data.username, discover.data.password)
  871.             if ok then
  872.                 base.draw.box(1, 51, 10, 1, " ", "lightGrey", "lightGrey")
  873.                 base.draw.textc("You was successfully logged in!", 10, false, "red", "lightGrey")
  874.                 base.draw.box(8, 18, 15, 1, " ", "lime", "lime")
  875.                 sleep(0.5)
  876.             else
  877.                 base.draw.box(1, 51, 10, 1, " ", "lightGrey", "lightGrey")
  878.                 base.draw.textc(tostring(discover.data.errormsg), 10, false, "red", "lightGrey")
  879.                 errorprompt = true
  880.                 sleep(0.5)
  881.                 base.draw.box(8, 18, 15, 1, " ", "lime", "lime")
  882.             end
  883.         end
  884.     end
  885.  
  886.     -- Unlock Termination if system.lock is false
  887.     base.draw.box(8, 21, 15, 1, " ", "lime", "lime"); sleep(0.15);
  888.     if not system.lock then
  889.         os.pullEvent = os.getEvent
  890.     end
  891.  
  892.     -- Install System Plugins
  893.     if system.plugins then
  894.         base.draw.box(1, 51, 10, 1, " ", "lightGrey", "lightGrey")
  895.         base.draw.textc("Installing Plugins...", 10, false, "red", "lightGrey")
  896.         base.draw.box(8, 24, 15, 1, " ", "lime", "lime"); sleep(0.15);
  897.  
  898.         local ok, err = pcall(function()
  899.  
  900.             -- Plugin Function
  901.             local function install(path)
  902.                 local tLetters = {"a","b","c","d","e","f"}; new = {}
  903.                 for i=1,4 do table.insert(new, tLetters[math.ceil(math.random(5))]) end
  904.                 newname = table.concat(new, "")
  905.                 aa = aa or {}
  906.                 local a = fs.open(path, "r")
  907.                 a = a.readAll()
  908.                 local env = {}
  909.                 a = loadstring(a)
  910.                 local env = getfenv()
  911.                 setfenv(a,env)
  912.                 local status, err = pcall(a, unpack(aa))
  913.                 if (not status) and err then
  914.                     printError("Error loading api")
  915.                     return false
  916.                 end
  917.                 local returned = err
  918.                 env = env
  919.                 _G[newname] = env
  920.             end
  921.             base.draw.box(8, 27, 15, 1, " ", "lime", "lime"); sleep(0.15);
  922.  
  923.             -- Get Plugins
  924.             if fs.exists(system.paths.plugins) then
  925.                 local list = fs.list(system.paths.plugins)
  926.                 for k,v in ipairs(list) do
  927.                     local path = fs.combine(system.paths.plugins, v)
  928.                     install(path)
  929.                 end
  930.             end
  931.             base.draw.box(8, 29, 15, 1, " ", "lime", "lime"); sleep(0.15);
  932.  
  933.         end)
  934.         if not ok then
  935.             store.crash(err)
  936.         end
  937.     end
  938.  
  939.     -- Start Threads
  940.     base.draw.box(8, 31, 15, 1, " ", "lime", "lime")
  941.     local ok, err = pcall(function()
  942.  
  943.         -- Draw Screen
  944.         base.draw.box(1, 51, 10, 1, " ", "lightGrey", "lightGrey")
  945.         base.draw.textc("Downloading store data...", 10, false, "red", "lightGrey")
  946.         sleep(0.15)
  947.         discover:store_init()
  948.         base.draw.box(8, 34, 15, 1, " ", "lime", "lime"); sleep(0.15)
  949.  
  950.         base.thread.create("Home", store.home)
  951.         base.draw.box(1, 51, 10, 1, " ", "lightGrey", "lightGrey")
  952.         base.draw.textc("Running process manager", 10, false, "red", "lightGrey")
  953.         base.draw.box(8, 37, 15, 1, " ", "lime", "lime"); sleep(0.15)
  954.         -- Launch Helper Worker
  955.         if errorprompt then
  956.             base.thread.create("Prompt", store.prompt)
  957.             base.thread.switch("Prompt")
  958.         else
  959.             base.thread.switch("Home")
  960.         end
  961.         -- Switch and Run
  962.         base.thread.run()
  963.  
  964.     end)
  965.  
  966.     if not ok then
  967.         store.crash(err)
  968.     end
  969. end
  970.  
  971. function store.report(err)
  972.     base.screen.colour("white")
  973.     base.draw.box(1, 51, 1, 1, " ", "grey", "grey")
  974.     base.draw.box(1, 51, 19, 1, " ", "grey", "grey")
  975.     base.draw.textc("Bug / Error Report", 1, false, "cyan", "grey")
  976.  
  977.     base.draw.texta("Details of report data:", 8, 3, false, "red", "white")
  978.     local repdata = {};
  979.     repdata["ERR_MSG"] = tostring(err);
  980.     repdata["CMP_IDN"] = tostring(os.getComputerID());
  981.     repdata["HDD_SPC"] = tostring(fs.getFreeSpace("/"));
  982.     repdata["THR_CNT"] = tostring("Threads: " .. #threads);
  983.     repdata["PRG_NAM"] = tostring(shell.getRunningProgram());
  984.     base.draw.textr("Send ", 19, false, "orange", "grey")
  985.     base.draw.textl(" Restart", 19, false, "cyan", "grey")
  986.     local i = 0
  987.     for k,v in pairs(repdata) do
  988.         i = i + 1
  989.         base.draw.box(8, 36, i+4, 1, " ", "black", "black")
  990.         base.draw.texta(k .. ": ", 8, i+4, false, "orange", "black")
  991.         base.draw.texta(v:sub(0, 27), 16, i+4, false, "lightBlue", "black")
  992.     end
  993.     while true do
  994.         local args = { os.pullEvent() }
  995.         if args[1] == "timer" then
  996.             base.draw.textr(base.time.current(), 1, false, "lime", "grey")
  997.         elseif args[1] == "mouse_click" then
  998.             if (args[3] >= 2 and args[3] <= 8) and args[4] == 19 then
  999.                 os.reboot()
  1000.             elseif (args[3] >= 47 and args[3] <= 50) and args[4] == 19 then
  1001.                 local ok, re = discover:report(repdata)
  1002.                 if ok then
  1003.                     base.gui.alert("Report was successfully sent!")
  1004.                     sleep(1)
  1005.                     os.reboot()
  1006.                 else
  1007.                     base.gui.alert("Error: " .. re)
  1008.                     sleep(2)
  1009.                     store.report(err)
  1010.                 end
  1011.             end
  1012.         end
  1013.     end
  1014. end
  1015.  
  1016. function store.prompt()
  1017.     base.screen.colour("white")
  1018.     store.draw.menu("Error Prompt")
  1019.  
  1020.  
  1021.     local text = "Please read the error below and take action. There are many reasons you were not able to login. One reason could be that you are banned, this means if you have put up content which is not appropriate, or you are using bad usernames/passwords then your account will be banned or if you spam the database. If your credentials are invalid make sure your username and password are correct, if they are then please attempt at changing your password, this uses your email to send you a validation key."
  1022.  
  1023.     for k,v in ipairs(base.data.wordwrap(discover.data.errormsg, 47)) do
  1024.         base.draw.texta(v, 3, k+14, false, "red", "white")
  1025.     end
  1026.     for k,v in ipairs(base.data.wordwrap(text, 51)) do
  1027.         base.draw.textl(v, k+3, false, "grey", "white")
  1028.     end
  1029.  
  1030.     base.draw.box(1, 51, 19, 1, " ", "grey" , "grey")
  1031.     base.draw.textc("Press the \"X\" in the taskbar to close", 19, false, "orange", "grey")
  1032.  
  1033.     while true do
  1034.         local args = { os.pullEvent() }
  1035.         if args[1] == "timer" then
  1036.             store.draw.menu("Error Prompt")
  1037.         elseif args[1] == "mouse_click" then
  1038.             if args[4] >= 1 and args[4] <= 2 then
  1039.                 store.draw.menu_input("Home", args[3], args[4])
  1040.             end
  1041.         end
  1042.     end
  1043. end
  1044.  
  1045. function store.crash(errmsg)
  1046.     base.screen.colour("lightGrey")
  1047.     base.draw.box(1, 51, 1, 1, "-", "grey", "lightGrey")
  1048.     base.draw.textc("Discover Store has Crashed", 2, false, "grey", "lightGrey")
  1049.     base.draw.box(1, 51, 3, 1, "-", "grey", "lightGrey")
  1050.  
  1051.     local text = "Oh no! It looks like Discover Store ran into an issue, there are two things you can do, either press the \"Restart\" button to reboot the computer, or press the \"Report\" button which will take you to a screen where you can report the problem to me. Error is below.";
  1052.     for k,v in ipairs(base.data.wordwrap(text, 49)) do
  1053.         base.draw.textl(" " .. v, k+3, false, "white", "lightGrey")
  1054.     end
  1055.  
  1056.     for k,v in ipairs(base.data.wordwrap(errmsg, 47)) do
  1057.         base.draw.texta(v, 3, k+10, false, "red", "lightGrey")
  1058.     end
  1059.     base.draw.box(2, 24, 18, 1, " ", "orange", "orange")
  1060.     base.draw.box(27, 24, 18, 1, " ", "orange", "orange")
  1061.     base.draw.texta("Restart / Reboot", 6, 18, false, "white", "orange")
  1062.     base.draw.texta("Report Bug", 34, 18, false, "white", "orange")
  1063.  
  1064.     while true do
  1065.         local args = { os.pullEvent() }
  1066.         if args[1] == "mouse_click" then
  1067.             if (args[3] >= 2 and args[3] <= 25) and (args[4] == 18) then
  1068.                 base.gui.alert("Rebooting computer...")
  1069.                 sleep(0.5)
  1070.                 os.reboot()
  1071.             elseif (args[3] >= 27 and args[3] <= 50) and (args[4] == 18) then
  1072.                 store.report(errmsg)
  1073.             end
  1074.         end
  1075.     end
  1076. end
  1077.  
  1078. function store.exit()
  1079.     base.screen.colour("black")
  1080.     local text = "Thank you, Created by DannySMc (http://dannysmc.com/)"
  1081.     for k,v in ipairs(base.data.wordwrap(text, 31)) do
  1082.         base.draw.textc(v, 6+k, false, "cyan", "black")
  1083.     end
  1084.     sleep(1.5); term.clear(); term.setCursorPos(1,1)
  1085.     base.thread.exit()
  1086. end
  1087.  
  1088. function store.home()
  1089.     base.screen.colour("white")
  1090.     store.draw.menu("Home")
  1091.     store.draw.logo()
  1092.     base.draw.box(1, 51, 19, 1, " ", "grey", "grey")
  1093.     base.draw.textr("Exit ", 19, false, "orange", "grey")
  1094.     base.draw.textl(" Search", 19, false, "lightBlue", "grey")
  1095.  
  1096.     while true do
  1097.         local args = { os.pullEvent() }
  1098.         if args[1] == "timer" then
  1099.             store.draw.menu("Home")
  1100.         elseif args[1] == "char" then
  1101.             if args[2] == "f" then
  1102.                 if not base.thread.find("Finder") then
  1103.                     base.thread.create("Finder", store.finder)
  1104.                 end
  1105.                 base.thread.switch("Finder")
  1106.             end
  1107.         elseif args[1] == "mouse_click" then
  1108.             if args[4] >= 1 and args[4] <= 2 then
  1109.                 store.draw.menu_input("Home", args[3], args[4])
  1110.             elseif (args[3] >= 47 and args[3]<= 50) and (args[4] == 19) then
  1111.                 store.exit()
  1112.                 break
  1113.             elseif (args[3] >= 2 and args[3] <= 7) and (args[4] == 19) then
  1114.                 if not base.thread.find("Search") then
  1115.                     base.thread.create("Search", store.apps.search)
  1116.                 end
  1117.                 base.thread.switch("Search")
  1118.             elseif (args[3] >= 2 and args[3] <= 25) and (args[4] == 9) then
  1119.                 if discover.data.loggedin then
  1120.                     store.account.logout()
  1121.                     base.screen.colour("white")
  1122.                     store.draw.menu("Home")
  1123.                     store.draw.logo()
  1124.                 else
  1125.                     store.account.login()
  1126.                     base.screen.colour("white")
  1127.                     store.draw.menu("Home")
  1128.                     store.draw.logo()
  1129.                 end
  1130.             elseif (args[3] >= 2 and args[3] <= 25) and (args[4] == 11) then
  1131.                 if not base.thread.find("Apps") then
  1132.                     base.thread.create("Apps", store.apps.all)
  1133.                 end
  1134.                 base.thread.switch("Apps")
  1135.             elseif (args[3] >= 2 and args[3] <= 25) and (args[4] == 13) then
  1136.                 if not base.thread.find("Snippets") then
  1137.                     base.thread.create("Snippets", store.snippets.main)
  1138.                 end
  1139.                 base.thread.switch("Snippets")
  1140.             elseif (args[3] >= 2 and args[3] <= 25) and (args[4] == 15) then
  1141.                 if discover.data.loggedin then
  1142.                     if not base.thread.find("Cloud") then
  1143.                         base.thread.create("Cloud", store.cloud.main)
  1144.                     end
  1145.                     base.thread.switch("Cloud")
  1146.                 else
  1147.                     base.gui.alert("Please login")
  1148.                     sleep(1)
  1149.                     base.screen.colour("white")
  1150.                     store.draw.menu("Home")
  1151.                     store.draw.logo()
  1152.                 end
  1153.             elseif (args[3] >= 2 and args[3] <= 25) and (args[4] == 17) then
  1154.                 if discover.data.loggedin then
  1155.                     if not base.thread.find("Social") then
  1156.                         base.thread.create("Social", store.social.main)
  1157.                     end
  1158.                     base.thread.switch("Social")
  1159.                 else
  1160.                     base.gui.alert("Please login")
  1161.                     sleep(1)
  1162.                     base.screen.colour("white")
  1163.                     store.draw.menu("Home")
  1164.                     store.draw.logo()
  1165.                 end
  1166.             elseif (args[3] >= 27 and args[3] <= 50) and (args[4] == 9) then
  1167.                 if discover.data.loggedin then
  1168.                     if not base.thread.find("Account") then
  1169.                         base.thread.create("Account", store.account.home)
  1170.                     end
  1171.                     base.thread.switch("Account")
  1172.                 else
  1173.                     base.gui.alert("Please login")
  1174.                     sleep(1)
  1175.                     base.screen.colour("white")
  1176.                     store.draw.menu("Home")
  1177.                     store.draw.logo()
  1178.                 end
  1179.             elseif (args[3] >= 27 and args[3] <= 50) and (args[4] == 11) then
  1180.                 if not base.thread.find("Help") then
  1181.                     base.thread.create("Help", store.help)
  1182.                 end
  1183.                 base.thread.switch("Help")
  1184.             elseif (args[3] >= 27 and args[3] <= 50) and (args[4] == 13) then
  1185.                 if not base.thread.find("Updates") then
  1186.                     base.thread.create("Updates", store.updates)
  1187.                 end
  1188.                 base.thread.switch("Updates")
  1189.             elseif (args[3] >= 27 and args[3] <= 50) and (args[4] == 15) then
  1190.                 if not base.thread.find("Settings") then
  1191.                     base.thread.create("Settings", store.settings)
  1192.                 end
  1193.                 base.thread.switch("Settings")
  1194.             elseif (args[3] >= 27 and args[3] <= 50) and (args[4] == 17) then
  1195.                 if not base.thread.find("Credits") then
  1196.                     base.thread.create("Credits", store.credits)
  1197.                 end
  1198.                 base.thread.switch("Credits")
  1199.             end
  1200.         end
  1201.     end
  1202. end
  1203.  
  1204. function store.finder()
  1205.     base.screen.colour("white")
  1206.     store.draw.menu("Finder")
  1207.     local scroll = 0
  1208.     local options = {
  1209.         "+Apps";
  1210.         "-Search Apps";
  1211.         "-View All";
  1212.         "-View Categories";
  1213.         "-View Versions";
  1214.         "+Account";
  1215.         "-Upload App";
  1216.         "-Update App";
  1217.         "-Edit App";
  1218.         "-My Apps";
  1219.         "-Notifications";
  1220.         "-Change Password";
  1221.         "-Change Email";
  1222.         "+Snippets";
  1223.         "-Upload Snippet";
  1224.         "-View all Snippets";
  1225.         "-View my Snippets";
  1226.         "+Cloud";
  1227.         "-View Cloud";
  1228.         "-Usage Stats";
  1229.         "+Core";
  1230.         "-Help / FAQ";
  1231.         "-Update Log";
  1232.         "-Settings";
  1233.         "-Credits";
  1234.         "-Exit";
  1235.     }
  1236.  
  1237.     local function run(scroll)
  1238.         for i=1, 14 do
  1239.             base.draw.box(1, 51, i+3, 1, " ", "white","white")
  1240.             if options[i+scroll]:sub(1,1) == "+" then
  1241.                 base.draw.texta("> " .. options[i+scroll]:sub(2), 2, i+3, false, "grey", "white")
  1242.             elseif options[i+scroll]:sub(1,1) == "-" then
  1243.                 base.draw.texta("- " .. options[i+scroll]:sub(2), 4, i+3, false, "lightGrey", "white")
  1244.             end
  1245.         end
  1246.     end
  1247.  
  1248.     run(scroll)
  1249.     while true do
  1250.         local args = { os.pullEvent() }
  1251.         if args[1] == "timer" then
  1252.             store.draw.menu("Finder")
  1253.         elseif args[1] == "mouse_click" then
  1254.             if args[4] >= 1 and args[4] <= 2 then
  1255.                 store.draw.menu_input("Finder", args[3], args[4])
  1256.             end
  1257.         elseif args[1] == "mouse_scroll" then
  1258.             if args[2] == -1 then
  1259.                 if scroll > 0 then
  1260.                     scroll = scroll - 1
  1261.                     run(scroll)
  1262.                 end
  1263.             elseif args[2] == 1 then
  1264.                 if scroll + 14 <= #options-1 then
  1265.                     scroll = scroll + 1
  1266.                     run(scroll)
  1267.                 end
  1268.             end
  1269.         end
  1270.     end
  1271. end
  1272.  
  1273. function store.apps.all()
  1274.     base.screen.colour("white")
  1275.     store.draw.menu("All Apps")
  1276.     local scroll = 0
  1277.     appslist = discover:get("apps")
  1278.  
  1279.     base.draw.texta("        Categories        |        Versions        ", 1, 3, false, "white", "lightGrey")
  1280.  
  1281.     base.draw.box(1, 51, 19, 1, " ", "grey", "grey")
  1282.     base.draw.texta("Total Apps: "..#appslist, 2, 19, false, "lightBlue", "grey")
  1283.     base.draw.textr("Scroll Enabled ", 19, false, "orange", "grey")
  1284.  
  1285.     local function fix(num)
  1286.         if tostring(num):len() == 1 then
  1287.             return "  "..tostring(num)
  1288.         elseif tostring(num):len() == 2 then
  1289.             return " "..tostring(num)
  1290.         else
  1291.             return tostring(num)
  1292.         end
  1293.     end
  1294.  
  1295.     local function run(scroll)
  1296.         for i = 1, 13 do
  1297.             if #appslist >= i + scroll then
  1298.                 base.draw.box(1, 51, i+4, 1, " ", "white", "white")
  1299.                 base.draw.textl(fix(i+scroll)..": "..appslist[i+scroll].name, i+4, false, "grey", "white")
  1300.             end
  1301.         end
  1302.     end
  1303.  
  1304.     run(scroll)
  1305.  
  1306.     while true do
  1307.         local args = { os.pullEvent() }
  1308.         if args[1] == "timer" then
  1309.             store.draw.menu("All Apps")
  1310.         elseif args[1] == "mouse_click" then
  1311.             if args[4] >= 1 and args[4] <= 2 then
  1312.                 store.draw.menu_input("Help / FAQ", args[3], args[4])
  1313.             elseif (args[3] >= 1 and args[3] <= 25) and (args[4] == 3) then
  1314.                 store.apps.categories()
  1315.             elseif (args[3] >= 26 and args[3] <= 51) and (args[4] == 3) then
  1316.                 store.apps.versions()
  1317.             elseif (args[3] >= 1 and args[3] <= 51) and (args[4] >= 5 and args[4] <= 17) then
  1318.                 local curid = args[4] - 4 + scroll
  1319.                 local tname = "View"..tostring(appslist[curid].id)
  1320.                 base.thread.create(tname, store.apps.view)
  1321.                 viewapps[1] =  appslist[curid].id
  1322.                 viewapps[2] = appslist
  1323.                 base.thread.switch(tname)
  1324.             end
  1325.         elseif args[1] == "mouse_scroll" then
  1326.             if args[2] == -1 then
  1327.                 if scroll > 0 then
  1328.                     scroll = scroll - 1
  1329.                     run(scroll)
  1330.                 end
  1331.             elseif args[2] == 1 then
  1332.                 if scroll + 13 <= #appslist-1 then
  1333.                     scroll = scroll + 1
  1334.                     run(scroll)
  1335.                 end
  1336.             end
  1337.         end
  1338.     end
  1339. end
  1340.  
  1341. function store.apps.versions(version)
  1342.     base.screen.colour("white")
  1343.     store.draw.menu("Versions")
  1344.     base.draw.box(21, 1, 5, 13, "|", "lightGrey", "white")
  1345.     base.draw.box(1, 51, 19, 1, " ", "grey", "grey")
  1346.     base.draw.texta("Total Versions: "..#discover.data.versions, 2, 19, false, "lightBlue", "grey")
  1347.     base.draw.textr("SCroll Enabled", 19, false, "orange", "grey")
  1348.     base.draw.texta("        All         |          Categories          ", 1, 3, false, "white", "lightGrey")
  1349.  
  1350.     -- Vars
  1351.     local lscroll = 0
  1352.     local rscroll = 0
  1353.     local ldata = discover.data.versions
  1354.     local rdata = {}
  1355.     local lselect = ""
  1356.     local allapps = discover.data.apps
  1357.  
  1358.     local function lrun(lscroll)
  1359.         for i=1, 13 do
  1360.             if #ldata >= i + lscroll then
  1361.                 if lselect == ldata[i+lscroll] then
  1362.                     base.draw.box(1, 19, i+4, 1, " ", "white", "white")
  1363.                     base.draw.texta(ldata[i+lscroll], 1, i+4, false, "grey", "white")
  1364.                 else
  1365.                     base.draw.box(1, 19, i+4, 1, " ", "white", "white")
  1366.                     base.draw.texta(ldata[i+lscroll], 1, i+4, false, "cyan", "white")
  1367.                 end
  1368.             end
  1369.         end
  1370.     end
  1371.  
  1372.     local function rrun(rscroll)
  1373.         for i=1, 13 do
  1374.             if #rdata >= i + rscroll then
  1375.                 base.draw.box(22, 29, i+4, 1, " ", "white", "white")
  1376.                 base.draw.texta(rdata[i+rscroll].name:sub(1, 25), 23, i+4, false, "grey", "white")
  1377.             end
  1378.         end
  1379.     end
  1380.  
  1381.     lrun(lscroll)
  1382.     rrun(rscroll)
  1383.  
  1384.     while true do
  1385.         local args = { os.pullEvent() }
  1386.         if args[1] == "timer" then
  1387.             store.draw.menu("Versions")
  1388.         elseif args[1] == "mouse_click" then
  1389.             if args[4] >= 1 and args[4] <= 2 then
  1390.                 store.draw.menu_input("Versions", args[3], args[4])
  1391.             elseif (args[3] >= 1 and args[3] <= 25) and (args[4] == 3) then
  1392.                 store.apps.all()
  1393.             elseif (args[3] >= 26 and args[3] <= 51) and (args[4] == 3) then
  1394.                 store.apps.categories()
  1395.             elseif (args[3] >= 1 and args[3] <= 20) and (args[4] >= 5 and args[4] <= 17) then
  1396.                 -- Choose
  1397.                 local cid = args[4] - 4 + lscroll
  1398.                 if #ldata >= cid then
  1399.                     lselect = ldata[cid]
  1400.                     rdata = {}
  1401.                     for k,v in ipairs(allapps) do
  1402.                         if v.version == lselect then
  1403.                             rdata[#rdata+1] = v
  1404.                         end
  1405.                     end
  1406.                     for i=1, 13 do
  1407.                         base.draw.box(22, 29, i+3, 1, false, "white", "white")
  1408.                     end
  1409.                     rscroll = 0
  1410.                     rrun(rscroll)
  1411.                     lrun(lscroll)
  1412.                 end
  1413.             elseif (args[3] >= 22 and args[3] <= 51) and (args[4] >= 5 and args[4] <= 17) then
  1414.                 -- View app
  1415.                 local cid = args[4] - 4 + rscroll
  1416.                 if #rdata >= cid then
  1417.                     viewapps[1] = rdata[cid].id
  1418.                     viewapps[2] = discover.data.apps
  1419.                     if not base.thread.find("View"..tostring(rdata[cid].id)) then
  1420.                         base.thread.create("View"..tostring(rdata[cid].id), store.apps.view)
  1421.                     end
  1422.                     base.thread.switch("View"..tostring(rdata[cid].id))
  1423.                 end
  1424.             end
  1425.         elseif args[1] == "mouse_scroll" then
  1426.             if args[2] == -1 then
  1427.                 if (args[3] >= 1 and args[3] <= 20) and (args[4] >= 5 and args[4] <= 17) then
  1428.                     if lscroll > 0  then
  1429.                         lscroll = lscroll - 1
  1430.                         lrun(lscroll)
  1431.                     end
  1432.                 elseif (args[3] >= 22 and args[3] <= 51) and (args[4] >= 5 and args[4] <= 17) then
  1433.                     if rscroll > 0 then
  1434.                         rscroll = rscroll - 1
  1435.                         rrun(rscroll)
  1436.                     end
  1437.                 end
  1438.             elseif args[2] == 1 then
  1439.                 if (args[3] >= 1 and args[3] <= 20) and (args[4] >= 5 and args[4] <= 17) then
  1440.                     if lscroll + 13 <= #ldata-1 then
  1441.                         lscroll = lscroll + 1
  1442.                         lrun(lscroll)
  1443.                     end
  1444.                 elseif (args[3] >= 22 and args[3] <= 51) and (args[4] >= 5 and args[4] <= 17) then
  1445.                     if rscroll + 13 <= #rdata-1 then
  1446.                         rscroll = rscroll + 1
  1447.                         rrun(rscroll)
  1448.                     end
  1449.                 end
  1450.             end
  1451.         end
  1452.     end
  1453. end
  1454.  
  1455. function store.apps.categories()
  1456.     base.screen.colour("white")
  1457.     store.draw.menu("Categories")
  1458.     base.draw.box(21, 1, 5, 13, "|", "lightGrey", "white")
  1459.     base.draw.box(1, 51, 19, 1, " ", "grey", "grey")
  1460.     base.draw.texta("Total Categories: "..#discover.data.categories, 2, 19, false, "lightBlue", "grey")
  1461.     base.draw.textr("SCroll Enabled", 19, false, "orange", "grey")
  1462.     base.draw.texta("        All         |           Versions           ", 1, 3, false, "white", "lightGrey")
  1463.  
  1464.     -- Vars
  1465.     local lscroll = 0
  1466.     local rscroll = 0
  1467.     local ldata = discover.data.categories
  1468.     local rdata = {}
  1469.     local lselect = ""
  1470.     local allapps = discover.data.apps
  1471.  
  1472.     local function lrun(lscroll)
  1473.         for i=1, 13 do
  1474.             if #ldata >= i + lscroll then
  1475.                 if lselect == ldata[i+lscroll] then
  1476.                     base.draw.box(1, 19, i+4, 1, " ", "white", "white")
  1477.                     base.draw.texta(ldata[i+lscroll], 1, i+4, false, "grey", "white")
  1478.                 else
  1479.                     base.draw.box(1, 19, i+4, 1, " ", "white", "white")
  1480.                     base.draw.texta(ldata[i+lscroll], 1, i+4, false, "cyan", "white")
  1481.                 end
  1482.             end
  1483.         end
  1484.     end
  1485.  
  1486.     local function rrun(rscroll)
  1487.         for i=1, 13 do
  1488.             if #rdata >= i + rscroll then
  1489.                 base.draw.box(22, 29, i+4, 1, " ", "white", "white")
  1490.                 base.draw.texta(rdata[i+rscroll].name:sub(1, 25), 23, i+4, false, "grey", "white")
  1491.             end
  1492.         end
  1493.     end
  1494.  
  1495.     lrun(lscroll)
  1496.     rrun(rscroll)
  1497.  
  1498.     while true do
  1499.         local args = { os.pullEvent() }
  1500.         if args[1] == "timer" then
  1501.             store.draw.menu("Categories")
  1502.         elseif args[1] == "mouse_click" then
  1503.             if args[4] >= 1 and args[4] <= 2 then
  1504.                 store.draw.menu_input("Categories", args[3], args[4])
  1505.             elseif (args[3] >= 1 and args[3] <= 25) and (args[4] == 3) then
  1506.                 store.apps.all()
  1507.             elseif (args[3] >= 26 and args[3] <= 51) and (args[4] == 3) then
  1508.                 store.apps.versions()
  1509.             elseif (args[3] >= 1 and args[3] <= 20) and (args[4] >= 5 and args[4] <= 17) then
  1510.                 -- Choose
  1511.                 local cid = args[4] - 4 + lscroll
  1512.                 if #ldata >= cid then
  1513.                     lselect = ldata[cid]
  1514.                     rdata = {}
  1515.                     for k,v in ipairs(allapps) do
  1516.                         if v.category == lselect then
  1517.                             rdata[#rdata+1] = v
  1518.                         end
  1519.                     end
  1520.                     for i=1, 14 do
  1521.                         base.draw.box(22, 29, i+3, 1, false, "white", "white")
  1522.                     end
  1523.                     rscroll = 0
  1524.                     rrun(rscroll)
  1525.                     lrun(lscroll)
  1526.                 end
  1527.             elseif (args[3] >= 22 and args[3] <= 51) and (args[4] >= 5 and args[4] <= 17) then
  1528.                 -- View app
  1529.                 local cid = args[4] - 4 + rscroll
  1530.                 if #rdata >= cid then
  1531.                     viewapps[1] = rdata[cid].id
  1532.                     viewapps[2] = discover.data.apps
  1533.                     if not base.thread.find("View"..tostring(rdata[cid].id)) then
  1534.                         base.thread.create("View"..tostring(rdata[cid].id), store.apps.view)
  1535.                     end
  1536.                     base.thread.switch("View"..tostring(rdata[cid].id))
  1537.                 end
  1538.             end
  1539.         elseif args[1] == "mouse_scroll" then
  1540.             if args[2] == -1 then
  1541.                 if (args[3] >= 1 and args[3] <= 20) and (args[4] >= 4 and args[4] <= 17) then
  1542.                     if lscroll > 0  then
  1543.                         lscroll = lscroll - 1
  1544.                         lrun(lscroll)
  1545.                     end
  1546.                 elseif (args[3] >= 22 and args[3] <= 51) and (args[4] >= 4 and args[4] <= 17) then
  1547.                     if rscroll > 0 then
  1548.                         rscroll = rscroll - 1
  1549.                         rrun(rscroll)
  1550.                     end
  1551.                 end
  1552.             elseif args[2] == 1 then
  1553.                 if (args[3] >= 1 and args[3] <= 20) and (args[4] >= 4 and args[4] <= 17) then
  1554.                     if lscroll + 14 <= #ldata-1 then
  1555.                         lscroll = lscroll + 1
  1556.                         lrun(lscroll)
  1557.                     end
  1558.                 elseif (args[3] >= 22 and args[3] <= 51) and (args[4] >= 4 and args[4] <= 17) then
  1559.                     if rscroll + 14 <= #rdata-1 then
  1560.                         rscroll = rscroll + 1
  1561.                         rrun(rscroll)
  1562.                     end
  1563.                 end
  1564.             end
  1565.         end
  1566.     end
  1567. end
  1568.  
  1569. function store.apps.view()
  1570.     base.screen.colour("white")
  1571.     base.draw.textc("Loading...", 9, false, "grey", "white")
  1572.     local scroll = 0
  1573.  
  1574.     local appid = viewapps[1]
  1575.     local appslist = viewapps[2]
  1576.  
  1577.     for k,v in ipairs(appslist) do
  1578.         if tonumber(v.id) == tonumber(appid) then
  1579.             apppos = k
  1580.             break
  1581.         end
  1582.     end
  1583.  
  1584.     local appdesc = base.data.wordwrap(appslist[apppos].description, 49)
  1585.  
  1586.     base.screen.colour("white")
  1587.     store.draw.menu("View App "..tostring(appslist[apppos].id))
  1588.     base.draw.box(1, 51, 19, 1, " ", "grey", "grey")
  1589.     base.draw.texta("Comments", 2, 19, false, "lightBlue", "grey")
  1590.  
  1591.     local function drawdesc(scroll)
  1592.         for i = 1, 7 do
  1593.             if #appdesc >= i + scroll then
  1594.                 base.draw.box(1, 51, i+9, 1, " ", "white", "white")
  1595.                 base.draw.textl(appdesc[i+scroll], i+9, false, "grey", "white")
  1596.             end
  1597.         end
  1598.     end
  1599.  
  1600.     local function run()
  1601.         base.draw.textl("Name (ID):", 4, false, "lightGrey", "white")
  1602.         base.draw.texta(appslist[apppos].name.." ("..appslist[apppos].id..")", 12, 4, false, "grey", "white")
  1603.         base.draw.textl("Category:", 5, false, "lightGrey", "white")
  1604.         base.draw.texta(appslist[apppos].category, 12, 5, false, "grey", "white")
  1605.         base.draw.textl("Version:", 6, false, "lightGrey", "white")
  1606.         base.draw.texta(appslist[apppos].version, 12, 6, false, "grey", "white")
  1607.         base.draw.textl("Creator:", 7, false, "lightGrey", "white")
  1608.         base.draw.texta(appslist[apppos].creator, 12, 7, false, "grey", "white")
  1609.         base.draw.textl("App Hash:", 18, false, "lightGrey", "white")
  1610.         base.draw.texta(appslist[apppos].hash, 11, 18, false, "grey", "white")
  1611.         base.draw.textl("Description", 9, false, "lightGrey", "white")
  1612.         base.draw.textr(appslist[apppos].downloads.." download(s) ", 19, false, "orange", "grey")
  1613.         drawdesc(scroll)
  1614.         base.draw.texta(" Download ", 41, 5, false, "white", "cyan")
  1615.         base.draw.texta("   App!   ", 41, 6, false, "white", "cyan")
  1616.     end
  1617.  
  1618.     run()
  1619.  
  1620.     while true do
  1621.         local args = { os.pullEvent() }
  1622.         if args[1] == "timer" then
  1623.             store.draw.menu("View App "..tostring(appslist[apppos].id))
  1624.         elseif args[1] == "mouse_click" then
  1625.             if args[4] >= 1 and args[4] <= 2 then
  1626.                 store.draw.menu_input("Help / FAQ", args[3], args[4])
  1627.             elseif (args[3] >= 41 and args[3] <= 50) and (args[4] >= 5 and args[4] <= 6) then
  1628.                 temp.download = appslist[apppos].id
  1629.                 base.thread.create("Download"..tostring(appslist[apppos].id), store.apps.download)
  1630.                 base.thread.switch("Download"..tostring(appslist[apppos].id))
  1631.             elseif (args[3] >= 2 and args[3] <= 9) and args[4] == 19 then
  1632.                 store.apps.comments(appslist[apppos].id)
  1633.                 base.screen.colour("white")
  1634.                 store.draw.menu("View App "..tostring(appslist[apppos].id))
  1635.                 base.draw.box(1, 51, 19, 1, " ", "grey", "grey")
  1636.                 base.draw.texta("Comments", 2, 19, false, "lightBlue", "grey")
  1637.                 run()
  1638.             end
  1639.         elseif args[1] == "mouse_scroll" then
  1640.             if args[2] == -1 then
  1641.                 if scroll > 0 then
  1642.                     scroll = scroll - 1
  1643.                     run(scroll)
  1644.                 end
  1645.             elseif args[2] == 1 then
  1646.                 if scroll + 14 <= #appdesc then
  1647.                     scroll = scroll + 1
  1648.                     run(scroll)
  1649.                 end
  1650.             end
  1651.         end
  1652.     end
  1653. end
  1654.  
  1655. function store.apps.comments(appid)
  1656.     base.screen.colour("white")
  1657.     base.draw.textc("Download comments...", 9, false, "grey", "white")
  1658.     local scroll = 0
  1659.     local ok = discover:store_comments_get(appid)
  1660.     if not ok then
  1661.         viewapps[1] = appid
  1662.         store.apps.view()
  1663.     end
  1664.     comments = discover.data.comments
  1665.     base.screen.colour("white")
  1666.     store.draw.menu("Comments: "..tostring(appid))
  1667.     base.draw.box(1, 51, 19, 1, " ", "grey", "grey")
  1668.     if discover.data.loggedin then
  1669.         base.draw.textl(" Add", 19, false, "lightBlue", "grey")
  1670.     end
  1671.     base.draw.textr("Back ", 19, false, "orange", "grey")
  1672.  
  1673.     local function run(scroll)
  1674.         if #comments == 0 then
  1675.             base.draw.textc("No comments to display", 9, false, "grey", "white")
  1676.         end
  1677.         for i=1, 14 do
  1678.             if #comments >= i + scroll then
  1679.                 base.draw.box(1, 51, i+9, 1, " ", "white", "white")
  1680.                 base.draw.textl(comments[i+scroll].comment, i+3, false, "grey", "white")
  1681.                 base.draw.textr(comments[i+scroll].username, i+3, false, "cyan", "white")
  1682.             end
  1683.         end
  1684.     end
  1685.  
  1686.     run(scroll)
  1687.     while true do
  1688.         local args = { os.pullEvent() }
  1689.         if args[1] == "timer" then
  1690.             store.draw.menu("Comments: "..tostring(appid))
  1691.         elseif args[1] == "mouse_click" then
  1692.             if args[4] >= 1 and args[4] <= 2 then
  1693.                 store.draw.menu_input("Help / FAQ", args[3], args[4])
  1694.             elseif (args[3] >= 2 and args[3] <= 4) and (args[4] == 19) then
  1695.                 if discover.data.loggedin then
  1696.                     local comment = base.gui.input("Comment Text:")
  1697.                     local status = discover:store_comments_set( appid, comment )
  1698.                     if status then
  1699.                         base.gui.alert("Added!")
  1700.                         sleep(0.5)
  1701.                     else
  1702.                         base.gui.alert("Failed")
  1703.                         sleep(1)
  1704.                     end
  1705.                     base.screen.colour("white")
  1706.                     base.draw.textc("Download comments...", 9, false, "grey", "white")
  1707.                     local scroll = 0
  1708.                     local ok = discover:store_comments_get(appid)
  1709.                     if not ok then
  1710.                         viewapps[1] = appid
  1711.                         store.apps.view()
  1712.                     end
  1713.                     comments = discover.data.comments
  1714.                     base.screen.colour("white")
  1715.                     store.draw.menu("Comments: "..tostring(appid))
  1716.                     base.draw.box(1, 51, 19, 1, " ", "grey", "grey")
  1717.                     if discover.data.loggedin then
  1718.                         base.draw.textl(" Add", 19, false, "lightBlue", "grey")
  1719.                     end
  1720.                     base.draw.textr("Back ", 19, false, "orange", "grey")
  1721.                     run(scroll)
  1722.                 end
  1723.             elseif (args[3] >= 47 and args[3] <= 50) and (args[4] == 19) then
  1724.                 break
  1725.             end
  1726.         elseif args[1] == "mouse_scroll" then
  1727.             if args[2] == -1 then
  1728.                 if scroll > 0 then
  1729.                     scroll = scroll - 1
  1730.                     run(scroll)
  1731.                 end
  1732.             elseif args[2] == 1 then
  1733.                 if scroll + 14 <= #comments then
  1734.                     scroll = scroll + 1
  1735.                     run(scroll)
  1736.                 end
  1737.             end
  1738.         end        
  1739.     end
  1740. end
  1741.  
  1742. function store.account.login()
  1743.     base.screen.colour("white")
  1744.     store.draw.menu("Login")
  1745.     base.draw.box(1, 51, 19, 1, " ", "grey", "grey")
  1746.     base.draw.textl(" Cancel", 19, false, "orange", "grey")
  1747.     base.draw.textr("Login ", 19, false, "cyan", "grey")
  1748.  
  1749.     local function run()
  1750.         base.draw.textc("Discover API Login", 4, false, "grey", "white")
  1751.         base.draw.texta("Username:", 8, 7, false, "lightGrey", "white")
  1752.         base.draw.box(8, 36, 8, 1, " ", "cyan", "cyan")
  1753.         base.draw.texta("Password:", 8, 10, false, "lightGrey", "white")
  1754.         base.draw.box(8, 36, 11, 1, " ", "cyan", "cyan")
  1755.         base.draw.textc("Need an account? Register here!", 14, false, "grey", "white")
  1756.     end
  1757.  
  1758.     run()
  1759.     restart_home = true
  1760.  
  1761.     while not discover.data.loggedin or restart_home do
  1762.         local args = { os.pullEvent() }
  1763.         if args[1] == "timer" then
  1764.             store.draw.menu("Login")
  1765.         elseif args[1] == "mouse_click" then
  1766.             if args[4] >= 1 and args[4] <= 2 then
  1767.                 store.draw.menu_input("Login", args[3], args[4])
  1768.             elseif (args[3] >= 8 and args[3] <= 43) and (args[4] == 8) then
  1769.                 base.draw.box(8, 36, 8, 1, " ", "cyan", "cyan")
  1770.                 base.colour.set("white", "cyan")
  1771.                 term.setCursorPos(8, 8)
  1772.                 write(": ")
  1773.                 username = tostring(base.io.limitRead(34))
  1774.             elseif (args[3] >= 8 and args[3] <= 43) and (args[4] == 11) then
  1775.                 base.draw.box(8, 36, 11, 1, " ", "cyan", "cyan")
  1776.                 base.colour.set("white", "cyan")
  1777.                 term.setCursorPos(8, 11)
  1778.                 write(": ")
  1779.                 password = tostring(base.io.limitRead(34, "*"))
  1780.                 password = base.crypto.sha256(password)
  1781.             elseif (args[3] >= 8 and args[3] <= 43) and (args[4] == 14) then
  1782.                 store.account.register()
  1783.             elseif (args[3] >= 2 and args[3] <= 10) and (args[4] == 19) then
  1784.                 break
  1785.             elseif (args[3] >= 46 and args[3] <= 50) and (args[4] == 19) then
  1786.                 if username and password then
  1787.                     base.draw.textc("Requesting Authentication, Please Wait", 17, false, "lightGrey", "white")
  1788.                     if discover:login(username, password) then
  1789.                         discover.data.loggedin = true
  1790.                         base.gui.alert("Logged In!")
  1791.                         if system.storeconfig then
  1792.                             new = {}
  1793.                             new.username = discover.data.username
  1794.                             new.password = discover.data.password
  1795.                             new.storeconfig = system.storeconfig
  1796.                             new.plugins = system.plugins
  1797.                             new.authkey = discover.data.authkey
  1798.                             dat = textutils.serialize(new)
  1799.                             local f = fs.open(system.paths.config, "w")
  1800.                             f.write(base.base64.encode(dat))
  1801.                             f.close()
  1802.                         end
  1803.                         sleep(0.8)
  1804.                         store.home()
  1805.                     else
  1806.                         base.draw.box(1, 51, 17, 1, " ", "white", "white")
  1807.                         base.draw.textc(tostring(discover.data.errormsg), 17, false, "lightGrey", "white")
  1808.                         sleep(1)
  1809.                         store.home()
  1810.                     end
  1811.                 else
  1812.                     base.draw.textc("Please fill in the fields", 17, false, "lightGrey", "white")
  1813.                 end
  1814.             end
  1815.         end
  1816.     end
  1817. end
  1818.  
  1819. function store.account.register()
  1820.     base.screen.colour("white")
  1821.     store.draw.menu("Login")
  1822.     base.draw.box(1, 51, 19, 1, " ", "grey", "grey")
  1823.     base.draw.textl(" Cancel", 19, false, "orange", "grey")
  1824.     base.draw.textr("Register ", 19, false, "cyan", "grey")
  1825.  
  1826.     local function run()
  1827.         base.draw.textc("Discover API Registration", 4, false, "grey", "white")
  1828.         base.draw.texta("Username:", 8, 7, false, "lightGrey", "white")
  1829.         base.draw.box(8, 36, 8, 1, " ", "cyan", "cyan")
  1830.         base.draw.texta("Password:", 8, 10, false, "lightGrey", "white")
  1831.         base.draw.box(8, 36, 11, 1, " ", "cyan", "cyan")
  1832.         base.draw.texta("Email:", 8, 13, false, "lightGrey", "white")
  1833.         base.draw.box(8, 36, 14, 1, " ", "cyan", "cyan")
  1834.         base.draw.textc("Have an account? Login here!", 17, false, "grey", "white")
  1835.     end
  1836.  
  1837.     run()
  1838.     restart_home = true
  1839.  
  1840.     while not discover.data.loggedin or restart_home do
  1841.         local args = { os.pullEvent() }
  1842.         if args[1] == "timer" then
  1843.             store.draw.menu("Login")
  1844.         elseif args[1] == "mouse_click" then
  1845.             if args[4] >= 1 and args[4] <= 2 then
  1846.                 store.draw.menu_input("Login", args[3], args[4])
  1847.             elseif (args[3] >= 8 and args[3] <= 43) and (args[4] == 8) then
  1848.                 base.draw.box(8, 36, 8, 1, " ", "cyan", "cyan")
  1849.                 base.colour.set("white", "cyan")
  1850.                 term.setCursorPos(8, 8)
  1851.                 write(": ")
  1852.                 username = tostring(base.io.limitRead(34))
  1853.             elseif (args[3] >= 8 and args[3] <= 43) and (args[4] == 11) then
  1854.                 base.draw.box(8, 36, 11, 1, " ", "cyan", "cyan")
  1855.                 base.colour.set("white", "cyan")
  1856.                 term.setCursorPos(8, 11)
  1857.                 write(": ")
  1858.                 password = tostring(base.io.limitRead(34, "*"))
  1859.                 password = base.crypto.sha256(password)
  1860.             elseif (args[3] >= 8 and args[3] <= 43) and (args[4] == 14) then
  1861.                 base.draw.box(8, 36, 14, 1, " ", "cyan", "cyan")
  1862.                 base.colour.set("white", "cyan")
  1863.                 term.setCursorPos(8, 14)
  1864.                 write(": ")
  1865.                 email = tostring(base.io.limitRead(34))
  1866.             elseif (args[3] >= 9 and args[3] <= 42) and (args[4] == 17) then
  1867.                 store.account.login()
  1868.             elseif (args[3] >= 2 and args[3] <= 10) and (args[4] == 19) then
  1869.                 break
  1870.             elseif (args[3] >= 43 and args[3] <= 50) and (args[4] == 19) then
  1871.                 if username and password and email then
  1872.                     base.draw.textc("Requesting Authentication, Please Wait", 17, false, "lightGrey", "white")
  1873.                     if discover:register(username, password, email) then
  1874.                         base.gui.alert("Registered. Obtaining authkey, please wait")
  1875.                         sleep(0.5)
  1876.                         local status = discover:login(username, password)
  1877.                         if status then
  1878.                             base.gui.alert("Logged in!")
  1879.                             sleep(0.8)
  1880.                             store.home()
  1881.                         else
  1882.                             base.gui.alert(discover.data.errormsg)
  1883.                             sleep(1.5)
  1884.                             store.home()
  1885.                         end
  1886.                     else
  1887.                         base.draw.box(1, 51, 17, 1, " ", "white", "white")
  1888.                         base.draw.textc(tostring(discover.data.errormsg), 17, false, "lightGrey", "white")
  1889.                         sleep(1)
  1890.                         store.account.home()
  1891.                     end
  1892.                 else
  1893.                     base.draw.textc("Please fill in the fields", 17, false, "lightGrey", "white")
  1894.                 end
  1895.             end
  1896.         end
  1897.     end
  1898. end
  1899.  
  1900. function store.account.logout()
  1901.     base.gui.alert("Logging out...")
  1902.     sleep(0.5)
  1903.     discover:logout()
  1904.     base.gui.alert("Logged out!")
  1905.     sleep(0.5)
  1906. end
  1907.  
  1908. function store.apps.search(searchterm)
  1909.     if searchterm == "mouse_up" then
  1910.         searchterm = nil
  1911.     end
  1912.     base.screen.colour("white")
  1913.     store.draw.menu("Search")
  1914.     base.draw.box(1, 51, 19, 1, " ", "grey", "grey")
  1915.     base.draw.box(3, 47, 19, 1, " ", "lightGrey", "lightGrey")
  1916.     base.draw.textc("Click here to search", 19, false, "white", "lightGrey")
  1917.     local appslist = discover:get("apps")
  1918.     local apps = appslist
  1919.     local scroll = 0
  1920.     if searchterm then
  1921.         apps = {}
  1922.         for k,v in ipairs(appslist) do
  1923.             if string.lower(v.name):match(searchterm:lower()) then
  1924.                 table.insert(apps, v)
  1925.             end
  1926.         end
  1927.     end
  1928.    
  1929.     local function run(scroll)
  1930.         if #apps > 0 then
  1931.             for i=1, 14 do
  1932.                 if (scroll + i) <= #apps then
  1933.                     base.draw.box(1, 51, i+3, 1, " ", "white", "white")
  1934.                     base.draw.texta(tostring(i+scroll) .. ": " .. apps[i+scroll].name, 1, i+3, false, "grey", "white")
  1935.                 end
  1936.             end
  1937.         else
  1938.             base.draw.textc("No apps match your search term", 10, false, "red", "white")
  1939.         end
  1940.     end
  1941.  
  1942.     run(scroll)
  1943.     while true do
  1944.         local args = { os.pullEvent() }
  1945.         if args[1] == "timer" then
  1946.             store.draw.menu("Search")
  1947.         elseif args[1] == "mouse_click" then
  1948.             if args[4] >= 1 and args[4] <= 2 then
  1949.                 store.draw.menu_input("Search", args[3], args[4])
  1950.             elseif (args[3] >= 3 and args[3] <= 49) and (args[4] == 19) then
  1951.                 base.draw.box(3, 47, 19, 1, " ", "lightGrey", "lightGrey")
  1952.                 base.colour.set("orange", "lightGrey")
  1953.                 term.setCursorPos(3, 19)
  1954.                 write(": ")
  1955.                 local keyterm = tostring(base.io.limitRead(45))
  1956.                 term.setCursorPos(1,4)
  1957.                 store.apps.search(keyterm)
  1958.             elseif (args[3] >= 1 and args[3] <= 51) and (args[4] >= 4 and args[4] <= 17) then
  1959.                 local curid = args[4] - 3 + scroll
  1960.                 if curid > 0 and curid <= #apps then
  1961.                     local tname = "View"..tostring(apps[curid].id)
  1962.                     base.thread.create(tname, store.apps.view)
  1963.                     viewapps[1] =  apps[curid].id
  1964.                     viewapps[2] = apps
  1965.                     base.thread.switch(tname)
  1966.                 end
  1967.             end
  1968.         elseif args[1] == "mouse_scroll" then
  1969.             if args[2] == -1 then
  1970.                 if scroll > 0 then
  1971.                     scroll = scroll - 1
  1972.                     run(scroll)
  1973.                 end
  1974.             elseif args[2] == 1 then
  1975.                 if scroll + 14 < #apps then
  1976.                     scroll = scroll + 1
  1977.                     run(scroll)
  1978.                 end
  1979.             end
  1980.         end
  1981.     end
  1982. end
  1983.  
  1984. function store.account.upload(step)
  1985.     if not step then
  1986.         step = ""
  1987.     end
  1988.     if step == "1" then
  1989.         base.screen.colour("white")
  1990.         store.draw.menu("Upload (Step 1)")
  1991.         base.draw.box(1, 51, 19, 11, " ", "grey", "grey")
  1992.         base.draw.textl(" Cancel", 19, false, "orange", "grey")
  1993.         base.draw.textr("Next Step ", 19, false, "orange", "grey")
  1994.         base.draw.textc("Press \"up\" to see preset versions / categories.", 18, false, "lightGrey", "white")
  1995.  
  1996.         local function run()
  1997.             base.draw.textc("Please follow on-screen instructions!", 4, false, "cyan", "white")
  1998.             base.draw.texta("App Name:", 8, 6, false, "lightGrey", "white")
  1999.             base.draw.box(8, 36, 7, 1, " ", "cyan", "cyan")
  2000.             base.draw.texta("App Description:", 8, 9, false, "lightGrey", "white")
  2001.             base.draw.box(8, 36, 10, 1, " ", "cyan", "cyan")
  2002.             base.draw.texta("App Version:", 8, 12, false, "lightGrey", "white")
  2003.             base.draw.box(8, 36, 13, 1, " ", "cyan", "cyan")
  2004.             base.draw.texta("App Category:", 8, 15, false, "lightGrey", "white")
  2005.             base.draw.box(8, 36, 16, 1, " ", "cyan", "cyan")
  2006.         end
  2007.  
  2008.         local function render()
  2009.             if up_name then
  2010.                 base.draw.texta(tostring(": "..up_name), 8, 7, false, "white", "cyan")
  2011.             end
  2012.             if up_desc then
  2013.                 base.draw.texta(tostring(": "..up_desc), 8, 10, false, "white", "cyan")
  2014.             end
  2015.             if up_vers then
  2016.                 base.draw.texta(tostring(": "..up_vers), 8, 13, false, "white", "cyan")
  2017.             end
  2018.             if up_cate then
  2019.                 base.draw.texta(tostring(": "..up_cate), 8, 16, false, "white", "cyan")
  2020.             end
  2021.         end
  2022.  
  2023.         render()
  2024.         run()
  2025.         while true do
  2026.             local args = { os.pullEvent() }
  2027.             if args[1] == "timer" then
  2028.                 store.draw.menu("Upload (Step 1)")
  2029.             elseif args[1] == "mouse_click" then
  2030.                 if args[4] >= 1 and args[4] <= 2 then
  2031.                     store.draw.menu_input("Upload", args[3], args[4])
  2032.                 elseif (args[3] >= 2 and args[3] <= 7) and (args[4] == 19) then
  2033.                     base.thread.remove("Upload")
  2034.                     if not base.thread.find("Account") then
  2035.                         base.thread.create("Account", store.account.home)
  2036.                     end
  2037.                     base.thread.switch("Account")
  2038.                 elseif (args[3] >= 42 and args[3] <= 50) and (args[4] == 19) then
  2039.                     if up_name and up_desc and up_vers and up_cate then
  2040.                         store.account.upload("2")
  2041.                     else
  2042.                         base.draw.box(1, 51, 17, 1, " ", "white", "white")
  2043.                         base.draw.textc("Please fill out all fields", 17, false, "red", "white")
  2044.                         sleep(1)
  2045.                         base.draw.box(1, 51, 17, 1, " ", "white", "white")
  2046.                     end
  2047.                 elseif (args[3] >= 8 and args[3] <= 43) and (args[4] == 7) then
  2048.                     base.draw.box(1, 51, 7, 1, " ", "white", "white")
  2049.                     base.draw.box(8, 36, 7, 1, " ", "cyan", "cyan")
  2050.                     base.colour.set("white", "cyan")
  2051.                     term.setCursorPos(8, 7)
  2052.                     write(": ")
  2053.                     up_name = tostring(base.io.limitRead(34))
  2054.                 elseif (args[3] >= 8 and args[3] <= 43) and (args[4] == 10) then
  2055.                     base.draw.box(1, 51, 10, 1, " ", "white", "white")
  2056.                     base.draw.box(8, 36, 10, 1, " ", "cyan", "cyan")
  2057.                     base.colour.set("white", "cyan")
  2058.                     term.setCursorPos(8, 10)
  2059.                     write(": ")
  2060.                     up_desc = tostring(base.io.limitRead(34))
  2061.                 elseif (args[3] >= 8 and args[3] <= 43) and (args[4] == 13) then
  2062.                     base.draw.box(1, 51, 13, 1, " ", "white", "white")
  2063.                     base.draw.box(8, 36, 13, 1, " ", "cyan", "cyan")
  2064.                     base.colour.set("white", "cyan")
  2065.                     term.setCursorPos(8, 13)
  2066.                     write(": ")
  2067.                     up_vers = tostring(read(_, discover.data.versions))
  2068.                 elseif (args[3] >= 8 and args[3] <= 43) and (args[4] == 16) then
  2069.                     base.draw.box(1, 51, 16, 1, " ", "white", "white")
  2070.                     base.draw.box(8, 36, 16, 1, " ", "cyan", "cyan")
  2071.                     base.colour.set("white", "cyan")
  2072.                     term.setCursorPos(8, 16)
  2073.                     write(": ")
  2074.                     up_cate = tostring(read(_, discover.data.categories))
  2075.                 end
  2076.             end
  2077.         end
  2078.     elseif step == "2" then
  2079.         base.screen.colour("white")
  2080.         store.draw.menu("Upload (Step 2)")
  2081.         base.draw.box(1, 51, 19, 11, " ", "grey", "grey")
  2082.         base.draw.textl(" Back", 19, false, "orange", "grey")
  2083.         base.draw.textr("Upload ", 19, false, "orange", "grey")
  2084.  
  2085.         local function run()
  2086.             base.draw.textc("Please follow on-screen instructions!", 4, false, "cyan", "white")
  2087.             base.draw.texta("App Status:", 8, 6, false, "lightGrey", "white")
  2088.             base.draw.box(8, 36, 7, 1, " ", "cyan", "cyan")
  2089.             base.draw.texta("App\'s file path:", 8, 9, false, "lightGrey", "white")
  2090.             base.draw.box(8, 36, 10, 1, " ", "cyan", "cyan")
  2091.         end
  2092.  
  2093.         local function exit()
  2094.             up_stat = nil
  2095.             up_path = nil
  2096.             up_desc = nil
  2097.             up_cate = nil
  2098.             up_vers = nil
  2099.             up_name = nil
  2100.             base.thread.remove("Upload")
  2101.             if not base.thread.find("Account") then
  2102.                 base.thread.create("Account", store.account.home)
  2103.             end
  2104.             base.thread.switch("Account")
  2105.         end
  2106.         local use_paste = true; local use_file = false;
  2107.         local function input_type()
  2108.             if use_paste then
  2109.                 use_paste = false
  2110.                 use_file = true
  2111.                 base.draw.box(8, 27, 10, 1, " ", "cyan", "cyan")
  2112.                 base.draw.box(8, 27, 9, 1, " ", "white", "white")
  2113.                 base.draw.texta("App\'s file path:", 8, 9, false, "lightGrey", "white")
  2114.                 base.draw.texta(" Toggle ", 36, 10, false, "white", "orange")
  2115.             elseif use_file then
  2116.                 use_paste = true
  2117.                 use_file = false
  2118.                 base.draw.box(8, 27, 10, 1, " ", "cyan", "cyan")
  2119.                 base.draw.box(8, 27, 9, 1, " ", "white", "white")
  2120.                 base.draw.texta("Pastebin ID:", 8, 9, false, "lightGrey", "white")
  2121.                 base.draw.texta(" Toggle ", 36, 10, false, "white", "orange")
  2122.             end
  2123.         end
  2124.  
  2125.         local function render()
  2126.             if up_stat then
  2127.                 base.draw.texta(tostring(": "..up_stat), 8, 7, false, "white", "cyan")
  2128.             end
  2129.             if up_path then
  2130.                 base.draw.texta(tostring(": "..up_path), 8, 10, false, "white", "cyan")
  2131.             end
  2132.         end
  2133.  
  2134.         run()
  2135.         render()
  2136.         input_type()
  2137.         while true do
  2138.             local args = { os.pullEvent() }
  2139.             if args[1] == "timer" then
  2140.                 store.draw.menu("Upload (Step 2)")
  2141.             elseif args[1] == "mouse_click" then
  2142.                 if args[4] >= 1 and args[4] <= 2 then
  2143.                     store.draw.menu_input("Upload", args[3], args[4])
  2144.                 elseif (args[3] >= 8 and args[3] <= 43) and (args[4] == 7) then
  2145.                     base.draw.box(1, 51, 7, 1, " ", "white", "white")
  2146.                     base.draw.box(8, 36, 7, 1, " ", "cyan", "cyan")
  2147.                     base.colour.set("white", "cyan")
  2148.                     term.setCursorPos(8, 7)
  2149.                     write(": ")
  2150.                     up_stat = tostring(read(_, {"public", "private"}))
  2151.                 elseif (args[3] >= 36 and args[3] <= 43) and (args[4] == 10) then
  2152.                     input_type()
  2153.                 elseif (args[3] >= 8 and args[3] <= 35) and (args[4] == 10) then
  2154.                     base.draw.box(8, 27, 10, 1, " ", "cyan", "cyan")
  2155.                     base.colour.set("white", "cyan")
  2156.                     term.setCursorPos(8, 10)
  2157.                     write(": ")
  2158.                     up_path = tostring(base.io.limitRead(34))
  2159.                 elseif (args[3] >= 45 and args[3] <= 50) and (args[4] == 19) then
  2160.                     if up_stat and up_path then
  2161.                         for i=12, 17 do
  2162.                             base.draw.box(1, 51, i, 1, " ", "white", "white")
  2163.                         end
  2164.  
  2165.                         if use_paste then
  2166.                             base.draw.texta(":: Downloading File...", 8, 12, false, "grey", "white")
  2167.                             app = http.get("http://pastebin.com/raw/" .. textutils.urlEncode(tostring(up_path)))
  2168.                             base.draw.texta(":: Extracting Data...", 8, 13, false, "grey", "white")
  2169.                             up_path_content = app.readAll()
  2170.                         elseif use_file then
  2171.                             base.draw.texta(":: Finding File...", 8, 12, false, "grey", "white")
  2172.                             if fs.exists(up_path) then
  2173.                                 base.draw.texta(":: Extracting Data...", 8, 13, false, "grey", "white")
  2174.                                 local f = fs.open(up_path, "r")
  2175.                                 up_path_content = f.readAll()
  2176.                                 f.close()
  2177.                             else
  2178.                                 base.draw.texta(":: ERROR -> No file found", 8, 13, false, "grey", "white")
  2179.                                 sleep(1)
  2180.                                 store.account.upload("2")
  2181.                             end
  2182.                         end
  2183.                         base.draw.texta(":: Sending Server Request...", 8, 14, false, "grey", "white")
  2184.                         local status = discover:store_upload( up_name, up_desc, up_cate, up_vers, up_stat, up_path_content )
  2185.                         if status then
  2186.                             base.draw.texta(":: Upload was successfull!", 8, 15, false, "grey", "white")
  2187.                             sleep(1)
  2188.                             base.gui.alert("Updating local app database...")
  2189.                             discover:store_init()
  2190.                             exit()
  2191.                         else
  2192.                             base.draw.texta(":: Unable to store data", 8, 15, false, "grey", "white")
  2193.                             base.draw.texta(":: "..tostring(discover.data.errormsg), 8, 15, false, "grey", "white")
  2194.                             sleep(2)
  2195.                         end
  2196.                     else
  2197.                         base.draw.box(1, 51, 18, 1, " ", "white", "white")
  2198.                         base.draw.textc("Please fill out all fields", 18, false, "red", "white")
  2199.                         sleep(1)
  2200.                         base.draw.box(1, 51, 18, 1, " ", "white", "white")
  2201.                     end
  2202.                 elseif (args[3] >= 2 and args[3] <= 5) and (args[4] == 19) then
  2203.                     store.account.upload("1")
  2204.                 end
  2205.             end
  2206.         end
  2207.     else
  2208.         base.screen.colour("white")
  2209.         store.draw.menu("Upload")
  2210.         base.draw.box(1, 51, 19, 11, " ", "grey", "grey")
  2211.         base.draw.textl(" Cancel", 19, false, "orange", "grey")
  2212.         base.draw.textr("Accept ", 19, false, "orange", "grey")
  2213.         local scroll = 0
  2214.  
  2215.         local function run(scroll)
  2216.             base.draw.textc("Please read the following before submitting:", 4, false, "lightGrey", "white")
  2217.             local text = "Apps uploaded to this system are saved to a database/server. We do NOT edit your code and/or modify it for our own use. App moderators will check apps for malicious code to try and stop any kind of data stealing. We also say that if your app is full of errors, it may be set to private, and a notification sent to your account/email in the database, mentioning this - of course once updated you can set it to public again. Program installers are also very welcome."
  2218.             tText = base.data.wordwrap(text, 47)
  2219.             for i=1, 12 do
  2220.                 if (scroll + i) <= #tText then
  2221.                     base.draw.box(1, 51, i+5, 1, " ", "white", "white")
  2222.                     base.draw.texta(tText[i+scroll], 3, i+5, false, "grey", "white")
  2223.                 end
  2224.             end
  2225.         end
  2226.  
  2227.         run(scroll)
  2228.         while true do
  2229.             local args = { os.pullEvent() }
  2230.             if args[1] == "timer" then
  2231.                 store.draw.menu("upload")
  2232.             elseif args[1] == "mouse_click" then
  2233.                 if args[4] >= 1 and args[4] <= 2 then
  2234.                     store.draw.menu_input("Upload", args[3], args[4])
  2235.                 elseif (args[3] >= 2 and args[3] <= 7) and (args[4] == 19) then
  2236.                     base.thread.remove("Upload")
  2237.                     if not base.thread.find("Account") then
  2238.                         base.thread.create("Account", store.account.home)
  2239.                     end
  2240.                     base.thread.switch("Account")
  2241.                 elseif (args[3] >= 45 and args[3] <= 50) and (args[4] == 19) then
  2242.                     store.account.upload("1")
  2243.                 end
  2244.             elseif args[1] == "mouse_scroll" then
  2245.                 if args[2] == -1 then
  2246.                     if scroll > 0 then
  2247.                         scroll = scroll - 1
  2248.                         run(scroll)
  2249.                     end
  2250.                 elseif args[2] == 1 then
  2251.                     if scroll + 12 < #tText then
  2252.                         scroll = scroll + 1
  2253.                         run(scroll)
  2254.                     end
  2255.                 end
  2256.             end
  2257.         end
  2258.     end
  2259. end
  2260.  
  2261. function store.apps.download()
  2262.     base.screen.colour("white")
  2263.     store.draw.menu("Download")
  2264.     local appid = temp.download
  2265.  
  2266.     local text = "You are attempting to download an app, please choose a name for the file download";
  2267.  
  2268.  
  2269.     local function run()
  2270.         for k,v in ipairs(base.data.wordwrap(text, 45)) do
  2271.             base.draw.textc(v, k+3, false, "grey", "white")
  2272.         end
  2273.         base.draw.texta("File Name / Path:", 8, 8, false, "lightGrey", "white")
  2274.         base.draw.box(8, 36, 9, 1, " ", "cyan", "cyan")
  2275.         base.draw.texta(" Download ", 8, 12, false, "white", "cyan")
  2276.         base.draw.texta(" Cancel ", 36, 12, false, "white", "cyan")
  2277.     end
  2278.  
  2279.  
  2280.     run()
  2281.  
  2282.     while true do
  2283.         local args = { os.pullEvent() }
  2284.         if args[1] == "timer" then
  2285.             store.draw.menu("Download")
  2286.         elseif args[1] == "mouse_click" then
  2287.             if args[4] >= 1 and args[4] <= 2 then
  2288.                 store.draw.menu_input("Download", args[3], args[4])
  2289.             elseif (args[3] >= 8 and args[3] <= 17) and (args[4] == 12) then
  2290.                 if filepath then
  2291.                     local data = discover:store_download(appid)
  2292.                     if data then
  2293.                         local f = fs.open(filepath, "w")
  2294.                         f.write(data.readAll())
  2295.                         f.close()
  2296.                         base.gui.alert("Saved!")
  2297.                         sleep(1)
  2298.                         base.thread.remove("Download" .. tostring(appid))
  2299.                         if base.thread.find("Apps") then
  2300.                             base.thread.create("Apps", store.apps.all)
  2301.                         end
  2302.                         base.thread.switch("Apps")
  2303.                     else
  2304.                         base.draw.box(1, 51, 14, 1, " ", "white", "white")
  2305.                         base.draw.textc("An error occured", 14, false, "lightGrey", "white")
  2306.                     end
  2307.                 else
  2308.                     base.draw.box(1, 51, 14, 1, " ", "white", "white")
  2309.                     base.draw.textc("Please supply a file path / name!", 14, false, "lightGrey", "white")
  2310.                 end
  2311.             elseif (args[3] >= 36 and args[3] <= 43) and (args[4] == 12) then
  2312.                 base.thread.remove("Download"..tostring(appid))
  2313.                 base.thread.switch("Home")
  2314.             elseif (args[3] >= 8 and args[3] <= 43) and (args[4] == 9) then
  2315.                 base.draw.box(8, 36, 9, 1, " ", "cyan", "cyan")
  2316.                 base.colour.set("white", "cyan")
  2317.                 term.setCursorPos(8, 9)
  2318.                 write(": ")
  2319.                 filepath = tostring(base.io.limitRead(34))
  2320.             end
  2321.         end
  2322.     end
  2323. end
  2324.  
  2325. function store.account.myapps()
  2326.     base.screen.colour("white")
  2327.     base.draw.textc("Downloading your apps list...", 9, false, "grey", "white")
  2328.     if not discover:store_apps_user() then
  2329.         base.gui.alert("Could not obtain your Apps list...")
  2330.         sleep(1.5)
  2331.         if not base.thread.find("Account") then
  2332.             base.thread.create("Account", store.account.home)
  2333.         end
  2334.         base.thread.remove("MyApps")
  2335.         base.thread.switch("Account")
  2336.     end
  2337.  
  2338.     appslist = discover.data.appsuser
  2339.  
  2340.     base.draw.box(1, 51, 9, 1, " ", "white", "white")
  2341.     store.draw.menu("MyApps")
  2342.     base.draw.box(1, 51, 19, 1, " ", "grey", "grey")
  2343.     base.draw.texta("Your Apps: "..tostring(#appslist), 2, 19, false, "orange", "grey")
  2344.     scroll = 0
  2345.  
  2346.     local function fix(num)
  2347.         if tostring(num):len() == 1 then
  2348.             return " "..tostring(num)
  2349.         else
  2350.             return tostring(num)
  2351.         end
  2352.     end
  2353.  
  2354.     local function run(scroll)
  2355.         for i = 1, 14 do
  2356.             if #appslist >= i + scroll then
  2357.                 base.draw.box(1, 51, i+3, 1, " ", "white", "white")
  2358.                 base.draw.texta(tostring(fix(i+scroll)..": "..appslist[i+scroll].name):sub(1, 40), 1, i+3, false, "grey", "white")
  2359.                 base.draw.texta("X", 50, i+3, false, "red", "white")
  2360.                 base.draw.texta("Edit", 44, i+3, false, "lightBlue", "white")
  2361.                 base.draw.texta("Upd", 40, i+3, false, "lightBlue", "white")
  2362.             end
  2363.         end
  2364.     end
  2365.  
  2366.     run(scroll)
  2367.  
  2368.     while true do
  2369.         local args = { os.pullEvent() }
  2370.         if args[1] == "timer" then
  2371.             store.draw.menu("MyApps")
  2372.         elseif args[1] == "mouse_click" then
  2373.             if args[4] >= 1 and args[4] <= 2 then
  2374.                 store.draw.menu_input("MyApps", args[3], args[4])
  2375.             elseif (args[3] >= 40 and args[3] <= 42) and (args[4] >= 4 and args[4] <= 17) then
  2376.                 -- Do update
  2377.                 local appid = appslist[args[4] - 3 + scroll].id
  2378.                 temp.edit_appid = appid
  2379.                 base.thread.create("Update", store.account.update)
  2380.                 base.thread.switch("Update")
  2381.             elseif (args[3] >= 44 and args[3] <= 47) and (args[4] >= 4 and args[4] <= 17) then
  2382.                 -- Do Edit
  2383.                 local appid = appslist[args[4] - 3 + scroll].id
  2384.                 temp.edit_appid = appid
  2385.                 base.thread.create("Edit", store.account.edit)
  2386.                 base.thread.switch("Edit")
  2387.             elseif (args[3] == 50) and (args[4] >= 4 and args[4] <= 17) then
  2388.                 -- Do Delete
  2389.                 local appid = appslist[args[4] - 3 + scroll].id
  2390.                 local appname = appslist[args[4] - 3 + scroll].name
  2391.                 base.draw.box(8, 36, 8, 2, " ", "grey", "grey")
  2392.                 base.draw.box(8, 36, 10, 2, " ", "grey", "grey")
  2393.                 local text = "To delete the app: "..tostring(appname).." press \"enter\" otherwise please press any other button to exit."
  2394.                 for k,v in ipairs(base.data.wordwrap(text, 34)) do
  2395.                     base.draw.texta(v, 9, k+7, false, "white", "grey")
  2396.                 end
  2397.                 while true do
  2398.                     local ev, nk = os.pullEvent("key")
  2399.                     if ev == "key" then
  2400.                         if nk == 28 then
  2401.                             base.screen.colour("white")
  2402.                             store.draw.menu("MyApps")
  2403.                             base.colour.set("cyan", "white")
  2404.                             term.setCursorPos(1, 4)
  2405.                             print("Deleting...")
  2406.                             local status = discover:store_delete( appid )
  2407.                             if status then
  2408.                                 print("\nApp was deleted!!")
  2409.                                 sleep(0.5)
  2410.                                 print("Updating local cache...")
  2411.                                 discover:store_init()
  2412.                                 sleep(0.5)
  2413.                                 store.account.myapps()
  2414.                             else
  2415.                                 base.gui.alert(discover.data.errormsg)
  2416.                                 sleep(1.5)
  2417.                                 store.account.myapps()
  2418.                             end
  2419.                         else
  2420.                             break
  2421.                         end
  2422.                     else
  2423.                         break
  2424.                     end
  2425.                 end
  2426.             end
  2427.         elseif args[1] == "mouse_scroll" then
  2428.             if args[2] == -1 then
  2429.                 if scroll > 0 then
  2430.                     scroll = scroll - 1
  2431.                     run(scroll)
  2432.                 end
  2433.             elseif args[2] == 1 then
  2434.                 if scroll + 14 < #appslist then
  2435.                     scroll = scroll + 1
  2436.                     run(scroll)
  2437.                 end
  2438.             end
  2439.         end
  2440.     end
  2441. end
  2442.  
  2443. function store.account.home()
  2444.     base.screen.colour("white")
  2445.     store.draw.menu("My Account")
  2446.  
  2447.     local function run()
  2448.         for i=1, 20 do
  2449.             base.draw.box(i, 1, 3, 17, " ", "lightGrey", "lightGrey")
  2450.         end
  2451.         base.draw.box(2, 18, 5, 1, " ", "orange", "orange")
  2452.         base.draw.box(2, 18, 7, 1, " ", "orange", "orange")
  2453.         base.draw.box(2, 18, 9, 1, " ", "orange", "orange")
  2454.         base.draw.box(2, 18, 11, 1, " ", "orange", "orange")
  2455.         base.draw.box(2, 18, 13, 1, " ", "orange", "orange")
  2456.         base.draw.box(2, 18, 15, 1, " ", "orange", "orange")
  2457.         base.draw.box(2, 18, 17, 1, " ", "orange", "orange")
  2458.         base.draw.texta("Upload an App", 3, 5, false, "white", "orange")
  2459.         base.draw.texta("Update an App", 3, 7, false, "white", "orange")
  2460.         base.draw.texta("View my Apps", 3, 9, false, "white", "orange")
  2461.         base.draw.texta("Notifications", 3, 11, false, "white", "orange")
  2462.         base.draw.texta("Change Password", 3, 13, false, "white", "orange")
  2463.         base.draw.texta("Change Email", 3, 15, false, "white", "orange")
  2464.         base.draw.texta("My Statistics", 3, 17, false, "white", "orange")
  2465.  
  2466.         -- Draw info
  2467.         base.draw.texta("My Details", 31, 4, false, "grey", "white")
  2468.         base.draw.texta("Username:", 22, 7, false, "lightGrey", "white")
  2469.         base.draw.box(22, 29, 8, 1, " ", "cyan", "cyan")
  2470.         base.draw.texta(tostring(discover.data.username), 23, 8, false, "white", "cyan")
  2471.         base.draw.texta("AuthKey:", 22, 11, false, "lightGrey", "white")
  2472.         base.draw.box(22, 29, 12, 1, " ", "cyan", "cyan")
  2473.         base.draw.box(22, 29, 13, 1, " ", "cyan", "cyan")
  2474.         base.draw.box(22, 29, 14, 1, " ", "cyan", "cyan")
  2475.         base.draw.box(22, 29, 15, 1, " ", "cyan", "cyan")
  2476.         base.draw.box(22, 29, 16, 1, " ", "cyan", "cyan")
  2477.         base.draw.texta(discover.data.authkey:sub(1, 27) , 23, 12, false, "white", "cyan")
  2478.         base.draw.texta(discover.data.authkey:sub(28, 54) , 23, 13, false, "white", "cyan")
  2479.         base.draw.texta(discover.data.authkey:sub(55, 81) , 23, 14, false, "white", "cyan")
  2480.         base.draw.texta(discover.data.authkey:sub(82, 108) , 23, 15, false, "white", "cyan")
  2481.         base.draw.texta(discover.data.authkey:sub(109) , 23, 16, false, "white", "cyan")
  2482.     end
  2483.  
  2484.     run()
  2485.     while true do
  2486.         local args = { os.pullEvent() }
  2487.         if args[1] == "timer" then
  2488.             store.draw.menu("My Account")
  2489.         elseif args[1] == "mouse_click" then
  2490.             if args[4] >= 1 and args[4] <= 2 then
  2491.                 store.draw.menu_input("Account", args[3], args[4])
  2492.             elseif (args[3] >= 2 and args[3] <= 18) and (args[4] == 5) then
  2493.                 if not base.thread.find("Upload") then
  2494.                     base.thread.create("Upload", store.account.upload)
  2495.                 end
  2496.                 base.thread.switch("Upload")
  2497.             elseif (args[3] >= 2 and args[3] <= 18) and (args[4] == 7) then
  2498.                 if not base.thread.find("Update") then
  2499.                     base.thread.create("Update", store.account.update)
  2500.                 end
  2501.                 base.thread.switch("Update")
  2502.             elseif (args[3] >= 2 and args[3] <= 18) and (args[4] == 9) then
  2503.                 if not base.thread.find("MyApps") then
  2504.                     base.thread.create("MyApps", store.account.myapps)
  2505.                 end
  2506.                 base.thread.switch("MyApps")
  2507.             elseif (args[3] >= 2 and args[3] <= 18) and (args[4] == 11) then
  2508.                 if not base.thread.find("Notifications") then
  2509.                     base.thread.create("Notifications", store.account.notifications)
  2510.                 end
  2511.                 base.thread.switch("Notifications")
  2512.             elseif (args[3] >= 2 and args[3] <= 18) and (args[4] == 13) then
  2513.                 if not base.thread.find("ModifyP") then
  2514.                     base.thread.create("ModifyP", store.account.modifypass)
  2515.                 end
  2516.                 base.thread.switch("ModifyP")
  2517.             elseif (args[3] >= 2 and args[3] <= 18) and (args[4] == 15) then
  2518.                 if not base.thread.find("ModifyE") then
  2519.                     base.thread.create("ModifyE", store.account.modifyemail)
  2520.                 end
  2521.                 base.thread.switch("ModifyE")
  2522.             elseif (args[3] >= 2 and args[3] <= 18) and (args[4] == 17) then
  2523.                 if not base.thread.find("MyStats") then
  2524.                     base.thread.create("MyStats", store.account.stats)
  2525.                 end
  2526.                 base.thread.switch("MyStats")
  2527.             end
  2528.         end
  2529.     end
  2530. end
  2531.  
  2532. function store.account.modifyemail(keyabc)
  2533.     if (keyabc == 1) then
  2534.         base.screen.colour("white")
  2535.         store.draw.menu("Modify Email")
  2536.  
  2537.         base.draw.box(1, 51, 19, 1, " ", "grey", "grey")
  2538.         base.draw.textl(" Back", 19, false, "orange", "grey")
  2539.         base.draw.textr("Submit ", 19, false, "cyan", "grey")
  2540.         local text = "Please enter your account key you got via email, and the new email address you wish to use then hit submit, once this confirms your email address will be updated."
  2541.         for k,v in ipairs(base.data.wordwrap(text, 49)) do
  2542.             base.draw.textc(v, k+3, false, "lightGrey", "white")
  2543.         end
  2544.         base.draw.texta("Account Key", 8, 11, false, "lightGrey", "white"); base.draw.box(8, 36, 12, 1, " ", "cyan", "cyan");
  2545.         base.draw.texta("New Email", 8, 15, false, "lightGrey", "white"); base.draw.box(8, 36, 16, 1, " ", "cyan", "cyan");
  2546.  
  2547.         while true do
  2548.             local args = { os.pullEvent() }
  2549.             if args[1] == "timer" then
  2550.                 store.draw.menu("Modify Email")
  2551.             elseif args[1] == "mouse_click" then
  2552.                 if args[4] >= 1 and args[4] <= 2 then
  2553.                     store.draw.menu_input("Modify", args[3], args[4])
  2554.                 elseif (args[3] >= 8 and args[3] <= 43) and (args[4] == 12) then
  2555.                     base.draw.box(8, 36, 12, 1, " ", "cyan", "cyan")
  2556.                     base.colour.set("white", "cyan")
  2557.                     term.setCursorPos(8, 12)
  2558.                     write(": ")
  2559.                     me_key = tostring(base.io.limitRead(34))
  2560.                 elseif (args[3] >= 8 and args[3] <= 43) and (args[4] == 16) then
  2561.                     base.draw.box(8, 36, 16, 1, " ", "cyan", "cyan")
  2562.                     base.colour.set("white", "cyan")
  2563.                     term.setCursorPos(8, 16)
  2564.                     write(": ")
  2565.                     me_email = tostring(base.io.limitRead(34))
  2566.                 elseif (args[3] >= 2 and args[3] <= 6) and (args[4] == 19) then
  2567.                     store.account.modifyemail(0)
  2568.                 elseif (args[3] >= 44 and args[3] <= 50) and (args[4] == 19) then
  2569.                     if me_email and me_key then
  2570.                         local query = "cmd=change_email&key="..textutils.urlEncode(tostring(me_key)).."&username="..textutils.urlEncode(tostring(discover.data.username)).."&newemail="..textutils.urlEncode(tostring(me_email));
  2571.                         local req = http.post(discover.data.urls.user, query)
  2572.                         req = textutils.unserialize(req.readAll())
  2573.                         if req.status then
  2574.                             base.draw.textc(tostring(req.message), 18, false, "red", "white")
  2575.                             sleep(0.75)
  2576.                             base.draw.box(1, 51, 18, 1, " ", "white", "white")
  2577.                         else
  2578.                             base.draw.textc(tostring(req.error), 18, false, "red", "white")
  2579.                             sleep(1)
  2580.                             base.draw.box(1, 51, 18, 1, " ", "white", "white")
  2581.                         end
  2582.                     else
  2583.                         base.draw.textc("Please fill in your key and email", 18, false, "red", "white")
  2584.                         sleep(0.75)
  2585.                         base.draw.box(1, 51, 18, 1, " ", "white", "white")
  2586.                     end
  2587.                 end
  2588.             end
  2589.         end
  2590.     else
  2591.         base.screen.colour("white")
  2592.         store.draw.menu("Modify Email | Request Key")
  2593.  
  2594.         base.draw.box(1, 51, 19, 1, " ", "grey", "grey")
  2595.         base.draw.textl(" Request Key", 19, false, "orange", "grey")
  2596.         base.draw.textr("Enter Key ", 19, false, "cyan", "grey")
  2597.  
  2598.         local text = "To protect accounts, please fill out your username and password below, and then submit to request a key, the key will be sent to your registered email on your account. Once requested the key is valid once, allowing you to change any user details. After one use the key expires and becomes useless."
  2599.         for k,v in ipairs(base.data.wordwrap(text, 51)) do
  2600.             base.draw.texta(v, 2, k+3, false, "lightGrey", "white")
  2601.         end
  2602.  
  2603.         base.draw.box(8, 36, 14, 1, " ", "cyan", "cyan"); base.draw.box(8, 36, 17, 1, " ", "cyan", "cyan");
  2604.         base.draw.texta("Username", 8, 13, false, "lightGrey", "white"); base.draw.texta("Password", 8, 16, false, "lightGrey", "white");
  2605.  
  2606.         while true do
  2607.             local args = { os.pullEvent() }
  2608.             if args[1] == "timer" then
  2609.                 store.draw.menu("Modify Email | Request Key")
  2610.             elseif args[1] == "mouse_click" then
  2611.                 if args[4] >= 1 and args[4] <= 2 then
  2612.                     store.draw.menu_input("Modify", args[3], args[4])
  2613.                 elseif (args[3] >= 2 and args[3] <= 13) and (args[4] == 19) then
  2614.                     if mp_username and mp_password then
  2615.                         local query = "cmd=request_key&username="..textutils.urlEncode(tostring(mp_username)).."&password="..textutils.urlEncode(tostring(base.crypto.sha256(mp_password)))
  2616.                         local req = http.post(discover.data.urls.user, query)
  2617.                         req = textutils.unserialize(req.readAll())
  2618.                         if (req.status == true) then
  2619.                             base.draw.textc(tostring(req.message), 18, false, "red", "white")
  2620.                             sleep(0.75)
  2621.                             base.draw.box(1, 51, 18, 1, " ", "white", "white")
  2622.                         else
  2623.                             base.draw.textc(tostring(req.error), 18, false, "red", "white")
  2624.                             sleep(1)
  2625.                             base.draw.box(1, 51, 18, 1, " ", "white", "white")
  2626.                         end
  2627.                     else
  2628.                         base.draw.textc("Please fill in your username and password", 18, false, "red", "white")
  2629.                         sleep(0.75)
  2630.                         base.draw.box(1, 51, 18, 1, " ", "white", "white")
  2631.                     end
  2632.                 elseif (args[3] >= 8 and args[3] <= 43) and (args[4] == 14) then
  2633.                     base.draw.box(8, 36, 14, 1, " ", "cyan", "cyan")
  2634.                     base.colour.set("white", "cyan")
  2635.                     term.setCursorPos(8, 14)
  2636.                     write(": ")
  2637.                     mp_username = tostring(base.io.limitRead(34))
  2638.                 elseif (args[3] >= 8 and args[3] <= 43) and (args[4] == 17) then
  2639.                     base.draw.box(8, 36, 17, 1, " ", "cyan", "cyan")
  2640.                     base.colour.set("white", "cyan")
  2641.                     term.setCursorPos(8, 17)
  2642.                     write(": ")
  2643.                     mp_password = tostring(base.io.limitRead(34, "*"))
  2644.                 elseif (args[3] >= 41 and args[3] <= 50) and (args[4] == 19) then
  2645.                     store.account.modifyemail(1)
  2646.                 end
  2647.             end
  2648.         end
  2649.     end
  2650. end
  2651.  
  2652. function store.account.modifypass(keyabc)
  2653.     if (keyabc == 1) then
  2654.         base.screen.colour("white")
  2655.         store.draw.menu("Modify Password")
  2656.  
  2657.         base.draw.box(1, 51, 19, 1, " ", "grey", "grey")
  2658.         base.draw.textl(" Back", 19, false, "orange", "grey")
  2659.         base.draw.textr("Submit ", 19, false, "cyan", "grey")
  2660.         local text = "Please enter your account key you got via password, and the new password address you wish to use then hit submit, once this confirms your password address will be updated."
  2661.         for k,v in ipairs(base.data.wordwrap(text, 49)) do
  2662.             base.draw.textc(v, k+3, false, "lightGrey", "white")
  2663.         end
  2664.         base.draw.texta("Account Key", 8, 11, false, "lightGrey", "white"); base.draw.box(8, 36, 12, 1, " ", "cyan", "cyan");
  2665.         base.draw.texta("New Password", 8, 15, false, "lightGrey", "white"); base.draw.box(8, 36, 16, 1, " ", "cyan", "cyan");
  2666.  
  2667.         while true do
  2668.             local args = { os.pullEvent() }
  2669.             if args[1] == "timer" then
  2670.                 store.draw.menu("Modify Password")
  2671.             elseif args[1] == "mouse_click" then
  2672.                 if args[4] >= 1 and args[4] <= 2 then
  2673.                     store.draw.menu_input("Modify", args[3], args[4])
  2674.                 elseif (args[3] >= 8 and args[3] <= 43) and (args[4] == 12) then
  2675.                     base.draw.box(8, 36, 12, 1, " ", "cyan", "cyan")
  2676.                     base.colour.set("white", "cyan")
  2677.                     term.setCursorPos(8, 12)
  2678.                     write(": ")
  2679.                     mp_key = tostring(base.io.limitRead(34))
  2680.                 elseif (args[3] >= 8 and args[3] <= 43) and (args[4] == 16) then
  2681.                     base.draw.box(8, 36, 16, 1, " ", "cyan", "cyan")
  2682.                     base.colour.set("white", "cyan")
  2683.                     term.setCursorPos(8, 16)
  2684.                     write(": ")
  2685.                     mp_pass = tostring(base.io.limitRead(34, "*"))
  2686.                 elseif (args[3] >= 2 and args[3] <= 6) and (args[4] == 19) then
  2687.                     store.account.modifyemail(0)
  2688.                 elseif (args[3] >= 44 and args[3] <= 50) and (args[4] == 19) then
  2689.                     if mp_pass and mp_key then
  2690.                         local query = "cmd=change_password&key="..textutils.urlEncode(tostring(mp_key)).."&username="..textutils.urlEncode(tostring(discover.data.username)).."&newpass="..textutils.urlEncode(tostring(base.crypto.sha256(mp_pass)));
  2691.                         local req = http.post(discover.data.urls.user, query)
  2692.                         req = textutils.unserialize(req.readAll())
  2693.                         if req.status then
  2694.                             base.draw.textc(tostring(req.message), 18, false, "red", "white")
  2695.                             sleep(0.75)
  2696.                             base.draw.box(1, 51, 18, 1, " ", "white", "white")
  2697.                         else
  2698.                             base.draw.textc(tostring(req.error), 18, false, "red", "white")
  2699.                             sleep(1)
  2700.                             base.draw.box(1, 51, 18, 1, " ", "white", "white")
  2701.                         end
  2702.                     else
  2703.                         base.draw.textc("Please fill in your key and password", 18, false, "red", "white")
  2704.                         sleep(0.75)
  2705.                         base.draw.box(1, 51, 18, 1, " ", "white", "white")
  2706.                     end
  2707.                 end
  2708.             end
  2709.         end
  2710.     else
  2711.         base.screen.colour("white")
  2712.         store.draw.menu("Modify Password | Request Key")
  2713.  
  2714.         base.draw.box(1, 51, 19, 1, " ", "grey", "grey")
  2715.         base.draw.textl(" Request Key", 19, false, "orange", "grey")
  2716.         base.draw.textr("Enter Key ", 19, false, "cyan", "grey")
  2717.  
  2718.         local text = "To protect accounts, please fill out your username and password below, and then submit to request a key, the key will be sent to your registered email on your account. Once requested the key is valid once, allowing you to change any user details. After one use the key expires and becomes useless."
  2719.         for k,v in ipairs(base.data.wordwrap(text, 51)) do
  2720.             base.draw.texta(v, 2, k+3, false, "lightGrey", "white")
  2721.         end
  2722.  
  2723.         base.draw.box(8, 36, 14, 1, " ", "cyan", "cyan"); base.draw.box(8, 36, 17, 1, " ", "cyan", "cyan");
  2724.         base.draw.texta("Username", 8, 13, false, "lightGrey", "white"); base.draw.texta("Password", 8, 16, false, "lightGrey", "white");
  2725.  
  2726.         while true do
  2727.             local args = { os.pullEvent() }
  2728.             if args[1] == "timer" then
  2729.                 store.draw.menu("Modify Password | Request Key")
  2730.             elseif args[1] == "mouse_click" then
  2731.                 if args[4] >= 1 and args[4] <= 2 then
  2732.                     store.draw.menu_input("Modify", args[3], args[4])
  2733.                 elseif (args[3] >= 2 and args[3] <= 13) and (args[4] == 19) then
  2734.                     if mp_username and mp_password then
  2735.                         local query = "cmd=request_key&username="..textutils.urlEncode(tostring(mp_username)).."&password="..textutils.urlEncode(tostring(base.crypto.sha256(mp_password)))
  2736.                         local req = http.post(discover.data.urls.user, query)
  2737.                         req = textutils.unserialize(req.readAll())
  2738.                         if (req.status == true) then
  2739.                             base.draw.textc(tostring(req.message), 18, false, "red", "white")
  2740.                             sleep(0.75)
  2741.                             base.draw.box(1, 51, 18, 1, " ", "white", "white")
  2742.                         else
  2743.                             base.draw.textc(tostring(req.error), 18, false, "red", "white")
  2744.                             sleep(1)
  2745.                             base.draw.box(1, 51, 18, 1, " ", "white", "white")
  2746.                         end
  2747.                     else
  2748.                         base.draw.textc("Please fill in your username and password", 18, false, "red", "white")
  2749.                         sleep(0.75)
  2750.                         base.draw.box(1, 51, 18, 1, " ", "white", "white")
  2751.                     end
  2752.                 elseif (args[3] >= 8 and args[3] <= 43) and (args[4] == 14) then
  2753.                     base.draw.box(8, 36, 14, 1, " ", "cyan", "cyan")
  2754.                     base.colour.set("white", "cyan")
  2755.                     term.setCursorPos(8, 14)
  2756.                     write(": ")
  2757.                     mp_username = tostring(base.io.limitRead(34))
  2758.                 elseif (args[3] >= 8 and args[3] <= 43) and (args[4] == 17) then
  2759.                     base.draw.box(8, 36, 17, 1, " ", "cyan", "cyan")
  2760.                     base.colour.set("white", "cyan")
  2761.                     term.setCursorPos(8, 17)
  2762.                     write(": ")
  2763.                     mp_password = tostring(base.io.limitRead(34, "*"))
  2764.                 elseif (args[3] >= 41 and args[3] <= 50) and (args[4] == 19) then
  2765.                     store.account.modifypass(1)
  2766.                 end
  2767.             end
  2768.         end
  2769.     end
  2770. end
  2771.  
  2772. function store.account.update()
  2773.     if temp.edit_appid then
  2774.         upd_appid = temp.edit_appid
  2775.     end
  2776.     base.screen.colour("white")
  2777.     store.draw.menu("Update")
  2778.     base.draw.box(1, 51, 19, 1, " ", "grey", "grey")
  2779.     base.draw.textl(" Cancel", 19, false, "orange", "grey")
  2780.     base.draw.textr("Update ", 19, false, "cyan", "grey")
  2781.  
  2782.     local function exit()
  2783.         upd_stat = nil
  2784.         upd_path = nil
  2785.         upd_vers = nil
  2786.         upd_path_content = nil
  2787.         upd_appid = nil
  2788.         base.thread.remove("Update")
  2789.         if not base.thread.find("Account") then
  2790.             base.thread.create("Account", store.account.home)
  2791.         end
  2792.         base.thread.switch("Account")
  2793.     end
  2794.     local use_file = true
  2795.     local use_paste = false;
  2796.     local function input_type()
  2797.         if use_file then
  2798.             base.draw.box(8, 27, 15, 1, " ", "white", "white")
  2799.             base.draw.texta("File Path:", 8, 15, false, "lightGrey", "white")
  2800.             base.draw.box(8, 27, 16, 1, " ", "cyan", "cyan")
  2801.             base.draw.texta(" Toggle ", 36, 16, false, "white", "orange")
  2802.         elseif use_paste then
  2803.             base.draw.box(8, 27, 15, 1, " ", "white", "white")
  2804.             base.draw.texta("Pastebin ID:", 8, 15, false, "lightGrey", "white")
  2805.             base.draw.box(8, 27, 16, 1, " ", "cyan", "cyan")
  2806.             base.draw.texta(" Toggle ", 36, 16, false, "white", "orange")
  2807.         end
  2808.     end
  2809.     input_type()
  2810.     local function run()
  2811.         base.draw.textc("Please follow on-screen instructions!", 4, false, "cyan", "white")
  2812.         base.draw.texta("App ID:", 8, 6, false, "lightGrey", "white")
  2813.         if temp.edit_appid then
  2814.             base.draw.texta("> "..upd_appid, 8, 7, false, "red", "white")
  2815.         else
  2816.             base.draw.box(8, 36, 7, 1, " ", "cyan", "cyan")
  2817.         end
  2818.         base.draw.texta("Version:", 8, 9, false, "lightGrey", "white")
  2819.         base.draw.box(8, 36, 10, 1, " ", "cyan", "cyan")
  2820.         base.draw.texta("Status:", 8, 12, false, "lightGrey", "white")
  2821.         base.draw.box(8, 36, 13, 1, " ", "cyan", "cyan")
  2822.     end
  2823.  
  2824.     run()
  2825.     while true do
  2826.         local args = { os.pullEvent() }
  2827.         if args[1] == "timer" then
  2828.             store.draw.menu("Update")
  2829.         elseif args[1] == "mouse_click" then
  2830.             if args[4] >= 1 and args[4] <= 2 then
  2831.                 store.draw.menu_input("Update", args[3], args[4])
  2832.             elseif (args[3] >= 36 and args[3] <= 43) and (args[4] == 16) then
  2833.                 if use_file then
  2834.                     use_paste = true
  2835.                     use_file = false
  2836.                 elseif use_paste then
  2837.                     use_file = true
  2838.                     use_paste = false
  2839.                 end
  2840.                 input_type()
  2841.             elseif (args[3] >= 8 and args[3] <= 43) and (args[4] == 7) then
  2842.                 base.draw.box(1, 51, 7, 1, " ", "white", "white")
  2843.                 base.draw.box(8, 36, 7, 1, " ", "cyan", "cyan")
  2844.                 base.colour.set("white", "cyan")
  2845.                 term.setCursorPos(8, 7)
  2846.                 write(": ")
  2847.                 upd_appid = tostring(base.io.limitRead(34))
  2848.             elseif (args[3] >= 8 and args[3] <= 43) and (args[4] == 10) then
  2849.                 base.draw.box(1, 51, 10, 1, " ", "white", "white")
  2850.                 base.draw.box(8, 36, 10, 1, " ", "cyan", "cyan")
  2851.                 base.colour.set("white", "cyan")
  2852.                 term.setCursorPos(8, 10)
  2853.                 write(": ")
  2854.                 upd_vers = tostring(read(_, discover.data.versions))
  2855.             elseif (args[3] >= 8 and args[3] <= 43) and (args[4] == 13) then
  2856.                 base.draw.box(1, 51, 13, 1, " ", "white", "white")
  2857.                 base.draw.box(8, 36, 13, 1, " ", "cyan", "cyan")
  2858.                 base.colour.set("white", "cyan")
  2859.                 term.setCursorPos(8, 13)
  2860.                 write(": ")
  2861.                 upd_stat = tostring(read(_, {"public", "private"}))
  2862.             elseif (args[3] >= 8 and args[3] <= 43) and (args[4] == 16) then
  2863.                 base.draw.box(8, 27, 16, 1, " ", "white", "white")
  2864.                 base.draw.box(8, 27, 16, 1, " ", "cyan", "cyan")
  2865.                 base.colour.set("white", "cyan")
  2866.                 term.setCursorPos(8, 16)
  2867.                 write(": ")
  2868.                 upd_path = tostring(read(_, discover.data.categories))
  2869.             elseif (args[3] >= 45 and args[3] <= 50) and (args[4] == 19) then
  2870.                 if upd_appid and upd_vers and upd_stat and upd_path then
  2871.                     if use_paste then
  2872.                         shell.run("pastebin get " .. upd_path .. " .temp")
  2873.                         local d = fs.open(".temp", "r")
  2874.                         upd_path_content = d.readAll()
  2875.                         d.close()
  2876.                         fs.delete(".temp")
  2877.                     elseif use_file then
  2878.                         if not fs.exists(upd_path) then
  2879.                             base.draw.box(1, 51, 18, 1, " ", "white", "white")
  2880.                             base.draw.textc("No file found in the given path", 18, false, "red", "white")
  2881.                             sleep(0.8)
  2882.                             base.draw.box(1, 51, 18, 1, " ", "white", "white")
  2883.                             store.account.update()
  2884.                         end
  2885.                         local f = fs.open(upd_path, "r")
  2886.                         upd_path_content = f.readAll()
  2887.                         f.close()
  2888.                     end
  2889.                     local status = discover:store_update( upd_appid, upd_vers, upd_stat, upd_path_content )
  2890.                     if status then
  2891.                         base.gui.alert("App was updated!")
  2892.                         sleep(1)
  2893.                         base.gui.alert("Updating local app database...")
  2894.                         discover:store_init()
  2895.                         exit()
  2896.                     else
  2897.                         base.draw.box(1, 51, 18, 1, " ", "white", "white")
  2898.                         base.draw.textc(discover.data.errormsg, 18, false, "red", "white")
  2899.                         sleep(1.2)
  2900.                         base.draw.box(1, 51, 18, 1, " ", "white", "white")
  2901.                     end
  2902.                 else
  2903.                     base.draw.box(1, 51, 18, 1, " ", "white", "white")
  2904.                     base.draw.textc("Please fill out all fields", 18, false, "red", "white")
  2905.                     sleep(0.8)
  2906.                     base.draw.box(1, 51, 18, 1, " ", "white", "white")
  2907.                 end
  2908.             elseif (args[3] >= 2 and args[3] <= 7) and (args[4] == 19) then
  2909.                 exit()
  2910.             end
  2911.         end
  2912.     end
  2913. end
  2914.  
  2915. function store.account.notifications()
  2916.     base.screen.colour("white")
  2917.     store.draw.menu("Notifications")
  2918.     base.draw.box(1, 51, 19, 1, " ", "grey", "grey")
  2919.     base.draw.textl(" " .. #discover.data.notifications .. " notification(s)", 19, false, "lightBlue", "grey")
  2920.     local scroll = 0
  2921.  
  2922.     local function run(scroll)
  2923.         if #discover.data.notifications > 0 then
  2924.             for i=1, 14 do
  2925.                 if #discover.data.notifications >= i + scroll then
  2926.                     base.draw.box(1, 51, i+3, 1, " ", "white", "white")
  2927.                     base.draw.texta(i+scroll .. ":", 1, i+3, false, "grey", "white")
  2928.                     base.draw.texta(discover.data.notifications[i+scroll].message:sub(1,35), 5, i+3, false, "cyan", "white")
  2929.                     base.draw.texta("X", 50, i+3, false, "red", "white")
  2930.                 else
  2931.                     break
  2932.                 end
  2933.             end
  2934.         else
  2935.             base.draw.textc("You have no new notifications", 9, false, "red", "white")
  2936.         end
  2937.     end
  2938.  
  2939.     run(scroll)
  2940.     while true do
  2941.         local args = { os.pullEvent() }
  2942.         if args[1] == "timer" then
  2943.             store.draw.menu("Notifications")
  2944.         elseif args[1] == "mouse_click" then
  2945.             if args[4] >= 1 and args[4] <= 2 then
  2946.                 store.draw.menu_input("Notifications", args[3], args[4])
  2947.             elseif (args[3] >= 1 and args[3] <= 48) and (args[4] >= 4 and args[4] <= 17) then
  2948.                 local y = args[4]-3+scroll
  2949.                 if #discover.data.notifications >= y then
  2950.                     store.account.view_notification(y)
  2951.                 end
  2952.             elseif (args[3] == 50) then
  2953.                 local y = args[4]-3+scroll
  2954.                 if discover:delete_n(discover.data.notifications[y].id) then
  2955.                     base.gui.alert("Deleted notification!")
  2956.                     discover:view_n()
  2957.                     sleep(1)
  2958.                     store.account.notifications()
  2959.                 else
  2960.                     base.gui.alert("Could not delete notification!")
  2961.                     discover:view_n()
  2962.                     sleep(1.5)
  2963.                     store.account.view_notification(id)
  2964.                 end
  2965.             end
  2966.         elseif args[1] == "mouse_scroll" then
  2967.             if args[2] == -1 then
  2968.                 if scroll > 0 then
  2969.                     scroll = scroll - 1
  2970.                     run(scroll)
  2971.                 end
  2972.             elseif args[2] == 1 then
  2973.                 if scroll + 14 < #discover.data.notifications then
  2974.                     scroll = scroll + 1
  2975.                     run(scroll)
  2976.                 end
  2977.             end
  2978.         end
  2979.     end
  2980. end
  2981.  
  2982. function store.account.view_notification(id)
  2983.     base.screen.colour("white")
  2984.     store.draw.menu("View Notification")
  2985.     base.draw.box(1, 51, 19, 1, " ", "grey", "grey")
  2986.     base.draw.texta("Exit", 47, 19, false, "orange", "grey")
  2987.     base.draw.texta("Delete", 2, 19, false, "lightBlue", "grey")
  2988.  
  2989.     for k,v in ipairs(base.data.wordwrap(discover.data.notifications[id].message, 51)) do
  2990.         base.draw.texta(v, 1, k+3, false, "cyan", "white")
  2991.     end
  2992.  
  2993.     base.draw.textc("Time Stamp: " .. tostring(discover.data.notifications[id].ntime), 18, false, "lightGrey", "white")
  2994.  
  2995.     while true do
  2996.         local args = { os.pullEvent() }
  2997.         if args[1] == "timer" then
  2998.             store.draw.menu("View Notification")
  2999.         elseif args[1] == "mouse_click" then
  3000.             if args[4] >= 1 and args[4] <= 2 then
  3001.                 store.draw.menu_input("View Notification", args[3], args[4])
  3002.             elseif (args[3] >= 47 and args[3] <= 50) and (args[4] == 19) then
  3003.                 store.account.notifications()
  3004.             elseif (args[3] >= 2 and args[3] <= 7) and (args[4] == 19) then
  3005.                 if discover:delete_n(discover.data.notifications[id].id) then
  3006.                     base.gui.alert("Deleted notification!")
  3007.                     discover:view_n()
  3008.                     sleep(1)
  3009.                     store.account.notifications()
  3010.                 else
  3011.                     base.gui.alert("Could not delete notification!")
  3012.                     discover:view_n()
  3013.                     sleep(1.5)
  3014.                     store.account.view_notification(id)
  3015.                 end
  3016.             end
  3017.         end
  3018.     end
  3019. end
  3020.  
  3021. function store.account.edit()
  3022.     local appid = temp.edit_appid
  3023.     if not appid then
  3024.         base.gui.alert("No App ID Supplied")
  3025.         sleep(1.5)
  3026.         base.thread.remove("Edit")
  3027.         if not base.thread.find("Account") then
  3028.             base.thread.create("Account", store.account.home)
  3029.         end
  3030.         base.thread.switch("Account")
  3031.     end
  3032.  
  3033.     base.screen.colour("white")
  3034.     store.draw.menu("Edit")
  3035.     base.draw.box(1, 51, 19, 1, " ", "grey", "grey")
  3036.     base.draw.textl(" Cancel ", 19, false, "orange", "grey")
  3037.     base.draw.textr("Edit ", 19, false, "lightBlue", "grey")
  3038.  
  3039.     local function run(scroll)
  3040.         base.draw.texta("App ID:", 8, 4, false, "lightGrey", "white")
  3041.         base.draw.texta("> "..temp.edit_appid, 8, 5, false, "red", "white")
  3042.        
  3043.         base.draw.texta("Name:", 8, 7, false, "lightGrey", "white")
  3044.         base.draw.box(8, 36, 8, 1, " ", "cyan", "cyan")
  3045.  
  3046.         base.draw.texta("Description:", 8, 10, false, "lightGrey", "white")
  3047.         base.draw.box(8, 36, 11, 1, " ", "cyan", "cyan")
  3048.  
  3049.         base.draw.texta("Category:", 8, 13, false, "lightGrey", "white")
  3050.         base.draw.box(8, 36, 14, 1, " ", "cyan", "cyan")
  3051.  
  3052.         base.draw.texta("Status:", 8, 16, false, "lightGrey", "white")
  3053.         base.draw.box(8, 36, 17, 1, " ", "cyan", "cyan")
  3054.     end
  3055.  
  3056.     run(scroll)
  3057.     while true do
  3058.         local args = { os.pullEvent() }
  3059.         if args[1] == "timer" then
  3060.             store.draw.menu("Edit")
  3061.         elseif args[1] == "mouse_click" then
  3062.             if args[4] >= 1 and args[4] <= 2 then
  3063.                 store.draw.menu_input("Edit", args[3], args[4])
  3064.             elseif (args[3] >= 2 and args[3] <= 7) and (args[4] == 19) then
  3065.                 if not base.thread.find("MyApps") then
  3066.                     base.thread.create("MyApps", store.account.home)
  3067.                 end
  3068.                 base.thread.remove("Edit")
  3069.                 base.thread.switch("MyApps")
  3070.             elseif (args[3] >= 47 and args[3] <= 50) and (args[4] == 19) then
  3071.                 local status = discover:store_edit( appid, edit_name,edit_desc,edit_cate, edit_stat )
  3072.                 if status then
  3073.                     base.gui.alert("Edited!")
  3074.                     sleep(0.5)
  3075.                     base.gui.alert("Updating local app database...")
  3076.                     discover:store_init()
  3077.                     if not base.thread.find("MyApps") then
  3078.                         base.thread.create("MyApps", store.account.home)
  3079.                     end
  3080.                     base.thread.remove("Edit")
  3081.                     base.thread.switch("MyApps")
  3082.                 else
  3083.                     base.gui.alert(discover.data.errormsg)
  3084.                     sleep(1.2)
  3085.                     if not base.thread.find("MyApps") then
  3086.                         base.thread.create("MyApps", store.account.home)
  3087.                     end
  3088.                     base.thread.remove("Edit")
  3089.                     base.thread.switch("MyApps")
  3090.                 end
  3091.             elseif (args[3] >= 8 and args[3] <= 47) and (args[4] == 8) then
  3092.                 base.draw.box(8, 36, 8, 1, " ", "cyan", "cyan")
  3093.                 base.colour.set("white", "cyan")
  3094.                 term.setCursorPos(8, 8)
  3095.                 write(": ")
  3096.                 edit_name = tostring(base.io.limitRead(34))
  3097.             elseif (args[3] >= 8 and args[3] <= 47) and (args[4] == 11) then
  3098.                 base.draw.box(8, 36, 11, 1, " ", "cyan", "cyan")
  3099.                 base.colour.set("white", "cyan")
  3100.                 term.setCursorPos(8, 11)
  3101.                 write(": ")
  3102.                 edit_desc = tostring(base.io.limitRead(34))
  3103.             elseif (args[3] >= 8 and args[3] <= 47) and (args[4] == 14) then
  3104.                 base.draw.box(8, 36, 14, 1, " ", "cyan", "cyan")
  3105.                 base.colour.set("white", "cyan")
  3106.                 term.setCursorPos(8, 14)
  3107.                 write(": ")
  3108.                 edit_cate = tostring(read(_, discover.data.categories))
  3109.             elseif (args[3] >= 8 and args[3] <= 47) and (args[4] == 17) then
  3110.                 base.draw.box(8, 36, 17, 1, " ", "cyan", "cyan")
  3111.                 base.colour.set("white", "cyan")
  3112.                 term.setCursorPos(8, 17)
  3113.                 write(": ")
  3114.                 edit_stat = tostring(read(_, {"public", "private"}))
  3115.             end
  3116.         end
  3117.     end
  3118. end
  3119.  
  3120. function store.account.stats()
  3121.     base.screen.colour("white")
  3122.     store.draw.menu("My Statistics")
  3123.  
  3124.     local function getstats()
  3125.         base.draw.textc("Processing...", 9, false, "grey", "white")
  3126.         sleep(0.5)
  3127.         stats_data = discover:get_stats()
  3128.         base.draw.box(1, 51, 9, 1, " ", "white", "white")
  3129.     end
  3130.  
  3131.     local function run()
  3132.         local text = "Here you can see your statistics for uploads, downloads on both apps, and snippets, we will soon implement a rating system, where higher rated users will go on the front page."
  3133.         for k,v in ipairs(base.data.wordwrap(text, 49)) do
  3134.             base.draw.texta(v, 2, k+3, false, "lightGrey", "white")
  3135.         end
  3136.         base.draw.texta("App Uploads: ", 2, 12, false, "grey", "white")
  3137.         base.draw.texta("Snippet Uploads: ", 2, 14, false, "grey", "white")
  3138.         base.draw.texta("Downloads (Apps): ", 2, 16, false, "grey", "white")
  3139.         base.draw.texta("Downloads (Snippets):", 2, 18, false, "grey", "white")
  3140.         base.draw.texta(stats_data.uploaded_apps, 25, 12, false, "cyan", "white")
  3141.         base.draw.texta(stats_data.uploaded_snips, 25, 14, false, "cyan", "white")
  3142.         base.draw.texta(stats_data.app_downloads, 25, 16, false, "cyan", "white")
  3143.         base.draw.texta(stats_data.snip_downloads, 25, 18, false, "cyan", "white")
  3144.     end
  3145.  
  3146.     getstats()
  3147.     run()
  3148.  
  3149.     while true do
  3150.         local args = { os.pullEvent() }
  3151.         if args[1] == "timer" then
  3152.             store.draw.menu("My Statistics")
  3153.         elseif args[1] == "mouse_click" then
  3154.             if args[4] >= 1 and args[4] <= 2 then
  3155.                 store.draw.menu_input("Settings (System)", args[3], args[4])
  3156.             end
  3157.         end
  3158.     end
  3159. end
  3160.  
  3161. -- ######################### START SOCIAL CODE ###########################
  3162.  
  3163. function store.social.main()
  3164.     base.screen.colour("white")
  3165.     store.draw.menu("Social")
  3166.  
  3167.     for i=1, 20 do
  3168.         base.draw.box(i, 1, 3, 17, " ", "lightGrey", "lightGrey")
  3169.     end
  3170.     base.draw.box(2, 18, 5, 1, " ", "orange", "orange")
  3171.     base.draw.texta(" Mailbox", 2, 5, false, "white", "orange")
  3172.     base.draw.box(2, 18, 7, 1, " ", "orange", "orange")
  3173.     base.draw.texta(" News Feed", 2, 7, false, "white", "orange")
  3174.     --base.draw.box(2, 18, 9, 1, " ", "orange", "orange")
  3175.     --base.draw.texta(" Chats / Channels", 2, 9, false, "white", "orange")
  3176.  
  3177.     local text = "Welcome to Discover Social. A new social aspect to the Discover API, where you can interact with live chat, a new mail system, and even a news feed, where you can talk, post and just generally socialise. If you wish to work on new ideas, then please contact me by CCForums or other as we are recruiting developers at the moment to help create amazing things."
  3178.     for k,v in ipairs(base.data.wordwrap(text, 29)) do
  3179.         base.draw.texta(v, 22, k+3, false, "cyan", "white")
  3180.     end
  3181.  
  3182.     while true do
  3183.         local args = { os.pullEvent() }
  3184.         if args[1] == "timer" then
  3185.             store.draw.menu("Social")
  3186.         elseif args[1] == "mouse_click" then
  3187.             if args[4] >= 1 and args[4] <= 2 then
  3188.                 store.draw.menu_input("Social", args[3], args[4])
  3189.             elseif (args[3] >= 2 and args[3] <= 19) and (args[4] == 5) then
  3190.                 if not base.thread.find("Mail") then
  3191.                     base.thread.create("Mail", store.social.mail)
  3192.                 end
  3193.                 base.thread.switch("Mail")
  3194.             elseif (args[3] >= 2 and args[3] <= 19) and (args[4] == 7) then
  3195.                 if not base.thread.find("Feed") then
  3196.                     base.thread.create("Feed", store.social.feed)
  3197.                 end
  3198.                 base.thread.switch("Feed")
  3199.             elseif (args[3] >= 2 and args[3] <= 19) and (args[4] == 9) then
  3200.                 -- if not base.thread.find("Chat") then
  3201.                 --  base.thread.create("Chat", store.social.chat)
  3202.                 -- end
  3203.                 -- base.thread.switch("Chat")
  3204.             end
  3205.         end
  3206.     end
  3207. end
  3208.  
  3209. function store.social.mail(page, arg)
  3210.     if (page == "create") then
  3211.         base.screen.colour("white")
  3212.         store.draw.menu("Mail: Create")
  3213.  
  3214.         base.draw.texta("Recipient:", 8, 4, false, "lightGrey", "white")
  3215.         base.draw.texta("Subject:", 8, 7, false, "lightGrey", "white")
  3216.         base.draw.texta("Message:", 8, 10, false, "lightGrey", "white")
  3217.         base.draw.texta("Attachment:", 8, 13, false, "lightGrey", "white")
  3218.         base.draw.box(8, 36, 5, 1, " ", "cyan", "cyan")
  3219.         base.draw.box(8, 36, 8, 1, " ", "cyan", "cyan")
  3220.         base.draw.box(8, 36, 11, 1, " ", "cyan", "cyan")
  3221.         base.draw.box(8, 36, 14, 1, " ", "cyan", "cyan")
  3222.  
  3223.         base.draw.box(1, 51, 19, 1, " ", "grey", "grey")
  3224.         base.draw.textl(" Cancel", 19, false, "orange", "grey")
  3225.         base.draw.textr("Send ", 19, false, "lightBlue", "grey")
  3226.  
  3227.         -- Add reply
  3228.         if arg then
  3229.             base.draw.box(8, 36, 5, 1, " ", "white", "white")
  3230.             base.draw.texta("> " .. arg, 8, 5, false, "red", "white")
  3231.             recipient = arg;
  3232.         end
  3233.  
  3234.         while true do
  3235.             local args = { os.pullEvent() }
  3236.             if args[1] == "timer" then
  3237.                 store.draw.menu("Mail: Create")
  3238.             elseif args[1] == "mouse_click" then
  3239.                 if args[4] >= 1 and args[4] <= 2 then
  3240.                     store.draw.menu_input("Mail", args[3], args[4])
  3241.                 elseif (args[3] >= 8 and args[3] <= 43) and (args[4] == 5) then
  3242.                     base.draw.box(8, 36, 5, 1, " ", "cyan", "cyan")
  3243.                     term.setCursorPos(8, 5)
  3244.                     base.colour.set("white", "cyan")
  3245.                     write(": ")
  3246.                     recipient = tostring(read())
  3247.                 elseif (args[3] >= 8 and args[3] <= 43) and (args[4] == 8) then
  3248.                     base.draw.box(8, 36, 8, 1, " ", "cyan", "cyan")
  3249.                     term.setCursorPos(8, 8)
  3250.                     base.colour.set("white", "cyan")
  3251.                     write(": ")
  3252.                     subject = tostring(base.io.limitRead(34))
  3253.                 elseif (args[3] >= 8 and args[3] <= 43) and (args[4] == 11) then
  3254.                     base.draw.box(8, 36, 11, 1, " ", "cyan", "cyan")
  3255.                     term.setCursorPos(8, 11)
  3256.                     base.colour.set("white", "cyan")
  3257.                     write(": ")
  3258.                     message = tostring(base.io.limitRead(34))
  3259.                 elseif (args[3] >= 8 and args[3] <= 43) and (args[4] == 14) then
  3260.                     base.draw.box(8, 36, 14, 1, " ", "cyan", "cyan")
  3261.                     term.setCursorPos(8, 14)
  3262.                     base.colour.set("white", "cyan")
  3263.                     write(": ")
  3264.                     attachment = tostring(base.io.limitRead(34))
  3265.                 elseif (args[3] >= 2 and args[3] <= 7) and (args[4] == 19) then
  3266.                     store.social.mail()
  3267.                 elseif (args[3] >= 47 and args[3] <= 50) and (args[4] == 19) then
  3268.                     if recipient and subject and message then
  3269.                         if attachment then
  3270.                             if fs.exists(attachment) then
  3271.                                 local f = fs.open(attachment, "r")
  3272.                                 attachdata = f.readAll()
  3273.                                 f.close()
  3274.                             else
  3275.                                 base.draw.textc("Incorrect attachment path", 18, false, "red", "white")
  3276.                                 sleep(0.5)
  3277.                                 store.social.mail('create', arg)
  3278.                             end
  3279.                         end
  3280.                         if discover:mail_send(recipient, subject, message, attachdata) then
  3281.                             base.gui.alert("Mail was sent!")
  3282.                             sleep(0.5)
  3283.                             store.social.mail()
  3284.                         else
  3285.                             base.draw.textc(tostring(discover.data.errormsg), 18, false, "red", "white")
  3286.                             sleep(0.5)
  3287.                             base.draw.box(1, 51, 18, 1, " ", "white", "white")
  3288.                         end
  3289.                     else
  3290.                         base.draw.textc("Please fill in all fields", 18, false, "red", "white")
  3291.                         sleep(0.5)
  3292.                         base.draw.box(1, 51, 18, 1, " ", "white", "white")
  3293.                     end
  3294.                 end
  3295.             end
  3296.         end
  3297.     elseif (page == "sent") then
  3298.         base.screen.colour("white")
  3299.         store.draw.menu("Mail: Sent")
  3300.         local page_num = 1
  3301.  
  3302.         base.draw.textc("Downloading mailbox, please wait", 10, false, "red", "white")
  3303.         if not discover:mail_get_own() then error("Could not download mailbox") end
  3304.         base.draw.box(1, 51, 10, 1, " ", "white", "white")
  3305.  
  3306.         local page_amount = math.ceil(#discover.data.mail / 3);
  3307.  
  3308.         for i=1, 12 do base.draw.box(i, 1, 3, 17, " ", "lightGrey", "lightGrey") end
  3309.         base.draw.box(2, 10, 5, 1, " ", "orange", "orange")
  3310.         base.draw.texta(" Inbox", 2, 5, false, "white", "orange")
  3311.         base.draw.box(2, 10, 7, 1, " ", "orange", "orange")
  3312.         base.draw.texta(" Create", 2, 7, false, "white", "orange")
  3313.         base.draw.box(2, 10, 9, 1, " ", "orange", "orange")
  3314.         base.draw.texta(" Sent", 2, 9, false, "white", "orange")
  3315.         base.draw.textl(" Page: " .. page_num .. "/" .. page_amount, 19, false, "white", "lightGrey")
  3316.  
  3317.         local function render()
  3318.             if #discover.data.mail > 0 then
  3319.                 local pid = (page_num * 4) - 4;
  3320.                 local pos = {4,8,12,16}
  3321.                 for i=1, 4 do
  3322.                     if ((i+pid) <= #discover.data.mail) then
  3323.                         base.draw.box(13, 38, pos[i], 1, " ", "white", "white");
  3324.                         base.draw.box(13, 38, pos[i]+1, 1, " ", "white", "white");
  3325.                         base.draw.box(13, 38, pos[i]+2, 1, " ", "white", "white");
  3326.                         local a = tostring(discover.data.mail[i+pid]['sender']); local b = a:sub(1,1):upper(); local c = a:sub(2);
  3327.                         base.draw.texta(tostring(b .. "" .. c), 14, pos[i], false, "grey", "white")
  3328.                         base.draw.texta(tostring(discover.data.mail[i+pid]['subject']:sub(1,30)), 14, pos[i]+1, false, "cyan", "white")
  3329.                         base.draw.texta(tostring(discover.data.mail[i+pid]['sent_date']), 14, pos[i]+2, false, "lightGrey", "white")
  3330.                     else
  3331.                         base.draw.box(13, 38, pos[i], 1, " ", "white", "white");
  3332.                         base.draw.box(13, 38, pos[i]+1, 1, " ", "white", "white");
  3333.                         base.draw.box(13, 38, pos[i]+2, 1, " ", "white", "white");
  3334.                     end
  3335.                 end
  3336.             else
  3337.                 base.draw.texta("No mail to display", 23, 11, false, "red", "white")
  3338.             end
  3339.         end
  3340.  
  3341.         render()
  3342.         while true do
  3343.             local args = { os.pullEvent() }
  3344.             if args[1] == "timer" then
  3345.                 store.draw.menu("Mail: Sent")
  3346.             elseif args[1] == "mouse_click" then
  3347.                 if args[4] >= 1 and args[4] <= 2 then
  3348.                     store.draw.menu_input("Mail", args[3], args[4])            
  3349.                 elseif (args[3] >= 1 and args[3] <= 12) and (args[4] >= 3 and args[4] <= 19) then
  3350.                     if (args[3] >= 2 and args[3] <= 11) and args[4] == 5 then
  3351.                         store.social.mail()
  3352.                     elseif (args[3] >= 2 and args[3] <= 11) and args[4] == 7 then
  3353.                         store.social.mail("create")
  3354.                     elseif (args[3] >= 2 and args[3] <= 11) and args[4] == 9 then
  3355.                         store.social.mail("sent")
  3356.                     end
  3357.                 end
  3358.             elseif args[1] == "mouse_scroll" then
  3359.                 if args[2] == -1 then
  3360.                     if page_num > 1 then
  3361.                         page_num = page_num - 1
  3362.                         render()
  3363.                         base.draw.textl(" Page: " .. page_num .. "/" .. page_amount, 19, false, "white", "lightGrey")
  3364.                     end
  3365.                 elseif args[2] == 1 then
  3366.                     if page_num < page_amount then
  3367.                         page_num = page_num + 1
  3368.                         render()
  3369.                         base.draw.textl(" Page: " .. page_num .. "/" .. page_amount, 19, false, "white", "lightGrey")
  3370.                     end
  3371.                 end
  3372.             end
  3373.         end
  3374.     elseif (page == "view" and arg) then
  3375.         base.screen.colour("white")
  3376.         store.draw.menu("Mail: View")
  3377.  
  3378.         -- Load data
  3379.         base.draw.textc("Loading...", 10, false, "red", "white");
  3380.         local mail_data = {}; for k, v in ipairs(discover.data.mail) do if v.id == arg then mail_data = v; break end end; sleep(0.15);
  3381.  
  3382.         -- Send read receipt
  3383.         local status = discover:mail_view(mail_data['id'])
  3384.         base.draw.box(1, 51, 10, 1, " ", "white", "white"); local tMessage = {}; local scroll = 0
  3385.  
  3386.         base.draw.box(1, 51, 19, 1, " ", "grey", "grey");
  3387.         base.draw.textl(" Back", 19, false, "orange", "grey")
  3388.         base.draw.textr("Reply ", 19, false, "cyan", "grey")
  3389.         base.draw.textc("Delete", 19, false, "red", "grey")
  3390.  
  3391.         local function render()
  3392.             base.draw.texta("--------------------< Message >--------------------", 1, 8, false, "lightGrey", "white")
  3393.             base.draw.texta("To:", 2, 4, false, "grey", "white")
  3394.             base.draw.texta(mail_data['recipient']:sub(1,22), 8, 4, false, "lightBlue", "white")
  3395.             base.draw.texta("From:", 26, 4, false, "grey", "white")
  3396.             base.draw.texta(mail_data['sender']:sub(1,22), 31, 4, false, "lightBlue", "white")
  3397.             base.draw.texta("Sent:", 2, 5, false, "grey", "white")
  3398.             base.draw.texta(mail_data['sent_date'], 8, 5, false, "lightBlue", "white")
  3399.             base.draw.texta("Subject: ", 2, 6, false, "grey", "white")
  3400.             base.draw.texta(mail_data['subject'], 11, 6, false, "lightBlue", "white")
  3401.             tMessage = base.data.wordwrap(mail_data['message'], 47);
  3402.         end
  3403.  
  3404.         local f = fs.open("out.lua", "w"); f.write(textutils.serialize(mail_data)); f.close()
  3405.         if mail_data['attachments']:len() > 5 then
  3406.             base.draw.textc("Download attachment", 18, false, "lightGrey", "white")
  3407.         end
  3408.  
  3409.         local function render_message()
  3410.             for i=1, 7 do
  3411.                 if scroll + i <= #tMessage then
  3412.                     base.draw.box(1, 51, i+9, 1, " ", "white", "white")
  3413.                     base.draw.texta(tMessage[i+scroll], 3, i+9, false, "grey", "white")
  3414.                 end
  3415.             end
  3416.         end
  3417.  
  3418.         render();
  3419.         render_message();
  3420.         while true do
  3421.             local args = { os.pullEvent() }
  3422.             if args[1] == "timer" then
  3423.                 store.draw.menu("Mail: View")
  3424.             elseif args[1] == "mouse_click" then
  3425.                 if args[4] >= 1 and args[4] <= 2 then
  3426.                     store.draw.menu_input("Mail", args[3], args[4])
  3427.                 elseif (args[3] >= 2 and args[3] <= 5) and args[4] == 19 then
  3428.                     store.social.mail()
  3429.                 elseif (args[3] >= 46 and args[3] <= 50) and args[4] == 19 then
  3430.                     store.social.mail("create", mail_data['sender'])
  3431.                 elseif (args[3] >= 22 and args[3] <= 28) and (args[4] == 19) then
  3432.                     base.gui.alert("Deleting...")
  3433.                     local status = discover:mail_delete(mail_data['id'])
  3434.                     if status then
  3435.                         base.gui.alert("Mail was deleted")
  3436.                         sleep(0.5)
  3437.                         store.social.mail()
  3438.                     else
  3439.                         base.gui.alert(tostring(discover.data.errormsg))
  3440.                         sleep(1)
  3441.                         store.social.mail()
  3442.                     end
  3443.                 elseif (args[3] >= 12 and args[3] <= 42) and (args[4] == 18) then
  3444.                     if mail_data['attachments']:len() > 5 then
  3445.                         local data = base.base64.decode(mail_data['attachments']);
  3446.                         local f = fs.open(base.gui.input("Save as:"), "w");
  3447.                         f.write(data)
  3448.                         f.close()
  3449.                         store.social.mail('view', arg)
  3450.                     end
  3451.                 elseif (args[3] >= 1 and args[3] <= 12) and (args[4] >= 3 and args[4] <= 19) then
  3452.                     if (args[3] >= 2 and args[3] <= 11) and args[4] == 5 then
  3453.                         store.social.mail()
  3454.                     elseif (args[3] >= 2 and args[3] <= 11) and args[4] == 7 then
  3455.                         store.social.mail("create")
  3456.                     elseif (args[3] >= 2 and args[3] <= 11) and args[4] == 9 then
  3457.                         store.social.mail("sent")
  3458.                     end
  3459.                 end
  3460.             elseif args[1] == "mouse_scroll" then
  3461.                 if args[2] == -1 then
  3462.                     if scroll > 0 then
  3463.                         scroll = scroll - 1
  3464.                         render_message()
  3465.                     end
  3466.                 elseif args[2] == 1 then
  3467.                     if 7+scroll < #tMessage then
  3468.                         scroll = scroll + 1
  3469.                         render_message()
  3470.                     end
  3471.                 end
  3472.             end
  3473.         end
  3474.     else
  3475.         base.screen.colour("white")
  3476.         store.draw.menu("Mail: Inbox")
  3477.         local page_num = 1
  3478.  
  3479.         base.draw.textc("Download mailbox, please wait", 10, false, "red", "white")
  3480.         if not discover:mail_get() then error("Could not download mailbox") end
  3481.         base.draw.box(1, 51, 10, 1, " ", "white", "white")
  3482.  
  3483.         local page_amount = math.ceil(#discover.data.mail / 3);
  3484.  
  3485.         for i=1, 12 do base.draw.box(i, 1, 3, 17, " ", "lightGrey", "lightGrey") end
  3486.         base.draw.box(2, 10, 5, 1, " ", "orange", "orange")
  3487.         base.draw.texta(" Inbox", 2, 5, false, "white", "orange")
  3488.         base.draw.box(2, 10, 7, 1, " ", "orange", "orange")
  3489.         base.draw.texta(" Create", 2, 7, false, "white", "orange")
  3490.         base.draw.box(2, 10, 9, 1, " ", "orange", "orange")
  3491.         base.draw.texta(" Sent", 2, 9, false, "white", "orange")
  3492.         local unread = 0; for k,v in ipairs(discover.data.mail) do if v.status == 'unread' then unread = unread + 1 end end;
  3493.         base.draw.textl(" Unread: " .. unread, 18, false, "white", "lightGrey")
  3494.         base.draw.textl(" Page: " .. page_num .. "/" .. page_amount, 19, false, "white", "lightGrey")
  3495.  
  3496.         local function render()
  3497.             if #discover.data.mail > 0 then
  3498.                 local pid = (page_num * 4) - 4;
  3499.                 local pos = {4,8,12,16}
  3500.                 for i=1, 4 do
  3501.                     if ((i+pid) <= #discover.data.mail) then
  3502.                         base.draw.box(13, 39, pos[i], 1, " ", "white", "white");
  3503.                         base.draw.box(13, 39, pos[i]+1, 1, " ", "white", "white");
  3504.                         base.draw.box(13, 39, pos[i]+2, 1, " ", "white", "white");
  3505.                         local a = tostring(discover.data.mail[i+pid]['sender']); local b = a:sub(1,1):upper(); local c = a:sub(2);
  3506.                         if discover.data.mail[i+pid]['status'] == 'unread' then
  3507.                             base.draw.texta(tostring(b .. "" .. c), 14, pos[i], false, "grey", "white")
  3508.                             base.draw.texta(tostring(discover.data.mail[i+pid]['subject']:sub(1,30)), 14, pos[i]+1, false, "cyan", "white")
  3509.                             base.draw.texta(tostring(discover.data.mail[i+pid]['sent_date']), 14, pos[i]+2, false, "lightGrey", "white")
  3510.                             base.draw.box(51, 1, pos[i], 3, " ", "red", "red")
  3511.                         else
  3512.                             base.draw.texta(tostring(b .. "" .. c), 14, pos[i], false, "grey", "white")
  3513.                             base.draw.texta(tostring(discover.data.mail[i+pid]['subject']:sub(1,30)), 14, pos[i]+1, false, "cyan", "white")
  3514.                             base.draw.texta(tostring(discover.data.mail[i+pid]['sent_date']), 14, pos[i]+2, false, "lightGrey", "white")
  3515.                         end
  3516.                     else
  3517.                         base.draw.box(13, 39, pos[i], 1, " ", "white", "white");
  3518.                         base.draw.box(13, 39, pos[i]+1, 1, " ", "white", "white");
  3519.                         base.draw.box(13, 39, pos[i]+2, 1, " ", "white", "white");
  3520.                     end
  3521.                 end
  3522.             else
  3523.                 base.draw.texta("No mail to display", 23, 11, false, "red", "white")
  3524.             end
  3525.         end
  3526.  
  3527.         render()
  3528.         while true do
  3529.             local args = { os.pullEvent() }
  3530.             if args[1] == "timer" then
  3531.                 store.draw.menu("Mail: Inbox")
  3532.             elseif args[1] == "mouse_click" then
  3533.                 if args[4] >= 1 and args[4] <= 2 then
  3534.                     store.draw.menu_input("Mail", args[3], args[4])
  3535.                 elseif (args[3] >= 13 and args[3] <= 51) and (args[4] >= 3 and args[4] <= 19) then
  3536.                     if (args[4] >= 4 and args[4] <= 6) then
  3537.                         local nid = page_num * 4 - 4 + 1
  3538.                         if nid <= #discover.data.mail then
  3539.                             store.social.mail("view", discover.data.mail[nid]['id']);
  3540.                         end
  3541.                     elseif (args[4] >= 8 and args[4] <= 10) then
  3542.                         local nid = page_num * 4 - 4 + 2
  3543.                         if nid <= #discover.data.mail then
  3544.                             store.social.mail("view", discover.data.mail[nid]['id']);
  3545.                         end
  3546.                     elseif (args[4] >= 12 and args[4] <= 14) then
  3547.                         local nid = page_num * 4 - 4 + 3
  3548.                         if nid <= #discover.data.mail then
  3549.                             store.social.mail("view", discover.data.mail[nid]['id']);
  3550.                         end
  3551.                     elseif (args[4] >= 16 and args[4] <= 18) then
  3552.                         local nid = page_num * 4 - 4 + 4
  3553.                         if nid <= #discover.data.mail then
  3554.                             store.social.mail("view", discover.data.mail[nid]['id']);
  3555.                         end
  3556.                     end                
  3557.                 elseif (args[3] >= 1 and args[3] <= 12) and (args[4] >= 3 and args[4] <= 19) then
  3558.                     if (args[3] >= 2 and args[3] <= 11) and args[4] == 5 then
  3559.                         store.social.mail()
  3560.                     elseif (args[3] >= 2 and args[3] <= 11) and args[4] == 7 then
  3561.                         store.social.mail("create")
  3562.                     elseif (args[3] >= 2 and args[3] <= 11) and args[4] == 9 then
  3563.                         store.social.mail("sent")
  3564.                     end
  3565.                 end
  3566.             elseif args[1] == "mouse_scroll" then
  3567.                 if args[2] == -1 then
  3568.                     if page_num > 1 then
  3569.                         page_num = page_num - 1
  3570.                         render()
  3571.                         base.draw.textl(" Unread: " .. unread, 18, false, "white", "lightGrey")
  3572.                         base.draw.textl(" Page: " .. page_num .. "/" .. page_amount, 19, false, "white", "lightGrey")
  3573.                     end
  3574.                 elseif args[2] == 1 then
  3575.                     if page_num < page_amount then
  3576.                         page_num = page_num + 1
  3577.                         render()
  3578.                         base.draw.textl(" Unread: " .. unread, 18, false, "white", "lightGrey")
  3579.                         base.draw.textl(" Page: " .. page_num .. "/" .. page_amount, 19, false, "white", "lightGrey")
  3580.                     end
  3581.                 end
  3582.             end
  3583.         end
  3584.     end
  3585. end
  3586.  
  3587. function store.social.chat(page)
  3588.     base.screen.colour("white")
  3589.     store.draw.menu("Chat")
  3590.  
  3591.     for i=1, 12 do base.draw.box(i, 1, 3, 17, " ", "lightGrey", "lightGrey") end
  3592.     base.draw.box(2, 10, 5, 1, " ", "orange", "orange")
  3593.     base.draw.texta(" Global", 2, 5, false, "white", "orange")
  3594.     base.draw.box(2, 10, 7, 1, " ", "orange", "orange")
  3595.     base.draw.texta(" Channels", 2, 7, false, "white", "orange")
  3596.     base.draw.box(2, 10, 9, 1, " ", "orange", "orange")
  3597.     base.draw.texta(" Personal", 2, 9, false, "white", "orange")
  3598.  
  3599.     while true do
  3600.         local args = { os.pullEvent() }
  3601.         if args[1] == "timer" then
  3602.             store.draw.menu("Chat")
  3603.         elseif args[1] == "mouse_click" then
  3604.             if args[4] >= 1 and args[4] <= 2 then
  3605.                 store.draw.menu_input("Chat", args[3], args[4])
  3606.             end
  3607.         end
  3608.     end
  3609. end
  3610.  
  3611. function store.social.feed(page)
  3612.     base.screen.colour("white")
  3613.     store.draw.menu("Feed")
  3614.     local feed = {}; local scroll = 0;
  3615.  
  3616.     base.draw.textc("Downloading feed, please wait...", 10, false, "red", "white")
  3617.     local status = discover:feed_view()
  3618.     if not status then
  3619.         base.gui.alert("Could not download feed")
  3620.         sleep(1)
  3621.         base.thread.remove("Feed")
  3622.         base.thread.switch("Home")
  3623.     end
  3624.     base.draw.box(1, 51, 10, 1, " ", "white", "white")
  3625.     base.draw.box(1, 51, 19, 1, " ", "grey", "grey")
  3626.     base.draw.textl(" Create Post", 19, false, "lightBlue", "grey")
  3627.     base.draw.textr("Refresh ", 19, false, "lightBlue", "grey")
  3628.  
  3629.     local function parse()
  3630.         feed = {}; table.insert(feed, ":B:")
  3631.         for k,v in ipairs(discover.data.feed) do
  3632.             table.insert(feed, ":A:" .. v.author)
  3633.             for i, j in ipairs(base.data.wordwrap(v.message, 45)) do
  3634.                 table.insert(feed, ":M:" .. j)
  3635.             end
  3636.             table.insert(feed, ":T:" .. v.sent_time)
  3637.             table.insert(feed, ":B:")
  3638.         end
  3639.     end
  3640.     local function render()
  3641.         for i=3, 18 do base.draw.box(1, 51, i, 1, " ", "white", "white") end
  3642.         base.draw.textc("No feed posts to show", 10, false, "red", "white")
  3643.         if #feed > 0 then
  3644.             for i=1, 14 do
  3645.                 if i+scroll <= #feed then
  3646.                     base.draw.box(1, 51, i+3, 1, " ", "white","white")
  3647.                     if feed[i+scroll]:sub(1,3) == ":A:" then
  3648.                         base.draw.textl("  " .. feed[i+scroll]:sub(4), i+3, false, "red", "white")
  3649.                     elseif feed[i+scroll]:sub(1,3) == ":M:" then
  3650.                         base.draw.textl("   " .. feed[i+scroll]:sub(4), i+3, false, "cyan", "white")
  3651.                     elseif feed[i+scroll]:sub(1,3) == ":T:" then
  3652.                         base.draw.textr(feed[i+scroll]:sub(4) .. "  ", i+3, false, "orange", "white")
  3653.                     elseif feed[i+scroll]:sub(1,3) == ":B:" then
  3654.                         base.draw.textc("- - - - - - - - - - - - - - - - - - - - - - - -", i+3, false, "lightGrey", "white")
  3655.                     else
  3656.                         -- Leave space
  3657.                     end
  3658.                 end
  3659.             end
  3660.         else
  3661.             for i=3, 18 do base.draw.box(1, 51, i, 1, " ", "white", "white") end
  3662.             base.draw.textc("No feed posts to show", 10, false, "red", "white")
  3663.         end
  3664.     end
  3665.     parse(); render();
  3666.     while true do
  3667.         local args = { os.pullEvent() }
  3668.         if args[1] == "timer" then
  3669.             store.draw.menu("Feed")
  3670.         elseif args[1] == "mouse_click" then
  3671.             if args[4] >= 1 and args[4] <= 2 then
  3672.                 store.draw.menu_input("Feed", args[3], args[4])
  3673.             elseif (args[3] >= 2 and args[3] <= 12) and args[4] == 19 then
  3674.                 local message = base.gui.input("What do you want to say?")
  3675.                 local status = discover:feed_new(message)
  3676.                 if not status then
  3677.                     base.gui.alert("Could not create new post")
  3678.                     sleep(1)
  3679.                     store.social.feed()
  3680.                 end
  3681.                 base.gui.alert("Submitted!"); sleep(0.5);
  3682.                 base.gui.alert("Updating feed..."); sleep(0.5)
  3683.                 local status = discover:feed_view()
  3684.                 if not status then
  3685.                     base.gui.alert("Could not download feed")
  3686.                     sleep(1)
  3687.                     base.thread.remove("Feed")
  3688.                     base.thread.switch("Home")
  3689.                 end
  3690.                 parse(); render();
  3691.             elseif (args[3] >= 44 and args[3] <= 50) and args[4] == 19 then
  3692.                 base.gui.alert("Downloading feed, please wait..."); sleep(0.5)
  3693.                 local status = discover:feed_view()
  3694.                 if not status then
  3695.                     base.gui.alert("Could not download feed")
  3696.                     sleep(1)
  3697.                     base.thread.remove("Feed")
  3698.                     base.thread.switch("Home")
  3699.                 end
  3700.                 parse(); render();
  3701.             end
  3702.         elseif args[1] == "mouse_scroll" then
  3703.             if args[2] == -1 then
  3704.                 if scroll > 0 then
  3705.                     scroll = scroll - 1
  3706.                     render();
  3707.                 end
  3708.             elseif args[2] == 1 then
  3709.                 if (scroll + 14) < #feed then
  3710.                     scroll = scroll + 1
  3711.                     render();
  3712.                 end
  3713.             end
  3714.         end
  3715.     end
  3716. end
  3717.  
  3718.  
  3719. -- ######################### START CLOUD CODE ###########################
  3720. function store.cloud.main()
  3721.     base.screen.colour("white")
  3722.     store.draw.menu("Cloud")
  3723.     local rscroll = 0
  3724.     local lscroll = 0
  3725.     local localfiles = {}
  3726.     local lfiles = fs.list("/")
  3727.     for _,v in ipairs(lfiles) do
  3728.         if not fs.isDir(v) then
  3729.             table.insert(localfiles, v)
  3730.         end
  3731.     end
  3732.  
  3733.     local fileoptions = {"Rename"}
  3734.  
  3735.     base.draw.textc("Listing your files, please wait...", 10, false, "red", "white")
  3736.     filelist = discover:cloud_get()
  3737.     if filelist then
  3738.         base.draw.box(1, 51, 10, 1, " ", "white", "white")
  3739.     else
  3740.         base.gui.alert(tostring(discover:get("errormsg")))
  3741.         sleep(1.5)
  3742.         base.thread.remove("Cloud")
  3743.         base.thread.switch("Home")
  3744.     end
  3745.     base.draw.box(26,1, 3, 17, " ", "grey", "grey")
  3746.     base.draw.box(1, 51, 19, 1, " ", "grey", "grey")
  3747.     base.draw.texta("- Local Files -", 5, 3, false, "lightGrey", "white")
  3748.     base.draw.texta("- Remote Files -", 32, 3, false, "lightGrey", "white")
  3749.     base.draw.textr("Scroll Enabled ", 19, false, "orange", "grey")
  3750.  
  3751.     local function runr(rscroll)
  3752.         if #filelist > 0 then
  3753.             for i=1, 14 do
  3754.                 if #filelist >= i + rscroll then
  3755.                     base.draw.box(27, 24, i+4, 1, " ", "white", "white")
  3756.                     base.draw.texta(filelist[i+rscroll].filename:sub(1, 19), 28, i+4, false, "cyan", "white")
  3757.                     base.draw.texta("<", 48, i+4, false, "lightBlue", "white")
  3758.                     base.draw.texta("X", 50, i+4, false, "red", "white")
  3759.                 else
  3760.                     break
  3761.                 end
  3762.             end
  3763.         else
  3764.             base.draw.texta("No files to show", 31, 10, false, "red", "white")
  3765.         end
  3766.     end
  3767.     local function runl(lscroll)
  3768.         if #localfiles > 0 then
  3769.             for i=1, 14 do
  3770.                 if #localfiles >= i + lscroll then
  3771.                     base.draw.box(2, 24, i+4, 1, " ", "white", "white")
  3772.                     base.draw.texta(localfiles[i+lscroll]:sub(1, 19), 2, i+4, false, "cyan", "white")
  3773.                     base.draw.texta(">", 22, i+4, false, "lightBlue", "white")
  3774.                     base.draw.texta("X", 24, i+4, false, "red", "white")
  3775.                 else
  3776.                     break
  3777.                 end
  3778.             end
  3779.         else
  3780.             base.draw.texta("No files to show", 2, 10, false, "red", "white")
  3781.         end
  3782.     end
  3783.     runr(rscroll)
  3784.     runl(lscroll)
  3785.     while true do
  3786.         local args = { os.pullEvent() }
  3787.         if args[1] == "timer" then
  3788.             store.draw.menu("Cloud")
  3789.         elseif args[1] == "mouse_click" then
  3790.             if args[4] >= 1 and args[4] <= 2 then
  3791.                 store.draw.menu_input("Cloud", args[3], args[4])
  3792.             elseif (args[3] == 22) and (args[4] >= 4 and args[4] <= 17) then
  3793.                 -- Push local file
  3794.                 local curid = args[4] - 4 + lscroll
  3795.                 if (curid > 0 and curid <= #localfiles) then
  3796.                     if fs.exists(localfiles[curid]) then
  3797.                         base.gui.alert("Converting file for upload, please wait");sleep(0.25)
  3798.                         local status = discover:cloud_upload(localfiles[curid])
  3799.                         if status then
  3800.                             base.gui.alert("File pushed to server!")
  3801.                             sleep(0.5)
  3802.                             store.cloud.main()
  3803.                         else
  3804.                             base.gui.alert("File could not be pushed!")
  3805.                             sleep(0.5)
  3806.                             store.cloud.main()
  3807.                         end
  3808.                     else
  3809.                         base.gui.alert("File doesn't exist!")
  3810.                         sleep(0.5)
  3811.                         store.cloud.main()
  3812.                     end
  3813.                 end
  3814.             elseif (args[3] >= 1 and args[3] <= 22) and (args[4] >= 4 and args[4] <= 17) then
  3815.                 -- Load options for local
  3816.                 local curid = args[4] - 4 + lscroll
  3817.                 if (curid > 0 and curid <= #localfiles) then
  3818.                     base.draw.texta(table.concat(fileoptions, " | "), 2, 19, false, "cyan", "grey")
  3819.                     local arg = { os.pullEvent("mouse_click") }
  3820.                     if (arg[3] >= 2 and arg[3] <= 7) and (arg[4] == 19) then
  3821.                         -- Rename
  3822.                         base.draw.box(8, 36, 9, 2, " ", "grey", "grey")
  3823.                         base.draw.box(10, 32, 10, 1, " ", "lightGrey", "lightGrey")
  3824.                         base.draw.textc("New File Name", 9, false, "white", "grey")
  3825.                         base.colour.set("black", "lightGrey")
  3826.                         term.setCursorPos(10, 10)
  3827.                         write(": ")
  3828.                         local newname = tostring(base.io.limitRead(30))
  3829.                         fs.move(localfiles[curid], newname)
  3830.                         base.gui.alert("File Renamed!")
  3831.                         sleep(0.5)
  3832.                         store.cloud.main()
  3833.                     else
  3834.                         base.draw.box(1, 30, 19, 1, " ", "grey", "grey")
  3835.                     end
  3836.                 end
  3837.             elseif (args[3] >= 27 and args[3] <= 47) and (args[4] >= 4 and args[4] <= 17) then
  3838.                 -- Load options for remote
  3839.                 local curid = args[4] - 4 + rscroll
  3840.                 if (curid > 0 and curid <= #filelist) then
  3841.                     base.draw.texta(table.concat(fileoptions, " | "), 2, 19, false, "cyan", "grey")
  3842.                     local arg = { os.pullEvent("mouse_click") }
  3843.                     if (arg[3] >= 2 and arg[3] <= 7) and (arg[4] == 19) then
  3844.                         -- Rename
  3845.                         base.draw.box(8, 36, 9, 2, " ", "grey", "grey")
  3846.                         base.draw.box(10, 32, 10, 1, " ", "lightGrey", "lightGrey")
  3847.                         base.draw.textc("New File Name", 9, false, "white", "grey")
  3848.                         base.colour.set("black", "lightGrey")
  3849.                         term.setCursorPos(10, 10)
  3850.                         write(": ")
  3851.                         local newname = tostring(base.io.limitRead(30))
  3852.                         local status = discover:cloud_rename(filelist[curid].id, newname)
  3853.                         if status then
  3854.                             base.gui.alert("File was renamed!")
  3855.                             sleep(0.5)
  3856.                             store.cloud.main()
  3857.                         else
  3858.                             base.gui.alert("File could not be renamed!")
  3859.                             sleep(0.5)
  3860.                             store.cloud.main()
  3861.                         end
  3862.                     else
  3863.                         base.draw.box(1, 30, 19, 1, " ", "grey", "grey")
  3864.                     end
  3865.                 end
  3866.             elseif (args[3] == 24) and (args[4] >= 4 and args[4] <= 17) then
  3867.                 -- Delete local file
  3868.                 local curid = args[4] - 4 + lscroll
  3869.                 if (curid > 0 and curid <= #localfiles) then
  3870.                     if fs.exists(localfiles[curid]) then
  3871.                         fs.delete(localfiles[curid])
  3872.                         base.gui.alert("File Deleted!")
  3873.                         sleep(0.5)
  3874.                         store.cloud.main()
  3875.                     else
  3876.                         base.gui.alert("File doesn't exist!")
  3877.                         sleep(0.5)
  3878.                         store.cloud.main()
  3879.                     end
  3880.                 end
  3881.             elseif (args[3] == 48) and (args[4] >= 4 and args[4] <= 17) then
  3882.                 -- Pull remote file
  3883.                 local curid = args[4] - 4 + rscroll
  3884.                 if (curid > 0 and curid <= #filelist) then
  3885.                     local f = fs.open(filelist[curid].filename, "w")
  3886.                     f.write(base.base64.decode(filelist[curid].filedata))
  3887.                     f.close()
  3888.                     base.gui.alert("File was pulled from server!")
  3889.                     sleep(0.5)
  3890.                     store.cloud.main()
  3891.                 end
  3892.             elseif (args[3] == 50) and (args[4] >= 4 and args[4] <= 17) then
  3893.                 -- Delete remote file
  3894.                 local curid = args[4] - 4 + rscroll
  3895.                 if (curid > 0 and curid <= #filelist) then
  3896.                     local status = discover:cloud_delete(filelist[curid].id)
  3897.                     if status then
  3898.                         base.gui.alert("File was deleted!")
  3899.                         sleep(0.5)
  3900.                         store.cloud.main()
  3901.                     else
  3902.                         base.gui.alert("File could not be deleted!")
  3903.                         sleep(0.5)
  3904.                         store.cloud.main()
  3905.                     end
  3906.                 end
  3907.             end
  3908.         elseif args[1] == "mouse_scroll" then
  3909.             if (args[3] >= 1 and args[3] <= 25) and (args[4] >= 4 and args[4] <= 17) then
  3910.                 if args[2] == -1 then
  3911.                     if lscroll > 0 then
  3912.                         lscroll = lscroll - 1
  3913.                         runl(lscroll)
  3914.                     end
  3915.                 elseif args[2] == 1 then
  3916.                     if lscroll + 13 < #localfiles then
  3917.                         lscroll = lscroll + 1
  3918.                         runl(lscroll)
  3919.                     end
  3920.                 end
  3921.             elseif (args[3] >= 27 and args[3] <= 51) and (args[4] >= 4 and args[4] <= 17) then
  3922.                 if args[2] == -1 then
  3923.                     if rscroll > 0 then
  3924.                         rscroll = rscroll - 1
  3925.                         runr(rscroll)
  3926.                     end
  3927.                 elseif args[2] == 1 then
  3928.                     if rscroll + 13 < #filelist then
  3929.                         rscroll = rscroll + 1
  3930.                         runr(rscroll)
  3931.                     end
  3932.                 end
  3933.             end
  3934.         end
  3935.     end
  3936. end
  3937.  
  3938. -- ######################### START SNIPPET CODE ###########################
  3939. function store.snippets.main()
  3940.     base.screen.colour("white")
  3941.     store.draw.menu("Snippets")
  3942.  
  3943.     for i=1, 22 do
  3944.         base.draw.box(i, 1, 3, 17, " ", "lightGrey", "lightGrey")
  3945.     end
  3946.     local pos = {4,6,8,10,12,14,16,18}
  3947.     local menu = {"View all snippets", "Upload new snippet", "View my snippets"}
  3948.     for k,v in ipairs(menu) do
  3949.         base.draw.box(2, 20, pos[k], 1, " ", "orange", "orange")
  3950.         base.draw.texta(v, 3, pos[k], false, "white", "orange")
  3951.     end
  3952.  
  3953.     local text = "The snippet server allows you to store snippets of code as a separate file which can be downloaded, edited, shared, and added as dependencies to programs using the Discover Dependencies Manager (DDM), which is a work in progress, but works very well."
  3954.     for k,v in ipairs(base.data.wordwrap(text, 27)) do
  3955.         base.draw.texta(v, 24, k+3, false, "lightGrey", "white")
  3956.     end
  3957.  
  3958.     while true do
  3959.         local args = { os.pullEvent() }
  3960.         if args[1] == "timer" then
  3961.             store.draw.menu("Snippets")
  3962.         elseif args[1] == "mouse_click" then
  3963.             if args[4] >= 1 and args[4] <= 2 then
  3964.                 store.draw.menu_input("Snippets", args[3], args[4])
  3965.             elseif (args[3] >= 2 and args[3] <= 21) and (args[4] == 4) then
  3966.                 store.snippets.view()
  3967.             elseif (args[3] >= 2 and args[3] <= 21) and (args[4] == 6) then
  3968.                 store.snippets.upload()
  3969.             elseif (args[3] >= 2 and args[3] <= 21) and (args[4] == 8) then
  3970.                 store.snippets.user()
  3971.             end
  3972.         end
  3973.     end
  3974. end
  3975.  
  3976. function store.snippets.view()
  3977.     base.screen.colour("white")
  3978.     store.draw.menu("Snippets (View)")
  3979.     base.draw.box(1, 51, 19, 1, " ", "grey", "grey")
  3980.     base.draw.textr("Back ", 19, false, "orange", "grey")
  3981.     local scroll = 0
  3982.  
  3983.     local stat = discover:snippets_list()
  3984.     if not stat then
  3985.         base.draw.textc("Could not download snippets listing", 10, false, "red", "white")
  3986.         sleep(2.5)
  3987.         base.thread.remove("Snippets")
  3988.         base.thread.switch("Home")
  3989.     end
  3990.     base.draw.texta("Total: "..#discover.data.snippets, 2, 19, false, "lightBlue", "grey")
  3991.  
  3992.     local function fix(num)
  3993.         if tostring(num):len() == 1 then
  3994.             return "  "..tostring(num)
  3995.         elseif tostring(num):len() == 2 then
  3996.             return " "..tostring(num)
  3997.         else
  3998.             return tostring(num)
  3999.         end
  4000.     end
  4001.  
  4002.     local function run(scroll)
  4003.         if #discover.data.snippets > 0 then
  4004.             for i = 1, 14 do
  4005.                 if #discover.data.snippets >= i + scroll then
  4006.                     base.draw.box(1, 51, i+3, 1, " ", "white", "white")
  4007.                     base.draw.textl(fix(i+scroll)..": "..discover.data.snippets[i+scroll].name, i+3, false, "grey", "white")
  4008.                 end
  4009.             end
  4010.         else
  4011.             base.draw.textc("There are no snippets to display", 10, false, "red", "white")
  4012.         end
  4013.     end
  4014.  
  4015.     run(scroll)
  4016.  
  4017.     while true do
  4018.         local args = { os.pullEvent() }
  4019.         if args[1] == "timer" then
  4020.             store.draw.menu("Snippets (View)")
  4021.         elseif args[1] == "mouse_click" then
  4022.             if args[4] >= 1 and args[4] <= 2 then
  4023.                 store.draw.menu_input("Snippets (View)", args[3], args[4])
  4024.             elseif (args[3] >= 47 and args[3] <= 51) and (args[4] == 19) then
  4025.                 store.snippets.main()
  4026.             elseif (args[3] >= 1 and args[3] <= 51) and (args[4] >= 4 and args[4] <= 17) then
  4027.                 local curid = args[4] - 3 + scroll
  4028.                 if #discover.data.snippets >= curid then
  4029.                     store.snippets.view_snip(discover.data.snippets[curid])
  4030.                     store.snippets.view()
  4031.                 end
  4032.             end
  4033.         elseif args[1] == "mouse_scroll" then
  4034.             if args[2] == -1 then
  4035.                 if scroll > 0 then
  4036.                     scroll = scroll - 1
  4037.                     run(scroll)
  4038.                 end
  4039.             elseif args[2] == 1 then
  4040.                 if scroll + 14 <= #discover.data.snippets-1 then
  4041.                     scroll = scroll + 1
  4042.                     run(scroll)
  4043.                 end
  4044.             end
  4045.         end
  4046.     end
  4047. end
  4048.  
  4049. function store.snippets.view_snip(snippet_data)
  4050.     base.screen.colour("white")
  4051.     store.draw.menu("Snippets (View Snippet)")
  4052.     base.draw.box(1, 51, 19, 1, " ", "grey", "grey")
  4053.     base.draw.textr("Back ", 19, false, "orange", "grey")
  4054.  
  4055.     base.draw.texta("Name (ID):", 1, 4, false, "lightGrey", "white")
  4056.     base.draw.texta("Version:", 1, 5, false, "lightGrey", "white")
  4057.     base.draw.texta("Creator:", 1, 6, false, "lightGrey", "white")
  4058.     base.draw.texta("Index / Status:", 1, 7, false, "lightGrey", "white")
  4059.     base.draw.textl(" Downloads: "..tostring(snippet_data.downloads), 19, false, "lightBlue", "grey")
  4060.     base.draw.texta("Description:", 1, 9, false, "lightGrey", "white")
  4061.     base.draw.texta(tostring(snippet_data.name).." ("..tostring(snippet_data.id)..")", 17, 4, false, "cyan", "white")
  4062.     base.draw.texta(tostring(snippet_data.version), 17, 5, false, "cyan", "white")
  4063.     base.draw.texta(tostring(snippet_data.creator), 17, 6, false, "cyan", "white")
  4064.     base.draw.texta(tostring(snippet_data.index).." / "..tostring(snippet_data.status), 17, 7, false, "cyan", "white")
  4065.    
  4066.     for k,v in ipairs(base.data.wordwrap(snippet_data.description, 51)) do
  4067.         base.draw.textl(v, k+10, false, "grey", "white")
  4068.     end
  4069.  
  4070.     base.draw.texta(" Download ", 41, 5, false, "white", "cyan")
  4071.     base.draw.texta(" Snippet! ", 41, 6, false, "white", "cyan")
  4072.  
  4073.     while true do
  4074.         local args = { os.pullEvent() }
  4075.         if args[1] == "timer" then
  4076.             store.draw.menu("Snippets (View Snippet)")
  4077.         elseif args[1] == "mouse_click" then
  4078.             if args[4] >= 1 and args[4] <= 2 then
  4079.                 store.draw.menu_input("Snippets (View)", args[3], args[4])
  4080.             elseif (args[3] >= 47 and args[3] <= 50) and (args[4] == 19) then
  4081.                 break
  4082.             elseif (args[3] >= 41 and args[3] <= 50) and (args[4] >= 5 and args[4] <= 6) then
  4083.                 for i=7, 14 do
  4084.                     base.draw.box(8, 35, i, 1, " ", "white", "white")
  4085.                 end
  4086.                 base.draw.box(8, 35, 7, 6, " ", "grey", "grey")
  4087.                 base.colour.set("lightGrey", "white")
  4088.                 term.setCursorPos(9, 8)
  4089.                 write(":: Path/Name: ")
  4090.                 local name = tostring(base.io.limitRead(34))
  4091.                 base.draw.texta(":: Requesting file", 9, 9, false, "lightGrey", "white")
  4092.                 sleep(0.5)
  4093.                 local data = discover:snippets_download(snippet_data.id)
  4094.                 base.draw.texta(":: File received", 9, 10, false, "lightGrey", "white")
  4095.                 base.draw.texta(":: Saving to file", 9, 11, false, "lightGrey", "white")
  4096.                 local f = fs.open(name, "w")
  4097.                 f.write(data)
  4098.                 f.close()
  4099.                 sleep(1)
  4100.                 store.snippets.view_snip(snippet_data)
  4101.             end
  4102.         end
  4103.     end
  4104. end
  4105.  
  4106. function store.snippets.upload()
  4107.     base.screen.colour("white")
  4108.     store.draw.menu("Snippets (Upload)")
  4109.     base.draw.box(1, 51, 19, 1, " ", "grey", "grey")
  4110.     base.draw.textr("Back ", 19, false, "orange", "grey")
  4111.     base.draw.textl(" Upload", 19, false, "lightBlue", "grey")
  4112.  
  4113.     base.draw.texta("Name:", 8, 4, false, "lightGrey", "white")
  4114.     base.draw.box(8, 36, 5, 1, " ", "cyan", "cyan")
  4115.     base.draw.texta("Description:", 8, 7, false, "lightGrey", "white")
  4116.     base.draw.box(8, 36, 8, 1, " ", "cyan", "cyan")
  4117.     base.draw.texta("Version:", 8, 10, false, "lightGrey", "white")
  4118.     base.draw.box(8, 36, 11, 1, " ", "cyan", "cyan")
  4119.     base.draw.texta("Status:", 8, 13, false, "lightGrey", "white")
  4120.     base.draw.box(8, 36, 14, 1, " ", "cyan", "cyan")
  4121.     base.draw.texta("Path:", 8, 16, false, "lightGrey", "white")
  4122.     base.draw.box(8, 36, 17, 1, " ", "cyan", "cyan")
  4123.  
  4124.     while true do
  4125.         local args = { os.pullEvent() }
  4126.         if args[1] == "timer" then
  4127.             store.draw.menu("Snippets (Upload)")
  4128.         elseif args[1] == "mouse_click" then
  4129.             if args[4] >= 1 and args[4] <= 2 then
  4130.                 store.draw.menu_input("Snippets (Upload)", args[3], args[4])
  4131.             elseif (args[3] >= 47 and args[3] <= 50) and (args[4] == 19) then
  4132.                 store.snippets.main()
  4133.             elseif (args[3] >= 8 and args[3] <= 43) and (args[4] == 5) then
  4134.                 base.draw.box(8, 36, 5, 1, " ", "cyan", "cyan")
  4135.                 base.colour.set("white", "cyan")
  4136.                 term.setCursorPos(8, 5)
  4137.                 write(": ")
  4138.                 name = tostring(base.io.limitRead(34))
  4139.             elseif (args[3] >= 8 and args[3] <= 43) and (args[4] == 8) then
  4140.                 base.draw.box(8, 36, 8, 1, " ", "cyan", "cyan")
  4141.                 base.colour.set("white", "cyan")
  4142.                 term.setCursorPos(8, 8)
  4143.                 write(": ")
  4144.                 desc = tostring(base.io.limitRead(34))
  4145.             elseif (args[3] >= 8 and args[3] <= 43) and (args[4] == 11) then
  4146.                 base.draw.box(8, 36, 11, 1, " ", "cyan", "cyan")
  4147.                 base.colour.set("white", "cyan")
  4148.                 term.setCursorPos(8, 11)
  4149.                 write(": ")
  4150.                 vers = tostring(base.io.limitRead(34))
  4151.             elseif (args[3] >= 8 and args[3] <= 43) and (args[4] == 14) then
  4152.                 base.draw.box(8, 36, 14, 1, " ", "cyan", "cyan")
  4153.                 base.colour.set("white", "cyan")
  4154.                 term.setCursorPos(8, 14)
  4155.                 write(": ")
  4156.                 stat = tostring(base.io.limitRead(34))
  4157.             elseif (args[3] >= 8 and args[3] <= 43) and (args[4] == 17) then
  4158.                 base.draw.box(8, 36, 17, 1, " ", "cyan", "cyan")
  4159.                 base.colour.set("white", "cyan")
  4160.                 term.setCursorPos(8, 17)
  4161.                 write(": ")
  4162.                 path = tostring(base.io.limitRead(34))
  4163.             elseif (args[3] >= 2 and args[3] <= 7) and (args[4] == 19) then
  4164.                 if name and desc and vers and stat and path then
  4165.                     if fs.exists(path) then
  4166.                         local stat = discover:snippets_upload(name, desc, vers, stat, path)
  4167.                         if stat then
  4168.                             base.gui.alert("Snippet upload was successful!")
  4169.                             sleep(0.5)
  4170.                             base.gui.alert("Updating local snippet database...")
  4171.                             discover:store_init()
  4172.                             store.snippets.main()
  4173.                         else
  4174.                             base.gui.alert("Error: "..tostring(discover.data.errormsg))
  4175.                             sleep(2)
  4176.                             store.snippets.main()
  4177.                         end
  4178.                     else
  4179.                         base.draw.textc("File does not exist at path", 18, false, "red", "white")
  4180.                         sleep(1)
  4181.                         base.draw.box(1, 51, 18, 1, " ", "white", "white")
  4182.                     end
  4183.                 else
  4184.                     base.draw.textc("Please fill out all fields", 18, false, "red", "white")
  4185.                     sleep(1)
  4186.                     base.draw.box(1, 51, 18, 1, " ", "white", "white")
  4187.                 end
  4188.             end
  4189.         end
  4190.     end
  4191. end
  4192.  
  4193. function store.snippets.user()
  4194.     base.screen.colour("white")
  4195.     store.draw.menu("Snippets (User)")
  4196.     base.draw.box(1, 51, 19, 1, " ", "grey", "grey")
  4197.     base.draw.textr("Back ", 19, false, "orange", "grey")
  4198.     local scroll = 0
  4199.  
  4200.     local stat = discover:snippets_list_user()
  4201.     if not stat then
  4202.         base.draw.textc("Could not download snippets listing", 10, false, "red", "white")
  4203.         base.draw.textc(discover.data.errormsg, 11, false, "lightGrey", "white")
  4204.         sleep(2.5)
  4205.         base.thread.remove("Snippets")
  4206.         base.thread.switch("Home")
  4207.     end
  4208.     base.draw.texta("Total: "..#discover.data.snippets_user, 2, 19, false, "lightBlue", "grey")
  4209.  
  4210.     local function fix(num)
  4211.         if tostring(num):len() == 1 then
  4212.             return "  "..tostring(num)
  4213.         elseif tostring(num):len() == 2 then
  4214.             return " "..tostring(num)
  4215.         else
  4216.             return tostring(num)
  4217.         end
  4218.     end
  4219.  
  4220.     local function run(scroll)
  4221.         if #discover.data.snippets_user > 0 then
  4222.             for i = 1, 14 do
  4223.                 if #discover.data.snippets_user >= i + scroll then
  4224.                     base.draw.box(1, 51, i+3, 1, " ", "white", "white")
  4225.                     -- base.draw.texta("Edit", 45, i+3, false, "cyan", "white")
  4226.                     base.draw.texta("X", 50, i+3, false, "red", "white")
  4227.                     base.draw.textl(fix(i+scroll)..": "..discover.data.snippets_user[i+scroll].name, i+3, false, "grey", "white")
  4228.                 end
  4229.             end
  4230.         else
  4231.             base.draw.textc("There are no snippets to display", 10, false, "red", "white")
  4232.         end
  4233.     end
  4234.  
  4235.     run(scroll)
  4236.  
  4237.     while true do
  4238.         local args = { os.pullEvent() }
  4239.         if args[1] == "timer" then
  4240.             store.draw.menu("Snippets (User)")
  4241.         elseif args[1] == "mouse_click" then
  4242.             if args[4] >= 1 and args[4] <= 2 then
  4243.                 store.draw.menu_input("Snippets (User)", args[3], args[4])
  4244.             elseif (args[3] >= 47 and args[3] <= 51) and (args[4] == 19) then
  4245.                 store.snippets.main()
  4246.             elseif (args[3] >= 1 and args[3] <= 43) and (args[4] >= 4 and args[4] <= 17) then
  4247.                 local curid = args[4] - 3 + scroll
  4248.                 if #discover.data.snippets_user >= curid then
  4249.                     -- View
  4250.                     store.snippets.view_snip(discover.data.snippets_user[curid])
  4251.                     store.snippets.user()
  4252.                 end
  4253.             -- elseif (args[3] >= 45 and args[3] <= 48) and (args[4] >= 4 and args[4] <= 17) then
  4254.             --  local curid = args[4] - 3 + scroll
  4255.             --  if #discover.data.snippets_user >= curid then
  4256.             --      -- Edit
  4257.             --      store.snippets.edit(discover.data.snippets_user[curid])
  4258.             --      store.snippets.user()
  4259.             --  end
  4260.             elseif (args[3] == 50) and (args[4] >= 4 and args[4] <= 17) then
  4261.                 local curid = args[4] - 3 + scroll
  4262.                 if #discover.data.snippets_user >= curid then
  4263.                     -- Delete
  4264.                     local stat = discover:snippets_delete(discover.data.snippets_user[curid].id)
  4265.                     if stat then
  4266.                         base.gui.alert("Snippet deleted!")
  4267.                         sleep(1)
  4268.                         base.gui.alert("Updating local app database...")
  4269.                         discover:store_init()
  4270.                         store.snippets.user()
  4271.                     else
  4272.                         base.gui.alert("Snippet was unable to be deleted!")
  4273.                         sleep(1)
  4274.                         base.gui.alert(discover.data.errormsg)
  4275.                         sleep(1.5)
  4276.                         store.snippets.user()
  4277.                     end
  4278.                 end
  4279.             end
  4280.         elseif args[1] == "mouse_scroll" then
  4281.             if args[2] == -1 then
  4282.                 if scroll > 0 then
  4283.                     scroll = scroll - 1
  4284.                     run(scroll)
  4285.                 end
  4286.             elseif args[2] == 1 then
  4287.                 if scroll + 14 <= #discover.data.snippets_user-1 then
  4288.                     scroll = scroll + 1
  4289.                     run(scroll)
  4290.                 end
  4291.             end
  4292.         end
  4293.     end
  4294. end
  4295.  
  4296. function store.settings(screen)
  4297.     local function clears()
  4298.         for i=1, 51 do
  4299.             if i >= 1 and i <= 20 then
  4300.                 base.draw.box(i, 1, 3, 17, " ", "lightGrey", "lightGrey")
  4301.             end
  4302.             if i>= 21 and i <= 51 then
  4303.                 base.draw.box(i, 1, 3, 17, " ", "white", "white")
  4304.             end
  4305.         end
  4306.         base.draw.box(1, 51, 19, 1, " ", "grey", "grey")
  4307.     end
  4308.  
  4309.     if not screen then
  4310.         screen = ""
  4311.     end
  4312.  
  4313.     local function draw_menu()
  4314.         base.draw.box(2, 18, 4, 1, " ", "orange", "orange")
  4315.         base.draw.box(2, 18, 6, 1, " ", "orange", "orange")
  4316.         base.draw.box(2, 18, 8, 1, " ", "orange", "orange")
  4317.         base.draw.box(2, 18, 10, 1, " ", "orange", "orange")
  4318.         base.draw.texta("Main Menu", 3, 4, false, "white", "orange")
  4319.         base.draw.texta("System Settings", 3, 6, false, "white", "orange")
  4320.         base.draw.texta("Discover Details", 3, 8, false, "white", "orange")
  4321.         base.draw.texta("Code Snippets", 3, 10, false, "white", "orange")
  4322.         if screen == "System" then
  4323.             base.draw.box(2, 18, 6, 1, " ", "red", "red")
  4324.             base.draw.texta("System Settings", 3, 6, false, "white", "red")
  4325.         elseif screen == "Details" then
  4326.             base.draw.box(2, 18, 8, 1, " ", "red", "red")
  4327.             base.draw.texta("Discover Details", 3, 8, false, "white", "red")
  4328.         elseif screen == "CodeSnippets" then
  4329.             base.draw.box(2, 18, 10, 1, " ", "red", "red")
  4330.             base.draw.texta("Code Snippets", 3, 10, false, "white", "red")
  4331.         else
  4332.             base.draw.box(2, 18, 4, 1, " ", "red", "red")
  4333.             base.draw.texta("Main Menu", 3, 4, false, "white", "red")
  4334.         end
  4335.     end
  4336.  
  4337.     if screen == "System" then
  4338.         -- System
  4339.         local scroll = 0
  4340.  
  4341.         clears()
  4342.         store.draw.menu("Settings (System)")
  4343.  
  4344.         base.draw.box(1, 51, 19, 1, " ", "grey", "grey")
  4345.         base.draw.textr("Scroll Enabled ", 19, false, "orange", "grey")
  4346.  
  4347.         local function run(scroll)
  4348.             base.draw.textr("----------------------------- ", 4, false, "lightGrey", "white")
  4349.             base.draw.texta("Toggle config storage:", 22, 5, false, "grey", "white")
  4350.             base.draw.box(22, 29, 7, 1, " ", "white", "white")
  4351.             base.draw.texta("Status:", 22, 7, false, "grey", "white")
  4352.             if system.storeconfig then
  4353.                 base.draw.texta("Enabled", 30, 7, false, "cyan", "white")
  4354.                 new = {}
  4355.                 new.username = discover.data.username
  4356.                 new.password = discover.data.password
  4357.                 new.storeconfig = system.storeconfig
  4358.                 new.plugins = system.plugins
  4359.                 new.authkey = discover.data.authkey
  4360.                 dat = textutils.serialize(new)
  4361.                 local f = fs.open(system.paths.config, "w")
  4362.                 f.write(base.base64.encode(dat))
  4363.                 f.close()
  4364.             else
  4365.                 base.draw.texta("Disabled", 30, 7, false, "red", "white")
  4366.                 fs.delete(system.paths.config)
  4367.             end
  4368.             base.draw.textr("----------------------------- ", 8, false, "lightGrey", "white")
  4369.             base.draw.texta("Toggle plugins:", 22, 9, false, "grey", "white")
  4370.             base.draw.box(22, 29, 11, 1, " ", "white", "white")
  4371.             base.draw.texta("Status:", 22, 11, false, "grey", "white")
  4372.             if system.plugins then
  4373.                 base.draw.texta("Enabled", 30, 11, false, "cyan", "white")
  4374.             else
  4375.                 base.draw.texta("Disabled", 30, 11, false, "red", "white")
  4376.             end
  4377.             base.draw.textr("----------------------------- ", 12, false, "lightGrey", "white")
  4378.             base.draw.texta("Toggle program lock:", 22, 13, false, "grey", "white")
  4379.             base.draw.box(22, 29, 15, 1, " ", "white", "white")
  4380.             base.draw.texta("Status:", 22, 15, false, "grey", "white")
  4381.             if system.lock_program then
  4382.                 base.draw.texta("Enabled", 30, 15, false, "cyan", "white")
  4383.             else
  4384.                 base.draw.texta("Disabled", 30, 15, false, "red", "white")
  4385.             end
  4386.             base.draw.textr("----------------------------- ", 16, false, "lightGrey", "white")
  4387.             base.draw.texta(" T ", 48, 6, false, "white", "orange")
  4388.             base.draw.texta(" T ", 48, 10, false, "white", "orange")
  4389.             base.draw.texta(" T ", 48, 14, false, "white", "orange")
  4390.         end
  4391.  
  4392.         draw_menu()
  4393.         run(scroll)
  4394.         while true do
  4395.             local args = { os.pullEvent() }
  4396.             if args[1] == "timer" then
  4397.                 store.draw.menu("Settings (System)")
  4398.             elseif args[1] == "mouse_click" then
  4399.                 if args[4] >= 1 and args[4] <= 2 then
  4400.                     store.draw.menu_input("Settings (System)", args[3], args[4])
  4401.                 elseif (args[3] >= 2 and args[3] <= 18) and args[4] == 4 then
  4402.                     store.settings()
  4403.                 elseif (args[3] >= 2 and args[3] <= 18) and args[4] == 6 then
  4404.                     store.settings("System")
  4405.                 elseif (args[3] >= 2 and args[3] <= 18) and args[4] == 8 then
  4406.                     store.settings("Details")
  4407.                 elseif (args[3] >= 2 and args[3] <= 18) and args[4] == 10 then
  4408.                     store.settings("CodeSnippets")
  4409.                 elseif (args[3] >= 48 and args[3] <= 50) and (args[4] == 6) then
  4410.                     if system.storeconfig then
  4411.                         system.storeconfig = false
  4412.                         if fs.exists(system.paths.config) then
  4413.                             fs.delete(system.paths.config)
  4414.                         end
  4415.                     else
  4416.                         system.storeconfig = true
  4417.                     end
  4418.                     run(scroll)
  4419.                 elseif (args[3] >= 48 and args[3] <= 50) and (args[4] == 10) then
  4420.                     if system.plugins then
  4421.                         system.plugins = false
  4422.                     else
  4423.                         system.plugins = true
  4424.                     end
  4425.                     run(scroll)
  4426.                 elseif (args[3] >= 48 and args[3] <= 50) and (args[4] == 14) then
  4427.                     if system.lock_program then
  4428.                         system.lock_program = false
  4429.                     else
  4430.                         system.lock_program = true
  4431.                     end
  4432.                     run(scroll)
  4433.                 end
  4434.             end
  4435.         end
  4436.     elseif screen == "Details" then
  4437.         -- Details
  4438.         local scroll = 0
  4439.  
  4440.         clears()
  4441.         store.draw.menu("Settings (Discover Details)")
  4442.  
  4443.         base.draw.box(1, 51, 19, 1, " ", "grey", "grey")
  4444.         base.draw.textr("Scroll Enabled ", 19, false, "orange", "grey")
  4445.  
  4446.         local function run(scroll)
  4447.             base.draw.textr("----------------------------- ", 4, false, "lightGrey", "white")
  4448.             base.draw.texta("Discover API Version:", 22, 5, false, "grey", "white")
  4449.             base.draw.texta(tostring(discover:get("version_api")), 22, 7, false, "cyan", "white")
  4450.             base.draw.textr("----------------------------- ", 8, false, "lightGrey", "white")
  4451.             base.draw.texta("Discover System Version:", 22, 9, false, "grey", "white")
  4452.             base.draw.texta(tostring(discover:get("version")), 22, 11, false, "cyan", "white")
  4453.             base.draw.textr("----------------------------- ", 12, false, "lightGrey", "white")
  4454.         end
  4455.  
  4456.         draw_menu()
  4457.         run(scroll)
  4458.         while true do
  4459.             local args = { os.pullEvent() }
  4460.             if args[1] == "timer" then
  4461.                 store.draw.menu("Settings (Discover Details)")
  4462.             elseif args[1] == "mouse_click" then
  4463.                 if args[4] >= 1 and args[4] <= 2 then
  4464.                     store.draw.menu_input("Settings (Menu)", args[3], args[4])
  4465.                 elseif (args[3] >= 2 and args[3] <= 18) and args[4] == 4 then
  4466.                     store.settings()
  4467.                 elseif (args[3] >= 2 and args[3] <= 18) and args[4] == 6 then
  4468.                     store.settings("System")
  4469.                 elseif (args[3] >= 2 and args[3] <= 18) and args[4] == 8 then
  4470.                     store.settings("Details")
  4471.                 elseif (args[3] >= 2 and args[3] <= 18) and args[4] == 10 then
  4472.                     store.settings("CodeSnippets")
  4473.                 end
  4474.             end
  4475.         end
  4476.     elseif screen == "CodeSnippets" then
  4477.         -- Details
  4478.         local scroll = 0
  4479.  
  4480.         clears()
  4481.         store.draw.menu("Settings (Code Snippets)")
  4482.  
  4483.         base.draw.box(1, 51, 19, 1, " ", "grey", "grey")
  4484.  
  4485.         local tData = {
  4486.             "---";
  4487.             "";
  4488.             "#Store Require Script";
  4489.             "Allows you to require apps";
  4490.             "into your code";
  4491.             "";
  4492.             "---";
  4493.         }
  4494.  
  4495.         local function run(scroll)
  4496.             for i=1, 14 do
  4497.                 if #tData >= i + scroll then
  4498.                     base.draw.box(22, 30, i+3, 1, " ", "white", "white")
  4499.                     if tData[i+scroll]:sub(1,1) == "-" then
  4500.                         base.draw.texta("-----------------------", 22, i+3, false, "lightGrey", "white")
  4501.                     elseif tData[i+scroll]:sub(1,1) == "#" then
  4502.                         base.draw.texta(tData[i+scroll]:sub(2), 22, i+3, false, "grey", "white")
  4503.                     else
  4504.                         base.draw.texta(tData[i+scroll], 22, i+3, false, "cyan", "white")
  4505.                     end
  4506.                 end
  4507.             end
  4508.         end
  4509.  
  4510.         draw_menu()
  4511.         run(scroll)
  4512.         while true do
  4513.             local args = { os.pullEvent() }
  4514.             if args[1] == "timer" then
  4515.                 store.draw.menu("Settings (Code Snippets)")
  4516.             elseif args[1] == "mouse_click" then
  4517.                 if args[4] >= 1 and args[4] <= 2 then
  4518.                     store.draw.menu_input("Settings (Code Snippets)", args[3], args[4])
  4519.                 elseif (args[3] >= 2 and args[3] <= 18) and args[4] == 4 then
  4520.                     store.settings()
  4521.                 elseif (args[3] >= 2 and args[3] <= 18) and args[4] == 6 then
  4522.                     store.settings("System")
  4523.                 elseif (args[3] >= 2 and args[3] <= 18) and args[4] == 8 then
  4524.                     store.settings("Details")
  4525.                 elseif (args[3] >= 2 and args[3] <= 18) and args[4] == 10 then
  4526.                     store.settings("CodeSnippets")
  4527.                 elseif (args[3] >= 21 and args[3] <= 51) and (args[4] >= 4 and args[4] <= 18) then
  4528.                     -- Run Function Downloads
  4529.                    
  4530.                 end
  4531.             elseif args[1] == "mouse_scroll" then
  4532.                 if args[2] == -1 then
  4533.                     if scroll > 0 then
  4534.                         scroll = scroll - 1
  4535.                         run(scroll)
  4536.                     end
  4537.                 elseif args[2] == 1 then
  4538.                     if scroll + 14 < #tData then
  4539.                         scroll = scroll + 1
  4540.                         run(scroll)
  4541.                     end
  4542.                 end
  4543.             end
  4544.         end
  4545.     else
  4546.         -- Home
  4547.         base.screen.colour("white")
  4548.         local scroll = 0
  4549.         store.draw.menu("Settings (Menu)")
  4550.  
  4551.         clears()
  4552.  
  4553.         base.draw.textr("Scroll Enabled ", 19, false, "orange", "grey")
  4554.  
  4555.         local function run(scoll)
  4556.             local text = "This is the settings menu, please choose a sub-category to see the available options. Some options are for use on servers and for custom App Stores, please see Discover API: Store Documentation for more information. The options are on the left side (orange buttons), and please note that the right side of the screen (in white) is scrollable."
  4557.             tText = base.data.wordwrap(text, 29)
  4558.  
  4559.             for i=1, 14 do
  4560.                 if #tText >= i + scroll then
  4561.                     base.draw.box(21, 30, i+3, 1, " ", "white", "white")
  4562.                     base.draw.texta(tText[i+scroll], 22, i+3, false, "grey", "white")
  4563.                 end
  4564.             end
  4565.         end
  4566.  
  4567.         draw_menu()
  4568.         run(scroll)
  4569.         while true do
  4570.             local args = { os.pullEvent() }
  4571.             if args[1] == "timer" then
  4572.                 store.draw.menu("Settings (Menu)")
  4573.             elseif args[1] == "mouse_click" then
  4574.                 if args[4] >= 1 and args[4] <= 2 then
  4575.                     store.draw.menu_input("Settings (Menu)", args[3], args[4])
  4576.                 elseif (args[3] >= 2 and args[3] <= 18) and args[4] == 4 then
  4577.                     store.settings()
  4578.                 elseif (args[3] >= 2 and args[3] <= 18) and args[4] == 6 then
  4579.                     store.settings("System")
  4580.                 elseif (args[3] >= 2 and args[3] <= 18) and args[4] == 8 then
  4581.                     store.settings("Details")
  4582.                 elseif (args[3] >= 2 and args[3] <= 18) and args[4] == 10 then
  4583.                     store.settings("CodeSnippets")
  4584.                 end
  4585.             elseif args[1] == "mouse_scroll" then
  4586.                 if args[2] == -1 then
  4587.                     if scroll > 0 then
  4588.                         scroll = scroll - 1
  4589.                         run(scroll)
  4590.                     end
  4591.                 elseif args[2] == 1 then
  4592.                     if scroll + 14 < #tText then
  4593.                         scroll = scroll + 1
  4594.                         run(scroll)
  4595.                     end
  4596.                 end
  4597.             end
  4598.         end
  4599.     end
  4600. end
  4601.  
  4602. function store.help(name)
  4603.     tData = {
  4604.         {
  4605.             ["name"] = "How to use the App Store";
  4606.             ["content"] = "Using the App Store is super simple. The Store uses a multitasking system with a task bar in the header, so you can have 20 screens open, and use the arrow buttons to switch between the task list, and click what you need. All tasks can be closed with the little \"x\" on the left of them. Most things you need are on the home screen, so if you need to upload an app, then you can simply click the button, a new thread will open with the content and you can switch back and forth with ease and no problems. Editing apps and updating apps is done in your \"My Account\" as this will display your apps and your details, all apps will have buttons by the side of their name (if you have permissions) to edit them. Statistics are simply a list of your downloads, comments and your best submitted apps.";
  4607.         };
  4608.         {
  4609.             ["name"] = "Snippets Section";
  4610.             ["content"] = "One of the requested features I have seen a lot is a way of being able to add snippets to the store, so I have added this feature, snippets can be public or private to just you, each snippet will get a generated id, this id can be used to download the snippet via the store or via the stores new command line tool. Each snippet has a set limit of up to 4000 lines, or around 250,000 characters. This of course is to make sure it is a snippet! Not an App, apps must be uploaded via the apps, and snippets are for simple code sections you wish to use. Snippets can also be included in code using a small script which can be downloaded from the settings menu.";
  4611.         };
  4612.         {
  4613.             ["name"] = "Discover Cloud";
  4614.             ["content"] = "Think of the cloud as repository of files, where you can upload/download files whenever you want, the idea is that all files are stored for you to retrieve on another computer or something else, we are in the middle of creating a new App Store Website, which will have online editors that are linked to the DiscoverCloud. The DiscoverCloud will be internal the the Store until I have ironed out the bugs and made some more awesome functions, the standalone program will come later on and will be a modified shell extension, allowing you to view remote files as if they are on your computer. You aren't limited on what you can save, there are many more addons to add to the cloud but for now, this will be in Alpha until I have finished the new features to give it, the cloud will be the main focal point of the App Store's 5.x updates, as this is something that I can think would be useful to many people.";
  4615.         };
  4616.         {
  4617.             ["name"] = "Discover Social";
  4618.             ["content"] = "What is Discover Social you ask? Well I made an API called SocialNet once but because of it having many bugs and no official client, I thought maybe it would be cooler to actually make a much more advanced API with a nice interface to use for the Store. Therefore I thought about making the social aspect to Discover. Now Discover will have a better client which will later work with the Discover Social API. But until then I thought I would add it to this program instead. I know a lot of people have wanted this kind of functionality and it does add tons of awesome and powerful ideas. I am currently recruiting for developers that can help me build a lot of these ideas so if you are interested please send me a message!";
  4619.         };
  4620.         {
  4621.             ["name"] = "How to use: Discover Cloud";
  4622.             ["content"] = "Usage of the cloud is simple, currently there are only two features it has, and as I work on it more in the next month, I plan to have it very extensive and powerful. The current features, are uploading, and deleting. When you run the Discover Cloud, it will popup with two sides of the screen, the left (Local files) and the right (Remote files), to upload a file from your local files, go to the left side (local files), choose the file you want to upload, and then press the arrow \">\" and this will push the file to the server, and then refresh the page, it also comes with a delete function for local files, so click the \"X\" will delete the local file, with the remote files to delete use the \"X\" and to download the file use the \"<\" button, which will pull it from the server, please note all file transfers are done as copies to make sure you don't upload it by mistake and vice versa.";
  4623.         };
  4624.         {
  4625.             ["name"] = "Discover API System";
  4626.             ["content"] = "Discover API System is the newest design I have made which combines a more secure approach at using the database, this is because the old API is going down due to it being abused so now this new version supports rate limiting, so you can not send a certain amount of requests in a time limit, you follow auth keys which expire and make it even more secure. You can learn to use it by going here: \"http://discover.dannysmc.com/\", thanks for reading.";
  4627.         };
  4628.         {
  4629.             ["name"] = "Notifications";
  4630.             ["content"] = "Simply put, a notification will be something that can tell you something, so say someone commented on your app, then once this occurs this will be added to your notifications tray, allowing you to read through them. If you wish to remove a notification you can just click on the little \"x\" on the side of the notification, or click the notification for more information. You can also have email notifications which is an opt-in feature.";
  4631.         };
  4632.         {
  4633.             ["name"] = "Mailbox";
  4634.             ["content"] = "The mailbox is a new aspect introduced that allows you to send and receive mail between users that are part of the Discover API Network. From now we have over 500 users registered, meaning you can talk to other players and send them information as well as send them files. To use the mailbox go to: Social Network -> Mailbox, here you will be presented with some simple options. Inbox is loaded first of all, but in essence it is just your current inbox, any items that are unread will have a sidebar to the right of the mail that is coloured red, to read an email just click it. Once inside the email you can see all the details plus the message field is scrollable. You will have 3 options at the bottom, back goes back to your inbox, delete will delete the mail and return to your inbox and reply will auto fill the user for you and then send you to the create screen. Email creation (Create): here you will have 4 fields, Recipient, this is who you are sending the mail to, remember this is just the username, I thought it was silly to add full addresses but I may be opening up a larger network for all users to access meaning there will be an API that connects with other mail networks from other users, but I have not finalised this. The subject is of course the subject of the email, message is the full message you want to send. Once they are all filled out you can send an email with the send button or cancel with the cancel button. There is a field for attachments, this is to allow you to send a file to another user, you can use Creator's Compress program to compress and archive lots of files as it only supports single attachments at the moment. The sent option just shows you the sent emails you have done, these are not deletable just yet, but I shall be adding that feature in the next update. The actual inbox screen IS scrollable using pages so each scroll will take you to a new page. Page listings are showed in the bottom left corner as well as a count of how many unread messages you have.";
  4635.         };
  4636.         {
  4637.             ["name"] = "News Feed";
  4638.             ["content"] = "News feed is just another way to post status updates and inform users about things you are doing. To use the news feed go to: Social Network -> News Feed, once here you will be presented with a scrollable screen with a username, in red, post in cyan, and the date it was posted in orange. To create a new post just click the Create Post button and this will give you a popup box that allows you to insert text, once you press Enter it will automatically insert your new status. Pressing refresh will refresh your feed.";
  4639.         };
  4640.         {
  4641.             ["name"] = "Store Settings";
  4642.             ["content"] = "Settings are simply a list of all your settings that are stored, so this can be what is stored against your file, so if you want to store your username and password, or just your authkey or even cache the Apps, Versions, and Categories lists. As well as the option to allow background processes to run, like auto-update and more.";
  4643.         };
  4644.         {
  4645.             ["name"] = "Store Statistics";
  4646.             ["content"] = "You can see the Statistics of your account and the Store, so you can see how many users, apps, comments, and downloads (total), as well as your personal amount. This also allows you to see how well you are doing and your position on the Discover System.";
  4647.         };
  4648.         {
  4649.             ["name"] = "Uploading/Downloading/Editing/Updating Apps";
  4650.             ["content"] = "Uploading apps is super easy using the drop downs for categories and versioning. We always suggest following the proper versioning system, but of course most users like to make their own. Downloading apps is now done via PHP instead of from a URL, this is to ensure you follow the download rules so we can log downloads. Editing and Updating are as simple as editing updating code for apps.";
  4651.         };
  4652.         {
  4653.             ["name"] = "Discover API Account";
  4654.             ["content"] = "A user account on Discover is super simple, we use an oAuth based system to allow API's to access your SocialNet system and App Store data. This is not mainly used but will be used for external applications wanting access to your details. You can revert this online using the Discover Systems Website (This is still under production.";
  4655.         };
  4656.         {
  4657.             ["name"] = "How do plugins work?";
  4658.             ["content"] = "If you found a function that is faulty or has broken, we allow you to rewrite code with the use of plugins. A plugin is loaded upon system startup which means you can use a plugin to add or remove functionality. An example would be that you want to add support for only allowing downloading programs and then sending them to a computer via rednet etc, then you can overwrite a function by just writing the same function and amending it how you need. This means you can extend it\'s functionality massively, by adding more functions. Of course if you wish to add more options then you will have to use my API, which is already loaded.";
  4659.         };
  4660.         {
  4661.             ["name"] = "What do you mean \"new api\"?";
  4662.             ["content"] = "Well if you follow the App Store's Development you will know that I stopped updating a month ago (or more), and this was to stop and re-develop the Store System, making it easier to use and to contain a whole new set of functions I had learnt while being at my current place of work. The new API introduces tons of the new systems like IP Blocking, Account Blocking, Rate limiting, and spam protection.";
  4663.         };
  4664.         {
  4665.             ["name"] = "How can I get involved?";
  4666.             ["content"] = "Well if you are genuinely interested in getting involved and helping development with your own ideas and coding skills then you are very welcome, I would love to be able to get players to join in and help build this into something, as the way the system works is super simple and easy to work with. Even with coroutines being used and a simple manager, all coroutines have their own buffer and will be inserted into the task manager as soon as they are created. Then resuming them is all built into the API.";
  4667.         };
  4668.         {
  4669.             ["name"] = "App Store file size problems?";
  4670.             ["content"] = "I know that recently with all these fairly large updates the actual store's file is becoming larger and larger, I plan to create a web runner so instead, you run a wrapper, that will download and run the program at run time making it easier to work with so you don't have to worry about the size, this also means updates will be instant, instead of when you update.";
  4671.         };
  4672.     }
  4673.  
  4674.     if name:sub(1,7) == "content" then
  4675.         local scroll = 0
  4676.         conid = tonumber(name:sub(8))
  4677.         base.screen.colour("white")
  4678.         store.draw.menu("Help / FAQ")
  4679.  
  4680.         base.draw.box(1, 51, 19, 1, " ", "grey", "grey")
  4681.         base.draw.texta("Back", 2, 19, false, "lightBlue", "grey")
  4682.         base.draw.textr("Scroll enabled ", 19, false, "orange", "grey")
  4683.  
  4684.         pagecontent = base.data.wordwrap(tData[conid].content, 49)
  4685.  
  4686.         local function run(scroll)
  4687.             for i=1, 14 do
  4688.                 if #pagecontent >= i + scroll then
  4689.                     base.draw.box(1, 51, i+3, 1, " ", "white", "white")
  4690.                     base.draw.textl(pagecontent[i+scroll], i+3, false, "cyan", "white")
  4691.                 else
  4692.                     break
  4693.                 end
  4694.             end
  4695.         end
  4696.  
  4697.         run(scroll)
  4698.  
  4699.         while true do
  4700.             local args = { os.pullEvent() }
  4701.             if args[1] == "timer" then
  4702.                 store.draw.menu("Help / FAQ")
  4703.             elseif args[1] == "mouse_click" then
  4704.                 if args[4] >= 1 and args[4] <= 2 then
  4705.                     store.draw.menu_input("Help / FAQ", args[3], args[4])
  4706.                 elseif (args[3] >= 2 and args[3] <= 5) and args[4] == 19 then
  4707.                     store.help("menu")
  4708.                 end
  4709.             elseif args[1] == "mouse_scroll" then
  4710.                 if args[2] == -1 then
  4711.                     if scroll > 0 then
  4712.                         scroll = scroll - 1
  4713.                         run(scroll)
  4714.                     end
  4715.                 elseif args[2] == 1 then
  4716.                     if scroll + 14 < #pagecontent then
  4717.                         scroll = scroll + 1
  4718.                         run(scroll)
  4719.                     end
  4720.                 end
  4721.             end
  4722.         end
  4723.     else
  4724.         local scroll = 0
  4725.         base.screen.colour("white")
  4726.         store.draw.menu("Help / FAQ")
  4727.  
  4728.         base.draw.box(1, 51, 19, 1, " ", "grey", "grey")
  4729.         base.draw.textc("Help Topics: "..tostring(#tData), 19, false, "lightBlue", "grey")
  4730.  
  4731.         local function fix(num)
  4732.             if tostring(num):len() == 1 then
  4733.                 return " "..tostring(num)
  4734.             else
  4735.                 return tostring(num)
  4736.             end
  4737.         end
  4738.  
  4739.         local function run(scroll)
  4740.             for i=1, 14 do
  4741.                 if #tData >= i + scroll then
  4742.                     base.draw.box(1, 51, i+3, 1, " ", "white", "white")
  4743.                     base.draw.texta(tostring(fix(i+scroll)) .. ": " .. tData[i+scroll].name,  1, i+3, false, "cyan", "white")
  4744.                 else
  4745.                     break
  4746.                 end
  4747.             end
  4748.         end
  4749.  
  4750.         run(scroll)
  4751.  
  4752.         while true do
  4753.             local args = { os.pullEvent() }
  4754.             if args[1] == "timer" then
  4755.                 store.draw.menu("Help / FAQ")
  4756.             elseif args[1] == "mouse_click" then
  4757.                 if args[4] >= 1 and args[4] <= 2 then
  4758.                     store.draw.menu_input("Help / FAQ", args[3], args[4])
  4759.                 elseif (args[3] >= 1 and args[3] <= 51) and (args[4] >= 4 and args[4] <= 19) then
  4760.                     -- Get current option
  4761.                     local curid = args[4] - 3 + scroll
  4762.                     if curid <= #tData then
  4763.                         store.help("content"..tostring(curid))
  4764.                     end
  4765.                 end
  4766.             elseif args[1] == "mouse_scroll" then
  4767.                 if args[2] == -1 then
  4768.                     if scroll > 0 then
  4769.                         scroll = scroll - 1
  4770.                         run(scroll)
  4771.                     end
  4772.                 elseif args[2] == 1 then
  4773.                     if scroll + 14 < #tData then
  4774.                         scroll = scroll + 1
  4775.                         run(scroll)
  4776.                     end
  4777.                 end
  4778.             end
  4779.         end
  4780.     end
  4781. end
  4782.  
  4783. function store.updates(name)
  4784.     tData = {
  4785.         {
  4786.             ["name"] = "Update: 6.0.1 (Beta)";
  4787.             ["content"] = "The newest version of the App Store comes with some new surprises! We have a new Social Network category, which allows you to in turn adds a little more to the store. You have two new categories. Mailbox and News Feed. Mailbox is a functional mail client allowing you to send mail to other users and even offers you to send files to and from. If you want to send more than one file then please use Creator's Compress program to compress all the files into one file then use that file to send to another user. I am working on a live chat system currently allowing you to do even more, this will come in the next version I hope, I have also added an issue reporter, so when you have an error in your program you can actually send issues to me directly where I can work on them and fix them. The feed is actually a simple news feed where you can post updates and even just general chat. Hopefully when the chat comes you will have a live chat you can interact with.";
  4788.         };
  4789.         {
  4790.             ["name"] = "Update: 5.9.8 (Beta)";
  4791.             ["content"] = "Added Beta versions of the Discover Social code, including the Mailbox, Live Chat and the News Feed options. Mailbox is completed so far I am just working on the news feed next and then the live chat as the live chat may be a problem.";
  4792.         };
  4793.         {
  4794.             ["name"] = "Update: 5.8.1 (Release)";
  4795.             ["content"] = "Added bug reporting when a crash occurs, it will offer to send the information of the bug to the server for you which then goes to my issue manager. Fixed bug from the edit app page where it was not sending the right data to the discover object.";
  4796.         };
  4797.         {
  4798.             ["name"] = "Update: 5.7.2 (Release)";
  4799.             ["content"] = "Fixed the delete function, which crashed because of an invalid return from the server, also added a test version of the finder,to access this use the 'f' key on the home menu.";
  4800.         };
  4801.         {
  4802.             ["name"] = "Update: 5.6.1 (Release)";
  4803.             ["content"] = "Added new loading screen and changed a few bits and bobs on the settings page as well as some new amends for the backend.";
  4804.         };
  4805.         {
  4806.             ["name"] = "Update: 5.5.2 (Release)";
  4807.             ["content"] = "Added new update logs, converted the API for the store to a newer one called Base, due to it running an old API roughly 2 years out of date.";
  4808.         };
  4809.         {
  4810.             ["name"] = "Update: 5.4.8 (Release)";
  4811.             ["content"] = "Added limitRead functions to contain the read function, added some new updates to the backend and added the DiscoverX link in the Menu for when it is released to test it out.";
  4812.         };
  4813.         {
  4814.             ["name"] = "Update: 5.3.5 (Release)";
  4815.             ["content"] = "Added the ability to Upload from pastebin by simply providing a pastebin ID (click toggle on the file path) when uploading, Fixed the exit function, had to amend the coroutine manager (Wasn't exiting/removing threads correctly), added DiscoverX feature menu item.";
  4816.         };
  4817.         {
  4818.             ["name"] = "Update: 5.2.1 (Release)";
  4819.             ["content"] = "Account modification updates, allowing you to update your email and password using a generated key sent to the currently registered email, to help keep accounts secure. Updated the credits section for all the helpers as well as a few words from me. Added new updates for allowing you to update/edit from the \"View my Apps\" screen instead, allowing you to set the ID from there. You can also now update an app using a pastebin ID as well.";
  4820.         };
  4821.         {
  4822.             ["name"] = "Update: 5.1.3 (Beta)";
  4823.             ["content"] = "Multiple fixes to the Discover Cloud Network, and added the ability to rename a file, when you click on a file in the files viewer. Added some additions wrapping text so it stays inside the boxes, thanks to Cranium for this code back in 2012 ;).";
  4824.         };
  4825.         {
  4826.             ["name"] = "Update: 5.0.1 (Alpha)";
  4827.             ["content"] = "Added DiscoverCloud, Allowing you to upload, download and delete files from a remote server, allowing you to have programs anywhere on any computer! Please see \"Help / FAQ\" for more information about how to use the Cloud and what it can do!";
  4828.         };
  4829.         {
  4830.             ["name"] = "Update: 4.9.8 (Release)";
  4831.             ["content"] = "Added a new search screen to search for finding apps!";
  4832.         };
  4833.         {
  4834.             ["name"] = "Update: 4.8.9 (Release)";
  4835.             ["content"] = "Added multiple bug fixes!";
  4836.         };
  4837.         {
  4838.             ["name"] = "Update: 4.8.2 (Beta)";
  4839.             ["content"] = "Added the notifications system, which was requested by LDDestroier, which when someone comments on your app, then a notification is created for you to view on the little \"N\" in the menubar at the top, or just go to \"My Profile -> Notifications\" and you can see them all there, this will allow you to view them in depth. Made an update for the statistics page as well.";
  4840.         };
  4841.         {
  4842.             ["name"] = "Update: 4.7.0 (Release)";
  4843.             ["content"] = "Added 2 new console commands 'search' and 'view' which can either search for an app or view an apps meta data.";
  4844.         };
  4845.         {
  4846.             ["name"] = "Update: 4.6.3 (Release)";
  4847.             ["content"] = "Added a fix for the comments issue, as the validation for auth keys was not working correctly, added some command line functions like 'install' and 'view'.";
  4848.         };
  4849.         {
  4850.             ["name"] = "Update: 4.5.1 (Beta)";
  4851.             ["content"] = "Added the latest discover cloud options so you can now use the cloud as a FTP type service. Allowing you to upload files to and from the server. Then you can access the files on the web at: http://syncc.dannysmc.com/ the Discover Cloud is the backend part of SynCC, and of course added an exit button.";
  4852.         };
  4853.         {
  4854.             ["name"] = "Update: 4.3.2 (Beta)";
  4855.             ["content"] = "Added some test code for the Snippets which act like gists I guess for Git, that you can upload bits of code, the character limit is locked at 100,000 characters, as otherwise anymore than that does not really count as a snippet of code. Snippets can have most of the same meta data, other than it uses a new storing method.";
  4856.         };
  4857.         {
  4858.             ["name"] = "Update: 4.2.8 (Beta)";
  4859.             ["content"] = "Added some changes to the Apps listing to have the categories, versions and all listings all connected, making some room for some more ideas I have for the App Store.";
  4860.         };
  4861.         {
  4862.             ["name"] = "Update: 4.2.1 (Release)";
  4863.             ["content"] = "After moving web servers I added some more bug fixes to allow the application to gain access to my web server again, as I had a lot of changes that had to be performed.";
  4864.         };
  4865.         {
  4866.             ["name"] = "Update: 4.1.4 (Beta)";
  4867.             ["content"] = "Fixed a few bugs, like Help / FAQ and Updates screens where there was problems with clickable regions. Fixed the inability to scroll up on certain emulators on the Versions and Categories screens, not sure why, just coded it a little more bullet proof. Added up new account screens, removed user settings because it was a waste of a button.";
  4868.         };
  4869.         {
  4870.             ["name"] = "Update: 4.1.1 (Beta)";
  4871.             ["content"] = "Currently the recent release, this is where everything was coded and functioning this is for all of the great store users to be able to test the Store, and tell me what they think, and give useful feedback, in the settings menu you can actually submit bugs, and review what you think of the Discover Store, and the new name. Also do you like the new API, this was built with security and ease in one.";
  4872.         };
  4873.         {
  4874.             ["name"] = "Update: 4.0.1 (Alpha)";
  4875.             ["content"] = "This update was the very first version of the new re-coded store App, this had all the correct versions of the new DiscoverAPI. This was coded without multitasking, but with the new system and the way the Store would function I felt it would be better to incorporate the new Thread System. The new threads manager harnesses ComputerCraft's alternative to multitasking allowing multiple threads, with little or no problem, and the new task manager I added to be able to flick through tasks with ease.";
  4876.         };
  4877.     }
  4878.  
  4879.     if name:sub(1,7) == "content" then
  4880.         local scroll = 0
  4881.         conid = tonumber(name:sub(8))
  4882.         base.screen.colour("white")
  4883.         store.draw.menu("Updates Log")
  4884.  
  4885.         base.draw.box(1, 51, 19, 1, " ", "grey", "grey")
  4886.         base.draw.texta("Back", 2, 19, false, "lightBlue", "grey")
  4887.         base.draw.textr("Scroll enabled ", 19, false, "orange", "grey")
  4888.  
  4889.         pagecontent = base.data.wordwrap(tData[conid].content, 49)
  4890.  
  4891.         local function run(scroll)
  4892.             for i=1, 14 do
  4893.                 if #pagecontent >= i + scroll then
  4894.                     base.draw.box(1, 51, i+3, 1, " ", "white", "white")
  4895.                     base.draw.textl(pagecontent[i+scroll], i+3, false, "cyan", "white")
  4896.                 else
  4897.                     break
  4898.                 end
  4899.             end
  4900.         end
  4901.  
  4902.         run(scroll)
  4903.  
  4904.         while true do
  4905.             local args = { os.pullEvent() }
  4906.             if args[1] == "timer" then
  4907.                 store.draw.menu("Updates Log")
  4908.             elseif args[1] == "mouse_click" then
  4909.                 if args[4] >= 1 and args[4] <= 2 then
  4910.                     store.draw.menu_input("Updates Log", args[3], args[4])
  4911.                 elseif (args[3] >= 2 and args[3] <= 5) and args[4] == 19 then
  4912.                     store.updates("menu")
  4913.                 end
  4914.             elseif args[1] == "mouse_scroll" then
  4915.                 if args[2] == -1 then
  4916.                     if scroll > 0 then
  4917.                         scroll = scroll - 1
  4918.                         run(scroll)
  4919.                     end
  4920.                 elseif args[2] == 1 then
  4921.                     if scroll + 14 < #pagecontent then
  4922.                         scroll = scroll + 1
  4923.                         run(scroll)
  4924.                     end
  4925.                 end
  4926.             end
  4927.         end
  4928.     else
  4929.         local scroll = 0
  4930.         base.screen.colour("white")
  4931.         store.draw.menu("Updates Log")
  4932.  
  4933.         base.draw.box(1, 51, 19, 1, " ", "grey", "grey")
  4934.         base.draw.textc("Update Logs: "..tostring(#tData), 19, false, "lightBlue", "grey")
  4935.  
  4936.         local function fix(num)
  4937.             if tostring(num):len() == 1 then
  4938.                 return " "..tostring(num)
  4939.             else
  4940.                 return tostring(num)
  4941.             end
  4942.         end
  4943.  
  4944.         local function run(scroll)
  4945.             for i=1, 14 do
  4946.                 if #tData >= i + scroll then
  4947.                     base.draw.box(1, 51, i+3, 1, " ", "white", "white")
  4948.                     base.draw.texta(tostring(fix(i+scroll)) .. ": " .. tData[i+scroll].name,  1, i+3, false, "cyan", "white")
  4949.                 else
  4950.                     break
  4951.                 end
  4952.             end
  4953.         end
  4954.  
  4955.         run(scroll)
  4956.  
  4957.         while true do
  4958.             local args = { os.pullEvent() }
  4959.             if args[1] == "timer" then
  4960.                 store.draw.menu("Updates Log")
  4961.             elseif args[1] == "mouse_click" then
  4962.                 if args[4] >= 1 and args[4] <= 2 then
  4963.                     store.draw.menu_input("Help / FAQ", args[3], args[4])
  4964.                 elseif (args[3] >= 1 and args[3] <= 51) and (args[4] >= 4 and args[4] <= 19) then
  4965.                     -- Get current option
  4966.                     local curid = args[4] - 3 + scroll
  4967.                     if curid <= #tData then
  4968.                         store.updates("content"..tostring(curid))
  4969.                     end
  4970.                 end
  4971.             elseif args[1] == "mouse_scroll" then
  4972.                 if args[2] == -1 then
  4973.                     if scroll > 0 then
  4974.                         scroll = scroll - 1
  4975.                         run(scroll)
  4976.                     end
  4977.                 elseif args[2] == 1 then
  4978.                     if scroll + 14 < #tData then
  4979.                         scroll = scroll + 1
  4980.                         run(scroll)
  4981.                     end
  4982.                 end
  4983.             end
  4984.         end
  4985.     end
  4986. end
  4987.  
  4988. function store.credits()
  4989.     base.screen.colour("white")
  4990.     store.draw.menu("Credits")
  4991.     local text = "Thank you! Thank you for keeping the App Store alive, through tons of updates, Creator thanks for all the constant ideas and bug fixes, Cranium (even though he does not know it) for some great code snippets, and ByteMe for UI ideas. The reason I have kept going is because you're always helping me out, and it is great to see, I hope that it becomes more popular and gets many more apps now that I have added all the new features. - DannySMc"
  4992.     for k,v in ipairs(base.data.wordwrap(text, 51)) do
  4993.         base.draw.textl(v, k+3, false, "grey", "white")
  4994.     end
  4995.  
  4996.     base.draw.box(1, 51, 19, 1, " ", "grey" , "grey")
  4997.     base.draw.textc("Press the \"X\" in the taskbar to close", 19, false, "orange", "grey")
  4998.  
  4999.     while true do
  5000.         local args = { os.pullEvent() }
  5001.         if args[1] == "timer" then
  5002.             store.draw.menu("Credits")
  5003.         elseif args[1] == "mouse_click" then
  5004.             if args[4] >= 1 and args[4] <= 2 then
  5005.                 store.draw.menu_input("Home", args[3], args[4])
  5006.             end
  5007.         end
  5008.     end
  5009. end
  5010.  
  5011. function store.command(func, var_a, var_b)
  5012.     if func == "install" then
  5013.         if var_a and var_b then
  5014.             write("Installing app, please wait... ")
  5015.             local query = "cmd=shell_install&index="..textutils.urlEncode(tostring(var_a))
  5016.             local req = http.post(discover.data.urls.store, query)
  5017.             if req then
  5018.                 req = req.readAll()
  5019.                 local f = fs.open(var_b, "w")
  5020.                 f.write(req)
  5021.                 f.close()
  5022.                 print("Success")
  5023.             else
  5024.                 printError("There was an error while fetching your file: "..tostring(req.readAll()))
  5025.             end
  5026.         else
  5027.             if not var_a then
  5028.                 printError("Please specify an index code")
  5029.             elseif not var_b then
  5030.                 printError("Please specify a file name")
  5031.             end
  5032.         end
  5033.     elseif func == "list" then
  5034.         local query = "cmd=list_apps"
  5035.         local req = http.post(discover.data.urls.store, query)
  5036.         req = textutils.unserialize(req.readAll())
  5037.         if req.status then
  5038.             local count = 0
  5039.             print("Press any key to view next, press \"c\" to exit")
  5040.             repeat
  5041.                 count = count + 1
  5042.                 print(req.data[count].name .. " - (" .. req.data[count].index .. ")")
  5043.                 local ev, k = os.pullEvent("key")
  5044.                 if k == 46 then
  5045.                     break
  5046.                 end
  5047.             until count == #req.data
  5048.         else
  5049.             printError("[ERROR]: "..tostring(req.error))
  5050.         end
  5051.     elseif func == "search" then
  5052.         if var_a then
  5053.             write("Downloading... ")
  5054.             local query = "cmd=list_apps"
  5055.             local req = http.post(discover.data.urls.store, query)
  5056.             print("[OK]")
  5057.             write("Reading... ")
  5058.             req = textutils.unserialize(req.readAll())
  5059.             print("[OK]")
  5060.             write("Searching... ")
  5061.             local results = {}
  5062.             for k,v in ipairs(req.data) do
  5063.                 if v.name:lower():find(var_a) then
  5064.                     table.insert(results, v.name.." - ("..v.index..")")
  5065.                 end
  5066.             end
  5067.             print("[OK]")
  5068.             print("Found " .. #results .. " result(s)")
  5069.             local count = 0
  5070.             print("Press any key to view next, press \"c\" to exit")
  5071.             repeat
  5072.                 count = count + 1
  5073.                 print(results[count])
  5074.                 local ev, k = os.pullEvent("key")
  5075.                 if k == 46 then
  5076.                     break
  5077.                 end
  5078.             until count == #results
  5079.         else
  5080.             printError("Please supply a search term")
  5081.         end
  5082.     elseif func == "view" then
  5083.         if var_a then
  5084.             local query = "cmd=list_apps"
  5085.             local req = http.post(discover.data.urls.store, query)
  5086.             req = textutils.unserialize(req.readAll())
  5087.             if req.status then
  5088.                 for _,v in ipairs(req.data) do
  5089.                     if v.index == var_a then
  5090.                         viewapp = v
  5091.                         break
  5092.                     end
  5093.                 end
  5094.                 if viewapp then
  5095.                     for k,v in pairs(viewapp) do
  5096.                         print(tostring(k)..": "..tostring(v))
  5097.                     end
  5098.                 else
  5099.                     printError("Could not find that app")
  5100.                 end
  5101.             else
  5102.                 printError("There was a server side error, please try again later")
  5103.             end
  5104.         else
  5105.             printError("Please supply an index code")
  5106.         end
  5107.     else
  5108.         printError("Please use help for functions list")
  5109.     end
  5110. end
  5111.  
  5112. -- Run Discover Init
  5113. if #tArgs > 0 then
  5114.     if http and term.isColour() then
  5115.         store.command(unpack(tArgs))
  5116.     else
  5117.         printError("Please make sure HTTP is enabled and you are using an advanced computer (gold)")
  5118.     end
  5119. else
  5120.     if downloadapi then
  5121.         store.init()
  5122.     else
  5123.         print("Discover Crashed")
  5124.         sleep(2)
  5125.         shell.run("shell")
  5126.     end
  5127. end
Add Comment
Please, Sign In to add comment