Burst gun server-side checking issue

I’m trying to make a simple check for burst gun on server side, basically the way it works is, if a player fires more burst shots than the burst size of the gun within a single fire-rate duration, then the rest of the shots in that burst will not be registered by the server. I ended up just messing this up and now I just dont know where to go from here…

local function onFireEvent(player: Player, tool: Tool?, origin: Vector3?, direction: Vector3?, hit: Instance?)
	if not validateShotArguments(tool, origin, direction, hit) then
		return
	end
	if not validateShot(player, tool, origin, direction, hit) then
		return
	end
	local configuration = tool.Configuration
	if not burstCounts[tool] then
		burstCounts[tool] = 0
	end
	if fireRateDebounces[tool] then
		if configuration.FireMode.Value == "Burst" then
			if burstCounts[tool] >= configuration.BurstSize.Value then
				warn(`Player exceeded burst limit with {burstCounts[tool]} shots`)
				burstCounts[tool] = 0
				return
			end

			if fireRateDebounces[tool] > configuration.RateOfFire.Value - FIRERATE_BUFFER then
				burstCounts[tool] += 1
				fireRateDebounces[tool] = os.clock()
			end
		else
			if fireRateDebounces[tool] < configuration.RateOfFire.Value - FIRERATE_BUFFER then
				return
			end
		end
	end
	if hit then
		local target = hit:FindFirstAncestorOfClass("Model")
		if target then
			local targetHumanoid = target:FindFirstChild("Humanoid")
			if targetHumanoid and targetHumanoid.Health > 0 then
				if target:HasTag("Zombie") then
					local damage = configuration.Damage.Value
					if hit.Name == "Head" then
						damage *= configuration.HeadshotDamageMultiplier.Value
					end
					targetHumanoid:TakeDamage(damage)
					print(damage)
				end
			end
		end
	end
	local handle = tool.Handle
	local fireSound = handle:FindFirstChild("Fire")
	if fireSound then
		fireSound:Play()
	end
	configuration.Ammunition.Value -= 1
	fireRateDebounces[tool] = os.clock()
	if burstCounts[tool] then
		burstCounts[tool] += 1
	end
end

I found a bug that burst count (burstCounts) and debounce (fireRateDebounces) are both getting muddled, I also found another bug where the incrementing of burst counts is not correctly synced with the firing checks and also the shots after exceeding the burst size isn’t right.


local burstCounts = {}
local fireRateDebounces = {}


local function onFireEvent(player: Player, tool: Tool?, origin: Vector3?, direction: Vector3?, hit: Instance?)
    if not validateShotArguments(tool, origin, direction, hit) then
        return
    end
    if not validateShot(player, tool, origin, direction, hit) then
        return
    end


    local configuration = tool.Configuration
    if not burstCounts[tool] then
        burstCounts[tool] = 0
    end
    if not fireRateDebounces[tool] then
        fireRateDebounces[tool] = 0
    end


    if configuration.FireMode.Value == "Burst" then

        if burstCounts[tool] >= configuration.BurstSize.Value then
            warn(`Player exceeded burst limit with {burstCounts[tool]} shots`)
            return
        end


        local currentTime = os.clock()
        if currentTime - fireRateDebounces[tool] < (60 / configuration.RateOfFire.Value) then
     
            return
        end


        burstCounts[tool] += 1
        fireRateDebounces[tool] = currentTime
    else

        local currentTime = os.clock()
        if currentTime - fireRateDebounces[tool] < (60 / configuration.RateOfFire.Value) then
            return
        end
        fireRateDebounces[tool] = currentTime
    end

   
    if hit then
        local target = hit:FindFirstAncestorOfClass("Model")
        if target then
            local targetHumanoid = target:FindFirstChild("Humanoid")
            if targetHumanoid and targetHumanoid.Health > 0 then
                if target:HasTag("Zombie") then
                    local damage = configuration.Damage.Value
                    if hit.Name == "Head" then
                        damage *= configuration.HeadshotDamageMultiplier.Value
                    end
                    targetHumanoid:TakeDamage(damage)
                    print(damage)
                end
            end
        end
    end


    local handle = tool.Handle
    local fireSound = handle:FindFirstChild("Fire")
    if fireSound then
        fireSound:Play()
    end

    
    configuration.Ammunition.Value -= 1
    if configuration.FireMode.Value == "Burst" then
       
        if burstCounts[tool] >= configuration.BurstSize.Value then
            burstCounts[tool] = 0
        end
    end
end

I hope this helps you.

1 Like

Thanks, with some modifications to your code, I got a rough working version of it. It might not be scripted the best but it works! My game is PvE and does not require a super well made anticheat.

local function onFireEvent(player: Player, tool: Tool?, origin: Vector3?, direction: Vector3?, hit: Instance?)
	if not validateShotArguments(tool, origin, direction, hit) then
		return
	end
	if not validateShot(player, tool, origin, direction, hit) then
		return
	end
	local configuration = tool.Configuration
	if not burstCounts[tool] then
		burstCounts[tool] = 0
	end
	if not fireRateDebounces[tool] then
		fireRateDebounces[tool] = 0
	end
	local currentTime = os.clock()
	if configuration.FireMode.Value == "Burst" then
		if burstCounts[tool] >= configuration.BurstSize.Value then
			burstCounts[tool] = 0
			return
		end
		if currentTime - fireRateDebounces[tool] < configuration.RateOfFire.Value and burstCounts[tool] >= configuration.BurstSize.Value then
			return
		end
		burstCounts[tool] += 1
	else
		if currentTime - fireRateDebounces[tool] < configuration.RateOfFire.Value then
			return
		end
	end
	if hit then
		local target = hit:FindFirstAncestorOfClass("Model")
		if target then
			local targetHumanoid = target:FindFirstChild("Humanoid")
			if targetHumanoid and targetHumanoid.Health > 0 then
				if target:HasTag("Zombie") then
					local damage = configuration.Damage.Value
					if hit.Name == "Head" then
						damage *= configuration.HeadshotDamageMultiplier.Value
					end
					targetHumanoid:TakeDamage(damage)
					print(damage)
				end
			end
		end
	end
	local handle = tool.Handle
	local fireSound = handle:FindFirstChild("Fire")
	print('Played')
	if fireSound then
		fireSound:Play()
	end
	configuration.Ammunition.Value -= 1
	if configuration.FireMode.Value == "Burst" then
		if burstCounts[tool] >= configuration.BurstSize.Value then
			burstCounts[tool] = 0
		end
	end
	fireRateDebounces[tool] = currentTime
end
1 Like

I am really glad this helps you! Tell me if you need anymore help