Initial auto create impl

This commit is contained in:
2025-12-07 20:31:05 +01:00
parent 6b2757a52f
commit 668870b92e
6 changed files with 167 additions and 20 deletions

View File

@@ -107,6 +107,15 @@ pub enum CreationError {
#[error("Invalid directory")]
DirectoryError,
#[error("Failed to parse manifest")]
ManifestError,
#[error("Version does not exist")]
VersionError,
#[error("Network Error")]
NetworkError,
}
#[derive(Debug, Clone, Error)]
pub enum ManifestError {

View File

@@ -41,24 +41,26 @@ pub struct InstanceHandle {
impl InstanceHandle {
pub fn new_with_params(
root_dir: &str,
jar_path: &str,
mc_version: &str,
root_dir: PathBuf,
jar_path: PathBuf,
mc_version: MinecraftVersion,
mc_type: MinecraftType,
) -> Result<Self, HandleError> {
let parsed_version: MinecraftVersion = mc_version
.parse()
.map_err(|_| HandleError::InvalidVersion(mc_version.to_string()))?;
let parsed_version: MinecraftVersion = mc_version;
let root: PathBuf = root_dir.into();
let root: PathBuf = root_dir.clone().into();
if !root.exists() || !root.is_dir() {
return Err(HandleError::InvalidDirectory(root_dir.to_string()));
return Err(HandleError::InvalidDirectory(
root_dir.to_str().unwrap().to_string(),
));
}
let path: PathBuf = jar_path.into();
let path: PathBuf = jar_path.clone().into();
let conc = root.join(path.clone());
if !path.is_relative() || !conc.is_file() {
return Err(HandleError::InvalidPathJAR(jar_path.to_string()));
return Err(HandleError::InvalidPathJAR(
jar_path.to_str().unwrap().to_string(),
));
}
let data = InstanceData {

View File

@@ -1,5 +1,6 @@
#![cfg(feature = "mc-vanilla")]
use async_trait::async_trait;
use reqwest::Client;
use serde::Deserialize;
@@ -12,13 +13,13 @@ pub struct VanillaManifestV2 {
}
#[derive(Debug, Clone, Deserialize)]
struct VanillaManifestV2Latest {
pub struct VanillaManifestV2Latest {
release: String,
snapshot: String,
}
#[derive(Debug, Clone, Deserialize)]
struct VanillaManifestV2Version {
pub struct VanillaManifestV2Version {
id: String,
#[serde(rename = "type")]
mc_type: String,
@@ -28,7 +29,52 @@ struct VanillaManifestV2Version {
release_time: String,
sha1: String,
#[serde(rename = "complianceLevel")]
compliance_level: String,
compliance_level: u32,
}
#[derive(Debug, Clone, Deserialize)]
pub struct VanillaReleaseManifest {
downloads: VanillaReleaseManifestDownloads,
}
#[derive(Debug, Clone, Deserialize)]
pub struct VanillaReleaseManifestDownloads {
client: VanillaReleaseManifestDownloadsItem,
client_mappings: VanillaReleaseManifestDownloadsItem,
server: VanillaReleaseManifestDownloadsItem,
server_mappings: VanillaReleaseManifestDownloadsItem,
}
#[derive(Debug, Clone, Deserialize)]
pub struct VanillaReleaseManifestDownloadsItem {
sha1: String,
size: u32,
url: String,
}
impl VanillaReleaseManifest {
pub async fn load(version: VanillaManifestV2Version) -> Result<Self, ManifestError> {
let client = Client::new();
let manifest: VanillaReleaseManifest = client
.get(&version.url)
.send()
.await
.map_err(|_| ManifestError::LoadUrlError)?
.error_for_status()
.map_err(|_| ManifestError::LoadUrlError)?
.json()
.await
.map_err(|e| {
eprintln!("{}", e);
ManifestError::JsonParseError
})?;
Ok(manifest)
}
pub fn server_url(&self) -> String {
self.downloads.server.url.clone()
}
}
impl VanillaManifestV2 {
@@ -44,7 +90,10 @@ impl VanillaManifestV2 {
.map_err(|_| ManifestError::LoadUrlError)?
.json()
.await
.map_err(|_| ManifestError::JsonParseError)?;
.map_err(|e| {
eprintln!("{}", e);
ManifestError::JsonParseError
})?;
Ok(manifest)
}

View File

@@ -1,12 +1,18 @@
use std::{path::PathBuf, str::FromStr};
use std::{ops::RangeInclusive, path::PathBuf, str::FromStr};
use tokio::sync::RwLock;
use tokio::{
fs::{File, create_dir},
io::{self, AsyncWriteExt},
sync::RwLock,
};
use uuid::Uuid;
use crate::{
config::{MinecraftType, MinecraftVersion, Version},
error::CreationError,
instance::InstanceHandle,
manifests::vanilla::{VanillaManifestV2, VanillaManifestV2Version, VanillaReleaseManifest},
server,
};
pub struct MineGuardConfig {
@@ -18,8 +24,8 @@ pub struct MineGuardConfig {
}
pub struct MineGuardServer {
handle: RwLock<InstanceHandle>,
config: RwLock<MineGuardConfig>,
pub handle: RwLock<InstanceHandle>,
pub config: RwLock<MineGuardConfig>,
}
impl MineGuardConfig {
@@ -35,7 +41,7 @@ impl MineGuardConfig {
}
impl MineGuardServer {
pub fn create(
pub async fn create(
mc_version: MinecraftVersion,
mc_type: MinecraftType,
directory: PathBuf,
@@ -44,6 +50,74 @@ impl MineGuardServer {
return Err(CreationError::DirectoryError);
}
todo!()
let uuid = Uuid::new_v4();
let server_root = directory.join(uuid.to_string());
let jar_path_rel =
PathBuf::from_str("server.jar").map_err(|_| CreationError::DirectoryError)?;
let jar_path_full = server_root.join(jar_path_rel.clone());
create_dir(server_root.clone())
.await
.map_err(|_| CreationError::DirectoryError)?;
let mut url = String::new();
if mc_type == MinecraftType::Vanilla {
let vanilla_manifest = VanillaManifestV2::load()
.await
.map_err(|_| CreationError::ManifestError)?;
let find_ver = match vanilla_manifest
.find(mc_version.clone())
.map_err(|_| CreationError::ManifestError)?
{
Some(val) => val,
None => return Err(CreationError::VersionError),
};
let release_manifest = VanillaReleaseManifest::load(find_ver)
.await
.map_err(|_| CreationError::ManifestError)?;
url = release_manifest.server_url();
}
let resp = reqwest::get(url)
.await
.map_err(|_| CreationError::NetworkError)?;
let mut body = resp
.bytes()
.await
.map_err(|_| CreationError::NetworkError)?;
let mut out = File::create(jar_path_full)
.await
.map_err(|_| CreationError::DirectoryError)?;
out.write_all_buf(&mut body)
.await
.map_err(|_| CreationError::DirectoryError)?;
let config = MineGuardConfig {
uuid: uuid,
server_dir: server_root,
jar_path: jar_path_rel,
mc_version: mc_version,
mc_type: mc_type,
};
let handle = InstanceHandle::new_with_params(
config.server_dir.clone(),
config.jar_path.clone(),
config.mc_version.clone(),
config.mc_type.clone(),
)
.map_err(|_| CreationError::CreationError)?;
let server = MineGuardServer {
config: RwLock::new(config),
handle: RwLock::new(handle),
};
Ok(server)
}
}