Improve stability.

This commit is contained in:
Eusth 2017-01-08 17:49:11 +01:00
parent 687135d55f
commit 6e691c3071
4 changed files with 56 additions and 20 deletions

View file

@ -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.

View file

@ -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")); {
_Module.Write(_File.FullName);
} else
{
throw new Exception("Could not find any entry type!");
}
}
targetMethod.Body.Instructions.Insert(0, Instruction.Create(OpCodes.Call, methodReference)); private bool PatchType(TypeDefinition targetType, ModuleDefinition injector)
_Module.Write(_File.FullName); {
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 TypeDefinition FindEntryType() private IEnumerable<TypeDefinition> FindEntryTypes()
{ {
return _Module.GetTypes().FirstOrDefault(m => m.Name == ENTRY_TYPE); return _Module.GetTypes().Where(m => ENTRY_TYPES.Contains(m.Name));
} }
} }
} }

View file

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

View file

@ -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)