Initial auto create impl
This commit is contained in:
12
Cargo.lock
generated
12
Cargo.lock
generated
@@ -20,6 +20,17 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.89"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atomic-waker"
|
||||
version = "1.1.2"
|
||||
@@ -618,6 +629,7 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
|
||||
name = "mineguard"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"chrono",
|
||||
"regex",
|
||||
"reqwest",
|
||||
|
||||
@@ -21,6 +21,7 @@ mc-vanilla = ["dep:serde", "dep:serde_json", "dep:reqwest"]
|
||||
# Add new feature groups here; attach their optional dependencies to the relevant feature list.
|
||||
|
||||
[dependencies]
|
||||
async-trait = "0.1.89"
|
||||
chrono = {version = "0.4.42", optional = true}
|
||||
regex = {version = "1.12.2", optional = true}
|
||||
reqwest = { version = "0.12.24", optional = true, features = ["json"] }
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user