RPC Client -> Server not working | Owner Problem?

Hey,

i have a problem with an RPC that goes from Client to Server.

I have a replicated ActorComponent that serves as an Inventory for several Actors in my Game.
For now, my PlayerState has one and a chest has one.

Inside of the ActorComponent, i have a replicated Array and Client to Server RPCs that are called
from the Client inside of a UMG widget. So if he drags an Item from one Slot to another, he asks
the Server to do this for him.

This works for the PlayerState Component, but not for the Chest. The Chest is calling the function,
but not the Client to Server RPC.

So i learned that a client needs to be the NetOwner of an Actor to be allowed to call RPCs from Client
to Server on it. The Chest is placed in the Scene and not spawned. Also serveral players at once can
look into the chest and use it. Even if i set the NetOwner of the Chest to the PlayerController of the
using Player, the Chest wouldn’t work for the others, would it?

I could set the owner each time a Player is swapping an item around, but i don’t think this is correct.

HOW can i manage this? All the inventory related functions are in my component. Would i need to have
functions in my Controller to get access to the Chest functions? Like passing all the data, that
i would pass to the RPC directly, to an RPC in the Controller that then calls the function in the Chest Component?

I’m not that good in NetOwner things, so i would be happy about help here ):

EDIT:

Ok, so i made an RPC in my Controller, doing the following:



void AUnknownProjectPlayerController::ServerPC_MoveItemToInventorySlot_Implementation(UInventoryComponent* _TargetInvCom, int32 _TargetSlot, UInventoryComponent* _SourceInvCom, int32 _SourceSlot)
{
	if (_TargetInvCom)
	{
		_TargetInvCom->MoveItemToInventorySlot(_TargetSlot, _SourceInvCom, _SourceSlot);
	}
}

And this gets called in the Component, instead of the replicated function that i would ran there (which does the same).

Is this a legal way to do so?

Curious about alternative ways to handle this as well, i personally just passed all the commands through the player pawn but it is not the cleanest method.

From what I’ve read (and also what I do) - passing server RPCs through the playercontroller or other structures is the standard approach

Ok thanks (: at least i am on the correct way!

Theres two ways:

  • Doing it via an already owned actor, like the PC or the pawn
  • Change the Chest actor’s net owner by calling SetOwner server-side

You could make the server change a chest’s net owner to whoever uses it.

I know that i could let the Server change the NetOwner to the PC of the user, but this would also need an RPC
and multiple users use this Chest at once. :open_mouth:

Oops, my bad for not reading fully through! I was reading on my cell. With multiple users being able to use the same chest at once, I guess I would do the same approach as you’re doing right now.

Sad to hear that as for some reason it feels dirty to me. Is this a security thing?

Yes, you can only call server RPCs on actors the server assigned to you. This rule can be used to prevent a broad range of hacks based on sending inputs your client is not allowed to send. I don’t know what is actually done though, except that a legal (non-hacked) game client would not send a server RPC for an actor it does not own.

I imagine even if a hacked client tries to send some invalid RPC, the server ignores it and could detect that something is wrong. This is just conjecture from my end though. Maybe someone else knows more about network security mechanisms in place.

No, in the sense that it’s not any more secure than other methods. It’s an architectural choice that as others have said here, makes for messy code. A cleaner, still network-secure design, would allow you to flag functions on the chest as RPC’s that would be always be sent to the server where the chest’s secure state code is handled; as a nice perk, such an RPC would implicitly contain the chest id and the player controller id which is all most object interaction rpc’s would need. In fact new interaction objects like this can be introduced without any changes to the player controller (ie good OOD). Requiring us to relay chest data through a specialized RPC on our player controller is messy indeed.

Both architectures have the same security capabilities because both run server side logic that can check what ever it wants. Both solutions are open to spam; all that changes is the RPC signature of the spam.

You already have a PlayerController, just have your RPC there. Then, while already in the server (Client -> PlayerController -> RPC) just call the methods in the Chest that are not RPC’s.

Edit: I see you mentioned this in your initial post, and it’s totally acceptable (probably the best) solution for this problem.

Hey guys and girls,

i already solved this with the PlayerController as a bridge (as most of you mentioned). Thanks for your time!
This thread is already solved for me. If you have any questions that build up on mine, feel free to ask them.

Yes, the PC can be used for this, however, it’s bad coding (see blob), forced on us by the engine architecture.

I hope Epic reinstates the ability for all objects to have server-side RPCs like they had in Unrealscript.