Invoking The Server Is Yielding The Local Script?

I’m quite new to utilising remote functions, and using the ROBLOX API code examples, I included it in the creation of my custom admin panel, however, this has led to some problems. Using some print debugging, i was able to pinpoint the line of code that was yielding the whole script, and it was the line that was invoking the server:

local IsVerified = game:GetService("ReplicatedStorage").isVerifiedCallback:InvokeServer() --Handling On Server To Avoid Possible Bypassing Of Checks

(Ignore the comment)

Which means its an issue with my server handling, even though I can’t spot where I messed up. Section of code handling the remote function:

function ReturnVerified(Player)
	local verified = false
	for i, v in pairs(require(game.ServerStorage.allowedIDs)) do
		if Player.UserId == v then
			verified = true
		elseif Player:GetRankInGroup(groupId) >= requiredRank then
			verified = true
		else
			verified = false
		end
	end
	return verified
end

game.ReplicatedStorage.isVerifiedCallback.OnServerInvoke = ReturnVerified()

Help?

1 Like

That last line should be:

game.ReplicatedStorage.isVerifiedCallback.OnServerInvoke = ReturnVerified
--(No parentheses at end)

I believe.

1 Like

That helped, but its still yielding (I’m currently debugging again just to double check)

It’s supposed to yield because if the server didn’t return anything yet, the client has to wait for the server to return the value that the client asked for.

I know, which is why I’m returning the verified boolean. That’s what I want the local script to handle

So you fixed your issue???

Im checking right now. One second

Nope. I don’t know what is causing it. I print debugged it and it still yields at the invoke server part. Full Local script code is as followed:

local StatusFrame = script.Parent.Parent.Parent.Status
local Player = game.Players.LocalPlayer
local Notification = script.Parent.Parent.Parent.Notification
local NotificationPosition = UDim2.new(0.406, 0,.035, 0)
local ReturnPosition = UDim2.new(0.406, 0,-.2, 0)
local TableOfStrings= {
	"Configuring Settings...",
	"Communicating with other scripts...",
	"Verifying Player's eligibility...",
	"Fetching Data...",
	"Finalizing Processes...",
	"J+ Admin Configuaration Complete!"
}

script.Parent.MouseButton1Click:Connect(function()
	if not Player:WaitForChild("Verified").Value then
		for i = 1, 0.5, -.01 do
			StatusFrame.BackgroundTransparency = i
			wait(.01)
		end
		StatusFrame.TextLabel.Position = UDim2.new(0, 0,0.25, 0)
		StatusFrame.TextLabel:TweenSize(UDim2.new(1, 0,0.5, 0), Enum.EasingDirection.Out, Enum.EasingStyle.Quint, 3,false)
		for i = 1,0,-.05 do
			StatusFrame.TextLabel.BackgroundTransparency = i
			wait(.01)
		end
		wait(1)
		for indexNumber, String in pairs(TableOfStrings) do
			StatusFrame.TextLabel.Text = String
			for i = 1, 0, -.01 do
				StatusFrame.TextLabel.TextTransparency = i
				wait(.01)
			end
			wait(1.3)
			for i = 0,1, .01 do
				StatusFrame.TextLabel.TextTransparency = i
				wait(.01)
			end
		end
print("e")
		local IsVerified = game:GetService("ReplicatedStorage").isVerifiedCallback:InvokeServer() --Handling On Server To Avoid Possible Bypassing Of Checks
		if IsVerified then
			print("e")
			game.ReplicatedStorage.updateLoggedInVal:FireServer(true)
			StatusFrame.TextLabel.Text = "Welcome To J+ Admin "..Player.Name.."!"
			for i = 1, 0, -.01 do
				StatusFrame.TextLabel.TextTransparency = i
				wait(.01)
			end	
			wait(3)
			for i = 0,1, .01 do
				StatusFrame.TextLabel.TextTransparency = i
				wait(.01)
			end
		else
			StatusFrame.TextLabel.Text = "Sorry, but you do not have the permission to access J+ Admin, Please Contact The Administrator"
			Notification.TextLabel.Text = "Verificaition Failure"
			Notification:TweenPosition(NotificationPosition, Enum.EasingDirection.In, Enum.EasingStyle.Quint,2,false)
			wait(4)
			Notification:TweenPosition(ReturnPosition, Enum.EasingDirection.Out, Enum.EasingStyle.Quint,2, false)
			for i = 1, 0, -.01 do
				StatusFrame.TextLabel.TextTransparency = i
				wait(.01)
			end	
			wait(3)
			for i = 0,1, .01 do
				StatusFrame.TextLabel.TextTransparency = i
				wait(.01)
			end
		end
		StatusFrame.TextLabel:TweenSize(UDim2.new(0, 0,0.5, 0), Enum.EasingDirection.In, Enum.EasingStyle.Quint, 3, false)
		for i = 0,1, .01 do
			StatusFrame.TextLabel.BackgroundTransparency = i
			wait(.01)
		end
		for i = 0.5, 1, .01 do
			StatusFrame.BackgroundTransparency = i
			wait(.01)
		end
		--// A lot of tweening //--
		game.ReplicatedStorage.promptNotification:Invoke("Successfully Verified "..Player.Name.."!",4)
		wait(2)
		game.ReplicatedStorage.promptNotification:Invoke("Loading Admin Gui!",3)
		wait(2)
		script.Parent.Parent.Parent.MainAdminGui.Visible = true
		print("Ran Script Successfully")
	else
		game.ReplicatedStorage.promptNotification:Invoke("Loading Admin Gui!",3)
		wait(4)
		script.Parent.Parent.Parent.MainAdminGui.Visible = true

	end

end)

Wait. Is it yielding forever? Or just until the server returns a value?

For ever, It never changes the text label text, for some reason

Hmm. You could use prints to see where the script gets stuck at.

Ill try using them on the server script too

Alright. If you find where the script gets hung up at, post a reply to the topic so we can help you fix it.

1 Like

You’re requiring that module all the time that RemoteFunction is invoked. Why don’t you have it cached ?

local AllowedIDs = require(game.ServerStorage.allowedIDs);
function ReturnVerified(Player)
if table.find(AllowedIDs, Player.UserId)  or Player:GetRankInGroup(groupId) >= requiredRank then
return true; --// we don't need a loop.
end;
return false;
end

game.ReplicatedStorage.isVerifiedCallback.OnServerInvoke = ReturnVerified
1 Like

For some reason, it isn’t calling the function linked to the remote function on the server side

You could just do

game.ReplicatedStorage.isVerifiedCallback.OnServerInvoke = function(Player)
    	local verified = false
	    for i, v in pairs(require(game.ServerStorage.allowedIDs)) do
		if Player.UserId == v then
			verified = true
		elseif Player:GetRankInGroup(groupId) >= requiredRank then
			verified = true
		else
			verified = false
		end
	end
	return verified
end

See if that makes any difference.

1 Like

That does not help at all, that’s not the problem there, besides, this is bad, you’re looping through all numbers and doing useless checks over and over again + you’re requiring the module every time the RemoteFunction is Invoked, so this is overall bad. Don’t do that.

1 Like

Also, one thing that I did notice is, you should break out of the loop once you have already set verified

	local verified = false
	for i, v in pairs(require(game.ServerStorage.allowedIDs)) do
		if Player.UserId == v then
			verified = true
            break
		elseif Player:GetRankInGroup(groupId) >= requiredRank then
			verified = true
            break
		else
			verified = false
            break
		end
	end
	return verified
1 Like

Trying that proved to be ineffective, but thank you for simplifying it for me, I didnt notice a loop was unnecessary

OP, I read your code and it looks like you’re trying to do this for security, well, this can still be bypassed by exploiters by simply hooking remote function’s InvokeServer and make it return true whenever you call it from client. Remember one thing, exploiters own the client, anything there can be modified. You have to rely on server.

When an admin joins the server, give them the admin ui from server using a remote event (fire client to open the admin ui), besides, every action should be checked on server-side and make sure that player is able to execute that action (eg ban, requires x permission).

2 Likes