what my script does is when they click a button it fires an event that triggers all client and pulls up a gui when the gui completes I want to fire another event saying that the gui finished and end the round. but I know that people that exploit will be able to call that event because its client sided to server then the game will end when I don’t want it to. Sry if this is confusing but if you do understand is there a better way. to call from one client to server to end a round.
I have a question? Why would you want to make the client able to end a round?
so basically i have a gui that like a voting system and people vote and when everyone is done voting I need someway to tell when they are done so all I can think of is to fire a client sided event
Basically, you start the voting, and you notify all the clients, and give them 2 options:
Yes or no.
Then, they send what they voted, the server stores which client voted yes or no.
(So exploiters don’t vote multiple times)
After the voting is over, the server sees if there are more yes that nos, and if so, ends the round, and notifies all clients about that.
You should also look at this topic where you can find information about how to make a votation system, the final product was able to safetely hold a votation and stop exploiters from messing it up. (Just replace the kick code with your code and it should help you)
The server should initiate and decide when the round is complete. As @Jrelvas1 said, you should make sure the server can only store 1 vote per person.
And the server should be able to tell as each vote comes in whether there are still people missing or not. My advice is to add a timer/countdown so if they don’t respond in 30 seconds they abstain and the server calls it.
Alright thank you I’ll see what I can do
Great! Don’t be scared of replying to me if you run into any issues!
Sanity Checks!
In order to prevent exploiting, you will need to work with input client-server sanity checks. If the I/O is invalid, do not process the code.
It’s simple, add a few if else
statements. Utilize the first argument, which is always the player for the remotes.
To avoid firing the remote and signaling the server unnecessarily, you could add a check if the server is initializing voting or not. Followed up by checking if the player has voted using the player argument and if the vote is the same as the previous. If there are no previous votes or the vote is different from the previous, match the string with the selection and check if it exists. Then proceed to adding up the vote.
Example
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remote = ReplicatedStorage["your remote name here"] -- if the remote is stored there, otherwise reference the remote from server to the one you wish to connect
local voting = false
local votes = {}
local choices = {}
local possibleChoices = {
"Red"; "Blue"; "Green"; "Yellow";
"Black"; "Purple"; "White"; "Teal"
}
remote.OnServerEvent:Connect(function(player, vote) -- anonymous function
if not voting or votes[player.UserId] == vote then return end -- we're using the player.UserId key; note that it is checking if the voting is ongoing or not
for _, choice in next, choices do
if choice == vote then
votes[player.UserId] = vote
break
end
end
end)
while true do -- hahahaha
wait(10) -- 10 seconds before voting
voting = true
votes = {}
for i = 1, 3 do
local choice = possibleChoices[math.random(#possibleChoices)] -- beware of dupes
table.insert(choices, choice)
end
wait(45) -- 45 seconds voting time lol
voting = false
choices = {}
end
On the client, hook the function which fires the remote with something that has an input.