Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

asyncify read/write packet #1

Merged
merged 1 commit into from
Aug 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[toolchain]
channel = "nightly-2024-08-19"
11 changes: 7 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
#![feature(async_closure)]

pub mod cli;
pub mod config;
pub mod output;
pub mod protocol;

use tokio::io::{AsyncWriteExt};
use std::net::{ToSocketAddrs};
use std::net::ToSocketAddrs;
use tokio::io::AsyncWriteExt;

use anyhow::{Context, Result};
use tokio::net::TcpStream;
pub use cli::Cli;
pub use config::Config;
use tokio::net::TcpStream;

use protocol::StatusResponse;

const APP_NAME: &str = "mc_status";

pub async fn get_server_status(host: &str, port: u16) -> Result<StatusResponse> {
let addr = &(host, port).to_socket_addrs()?.next().unwrap();
let stream= &mut TcpStream::connect(addr).await
let stream = &mut TcpStream::connect(addr)
.await
.context("failed to connect")?;

let protocol_version = -1;
Expand Down
32 changes: 17 additions & 15 deletions src/protocol.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use std::future::Future;
use std::io::{Cursor};
use std::io::Cursor;

use anyhow::{ensure, Result};
use tokio::io::{AsyncRead, AsyncWrite, AsyncReadExt, AsyncWriteExt};
use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt};

pub mod status_response;
pub mod varint;
Expand All @@ -16,35 +15,36 @@ pub async fn write_handshake<W: AsyncWrite + Unpin>(
port: u16,
next_state: i32,
) -> Result<()> {
write_packet(w, 0x00, move |w|async move{
write_packet(w, 0x00, async |w| {
varint::write(w, protocol_version).await?;
write_string(w, host).await?;
write_unsigned_short(w, port).await?;
varint::write(w, next_state).await?;
Ok(())
}).await
})
.await
}

pub async fn write_status_request<W: AsyncWrite + Unpin>(w: &mut W) -> Result<()> {
write_packet(w, 0x00, |_|async {Ok(())}).await
write_packet(w, 0x00, async |_| Ok(())).await
}

pub async fn read_status_response<R: AsyncRead + Unpin>(r: &mut R) -> Result<StatusResponse> {
read_packet(r, move|id, r|async move {
read_packet(r, async |id, r| {
ensure!(id == 0x00);

let status_response = read_string(r).await?;
let status_response = serde_json::from_str::<StatusResponse>(&status_response)?;

Ok(status_response)
}).await
})
.await
}

pub async fn write_packet<'a, W, F, Fut>(w: &'a mut W, id: i32, f: F) -> Result<()>
pub async fn write_packet<W, F>(w: &mut W, id: i32, f: F) -> Result<()>
where
W: AsyncWrite + Unpin,
F: FnOnce(&'a mut (dyn AsyncWrite + Unpin)) -> Fut,
Fut: Future<Output=Result<()>> + 'a,
F: async FnOnce(&mut Vec<u8>) -> Result<()>,
{
let buf = &mut Vec::new();

Expand All @@ -57,11 +57,10 @@ where
Ok(())
}

pub async fn read_packet<R, F, T, Fut>(r: &mut R, f: F) -> Result<T>
pub async fn read_packet<R, F, T>(r: &mut R, f: F) -> Result<T>
where
R: AsyncRead + Unpin,
F: FnOnce(i32, &mut (dyn AsyncRead + Unpin)) -> Fut,
Fut: Future<Output=Result<T>>,
F: async FnOnce(i32, &mut (dyn AsyncRead + Unpin)) -> Result<T>,
{
let len = varint::read(r).await? as usize;
let mut data = vec![0; len];
Expand All @@ -74,7 +73,10 @@ where
Ok(value)
}

pub async fn write_unsigned_short<W: AsyncWrite + ?Sized + Unpin>(w: &mut W, value: u16) -> Result<()> {
pub async fn write_unsigned_short<W: AsyncWrite + ?Sized + Unpin>(
w: &mut W,
value: u16,
) -> Result<()> {
w.write_all(&value.to_be_bytes()).await?;
Ok(())
}
Expand Down