mirror of
https://git.funtimes909.xyz/ServerSeekerV2/ServerSeekerV2.git
synced 2026-10-10 20:23:09 +08:00
Huge refactor for server response parsing (still WIP)
This commit is contained in:
+9
-6
@@ -16,18 +16,21 @@ use crate::ping::ping_server;
|
||||
async fn main() {
|
||||
// Handle config file
|
||||
let config_file: String = std::env::args().nth(1).unwrap_or("config.toml".to_string());
|
||||
let config: Config = load_config(config_file);
|
||||
let config: &Config = &load_config(config_file);
|
||||
|
||||
// Create database URL
|
||||
let database_url = format!("postgresql://{}:{}@{}/postgres",
|
||||
&config.database.user,
|
||||
&config.database.password,
|
||||
&config.database.url);
|
||||
|
||||
let mut conn: PgConnection = connect(&database_url);
|
||||
config.database.user,
|
||||
config.database.password,
|
||||
config.database.url);
|
||||
|
||||
// let address: &str = "192.168.1.220";
|
||||
let address: &str = "51.161.87.128";
|
||||
// let address: &str = "127.0.0.1";
|
||||
let port: u16 = 25565;
|
||||
let server = ping_server(&address, &port).await;
|
||||
|
||||
if let Ok(server) = server {
|
||||
println!("Server {:?} responded! Version: {:?}, MOTD: {:?}, Chat Reports: {:?}", &address, &server.version, &server.motd, &server.prevents_reports);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -49,7 +49,7 @@ pub async fn ping_server(address: &str, port: &u16) -> Result<Server, Error> {
|
||||
]
|
||||
).to_string();
|
||||
|
||||
Ok(parse_response(response.as_str()))
|
||||
Ok(parse_response(response.as_str())?)
|
||||
}
|
||||
Err(_) => {
|
||||
Err(Error::new(ErrorKind::NetworkUnreachable, "Server did not respond."))
|
||||
|
||||
+74
-56
@@ -5,7 +5,7 @@ use serde_json::Value;
|
||||
|
||||
pub struct Server {
|
||||
pub version: Option<String>,
|
||||
pub protocol: Option<i32>,
|
||||
pub protocol: Option<i64>,
|
||||
pub icon: Option<String>,
|
||||
pub motd: Option<String>,
|
||||
pub prevents_reports: Option<bool>,
|
||||
@@ -25,88 +25,106 @@ pub struct Mod {
|
||||
pub mod_name: String,
|
||||
}
|
||||
|
||||
// None values should insert NULL into the database if no value is found
|
||||
impl Default for Server {
|
||||
fn default() -> Self {
|
||||
Server {
|
||||
version: None,
|
||||
protocol: None,
|
||||
icon: None,
|
||||
motd: None,
|
||||
prevents_reports: None,
|
||||
enforces_secure_chat: None,
|
||||
mods: None,
|
||||
players: None,
|
||||
// Lifetimes *should* solve this mess
|
||||
// Recursive JSON array/object parser
|
||||
fn parse_motd(motd: &Value, mut current_motd: String) -> Result<String, Error> {
|
||||
let mut current_motd = current_motd.clone();
|
||||
|
||||
if let Some(object) = motd.as_object() {
|
||||
if object.contains_key("color") {
|
||||
¤t_motd.push_str(&object["color"].to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Lifetimes will solve this mess
|
||||
fn parse_motd(motd: Value) -> Result<String, ErrorKind::InvalidData> {
|
||||
if motd.is_array() {
|
||||
for value in motd.as_array() {
|
||||
// Recursion
|
||||
if value.is_object() || value.is_array() {
|
||||
parse_motd(value.clone())?;
|
||||
} else {}
|
||||
if object.contains_key("bold") {
|
||||
¤t_motd.push_str("§l");
|
||||
}
|
||||
} else {
|
||||
if let Some(object) = motd.as_object() {
|
||||
for value in object {
|
||||
// Recursion
|
||||
if value.is_object() || value.is_array() {
|
||||
parse_motd(value.clone())?;
|
||||
}
|
||||
|
||||
if let Some(color) = value.get("color") {}
|
||||
if object.contains_key("underlined") {
|
||||
¤t_motd.push_str("§n");
|
||||
}
|
||||
|
||||
if let Some(bold) = value.get("bold") {}
|
||||
|
||||
if let Some(text) = value.get("text") {}
|
||||
if object.contains_key("text") {
|
||||
if let Some(text) = object["text"].as_str() {
|
||||
current_motd.push_str(text);
|
||||
}
|
||||
}
|
||||
|
||||
if object.contains_key("extra") {
|
||||
match object.get("extra") {
|
||||
Some(extra) => parse_motd(extra, current_motd.clone())?,
|
||||
None => Err(Error::new(ErrorKind::InvalidData, "Extra array malformed"))?,
|
||||
};
|
||||
}
|
||||
|
||||
Ok(current_motd)
|
||||
} else {
|
||||
if let Some(array) = motd.as_array() {
|
||||
for value in array {
|
||||
if value.is_object() || value.is_array() {
|
||||
parse_motd(value, current_motd.clone())?;
|
||||
} else {
|
||||
¤t_motd.push_str(value.as_str().unwrap());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(current_motd)
|
||||
}
|
||||
}
|
||||
|
||||
// I no longer care about trying to make the parsing code good,
|
||||
// there is no proper standard for how servers should respond so this is what you get
|
||||
pub fn parse_response(response: &str) -> Result<Server, Error> {
|
||||
let json = Value::from_str(response)?;
|
||||
let json = match Value::from_str(response) {
|
||||
Ok(json) => json,
|
||||
Err(err) => return Err(Error::new(ErrorKind::InvalidData, format!("{:?}", err)))
|
||||
};
|
||||
|
||||
let mut version = ();
|
||||
let mut protocol = ();
|
||||
let mut version: Option<String> = None;
|
||||
let mut protocol: Option<i64> = None;
|
||||
let mut icon: Option<String> = None;
|
||||
let mut motd: Option<String> = None;
|
||||
let mut prevents_reports: Option<bool> = None;
|
||||
let mut enforces_secure_chat: Option<bool> = None;
|
||||
let mut mods: Option<Vec<Mod>> = None;
|
||||
let mut players: Option<Vec<Player>> = None;
|
||||
|
||||
// TODO! I think I can make this all better
|
||||
if let Some(value) = json.get("version") {
|
||||
if let Some(name) = json.get("name") {
|
||||
version = version.as_str();
|
||||
if let Some(name) = value.get("name") {
|
||||
version = name.as_str().map(|s| s.to_string());
|
||||
}
|
||||
|
||||
if let Some(value) = json.get("protocol") {
|
||||
if let Some(value) = value.get("protocol") {
|
||||
protocol = value.as_i64()
|
||||
}
|
||||
}
|
||||
|
||||
let protocol = json["version"]["protocol"].as_i64();
|
||||
let icon = json["favicon"].to_string();
|
||||
let prevents_reports = json["preventsReports"].as_bool();
|
||||
let enforces_secure_chat = json["enforceSecure"].as_bool();
|
||||
|
||||
let motd: String;
|
||||
if json["description"].is_object() {
|
||||
// motd = parse_motd(json.get("description").clone(), &mut "".to_string());
|
||||
} else {
|
||||
motd = json.get("description").unwrap().to_string();
|
||||
if let Some(value) = json.get("icon") {
|
||||
icon = value.as_str().map(|s| s.to_string())
|
||||
}
|
||||
|
||||
println!("{}", motd);
|
||||
if let Some(value) = json.get("description") {
|
||||
motd = match parse_motd(value, "".to_string()) {
|
||||
Ok(description) => Some(description),
|
||||
Err(_) => None,
|
||||
};
|
||||
}
|
||||
|
||||
if let Some(value) = json.get("preventsChatReports") {
|
||||
prevents_reports = value.as_bool();
|
||||
}
|
||||
|
||||
if let Some(value) = json.get("enforceSecureChat") {
|
||||
enforces_secure_chat = value.as_bool();
|
||||
}
|
||||
|
||||
Ok(Server {
|
||||
version: None,
|
||||
protocol: None,
|
||||
icon: None,
|
||||
motd: None,
|
||||
prevents_reports: None,
|
||||
version,
|
||||
protocol,
|
||||
icon,
|
||||
motd,
|
||||
prevents_reports,
|
||||
enforces_secure_chat,
|
||||
mods: None,
|
||||
players: None,
|
||||
|
||||
Reference in New Issue
Block a user