Skip to content

Commit

Permalink
Merge branch 'main' into website
Browse files Browse the repository at this point in the history
  • Loading branch information
cBournhonesque committed May 7, 2024
2 parents 16eb95d + 9e261ef commit f53ca3d
Show file tree
Hide file tree
Showing 46 changed files with 1,609 additions and 151 deletions.
25 changes: 22 additions & 3 deletions book/src/concepts/connection/title.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,44 @@ To establish that connection, that needs to be some machinery that runs on top o
- storing the list of connected remote peers
- etc.

In lightyear, it is possible to use different connection types, via the two traits
`NetClient` and `NetServer`.
`lightyear` uses the traits `NetClient` and `NetServer` to abstract over the connection logic.

Multiple implementations are provided:
- Netcode
- Steam
- Local


## Netcode

This implementation is based on the [netcode.io](https://github.com/networkprotocol/netcode/blob/master/STANDARD.md) standard created
by Glenn Fiedler (of GafferOnGames fame). It describes a protocol to establish a secure connection between two peers, provided
that there is a transport layer to exchange packets.
that there is an unoredered unreliable transport layer to exchange packets.

For my purpose I am using [this](https://github.com/benny-n/netcode) Rust implementation of the standard.

You can use the Netcode connection by using the `NetcodeClient` and `NetcodeServer` structs, coupled with any of the available
transports (Udp, WebTransport, etc.)

To connect to a game server, the client needs to send a `ConnectToken` to the game server to start the connection process.

There are several ways to obtain a `ConnectToken`:
- the client can request a `ConnectToken` via a secure (e.g. HTTPS) connection from a backend server.
The server must use the same `protocol_id` and `private_key` as the game servers.
The backend server could be a dedicated webserver; or the game server itself, if it has a way to
establish secure connection.
- when testing, it can be convenient for the client to create its own `ConnectToken` manually.
You can use `Authentication::Manual` for those cases.

Currently `lightyear` does not provide any functionality to let a game server send a `ConnectToken` securely to a client.
You will have to handle this logic youself.


## Steam

This implementation is based on the Steamworks SDK.

## Local

Local connections are used when running in host-server mode: the server and the client are running in the same bevy App.
No packets are actually sent over the network since the client and server share the same `World`.
15 changes: 15 additions & 0 deletions examples/auth/.cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[build]
# it is a good idea to specify your target here, to avoid losing incremental compilation when compiling to wasm
# target = "aarch64-apple-darwin"
rustflags = ["--cfg", "web_sys_unstable_apis"]

[target.wasm32-unknown-unknown]
runner = "wasm-server-runner"

# Enable max optimizations for dependencies, but not for our code:
[profile.dev.package."*"]
opt-level = 3

# Enable only a small amount of optimization in debug mode
[profile.dev]
opt-level = 1
41 changes: 41 additions & 0 deletions examples/auth/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
[package]
name = "auth"
version = "0.1.0"
authors = ["Charles Bournhonesque <charlesbour@gmail.com>"]
edition = "2021"
rust-version = "1.65"
description = "Examples for the lightyearServer-client networking library for the Bevy game engine"
readme = "README.md"
repository = "https://github.com/cBournhonesque/lightyear"
keywords = ["bevy", "multiplayer", "networking", "netcode", "gamedev"]
categories = ["game-development", "network-programming"]
license = "MIT OR Apache-2.0"
publish = false

[features]
metrics = ["lightyear/metrics", "dep:metrics-exporter-prometheus"]
mock_time = ["lightyear/mock_time"]

[dependencies]
lightyear = { path = "../../lightyear", features = [
"steam",
"webtransport",
"websocket",
"render",
] }
async-compat = "0.2.3"
serde = { version = "1.0.188", features = ["derive"] }
anyhow = { version = "1.0.75", features = [] }
tracing = "0.1"
tracing-subscriber = "0.3.17"
bevy = { version = "0.13", features = ["bevy_core_pipeline"] }
bevy_mod_picking = { version = "0.18.2", features = ["backend_bevy_ui"] }
derive_more = { version = "0.99", features = ["add", "mul"] }
rand = "0.8.1"
clap = { version = "4.4", features = ["derive"] }
mock_instant = "0.4"
metrics-exporter-prometheus = { version = "0.13.0", optional = true }
bevy-inspector-egui = "0.24"
cfg-if = "1.0.0"
crossbeam-channel = "0.5.11"
tokio = "1.37.0"
33 changes: 33 additions & 0 deletions examples/auth/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Auth with ConnectTokens

This example will showcase how to get a `ConnectToken` to establish a connection with a game server.

You can find more information in the [book](https://cbournhonesque.github.io/lightyear/book/concepts/connection/title.html#netcode), but basically
you need a `ConnectToken` to establish a connection with a server using the Netcode protocol. (it is not required if you are using
a different means to establish a connection, such as steam sockets)

The `ConnectToken` is a token that is generated by a backend server, using a private key that is shared with your game servers.
It is sent to the client using a secure method of your choice (TCP+TLS, websockets, HTTPS, etc.).
Once the client has received the `ConnectToken`, they can use it to establish a connection with the game server.

In this example, the game server and the backend will run in the same process. The server will run a separate task
that listens on a TCP socket for incoming requests. For every request, it will generate a `ConnectToken` that it will send
to the client. The client can then use the `ConnectToken` to start the `lightyear` connection.


## Running the example

There are different 'modes' of operation:

- as a dedicated server with `cargo run -- server`
- as a listen server with `cargo run -- listen-server`. This will launch 2 independent bevy apps (client and server) in
separate threads.
They will communicate via channels (so with almost 0 latency)
- as a listen server with `cargo run -- host-server`. This will launch a single bevy app, where the server will also act
as a client. Functionally, it is similar to the "listen-server" mode, but you have a single bevy `World` instead of
separate client and server `Worlds`s.

Then you can launch clients with the commands:
- `cargo run -- client`

You can modify the file `assets/settings.ron` to modify some networking settings.
59 changes: 59 additions & 0 deletions examples/auth/assets/settings.ron
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
Settings(
client: ClientSettings(
inspector: true,
client_id: 0,
client_port: 0, // the OS will assign a random open port
server_addr: "127.0.0.1",
conditioner: Some(Conditioner(
latency_ms: 200,
jitter_ms: 20,
packet_loss: 0.05
)),
// server_port: 5000,
// transport: WebTransport(
// this is only needed for wasm, the self-signed certificates are only valid for 2 weeks
// the server will print the certificate digest on startup
// certificate_digest: "24:48:ea:6f:13:a4:4f:2f:42:b9:f3:71:3f:79:c5:7a:d1:1d:29:ab:de:b0:03:4d:94:92:7b:84:69:01:85:1d",
// ),
server_port: 5001,
transport: Udp,
// server_port: 5002,
// transport: WebSocket,
// server_port: 5003,
// transport: Steam(
// app_id: 480,
// )
),
server: ServerSettings(
headless: true,
inspector: false,
conditioner: Some(Conditioner(
latency_ms: 200,
jitter_ms: 20,
packet_loss: 0.05
)),
transport: [
WebTransport(
local_port: 5000
),
Udp(
local_port: 5001
),
WebSocket(
local_port: 5002
),
// Steam(
// app_id: 480,
// server_ip: "0.0.0.0",
// game_port: 5003,
// query_port: 27016,
// ),
],
netcode_auth_port: 5005,
),
shared: SharedSettings(
protocol_id: 0,
private_key: (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
compression: None,
)
)
8 changes: 8 additions & 0 deletions examples/auth/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<title>Bevy game</title>
</head>
</html>
Loading

0 comments on commit f53ca3d

Please sign in to comment.