@@ -2,6 +2,7 @@ use super::client::*;
22use super :: publish:: * ;
33use super :: types:: * ;
44use super :: * ;
5+ use std:: collections:: BTreeMap ;
56
67struct SharedContentSnapshot {
78 version_ids : Vec < String > ,
@@ -36,6 +37,7 @@ pub(super) async fn shared_instance_update_diffs(
3637 & before,
3738 & after,
3839 & HashSet :: new ( ) ,
40+ & HashSet :: new ( ) ,
3941 & BTreeSet :: new ( ) ,
4042 CommonExternalFilePolicy :: AssumeUpdated ,
4143 state,
@@ -53,22 +55,8 @@ pub(super) async fn shared_instance_publish_diffs(
5355 let after_configuration = local_configuration ( metadata) ;
5456 let modpack_unlinked = before_configuration. modpack_version_id . is_some ( )
5557 && after_configuration. modpack_version_id . is_none ( ) ;
56- let disabled_versions = async {
57- if snapshot. disabled_version_ids . is_empty ( ) {
58- Ok ( HashMap :: new ( ) )
59- } else {
60- shared_versions_by_project (
61- & snapshot. disabled_version_ids ,
62- true ,
63- state,
64- )
65- . await
66- }
67- } ;
68- let ( ( version_ids, external_files) , disabled_versions) = tokio:: try_join!(
69- remote_publish_content( version, modpack_unlinked, state) ,
70- disabled_versions,
71- ) ?;
58+ let ( version_ids, external_files) =
59+ remote_publish_content ( version, modpack_unlinked, state) . await ?;
7260 let before = SharedContentSnapshot {
7361 version_ids,
7462 external_files,
@@ -93,14 +81,11 @@ pub(super) async fn shared_instance_publish_diffs(
9381 . collect :: < crate :: Result < _ > > ( ) ?,
9482 configuration : after_configuration,
9583 } ;
96- let mut removed_disabled_project_ids =
97- snapshot. disabled_project_ids . clone ( ) ;
98- removed_disabled_project_ids. extend ( disabled_versions. into_keys ( ) ) ;
99-
10084 shared_content_diffs (
10185 & before,
10286 & after,
103- & removed_disabled_project_ids,
87+ & snapshot. disabled_project_ids ,
88+ & snapshot. disabled_version_ids . iter ( ) . cloned ( ) . collect ( ) ,
10489 & snapshot. disabled_external_files ,
10590 CommonExternalFilePolicy :: AssumeUnchanged ,
10691 state,
@@ -295,30 +280,24 @@ async fn shared_content_diffs(
295280 before : & SharedContentSnapshot ,
296281 after : & SharedContentSnapshot ,
297282 removed_disabled_project_ids : & HashSet < String > ,
283+ removed_disabled_version_ids : & HashSet < String > ,
298284 removed_disabled_external_files : & BTreeSet < ExternalFileKey > ,
299285 common_external_files : CommonExternalFilePolicy ,
300286 state : & State ,
301287) -> crate :: Result < Vec < SharedInstanceUpdateDiff > > {
302288 let ( before_versions, after_versions) = tokio:: try_join!(
303- shared_versions_by_project ( & before. version_ids, true , state) ,
304- shared_versions_by_project ( & after. version_ids, false , state) ,
289+ shared_versions_by_id ( & before. version_ids, true , state) ,
290+ shared_versions_by_id ( & after. version_ids, false , state) ,
305291 ) ?;
306- let to_snapshot =
307- |source : & SharedContentSnapshot ,
308- versions : & HashMap < String , crate :: state:: Version > | {
309- ContentSetSnapshot {
310- projects : versions
311- . iter ( )
312- . map ( |( project_id, version) | {
313- ( project_id. clone ( ) , version. id . clone ( ) )
314- } )
315- . collect ( ) ,
316- external_files : source. external_files . clone ( ) ,
317- }
318- } ;
319- let diff = diff_content_sets (
320- & to_snapshot ( before, & before_versions) ,
321- & to_snapshot ( after, & after_versions) ,
292+ let mut diff = diff_content_sets (
293+ & ContentSetSnapshot {
294+ projects : BTreeMap :: default ( ) ,
295+ external_files : before. external_files . clone ( ) ,
296+ } ,
297+ & ContentSetSnapshot {
298+ projects : BTreeMap :: default ( ) ,
299+ external_files : after. external_files . clone ( ) ,
300+ } ,
322301 & ContentSetDiffOptions {
323302 common_external_files,
324303 } ,
@@ -327,6 +306,52 @@ async fn shared_content_diffs(
327306 & before. configuration ,
328307 & after. configuration ,
329308 ) ) ;
309+ let project_ids = before_versions
310+ . values ( )
311+ . chain ( after_versions. values ( ) )
312+ . map ( |version| version. project_id . clone ( ) )
313+ . collect :: < BTreeSet < _ > > ( ) ;
314+ for project_id in project_ids {
315+ let removed = before_versions
316+ . values ( )
317+ . filter ( |version| {
318+ version. project_id == project_id
319+ && !after_versions. contains_key ( & version. id )
320+ } )
321+ . map ( |version| version. id . clone ( ) )
322+ . collect :: < BTreeSet < _ > > ( ) ;
323+ let added = after_versions
324+ . values ( )
325+ . filter ( |version| {
326+ version. project_id == project_id
327+ && !before_versions. contains_key ( & version. id )
328+ } )
329+ . map ( |version| version. id . clone ( ) )
330+ . collect :: < BTreeSet < _ > > ( ) ;
331+ // Only pair an unambiguous replacement; preserve every other version change.
332+ if removed. len ( ) == 1 && added. len ( ) == 1 {
333+ diff. content . push ( ContentSetDiffEntry :: Project {
334+ project_id,
335+ change : Change :: Updated {
336+ before : removed. into_iter ( ) . next ( ) . unwrap ( ) ,
337+ after : added. into_iter ( ) . next ( ) . unwrap ( ) ,
338+ } ,
339+ } ) ;
340+ } else {
341+ for before in removed {
342+ diff. content . push ( ContentSetDiffEntry :: Project {
343+ project_id : project_id. clone ( ) ,
344+ change : Change :: Removed { before } ,
345+ } ) ;
346+ }
347+ for after in added {
348+ diff. content . push ( ContentSetDiffEntry :: Project {
349+ project_id : project_id. clone ( ) ,
350+ change : Change :: Added { after } ,
351+ } ) ;
352+ }
353+ }
354+ }
330355 let resolved_before_ids = before_versions
331356 . values ( )
332357 . map ( |version| version. id . as_str ( ) )
@@ -367,7 +392,10 @@ async fn shared_content_diffs(
367392 match entry {
368393 ContentSetDiffEntry :: Project { project_id, change } => {
369394 let disabled = change. kind ( ) == ContentSetDiffKind :: Removed
370- && removed_disabled_project_ids. contains ( & project_id) ;
395+ && ( removed_disabled_project_ids. contains ( & project_id)
396+ || change. before ( ) . is_some_and ( |id| {
397+ removed_disabled_version_ids. contains ( id)
398+ } ) ) ;
371399 content_diffs. push ( SharedInstanceUpdateDiff {
372400 type_ : shared_update_diff_type ( change. kind ( ) ) ,
373401 project_name : Some (
@@ -378,13 +406,13 @@ async fn shared_content_diffs(
378406 ) ,
379407 current_version_name : change. before ( ) . map ( |id| {
380408 before_versions
381- . get ( & project_id )
409+ . get ( id )
382410 . map ( |version| version. version_number . clone ( ) )
383411 . unwrap_or_else ( || id. clone ( ) )
384412 } ) ,
385413 new_version_name : change. after ( ) . map ( |id| {
386414 after_versions
387- . get ( & project_id )
415+ . get ( id )
388416 . map ( |version| version. version_number . clone ( ) )
389417 . unwrap_or_else ( || id. clone ( ) )
390418 } ) ,
0 commit comments