Skip to content
This repository was archived by the owner on Jan 18, 2024. It is now read-only.

Protocol

Luka Camus edited this page Jan 14, 2024 · 5 revisions

R-Type Protocol

This is a binary protocol, which means that this is not human-readable, we use a structure, which is reproducible.

The structure must be 132 bytes, with a enum of 4 bytes, the type of communication; and and array of char of 128 bytes, for the arguments of the communication. You can communicate with the server and the client by passing an address to the structure, and it will be constructed as sent on the other side.

Communication values

For the communication, the enum must be able to have all of the following values:

enum value meaning
None Default value. Should not be used.
Connection When a client tries to connect to a game, can be refused if there is already the max number of clients (4).
Refusal Answer by the server for the Connection request. The client may try again, but it's not guaranteed that the outcome will change.
Ok Answer by the server. Everything is okay.
End End the game for one player.
Destruction Destruct one entity : Destruction [Id]
Position Send the position of an entity : Position [Id] [x] [y]
Input Send the input of the player to server : Input [UP/RIGHT/DOWN/LEFT/W(Shooting)]
Entity Send informations about entities (their id, tag, and position x and y) => Entity [Id] [Tag] [x] [y]
ToGame Client passing from waiting mode to game. Sent by server
Room Server -> send infos about room [id] [nb_player] [status], Client -> join room [id] or create one
Music Send the music that the client should play, [MusicString]
Background Send the background that the client should display, [BackgroundString]
Solo Sent by Player -> wanting to be in solo game

C++ usage

The class used to communicate between the server and the client is common to both, and in the folderRType-Utils. It look like that:

#pragma pack(push, 1)
    struct Communication {
        public:
            /* variables */
            NetworkType type{None};
            std::array<char, MAX_SIZE> args;
    };
#pragma pack(pop)

We have an enum, that takes the type of message, and the arguments, in a char array. The #pragma pack are used for the buffering of the extra bytes of the structure when it's declared, and sent/recieved.

Associated method

To avoid adding value to the args variable by hand, we have the method add_param, which is templated:

template <typename TType> void add_param(TType param)
{
    std::string to_add{};
    size_t ind{0};
    size_t arg_ind{0};

    if constexpr (std::is_arithmetic<TType>::value)
        to_add = std::to_string(param);
    else
        to_add = param;
    while (this->args[arg_ind]) {
        arg_ind++;
    }
    if (arg_ind != 0)
        this->args[arg_ind++] = ' ';
    for (size_t i = arg_ind; i < MAX_SIZE && i < arg_ind + to_add.size(); i++) {
        this->args[i] = to_add[ind];
        ind++;
    }
}

It's gonna add the given value to the args component, with a space before it if it's not the first value added.
NOTE: it will stop at the size max of the array without warning the user.

Clone this wiki locally