mirror of
https://git.funtimes909.xyz/ServerSeekerV2/ServerSeekerV2.git
synced 2026-10-11 18:08:14 +08:00
Initial work to update code to use new database format
This commit is contained in:
4 files changed
+61
-57
No files matched your search
Generated
+18
-1
@@ -7,7 +7,6 @@ name = "ServerSeekerV2-Rust"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"indicatif",
|
||||
"serde",
|
||||
@@ -677,6 +676,12 @@ dependencies = [
|
||||
"web-time",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ipnet"
|
||||
version = "2.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130"
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.15"
|
||||
@@ -1266,6 +1271,7 @@ dependencies = [
|
||||
"hashbrown",
|
||||
"hashlink",
|
||||
"indexmap",
|
||||
"ipnet",
|
||||
"log",
|
||||
"memchr",
|
||||
"once_cell",
|
||||
@@ -1279,6 +1285,7 @@ dependencies = [
|
||||
"tokio-stream",
|
||||
"tracing",
|
||||
"url",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1359,6 +1366,7 @@ dependencies = [
|
||||
"stringprep",
|
||||
"thiserror",
|
||||
"tracing",
|
||||
"uuid",
|
||||
"whoami",
|
||||
]
|
||||
|
||||
@@ -1382,6 +1390,7 @@ dependencies = [
|
||||
"hkdf",
|
||||
"hmac",
|
||||
"home",
|
||||
"ipnet",
|
||||
"itoa",
|
||||
"log",
|
||||
"md-5",
|
||||
@@ -1396,6 +1405,7 @@ dependencies = [
|
||||
"stringprep",
|
||||
"thiserror",
|
||||
"tracing",
|
||||
"uuid",
|
||||
"whoami",
|
||||
]
|
||||
|
||||
@@ -1421,6 +1431,7 @@ dependencies = [
|
||||
"thiserror",
|
||||
"tracing",
|
||||
"url",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1737,6 +1748,12 @@ version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "1.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "458f7a779bf54acc9f347480ac654f68407d3aab21269a6e3c9f922acd9e2da9"
|
||||
|
||||
[[package]]
|
||||
name = "valuable"
|
||||
version = "0.1.1"
|
||||
|
||||
+2
-2
@@ -13,9 +13,8 @@ toml = "0.8"
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
tracing = { version = "0.1", features = ["release_max_level_info"] }
|
||||
tracing-subscriber = "0.3"
|
||||
sqlx = { version = "0.8", features = ["postgres", "runtime-tokio"] }
|
||||
sqlx = { version = "0.8", features = ["postgres", "runtime-tokio", "ipnet", "uuid", "json"] }
|
||||
indicatif = { version = "0.17" }
|
||||
futures-core = "0.3"
|
||||
futures-util = "0.3"
|
||||
anyhow = "1.0.98"
|
||||
|
||||
@@ -23,3 +22,4 @@ anyhow = "1.0.98"
|
||||
strip = true
|
||||
lto = "fat"
|
||||
opt-level = 3
|
||||
codegen-units = 1
|
||||
+31
-46
@@ -1,11 +1,12 @@
|
||||
use crate::response::Server;
|
||||
use sqlx::postgres::PgRow;
|
||||
use sqlx::types::ipnet::IpNet;
|
||||
use sqlx::types::Uuid;
|
||||
use sqlx::{Error, PgConnection, Pool, Postgres};
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
use tracing::{debug, info};
|
||||
|
||||
pub async fn fetch_servers(pool: &Pool<Postgres>) -> Vec<PgRow> {
|
||||
sqlx::query("SELECT address FROM servers ORDER BY lastseen ASC")
|
||||
sqlx::query("SELECT address FROM servers ORDER BY last_seen ASC")
|
||||
.fetch_all(pool)
|
||||
.await
|
||||
.expect("failed to fetch servers")
|
||||
@@ -16,86 +17,70 @@ pub async fn update(
|
||||
(address, port): &(String, u16),
|
||||
transaction: &mut PgConnection,
|
||||
) -> Result<(), Error> {
|
||||
// Remove from database if server has opted out
|
||||
if server.check_opt_out() {
|
||||
sqlx::query("DELETE FROM servers WHERE address = $1")
|
||||
.bind(address)
|
||||
.execute(&mut *transaction)
|
||||
.await?;
|
||||
|
||||
info!("Removing {address} from database due to opt-out");
|
||||
return Ok(());
|
||||
}
|
||||
let (address, port) = (
|
||||
address.parse::<IpNet>().expect("Failed to parse address"),
|
||||
*port as i32,
|
||||
);
|
||||
|
||||
let timestamp = SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.expect("system time is before the unix epoch")
|
||||
.as_secs() as i32;
|
||||
|
||||
// TODO: Can't be used in the database yet
|
||||
// let server_type = server.get_type();
|
||||
|
||||
let description: String = match server.description {
|
||||
Some(description) => description.into(),
|
||||
None => {
|
||||
debug!("Server {address} failed while updating database: Missing MOTD");
|
||||
return Ok(());
|
||||
}
|
||||
};
|
||||
|
||||
// Update server
|
||||
sqlx::query(
|
||||
"UPDATE servers SET
|
||||
version = $1,
|
||||
protocol = $2,
|
||||
icon = $3,
|
||||
motd = $4,
|
||||
preventsreports = $5,
|
||||
enforcesecure = $6,
|
||||
lastseen = $7,
|
||||
onlineplayers = $8,
|
||||
maxplayers = $9
|
||||
description = $4,
|
||||
prevents_chat_reports = $5,
|
||||
enforces_secure_chat = $6,
|
||||
last_seen = $7,
|
||||
online_players = $8,
|
||||
max_players = $9
|
||||
WHERE address = $10
|
||||
AND port = $11",
|
||||
)
|
||||
.bind(address)
|
||||
.bind(port)
|
||||
.bind(server.version.name)
|
||||
.bind(server.version.protocol)
|
||||
.bind(server.favicon)
|
||||
.bind(description)
|
||||
.bind(server.description)
|
||||
.bind(server.prevents_reports)
|
||||
.bind(server.enforces_secure_chat)
|
||||
.bind(timestamp)
|
||||
.bind(server.players.online)
|
||||
.bind(server.players.max)
|
||||
.bind(address)
|
||||
.bind(*port as i64)
|
||||
.execute(&mut *transaction)
|
||||
.await?;
|
||||
|
||||
// Update players
|
||||
if let Some(sample) = server.players.sample {
|
||||
for player in sample {
|
||||
sqlx::query("INSERT INTO playerhistory (address, port, playeruuid, playername, firstseen, lastseen) VALUES ($1, $2, $3, $4, $5, $6)
|
||||
ON CONFLICT (address, port, playeruuid) DO UPDATE SET
|
||||
lastseen = EXCLUDED.lastseen,
|
||||
playername = EXCLUDED.playername")
|
||||
.bind(address)
|
||||
.bind(*port as i64)
|
||||
.bind(player.id)
|
||||
.bind(player.name)
|
||||
.bind(timestamp)
|
||||
.bind(timestamp)
|
||||
.execute(&mut *transaction)
|
||||
.await?;
|
||||
if let Ok(uuid) = Uuid::parse_str(&player.id) {
|
||||
sqlx::query("INSERT INTO players (address, port, uuid, name, first_seen, last_seen) VALUES ($1, $2, $3, $4, $5, $6)
|
||||
ON CONFLICT (address, port, uuid) DO UPDATE SET
|
||||
last_seen = EXCLUDED.last_seen")
|
||||
.bind(address)
|
||||
.bind(port)
|
||||
.bind(uuid)
|
||||
.bind(player.name)
|
||||
.bind(timestamp)
|
||||
.bind(timestamp)
|
||||
.execute(&mut *transaction)
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update mods
|
||||
if let Some(mods_sample) = server.forge_data {
|
||||
for mods in mods_sample.mods {
|
||||
sqlx::query("INSERT INTO mods (address, port, modid, modmarker) VALUES ($1, $2, $3, $4) ON CONFLICT (address, port, modid) DO NOTHING")
|
||||
sqlx::query("INSERT INTO mods (address, port, id, mod_marker) VALUES ($1, $2, $3, $4) ON CONFLICT (address, port, id) DO NOTHING")
|
||||
.bind(address)
|
||||
.bind(*port as i64)
|
||||
.bind(port)
|
||||
.bind(mods.id)
|
||||
.bind(mods.marker)
|
||||
.bind(timestamp)
|
||||
|
||||
+10
-8
@@ -1,7 +1,9 @@
|
||||
use crate::config::PlayerTracking;
|
||||
use serde::Deserialize;
|
||||
use serde_json::Value;
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, sqlx::Type)]
|
||||
#[sqlx(type_name = "software")]
|
||||
pub enum ServerType {
|
||||
Java,
|
||||
Neoforge,
|
||||
@@ -24,7 +26,7 @@ pub struct Server {
|
||||
pub version: Version,
|
||||
pub favicon: Option<String>,
|
||||
pub players: Players,
|
||||
pub description: Option<Description>,
|
||||
pub description: Option<Value>,
|
||||
#[serde(rename = "preventsChatReports")]
|
||||
pub prevents_reports: Option<bool>,
|
||||
#[serde(rename = "enforcesSecureChat")]
|
||||
@@ -126,12 +128,12 @@ impl Server {
|
||||
}
|
||||
|
||||
// Has the user opted out of scanning?
|
||||
pub fn check_opt_out(&self) -> bool {
|
||||
match &self.description {
|
||||
Some(description) => String::from(description.clone()).contains("§b§d§f§d§b"),
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
// pub fn check_opt_out(&self) -> bool {
|
||||
// match &self.description {
|
||||
// Some(description) => String::from(description.clone()).contains("§b§d§f§d§b"),
|
||||
// None => false,
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
impl Players {
|
||||
|
||||
Reference in new issue
Block a user