Multiplayer Inventory - how to prevent cheating?

I think (but not 100% sure) if the information are in the PlayerState they can ONLY be modified by the authority. The clients can only “read” it.
Another thing is don’t hesitate to make the server check everything. For example, when you pick up an item or fire on someone only get trace hit on the client and send it on the server. The server will check if it is possible (position of the player and is the item there etc) then the server will make changes on his side (they will be replicated with the playerstate) and it will send an event to the client to say “hey, you have been updated at multiple places look it up”.

First, let me explain how I currently have my inventory setup…

(PlayerController) Player hits F key → PickupItem Custom Event in PlayerBP (Run on Server)

(PlayerBP) Grabs item info → cast to playerState → Add item info into inventory array → cast to PlayerController → UpdateInventory (Run on Owning Client)

(PlayerController) Cast to inventory widget → UpdateInventory (Widget)

48895-33.png

(Widget) Now, this is where I grab the InventoryInfoArray from playerState, and I use this information to create the inventory UI (buttons, icons, stat information, etc…)

Is this all correct? My concern is this… If I am feeding the InventoryInfoArray (from playerState) to the client, so client can update his UI… Can a cheater not interfere with this information? Can a cheater get, say, his HP from playerState and change it?

I clearly don’t understand how cheating fundamentally works… It’s a huge road block right now, because I don’t want to develop anymore until I know for sure I am doing the best anti-cheat possible.

(If screenshots are too small open in new tab)

So, does this mean if I try to have a client change a variable in playerState it won’t be able to?

I just tried, and the client was able to change a variable, unless I misunderstood something

Just judging from your comment, clearly I didn’t do it correctly. For one, I didn’t use authority switch. Here’s what I did:

Well, a screenshot would certainly help. I actually did what you said before you commented and it was still getting changed. That was without the Switch Has Authority though… Still not sure what those do/are for. Also, I had to cast to my playerState otherwise I couldn’t access the variable.

Here’s what I have, right now, it doesn’t work. As in, “J” doesn’t print anything, because it doesn’t go through the switch.

Was it replicated ? Because I just tested.
I set it on the client (SwitchAuthority->remote to be sure) and then checked all the PlayerState in the server to see if it was updated (it wasn’t).

Can you show me where you change it on the client ?

I see so you are writing and reading the same variable in the BP on the same client.

Let’s try that in the PlayerController :

H->SwitchAuthority(remote)->Cast to RPGPlayerState->Set the variable

J->SwitchAuthoriy(Authority)->get GameState->ForEach (Players Array of game state)->print string (the variable)

Press H in the client windows and then press J in the server window.

Do you need me to take a screenshot of a blueprint or is it comprehensible ?

I think I see the issue.

SwitchAuthority is a switch that will execute Remote if you are a client and Authority if you are a server.

This means if you pressed J in the client window nothing happened because the switch went to authority and not remote.

Do you have a server window and a client window ?

You should press the H when using the client window and the press j when using the server window.

First of all “Run On server” is for replicated event it means that it will be run on the server (you don’t need to use switch authority).

If you want to run something on the server from a client you need to use a replicated event “Run on server” and the server can use “Multicast” to execute the event everywhere (on the server too) and “Run on client” to run on a specific client.

As for the speed changing it should not change a thing because if you don’t want people to cheat you should check the movement of player on the server. This means that the player pressed “forward” and told the server and the server updated the position that is replicated to all clients.

Do you get what I mean ?

Ahh! Oh course, I should have known to check on the server… So, it seems the variable gets changed on the client, but printing all player states on the server shows all set to “0”.

So, am I supposed to be using Authority Switches for… everything? Would “Run on Server” be the same as “Switch → Authority”?

If a cheater were to somehow create a way to change a variable… It would only be valid in his client, right? But isn’t the enough? For example, if the cheater changed his Speed variable… Wouldn’t he be faster? Or, changed his damage variable, more damage… Etc…

I’m starting to understand. Thank you!

Yes, I do understand. Thanks!

I have successfully done a lot in multiplayer, in terms of getting things functionally working, i.e picking items up, full inventory support, dropping items, damaging things, etc…

However, clearly I am not setup for anti-cheat, and I will still have a hard time of it because I still lack a fundamental understanding of how server/client relationship works, as well as the capabilities of cheaters.

But, I’ve learned a lot today. Thanks again!