A fork of Eusth's IPA
25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.

119 satır
3.2KB

  1. using System;
  2. using System.IO;
  3. using System.Linq;
  4. using Mono.Cecil;
  5. namespace IPA.Patcher
  6. {
  7. internal class VirtualizedModule
  8. {
  9. private const string ENTRY_TYPE = "Display";
  10. private FileInfo _File;
  11. private ModuleDefinition _Module;
  12. public static VirtualizedModule Load(string engineFile)
  13. {
  14. return new VirtualizedModule(engineFile);
  15. }
  16. private VirtualizedModule(string assemblyFile)
  17. {
  18. _File = new FileInfo(assemblyFile);
  19. LoadModules();
  20. }
  21. private void LoadModules()
  22. {
  23. var resolver = new DefaultAssemblyResolver();
  24. resolver.AddSearchDirectory(_File.DirectoryName);
  25. var parameters = new ReaderParameters
  26. {
  27. AssemblyResolver = resolver,
  28. };
  29. _Module = ModuleDefinition.ReadModule(_File.FullName, parameters);
  30. }
  31. /// <summary>
  32. ///
  33. /// </summary>
  34. /// <param name="module"></param>
  35. public void Virtualize()
  36. {
  37. foreach (var type in _Module.Types)
  38. {
  39. VirtualizeType(type);
  40. }
  41. _Module.Write(_File.FullName);
  42. }
  43. private void VirtualizeType(TypeDefinition type)
  44. {
  45. if (type.IsSealed)
  46. {
  47. // Unseal
  48. type.IsSealed = false;
  49. }
  50. if (type.IsInterface)
  51. return;
  52. if (type.IsAbstract)
  53. return;
  54. // These two don't seem to work.
  55. if (type.Name == "SceneControl" || type.Name == "ConfigUI")
  56. return;
  57. Console.WriteLine("Virtualizing {0}", type.Name);
  58. // Take care of sub types
  59. foreach (var subType in type.NestedTypes)
  60. {
  61. VirtualizeType(subType);
  62. }
  63. foreach (var method in type.Methods)
  64. {
  65. if (method.IsManaged
  66. && method.IsIL
  67. && !method.IsStatic
  68. && !method.IsVirtual
  69. && !method.IsAbstract
  70. && !method.IsAddOn
  71. && !method.IsConstructor
  72. && !method.IsSpecialName
  73. && !method.IsGenericInstance
  74. && !method.HasOverrides)
  75. {
  76. method.IsVirtual = true;
  77. method.IsPublic = true;
  78. method.IsPrivate = false;
  79. method.IsNewSlot = true;
  80. method.IsHideBySig = true;
  81. }
  82. }
  83. foreach (var field in type.Fields)
  84. {
  85. if (field.IsPrivate)
  86. field.IsFamily = true;
  87. }
  88. }
  89. public bool IsVirtualized
  90. {
  91. get
  92. {
  93. var awakeMethods = _Module.GetTypes().SelectMany(t => t.Methods.Where(m => m.Name == "Awake"));
  94. if (awakeMethods.Count() == 0)
  95. return false;
  96. return ((float)awakeMethods.Count(m => m.IsVirtual) / awakeMethods.Count()) > 0.5f;
  97. }
  98. }
  99. }
  100. }