added sending results to a leaderboard server and initialized server crate

This commit is contained in:
2026-03-24 18:39:05 +01:00
parent 60d9822b3f
commit b07154c5cf
9 changed files with 2149 additions and 10 deletions

1635
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -4,9 +4,15 @@ version = "0.1.0"
edition = "2024"
[dependencies]
chrono = { version = "0.4.44", features = ["serde"] }
clap = { version = "4.6.0", features = ["derive"] }
colored = "3.1.1"
cpal = {version = "0.17.3", default-features = false}
display-info = "0.5.9"
mac_address = "1.1.8"
num_cpus = "1.17.0"
reqwest = { version = "0.13.2", features = ["blocking", "json"] }
serde = { version = "1.0.228", features = ["derive"] }
serde_json = "1.0.149"
sysinfo = "0.38.4"
uuid = { version = "1.22.0", features = ["v4"] }

1
server/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/target

376
server/Cargo.lock generated Normal file
View File

@@ -0,0 +1,376 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "android_system_properties"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
dependencies = [
"libc",
]
[[package]]
name = "autocfg"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
[[package]]
name = "bumpalo"
version = "3.20.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb"
[[package]]
name = "cc"
version = "1.2.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a0dd1ca384932ff3641c8718a02769f1698e7563dc6974ffd03346116310423"
dependencies = [
"find-msvc-tools",
"shlex",
]
[[package]]
name = "cfg-if"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[package]]
name = "chrono"
version = "0.4.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0"
dependencies = [
"iana-time-zone",
"js-sys",
"num-traits",
"serde",
"wasm-bindgen",
"windows-link",
]
[[package]]
name = "core-foundation-sys"
version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
[[package]]
name = "find-msvc-tools"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
[[package]]
name = "iana-time-zone"
version = "0.1.65"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470"
dependencies = [
"android_system_properties",
"core-foundation-sys",
"iana-time-zone-haiku",
"js-sys",
"log",
"wasm-bindgen",
"windows-core",
]
[[package]]
name = "iana-time-zone-haiku"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
dependencies = [
"cc",
]
[[package]]
name = "itoa"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
[[package]]
name = "js-sys"
version = "0.3.91"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b49715b7073f385ba4bc528e5747d02e66cb39c6146efb66b781f131f0fb399c"
dependencies = [
"once_cell",
"wasm-bindgen",
]
[[package]]
name = "libc"
version = "0.2.183"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d"
[[package]]
name = "log"
version = "0.4.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
[[package]]
name = "memchr"
version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
[[package]]
name = "num-traits"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
]
[[package]]
name = "once_cell"
version = "1.21.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
[[package]]
name = "pin-project-lite"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
[[package]]
name = "proc-macro2"
version = "1.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rustversion"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
[[package]]
name = "serde"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
dependencies = [
"serde_core",
"serde_derive",
]
[[package]]
name = "serde_core"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.149"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86"
dependencies = [
"itoa",
"memchr",
"serde",
"serde_core",
"zmij",
]
[[package]]
name = "server"
version = "0.1.0"
dependencies = [
"chrono",
"serde",
"serde_json",
"tokio",
]
[[package]]
name = "shlex"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "syn"
version = "2.0.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "tokio"
version = "1.50.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "27ad5e34374e03cfffefc301becb44e9dc3c17584f414349ebe29ed26661822d"
dependencies = [
"pin-project-lite",
"tokio-macros",
]
[[package]]
name = "tokio-macros"
version = "2.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c55a2eff8b69ce66c84f85e1da1c233edc36ceb85a2058d11b0d6a3c7e7569c"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "unicode-ident"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
[[package]]
name = "wasm-bindgen"
version = "0.2.114"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6532f9a5c1ece3798cb1c2cfdba640b9b3ba884f5db45973a6f442510a87d38e"
dependencies = [
"cfg-if",
"once_cell",
"rustversion",
"wasm-bindgen-macro",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.114"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18a2d50fcf105fb33bb15f00e7a77b772945a2ee45dcf454961fd843e74c18e6"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.114"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03ce4caeaac547cdf713d280eda22a730824dd11e6b8c3ca9e42247b25c631e3"
dependencies = [
"bumpalo",
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.114"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75a326b8c223ee17883a4251907455a2431acc2791c98c26279376490c378c16"
dependencies = [
"unicode-ident",
]
[[package]]
name = "windows-core"
version = "0.62.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb"
dependencies = [
"windows-implement",
"windows-interface",
"windows-link",
"windows-result",
"windows-strings",
]
[[package]]
name = "windows-implement"
version = "0.60.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "windows-interface"
version = "0.59.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "windows-link"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
[[package]]
name = "windows-result"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5"
dependencies = [
"windows-link",
]
[[package]]
name = "windows-strings"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091"
dependencies = [
"windows-link",
]
[[package]]
name = "zmij"
version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"

10
server/Cargo.toml Normal file
View File

@@ -0,0 +1,10 @@
[package]
name = "server"
version = "0.1.0"
edition = "2024"
[dependencies]
chrono = { version = "0.4.44", features = ["serde"] }
serde = { version = "1.0.228", features = ["derive"] }
serde_json = "1.0.149"
tokio = { version = "1.50.0", features = ["rt-multi-thread", "macros"] }

3
server/src/main.rs Normal file
View File

@@ -0,0 +1,3 @@
fn main() {
println!("Hello, world!");
}

View File

@@ -1,4 +1,5 @@
use colored::Colorize;
use serde::Serialize;
use std::{
sync::{
Arc, Mutex,
@@ -13,6 +14,7 @@ use crate::vprintln;
// Factor determining how many times the calculation runs in the multi-threaded test.
pub const MULTI_THREAD_LOAD_FACTOR: usize = 32;
#[derive(Serialize)]
pub struct BenchmarkResults {
pub duration: Duration,
pub primes_found: u64,

View File

@@ -1,12 +1,22 @@
use std::{
collections::HashMap,
io::{self, Write},
};
use chrono::Utc;
use clap::Parser;
use colored::Colorize;
use mac_address::get_mac_address;
use serde::Serialize;
use sysinfo::System;
use slimes::{
application_header,
benchmark::{BenchmarkResults, run_benchmark_multithread, run_benchmark_singlethread},
slimes::get_all_slimes,
vprintln,
};
use uuid::Uuid;
#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
@@ -28,13 +38,56 @@ pub struct Cli {
#[arg(short, long)]
pub jobs: Option<usize>,
/// Don't send data to leaderboard server
#[arg(short, long)]
pub offline: bool,
/// Leaderboard server URL to send report to
#[arg(long, default_value = "https://alatreon.org/slimes")]
pub server_url: String,
/// Enable verbose output logging
#[arg(short, long)]
pub verbose: bool,
}
#[derive(Serialize)]
struct FullReport {
mac_address: String,
timestamp: String,
slimes: Option<HashMap<String, Vec<String>>>,
benchmark: Option<BenchmarkReport>,
}
#[derive(Serialize)]
struct BenchmarkReport {
prime_limit: u64,
logical_cores: usize,
single_thread: BenchmarkResults,
multi_thread: BenchmarkResults,
}
fn main() {
let cli = Cli::parse();
let mut report = FullReport {
mac_address: get_mac_address()
.ok()
.flatten()
.map(|m| m.to_string())
.unwrap_or_else(|| format!("unknown-mac#{}", Uuid::new_v4())),
timestamp: Utc::now().to_rfc3339(),
slimes: None,
benchmark: None,
};
vprintln!(
cli.verbose,
"Initialized report {} {}",
report.mac_address,
report.timestamp
);
let mut report_slimes = HashMap::new();
println!("{}", application_header().bright_blue());
@@ -45,9 +98,15 @@ fn main() {
sys.refresh_all();
for slime in slimes {
slime.print(&sys, cli.verbose);
let label = slime.label().to_string();
let values = slime.values(&sys, cli.verbose);
slime.print_from_values(&values);
report_slimes.insert(label, values);
}
println!();
report.slimes = Some(report_slimes);
}
if !cli.skip_benchmark {
@@ -81,6 +140,56 @@ fn main() {
"Parallel Scaling : {}",
scaling_color_formatter(format!("{:.2}x", multi_thread_speedup_ratio)).bold()
);
report.benchmark = Some(BenchmarkReport {
prime_limit: cli.prime_limit,
logical_cores: logical_core_count,
single_thread: singlethread_benchmark,
multi_thread: multithread_benchmark,
});
}
if !cli.offline {
let json_payload = serde_json::to_string_pretty(&report).unwrap();
vprintln!(cli.verbose, "Generated JSON report: {:?}", &json_payload);
println!();
if !confirm_upload() {
return;
}
send_to_server(&cli.server_url, &report);
}
}
fn confirm_upload() -> bool {
print!("Send data to leaderboard server? [Y/n] ");
io::stdout().flush().unwrap();
let mut input = String::new();
io::stdin()
.read_line(&mut input)
.expect("Failed to read line");
let input = input.trim().to_lowercase();
input.is_empty() || input.starts_with('y')
}
fn send_to_server(url: &str, report: &FullReport) {
let client = reqwest::blocking::Client::new();
match client.post(url).json(&report).send() {
Ok(resp) => {
if resp.status().is_success() {
println!("{}", "Successfully uploaded results!".green().bold());
} else {
eprintln!(
"{} Error sending to server: {}",
"Error:".red(),
resp.status()
);
}
}
Err(e) => eprintln!("{} Failed to connect: {}", "Error:".red(), e),
}
}

View File

@@ -24,6 +24,21 @@ pub trait Slime {
println!("{}", val.white());
}
}
fn print_from_values(&self, values: &Vec<String>) {
for (i, val) in values.iter().enumerate() {
if i == 0 {
print!(
"{} {:<10} ",
self.icon().color(self.color()),
format!("{}:", self.label()).bold().color(self.color())
);
} else {
print!(" {:<10} ", " ");
}
println!("{}", val.white());
}
}
}
pub fn get_all_slimes() -> Vec<Box<dyn Slime>> {