Skip to content

Commit 31b5410

Browse files
authored
Revert "Unify server pinging implementations between app and backend (#5510)" (#5558)
1 parent 4792985 commit 31b5410

13 files changed

Lines changed: 223 additions & 244 deletions

File tree

Cargo.lock

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apps/labrinth/src/models/exp/minecraft.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -423,11 +423,11 @@ pub struct JavaServerPingData {
423423
/// Reported version protocol number of the server.
424424
pub version_protocol: i32,
425425
/// Description/MOTD of the server as shown in the server list.
426-
pub description: Option<serde_json::Value>,
426+
pub description: String,
427427
/// Number of players online at the time.
428-
pub players_online: Option<i32>,
428+
pub players_online: i32,
429429
/// Maximum number of players allowed on the server.
430-
pub players_max: Option<i32>,
430+
pub players_max: i32,
431431
}
432432

433433
component::relations! {

apps/labrinth/src/queue/server_ping.rs

Lines changed: 41 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use crate::models::exp;
66
use crate::models::ids::ProjectId;
77
use crate::models::projects::ProjectStatus;
88
use crate::{database::PgPool, util::error::Context};
9+
use async_minecraft_ping::ServerDescription;
910
use chrono::{TimeDelta, Utc};
1011
use clickhouse::{Client, Row};
1112
use serde::Serialize;
@@ -106,16 +107,11 @@ impl ServerPingQueue {
106107
project_id: project_id.0,
107108
address: ping.address.clone(),
108109
latency_ms: data.map(|d| d.latency.as_millis() as u32),
109-
description: data.and_then(|d| {
110-
d.description.as_ref().map(|d| {
111-
serde_json::to_string(&d)
112-
.expect("serialization should not fail")
113-
})
114-
}),
110+
description: data.map(|d| d.description.clone()),
115111
version_name: data.map(|d| d.version_name.clone()),
116112
version_protocol: data.map(|d| d.version_protocol),
117-
players_online: data.and_then(|d| d.players_online),
118-
players_max: data.and_then(|d| d.players_max),
113+
players_online: data.map(|d| d.players_online),
114+
players_max: data.map(|d| d.players_max),
119115
};
120116

121117
ch.write(&row)
@@ -260,27 +256,45 @@ pub async fn ping_server(
260256
.map(|duration| duration.min(default_duration))
261257
.unwrap_or(default_duration);
262258

263-
let conn = async_minecraft_ping::ConnectionConfig::build(address)
264-
.with_srv_lookup()
265-
.with_timeout(timeout)
266-
.connect()
267-
.await
268-
.wrap_err("failed to connect to server")?;
259+
let (address, port) = match address.rsplit_once(':') {
260+
Some((addr, port)) => {
261+
let port = port.parse::<u16>().wrap_err("invalid port number")?;
262+
(addr, port)
263+
}
264+
None => (address, 25565),
265+
};
266+
267+
let task = async move {
268+
let conn = async_minecraft_ping::ConnectionConfig::build(address)
269+
.with_port(port)
270+
.with_srv_lookup()
271+
.connect()
272+
.await
273+
.wrap_err("failed to connect to server")?;
269274

270-
let status = conn
271-
.status()
275+
let status = conn
276+
.status()
277+
.await
278+
.wrap_err("failed to get server status")?
279+
.status;
280+
281+
eyre::Ok(exp::minecraft::JavaServerPingData {
282+
latency: start.elapsed(),
283+
version_name: status.version.name,
284+
version_protocol: status.version.protocol,
285+
description: match status.description {
286+
ServerDescription::Plain(text)
287+
| ServerDescription::Object { text } => text,
288+
},
289+
players_online: status.players.online,
290+
players_max: status.players.max,
291+
})
292+
};
293+
294+
tokio::time::timeout(timeout, task)
272295
.await
273-
.wrap_err("failed to get server status")?
274-
.status;
275-
276-
eyre::Ok(exp::minecraft::JavaServerPingData {
277-
latency: start.elapsed(),
278-
version_name: status.version.name,
279-
version_protocol: status.version.protocol,
280-
description: status.description,
281-
players_online: status.players.online,
282-
players_max: status.players.max,
283-
})
296+
.map_err(eyre::Error::new)
297+
.flatten()
284298
}
285299

286300
#[derive(Debug, Row, Serialize, Clone)]

packages/app-lib/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ dunce = { workspace = true }
3737
either = { workspace = true }
3838
encoding_rs = { workspace = true }
3939
enumset = { workspace = true }
40-
eyre = { workspace = true }
4140
flate2 = { workspace = true }
4241
fs4 = { workspace = true, features = ["tokio"] }
4342
futures = { workspace = true, features = ["alloc", "async-await"] }

packages/app-lib/src/api/worlds.rs

Lines changed: 55 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,14 @@ use crate::state::attached_world_data::AttachedWorldData;
66
use crate::state::{
77
Profile, ProfileInstallStage, attached_world_data, server_join_log,
88
};
9-
use crate::util::io;
109
use crate::util::protocol_version::OLD_PROTOCOL_VERSIONS;
1110
pub use crate::util::protocol_version::ProtocolVersion;
1211
pub use crate::util::server_ping::{
1312
ServerGameProfile, ServerPlayers, ServerStatus, ServerVersion,
1413
};
15-
use crate::{Context, ErrorKind, Result, State, launcher};
14+
use crate::util::{io, server_ping};
15+
use crate::{Error, ErrorKind, Result, State, launcher};
16+
use async_minecraft_ping::ServerDescription;
1617
use async_walkdir::WalkDir;
1718
use async_zip::{Compression, ZipEntryBuilder};
1819
use chrono::{DateTime, Local, TimeZone, Utc};
@@ -909,54 +910,67 @@ pub async fn get_server_status(
909910
"Pinging {address} with protocol version {protocol_version:?}"
910911
);
911912

912-
// get_server_status_old(address, protocol_version).await
913-
get_server_status_new(address, protocol_version).await
914-
}
915-
916-
// async fn _get_server_status_old(
917-
// address: &str,
918-
// protocol_version: Option<ProtocolVersion>,
919-
// ) -> Result<ServerStatus> {
920-
// let (original_host, original_port) = parse_server_address(address)?;
921-
// let (host, port) =
922-
// resolve_server_address(original_host, original_port).await?;
923-
// tracing::debug!(
924-
// "Pinging {address} with protocol version {protocol_version:?}"
925-
// );
926-
// server_ping::get_server_status(
927-
// &(&host as &str, port),
928-
// (original_host, original_port),
929-
// protocol_version,
930-
// )
931-
// .await
932-
933-
async fn get_server_status_new(
913+
get_server_status_old(address, protocol_version).await
914+
// get_server_status_new(address, protocol_version).await
915+
}
916+
917+
async fn get_server_status_old(
918+
address: &str,
919+
protocol_version: Option<ProtocolVersion>,
920+
) -> Result<ServerStatus> {
921+
let (original_host, original_port) = parse_server_address(address)?;
922+
let (host, port) =
923+
resolve_server_address(original_host, original_port).await?;
924+
tracing::debug!(
925+
"Pinging {address} with protocol version {protocol_version:?}"
926+
);
927+
server_ping::get_server_status(
928+
&(&host as &str, port),
929+
(original_host, original_port),
930+
protocol_version,
931+
)
932+
.await
933+
}
934+
935+
async fn _get_server_status_new(
934936
address: &str,
935937
protocol_version: Option<ProtocolVersion>,
936938
) -> Result<ServerStatus> {
939+
let (address, port) = match address.rsplit_once(':') {
940+
Some((addr, port)) => {
941+
let port = port.parse::<u16>().map_err(|_err| {
942+
Error::from(ErrorKind::InputError("invalid port number".into()))
943+
})?;
944+
(addr, port)
945+
}
946+
None => (address, 25565),
947+
};
948+
937949
let mut builder = async_minecraft_ping::ConnectionConfig::build(address)
950+
.with_port(port)
938951
.with_srv_lookup();
939952

940953
if let Some(version) = protocol_version {
941954
builder = builder.with_protocol_version(version.version as usize)
942955
}
943956

944-
let conn = builder
945-
.connect()
946-
.await
947-
.wrap_err("failed to connect to server")?;
957+
let conn = builder.connect().await.map_err(|_err| {
958+
Error::from(ErrorKind::InputError("failed to connect to server".into()))
959+
})?;
948960

949-
let ping_conn = conn
950-
.status()
951-
.await
952-
.wrap_err("failed to get server status")?;
961+
let ping_conn = conn.status().await.map_err(|_err| {
962+
Error::from(ErrorKind::InputError("failed to get server status".into()))
963+
})?;
953964
let status = &ping_conn.status;
954-
let description = status.description.as_ref().map(|d| {
955-
let json =
956-
serde_json::to_string(d).expect("serializing should not fail");
957-
RawValue::from_string(json)
958-
.expect("converting to `RawValue` should not fail")
959-
});
965+
let description = match &status.description {
966+
ServerDescription::Plain(text) => {
967+
serde_json::value::to_raw_value(&text).ok()
968+
}
969+
ServerDescription::Object { text } => {
970+
// TODO: `text` always seems to be empty?
971+
RawValue::from_string(text.clone()).ok()
972+
}
973+
};
960974

961975
let players = ServerPlayers {
962976
max: status.players.max,
@@ -986,10 +1000,9 @@ async fn get_server_status_new(
9861000
let latency = {
9871001
let start = Instant::now();
9881002
let ping_magic = Utc::now().timestamp_millis().cast_unsigned();
989-
ping_conn
990-
.ping(ping_magic)
991-
.await
992-
.wrap_err("failed to do ping")?;
1003+
ping_conn.ping(ping_magic).await.map_err(|_err| {
1004+
Error::from(ErrorKind::InputError("failed to do ping".into()))
1005+
})?;
9931006
start.elapsed().as_millis() as i64
9941007
};
9951008

packages/app-lib/src/error.rs

Lines changed: 2 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
//! Theseus error type
2-
use std::{
3-
convert::Infallible,
4-
fmt::{Debug, Display},
5-
sync::Arc,
6-
};
2+
use std::sync::Arc;
73

84
use crate::{profile, util};
95
use data_url::DataUrlError;
@@ -224,41 +220,4 @@ impl ErrorKind {
224220
}
225221
}
226222

227-
pub type Result<T, E = Error> = core::result::Result<T, E>;
228-
229-
pub trait Context<T, E>: Sized {
230-
fn wrap_err_with<D>(self, f: impl FnOnce() -> D) -> Result<T, Error>
231-
where
232-
D: Send + Sync + Debug + Display + 'static;
233-
234-
#[inline]
235-
fn wrap_err<D>(self, msg: D) -> Result<T, Error>
236-
where
237-
D: Send + Sync + Debug + Display + 'static,
238-
{
239-
self.wrap_err_with(|| msg)
240-
}
241-
}
242-
243-
impl<T, E> Context<T, E> for Result<T, E>
244-
where
245-
Self: eyre::WrapErr<T, E>,
246-
{
247-
fn wrap_err_with<D>(self, f: impl FnOnce() -> D) -> Result<T, Error>
248-
where
249-
D: Send + Sync + Debug + Display + 'static,
250-
{
251-
eyre::WrapErr::wrap_err_with(self, f).map_err(|err| {
252-
Error::from(ErrorKind::OtherError(format!("{err:#}")))
253-
})
254-
}
255-
}
256-
257-
impl<T> Context<T, Infallible> for Option<T> {
258-
fn wrap_err_with<D>(self, f: impl FnOnce() -> D) -> Result<T, Error>
259-
where
260-
D: Send + Sync + Debug + Display + 'static,
261-
{
262-
self.ok_or_else(|| Error::from(ErrorKind::OtherError(f().to_string())))
263-
}
264-
}
223+
pub type Result<T> = core::result::Result<T, Error>;

packages/app-lib/src/util/io.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ macro_rules! get_resource_file {
318318
Ok(dir) => dir,
319319
Err(e) => {
320320
break 'get_resource_file $crate::Result::Err(
321-
$crate::Error::from($crate::util::io::IOError::from(e)),
321+
$crate::util::io::IOError::from(e).into(),
322322
);
323323
}
324324
};

packages/app-lib/src/util/server_ping/imp.rs renamed to packages/app-lib/src/util/server_ping.rs

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,53 @@
1+
use crate::ErrorKind;
2+
use crate::error::Result;
3+
use crate::util::protocol_version::ProtocolVersion;
4+
use serde::{Deserialize, Serialize};
5+
use serde_json::value::RawValue;
6+
use std::time::Duration;
7+
use tokio::net::ToSocketAddrs;
8+
use tokio::select;
9+
use url::Url;
10+
11+
#[derive(Deserialize, Serialize, Debug, Clone)]
12+
#[serde(rename_all = "camelCase")]
13+
pub struct ServerStatus {
14+
#[serde(skip_serializing_if = "Option::is_none")]
15+
pub description: Option<Box<RawValue>>,
16+
#[serde(skip_serializing_if = "Option::is_none")]
17+
pub players: Option<ServerPlayers>,
18+
#[serde(skip_serializing_if = "Option::is_none")]
19+
pub version: Option<ServerVersion>,
20+
#[serde(skip_serializing_if = "Option::is_none")]
21+
pub favicon: Option<Url>,
22+
#[serde(default)]
23+
pub enforces_secure_chat: bool,
24+
25+
#[serde(skip_serializing_if = "Option::is_none")]
26+
pub ping: Option<i64>,
27+
}
28+
29+
#[derive(Deserialize, Serialize, Debug, Clone)]
30+
pub struct ServerPlayers {
31+
pub max: i32,
32+
pub online: i32,
33+
#[serde(default)]
34+
pub sample: Vec<ServerGameProfile>,
35+
}
36+
37+
#[derive(Deserialize, Serialize, Debug, Clone)]
38+
pub struct ServerGameProfile {
39+
pub id: String,
40+
pub name: String,
41+
}
42+
43+
#[derive(Deserialize, Serialize, Debug, Clone)]
44+
pub struct ServerVersion {
45+
pub name: String,
46+
pub protocol: i32,
47+
#[serde(skip_deserializing)]
48+
pub legacy: bool,
49+
}
50+
151
pub async fn get_server_status(
252
address: &impl ToSocketAddrs,
353
original_address: (&str, u16),
@@ -255,8 +305,8 @@ mod legacy {
255305
}),
256306
description: parts.next().and_then(|x| to_raw_value(x).ok()),
257307
players: Some(ServerPlayers {
258-
online: parts.next().and_then(|x| x.parse().ok()),
259-
max: parts.next().and_then(|x| x.parse().ok()),
308+
online: parts.next().and_then(|x| x.parse().ok()).unwrap_or(-1),
309+
max: parts.next().and_then(|x| x.parse().ok()).unwrap_or(-1),
260310
sample: vec![],
261311
}),
262312
favicon: None,

0 commit comments

Comments
 (0)