Remote function isnt working?

Im trying to use a remote function for a value check but it keeps thinking “emote” is the player aswell?

local emotecheck =script.Parent.RemoteFunction:InvokeServer(game.Players.LocalPlayer,emote)

script.Parent.RemoteFunction.OnServerInvoke = function(plr,emote)
	local emote = plr:WaitForChild("FavoriteEmotes"):WaitForChild(emote.Name).Value
	repeat wait(0.3) until emote ~= nil
	emote = plr:WaitForChild("FavoriteEmotes"):WaitForChild(emote.Name).Value
	return emote
end
2 Likes

when passing a local event/function to ther server, the first parameter for the server will automaitcally be the player, because it knows who sent the event/function. You should not give the player from the local script.

Locally you should write:

local emotecheck =script.Parent.RemoteFunction:InvokeServer(emote)

Hopefully this fixes the issue.

1 Like

I had tried this before unfortunately, and it reads that argument 1 is missing or nil

1 Like

That’s because emote is nil, Try to declare it in the local script instead.

1 Like

i already had this before though

		if emote.Value ~= "" or nil then
			local emotecheck = script.Parent.RemoteFunction:InvokeServer(emote)
2 Likes

If it’s the player that is nil, then I have no clue. It’s likealy a scoping error then, which is kind of impossible to fix with just that piece of code.

If it’s the emote that is nil then:
It may be because you’re passing a type of instance that is not allowed to be passed.
For example I tried passing my sounds once, and apparently Roblox cannot pass all instance types.

So instead of directly passing the emote, you could pass the emote’s name or any sort of identification, and then loop through the emotes on the server to find the emote based on the passed identification value.


script.Parent.RemoteFunction.OnServerInvoke = function(plr,emoteName)

	local choosenEmote = nil
	local emotesTable = plr:WaitForChild("FavoriteEmotes"):GetChildren()
	
	for index,emote in pairs(emotesTable) do
	
		if emote.Name == emoteName then
			
			choosenEmote = emote
			
		end
		
	end

	return choosenEmote

end
1 Like

the second condition or nil is incorrect, Its like doing:

if nil then -- checks if nil and returns false

what you should do instead:

if emote.Value ~= "" and emote.Value ~= nil then -- checks if emote.Value isn't "" and nil

Hope this helps.

2 Likes

So I took what you said and it kinda works, I did emote…Name when invoking the server and it runs, but instead of it using the emotes name its using the emotes value?

2 Likes

I just changed it i appreciate it

2 Likes

It should be emote.Name on the client’s invoke parameter.

If it’s already that, then Idk.
You could print inside of the loop to see what it’s doing.

2 Likes

so basically im getting all the emotes in pairs, and from there each of them gets checked, I ran the print and it ran with the emotes name so im not sure

I’m not sure if you mean that the loop finds the choosen emote correctly.
If it does choose it correctly, then maybe the return cannot pass the value back to the client, due to the Roblox limitiations.

Now they’re limitations for a reason:
When you’re doing this remoteFunction call, you’re actually just getting the same emote value as you originally had in your client. And your client decides the value anyway, so the player can still cheat. I’m assuming this is supposed to be an anti-cheat? It’s a bit difficult to suggest what to do when you are basically returning the same value that has been sent.

Could explain what you’re trying to achieve?

	local emotes = game.Players.LocalPlayer:WaitForChild("FavoriteEmotes"):GetChildren()

	for i, emote in pairs(emotes) do
		
		local newSector = script:WaitForChild("SectorPivot"):Clone()
		newSector.Sector.Size = UDim2.new(sectorWidth, 0, 0.5, 0)
		
		local rotation = (i-1) * (360/count)
		
		newSector.Rotation = rotation
		
		newSector.Sector.ImageTransparency = 1
		
		if emote.Value ~= "" and emote.Value ~= nil then
			local emotename = emote.Name
			print(emote.Name)
			local emotecheck = script.Parent.RemoteFunction:InvokeServer(emotename)

You could instead return someting like “true” or "false.

yeah its kinda of a anti-cheat, because players can pick and choose anything on their client I figured if i check the server on this before it loads itll stop it, but its not working out that way

Yeah, you’re not really checking on the server, just getting the value and then attempting to return it, which doesn’t do anything.

Instead, you should run conditional checks on the server after the choosen emote’s value is not nil (after the loop has run). Then return true if the player is allowed to emote, and return false if they’re not allowed. Or invoke the client with true / false.

Now, this may not be cheat proof either, since the player may be able to write their own code on the client to emote (I don’t know how it works exactly). You would instead want to run the emote code that comes after the local emotecheck = script.Parent.RemoteFunction:InvokeServer(emotename) on the server.

By running it on the server, the player’s only input is the emote itself, which means that they won’t be able to play it if you keep the rest of the emote logic on the server. Like if the player needs a certain amount of stamina to emote, you can define the stamina on the server.

If you want extra security, then you should not pass the emote’s name, but rather just the input itself and then handle it on the server. If input = 1 then check the player’s emote folder and see their 1 value. This should effectively make it so that players can still cheat the input (that’s how it is in Roblox), however they can only play the emotes that is on their emote list.

Long story short: You cannot prevent cheating if your conditional code and the core variables like the emote’s idenfitication is on the client.

1 Like

An example of this is my Home Button system.
If the player clicks the home button, the player teleports.
The conditions for activating the teleport is on the server, and when I return to the client, the only thing the client does is use it for client sound, which we don’t mind being cheated.

– Local

--Home button teleports player
local canTeleportHome = otherstats:WaitForChild("canTeleportHome")

homeButton.MouseButton1Up:Connect(function()
	
	local result = homeButtonFunction:InvokeServer()
		
	if result == false then
		
		homeFailSound:Play()
		
	end
	
end)

local function colourHomeButton()
	
	if canTeleportHome.Value == true then

		homeButton.BackgroundColor3 = Color3.fromRGB(100,254,66)

	elseif canTeleportHome.Value == false then
		
		homeButton.BackgroundColor3 = Color3.fromRGB(200,200,200)

	end
	
end

colourHomeButton()

canTeleportHome:GetPropertyChangedSignal("Value"):Connect(function()
	
	colourHomeButton()
	
end)

–Server

homeButtonFunction.OnServerInvoke = (function(recievedPlr)

	--print("ran for",recievedPlr)
	
        local character = recievedPlr.Character or recievedPlr.CharacterAdded:Wait()
	local hrp = character:WaitForChild("HumanoidRootPart", 1)
	if not hrp then return false end

	local otherstats = recievedPlr:WaitForChild("otherstats")
	local canTeleportHome = otherstats:WaitForChild("canTeleportHome")
	local homeCooldown = otherstats:WaitForChild("homeCooldown")

	if canTeleportHome.Value == false then return false end

	canTeleportHome.Value = false

	local homePart = character:FindFirstChild("HomePart")
	local emitter = RS:WaitForChild("HomeEmitter"):Clone()
	emitter.Parent = homePart

	task.wait(3)

	emitter:Destroy()
	hrp.CFrame = spawnPart.CFrame

	task.wait(0.25)

	savePositionBindEvent:Fire(recievedPlr)

end)

The original issue should be solved by returning a valid value for your remoteFunction result.
Such as “true” or "false.
That is basically what I do in my example.
Of course this would only make sense if you run conditional checks on the server, and only use the returned value for things like sounds or UI popup errors example: “not enough stamina to emote”.

1 Like

When invoking a remote function or remote event, player is ALWAYS the first argument.
Therefore, just remove the “game.Players.LocalPlayer” on the client side and that will fix your problem!

1 Like