Browse Source

Fixed installer application to NOT reinstall every time, to be prettier, and to actually INSTALL when in the install dir

pull/46/head
Anairkoen Schno 6 years ago
parent
commit
98118c619a
13 changed files with 96 additions and 67 deletions
  1. +1
    -0
      IPA.Tests/IPA.Tests.csproj
  2. +8
    -5
      IPA/Arguments.cs
  3. +1
    -0
      IPA/IPA.csproj
  4. +0
    -1
      IPA/PatchContext.cs
  5. +4
    -2
      IPA/Patcher/BackupUnit.cs
  6. +16
    -3
      IPA/Patcher/Patcher.cs
  7. +6
    -1
      IPA/Patcher/Virtualizer.cs
  8. +54
    -52
      IPA/Program.cs
  9. +2
    -2
      IPA/Properties/AssemblyInfo.cs
  10. +1
    -0
      IllusionInjector/IllusionInjector.csproj
  11. +1
    -1
      IllusionInjector/Updating/SelfPlugin.cs
  12. +1
    -0
      IllusionPlugin/IllusionPlugin.csproj
  13. +1
    -0
      MSBuildTasks/MSBuildTasks.csproj

+ 1
- 0
IPA.Tests/IPA.Tests.csproj View File

@ -32,6 +32,7 @@
<DefineConstants>TRACE</DefineConstants> <DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<UseVSHostingProcess>true</UseVSHostingProcess>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="System" /> <Reference Include="System" />


+ 8
- 5
IPA/Arguments.cs View File

@ -21,7 +21,7 @@ namespace IPA.ArgParsing
private Arguments(string[] args) private Arguments(string[] args)
{ {
toParse = args;
toParse = args.Skip(1).ToArray();
} }
public Arguments Flags(params ArgumentFlag[] toAdd) public Arguments Flags(params ArgumentFlag[] toAdd)
@ -145,8 +145,8 @@ namespace IPA.ArgParsing
public void PrintHelp() public void PrintHelp()
{ {
const string indent = " "; const string indent = " ";
string filename = Path.GetFileName(Assembly.GetExecutingAssembly().Location);
string format = @"help:
string filename = Environment.GetCommandLineArgs()[0];
string format = @"usage:
{2}{0} [FLAGS] [ARGUMENTS] {2}{0} [FLAGS] [ARGUMENTS]
flags: flags:
@ -154,9 +154,9 @@ flags:
var flagsBuilder = new StringBuilder(); var flagsBuilder = new StringBuilder();
foreach (var flag in flagObjects) foreach (var flag in flagObjects)
{ {
flagsBuilder.AppendFormat("{2}{0}{1}",
flagsBuilder.AppendFormat("{2}{0}{3}{1}",
string.Join(", ", flag.shortFlags.Select(s => $"-{s}").Concat( flag.longFlags.Select(s => $"--{s}")) ), string.Join(", ", flag.shortFlags.Select(s => $"-{s}").Concat( flag.longFlags.Select(s => $"--{s}")) ),
Environment.NewLine, indent);
Environment.NewLine, indent, flag.ValueString != null ? "=" + flag.ValueString : "");
flagsBuilder.AppendFormat("{2}{2}{0}{1}", flag.DocString, Environment.NewLine, indent); flagsBuilder.AppendFormat("{2}{2}{0}{1}", flag.DocString, Environment.NewLine, indent);
} }
@ -191,7 +191,10 @@ flags:
public bool Exists => exists; public bool Exists => exists;
public string Value => value; public string Value => value;
public bool HasValue => Exists && Value != null;
public string DocString { get; set; } = ""; public string DocString { get; set; } = "";
public string ValueString { get; set; } = null;
public static implicit operator bool(ArgumentFlag f) public static implicit operator bool(ArgumentFlag f)
{ {


+ 1
- 0
IPA/IPA.csproj View File

@ -34,6 +34,7 @@
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit> <Prefer32Bit>false</Prefer32Bit>
<UseVSHostingProcess>true</UseVSHostingProcess>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<ApplicationIcon>favicon.ico</ApplicationIcon> <ApplicationIcon>favicon.ico</ApplicationIcon>


+ 0
- 1
IPA/PatchContext.cs View File

@ -22,7 +22,6 @@ namespace IPA
public string LibsPathDst { get; private set; } public string LibsPathDst { get; private set; }
public string ManagedPath { get; private set; } public string ManagedPath { get; private set; }
public string EngineFile { get; private set; } public string EngineFile { get; private set; }
public string EngineWebRequestFile { get; private set; }
public string AssemblyFile { get; private set; } public string AssemblyFile { get; private set; }
public string ProjectRoot { get; private set; } public string ProjectRoot { get; private set; }
public string IPARoot { get; private set; } public string IPARoot { get; private set; }


+ 4
- 2
IPA/Patcher/BackupUnit.cs View File

@ -110,7 +110,8 @@ namespace IPA.Patcher
Console.WriteLine(" {0} => {1}", backupFile.FullName, target.FullName); Console.WriteLine(" {0} => {1}", backupFile.FullName, target.FullName);
target.Directory.Create(); target.Directory.Create();
backupFile.CopyTo(target.FullName, true); backupFile.CopyTo(target.FullName, true);
} else
}
else
{ {
Console.WriteLine(" x {0}", target.FullName); Console.WriteLine(" x {0}", target.FullName);
if(target.Exists) if(target.Exists)
@ -118,7 +119,8 @@ namespace IPA.Patcher
target.Delete(); target.Delete();
} }
} }
} else {
} else
{
Console.Error.WriteLine("Backup not found!"); Console.Error.WriteLine("Backup not found!");
} }
} }


+ 16
- 3
IPA/Patcher/Patcher.cs View File

@ -49,21 +49,34 @@ namespace IPA.Patcher
{ {
get get
{ {
var IIdata = new PatchData { IsPatched = false, Version = null };
foreach (var @ref in _Module.AssemblyReferences) { foreach (var @ref in _Module.AssemblyReferences) {
if (@ref.Name == "IllusionInjector") return new PatchData { IsPatched = true, Version = @ref.Version};
if (@ref.Name == "IllusionInjector") IIdata = new PatchData { IsPatched = true, Version = new Version(0,0,0,0) };
if (@ref.Name == "IllusionPlugin") return new PatchData { IsPatched = true, Version = @ref.Version };
} }
return new PatchData { IsPatched = false, Version = null};
return IIdata;
} }
} }
public void Patch(Version v) public void Patch(Version v)
{ {
// First, let's add the reference // First, let's add the reference
var nameReference = new AssemblyNameReference("IllusionInjector", v);
var nameReference = new AssemblyNameReference("IllusionInjector", new Version(1,0,0,0));
var versionNameReference = new AssemblyNameReference("IllusionPlugin", v);
var injectorPath = Path.Combine(_File.DirectoryName, "IllusionInjector.dll"); var injectorPath = Path.Combine(_File.DirectoryName, "IllusionInjector.dll");
var injector = ModuleDefinition.ReadModule(injectorPath); var injector = ModuleDefinition.ReadModule(injectorPath);
for (int i = 0; i < _Module.AssemblyReferences.Count; i++)
{
if (_Module.AssemblyReferences[i].Name == "IllusionInjector")
_Module.AssemblyReferences.RemoveAt(i--);
if (_Module.AssemblyReferences[i].Name == "IllusionPlugin")
_Module.AssemblyReferences.RemoveAt(i--);
}
_Module.AssemblyReferences.Add(nameReference); _Module.AssemblyReferences.Add(nameReference);
_Module.AssemblyReferences.Add(versionNameReference);
int patched = 0; int patched = 0;
foreach(var type in FindEntryTypes()) foreach(var type in FindEntryTypes())
{ {


+ 6
- 1
IPA/Patcher/Virtualizer.cs View File

@ -45,10 +45,12 @@ namespace IPA.Patcher
/// <param name="module"></param> /// <param name="module"></param>
public void Virtualize() public void Virtualize()
{ {
foreach (var type in _Module.Types) foreach (var type in _Module.Types)
{ {
VirtualizeType(type); VirtualizeType(type);
} }
Console.WriteLine();
_Module.Write(_File.FullName); _Module.Write(_File.FullName);
} }
@ -67,7 +69,10 @@ namespace IPA.Patcher
// 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);
//Console.CursorTop--;
Console.CursorLeft = 0;
Program.ClearLine();
Console.Write("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)
{ {


+ 54
- 52
IPA/Program.cs View File

@ -21,13 +21,13 @@ namespace IPA {
private static Version Version => Assembly.GetEntryAssembly().GetName().Version; private static Version Version => Assembly.GetEntryAssembly().GetName().Version;
public static ArgumentFlag ArgHelp = new ArgumentFlag("--help", "-h") { DocString = "prints this message" };
public static ArgumentFlag ArgWaitFor = new ArgumentFlag("--waitfor") { DocString = "waits for the specified PID to exit" };
public static ArgumentFlag ArgForce = new ArgumentFlag("--force", "-f") { DocString = "forces the operation to go through" };
public static ArgumentFlag ArgRevert = new ArgumentFlag("--revert") { DocString = "reverts the IPA installation" };
public static ArgumentFlag ArgNoWait = new ArgumentFlag("--nowait") { DocString = "doesn't wait for user input after the operation" };
public static ArgumentFlag ArgStart = new ArgumentFlag("--start") { DocString = "uses value as arguments to start the game after the patch/unpatch" };
public static ArgumentFlag ArgLaunch = new ArgumentFlag("--launch") { DocString = "uses positional parameters as arguments to start the game after patch/unpatch" };
public static ArgumentFlag ArgHelp = new ArgumentFlag("--help", "-h") { DocString = "prints this message" };
public static ArgumentFlag ArgWaitFor = new ArgumentFlag("--waitfor", "-w") { DocString = "waits for the specified PID to exit", ValueString = "PID" };
public static ArgumentFlag ArgForce = new ArgumentFlag("--force", "-f") { DocString = "forces the operation to go through" };
public static ArgumentFlag ArgRevert = new ArgumentFlag("--revert", "-r") { DocString = "reverts the IPA installation" };
public static ArgumentFlag ArgNoWait = new ArgumentFlag("--nowait", "-n") { DocString = "doesn't wait for user input after the operation" };
public static ArgumentFlag ArgStart = new ArgumentFlag("--start", "-s") { DocString = "uses value as arguments to start the game after the patch/unpatch", ValueString = "ARGUMENTS" };
public static ArgumentFlag ArgLaunch = new ArgumentFlag("--launch", "-l") { DocString = "uses positional parameters as arguments to start the game after patch/unpatch" };
static void Main(string[] args) static void Main(string[] args)
{ {
@ -41,8 +41,8 @@ namespace IPA {
try try
{ {
if (ArgWaitFor && ArgWaitFor.Value != null)
{
if (ArgWaitFor.HasValue)
{ // wait for process if necessary
int pid = int.Parse(ArgWaitFor.Value); int pid = int.Parse(ArgWaitFor.Value);
try try
@ -57,29 +57,20 @@ namespace IPA {
} }
PatchContext context; PatchContext context;
var argExeName = Arguments.CmdLine.PositionalArgs.FirstOrDefault(s => s.EndsWith(".exe")); var argExeName = Arguments.CmdLine.PositionalArgs.FirstOrDefault(s => s.EndsWith(".exe"));
if (argExeName == null) if (argExeName == null)
{
//Fail("Drag an (executable) file on the exe!");
context = PatchContext.Create(new DirectoryInfo(Directory.GetCurrentDirectory()).GetFiles() context = PatchContext.Create(new DirectoryInfo(Directory.GetCurrentDirectory()).GetFiles()
.First(o => o.FullName.EndsWith(".exe"))
.First(o => o.Extension == ".exe" && o.FullName != Assembly.GetCallingAssembly().Location)
.FullName); .FullName);
}
else else
{
context = PatchContext.Create(argExeName); context = PatchContext.Create(argExeName);
}
bool isRevert = ArgRevert || Keyboard.IsKeyDown(Keys.LMenu);
// Sanitizing // Sanitizing
Validate(context); Validate(context);
if (isRevert)
{
if (ArgRevert || Keyboard.IsKeyDown(Keys.LMenu))
Revert(context); Revert(context);
}
else else
{ {
Install(context); Install(context);
@ -89,6 +80,19 @@ namespace IPA {
catch (Exception e) { catch (Exception e) {
Fail(e.Message); Fail(e.Message);
} }
WaitForEnd();
}
private static void WaitForEnd()
{
if (!ArgNoWait)
{
Console.ForegroundColor = ConsoleColor.DarkYellow;
Console.WriteLine("[Press any key to continue]");
Console.ResetColor();
Console.ReadLine();
}
} }
private static void Validate(PatchContext c) { private static void Validate(PatchContext c) {
@ -113,7 +117,7 @@ namespace IPA {
Console.WriteLine( Console.WriteLine(
$"Preparing for update, {(patchedModule.Data.Version == null ? "UnPatched" : patchedModule.Data.Version.ToString())} => {Version}"); $"Preparing for update, {(patchedModule.Data.Version == null ? "UnPatched" : patchedModule.Data.Version.ToString())} => {Version}");
Console.WriteLine("--- Starting ---"); Console.WriteLine("--- Starting ---");
Revert(context, new[] {"newVersion"});
Revert(context);
Console.ResetColor(); Console.ResetColor();
@ -179,7 +183,7 @@ namespace IPA {
if (File.Exists(context.AssemblyFile)) { if (File.Exists(context.AssemblyFile)) {
var virtualizedModule = VirtualizedModule.Load(context.AssemblyFile); var virtualizedModule = VirtualizedModule.Load(context.AssemblyFile);
if (!virtualizedModule.IsVirtualized) { if (!virtualizedModule.IsVirtualized) {
Console.ForegroundColor = ConsoleColor.Blue;
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("Virtualizing Assembly-Csharp.dll... "); Console.WriteLine("Virtualizing Assembly-Csharp.dll... ");
backup.Add(context.AssemblyFile); backup.Add(context.AssemblyFile);
virtualizedModule.Virtualize(); virtualizedModule.Virtualize();
@ -191,45 +195,40 @@ namespace IPA {
#endregion #endregion
#region Creating shortcut #region Creating shortcut
/*if(!File.Exists(context.ShortcutPath))
if(!File.Exists(context.ShortcutPath))
{ {
Console.Write("Creating shortcut to IPA ({0})... ", context.IPA);
Console.ForegroundColor = ConsoleColor.DarkGreen;
Console.WriteLine("Creating shortcut to IPA ({0})... ", context.IPA);
try try
{ {
Shortcut.Create( Shortcut.Create(
fileName: context.ShortcutPath, fileName: context.ShortcutPath,
targetPath: context.IPA, targetPath: context.IPA,
arguments: Args(context.Executable, "--launch"),
arguments: Args(context.Executable, "-ln"),
workingDirectory: context.ProjectRoot, workingDirectory: context.ProjectRoot,
description: "Launches the game and makes sure it's in a patched state", description: "Launches the game and makes sure it's in a patched state",
hotkey: "", hotkey: "",
iconPath: context.Executable iconPath: context.Executable
); );
Console.WriteLine("Created");
} catch (Exception e)
} catch (Exception)
{ {
Console.ForegroundColor = ConsoleColor.Red;
Console.Error.WriteLine("Failed to create shortcut, but game was patched!"); Console.Error.WriteLine("Failed to create shortcut, but game was patched!");
} }
}*/
Console.ResetColor();
}
#endregion #endregion
} }
catch (Exception e) {
Fail("Oops! This should not have happened.\n\n" + e);
}
if (!ArgNoWait)
catch (Exception e)
{ {
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("Finished!");
Console.ResetColor();
Console.ReadLine();
Console.ForegroundColor = ConsoleColor.Red;
Fail("Oops! This should not have happened.\n\n" + e);
} }
Console.ResetColor();
} }
private static void Revert(PatchContext context, string[] args = null) {
private static void Revert(PatchContext context) {
Console.ForegroundColor = ConsoleColor.Cyan; Console.ForegroundColor = ConsoleColor.Cyan;
bool isNewVersion = (args != null && args.Contains("newVersion"));
Console.Write("Restoring backup... "); Console.Write("Restoring backup... ");
if (BackupManager.Restore(context)) { if (BackupManager.Restore(context)) {
@ -248,16 +247,11 @@ namespace IPA {
Console.WriteLine(""); Console.WriteLine("");
Console.WriteLine("--- Done reverting ---"); Console.WriteLine("--- Done reverting ---");
if (!ArgNoWait && !isNewVersion) {
Console.WriteLine("\n\n[Press any key to quit]");
Console.ReadKey();
}
Console.ResetColor(); Console.ResetColor();
} }
private static void StartIfNeedBe(PatchContext context) { private static void StartIfNeedBe(PatchContext context) {
if (ArgStart && ArgStart.Value != null)
if (ArgStart.HasValue)
{ {
Process.Start(context.Executable, ArgStart.Value); Process.Start(context.Executable, ArgStart.Value);
} }
@ -315,6 +309,14 @@ namespace IPA {
} }
} }
public static void ClearLine()
{
Console.SetCursorPosition(0, Console.CursorTop);
int tpos = Console.CursorTop;
Console.Write(new string(' ', Console.WindowWidth));
Console.SetCursorPosition(0, tpos);
}
private static IEnumerable<FileInfo> PassThroughInterceptor(FileInfo from, FileInfo to) { private static IEnumerable<FileInfo> PassThroughInterceptor(FileInfo from, FileInfo to) {
yield return to; yield return to;
} }
@ -331,6 +333,8 @@ namespace IPA {
if (!targetFile.Exists || targetFile.LastWriteTimeUtc < fi.LastWriteTimeUtc || aggressive) { if (!targetFile.Exists || targetFile.LastWriteTimeUtc < fi.LastWriteTimeUtc || aggressive) {
targetFile.Directory.Create(); targetFile.Directory.Create();
Console.CursorTop--;
ClearLine();
Console.WriteLine(@"Copying {0}", targetFile.FullName); Console.WriteLine(@"Copying {0}", targetFile.FullName);
backup.Add(targetFile); backup.Add(targetFile);
fi.CopyTo(targetFile.FullName, true); fi.CopyTo(targetFile.FullName, true);
@ -348,10 +352,8 @@ namespace IPA {
static void Fail(string message) { static void Fail(string message) {
Console.Error.Write("ERROR: " + message); Console.Error.Write("ERROR: " + message);
if (!ArgNoWait) {
Console.WriteLine("\n\n[Press any key to quit]");
Console.ReadKey();
}
WaitForEnd();
Environment.Exit(1); Environment.Exit(1);
} }


+ 2
- 2
IPA/Properties/AssemblyInfo.cs View File

@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("3.8.8.*")]
[assembly: AssemblyFileVersion("3.8.8")]
[assembly: AssemblyVersion("3.8.9.*")]
[assembly: AssemblyFileVersion("3.8.9")]

+ 1
- 0
IllusionInjector/IllusionInjector.csproj View File

@ -36,6 +36,7 @@
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit> <Prefer32Bit>false</Prefer32Bit>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<UseVSHostingProcess>true</UseVSHostingProcess>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="I18N"> <Reference Include="I18N">


+ 1
- 1
IllusionInjector/Updating/SelfPlugin.cs View File

@ -12,7 +12,7 @@ namespace IllusionInjector.Updating
internal class SelfPlugin : IBeatSaberPlugin internal class SelfPlugin : IBeatSaberPlugin
{ {
internal const string IPA_Name = "Beat Saber IPA"; internal const string IPA_Name = "Beat Saber IPA";
internal const string IPA_Version = "3.8.8";
internal const string IPA_Version = "3.8.9";
public string Name => IPA_Name; public string Name => IPA_Name;


+ 1
- 0
IllusionPlugin/IllusionPlugin.csproj View File

@ -33,6 +33,7 @@
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<DocumentationFile>bin\Release\IllusionPlugin.XML</DocumentationFile> <DocumentationFile>bin\Release\IllusionPlugin.XML</DocumentationFile>
<Prefer32Bit>false</Prefer32Bit> <Prefer32Bit>false</Prefer32Bit>
<UseVSHostingProcess>true</UseVSHostingProcess>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="System" /> <Reference Include="System" />


+ 1
- 0
MSBuildTasks/MSBuildTasks.csproj View File

@ -29,6 +29,7 @@
<DefineConstants>TRACE</DefineConstants> <DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<UseVSHostingProcess>true</UseVSHostingProcess>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="Microsoft.Build.Framework, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> <Reference Include="Microsoft.Build.Framework, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">


Loading…
Cancel
Save