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); }
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)); }