Add methods to Config to use a custom session server (#72)

* Add methods to Config to use a custom session server

Added new methods to the Config trait, that enables
implementors to use a custom session server host
or even a fully custom URL.

* Fix error in documentation

* Make format_session_server_url return a String
This commit is contained in:
Tim Satke 2022-09-20 05:23:39 +02:00 committed by GitHub
parent d25f3674fb
commit d9b7008827
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 34 additions and 8 deletions

View file

@ -1,7 +1,7 @@
//! Configuration for the server.
use std::borrow::Cow;
use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4};
use std::net::{IpAddr, Ipv4Addr, SocketAddr, SocketAddrV4};
use std::panic::{RefUnwindSafe, UnwindSafe};
use async_trait::async_trait;
@ -208,6 +208,26 @@ pub trait Config: Sized + Send + Sync + UnwindSafe + RefUnwindSafe + 'static {
Ok(())
}
/// Called upon (every) client connect (if online mode is enabled) to obtain
/// the full URL to use for session server requests. Defaults to
/// `https://sessionserver.mojang.com/session/minecraft/hasJoined?username=<username>&serverId=<auth-digest>&ip=<player-ip>`.
///
/// It is assumed, that upon successful request, a structure matching the
/// description in the [wiki](https://wiki.vg/Protocol_Encryption#Server) was obtained.
/// Providing a URL that does not return such a structure will result in a
/// disconnect for every client that connects.
///
/// The arguments are described in the linked wiki article.
fn format_session_server_url(
&self,
server: &SharedServer<Self>,
username: &str,
auth_digest: &str,
player_ip: &IpAddr,
) -> String {
format!("https://sessionserver.mojang.com/session/minecraft/hasJoined?username={username}&serverId={auth_digest}&ip={player_ip}")
}
/// Called after the server is created, but prior to accepting connections
/// and entering the update loop.
///

View file

@ -704,9 +704,15 @@ async fn handle_login<C: Config>(
.chain(&server.0.public_key_der)
.finalize();
let hex_hash = weird_hex_encoding(&hash);
let hex_hash = auth_digest(&hash);
let url = format!("https://sessionserver.mojang.com/session/minecraft/hasJoined?username={username}&serverId={hex_hash}&ip={}", remote_addr.ip());
let url = C::format_session_server_url(
server.config(),
server,
&username,
&hex_hash,
&remote_addr.ip(),
);
let resp = server.0.http_client.get(url).send().await?;
let status = resp.status();
@ -823,7 +829,7 @@ async fn handle_play<C: Config>(
Ok(())
}
fn weird_hex_encoding(bytes: &[u8]) -> String {
fn auth_digest(bytes: &[u8]) -> String {
BigInt::from_signed_bytes_be(bytes).to_str_radix(16)
}
@ -832,17 +838,17 @@ mod tests {
use super::*;
#[test]
fn weird_hex_encoding_correct() {
fn auth_digest_correct() {
assert_eq!(
weird_hex_encoding(&Sha1::digest("Notch")),
auth_digest(&Sha1::digest("Notch")),
"4ed1f46bbe04bc756bcb17c0c7ce3e4632f06a48"
);
assert_eq!(
weird_hex_encoding(&Sha1::digest("jeb_")),
auth_digest(&Sha1::digest("jeb_")),
"-7c9d5b0044c130109a5d7b5fb5c317c02b4e28c1"
);
assert_eq!(
weird_hex_encoding(&Sha1::digest("simon")),
auth_digest(&Sha1::digest("simon")),
"88e16a1019277b15d58faf0541e11910eb756f6"
);
}