Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

Using user input service in server script. [SOLVED]?

Asked by 5 years ago
Edited 5 years ago
game.Players.PlayerAdded:connect(function(player)
local animation = script:FindFirstChild("Animation")

game:GetService("UserInputService").InputBegan:connect(function(inputObject, gameProcessedEvent)
    if inputObject.KeyCode == Enum.KeyCode.Q and gameProcessedEvent == false then
local animationtrack = player.Character.Humanoid:LoadAnimation(animation) 
animationtrack:Play()
-- rest of script...
0
well you could use sanity checks on the server :p theking48989987 2147 — 5y

1 answer

Log in to vote
1
Answered by 5 years ago
Edited 5 years ago

The apparent problem


Unfortunately the UserInputService and ContextActionService are all services only available to be used by the client , as it isnt replicated between server and client. Because of this, using any events, functions, and properties that are a member of either service won't work.

The Sanity Check


A common tool used by developers is what as known as a sanity check. A sanity check basically makes sure that all values sent from client to server makes sense. For example, the increase of a type of virtual currency , i.e. Gold

Say for example, I am playing a game that uses the F key to increase my gold and the creators of the game let the client calculate how much gold to get, So I modify the scripts responsible for calculating the gold increase. Since the server doesnt check if the amount of gold is logical, i can get away with giving myself any amount of gold i.e. 9e17 gold.

An example of such a script would be :

--client
local plr = game.Players.LocalPlayer
local level = plr:WaitForChild("Level")
local cas = game:GetService("ContextActionService")
local remote = game.ReplicatedStorage.RemoteEvent

function work (actions,InputState,Input)
    remote:FireServer(action,level.Value * 50)
end

cas:BindAction("Work",work,false,Enum.KeyCode.F)

--server

local remote = game.ReplicatedStorage.RemoteEvent

remote.OnServerEvent:Connect(function(plr,action,money)
    if action == "Work" then
        local gold = plr.leaderstats.gold
        gold.Value = gold.Value + money
    end
end)

This is a terrible way to do something as there are no checks limiting the power of the client. Alternatively, something with a sanity check would be way better

--server

local remote = game.ReplicatedStorage.RemoteEvent

remote.OnServerEvent:Connect(function(plr,action,money)
    local level = plr.Level
    local gold = plr.leaderstats.gold
    if action == "Work" and money == level.Value * 50 then
        gold.Value = gold.Value + money
    elseif money ~= level.Value * 50 then
        plr:Kick("nice try")
    end
end)

This would be a slightly better alternative as the server has some control over how the player can get income. However, it is not an ideal solution as of yet.

The Debounce


A debounce is a quick and easy way to make sure something doesn't happen more than you wanted it to. And in this case, can be a quick patch for any exploiter that just loops the fireserver function or anyone who uses an autoclicker (/ f presser?)

--server

local used = {}
local remote = game.ReplicatedStorage.RemoteEvent

remote.OnServerEvent:Connect(function(plr,action,money)
    local level = plr.Level
    if action == "Work" and money == level.Value * 50 and not used[plr] then
        local gold = plr.leaderstats.gold
        gold.Value = gold.Value + money

        ------------------------------------
        used[plr] = true
        delay(0.5 function()
            used[plr] = nil
        end)
        -------------------------------------
    elseif money ~= level.Value * 50
        plr:Kick("nice try")
    end
end)

Currently, most things are set already, However, one thing would make this a bit for efficient , that being avoiding calculating the stat increase on the client and just doing it on the server:

--client
local plr = game.Players.LocalPlayer
local level = plr:WaitForChild("Level")
local cas = game:GetService("ContextActionService")
local remote = game.ReplicatedStorage.RemoteEvent

function work (actions,InputState,Input)
    remote:FireServer(action)
end

cas:BindAction("Work",work,false,Enum.KeyCode.F)

--server

local remote = game.ReplicatedStorage.RemoteEvent
local used = {}

remote.OnServerEvent:Connect(function(plr,action)
    local level = plr.Level
    local gold = plr.leaderstats.gold
    if action == "Work" and not used[plr] then
        gold.Value = gold.Value + level.Value * 50

        used[plr] = true
        delay(0.5 function()
            used[plr] = nil
        end)
    end
end)

Hopefully this helped you with your task :3

0
sorry for making such a long post :/ theking48989987 2147 — 5y
0
like i said, moving the entire thing to a server script just isnt possible unless you change some major areas of gameplay including not letting a InputBegan event increase stats theking48989987 2147 — 5y
0
i also think that a remote event would be better for this purpose theking48989987 2147 — 5y
0
Alright ima accept this because if it was not for this I would have not found a fix. As your post reminded me of something / gave me a idea on how to fix it and that idea works. Yes it still allows them to spam it. But the thing is the server script itself has a wait causing them to have to wait to use it again happytimeroblox101 36 — 5y
Ad

Answer this question