Started vanilla auto creation

This commit is contained in:
2025-12-06 22:55:06 +01:00
parent f3c7172178
commit 6b2757a52f
10 changed files with 1268 additions and 16 deletions

1123
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -17,12 +17,15 @@ core = ["dep:thiserror", "dep:tokio", "dep:tokio-stream", "dep:tokio-util"]
# Placeholder for upcoming event-driven functionality.
events = ["dep:uuid", "dep:chrono", "dep:regex"]
mc-vanilla = []
mc-vanilla = ["dep:serde", "dep:serde_json", "dep:reqwest"]
# Add new feature groups here; attach their optional dependencies to the relevant feature list.
[dependencies]
chrono = {version = "0.4.42", optional = true}
regex = {version = "1.12.2", optional = true}
reqwest = { version = "0.12.24", optional = true, features = ["json"] }
serde = { version = "1.0.228", optional = true, features = ["derive"] }
serde_json = {version = "1.0.145", optional = true}
thiserror = { version = "2.0.17", optional = true }
# Core async runtime and utilities
# Add new feature-specific optional dependencies alongside the relevant feature entry above.

View File

@@ -3,6 +3,8 @@ use std::{
str::FromStr,
};
use tokio::sync::watch;
use crate::error::VersionError;
/// Identifies the type of Minecraft distribution supported by the configuration.
@@ -46,6 +48,15 @@ impl Display for Snapshot {
}
}
impl Display for MinecraftVersion {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
MinecraftVersion::Release(version) => write!(f, "{}", version.to_string()),
MinecraftVersion::Snapshot(snapshot) => write!(f, "{}", snapshot.to_string()),
}
}
}
impl FromStr for Version {
type Err = VersionError;

View File

@@ -99,3 +99,22 @@ pub enum ParserError {
#[error("ParserError")]
ParserError,
}
#[derive(Debug, Clone, Error)]
pub enum CreationError {
#[error("CreationError")]
CreationError,
#[error("Invalid directory")]
DirectoryError,
}
#[derive(Debug, Clone, Error)]
pub enum ManifestError {
#[error("ManifestError")]
ManifestError,
#[error("Failed to load mainfest")]
LoadUrlError,
#[error("Failed to parse manifest json")]
JsonParseError,
}

View File

@@ -290,10 +290,11 @@ impl InstanceHandle {
.map_err(|_| ServerError::NoStdoutPipe)?;
let shutdown1 = self.shutdown.clone();
let shutdown2 = self.shutdown.clone();
let _event_tx = self.events_tx.clone();
let event_tx = self.events_tx.clone();
if let Some(mut internal_rx) = self.internal_rx.take() {
tokio::spawn(async move {
let tx = event_tx;
loop {
tokio::select! {
_ = shutdown1.cancelled() => {
@@ -302,7 +303,7 @@ impl InstanceHandle {
maybe_event = internal_rx.recv() => {
if let Some(event) = maybe_event {
println!("event: {}", event);
_ = tx.send(event);
}
}
}
@@ -322,8 +323,7 @@ impl InstanceHandle {
}
line = rx.next() => {
if let Some(Ok(val)) = line {
println!("{}", val);
// TODO: Call parser
}
}
}

View File

@@ -1,4 +1,6 @@
pub mod config;
pub mod error;
pub mod instance;
pub mod manifests;
pub mod server;
pub mod utils;

1
src/manifests/mod.rs Normal file
View File

@@ -0,0 +1 @@
pub mod vanilla;

65
src/manifests/vanilla.rs Normal file
View File

@@ -0,0 +1,65 @@
#![cfg(feature = "mc-vanilla")]
use reqwest::Client;
use serde::Deserialize;
use crate::{config::MinecraftVersion, error::ManifestError};
#[derive(Debug, Clone, Deserialize)]
pub struct VanillaManifestV2 {
latest: VanillaManifestV2Latest,
versions: Vec<VanillaManifestV2Version>,
}
#[derive(Debug, Clone, Deserialize)]
struct VanillaManifestV2Latest {
release: String,
snapshot: String,
}
#[derive(Debug, Clone, Deserialize)]
struct VanillaManifestV2Version {
id: String,
#[serde(rename = "type")]
mc_type: String,
url: String,
time: String,
#[serde(rename = "releaseTime")]
release_time: String,
sha1: String,
#[serde(rename = "complianceLevel")]
compliance_level: String,
}
impl VanillaManifestV2 {
pub async fn load() -> Result<Self, ManifestError> {
let client = Client::new();
let manifest: VanillaManifestV2 = client
.get("https://piston-meta.mojang.com/mc/game/version_manifest_v2.json")
.send()
.await
.map_err(|_| ManifestError::LoadUrlError)?
.error_for_status()
.map_err(|_| ManifestError::LoadUrlError)?
.json()
.await
.map_err(|_| ManifestError::JsonParseError)?;
Ok(manifest)
}
pub fn find(
&self,
version: MinecraftVersion,
) -> Result<Option<VanillaManifestV2Version>, ManifestError> {
let id = version.to_string();
let found = match self.versions.iter().find(|p| p.id == id) {
Some(val) => Some(val.clone()),
None => None,
};
Ok(found)
}
}

49
src/server/domain.rs Normal file
View File

@@ -0,0 +1,49 @@
use std::{path::PathBuf, str::FromStr};
use tokio::sync::RwLock;
use uuid::Uuid;
use crate::{
config::{MinecraftType, MinecraftVersion, Version},
error::CreationError,
instance::InstanceHandle,
};
pub struct MineGuardConfig {
uuid: Uuid,
server_dir: PathBuf,
jar_path: PathBuf,
mc_version: MinecraftVersion,
mc_type: MinecraftType,
}
pub struct MineGuardServer {
handle: RwLock<InstanceHandle>,
config: RwLock<MineGuardConfig>,
}
impl MineGuardConfig {
pub fn new() -> Self {
Self {
uuid: Uuid::new_v4(),
server_dir: PathBuf::new(),
jar_path: PathBuf::new(),
mc_version: MinecraftVersion::Release(Version::from_str("0.00.00").unwrap()),
mc_type: MinecraftType::Vanilla,
}
}
}
impl MineGuardServer {
pub fn create(
mc_version: MinecraftVersion,
mc_type: MinecraftType,
directory: PathBuf,
) -> Result<Self, CreationError> {
if !directory.is_dir() {
return Err(CreationError::DirectoryError);
}
todo!()
}
}

1
src/server/mod.rs Normal file
View File

@@ -0,0 +1 @@
pub mod domain;