mirror of
https://github.com/tribufu/rust-gamedig
synced 2026-05-06 15:27:28 +00:00
Better, faster and stronger errors.
This commit is contained in:
parent
b988b51cff
commit
304b8340d2
7 changed files with 75 additions and 69 deletions
|
|
@ -73,33 +73,33 @@ impl Java {
|
|||
let mut pos = 0;
|
||||
|
||||
if get_varint(&buf, &mut pos)? != 0 { //first var int is the packet id
|
||||
return Err(GDError::PacketBad("Bad receive packet id.".to_string()));
|
||||
return Err(GDError::PacketBad("Bad receive packet id."));
|
||||
}
|
||||
|
||||
let json_response = get_string(&buf, &mut pos)?;
|
||||
let value_response: Value = serde_json::from_str(&json_response)
|
||||
.map_err(|e| GDError::JsonParse(e.to_string()))?;
|
||||
.map_err(|e| GDError::JsonParse(e.to_string().as_str()))?;
|
||||
|
||||
let version_name = value_response["version"]["name"].as_str()
|
||||
.ok_or(GDError::PacketBad("Couldn't get expected string.".to_string()))?.to_string();
|
||||
.ok_or(GDError::PacketBad("Couldn't get expected string."))?.to_string();
|
||||
let version_protocol = value_response["version"]["protocol"].as_i64()
|
||||
.ok_or(GDError::PacketBad("Couldn't get expected number.".to_string()))? as i32;
|
||||
.ok_or(GDError::PacketBad("Couldn't get expected number."))? as i32;
|
||||
|
||||
let max_players = value_response["players"]["max"].as_u64()
|
||||
.ok_or(GDError::PacketBad("Couldn't get expected number.".to_string()))? as u32;
|
||||
.ok_or(GDError::PacketBad("Couldn't get expected number."))? as u32;
|
||||
let online_players = value_response["players"]["online"].as_u64()
|
||||
.ok_or(GDError::PacketBad("Couldn't get expected number.".to_string()))? as u32;
|
||||
.ok_or(GDError::PacketBad("Couldn't get expected number."))? as u32;
|
||||
let sample_players: Option<Vec<Player>> = match value_response["players"]["sample"].is_null() {
|
||||
true => None,
|
||||
false => Some({
|
||||
let players_values = value_response["players"]["sample"].as_array()
|
||||
.ok_or(GDError::PacketBad("Couldn't get expected array.".to_string()))?;
|
||||
.ok_or(GDError::PacketBad("Couldn't get expected array."))?;
|
||||
|
||||
let mut players = Vec::with_capacity(players_values.len());
|
||||
for player in players_values {
|
||||
players.push(Player {
|
||||
name: player["name"].as_str().ok_or(GDError::PacketBad("Couldn't get expected string.".to_string()))?.to_string(),
|
||||
id: player["id"].as_str().ok_or(GDError::PacketBad("Couldn't get expected string.".to_string()))?.to_string()
|
||||
name: player["name"].as_str().ok_or(GDError::PacketBad("Couldn't get expected string."))?.to_string(),
|
||||
id: player["id"].as_str().ok_or(GDError::PacketBad("Couldn't get expected string."))?.to_string()
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ use crate::protocols::minecraft::{LegacyGroup, Response, Server};
|
|||
use crate::protocols::types::TimeoutSettings;
|
||||
use crate::socket::{Socket, TcpSocket};
|
||||
use crate::utils::buffer::{get_string_utf16_be, get_u16_be, get_u8};
|
||||
use crate::utils::error_by_expected_size;
|
||||
|
||||
pub struct LegacyBV1_8 {
|
||||
socket: TcpSocket
|
||||
|
|
@ -30,26 +31,22 @@ impl LegacyBV1_8 {
|
|||
let mut pos = 0;
|
||||
|
||||
if get_u8(&buf, &mut pos)? != 0xFF {
|
||||
return Err(GDError::PacketBad("Expected 0xFF".to_string()));
|
||||
return Err(GDError::ProtocolRule("Expected 0xFF at the begin of the packet."));
|
||||
}
|
||||
|
||||
let length = get_u16_be(&buf, &mut pos)? * 2;
|
||||
if buf.len() != (length + 3) as usize { //+ 3 because of the first byte and the u16
|
||||
return Err(GDError::PacketBad("Not right size".to_string()));
|
||||
}
|
||||
error_by_expected_size((length + 3) as usize, buf.len())?;
|
||||
|
||||
let packet_string = get_string_utf16_be(&buf, &mut pos)?;
|
||||
|
||||
let split: Vec<&str> = packet_string.split("§").collect();
|
||||
if split.len() != 3 {
|
||||
return Err(GDError::PacketBad("Not right size".to_string()));
|
||||
}
|
||||
error_by_expected_size(3, split.len())?;
|
||||
|
||||
let description = split[0].to_string();
|
||||
let online_players = split[1].parse()
|
||||
.map_err(|_| GDError::PacketBad("Expected int".to_string()))?;
|
||||
.map_err(|_| GDError::PacketBad("Failed to parse to expected int."))?;
|
||||
let max_players = split[2].parse()
|
||||
.map_err(|_| GDError::PacketBad("Expected int".to_string()))?;
|
||||
.map_err(|_| GDError::PacketBad("Failed to parse to expected int."))?;
|
||||
|
||||
Ok(Response {
|
||||
version_name: "Beta 1.8+".to_string(),
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ use crate::protocols::minecraft::protocol::legacy_v1_6::LegacyV1_6;
|
|||
use crate::protocols::types::TimeoutSettings;
|
||||
use crate::socket::{Socket, TcpSocket};
|
||||
use crate::utils::buffer::{get_string_utf16_be, get_u16_be, get_u8};
|
||||
use crate::utils::error_by_expected_size;
|
||||
|
||||
pub struct LegacyV1_4 {
|
||||
socket: TcpSocket
|
||||
|
|
@ -31,13 +32,11 @@ impl LegacyV1_4 {
|
|||
let mut pos = 0;
|
||||
|
||||
if get_u8(&buf, &mut pos)? != 0xFF {
|
||||
return Err(GDError::PacketBad("Expected 0xFF".to_string()));
|
||||
return Err(GDError::ProtocolRule("Expected 0xFF at the begin of the packet."));
|
||||
}
|
||||
|
||||
let length = get_u16_be(&buf, &mut pos)? * 2;
|
||||
if buf.len() != (length + 3) as usize { //+ 3 because of the first byte and the u16
|
||||
return Err(GDError::PacketBad("Not right size".to_string()));
|
||||
}
|
||||
error_by_expected_size((length + 3) as usize, buf.len())?;
|
||||
|
||||
if LegacyV1_6::is_protocol(&buf, &mut pos)? {
|
||||
return LegacyV1_6::get_response(&buf, &mut pos);
|
||||
|
|
@ -46,15 +45,13 @@ impl LegacyV1_4 {
|
|||
let packet_string = get_string_utf16_be(&buf, &mut pos)?;
|
||||
|
||||
let split: Vec<&str> = packet_string.split("§").collect();
|
||||
if split.len() != 3 {
|
||||
return Err(GDError::PacketBad("Not right size".to_string()));
|
||||
}
|
||||
error_by_expected_size(3, split.len())?;
|
||||
|
||||
let description = split[0].to_string();
|
||||
let online_players = split[1].parse()
|
||||
.map_err(|_| GDError::PacketBad("Expected int".to_string()))?;
|
||||
.map_err(|_| GDError::PacketBad("Failed to parse to expected int."))?;
|
||||
let max_players = split[2].parse()
|
||||
.map_err(|_| GDError::PacketBad("Expected int".to_string()))?;
|
||||
.map_err(|_| GDError::PacketBad("Failed to parse to expected int."))?;
|
||||
|
||||
Ok(Response {
|
||||
version_name: "1.4+".to_string(),
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ use crate::protocols::minecraft::{LegacyGroup, Response, Server};
|
|||
use crate::protocols::types::TimeoutSettings;
|
||||
use crate::socket::{Socket, TcpSocket};
|
||||
use crate::utils::buffer::{get_string_utf16_be, get_u16_be, get_u8};
|
||||
use crate::utils::error_by_expected_size;
|
||||
|
||||
pub struct LegacyV1_6 {
|
||||
socket: TcpSocket
|
||||
|
|
@ -48,18 +49,16 @@ impl LegacyV1_6 {
|
|||
let packet_string = get_string_utf16_be(&buf, pos)?;
|
||||
|
||||
let split: Vec<&str> = packet_string.split("\x00").collect();
|
||||
if split.len() != 5 {
|
||||
return Err(GDError::PacketBad("Not right split size".to_string()));
|
||||
}
|
||||
error_by_expected_size(5, split.len())?;
|
||||
|
||||
let version_protocol = split[0].parse()
|
||||
.map_err(|_| GDError::PacketBad("Expected int".to_string()))?;
|
||||
.map_err(|_| GDError::PacketBad("Failed to parse to expected int."))?;
|
||||
let version_name = split[1].to_string();
|
||||
let description = split[2].to_string();
|
||||
let max_players = split[3].parse()
|
||||
.map_err(|_| GDError::PacketBad("Expected int".to_string()))?;
|
||||
.map_err(|_| GDError::PacketBad("Failed to parse to expected int."))?;
|
||||
let online_players = split[4].parse()
|
||||
.map_err(|_| GDError::PacketBad("Expected int".to_string()))?;
|
||||
.map_err(|_| GDError::PacketBad("Failed to parse to expected int."))?;
|
||||
|
||||
Ok(Response {
|
||||
version_name,
|
||||
|
|
@ -82,16 +81,14 @@ impl LegacyV1_6 {
|
|||
let mut pos = 0;
|
||||
|
||||
if get_u8(&buf, &mut pos)? != 0xFF {
|
||||
return Err(GDError::PacketBad("Expected 0xFF".to_string()));
|
||||
return Err(GDError::ProtocolRule("Expected a certain byte (0xFF) at the begin of the packet."));
|
||||
}
|
||||
|
||||
let length = get_u16_be(&buf, &mut pos)? * 2;
|
||||
if buf.len() != (length + 3) as usize { //+ 3 because of the first byte and the u16
|
||||
return Err(GDError::PacketBad("Not right size".to_string()));
|
||||
}
|
||||
error_by_expected_size((length + 3) as usize, buf.len())?;
|
||||
|
||||
if !LegacyV1_6::is_protocol(&buf, &mut pos)? {
|
||||
return Err(GDError::PacketBad("Not good".to_string()));
|
||||
return Err(GDError::ProtocolRule("Expected certain bytes at the beginning of the packet."));
|
||||
}
|
||||
|
||||
LegacyV1_6::get_response(&buf, &mut pos)
|
||||
|
|
|
|||
|
|
@ -117,18 +117,18 @@ impl SplitPacket {
|
|||
fn get_payload(&self) -> GDResult<Vec<u8>> {
|
||||
if self.compressed {
|
||||
let mut decoder = Decoder::new();
|
||||
decoder.write(&self.payload).map_err(|e| GDError::Decompress(e.to_string()))?;
|
||||
decoder.write(&self.payload).map_err(|e| GDError::Decompress(e.to_string().as_str()))?;
|
||||
|
||||
let decompressed_size = self.decompressed_size.unwrap() as usize;
|
||||
|
||||
let mut decompressed_payload = Vec::with_capacity(decompressed_size);
|
||||
decoder.read(&mut decompressed_payload).map_err(|e| GDError::Decompress(e.to_string()))?;
|
||||
decoder.read(&mut decompressed_payload).map_err(|e| GDError::Decompress(e.to_string().as_str()))?;
|
||||
|
||||
if decompressed_payload.len() != decompressed_size {
|
||||
Err(GDError::Decompress("Valve Protocol: The decompressed payload size doesn't match the expected one.".to_string()))
|
||||
Err(GDError::Decompress("The decompressed payload size doesn't match the expected one."))
|
||||
}
|
||||
else if crc32fast::hash(&decompressed_payload) != self.uncompressed_crc32.unwrap() {
|
||||
Err(GDError::Decompress("Valve Protocol: The decompressed crc32 hash does not match the expected one.".to_string()))
|
||||
Err(GDError::Decompress("The decompressed crc32 hash does not match the expected one."))
|
||||
}
|
||||
else {
|
||||
Ok(decompressed_payload)
|
||||
|
|
@ -420,7 +420,7 @@ fn get_response(address: &str, port: u16, app: App, gather_settings: GatheringSe
|
|||
if let App::Source(x) = &app {
|
||||
if let Some(appid) = x {
|
||||
if *appid != info.appid {
|
||||
return Err(GDError::BadGame(format!("Expected {}, found {} instead!", *appid, info.appid)));
|
||||
return Err(GDError::BadGame(format!("Expected {}, found {} instead!", *appid, info.appid).as_str()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue