Advertisement
IAmKingMatt

BallOut Datastore Module

May 21st, 2022
1,115
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. --[[
  2.     --[ Datastore Service ]--
  3.     [+] Manages data for the servers!
  4. --]]
  5. --// Services
  6. local playerService = game:GetService("Players")
  7. local serverStorage = game:GetService("ServerStorage")
  8. local replicatedStorage = game:GetService("ReplicatedStorage")
  9. local dataStoreService = game:GetService("DataStoreService")
  10. local marketplace = game:GetService("MarketplaceService")
  11. local messageService = game:GetService("MessagingService")
  12. local chatService = require(game.ServerScriptService:WaitForChild("ChatServiceRunner").ChatService)
  13. local teleportService = game:GetService("TeleportService")
  14. local httpService = game:GetService("HttpService")
  15.  
  16. --// Modules
  17. local modules = serverStorage:WaitForChild("Modules")
  18. local valmod = require(modules.CoreModules.ValueModule)
  19. local items = require(modules.Services.MarketService.ItemStorage)
  20.  
  21. --// Storages
  22. local playerdatastore = dataStoreService:GetDataStore("BallOutPlayerData v.0.0.17")
  23. local admindatastore = dataStoreService:GetDataStore("BallOutAdminData v.0.0.02")
  24. local youtubedatastore = dataStoreService:GetDataStore("BallOutYoutube v.0.0.02")
  25. local bandatastore = dataStoreService:GetDataStore("BallOutBanData v.0.0.01")
  26.  
  27. --// Default
  28. local defalut = require(script.DataManager)
  29.  
  30. --// Data
  31. local adminData = admindatastore:GetAsync("Admins v.0.0.01")
  32. local youtubeData = youtubedatastore:GetAsync("YoutubeData v.0.0.01")
  33. local banData = bandatastore:GetAsync("Bans v.0.0.01")
  34.  
  35. --// Checking data stores!
  36. if not (adminData) then
  37.     admindatastore:SetAsync("Admins v.0.0.01", defalut.AdminData)
  38.     adminData = admindatastore:GetAsync("Admins v.0.0.01")
  39. end
  40.  
  41. if not (youtubeData) then
  42.     youtubedatastore:SetAsync("YoutubeData v.0.0.01", {})
  43.     youtubeData = youtubedatastore:GetAsync("YoutubeData v.0.0.01")
  44. end
  45.  
  46. if not (banData) then
  47.     bandatastore:SetAsync("Bans v.0.0.01", {})
  48.     banData = bandatastore:GetAsync("Bans v.0.0.01")
  49. end
  50.  
  51.  
  52. --[ CLIENT ]--
  53. local client = replicatedStorage:WaitForChild("Communication").Client
  54.  
  55. --// Game ID's
  56. local park = 4699691339
  57. local mobileOnlyPark = 5335220878
  58.  
  59. --// Keys
  60. local dataStoreKeys = {
  61.     ["AdminData"] = "Admins v.0.0.01",
  62.     ["BansData"] = "Bans v.0.0.01",
  63.     ["YoutubeData"] = "YoutubeData v.0.0.01",
  64. }
  65.  
  66. local dataTable = {
  67.     youtubeData = youtubeData,
  68.     adminData = adminData,
  69. }
  70.  
  71. local dataStores = {
  72.     ["PlayerData"] = playerdatastore,
  73.     ["AdminData"] = admindatastore,
  74.     ["BansData"] = bandatastore,
  75.     ["YoutubeData"] = youtubedatastore,
  76. }
  77.  
  78. local gamepasses = {
  79.     DoubleExp = 7111021,
  80.     QuadExp = 7111036,
  81.     NewDoubleExp = 10465070,
  82.     NewQuadExp = 10465075,
  83. }
  84.  
  85. --// Structures
  86. local values = {
  87.     string = "StringValue",
  88.     number = "NumberValue",
  89.     boolean = "BoolValue"
  90. }
  91.  
  92.  
  93. --// Load Player Values
  94. local function LoadValues(player)
  95.     local vals = Instance.new("Configuration", player)
  96.     vals.Name = "values"
  97.    
  98.     for VN, VV in pairs(defalut.Default.PlayerValues) do
  99.         local values = Instance.new(values[type(VV)], vals)
  100.         values.Value = VV
  101.         values.Name = VN
  102.     end
  103. end
  104.  
  105. --// Load Player Stats
  106. local function LoadStats(player, data)
  107.     local statsfolder = Instance.new("Configuration", player)
  108.     statsfolder.Name = "stats"
  109.    
  110.     --[ Build ]--
  111.     for statname, statvalue in pairs(data.stats) do
  112.         if (typeof(statvalue) ~= "table") then
  113.             local object = Instance.new(values[type(statvalue)], statsfolder)
  114.             object.Name = statname
  115.             object.Value = statvalue
  116.         end
  117.     end
  118.    
  119.     --// Check
  120.     if (game.PlaceId == park) then
  121.         local parkRecord = data.stats.park
  122.        
  123.         --// Load
  124.         for statname, statvalue in pairs(parkRecord) do
  125.             local object = Instance.new(values[type(statvalue)], statsfolder)
  126.             object.Name = statname
  127.             object.Value = statvalue
  128.         end
  129.     else
  130.         local recRecord = data.stats.rec
  131.        
  132.         --// Load
  133.         for statname, statvalue in pairs(recRecord) do
  134.             local object = Instance.new(values[type(statvalue)], statsfolder)
  135.             object.Name = statname
  136.             object.Value = statvalue
  137.         end
  138.     end
  139. end
  140.  
  141. local function GetBoost(player, stats)
  142.     --[ CHECK ]--
  143.     local doubleExp = marketplace:UserOwnsGamePassAsync(player.userId, gamepasses.DoubleExp)
  144.     local quadExp = marketplace:UserOwnsGamePassAsync(player.userId, gamepasses.QuadExp)
  145.     local newDoubleExp = marketplace:UserOwnsGamePassAsync(player.userId, gamepasses.NewDoubleExp)
  146.     local newQuadExp = marketplace:UserOwnsGamePassAsync(player.userId, gamepasses.NewQuadExp)
  147.     local boost = Instance.new("NumberValue", stats)
  148.     boost.Name = "boost"
  149.     boost.Value = 0
  150.    
  151.     if (doubleExp) or (newDoubleExp) then
  152.         boost.Value = boost.Value + 2
  153.     end
  154.    
  155.     if (quadExp) or (newQuadExp) then
  156.         boost.Value = boost.Value + 4
  157.     end
  158.    
  159.     --// Check Boost
  160.     if (boost.Value < 1) then
  161.         boost.Value = 1
  162.     end
  163. end
  164.  
  165. local function IsActive(COURT)
  166.     local _settings = COURT.Court.Settings
  167.    
  168.     --[ CHECK ]--
  169.     return _settings.active.Value
  170. end
  171.  
  172. local function GetCourt(courtName)
  173.     for _, obj in pairs(workspace:GetChildren()) do
  174.         if (obj:IsA("Model")) and (obj.Name == courtName) then
  175.             return obj
  176.         end
  177.     end
  178. end
  179.  
  180. local function LoadExtraValues(player, data)
  181.     local playerDataKey = tostring(player.userId)
  182.     local isAdmin = adminData[playerDataKey]
  183.     local isYoutuber = youtubeData[playerDataKey]
  184.     local isBanned = banData[playerDataKey]
  185.    
  186.     --// Check ban
  187.     if (isBanned) then
  188.         return player:Kick("You're banned!")
  189.     end
  190.    
  191.     --// Check Admin
  192.     if (isAdmin) then
  193.         local playerGui = player:WaitForChild("PlayerGui")
  194.         local character = player.Character
  195.         local youtubeAdderUi = serverStorage.ServerPlayerAssets.YoutuberAdder:Clone()
  196.         local banPanelUI = serverStorage.ServerPlayerAssets.BanPanel:Clone()
  197.         youtubeAdderUi.Parent = playerGui
  198.         banPanelUI.Parent = playerGui
  199.        
  200.         --// Check
  201.         if (character) then
  202.             local tag = character.Tag.Tag
  203.             tag.TextColor3 = Color3.fromRGB(255, 255, 60)
  204.         else
  205.             player.CharacterAdded:Connect(function(char)
  206.                 local tag = char.Tag.Tag
  207.                 tag.TextColor3 = Color3.fromRGB(255, 255, 60)
  208.             end)
  209.         end
  210.         coroutine.resume(coroutine.create(function()
  211.             local speaker = chatService:GetSpeaker(player.Name)
  212.        
  213.             --// Wait For Speaker
  214.             while not (speaker) do
  215.                 speaker = chatService:GetSpeaker(player.Name)
  216.                 wait(0.01)
  217.             end
  218.             if not (isYoutuber) then
  219.                 speaker:SetExtraData("Tags", {
  220.                     {
  221.                         TagText = "Owner",
  222.                         TagColor = Color3.fromRGB(255, 255, 60)
  223.                     }
  224.                 })
  225.             else
  226.                 speaker:SetExtraData("Tags", {
  227.                     {
  228.                         TagText = "Owner",
  229.                         TagColor = Color3.fromRGB(255, 255, 60)
  230.                     },
  231.                     {
  232.                         TagText = "Youtuber",
  233.                         TagColor = Color3.fromRGB(147, 0, 0)
  234.                     }
  235.                 })
  236.             end
  237.             speaker:SetExtraData("ChatColor", Color3.fromRGB(255, 255, 60))
  238.             speaker:SetExtraData("NameColor", BrickColor.new("Pastel yellow").Color)
  239.         end))
  240.     end
  241.    
  242.     --// Check Youtube
  243.     if (isYoutuber) then
  244.         if (isAdmin) then
  245.             local character = player.Character
  246.             local youtubeLogo = serverStorage.ServerPlayerAssets.YoutubeLogo:Clone()
  247.            
  248.             --// Check
  249.             if (character) then
  250.                 local tag = character.Tag.Tag
  251.                 youtubeLogo.Parent = tag
  252.             else
  253.                 player.CharacterAdded:Connect(function(char)
  254.                     local tag = char.Tag.Tag
  255.                     youtubeLogo.Parent = tag
  256.                 end)
  257.             end
  258.         else
  259.             local character = player.Character
  260.             local youtubeLogo = serverStorage.ServerPlayerAssets.YoutubeLogo:Clone()
  261.  
  262.             --// Check
  263.             if (character) then
  264.                 local tag = character.Tag.Tag
  265.                 tag.TextColor3 = Color3.fromRGB(147, 0, 0)
  266.                 youtubeLogo.Parent = tag
  267.             else
  268.                 player.CharacterAdded:Connect(function(char)
  269.                     local tag = char.Tag.Tag
  270.                     tag.TextColor3 = Color3.fromRGB(147, 0, 0)
  271.                     youtubeLogo.Parent = tag
  272.                 end)
  273.             end
  274.             coroutine.resume(coroutine.create(function()
  275.                 local speaker = chatService:GetSpeaker(player.Name)
  276.            
  277.                 --// Wait For Speaker
  278.                 while not (speaker) do
  279.                     speaker = chatService:GetSpeaker(player.Name)
  280.                     wait(0.01)
  281.                 end
  282.                 speaker:SetExtraData("Tags", {
  283.                     {
  284.                         TagText = "Youtuber",
  285.                         TagColor = Color3.fromRGB(147, 0, 0)
  286.                     }
  287.                 })
  288.                 speaker:SetExtraData("ChatColor", Color3.fromRGB(147, 0, 0))
  289.                 speaker:SetExtraData("NameColor", BrickColor.new("Persimmon").Color)
  290.             end))
  291.         end
  292.        
  293.         --// Check
  294.         local inventory = data.assets.inventory
  295.         local trails = inventory.trails
  296.         local ballTextures = inventory.balltextures
  297.        
  298.         --// Check
  299.         if not (trails["Youtuber"]) then
  300.             print("ADDING YOUTUBER TRAIL")
  301.             trails["Youtuber"] = "Youtuber"
  302.         end
  303.         if not (ballTextures["Youtuber"]) then
  304.             print("ADDING YOUTUBER TRAIL")
  305.             ballTextures["Youtuber"] = "Youtuber"
  306.         end
  307.     end
  308.     return isYoutuber
  309. end
  310.  
  311. --[ DATASTORE_SERVICE ]--
  312. local DS = {}
  313.  
  314. --[ Load Data ]--
  315. function DS:LoadAsync(player)
  316.     print("LOADING PLAYER")
  317.     local rawdata = playerdatastore:GetAsync(player.userId) or defalut:NewData()
  318.     local data = defalut:CheckForUpdates(rawdata)
  319.    
  320.     --[ Load Values
  321.     LoadExtraValues(player, data)
  322.     LoadStats(player, data)
  323.     LoadValues(player)
  324.    
  325.     --[ Store ]--
  326.     client.Player.getdata:FireClient(player, data)
  327.     _G.DS[player.Name] = data
  328.    
  329.     --// Create
  330.     coroutine.resume(coroutine.create(function()
  331.         --[ CONTROL_EXP ]--
  332.         local stats = player:WaitForChild("stats")
  333.         local char = player.Character
  334.         local levelbadge = char.Level.LevelBadge
  335.         local tag = char:FindFirstChild("Tag")
  336.        
  337.         --// Boost
  338.         GetBoost(player, stats)
  339.         valmod:Connect(levelbadge, stats)
  340.     end))
  341.     warn(httpService:JSONEncode(data):len())
  342. end
  343.  
  344.  
  345. --[ Save Player Data ]--
  346. function DS:SaveAsync(player, isShutDown)
  347.     local data = _G.DS[player.Name]
  348.     local vals = player:FindFirstChild("values")
  349.     local stats = player:FindFirstChild("stats")
  350.    
  351.     --[ Check ]--
  352.     if not (data) then
  353.         warn(string.format("%s's data could not found in the container!", player.Name))
  354.     --[ Data Exists ]--
  355.     else
  356.         --[ Save Data ]--
  357.         playerdatastore:UpdateAsync(player.userId, function(oldData)
  358.             local currentData = oldData or defalut:NewData()
  359.             local cachedData = data
  360.            
  361.             --// Check
  362.             if not (isShutDown) then
  363.                 local courtdata = _G[vals.Court.Value]
  364.                
  365.                 --[ Check ]--
  366.                 if (courtdata) then
  367.                     local court = courtdata.court
  368.                     local getteam = courtdata.winningteam
  369.                    
  370.                     --// Check for activity
  371.                     if (courtdata.active.Value) then
  372.                         stats.loses.Value = stats.loses.Value + 1
  373.                         stats.streak.Value = 0
  374.                     elseif (getteam) then
  375.                         local hasWon
  376.                        
  377.                         --// Find
  378.                         for _, character in pairs(getteam) do
  379.                             if (character.Name == player.Name) then
  380.                                 hasWon = character.Name
  381.                                 break
  382.                             end
  383.                         end
  384.                        
  385.                         --// Check
  386.                         if not (hasWon) then
  387.                             stats.loses.Value = stats.loses.Value + 1
  388.                             stats.streak.Value = 0
  389.                         end
  390.                     end
  391.                 end
  392.             end
  393.                
  394.             --[ Load ]--
  395.             for name, stat in pairs(currentData.stats) do
  396.                 if (stats:FindFirstChild(name)) then
  397.                     currentData.stats[name] = stats:FindFirstChild(name).Value
  398.                 end
  399.             end
  400.            
  401.             --// Check
  402.             if (game.PlaceId == park) or (game.PlaceId == mobileOnlyPark) then
  403.                 local parkRecord = currentData.stats.park
  404.                 for statName, statValue in pairs(parkRecord) do
  405.                     parkRecord[statName] = stats:FindFirstChild(statName).Value
  406.                 end
  407.             end
  408.            
  409.             --// Assets
  410.             local cachedAssets = cachedData.assets
  411.             local cachedInventory = cachedAssets.inventory
  412.             local cachedGuiLayout = cachedAssets.guilayout
  413.            
  414.             --// Update Equipped
  415.             for assetName, assetValue in pairs(cachedAssets) do
  416.                 currentData.assets[assetName] = assetValue
  417.             end
  418.            
  419.             --// Update Inventory
  420.             for className, classData in pairs(cachedInventory) do
  421.                 currentData.assets.inventory[className] = classData
  422.             end
  423.            
  424.             --// Update Layout
  425.             for guiName, guiPositionData in pairs(cachedGuiLayout) do
  426.                 currentData.assets.guilayout[guiName] = guiPositionData
  427.             end
  428.            
  429.             print("UPDATING DATA")
  430.             return currentData
  431.         end)
  432.     end
  433.     --[ Remove ]--
  434.     _G.DS[player.Name] = nil
  435. end
  436.  
  437. --[ Update Custom Datastore ]--
  438. function DS:UpdateDatastoreAsync(DATASTORE, KEY, VALUE)
  439.     local data = self:GetDatastoreAsync(DATASTORE)
  440.     local dataStore = dataStores[DATASTORE]
  441.     data[KEY] = VALUE
  442.     dataStores[DATASTORE]:SetAsync(dataStoreKeys[DATASTORE], data)
  443.    
  444.     --// Check
  445.     if (dataStore == youtubedatastore) then
  446.         youtubeData = dataStores[DATASTORE]:GetAsync(dataStoreKeys[DATASTORE], data)
  447.         dataTable["youtubeData"] = youtubeData
  448.     elseif (dataStore == admindatastore) then
  449.         adminData = dataStores[DATASTORE]:GetAsync(dataStoreKeys[DATASTORE], data)
  450.         dataTable["adminData"] = adminData
  451.     elseif (dataStore == bandatastore) then
  452.         banData = dataStores[DATASTORE]:GetAsync(dataStoreKeys[DATASTORE], data)
  453.         dataTable["banData"] = banData
  454.     end
  455. end
  456.  
  457. function DS:GetDatastoreAsync(DATASTORE)
  458.     return dataStores[DATASTORE]:GetAsync(dataStoreKeys[DATASTORE]) or {}
  459. end
  460.  
  461. function DS:GetDataTable(tableName)
  462.     return dataTable[tableName]
  463. end
  464.  
  465. client.Player.save.OnServerEvent:Connect(function(player, layoutData)
  466.     for i, v in pairs(layoutData) do
  467.         print(i, unpack(v))
  468.     end
  469.     _G.DS[player.Name].assets.guilayout = layoutData
  470. end)
  471. return DS
Advertisement
RAW Paste Data Copied
Advertisement