Advertisement
Vortex23

SaveManager

Aug 13th, 2024 (edited)
15,002
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 11.25 KB | None | 0 0
  1. local cloneref = cloneref or function(o) return o end
  2. local httpService = cloneref(game:GetService('HttpService'))
  3.  
  4. if copyfunction and isfolder then -- fix for mobile executors :/
  5.     local isfolder_, isfile_, listfiles_ = copyfunction(isfolder), copyfunction(isfile), copyfunction(listfiles);
  6.     local success_, error_ = pcall(function() return isfolder_(tostring(math.random(999999999, 999999999999))) end);
  7.  
  8.     if success_ == false or (tostring(error_):match("not") and tostring(error_):match("found")) then
  9.         getgenv().isfolder = function(folder)
  10.             local s, data = pcall(function() return isfolder_(folder) end)
  11.             if s == false then return nil end
  12.             return data
  13.         end
  14.    
  15.         getgenv().isfile = function(file)
  16.             local s, data = pcall(function() return isfile_(file) end)
  17.             if s == false then return nil end
  18.             return data
  19.         end
  20.    
  21.         getgenv().listfiles = function(folder)
  22.             local s, data = pcall(function() return listfiles_(folder) end)
  23.             if s == false then return {} end
  24.             return data
  25.         end
  26.     end
  27. end
  28.  
  29. local SaveManager = {} do
  30.     SaveManager.Folder = 'LinoriaLibSettings'
  31.     SaveManager.Ignore = {}
  32.     SaveManager.Parser = {
  33.         Toggle = {
  34.             Save = function(idx, object)
  35.                 return { type = 'Toggle', idx = idx, value = object.Value }
  36.             end,
  37.             Load = function(idx, data)
  38.                 if getgenv().Linoria.Toggles[idx] then
  39.                     getgenv().Linoria.Toggles[idx]:SetValue(data.value)
  40.                 end
  41.             end,
  42.         },
  43.         Slider = {
  44.             Save = function(idx, object)
  45.                 return { type = 'Slider', idx = idx, value = tostring(object.Value) }
  46.             end,
  47.             Load = function(idx, data)
  48.                 if getgenv().Linoria.Options[idx] then
  49.                     getgenv().Linoria.Options[idx]:SetValue(data.value)
  50.                 end
  51.             end,
  52.         },
  53.         Dropdown = {
  54.             Save = function(idx, object)
  55.                 return { type = 'Dropdown', idx = idx, value = object.Value, mutli = object.Multi }
  56.             end,
  57.             Load = function(idx, data)
  58.                 if getgenv().Linoria.Options[idx] then
  59.                     getgenv().Linoria.Options[idx]:SetValue(data.value)
  60.                 end
  61.             end,
  62.         },
  63.         ColorPicker = {
  64.             Save = function(idx, object)
  65.                 return { type = 'ColorPicker', idx = idx, value = object.Value:ToHex(), transparency = object.Transparency }
  66.             end,
  67.             Load = function(idx, data)
  68.                 if getgenv().Linoria.Options[idx] then
  69.                     getgenv().Linoria.Options[idx]:SetValueRGB(Color3.fromHex(data.value), data.transparency)
  70.                 end
  71.             end,
  72.         },
  73.         KeyPicker = {
  74.             Save = function(idx, object)
  75.                 return { type = 'KeyPicker', idx = idx, mode = object.Mode, key = object.Value }
  76.             end,
  77.             Load = function(idx, data)
  78.                 if getgenv().Linoria.Options[idx] then
  79.                     getgenv().Linoria.Options[idx]:SetValue({ data.key, data.mode })
  80.                 end
  81.             end,
  82.         },
  83.  
  84.         Input = {
  85.             Save = function(idx, object)
  86.                 return { type = 'Input', idx = idx, text = object.Value }
  87.             end,
  88.             Load = function(idx, data)
  89.                 if getgenv().Linoria.Options[idx] and type(data.text) == 'string' then
  90.                     getgenv().Linoria.Options[idx]:SetValue(data.text)
  91.                 end
  92.             end,
  93.         },
  94.     }
  95.  
  96.     function SaveManager:CheckFolderTree()
  97.         pcall(function()
  98.             if not isfolder(self.Folder) then -- who tought that isfolder should error when the folder is not found 😭
  99.                 SaveManager:BuildFolderTree()
  100.                 task.wait()
  101.             end
  102.         end)
  103.     end
  104.    
  105.     function SaveManager:SetIgnoreIndexes(list)
  106.         for _, key in next, list do
  107.             self.Ignore[key] = true
  108.         end
  109.     end
  110.  
  111.     function SaveManager:SetFolder(folder)
  112.         self.Folder = folder;
  113.         self:BuildFolderTree()
  114.     end
  115.  
  116.     function SaveManager:Save(name)
  117.         if (not name) then
  118.             return false, 'no config file is selected'
  119.         end
  120.         SaveManager:CheckFolderTree()
  121.        
  122.         local fullPath = self.Folder .. '/settings/' .. name .. '.json'
  123.         local data = {
  124.             objects = {}
  125.         }
  126.  
  127.         for idx, toggle in next, getgenv().Linoria.Toggles do
  128.             if self.Ignore[idx] then continue end
  129.  
  130.             table.insert(data.objects, self.Parser[toggle.Type].Save(idx, toggle))
  131.         end
  132.  
  133.         for idx, option in next, getgenv().Linoria.Options do
  134.             if not self.Parser[option.Type] then continue end
  135.             if self.Ignore[idx] then continue end
  136.  
  137.             table.insert(data.objects, self.Parser[option.Type].Save(idx, option))
  138.         end
  139.  
  140.         local success, encoded = pcall(httpService.JSONEncode, httpService, data)
  141.         if not success then
  142.             return false, 'failed to encode data'
  143.         end
  144.  
  145.         writefile(fullPath, encoded)
  146.         return true
  147.     end
  148.  
  149.     function SaveManager:Load(name)
  150.         if (not name) then
  151.             return false, 'no config file is selected'
  152.         end
  153.         SaveManager:CheckFolderTree()
  154.        
  155.         local file = self.Folder .. '/settings/' .. name .. '.json'
  156.         if not isfile(file) then return false, 'invalid file' end
  157.  
  158.         local success, decoded = pcall(httpService.JSONDecode, httpService, readfile(file))
  159.         if not success then return false, 'decode error' end
  160.  
  161.         for _, option in next, decoded.objects do
  162.             if self.Parser[option.type] then
  163.                 task.spawn(function() self.Parser[option.type].Load(option.idx, option) end) -- task.spawn() so the config loading wont get stuck.
  164.             end
  165.         end
  166.  
  167.         return true
  168.     end
  169.  
  170.     function SaveManager:Delete(name)
  171.         if (not name) then
  172.             return false, 'no config file is selected'
  173.         end
  174.        
  175.         local file = self.Folder .. '/settings/' .. name .. '.json'
  176.         if not isfile(file) then return false, 'invalid file' end
  177.  
  178.         local success, decoded = pcall(delfile, file)
  179.         if not success then return false, 'delete file error' end
  180.        
  181.         return true
  182.     end
  183.  
  184.     function SaveManager:IgnoreThemeSettings()
  185.         self:SetIgnoreIndexes({
  186.             "BackgroundColor", "MainColor", "AccentColor", "OutlineColor", "FontColor", -- themes
  187.             "ThemeManager_ThemeList", 'ThemeManager_CustomThemeList', 'ThemeManager_CustomThemeName', -- themes
  188.             "VideoLink",
  189.         })
  190.     end
  191.  
  192.     function SaveManager:BuildFolderTree()
  193.         local paths = {
  194.             self.Folder,
  195.             self.Folder .. '/themes',
  196.             self.Folder .. '/settings'
  197.         }
  198.  
  199.         for i = 1, #paths do
  200.             local str = paths[i]
  201.             if not isfolder(str) then
  202.                 makefolder(str)
  203.             end
  204.         end
  205.     end
  206.  
  207.     function SaveManager:RefreshConfigList()
  208.         SaveManager:CheckFolderTree()
  209.         local list = listfiles(self.Folder .. '/settings')
  210.  
  211.         local out = {}
  212.         for i = 1, #list do
  213.             local file = list[i]
  214.             if file:sub(-5) == '.json' then
  215.                 -- i hate this but it has to be done ...
  216.  
  217.                 local pos = file:find('.json', 1, true)
  218.                 local start = pos
  219.  
  220.                 local char = file:sub(pos, pos)
  221.                 while char ~= '/' and char ~= '\\' and char ~= '' do
  222.                     pos = pos - 1
  223.                     char = file:sub(pos, pos)
  224.                 end
  225.  
  226.                 if char == '/' or char == '\\' then
  227.                     table.insert(out, file:sub(pos + 1, start - 1))
  228.                 end
  229.             end
  230.         end
  231.        
  232.         return out
  233.     end
  234.  
  235.     function SaveManager:SetLibrary(library)
  236.         self.Library = library
  237.     end
  238.  
  239.     function SaveManager:LoadAutoloadConfig()
  240.         SaveManager:CheckFolderTree()
  241.        
  242.         if isfile(self.Folder .. '/settings/autoload.txt') then
  243.             local name = readfile(self.Folder .. '/settings/autoload.txt')
  244.  
  245.             local success, err = self:Load(name)
  246.             if not success then
  247.                 return self.Library:Notify('Failed to load autoload config: ' .. err)
  248.             end
  249.  
  250.             self.Library:Notify(string.format('Auto loaded config %q', name))
  251.         end
  252.     end
  253.  
  254.  
  255.     function SaveManager:BuildConfigSection(tab)
  256.         assert(self.Library, 'Must set SaveManager.Library')
  257.  
  258.         local section = tab:AddRightGroupbox('Configuration')
  259.  
  260.         section:AddInput('SaveManager_ConfigName',    { Text = 'Config name' })
  261.         section:AddButton('Create config', function()
  262.             local name = getgenv().Linoria.Options.SaveManager_ConfigName.Value
  263.  
  264.             if name:gsub(' ', '') == '' then
  265.                 return self.Library:Notify('Invalid config name (empty)', 2)
  266.             end
  267.  
  268.             local success, err = self:Save(name)
  269.             if not success then
  270.                 return self.Library:Notify('Failed to create config: ' .. err)
  271.             end
  272.  
  273.             self.Library:Notify(string.format('Created config %q', name))
  274.  
  275.             getgenv().Linoria.Options.SaveManager_ConfigList:SetValues(self:RefreshConfigList())
  276.             getgenv().Linoria.Options.SaveManager_ConfigList:SetValue(nil)
  277.         end)
  278.  
  279.         section:AddDivider()
  280.  
  281.         section:AddDropdown('SaveManager_ConfigList', { Text = 'Config list', Values = self:RefreshConfigList(), AllowNull = true })
  282.         section:AddButton('Load config', function()
  283.             local name = getgenv().Linoria.Options.SaveManager_ConfigList.Value
  284.  
  285.             local success, err = self:Load(name)
  286.             if not success then
  287.                 return self.Library:Notify('Failed to load config: ' .. err)
  288.             end
  289.  
  290.             self.Library:Notify(string.format('Loaded config %q', name))
  291.         end)
  292.         section:AddButton('Overwrite config', function()
  293.             local name = getgenv().Linoria.Options.SaveManager_ConfigList.Value
  294.  
  295.             local success, err = self:Save(name)
  296.             if not success then
  297.                 return self.Library:Notify('Failed to overwrite config: ' .. err)
  298.             end
  299.  
  300.             self.Library:Notify(string.format('Overwrote config %q', name))
  301.         end)
  302.        
  303.         getgenv().AutoOverwrite = false
  304.  
  305.         section:AddToggle('__AutoStoreFruit', {
  306.             Default = false,
  307.             Text = 'Auto Overwrite config',
  308.             Tooltip = 'auto overwrite config every 2s',
  309.             Callback = function(s)
  310.                 getgenv().AutoOverwrite = s
  311.             end
  312.         })
  313.  
  314.         spawn(function()
  315.           while task.wait(2) do
  316.             if getgenv().AutoOverwrite then
  317.                 pcall(function()
  318.                     local name = getgenv().Linoria.Options.SaveManager_ConfigList.Value
  319.  
  320.                     local success, err = self:Save(name)
  321.                         if not success then
  322.                             return self.Library:Notify('Failed to overwrite config: ' .. err)
  323.                         end
  324.  
  325.                         self.Library:Notify(string.format('Overwrote config %q', name))
  326.                     end)
  327.                 end
  328.             end
  329.         end)
  330.        
  331.         section:AddButton('Delete config', function()
  332.             local name = getgenv().Linoria.Options.SaveManager_ConfigList.Value
  333.  
  334.             local success, err = self:Delete(name)
  335.             if not success then
  336.                 return self.Library:Notify('Failed to delete config: ' .. err)
  337.             end
  338.  
  339.             self.Library:Notify(string.format('Deleted config %q', name))
  340.             getgenv().Linoria.Options.SaveManager_ConfigList:SetValues(self:RefreshConfigList())
  341.             getgenv().Linoria.Options.SaveManager_ConfigList:SetValue(nil)
  342.         end)
  343.  
  344.         section:AddButton('Refresh list', function()
  345.             getgenv().Linoria.Options.SaveManager_ConfigList:SetValues(self:RefreshConfigList())
  346.             getgenv().Linoria.Options.SaveManager_ConfigList:SetValue(nil)
  347.         end)
  348.  
  349.         section:AddButton('Set as autoload', function()
  350.             local name = getgenv().Linoria.Options.SaveManager_ConfigList.Value
  351.             writefile(self.Folder .. '/settings/autoload.txt', name)
  352.             SaveManager.AutoloadLabel:SetText('Current autoload config: ' .. name)
  353.             self.Library:Notify(string.format('Set %q to auto load', name))
  354.         end)
  355.         section:AddButton('Reset autoload', function()
  356.             local success = pcall(delfile, self.Folder .. '/settings/autoload.txt')
  357.             if not success then
  358.                 return self.Library:Notify('Failed to reset autoload: delete file error')
  359.             end
  360.                
  361.             self.Library:Notify('Set autoload to none')
  362.             SaveManager.AutoloadLabel:SetText('Current autoload config: none')
  363.         end)
  364.  
  365.         SaveManager.AutoloadLabel = section:AddLabel('Current autoload config: none', true)
  366.  
  367.         if isfile(self.Folder .. '/settings/autoload.txt') then
  368.             local name = readfile(self.Folder .. '/settings/autoload.txt')
  369.             SaveManager.AutoloadLabel:SetText('Current autoload config: ' .. name)
  370.         end
  371.  
  372.         SaveManager:SetIgnoreIndexes({ 'SaveManager_ConfigList', 'SaveManager_ConfigName' })
  373.     end
  374.  
  375.     SaveManager:BuildFolderTree()
  376. end
  377.  
  378. return SaveManager
  379.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement