Ejemplo n.º 1
0
        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());
            }
        }
Ejemplo n.º 2
0
        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();
        }