late-java-core 2.2.9

A Rust library for launching Minecraft Java Edition
// Funciones de utilidad adicionales

use crate::error::{Result, LateJavaCoreError};
use serde_json::Value;

/// Obtener ruta de librerías desde coordenadas Maven/Gradle
pub fn get_path_libraries(main: &str, native_string: Option<&str>, force_ext: Option<&str>) -> LibraryPath {
    let lib_split: Vec<&str> = main.split(':').collect();
    
    if lib_split.len() < 3 {
        return LibraryPath {
            path: main.to_string(),
            name: main.to_string(),
            version: "".to_string(),
        };
    }

    // Si hay un cuarto elemento, es típicamente un clasificador añadido a la versión
    let file_name = if lib_split.len() > 3 {
        format!("{}-{}", lib_split[2], lib_split[3])
    } else {
        lib_split[2].to_string()
    };

    // Reemplazar '@' en versiones si está presente (ej: "1.0@beta" => "1.0.beta")
    let final_file_name = if file_name.contains('@') {
        file_name.replace('@', ".")
    } else {
        format!("{}{}{}", file_name, native_string.unwrap_or(""), force_ext.unwrap_or(".jar"))
    };

    // Construir la ruta: "net.minecraftforge" => "net/minecraftforge"
    // artifact => "forge"
    // version => "1.19-41.0.63"
    let path_lib = format!("{}/{}/{}", 
        lib_split[0].replace('.', "/"), 
        lib_split[1], 
        lib_split[2].split('@').next().unwrap_or("")
    );

    LibraryPath {
        path: path_lib,
        name: format!("{}-{}", lib_split[1], final_file_name),
        version: lib_split[2].to_string(),
    }
}

#[derive(Debug, Clone)]
pub struct LibraryPath {
    pub path: String,
    pub name: String,
    pub version: String,
}

/// Obtener hash de archivo (versión simplificada)
pub async fn get_file_hash(file_path: &str) -> Result<String> {
    use sha1::{Sha1, Digest};
    
    let content = std::fs::read(file_path)?;
    let mut hasher = Sha1::new();
    hasher.update(&content);
    Ok(format!("{:x}", hasher.finalize()))
}

/// Verificar si una versión de Minecraft es antigua
pub fn is_old(json: &Value) -> bool {
    json.get("assets")
        .and_then(|assets| assets.as_str())
        .map(|assets| assets == "legacy" || assets == "pre-1.6")
        .unwrap_or(false)
}

/// Obtener metadatos de loader
pub fn get_loader_metadata(loader_type: &str) -> Option<LoaderMetadata> {
    match loader_type.to_lowercase().as_str() {
        "forge" => Some(LoaderMetadata {
            meta_data: "https://files.minecraftforge.net/net/minecraftforge/forge/maven-metadata.json".to_string(),
            meta: "https://files.minecraftforge.net/net/minecraftforge/forge/${build}/meta.json".to_string(),
            promotions: "https://files.minecraftforge.net/net/minecraftforge/forge/promotions_slim.json".to_string(),
            install: "https://maven.minecraftforge.net/net/minecraftforge/forge/${version}/forge-${version}-installer".to_string(),
            universal: "https://maven.minecraftforge.net/net/minecraftforge/forge/${version}/forge-${version}-universal".to_string(),
            client: "https://maven.minecraftforge.net/net/minecraftforge/forge/${version}/forge-${version}-client".to_string(),
        }),
        "neoforge" => Some(LoaderMetadata {
            meta_data: "https://maven.neoforged.net/api/maven/versions/releases/net/neoforged/neoforge".to_string(),
            meta: "".to_string(),
            promotions: "".to_string(),
            install: "https://maven.neoforged.net/releases/net/neoforged/neoforge/${version}/neoforge-${version}-installer.jar".to_string(),
            universal: "".to_string(),
            client: "".to_string(),
        }),
        "fabric" => Some(LoaderMetadata {
            meta_data: "https://meta.fabricmc.net/v2/versions".to_string(),
            meta: "".to_string(),
            promotions: "".to_string(),
            install: "".to_string(),
            universal: "".to_string(),
            client: "".to_string(),
        }),
        "legacyfabric" => Some(LoaderMetadata {
            meta_data: "https://meta.legacyfabric.net/v2/versions".to_string(),
            meta: "".to_string(),
            promotions: "".to_string(),
            install: "".to_string(),
            universal: "".to_string(),
            client: "".to_string(),
        }),
        "quilt" => Some(LoaderMetadata {
            meta_data: "https://meta.quiltmc.org/v3/versions".to_string(),
            meta: "".to_string(),
            promotions: "".to_string(),
            install: "".to_string(),
            universal: "".to_string(),
            client: "".to_string(),
        }),
        _ => None,
    }
}

#[derive(Debug, Clone)]
pub struct LoaderMetadata {
    pub meta_data: String,
    pub meta: String,
    pub promotions: String,
    pub install: String,
    pub universal: String,
    pub client: String,
}

/// Espejos Maven para descargar librerías
pub const MIRRORS: &[&str] = &[
    "https://maven.minecraftforge.net",
    "https://maven.neoforged.net/releases",
    "https://maven.creeperhost.net",
    "https://libraries.minecraft.net",
    "https://repo1.maven.org/maven2",
];

/// Determinar si una librería debe ser omitida basada en sus reglas
pub fn should_skip_library(lib: &Value) -> bool {
    let rules = lib.get("rules").and_then(|r| r.as_array());
    if rules.is_none() {
        return false;
    }

    let rules = rules.unwrap();
    let current_os = std::env::consts::OS;
    let mojang_os = match current_os {
        "windows" => "windows",
        "macos" => "osx",
        "linux" => "linux",
        _ => current_os,
    };

    let mut should_skip = true;

    for rule in rules {
        if let Some(os_rule) = rule.get("os") {
            if let Some(os_name) = os_rule.get("name").and_then(|n| n.as_str()) {
                let action = rule.get("action").and_then(|a| a.as_str()).unwrap_or("allow");
                
                match action {
                    "allow" => {
                        if os_name == mojang_os {
                            should_skip = false;
                        }
                    }
                    "disallow" => {
                        if os_name == mojang_os {
                            should_skip = true;
                        }
                    }
                    _ => {}
                }
            }
        }
    }

    should_skip
}