Initial auto create impl
This commit is contained in:
12
Cargo.lock
generated
12
Cargo.lock
generated
@@ -20,6 +20,17 @@ dependencies = [
|
|||||||
"libc",
|
"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]]
|
[[package]]
|
||||||
name = "atomic-waker"
|
name = "atomic-waker"
|
||||||
version = "1.1.2"
|
version = "1.1.2"
|
||||||
@@ -618,6 +629,7 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
|
|||||||
name = "mineguard"
|
name = "mineguard"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"async-trait",
|
||||||
"chrono",
|
"chrono",
|
||||||
"regex",
|
"regex",
|
||||||
"reqwest",
|
"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.
|
# Add new feature groups here; attach their optional dependencies to the relevant feature list.
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
async-trait = "0.1.89"
|
||||||
chrono = {version = "0.4.42", optional = true}
|
chrono = {version = "0.4.42", optional = true}
|
||||||
regex = {version = "1.12.2", optional = true}
|
regex = {version = "1.12.2", optional = true}
|
||||||
reqwest = { version = "0.12.24", optional = true, features = ["json"] }
|
reqwest = { version = "0.12.24", optional = true, features = ["json"] }
|
||||||
|
|||||||
@@ -107,6 +107,15 @@ pub enum CreationError {
|
|||||||
|
|
||||||
#[error("Invalid directory")]
|
#[error("Invalid directory")]
|
||||||
DirectoryError,
|
DirectoryError,
|
||||||
|
|
||||||
|
#[error("Failed to parse manifest")]
|
||||||
|
ManifestError,
|
||||||
|
|
||||||
|
#[error("Version does not exist")]
|
||||||
|
VersionError,
|
||||||
|
|
||||||
|
#[error("Network Error")]
|
||||||
|
NetworkError,
|
||||||
}
|
}
|
||||||
#[derive(Debug, Clone, Error)]
|
#[derive(Debug, Clone, Error)]
|
||||||
pub enum ManifestError {
|
pub enum ManifestError {
|
||||||
|
|||||||
@@ -41,24 +41,26 @@ pub struct InstanceHandle {
|
|||||||
|
|
||||||
impl InstanceHandle {
|
impl InstanceHandle {
|
||||||
pub fn new_with_params(
|
pub fn new_with_params(
|
||||||
root_dir: &str,
|
root_dir: PathBuf,
|
||||||
jar_path: &str,
|
jar_path: PathBuf,
|
||||||
mc_version: &str,
|
mc_version: MinecraftVersion,
|
||||||
mc_type: MinecraftType,
|
mc_type: MinecraftType,
|
||||||
) -> Result<Self, HandleError> {
|
) -> Result<Self, HandleError> {
|
||||||
let parsed_version: MinecraftVersion = mc_version
|
let parsed_version: MinecraftVersion = mc_version;
|
||||||
.parse()
|
|
||||||
.map_err(|_| HandleError::InvalidVersion(mc_version.to_string()))?;
|
|
||||||
|
|
||||||
let root: PathBuf = root_dir.into();
|
let root: PathBuf = root_dir.clone().into();
|
||||||
if !root.exists() || !root.is_dir() {
|
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());
|
let conc = root.join(path.clone());
|
||||||
if !path.is_relative() || !conc.is_file() {
|
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 {
|
let data = InstanceData {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#![cfg(feature = "mc-vanilla")]
|
#![cfg(feature = "mc-vanilla")]
|
||||||
|
|
||||||
|
use async_trait::async_trait;
|
||||||
use reqwest::Client;
|
use reqwest::Client;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
@@ -12,13 +13,13 @@ pub struct VanillaManifestV2 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize)]
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
struct VanillaManifestV2Latest {
|
pub struct VanillaManifestV2Latest {
|
||||||
release: String,
|
release: String,
|
||||||
snapshot: String,
|
snapshot: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize)]
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
struct VanillaManifestV2Version {
|
pub struct VanillaManifestV2Version {
|
||||||
id: String,
|
id: String,
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
mc_type: String,
|
mc_type: String,
|
||||||
@@ -28,7 +29,52 @@ struct VanillaManifestV2Version {
|
|||||||
release_time: String,
|
release_time: String,
|
||||||
sha1: String,
|
sha1: String,
|
||||||
#[serde(rename = "complianceLevel")]
|
#[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 {
|
impl VanillaManifestV2 {
|
||||||
@@ -44,7 +90,10 @@ impl VanillaManifestV2 {
|
|||||||
.map_err(|_| ManifestError::LoadUrlError)?
|
.map_err(|_| ManifestError::LoadUrlError)?
|
||||||
.json()
|
.json()
|
||||||
.await
|
.await
|
||||||
.map_err(|_| ManifestError::JsonParseError)?;
|
.map_err(|e| {
|
||||||
|
eprintln!("{}", e);
|
||||||
|
ManifestError::JsonParseError
|
||||||
|
})?;
|
||||||
|
|
||||||
Ok(manifest)
|
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 uuid::Uuid;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
config::{MinecraftType, MinecraftVersion, Version},
|
config::{MinecraftType, MinecraftVersion, Version},
|
||||||
error::CreationError,
|
error::CreationError,
|
||||||
instance::InstanceHandle,
|
instance::InstanceHandle,
|
||||||
|
manifests::vanilla::{VanillaManifestV2, VanillaManifestV2Version, VanillaReleaseManifest},
|
||||||
|
server,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct MineGuardConfig {
|
pub struct MineGuardConfig {
|
||||||
@@ -18,8 +24,8 @@ pub struct MineGuardConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct MineGuardServer {
|
pub struct MineGuardServer {
|
||||||
handle: RwLock<InstanceHandle>,
|
pub handle: RwLock<InstanceHandle>,
|
||||||
config: RwLock<MineGuardConfig>,
|
pub config: RwLock<MineGuardConfig>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MineGuardConfig {
|
impl MineGuardConfig {
|
||||||
@@ -35,7 +41,7 @@ impl MineGuardConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl MineGuardServer {
|
impl MineGuardServer {
|
||||||
pub fn create(
|
pub async fn create(
|
||||||
mc_version: MinecraftVersion,
|
mc_version: MinecraftVersion,
|
||||||
mc_type: MinecraftType,
|
mc_type: MinecraftType,
|
||||||
directory: PathBuf,
|
directory: PathBuf,
|
||||||
@@ -44,6 +50,74 @@ impl MineGuardServer {
|
|||||||
return Err(CreationError::DirectoryError);
|
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