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);
}
}