public static void OpenDnspy(MethodBase method)
        {
            if (string.IsNullOrEmpty(Settings.PathToDnspy))
            {
                Log.ErrorOnce("[Analyzer] You have not given a local path to dnspy", 10293838);
                return;
            }

            var meth = method;
            var path = meth.DeclaringType.Assembly.Location;

            if (path == null || path.Length == 0)
            {
                var contentPack = LoadedModManager.RunningMods.FirstOrDefault(m =>
                                                                              m.assemblies.loadedAssemblies.Contains(meth.DeclaringType.Assembly));
                if (contentPack != null)
                {
                    path = ModContentPack
                           .GetAllFilesForModPreserveOrder(contentPack, "Assemblies/", p => p.ToLower() == ".dll")
                           .Select(fileInfo => fileInfo.Item2.FullName)
                           .First(dll =>
                    {
                        var assembly = Assembly.ReflectionOnlyLoadFrom(dll);
                        return(assembly.GetType(meth.DeclaringType.FullName) != null);
                    });
                }
            }

            var token = meth.MetadataToken;

            if (token != 0)
            {
                Process.Start(Settings.PathToDnspy, $"\"{path}\" --select 0x{token:X8}");
            }
        }
        public List <string> LoadAllFiles(string folderPath)
        {
            var list = new List <string>();

            foreach (ModContentPack mod in LoadedModManager.RunningModsListForReading)
            {
                foreach (var f in ModContentPack.GetAllFilesForModPreserveOrder(mod, "Textures/"))
                {
                    var fullPath = f.Item2.Directory.FullName;
                    fullPath = fullPath.Replace("\\", "/");
                    if (fullPath.EndsWith("Textures/" + folderPath))
                    {
                        var path = f.Item2.FullName;
                        if (path.EndsWith(".png"))
                        {
                            path = path.Replace("\\", "/");
                            path = path.Substring(path.IndexOf("/Textures/") + 10);
                            path = path.Replace(".png", "");
                            list.Add(path);
                        }
                    }
                }
            }
            return(list);
        }
Пример #3
0
        public static void PresentMenu()
        {
            var elements = calls.Values.ToList();

            calls.Clear();

            if (elements.Count == 0)
            {
                return;
            }
            elements.Sort(new Element.Comparer());

            var mouse = UI.MousePositionOnUI;

            FloatMenuUtility.MakeMenu(elements.AsEnumerable(), element => element.GetPath(GUILocator.Settings.numberOfMethodsToDisplay), element => delegate()
            {
                var options = element.trace
                              .GetFrames()
                              .Skip(1)
                              .Select(f => f.GetRealMethod())
                              .Select(member =>
                {
                    var path = member.DeclaringType.Assembly.Location;
                    if (path == null || path.Length == 0)
                    {
                        var contentPack = LoadedModManager.RunningMods.FirstOrDefault(m => m.assemblies.loadedAssemblies.Contains(member.DeclaringType.Assembly));
                        if (contentPack != null)
                        {
                            path = ModContentPack.GetAllFilesForModPreserveOrder(contentPack, "Assemblies/", p => p.ToLower() == ".dll", null)
                                   .Select(fileInfo => fileInfo.Item2.FullName)
                                   .First(dll =>
                            {
                                var assembly = Assembly.ReflectionOnlyLoadFrom(dll);
                                return(assembly.GetType(member.DeclaringType.FullName) != null);
                            });
                        }
                    }

                    var option = Misc.FloatMenuOption(Element.MethodString(member), delegate()
                    {
                        var token = member.MetadataToken;
                        if (token != 0)
                        {
                            _ = Process.Start(GUILocator.Settings.dnSpyPath, $"\"{path}\" --select 0x{token:X8}");
                        }
                    });
                    option.Disabled = member.MetadataToken == 0;
                    return(option);
                });
                if (options.Any())
                {
                    Find.WindowStack.Add(new FloatMenu(options.ToList()));
                }
            });
        }
        static void LoadConditional(ModContentPack content)
        {
            var asmPath = ModContentPack
                          .GetAllFilesForModPreserveOrder(content, "Referenced/", f => f.ToLower() == ".dll")
                          .FirstOrDefault(f => f.Item2.Name == "Multiplayer_Compat_Referenced.dll")?.Item2;

            if (asmPath == null)
            {
                return;
            }

            var asm = AssemblyDefinition.ReadAssembly(asmPath.FullName);

            foreach (var t in asm.MainModule.GetTypes().ToArray())
            {
                var attr = t.CustomAttributes
                           .Where(a => a.Constructor.DeclaringType.Name is nameof(MpCompatForAttribute) or nameof(MpCompatRequireModAttribute))
                           .ToArray();
                if (!attr.Any())
                {
                    continue;
                }

                var anyMod = attr.Any(a =>
                {
                    var modId = ((string)a.ConstructorArguments.First().Value).ToLower();
                    var mod   = LoadedModManager.RunningMods.FirstOrDefault(m => m.PackageId.NoModIdSuffix() == modId);
                    return(mod != null);
                });

                if (!anyMod)
                {
                    asm.MainModule.Types.Remove(t);
                }
            }

            var stream = new MemoryStream();

            asm.Write(stream);

            var loadedAsm = AppDomain.CurrentDomain.Load(stream.ToArray());

            content.assemblies.loadedAssemblies.Add(loadedAsm);
            // As we're adding the new assembly, the classes added by it aren't included by the MP GenTypes AllSubclasses/AllSubclassesNonAbstract optimization
            // GenTypes.ClearCache() won't work, as MP isn't doing anything when it's called
            var mpType = AccessTools.TypeByName("Multiplayer.Client.Multiplayer");

            ((IDictionary)AccessTools.Field(mpType, "subClasses").GetValue(null)).Clear();
            ((IDictionary)AccessTools.Field(mpType, "subClassesNonAbstract").GetValue(null)).Clear();
            ((IDictionary)AccessTools.Field(mpType, "implementations").GetValue(null)).Clear();
            AccessTools.Method(mpType, "CacheTypeHierarchy").Invoke(null, Array.Empty <object>());
        }
        static void BuildReference(string refsFolder, FileInfo request)
        {
            var asmId = Path.GetFileNameWithoutExtension(request.Name);

            var assembly = LoadedModManager.RunningModsListForReading
                           .SelectMany(m => ModContentPack.GetAllFilesForModPreserveOrder(m, "Assemblies/", f => f.ToLower() == ".dll"))
                           .FirstOrDefault(f => f.Item2.Name == asmId + ".dll")?.Item2;

            var hash     = ComputeHash(assembly.FullName);
            var hashFile = Path.Combine(refsFolder, asmId + ".txt");

            if (File.Exists(hashFile) && File.ReadAllText(hashFile) == hash)
            {
                return;
            }

            Console.WriteLine($"MpCompat References: Writing {asmId}.dll");

            var outFile = Path.Combine(refsFolder, asmId + ".dll");
            var asmDef  = AssemblyDefinition.ReadAssembly(assembly.FullName);

            foreach (var t in asmDef.MainModule.GetTypes())
            {
                if (t.IsNested)
                {
                    t.IsNestedPublic = true;
                }
                else
                {
                    t.IsPublic = true;
                }

                foreach (var m in t.Methods)
                {
                    m.IsPublic = true;
                    m.Body     = new Mono.Cecil.Cil.MethodBody(m);
                }

                foreach (var f in t.Fields)
                {
                    f.IsInitOnly = false;
                    f.IsPublic   = true;
                }
            }

            asmDef.Write(outFile);
            File.WriteAllText(hashFile, hash);
        }
 public static IEnumerable <FileInfo> ModListAssemblies(this ModContentPack mod)
 {
     return(ModContentPack.GetAllFilesForModPreserveOrder(mod, "Assemblies/", (string e) => e.ToLower() == ".dll", null)
            .Select(t => t.Item2));
 }