forked from didirus/AstralRinth
Legacy ping support (#4062)
* Detection of protocol versions before 18w47b * Refactor old_protocol_versions into protocol_version * Ping servers closer to how a client of an instance's version would ping a server * Allow pinging legacy servers from a modern profile in the same way a modern client would * Ping 1.4.2 through 1.5.2 like a Vanilla client in those versions would when in such an instance
This commit is contained in:
@@ -27,6 +27,7 @@ hashlink.workspace = true
|
||||
png.workspace = true
|
||||
bytemuck.workspace = true
|
||||
rgb.workspace = true
|
||||
phf.workspace = true
|
||||
|
||||
chrono = { workspace = true, features = ["serde"] }
|
||||
daedalus.workspace = true
|
||||
|
||||
@@ -5,6 +5,8 @@ use crate::state::attached_world_data::AttachedWorldData;
|
||||
use crate::state::{
|
||||
Profile, ProfileInstallStage, attached_world_data, server_join_log,
|
||||
};
|
||||
use crate::util::protocol_version::OLD_PROTOCOL_VERSIONS;
|
||||
pub use crate::util::protocol_version::ProtocolVersion;
|
||||
pub use crate::util::server_ping::{
|
||||
ServerGameProfile, ServerPlayers, ServerStatus, ServerVersion,
|
||||
};
|
||||
@@ -835,7 +837,7 @@ mod servers_data {
|
||||
|
||||
pub async fn get_profile_protocol_version(
|
||||
profile: &str,
|
||||
) -> Result<Option<i32>> {
|
||||
) -> Result<Option<ProtocolVersion>> {
|
||||
let mut profile = super::profile::get(profile).await?.ok_or_else(|| {
|
||||
ErrorKind::UnmanagedProfileError(format!(
|
||||
"Could not find profile {profile}"
|
||||
@@ -846,7 +848,12 @@ pub async fn get_profile_protocol_version(
|
||||
}
|
||||
|
||||
if let Some(protocol_version) = profile.protocol_version {
|
||||
return Ok(Some(protocol_version));
|
||||
return Ok(Some(ProtocolVersion::modern(protocol_version)));
|
||||
}
|
||||
if let Some(protocol_version) =
|
||||
OLD_PROTOCOL_VERSIONS.get(&profile.game_version)
|
||||
{
|
||||
return Ok(Some(*protocol_version));
|
||||
}
|
||||
|
||||
let minecraft = crate::api::metadata::get_minecraft_versions().await?;
|
||||
@@ -854,7 +861,7 @@ pub async fn get_profile_protocol_version(
|
||||
.versions
|
||||
.iter()
|
||||
.position(|it| it.id == profile.game_version)
|
||||
.ok_or(crate::ErrorKind::LauncherError(format!(
|
||||
.ok_or(ErrorKind::LauncherError(format!(
|
||||
"Invalid game version: {}",
|
||||
profile.game_version
|
||||
)))?;
|
||||
@@ -890,16 +897,19 @@ pub async fn get_profile_protocol_version(
|
||||
profile.protocol_version = version;
|
||||
profile.upsert(&state.pool).await?;
|
||||
}
|
||||
Ok(version)
|
||||
Ok(version.map(ProtocolVersion::modern))
|
||||
}
|
||||
|
||||
pub async fn get_server_status(
|
||||
address: &str,
|
||||
protocol_version: Option<i32>,
|
||||
protocol_version: Option<ProtocolVersion>,
|
||||
) -> Result<ServerStatus> {
|
||||
let (original_host, original_port) = parse_server_address(address)?;
|
||||
let (host, port) =
|
||||
resolve_server_address(original_host, original_port).await?;
|
||||
tracing::debug!(
|
||||
"Pinging {address} with protocol version {protocol_version:?}"
|
||||
);
|
||||
server_ping::get_server_status(
|
||||
&(&host as &str, port),
|
||||
(original_host, original_port),
|
||||
|
||||
@@ -419,7 +419,7 @@ pub async fn install_minecraft(
|
||||
|
||||
pub async fn read_protocol_version_from_jar(
|
||||
path: PathBuf,
|
||||
) -> crate::Result<Option<i32>> {
|
||||
) -> crate::Result<Option<u32>> {
|
||||
let zip = async_zip::tokio::read::fs::ZipFileReader::new(path).await?;
|
||||
let Some(entry_index) = zip
|
||||
.file()
|
||||
@@ -432,7 +432,7 @@ pub async fn read_protocol_version_from_jar(
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
struct VersionData {
|
||||
protocol_version: Option<i32>,
|
||||
protocol_version: Option<u32>,
|
||||
}
|
||||
|
||||
let mut data = vec![];
|
||||
|
||||
@@ -32,7 +32,7 @@ pub struct Profile {
|
||||
pub icon_path: Option<String>,
|
||||
|
||||
pub game_version: String,
|
||||
pub protocol_version: Option<i32>,
|
||||
pub protocol_version: Option<u32>,
|
||||
pub loader: ModLoader,
|
||||
pub loader_version: Option<String>,
|
||||
|
||||
@@ -320,7 +320,7 @@ impl TryFrom<ProfileQueryResult> for Profile {
|
||||
name: x.name,
|
||||
icon_path: x.icon_path,
|
||||
game_version: x.game_version,
|
||||
protocol_version: x.protocol_version.map(|x| x as i32),
|
||||
protocol_version: x.protocol_version.map(|x| x as u32),
|
||||
loader: ModLoader::from_string(&x.mod_loader),
|
||||
loader_version: x.mod_loader_version,
|
||||
groups: serde_json::from_value(x.groups).unwrap_or_default(),
|
||||
|
||||
@@ -3,4 +3,5 @@ pub mod fetch;
|
||||
pub mod io;
|
||||
pub mod jre;
|
||||
pub mod platform;
|
||||
pub mod protocol_version;
|
||||
pub mod server_ping;
|
||||
|
||||
478
packages/app-lib/src/util/protocol_version.rs
Normal file
478
packages/app-lib/src/util/protocol_version.rs
Normal file
@@ -0,0 +1,478 @@
|
||||
use phf::phf_map;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Deserialize, Serialize, Debug, Copy, Clone)]
|
||||
pub struct ProtocolVersion {
|
||||
pub version: u32,
|
||||
pub legacy: bool,
|
||||
}
|
||||
|
||||
impl ProtocolVersion {
|
||||
pub const fn modern(version: u32) -> Self {
|
||||
Self {
|
||||
version,
|
||||
legacy: false,
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn legacy(version: u32) -> Self {
|
||||
Self {
|
||||
version,
|
||||
legacy: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The map of protocol versions from before version.json was added. For newer versions, the
|
||||
/// protocol version can just be read from version.json.
|
||||
pub const OLD_PROTOCOL_VERSIONS: phf::Map<&str, ProtocolVersion> = phf_map! {
|
||||
// April fools versions
|
||||
"1.RV-Pre1" => ProtocolVersion::modern(108),
|
||||
"15w14a" => ProtocolVersion::modern(48),
|
||||
"2point0_purple" => ProtocolVersion::legacy(92),
|
||||
"2point0_red" => ProtocolVersion::legacy(91),
|
||||
"2point0_blue" => ProtocolVersion::legacy(90),
|
||||
|
||||
// Normal versions
|
||||
"18w47a" => ProtocolVersion::modern(446),
|
||||
"18w46a" => ProtocolVersion::modern(445),
|
||||
"18w45a" => ProtocolVersion::modern(444),
|
||||
"18w44a" => ProtocolVersion::modern(443),
|
||||
"18w43c" => ProtocolVersion::modern(442),
|
||||
"18w43b" => ProtocolVersion::modern(441),
|
||||
"18w43a" => ProtocolVersion::modern(440),
|
||||
"1.13.2" => ProtocolVersion::modern(404),
|
||||
"1.13.2-pre2" => ProtocolVersion::modern(403),
|
||||
"1.13.2-pre1" => ProtocolVersion::modern(402),
|
||||
"1.13.1" => ProtocolVersion::modern(401),
|
||||
"1.13.1-pre2" => ProtocolVersion::modern(400),
|
||||
"1.13.1-pre1" => ProtocolVersion::modern(399),
|
||||
"18w33a" => ProtocolVersion::modern(398),
|
||||
"18w32a" => ProtocolVersion::modern(397),
|
||||
"18w31a" => ProtocolVersion::modern(396),
|
||||
"18w30b" => ProtocolVersion::modern(395),
|
||||
"18w30a" => ProtocolVersion::modern(394),
|
||||
"1.13" => ProtocolVersion::modern(393),
|
||||
"1.13-pre10" => ProtocolVersion::modern(392),
|
||||
"1.13-pre9" => ProtocolVersion::modern(391),
|
||||
"1.13-pre8" => ProtocolVersion::modern(390),
|
||||
"1.13-pre7" => ProtocolVersion::modern(389),
|
||||
"1.13-pre6" => ProtocolVersion::modern(388),
|
||||
"1.13-pre5" => ProtocolVersion::modern(387),
|
||||
"1.13-pre4" => ProtocolVersion::modern(386),
|
||||
"1.13-pre3" => ProtocolVersion::modern(385),
|
||||
"1.13-pre2" => ProtocolVersion::modern(384),
|
||||
"1.13-pre1" => ProtocolVersion::modern(383),
|
||||
"18w22c" => ProtocolVersion::modern(382),
|
||||
"18w22b" => ProtocolVersion::modern(381),
|
||||
"18w22a" => ProtocolVersion::modern(380),
|
||||
"18w21b" => ProtocolVersion::modern(379),
|
||||
"18w21a" => ProtocolVersion::modern(378),
|
||||
"18w20c" => ProtocolVersion::modern(377),
|
||||
"18w20b" => ProtocolVersion::modern(376),
|
||||
"18w20a" => ProtocolVersion::modern(375),
|
||||
"18w19b" => ProtocolVersion::modern(374),
|
||||
"18w19a" => ProtocolVersion::modern(373),
|
||||
"18w16a" => ProtocolVersion::modern(372),
|
||||
"18w15a" => ProtocolVersion::modern(371),
|
||||
"18w14b" => ProtocolVersion::modern(370),
|
||||
"18w14a" => ProtocolVersion::modern(369),
|
||||
"18w11a" => ProtocolVersion::modern(368),
|
||||
"18w10d" => ProtocolVersion::modern(367),
|
||||
"18w10c" => ProtocolVersion::modern(366),
|
||||
"18w10b" => ProtocolVersion::modern(365),
|
||||
"18w10a" => ProtocolVersion::modern(364),
|
||||
"18w09a" => ProtocolVersion::modern(363),
|
||||
"18w08b" => ProtocolVersion::modern(362),
|
||||
"18w08a" => ProtocolVersion::modern(361),
|
||||
"18w07c" => ProtocolVersion::modern(360),
|
||||
"18w07b" => ProtocolVersion::modern(359),
|
||||
"18w07a" => ProtocolVersion::modern(358),
|
||||
"18w06a" => ProtocolVersion::modern(357),
|
||||
"18w05a" => ProtocolVersion::modern(356),
|
||||
"18w03b" => ProtocolVersion::modern(355),
|
||||
"18w03a" => ProtocolVersion::modern(354),
|
||||
"18w02a" => ProtocolVersion::modern(353),
|
||||
"18w01a" => ProtocolVersion::modern(352),
|
||||
"17w50a" => ProtocolVersion::modern(351),
|
||||
"17w49b" => ProtocolVersion::modern(350),
|
||||
"17w49a" => ProtocolVersion::modern(349),
|
||||
"17w48a" => ProtocolVersion::modern(348),
|
||||
"17w47b" => ProtocolVersion::modern(347),
|
||||
"17w47a" => ProtocolVersion::modern(346),
|
||||
"17w46a" => ProtocolVersion::modern(345),
|
||||
"17w45b" => ProtocolVersion::modern(344),
|
||||
"17w45a" => ProtocolVersion::modern(343),
|
||||
"17w43b" => ProtocolVersion::modern(342),
|
||||
"17w43a" => ProtocolVersion::modern(341),
|
||||
"1.12.2" => ProtocolVersion::modern(340),
|
||||
"1.21.2-pre2" => ProtocolVersion::modern(339),
|
||||
"1.21.2-pre1" => ProtocolVersion::modern(339),
|
||||
"1.12.1" => ProtocolVersion::modern(338),
|
||||
"1.12.1-pre1" => ProtocolVersion::modern(337),
|
||||
"17w31a" => ProtocolVersion::modern(336),
|
||||
"1.12" => ProtocolVersion::modern(335),
|
||||
"1.12-pre7" => ProtocolVersion::modern(334),
|
||||
"1.12-pre6" => ProtocolVersion::modern(333),
|
||||
"1.12-pre5" => ProtocolVersion::modern(332),
|
||||
"1.12-pre4" => ProtocolVersion::modern(331),
|
||||
"1.12-pre3" => ProtocolVersion::modern(330),
|
||||
"1.12-pre2" => ProtocolVersion::modern(329),
|
||||
"1.12-pre1" => ProtocolVersion::modern(328),
|
||||
"17w18b" => ProtocolVersion::modern(327),
|
||||
"17w18a" => ProtocolVersion::modern(326),
|
||||
"17w17b" => ProtocolVersion::modern(325),
|
||||
"17w17a" => ProtocolVersion::modern(324),
|
||||
"17w16b" => ProtocolVersion::modern(323),
|
||||
"17w16a" => ProtocolVersion::modern(322),
|
||||
"17w15a" => ProtocolVersion::modern(321),
|
||||
"17w14a" => ProtocolVersion::modern(320),
|
||||
"17w13b" => ProtocolVersion::modern(319),
|
||||
"17w13a" => ProtocolVersion::modern(318),
|
||||
"17w06a" => ProtocolVersion::modern(317),
|
||||
"1.11.2" => ProtocolVersion::modern(316),
|
||||
"1.11.1" => ProtocolVersion::modern(316),
|
||||
"16w50a" => ProtocolVersion::modern(316),
|
||||
"1.11" => ProtocolVersion::modern(315),
|
||||
"1.11-pre1" => ProtocolVersion::modern(314),
|
||||
"16w44a" => ProtocolVersion::modern(313),
|
||||
"16w43a" => ProtocolVersion::modern(313),
|
||||
"16w42a" => ProtocolVersion::modern(312),
|
||||
"16w41a" => ProtocolVersion::modern(311),
|
||||
"16w40a" => ProtocolVersion::modern(310),
|
||||
"16w39c" => ProtocolVersion::modern(309),
|
||||
"16w39b" => ProtocolVersion::modern(308),
|
||||
"16w39a" => ProtocolVersion::modern(307),
|
||||
"16w38a" => ProtocolVersion::modern(306),
|
||||
"16w36a" => ProtocolVersion::modern(305),
|
||||
"16w35a" => ProtocolVersion::modern(304),
|
||||
"16w33a" => ProtocolVersion::modern(303),
|
||||
"16w32b" => ProtocolVersion::modern(302),
|
||||
"16w32a" => ProtocolVersion::modern(301),
|
||||
"1.10.2" => ProtocolVersion::modern(210),
|
||||
"1.10.1" => ProtocolVersion::modern(210),
|
||||
"1.10" => ProtocolVersion::modern(210),
|
||||
"1.10-pre2" => ProtocolVersion::modern(205),
|
||||
"1.10-pre1" => ProtocolVersion::modern(204),
|
||||
"16w21b" => ProtocolVersion::modern(203),
|
||||
"16w21a" => ProtocolVersion::modern(202),
|
||||
"16w20a" => ProtocolVersion::modern(201),
|
||||
"1.9.4" => ProtocolVersion::modern(110),
|
||||
"1.9.3" => ProtocolVersion::modern(110),
|
||||
"1.9.3-pre3" => ProtocolVersion::modern(110),
|
||||
"1.9.3-pre2" => ProtocolVersion::modern(110),
|
||||
"1.9.3-pre1" => ProtocolVersion::modern(109),
|
||||
"16w15b" => ProtocolVersion::modern(109),
|
||||
"16w15a" => ProtocolVersion::modern(109),
|
||||
"16w14a" => ProtocolVersion::modern(109),
|
||||
"1.9.2" => ProtocolVersion::modern(109),
|
||||
"1.9.1" => ProtocolVersion::modern(108),
|
||||
"1.9.1-pre3" => ProtocolVersion::modern(108),
|
||||
"1.9.1-pre2" => ProtocolVersion::modern(108),
|
||||
"1.9.1-pre1" => ProtocolVersion::modern(107),
|
||||
"1.9" => ProtocolVersion::modern(107),
|
||||
"1.9-pre4" => ProtocolVersion::modern(106),
|
||||
"1.9-pre3" => ProtocolVersion::modern(105),
|
||||
"1.9-pre2" => ProtocolVersion::modern(104),
|
||||
"1.9-pre1" => ProtocolVersion::modern(103),
|
||||
"16w07b" => ProtocolVersion::modern(102),
|
||||
"16w07a" => ProtocolVersion::modern(101),
|
||||
"16w06a" => ProtocolVersion::modern(100),
|
||||
"16w05b" => ProtocolVersion::modern(99),
|
||||
"16w05a" => ProtocolVersion::modern(98),
|
||||
"16w04a" => ProtocolVersion::modern(97),
|
||||
"16w03a" => ProtocolVersion::modern(96),
|
||||
"16w02a" => ProtocolVersion::modern(95),
|
||||
"15w51b" => ProtocolVersion::modern(94),
|
||||
"15w51a" => ProtocolVersion::modern(93),
|
||||
"15w50a" => ProtocolVersion::modern(92),
|
||||
"15w49b" => ProtocolVersion::modern(91),
|
||||
"15w49a" => ProtocolVersion::modern(90),
|
||||
"15w47c" => ProtocolVersion::modern(89),
|
||||
"15w47b" => ProtocolVersion::modern(88),
|
||||
"15w47a" => ProtocolVersion::modern(87),
|
||||
"15w46a" => ProtocolVersion::modern(86),
|
||||
"15w45a" => ProtocolVersion::modern(85),
|
||||
"15w44b" => ProtocolVersion::modern(84),
|
||||
"15w44a" => ProtocolVersion::modern(83),
|
||||
"15w43c" => ProtocolVersion::modern(82),
|
||||
"15w43b" => ProtocolVersion::modern(81),
|
||||
"15w43a" => ProtocolVersion::modern(80),
|
||||
"15w42a" => ProtocolVersion::modern(79),
|
||||
"15w41b" => ProtocolVersion::modern(78),
|
||||
"15w41a" => ProtocolVersion::modern(77),
|
||||
"15w40b" => ProtocolVersion::modern(76),
|
||||
"15w40a" => ProtocolVersion::modern(75),
|
||||
"15w39c" => ProtocolVersion::modern(74),
|
||||
"15w39b" => ProtocolVersion::modern(74),
|
||||
"15w39a" => ProtocolVersion::modern(74),
|
||||
"15w38b" => ProtocolVersion::modern(73),
|
||||
"15w38a" => ProtocolVersion::modern(72),
|
||||
"15w37a" => ProtocolVersion::modern(71),
|
||||
"15w36d" => ProtocolVersion::modern(70),
|
||||
"15w36c" => ProtocolVersion::modern(69),
|
||||
"15w36b" => ProtocolVersion::modern(68),
|
||||
"15w36a" => ProtocolVersion::modern(67),
|
||||
"15w35e" => ProtocolVersion::modern(66),
|
||||
"15w35d" => ProtocolVersion::modern(65),
|
||||
"15w35c" => ProtocolVersion::modern(64),
|
||||
"15w35b" => ProtocolVersion::modern(63),
|
||||
"15w35a" => ProtocolVersion::modern(62),
|
||||
"15w34d" => ProtocolVersion::modern(61),
|
||||
"15w34c" => ProtocolVersion::modern(60),
|
||||
"15w34b" => ProtocolVersion::modern(59),
|
||||
"15w34a" => ProtocolVersion::modern(58),
|
||||
"15w33c" => ProtocolVersion::modern(57),
|
||||
"15w33b" => ProtocolVersion::modern(56),
|
||||
"15w33a" => ProtocolVersion::modern(55),
|
||||
"15w32c" => ProtocolVersion::modern(54),
|
||||
"15w32b" => ProtocolVersion::modern(53),
|
||||
"15w32a" => ProtocolVersion::modern(52),
|
||||
"15w31c" => ProtocolVersion::modern(51),
|
||||
"15w31b" => ProtocolVersion::modern(50),
|
||||
"15w31a" => ProtocolVersion::modern(49),
|
||||
"1.8.9" => ProtocolVersion::modern(47),
|
||||
"1.8.8" => ProtocolVersion::modern(47),
|
||||
"1.8.7" => ProtocolVersion::modern(47),
|
||||
"1.8.6" => ProtocolVersion::modern(47),
|
||||
"1.8.5" => ProtocolVersion::modern(47),
|
||||
"1.8.4" => ProtocolVersion::modern(47),
|
||||
"1.8.3" => ProtocolVersion::modern(47),
|
||||
"1.8.2" => ProtocolVersion::modern(47),
|
||||
"1.8.2-pre7" => ProtocolVersion::modern(47),
|
||||
"1.8.2-pre6" => ProtocolVersion::modern(47),
|
||||
"1.8.2-pre5" => ProtocolVersion::modern(47),
|
||||
"1.8.2-pre4" => ProtocolVersion::modern(47),
|
||||
"1.8.2-pre3" => ProtocolVersion::modern(47),
|
||||
"1.8.2-pre2" => ProtocolVersion::modern(47),
|
||||
"1.8.2-pre1" => ProtocolVersion::modern(47),
|
||||
"1.8.1" => ProtocolVersion::modern(47),
|
||||
"1.8.1-pre5" => ProtocolVersion::modern(47),
|
||||
"1.8.1-pre4" => ProtocolVersion::modern(47),
|
||||
"1.8.1-pre3" => ProtocolVersion::modern(47),
|
||||
"1.8.1-pre2" => ProtocolVersion::modern(47),
|
||||
"1.8.1-pre1" => ProtocolVersion::modern(47),
|
||||
"1.8" => ProtocolVersion::modern(47),
|
||||
"1.8-pre3" => ProtocolVersion::modern(46),
|
||||
"1.8-pre2" => ProtocolVersion::modern(45),
|
||||
"1.8-pre1" => ProtocolVersion::modern(44),
|
||||
"14w34d" => ProtocolVersion::modern(43),
|
||||
"14w34c" => ProtocolVersion::modern(42),
|
||||
"14w34b" => ProtocolVersion::modern(41),
|
||||
"14w34a" => ProtocolVersion::modern(40),
|
||||
"14w33c" => ProtocolVersion::modern(39),
|
||||
"14w33b" => ProtocolVersion::modern(38),
|
||||
"14w33a" => ProtocolVersion::modern(37),
|
||||
"14w32d" => ProtocolVersion::modern(36),
|
||||
"14w32c" => ProtocolVersion::modern(35),
|
||||
"14w32b" => ProtocolVersion::modern(34),
|
||||
"14w32a" => ProtocolVersion::modern(33),
|
||||
"14w31a" => ProtocolVersion::modern(32),
|
||||
"14w30c" => ProtocolVersion::modern(31),
|
||||
"14w30b" => ProtocolVersion::modern(30),
|
||||
"14w30a" => ProtocolVersion::modern(30),
|
||||
"14w29b" => ProtocolVersion::modern(29),
|
||||
"14w29a" => ProtocolVersion::modern(29),
|
||||
"14w28b" => ProtocolVersion::modern(28),
|
||||
"14w28a" => ProtocolVersion::modern(27),
|
||||
"14w27b" => ProtocolVersion::modern(26),
|
||||
"14w27a" => ProtocolVersion::modern(26),
|
||||
"14w26c" => ProtocolVersion::modern(25),
|
||||
"14w26b" => ProtocolVersion::modern(24),
|
||||
"14w26a" => ProtocolVersion::modern(23),
|
||||
"14w25b" => ProtocolVersion::modern(22),
|
||||
"14w25a" => ProtocolVersion::modern(21),
|
||||
"14w21b" => ProtocolVersion::modern(20),
|
||||
"14w21a" => ProtocolVersion::modern(19),
|
||||
"14w20b" => ProtocolVersion::modern(18),
|
||||
"14w20a" => ProtocolVersion::modern(18),
|
||||
"14w19a" => ProtocolVersion::modern(17),
|
||||
"14w18b" => ProtocolVersion::modern(16),
|
||||
"14w18a" => ProtocolVersion::modern(16),
|
||||
"14w17a" => ProtocolVersion::modern(15),
|
||||
"14w11b" => ProtocolVersion::modern(14),
|
||||
"14w11a" => ProtocolVersion::modern(14),
|
||||
"14w10c" => ProtocolVersion::modern(13),
|
||||
"14w10b" => ProtocolVersion::modern(13),
|
||||
"14w10a" => ProtocolVersion::modern(13),
|
||||
"14w08a" => ProtocolVersion::modern(12),
|
||||
"14w07a" => ProtocolVersion::modern(11),
|
||||
"14w06b" => ProtocolVersion::modern(10),
|
||||
"14w06a" => ProtocolVersion::modern(10),
|
||||
"14w05b" => ProtocolVersion::modern(9),
|
||||
"14w05a" => ProtocolVersion::modern(9),
|
||||
"14w04b" => ProtocolVersion::modern(8),
|
||||
"14w04a" => ProtocolVersion::modern(7),
|
||||
"14w03b" => ProtocolVersion::modern(6),
|
||||
"14w03a" => ProtocolVersion::modern(6),
|
||||
"14w02c" => ProtocolVersion::modern(5),
|
||||
"14w02b" => ProtocolVersion::modern(5),
|
||||
"14w02a" => ProtocolVersion::modern(5),
|
||||
"1.7.10" => ProtocolVersion::modern(5),
|
||||
"1.7.10-pre4" => ProtocolVersion::modern(5),
|
||||
"1.7.10-pre3" => ProtocolVersion::modern(5),
|
||||
"1.7.10-pre2" => ProtocolVersion::modern(5),
|
||||
"1.7.10-pre1" => ProtocolVersion::modern(5),
|
||||
"1.7.9" => ProtocolVersion::modern(5),
|
||||
"1.7.8" => ProtocolVersion::modern(5),
|
||||
"1.7.7" => ProtocolVersion::modern(5),
|
||||
"1.7.6" => ProtocolVersion::modern(5),
|
||||
"1.7.6-pre2" => ProtocolVersion::modern(5),
|
||||
"1.7.6-pre1" => ProtocolVersion::modern(5),
|
||||
"1.7.5" => ProtocolVersion::modern(4),
|
||||
"1.7.4" => ProtocolVersion::modern(4),
|
||||
"1.7.3" => ProtocolVersion::modern(4),
|
||||
"13w49a" => ProtocolVersion::modern(4),
|
||||
"13w48b" => ProtocolVersion::modern(4),
|
||||
"13w48a" => ProtocolVersion::modern(4),
|
||||
"13w47e" => ProtocolVersion::modern(4),
|
||||
"13w47d" => ProtocolVersion::modern(4),
|
||||
"13w47c" => ProtocolVersion::modern(4),
|
||||
"13w47b" => ProtocolVersion::modern(4),
|
||||
"13w47a" => ProtocolVersion::modern(4),
|
||||
"1.7.2" => ProtocolVersion::modern(4),
|
||||
"1.7.1" => ProtocolVersion::modern(3),
|
||||
"1.7" => ProtocolVersion::modern(3),
|
||||
"13w43a" => ProtocolVersion::modern(2),
|
||||
"13w42b" => ProtocolVersion::modern(1),
|
||||
"13w42a" => ProtocolVersion::modern(1),
|
||||
"13w41b" => ProtocolVersion::modern(0),
|
||||
"13w41a" => ProtocolVersion::modern(0),
|
||||
"13w39b" => ProtocolVersion::legacy(80),
|
||||
"13w39a" => ProtocolVersion::legacy(80),
|
||||
"13w38c" => ProtocolVersion::legacy(79),
|
||||
"13w38b" => ProtocolVersion::legacy(79),
|
||||
"13w38a" => ProtocolVersion::legacy(79),
|
||||
"1.6.4" => ProtocolVersion::legacy(78),
|
||||
"1.6.3" => ProtocolVersion::legacy(77),
|
||||
"13w37b" => ProtocolVersion::legacy(76),
|
||||
"13w37a" => ProtocolVersion::legacy(76),
|
||||
"13w36b" => ProtocolVersion::legacy(75),
|
||||
"13w36a" => ProtocolVersion::legacy(75),
|
||||
"1.6.2" => ProtocolVersion::legacy(74),
|
||||
"1.6.1" => ProtocolVersion::legacy(73),
|
||||
"1.6" => ProtocolVersion::legacy(72),
|
||||
"13w26a" => ProtocolVersion::legacy(72),
|
||||
"13w25c" => ProtocolVersion::legacy(71),
|
||||
"13w25b" => ProtocolVersion::legacy(71),
|
||||
"13w25a" => ProtocolVersion::legacy(71),
|
||||
"13w24b" => ProtocolVersion::legacy(70),
|
||||
"13w24a" => ProtocolVersion::legacy(69),
|
||||
"13w23b" => ProtocolVersion::legacy(68),
|
||||
"13w23a" => ProtocolVersion::legacy(67),
|
||||
"13w22a" => ProtocolVersion::legacy(67),
|
||||
"13w21b" => ProtocolVersion::legacy(67),
|
||||
"13w21a" => ProtocolVersion::legacy(67),
|
||||
"13w19a" => ProtocolVersion::legacy(66),
|
||||
"13w18c" => ProtocolVersion::legacy(65),
|
||||
"13w18b" => ProtocolVersion::legacy(65),
|
||||
"13w18a" => ProtocolVersion::legacy(65),
|
||||
"13w17a" => ProtocolVersion::legacy(64),
|
||||
"13w16b" => ProtocolVersion::legacy(63),
|
||||
"13w16a" => ProtocolVersion::legacy(62),
|
||||
"1.5.2" => ProtocolVersion::legacy(61),
|
||||
"1.5.1" => ProtocolVersion::legacy(60),
|
||||
"13w12~" => ProtocolVersion::legacy(60),
|
||||
"13w11a" => ProtocolVersion::legacy(60),
|
||||
"1.5" => ProtocolVersion::legacy(60),
|
||||
"13w10b" => ProtocolVersion::legacy(60),
|
||||
"13w10a" => ProtocolVersion::legacy(60),
|
||||
"13w09c" => ProtocolVersion::legacy(60),
|
||||
"13w09b" => ProtocolVersion::legacy(59),
|
||||
"13w09a" => ProtocolVersion::legacy(59),
|
||||
"13w07a" => ProtocolVersion::legacy(58),
|
||||
"13w06a" => ProtocolVersion::legacy(58),
|
||||
"13w05b" => ProtocolVersion::legacy(56),
|
||||
"13w05a" => ProtocolVersion::legacy(56),
|
||||
"13w04a" => ProtocolVersion::legacy(55),
|
||||
"13w03a" => ProtocolVersion::legacy(54),
|
||||
"13w02b" => ProtocolVersion::legacy(53),
|
||||
"13w02a" => ProtocolVersion::legacy(53),
|
||||
"13w01b" => ProtocolVersion::legacy(52),
|
||||
"13w01a" => ProtocolVersion::legacy(52),
|
||||
"1.4.7" => ProtocolVersion::legacy(51),
|
||||
"1.4.6" => ProtocolVersion::legacy(51),
|
||||
"12w50b" => ProtocolVersion::legacy(51),
|
||||
"12w50a" => ProtocolVersion::legacy(51),
|
||||
"12w49a" => ProtocolVersion::legacy(50),
|
||||
"1.4.5" => ProtocolVersion::legacy(49),
|
||||
"1.4.4" => ProtocolVersion::legacy(49),
|
||||
"1.4.3" => ProtocolVersion::legacy(48),
|
||||
"1.4.2" => ProtocolVersion::legacy(47),
|
||||
"1.4.1" => ProtocolVersion::legacy(47),
|
||||
"1.4" => ProtocolVersion::legacy(47),
|
||||
"12w42b" => ProtocolVersion::legacy(47),
|
||||
"12w42a" => ProtocolVersion::legacy(46),
|
||||
"12w41b" => ProtocolVersion::legacy(46),
|
||||
"12w41a" => ProtocolVersion::legacy(46),
|
||||
"12w40b" => ProtocolVersion::legacy(45),
|
||||
"12w40a" => ProtocolVersion::legacy(44),
|
||||
"12w39b" => ProtocolVersion::legacy(43),
|
||||
"12w39a" => ProtocolVersion::legacy(43),
|
||||
"12w38b" => ProtocolVersion::legacy(43),
|
||||
"12w38a" => ProtocolVersion::legacy(43),
|
||||
"12w37a" => ProtocolVersion::legacy(42),
|
||||
"12w36a" => ProtocolVersion::legacy(42),
|
||||
"12w34b" => ProtocolVersion::legacy(42),
|
||||
"12w34a" => ProtocolVersion::legacy(41),
|
||||
"12w32a" => ProtocolVersion::legacy(40),
|
||||
"1.3.2" => ProtocolVersion::legacy(39),
|
||||
"1.3.1" => ProtocolVersion::legacy(39),
|
||||
"1.3" => ProtocolVersion::legacy(39),
|
||||
"12w30e" => ProtocolVersion::legacy(39),
|
||||
"12w30d" => ProtocolVersion::legacy(39),
|
||||
"12w30c" => ProtocolVersion::legacy(39),
|
||||
"12w30b" => ProtocolVersion::legacy(38),
|
||||
"12w30a" => ProtocolVersion::legacy(38),
|
||||
"12w27a" => ProtocolVersion::legacy(38),
|
||||
"12w26a" => ProtocolVersion::legacy(37),
|
||||
"12w25a" => ProtocolVersion::legacy(37),
|
||||
"12w24a" => ProtocolVersion::legacy(36),
|
||||
"12w23b" => ProtocolVersion::legacy(35),
|
||||
"12w23a" => ProtocolVersion::legacy(35),
|
||||
"12w22a" => ProtocolVersion::legacy(34),
|
||||
"12w21b" => ProtocolVersion::legacy(33),
|
||||
"12w21a" => ProtocolVersion::legacy(33),
|
||||
"12w19a" => ProtocolVersion::legacy(32),
|
||||
"12w18a" => ProtocolVersion::legacy(32),
|
||||
"12w17a" => ProtocolVersion::legacy(31),
|
||||
"12w16a" => ProtocolVersion::legacy(30),
|
||||
"12w15a" => ProtocolVersion::legacy(29),
|
||||
"1.2.5" => ProtocolVersion::legacy(29),
|
||||
"1.2.4" => ProtocolVersion::legacy(29),
|
||||
"1.2.3" => ProtocolVersion::legacy(28),
|
||||
"1.2.2" => ProtocolVersion::legacy(28),
|
||||
"1.2.1" => ProtocolVersion::legacy(28),
|
||||
"1.2" => ProtocolVersion::legacy(28),
|
||||
"12w08a" => ProtocolVersion::legacy(28),
|
||||
"12w07b" => ProtocolVersion::legacy(27),
|
||||
"12w07a" => ProtocolVersion::legacy(27),
|
||||
"12w06a" => ProtocolVersion::legacy(25),
|
||||
"12w05b" => ProtocolVersion::legacy(24),
|
||||
"12w05a" => ProtocolVersion::legacy(24),
|
||||
"12w04a" => ProtocolVersion::legacy(24),
|
||||
"12w03a" => ProtocolVersion::legacy(24),
|
||||
"1.1" => ProtocolVersion::legacy(23),
|
||||
"12w01a" => ProtocolVersion::legacy(23),
|
||||
"11w50a" => ProtocolVersion::legacy(22),
|
||||
"11w49a" => ProtocolVersion::legacy(22),
|
||||
"11w48a" => ProtocolVersion::legacy(22),
|
||||
"11w47a" => ProtocolVersion::legacy(22),
|
||||
"1.0.1" => ProtocolVersion::legacy(22),
|
||||
"1.0.0" => ProtocolVersion::legacy(22),
|
||||
"1.0.0-rc2-1" => ProtocolVersion::legacy(22),
|
||||
"1.0.0-rc2-2" => ProtocolVersion::legacy(22),
|
||||
"1.0.0-rc2-3" => ProtocolVersion::legacy(22),
|
||||
"1.0.0-rc1" => ProtocolVersion::legacy(22),
|
||||
"b1.9-pre6" => ProtocolVersion::legacy(22),
|
||||
"b1.9-pre5" => ProtocolVersion::legacy(21),
|
||||
"b1.9-pre4" => ProtocolVersion::legacy(20),
|
||||
"b1.9-pre3" => ProtocolVersion::legacy(19),
|
||||
"b1.9-pre2" => ProtocolVersion::legacy(19),
|
||||
"b1.9-pre1" => ProtocolVersion::legacy(18),
|
||||
"b1.8.1" => ProtocolVersion::legacy(17),
|
||||
"b1.8" => ProtocolVersion::legacy(17),
|
||||
"b1.8-pre2" => ProtocolVersion::legacy(16),
|
||||
"b1.8-pre1-1" => ProtocolVersion::legacy(15),
|
||||
"b1.8-pre1-2" => ProtocolVersion::legacy(15),
|
||||
};
|
||||
@@ -1,5 +1,6 @@
|
||||
use crate::ErrorKind;
|
||||
use crate::error::Result;
|
||||
use crate::util::protocol_version::ProtocolVersion;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::value::RawValue;
|
||||
use std::time::Duration;
|
||||
@@ -42,16 +43,23 @@ pub struct ServerGameProfile {
|
||||
#[derive(Deserialize, Serialize, Debug, Clone)]
|
||||
pub struct ServerVersion {
|
||||
pub name: String,
|
||||
pub protocol: i32,
|
||||
pub protocol: u32,
|
||||
#[serde(skip_deserializing)]
|
||||
pub legacy: bool,
|
||||
}
|
||||
|
||||
pub async fn get_server_status(
|
||||
address: &impl ToSocketAddrs,
|
||||
original_address: (&str, u16),
|
||||
protocol_version: Option<i32>,
|
||||
protocol_version: Option<ProtocolVersion>,
|
||||
) -> Result<ServerStatus> {
|
||||
select! {
|
||||
res = modern::status(address, original_address, protocol_version) => res,
|
||||
res = async {
|
||||
match protocol_version {
|
||||
Some(ProtocolVersion { legacy: true, version }) => legacy::status(address, original_address, Some(version as u8)).await,
|
||||
protocol => modern::status(address, original_address, protocol.map(|v| v.version)).await,
|
||||
}
|
||||
} => res,
|
||||
_ = tokio::time::sleep(Duration::from_secs(30)) => Err(ErrorKind::OtherError(
|
||||
format!("Ping of {}:{} timed out", original_address.0, original_address.1)
|
||||
).into())
|
||||
@@ -68,7 +76,7 @@ mod modern {
|
||||
pub async fn status(
|
||||
address: &impl ToSocketAddrs,
|
||||
original_address: (&str, u16),
|
||||
protocol_version: Option<i32>,
|
||||
protocol_version: Option<u32>,
|
||||
) -> crate::Result<ServerStatus> {
|
||||
let mut stream = TcpStream::connect(address).await?;
|
||||
handshake(&mut stream, original_address, protocol_version).await?;
|
||||
@@ -80,10 +88,10 @@ mod modern {
|
||||
async fn handshake(
|
||||
stream: &mut TcpStream,
|
||||
original_address: (&str, u16),
|
||||
protocol_version: Option<i32>,
|
||||
protocol_version: Option<u32>,
|
||||
) -> crate::Result<()> {
|
||||
let (host, port) = original_address;
|
||||
let protocol_version = protocol_version.unwrap_or(-1);
|
||||
let protocol_version = protocol_version.map_or(-1, |x| x as i32);
|
||||
|
||||
const PACKET_ID: i32 = 0;
|
||||
const NEXT_STATE: i32 = 1;
|
||||
@@ -221,3 +229,95 @@ mod modern {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod legacy {
|
||||
use super::ServerStatus;
|
||||
use crate::worlds::{ServerPlayers, ServerVersion};
|
||||
use crate::{Error, ErrorKind};
|
||||
use serde_json::value::to_raw_value;
|
||||
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
||||
use tokio::net::{TcpStream, ToSocketAddrs};
|
||||
|
||||
pub async fn status(
|
||||
address: &impl ToSocketAddrs,
|
||||
original_address: (&str, u16),
|
||||
protocol_version: Option<u8>,
|
||||
) -> crate::Result<ServerStatus> {
|
||||
let protocol_version = protocol_version.unwrap_or(74);
|
||||
|
||||
let mut packet = vec![0xfe];
|
||||
if protocol_version >= 47 {
|
||||
packet.push(0x01);
|
||||
}
|
||||
if protocol_version >= 73 {
|
||||
packet.push(0xfa);
|
||||
write_legacy(&mut packet, "MC|PingHost");
|
||||
|
||||
let (host, port) = original_address;
|
||||
let len_index = packet.len();
|
||||
packet.push(protocol_version);
|
||||
write_legacy(&mut packet, host);
|
||||
packet.extend_from_slice(&(port as u32).to_be_bytes());
|
||||
packet.splice(
|
||||
len_index..len_index,
|
||||
((packet.len() - len_index) as u16).to_be_bytes(),
|
||||
);
|
||||
}
|
||||
|
||||
let mut stream = TcpStream::connect(address).await?;
|
||||
stream.write_all(&packet).await?;
|
||||
stream.flush().await?;
|
||||
|
||||
let packet_id = stream.read_u8().await?;
|
||||
if packet_id != 0xff {
|
||||
return Err(Error::from(ErrorKind::InputError(
|
||||
"Unexpected legacy status response".to_string(),
|
||||
)));
|
||||
}
|
||||
|
||||
let data_length = stream.read_u16().await?;
|
||||
let mut data = vec![0u8; data_length as usize * 2];
|
||||
stream.read_exact(&mut data).await?;
|
||||
|
||||
drop(stream);
|
||||
|
||||
let data = String::from_utf16_lossy(
|
||||
&data
|
||||
.chunks_exact(2)
|
||||
.map(|a| u16::from_be_bytes([a[0], a[1]]))
|
||||
.collect::<Vec<u16>>(),
|
||||
);
|
||||
let mut ancient_server = false;
|
||||
let mut parts = data.split('\0');
|
||||
if parts.next() != Some("§1") {
|
||||
ancient_server = true;
|
||||
parts = data.split('§');
|
||||
}
|
||||
|
||||
Ok(ServerStatus {
|
||||
version: (!ancient_server).then(|| ServerVersion {
|
||||
protocol: parts
|
||||
.next()
|
||||
.and_then(|x| x.parse().ok())
|
||||
.unwrap_or(0),
|
||||
name: parts.next().unwrap_or("").to_owned(),
|
||||
legacy: true,
|
||||
}),
|
||||
description: parts.next().and_then(|x| to_raw_value(x).ok()),
|
||||
players: Some(ServerPlayers {
|
||||
online: parts.next().and_then(|x| x.parse().ok()).unwrap_or(-1),
|
||||
max: parts.next().and_then(|x| x.parse().ok()).unwrap_or(-1),
|
||||
sample: vec![],
|
||||
}),
|
||||
favicon: None,
|
||||
enforces_secure_chat: false,
|
||||
ping: None,
|
||||
})
|
||||
}
|
||||
|
||||
fn write_legacy(out: &mut Vec<u8>, text: &str) {
|
||||
let encoded = text.encode_utf16().collect::<Vec<_>>();
|
||||
out.extend_from_slice(&(encoded.len() as u16).to_be_bytes());
|
||||
out.extend(encoded.into_iter().flat_map(u16::to_be_bytes));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user