I made a datastore module for my admin system, which holds their admin level and if they’re banned or not, and I’m not sure if this would work.
local Data = {}
local datastore = game:GetService("DataStoreService"):GetDataStore("KeeAdminData")
Data.Set = function(player, data)
local success, err = pcall(function() datastore:SetAsync(player.UserId.."_AdminDS", data) end)
if success then
return
end
end
Data.Get = function(player)
local data
local success, err = pcall(function() data = datastore:GetAsync(player.UserId.."_AdminDS") end)
if success then
if data then
return datastore:GetAsync(player.UserId.."_AdminDS")
else
Data.Set(player, {Ban = {Banned = false, BanReason = "N/A", Moderator = nil}, Level = 0})
return datastore:GetAsync(player.UserId.."_AdminDS")
end
end
end
return Data
you should probably cache it instead of getting and setting the datastore everytime. that’ll cause a lot of throttling issues, even if datastore v2 fixes that. ill give you a rough example of what something like that would look like.
for some background, modulescripts have their own environment just normal scripts (in other words they can do the stuff a normal script can do)
local DataStore = {}
local AdminDatastore = ...
local data_cache = {} -- our lil cache
function DataStore.Get(player)
-- no tabs, sorry
local data = data_cache[player] or AdminDatastore:GetAsync("Player_" .. player.UserId)
if not data_cache[player]
data_cache[player] = data
end
return data
end
function DataStore.Set(player, data)
data_cache[player] = data
end
-- TODO: handle player removing
...
return DataStore
if you’re already caching the data, than you don’t need to worry about it, otherwise this tends to be a bad practice.
other things to note is that bindtoclose isn’t really necessary, that’s already handled by playerremoving.
oh that’s actually pretty simple, you’re probably going to want to want to hook to a playeradded event and fill in the values that don’t exist
local DATA_TEMPLATE = { -- once again no tables
Banned = false,
... -- your other values
}
local AdminDataStore = ... -- you can also implement the module
function playerAdded(player)
-- no tabs again sorry
local data = DataStore:GetAsync("Player_" .. player.UserId) or DATA_TEMPLATE
for index, value in pairs(DATA_TEMPLATE) do
if not data[index] then
data[index] = value -- for other use cases you may want to look into deep copying if you want to copy values deeper into your table structure
end
end
data_cache[player] = data
end
for _, player in ipairs(Players:GetPlayers()) do
coroutine.wrap(playerAdded)(player)
end
Players.PlayerAdded:Connect(playerAdded)
It’s basically the same but harder to setup + make the script + datastore has lower limits + request limit + discord banned Roblox from sending requests so you would need a proxy which is harder and longer + proxy’s might have more limits than discord + the proxy will prob ask for money + you would have to host the bot which makes it 10x harder
i generally like to use bots as a proxy for webhooks since you can use express and discord.js on a website such as glitch.com, and it will do all the same things a webhook would do without limits
not to mention you can edit messages that were sent in the past by the bot