mirror of
https://github.com/italicsjenga/valence.git
synced 2025-01-10 06:41:30 +11:00
parent
4df6cedf0a
commit
e3c0aec967
|
@ -138,7 +138,8 @@ impl PacketDecoder {
|
||||||
self.cipher = Some(cipher);
|
self.cipher = Some(cipher);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Decrypts the provided byte slice in place using the cipher, without consuming the cipher.
|
/// Decrypts the provided byte slice in place using the cipher, without
|
||||||
|
/// consuming the cipher.
|
||||||
#[cfg(feature = "encryption")]
|
#[cfg(feature = "encryption")]
|
||||||
fn decrypt_bytes(cipher: &mut Cipher, bytes: &mut [u8]) {
|
fn decrypt_bytes(cipher: &mut Cipher, bytes: &mut [u8]) {
|
||||||
for chunk in bytes.chunks_mut(Cipher::block_size()) {
|
for chunk in bytes.chunks_mut(Cipher::block_size()) {
|
||||||
|
|
|
@ -4,7 +4,7 @@ use std::io;
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use anyhow::{anyhow, bail, ensure, Context};
|
use anyhow::{bail, ensure, Context};
|
||||||
use base64::prelude::*;
|
use base64::prelude::*;
|
||||||
use hmac::digest::Update;
|
use hmac::digest::Update;
|
||||||
use hmac::{Hmac, Mac};
|
use hmac::{Hmac, Mac};
|
||||||
|
@ -230,7 +230,9 @@ async fn handle_login(
|
||||||
let info = match shared.connection_mode() {
|
let info = match shared.connection_mode() {
|
||||||
ConnectionMode::Online { .. } => login_online(shared, conn, remote_addr, username).await?,
|
ConnectionMode::Online { .. } => login_online(shared, conn, remote_addr, username).await?,
|
||||||
ConnectionMode::Offline => login_offline(remote_addr, username)?,
|
ConnectionMode::Offline => login_offline(remote_addr, username)?,
|
||||||
ConnectionMode::BungeeCord => login_bungeecord(&handshake.server_address, username)?,
|
ConnectionMode::BungeeCord => {
|
||||||
|
login_bungeecord(remote_addr, &handshake.server_address, username)?
|
||||||
|
}
|
||||||
ConnectionMode::Velocity { secret } => login_velocity(conn, username, secret).await?,
|
ConnectionMode::Velocity { secret } => login_velocity(conn, username, secret).await?,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -375,11 +377,15 @@ fn auth_digest(bytes: &[u8]) -> String {
|
||||||
BigInt::from_signed_bytes_be(bytes).to_str_radix(16)
|
BigInt::from_signed_bytes_be(bytes).to_str_radix(16)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn offline_uuid(username: &str) -> anyhow::Result<Uuid> {
|
||||||
|
Uuid::from_slice(&Sha256::digest(username)[..16]).map_err(Into::into)
|
||||||
|
}
|
||||||
|
|
||||||
/// Login procedure for offline mode.
|
/// Login procedure for offline mode.
|
||||||
fn login_offline(remote_addr: SocketAddr, username: String) -> anyhow::Result<NewClientInfo> {
|
fn login_offline(remote_addr: SocketAddr, username: String) -> anyhow::Result<NewClientInfo> {
|
||||||
Ok(NewClientInfo {
|
Ok(NewClientInfo {
|
||||||
// Derive the client's UUID from a hash of their username.
|
// Derive the client's UUID from a hash of their username.
|
||||||
uuid: Uuid::from_slice(&Sha256::digest(username.as_str())[..16])?,
|
uuid: offline_uuid(username.as_str())?,
|
||||||
username,
|
username,
|
||||||
properties: vec![].into(),
|
properties: vec![].into(),
|
||||||
ip: remote_addr.ip(),
|
ip: remote_addr.ip(),
|
||||||
|
@ -387,24 +393,39 @@ fn login_offline(remote_addr: SocketAddr, username: String) -> anyhow::Result<Ne
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Login procedure for BungeeCord.
|
/// Login procedure for BungeeCord.
|
||||||
fn login_bungeecord(server_address: &str, username: String) -> anyhow::Result<NewClientInfo> {
|
fn login_bungeecord(
|
||||||
|
remote_addr: SocketAddr,
|
||||||
|
server_address: &str,
|
||||||
|
username: String,
|
||||||
|
) -> anyhow::Result<NewClientInfo> {
|
||||||
// Get data from server_address field of the handshake
|
// Get data from server_address field of the handshake
|
||||||
let [_, client_ip, uuid, properties]: [&str; 4] = server_address
|
let data = server_address.split('\0').take(4).collect::<Vec<_>>();
|
||||||
.split('\0')
|
|
||||||
.take(4)
|
// Ip of player, only given if ip_forward on bungee is true
|
||||||
.collect::<Vec<_>>()
|
let ip = match data.get(1) {
|
||||||
.try_into()
|
Some(ip) => ip.parse()?,
|
||||||
.map_err(|_| anyhow!("malformed BungeeCord server address data"))?;
|
None => remote_addr.ip(),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Uuid of player, only given if ip_forward on bungee is true
|
||||||
|
let uuid = match data.get(2) {
|
||||||
|
Some(uuid) => uuid.parse()?,
|
||||||
|
None => offline_uuid(username.as_str())?,
|
||||||
|
};
|
||||||
|
|
||||||
// Read properties and get textures
|
// Read properties and get textures
|
||||||
let properties: Vec<Property> =
|
// Properties of player's game profile, only given if ip_forward and online_mode on bungee both are true
|
||||||
serde_json::from_str(properties).context("failed to parse BungeeCord player properties")?;
|
let properties: Vec<Property> = match data.get(3) {
|
||||||
|
Some(properties) => serde_json::from_str(properties)
|
||||||
|
.context("failed to parse BungeeCord player properties")?,
|
||||||
|
None => vec![],
|
||||||
|
};
|
||||||
|
|
||||||
Ok(NewClientInfo {
|
Ok(NewClientInfo {
|
||||||
uuid: uuid.parse()?,
|
uuid,
|
||||||
username,
|
username,
|
||||||
properties: properties.into(),
|
properties: properties.into(),
|
||||||
ip: client_ip.parse()?,
|
ip,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue