mirror of
https://github.com/NuclearPowered/Reactor.OxygenFilter.git
synced 2026-10-19 15:52:01 +00:00
Improve multi platform support, fix signatures again
This commit is contained in:
16 files changed
+324
-153
No files matched your search
@@ -1,5 +1,7 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using Mono.Cecil;
|
||||
|
||||
@@ -36,5 +38,11 @@ namespace Reactor.Greenhouse
|
||||
_stopwatch.Stop();
|
||||
return _stopwatch.Elapsed;
|
||||
}
|
||||
|
||||
public static void ForceExtractToFile(this ZipArchiveEntry source, string destinationFileName)
|
||||
{
|
||||
Directory.GetParent(destinationFileName)!.Create();
|
||||
source.ExtractToFile(destinationFileName, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -102,11 +102,7 @@ namespace Reactor.Greenhouse.Generation
|
||||
{
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,11 +149,7 @@ namespace Reactor.Greenhouse.Generation
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
@@ -12,31 +10,25 @@ using Newtonsoft.Json;
|
||||
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
|
||||
{
|
||||
@@ -50,42 +42,30 @@ namespace Reactor.Greenhouse
|
||||
Console.WriteLine($"Generating mappings from {oldFile}");
|
||||
using var cleanModule = ModuleDefinition.ReadModule(File.OpenRead(oldFile));
|
||||
|
||||
if (!steam && !itch)
|
||||
foreach (var game in gameManager.Games)
|
||||
{
|
||||
Console.WriteLine("No game providers used! (use --help for more info)");
|
||||
return;
|
||||
}
|
||||
|
||||
if (steam)
|
||||
{
|
||||
await GenerateAsync(gameManager.Steam, cleanModule);
|
||||
}
|
||||
|
||||
if (itch)
|
||||
{
|
||||
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)
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -13,17 +13,14 @@ namespace Reactor.Greenhouse.Setup
|
||||
{
|
||||
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");
|
||||
}
|
||||
@@ -32,23 +29,36 @@ namespace Reactor.Greenhouse.Setup
|
||||
{
|
||||
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
|
||||
}
|
||||
|
||||
Version = GameVersionParser.Parse(System.IO.Path.Combine(Path, "Among Us_Data", "globalgamemanagers"));
|
||||
var 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)
|
||||
{
|
||||
@@ -56,7 +66,7 @@ namespace Reactor.Greenhouse.Setup
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using DepotDownloader;
|
||||
using Reactor.Greenhouse.Setup.Provider;
|
||||
@@ -10,58 +11,40 @@ namespace Reactor.Greenhouse.Setup
|
||||
{
|
||||
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)
|
||||
foreach (var game in Games)
|
||||
{
|
||||
Steam.UpdateVersion();
|
||||
}
|
||||
|
||||
if (setupItch)
|
||||
{
|
||||
Itch.UpdateVersion();
|
||||
}
|
||||
|
||||
if (setupSteam)
|
||||
{
|
||||
Steam.Dump();
|
||||
}
|
||||
|
||||
if (setupItch)
|
||||
{
|
||||
Itch.Dump();
|
||||
game.CheckVersion();
|
||||
game.Dump();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Reactor.Greenhouse.Setup.Provider
|
||||
{
|
||||
public class AndroidProvider : BaseProvider
|
||||
{
|
||||
private Dictionary<GameVersion, string> VersionMap { get; } = new Dictionary<GameVersion, string>
|
||||
{
|
||||
[new GameVersion("2020.11.17a")] = "https://www.apkmirror.com/wp-content/themes/APKMirror/download.php?id=1753109"
|
||||
};
|
||||
|
||||
public string DownloadUrl { get; }
|
||||
|
||||
public AndroidProvider(GameVersion version) : base(version)
|
||||
{
|
||||
DownloadUrl = VersionMap[version];
|
||||
}
|
||||
|
||||
private HttpClient HttpClient { get; } = new HttpClient();
|
||||
|
||||
public override void Setup()
|
||||
{
|
||||
}
|
||||
|
||||
public override async Task DownloadAsync()
|
||||
{
|
||||
using var zipArchive = new ZipArchive(await HttpClient.GetStreamAsync(DownloadUrl), ZipArchiveMode.Read);
|
||||
|
||||
zipArchive.GetEntry("lib/arm64-v8a/libil2cpp.so")!
|
||||
.ForceExtractToFile(Path.Combine(Game.Path, "libil2cpp.so"));
|
||||
|
||||
zipArchive.GetEntry("assets/bin/Data/Managed/Metadata/global-metadata.dat")!
|
||||
.ForceExtractToFile(Path.Combine(Game.Path, "Among Us_Data", "il2cpp_data", "Metadata", "global-metadata.dat"));
|
||||
}
|
||||
|
||||
public override bool IsUpdateNeeded()
|
||||
{
|
||||
return !Directory.Exists(Game.Path);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,12 @@ namespace Reactor.Greenhouse.Setup.Provider
|
||||
public abstract class BaseProvider
|
||||
{
|
||||
public Game Game { get; internal set; }
|
||||
public GameVersion Version { get; }
|
||||
|
||||
protected BaseProvider(GameVersion version)
|
||||
{
|
||||
Version = version;
|
||||
}
|
||||
|
||||
public abstract void Setup();
|
||||
public abstract Task DownloadAsync();
|
||||
|
||||
@@ -16,6 +16,18 @@ namespace Reactor.Greenhouse.Setup.Provider
|
||||
{
|
||||
public class ItchProvider : BaseProvider
|
||||
{
|
||||
private Dictionary<GameVersion, int> VersionMap { get; } = new Dictionary<GameVersion, int>
|
||||
{
|
||||
[new GameVersion("2020.11.17i")] = 1047908,
|
||||
};
|
||||
|
||||
public int UploadId { get; }
|
||||
|
||||
public ItchProvider(GameVersion version) : base(version)
|
||||
{
|
||||
UploadId = VersionMap[version];
|
||||
}
|
||||
|
||||
private HttpClient HttpClient { get; } = new HttpClient(new HttpClientHandler
|
||||
{
|
||||
CookieContainer = new CookieContainer()
|
||||
@@ -71,7 +83,7 @@ namespace Reactor.Greenhouse.Setup.Provider
|
||||
var downloadPageUrl = ((IHtmlAnchorElement) pageDocument.QuerySelector("a[class=button]")).Href;
|
||||
|
||||
var downloadDocument = htmlParser.ParseDocument(await HttpClient.GetStringAsync(downloadPageUrl));
|
||||
var uploadId = ((IHtmlAnchorElement) downloadDocument.QuerySelector("a[class='button download_btn']")).Dataset["upload_id"];
|
||||
// var uploadId = ((IHtmlAnchorElement) downloadDocument.QuerySelector("a[class='button download_btn']")).Dataset["upload_id"];
|
||||
|
||||
var keyRegex = new Regex("key\":\"(.+)\",");
|
||||
var key = downloadDocument.QuerySelectorAll("script[type='text/javascript']")
|
||||
@@ -80,7 +92,7 @@ namespace Reactor.Greenhouse.Setup.Provider
|
||||
.Single(x => x.Success)
|
||||
.Groups[1].Value;
|
||||
|
||||
var json = await HttpClient.PostAsync($"https://innersloth.itch.io/among-us/file/{uploadId}?key={key}", null);
|
||||
var json = await HttpClient.PostAsync($"https://innersloth.itch.io/among-us/file/{UploadId}?key={key}", null);
|
||||
var response = JsonConvert.DeserializeObject<DownloadResponse>(await json.Content.ReadAsStringAsync());
|
||||
|
||||
Console.WriteLine($"Downloading {response.Url}");
|
||||
@@ -91,10 +103,8 @@ namespace Reactor.Greenhouse.Setup.Provider
|
||||
{
|
||||
if (files.Contains(entry.Name))
|
||||
{
|
||||
var path = Path.Combine("work", "itch", entry.FullName.Substring(entry.FullName.IndexOf("/", StringComparison.Ordinal) + 1));
|
||||
|
||||
Directory.GetParent(path)!.Create();
|
||||
entry.ExtractToFile(path, true);
|
||||
var path = Path.Combine(Game.Path, entry.FullName[(entry.FullName.IndexOf("/", StringComparison.Ordinal) + 1)..]);
|
||||
entry.ForceExtractToFile(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using DepotDownloader;
|
||||
using SteamKit2;
|
||||
|
||||
namespace Reactor.Greenhouse.Setup.Provider
|
||||
{
|
||||
@@ -12,43 +11,37 @@ namespace Reactor.Greenhouse.Setup.Provider
|
||||
{
|
||||
private const uint AppId = 945360;
|
||||
private const uint DepotId = 945361;
|
||||
private const ulong PreObfuscationManifest = 3596575937380717449;
|
||||
|
||||
public bool IsPreObfuscation { get; }
|
||||
|
||||
public SteamProvider(bool isPreObfuscation)
|
||||
private Dictionary<GameVersion, ulong> VersionMap { get; } = new Dictionary<GameVersion, ulong>
|
||||
{
|
||||
IsPreObfuscation = isPreObfuscation;
|
||||
[new GameVersion("2019.10.10s")] = 3162069540887216240,
|
||||
[new GameVersion("2020.12.9s")] = 3306639722673334636
|
||||
};
|
||||
|
||||
public ulong Manifest { get; }
|
||||
|
||||
public SteamProvider(GameVersion version) : base(version)
|
||||
{
|
||||
Manifest = VersionMap[version];
|
||||
}
|
||||
|
||||
public override bool IsUpdateNeeded()
|
||||
{
|
||||
DepotConfigStore.LoadFromFile(Path.Combine(Game.Path, ".DepotDownloader", "depot.config"));
|
||||
if (DepotConfigStore.Instance.InstalledManifestIDs.TryGetValue(DepotId, out var installedManifest))
|
||||
try
|
||||
{
|
||||
if (IsPreObfuscation)
|
||||
DepotConfigStore.LoadFromFile(Path.Combine(Game.Path, ".DepotDownloader", "depot.config"));
|
||||
if (DepotConfigStore.Instance.InstalledManifestIDs.TryGetValue(DepotId, out var installedManifest))
|
||||
{
|
||||
if (installedManifest == PreObfuscationManifest)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ContentDownloader.steam3 == null)
|
||||
{
|
||||
ContentDownloader.InitializeSteam3();
|
||||
}
|
||||
|
||||
ContentDownloader.steam3!.RequestAppInfo(AppId);
|
||||
|
||||
var depots = ContentDownloader.GetSteam3AppSection(AppId, EAppInfoSection.Depots);
|
||||
if (installedManifest == depots[DepotId.ToString()]["manifests"][ContentDownloader.DEFAULT_BRANCH].AsUnsignedLong())
|
||||
if (installedManifest == Manifest)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
ContentDownloader.ShutdownSteam3();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -114,7 +107,7 @@ namespace Reactor.Greenhouse.Setup.Provider
|
||||
public override Task DownloadAsync()
|
||||
{
|
||||
ContentDownloader.Config.InstallDirectory = Game.Path;
|
||||
return ContentDownloader.DownloadAppAsync(AppId, DepotId, IsPreObfuscation ? PreObfuscationManifest : ContentDownloader.INVALID_MANIFEST_ID);
|
||||
return ContentDownloader.DownloadAppAsync(AppId, DepotId, Manifest);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@
|
||||
<LangVersion>latest</LangVersion>
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
|
||||
<Version>0.2.6</Version>
|
||||
<Version>0.2.7</Version>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<RepositoryUrl>https://github.com/NuclearPowered/Reactor.OxygenFilter</RepositoryUrl>
|
||||
<PackageLicenseExpression>LGPL-3.0-or-later</PackageLicenseExpression>
|
||||
|
||||
@@ -229,8 +229,28 @@ namespace Reactor.OxygenFilter.MSBuild
|
||||
}
|
||||
|
||||
// get same method from obfuscated assembly
|
||||
var signature = deobfuscatedCall.GetSignature(t => GetObfuscated(t) ?? t.FullName);
|
||||
MethodReference definition = typeDefinition.GetMethods().Single(x => x.Name == obfuscated && x.GetSignature() == signature);
|
||||
var nameMatched = typeDefinition.GetMethods().Where(x => x.Name == obfuscated).ToArray();
|
||||
|
||||
var signature = deobfuscatedCall.GetSignature((member, original) =>
|
||||
{
|
||||
if (member is TypeReference typeReference && typeReference.Scope.Name == "Assembly-CSharp.dll-Deobfuscated")
|
||||
{
|
||||
var resolved = typeReference.Resolve();
|
||||
if (resolved != null)
|
||||
{
|
||||
var s = GetObfuscated(resolved);
|
||||
|
||||
if (s != null)
|
||||
{
|
||||
return s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return original;
|
||||
});
|
||||
|
||||
MethodReference definition = nameMatched.Length <= 1 ? nameMatched.Single() : nameMatched.Single(x => x.GetSignature() == signature);
|
||||
|
||||
// obfuscate generics
|
||||
if (deobfuscatedCallReference is GenericInstanceMethod generic)
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Reflection.Emit;
|
||||
using System.Text;
|
||||
using Mono.Cecil;
|
||||
|
||||
@@ -7,34 +9,72 @@ namespace Reactor.OxygenFilter
|
||||
{
|
||||
public static class Extensions
|
||||
{
|
||||
private static readonly PropertyInfo _suffix = typeof(ArrayType).GetProperty("Suffix", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
|
||||
private static readonly Func<TypeSpecification, string> _callBaseFullName;
|
||||
|
||||
static Extensions()
|
||||
{
|
||||
var dynamicMethod = new DynamicMethod("CallBaseFullname", typeof(string), new[] { typeof(TypeSpecification) }, typeof(Extensions));
|
||||
var il = dynamicMethod.GetILGenerator();
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
il.Emit(OpCodes.Call, typeof(TypeSpecification).GetProperty(nameof(TypeSpecification.FullName))!.GetMethod);
|
||||
il.Emit(OpCodes.Ret);
|
||||
|
||||
_callBaseFullName = (Func<TypeSpecification, string>) dynamicMethod.CreateDelegate(typeof(Func<TypeSpecification, string>));
|
||||
}
|
||||
|
||||
public delegate string MapDelegate(MemberReference member, string original);
|
||||
|
||||
public static void AppendMappedFullName(this StringBuilder sb, MemberReference member, MapDelegate map = null)
|
||||
{
|
||||
map ??= (_, original) => original;
|
||||
|
||||
if (member is TypeSpecification typeSpecification)
|
||||
{
|
||||
sb.Append(map(typeSpecification, _callBaseFullName(typeSpecification)));
|
||||
|
||||
if (typeSpecification is GenericInstanceType genericInstanceType)
|
||||
{
|
||||
sb.Append("<");
|
||||
var arguments = genericInstanceType.GenericArguments;
|
||||
for (var i = 0; i < arguments.Count; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
sb.Append(",");
|
||||
|
||||
sb.AppendMappedFullName(arguments[i], map);
|
||||
}
|
||||
|
||||
sb.Append(">");
|
||||
}
|
||||
|
||||
if (typeSpecification is ArrayType arrayType)
|
||||
{
|
||||
sb.Append((string) _suffix.GetValue(arrayType));
|
||||
}
|
||||
|
||||
if (typeSpecification is ByReferenceType)
|
||||
{
|
||||
sb.Append("&");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append(map(member, member.FullName));
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsObfuscated(this string text)
|
||||
{
|
||||
return text.Length == 11 && text.All(char.IsUpper);
|
||||
}
|
||||
|
||||
public static string GetSignature(this MethodDefinition methodDefinition, Func<TypeDefinition, string> map = null)
|
||||
public static string GetSignature(this MethodDefinition methodDefinition, MapDelegate map = null)
|
||||
{
|
||||
map ??= provider => provider.FullName;
|
||||
|
||||
string MapIfResolved(TypeReference typeReference)
|
||||
{
|
||||
TypeDefinition resolved = null;
|
||||
|
||||
try
|
||||
{
|
||||
resolved = typeReference.Resolve();
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
return resolved != null ? map(resolved) : typeReference.FullName;
|
||||
}
|
||||
|
||||
var sb = new StringBuilder();
|
||||
|
||||
sb.Append(MapIfResolved(methodDefinition.ReturnType));
|
||||
sb.AppendMappedFullName(methodDefinition.ReturnType, map);
|
||||
sb.Append(" ");
|
||||
|
||||
sb.Append("(");
|
||||
@@ -50,7 +90,7 @@ namespace Reactor.OxygenFilter
|
||||
if (parameterType is SentinelType)
|
||||
sb.Append("...,");
|
||||
|
||||
sb.Append(MapIfResolved(parameterType));
|
||||
sb.AppendMappedFullName(parameterType, map);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Mono.Cecil;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Reactor.OxygenFilter
|
||||
@@ -188,6 +189,14 @@ namespace Reactor.OxygenFilter
|
||||
public MappedMethod(OriginalDescriptor original, string mapped) : base(original, mapped)
|
||||
{
|
||||
}
|
||||
|
||||
public MappedMethod(MethodDefinition methodDefinition, string mapped) : base(new OriginalDescriptor
|
||||
{
|
||||
Name = methodDefinition.Name,
|
||||
Signature = methodDefinition.GetSignature()
|
||||
}, mapped)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class MappedType : MappedMember
|
||||
|
||||
@@ -3,15 +3,16 @@
|
||||
<TargetFrameworks>net472;netstandard2.0</TargetFrameworks>
|
||||
<LangVersion>latest</LangVersion>
|
||||
|
||||
<Version>0.1.1</Version>
|
||||
<Version>0.1.2</Version>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<RepositoryUrl>https://github.com/NuclearPowered/Reactor.OxygenFilter</RepositoryUrl>
|
||||
<PackageLicenseExpression>LGPL-3.0-or-later</PackageLicenseExpression>
|
||||
<Description>Library for deobfuscating Among Us</Description>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Mono.Cecil" Version="0.11.3" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||
<PackageReference Include="System.Reflection.Emit.Lightweight" Version="4.7.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Reference in new issue
Block a user