fix(content): stop removed bundle mods coming back
This commit is contained in:
parent
d9e4f99add
commit
56b421b187
2 changed files with 51 additions and 6 deletions
|
|
@ -68,13 +68,28 @@ pub async fn unlink_cluster_file(
|
|||
content_type: ContentType,
|
||||
file_name: &str,
|
||||
) -> ContentResult<()> {
|
||||
let path = paths::clusters_dir()?
|
||||
let dir = paths::clusters_dir()?
|
||||
.join(&cluster.folder_name)
|
||||
.join(content_type.folder_name())
|
||||
.join(file_name);
|
||||
.join(content_type.folder_name());
|
||||
|
||||
if path.exists() {
|
||||
polyio::remove_file(&path).await?;
|
||||
}
|
||||
// Both spellings: the database always stores the bare name, but the folder
|
||||
// can still be holding a `<name>.disabled` left by an older launcher or by
|
||||
// the user renaming it by hand. Removing a package has to take both.
|
||||
remove_entry(&dir.join(file_name)).await?;
|
||||
remove_entry(&dir.join(format!("{file_name}.disabled"))).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Deletes `path` if anything is there, symlink or not.
|
||||
///
|
||||
/// `Path::exists` resolves symlinks, so a link whose artifact was evicted from
|
||||
/// the cache reads as absent and the dead link survives every unlink; the
|
||||
/// package then keeps showing up in the folder it was removed from.
|
||||
async fn remove_entry(path: &Path) -> ContentResult<()> {
|
||||
if polyio::symlink_metadata(path).await.is_err() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
polyio::remove_file(path).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -126,6 +126,21 @@ pub async fn import_manual_content(
|
|||
continue;
|
||||
}
|
||||
|
||||
// The shared dir is rebuilt from the database on every launch, so
|
||||
// anything here that the launcher already has in its artifact cache
|
||||
// is a leftover from a session whose cleanup never ran — a crash, or
|
||||
// a bundle update that dropped the package in between. Importing it
|
||||
// would re-link the package the update just removed, and the next
|
||||
// launch would put it back in the game. Drop it instead; the cache
|
||||
// still holds the file if it is ever wanted again.
|
||||
if is_cached_artifact(services, &path).await {
|
||||
tracing::debug!(file = name, "discarding stale launcher content in shared dir");
|
||||
if let Err(err) = polyio::remove_file(&path).await {
|
||||
tracing::warn!(file = name, error = %err, "failed to discard stale shared content");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
match PackageStore::import_local_file(&path, content_type, cluster.id, &services.content()).await {
|
||||
Ok(_) => {
|
||||
tracing::debug!(file = name, "registered manually-added shared content")
|
||||
|
|
@ -140,6 +155,21 @@ pub async fn import_manual_content(
|
|||
}
|
||||
}
|
||||
|
||||
/// Whether `path` is a copy of something already in the launcher's artifact
|
||||
/// cache, i.e. content the launcher itself put in the shared dir rather than
|
||||
/// something the user dropped there.
|
||||
async fn is_cached_artifact(services: &LauncherServices, path: &Path) -> bool {
|
||||
let Ok(hash) = polyio::sha1_file(path).await else {
|
||||
return false;
|
||||
};
|
||||
|
||||
artifact_dao::get_artifact_by_hash(&services.db, &polyio::normalize_hash(&hash))
|
||||
.await
|
||||
.ok()
|
||||
.flatten()
|
||||
.is_some()
|
||||
}
|
||||
|
||||
fn has_content_extension(content_type: ContentType, name: &str) -> bool {
|
||||
let lower = name.to_lowercase();
|
||||
match content_type {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue