rust-gamedig/src/socket.rs
CosminPerRam ee0223a7a3
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
2022-11-24 22:52:54 +02:00

88 lines
3.1 KiB
Rust

use std::io::{Read, Write};
use std::net;
use crate::{GDError, GDResult};
use crate::protocols::types::TimeoutSettings;
use crate::utils::complete_address;
static DEFAULT_PACKET_SIZE: usize = 1024;
pub trait Socket {
fn new(address: &str, port: u16) -> GDResult<Self> where Self: Sized;
fn apply_timeout(&self, timeout_settings: Option<TimeoutSettings>) -> GDResult<()>;
fn send(&mut self, data: &[u8]) -> GDResult<()>;
fn receive(&mut self, size: Option<usize>) -> GDResult<Vec<u8>>;
}
pub struct TcpSocket {
socket: net::TcpStream
}
impl Socket for TcpSocket {
fn new(address: &str, port: u16) -> GDResult<Self> {
let complete_address = complete_address(address, port)?;
let socket = net::TcpStream::connect(complete_address).map_err(|e| GDError::SocketConnect(e.to_string()))?;
Ok(Self {
socket
})
}
fn apply_timeout(&self, timeout_settings: Option<TimeoutSettings>) -> GDResult<()> {
let settings = timeout_settings.unwrap_or(TimeoutSettings::default());
self.socket.set_read_timeout(settings.get_read()).unwrap(); //unwrapping because TimeoutSettings::new
self.socket.set_write_timeout(settings.get_write()).unwrap(); //checks if these are 0 and throws an error
Ok(())
}
fn send(&mut self, data: &[u8]) -> GDResult<()> {
self.socket.write(&data).map_err(|e| GDError::PacketSend(e.to_string()))?;
Ok(())
}
fn receive(&mut self, size: Option<usize>) -> GDResult<Vec<u8>> {
let mut buf = Vec::with_capacity(size.unwrap_or(DEFAULT_PACKET_SIZE));
self.socket.read_to_end(&mut buf).map_err(|e| GDError::PacketReceive(e.to_string()))?;
Ok(buf)
}
}
pub struct UdpSocket {
socket: net::UdpSocket,
complete_address: String
}
impl Socket for UdpSocket {
fn new(address: &str, port: u16) -> GDResult<Self> {
let complete_address = complete_address(address, port)?;
let socket = net::UdpSocket::bind("0.0.0.0:0").map_err(|e| GDError::SocketBind(e.to_string()))?;
Ok(Self {
socket,
complete_address
})
}
fn apply_timeout(&self, timeout_settings: Option<TimeoutSettings>) -> GDResult<()> {
let settings = timeout_settings.unwrap_or(TimeoutSettings::default());
self.socket.set_read_timeout(settings.get_read()).unwrap(); //unwrapping because TimeoutSettings::new
self.socket.set_write_timeout(settings.get_write()).unwrap(); //checks if these are 0 and throws an error
Ok(())
}
fn send(&mut self, data: &[u8]) -> GDResult<()> {
self.socket.send_to(&data, &self.complete_address).map_err(|e| GDError::PacketSend(e.to_string()))?;
Ok(())
}
fn receive(&mut self, size: Option<usize>) -> GDResult<Vec<u8>> {
let mut buf: Vec<u8> = vec![0; size.unwrap_or(DEFAULT_PACKET_SIZE)];
let (number_of_bytes_received, _) = self.socket.recv_from(&mut buf).map_err(|e| GDError::PacketReceive(e.to_string()))?;
Ok(buf[..number_of_bytes_received].to_vec())
}
}