summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornea <nea@nea.moe>2023-03-27 21:54:37 +0200
committernea <nea@nea.moe>2023-03-27 21:54:37 +0200
commitb9da3e24eb07abcb33932480b8dbbcf69024c614 (patch)
tree8347175e88cb5333107460a6b9114146386252fb
parentb1c4131231227a7780e1c1940b399983cdd7f552 (diff)
downloadmgasi-b9da3e24eb07abcb33932480b8dbbcf69024c614.tar.gz
mgasi-b9da3e24eb07abcb33932480b8dbbcf69024c614.tar.bz2
mgasi-b9da3e24eb07abcb33932480b8dbbcf69024c614.zip
Proper async server and ctrl-c handling
-rw-r--r--Cargo.lock144
-rw-r--r--Cargo.toml4
-rw-r--r--src/connect.rs29
-rw-r--r--src/main.rs79
4 files changed, 160 insertions, 96 deletions
diff --git a/Cargo.lock b/Cargo.lock
index b9cd0ef..165897f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -41,19 +41,19 @@ dependencies = [
[[package]]
name = "anyhow"
-version = "1.0.68"
+version = "1.0.70"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61"
+checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4"
[[package]]
name = "async-trait"
-version = "0.1.62"
+version = "0.1.68"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "689894c2db1ea643a50834b999abf1c110887402542955ff5451dab8f861f9ed"
+checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.10",
]
[[package]]
@@ -76,15 +76,15 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bytes"
-version = "1.3.0"
+version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c"
+checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be"
[[package]]
name = "cc"
-version = "1.0.78"
+version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d"
+checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
[[package]]
name = "cfg-if"
@@ -165,15 +165,15 @@ dependencies = [
[[package]]
name = "itoa"
-version = "1.0.5"
+version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440"
+checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
[[package]]
name = "libc"
-version = "0.2.139"
+version = "0.2.140"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
+checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c"
[[package]]
name = "libz-sys"
@@ -242,9 +242,9 @@ dependencies = [
[[package]]
name = "mio"
-version = "0.8.5"
+version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de"
+checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9"
dependencies = [
"libc",
"log",
@@ -280,9 +280,9 @@ dependencies = [
[[package]]
name = "parking_lot_core"
-version = "0.9.6"
+version = "0.9.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba1ef8814b5c993410bb3adfad7a5ed269563e4a2f90c41f5d85be7fb47133bf"
+checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521"
dependencies = [
"cfg-if",
"libc",
@@ -311,18 +311,18 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
name = "proc-macro2"
-version = "1.0.50"
+version = "1.0.54"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2"
+checksum = "e472a104799c74b514a57226160104aa483546de37e839ec50e3c2e41dd87534"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
-version = "1.0.23"
+version = "1.0.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b"
+checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc"
dependencies = [
"proc-macro2",
]
@@ -379,9 +379,9 @@ dependencies = [
[[package]]
name = "ryu"
-version = "1.0.12"
+version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde"
+checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041"
[[package]]
name = "scopeguard"
@@ -391,29 +391,29 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "serde"
-version = "1.0.152"
+version = "1.0.158"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb"
+checksum = "771d4d9c4163ee138805e12c710dd365e4f44be8be0503cb1bb9eb989425d9c9"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
-version = "1.0.152"
+version = "1.0.158"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e"
+checksum = "e801c1712f48475582b7696ac71e0ca34ebb30e09338425384269d9717c62cad"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.10",
]
[[package]]
name = "serde_json"
-version = "1.0.91"
+version = "1.0.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883"
+checksum = "d721eca97ac802aa7777b701877c8004d950fc142651367300d21c1cc0194744"
dependencies = [
"itoa",
"ryu",
@@ -422,9 +422,9 @@ dependencies = [
[[package]]
name = "signal-hook-registry"
-version = "1.4.0"
+version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0"
+checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1"
dependencies = [
"libc",
]
@@ -437,9 +437,9 @@ checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
[[package]]
name = "socket2"
-version = "0.4.7"
+version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd"
+checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662"
dependencies = [
"libc",
"winapi",
@@ -447,9 +447,20 @@ dependencies = [
[[package]]
name = "syn"
-version = "1.0.107"
+version = "1.0.109"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5"
+checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "syn"
+version = "2.0.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5aad1363ed6d37b84299588d62d3a7d95b5a5c2d9aad5c85609fda12afaa1f40"
dependencies = [
"proc-macro2",
"quote",
@@ -458,29 +469,29 @@ dependencies = [
[[package]]
name = "thiserror"
-version = "1.0.38"
+version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0"
+checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
-version = "1.0.38"
+version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f"
+checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.10",
]
[[package]]
name = "tokio"
-version = "1.24.2"
+version = "1.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "597a12a59981d9e3c38d216785b0c37399f6e415e8d0712047620f189371b0bb"
+checksum = "03201d01c3c27a29c8a5cee5b55a93ddae1ccf6f08f65365c2c918f8c1b76f64"
dependencies = [
"autocfg",
"bytes",
@@ -504,7 +515,7 @@ checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 1.0.109",
]
[[package]]
@@ -515,9 +526,9 @@ checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
[[package]]
name = "unicode-ident"
-version = "1.0.6"
+version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc"
+checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4"
[[package]]
name = "vcpkg"
@@ -567,9 +578,18 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-sys"
-version = "0.42.0"
+version = "0.45.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
+dependencies = [
+ "windows-targets",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
+checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
@@ -582,42 +602,42 @@ dependencies = [
[[package]]
name = "windows_aarch64_gnullvm"
-version = "0.42.1"
+version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608"
+checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
[[package]]
name = "windows_aarch64_msvc"
-version = "0.42.1"
+version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7"
+checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
[[package]]
name = "windows_i686_gnu"
-version = "0.42.1"
+version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640"
+checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
[[package]]
name = "windows_i686_msvc"
-version = "0.42.1"
+version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605"
+checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
[[package]]
name = "windows_x86_64_gnu"
-version = "0.42.1"
+version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45"
+checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
[[package]]
name = "windows_x86_64_gnullvm"
-version = "0.42.1"
+version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463"
+checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
[[package]]
name = "windows_x86_64_msvc"
-version = "0.42.1"
+version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd"
+checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
diff --git a/Cargo.toml b/Cargo.toml
index 323ed46..4320d7c 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -8,11 +8,11 @@ edition = "2021"
[dependencies]
[dependencies.craftio-rs]
-version = "0.1.0"
+version = "*"
features = ["default"]
[dependencies.tokio]
-version = "1.15.0"
+version = "*"
features = ["full"]
[dependencies.anyhow]
diff --git a/src/connect.rs b/src/connect.rs
index 82590fb..1feb03e 100644
--- a/src/connect.rs
+++ b/src/connect.rs
@@ -1,9 +1,9 @@
-use std::net::TcpStream;
-
use anyhow::Result;
-use craftio_rs::{CraftSyncReader, CraftSyncWriter, CraftTcpConnection};
+use craftio_rs::{CraftAsyncReader, CraftAsyncWriter, CraftTokioConnection};
use mcproto_rs::protocol::HasPacketKind;
use mcproto_rs::v1_19_3::{Packet761, Packet761Kind, RawPacket761};
+use tokio::io::BufReader;
+use tokio::net::TcpStream;
#[macro_export]
macro_rules! await_packet {
@@ -36,24 +36,19 @@ macro_rules! assert_packet {
}
pub struct MinecraftClient {
- pub connection: CraftTcpConnection,
+ pub connection: CraftTokioConnection,
}
impl MinecraftClient {
- pub fn new(connection: CraftTcpConnection) -> Self {
- Self { connection }
- }
-
- pub fn from_stream(stream: TcpStream) -> Result<Self> {
- Ok(Self {
- connection: CraftTcpConnection::from_std(
- stream,
- mcproto_rs::protocol::PacketDirection::ServerBound,
- )?,
- })
+ pub fn from_stream(stream: TcpStream) -> Self {
+ let (read, write) = stream.into_split();
+ let bufread = BufReader::new(read);
+ MinecraftClient {
+ connection: CraftTokioConnection::from_async((bufread, write), mcproto_rs::protocol::PacketDirection::ServerBound),
+ }
}
pub async fn read_next_packet(&mut self) -> Result<Option<Packet761>> {
- if let Some(raw) = self.connection.read_packet::<RawPacket761>()? {
+ if let Some(raw) = self.connection.read_packet_async::<RawPacket761>().await? {
println!("Client -> Server: {:?}", raw);
Ok(Some(raw))
} else {
@@ -62,7 +57,7 @@ impl MinecraftClient {
}
pub async fn send_packet(&mut self, packet: Packet761) -> Result<()> {
println!("Server -> Client: {:?}", packet);
- self.connection.write_packet(packet)?;
+ self.connection.write_packet_async(packet).await?;
Ok(())
}
pub async fn wait_for_packet(&mut self, packet_kind: Packet761Kind) -> Result<Packet761> {
diff --git a/src/main.rs b/src/main.rs
index 088f27f..a113a30 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,40 +1,89 @@
-use std::net::{IpAddr, Ipv4Addr, SocketAddr, TcpListener, TcpStream};
+use std::net::{IpAddr, Ipv4Addr, SocketAddr};
use std::time::Duration;
use anyhow::Result;
-use craftio_rs::{CraftIo, CraftSyncReader, CraftSyncWriter, CraftTcpConnection};
+use craftio_rs::CraftIo;
use mcproto_rs::nbt::Tag;
-use mcproto_rs::protocol::{HasPacketKind, State};
+use mcproto_rs::protocol::State;
use mcproto_rs::Serializer;
use mcproto_rs::status::{StatusPlayersSpec, StatusSpec, StatusVersionSpec};
use mcproto_rs::types::{BytesSerializer, Chat, IntPosition, ItemStack, NamedNbtTag, RemainingBytes, Vec3};
use mcproto_rs::uuid::UUID4;
use mcproto_rs::v1_19_3::{BitSet, BlobArray, BookSettings, ChunkDataAndUpdateLightSpec, ChunkDataSpec, ChunkSection, CommandNode, CommandNodeSpec, CommandsSpec, EntityEventSpec, InitializeWorldBorderSpec, KeepAliveClientBoundSpec, LightDataSpec, PalettedContainer, PluginMessageSpec, RecipeBookAction, RecipeBookInitSpec, SetCenterChunkSpec, SetContainerContentSpec, SetDefaultSpawnPositionSpec, SynchronizePlayerPositionSpec, TagType, TypedTagList, UpdateRecipeBookSpec};
-use mcproto_rs::v1_19_3::{GameMode, HandshakeNextState, LoginPlaySpec, LoginSuccessSpec, Packet761, Packet761Kind, PingRequestSpec, PingResponseSpec, PreviousGameMode, RawPacket761, SetHeldItemClientSpec, StatusResponseSpec, UpdateRecipesSpec, UpdateTagsSpec};
+use mcproto_rs::v1_19_3::{GameMode, HandshakeNextState, LoginPlaySpec, LoginSuccessSpec, Packet761, Packet761Kind, PingRequestSpec, PingResponseSpec, PreviousGameMode, SetHeldItemClientSpec, StatusResponseSpec, UpdateRecipesSpec, UpdateTagsSpec};
use tokio;
-use crate::connect::MinecraftClient;
+use tokio::net::TcpStream;
+use tokio::signal::unix::{signal, SignalKind};
+use tokio::sync::{broadcast};
+use tokio::sync::broadcast::Receiver;
+use tokio::task::JoinHandle;
+use crate::connect::MinecraftClient;
pub mod connect;
pub mod nbtdsl;
+
#[tokio::main]
async fn main() -> Result<()> {
+ let (shutdown_send, _recv) = broadcast::channel::<()>(1);
+
+ let bind = tokio::net::TcpListener::bind(SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), 25565)).await?;
+ let server_rx = shutdown_send.subscribe();
+ let server_handle = tokio::spawn(async {
+ listener(bind, server_rx).await;
+ ()
+ });
+
+ println!("Awaiting shutdown request");
+ signal(SignalKind::interrupt())?.recv().await;
+ println!("Shutdown request detected");
+ shutdown_send.send(())?;
+ server_handle.await?;
+
+ Ok(())
+}
+
+async fn listener(listener: tokio::net::TcpListener, mut receiver: Receiver<()>) {
println!("Starting server");
- let bind = TcpListener::bind(SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), 25565))?;
+ let mut handles: Vec<JoinHandle<()>> = Vec::new();
loop {
- if let Ok((socket, address)) = bind.accept() {
- println!("Connection accepted from {}", address);
- let client = MinecraftClient::from_stream(socket)?;
- tokio::spawn(async {
- if let Err(x) = handle_conn(client).await {
- println!("Error: {:?}", x);
- }
- });
- }
+ let x: Option<(TcpStream, SocketAddr)> = tokio::select! {
+ _ = receiver.recv() => {
+ break;
+ }
+ conn = listener.accept() => { conn.ok() }
+ };
+ let (stream, from) = match x {
+ None => { continue }
+ Some(y) => { y }
+ };
+ println!("Connection accepted from {}", from);
+ let client = MinecraftClient::from_stream(stream);
+ let handle = tokio::spawn(async {
+ if let Err(x) = handle_conn(client).await {
+ println!("Error: {:?}", x);
+ }
+ });
+ handles.push(handle);
}
+ println!("Shutdown started");
+ for x in &handles {
+ x.abort();
+ }
+ /*
+ TODO: proper kicks so that we can just join
+ for x in handles {
+ match x.await {
+ Ok(_) => {}
+ Err(_) => {
+ println!("Failed to join server during exit!")
+ }
+ };
+ }*/
}
+
async fn handle_conn(mut client: MinecraftClient) -> Result<()> {
let hs = assert_packet!(Handshake, client, "Missing packet");
if hs.next_state == HandshakeNextState::Login {