How to check for name changes and revert them

Hello,

I’m a solo developer working on a game, and currently in the hellish phase of working on an inventory system. Making it so that if there’s lets say a fruit on the ground, when clicking on it, a function runs that fires the name of the clicked object, in this case “Fruit” from Local > Server and then updates the players inventory. But the thing is (and please correct me if i am wrong) someone could EASILY exploit the game, find the “Fruit” item and rename it to lets say “Gold Bar” and suddenly the local side reads “Gold Bar” not “Fruit”. Is there way I could run like a for i, v in pairs or something like that for all interactable that in case they have their name changes they get set back?

Possible fixes: Putting a local script inside each object and running it there, but, exploiters could just disable that, no?

TL:DR I hate scripting because i can’t even just focus on the game, need to focus more on the ifs, ands, and buts when it comes to exploiters ruining the game.

If anybody has a suggestion for an inventory system (Really just detecting a part and sending it to server) that way exploiters can’t get whatever they want, that’d mean the world to me. Like I said, I’m a solo developer juggling building, modeling, scripting, animation, music, vfx, all of it on my own. So any and all help goes a long long way.

Regardless of what you do on the client side, it will be exploitable. You will have to fix your server side, don’t just trust the client to give you what item they are picking up, you have to check if an item that was passed is actually on the ground or not. There are a lot of checks you can do on the server to verify if it’s actually a valid item, store the dropped items in a table, check if the table has the item when picking it up, use magnitude checks, etc…
Here’s what i do when the client requests an item:

function InventoryService.Client:RequestItem(player: Player, guid: string)
	local item = workspace.DroppedItems:FindFirstChild(guid)
	if self.Server.DroppedItems[guid] ~= nil and self.Server.DroppedItems[guid].Identifier and item then
		local itemIdentifier = self.Server.DroppedItems[guid].Identifier
		if DISTANCE_CHECK(player, item, 50) then
			self.Server:addItem(player, itemIdentifier, tonumber(item:GetAttribute("Quantity")) or 1)
			self.Server:removeDroppedItem(player, guid, tonumber(item:GetAttribute("Quantity")) or 1)
		end
	end
end

When dropping it, store it somewhere, so later on you can verify whether its valid or not.

function InventoryService:createDroppedItem(player: Player, itemIdentifier: string, quantity: number)
	local itemModel = self.ItemService:GetItemModel(itemIdentifier)
	if itemModel then
		local droppedItem: BasePart = itemModel:Clone()

		local guid = generateRandomItemIdentifier()
		droppedItem.Name = guid
		droppedItem:SetAttribute("Quantity", quantity)
		droppedItem:SetAttribute("Name", itemIdentifier)

		self.DroppedItems[guid] = {
			Identifier = itemIdentifier,
			Quantity = quantity,
		}

		local quadtree = Knit.GetService("QuadtreeService"):getQuadtree()

		local playerCharacter = player.Character
		local dropPosition = playerCharacter and playerCharacter.PrimaryPart.Position + Vector3.new(0, -1.5, 0)
			or Vector3.new(0, 10, 0)

		droppedItem.CanCollide = false
		droppedItem.Anchored = true
		if droppedItem:IsA("Model") then
			droppedItem:SetPrimaryPartCFrame(CFrame.new(dropPosition))
			if quadtree then
				quadtree:insert({
					position = droppedItem.PrimaryPart.Position,
					reference = droppedItem,
				})
				print("Inserted into quadtree")
			else
				warn("Quadtree not found.")
			end
		else
			droppedItem.Position = dropPosition
			if quadtree then
				quadtree:insert({
					position = droppedItem.Position,
					reference = droppedItem,
				})
				print("Inserted into quadtree")
			else
				warn("Quadtree not found.")
			end
		end

		droppedItem.Parent = workspace.DroppedItems

		self.Client.ItemDropped:FireAll(droppedItem, quantity)
		return droppedItem
	end
end

In my example i used a Quadtree, hence why im not passing where the item was dropped, and the client can only “see” the items around them in an x meter radius, a solid way to defend against exploiters

Lmk if you have any questions

1 Like

Thanks again Lava, you also helped me out with the Mouse.Target/RunService.Stepped I was having. Thank you for actually taking the time to sit down and write this all out to help me, genuinely means the world to me. Given a few months, I’ll have something small to show you.

1 Like