# cg-game-server ## About This is a library that consists mostly of traits that are meant to speed up and standardize the development of [CodeGame](https://github.com/code-game-project) game servers. It's the server's job to keep the players connected to each other and prevent them from cheating using minimal server-side state. All decisions are made by the client but always verified by the server. ## Installation Add the following dependencies to your Cargo.toml: ```toml # this lib cg-game-server = "0.1.0" # CodeGame uses actix as its web framework, the traits in this project are built for actix actix = "0.10" actix-web = {version = "3", features = ["openssl"]} actix-web-actors = "3" # the project uses serde and serde_json to communicate with the clients serde = {version = "1.0.133", features = ["derive"]} serde_json = "1.0.74" ``` ## How to use TL;DR: For some examples, please see [the official games](https://github.com/orgs/code-game-project/teams/games/repositories). Apart from the `main.rs` module that starts the webserver, each CodeGame game server consists of three parts: - [events](#Events) - [socket](#Socket) - [server](#Server) Here's a closer look at each: ### Events Events are `structs` that represent an action. Events flow between sockets and them and their clients, carrying data with them. There are two types of events `ReceiveableEvents` (`R` in generics), which are sent to the server by a client (received by a socket), and `SendableEvents` (`S` in generics), which are sent between sockets. When creating your own events it is recommended that you create two `enums`. Be sure to include the standard events in your enums too. It should look something like this: ```rust use cg_game_server::events::{Error, Join, Leave}; use actix::prelude::Message; use serde::{Deserialize, Serialize}; use std::result::Result; /// Deserialization `Result` for deserializing `ReceiveableEvents` pub type ReceiveableEventSerde = Result; /// Events that the client may send to the server #[derive(Serialize, Deserialize, Debug, Message, Clone)] #[rtype(result = "()")] #[serde(tag = "event_name")] pub enum ReceiveableEvents { #[serde(rename = "join")] Join(Join), #[serde(rename = "leave")] Leave(Leave), } /// Events that the server may send to the client #[derive(Serialize, Debug, Message, Clone)] #[rtype(result = "()")] #[serde(tag = "event_name")] pub enum SendableEvents { #[serde(rename = "error")] Error(Error), #[serde(rename = "join")] Joined(Join), #[serde(rename = "leave")] Left(Leave), } ``` ### Socket The `Socket` (`C` in generics) is what client connects to. It contains the game logic and is responsible for interpreting events sent by the client. Furthermore it sends all events that it reiceives from other sockets to the client. A socket is required to `impl`ement the following: - `actix::Actor` -> required by actix, can send and receive messages - `actix::StreamHandler` -> required by actix, handles WebSocket communication - `actix::Handler>` required by CodeGame, handles `SendableEvents` sent to a socket - `actix::GameServerCommunications` required by CodeGame, makes sure that the basic game server communication functions are available for every `impl`ementation of `Socket` ### Server The `GameServer` (`G` in generics) is the middle man. Its `actix::Addr` is passed to each new socket. Sockets can send events to the game server which it either processes or relays to other sockets. A server is required to `impl`ement the following: - `actix::Actor` -> required by actix, can send and receive messages - `actix::Handler>` required by CodeGame, handles `SendableEvents` sent to sockets - `actix::Handler>>` required by CodeGame, handles `Connect` events sent to the server - `actix::Handler>` required by CodeGame, handles `Disconnect` events sent to the server - `actix::Handler>` required by CodeGame, handles `Join` events sent to the server - `actix::Handler>` required by CodeGame, handles `Leave` events sent to the server