internal static void EnsureSyncedDependencyStability(TopoSort <LoadingMod> synced, TopoSort <LoadingMod> full) { var errored = new HashSet <LoadingMod>(); var errorLog = new StringBuilder(); foreach (var mod in synced.list) { var chains = new List <List <LoadingMod> >(); //define recursive chain finding method Action <LoadingMod, Stack <LoadingMod> > FindChains = null; FindChains = (search, stack) => { stack.Push(search); if (search.properties.side == ModSide.Both && stack.Count > 1) { if (stack.Count > 2) //direct Both -> Both references are ignored { chains.Add(stack.Reverse().ToList()); } } else { //recursively build the chain, all entries in stack should be unsynced foreach (var dep in full.Dependencies(search)) { FindChains(dep, stack); } } stack.Pop(); }; FindChains(mod, new Stack <LoadingMod>()); if (chains.Count == 0) { continue; } var syncedDependencies = synced.AllDependencies(mod); foreach (var chain in chains) { if (!syncedDependencies.Contains(chain.Last())) { errored.Add(mod); errorLog.AppendLine(mod + " indirectly depends on " + chain.Last() + " via " + string.Join(" -> ", chain)); } } } if (errored.Count > 0) { errorLog.AppendLine("Some of these mods may not exist on both client and server. Add a direct sort entries or weak references."); throw new ModSortingException(errored, errorLog.ToString()); } }
internal static void ResizeArrays() { var positions = Layers.ToDictionary(l => l, l => l.GetDefaultPosition()); PlayerHooks.ModifyDrawLayerOrdering(positions); // net core please!! //foreach (var (layer, pos) in positions.ToArray()) { foreach (var kv in positions.ToArray()) { var layer = kv.Key; switch (kv.Value) { case Between _: continue; case BeforeParent b: b.Parent.AddChildBefore(layer); break; case AfterParent a: a.Parent.AddChildAfter(layer); break; case Multiple m: int slot = 0; foreach (var(pos, cond) in m.Positions) { positions.Add(new PlayerDrawLayerSlot(layer, cond, slot++), pos); } break; default: throw new ArgumentException($"PlayerDrawLayer {layer} has unknown Position type {kv.Value}"); } positions.Remove(kv.Key); } var sort = new TopoSort <PlayerDrawLayer>(positions.Keys, l => new[] { ((Between)positions[l]).Layer1 }.Where(l => l != null), l => new[] { ((Between)positions[l]).Layer2 }.Where(l => l != null)); _drawOrder = sort.Sort().ToArray(); }