You've already forked AstralRinth
forked from didirus/AstralRinth
Fix old Minecraft versions not having playtime resolved for servers (#3871)
* Fix old Minecraft versions not having playtime resolved for servers * Revert and clean up get_server_worlds_in_profile a bit * Add a semaphore to resolve_server_address in general to apply to all DNS queries * Remove unused tokio-stream dependency from theseus
This commit is contained in:
@@ -26,6 +26,8 @@ use std::net::{Ipv4Addr, Ipv6Addr};
|
|||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::sync::LazyLock;
|
use std::sync::LazyLock;
|
||||||
use tokio::io::AsyncWriteExt;
|
use tokio::io::AsyncWriteExt;
|
||||||
|
use tokio::sync::Semaphore;
|
||||||
|
use tokio::task::JoinSet;
|
||||||
use tokio_util::compat::FuturesAsyncWriteCompatExt;
|
use tokio_util::compat::FuturesAsyncWriteCompatExt;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
@@ -394,25 +396,27 @@ async fn get_server_worlds_in_profile(
|
|||||||
.await
|
.await
|
||||||
.ok();
|
.ok();
|
||||||
|
|
||||||
|
let first_server_index = worlds.len();
|
||||||
for (index, server) in servers.into_iter().enumerate() {
|
for (index, server) in servers.into_iter().enumerate() {
|
||||||
if server.hidden {
|
if server.hidden {
|
||||||
// TODO: Figure out whether we want to hide or show direct connect servers
|
// TODO: Figure out whether we want to hide or show direct connect servers
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let icon = server.icon.and_then(|icon| {
|
|
||||||
Url::parse(&format!("data:image/png;base64,{icon}")).ok()
|
|
||||||
});
|
|
||||||
let last_played = join_log
|
|
||||||
.as_ref()
|
|
||||||
.and_then(|log| {
|
|
||||||
let address = parse_server_address(&server.ip).ok()?;
|
|
||||||
log.get(&(address.0.to_owned(), address.1))
|
|
||||||
})
|
|
||||||
.copied();
|
|
||||||
let world = World {
|
let world = World {
|
||||||
name: server.name,
|
name: server.name,
|
||||||
last_played,
|
last_played: join_log
|
||||||
icon: icon.map(Either::Right),
|
.as_ref()
|
||||||
|
.and_then(|log| {
|
||||||
|
let (host, port) = parse_server_address(&server.ip).ok()?;
|
||||||
|
log.get(&(host.to_owned(), port))
|
||||||
|
})
|
||||||
|
.copied(),
|
||||||
|
icon: server
|
||||||
|
.icon
|
||||||
|
.and_then(|icon| {
|
||||||
|
Url::parse(&format!("data:image/png;base64,{icon}")).ok()
|
||||||
|
})
|
||||||
|
.map(Either::Right),
|
||||||
display_status: DisplayStatus::Normal,
|
display_status: DisplayStatus::Normal,
|
||||||
details: WorldDetails::Server {
|
details: WorldDetails::Server {
|
||||||
index,
|
index,
|
||||||
@@ -423,6 +427,30 @@ async fn get_server_worlds_in_profile(
|
|||||||
worlds.push(world);
|
worlds.push(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(join_log) = join_log {
|
||||||
|
let mut futures = JoinSet::new();
|
||||||
|
for (index, world) in worlds.iter().enumerate().skip(first_server_index)
|
||||||
|
{
|
||||||
|
if world.last_played.is_some() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if let WorldDetails::Server { address, .. } = &world.details
|
||||||
|
&& let Ok((host, port)) = parse_server_address(address)
|
||||||
|
{
|
||||||
|
let host = host.to_owned();
|
||||||
|
futures.spawn(async move {
|
||||||
|
resolve_server_address(&host, port)
|
||||||
|
.await
|
||||||
|
.ok()
|
||||||
|
.map(|x| (index, x))
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (index, address) in futures.join_all().await.into_iter().flatten() {
|
||||||
|
worlds[index].last_played = join_log.get(&address).copied();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -943,9 +971,13 @@ async fn resolve_server_address(
|
|||||||
host: &str,
|
host: &str,
|
||||||
port: u16,
|
port: u16,
|
||||||
) -> Result<(String, u16)> {
|
) -> Result<(String, u16)> {
|
||||||
|
static SIMULTANEOUS_DNS_QUERIES: Semaphore = Semaphore::const_new(24);
|
||||||
|
|
||||||
if host.parse::<Ipv4Addr>().is_ok() || host.parse::<Ipv6Addr>().is_ok() {
|
if host.parse::<Ipv4Addr>().is_ok() || host.parse::<Ipv6Addr>().is_ok() {
|
||||||
return Ok((host.to_owned(), port));
|
return Ok((host.to_owned(), port));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let _permit = SIMULTANEOUS_DNS_QUERIES.acquire().await?;
|
||||||
let resolver = hickory_resolver::TokioResolver::builder_tokio()?.build();
|
let resolver = hickory_resolver::TokioResolver::builder_tokio()?.build();
|
||||||
Ok(
|
Ok(
|
||||||
match resolver.srv_lookup(format!("_minecraft._tcp.{host}")).await {
|
match resolver.srv_lookup(format!("_minecraft._tcp.{host}")).await {
|
||||||
|
|||||||
Reference in New Issue
Block a user