Skip to content
This repository has been archived by the owner on Jul 26, 2021. It is now read-only.

Commit

Permalink
Improve multi platform support, fix signatures again
Browse files Browse the repository at this point in the history
  • Loading branch information
js6pak committed Feb 16, 2021
1 parent 81696bc commit f2631d3
Show file tree
Hide file tree
Showing 16 changed files with 315 additions and 144 deletions.
8 changes: 8 additions & 0 deletions Reactor.Greenhouse/Extensions.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using Mono.Cecil;

Expand Down Expand Up @@ -36,5 +38,11 @@ public static TimeSpan Time(this Action action)
_stopwatch.Stop();
return _stopwatch.Elapsed;
}

public static void ForceExtractToFile(this ZipArchiveEntry source, string destinationFileName)
{
Directory.GetParent(destinationFileName)!.Create();
source.ExtractToFile(destinationFileName, true);
}
}
}
12 changes: 2 additions & 10 deletions Reactor.Greenhouse/Generation/TypeContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,7 @@ public MappedType ToMappedType(TypeDefinition obfuscatedType)
{
var matched = matching.Single();

mappedType.Methods.Add(new MappedMethod(new OriginalDescriptor
{
Name = matched.Name,
Signature = matched.GetSignature()
}, cleanMethod.Name));
mappedType.Methods.Add(new MappedMethod(matched, cleanMethod.Name));
}
}

Expand Down Expand Up @@ -153,11 +149,7 @@ public MappedType ToMappedType(TypeDefinition obfuscatedType)

if (methodMatch.Success)
{
nested.Methods.Add(new MappedMethod(new OriginalDescriptor
{
Name = nestedMethod.Name,
Signature = nestedMethod.GetSignature()
}, methodMatch.Groups[1].Value));
nested.Methods.Add(new MappedMethod(nestedMethod, methodMatch.Groups[1].Value));
}
}

Expand Down
50 changes: 15 additions & 35 deletions Reactor.Greenhouse/Program.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.CommandLine;
using System.CommandLine.Invocation;
using System.IO;
using System.Linq;
using System.Reflection;
Expand All @@ -12,31 +10,25 @@
using Newtonsoft.Json.Serialization;
using Reactor.Greenhouse.Generation;
using Reactor.Greenhouse.Setup;
using Reactor.Greenhouse.Setup.Provider;
using Reactor.OxygenFilter;

namespace Reactor.Greenhouse
{
internal static class Program
{
private static Task<int> Main(string[] args)
public static async Task Main(string[] args)
{
var rootCommand = new RootCommand
if (!args.Any())
{
new Option<bool>("steam"),
new Option<bool>("itch"),
};
Console.WriteLine("No game versions used!");
return;
}

rootCommand.Handler = CommandHandler.Create<bool, bool>(GenerateAsync);
var gameVersions = args.Select(x => new GameVersion(x)).ToArray();

return rootCommand.InvokeAsync(args);
}
var gameManager = new GameManager(gameVersions);

public static async Task GenerateAsync(bool steam, bool itch)
{
var gameManager = new GameManager();

await gameManager.SetupAsync(steam, itch);
await gameManager.SetupAsync();

JsonConvert.DefaultSettings = () => new JsonSerializerSettings
{
Expand All @@ -50,42 +42,30 @@ public static async Task GenerateAsync(bool steam, bool itch)
Console.WriteLine($"Generating mappings from {oldFile}");
using var cleanModule = ModuleDefinition.ReadModule(File.OpenRead(oldFile));

if (!steam && !itch)
{
Console.WriteLine("No game providers used! (use --help for more info)");
return;
}

if (steam)
{
await GenerateAsync(gameManager.Steam, cleanModule);
}

if (itch)
foreach (var game in gameManager.Games)
{
await GenerateAsync(gameManager.Itch, cleanModule);
await GenerateAsync(game, cleanModule);
}
}

private static async Task GenerateAsync(Game game, ModuleDefinition cleanModule)
{
Console.WriteLine($"Compiling mappings for {game.Name} ({game.Version})");
var version = game.Provider.Version;
Console.WriteLine($"Compiling mappings for {game.Name} ({version})");

using var moduleDef = ModuleDefinition.ReadModule(File.OpenRead(game.Dll));
var version = game.Version;
var postfix = game.Postfix;

var generated = Generator.Generate(new GenerationContext(cleanModule, moduleDef));

await File.WriteAllTextAsync(Path.Combine("work", version + postfix + ".generated.json"), JsonConvert.SerializeObject(generated, Formatting.Indented));
await File.WriteAllTextAsync(Path.Combine("work", version + ".generated.json"), JsonConvert.SerializeObject(generated, Formatting.Indented));

Apply(generated, Path.Combine("universal.json"));
Apply(generated, Path.Combine(version + postfix + ".json"));
Apply(generated, Path.Combine(version + ".json"));

generated.Compile(moduleDef);

Directory.CreateDirectory(Path.Combine("bin"));
await File.WriteAllTextAsync(Path.Combine("bin", version + postfix + ".json"), JsonConvert.SerializeObject(generated));
await File.WriteAllTextAsync(Path.Combine("bin", version + ".json"), JsonConvert.SerializeObject(generated));
}

private static void Apply(Mappings generated, string file)
Expand Down
1 change: 0 additions & 1 deletion Reactor.Greenhouse/Reactor.Greenhouse.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
<PackageReference Include="Iced" Version="1.10.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="5.0.0" />
<PackageReference Include="Mono.Cecil" Version="0.11.3" />
<PackageReference Include="System.CommandLine" Version="2.0.0-beta1.20574.7" />
<ProjectReference Include="..\Reactor.OxygenFilter\Reactor.OxygenFilter.csproj" />
<PackageReference Include="js6pak.Il2CppDumper" Version="6.4.20" />
</ItemGroup>
Expand Down
32 changes: 21 additions & 11 deletions Reactor.Greenhouse/Setup/Game.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,14 @@ public class Game
{
public BaseProvider Provider { get; }
public string Name { get; }
public char Postfix { get; }
public string Path { get; }
public string Dll { get; }
public string Version { get; private set; }

public Game(BaseProvider provider, string name, string path)
{
Provider = provider;
provider.Game = this;
Name = name;
Postfix = char.ToLowerInvariant(name[0]);
Path = path;
Dll = IOPath.Combine(Path, "DummyDll", "Assembly-CSharp.dll");
}
Expand All @@ -32,31 +29,44 @@ public async Task DownloadAsync()
{
Provider.Setup();
await Provider.DownloadAsync();
UpdateVersion();
CheckVersion();
}

public void UpdateVersion()
public void CheckVersion()
{
if (Version != null)
return;
if (Provider.Version.Platform == GamePlatform.Android)
{
return; // TODO
}

var version = GameVersionParser.Parse(System.IO.Path.Combine(Path, "Among Us_Data", "globalgamemanagers"));

Version = GameVersionParser.Parse(System.IO.Path.Combine(Path, "Among Us_Data", "globalgamemanagers"));
if (!Provider.Version.Equals(new GameVersion(version), true))
{
throw new Exception("Downloaded game has invalid version");
}
}

public void Dump()
{
Console.WriteLine($"Dumping {Name}");

var hash = ComputeHash(IOPath.Combine(Path, "GameAssembly.dll"));
var hashFile = IOPath.Combine(Path, "Assembly-CSharp.dll.md5");
var gameAssembly = Provider.Version.Platform switch
{
GamePlatform.Android => "libil2cpp.so",
_ => "GameAssembly.dll"
};

var hash = ComputeHash(IOPath.Combine(Path, gameAssembly));
var hashFile = IOPath.Combine(Path, gameAssembly + ".md5");

if (File.Exists(hashFile) && File.ReadAllText(hashFile) == hash)
{
return;
}

if (!Il2CppDumper.Il2CppDumper.PerformDump(
IOPath.Combine(Path, "GameAssembly.dll"),
IOPath.Combine(Path, gameAssembly),
IOPath.Combine(Path, "Among Us_Data", "il2cpp_data", "Metadata", "global-metadata.dat"),
Path,
new Config
Expand Down
59 changes: 21 additions & 38 deletions Reactor.Greenhouse/Setup/GameManager.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using DepotDownloader;
using Reactor.Greenhouse.Setup.Provider;
Expand All @@ -10,58 +11,40 @@ public class GameManager
{
public string WorkPath { get; }

public Game Steam { get; }
public Game Itch { get; }
public Game[] Games { get; }

public GameManager()
public GameManager(GameVersion[] gameVersions)
{
WorkPath = Path.GetFullPath("work");
Steam = new Game(new SteamProvider(false), "steam", Path.Combine(WorkPath, "steam"));
Itch = new Game(new ItchProvider(), "itch", Path.Combine(WorkPath, "itch"));

Games = gameVersions.Select(gameVersion => new Game(
gameVersion.Platform switch
{
GamePlatform.Steam => new SteamProvider(gameVersion),
GamePlatform.Itch => new ItchProvider(gameVersion),
GamePlatform.Android => new AndroidProvider(gameVersion),
_ => throw new ArgumentOutOfRangeException(nameof(gameVersions))
}, gameVersion.ToString(), Path.Combine(WorkPath, gameVersion.ToString())
)).ToArray();
}

public async Task SetupAsync(bool setupSteam, bool setupItch)
public async Task SetupAsync()
{
var steam = setupSteam && Steam.Provider.IsUpdateNeeded();
var itch = setupItch && Itch.Provider.IsUpdateNeeded();

if (steam || itch)
foreach (var game in Games)
{
ContentDownloader.ShutdownSteam3();

if (steam)
if (game.Provider.IsUpdateNeeded())
{
await Steam.DownloadAsync();
Console.WriteLine($"Downloaded {nameof(Steam)} ({Steam.Version})");
}

if (itch)
{
await Itch.DownloadAsync();
Console.WriteLine($"Downloaded {nameof(Itch)} ({Itch.Version})");
await game.DownloadAsync();
Console.WriteLine($"Downloaded {game.Provider.Version}");
}
}

ContentDownloader.ShutdownSteam3();

if (setupSteam)
{
Steam.UpdateVersion();
}

if (setupItch)
{
Itch.UpdateVersion();
}

if (setupSteam)
{
Steam.Dump();
}

if (setupItch)
foreach (var game in Games)
{
Itch.Dump();
game.CheckVersion();
game.Dump();
}
}
}
Expand Down
75 changes: 75 additions & 0 deletions Reactor.Greenhouse/Setup/GameVersion.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
using System;
using System.Text.RegularExpressions;

namespace Reactor.Greenhouse.Setup
{
public class GameVersion
{
private static readonly Regex _regex = new Regex(@"^(?<major>[0-9]+)\.(?<minor>[0-9]+)\.(?<patch>[0-9]+)(?<platform>[sia])?", RegexOptions.Compiled);

public static GamePlatform GamePlatformFromShorthand(string shorthand)
{
return shorthand switch
{
"s" => GamePlatform.Steam,
"i" => GamePlatform.Itch,
"a" => GamePlatform.Android,
_ => throw new ArgumentOutOfRangeException(nameof(shorthand))
};
}

public int Major { get; }
public int Minor { get; }
public int Patch { get; }
public GamePlatform? Platform { get; }

public GameVersion(string version)
{
var match = _regex.Match(version);

Major = int.Parse(match.Groups["major"].Value);
Minor = int.Parse(match.Groups["minor"].Value);
Patch = int.Parse(match.Groups["patch"].Value);

var platform = match.Groups["platform"];
Platform = platform.Success && !string.IsNullOrEmpty(platform.Value) ? GamePlatformFromShorthand(platform.Value) : null;
}

public override string ToString()
{
return $"{Major}.{Minor}.{Patch}" + Platform switch
{
GamePlatform.Steam => "s",
GamePlatform.Itch => "i",
GamePlatform.Android => "a",
null => string.Empty,
_ => throw new ArgumentOutOfRangeException()
};
}

public bool Equals(GameVersion other, bool ignorePlatform = false)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;

return Major == other.Major && Minor == other.Minor && Patch == other.Patch && (ignorePlatform || Platform == other.Platform);
}

public override bool Equals(object obj)
{
return Equals((GameVersion) obj);
}

public override int GetHashCode()
{
return HashCode.Combine(Major, Minor, Patch, Platform);
}
}

public enum GamePlatform
{
Steam,
Itch,
Android
}
}
Loading

0 comments on commit f2631d3

Please sign in to comment.