diff --git a/.github/workflows/rust-clippy.yml b/.github/workflows/rust-clippy.yml index cf2a176..2345b97 100644 --- a/.github/workflows/rust-clippy.yml +++ b/.github/workflows/rust-clippy.yml @@ -51,7 +51,7 @@ jobs: run: cargo install clippy-sarif sarif-fmt - name: Run rust-clippy - run: cargo clippy --all-features --message-format=json | clippy-sarif | tee rust-clippy-results.sarif | sarif-fmt + run: cargo clippy --message-format=json | clippy-sarif | tee rust-clippy-results.sarif | sarif-fmt continue-on-error: true - name: Upload analysis results to GitHub diff --git a/Cargo.lock b/Cargo.lock index b0f51ee..bc53faa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -125,6 +125,17 @@ name = "character_delight" version = "0.1.0" source = "git+https://github.com/PineBale/CharacterDelight-Rust.git?tag=0.1.0#81012de80c61a305d25c9468b211245c46af3021" +[[package]] +name = "chrono" +version = "0.4.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327" +dependencies = [ + "js-sys", + "num-traits", + "wasm-bindgen", +] + [[package]] name = "clap" version = "4.6.1" @@ -318,6 +329,12 @@ dependencies = [ "syn", ] +[[package]] +name = "futures-sink" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" + [[package]] name = "futures-task" version = "0.3.32" @@ -331,8 +348,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" dependencies = [ "futures-core", + "futures-io", "futures-macro", + "futures-sink", "futures-task", + "memchr", "pin-project-lite", "slab", ] @@ -453,6 +473,26 @@ dependencies = [ "tracing", ] +[[package]] +name = "http" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6970f50e31d6fc17d3fa27329444bfa74e196cf62e95052a3f6fee181dba6425" +dependencies = [ + "bytes", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http", +] + [[package]] name = "icu_collections" version = "2.2.0" @@ -659,13 +699,12 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.98" +version = "0.3.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67df7112613f8bfd9150013a0314e196f4800d3201ae742489d999db2f979f08" +checksum = "03d04c30968dffe80775bd4d7fb676131cd04a1fb46d2686dbffbaec2d9dfd31" dependencies = [ "cfg-if", "futures-util", - "once_cell", "wasm-bindgen", ] @@ -702,6 +741,12 @@ version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +[[package]] +name = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + [[package]] name = "mcping" version = "0.1.2" @@ -709,8 +754,11 @@ dependencies = [ "character_delight", "clap", "hickory-resolver", + "http", "once_cell", "tokio", + "worker", + "worker-macros", ] [[package]] @@ -807,6 +855,26 @@ version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" +[[package]] +name = "pin-project" +version = "1.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2466b2336ed02bcdca6b294417127b90ec92038d1d5c4fbeac971a922e0e0924" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "pin-project-lite" version = "0.2.17" @@ -934,6 +1002,12 @@ version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" +[[package]] +name = "ryu" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" + [[package]] name = "same-file" version = "1.0.6" @@ -965,6 +1039,17 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde-wasm-bindgen" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8302e169f0eddcc139c70f139d19d6467353af16f9fce27e8c30158036a1e16b" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + [[package]] name = "serde_core" version = "1.0.228" @@ -998,6 +1083,18 @@ dependencies = [ "zmij", ] +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + [[package]] name = "shlex" version = "1.3.0" @@ -1054,6 +1151,27 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "strum" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "syn" version = "2.0.117" @@ -1282,9 +1400,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.121" +version = "0.2.125" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49ace1d07c165b0864824eee619580c4689389afa9dc9ed3a4c75040d82e6790" +checksum = "8ddb3f79143bced6de84270411622a2699cee572fc0875aeaf1e7867cf9fca1a" dependencies = [ "cfg-if", "once_cell", @@ -1293,11 +1411,21 @@ dependencies = [ "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "503b14d284f2c8dac03b819967e155ea753f573586193b2b2c95990cb5d69280" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "wasm-bindgen-macro" -version = "0.2.121" +version = "0.2.125" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e68e6f4afd367a562002c05637acb8578ff2dea1943df76afb9e83d177c8578" +checksum = "4e21a184b13fb19e157296e2c46056aec9092264fab83e4ba59e68c61b323c3d" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1305,9 +1433,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.121" +version = "0.2.125" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d95a9ec35c64b2a7cb35d3fead40c4238d0940c86d107136999567a4703259f2" +checksum = "fecefd9c35bd935a20fc3fc344b5f29138961e4f47fb03297d88f2587afb5ebd" dependencies = [ "bumpalo", "proc-macro2", @@ -1318,9 +1446,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.121" +version = "0.2.125" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4e0100b01e9f0d03189a92b96772a1fb998639d981193d7dbab487302513441" +checksum = "23939e44bb9a5d7576fa2b563dc2e136628f1224e88a8deed09e04858b77871f" dependencies = [ "unicode-ident", ] @@ -1347,6 +1475,19 @@ dependencies = [ "wasmparser", ] +[[package]] +name = "wasm-streams" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7d3be8814f5ba5f074491a469eed3d73c273ffad955f25ed1635efac4b0d269" +dependencies = [ + "futures-util", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + [[package]] name = "wasmparser" version = "0.244.0" @@ -1359,6 +1500,16 @@ dependencies = [ "semver", ] +[[package]] +name = "web-sys" +version = "0.3.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6430a72df5eb332242960fe84b3002a241163998241eb596d4f739b9757061d" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "widestring" version = "1.2.1" @@ -1585,6 +1736,65 @@ dependencies = [ "wasmparser", ] +[[package]] +name = "worker" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f8adbf6c9ae45b665dee995c5e3a342c2bd7d58a2e8ca5c75b50ce8b1b8bfd9" +dependencies = [ + "async-trait", + "bytes", + "chrono", + "futures-channel", + "futures-util", + "http", + "http-body", + "js-sys", + "matchit", + "pin-project", + "serde", + "serde-wasm-bindgen", + "serde_json", + "serde_urlencoded", + "strum", + "tokio", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", + "worker-macros", + "worker-sys", +] + +[[package]] +name = "worker-macros" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d908735d273dd7f9c325a842623f4e5a745e0686187ce465b34dc162ad348df" +dependencies = [ + "async-trait", + "proc-macro2", + "quote", + "strum", + "syn", + "wasm-bindgen", + "wasm-bindgen-macro-support", + "worker-sys", +] + +[[package]] +name = "worker-sys" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33faa1a8fa6c7eec67b196e008859c44d468a5ad4f991855cdc856f119e0e98f" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "writeable" version = "0.6.3" diff --git a/Cargo.toml b/Cargo.toml index 4cb1a24..0fddf1c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,9 +8,24 @@ readme = "README.md" license-file = "LICENSE" publish = false +[lib] +crate-type = ["cdylib", "rlib"] + +[[bin]] +name = "mcping" +path = "src/main.rs" + [dependencies] character_delight = { git = "https://github.com/PineBale/CharacterDelight-Rust.git", tag = "0.1.0" } -hickory-resolver = "0.26.1" -tokio = "1.52.3" -clap = { version = "4.6.1", features = ["derive"] } -once_cell = "1.21.4" \ No newline at end of file +once_cell = "1.21.4" +hickory-resolver = { version = "0.26.1", optional = true } +tokio = { version = "1.52.3", optional = true } +clap = { version = "4.6.1", features = ["derive"], optional = true } +worker = { version = "0.8.5", features = ["http"], optional = true } +worker-macros = { version = "0.8.5", features = ["http"], optional = true } +http = { version = "1.4.2", optional = true } + +[features] +default = ["native"] +native = ["dep:hickory-resolver", "dep:tokio", "dep:clap"] +cloudflare-worker = ["dep:worker", "dep:worker-macros", "dep:http"] diff --git a/Makefile b/Makefile index 720965d..ae2846d 100644 --- a/Makefile +++ b/Makefile @@ -1,14 +1,14 @@ -CARGO ?= cargo -PROFILE ?= release -FEATURES ?= --all-features +CARGO ?= cargo +PROFILE ?= release +FEATURES ?= -CLIPPY_PROFILE ?= dev -TEST_PROFILE ?= dev +CLIPPY_PROFILE ?= $(PROFILE) +TEST_PROFILE ?= $(PROFILE) -CLIPPY_FLAGS = $(FEATURES) --all-targets -- -D warnings -TARPAULIN_FLAGS = --run-types AllTargets --out lcov --out stdout +CLIPPY_FLAGS = $(FEATURES) --all-targets -- -D warnings +TARPAULIN_FLAGS = --run-types AllTargets --out lcov --out stdout --skip-clean --target-dir target/tarpaulin -.PHONY: all build test lint lint-fix fmt fmt-check clean ci help +.PHONY: all build test lint lint-fix fmt fmt-check clean ci coverage all: fmt-check lint test build @@ -16,6 +16,9 @@ build: $(CARGO) build --profile $(PROFILE) $(FEATURES) test: + $(CARGO) test --profile $(TEST_PROFILE) $(FEATURES) + +coverage: $(CARGO) tarpaulin --profile $(TEST_PROFILE) $(FEATURES) $(TARPAULIN_FLAGS) lint: @@ -33,4 +36,4 @@ fmt-check: clean: $(CARGO) clean -ci: fmt-check lint test build +ci: fmt-check lint coverage build diff --git a/src/base/mod.rs b/src/base/mod.rs new file mode 100644 index 0000000..dbe5b5f --- /dev/null +++ b/src/base/mod.rs @@ -0,0 +1,7 @@ +pub mod packet; +pub mod protocol; +pub mod util; + +pub use packet::*; +pub use protocol::*; +pub use util::*; diff --git a/src/packet.rs b/src/base/packet.rs similarity index 96% rename from src/packet.rs rename to src/base/packet.rs index 20183e3..79754c4 100644 --- a/src/packet.rs +++ b/src/base/packet.rs @@ -1,9 +1,8 @@ #![allow(unused)] +use crate::base::ProtocolNum; use character_delight::create_varint; -use crate::protocol::ProtocolNum; - fn packet_raw_content_add_varint_length(packet_content: &mut Vec) { packet_content.splice(0..0, create_varint(packet_content.len() as i32)); } @@ -39,8 +38,8 @@ pub fn compose_status_request_packet() -> Vec { #[cfg(test)] mod tests { - use crate::protocol::MINECRAFT_1_21_8; - use crate::protocol::MINECRAFT_1_8; + use crate::base::MINECRAFT_1_21_8; + use crate::base::MINECRAFT_1_8; use super::*; diff --git a/src/protocol.rs b/src/base/protocol.rs similarity index 100% rename from src/protocol.rs rename to src/base/protocol.rs diff --git a/src/base/util.rs b/src/base/util.rs new file mode 100644 index 0000000..4435f31 --- /dev/null +++ b/src/base/util.rs @@ -0,0 +1,35 @@ +use crate::base::{is_known_protocol_number, ProtocolNum, DEFAULT_PORT}; + +pub fn parse_server_address<'a>( + address: &'a str, + fakehost: &'a str, + protocol: ProtocolNum, +) -> Result<(&'a str, &'a str, u16), &'static str> { + if !is_known_protocol_number(protocol) { + return Err("Unknown protocol number"); + } + + let address_to_use; + let port_to_use; + + match address.find(":") { + Some(p) => { + address_to_use = &address[..p]; + port_to_use = String::from(&address[p + 1..]) + .parse::() + .expect("Invalid port number"); + } + None => { + address_to_use = address; + port_to_use = DEFAULT_PORT; + } + } + + let hostname_to_use = if fakehost.is_empty() { + address_to_use + } else { + fakehost + }; + + Ok((address_to_use, hostname_to_use, port_to_use)) +} diff --git a/src/lib.rs b/src/lib.rs index cb66e41..f90dd4d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,9 +1,13 @@ -pub use dns::*; -pub use packet::*; -pub use pinger::*; -pub use protocol::*; +#[cfg(all(feature = "native", feature = "cloudflare-worker"))] +compile_error!("You cannot enable both of the flags!"); -pub mod dns; -pub mod packet; -pub mod pinger; -pub mod protocol; +#[cfg(not(any(feature = "native", feature = "cloudflare-worker")))] +compile_error!("Enable one of the flags!"); + +pub mod base; +pub use base::*; + +#[cfg(feature = "native")] +pub mod native; +#[cfg(feature = "native")] +pub use native::*; diff --git a/src/main.rs b/src/main.rs index 4c613f8..1b7855b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,12 @@ -use crate::protocol::get_protocol_number_by_version; +#![cfg(feature = "native")] + +use crate::base::get_protocol_number_by_version; +use crate::native::pinger::ping; use clap::{ArgAction, Parser}; use std::io::{stdout, Write}; -mod dns; -mod packet; -mod protocol; +mod base; +mod native; #[derive(Parser)] #[command( @@ -38,7 +40,7 @@ async fn main() { Some(v) => v, None => panic!("Unknown Minecraft version {vs}"), }; - let res = mcping::ping( + let res = ping( &args.address, &args.fakehost.unwrap_or_default(), v, diff --git a/src/dns.rs b/src/native/dns.rs similarity index 98% rename from src/dns.rs rename to src/native/dns.rs index 3c2300d..a7ee5dc 100644 --- a/src/dns.rs +++ b/src/native/dns.rs @@ -4,12 +4,11 @@ use std::net::{IpAddr, Ipv4Addr}; use std::str::FromStr; use std::sync::OnceLock; +use crate::base::DEFAULT_PORT; use hickory_resolver::net::runtime::TokioRuntimeProvider; use hickory_resolver::proto::rr::RData; use hickory_resolver::Resolver; -use crate::protocol::DEFAULT_PORT; - fn get_resolver() -> &'static Resolver { static RESOLVER: OnceLock> = OnceLock::new(); RESOLVER.get_or_init(|| Resolver::builder_tokio().unwrap().build().unwrap()) diff --git a/src/native/mod.rs b/src/native/mod.rs new file mode 100644 index 0000000..c0e4388 --- /dev/null +++ b/src/native/mod.rs @@ -0,0 +1,4 @@ +pub mod dns; +pub mod pinger; + +pub use dns::*; diff --git a/src/pinger.rs b/src/native/pinger.rs similarity index 80% rename from src/pinger.rs rename to src/native/pinger.rs index 7ce0b01..a7a2df6 100644 --- a/src/pinger.rs +++ b/src/native/pinger.rs @@ -1,8 +1,9 @@ #![allow(unused)] -use crate::dns::*; -use crate::packet::*; -use crate::protocol::*; +use crate::base::{ + compose_handshake_packet, compose_status_request_packet, parse_server_address, ProtocolNum, +}; +use crate::native::resolve; use std::io::{Read, Write}; use std::net::{Shutdown, SocketAddr, TcpStream}; use std::slice; @@ -14,34 +15,12 @@ pub async fn ping( protocol_number: ProtocolNum, timeout: u8, ) -> Result, &'static str> { - if !is_known_protocol_number(protocol_number) { - return Err("Unknown protocol number"); - } if timeout == 0 { return Err("Timeout in seconds must be bigger than 0"); } - let address_to_use; - let port_to_use; - - match input_address.find(":") { - Some(p) => { - address_to_use = &input_address[..p]; - port_to_use = String::from(&input_address[p + 1..]) - .parse::() - .expect("Invalid port number"); - } - None => { - address_to_use = input_address; - port_to_use = DEFAULT_PORT; - } - } - - let hostname_to_use = if input_fakehost.is_empty() { - address_to_use - } else { - input_fakehost - }; + let (address_to_use, hostname_to_use, port_to_use) = + parse_server_address(input_address, input_fakehost, protocol_number)?; let ips = resolve(address_to_use, port_to_use).await?; diff --git a/tests/dns_test.rs b/tests/dns_test.rs index 01aa1d6..c594244 100644 --- a/tests/dns_test.rs +++ b/tests/dns_test.rs @@ -1,4 +1,7 @@ -use mcping::{resolve, DEFAULT_PORT}; +#![cfg(feature = "native")] + +use mcping::dns::resolve; +use mcping::DEFAULT_PORT; use std::net::Ipv4Addr; use std::str::FromStr;