Server, player, Shared, GetNWInt, What is the deal?

Hi (back)!

I have one question that I couldn’t find an explanation with the search button, i think i’m not the only one asking:

What is the difference between making some money system clientside, serverside, shared?

For example here is a bit of code: (simple money system)




function cnr_getmoney(ply)
	return ply:GetNWInt("money")
end

function cnr_setmoney(ply,amount)
	ply:SetNWInt("money",amount)
	cnr_saveply(ply) -- Sql save
end

function cnr_addmoney(ply,amount)
	if amount > 0 then
		cnr_setmoney(ply,cnr_getmoney(ply) + amount)
	else
		cnr_error(ply,"amount invalid") -- ply:ChatPrint the error to the player
	end
end

function cnr_pay(giver,receiver,amount)
	if cnr_getmoney(giver) >= amount then
		cnr_rmvmoney(giver,amount) -- cnr_rmvmoney is the same as cnr_addmoney
		cnr_addmoney(receiver,amount)
	else
		cnr_error(giver,"not enough money")
	end
end

concommand.Add("givemoney", cnr_ply_pay)

function cnr_firsttime(ply)
	cnr_setmoney(ply,money_start)
end



Why should some function be run only by server, player or shared? Which one? And why?

My cnr_error should be clientside, but if it is in serverside code how does it work?

Should I better use ply:SetPData? What is the difference between NWInt and PData?

Anything dealig with money should be serverside as often as possible and rely on as little clientside trust as possible. Anything on the client could be tampered with and so you should treat it as such. SetPData saves data for that player on the server’s SQL server so it persists over games and maps while SetNW* will vanish on a map change or server restart

When it comes to data handling, never trust the client. :slight_smile:
People will always try to find exploits to get money etc.
So it’s pretty much as Exho said.

Ok! but still one other thing:

i set all my function serverside, but I need to show people their money.

So I create another function cnr_getplymoney, which is client side, and does a GetNWInt, BUT i still have one error



[ERROR] gamemodes/cnr/gamemode/cnr/cl_hud.lua:168: attempt to call global 'cnr_getplymoney' (a nil value)
  1. v - gamemodes/cnr/gamemode/cnr/cl_hud.lua:168
   2. unknown - lua/includes/modules/hook.lua:84


tryed with GetPData, but still no luck :frowning:

alrighttt let me magically zoom into your code and see what the problem is…

no seriously we need the code

here is the full code:

money.lua, serverside




-- Variables
money_start = 100 -- amount of money new player start with



-- Server Function

function cnr_setmoney(ply,amount)
	ply:SetNWInt("money",amount)
-- ply:SetPData("money",amount) This break my givemoney command 
	cnr_saveply(ply)
end

function cnr_addmoney(ply,amount)
	if amount > 0 then
		cnr_setmoney(ply,cnr_getmoney(ply) + amount)
	else
		cnr_error(ply,"amount invalid")
	end
end

function cnr_rmvmoney(ply,amount)
	local money = cnr_getmoney(ply)
	if amount > 0 then
		if money - amount >= 0 then
			cnr_setmoney(ply,cnr_getmoney(ply) - amount)
		else
			cnr_error(ply,"not enough money")
		end
	else
		cnr_error(ply,"amount invalid")
	end
end

function cnr_pay(giver,receiver,amount)
	if cnr_getmoney(giver) >= amount then
		cnr_rmvmoney(giver,amount)
		cnr_addmoney(receiver,amount)
	else
		cnr_error(giver,"not enough money")
	end
end

function cnr_ply_pay(ply,cmd,args)
	local receiver = ply:GetEyeTrace().Entity
	if !receiver:IsPlayer() then -- ENLEVER LE ! APRES LES TESTS
		cnr_pay(ply,receiver,tonumber(args[1]))
	else
		cnr_error(ply,"must be looking at a player")
	end
end

function cnr_firsttime(ply)
	cnr_setmoney(ply,money_start)
end

hook.Add("cnr_plyfirstconnexion","Money ply first connexion", cnr_firsttime)

concommand.Add("givemoney", cnr_ply_pay)


function cnr_getmoney(ply)
	return ply:GetNWInt("money")
end




cl_money.lua, clientside



function cnr_getplymoney(ply)
	return ply:GetNWInt("money")
end


I Believe the problem isn’t the coding itself, but surely I missed something with client-server interaction!

Hud (clientside) use cnr_getplymoney(LocalPlayer()) to get the money information

also, using SetPData() break my givemoney command



[ERROR] gamemodes/cnr/gamemode/cnr/money.lua:10: attempt to call method 'SetPData' (a nil value)
  1. cnr_setmoney - gamemodes/cnr/gamemode/cnr/money.lua:10
   2. cnr_addmoney - gamemodes/cnr/gamemode/cnr/money.lua:16
    3. cnr_pay - gamemodes/cnr/gamemode/cnr/money.lua:38
     4. unknown - gamemodes/cnr/gamemode/cnr/money.lua:47
      5. unknown - lua/includes/modules/concommand.lua:54


Snip

Don’t snip man! I saw what you did!
And don’t laugh, but because of you I have found a fix that work! \o/ (but I still don’t understand why)

my clientside files, ive made it sharedside and now it work

if someone can explain me! :slight_smile:

make sure how you call functions is right, as in make sure it’s serverside when you call a serverside func and so on