Skip to content

Commit 2c7655a

Browse files
committed
perf(scanner)!: improve RAM performance from 16 bytes per IP to 4 bytes per IP
1 parent daa4d84 commit 2c7655a

2 files changed

Lines changed: 31 additions & 32 deletions

File tree

src/minecraft/utils.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::net::Ipv4Addr;
12
use serde_json::Value;
23
use tokio::io::AsyncReadExt;
34
use tokio::net::TcpStream;
@@ -40,19 +41,27 @@ pub trait MinecraftPacket {
4041

4142
pub struct Handshake {
4243
pub protocol: i32,
43-
pub address: String,
44+
pub address: Ipv4Addr,
4445
pub port: u16,
4546
pub next_state: i32,
4647
}
4748

4849
impl MinecraftPacket for Handshake {
4950
fn serialize(&self) -> Vec<u8> {
5051
let mut data = Vec::new();
52+
// Packet ID for handshake
5153
write_varint(0x00, &mut data);
54+
// Client protocol version
5255
write_varint(self.protocol, &mut data);
53-
write_varint(self.address.len() as i32, &mut data);
54-
data.extend_from_slice(self.address.as_bytes());
56+
// IP address
57+
let addr_str = self.address.to_string();
58+
let addr_bytes = addr_str.as_bytes();
59+
60+
write_varint(addr_bytes.len() as i32, &mut data);
61+
data.extend_from_slice(addr_bytes);
62+
// Port
5563
data.extend_from_slice(&self.port.to_be_bytes());
64+
// Next state
5665
write_varint(self.next_state, &mut data);
5766
prepend_length(data)
5867
}

src/scanning/file_scanner.rs

Lines changed: 19 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::net::Ipv4Addr;
2+
use std::str::FromStr;
13
use std::time::{Duration, Instant};
24
use colored_text::Colorize;
35
use futures::StreamExt;
@@ -9,8 +11,9 @@ use crate::config::MainConfig;
911
use crate::logger::DefaultColor;
1012
use crate::manager::TaskManager;
1113
use crate::scanning::scanner::{scan, ScanConfig};
12-
use crate::scanning::utils::{count_lines_fast, format_time, prettier_ping_result};
14+
use crate::scanning::utils::{count_lines_fast, format_time, prettier_ping_result, save_server};
1315

16+
// TODO: Make a live stream from the file to scanner, because its more RAM efficient
1417
pub async fn scan_file(path: String) {
1518
let _ = TaskManager::spawn("File Scanner", move |_cancel_token| async move {
1619
let file = match File::open(&path).await {
@@ -44,13 +47,18 @@ pub async fn scan_file(path: String) {
4447
// Skip comments
4548
if line.is_empty() || line.starts_with('#') { continue; }
4649

47-
// Parse port (IP[:PORT])
50+
// Parse port
51+
// Format: IP[:PORT]
4852
if let Some((ip, port_str)) = line.split_once(':') {
4953
if let Ok(port) = port_str.parse::<u16>() {
50-
targets.push((ip.to_string(), port));
54+
if let Ok(ipv4) = Ipv4Addr::from_str(ip) {
55+
targets.push((ipv4, port));
56+
}
5157
}
5258
} else {
53-
targets.push((line.to_string(), 25565));
59+
if let Ok(ipv4) = Ipv4Addr::from_str(line) {
60+
targets.push((ipv4, 25565)); // TODO: Add default ports
61+
}
5462
}
5563
}
5664

@@ -82,15 +90,15 @@ pub async fn scan_file(path: String) {
8290

8391
// Success
8492
if let Some(result) = maybe_result {
85-
let parsed = parse_server(result.ip.clone(), result.port, result.ping.clone(), result.query, result.join);
93+
let parsed = parse_server(result.ip, result.port, result.ping.clone(), result.query, result.join);
8694
found_batch.push(parsed);
8795
total_found_count += 1;
8896

8997
let mut output = String::new();
9098
output.push_str(
9199
&format!(
92100
"Found server: {}:{}\n",
93-
result.ip.hex(DefaultColor::Highlight.hex()),
101+
result.ip.to_string().hex(DefaultColor::Highlight.hex()),
94102
result.port.hex(DefaultColor::Highlight.hex())
95103
)
96104
);
@@ -132,41 +140,23 @@ pub async fn scan_file(path: String) {
132140
let elapsed_time = start_time.elapsed();
133141

134142
let pps = if elapsed_time.as_secs() > 0 {
135-
total_lines as f64 / elapsed_time.as_secs_f64()
143+
total_targets as f64 / elapsed_time.as_secs_f64()
136144
} else {
137145
0.0
138146
};
139147

148+
let percent = format!("{:.2}", (processed_count as f64 / total_targets as f64) * 100.0);
149+
140150
logger::info(
141151
format!(
142-
"File scan completed in {}. Found {} servers from {} targets. ({}{})",
152+
"File scan finished in {}. Found {} servers from {} targets. That is {}% ({}{})",
143153
format_time(elapsed_time.as_secs()).hex(DefaultColor::Highlight.hex()),
144154
total_found_count.hex(DefaultColor::Highlight.hex()),
145155
total_targets.hex(DefaultColor::Highlight.hex()),
156+
percent.hex(DefaultColor::Highlight.hex()),
146157
pps.round().hex(DefaultColor::Highlight.hex()),
147158
"pps".hex(DefaultColor::DarkHighlight.hex())
148159
)
149160
).send().await;
150161
}).await;
151-
}
152-
153-
pub async fn save_server(results: &Vec<(ServerInfo, ServerHistory)>) {
154-
let use_db = crate::USE_DATABASE.get().map(|a| **a).unwrap_or(true);
155-
156-
if !use_db {
157-
logger::debug("Skipping database insert...".into()).prefix("Database").send().await;
158-
return;
159-
}
160-
161-
match database::server::insert_servers(results).await {
162-
Err(e) => logger::error(
163-
format!("Failed to insert server to database: {}", e.hex(DefaultColor::Highlight.hex()))
164-
).prefix("File Scanner").send().await,
165-
Ok(_) => logger::success(
166-
format!(
167-
"Saved {} servers to the database!",
168-
results.len().hex(DefaultColor::Highlight.hex())
169-
)
170-
).prefix("File Scanner").send().await
171-
}
172162
}

0 commit comments

Comments
 (0)