Merge pull request #10014 from Hiuoy/feat/client-logging-hooks

Native hooks: ClientPlayerNetworkEvent.LoggingIn / .LoggingOut (client_player_network_logging_in, client_disconnecting's label)
This commit is contained in:
Kacper authored and GitHub committed 2026-11-06 09:19:55 +01:00
commit 345a66c710
5 files changed
+49

No files matched your search

@@ -2194,9 +2194,25 @@ impl Game<'_> {
mod_api::dispatch_client_start(self, mod_api::mods());
}
/// Before an actual connection is discarded, not on a dimension change.
/// NeoForge's `ClientPlayerNetworkEvent.LoggingOut`, told here after
/// `native_client_level_unload` and only when a connection ends.
pub(super) fn native_client_disconnecting(&self) {
mod_api::dispatch_client_disconnecting(self, mod_api::mods());
}
/// The window's player logs in to a server (NeoForge's
/// `ClientPlayerNetworkEvent.LoggingIn`, in
/// `ClientPacketListener.handleLogin`), single player's own server or a
/// remote one: once per login packet, after the new client level
/// (`native_client_level_load`). Respawns and dimension changes don't log
/// in again; a server that sends its player back through configuration
/// does, without a `native_client_disconnecting` between. Horizon makes
/// the player with the server's first position, so `native_player` is
/// None here. A mod may send the server its own packets
/// (`native_send_packet`). Client only.
/// API @API:client_player_network_logging_in@.
pub(super) fn native_client_player_network_logging_in(&mut self) {
mod_api::dispatch_client_player_network_logging_in(self, mod_api::mods());
}
/// Once before this client's final save/exit. A mod can flush and join its worker here.
pub(super) fn native_client_stopping(&self) {
mod_api::dispatch_client_stopping(self, mod_api::mods());
+2
View File
@@ -3310,6 +3310,8 @@ impl Game<'_> {
false,
horizon_client::level_loading::Reason::Other,
);
// handleLogin: ClientPlayerNetworkEvent.LoggingIn, the new level made.
self.native_client_player_network_logging_in();
// No ClientInformation here: the configuration phase sent it,
// and ClientPacketListener.broadcastClientInformation sends it
// again only when an option changes it.
+13
View File
@@ -3017,6 +3017,19 @@ game runs, for seasons (a golden autumn, a pale winter) or a world that greens a
- A season's mood in a shader pack (warmer grading, a lower sun, more haze) comes from the same mod through
`native_shader_params` (`frame.mods`); its server half can send the season to each client with mod messages.
### Logging in and out
`native_client_player_network_logging_in()` (client) is NeoForge's `ClientPlayerNetworkEvent.LoggingIn`: the window's
player logs in to a server, single player's own included. It fires once per login packet
(`ClientPacketListener.handleLogin`), after the new client level (`native_client_level_load`). Respawns and dimension
changes don't log in again; a server that sends its player back through configuration logs it in again, with no logout
between. Horizon makes the player with the server's first position, so `native_player()` is None here, but the
connection is up: `native_send_packet` reaches the server. The counterpart is `native_client_disconnecting()`,
NeoForge's `ClientPlayerNetworkEvent.LoggingOut`. It is told before a connection is discarded, after
`native_client_level_unload`, and only when a connection ends: NeoForge's documentation says its event may also fire as
a new integrated server is created, and Horizon's doesn't. A mod keeps its per-server state between the two: caches, a
handshake with its server half, a welcome message. Bundles need `"hooks": @API:client_player_network_logging_in@`.
### Sounds a client mod plays
`native_play_local_sound(sound, at, volume, pitch, delay)` (client) plays sound event `sound` at `at` for this player only,
+2
View File
@@ -5171,7 +5171,9 @@
"name": "client_disconnecting",
"version": 1,
"target": "horizon_client::game::native_hooks::Game<'_>::native_client_disconnecting",
"neoforge": "ClientPlayerNetworkEvent.LoggingOut (only when a connection ends)",
"side": "client",
"cancellable": false,
"mod_api": {
"contract": "listen"
}
@@ -0,0 +1,16 @@
{
"hooks": [
{
"name": "client_player_network_logging_in",
"target": "horizon_client::game::native_hooks::Game<'_>::native_client_player_network_logging_in",
"neoforge": "ClientPlayerNetworkEvent.LoggingIn",
"side": "client",
"cancellable": false,
"mod_api": {
"contract": "listen"
}
}
],
"rust_summary": "the window's player logging in to a server (`native_client_player_network_logging_in`).",
"doc_summary": "the window's player logging in to a server, single player's own included: `native_client_player_network_logging_in()`, NeoForge's `ClientPlayerNetworkEvent.LoggingIn`, once per login packet after the new client level, not on respawns or dimension changes. Its counterpart for logging out is `native_client_disconnecting` ([Logging in and out](#logging-in-and-out)). Bundles need \"hooks\": @API:client_player_network_logging_in@."
}