How would I add a dictionary into a module script from a server script?

I am storing my game bans inside a module script
Here is the module:

local Bans = {
	
	["hahafunnyban"] = {
		Username = "hahafunnyban",
		BannedOn = 1732287049,
		UserID = 124,
		Reason = "test",
		BannedUntil = 0,	
		Moderator = "modnamehere",	
	}
	
}

return Bans

this is a placeholder so I can list the bans on my admin panel, which is working

I am adding a ban player function to the admin panel, and I just wanted to know how I would add their ban to the module script

I tried table.insert using this script:

local bans = require(game:GetService("ReplicatedStorage"):WaitForChild("Modules"):WaitForChild("BanStorage"))

local emptyBan = {
	Username = "test",
	BannedOn = 0,
	UserID = 0,
	Reason = "",
	BannedUntil = 0,	
	Moderator = "",	
}

local newBan = emptyBan["UsernameHere"]

table.insert(bans, newBan)

nothing was added

I cant find anything on the devforum that worked.

It looks like you are inserting the ban in two different ways. The “hahafunnyban” is inserted as a dictionary entry but the “test” ban is inserted as an array entry. Instead of the last two lines insert the emptyBan like this.

bans["UsernameHere"] = emptyBan

There’s still no dictionary being added from what I can see

I didn’t quite match what it looks like you’re trying to do. This is more like it I think.

local newBan = table.clone(emptyBan)

newBan.Username = "UsernameHere"

bans["UsernameHere"] = newBan

However, you should still be seeing the new “UsernameHere” entry. Can you print(bans) at the bottom and see what you get?

When using this it doesnt seem to actually be adding anything, I also added a refresh function and it doesnt add the ban after that either

when printing it does show up
image

this code is also doing the same as above, nothing in the ui but when printing it shows its there

this is my code to get the ban list

local function RefreshBanList()

	local ts = game:GetService("TweenService")

	ts:Create(Holder.Bans.Refresh, TweenInfo.new(1.5), {Rotation = 360}):Play()
	task.delay(1.6, function()
		Holder.Bans.Refresh.Rotation = 0
		Holder.Bans.Refresh.Active = true
	end)

	for _,v in pairs(Holder.Bans.BanList:GetChildren()) do
		if v:IsA("TextButton") then
			v:Destroy()
		end
	end

	for _,Banned in pairs(BanStorage) do
		local Button = script.BanListTemplate:Clone()
		Button.Name = Banned.Username
		Button.Parent = Holder.Bans.BanList
		Button.Text = Banned.Username

		Button.Activated:Connect(function()
			Holder.Bans.ManageFrame.Username.Text = "Username: "..Banned.Username
			Holder.Bans.ManageFrame.UserID.Text = "User ID: "..Banned.UserID
			Holder.Bans.ManageFrame.BanStuff.BannedBy.Text = "Banned By: "..Banned.Moderator
			Holder.Bans.ManageFrame.Decoration.Visible = true
			Holder.Bans.ManageFrame.BanStuff.Reason.Text = "Reason: "..Banned.Reason
			Holder.Bans.ManageFrame.BanStuff.BannedOn.Text = "Banned On: "..tostring(DateTime.fromUnixTimestamp(Banned.BannedOn):FormatUniversalTime("LL", "en-us"))
			task.spawn(function()
				local Picture = Holder.Bans.ManageFrame.Picture
				local userId = game:GetService("Players"):GetUserIdFromNameAsync(Button.Name)
				local thumbType = Enum.ThumbnailType.HeadShot
				local thumbSize = Enum.ThumbnailSize.Size420x420
				local content, isReady = game.Players:GetUserThumbnailAsync(userId, thumbType, thumbSize)
				Picture.Image = content
			end)
			local BanTime = Banned.BannedUntil
			if BanTime == 0 then
				Holder.Bans.ManageFrame.BanStuff.BannedUntil.Text = "Permanent"
			else
				Holder.Bans.ManageFrame.BanStuff.BannedUntil.Text = "Banned Until: "..tostring(DateTime.fromUnixTimestamp(Banned.BannedUntil):FormatUniversalTime("LL", "en-us"))
			end
		end)
	end

end

Holder.Bans.Refresh.Activated:Connect(function()
	Holder.Bans.Refresh.Active = false
	RefreshBanList()
end)

I also printed the bans when using the refresh function, and the usernamehere ban isnt there, but it is when i print from the server..?

Is this code running on the server or the client? Ban code has to run on the server so that a client can’t manipulate it. UI code has to run on the client so it can be displayed.

The data in ModuleScripts doesn’t replicate from the server to the client automatically (even though the same ModuleScript can be required from both sides). There needs to be a RemoteEvent or something which communicates the new bans to the client that you are viewing the admin on.

The code to add a new ban is running on the server
The code that shows the UI is running on the client

re requiring the module each time I refresh doesn’t update it

This UI resets every time the player respawns, wouldn’t adding a new text button from the remote event just be removed after they respawn?

Also what would I do on the client when I get the event? whenever a banned player button is clicked it pulls all of the information from the module, so nothing would actually be displayed when the new button is clicked, it would just be a useless button

It will need to be a RemoteEvent (or RemoteFunction). The module can be defined on both the server and the client but it won’t contain the same data on both.

There are several different ways to structure it but you definitely are going to need some remote communication to display this on the client side.

Remote events and callbacks

1 Like

What you’re dealing with here is changing data that needs to be shared across all calls of this module script. What you could do is have a string instance in replicated storage(if you want the client to be able to see the bans but not edit them), or in server storage (if you want only the server to be able to see them). In that string instance you can store the JSONEncoded string of your data and manage it through the module.

If however you want the bans to persist across sessions and all running servers of your game, you will have to use datastores for permanent saves or memorystores in case the bans are only temporary, they can’t be longer than the maximum amount memory stores store data for, and the data per key isn’t much. If you want to mass fetch data you can try saving the info of multiple players under single keys, although that will make the system a bit more complex in nature.

1 Like

I was going to add an unban button on the UI, but I’m assuming it wouldn’t work

How would I go about managing the JSONEncoded string in the module?

The module fetches the value, deserializes it, manages it, then writes it back.

JSON was only used as an example here, you can store the data in an instance or multiple instances in any form you like, as long you know how to read and write to it. This is for in-game storage of data that isn’t large (basically here I assume that ban related data wont take many characters to be stored, because you add manually to it, not like a datastore that contains millions of keys).

1 Like

thank you

i’ll try it out when I get time and update

I fixed it a different way
I fired an event to all clients whenever a new ban is added, along with a clone of the module from the server. On the client, I set the ban module to the clone, BanStorage = bansClone
This seems to be working.

This entire logic can be simplified by storing the data in ReplicatedStorage. ReplicatedStorage is visible on the client and any changes the server does to an instance (like a StringValue) there automatically replicate to all clients. Also when a new client joins, they get the latest version of this replication (the one other players have).

Basically it helps you get rid of this sort of code and you can use it for things like UI text (for example intermission text, announcements). All you have to do is run code once on player load for the current value of an instance and then rerun it when the replicated instance fires the .Changed event.

1 Like

I’m saving bans to a data store each time the module is updated so they’ll get the newest version when they join

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.