Hey! I am trying to write a global banning script for one of my games. I’m using MessagingService once the player gets marked as banned to check in every server if the player is playing (to remove them from the game.) After I use JSONEncode to make the info work with MessagingService, trying to decode it seems to not be working properly. The error I get is here:
I have a Banning ModuleScript that is required by a BanHandler.
The BanHandler script goes as follows:
local banModule = require(script.Parent.BanModule)
local msgService = game:GetService("MessagingService")
local httpService = game:GetService("HttpService")
local pls = game:GetService("Players")
msgService:SubscribeAsync("Bans", function(message)
local data = httpService:JSONDecode(message)
local bannedStatus = data.Banned
local userId = data.UserID
local username = pls:GetNameFromUserIdAsync(tonumber(userId))
if pls:FindFirstChild(username) and bannedStatus then
pls[username]:Kick("Banned.")
end
end)
The Ban Module goes as following:
local module = {}
local DataStore = game:GetService("DataStoreService")
local msgService = game:GetService("MessagingService")
local httpService = game:GetService("HttpService")
local banStore = DataStore:GetDataStore("New Data 5")
function loadData(UserId)
local data
local success = pcall(function()
data = banStore:GetAsync(tostring(UserId))
end)
if(not success)then
wait(60)
loadData(UserId)
end
print("Player data grabbed")
return data
end
function module.BanPlayer(id)
local data = loadData(id)
if not data.BannedInformation then
data.BannedInformation = {
Banned = false
};
end
data.BannedInformation = {
Banned = true,
};
print("Ban set.")
banStore:SetAsync(id, data)
print("Ban published")
local msgData = {
UserID = id;
Banned = true;
};
local encoded = httpService:JSONEncode(msgData)
print(encoded)
msgService:PublishAsync("Bans", encoded)
end
return module
Here’s the entire output:
Thank you for any help, I’m sure this is a very dumb and simple issue.
This has me befuddled, the only thing I can think of is that somewhere along the way in being transmitted thru messagingservice the string somehow becomes malformed? Mind adding print("received: ", message) to the top of the subscribeasync callback and showing the output?
I may know the issue, but I’m not completely sure. At this point I think it’s because of how I’m calling the ban. I am currently in the testing phase, so I’m using the developer console to execute the command by doing:
local banModule = require(game.ServerScriptService.BanModule)
banModule.BanPlayer(1100753439)
This could be affecting it, which I am presuming it is. I will look more into this later tonight when I am able to get back on.
Well that’s certainly odd, it seems like messaging service is turning it back into a table somewhere along the line! I’d traverse it and see if it’s formed as expected (i.e. as it was prior to being encoding).
Here’s the link. Unfortunately the actual entry for SubscribeAsync does not tell you anything about the payload but the link above does:
The callback function for SubscribeAsync() receives a table, not a string. This table contains both message.Data (the developer-defined data sent via PublishAsync()) and message.Sent which is the Unix time in seconds at which the message was sent.
Thanks, it appears they misformatted the links on the SubscribeAsync and PublishAsync pages since those both lead to https://developer.roblox.com/en-us/api-reference/function/MessagingService/articles/cross-server-messaging and not https://developer.roblox.com/en-us/articles/cross-server-messaging.
You don’t need to encode or decode the data your passing as Roblox does it by default. You’re basically double encoding/decoding for no reason.
local data = httpService:JSONDecode(message)
This is most likely why your script is erroring. You’re trying to decode a dictionary passed by Roblox that’s not even encrypted in the first place. This dictionary contains two keys, ‘Data’ (in this case, your bans table), and ‘Sent’ in which the time the message was sent. Directly referencing to message.Data should work.
local data = message.Data
Make sure to get rid of the JSONEncode and JSONDecode as Roblox already does that for you!