Search code examples
c#network-programmingmultiplayer

What is the correct way to use RPCs in C# LiteEntitySystem


I am trying to use RPCs to notify the Server in "LiteEntitySytem.PawnLogic" class that setup has been completed in the Client.

I tried calling the method called NotifyServerThatSetupHasCompleted() from the client.

I expected the Server to have been notified. But the server was not notified. This is the code I used

//Server
using LiteEntitySystem;


public class BaseNetworkNPC : PawnLogic
{
    private bool hasSetupCompleted = false;
    private static RemoteCall setupCompletedRPC;

    public BaseNetworkNPC(EntityParams entityParams) : base(entityParams)
    {

    }

    protected override void RegisterRPC(ref RPCRegistrator r)
    {
        base.RegisterRPC(ref r);
        r.CreateRPCAction(this, SetupCompleted, ref setupCompletedRPC, ExecuteFlags.ExecuteOnServer);
        Debug.WriteLine("Registered setupCompletedRPC.");
    }

    protected override void Update()
    {
        base.Update();
        if (!hasSetupCompleted) return;
        FSMTick();
    }

    private void FSMTick()
    {
        Debug.WriteLine("FSMTicking");
        stateTimer += EntityManager.DeltaTimeF;
    }

    protected override void OnDestroy()
    {
        base.OnDestroy();
    }

    public void SetupCompleted()
    {
        Debug.WriteLine("Setup completed RPC triggered on the server.");
        hasSetupCompleted = true;
    }

    public void NotifyServerThatSetupHasCompleted()
    {
        if (EntityManager.IsClient)
        {
            Debug.WriteLine("Client is notifying server that setup has completed.");
            ExecuteRPC(in setupCompletedRPC);
        }
    }
}
//Client
internal class Client
{
    public void OnPeerConnected(NetPeer peer)
    {
        Server = peer;

    // Initialize ChatSystem with the connected server peer
    //_chatController.Initialize(Server);

    //I dont think this is needed because upon joining the API returns everything and the server knows where to place them
    //NetworkHelpers.SendPacket(Server, _writer, _packetProcessor, PacketType.Serialized, new ServerRequestPacket { RequestType = RequestType.StarSystem }, DeliveryMethod.ReliableOrdered);

        NetworkHelpers.SendPacket(
            Server,
            _writer,
            _packetProcessor,
            PacketType.Serialized,
            new JoinPacket
            {
                username = LoginVariables.Email,
                password = LoginVariables.Password,
                token = LoginVariables.Token
            },
            DeliveryMethod.ReliableOrdered
            );

        EntityTypesMap<GameEntities> typesMap = new EntityTypesMap<GameEntities>()
        .Register(GameEntities.NPC, e => new BaseNetworkNPC(e))
        .Register(GameEntities.NPCController, e => new NPCController(e));

        _entityManager = ClientEntityManager.Create<PlayerInputPacket>(
            typesMap,
            new LiteNetLibNetPeer(peer, true),
            (byte)PacketType.EntitySystem,
            60
            );

        _entityManager
        .GetEntities<BaseNetworkNPC>()
        .SubscribeToConstructed(CreateNPC, true);
    }

    private void CreateNPC(BaseNetworkNPC baseNetworkNPC)
    {
        baseNetworkNPC.NotifyServerThatSetupHasCompleted();
        // after running baseNetworkNPC.NotifyServerThatSetupHasCompleted(); server state never changes and BaseNetworkNPC.SetupCompleted() is never called
    }
}

Solution

  • RPCs works currently only from Server to Client. There is ClientRequests in HumanController - that can send info from client to server.