74 lines
2.0 KiB
Rust
74 lines
2.0 KiB
Rust
use std::time::Duration;
|
|
|
|
use async_std::net::TcpStream;
|
|
use async_std::prelude::*;
|
|
use rust_rcon::{Connection, Error as RconError};
|
|
use tokio::time;
|
|
|
|
use crate::config::Config;
|
|
use crate::proxy;
|
|
|
|
/// Minecraft RCON quirk.
|
|
///
|
|
/// Wait this time between RCON operations.
|
|
/// The Minecraft RCON implementation is very broken and brittle, this is used in the hopes to
|
|
/// improve reliability.
|
|
const QUIRK_RCON_GRACE_TIME: Duration = Duration::from_millis(200);
|
|
|
|
/// An RCON client.
|
|
pub struct Rcon {
|
|
con: Connection,
|
|
}
|
|
|
|
impl Rcon {
|
|
/// Connect to a host.
|
|
pub async fn connect(
|
|
config: &Config,
|
|
addr: &str,
|
|
pass: &str,
|
|
) -> Result<Self, Box<dyn std::error::Error>> {
|
|
// Connect to our TCP stream
|
|
let mut stream = TcpStream::connect(addr).await?;
|
|
|
|
// Add proxy header
|
|
if config.rcon.send_proxy_v2 {
|
|
trace!(target: "lazymc::rcon", "Sending local proxy header for RCON connection");
|
|
stream.write_all(&proxy::local_proxy_header()?).await?;
|
|
}
|
|
|
|
// Start connection
|
|
let con = Connection::builder()
|
|
.enable_minecraft_quirks(true)
|
|
.connect_stream(stream, pass)
|
|
.await?;
|
|
|
|
Ok(Self { con })
|
|
}
|
|
|
|
/// Connect to a host from the given configuration.
|
|
pub async fn connect_config(config: &Config) -> Result<Self, Box<dyn std::error::Error>> {
|
|
// RCON address
|
|
let mut addr = config.server.address;
|
|
addr.set_port(config.rcon.port);
|
|
let addr = addr.to_string();
|
|
|
|
Self::connect(config, &addr, &config.rcon.password).await
|
|
}
|
|
|
|
/// Send command over RCON.
|
|
pub async fn cmd(&mut self, cmd: &str) -> Result<String, RconError> {
|
|
// Minecraft quirk
|
|
time::sleep(QUIRK_RCON_GRACE_TIME).await;
|
|
|
|
// Actually send RCON command
|
|
debug!(target: "lazymc::rcon", "Sending RCON: {}", cmd);
|
|
self.con.cmd(cmd).await
|
|
}
|
|
|
|
/// Close connection.
|
|
pub async fn close(self) {
|
|
// Minecraft quirk
|
|
time::sleep(QUIRK_RCON_GRACE_TIME).await;
|
|
}
|
|
}
|