de:fortelove:

This commit is contained in:
js6pak committed 2021-03-09 14:54:34 +01:00
1 parent ea1e202962
commit 0ce2525dca
11 files changed
+163 -109

No files matched your search

+6 -1
View File
@@ -10,8 +10,13 @@ namespace Reactor.Greenhouse
{
public static class Compiler
{
public static void Apply(this Mappings current, Mappings mappings)
public static void Apply(this Mappings current, Mappings mappings, Func<string, Mappings> findMappingsFunc)
{
foreach (var id in mappings.DependsOn)
{
current.Apply(findMappingsFunc(id), findMappingsFunc);
}
static void ApplyType(List<MappedType> types, MappedType newType)
{
var type = types.SingleOrDefault(x => newType.Equals(x));
@@ -15,5 +15,21 @@ namespace Reactor.Greenhouse.Generation
CleanModule = cleanModule;
ObfuscatedModule = obfuscatedModule;
}
public TypeContext GetOrCreate(TypeDefinition obfuscated, TypeDefinition clean, TypeContext parent = null)
{
if (!Map.TryGetValue(obfuscated, out var typeContext))
{
typeContext = new TypeContext(this, double.MaxValue, clean)
{
ObfuscatedType = obfuscated,
Declaring = parent
};
Map[obfuscated] = typeContext;
}
return typeContext;
}
}
}
+51 -29
View File
@@ -41,20 +41,37 @@ namespace Reactor.Greenhouse.Generation
foreach (var (obfuscatedType, typeContext) in context.Map.ToDictionary(k => k.Key, v => v.Value))
{
var mappedType = typeContext.ToMappedType(
obfuscatedType,
(obfuscatedNested, cleanNested) =>
if (obfuscatedType.DeclaringType != null)
{
var existingParent = context.Map.SingleOrDefault(x => x.Value.CleanType == typeContext.CleanType.DeclaringType).Key;
if (existingParent != null && existingParent != obfuscatedType.DeclaringType)
{
if (!context.Map.TryGetValue(obfuscatedNested, out var nested))
{
nested = new TypeContext(context, double.MaxValue, cleanNested);
context.Map[obfuscatedNested] = nested;
}
context.Map.Remove(obfuscatedType);
continue;
}
}
return nested;
});
typeContext.ObfuscatedType = obfuscatedType;
typeContext.UpdateNested();
if (mappedType == null || obfuscatedType.DeclaringType != null)
if (obfuscatedType.DeclaringType != null)
{
var declaring = context.GetOrCreate(obfuscatedType.DeclaringType, typeContext.CleanType.DeclaringType);
declaring.Nested.Add(typeContext);
}
}
foreach (var (obfuscatedType, typeContext) in context.Map)
{
if (obfuscatedType.DeclaringType != null)
{
continue;
}
var mappedType = typeContext.ToMappedType();
if (mappedType == null)
continue;
result.Types.Add(mappedType);
@@ -63,38 +80,40 @@ namespace Reactor.Greenhouse.Generation
return result;
}
private static bool TestEnum(TypeDefinition cleanType, TypeDefinition obfuscatedType)
private static double TestEnum(TypeDefinition cleanType, TypeDefinition obfuscatedType)
{
if (!obfuscatedType.IsEnum)
return false;
return 0;
if (cleanType.Fields.Count != obfuscatedType.Fields.Count)
return false;
var points = 0d;
for (var i = 0; i < cleanType.Fields.Count; i++)
{
var cleanField = cleanType.Fields[i];
if (i >= obfuscatedType.Fields.Count)
break;
var obfuscatedField = obfuscatedType.Fields[i];
if (cleanField.Name != obfuscatedField.Name)
if (cleanField.Name == obfuscatedField.Name)
{
return false;
points++;
}
if (cleanField.HasConstant && !cleanField.Constant.Equals(obfuscatedField.Constant))
if (cleanField.HasConstant && cleanField.Constant.Equals(obfuscatedField.Constant))
{
return false;
points++;
}
}
return true;
return points;
}
private static double TestField(FieldDefinition cleanField, FieldDefinition obfuscatedField)
{
var points = 0d;
if (cleanField.Attributes.IgnoreVisibility() != obfuscatedField.Attributes.IgnoreVisibility())
if (cleanField.Attributes != obfuscatedField.Attributes)
{
points -= 1;
}
@@ -170,12 +189,18 @@ namespace Reactor.Greenhouse.Generation
if (cleanType.Name.StartsWith("<"))
return 0;
if (cleanType.Attributes.IgnoreVisibility() != obfuscatedType.Attributes.IgnoreVisibility())
if (cleanType.Attributes != obfuscatedType.Attributes)
return 0;
if (cleanType.DeclaringType != null && obfuscatedType.DeclaringType == null)
return 0;
if (cleanType.FullName == obfuscatedType.FullName)
return double.MaxValue;
if (cleanType.IsEnum)
{
return TestEnum(cleanType, obfuscatedType) ? double.MaxValue : 0;
return TestEnum(cleanType, obfuscatedType);
}
if (cleanType.BaseType != null && obfuscatedType.BaseType != null && cleanType.BaseType.FullName != obfuscatedType.BaseType.FullName)
@@ -188,12 +213,6 @@ namespace Reactor.Greenhouse.Generation
var points = 0d;
// this will only work with up to date mono dll (:fortelove:)
if (obfuscatedType.Fields.Count != cleanType.Fields.Count || obfuscatedType.Properties.Count != cleanType.Properties.Count || obfuscatedType.NestedTypes.Count != cleanType.NestedTypes.Count)
{
return 0;
}
for (var i = 0; i < cleanType.Fields.Count; i++)
{
var cleanField = cleanType.Fields[i];
@@ -252,6 +271,9 @@ namespace Reactor.Greenhouse.Generation
if (obfuscatedType.Name.StartsWith("<") && obfuscatedType.Name.EndsWith(">"))
continue;
if (obfuscatedType.FullName.StartsWith("Rewired"))
continue;
var points = TestType(cleanType, obfuscatedType);
if (points > winnerPoints)
+68 -53
View File
@@ -14,13 +14,18 @@ namespace Reactor.Greenhouse.Generation
public double Points { get; }
public TypeDefinition CleanType { get; }
public TypeDefinition ObfuscatedType { get; set; }
public TypeContext Declaring { get; set; }
public HashSet<TypeContext> Nested { get; } = new HashSet<TypeContext>();
public string CleanFullName => CleanType.FullName;
public TypeContext(GenerationContext context, double points, TypeDefinition cleanType)
{
Context = context;
Points = points;
CleanType = cleanType;
CleanType = cleanType ?? throw new ArgumentNullException(nameof(cleanType));
}
public override string ToString()
@@ -30,65 +35,85 @@ namespace Reactor.Greenhouse.Generation
private static readonly Regex CompilerGeneratedRegex = new Regex(@"^<([\w\d]+)>.__\d+$", RegexOptions.Compiled);
public MappedType ToMappedType(TypeDefinition obfuscatedType, Func<TypeDefinition, TypeDefinition, TypeContext> nestedFunc)
public void UpdateNested()
{
if (ObfuscatedType.NestedTypes.Count == CleanType.NestedTypes.Count)
{
for (var i = 0; i < CleanType.NestedTypes.Count; i++)
{
var cleanNested = CleanType.NestedTypes[i];
var obfuscatedNested = ObfuscatedType.NestedTypes[i];
Nested.Add(Context.GetOrCreate(obfuscatedNested, cleanNested, this));
}
}
}
public MappedType ToMappedType()
{
var match = CompilerGeneratedRegex.Match(CleanType.Name);
var mappedType = new MappedType(obfuscatedType.FullName, match.Success ? (match.Groups[1].Value + "__d") : CleanType.Name.Replace("<>", ""));
var mappedType = new MappedType(ObfuscatedType.FullName, match.Success ? (match.Groups[1].Value + "__d") : CleanType.Name.Replace("<>", ""));
for (var i = 0; i < CleanType.Fields.Count; i++)
if (ObfuscatedType.Fields.Count == CleanType.Fields.Count)
{
var cleanField = CleanType.Fields[i];
var obfuscatedField = obfuscatedType.Fields[i];
if (obfuscatedType.DeclaringType != null)
for (var i = 0; i < CleanType.Fields.Count; i++)
{
switch (obfuscatedField.Name)
var cleanField = CleanType.Fields[i];
var obfuscatedField = ObfuscatedType.Fields[i];
if (ObfuscatedType.DeclaringType != null)
{
case "<>1__state":
mappedType.Fields.Add(new MappedMember(obfuscatedField.Name, "__state"));
continue;
case "<>2__current":
mappedType.Fields.Add(new MappedMember(obfuscatedField.Name, "__current"));
continue;
case "<>4__this":
mappedType.Fields.Add(new MappedMember(obfuscatedField.Name, "__this"));
switch (obfuscatedField.Name)
{
case "<>1__state":
mappedType.Fields.Add(new MappedMember(obfuscatedField.Name, "__state"));
continue;
case "<>2__current":
mappedType.Fields.Add(new MappedMember(obfuscatedField.Name, "__current"));
continue;
case "<>4__this":
mappedType.Fields.Add(new MappedMember(obfuscatedField.Name, "__this"));
continue;
}
var fieldMatch = CompilerGeneratedRegex.Match(obfuscatedField.Name);
if (fieldMatch.Success)
{
mappedType.Fields.Add(new MappedMember(obfuscatedField.Name, fieldMatch.Groups[1].Value));
continue;
}
}
var fieldMatch = CompilerGeneratedRegex.Match(obfuscatedField.Name);
if (fieldMatch.Success)
{
mappedType.Fields.Add(new MappedMember(obfuscatedField.Name, fieldMatch.Groups[1].Value));
if (!obfuscatedField.Name.IsObfuscated())
continue;
}
mappedType.Fields.Add(new MappedMember(obfuscatedField.Name, cleanField.Name));
}
if (!obfuscatedField.Name.IsObfuscated())
continue;
mappedType.Fields.Add(new MappedMember(obfuscatedField.Name, cleanField.Name));
}
for (var i = 0; i < CleanType.Properties.Count; i++)
if (ObfuscatedType.Properties.Count == CleanType.Properties.Count)
{
var cleanProperty = CleanType.Properties[i];
var obfuscatedProperty = obfuscatedType.Properties[i];
for (var i = 0; i < CleanType.Properties.Count; i++)
{
var cleanProperty = CleanType.Properties[i];
var obfuscatedProperty = ObfuscatedType.Properties[i];
if (!obfuscatedProperty.Name.IsObfuscated())
continue;
if (!obfuscatedProperty.Name.IsObfuscated())
continue;
mappedType.Properties.Add(new MappedMember(obfuscatedProperty.Name, cleanProperty.Name));
mappedType.Properties.Add(new MappedMember(obfuscatedProperty.Name, cleanProperty.Name));
}
}
foreach (var cleanMethod in CleanType.GetMethods())
{
if (obfuscatedType.GetMethods().Any(x => x.Name == cleanMethod.Name))
if (ObfuscatedType.GetMethods().Any(x => x.Name == cleanMethod.Name))
continue;
var matching = new List<MethodDefinition>();
foreach (var obfuscatedMethod in obfuscatedType.GetMethods().Where(x => x.Name.IsObfuscated()))
foreach (var obfuscatedMethod in ObfuscatedType.GetMethods().Where(x => x.Name.IsObfuscated()))
{
if (cleanMethod.ReturnType.FullName != obfuscatedMethod.ReturnType.FullName)
continue;
@@ -132,9 +157,9 @@ namespace Reactor.Greenhouse.Generation
}
}
if (obfuscatedType.DeclaringType != null)
if (ObfuscatedType.DeclaringType != null)
{
foreach (var obfuscatedMethod in obfuscatedType.Methods)
foreach (var obfuscatedMethod in ObfuscatedType.Methods)
{
var methodMatch = CompilerGeneratedRegex.Match(obfuscatedMethod.Name);
@@ -145,26 +170,16 @@ namespace Reactor.Greenhouse.Generation
}
}
for (var i = 0; i < CleanType.NestedTypes.Count; i++)
foreach (var nestedTypeContext in Nested)
{
var cleanNested = CleanType.NestedTypes[i];
var obfuscatedNested = obfuscatedType.NestedTypes[i];
if (cleanNested.Fields.Count != obfuscatedNested.Fields.Count)
var nestedType = nestedTypeContext.ToMappedType();
if (nestedType != null)
{
break;
}
var nestedContext = nestedFunc(obfuscatedNested, cleanNested);
var mappedNested = nestedContext.ToMappedType(obfuscatedNested, nestedFunc);
if (mappedNested != null)
{
mappedType.Nested.Add(mappedNested);
mappedType.Nested.Add(nestedType);
}
}
if (!obfuscatedType.Name.IsObfuscated() && !mappedType.Fields.Any() && !mappedType.Methods.Any() && !mappedType.Properties.Any() && !mappedType.Nested.Any())
if (!ObfuscatedType.Name.IsObfuscated() && !mappedType.Fields.Any() && !mappedType.Methods.Any() && !mappedType.Properties.Any() && !mappedType.Nested.Any())
return null;
return mappedType;
+7 -8
View File
@@ -56,11 +56,14 @@ namespace Reactor.Greenhouse
using var moduleDef = ModuleDefinition.ReadModule(File.OpenRead(game.Dll));
var generated = Generator.Generate(new GenerationContext(cleanModule, moduleDef));
generated.GameVersion = version.ToString();
generated.Version = Mappings.CurrentVersion;
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 + ".json"));
var mappings = Read(version.ToString());
generated.Apply(mappings, Read);
generated.Compile(moduleDef);
@@ -68,13 +71,9 @@ namespace Reactor.Greenhouse
await File.WriteAllTextAsync(Path.Combine("bin", version + ".json"), JsonConvert.SerializeObject(generated));
}
private static void Apply(Mappings generated, string file)
private static Mappings Read(string file)
{
if (File.Exists(file))
{
var mappings = JsonConvert.DeserializeObject<Mappings>(File.ReadAllText(file));
generated.Apply(mappings);
}
return JsonConvert.DeserializeObject<Mappings>(File.ReadAllText(file + ".json"));
}
public class ShouldSerializeContractResolver : CamelCasePropertyNamesContractResolver
@@ -10,7 +10,8 @@ namespace Reactor.Greenhouse.Setup.Provider
{
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"
[new GameVersion("2020.11.17a")] = "https://www.apkmirror.com/wp-content/themes/APKMirror/download.php?id=1753109",
[new GameVersion("2021.3.5a")] = "https://www.apkmirror.com/wp-content/themes/APKMirror/download.php?id=2032358&forcebaseapk"
};
public string DownloadUrl { get; }
@@ -16,16 +16,8 @@ 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
@@ -57,6 +49,7 @@ namespace Reactor.Greenhouse.Setup.Provider
}
}
// TODO butlerd and multi version support?
public override async Task DownloadAsync()
{
var htmlParser = new HtmlParser();
@@ -83,7 +76,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']")
@@ -92,7 +85,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}");
@@ -15,7 +15,8 @@ namespace Reactor.Greenhouse.Setup.Provider
private Dictionary<GameVersion, ulong> VersionMap { get; } = new Dictionary<GameVersion, ulong>
{
[new GameVersion("2019.10.10s")] = 3162069540887216240,
[new GameVersion("2020.12.9s")] = 3306639722673334636
[new GameVersion("2020.12.9s")] = 3306639722673334636,
[new GameVersion("2021.3.5s")] = 5200448423569257054
};
public ulong Manifest { get; }
+7
View File
@@ -9,6 +9,13 @@ namespace Reactor.OxygenFilter
{
public class Mappings
{
public const int CurrentVersion = 1;
public int Version { get; set; }
public string GameVersion { get; set; }
public string[] DependsOn { get; set; } = new string[0];
public List<MappedType> Types { get; set; } = new List<MappedType>();
public MappedType Find(string name, Func<MappedType, string> predicate)
@@ -187,11 +187,6 @@ namespace Reactor.OxygenFilter
foreach (var member in typeDef.Methods)
{
if (member.Name.IsObfuscated() && member.CustomAttributes.All(x => x.AttributeType != mappedAttribute))
{
MapMember(member, $"Method_{i}");
}
var j = 0;
foreach (var parameter in member.Parameters)
{