Improve stability.
This commit is contained in:
parent
687135d55f
commit
6e691c3071
4 changed files with 56 additions and 20 deletions
|
@ -72,6 +72,9 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="favicon.ico" />
|
<Content Include="favicon.ico" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="IPA\Fallback\" />
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
Other similar extension points exist, see Microsoft.Common.targets.
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
|
|
@ -10,7 +10,7 @@ namespace IPA.Patcher
|
||||||
{
|
{
|
||||||
class PatchedModule
|
class PatchedModule
|
||||||
{
|
{
|
||||||
private const string ENTRY_TYPE = "Display";
|
private static readonly string[] ENTRY_TYPES = { "Input", "Display" };
|
||||||
|
|
||||||
private FileInfo _File;
|
private FileInfo _File;
|
||||||
private ModuleDefinition _Module;
|
private ModuleDefinition _Module;
|
||||||
|
@ -57,29 +57,43 @@ namespace IPA.Patcher
|
||||||
// First, let's add the reference
|
// First, let's add the reference
|
||||||
var nameReference = new AssemblyNameReference("IllusionInjector", new Version(1, 0, 0, 0));
|
var nameReference = new AssemblyNameReference("IllusionInjector", new Version(1, 0, 0, 0));
|
||||||
var injectorPath = Path.Combine(_File.DirectoryName, "IllusionInjector.dll");
|
var injectorPath = Path.Combine(_File.DirectoryName, "IllusionInjector.dll");
|
||||||
|
var injector = ModuleDefinition.ReadModule(injectorPath);
|
||||||
|
|
||||||
_Module.AssemblyReferences.Add(nameReference);
|
_Module.AssemblyReferences.Add(nameReference);
|
||||||
var targetType = FindEntryType();
|
int patched = 0;
|
||||||
|
foreach(var type in FindEntryTypes())
|
||||||
if (targetType == null) throw new Exception("Couldn't find entry class. Aborting.");
|
|
||||||
|
|
||||||
var targetMethod = targetType.Methods.FirstOrDefault(m => m.IsConstructor && m.IsStatic);
|
|
||||||
if (targetMethod == null)
|
|
||||||
{
|
{
|
||||||
throw new Exception("Couldn't find entry method. Aborting.");
|
if(PatchType(type, injector))
|
||||||
|
{
|
||||||
|
patched++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var injector = ModuleDefinition.ReadModule(injectorPath);
|
if(patched > 0)
|
||||||
var methodReference = _Module.Import(injector.GetType("IllusionInjector.Injector").Methods.First(m => m.Name == "Inject"));
|
{
|
||||||
|
|
||||||
targetMethod.Body.Instructions.Insert(0, Instruction.Create(OpCodes.Call, methodReference));
|
|
||||||
_Module.Write(_File.FullName);
|
_Module.Write(_File.FullName);
|
||||||
}
|
} else
|
||||||
|
|
||||||
|
|
||||||
private TypeDefinition FindEntryType()
|
|
||||||
{
|
{
|
||||||
return _Module.GetTypes().FirstOrDefault(m => m.Name == ENTRY_TYPE);
|
throw new Exception("Could not find any entry type!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool PatchType(TypeDefinition targetType, ModuleDefinition injector)
|
||||||
|
{
|
||||||
|
var targetMethod = targetType.Methods.FirstOrDefault(m => m.IsConstructor && m.IsStatic);
|
||||||
|
if (targetMethod != null)
|
||||||
|
{
|
||||||
|
var methodReference = _Module.Import(injector.GetType("IllusionInjector.Injector").Methods.First(m => m.Name == "Inject"));
|
||||||
|
targetMethod.Body.Instructions.Insert(0, Instruction.Create(OpCodes.Call, methodReference));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private IEnumerable<TypeDefinition> FindEntryTypes()
|
||||||
|
{
|
||||||
|
return _Module.GetTypes().Where(m => ENTRY_TYPES.Contains(m.Name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,17 +49,25 @@ namespace IPA.Patcher
|
||||||
{
|
{
|
||||||
VirtualizeType(type);
|
VirtualizeType(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_Module.Write(_File.FullName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void VirtualizeType(TypeDefinition type)
|
private void VirtualizeType(TypeDefinition type)
|
||||||
{
|
{
|
||||||
if (type.IsSealed) return;
|
if(type.IsSealed)
|
||||||
|
{
|
||||||
|
// Unseal
|
||||||
|
type.IsSealed = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (type.IsInterface) return;
|
if (type.IsInterface) return;
|
||||||
if (type.IsAbstract) return;
|
if (type.IsAbstract) return;
|
||||||
|
|
||||||
// These two don't seem to work.
|
// These two don't seem to work.
|
||||||
if (type.Name == "SceneControl" || type.Name == "ConfigUI") return;
|
if (type.Name == "SceneControl" || type.Name == "ConfigUI") return;
|
||||||
|
|
||||||
|
Console.WriteLine("Virtualizing {0}", type.Name);
|
||||||
// Take care of sub types
|
// Take care of sub types
|
||||||
foreach (var subType in type.NestedTypes)
|
foreach (var subType in type.NestedTypes)
|
||||||
{
|
{
|
||||||
|
@ -97,7 +105,10 @@ namespace IPA.Patcher
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return _Module.GetTypes().SelectMany(t => t.Methods.Where(m => m.Name == "Awake")).All(m => m.IsVirtual);
|
var awakeMethods = _Module.GetTypes().SelectMany(t => t.Methods.Where(m => m.Name == "Awake"));
|
||||||
|
if (awakeMethods.Count() == 0) return false;
|
||||||
|
|
||||||
|
return ((float)awakeMethods.Count(m => m.IsVirtual) / awakeMethods.Count()) > 0.5f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ namespace IPA
|
||||||
string managedFolder = Path.Combine("IPA", "Managed");
|
string managedFolder = Path.Combine("IPA", "Managed");
|
||||||
string pluginsFolder = "Plugins";
|
string pluginsFolder = "Plugins";
|
||||||
string projectName = Path.GetFileNameWithoutExtension(args[0]);
|
string projectName = Path.GetFileNameWithoutExtension(args[0]);
|
||||||
string dataPath = Path.Combine(Path.Combine(Environment.CurrentDirectory, projectName + "_Data"), "Managed");
|
string dataPath = Path.Combine(Path.Combine(Path.GetDirectoryName(args[0]), projectName + "_Data"), "Managed");
|
||||||
string engineFile = Path.Combine(dataPath, "UnityEngine.dll");
|
string engineFile = Path.Combine(dataPath, "UnityEngine.dll");
|
||||||
string assemblyFile = Path.Combine(dataPath, "Assembly-Csharp.dll");
|
string assemblyFile = Path.Combine(dataPath, "Assembly-Csharp.dll");
|
||||||
|
|
||||||
|
@ -35,11 +35,13 @@ namespace IPA
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Copying
|
// Copying
|
||||||
|
Console.Write("Updating files... ");
|
||||||
CopyAll(new DirectoryInfo(managedFolder), new DirectoryInfo(dataPath));
|
CopyAll(new DirectoryInfo(managedFolder), new DirectoryInfo(dataPath));
|
||||||
Console.WriteLine("Successfully copied files!");
|
Console.WriteLine("Successfully updated files!");
|
||||||
|
|
||||||
if (!Directory.Exists(pluginsFolder))
|
if (!Directory.Exists(pluginsFolder))
|
||||||
{
|
{
|
||||||
|
Console.WriteLine("Creating plugins folder... ");
|
||||||
Directory.CreateDirectory(pluginsFolder);
|
Directory.CreateDirectory(pluginsFolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,21 +49,27 @@ namespace IPA
|
||||||
var patchedModule = PatchedModule.Load(engineFile);
|
var patchedModule = PatchedModule.Load(engineFile);
|
||||||
if(!patchedModule.IsPatched)
|
if(!patchedModule.IsPatched)
|
||||||
{
|
{
|
||||||
|
Console.Write("Patching UnityEngine.dll... ");
|
||||||
BackupManager.MakeBackup(engineFile);
|
BackupManager.MakeBackup(engineFile);
|
||||||
patchedModule.Patch();
|
patchedModule.Patch();
|
||||||
|
Console.WriteLine("Done!");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Virtualizing
|
// Virtualizing
|
||||||
var virtualizedModule = VirtualizedModule.Load(assemblyFile);
|
var virtualizedModule = VirtualizedModule.Load(assemblyFile);
|
||||||
if(!virtualizedModule.IsVirtualized)
|
if(!virtualizedModule.IsVirtualized)
|
||||||
{
|
{
|
||||||
|
Console.Write("Virtualizing Assembly-Csharp.dll... ");
|
||||||
BackupManager.MakeBackup(assemblyFile);
|
BackupManager.MakeBackup(assemblyFile);
|
||||||
virtualizedModule.Virtualize();
|
virtualizedModule.Virtualize();
|
||||||
|
Console.WriteLine("Done!");
|
||||||
}
|
}
|
||||||
} catch(Exception e)
|
} catch(Exception e)
|
||||||
{
|
{
|
||||||
Fail("Oops! This should not have happened.\n\n" + e);
|
Fail("Oops! This should not have happened.\n\n" + e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Console.WriteLine("Finished!");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void CopyAll(DirectoryInfo source, DirectoryInfo target)
|
public static void CopyAll(DirectoryInfo source, DirectoryInfo target)
|
||||||
|
|
Loading…
Reference in a new issue