I need help with moving clienside variables to the server!

Hello :slight_smile: I’m trying to write a ULX command that will prompt a player to press a button to prove that they aren’t AFK. If they press the button, nothing happens. If they don’t press the button with some amount of time(20seconds ish), they get kicked for afk.

I have the Derma panel working 100%, and the ULX command works also. The issue I’m having is that a variable(X) I’m trying to define by entering a console command is only set clientside, but I want to set it serverside. There clearly is a simple answer/workaround, but I’m just not seeing it.

Here’s what I have currently:



function ulx.cafk( calling_ply, target_plys )	
	for _, v in ipairs( target_plys ) do
		v:ConCommand( "afkcheck" )
			timer.Simple( "afkkick", 3, afkkickfunction )
		end
		
	end

function afkkickfunction()
	if x == 1 then
	print("it works")
	end
	
	if x != 1 then
	print(x)
	PrintMessage( HUD_PRINTTALK, "fuck youuuu" )
	--v:Kick("AFK")	
	end
end
	
function timerstop()
x = 1
end

local cafk = ulx.command( CATEGORY_NAME, "ulx cafk", ulx.cafk, "!cafk" )
cafk:addParam{ type=ULib.cmds.PlayersArg }
cafk:defaultAccess( ULib.ACCESS_ADMIN )
cafk:help( "Checks if the target(s) is/are AFK and kicks them if they are." )

if CLIENT then
function afkcheck()
local afkcheck = vgui.Create( "DFrame" )
local nobutton = vgui.Create( "DButton" )
afkcheck:SetPos( ScrW()/2-225, ScrH()/2 - 100 )
afkcheck:SetSize( 450, 200 )
afkcheck:SetTitle( "Are you AFK?" )
afkcheck:SetVisible( true )
afkcheck:SetDraggable( true )
afkcheck:ShowCloseButton( true )
afkcheck:MakePopup()

nobutton:SetParent( afkcheck )
nobutton:SetText( "No!" )
	nobutton.DoClick = function()
	afkcheck:Remove()
	RunConsoleCommand("timerstop")
	end
nobutton:Center()
nobutton:SetSize( 150, 50 )

end
end
if CLIENT then 
concommand.Add( "afkcheck", afkcheck ) 
concommand.Add( "timerstop", timerstop )
end


Keep in mind this will not error. It simply prints fuck youuuu every time, wether you press the button or not.

What is ‘x’ when you print it in the afk function?

It’s nil. That’s the problem. I’m defining it in the function timerstop, but that function is run clientside and I can’t seem to get it to run serverside for the life of me.

If you’re trying to get it serverside, then network it.

I was reading this page http://maurits.tv/data/garrysmod/wiki/wiki.garrysmod.com/indexbd9b.html

and the only thing they say about client to server is that i should “use console commands” but i have no idea what that means, especially since console commands are only running clienside functions for me anyways.

You can use the net library to send information from the client to the server.

Don’t use console commands as people will figure it out and just spam it or something to prevent being kicked. Or create something to run it automatically every minute.

Ok I tried to use net library to send the value to the server but I always ended up getting the error
"[ERROR] addons/ulx/lua/ulx/modules/sh/pyroutilmod.lua:381: Calling net.Start with unpooled message name [http://goo.gl/qcx0y]
"

Here’s my code:



if SERVER then util.AddNetworkString( "X" ) end


function ulx.cafk( calling_ply, target_plys )	
	for _, v in ipairs( target_plys ) do
		v:ConCommand("afkcheck")
		timer.Create( "afkkick",3, 1, afkkickfunction )
		end
		
	end
function timerstop()
local fl = 1
net.Start( "X" )
net.WriteFloat( fl )
net.SendToServer()
end

function afkkickfunction()
	net.Receive( "X", function()
		x = net.ReadFloat()
	end)
	if x == 1 then
	print("it works")
	end
	
	if x != 1 then
	print(x)
	PrintMessage( HUD_PRINTTALK, "fuck youuuu" )
	--v:Kick("AFK")	
	end
end

local cafk = ulx.command( CATEGORY_NAME, "ulx cafk", ulx.cafk, "!cafk" )
cafk:addParam{ type=ULib.cmds.PlayersArg }
cafk:defaultAccess( ULib.ACCESS_ADMIN )
cafk:help( "Checks if the target(s) is/are AFK and kicks them if they are." )

if CLIENT then
function afkcheck()
local afkcheck = vgui.Create( "DFrame" )
local nobutton = vgui.Create( "DButton" )
afkcheck:SetPos( ScrW()/2-225, ScrH()/2 - 100 )
afkcheck:SetSize( 450, 200 )
afkcheck:SetTitle( "Are you AFK?" )
afkcheck:SetVisible( true )
afkcheck:SetDraggable( true )
afkcheck:ShowCloseButton( true )
afkcheck:MakePopup()

nobutton:SetParent( afkcheck )
nobutton:SetText( "No!" )
	nobutton.DoClick = function()
	afkcheck:Remove()
	timerstop()
	end
nobutton:Center()
nobutton:SetSize( 150, 50 )

end

concommand.Add( "afkcheck", afkcheck ) 
concommand.Add( "timerstop", timerstop )
end


Use the tutorial here. You must declare the message name serverside before you use it (either serverside or clientside):
[lua]util.AddNetworkString( “msg_name” )[/lua]

I did that already and am still getting the error :frowning: look at the top of my code.

I’ve seriously been at this for hours haha, does anyone have any ideas?

You have to do the util.AddNetworkString SERVER-side. Not CLIENT-side.

Make sure it’s not a protected name. You can make them as long as you like, be descriptive with your message names. They’re put into a hash table if I recall correctly so they’re compressed to 1, 2 or 3 length integer or something like that…

Grr this is so frustrating. Look at the code i’ve written! It’s write at the top there!



if SERVER then util.AddNetworkString( "X" ) end


I still get the error saying that I don’t have that there.

Edit: I had to change the name of the string to something other than “X”. I guess that stringname doens’t work for some reason.

Anyways I still don’t get how to get the variable across, fl is still returning nil.

Where exactly does it return nil? Post your code and put print(fl) where it is nil.

Here: the code:



if SERVER then util.AddNetworkString( "pyro_afkkick" )
end

function ulx.cafk( calling_ply, target_plys )	
	local pyro_afkkicktable = {}

	for i=1, #target_plys do
		local v = target_plys[ i ]
		if not v:Alive() then
			ULib.tsayError( calling_ply, v:Nick() .. " is dead! Some players go AFK when they die, try checking next round.", true )
		else
			v:ConCommand("afkcheck")
			timer.Create( "afkkick",3, 1, afkkickfunction )
			table.insert( pyro_afkkicktable, v )
			
		end
	end
		
	end
	

function timerstop()
local fl = 1
net.Start( "pyro_afkkick" )
net.WriteFloat( fl )
net.SendToServer()
print("timerstop ran correctly")
end

function afkkickfunction()

	net.Receive( "pyro_afkkick", function()
	local fl = net.ReadFloat()
	print( "the value below is the value of fl right after net.recieve
" )
	print( fl ) --returns 1
	end)
	
	if fl == 1 then
	print("it works")
	return
	end
	
	if fl != 1 then
	print( "this is the value of fl when the logic is evaluated" )
	print( fl ) --returns nil
	PrintMessage( HUD_PRINTTALK, "fuck youuuu" )
	--v:Kick("AFK")	
	end
	
end

local cafk = ulx.command( CATEGORY_NAME, "ulx cafk", ulx.cafk, "!cafk" )
cafk:addParam{ type=ULib.cmds.PlayersArg }
cafk:defaultAccess( ULib.ACCESS_ADMIN )
cafk:help( "Checks if the target(s) is/are AFK and kicks them if they are." )

if CLIENT then



function afkcheck()
local afkcheck = vgui.Create( "DFrame" )
local nobutton = vgui.Create( "DButton" )
afkcheck:SetPos( ScrW()/2-225, ScrH()/2 - 100 )
afkcheck:SetSize( 450, 200 )
afkcheck:SetTitle( "Are you AFK?" )
afkcheck:SetVisible( true )
afkcheck:SetDraggable( true )
afkcheck:ShowCloseButton( true )
afkcheck:MakePopup()

nobutton:SetParent( afkcheck )
nobutton:SetText( "No!" )
	
	nobutton.DoClick = function()
	afkcheck:Remove()
	timerstop()
	end
nobutton:Center()
nobutton:SetSize( 150, 50 )

end

concommand.Add( "afkcheck", afkcheck ) 
concommand.Add( "timerstop", timerstop )
end


So you run the command by the chat hook, !cafk “playername”

At that point then it runs a console command on all the target players and starts the clientside portion which displays the vgui panel. At the same time it starts a timer that will run the kick function if fl doesn’t == 1. When you click on the button it’s supposed to simply set fl to == 1.

I’m also trying to send information from the client to the server, because I’m using a TextEntry. I’m trying to use the net library and cannot get it to work either, can someone tell me what I’m doing wrong here?

Init:
[LUA]util.AddNetworkString(“TextEntry”)
net.Receive(“TextEntry”, function() TheTextEntry = MsgN(net.ReadString()); PrintMessage(3, MsgN(net.ReadString())) end)[/LUA]

cl_init:
[LUA]Slot1Button.DoClick = function() net.Start(“TextEntry”); net.WriteString(TextEntry:GetValue()); net.SendToServer(); RunConsoleCommand(“Loadout1”) end[/LUA]

[ERROR] gamemodes/islanddm/gamemode/init.lua:405: bad argument #2 to ‘PrintMessage’ (string expected, got no value)

You’re using MsgN as the second argument which does not return a value as it’s a print statement. You’ve essentially got a print statement within a print statement, just one shy of total-inception if I recall correctly. Remove MsgN( and a ) right on the otherside of the ReadString for that error.

What error are you receiving in post 14?

Am I screwed?

That worked thank you. I was just going by the wiki and that appeared to be the way to do it from the example it gives.

Oh my, I’m so sorry. I didn’t realize narpuppy hijacked your thread :frowning:

What’s the current error? What’s the current problem with the code you posted?

Ok I’ll post my most recent code and give you an up to date info on how it works and how I want it to work.




if SERVER then util.AddNetworkString( "pyro_afkkick" )
end

function ulx.cafk( calling_ply, target_plys )	
	local pyro_afkkicktable = {}

	for i=1, #target_plys do
		local v = target_plys[ i ]
		if not v:Alive() then
			ULib.tsayError( calling_ply, v:Nick() .. " is dead! Some players go AFK when they die, try checking next round.", true )
		else
			v:ConCommand("afkcheck")
			timer.Create( "afkkick",3, 1, afkkickfunction )
			table.insert( pyro_afkkicktable, v )
			
		end
	end
		
	end
	

function timerstop()
local fl = 1
net.Start( "pyro_afkkick" )
net.WriteFloat( fl )
net.SendToServer()
print("timerstop ran correctly")
end

function afkkickfunction()

	net.Receive( "pyro_afkkick", function()
	local fl = net.ReadFloat()
	print( "the value below is the value of fl right after net.recieve
" )
	print( fl ) --returns 1
	end)
	
	if fl == 1 then
	print("it works")
	return
	elseif fl ~= 1 then
	print( "this is the value of fl when the logic is evaluated" )
	print( fl ) --returns nil
	PrintMessage( HUD_PRINTTALK, "fuck youuuu" )
	--v:Kick("AFK")	
	end
	
end

local cafk = ulx.command( CATEGORY_NAME, "ulx cafk", ulx.cafk, "!cafk" )
cafk:addParam{ type=ULib.cmds.PlayersArg }
cafk:defaultAccess( ULib.ACCESS_ADMIN )
cafk:help( "Checks if the target(s) is/are AFK and kicks them if they are." )

if CLIENT then



function afkcheck()
local afkcheck = vgui.Create( "DFrame" )
local nobutton = vgui.Create( "DButton" )
afkcheck:SetPos( ScrW()/2-225, ScrH()/2 - 100 )
afkcheck:SetSize( 450, 200 )
afkcheck:SetTitle( "Are you AFK?" )
afkcheck:SetVisible( true )
afkcheck:SetDraggable( true )
afkcheck:ShowCloseButton( true )
afkcheck:MakePopup()

nobutton:SetParent( afkcheck )
nobutton:SetText( "No I'm not AFK Pyro you ignorant cunt! Jesus fucking christ what do you think I am?
 Some sort of animal? Well I have news for you fuckface, I have news for you.
A storms coming, maggot, a storm you've never seen before. 
I'll fuck you up so hard you'll wish down was up and you were your mother, bitch." )	
nobutton.DoClick = function()
	afkcheck:Remove()
	timerstop()
end
nobutton:SetSize( 450, 180 )
nobutton:SetPos( 0, 20 )
end

concommand.Add( "afkcheck", afkcheck )
end


There’s my code. It’s supposed to be a ULX command that will prompt a player with a button to press asking them if they are AFK. If they press the button, then they are assumoned not afk, and nothing happens. However if they don’t press the button, then they are kick for AFK.

Currently I use the base ULX setup(I want it to be fully integrated into my servers current ULX menu) for a command, and gathering players. From there I invoke a console command on each player to bring up the vgui menu, and simultaneously start a timer that, upon completing, will run a function that dictates if they are to be kicked or not.

The vgui menu is invoked clientside, it really is nothing more than a big button. Upon pressing the button ,the player destroys the menu and runs a clienside function. This clientside function sets a variable ( fl ) to be equal to 1. I then use net.send to send that variable to the server. After some period of time, the timer expires and runs the logic. If fl is equal to 1, then they aren’t kicked because they mus have pressed the button. If fl is equal to anything other than 1, then they are kicked, because fl was never defined if the button was never pressed.

Currently the issue I have is that while fl is defined directly after the net.recieve function, as soon as the variable enters the logic portion of the timer function, it seems to become undefined and I have no idea how to keep it defined.

I tried to be as explanatory as I could. If you have any questions please do post them here, I’m practically fingering the F5 key like it’s Emma Watson.