Game Pass Tool Problem

So I made multiple game passes that gives you a gear when you buy it in the shop. But the problem is when I buy a game pass for example the speed coil game pass, it gives me every single gear that all the other game passes have.

Here is what I mean


Script In the GUI Section
local mps = game:GetService("MarketplaceService")

local gamepass_id = 0 --game pass ID

script.Parent.MouseButton1Click:connect(function()

local player = game.Players.LocalPlayer

mps:PromptGamePassPurchase(player, gamepass_id)

end)

mps.PromptGamePassPurchaseFinished:connect(function(player, id, purchased)

if id == gamepass_id and purchased then

game.ReplicatedStorage.Give:FireServer("Speed Coil!")

end

end)
Script in the ServerScriptSerivce Section
local mps = game:GetService("MarketplaceService")
local gamepass_id = 0 -- Game pass ID

game.Players.PlayerAdded:Connect(function(player)
	if mps:UserOwnsGamePassAsync(player.UserId, gamepass_id) then
		game.ServerStorage.AccelerationCoil:Clone().Parent = player:WaitForChild("Backpack")
		game.ServerStorage.AccelerationCoil:Clone().Parent = player:WaitForChild("StarterGear")
	end
end)

	game.ReplicatedStorage.Give.OnServerEvent:connect(function(player)
	game.ServerStorage.AccelerationCoil:Clone().Parent = player:WaitForChild("Backpack")
end)
2 Likes

May I ask why do you send string “Speed Coil!” meanwhile your name of speed coil looks like it is AccelerationCoil? In this scenario, it would be good to send to the server a correct name of the object so we don’t need 10 remote events for example. At your preposition, you could just fire a server and that’s it.

I named it that because the name of the game pass is speed coil and the name of the tool i am using is called AccelerationCoil

Yeah but you are not even using it on the server event function, which means it’s pretty pointless to send a string to the server and then you don’t even use it in the first place.

I don’t really understand what you mean by server event function I am still very new to scripting.

Well, this is probably not going to fix your issue but I can explain to you. While firing remote event from local script to server the first argument on server-side would always be a local player and on the second place your string for example and that goes so on.

Client side:

game.ReplicatedStorage.Give:FireServer("Speed Coil!")

Server Side:

game.ReplicatedStorage.Give.OnServerEvent:Connect(function(player,yourstring) --arguments are here
   print(yourstring) -- this is going to print 'Speed Coil!'
	game.ServerStorage.AccelerationCoil:Clone().Parent = player:WaitForChild("Backpack")
end)
1 Like

Alright thanks for trying to explain it, I will try to see what I can do to fix the problem.

Hi. Apparently, the scripts should work well…
Are you using a unique value for gamepass_id per gamepass? Make sure it is not the same for every script that gives you gear.

I am using the same scripts for each game pass but i just changed the ID for it, I also don’t understand what you mean by

Nevermind, sorry.

Maybe you (as the gamepass creator) own all of the gamepasses and thus you receive all items. Have you tried disabling all the scripts except the ones that apply to a single gamepass?

But I don’t own the game passes, so I am not sure why its giving me all the gears from the other ones. But I will try disabling the other scripts to see what happens.

Okay so I disable all the other scripts and it only gives me the speed coil, so what would I do to fix the problem when I enable all the other scripts?

Did you forget to change gamepass_id in the other Scripts inside ServerScriptService?
I can’t think of any issue other than this…

Yeah all the game pass id are different in the Scripts.

I don’t really understand how I would go about doing this. What do you mean by

This code is exploitable. Do not trust the client with information about what the user wants to equip unless there are proper checks in place. You should use MarketPlaceService to check if the user owns the gamepass required to equip the speed coil.

You shouldn’t need to use the client at all here for anything other than buying the item it’s self from a GUI.

Have you tried testing it as a player by testing through the local server (you do so by pressing the start button shown in the image below. 5HNCJ8z

It may be possible that as the game owner / creator, you are automatically given the gamepasses and therefore spawn with them all. So by testing it as “Player1” through the local server, you can check if it’s working properly or not.

1 Like

Don’t duplicate scripts and change the ids, that doesn’t work in all circumstances and it just leads to more mess when you can handle this all in one script. Change up the code over duplicating it.

One of the primary problems is that your Give RemoteEvent doesn’t have any tool parameter, so any fire of Give will always run any connected functions. There’s also a lack of server-side security here so exploiters can freely give themselves tools.

I would advise that you get rid of PromptGamePassPurchaseFinished on the client and move it to the server, as the server is allowed to use it (as far as I know). The client would then only be responsible for prompting the game pass but the server would take it from there.

If your script is only meant to be a tool giver (as in one game pass equals one tool) and you aren’t adding any other special effects or multiple tools per pass, you could also make life easier by creating a dictionary of your game passes and what tools they should be giving.

I’m willing to give you a crude code sample of what I’m talking about since you’ve already made the attempt yourself. It’s up to you to understand what I’m doing, using my words above as reference.

local Players = game:GetService("Players")
local MarketplaceService = game:GetService("MarketplaceService")
local ServerStorage = game:GetService("ServerStorage")

local GAME_PASSES = {
    [0] = "AccelerationCoil",
}

-- Did this for convenience, not really necessary though
local function giveTool(player, toolName)
    local tool = ServerStorage:FindFirstChild(toolName)

    if player and tool then
        tool:Clone().Parent = player.Backpack
        tool:Clone().Parent = player.StarterGear
    end
end

Players.PlayerAdded:Connect(function (player)
    for passId, toolName in pairs(GAME_PASSES) do
        if MarketplaceService:UserOwnsGamePassAsync(player.UserId, passId) then
            giveTool(player, toolName)
        end
    end
end)

MarketplaceService.PromptGamePassPurchaseFinished:Connect(function (player, passId, purchased)
    if purchased then
        local toolName = GAME_PASSES[passId]

        if toolName then
            giveTool(player, toolName)
        end
    end
end)

You should get the gist if you read it. You may not understand what it’s doing but read carefully; looks like English if you take some time to read each line.

4 Likes

Thank you so much! I have been trying to fix this problem for almost a week now! You are a big help :slight_smile: