Hello, everyone. I have been making gun systems for around a year now, and I’ve never really given thought about the way I handle user input. Is this safe to use, or can it be easily exploited?
Local Code ( StarterCharacterScripts ):
Basically, we got a table for our binds:
local binds = {
[1] = Enum.KeyCode.One,
[2] = Enum.KeyCode.Two,
[3] = Enum.KeyCode.Three
}
then, we loop through that table using ContextActionService:
for i in pairs(binds) do
CAS:BindAction("equip"..i, equip, false, binds[i])
end
the equip()
function:
local function equip(name, state, obj)
if state ~= Enum.UserInputState.Begin then return end
local index = tonumber(string.split(name, "equip")[2])
if type(binds[index]) ~= type(obj) then return end
h:equip(index)
end
now, you may have noticed h, its just a module for weapon framework lol, I changed it to weapon
Received by module:
function module:equip(index)
_, _ = pcall(function()
if index == table.find(self.loadout, self.curwep.Name) then return end
end)
if self.equipped then
for i in self.loadedAnimations[self.curwep.Name] do
self.loadedAnimations[self.curwep.Name][i]:Stop()
end
self.settings = nil
end
if index > #self.loadout then return end
local wep = self.loadout[index]
local response = repStorage.events.equip:InvokeServer(index)
if not response then return end
wep = self.character:FindFirstChild(wep)
if not self.loadedAnimations[wep.Name] then
self.loadedAnimations[wep.Name] = {}
end
if not self.loadedAnimations[wep.Name].idle then
self.loadedAnimations[wep.Name].idle = self.humanoid:LoadAnimation(wep.animations.idle)
end
self.loadedAnimations[wep.Name].idle:Play()
self.settings = require(wep.settings)
self.curwep = wep
self.equipped = true
self.canFire = true
end
Server event equip
:
events.equip.OnServerInvoke = function(plr, index)
if players[plr.UserId].cooling then return false end
if not players[plr.UserId].loadout[index] then return false end
if players[plr.UserId].curwep then
local wep = plr.Character:FindFirstChild(players[plr.UserId].curwep.name)
if not wep then return end
wep:Destroy()
end
local wep = game.ReplicatedStorage.weapons:FindFirstChild(players[plr.UserId].loadout[index])
if not wep then return false end
wep = wep:Clone()
wep.Parent = plr.Character
local weld = wep.root.torso
weld.Part0 = plr.Character.Torso
weld.Part1 = wep.root
players[plr.UserId].equipped = true
local sets = require(wep.serverSets)
local ammoV
if players[plr.UserId].savedAmmo[players[plr.UserId].loadout[index]] then
ammoV = players[plr.UserId].savedAmmo
else
players[plr.UserId].savedAmmo[players[plr.UserId].loadout[index]] = sets.clip
ammoV = sets.slip
end
players[plr.UserId].curwep = {name = players[plr.UserId].loadout[index], settings = sets, ammo = ammoV}
coroutine.wrap(function()
players[plr.UserId].cooling = true
task.wait(COOLDOWN_TIME)
players[plr.UserId].cooling = false
end)()
return true
end
btw, players[plr.UserId]
is just a table with the given player’s info.