Files
rust-scan-mc/src/query.rs
T

168 lines
5.5 KiB
Rust
Raw Normal View History

2025-04-19 12:07:22 -06:00
use std::{net::IpAddr, str::FromStr};
use regex::Regex;
use crate::database::{QueryDataType, QueryType, split_nums};
2025-04-27 11:41:00 -06:00
fn try_parse_host(query: &str) -> Option<QueryDataType> {
if query.contains(":") {
let mut split = query.split(",");
let ip = IpAddr::from_str(split.nth(0).unwrap());
if let Some(port) = &split.nth(1) {
if let (Ok(ip), Ok(port)) = (ip, port.parse::<u16>()) {
return Some(QueryDataType::Host(ip, port));
}
}
}
2025-04-19 12:07:22 -06:00
if let Ok(ip) = IpAddr::from_str(&query) {
2025-04-27 11:41:00 -06:00
return Some(QueryDataType::Host(ip, 25565));
}
None
}
pub fn search(query: String) -> Result<Vec<QueryDataType>, Box<dyn std::error::Error>> {
if let Some(host) = try_parse_host(&query) {
return Ok(vec![host]);
2025-04-19 12:07:22 -06:00
}
let split = query.split(" ");
2025-04-27 11:41:00 -06:00
let delim = Regex::new("(?:!=|<=|>=|[=:+-><])")?;
2025-04-19 12:07:22 -06:00
let mut results = Vec::new();
for query in split {
2025-04-27 11:41:00 -06:00
if let Some(host) = try_parse_host(query) {
return Ok(vec![host]);
2025-04-19 12:07:22 -06:00
}
if let Some(m) = delim.find(query) {
2025-04-27 11:41:00 -06:00
let tag = query[0..m.start()].to_string().to_lowercase();
2025-04-19 12:07:22 -06:00
let delim = query[m.start()..m.end()].to_string();
let data = query[m.end()..query.len()].to_string();
2025-04-27 11:41:00 -06:00
fn get_equals_type_str(delim: &str) -> QueryType {
2025-04-19 12:07:22 -06:00
match delim {
2025-04-19 13:23:30 -06:00
":" | "+" => Some(QueryType::Includes),
"-" => Some(QueryType::NotIncludes),
2025-04-19 12:07:22 -06:00
"=" => Some(QueryType::Equals),
"!=" => Some(QueryType::NotEquals),
_ => None,
}
2025-04-27 11:41:00 -06:00
.expect(format!("Strings cannot be determined by \"{}\"", delim).as_str())
2025-04-19 12:07:22 -06:00
}
2025-04-27 11:41:00 -06:00
fn get_equals_type_num(delim: &str) -> QueryType {
match delim {
"=" => Some(QueryType::Equals),
"!=" => Some(QueryType::NotEquals),
">" => Some(QueryType::GreaterThan),
"<" => Some(QueryType::LessThan),
">=" => Some(QueryType::GreaterOrEqual),
"<=" => Some(QueryType::LessThanOrEqual),
_ => None,
}
.expect(format!("Nums cannot be determined by \"{}\"", delim).as_str())
}
(match tag.as_str() {
"version" => {
results.push(QueryDataType::Version(get_equals_type_str(&delim), data));
Ok(())
}
"protocol" => {
results.push(QueryDataType::Protocol(
get_equals_type_num(&delim),
data.parse::<u32>().expect("Error parsing protocol"),
));
Ok(())
}
2025-04-19 12:07:22 -06:00
2025-04-27 11:41:00 -06:00
"maxplayers" => {
results.push(QueryDataType::MaxPlayers(
get_equals_type_num(&delim),
data.parse::<u32>().expect("Error parsing max players"),
));
Ok(())
}
"onlineplayers" => {
results.push(QueryDataType::OnlinePlayers(
get_equals_type_num(&delim),
data.parse::<u32>().expect("Error parsing online players"),
));
Ok(())
}
"playerslist" => {
results.push(QueryDataType::PlayersList(
get_equals_type_str(&delim),
data,
));
Ok(())
}
"description" => {
results.push(QueryDataType::Description(
get_equals_type_str(&delim),
data,
));
Ok(())
}
"iconhash" => {
results.push(QueryDataType::IconHash(get_equals_type_str(&delim), data));
Ok(())
}
"modinfo" => {
results.push(QueryDataType::ModInfo(get_equals_type_str(&delim), data));
Ok(())
}
"forgedata" => {
results.push(QueryDataType::ForgeData(get_equals_type_str(&delim), data));
Ok(())
}
"securechat" => {
if !vec!["true".to_string(), "false".to_string(), "None".to_string()]
.contains(&data)
{
Err(())
} else {
results.push(QueryDataType::SecureChat(get_equals_type_str(&delim), data));
Ok(())
}
}
"previewschat" => {
if !vec!["true".to_string(), "false".to_string(), "None".to_string()]
.contains(&data)
{
Err(())
} else {
results.push(QueryDataType::PreviewsChat(
get_equals_type_str(&delim),
data,
));
2025-04-19 12:07:22 -06:00
2025-04-27 11:41:00 -06:00
Ok(())
2025-04-19 12:07:22 -06:00
}
}
2025-04-27 11:41:00 -06:00
_ => Err(()),
})
.expect(format!("Invalid Tag: \"{}\"", tag).as_str());
2025-04-19 12:07:22 -06:00
}
// (host, data) =
}
for result in &results {
println!("{:?}", result);
}
Ok(results)
}