Add server favicon to status responses
This commit is contained in:
parent
0715baed8c
commit
c9d7af0e3c
11
Cargo.lock
generated
11
Cargo.lock
generated
@ -163,6 +163,12 @@ version = "1.0.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "base64"
|
||||||
|
version = "0.13.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "1.3.2"
|
version = "1.3.2"
|
||||||
@ -750,6 +756,7 @@ name = "lazymc"
|
|||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
"base64",
|
||||||
"bytes",
|
"bytes",
|
||||||
"chrono",
|
"chrono",
|
||||||
"clap",
|
"clap",
|
||||||
@ -815,7 +822,7 @@ checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "minecraft-protocol"
|
name = "minecraft-protocol"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/timvisee/rust-minecraft-protocol?rev=a14b40e#a14b40ea9d9a9ed54a6f6546b6d19bc0db1b6c8c"
|
source = "git+https://github.com/timvisee/rust-minecraft-protocol?rev=356ea54#356ea5424374c5a7249be2f0f13fd3e0e2db5b58"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"minecraft-protocol-derive",
|
"minecraft-protocol-derive",
|
||||||
@ -828,7 +835,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "minecraft-protocol-derive"
|
name = "minecraft-protocol-derive"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
source = "git+https://github.com/timvisee/rust-minecraft-protocol?rev=a14b40e#a14b40ea9d9a9ed54a6f6546b6d19bc0db1b6c8c"
|
source = "git+https://github.com/timvisee/rust-minecraft-protocol?rev=356ea54#356ea5424374c5a7249be2f0f13fd3e0e2db5b58"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -32,6 +32,7 @@ lobby = ["named-binary-tag", "quartz_nbt", "uuid"]
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0"
|
anyhow = "1.0"
|
||||||
|
base64 = "0.13"
|
||||||
bytes = "1.1"
|
bytes = "1.1"
|
||||||
chrono = "0.4"
|
chrono = "0.4"
|
||||||
clap = { version = "3.0.0-beta.5", default-features = false, features = [ "std", "cargo", "color", "env", "suggestions", "unicode" ]}
|
clap = { version = "3.0.0-beta.5", default-features = false, features = [ "std", "cargo", "color", "env", "suggestions", "unicode" ]}
|
||||||
@ -41,7 +42,7 @@ dotenv = "0.15"
|
|||||||
flate2 = { version = "1.0", default-features = false, features = ["default"] }
|
flate2 = { version = "1.0", default-features = false, features = ["default"] }
|
||||||
futures = { version = "0.3", default-features = false, features = ["executor"] }
|
futures = { version = "0.3", default-features = false, features = ["executor"] }
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
minecraft-protocol = { git = "https://github.com/timvisee/rust-minecraft-protocol", rev = "a14b40e" }
|
minecraft-protocol = { git = "https://github.com/timvisee/rust-minecraft-protocol", rev = "356ea54" }
|
||||||
notify = "4.0"
|
notify = "4.0"
|
||||||
pretty_env_logger = "0.4"
|
pretty_env_logger = "0.4"
|
||||||
rand = "0.8"
|
rand = "0.8"
|
||||||
@ -49,7 +50,7 @@ serde = "1.0"
|
|||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
shlex = "1.1"
|
shlex = "1.1"
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
tokio = { version = "1", default-features = false, features = ["rt-multi-thread", "io-util", "net", "macros", "time", "process", "signal", "sync"] }
|
tokio = { version = "1", default-features = false, features = ["rt-multi-thread", "io-util", "net", "macros", "time", "process", "signal", "sync", "fs"] }
|
||||||
toml = "0.5"
|
toml = "0.5"
|
||||||
version-compare = "0.1"
|
version-compare = "0.1"
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ https://user-images.githubusercontent.com/856222/141378688-882082be-9efa-4cfe-81
|
|||||||
- _Lobby: keep client in emulated server with lobby world, teleport to real server when ready ([experimental*](./docs/join-method-lobby.md))_
|
- _Lobby: keep client in emulated server with lobby world, teleport to real server when ready ([experimental*](./docs/join-method-lobby.md))_
|
||||||
- Customizable MOTD and login messages
|
- Customizable MOTD and login messages
|
||||||
- Automatically manages `server.properties` (host, port and RCON settings)
|
- Automatically manages `server.properties` (host, port and RCON settings)
|
||||||
- Automatically handle banned IPs from server within `lazymc`
|
- Automatically block banned IPs from server within `lazymc`
|
||||||
- Graceful server sleep/shutdown through RCON (with `SIGTERM` fallback on Linux/Unix)
|
- Graceful server sleep/shutdown through RCON (with `SIGTERM` fallback on Linux/Unix)
|
||||||
- Restart server on crash
|
- Restart server on crash
|
||||||
- Lockout mode
|
- Lockout mode
|
||||||
|
@ -8,6 +8,7 @@ use minecraft_protocol::encoder::Encoder;
|
|||||||
use minecraft_protocol::version::v1_14_4::handshake::Handshake;
|
use minecraft_protocol::version::v1_14_4::handshake::Handshake;
|
||||||
use minecraft_protocol::version::v1_14_4::login::LoginStart;
|
use minecraft_protocol::version::v1_14_4::login::LoginStart;
|
||||||
use minecraft_protocol::version::v1_14_4::status::StatusResponse;
|
use minecraft_protocol::version::v1_14_4::status::StatusResponse;
|
||||||
|
use tokio::fs;
|
||||||
use tokio::io::AsyncWriteExt;
|
use tokio::io::AsyncWriteExt;
|
||||||
use tokio::net::TcpStream;
|
use tokio::net::TcpStream;
|
||||||
|
|
||||||
@ -25,6 +26,9 @@ const BAN_MESSAGE_PREFIX: &str = "Your IP address is banned from this server.\nR
|
|||||||
/// Default ban reason if unknown.
|
/// Default ban reason if unknown.
|
||||||
const DEFAULT_BAN_REASON: &str = "Banned by an operator.";
|
const DEFAULT_BAN_REASON: &str = "Banned by an operator.";
|
||||||
|
|
||||||
|
/// Server icon file path.
|
||||||
|
const SERVER_ICON_FILE: &str = "server-icon.png";
|
||||||
|
|
||||||
/// Proxy the given inbound stream to a target address.
|
/// Proxy the given inbound stream to a target address.
|
||||||
// TODO: do not drop error here, return Box<dyn Error>
|
// TODO: do not drop error here, return Box<dyn Error>
|
||||||
pub async fn serve(
|
pub async fn serve(
|
||||||
@ -226,6 +230,13 @@ async fn server_status(config: &Config, server: &Server) -> ServerStatus {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Get server favicon
|
||||||
|
let favicon = if config.motd.from_server && status.is_some() {
|
||||||
|
status.as_ref().unwrap().favicon.clone()
|
||||||
|
} else {
|
||||||
|
favicon(&config).await
|
||||||
|
};
|
||||||
|
|
||||||
// Build status resposne
|
// Build status resposne
|
||||||
ServerStatus {
|
ServerStatus {
|
||||||
version,
|
version,
|
||||||
@ -235,5 +246,36 @@ async fn server_status(config: &Config, server: &Server) -> ServerStatus {
|
|||||||
max,
|
max,
|
||||||
sample: vec![],
|
sample: vec![],
|
||||||
},
|
},
|
||||||
|
favicon,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get server status favicon.
|
||||||
|
async fn favicon(config: &Config) -> Option<String> {
|
||||||
|
// Get server dir
|
||||||
|
let dir = match config.server.directory.as_ref() {
|
||||||
|
Some(dir) => dir,
|
||||||
|
None => return None,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Server icon file, ensure it exists
|
||||||
|
let path = dir.join(SERVER_ICON_FILE);
|
||||||
|
if !path.is_file() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read icon data
|
||||||
|
let data = fs::read(path)
|
||||||
|
.await
|
||||||
|
.map_err(|err| {
|
||||||
|
error!(target: "lazymc", "Failed to read favicon from {}: {}", SERVER_ICON_FILE, err);
|
||||||
|
})
|
||||||
|
.ok()?;
|
||||||
|
|
||||||
|
// Format and return favicon
|
||||||
|
Some(format!(
|
||||||
|
"{}{}",
|
||||||
|
"data:image/png;base64,",
|
||||||
|
base64::encode(data)
|
||||||
|
))
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user