Клиент: Rust-интерфейс и протокол RSX

Чекпойнт: Rust-меню, настройки, Play, пауза, ресурспаки, кейбинды, RSX-протокол, шрифты и иконки. Перед финальным пушем история будет разбита на логические коммиты.
This commit is contained in:
SashegDev
2026-10-29 22:06:05 +03:00
parent 874b6f20c2
commit 808fd7924e
140 changed files with 7959 additions and 237 deletions
@@ -0,0 +1,24 @@
The icons in this folder are outline icons from theSVG UI (https://thesvg.org/ui),
rendered at 64 x 64 with cairosvg.
MIT License
Copyright (c) theSVG contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Binary file not shown.

After

Width:  |  Height:  |  Size: 964 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 342 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 327 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 739 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 995 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 906 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 947 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 364 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 331 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 307 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 714 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 904 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 835 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 838 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 935 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 607 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 665 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 569 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 750 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 561 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 764 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 757 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 582 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 295 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1023 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 626 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 987 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 815 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 721 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 829 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 435 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 939 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 685 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 980 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 422 B

+1 -1
View File
@@ -106,7 +106,7 @@ impl Assets {
root.join("horizon-resources.json"),
)?))?;
if manifest["data_version"].as_i64() != Some(i64::from(DATA_VERSION)) {
return Err(invalid("resources do not match Horizon's pinned data version").into());
return Err(invalid("resources do not match RustNotMC's pinned data version").into());
}
let (registry, flags) =
BlockRegistry::from_facts_json_with_flags(File::open(root.join("facts.json"))?)?;
+4 -4
View File
@@ -538,7 +538,7 @@ fn build_stream<T: cpal::SizedSample + cpal::FromSample<f32>>(
*out = T::from_sample(*s);
}
},
|e| log::warn!("Horizon: audio stream error: {e}"),
|e| log::warn!("RustNotMC: audio stream error: {e}"),
None,
)?;
Ok(stream)
@@ -556,7 +556,7 @@ impl Audio {
if output && registry.is_empty() {
// The game then plays nothing on a working output (#1035, #1076).
log::warn!(
"Horizon: no sounds in {}: they were not copied from your Minecraft \
"RustNotMC: no sounds in {}: they were not copied from your Minecraft \
install; prepare the game again in the launcher (or run \
horizon-prepare sounds)",
root.join("assets").display()
@@ -572,7 +572,7 @@ impl Audio {
Ok(v) => (Some(v), true),
Err(e) => {
if output {
log::warn!("Horizon: no sound: {e}");
log::warn!("RustNotMC: no sound: {e}");
}
(None, false)
}
@@ -627,7 +627,7 @@ impl Audio {
match open_device(&device, mixer.clone()) {
Ok((stream, config)) => {
log::info!(
"Horizon: audio output {name} ({} Hz, {} channels, {})",
"RustNotMC: audio output {name} ({} Hz, {} channels, {})",
config.sample_rate().0,
config.channels(),
config.sample_format()
+1 -1
View File
@@ -174,7 +174,7 @@ pub fn discovery_url() -> String {
fn agent() -> ureq::Agent {
ureq::AgentBuilder::new()
.timeout(Duration::from_secs(15))
.user_agent(&format!("Horizon/{}", horizon_core::release::VERSION))
.user_agent(&format!("RustNotMC/{}", horizon_core::release::VERSION))
.build()
}
+2 -2
View File
@@ -82,8 +82,8 @@ pub fn start(requests: Sender<Request>, setup: Setup) {
.spawn(move || {
let control = Control(requests);
match run(&control, setup) {
Ok(path) => println!("Horizon: benchmark report {}", path.display()),
Err(e) => eprintln!("Horizon: benchmark failed: {e}"),
Ok(path) => println!("RustNotMC: benchmark report {}", path.display()),
Err(e) => eprintln!("RustNotMC: benchmark failed: {e}"),
}
let _ = control.call("quit");
})
+1 -1
View File
@@ -1212,7 +1212,7 @@ impl Recipes {
let v: Value = match serde_json::from_slice(&fs::read(&path)?) {
Ok(v) => v,
Err(e) => {
log::warn!("Horizon: recipe {name} not loaded: {e}");
log::warn!("RustNotMC: recipe {name} not loaded: {e}");
continue;
}
};
+8 -8
View File
@@ -68,7 +68,7 @@ impl Report {
pub fn text(&self) -> String {
let comment = COMMENTS[self.time.timestamp().rem_euclid(COMMENTS.len() as i64) as usize];
let mut out = String::new();
let _ = writeln!(out, "---- Horizon Crash Report ----");
let _ = writeln!(out, "---- RustNotMC Crash Report ----");
let _ = writeln!(out, "// {comment}\n");
let _ = writeln!(out, "Time: {}", self.time.format("%Y-%m-%d %H:%M:%S"));
let _ = writeln!(out, "Description: {}\n", self.description);
@@ -253,7 +253,7 @@ fn memory() -> String {
/// The report's details: Horizon's and the machine's, then what the game set as it ran.
pub fn system_details() -> Vec<(String, String)> {
let mut out = vec![
("Horizon Version".to_owned(), version()),
("RustNotMC Version".to_owned(), version()),
(
"Minecraft Version".to_owned(),
horizon_core::VANILLA_VERSION.to_owned(),
@@ -283,7 +283,7 @@ fn deliver(home: &Path, report: Report) -> Option<PathBuf> {
crate::logging::write_only(
log::Level::Error,
&format!(
"Horizon crashed: {}\n{}",
"RustNotMC crashed: {}\n{}",
report.error,
report
.stack
@@ -297,11 +297,11 @@ fn deliver(home: &Path, report: Report) -> Option<PathBuf> {
crate::telemetry::keep_crash(home, &report);
match report.save(home) {
Ok(path) => {
eprintln!("Horizon: crash report saved to {}", path.display());
eprintln!("RustNotMC: crash report saved to {}", path.display());
Some(path)
}
Err(e) => {
eprintln!("Horizon: could not save a crash report: {e}");
eprintln!("RustNotMC: could not save a crash report: {e}");
eprintln!("{}", report.text());
None
}
@@ -556,7 +556,7 @@ mod tests {
thread: "Render thread".into(),
side: "client",
details: vec![
("Horizon Version".into(), "0.1.0".into()),
("RustNotMC Version".into(), "0.1.0".into()),
("Minecraft Version".into(), "26.3".into()),
("Graphics".into(), "Test GPU (Vulkan), driver 1.0".into()),
],
@@ -576,7 +576,7 @@ mod tests {
fn the_report_reads_like_vanillas() {
let text = report().text();
let lines: Vec<&str> = text.lines().collect();
assert_eq!(lines[0], "---- Horizon Crash Report ----");
assert_eq!(lines[0], "---- RustNotMC Crash Report ----");
assert!(lines[1].starts_with("// "));
assert_eq!(lines[3], "Time: 2026-10-14 09:05:07");
assert_eq!(lines[4], "Description: Unexpected error");
@@ -588,7 +588,7 @@ mod tests {
);
assert!(text.contains("-- Head --\nThread: Render thread\n"));
assert!(text.contains(
"-- System Details --\nDetails:\n\tHorizon Version: 0.1.0\n\tMinecraft Version: 26.3\n\tGraphics: Test GPU (Vulkan), driver 1.0\n"
"-- System Details --\nDetails:\n\tRustNotMC Version: 0.1.0\n\tMinecraft Version: 26.3\n\tGraphics: Test GPU (Vulkan), driver 1.0\n"
));
assert!(text.ends_with(
"-- Last 1 log lines --\n[09:05:06] [Render thread/INFO]: load assets: 1.20s\n"
@@ -16,7 +16,7 @@ use serde_json::{Value, json};
use crate::command::args::GameMode;
/// The "Horizon" application on Discord's developer portal (public: it names the game). Its
/// The "RustNotMC" application on Discord's developer portal (public: it names the game). Its
/// Rich Presence assets: `horizon`, the logo.
pub const DISCORD_APP_ID: &str = "1563857609738690560";
/// Whether the application has the game-mode images (`survival`, `creative`, `adventure`,
@@ -129,7 +129,7 @@ pub fn start(enabled: bool, automated: bool) {
Ok(handle) => {
let _ = THREAD.set(handle.thread().clone());
}
Err(e) => log::warn!("Horizon: no Discord presence: {e}"),
Err(e) => log::warn!("RustNotMC: no Discord presence: {e}"),
}
}
@@ -216,7 +216,7 @@ fn run() {
match c.set_activity(activity(wanted.status, wanted.since)) {
Ok(()) => sent = Some((wanted, now)),
Err(e) => {
log::info!("Horizon: Discord presence disconnected ({e})");
log::info!("RustNotMC: Discord presence disconnected ({e})");
client = None;
sent = None;
}
@@ -226,7 +226,7 @@ fn run() {
/// The activity Discord shows for `status`; `None` clears it.
fn activity(status: Status, since: Option<u64>) -> Option<Value> {
let mut assets = json!({"large_image": "horizon", "large_text": "Horizon"});
let mut assets = json!({"large_image": "horizon", "large_text": "RustNotMC"});
let (details, state, party) = match status {
Status::Off => return None,
Status::Menus => ("In the menus", None, None),
@@ -338,11 +338,11 @@ impl Client {
};
match client.handshake() {
Ok(()) => {
log::info!("Horizon: connected to Discord for Rich Presence");
log::info!("RustNotMC: connected to Discord for Rich Presence");
Some(client)
}
Err(e) => {
log::debug!("Horizon: Discord at {} refused: {e}", path.display());
log::debug!("RustNotMC: Discord at {} refused: {e}", path.display());
None
}
}
@@ -370,7 +370,7 @@ impl Client {
match read_frame(&mut self.pipe)? {
(FRAME, frame) if ours(&frame) => {
if frame["evt"] == "ERROR" {
log::info!("Horizon: Discord presence: {}", frame["data"]["message"]);
log::info!("RustNotMC: Discord presence: {}", frame["data"]["message"]);
}
return Ok(());
}
+29 -26
View File
@@ -390,7 +390,7 @@ impl Options {
match arg.as_str() {
"--help" | "-h" => {
println!(
"Horizon — Minecraft Java Edition {} in Rust\n\n --resources PATH Prepared resources (horizon-prepare)\n --render-distance N Chunks, 2..64 (default 12)\n --world NAME World folder under saves/ (default \"New World\")\n --seed N World seed for new worlds (default 0)\n --width N, --height N Window size (default 1280 x 720)\n --creative Creative mode (default survival)\n --test-terrain Simple test terrain instead of vanilla generation\n --frames N Exit after N frames (testing)\n --world-frames N Exit after N frames drawn in the world (testing)\n --smoke-report PATH Write a JSON report on exit\n --benchmark SCENARIO Run a benchmark (standard, village, forest, ocean, mountain), write its report to benchmarks/ and quit\n --control Accept horizon-ctl commands on a local socket\n --control-socket PATH Control socket path (default $XDG_RUNTIME_DIR/horizon-control.sock)\n --server HOST[:PORT] Join a multiplayer server (offline mode) at start\n --quickPlaySingleplayer WORLD Open this world of saves/ at start, only if it exists (vanilla's)\n --quickPlayMultiplayer HOST[:PORT] The same as --server (vanilla's name)\n --name NAME Player name for multiplayer (default: generated once, kept in horizon-player.txt)\n --session-file PATH Signed-in account from the launcher (read once, then deleted)\n --dev-mod PATH A Horizon mod (.hmod or folder) to develop: always on, reloaded when rebuilt\n --in-frame Run single player's world in the frame, not on its server thread\n --pregen Add Horizon's /pregen command (docs/pregeneration.md)\n\nControls: mouse look, WASD move, Space jump, Left Shift sneak, Left Ctrl sprint,\nleft click break, right click place/use, 1-9/scroll hotbar, E inventory,\nQ drop, F3 debug, Esc pause.",
"RustNotMC — Minecraft Java Edition {} in Rust\n\n --resources PATH Prepared resources (horizon-prepare)\n --render-distance N Chunks, 2..64 (default 12)\n --world NAME World folder under saves/ (default \"New World\")\n --seed N World seed for new worlds (default 0)\n --width N, --height N Window size (default 1280 x 720)\n --creative Creative mode (default survival)\n --test-terrain Simple test terrain instead of vanilla generation\n --frames N Exit after N frames (testing)\n --world-frames N Exit after N frames drawn in the world (testing)\n --smoke-report PATH Write a JSON report on exit\n --benchmark SCENARIO Run a benchmark (standard, village, forest, ocean, mountain), write its report to benchmarks/ and quit\n --control Accept horizon-ctl commands on a local socket\n --control-socket PATH Control socket path (default $XDG_RUNTIME_DIR/horizon-control.sock)\n --server HOST[:PORT] Join a multiplayer server (offline mode) at start\n --quickPlaySingleplayer WORLD Open this world of saves/ at start, only if it exists (vanilla's)\n --quickPlayMultiplayer HOST[:PORT] The same as --server (vanilla's name)\n --name NAME Player name for multiplayer (default: generated once, kept in horizon-player.txt)\n --session-file PATH Signed-in account from the launcher (read once, then deleted)\n --dev-mod PATH A Horizon mod (.hmod or folder) to develop: always on, reloaded when rebuilt\n --in-frame Run single player's world in the frame, not on its server thread\n --pregen Add Horizon's /pregen command (docs/pregeneration.md)\n\nControls: mouse look, WASD move, Space jump, Left Shift sneak, Left Ctrl sprint,\nleft click break, right click place/use, 1-9/scroll hotbar, E inventory,\nQ drop, F3 debug, Esc pause.",
horizon_core::VANILLA_VERSION
);
return Ok(None);
@@ -495,7 +495,7 @@ impl Options {
o.player_name = Some(session.name.clone());
horizon_client::auth::set_current(session);
}
Err(e) => eprintln!("Horizon: not signed in: {e}"),
Err(e) => eprintln!("RustNotMC: not signed in: {e}"),
}
}
Ok(Some(o))
@@ -12008,6 +12008,8 @@ impl Game<'_> {
|| self.title.as_ref().is_some_and(|t| {
matches!(self.screen, Screen::Options | Screen::Win)
|| !matches!(t.mode, horizon_client::title::Mode::Main)
// The Rust menu is translucent over the scene: it blurs it.
|| (t.rust_menu && matches!(t.mode, horizon_client::title::Mode::Main))
})
|| (self.title.is_none()
&& self.player.is_some()
@@ -12091,6 +12093,7 @@ impl Game<'_> {
self.close_container();
self.screen = Screen::Playing;
self.pause_menu = true;
self.ui.pause = None;
self.capture(true);
}
Screen::GameModeSwitcher => self.close_gamemode_switcher(false),
@@ -12373,7 +12376,7 @@ impl Game<'_> {
}
fn update_world(&mut self) {
if let Err(e) = self.poll_remote() {
log::warn!("Horizon: {e}");
log::warn!("RustNotMC: {e}");
}
self.prepare_lod();
if self.lod.is_some() {
@@ -12445,7 +12448,7 @@ impl Game<'_> {
.save_later(&modified, self.pack.assets.registry, self.res.biomes())
})
{
log::warn!("Horizon: failed to save unloaded chunks: {e}");
log::warn!("RustNotMC: failed to save unloaded chunks: {e}");
}
let (far_distance, far_reduced) = self.far_terrain_choice();
if let Some(renderer) = self.renderer.as_mut() {
@@ -12552,7 +12555,7 @@ impl ApplicationHandler for Game<'_> {
let size = self.options.window_size.map(f64::from);
self.fullscreen = horizon_client::window::FullscreenState::new(fullscreen);
let attributes = Window::default_attributes()
.with_title("Horizon")
.with_title("RustNotMC")
.with_window_icon(horizon_client::window::icon());
// Wayland names the window by its app id, which the horizon.desktop entry matches.
#[cfg(target_os = "linux")]
@@ -13402,7 +13405,7 @@ impl ApplicationHandler for Game<'_> {
format!(", cpu {:.1} ms", (end - start).as_secs_f32() * 1000.0)
});
log::info!(
"Horizon: slow frame {cpu:.1} ms{worked} ({steps} ticks): {}",
"RustNotMC: slow frame {cpu:.1} ms{worked} ({steps} ticks): {}",
horizon_client::spans::describe(&spans)
);
}
@@ -13466,7 +13469,7 @@ impl ApplicationHandler for Game<'_> {
if self.frames == 0 {
// The launcher times Play to this line (launcher/src/perf.rs).
log::info!(
"Horizon: first frame after {} ms",
"RustNotMC: first frame after {} ms",
self.started.elapsed().as_millis()
);
}
@@ -13580,7 +13583,7 @@ impl ApplicationHandler for Game<'_> {
fn exiting(&mut self, _event_loop: &ActiveEventLoop) {
self.pad_close_output();
if let Err(e) = self.save_for_exit() {
log::warn!("Horizon: failed to save the world on exit: {e}");
log::warn!("RustNotMC: failed to save the world on exit: {e}");
}
self.finish_perf();
}
@@ -14121,7 +14124,7 @@ impl Game<'_> {
));
}
self.pending_entry = Some(entry);
log::info!("Horizon: world entry waiting for world resources");
log::info!("RustNotMC: world entry waiting for world resources");
Ok(true)
}
@@ -14195,7 +14198,7 @@ impl Game<'_> {
fn join_world_rest(&mut self) -> Result<()> {
if self.rest_loader.is_some() {
let waited = Instant::now();
log::info!("Horizon: waiting for world resources");
log::info!("RustNotMC: waiting for world resources");
while self.rest_loader.is_some() {
self.poll_world_rest()?;
if self.rest_loader.is_some() {
@@ -14203,7 +14206,7 @@ impl Game<'_> {
}
}
log::info!(
"Horizon: world resources joined after {} ms",
"RustNotMC: world resources joined after {} ms",
waited.elapsed().as_millis()
);
}
@@ -14319,7 +14322,7 @@ fn load_resources(
// Minecraft.rollbackResourcePacks: the packs' textures don't fit, start
// with the game's own resources.
Err(e) if root != vanilla_root => {
log::warn!("Horizon: resource packs failed to load ({e}); using the default resources");
log::warn!("RustNotMC: resource packs failed to load ({e}); using the default resources");
pack_error = Some(e.to_string());
root = vanilla_root.to_path_buf();
None
@@ -14330,7 +14333,7 @@ fn load_resources(
if menu {
horizon_client::telemetry::mark_ui_ready();
log::info!(
"Horizon: UI bundle ready after {} ms",
"RustNotMC: UI bundle ready after {} ms",
started.elapsed().as_millis()
);
publish(ui, &root);
@@ -14348,7 +14351,7 @@ fn load_resources(
// Minecraft.rollbackResourcePacks: the packs break loading, start
// with the game's own resources.
Err(e) if root != vanilla_root => {
log::warn!("Horizon: resource packs failed to load ({e}); using the default resources");
log::warn!("RustNotMC: resource packs failed to load ({e}); using the default resources");
pack_error = Some(e.to_string());
root = vanilla_root.to_path_buf();
let assets = Assets::load(vanilla_root)?;
@@ -14370,7 +14373,7 @@ fn load_resources(
if menu {
horizon_client::telemetry::mark_ui_ready();
log::info!(
"Horizon: UI bundle ready after {} ms",
"RustNotMC: UI bundle ready after {} ms",
started.elapsed().as_millis()
);
publish(ui, &root);
@@ -14448,7 +14451,7 @@ fn load_resources(
if menu {
horizon_client::telemetry::mark_core_ready();
log::info!(
"Horizon: core-ready after {} ms",
"RustNotMC: core-ready after {} ms",
started.elapsed().as_millis()
);
}
@@ -14459,7 +14462,7 @@ fn load_resources(
let renderer_cpu = menu.then(|| prepare_renderer_textures(&pack));
if menu {
log::info!(
"Horizon: handoff CPU resources prepared on worker in {} ms",
"RustNotMC: handoff CPU resources prepared on worker in {} ms",
prepared_at.elapsed().as_millis()
);
}
@@ -14488,7 +14491,7 @@ fn load_resources(
progress.set(9);
horizon_client::telemetry::mark_rest_ready();
log::info!(
"Horizon: rest-ready after {} ms",
"RustNotMC: rest-ready after {} ms",
started.elapsed().as_millis()
);
Ok(())
@@ -14548,7 +14551,7 @@ fn load_world_rest(
let recipes = Recipes::load(root, &items)?;
let transformers = horizon_client::block_transform::Transformers::load(root, assets.registry)?;
log::info!(
"Horizon: resources loaded in {:.1}s; {} block states, {} items, {} biomes; {} worker threads",
"RustNotMC: resources loaded in {:.1}s; {} block states, {} items, {} biomes; {} worker threads",
started.elapsed().as_secs_f32(),
facts.states.len(),
items.items.len(),
@@ -14984,7 +14987,7 @@ impl Loading {
.map(f64::from);
self.fullscreen = horizon_client::window::FullscreenState::new(fullscreen);
let attributes = Window::default_attributes()
.with_title("Horizon")
.with_title("RustNotMC")
.with_window_icon(horizon_client::window::icon());
// Wayland names the window by its app id, which the horizon.desktop entry matches.
#[cfg(target_os = "linux")]
@@ -15035,7 +15038,7 @@ impl Loading {
/// and title panorama.
fn set_ui(&mut self, gui: UiResources, root: PathBuf) {
log::info!(
"Horizon: loading the title artwork after {} ms",
"RustNotMC: loading the title artwork after {} ms",
self.started.elapsed().as_millis()
);
self.menu.set_root(root, &self.settings);
@@ -15104,13 +15107,13 @@ impl Loading {
self.menu.perf.title_shown()
}
Ok(_) => {}
Err(e) => log::warn!("Horizon: loading screen frame failed: {e}"),
Err(e) => log::warn!("RustNotMC: loading screen frame failed: {e}"),
}
}
if !self.shown {
self.shown = true;
log::info!(
"Horizon: loading screen shown after {} ms",
"RustNotMC: loading screen shown after {} ms",
self.started.elapsed().as_millis()
);
}
@@ -15139,7 +15142,7 @@ impl Loading {
self.settings.horizon.api,
)?;
log::info!(
"Horizon: world renderer ready after {} ms",
"RustNotMC: world renderer ready after {} ms",
self.started.elapsed().as_millis()
);
let renderer_ms = renderer_at.elapsed().as_millis();
@@ -15180,7 +15183,7 @@ impl Loading {
game.apply_settings();
game.previous = Instant::now();
log::info!(
"Horizon: startup handoff {} ms (renderer {} ms, start_game {} ms)",
"RustNotMC: startup handoff {} ms (renderer {} ms, start_game {} ms)",
handoff_at.elapsed().as_millis(),
renderer_ms,
game_ms
@@ -15370,7 +15373,7 @@ pub fn run() -> Result<()> {
let mut pack_error = None;
options.resources = packs::startup_root(&vanilla_root, &early_settings.resource_packs, &[])
.unwrap_or_else(|e| {
log::warn!("Horizon: resource packs not applied: {e}");
log::warn!("RustNotMC: resource packs not applied: {e}");
pack_error = Some(e.to_string());
vanilla_root.clone()
});
@@ -25,7 +25,7 @@ impl Game<'_> {
if self.settings.extras.no_ai {
if self.options.control.is_some() {
log::warn!(
"Horizon: control socket not opened: {}",
"RustNotMC: control socket not opened: {}",
horizon_core::no_ai::REFUSAL
);
}
@@ -35,7 +35,7 @@ impl Game<'_> {
// Asked for on the command line: failing to listen is an error.
let server = control::Server::start(path)
.map_err(|e| format!("control socket {}: {e}", path.display()))?;
log::info!("Horizon: control socket {}", server.path().display());
log::info!("RustNotMC: control socket {}", server.path().display());
self.control = Some(server);
} else if self.agent_control_on {
self.open_agent_socket();
@@ -49,10 +49,10 @@ impl Game<'_> {
let path = self.agent_socket_path();
match control::Server::start(&path) {
Ok(server) => {
log::info!("Horizon: control socket {}", server.path().display());
log::info!("RustNotMC: control socket {}", server.path().display());
self.control = Some(server);
}
Err(e) => log::warn!("Horizon: control socket {}: {e}", path.display()),
Err(e) => log::warn!("RustNotMC: control socket {}: {e}", path.display()),
}
}
@@ -68,7 +68,7 @@ impl Game<'_> {
.is_some_and(|c| !c.path().as_os_str().is_empty());
if self.settings.extras.no_ai || (changed && !wanted) {
if open {
log::info!("Horizon: control socket closed");
log::info!("RustNotMC: control socket closed");
self.control = None;
}
} else if changed && wanted && self.control.is_none() {
@@ -130,7 +130,7 @@ impl Game<'_> {
let config = serde_json::json!({ "mcpServers": { "horizon-game": {
"command": ctl, "args": ["--socket", socket, "mcp"] } } });
format!(
"Horizon agent control (this computer only)\nSocket: {}\nTry it: \"{}\" --socket \"{}\" state\nMCP config:\n{}\n",
"RustNotMC agent control (this computer only)\nSocket: {}\nTry it: \"{}\" --socket \"{}\" state\nMCP config:\n{}\n",
socket.display(),
ctl.display(),
socket.display(),
+5
View File
@@ -99,6 +99,11 @@ pub struct UiState {
pub screenshot_message: Option<std::path::PathBuf>,
/// The options screens.
pub options: horizon_client::options_ui::OptionsUi,
/// The Rust pause menu over a world (`rustMenu`), whether the preference
/// allows it, and when the menu opened.
pub pause: Option<horizon_client::rustui::RustMenu>,
pub pause_rust: Option<bool>,
pub pause_at: Option<std::time::Instant>,
/// The prepared resources before resource packs are layered on.
pub vanilla_root: std::path::PathBuf,
/// Death screen cause and when the player died (buttons wait 20 ticks).
@@ -206,7 +206,7 @@ impl Game<'_> {
.count();
let [missing, lighting, unlit] = streaming.unstick_light(&mut self.world, &row);
log::warn!(
"Horizon: pregeneration waits on row {:?}: {missing} not loaded, {lighting} being lit, \
"RustNotMC: pregeneration waits on row {:?}: {missing} not loaded, {lighting} being lit, \
{unlit} unlit with no light job (queued again), {waiting} not post-processed; {:?}",
row.first(),
streaming.stages()
+1 -1
View File
@@ -343,7 +343,7 @@ impl Game<'_> {
"Worker-Main-1",
"WARN",
&format!(
"Horizon doesn't generate the {preset} world preset yet: using minecraft:normal"
"RustNotMC doesn't generate the {preset} world preset yet: using minecraft:normal"
),
);
}
+5 -5
View File
@@ -58,7 +58,7 @@ impl Game<'_> {
/// under the warning screen, it is what Back returns to.
pub(super) fn show_dialog(&mut self, tag: &Tag) {
let Some(dialog) = Dialog::parse(tag) else {
log::warn!("Horizon: failed to show dialog for data {tag:?}");
log::warn!("RustNotMC: failed to show dialog for data {tag:?}");
return;
};
let values = dialog.inputs.iter().map(|i| i.control.initial()).collect();
@@ -144,7 +144,7 @@ impl Game<'_> {
self.send_chat(&format!("/{command}"));
} else {
log::warn!(
"Horizon: commands are not supported in configuration, trying to run '{command}'"
"RustNotMC: commands are not supported in configuration, trying to run '{command}'"
);
}
}
@@ -153,7 +153,7 @@ impl Game<'_> {
use horizon_client::clipboard::Clipboard;
self.clipboard.set(&value);
}
Some(other) => log::info!("Horizon: dialog action {other:?} is not supported yet"),
Some(other) => log::info!("RustNotMC: dialog action {other:?} is not supported yet"),
None => {}
}
if !self.dialog_open() {
@@ -178,7 +178,7 @@ impl Game<'_> {
});
match found {
Some(tag) => self.show_dialog(&tag),
None => log::warn!("Horizon: unknown dialog {id}"),
None => log::warn!("RustNotMC: unknown dialog {id}"),
}
}
tag => self.show_dialog(tag),
@@ -200,7 +200,7 @@ impl Game<'_> {
.and_then(|r| r.registries.data("minecraft:dialog", *id).cloned());
match tag {
Some(tag) => self.show_dialog(&tag),
None => log::warn!("Horizon: unknown dialog {id}"),
None => log::warn!("RustNotMC: unknown dialog {id}"),
}
}
}
+1 -1
View File
@@ -111,7 +111,7 @@ impl Game<'_> {
&mut title.mode
{
log::info!(
"Horizon: reconnecting to {} in {} s",
"RustNotMC: reconnecting to {} in {} s",
horizon_client::net::shown_address(&retry.address),
retry.seconds_left(std::time::Instant::now())
);
+1 -1
View File
@@ -108,7 +108,7 @@ impl Game<'_> {
.collect();
let store = DataStore::load(&packs);
for (id, e) in &store.errors {
log::warn!("Horizon: failed to load function {id}: {e}");
log::warn!("RustNotMC: failed to load function {id}: {e}");
}
self.fns.store = store;
self.sync_function_registries();
+3 -3
View File
@@ -67,11 +67,11 @@ pub(super) fn install_live_features(
match features {
Ok(Some(features)) => {
res.behaviours().set_live_features(Arc::new(features));
log::info!("Horizon: live features ready in {:?}", started.elapsed());
log::info!("RustNotMC: live features ready in {:?}", started.elapsed());
}
Ok(None) => {
log::warn!("Horizon: the worldgen bundle has no features; saplings will not grow")
log::warn!("RustNotMC: the worldgen bundle has no features; saplings will not grow")
}
Err(e) => log::warn!("Horizon: live features unavailable: {e}"),
Err(e) => log::warn!("RustNotMC: live features unavailable: {e}"),
}
}
+3 -3
View File
@@ -139,7 +139,7 @@ impl Integrated {
impl Drop for Integrated {
fn drop(&mut self) {
if let Err(error) = self.halt() {
log::error!("Horizon: integrated server shutdown: {error}");
log::error!("RustNotMC: integrated server shutdown: {error}");
}
}
}
@@ -262,7 +262,7 @@ impl Game<'_> {
&ready_tx,
);
if let Err(e) = result {
log::error!("Horizon: integrated server: {e}");
log::error!("RustNotMC: integrated server: {e}");
*server_flags.failure.lock().unwrap() = Some(e.to_string());
let _ = ready_tx.send(Err(e.to_string()));
}
@@ -629,7 +629,7 @@ impl Game<'_> {
match pending {
Publish::Open(listener, settings) => {
if let Err(e) = host.hub.lan.listen_on(listener, true) {
log::error!("Horizon: Open to LAN: {e}");
log::error!("RustNotMC: Open to LAN: {e}");
}
host.settings = settings;
host.hub.config.force_game_mode = settings.force_game_mode;
+1 -1
View File
@@ -377,7 +377,7 @@ impl Game<'_> {
format!(", cpu {:.1} ms", (end - start).as_secs_f32() * 1000.0)
});
log::info!(
"Horizon: slow tick {wall:.1} ms{cpu} ({} mobs): {}",
"RustNotMC: slow tick {wall:.1} ms{cpu} ({} mobs): {}",
self.mobs.len(),
horizon_client::spans::describe(&spans)
);
+5 -5
View File
@@ -234,14 +234,14 @@ pub(super) fn content_root(
id: m.id.clone(),
content,
}),
Err(e) => log::warn!("Horizon: mod {} content not loaded: {e}", m.id),
Err(e) => log::warn!("RustNotMC: mod {} content not loaded: {e}", m.id),
}
}
match mod_content::resource_root(root, &mods, &here.join(".horizon-cache")) {
Ok(out) => {
if out != root {
log::info!(
"Horizon: content from {} mod(s) in {}",
"RustNotMC: content from {} mod(s) in {}",
mods.len(),
out.display()
);
@@ -249,7 +249,7 @@ pub(super) fn content_root(
out
}
Err(e) => {
log::warn!("Horizon: content mods not loaded: {e}");
log::warn!("RustNotMC: content mods not loaded: {e}");
root.to_owned()
}
}
@@ -264,7 +264,7 @@ impl Game<'_> {
let found = horizon_mods::find(&dir).len() + self.mods.dev.len();
if found > 0 {
log::warn!(
"Horizon: {found} mod(s) not started: this build has no mod runtime (build with --features mods)"
"RustNotMC: {found} mod(s) not started: this build has no mod runtime (build with --features mods)"
);
}
}
@@ -620,7 +620,7 @@ impl Game<'_> {
if self.options.execution_role.is_client() {
self.system_message(Text::literal("Mods reloaded").with_color(text::GRAY));
} else {
log::info!("Horizon: mods reloaded");
log::info!("RustNotMC: mods reloaded");
}
}
}
@@ -93,7 +93,7 @@ mod with_mods {
installed = true;
}
Err(e) => {
log::warn!("Horizon: {} not installed, next start retries: {e}", m.id);
log::warn!("RustNotMC: {} not installed, next start retries: {e}", m.id);
self.mods.moved.notices.push(
Text::literal(format!(
"{} moved to the mod browser; it couldn't be installed for you yet, Horizon tries again at the next start",
+18
View File
@@ -101,6 +101,24 @@ impl Game<'_> {
self.screen = Screen::Options;
self.options_from_title = from_title;
let ui = &mut self.ui.options;
// The Rust settings shell is the default; `horizon.txt`'s `rustSettings`
// off restores vanilla's screens (the rollback).
let dir = Self::options_path()
.parent()
.map(std::path::Path::to_path_buf)
.unwrap_or_default();
ui.rust = horizon_client::ui_theme::preference(&dir, "rustSettings").is_none_or(|v| {
!matches!(
v.trim().to_ascii_lowercase().as_str(),
"false" | "0" | "off"
)
});
// The shell's rail is the main page: it opens on the first category.
let page = if ui.rust && page == Page::Main {
Page::Video
} else {
page
};
ui.open_at(!from_title && self.title.is_none(), page);
let root = self.options.resources.clone();
ui.languages = lang::available(&[&root]);
+2 -2
View File
@@ -40,7 +40,7 @@ pub fn open_folder(dir: &Path) {
"xdg-open"
};
if let Err(e) = std::process::Command::new(program).arg(dir).spawn() {
log::warn!("Horizon: could not open {}: {e}", dir.display());
log::warn!("RustNotMC: could not open {}: {e}", dir.display());
}
}
/// `Util.getPlatform().openUri`: the system browser on the link.
@@ -137,7 +137,7 @@ impl Game<'_> {
return;
}
if let Err(e) = self.reload_selected_packs() {
log::warn!("Horizon: resource reload failed: {e}");
log::warn!("RustNotMC: resource reload failed: {e}");
if self.screen != super::Screen::Options {
self.open_options_at(
self.title.is_some(),
+1 -1
View File
@@ -160,7 +160,7 @@ impl Game<'_> {
fn pad_button_logged(&mut self, event_loop: &ActiveEventLoop, button: Button, down: bool) {
if let Err(e) = self.pad_button(event_loop, button, down) {
log::warn!("Horizon: controller {}: {e}", button.name());
log::warn!("RustNotMC: controller {}: {e}", button.name());
}
}
@@ -74,7 +74,7 @@ impl Pads {
}
Err(gilrs::Error::NotImplemented(_)) => None,
Err(e) => {
log::warn!("Horizon: controllers are unavailable: {e}");
log::warn!("RustNotMC: controllers are unavailable: {e}");
None
}
};
@@ -380,7 +380,7 @@ impl Game<'_> {
let end = Instant::now() + Duration::from_millis(u64::from(pulse.millis) + 50);
self.pad.devices.rumbles.push((effect, end));
}
Err(e) => log::debug!("Horizon: controller vibration: {e}"),
Err(e) => log::debug!("RustNotMC: controller vibration: {e}"),
}
}
+1 -1
View File
@@ -947,7 +947,7 @@ impl Game<'_> {
None => self.options_key(key.expect("a key"), None),
};
if let Err(e) = result {
log::warn!("Horizon: on-screen keyboard: {e}");
log::warn!("RustNotMC: on-screen keyboard: {e}");
}
} else if self.title.is_some() {
match key {
+1 -1
View File
@@ -1020,7 +1020,7 @@ impl Game<'_> {
let keys: HashSet<(i32, i32)> = unloaded.iter().map(|c| (c.x, c.z)).collect();
let chunks = self.entity_chunks(&keys, true);
if let Err(e) = self.save.save_entities_later(chunks) {
log::warn!("Horizon: failed to save entities: {e}");
log::warn!("RustNotMC: failed to save entities: {e}");
}
}
/// Leaving a dimension: its entities are saved with it.
+4 -4
View File
@@ -312,7 +312,7 @@ impl Game<'_> {
}
self.join_world_rest()?;
if let Err(error) = self.join_server(address, name, None, cookies) {
log::warn!("Horizon: could not join server: {error}");
log::warn!("RustNotMC: could not join server: {error}");
if self.title.is_none() {
self.title = Some(horizon_client::title::Title::new(
std::env::current_dir()?.join("saves"),
@@ -839,7 +839,7 @@ impl Game<'_> {
break;
}
Next::Lost => {
log::warn!("Horizon: the chunk decoder stopped; a column is missing");
log::warn!("RustNotMC: the chunk decoder stopped; a column is missing");
continue;
}
};
@@ -912,7 +912,7 @@ impl Game<'_> {
if let Some(r) = self.remote.as_mut() {
r.decode_errors += 1;
if r.decode_errors <= 20 {
log::warn!("Horizon: skipped undecodable packet {e}");
log::warn!("RustNotMC: skipped undecodable packet {e}");
}
}
}
@@ -920,7 +920,7 @@ impl Game<'_> {
reason,
from_server,
} => {
log::info!("Horizon: disconnected: {reason}");
log::info!("RustNotMC: disconnected: {reason}");
// ClientboundTransferPacket left a target: connect there
// instead of showing the disconnect, the stored cookies
// carried over (ClientCommonPacketListenerImpl.
@@ -186,7 +186,7 @@ impl ChunkDecoder {
}
});
if let Err(e) = spawned {
log::warn!("Horizon: no chunk decoder thread ({e}); chunks decode in the frame");
log::warn!("RustNotMC: no chunk decoder thread ({e}); chunks decode in the frame");
}
Self { jobs, done }
}
@@ -244,7 +244,7 @@ impl Game<'_> {
let chunk = match column {
Ok(chunk) => chunk,
Err(e) => {
log::warn!("Horizon: chunk {} {}: {e}", p.x, p.z);
log::warn!("RustNotMC: chunk {} {}: {e}", p.x, p.z);
return;
}
};
+88 -8
View File
@@ -133,7 +133,59 @@ impl Game<'_> {
pub(super) fn external_server(&self) -> bool {
self.remote.is_some() && self.integrated.is_none()
}
/// Builds the Rust pause menu on first use, when `rustMenu` is on.
fn ensure_rust_pause(&mut self) {
if self.ui.pause.is_some() {
return;
}
let rust = *self.ui.pause_rust.get_or_insert_with(|| {
let dir = Self::options_path()
.parent()
.map(std::path::Path::to_path_buf)
.unwrap_or_default();
horizon_client::ui_theme::preference(&dir, "rustMenu").is_none_or(|v| {
!matches!(
v.trim().to_ascii_lowercase().as_str(),
"false" | "0" | "off"
)
})
});
if !rust {
return;
}
let dir = Self::options_path()
.parent()
.map(std::path::Path::to_path_buf)
.unwrap_or_default();
let mut menu = horizon_client::rustui::RustMenu::new(&dir.join("saves"));
let server = self.remote.is_some();
let last = self.settings.file.string("lastServer");
menu.current = Some(horizon_client::rustui::CurrentServer {
name: if server {
last.clone()
} else {
self.level.name.to_string()
},
address: if server { last } else { String::new() },
singleplayer: !server,
});
menu.tab = horizon_client::rustui::Tab::Current;
self.ui.pause = Some(menu);
self.ui.pause_at = Some(std::time::Instant::now());
}
pub(super) fn draw_pause_menu(&mut self, batch: &mut HudBatch) {
self.ensure_rust_pause();
if let Some(menu) = &self.ui.pause {
let last = self.settings.file.string("lastServer");
let meta = horizon_client::rustui::Meta {
elapsed: self
.ui
.pause_at
.map_or(0.0, |at| at.elapsed().as_secs_f32()),
};
menu.draw(&self.gui.atlas, batch, self.cursor, &last, &meta);
return;
}
let friends = self.friends_view().shown;
let atlas = &self.gui.atlas;
let (w, h) = (batch.width, batch.height);
@@ -211,14 +263,42 @@ impl Game<'_> {
}
}
pub(super) fn pause_click(&mut self) -> Result<()> {
let (w, h) = {
let size = self
.renderer
.as_ref()
.map_or([1, 1], |r| [r.config.width, r.config.height]);
let b = HudBatch::new(size);
(b.width, b.height)
};
let size = self
.renderer
.as_ref()
.map_or([1, 1], |r| [r.config.width, r.config.height]);
let b = HudBatch::new(size);
let (w, h) = (b.width, b.height);
if self.ui.pause.is_some() {
let last = self.settings.file.string("lastServer");
let frame = horizon_client::rustui::Frame::new((w, h), b.scale, self.cursor);
let (outcome, sound) = {
let menu = self.ui.pause.as_mut().expect("checked above");
menu.click(&frame, &last)
};
if sound {
self.audio.play_button_click();
}
use horizon_client::rustui::Outcome as O;
match outcome {
O::Resume => {
self.ui.pause = None;
self.screen = Screen::Playing;
self.pause_menu = false;
self.capture(true);
}
O::Options => self.open_options(false),
O::Stats => self.open_stats(),
O::Advancements => self.open_advancements(true),
O::WorldOptions => self.open_world_options(),
O::Quit => {
self.ui.pause = None;
self.close_world()?;
}
_ => {}
}
return Ok(());
}
let links = !self.server_links().is_empty();
let friends = pause_icons(w, h, links)[FRIENDS_ICON];
let hit = pause_buttons(w, h, self.external_server(), links)
@@ -57,7 +57,7 @@ pub(super) fn trusted(links: Vec<ServerLink>) -> Vec<ServerLink> {
.filter(|l| {
let ok = valid_untrusted_uri(&l.link);
if !ok {
log::warn!("Horizon: server sent an invalid link: {}", l.link);
log::warn!("RustNotMC: server sent an invalid link: {}", l.link);
}
ok
})
@@ -384,13 +384,13 @@ mod run {
let state = match crate::game::render_control::parse_state(registry, &b.state) {
Ok(state) => state,
Err(e) => {
log::warn!("Horizon: a server mod set {}: {e}", b.state);
log::warn!("RustNotMC: a server mod set {}: {e}", b.state);
continue;
}
};
if let Err(e) = self.place_state([b.x, b.y, b.z], state, false) {
log::debug!(
"Horizon: a server mod's block at {} {} {}: {e:?}",
"RustNotMC: a server mod's block at {} {} {}: {e:?}",
b.x,
b.y,
b.z
@@ -565,7 +565,7 @@ mod run {
let over = queued.len() - MAX_QUEUED_WRITES;
queued.drain(..over);
log::warn!(
"Horizon: mod {name} set more blocks than wait for their level: {over} dropped"
"RustNotMC: mod {name} set more blocks than wait for their level: {over} dropped"
);
}
}
@@ -326,7 +326,7 @@ impl Game<'_> {
entry.accept_textures = setting;
}
if let Err(e) = servers::save(&file, &list) {
log::warn!("Horizon: could not save {}: {e}", file.display());
log::warn!("RustNotMC: could not save {}: {e}", file.display());
}
}
Ok(())
@@ -373,7 +373,7 @@ impl Game<'_> {
match download::Queue::open(dir) {
Ok(queue) => state.queue = Some(queue),
Err(e) => {
log::error!("Horizon: failed to open the download queue: {e}");
log::error!("RustNotMC: failed to open the download queue: {e}");
// Every request failed, as the notifier would hear it.
let (progress, events) = std::sync::mpsc::channel();
for _ in &requests {
@@ -411,7 +411,7 @@ impl Game<'_> {
.map(|(id, path)| packs::server_pack(*id, path))
.collect();
let Some(server) = server else {
log::warn!("Horizon: invalid pack metadata in a server pack, ignoring all");
log::warn!("RustNotMC: invalid pack metadata in a server pack, ignoring all");
self.finish_pack_reload(false);
return;
};
@@ -452,7 +452,7 @@ impl Game<'_> {
match handle {
Ok(handle) => self.server_packs.reload = Some(PackReload { progress, handle }),
Err(e) => {
log::error!("Horizon: could not start the pack reload worker: {e}");
log::error!("RustNotMC: could not start the pack reload worker: {e}");
self.finish_pack_reload(false);
}
}
@@ -476,7 +476,7 @@ impl Game<'_> {
{
Ok(()) => true,
Err(e) => {
log::warn!("Horizon: server resource pack reload failed: {e}");
log::warn!("RustNotMC: server resource pack reload failed: {e}");
false
}
};
@@ -656,7 +656,7 @@ impl Loading {
if let Some(loader) = loaded.rest_loader.take()
&& let Err(error) = loader.finish()
{
log::warn!("Horizon: replaced resource generation failed: {error}");
log::warn!("RustNotMC: replaced resource generation failed: {error}");
}
}
self.loaded = None;
@@ -255,7 +255,7 @@ pub(super) fn preload_world_data(
});
match spawned {
Ok(thread) => *preload = Preload::Started { thread, left: None },
Err(e) => log::warn!("Horizon: world data preload: {e}"),
Err(e) => log::warn!("RustNotMC: world data preload: {e}"),
}
}
Preload::Idle => {}
@@ -268,7 +268,7 @@ pub(super) fn preload_world_data(
super::lan::forget_sync_data();
horizon_threads::release_free_memory();
*preload = Preload::Idle;
log::info!("Horizon: preloaded world data dropped, no world opened");
log::info!("RustNotMC: preloaded world data dropped, no world opened");
}
}
}
+19 -19
View File
@@ -122,7 +122,7 @@ fn world_pass_after_culling<'e>(
keep_depth: bool,
) -> wgpu::RenderPass<'e> {
encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
label: Some("Horizon world, after culling"),
label: Some("RustNotMC world, after culling"),
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
view,
resolve_target: None,
@@ -815,7 +815,7 @@ struct Opened {
fn describe_adapter(adapter: &wgpu::Adapter) {
let info = adapter.get_info();
log::info!(
"Horizon renderer: {} ({:?}, {:?})",
"RustNotMC renderer: {} ({:?}, {:?})",
info.name,
info.backend,
info.device_type
@@ -885,7 +885,7 @@ async fn open_device(
for (attempt, backends) in order.iter().copied().enumerate() {
let name = backends_name(backends);
if attempt > 0 {
log::warn!("Horizon renderer: trying {name} ({})", failures.join("; "));
log::warn!("RustNotMC renderer: trying {name} ({})", failures.join("; "));
}
let instance = wgpu::Instance::new(instance_descriptor(backends));
let surface = if offscreen {
@@ -946,7 +946,7 @@ async fn open_device(
limits.max_texture_array_layers,
));
let desc = wgpu::DeviceDescriptor {
label: Some("Horizon device"),
label: Some("RustNotMC device"),
required_features: features,
required_limits: limits,
..Default::default()
@@ -994,7 +994,7 @@ const NO_GPU_DRIVER: &str = "No Vulkan or OpenGL graphics driver found: Horizon
/// only sign of where the game stopped. The log file is written unbuffered;
/// the flush is for loggers that buffer.
fn startup_step(step: std::fmt::Arguments) {
log::info!("Horizon renderer: {step}");
log::info!("RustNotMC renderer: {step}");
log::logger().flush();
}
/// How far the first frame on a new device got, for `startup_step`.
@@ -1149,7 +1149,7 @@ impl Renderer {
}
let gpu_timer = timing::GpuTimer::new(&device, &queue);
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
label: Some("Horizon terrain"),
label: Some("RustNotMC terrain"),
source: wgpu::ShaderSource::Wgsl(include_str!("terrain.wgsl").into()),
});
let entry = |binding, visibility, ty| wgpu::BindGroupLayoutEntry {
@@ -1166,14 +1166,14 @@ impl Renderer {
};
let sprite_arrays = layers.div_ceil(split).max(1);
if sprite_arrays > 1 {
log::info!("Horizon: {layers} block textures in {sprite_arrays} arrays");
log::info!("RustNotMC: {layers} block textures in {sprite_arrays} arrays");
}
let sprite_constants = [
("SPRITE_ARRAYS", f64::from(sprite_arrays)),
("SPRITE_SPLIT", f64::from(split)),
];
let bindings = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
label: Some("Horizon terrain bindings"),
label: Some("RustNotMC terrain bindings"),
entries: &[
entry(
0,
@@ -1222,7 +1222,7 @@ impl Renderer {
],
});
let layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
label: Some("Horizon terrain layout"),
label: Some("RustNotMC terrain layout"),
bind_group_layouts: &[Some(&bindings)],
..Default::default()
});
@@ -1413,7 +1413,7 @@ impl Renderer {
Some(alpha_blend),
);
let globals = device.create_buffer(&wgpu::BufferDescriptor {
label: Some("Horizon globals"),
label: Some("RustNotMC globals"),
size: std::mem::size_of::<Globals>() as u64,
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
mapped_at_creation: false,
@@ -1532,7 +1532,7 @@ impl Renderer {
});
let group = terrain_group(
&device,
"Horizon terrain resources",
"RustNotMC terrain resources",
&bindings,
&globals,
&sprite_views,
@@ -1668,7 +1668,7 @@ impl Renderer {
)?;
hud.atlas_texture = Some(atlas.clone());
let entity_shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
label: Some("Horizon entities"),
label: Some("RustNotMC entities"),
source: wgpu::ShaderSource::Wgsl(entity_shader().into()),
});
let entity_bindings = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
@@ -2266,7 +2266,7 @@ impl Renderer {
..Default::default()
});
let border_shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
label: Some("Horizon world border"),
label: Some("RustNotMC world border"),
source: wgpu::ShaderSource::Wgsl(include_str!("border.wgsl").into()),
});
let border_attributes = wgpu::vertex_attr_array![0=>Float32x3,1=>Float32x2];
@@ -2326,7 +2326,7 @@ impl Renderer {
cache: None,
});
let screen_shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
label: Some("Horizon screen effects"),
label: Some("RustNotMC screen effects"),
source: wgpu::ShaderSource::Wgsl(include_str!("screen.wgsl").into()),
});
let screen_attributes =
@@ -2757,7 +2757,7 @@ impl Renderer {
let read = cull.is_some_and(|c| c.depth_test() == cull::DepthTest::InShader);
device
.create_texture(&wgpu::TextureDescriptor {
label: Some("Horizon depth"),
label: Some("RustNotMC depth"),
size: wgpu::Extent3d {
width: config.width,
height: config.height,
@@ -3406,7 +3406,7 @@ impl Renderer {
let views = sprite_views(&self.sprite_textures, &self.sprite_unused, Some(levels + 1));
self.group = terrain_group(
&self.device,
"Horizon terrain resources",
"RustNotMC terrain resources",
&self.terrain_layout,
&self.globals,
&views,
@@ -3583,7 +3583,7 @@ impl Renderer {
let mut encoder = section_copies.unwrap_or_else(|| {
self.device
.create_command_encoder(&wgpu::CommandEncoderDescriptor {
label: Some("Horizon frame"),
label: Some("RustNotMC frame"),
})
});
if self.animated_textures {
@@ -4602,7 +4602,7 @@ impl Renderer {
},
})];
let mut pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
label: Some("Horizon world"),
label: Some("RustNotMC world"),
color_attachments: &attachments,
depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachment {
view: world_depth,
@@ -5269,7 +5269,7 @@ impl Renderer {
texture: &wgpu::Texture,
) -> wgpu::Buffer {
let buffer = self.device.create_buffer(&wgpu::BufferDescriptor {
label: Some("Horizon screenshot"),
label: Some("RustNotMC screenshot"),
size: u64::from(self.padded_row()) * u64::from(self.config.height),
usage: wgpu::BufferUsages::COPY_DST | wgpu::BufferUsages::MAP_READ,
mapped_at_creation: false,
+2 -2
View File
@@ -109,7 +109,7 @@ impl SpriteAnimator {
let bytes: u64 = chains.iter().map(|(chain, _)| chain.len() as u64).sum();
if bytes > limit {
log::warn!(
"Horizon: layer {}'s animation ({bytes} bytes) does not fit in a storage buffer; it stays still",
"RustNotMC: layer {}'s animation ({bytes} bytes) does not fit in a storage buffer; it stays still",
animation.layer
);
continue;
@@ -386,7 +386,7 @@ fn pipeline(device: &wgpu::Device) -> Option<wgpu::ComputePipeline> {
match internal.or(pollster::block_on(validation.pop())) {
None => Some(pipeline),
Some(e) => {
log::warn!("Horizon renderer: animated sprites drawn on the CPU ({e})");
log::warn!("RustNotMC renderer: animated sprites drawn on the CPU ({e})");
None
}
}
+1 -1
View File
@@ -162,7 +162,7 @@ impl Arena {
)?;
if !std::mem::replace(&mut self.spilled, true) {
log::warn!(
"Horizon: video memory is full; more terrain is kept in system memory \
"RustNotMC: video memory is full; more terrain is kept in system memory \
(lower the render distance if frames slow down)"
);
}
+9 -9
View File
@@ -72,7 +72,7 @@ pub struct Hdr {
impl Hdr {
pub fn new(device: &wgpu::Device, format: wgpu::TextureFormat, output: Output) -> Self {
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
label: Some("Horizon HDR"),
label: Some("RustNotMC HDR"),
source: wgpu::ShaderSource::Wgsl(include_str!("../hdr.wgsl").into()),
});
let texture = |binding| wgpu::BindGroupLayoutEntry {
@@ -86,7 +86,7 @@ impl Hdr {
count: None,
};
let layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
label: Some("Horizon HDR bindings"),
label: Some("RustNotMC HDR bindings"),
entries: &[
texture(0),
texture(1),
@@ -103,12 +103,12 @@ impl Hdr {
],
});
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
label: Some("Horizon HDR"),
label: Some("RustNotMC HDR"),
bind_group_layouts: &[Some(&layout)],
..Default::default()
});
let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
label: Some("Horizon HDR"),
label: Some("RustNotMC HDR"),
layout: Some(&pipeline_layout),
vertex: wgpu::VertexState {
module: &shader,
@@ -133,7 +133,7 @@ impl Hdr {
cache: None,
});
let params = device.create_buffer(&wgpu::BufferDescriptor {
label: Some("Horizon HDR parameters"),
label: Some("RustNotMC HDR parameters"),
size: 32,
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
mapped_at_creation: false,
@@ -171,13 +171,13 @@ impl Hdr {
})
};
let frame = texture(
"Horizon HDR frame",
"RustNotMC HDR frame",
wgpu::TextureUsages::RENDER_ATTACHMENT | wgpu::TextureUsages::COPY_SRC,
);
let world = texture("Horizon HDR world", wgpu::TextureUsages::COPY_DST);
let world = texture("RustNotMC HDR world", wgpu::TextureUsages::COPY_DST);
let view = |t: &wgpu::Texture| t.create_view(&Default::default());
let group = device.create_bind_group(&wgpu::BindGroupDescriptor {
label: Some("Horizon HDR bindings"),
label: Some("RustNotMC HDR bindings"),
layout: &self.layout,
entries: &[
wgpu::BindGroupEntry {
@@ -250,7 +250,7 @@ impl Hdr {
},
})];
let mut pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
label: Some("Horizon HDR"),
label: Some("RustNotMC HDR"),
color_attachments: &attachments,
..Default::default()
});
+1 -1
View File
@@ -602,7 +602,7 @@ impl Occlusion {
self.changed_late.clear();
return;
}
log::warn!("Horizon: the occlusion worker stopped; culling on the render thread");
log::warn!("RustNotMC: the occlusion worker stopped; culling on the render thread");
self.worker = None;
}
self.edits.clear();
+1 -1
View File
@@ -16,7 +16,7 @@ pub struct Faces {
impl Faces {
pub fn load(root: &Path) -> Self {
Self::try_load(root).unwrap_or_else(|error| {
log::warn!("Horizon: title panorama unavailable ({error})");
log::warn!("RustNotMC: title panorama unavailable ({error})");
Self {
size: 1,
pixels: [96, 110, 111, 255].repeat(6),
+7 -7
View File
@@ -25,11 +25,11 @@ pub struct Post {
impl Post {
pub fn new(device: &wgpu::Device, format: wgpu::TextureFormat) -> Self {
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
label: Some("Horizon post"),
label: Some("RustNotMC post"),
source: wgpu::ShaderSource::Wgsl(include_str!("../world_post.wgsl").into()),
});
let layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
label: Some("Horizon post bindings"),
label: Some("RustNotMC post bindings"),
entries: &[
wgpu::BindGroupLayoutEntry {
binding: 0,
@@ -50,13 +50,13 @@ impl Post {
],
});
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
label: Some("Horizon post"),
label: Some("RustNotMC post"),
bind_group_layouts: &[Some(&layout)],
..Default::default()
});
let pipeline = |entry: &str| {
device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
label: Some("Horizon post"),
label: Some("RustNotMC post"),
layout: Some(&pipeline_layout),
vertex: wgpu::VertexState {
module: &shader,
@@ -82,7 +82,7 @@ impl Post {
})
};
let sampler = device.create_sampler(&wgpu::SamplerDescriptor {
label: Some("Horizon post"),
label: Some("RustNotMC post"),
mag_filter: wgpu::FilterMode::Linear,
min_filter: wgpu::FilterMode::Linear,
..Default::default()
@@ -165,7 +165,7 @@ impl Post {
/// Bindings that copy (or anti-alias) `view` onto the screen in `finish_with`.
pub fn bind(&self, device: &wgpu::Device, view: &wgpu::TextureView) -> wgpu::BindGroup {
device.create_bind_group(&wgpu::BindGroupDescriptor {
label: Some("Horizon post"),
label: Some("RustNotMC post"),
layout: &self.layout,
entries: &[
wgpu::BindGroupEntry {
@@ -203,7 +203,7 @@ impl Post {
},
})];
let mut pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
label: Some("Horizon post"),
label: Some("RustNotMC post"),
color_attachments: &attachments,
..Default::default()
});
+2 -2
View File
@@ -34,7 +34,7 @@ pub fn start() {
Ok(handle) => {
let _ = PINGER.set(handle.thread().clone());
}
Err(e) => log::warn!("Horizon: no live count ping: {e}"),
Err(e) => log::warn!("RustNotMC: no live count ping: {e}"),
}
}
@@ -62,7 +62,7 @@ fn run(endpoint: &str) {
Err(e) => {
// Said once, not every minute the server is away.
if !failed {
log::info!("Horizon: the live count ping failed ({e}); trying again later");
log::info!("RustNotMC: the live count ping failed ({e}); trying again later");
}
failed = true;
wait = (wait * 2).min(MAX_WAIT);
+8 -1
View File
@@ -501,6 +501,13 @@ impl HudAtlas {
images.push(("horizon/white".into(), 4, 4, vec![255; 64]));
if full {
Self::slots(&mut images, crate::trims::slot_size(root));
// Our own icons are part of every atlas: no runtime upload, so a
// rebuild while resources load cannot wipe them.
for (name, bytes) in crate::rustui::icons::ICONS {
if let Ok((w, h, rgba)) = decode_bytes(bytes) {
images.push((format!("horizon/rustui-icons/{name}"), w, h, rgba));
}
}
}
// Blurred sprites are sampled linearly in the atlas (screen.wgsl): a
// border wrapped from their own edges keeps the filter off their
@@ -1152,7 +1159,7 @@ impl HudRenderer {
glint_sampler: &wgpu::Sampler,
) -> Result<Self> {
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
label: Some("Horizon HUD"),
label: Some("RustNotMC HUD"),
source: wgpu::ShaderSource::Wgsl(include_str!("hud.wgsl").into()),
});
+3
View File
@@ -140,6 +140,9 @@ pub mod random_tick_sections;
pub mod recipe_book;
pub mod recipe_book_screen;
pub mod reconnect;
pub mod rsx;
pub mod rsx_terrain;
pub mod rustui;
pub mod save;
pub mod scoreboard_cmd;
pub mod screen_draw;
+1 -1
View File
@@ -174,7 +174,7 @@ impl WaypointStyles {
{
out.insert(format!("{namespace}:{name}"), style);
} else {
log::warn!("Horizon: invalid waypoint style {}", path.display());
log::warn!("RustNotMC: invalid waypoint style {}", path.display());
}
}
}
+4 -4
View File
@@ -243,7 +243,7 @@ impl Writer {
{
let _ = writeln!(
stderr.lock(),
"Horizon: could not roll over the log: {e}"
"RustNotMC: could not roll over the log: {e}"
);
}
self.date = date;
@@ -362,14 +362,14 @@ pub fn init(home: &Path, main_thread: &'static str) {
Ok(Some(latest)) => Some(latest),
Ok(None) => {
eprintln!(
"Horizon: another game is writing {}; this one logs to the terminal only",
"RustNotMC: another game is writing {}; this one logs to the terminal only",
dir.join("latest.log").display()
);
None
}
Err(e) => {
eprintln!(
"Horizon: could not open {}: {e}",
"RustNotMC: could not open {}: {e}",
dir.join("latest.log").display()
);
None
@@ -386,7 +386,7 @@ pub fn init(home: &Path, main_thread: &'static str) {
.name("Log writer".into())
.spawn(move || writer.run(receive))
{
eprintln!("Horizon: could not start the log writer: {e}");
eprintln!("RustNotMC: could not start the log writer: {e}");
}
Logger {
out,
+2 -2
View File
@@ -24,11 +24,11 @@ fn main() {
if !help {
logging::init(&home, thread);
// The log's first line names the build, so a bug report that carries the log says which one it was.
log::info!("Horizon {}", crash::version());
log::info!("RustNotMC {}", crash::version());
crash::install(home.clone(), side);
}
if let Err(error) = game::run() {
log::error!("Horizon: {error}");
log::error!("RustNotMC: {error}");
if !help {
crash::report_error(&home, side, &*error);
}
@@ -156,7 +156,7 @@ pub fn load_registry(root: &Path) {
let id = rel.to_string_lossy().replace('\\', "/");
out.insert(format!("{ns}:{id}"), c);
}
None => log::warn!("Horizon: bad trial spawner config {}", path.display()),
None => log::warn!("RustNotMC: bad trial spawner config {}", path.display()),
}
}
}
+2 -2
View File
@@ -1247,11 +1247,11 @@ pub fn resource_root(base: &Path, mods: &[ContentMod], cache: &Path) -> Result<P
if fs::read(out.join(STAMP)).is_ok_and(|s| s == stamp.as_bytes()) {
// A reused root warns as the build did.
let warnings = fs::read_to_string(out.join(WARNINGS)).unwrap_or_default();
warnings.lines().for_each(|w| log::warn!("Horizon: {w}"));
warnings.lines().for_each(|w| log::warn!("RustNotMC: {w}"));
return Ok(out);
}
for warning in build(base, mods, &out)? {
log::warn!("Horizon: {warning}");
log::warn!("RustNotMC: {warning}");
}
fs::write(out.join(STAMP), stamp)?;
Ok(out)
+1 -1
View File
@@ -97,7 +97,7 @@ impl ParsedModels {
match read() {
Ok(model) => Arc::new(model),
Err(e) if or_missing => {
log::warn!("Horizon: missing block model {name}: {e}");
log::warn!("RustNotMC: missing block model {name}: {e}");
skipped.insert(name);
continue;
}
+2 -2
View File
@@ -159,7 +159,7 @@ impl StateModels {
Ok(loaded) => loaded,
Err(e) => {
log::warn!(
"Horizon: blockstate definition of {namespace}:{path} not loaded: {e}"
"RustNotMC: blockstate definition of {namespace}:{path} not loaded: {e}"
);
continue;
}
@@ -212,7 +212,7 @@ impl StateModels {
let library = match models.block_library(root, names.clone()) {
Ok(library) => library,
Err(e) => {
log::warn!("Horizon: block models incomplete ({e}); using the missing model");
log::warn!("RustNotMC: block models incomplete ({e}); using the missing model");
models.block_library_or_missing(root, names)?
}
};

Some files were not shown because too many files have changed in this diff Show More