consider dependencies of client mods also as client mods to prevent spilling them into the world save
All checks were successful
Build / Compute Version (push) Successful in 5s
Build / Build Nuget package (push) Successful in 34s

This commit is contained in:
zznty
2025-05-14 16:14:59 +07:00
parent fe5776c2c5
commit 41f38444a5

View File

@@ -1,4 +1,5 @@
using System.Reflection.Emit;
using System.Collections.Immutable;
using System.Reflection.Emit;
using HarmonyLib;
using Sandbox.Definitions;
using Sandbox.Engine.Networking;
@@ -26,7 +27,31 @@ internal static class ModInjector
[HarmonyPostfix]
private static void DownloadModsBlockingPostfix(List<MyObjectBuilder_Checkpoint.ModItem> mods, List<MyObjectBuilder_Checkpoint.ModItem> __state)
{
foreach (var mod in mods)
var worldMods = __state.Select(b => b.PublishedFileId).ToImmutableHashSet();
var resolvedMods = mods.ToImmutableDictionary(b => b.PublishedFileId);
// list of selected mods which are resolved
var requestedMods = mods.IntersectBy(Mods, b => b.PublishedFileId)
.ToDictionary(b => b.PublishedFileId);
// add dependencies of requested mods
// but skip if those are also requested by world we're loading in
foreach (var dependency in requestedMods.Values
.SelectMany(b => b.GetModData().Dependencies)
.Distinct().ToArray())
{
if (worldMods.Contains(dependency))
continue;
requestedMods.TryAdd(dependency, resolvedMods[dependency]);
}
// add resolved client mods and their exclusive dependencies
AdditionalFilledModItems.AddRange(requestedMods.Values);
// upsert world mods by resolved ones excluding our client ones and their exclusive dependencies
// so world mods is only populated by dependencies of original world mods
foreach (var mod in mods.ExceptBy(requestedMods.Keys, b => b.PublishedFileId))
{
var index = __state.FindIndex(b =>
b.PublishedFileId == mod.PublishedFileId && b.PublishedServiceName == mod.PublishedServiceName);
@@ -37,8 +62,6 @@ internal static class ModInjector
stateMod.SetModData(mod.GetModData());
__state[index] = stateMod;
}
else if (Mods.Contains(mod.PublishedFileId))
AdditionalFilledModItems.Add(mod);
else
__state.Add(mod);
}
@@ -104,7 +127,7 @@ internal static class ModInjector
foreach (var mod in Mods)
{
//avoid duplicates
if (mods.FindIndex(m => m.PublishedFileId == mod) != -1)
if (mods.Exists(m => m.PublishedFileId == mod))
continue;
mods.Add(new MyObjectBuilder_Checkpoint.ModItem(mod, "Steam"));