correct grammar, some typos, shortened some sentences

ebbit1q 2018-10-23 05:33:43 +02:00
parent 3a577aeceb
commit f992da2570

@ -12,27 +12,27 @@ The main server tasks are:
The main focus of this page is how points 3 and 4 are implemented, and how to bootstrap a raw tcp connection to a successful login.
# Basics
Cockatrice and Servatrice (the Cockatrice server) need to exchange informations between them. They both keep these informations stored in [objects](https://en.wikipedia.org/wiki/Object_(computer_science)), so they need a way to transform these objects to a format that's suitable to be transferred using a network connection. This process is commonly called [serialization](https://en.wikipedia.org/wiki/Serialization).
Cockatrice and Servatrice (the Cockatrice server) need to exchange information between them. They both keep this information stored in [objects](https://en.wikipedia.org/wiki/Object_(computer_science)), so they need a way to transform these objects to a format that's suitable to be transferred using a network connection. This process is commonly called [serialization](https://en.wikipedia.org/wiki/Serialization).
Cockatrice uses Google's [protobuf](https://github.com/google/protobuf) library to handle communications between the server and the client. Protobuf consists of:
* a pseudo language used to define data structures (usually in ".proto" files)
* a "compiler" that translates proto files to a representation usable in your favorite programming language (es. to a c++ class);
Cockatrice's protobuf definition files lives in the [common/pb](https://github.com/Cockatrice/Cockatrice/tree/master/common/pb) directory. Documentation fo the file format is available in the [official documentation](https://developers.google.com/protocol-buffers/docs/proto).
Each file contain one or more message definition, its variables, constraints and any related information.
Cockatrice's protobuf definition files live in the [common/pb](https://github.com/Cockatrice/Cockatrice/tree/master/common/pb) directory. Documentation for the file format is available in the [official documentation](https://developers.google.com/protocol-buffers/docs/proto).
Each file contains one or more message definitions, their variables, constraints and any related information.
Before Cockatrice and Servatrice are built, each message defined in proto files generate a corresponding c++ class; both Cockatrice and Servatrice includes those common files, in order to share a common base of messages that can be used to exchange data between them.
# Message types
Cockatrice messages can be grouped in:
* Commands: when the player makes an action, Cockatrice creates a "Command" message and sends it to the server;
* Responses: when the server receives a player command, usually replies with an outcome or the requested informations;
* Responses: when the server receives a player command, it usually replies with an outcome or the requested information;
* Events: when the server accepts a player's command, it usually also informs other players about what happened;
## Commands
A [CommandContainer](https://github.com/Cockatrice/Cockatrice/blob/master/common/pb/commands.proto) is the basic structure used by Cockatrice to send one or more commands to the server:
```protobuf
# defines that Cockatrice is using version 2 fo the protobuf data exchange format
# defines that Cockatrice is using version 2 of the protobuf data exchange format
syntax = "proto2";
# imports subgroups of available commands
@ -62,12 +62,12 @@ message CommandContainer {
```
As visible from the file, commands are grouped in:
* [Session commands](https://github.com/Cockatrice/Cockatrice/blob/master/common/pb/session_commands.proto): basic connection handling (eg. Command_Ping, Command_Login), user profile management (Command_ForgotPasswordRequest, Command_AccountEdit), list users, room and games, replay and deck transfers;
* [Game commands](https://github.com/Cockatrice/Cockatrice/blob/master/common/pb/game_commands.proto): game actions like shuffling (Command_Shuffle), card movements (Command_MoveCard, Command_DrawCards), players (Command_Kick, Command_Concede), arrows, counters, etc..
* [Session commands](https://github.com/Cockatrice/Cockatrice/blob/master/common/pb/session_commands.proto): basic connection handling (e.g.: Command_Ping, Command_Login), user profile management (Command_ForgotPasswordRequest, Command_AccountEdit), list users, room and games, replay and deck transfers;
* [Game commands](https://github.com/Cockatrice/Cockatrice/blob/master/common/pb/game_commands.proto): game actions like shuffling (Command_Shuffle), card movements (Command_MoveCard, Command_DrawCards), players (Command_Kick, Command_Concede), arrows, counters, etc...
* [Room commands](https://github.com/Cockatrice/Cockatrice/blob/master/common/pb/room_commands.proto): actions that can be done inside a chat room: say something (Command_RoomSay), game creation (Command_CreateGame, Command_JoinGame)
* [Moderator commands](https://github.com/Cockatrice/Cockatrice/blob/master/common/pb/moderator_commands.proto) and [Admin commands](https://github.com/Cockatrice/Cockatrice/blob/master/common/pb/admin_commands.proto): special actions that can be done by a moderator or admin user, like ban an user (Command_BanFromServer) or shutdown the server (Command_ShutdownServer).
* [Moderator commands](https://github.com/Cockatrice/Cockatrice/blob/master/common/pb/moderator_commands.proto) and [Admin commands](https://github.com/Cockatrice/Cockatrice/blob/master/common/pb/admin_commands.proto): special actions that can be done by a moderator or admin user, like ban an user (Command_BanFromServer) or shut down the server (Command_ShutdownServer).
To each command in a command group is assigned an unique id, eg:
Each command in a command group is assigned an unique id, e.g.:
```protobuf
message SessionCommand {
enum SessionCommandType {
@ -77,7 +77,7 @@ message SessionCommand {
LIST_USERS = 1003;
GET_GAMES_OF_USER = 1004;
```
These ids are what is really used to communicate to the server the command we want to execute; it's really important that commands doesn't get mixed or their id changed, or the server will misinterpret the command sent by clients.
These ids are what is really used to communicate to the server what command we want to execute; it's really important that commands doesn't get mixed or their id changed, or the server will misinterpret the command sent by the client.
## How to use a command
@ -97,7 +97,7 @@ message Command_Login {
repeated string clientfeatures = 5;
}
```
If we want to create such a message in the code, we just instanciate an object of class `Command_Login` and fill its properties (example from [cockatrice/src/remoteclient.cpp](https://github.com/Cockatrice/Cockatrice/blob/master/cockatrice/src/remoteclient.cpp#L156), line may vary):
If we want to create such a message in the code, we just instantiate an object of class `Command_Login` and fill its properties (example from [cockatrice/src/remoteclient.cpp](https://github.com/Cockatrice/Cockatrice/blob/master/cockatrice/src/remoteclient.cpp#L156), line may vary):
```c++
Command_Login cmdLogin;
cmdLogin.set_user_name(userName.toStdString());
@ -116,10 +116,10 @@ Once the command message is ready to be sent, a few helper methods can be used t
```
The `prepareSessionCommand` method:
1. creates a `CommandContainer` object
2. casts the user-provided Command_Login to a generic `SessionCommand` object and add it to the `CommandContainer` object, so that we have a fully formatted message to send
2. casts the user-provided Command_Login to a generic `SessionCommand` object and adds it to the `CommandContainer` object, so that we have a fully formatted message to send
3. creates a `PendingCommand` object that is used to track the server response to this specific message, and returns it.
The `PendingCommand` class abstracts the reception of the server response to Qt's [signal/slot](http://doc.qt.io/qt-5/signalsandslots.html) mechanism. We can then just connect the `PendingCommand`'s finished signal to the method that will be called when the server response will received, in this case `loginResponse`. The target method (slot) will also receive the full content of the response message.
The `PendingCommand` class abstracts the reception of the server response to Qt's [signal/slot](http://doc.qt.io/qt-5/signalsandslots.html) mechanism. We can then just connect the `PendingCommand`'s finished signal to the method that will be called when the server response would be received, in this case `loginResponse`. The target method (slot) will also receive the full content of the response message.
Now the command message is well-formed and we are ready to wait for the server response, and the `sendCommand()` method is called. The method name is self-explanatory, but it takes care of moving command objects into a specific thread, keeping commands inside a "send" queue and send them asynchronously to avoid lagging the user interface.