chore: ensure favicon is png and 64x64 (#1418)

This commit is contained in:
FabseGP
2026-02-07 09:34:13 +00:00
committed by GitHub
parent 86aeba7b4c
commit 1b7f018fd6
2 changed files with 46 additions and 22 deletions

View File

@@ -104,7 +104,7 @@ pub struct BasicConfiguration {
/// Whether to use a server favicon
pub use_favicon: bool,
/// Path to server favicon
pub favicon_path: String,
pub favicon_path: Option<String>,
/// The default level name
pub default_level_name: String,
/// Whether chat messages should be signed or not
@@ -139,7 +139,7 @@ impl Default for BasicConfiguration {
force_gamemode: false,
scrub_ips: true,
use_favicon: true,
favicon_path: "icon.png".to_string(),
favicon_path: None,
default_level_name: "world".to_string(),
allow_chat_reports: false,
white_list: false,
@@ -201,7 +201,6 @@ pub trait LoadConfiguration {
merged_config
} else {
let content = Self::default();
if let Err(err) = fs::write(&path, toml::to_string(&content).unwrap()) {
log::warn!(
"Couldn't write default config to {:?}. Reason: {}",

View File

@@ -18,6 +18,14 @@ const DEFAULT_ICON: &[u8] = include_bytes!("../../../assets/default_icon.png");
fn load_icon_from_file<P: AsRef<Path>>(path: P) -> Result<String, Box<dyn error::Error>> {
let buf = fs::read(path)?;
if buf.len() >= 24 {
let width = u32::from_be_bytes([buf[16], buf[17], buf[18], buf[19]]);
let height = u32::from_be_bytes([buf[20], buf[21], buf[22], buf[23]]);
if width != 64 || height != 64 {
return Err("Invalid favicon dimensions (must be 64x64)".into());
}
}
Ok(load_icon_from_bytes(&buf))
}
@@ -117,28 +125,45 @@ impl CachedStatus {
pub fn build_response(config: &BasicConfiguration) -> StatusResponse {
let favicon = if config.use_favicon {
let icon_path = &config.favicon_path;
log::debug!("Attempting to load server favicon from '{icon_path}'");
match load_icon_from_file(icon_path) {
Ok(icon) => Some(icon),
Err(e) => {
let error_message = e.downcast_ref::<std::io::Error>().map_or_else(
|| format!("other error: {e}; using default."),
|io_err| {
if io_err.kind() == std::io::ErrorKind::NotFound {
"not found; using default.".to_string()
} else {
format!("I/O error: {io_err}; using default.")
}
},
);
log::warn!("Failed to load favicon from '{icon_path}': {error_message}");
config.favicon_path.as_ref().map_or_else(
|| {
log::debug!("Loading default icon");
// Attempt to load default icon
Some(load_icon_from_bytes(DEFAULT_ICON))
}
}
},
|icon_path| {
if !std::path::Path::new(icon_path)
.extension()
.is_some_and(|ext| ext.eq_ignore_ascii_case("png"))
{
log::warn!("Favicon is not a PNG-image, using default.");
return Some(load_icon_from_bytes(DEFAULT_ICON));
}
log::debug!("Attempting to load server favicon from '{icon_path}'");
match load_icon_from_file(icon_path) {
Ok(icon) => Some(icon),
Err(e) => {
let error_message = e.downcast_ref::<std::io::Error>().map_or_else(
|| format!("other error: {e}; using default."),
|io_err| {
if io_err.kind() == std::io::ErrorKind::NotFound {
"not found; using default.".to_string()
} else {
format!("I/O error: {io_err}; using default.")
}
},
);
log::warn!(
"Failed to load favicon from '{icon_path}': {error_message}"
);
Some(load_icon_from_bytes(DEFAULT_ICON))
}
}
},
)
} else {
log::info!("Favicon usage is disabled.");
None