Minecraft implementation (#6)

* Initial minecraft support

* Made previews_chat an option

* Better error handling and removed version structure

* Minecraft Server types

* Fixed compilation and renamed stuff

* 'extract till you drop!' extracted sockets

* extracted java version and fixed socket udp receive

* Legacy 1.4 and 1.6 implementation (incomplete)

* Furter implementation

* Implementations work

* Protocol beta v1.8+ implemented

* Removed bedrock support

* Added auto query

* Renamed minecraft to mc and added to md's

* Docs, renames and small optimization changes

* Changed java version to be able to return None on players sample
This commit is contained in:
CosminPerRam 2022-11-24 22:52:54 +02:00 committed by GitHub
parent 974e093e23
commit ee0223a7a3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 810 additions and 80 deletions

View file

@ -43,6 +43,16 @@ pub mod buffer {
Ok(value)
}
pub fn get_u16_be(buf: &[u8], pos: &mut usize) -> GDResult<u16> {
if buf.len() <= *pos + 1 {
return Err(GDError::PacketUnderflow("Unexpectedly short packet.".to_string()));
}
let value = u16::from_be_bytes([buf[*pos], buf[*pos + 1]]);
*pos += 2;
Ok(value)
}
pub fn get_u32_le(buf: &[u8], pos: &mut usize) -> GDResult<u32> {
if buf.len() <= *pos + 3 {
return Err(GDError::PacketUnderflow("Unexpectedly short packet.".to_string()));
@ -73,10 +83,25 @@ pub mod buffer {
Ok(value)
}
pub fn get_string(buf: &[u8], pos: &mut usize) -> GDResult<String> {
pub fn get_string_utf8_le(buf: &[u8], pos: &mut usize) -> GDResult<String> {
let sub_buf = &buf[*pos..];
let first_null_position = sub_buf.iter().position(|&x| x == 0).ok_or(GDError::PacketBad("Unexpectedly formatted packet.".to_string()))?;
let value = std::str::from_utf8(&sub_buf[..first_null_position]).unwrap().to_string();
let first_null_position = sub_buf.iter().position(|&x| x == 0)
.ok_or(GDError::PacketBad("Unexpectedly formatted packet.".to_string()))?;
let value = std::str::from_utf8(&sub_buf[..first_null_position])
.map_err(|_| GDError::PacketBad("Badly formatted string.".to_string()))?.to_string();
*pos += value.len() + 1;
Ok(value)
}
pub fn get_string_utf16_be(buf: &[u8], pos: &mut usize) -> GDResult<String> {
let sub_buf = &buf[*pos..];
let paired_buf: Vec<u16> = sub_buf.chunks_exact(2)
.into_iter().map(|a| u16::from_be_bytes([a[0], a[1]])).collect();
let value = String::from_utf16(&paired_buf)
.map_err(|_| GDError::PacketBad("Badly formatted string.".to_string()))?.to_string();
*pos += value.len() + 1;
Ok(value)
}
@ -143,12 +168,12 @@ mod tests {
}
#[test]
fn get_string_test() {
fn get_string_utf8_le_test() {
let data = [72, 101, 108, 108, 111, 0, 72];
let mut pos = 0;
assert_eq!(buffer::get_string(&data, &mut pos).unwrap(), "Hello");
assert_eq!(buffer::get_string_utf8_le(&data, &mut pos).unwrap(), "Hello");
assert_eq!(pos, 6);
assert!(buffer::get_string(&data, &mut pos).is_err());
assert!(buffer::get_string_utf8_le(&data, &mut pos).is_err());
assert_eq!(pos, 6);
}
}