Skip to main content

nurtex_protocol/connection/
utils.rs

1use nurtex_encrypt::{digest_data, encrypt};
2
3use crate::packets::login::{ClientsideEncryptionRequest, ServersideEncryptionResponse};
4
5/// Функция обработки запроса шифрования
6pub fn handle_encryption_request(request: &ClientsideEncryptionRequest) -> Option<(ServersideEncryptionResponse, [u8; 16])> {
7  if let Some(encryption) = encrypt(&request.public_key, &request.verify_token) {
8    let response = ServersideEncryptionResponse {
9      shared_secret: encryption.encrypted_public_key,
10      verify_token: encryption.encrypted_challenge,
11    };
12
13    Some((response, encryption.secret_key))
14  } else {
15    None
16  }
17}
18
19/// Функция получения хэша сервера
20pub fn get_server_hash(server_id: &str, shared_secret: &[u8; 16], public_key: &[u8]) -> String {
21  let hash = digest_data(server_id.as_bytes(), public_key, shared_secret);
22  create_minecraft_hash(&hash)
23}
24
25/// Функция создания Minecraft хэша
26fn create_minecraft_hash(hash: &[u8]) -> String {
27  let is_negative = (hash[0] & 0x80) == 0x80;
28
29  let hash_value = if is_negative {
30    let mut result = Vec::with_capacity(hash.len());
31    let mut carry = true;
32
33    for &byte in hash.iter().rev() {
34      let inverted = !byte;
35
36      if carry {
37        let (sum, overflow) = inverted.overflowing_add(1);
38        result.push(sum);
39        carry = overflow;
40      } else {
41        result.push(inverted);
42      }
43    }
44
45    result.reverse();
46
47    result
48  } else {
49    hash.to_vec()
50  };
51
52  let hex = hash_value.iter().map(|b| format!("{:02x}", b)).collect::<String>();
53
54  let trimmed = hex.trim_start_matches('0');
55
56  if is_negative {
57    format!("-{}", if trimmed.is_empty() { "0" } else { trimmed })
58  } else {
59    if trimmed.is_empty() { "0" } else { trimmed }.to_string()
60  }
61}