feat:移除了弹窗,服务器添加sls
This commit is contained in:
commit
6a295f9a7a
4082 files changed
+1322534
No files matched your search
@@ -0,0 +1,189 @@
|
||||
use crate::event::InstancePayloadType;
|
||||
use crate::event::emit::emit_instance;
|
||||
use crate::state::instances::adapters::sqlite::instance_rows;
|
||||
use crate::state::{
|
||||
CreateDirectLinkInstance, CreateInstance, EditInstance, InstanceLink,
|
||||
InstanceMetadata, ModLoader, State,
|
||||
};
|
||||
use crate::util::{fetch::write_cached_icon, io};
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[tracing::instrument]
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub(crate) async fn create(
|
||||
name: String,
|
||||
game_version: String,
|
||||
modloader: ModLoader,
|
||||
loader_version: Option<String>,
|
||||
icon_path: Option<String>,
|
||||
link: InstanceLink,
|
||||
symlink_target: Option<String>,
|
||||
game_dir_override: Option<String>,
|
||||
) -> crate::Result<InstanceMetadata> {
|
||||
let state = State::get().await?;
|
||||
let instance = crate::state::create_instance(
|
||||
CreateInstance {
|
||||
name,
|
||||
path: None,
|
||||
game_version,
|
||||
loader: modloader,
|
||||
loader_version,
|
||||
icon_path,
|
||||
link,
|
||||
symlink_target,
|
||||
game_dir_override,
|
||||
},
|
||||
&state,
|
||||
)
|
||||
.await?;
|
||||
|
||||
let result = async {
|
||||
emit_instance(&instance.id, InstancePayloadType::Created).await?;
|
||||
|
||||
crate::state::get_instance(&instance.id, &state.pool)
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
crate::ErrorKind::InputError(
|
||||
"Created instance could not be loaded".to_string(),
|
||||
)
|
||||
.into()
|
||||
})
|
||||
}
|
||||
.await;
|
||||
|
||||
if result.is_err() {
|
||||
let _ = crate::state::remove_instance(&instance.id, &state).await;
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
/// Creates a "directly associated" instance that launches an externally
|
||||
/// managed (HMCL/PCL) local version in place: nothing is copied, symlinked,
|
||||
/// or reinstalled, and the game directory points at the linked `.minecraft`.
|
||||
#[tracing::instrument]
|
||||
pub async fn create_with_direct_link(
|
||||
input: CreateDirectLinkInstance,
|
||||
) -> crate::Result<InstanceMetadata> {
|
||||
let state = State::get().await?;
|
||||
let instance =
|
||||
crate::state::create_direct_link_instance(input, &state).await?;
|
||||
|
||||
let result = async {
|
||||
emit_instance(&instance.id, InstancePayloadType::Created).await?;
|
||||
|
||||
crate::state::get_instance(&instance.id, &state.pool)
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
crate::ErrorKind::InputError(
|
||||
"Created instance could not be loaded".to_string(),
|
||||
)
|
||||
.into()
|
||||
})
|
||||
}
|
||||
.await;
|
||||
|
||||
if result.is_err() {
|
||||
let _ = crate::state::remove_instance(&instance.id, &state).await;
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
/// Reconcile configured external Minecraft roots with direct-link records.
|
||||
pub async fn sync_direct_links(
|
||||
roots: Vec<crate::state::ExternalMinecraftRoot>,
|
||||
) -> crate::Result<crate::state::DirectLinkSyncReport> {
|
||||
let state = State::get().await?;
|
||||
crate::state::sync_direct_link_instances(roots, &state).await
|
||||
}
|
||||
|
||||
pub async fn edit(
|
||||
instance_id: &str,
|
||||
patch: EditInstance,
|
||||
) -> crate::Result<InstanceMetadata> {
|
||||
let state = State::get().await?;
|
||||
crate::state::edit_instance(instance_id, patch, &state.pool).await?;
|
||||
|
||||
let instance = crate::state::get_instance(instance_id, &state.pool)
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
crate::ErrorKind::InputError("Unknown instance".to_string())
|
||||
.as_error()
|
||||
})?;
|
||||
|
||||
emit_instance(&instance.instance.id, InstancePayloadType::Edited).await?;
|
||||
|
||||
Ok(instance)
|
||||
}
|
||||
|
||||
pub async fn cache_icon(
|
||||
icon_name: &str,
|
||||
bytes: Vec<u8>,
|
||||
) -> crate::Result<String> {
|
||||
let state = State::get().await?;
|
||||
let path = write_cached_icon(
|
||||
icon_name,
|
||||
&state.directories.caches_dir(),
|
||||
bytes::Bytes::from(bytes),
|
||||
&state.io_semaphore,
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(path.to_string_lossy().to_string())
|
||||
}
|
||||
|
||||
pub async fn edit_icon(
|
||||
instance_id: &str,
|
||||
icon_path: Option<&Path>,
|
||||
) -> crate::Result<()> {
|
||||
let state = State::get().await?;
|
||||
let instance =
|
||||
instance_rows::get_instance_display_info(instance_id, &state.pool)
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
crate::ErrorKind::InputError("Unknown instance".to_string())
|
||||
})?;
|
||||
let icon_path = if let Some(icon) = icon_path {
|
||||
let bytes = io::read(icon).await?;
|
||||
let file = crate::util::fetch::write_cached_icon(
|
||||
&icon.to_string_lossy(),
|
||||
&state.directories.caches_dir(),
|
||||
bytes::Bytes::from(bytes),
|
||||
&state.io_semaphore,
|
||||
)
|
||||
.await?;
|
||||
Some(file.to_string_lossy().to_string())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
crate::state::edit_instance(
|
||||
instance_id,
|
||||
EditInstance {
|
||||
icon_path: Some(icon_path),
|
||||
..EditInstance::default()
|
||||
},
|
||||
&state.pool,
|
||||
)
|
||||
.await?;
|
||||
emit_instance(&instance.id, InstancePayloadType::Edited).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tracing::instrument]
|
||||
pub async fn remove(instance_id: &str) -> crate::Result<()> {
|
||||
let state = State::get().await?;
|
||||
let instance =
|
||||
instance_rows::get_instance_display_info(instance_id, &state.pool)
|
||||
.await?;
|
||||
crate::state::remove_instance(instance_id, &state).await?;
|
||||
|
||||
if let Some(instance) = instance {
|
||||
emit_instance(&instance.id, InstancePayloadType::Removed).await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Reference in new issue
Block a user