Derive correct UUID for offline players in lobby logic

This commit is contained in:
timvisee
2021-11-22 20:14:29 +01:00
parent 46fa594065
commit 3e933f7566
5 changed files with 82 additions and 6 deletions

View File

@@ -20,10 +20,9 @@ use tokio::net::tcp::{ReadHalf, WriteHalf};
use tokio::net::TcpStream;
use tokio::select;
use tokio::time;
use uuid::Uuid;
use crate::config::*;
use crate::mc;
use crate::mc::{self, uuid};
use crate::net;
use crate::proto;
use crate::proto::client::{Client, ClientInfo, ClientState};
@@ -198,10 +197,7 @@ async fn respond_login_success(
) -> Result<(), ()> {
packet::write_packet(
LoginSuccess {
uuid: Uuid::new_v3(
&Uuid::new_v3(&Uuid::nil(), b"OfflinePlayer"),
login_start.name.as_bytes(),
),
uuid: uuid::offline_player_uuid(&login_start.name),
username: login_start.name.clone(),
},
client,

View File

@@ -2,6 +2,7 @@ pub mod ban;
#[cfg(feature = "rcon")]
pub mod rcon;
pub mod server_properties;
pub mod uuid;
/// Minecraft ticks per second.
#[allow(unused)]

26
src/mc/uuid.rs Normal file
View File

@@ -0,0 +1,26 @@
use md5::{Digest, Md5};
use uuid::Uuid;
/// Offline player namespace.
const OFFLINE_PLAYER_NAMESPACE: &str = "OfflinePlayer:";
/// Get UUID for given player username.
pub fn player_uuid(username: &str) -> Uuid {
Uuid::from_bytes(jdk_name_uuid_from_bytes(username.as_bytes()))
}
/// Get UUID for given offline player username.
pub fn offline_player_uuid(username: &str) -> Uuid {
player_uuid(&format!("{}{}", OFFLINE_PLAYER_NAMESPACE, username))
}
/// Java's `UUID.nameUUIDFromBytes`.
///
/// Static factory to retrieve a type 3 (name based) `Uuid` based on the specified byte array.
///
/// Ported from: https://github.com/AdoptOpenJDK/openjdk-jdk8u/blob/9a91972c76ddda5c1ce28b50ca38cbd8a30b7a72/jdk/src/share/classes/java/util/UUID.java#L153-L175
fn jdk_name_uuid_from_bytes(data: &[u8]) -> [u8; 16] {
let mut hasher = Md5::new();
hasher.update(data);
hasher.finalize().into()
}