Browse Source

Improve stability.

tags/3.0d
Eusth 8 years ago
parent
commit
6e691c3071
4 changed files with 55 additions and 19 deletions
  1. +3
    -0
      IPA/IPA.csproj
  2. +28
    -14
      IPA/Patcher/Patcher.cs
  3. +13
    -2
      IPA/Patcher/Virtualizer.cs
  4. +11
    -3
      IPA/Program.cs

+ 3
- 0
IPA/IPA.csproj View File

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


+ 28
- 14
IPA/Patcher/Patcher.cs View File

@@ -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.");
int patched = 0;
foreach(var type in FindEntryTypes())
{
if(PatchType(type, injector))
{
patched++;
}
}
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)
if (targetMethod != null)
{
throw new Exception("Couldn't find entry method. Aborting.");
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;
}

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));
_Module.Write(_File.FullName);
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));
}
}
}

+ 13
- 2
IPA/Patcher/Virtualizer.cs View File

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


+ 11
- 3
IPA/Program.cs View File

@@ -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…
Cancel
Save