Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --// Author(s): MohhayScripts
- --// Version: 1.2.0
- --// Services
- local Players = game:GetService("Players")
- local ReplicatedStorage = game:GetService("ReplicatedStorage")
- local RunService = game:GetService("RunService")
- local ServerStorage = game:GetService("ServerStorage")
- --// Modules
- local Astronet = require(ServerStorage.AstronetServer)
- local ProfileService = Astronet.Require("ProfileService")
- local ReplicaService = Astronet.Require("ReplicaService")
- local ProfileTemplate = Astronet.Require("ProfileTemplate")
- local Logger = Astronet.Require("Logger").attach(script.Name)
- local Promise = Astronet.Require("Promise")
- local Settings = require(ReplicatedStorage.Settings)
- --// Types
- --// Variables
- local ProfileStore = ProfileService.GetProfileStore("PlayerData", ProfileTemplate)
- local ProfileClassToken = ReplicaService.NewClassToken("PlayerProfile")
- local PlayerProfiles = {} -- [player] = {Profile = profile, Replica = replica, _player = Player}
- --// Functions
- local function PlayerAdded(Player)
- local Profile = ProfileStore:LoadProfileAsync("Player_" .. Player.UserId)
- if Profile ~= nil then
- Profile:AddUserId(Player.UserId) -- GDPR compliance
- Profile:Reconcile() -- Fill in missing variables from ProfileTemplate (optional)
- Profile:ListenToRelease(function()
- PlayerProfiles[Player].Replica:Destroy()
- PlayerProfiles[Player] = nil
- -- The profile could've been loaded on another Roblox server:
- Player:Kick("Another server is trying to load your data. Please close all instances of Roblox and rejoin the game if this was unintentional!")
- end)
- if Player:IsDescendantOf(Players) == true then
- -- A profile has been successfully loaded:
- -- do something with profile
- local player_profile = {
- Profile = Profile,
- Replica = ReplicaService.NewReplica({
- ClassToken = ProfileClassToken,
- Tags = {Player = Player},
- Data = Profile.Data,
- Replication = "All",
- }),
- _player = Player,
- }
- setmetatable(player_profile, Profile)
- PlayerProfiles[Player] = player_profile
- else
- -- Player left before the profile loaded:
- Profile:Release()
- end
- else
- -- The profile couldn't be loaded possibly due to other
- -- Roblox servers trying to load this profile at the same time:
- Player:Kick("Failed to load data, another server is trying to load your data at the same time. Please rejoin the game after a few seconds!")
- end
- end
- --// Init
- local DataService = {}
- function DataService:GetData(Player: Player): typeof(ProfileTemplate) | nil
- local playerProfile = PlayerProfiles[Player]
- if not playerProfile or not playerProfile.Profile then
- Logger.error(`{Player.Name} playerProfile or playerProfile.Profile does not exist. [playerProfile: {if playerProfile then Logger.parse(playerProfile) else "nil"};]`)
- return
- end
- return playerProfile.Profile.Data
- end
- function DataService:GetDataPromise(Player: Player) -- Promise variant of DataService:GetData()
- local playerProfile = PlayerProfiles[Player]
- if playerProfile ~= nil and playerProfile.Profile ~= nil then
- return Promise.resolve(playerProfile.Profile.Data)
- end
- return Promise.new(function(resolve, _reject, onCancel)
- local heartbeat
- local function OnDone()
- heartbeat:Disconnect()
- end
- local function Update()
- local v = PlayerProfiles[Player]
- if v ~= nil and v.Profile ~= nil then
- OnDone()
- resolve(v.Profile.Data)
- end
- end
- heartbeat = RunService.Heartbeat:Connect(Update)
- onCancel(OnDone)
- end):timeout(20)
- end
- function DataService:GetDataByKey(Player: Player, key: string): any | nil
- local playerProfile = PlayerProfiles[Player]
- if not playerProfile or not playerProfile.Profile or not playerProfile.Profile.Data[key] then
- Logger.error(`{Player.Name} playerProfile or playerProfile.Profile or playerProfile.Profile.Data[{key}] does not exist. [playerProfile: {if playerProfile then Logger.parse(playerProfile) else "nil"};]`)
- return
- end
- return playerProfile.Profile.Data[key]
- end
- function DataService:GetDataByKeyPromise(Player: Player, key: string) -- Promise variant of DataService:GetDataByKey()
- local playerProfile = PlayerProfiles[Player]
- if playerProfile ~= nil and playerProfile.Profile ~= nil and playerProfile.Profile.Data[key] ~= nil then
- return Promise.resolve(playerProfile.Profile.Data[key])
- end
- return Promise.new(function(resolve, _reject, onCancel)
- local heartbeat
- local function OnDone()
- heartbeat:Disconnect()
- end
- local function Update()
- local v = PlayerProfiles[Player]
- if v ~= nil and v.Profile ~= nil and v.Profile.Data[key] ~= nil then
- OnDone()
- resolve(v.Profile.Data[key])
- end
- end
- heartbeat = RunService.Heartbeat:Connect(Update)
- onCancel(OnDone)
- end):timeout(20)
- end
- function DataService:SetData(Player: Player, data: {any}): ()
- local playerProfile = PlayerProfiles[Player]
- if not playerProfile or not playerProfile.Profile then
- Logger.error(`Failed to set data because {Player.Name} playerProfile or playerProfile.Profile does not exist.`)
- end
- PlayerProfiles[Player].Profile.Data = data
- Logger.info(`Successfully saved data to {Player.Name} playerProfile.Profile.Data.`)
- end
- function DataService:SetDataByKey(Player: Player, key: string, value: any): ()
- local playerProfile = PlayerProfiles[Player]
- if not playerProfile or not playerProfile.Profile or not playerProfile.Profile.Data[key] then
- Logger.error(`Failed to set data because {Player.Name} playerProfile or playerProfile.Profile or playerProfile.Profile.Data[{key}] does not exist. [playerProfile: {if playerProfile then Logger.parse(playerProfile) else "nil"};]`)
- return
- end
- playerProfile.Profile.Data[key] = value
- Logger.info(`Successfully saved data to {Player.Name} playerProfile.Profile.Data[{key}].`)
- end
- function DataService:Init()
- if RunService:IsStudio() and Settings.ProfileService.Mock then
- ProfileStore = ProfileStore.Mock
- end
- Players.PlayerAdded:Connect(PlayerAdded)
- for _, Player in Players:GetPlayers() do
- task.spawn(PlayerAdded, Player)
- end
- Players.PlayerRemoving:Connect(function(Player)
- local Profile = PlayerProfiles[Player]
- if Profile ~= nil then
- Profile.Profile:Release()
- end
- end)
- end
- return DataService
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement