Skip to content

Sync an action with the server

rootcan edited this page May 18, 2022 · 4 revisions

Syncing an action with the server

Objectives

  • Learn how to send a packet from the client
  • Learn how to process this packet from the server
  • Learn how to process back the packet as a client

Pre-requesites

Getting Started

Syncing an event is separated in 2 or 3 parts:

  • sending a packet from a client
  • handling the packet receiving, and sending to the other clients a packet (the same preferably)
  • processing the packet on the other clients' side

I'll be using the patch I wrote for Patching a method tutorial as a trigger for the event I want to sync, but you can obviously use any other place

  1. To start, I'll make sure to know from where exactly and under which condition(s) I want to send the packet on the first client. In my case it will be in SignalPing_OnTriggerEnter_Patch:
if (__instance.pingInstance.visible)
{
    Log.Debug("A Signal Ping was removed, now do something");
    // This is where I want to send the packet
}
  1. I need to have a specific packet for the action I want to sync. Thus, I'll create a new file under NitroxModel/Packets which I'll call SignalPingRemove. It needs to:
  • implement the abstract class Packet
  • have the [Serializable] attribute on top of it
  • have a constructor and the necessary fields
using System;

namespace NitroxModel.Packets;

[Serializable]
public class SignalPingRemove : Packet
{
    public string DescriptionKey;

    public SignalPingRemove(string descriptionKey)
    {
        DescriptionKey = descriptionKey;
    }
}

An empty packet would look the same but without the field and its initialization. But in my case, I need one other information which is its description key

Just like this, the packet is created and I can use it for both server and client.

  1. To send the packet from a Patch class, I can simply write:
// From a Patch class
Resolve<IPacketSender>().Send(...packet...)

// From any other place
using NitroxModel.Core;
...
NitroxServiceLocator.LocateService<IPacketSender>().Send(...packet...);

In my case I'll input the packet I created earlier and fill it with the informations I have

Resolve<IPacketSender>().Send(new SignalPingRemove(__instance.descriptionKey));
  1. Now that the client is sending this packet to the server, the latter must process it. To do so, create a new file under NitroxServer/Communication/Packets/Processors which you can name after the packet itself. In my case it will be SignalPingRemoveProcessor. This is what an empty server packet processor looks like:
using NitroxModel.Packets;
using NitroxServer.Communication.Packets.Processors.Abstract;

namespace NitroxServer.Communication.Packets.Processors;

public class SignalPingRemoveProcessor : AuthenticatedPacketProcessor<SignalPingRemove>
{
    public override void Process(SignalPingRemove packet, Player player)
    {

    }
}

The AuthenticatedPacketProcessor abstract class needs the generic type of the packet you created earlier. It will also be used in the Process method