summaryrefslogblamecommitdiff
path: root/src/util.rs
blob: 4e9f5a0242f398cd189c96fd5d02e85825f76bfd (plain) (tree)








































































































































                                                                                                                                                                   
use std::fs;

use serde::{Deserialize, Serialize};
use thirtyfour::{DesiredCapabilities, WebDriver, By};
use toml::Table;
use tracing::{info, debug};

use crate::errors::CliError;


#[derive(Deserialize, Serialize)]
pub struct PackConfig {
    pub pack: Pack,
    pub mods: Table,
}

#[derive(Deserialize, Serialize)]
pub struct Pack {
    pub name: String,
    pub pack_base_url: String,
    pub forge_url: String,
    pub game_version: String,
    pub java_args: String,
}

#[derive(Deserialize, Serialize)]
pub struct PackLock {
    pub global: LockGlobal,
    pub mod_versions: Table,
}

#[derive(Deserialize, Serialize)]
pub struct LockGlobal {
    pub pack_version: u16,
}

pub fn read_pack_config() -> Result<PackConfig, CliError> {
   let contents = fs::read_to_string("./pack.toml")?; 

   let res: PackConfig = toml::from_str(&contents)?;

   Ok(res)
}

pub fn read_pack_lock() -> Result<PackLock, CliError> {
   let contents = fs::read_to_string("./pack.lock")?; 

   let res = toml::from_str(&contents)?;

   Ok(res)
}

pub async fn find_updated_urls(urls: toml::map::Values<'_>, game_version: String) -> Result<Vec<String>, CliError> {
    let res: Vec<String> = Vec::new();
    debug!("Attempting to find updated URLs");
    debug!("Attempting to open webdriver");
    let caps = DesiredCapabilities::firefox();
    let driver = WebDriver::new("http://localhost:9515", caps).await?;
    driver.close_window().await?;
    debug!("Closed test window");

    for url in urls {
        find_url(url.to_string(), &game_version).await?;
    }

    Ok(res)
}

async fn find_url(homepage_url: String, game_version: &String) -> Result<String, CliError> {
    if homepage_url.contains("curseforge") {
        let caps = DesiredCapabilities::firefox();
        let driver = WebDriver::new("http://localhost:9515", caps).await?;

        find_cdn(&driver, homepage_url, game_version).await?;
        driver.close_window().await?;
    } else {

    }

    Ok(String::new())
}


#[derive(Debug)]
struct RowInfo {
    pub release_type: String,
    pub filename: String,
    pub cdn_id: String,
    pub game_version: (u16, u16, u16)
}

/**
 * Ugh...
 */
async fn find_cdn(driver: &WebDriver, homepage_url: String, game_version: &String) -> Result<String, CliError> {
    let mut page_index = 0;
    let best_row: RowInfo;
    loop {
        let mut url = homepage_url.clone();
        url.push_str(&format!("/files/all?page={}", page_index));
        driver.goto(&url).await?;

        let mod_vers = driver.find(By::ClassName("listing")).await?.find_all(By::XPath("tbody/tr")).await?;

        let mut rows: Vec<RowInfo> = Vec::new();
        for entry in mod_vers {
            let entry_cells = entry.find_all(By::Tag("td")).await?;
            let release_type = entry_cells[0].text().await?;
            let tmp0 = &entry_cells[1].find_all(By::Tag("a")).await?[0].text().await?;
            let initial_filename = urlencoding::encode(tmp0);
 
            let tmp = entry_cells[4].find(By::ClassName("mr-2")).await?.text().await?;
            let tmp2: Vec<&str> = tmp.split(".").collect();
            let version = (tmp2[0].clone().parse::<u16>()?, tmp2[1].clone().parse::<u16>()?, tmp2[2].parse::<u16>()?);

            let tmp3 = entry_cells[1].find(By::Tag("a")).await?.prop("href").await?.unwrap();
            let tmp4: Vec<&str> = tmp3.split("/").collect();
            let cdn_id = *tmp4.last().unwrap();

            if !(initial_filename.to_lowercase().contains("fabric")) || (initial_filename.to_lowercase().contains("forge")) {
                rows.push(RowInfo {
                    release_type,
                    cdn_id: cdn_id.to_string(),
                    game_version: version,
                    filename: initial_filename.to_string()
                })
            }
        }
        rows.sort_by_key(|k| k.game_version); 

        let tuple_game_version_tmp: Vec<&str> = game_version.split(".").collect();
        let tuple_game_version = (tuple_game_version_tmp[0].parse::<u16>()?, tuple_game_version_tmp[1].parse::<u16>()?, tuple_game_version_tmp[2].parse::<u16>()?);
        let best_rows: Vec<&RowInfo> = rows.iter().filter(|x| x.game_version > tuple_game_version).collect();

        info!("{:?}", best_rows);
    }
}