PlugSnatcher/src-tauri/src/commands/plugin_commands.rs

371 lines
13 KiB
Rust

use tauri::{command, AppHandle};
use crate::models::repository::RepositorySource;
use crate::models::server::ServerType;
use crate::models::plugin::Plugin;
use crate::services::update_manager::{compare_plugin_versions, backup_plugin, replace_plugin};
/// Search for plugins in specified repositories
#[command]
pub async fn search_plugins(query: String, repositories: Vec<RepositorySource>) -> Result<Vec<crate::models::repository::RepositoryPlugin>, String> {
crate::lib_search_plugins_in_repositories(&query, repositories).await
}
/// Get plugin details from a repository
#[command]
pub async fn get_plugin_details(
plugin_id: String,
repository: RepositorySource,
server_type_str: Option<String>,
) -> Result<crate::models::repository::RepositoryPlugin, String> {
// Convert server_type_str to ServerType if provided
let server_type = if let Some(type_str) = server_type_str {
match type_str.as_str() {
"paper" => Some(crate::models::server::ServerType::Paper),
"spigot" => Some(crate::models::server::ServerType::Spigot),
"bukkit" => Some(crate::models::server::ServerType::Bukkit),
"velocity" => Some(crate::models::server::ServerType::Velocity),
"bungeecord" => Some(crate::models::server::ServerType::BungeeCord),
"waterfall" => Some(crate::models::server::ServerType::Waterfall),
"forge" => Some(crate::models::server::ServerType::Forge),
"fabric" => Some(crate::models::server::ServerType::Fabric),
_ => None,
}
} else {
None
};
crate::lib_get_plugin_details_from_repository(&plugin_id, repository, server_type.as_ref()).await
}
/// Download a plugin from a repository
#[command]
pub async fn download_plugin(
plugin_id: String,
version: String,
repository: String,
destination: String,
server_type_str: Option<String>
) -> Result<String, String> {
// Convert repository string to RepositorySource
let repo_source = match repository.to_lowercase().as_str() {
"hangarmc" => RepositorySource::HangarMC,
"spigotmc" => RepositorySource::SpigotMC,
"modrinth" => RepositorySource::Modrinth,
"github" => RepositorySource::GitHub,
"bukkitdev" => RepositorySource::BukkitDev,
_ => RepositorySource::Custom(repository.clone()),
};
// Convert server_type_str to ServerType if provided
let server_type = if let Some(type_str) = server_type_str {
match type_str.as_str() {
"paper" => Some(ServerType::Paper),
"spigot" => Some(ServerType::Spigot),
"bukkit" => Some(ServerType::Bukkit),
"velocity" => Some(ServerType::Velocity),
"bungeecord" => Some(ServerType::BungeeCord),
"waterfall" => Some(ServerType::Waterfall),
"forge" => Some(ServerType::Forge),
"fabric" => Some(ServerType::Fabric),
_ => None,
}
} else {
None
};
crate::lib_download_plugin_from_repository(&plugin_id, &version, repo_source, &destination, server_type.as_ref()).await
}
/// Update a plugin with a new version
#[command]
pub async fn update_plugin(
app_handle: AppHandle,
plugin_id: String,
version: String,
repository: String,
current_file_path: String,
server_type_str: Option<String>
) -> Result<String, String> {
// Convert repository string to RepositorySource
let repo_source = match repository.to_lowercase().as_str() {
"hangarmc" => RepositorySource::HangarMC,
"spigotmc" => RepositorySource::SpigotMC,
"modrinth" => RepositorySource::Modrinth,
"github" => RepositorySource::GitHub,
"bukkitdev" => RepositorySource::BukkitDev,
_ => RepositorySource::Custom(repository.clone()),
};
// Convert server_type_str to ServerInfo if provided
let server_info = if let Some(type_str) = server_type_str {
let server_type = match type_str.as_str() {
"paper" => ServerType::Paper,
"spigot" => ServerType::Spigot,
"bukkit" => ServerType::Bukkit,
"velocity" => ServerType::Velocity,
"bungeecord" => ServerType::BungeeCord,
"waterfall" => ServerType::Waterfall,
"forge" => ServerType::Forge,
"fabric" => ServerType::Fabric,
_ => ServerType::Unknown,
};
Some(crate::models::server::ServerInfo {
server_type,
minecraft_version: None,
plugins_directory: "".to_string(),
plugins_count: 0,
})
} else {
None
};
// Replace the plugin
replace_plugin(plugin_id, version, repo_source, current_file_path, server_info).await
}
/// Check for updates for multiple plugins
#[command]
pub async fn check_plugin_updates(
app_handle: AppHandle,
plugins: Vec<Plugin>,
repositories: Vec<String>,
server_path: String
) -> Result<Vec<Plugin>, String> {
// Convert repository strings to RepositorySource
let repos: Vec<RepositorySource> = repositories.into_iter()
.map(|repo| match repo.to_lowercase().as_str() {
"hangarmc" => RepositorySource::HangarMC,
"spigotmc" => RepositorySource::SpigotMC,
"modrinth" => RepositorySource::Modrinth,
"github" => RepositorySource::GitHub,
"bukkitdev" => RepositorySource::BukkitDev,
_ => RepositorySource::Custom(repo),
})
.collect();
// Get server info from the path for compatibility checking
let scan_result = match crate::services::plugin_scanner::perform_scan(&app_handle, &server_path).await {
Ok(result) => result,
Err(e) => {
println!("Warning: Could not get server info for compatibility check: {}", e);
// Create a minimal result with default server info
let server_info = crate::models::server::ServerInfo {
server_type: crate::models::server::ServerType::Unknown,
minecraft_version: None,
plugins_directory: format!("{}/plugins", server_path),
plugins_count: 0
};
crate::models::server::ScanResult {
server_info,
plugins: Vec::new()
}
}
};
crate::services::update_manager::check_for_plugin_updates(app_handle, plugins, repos, &scan_result.server_info).await
}
/// Check for updates for a single plugin
#[command]
pub async fn check_single_plugin_update_command(
app_handle: AppHandle,
plugin: Plugin,
repositories: Vec<String>,
server_path: Option<String>
) -> Result<(), String> {
// Convert repository strings to RepositorySource
let repos: Vec<RepositorySource> = repositories.into_iter()
.map(|repo| match repo.to_lowercase().as_str() {
"hangarmc" => RepositorySource::HangarMC,
"spigotmc" => RepositorySource::SpigotMC,
"modrinth" => RepositorySource::Modrinth,
"github" => RepositorySource::GitHub,
"bukkitdev" => RepositorySource::BukkitDev,
_ => RepositorySource::Custom(repo),
})
.collect();
// Get server info if a path was provided
let server_info = if let Some(path) = server_path {
match crate::services::plugin_scanner::perform_scan(&app_handle, &path).await {
Ok(result) => Some(result.server_info),
Err(e) => {
println!("Warning: Could not get server info for compatibility check: {}", e);
None
}
}
} else {
None
};
// Pass the optional server info to the update function
crate::services::update_manager::check_single_plugin_update(app_handle, plugin, repos, server_info.as_ref()).await
}
/// Create a backup of a plugin file
#[command]
pub async fn backup_plugin_command(plugin_file_path: String) -> Result<String, String> {
backup_plugin(plugin_file_path).await
}
/// Set repository source for a plugin
#[command]
pub async fn set_plugin_repository(
app_handle: AppHandle,
plugin_file_path: String,
repository: String,
repository_id: String,
page_url: String,
server_path: String
) -> Result<Plugin, String> {
// Convert repository string to RepositorySource
let repo_source = match repository.to_lowercase().as_str() {
"hangarmc" => RepositorySource::HangarMC,
"spigotmc" => RepositorySource::SpigotMC,
"modrinth" => RepositorySource::Modrinth,
"github" => RepositorySource::GitHub,
"bukkitdev" => RepositorySource::BukkitDev,
_ => RepositorySource::Custom(repository.clone()),
};
// Load the plugin data
let plugins = crate::services::plugin_scanner::perform_scan(&app_handle, &server_path).await?.plugins;
// Find the specific plugin
let mut plugin = plugins.into_iter()
.find(|p| p.file_path == plugin_file_path)
.ok_or_else(|| format!("Plugin not found: {}", plugin_file_path))?;
// Update repository information
plugin.repository_source = Some(repo_source);
plugin.repository_id = Some(repository_id);
plugin.repository_url = Some(page_url);
// Trigger an update check
if let Some(repo_id) = &plugin.repository_id {
if let Some(repo_source) = &plugin.repository_source {
match crate::lib_get_plugin_details_from_repository(repo_id, repo_source.clone(), None).await {
Ok(repo_plugin) => {
// Set latest version if newer
if repo_plugin.version != plugin.version {
let has_update = compare_plugin_versions(&plugin.version, &repo_plugin.version);
plugin.latest_version = Some(repo_plugin.version);
plugin.has_update = has_update;
plugin.changelog = repo_plugin.changelog;
} else {
plugin.has_update = false;
}
},
Err(e) => {
println!("Error checking for updates: {}", e);
}
}
}
}
Ok(plugin)
}
/// Load saved plugin data for a specific server
#[command]
pub async fn load_plugin_data(
app_handle: AppHandle,
server_path: String,
) -> Result<Vec<Plugin>, String> {
let data_dir = crate::services::plugin_scanner::get_plugin_data_path(&app_handle, &server_path)?;
let data_path = data_dir.join("plugins.json");
if !data_path.exists() {
// If the file doesn't exist, it's not an error, just return empty list
return Ok(Vec::new());
}
// Read the file content
let json_data = std::fs::read_to_string(&data_path)
.map_err(|e| format!("Failed to read plugin data file: {}", e))?;
// Deserialize the JSON data
let plugins: Vec<Plugin> = serde_json::from_str(&json_data)
.map_err(|e| format!("Failed to deserialize plugin data: {}", e))?;
Ok(plugins)
}
/// Save plugin data for a specific server
#[command]
pub async fn save_plugin_data(
app_handle: AppHandle,
plugins: Vec<Plugin>,
server_path: String,
) -> Result<(), String> {
let data_dir = crate::services::plugin_scanner::get_plugin_data_path(&app_handle, &server_path)?;
// Create directory if it doesn't exist
if !data_dir.exists() {
std::fs::create_dir_all(&data_dir)
.map_err(|e| format!("Failed to create plugin data directory: {}", e))?;
}
// Save plugins data
let data_path = data_dir.join("plugins.json");
let json_data = serde_json::to_string_pretty(&plugins)
.map_err(|e| format!("Failed to serialize plugin data for saving: {}", e))?;
std::fs::write(&data_path, json_data)
.map_err(|e| format!("Failed to write plugin data file: {}", e))?;
Ok(())
}
/// Get versions for a plugin from a repository
#[command]
pub async fn get_plugin_versions(
plugin_id: String,
repository: String
) -> Result<Vec<String>, String> {
// This is a placeholder - would need to implement the actual repository API call
Ok(vec!["1.0.0".to_string(), "1.1.0".to_string(), "1.2.0".to_string()])
}
/// Get potential matches for a plugin from repositories
#[command]
pub async fn get_potential_plugin_matches(
app_handle: AppHandle,
plugin: Plugin,
repositories: Vec<String>
) -> Result<Vec<crate::models::repository::PotentialPluginMatch>, String> {
// Convert repository strings to RepositorySource
let repos: Vec<RepositorySource> = repositories.into_iter()
.map(|repo| match repo.to_lowercase().as_str() {
"hangarmc" => RepositorySource::HangarMC,
"spigotmc" => RepositorySource::SpigotMC,
"modrinth" => RepositorySource::Modrinth,
"github" => RepositorySource::GitHub,
"bukkitdev" => RepositorySource::BukkitDev,
_ => RepositorySource::Custom(repo),
})
.collect();
// This is a placeholder - would need to implement actual search
Ok(Vec::new())
}
/// Compare two version strings
#[command]
pub fn compare_versions(version1: String, version2: String) -> bool {
compare_plugin_versions(&version1, &version2)
}
/// Check if a plugin is compatible with a specific Minecraft version
#[command]
pub fn is_plugin_compatible(plugin_version: String, minecraft_version: String) -> bool {
// This is a placeholder - would need to implement actual compatibility check
true
}
/// Simple greeting function for testing
#[command]
pub fn greet(name: &str) -> String {
format!("Hello, {}! Welcome to PlugSnatcher.", name)
}