Skip to content

Commit

Permalink
Waterfall support
Browse files Browse the repository at this point in the history
  • Loading branch information
Loudbooks committed Feb 3, 2024
1 parent 52da967 commit caf0d9b
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 3 deletions.
1 change: 1 addition & 0 deletions src/downloader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub trait Installer: Sync {
fn get_description(&self) -> String;
fn get_type(&self) -> ServerType;
fn custom_script(&self) -> bool;
fn version_required(&self) -> bool { true }

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

fn version_required(&self) -> bool {
false
}

async fn startup_message(&self, string: String) -> Option<std::net::SocketAddrV4> {
basic_proxy_address_from_string(string).await
}
Expand Down
1 change: 1 addition & 0 deletions src/downloaders/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ pub(crate) mod forge;
pub(crate) mod neoforge;
pub(crate) mod bungeecord;
pub(crate) mod velocity;
pub(crate) mod waterfall;
4 changes: 4 additions & 0 deletions src/downloaders/velocity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ impl Installer for Velocity {
false
}

fn version_required(&self) -> bool {
false
}

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

use std::error::Error;
use std::net::SocketAddrV4;
use async_trait::async_trait;
use reqwest::Client;
use crate::downloader::{basic_server_address_from_string, download_file, Installer};
use crate::downloaderror::DownloadError;
use crate::servertype::ServerType;
use crate::servertype::ServerType::Proxy;

pub(crate) struct Waterfall {}

#[async_trait]
impl Installer for Waterfall {
fn get_name(&self) -> String {
"Waterfall".to_string()
}

fn get_description(&self) -> String {
"A proxy that supports Bungeecord plugins, by PaperMC".to_string()
}

fn get_type(&self) -> ServerType {
Proxy
}

fn custom_script(&self) -> bool {
false
}

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

async fn download(&self, client: Client, minecraft_version: Option<String>) -> Result<String, DownloadError> {
let waterfall_version = get_latest_waterfall_version(minecraft_version).await.expect("Failed to get latest waterfall version");
let latest_build = get_latest_build(&waterfall_version).await.expect("Failed to get latest waterfall build");

println!(
"Using Waterfall version {} with build {}.",
waterfall_version, latest_build
);

let url = format!(
"https://api.papermc.io/v2/projects/waterfall/versions/{}/builds/{}/downloads/waterfall-{}-{}.jar",
waterfall_version,
latest_build,
waterfall_version, latest_build
);

download_file(&client, &url, "./server.jar").await?;

Ok(waterfall_version)
}
}

async fn get_latest_waterfall_version(minecraft_version: Option<String>) -> Result<String, Box<dyn Error>> {
let url = "https://papermc.io/api/v2/projects/waterfall";
let response = reqwest::get(url).await?;
let json: serde_json::Value = response.json().await?;
let versions = json["versions"].as_array().ok_or("JSON is invalid!")?;

if minecraft_version.is_none() {
let waterfall_version = versions
.last()
.and_then(|v| v.as_str())
.ok_or("Version not found!")?;

Ok(waterfall_version.to_string())
} else {
let minecraft_version = minecraft_version.unwrap();
let waterfall_version = versions
.iter()
.filter_map(|version| {
let version = version.as_str()?;
if version.starts_with(&minecraft_version) {
Some(version)
} else {
None
}
})
.max()
.ok_or("Version not found!")?;

Ok(waterfall_version.to_string())
}
}

async fn get_latest_build(waterfall_version: &str) -> Result<String, Box<dyn Error>> {
let url = format!(
"https://api.papermc.io/v2/projects/waterfall/versions/{}/builds",
waterfall_version
);
let response = reqwest::get(&url).await?;
let json: serde_json::Value = response.json().await?;

let build = json["builds"]
.as_array()
.ok_or("JSON is invalid")?
.iter()
.filter_map(|build| {
let channel = build["channel"].as_str()?;
let build_number = build["build"].as_u64()?;
if channel == "default" {
Some(build_number)
} else {
None
}
})
.max()
.ok_or("No builds found")?;

Ok(build.to_string())
}
8 changes: 5 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ use crate::downloaders::neoforge::NeoForge;
use crate::downloaders::paper::Paper;
use crate::downloaders::vanilla::Vanilla;
use crate::downloaders::velocity::Velocity;
use crate::downloaders::waterfall::Waterfall;
use crate::os::OS;
use crate::servertype::ServerType::{Proxy, Server};

Expand All @@ -40,7 +41,8 @@ async fn main() {
Box::new(Forge {}),
Box::new(NeoForge {}),
Box::new(BungeeCord {}),
Box::new(Velocity {})
Box::new(Velocity {}),
Box::new(Waterfall {})
];

let is_arm = env::consts::ARCH.contains("arch64") || env::consts::ARCH.contains("arm");
Expand Down Expand Up @@ -161,7 +163,7 @@ async fn main() {
}

println!();
print!("Enter the number of the server you want to run: (1-6): ");
print!("Enter the number of the server you want to run: (1-{}): ", downloaders.len());

let mut server_type = user_input();
let total_types: i32 = downloaders.len() as i32;
Expand All @@ -180,7 +182,7 @@ async fn main() {
println!();
print!("What version of Minecraft do you want to run? Type latest for the latest version: ");

let minecraft_version = if server_object.get_type() == Server {
let minecraft_version = if server_object.version_required() {
let input = user_input();

if input == "latest" {
Expand Down

0 comments on commit caf0d9b

Please sign in to comment.