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>
|
||||
<Content Include="favicon.ico" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="IPA\Fallback\" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- 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.
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace IPA.Patcher
|
|||
{
|
||||
class PatchedModule
|
||||
{
|
||||
private const string ENTRY_TYPE = "Display";
|
||||
private static readonly string[] ENTRY_TYPES = { "Input", "Display" };
|
||||
|
||||
private FileInfo _File;
|
||||
private ModuleDefinition _Module;
|
||||
|
@ -57,29 +57,43 @@ namespace IPA.Patcher
|
|||
// First, let's add the reference
|
||||
var nameReference = new AssemblyNameReference("IllusionInjector", new Version(1, 0, 0, 0));
|
||||
var injectorPath = Path.Combine(_File.DirectoryName, "IllusionInjector.dll");
|
||||
var injector = ModuleDefinition.ReadModule(injectorPath);
|
||||
|
||||
_Module.AssemblyReferences.Add(nameReference);
|
||||
var targetType = FindEntryType();
|
||||
|
||||
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)
|
||||
int patched = 0;
|
||||
foreach(var type in FindEntryTypes())
|
||||
{
|
||||
throw new Exception("Couldn't find entry method. Aborting.");
|
||||
if(PatchType(type, injector))
|
||||
{
|
||||
patched++;
|
||||
}
|
||||
}
|
||||
|
||||
var injector = ModuleDefinition.ReadModule(injectorPath);
|
||||
var methodReference = _Module.Import(injector.GetType("IllusionInjector.Injector").Methods.First(m => m.Name == "Inject"));
|
||||
|
||||
targetMethod.Body.Instructions.Insert(0, Instruction.Create(OpCodes.Call, methodReference));
|
||||
if(patched > 0)
|
||||
{
|
||||
_Module.Write(_File.FullName);
|
||||
} else
|
||||
{
|
||||
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 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,17 +49,25 @@ namespace IPA.Patcher
|
|||
{
|
||||
VirtualizeType(type);
|
||||
}
|
||||
|
||||
_Module.Write(_File.FullName);
|
||||
}
|
||||
|
||||
private void VirtualizeType(TypeDefinition type)
|
||||
{
|
||||
if (type.IsSealed) return;
|
||||
if(type.IsSealed)
|
||||
{
|
||||
// Unseal
|
||||
type.IsSealed = false;
|
||||
}
|
||||
|
||||
if (type.IsInterface) return;
|
||||
if (type.IsAbstract) return;
|
||||
|
||||
// These two don't seem to work.
|
||||
if (type.Name == "SceneControl" || type.Name == "ConfigUI") return;
|
||||
|
||||
Console.WriteLine("Virtualizing {0}", type.Name);
|
||||
// Take care of sub types
|
||||
foreach (var subType in type.NestedTypes)
|
||||
{
|
||||
|
@ -97,7 +105,10 @@ namespace IPA.Patcher
|
|||
{
|
||||
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 pluginsFolder = "Plugins";
|
||||
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 assemblyFile = Path.Combine(dataPath, "Assembly-Csharp.dll");
|
||||
|
||||
|
@ -35,11 +35,13 @@ namespace IPA
|
|||
try
|
||||
{
|
||||
// Copying
|
||||
Console.Write("Updating files... ");
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -47,21 +49,27 @@ namespace IPA
|
|||
var patchedModule = PatchedModule.Load(engineFile);
|
||||
if(!patchedModule.IsPatched)
|
||||
{
|
||||
Console.Write("Patching UnityEngine.dll... ");
|
||||
BackupManager.MakeBackup(engineFile);
|
||||
patchedModule.Patch();
|
||||
Console.WriteLine("Done!");
|
||||
}
|
||||
|
||||
// Virtualizing
|
||||
var virtualizedModule = VirtualizedModule.Load(assemblyFile);
|
||||
if(!virtualizedModule.IsVirtualized)
|
||||
{
|
||||
Console.Write("Virtualizing Assembly-Csharp.dll... ");
|
||||
BackupManager.MakeBackup(assemblyFile);
|
||||
virtualizedModule.Virtualize();
|
||||
Console.WriteLine("Done!");
|
||||
}
|
||||
} catch(Exception e)
|
||||
{
|
||||
Fail("Oops! This should not have happened.\n\n" + e);
|
||||
}
|
||||
|
||||
Console.WriteLine("Finished!");
|
||||
}
|
||||
|
||||
public static void CopyAll(DirectoryInfo source, DirectoryInfo target)
|
||||
|
|
Loading…
Reference in a new issue