I’m making a custom server lock system. The server is locked by default, which is supposed to kick the players as soon as they join.
The thing is, instead of displaying the actual kick message, the player gets kicked with “Please check your internet connection and try again.”
I’m not exactly sure what’s causing this, but here’s the code:
local mod = require(game.ReplicatedStorage.PanelFD.Settings)
game.Players.PlayerAdded:Connect(function(plr)
local rank = plr:GetRankInGroup(mod.GroupID)
if game.ReplicatedStorage.PanelFD.Locked.Value == true and rank < mod.Customer then
plr:Kick(mod.KickMessage)
end
end)
local settings_ = {
GroupID = 123; --Not the actual ID
--// Roles
Staff = 100;
Customer = 6;
--// Misc
KickMessage = "This is the Kick Message"
}
return settings_
This issue often occurs because the kick message isn’t displayed if the player is kicked before fully joining the server, add a short wait before kicking.
local mod = require(game.ReplicatedStorage.PanelFD.Settings)
game.Players.PlayerAdded:Connect(function(plr)
local rank = plr:GetRankInGroup(mod.GroupID)
if game.ReplicatedStorage.PanelFD.Locked.Value == true and rank < mod.Customer then
task.wait(1)
plr:Kick(mod.KickMessage)
end
end)
No, if you are requiring a module and have a set a variable, you get what is inside the module, to get the child of it, is by NOT using require and define the Module directly.
I had to do task.wait(10) since the game is really big and it takes quite a long time to load, but sometimes the player is able to walk around for a bit before being kicked and that’s not exactly the best.
Also tried game.Loaded:Wait() but it does’t work, probably since things far away don’t get loaded in.
This is not a solution but I wanted to clean that code up for you with some good practices
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local mod = require(ReplicatedStorage.PanelFD.Settings)
Players.PlayerAdded:Connect(function(plr)
local success: boolean, rank: number? = pcall(plr.GetRankInGroup, plr, mod.GroupID)
if not success then
warn(`Failed to get rank for {plr.Name}: {rank}`)
return
else
local locked: boolean = ReplicatedStorage.PanelFD.Locked.Value
if locked and (rank and rank < mod.Customer) then
plr:Kick(mod.KickMessage)
end
end
end)
Asynchronous calls to the Roblox API should use promises / protected calls, since you aren’t guaranteed a returned variable on GetRankInGroup
Defining services at the top of your script follows the Luau style guide, which is recommended for good practices on code structuring and preventing DRY (Don’t Repeat Yourself)
Types assigned to let your tools (including your code editor) know how to work around your codebase. If you’re using the native Roblox code editor, this shouldn’t matter; but if you intend to apply tools like VSCode, this will help with intellisense and such.
The error message for when a player is kicked should be 267, instead of 277. Are you certain that it isn’t something else causing the disconnection to occur, such as another script deleting the player when they spawn?
This test may look unnecessary, but try simply kicking the player when they spawn in a new baseplate with the sole script being a server Script inside ServerScriptService:
local Players = game:GetService("Players")
Players.PlayerAdded:Connect(function(player: Player)
player:Kick("This is a test kick message")
end)
If the kick message is displayed correctly, that confirms that either another script is causing the issue, or one of Workspace’s properties that deal with the game’s configuration/settings that you may have changed from default
try kicking when characteradded or characterappearanceloaded i guess (im not good scripter) but if you want to kick when game is loaded then do what @VonsRevenges said
The solution you provided is not related to the problem he is meeting, he has no problem with getting the group rank, the problem is with the KickMessage.
When a game has a large amount of network events occurring during the join (which it most likely is, if he’s replicating states to the client side), then the network will drop. This protected call ensures that the kick isn’t the issue because it’s yielding for the response; which means it will wait until the response is given. That is preferred over a task.wait because you aren’t 100% sure that the task.wait will yield for the response.
So yes, it isn’t a solution: it’s an isolation trick to make sure that the original post isn’t focused on X, when the issue is Y.
That’s the whole point of my first post, respectively. I provided an isolation from the network. So your task.wait method will work, but the recommended practice is to not yield the thread with sleep methods and use event-based yields instead. Mainly because everyone has different devices, so the task.wait() will yield in different timestamps.
The job of pcall and xpcall is to provide a safe way to call functions that have a chance to error for reasons outside of the programmer’s control (such as a server shutting down)
Due to this, they’re usually used for functions that yield before returning the result, but it isn’t pcall and xpcall themselves that are yielding. ypcall is a protected call function that does itself yield, but it’s deprecated
GetRankInGroup needs to retrieve data from Roblox’s server, which is why pcall or xpcall should be used when calling it, since it isn’t guaranteed that the server isn’t experiencing any issues at the time