1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
//! Safer access to a running Source SDK 2013 server from a plugin.
//!
//! # Entry point
//!
//! Everything starts from a [`Server`], which [`Server::new`] creates from the
//! engine's and game server's interface factories for the duration of one
//! callback. Its safety contract covers what every other type relies on, and
//! each interface is then a safe accessor away, such as [`Server::valve_engine`]
//! or [`Server::server_game_dll`]. Operations with additional requirements,
//! such as entity spawning or schema-dependent attribute writes, document
//! their own `unsafe` contracts.
//!
//! # Features and build inputs
//!
//! Use nightly Rust on `x86_64-pc-windows-msvc` or
//! `x86_64-unknown-linux-gnu`. Ordinary builds use pre-generated bindings;
//! Valve's C++ SDK and libclang are needed only for intentional regeneration.
//!
//! - `tf2` enables the game-specific wrappers in `tf2`.
//! - `tf2_loadout` enables `tf2` and the loadout re-applier in `tf2::loadout`.
//! - `_test-support` exposes doc-hidden fakes for tests only.
//!
//! # Handles and aliasing
//!
//! The engine and game own their objects and mutate them through their own
//! pointers at any time, including in the middle of calls made from Rust. A
//! Rust reference into such an object would promise an immutability (`&T`) or
//! exclusivity (`&mut T`) that Rust cannot guarantee, so this crate never
//! creates one. Engine objects are reached through handles instead, which
//! store the pointer the engine returned and access the object only through
//! virtual calls and raw reads and writes, like a `Cell`:
//!
//! - Handles are `Copy`, and their methods take `self`. Sharing a handle is
//! like sharing `&Cell<T>`: exclusivity would protect nothing, since the
//! engine keeps its own pointers.
//! - Handles carry the scope lifetime of the `Server` they came from, so none
//! outlives the callback in which the engine keeps the object alive.
//! - Handles are `!Send` and `!Sync`: access through them is restricted to the
//! server's main thread, even when the engine does other work on workers.
//! - Data read out of the engine is copied unless it stays unchanged for the
//! whole scope, such as class names or static strings.
//!
//! Uniqueness is reserved for what the plugin owns: an [`OwnedGameEvent`] is
//! freed exactly once, and a [`GameEventListener`] is registered by pinned
//! reference and is `!Unpin`, since the engine keeps its address.
//!
//! [`OwnedGameEvent`]: interfaces::game_event::OwnedGameEvent
//! [`GameEventListener`]: interfaces::game_event::GameEventListener
use PhantomData;
/// The hand-written raw bindings and low-level utilities this crate wraps,
/// for what [`sys`] does not generate.
pub use sdk_raw as raw;
pub use ;
/// The raw Source SDK bindings this crate wraps.
pub use sys;
/// Makes a type `!Send` and `!Sync`.
///
/// Engine state may only be touched from the server's main thread.
pub type NotThreadSafe = ;