Skip to content

Commit

Permalink
Version lister, Fix #3
Browse files Browse the repository at this point in the history
  • Loading branch information
Loudbooks committed Feb 4, 2024
1 parent c52e08d commit 5e91749
Show file tree
Hide file tree
Showing 13 changed files with 177 additions and 8 deletions.
1 change: 1 addition & 0 deletions src/downloader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub trait Installer: Sync {
fn custom_script(&self) -> bool;
fn version_required(&self) -> bool { true }

async fn get_versions(&self, client: Client) -> Vec<String>;
async fn startup_message(&self, string: String) -> Option<SocketAddrV4>;
async fn download(&self, client: Client, minecraft_version: Option<String>) -> Result<String, DownloadError>;
async fn build(&self, _java_path: String, _minecraft_version: Option<String>) {}
Expand Down
6 changes: 6 additions & 0 deletions src/downloaders/bungeecord.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ impl Installer for BungeeCord {
false
}

async fn get_versions(&self, client: reqwest::Client) -> Vec<String> {
let version = client.get("https://ci.md-5.net/job/BungeeCord/lastSuccessfulBuild/buildNumber").send().await.expect("Failed to get latest version for ").text();

vec![version.await.unwrap_or("".to_string())]
}

async fn startup_message(&self, string: String) -> Option<std::net::SocketAddrV4> {
basic_proxy_address_from_string(string).await
}
Expand Down
10 changes: 10 additions & 0 deletions src/downloaders/fabric.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,16 @@ impl Installer for Fabric {
false
}

async fn get_versions(&self, client: Client) -> Vec<String> {
let json: serde_json::Value = client.get("https://meta.fabricmc.net/v2/versions/game").send().await.expect("Failed to get latest version for Fabric").json().await.expect("Failed to get latest version for Fabric");

let versions: Vec<String> = json.as_array().map(|versions| {
versions.iter().map(|version| version["version"].as_str().unwrap().to_string()).collect()
}).unwrap_or_default();

versions
}

async fn startup_message(&self, string: String) -> Option<SocketAddrV4> {
basic_server_address_from_string(string).await
}
Expand Down
15 changes: 15 additions & 0 deletions src/downloaders/forge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,21 @@ impl Installer for Forge {
false
}

async fn get_versions(&self, client: Client) -> Vec<String> {
let url = "https://files.minecraftforge.net/maven/net/minecraftforge/forge/promotions_slim.json";
let response = client.get(url).send().await.expect("Failed to get latest version for Forge");
let json: Value = response.json().await.expect("Failed to get latest version for Forge");

let game_versions = json["promos"].as_object().expect("Invalid JSON format");

let versions: Vec<String> = game_versions
.iter()
.map(|(version, _)| version.to_string().replace("-latest", "").replace("-recommended", ""))
.collect();

versions
}

async fn startup_message(&self, string: String) -> Option<SocketAddrV4> {
basic_server_address_from_string(string).await
}
Expand Down
8 changes: 8 additions & 0 deletions src/downloaders/geyser.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@

use async_trait::async_trait;
use reqwest::Client;
use crate::downloader::{basic_server_address_from_string, download_file, Installer};
use crate::servertype::ServerType;
use crate::servertype::ServerType::Server;
Expand Down Expand Up @@ -28,6 +29,13 @@ impl Installer for Geyser {
false
}

async fn get_versions(&self, client: Client) -> Vec<String> {
let json: serde_json::Value = client.get("https://download.geysermc.org/v2/projects/geyser/versions/latest").send().await.expect("Failed to get latest version for Geyser").json().await.expect("Failed to get latest version for Geyser");
let version = json["version"].as_str().unwrap().to_string();

vec![version]
}

async fn startup_message(&self, string: String) -> Option<std::net::SocketAddrV4> {
basic_server_address_from_string(string).await
}
Expand Down
2 changes: 1 addition & 1 deletion src/downloaders/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ pub(crate) mod bungeecord;
pub(crate) mod velocity;
pub(crate) mod waterfall;
pub(crate) mod geyser;
pub(crate) mod purpur;
pub(crate) mod purpur;
18 changes: 17 additions & 1 deletion src/downloaders/neoforge.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::fs::File;
use std::io::Read;
use async_trait::async_trait;
use reqwest::Client;
use serde_json::Value;
use tokio::fs;
use xml2json_rs::JsonBuilder;
Expand Down Expand Up @@ -28,11 +29,26 @@ impl Installer for NeoForge {
true
}

async fn get_versions(&self, _client: Client) -> Vec<String> {
let mut versions: Vec<String> = vec![];

for version in get_version_array().await {
let array = version.as_str().unwrap().split('.').collect::<Vec<&str>>();
let full_string = format!("1.{}", array[0].to_string() + "." + array[1]);

if !versions.contains(&full_string) {
versions.push(full_string);
}
}

versions
}

async fn startup_message(&self, string: String) -> Option<std::net::SocketAddrV4> {
crate::downloader::basic_server_address_from_string(string).await
}

async fn download(&self, client: reqwest::Client, minecraft_version: Option<String>) -> Result<String, crate::downloaderror::DownloadError> {
async fn download(&self, client: Client, minecraft_version: Option<String>) -> Result<String, crate::downloaderror::DownloadError> {
let neo_version = get_neoforge_version(minecraft_version).await.expect("Failed to get latest NeoForge version");

println!("Using NeoForge version {}.", neo_version);
Expand Down
14 changes: 14 additions & 0 deletions src/downloaders/paper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,20 @@ impl Installer for Paper {
false
}

async fn get_versions(&self, client: Client) -> Vec<String> {
let json: serde_json::Value = client.get("https://papermc.io/api/v2/projects/paper").send().await.expect("Failed to get latest version for Paper").json().await.expect("Failed to get latest version for Paper");

let versions = json["versions"].as_array().unwrap();
let mut version_strings = Vec::new();

for version in versions {
let version_string = version.as_str().unwrap().to_string();
version_strings.push(version_string);
}

version_strings
}

async fn startup_message(&self, string: String) -> Option<SocketAddrV4> {
basic_server_address_from_string(string).await
}
Expand Down
14 changes: 14 additions & 0 deletions src/downloaders/purpur.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,20 @@ impl Installer for Purpur {
false
}

async fn get_versions(&self, client: Client) -> Vec<String> {
let json: serde_json::Value = client.get("https://api.purpurmc.org/v2/purpur/").send().await.expect("Failed to get latest version for Purpur").json().await.expect("Failed to get latest version for Purpur");

let versions = json["versions"].as_array().unwrap();
let mut version_strings = Vec::new();

for version in versions {
let version_string = version.as_str().unwrap().to_string();
version_strings.push(version_string);
}

version_strings
}

async fn startup_message(&self, string: String) -> Option<SocketAddrV4> {
basic_server_address_from_string(string).await
}
Expand Down
4 changes: 4 additions & 0 deletions src/downloaders/vanilla.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ impl Installer for Vanilla {
false
}

async fn get_versions(&self, _client: Client) -> Vec<String> {
vec!["All Versions".to_string()] // Literally all versions. This is a Vanilla server, after all.
}

async fn startup_message(&self, string: String) -> Option<SocketAddrV4> {
basic_server_address_from_string(string).await
}
Expand Down
8 changes: 8 additions & 0 deletions src/downloaders/velocity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@ impl Installer for Velocity {
false
}

async fn get_versions(&self, client: Client) -> Vec<String> {
let json: serde_json::Value = client.get("https://papermc.io/api/v2/projects/velocity").send().await.expect("Failed to get latest version for Velocity").json().await.expect("Failed to get latest version for Velocity");

let versions = json["versions"].as_array().unwrap().last();

vec![versions.unwrap().as_str().unwrap().to_string()]
}

async fn startup_message(&self, string: String) -> Option<SocketAddrV4> {
basic_proxy_address_from_string(string).await
}
Expand Down
14 changes: 14 additions & 0 deletions src/downloaders/waterfall.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,20 @@ impl Installer for Waterfall {
false
}

async fn get_versions(&self, client: Client) -> Vec<String> {
let json: serde_json::Value = client.get("https://papermc.io/api/v2/projects/waterfall").send().await.expect("Failed to get latest version for Waterfall").json().await.expect("Failed to get latest version for Waterfall");

let versions = json["versions"].as_array().unwrap();
let mut version_strings = Vec::new();

for version in versions {
let version_string = version.as_str().unwrap().to_string();
version_strings.push(version_string);
}

version_strings
}

async fn startup_message(&self, string: String) -> Option<SocketAddrV4> {
basic_server_address_from_string(string).await
}
Expand Down
71 changes: 65 additions & 6 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,19 +151,40 @@ async fn main() {

let client = Client::new();

println!("What kind of server do you want to run?");
println!("Servers:" );
let mut out_string: Vec<String> = vec![];

println!("Gathering server information...");

out_string.push("Servers:".to_string());
let server_downloaders = downloaders.iter().filter(|downloader| downloader.get_type() == Server).collect::<Vec<&Box<dyn Installer>>>();
for (mut index, downloader) in server_downloaders.iter().enumerate() {
let mut versions = downloader.get_versions(client.clone()).await;

if versions.len() > 20 {
versions = vec![format!("Too many versions, type {}V to list.", index + 1)];
}

index += 1;
println!(" {}. {} - {}", index, downloader.get_name(), downloader.get_description());
out_string.push(format!(" {}. {} - {} - [{}]", index, downloader.get_name(), downloader.get_description(), versions.join(", ")));
}

println!("Proxies:");
out_string.push("Proxies:".to_string());
let proxy_downloaders = downloaders.iter().filter(|downloader| downloader.get_type() == Proxy).collect::<Vec<&Box<dyn Installer>>>();
for (mut index, downloader) in proxy_downloaders.iter().enumerate() {
let mut versions = downloader.get_versions(client.clone()).await;

if versions.len() > 20 {
versions = vec![format!("Too many versions, type {}V to list.", index + 1)];
}

index += 1;
println!(" {}. {} - {}", index + server_downloaders.len(), downloader.get_name(), downloader.get_description());
out_string.push(format!(" {}. {} - {} - [{}]", index + server_downloaders.len(), downloader.get_name(), downloader.get_description(), versions.join(", ")));
}

println!("What kind of server do you want to run?");

for line in out_string {
println!("{}", line);
}

println!();
Expand All @@ -176,7 +197,45 @@ async fn main() {
Ok(value) => !(1..=total_types).contains(&value),
Err(_) => true,
} {
print!("Please enter a valid number: ");
if server_type.ends_with('V') || server_type.ends_with('v') {
let index = server_type.replace(['V', 'v'], "").parse::<usize>().expect("Failed to parse index");
let downloader = downloaders.get(index - 1).expect("Failed to get downloader");

let versions = downloader.get_versions(client.clone()).await;
let mut out_string: Vec<String> = vec![];

for version in versions {
let start = if version.contains('.') {
let version_string = version.split('.').collect::<Vec<&str>>().first().unwrap().to_string() + "." + version.split('.').collect::<Vec<&str>>().get(1).unwrap().split('-').collect::<Vec<&str>>().first().unwrap();
version_string
} else {
version.split('w').collect::<Vec<&str>>().first().unwrap().to_string()
};

if out_string.iter().any(|s| s.starts_with(start.as_str())) {
out_string = out_string.iter().map(|s| {
if s.starts_with(start.as_str()) {
format!("{}, {}", s, version)
} else {
s.to_string()
}
}).collect::<Vec<String>>();
} else {
out_string.push(version);
}
}

println!("Versions for {}:", downloader.get_name());
for version in out_string {
println!("{}", version);
println!();
}

print!("Enter the number of the server you want to run: (1-{}): ", downloaders.len());
} else {
print!("Please enter a valid number: ");
}

server_type = user_input();
}

Expand Down

0 comments on commit 5e91749

Please sign in to comment.