Config save and load start
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -1342,6 +1342,7 @@ checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom 0.3.4",
|
"getrandom 0.3.4",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
|
"serde_core",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -33,4 +33,4 @@ thiserror = { version = "2.0.17", optional = true }
|
|||||||
tokio = { version = "1.48.0", features = ["process", "rt-multi-thread", "macros", "io-std", "io-util"], optional = true }
|
tokio = { version = "1.48.0", features = ["process", "rt-multi-thread", "macros", "io-std", "io-util"], optional = true }
|
||||||
tokio-stream = { version = "0.1.17", features = ["full", "io-util", "signal", "tokio-util"], optional = true }
|
tokio-stream = { version = "0.1.17", features = ["full", "io-util", "signal", "tokio-util"], optional = true }
|
||||||
tokio-util = { version = "0.7.17", features = ["full"], optional = true }
|
tokio-util = { version = "0.7.17", features = ["full"], optional = true }
|
||||||
uuid = { version = "1.19.0", features = ["v4"], optional = true }
|
uuid = { version = "1.19.0", features = ["serde", "v4"], optional = true }
|
||||||
|
|||||||
@@ -3,18 +3,19 @@ use std::{
|
|||||||
str::FromStr,
|
str::FromStr,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
use tokio::sync::watch;
|
use tokio::sync::watch;
|
||||||
|
|
||||||
use crate::error::VersionError;
|
use crate::error::VersionError;
|
||||||
|
|
||||||
/// Identifies the type of Minecraft distribution supported by the configuration.
|
/// Identifies the type of Minecraft distribution supported by the configuration.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
|
||||||
pub enum MinecraftType {
|
pub enum MinecraftType {
|
||||||
Vanilla,
|
Vanilla,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Semantic release version parsed from strings like `1.20.4`.
|
/// Semantic release version parsed from strings like `1.20.4`.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
|
||||||
pub struct Version {
|
pub struct Version {
|
||||||
pub major: u32,
|
pub major: u32,
|
||||||
pub minor: u32,
|
pub minor: u32,
|
||||||
@@ -22,7 +23,7 @@ pub struct Version {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Snapshot version parsed from strings like `23w13b`.
|
/// Snapshot version parsed from strings like `23w13b`.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
|
||||||
pub struct Snapshot {
|
pub struct Snapshot {
|
||||||
pub year: u32,
|
pub year: u32,
|
||||||
pub week: u32,
|
pub week: u32,
|
||||||
@@ -30,7 +31,7 @@ pub struct Snapshot {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Enum covering both release and snapshot Minecraft version formats.
|
/// Enum covering both release and snapshot Minecraft version formats.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
|
||||||
pub enum MinecraftVersion {
|
pub enum MinecraftVersion {
|
||||||
Release(Version),
|
Release(Version),
|
||||||
Snapshot(Snapshot),
|
Snapshot(Snapshot),
|
||||||
|
|||||||
@@ -96,6 +96,9 @@ pub enum ServerError {
|
|||||||
NoEULA,
|
NoEULA,
|
||||||
#[error("Failed to write eula.txt")]
|
#[error("Failed to write eula.txt")]
|
||||||
WriteEULAFailed,
|
WriteEULAFailed,
|
||||||
|
|
||||||
|
#[error("File io error")]
|
||||||
|
FileIO,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "events")]
|
#[cfg(feature = "events")]
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ use crate::{
|
|||||||
stream::{EventPayload, InternalEvent},
|
stream::{EventPayload, InternalEvent},
|
||||||
},
|
},
|
||||||
error::{HandleError, ServerError, SubscribeError},
|
error::{HandleError, ServerError, SubscribeError},
|
||||||
|
server::domain::MineGuardConfig,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{InstanceData, InstanceStatus};
|
use super::{InstanceData, InstanceStatus};
|
||||||
@@ -44,6 +45,14 @@ pub struct InstanceHandle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl InstanceHandle {
|
impl InstanceHandle {
|
||||||
|
pub fn new_with_config(config: MineGuardConfig) -> Result<Self, HandleError> {
|
||||||
|
InstanceHandle::new_with_params(
|
||||||
|
config.server_dir,
|
||||||
|
config.jar_path,
|
||||||
|
config.mc_version,
|
||||||
|
config.mc_type,
|
||||||
|
)
|
||||||
|
}
|
||||||
pub fn new_with_params(
|
pub fn new_with_params(
|
||||||
root_dir: PathBuf,
|
root_dir: PathBuf,
|
||||||
jar_path: PathBuf,
|
jar_path: PathBuf,
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
use std::{ops::RangeInclusive, path::PathBuf, str::FromStr};
|
use std::{ops::RangeInclusive, path::PathBuf, str::FromStr};
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use serde_json::json;
|
||||||
use tokio::{
|
use tokio::{
|
||||||
fs::{File, create_dir},
|
fs::{File, create_dir, read, read_dir},
|
||||||
io::{self, AsyncWriteExt},
|
io::{self, AsyncWriteExt},
|
||||||
sync::{RwLock, watch},
|
sync::{RwLock, watch},
|
||||||
};
|
};
|
||||||
@@ -9,21 +11,23 @@ use tokio_stream::wrappers::BroadcastStream;
|
|||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
config::{MinecraftType, MinecraftVersion, StreamSource, Version, stream::InstanceEvent},
|
config::{self, MinecraftType, MinecraftVersion, StreamSource, Version, stream::InstanceEvent},
|
||||||
error::{CreationError, ServerError, SubscribeError},
|
error::{CreationError, ServerError, SubscribeError},
|
||||||
instance::InstanceHandle,
|
instance::InstanceHandle,
|
||||||
manifests::vanilla::{VanillaManifestV2, VanillaManifestV2Version, VanillaReleaseManifest},
|
manifests::vanilla::{VanillaManifestV2, VanillaManifestV2Version, VanillaReleaseManifest},
|
||||||
server,
|
server,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||||
pub struct MineGuardConfig {
|
pub struct MineGuardConfig {
|
||||||
uuid: Uuid,
|
uuid: Uuid,
|
||||||
server_dir: PathBuf,
|
pub server_dir: PathBuf,
|
||||||
jar_path: PathBuf,
|
pub jar_path: PathBuf,
|
||||||
mc_version: MinecraftVersion,
|
pub mc_version: MinecraftVersion,
|
||||||
mc_type: MinecraftType,
|
pub mc_type: MinecraftType,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct MineGuardServer {
|
pub struct MineGuardServer {
|
||||||
pub handle: RwLock<InstanceHandle>,
|
pub handle: RwLock<InstanceHandle>,
|
||||||
pub config: RwLock<MineGuardConfig>,
|
pub config: RwLock<MineGuardConfig>,
|
||||||
@@ -42,6 +46,15 @@ impl MineGuardConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl MineGuardServer {
|
impl MineGuardServer {
|
||||||
|
async fn load_cfg_handle(
|
||||||
|
config: MineGuardConfig,
|
||||||
|
handle: InstanceHandle,
|
||||||
|
) -> Result<Self, CreationError> {
|
||||||
|
Ok(Self {
|
||||||
|
config: RwLock::new(config),
|
||||||
|
handle: RwLock::new(handle),
|
||||||
|
})
|
||||||
|
}
|
||||||
pub async fn create(
|
pub async fn create(
|
||||||
mc_version: MinecraftVersion,
|
mc_version: MinecraftVersion,
|
||||||
mc_type: MinecraftType,
|
mc_type: MinecraftType,
|
||||||
@@ -62,6 +75,11 @@ impl MineGuardServer {
|
|||||||
.await
|
.await
|
||||||
.map_err(|_| CreationError::DirectoryError)?;
|
.map_err(|_| CreationError::DirectoryError)?;
|
||||||
|
|
||||||
|
let internal_dir = server_root.join(".mineguard");
|
||||||
|
create_dir(internal_dir)
|
||||||
|
.await
|
||||||
|
.map_err(|_| CreationError::DirectoryError)?;
|
||||||
|
|
||||||
let mut url = String::new();
|
let mut url = String::new();
|
||||||
|
|
||||||
if mc_type == MinecraftType::Vanilla {
|
if mc_type == MinecraftType::Vanilla {
|
||||||
@@ -162,4 +180,69 @@ impl MineGuardServer {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn write_config(&self) -> Result<(), ServerError> {
|
||||||
|
let config_r = self.config.read().await;
|
||||||
|
let root_path = config_r.server_dir.clone();
|
||||||
|
let config_clone = config_r.clone();
|
||||||
|
drop(config_r);
|
||||||
|
|
||||||
|
let config_path = root_path.join(".mineguard/config.json");
|
||||||
|
|
||||||
|
let json = serde_json::to_vec_pretty(&config_clone).map_err(|_| ServerError::FileIO)?;
|
||||||
|
|
||||||
|
File::create(config_path)
|
||||||
|
.await
|
||||||
|
.map_err(|_| ServerError::FileIO)?
|
||||||
|
.write_all(&json)
|
||||||
|
.await
|
||||||
|
.map_err(|_| ServerError::FileIO)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn load(path: &PathBuf) -> Result<Self, CreationError> {
|
||||||
|
let config_path = path.join(".mineguard/config.json");
|
||||||
|
|
||||||
|
let data = read(config_path)
|
||||||
|
.await
|
||||||
|
.map_err(|_| CreationError::DirectoryError)?;
|
||||||
|
|
||||||
|
let config: MineGuardConfig =
|
||||||
|
serde_json::from_slice(&data).map_err(|_| CreationError::CreationError)?;
|
||||||
|
let handle = InstanceHandle::new_with_config(config.clone())
|
||||||
|
.map_err(|_| CreationError::CreationError)?;
|
||||||
|
|
||||||
|
MineGuardServer::load_cfg_handle(config, handle).await
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn load_all(path: PathBuf) -> Result<Vec<Self>, CreationError> {
|
||||||
|
let mut dirs = Vec::new();
|
||||||
|
let mut entries = read_dir(path)
|
||||||
|
.await
|
||||||
|
.map_err(|_| CreationError::DirectoryError)?;
|
||||||
|
|
||||||
|
while let Some(entry) = entries
|
||||||
|
.next_entry()
|
||||||
|
.await
|
||||||
|
.map_err(|_| CreationError::DirectoryError)?
|
||||||
|
{
|
||||||
|
let meta = entry
|
||||||
|
.metadata()
|
||||||
|
.await
|
||||||
|
.map_err(|_| CreationError::DirectoryError)?;
|
||||||
|
if meta.is_dir() {
|
||||||
|
dirs.push(entry.path());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut servers: Vec<Self> = Vec::new();
|
||||||
|
|
||||||
|
for v in dirs {
|
||||||
|
println!("{}", v.to_str().unwrap());
|
||||||
|
servers.push(Self::load(&v).await?);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(servers)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user