Hello Devs,
Im currently working on a Rebirth System. Here is my Script in a Part:
local RebirthQueue = {}
script.Parent.Touched:Connect(function(p)
local Event = game.ReplicatedStorage:WaitForChild("Rebirth")
local Points = script.Parent.Parent.PointAmount.Value
local plr = game.Players:GetPlayerFromCharacter(p.Parent)
if plr then
if not table.find(RebirthQueue, plr) then
table.insert(RebirthQueue, plr)
Event:FireClient(plr, Points)
end
end
end)
game.ReplicatedStorage.RemoveTable.OnServerEvent:Connect(function(p)
local plr = game.Players:GetPlayerFromCharacter(p.Parent)
wait(5)
table.remove(RebirthQueue, table.find(RebirthQueue, plr))
end)
If the Part is touched and the Table is not there just a gui gets visible. Here is the local script in the Frame (in the guis) which opens:
local Event = game.ReplicatedStorage:WaitForChild("Rebirth")
local RebirthQueue = {}
Event.OnClientEvent:Connect(function(Points)
local PointsAmount = Points
if Event ~= nil then
script.Parent.Visible = true
script.Parent.Points.Value = Points
end
script.Parent.TextFrame.Yes.MouseButton1Click:Connect(function()
script.Parent.Visible = false
game.ReplicatedStorage.Rebirth:FireServer(PointsAmount)
game.ReplicatedStorage.RemoveTable:FireServer()
end)
end)
The Gui asks the player if he really wants to rebirth. I also added a no button which fires the RemoveTable Event. If the Player clicks yes this happens. Server script:
Everything works fine (the guis appears and closes, also removes the table if clicked yes or no, changes the Values if clicked yes)
THE ERROR IS: Every time I click the Button again the Gui appears. When I clicked yes my points value should get + 10 (because the points value is set to 10). Now when I touch the Part again and click yes on the guis my value gets + 20, if I touch it again after it goes + 30 and so on… I really don’t know what causes this, also there are no errors shown in the output. Any help would be HIGHLY appreciated!!!
I’m not entirely sure what the error is, but I think if you handle as much as possible on the server it will probably fix the error, and prevent exploiters from gaining a ton of stats. Basically for the client the only thing you have is a gui that fires a remote if you click yes, and for the server calculate the points and if the player is eligible for a rebirth.
Hi,
I added a debounce to the Part for the local Player. I have multiple parts which this function (opening the sam gui) and the guis text changes to the Amount of the Value located in the Parts) So the Part just opens the Gui and changes the Value so if the player clicks yes the player gets as much value points as the value of the value in the part has. If you touch these parts multiple parts the Amount of the Value just gets + the new value (if you touched a part with 10 points value and after that again the reward will be 20 points). How to fix that
After a lot of testing I realized that it’s actually quite a simple mistake. Every time the client detects the remote event for rebirth it connects another function to clicking the yes buttons that says to award ten points. The click function should only be connected once, not every time that the remote fires.
This code is incredibly inefficient and extremely vulnerable to exploits, so I recommend rewriting the whole thing with handling done entirely on the server. Also removing things such as the table queue system. If you want I can write you an example of more optimized code.
This would be an incredible help if you would do this! I added the table function because i dont want that the remote event gets fired everytime the player stand on the part… i dont think adding a debounce in a script would be a good idea because its for everyone not for the local player
Sorry for the late reply, but I’ve made some code using the zone module. You could also do this with click detectors or touched, but zone is better imo.
Server
local remote = game:GetService("ReplicatedStorage").RebirthEvent
local part = game:GetService("Workspace").RebirthZone
local zoneModule = require(script.Zone)
local guiZone = zoneModule.new(part)
guiZone.playerEntered:Connect(function(plr)
if plr.PlayerGui:FindFirstChild("VeryEpicGui") then return end
local c = script.VeryEpicGui:clone()
c.Parent = plr.PlayerGui
end)
guiZone.playerExited:Connect(function(plr)
while plr.PlayerGui:FindFirstChild("VeryEpicGui") ~= nil do
plr.PlayerGui:FindFirstChild("VeryEpicGui"):Destroy()
end
end)
remote.OnServerEvent:Connect(function(plr)
-- any logic for checking if player is eligible for rebirth
plr.leaderstats.Points+=part.PointsWorth.Value -- this script can be edited to give different amounts of points, just remember to never have the client tell how many points to give.
plr.leaderstats.Stage.Value = 1
plr:LoadCharacter()
end)
I haven’t taken a look at all the replies yet, but this seem to be a wrong way of approaching a problem.
Instead there should be checks in place, to see if something is already existing (when the topic is duplicating values).
Hi!
First of all, you should not send stuff like “PointsAmount” from the client to the server, instead the server should handle what the “PointsAmount” should be, and how to check if they have enough of X or Y. Otherwise the client could modify the clientscript and send 10 million.
Please describe for me what the problem is, since I didn’t quite get what the issue was.
The only problem here is that i have a golder called rebirths and lots of these parts… is there a way to handle them all like getting all children and if the children is touched and is the name of the part thr gui gets visible?
When they press “Yes” check on the server how many times a signal got through, when you press “Yes” a second time, go check if the signal fired twice that time.
Ok i tested this and it seems to work. The only problem is that I have multiple parts which have the same function as this too. So the Value would be different if you touched part x not part y…
if you don’t really care about exploiters then you could do something where the client passes the part that they touched through the remote, and the server checks the value of that part if that part exists.