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

Commit

Permalink
Better duplication prevention and nested support
Browse files Browse the repository at this point in the history
  • Loading branch information
js6pak committed Jan 15, 2021
1 parent 79df790 commit 4a527d5
Show file tree
Hide file tree
Showing 9 changed files with 101 additions and 80 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,4 @@ obj/
/packages/
riderModule.iml
/_ReSharper.Caches/
work
.idea
12 changes: 8 additions & 4 deletions Reactor.Greenhouse/Compiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Linq;
using System.Text.RegularExpressions;
using Mono.Cecil;
using Mono.Cecil.Rocks;
using Reactor.OxygenFilter;

namespace Reactor.Greenhouse
Expand Down Expand Up @@ -115,15 +116,15 @@ private static bool TestProperty(MappedMember property, TypeDefinition typeDef,

private static bool TestType(MappedType type, TypeDefinition typeDef, Mappings mappings)
{
return (type.Original.Name == null || type.Original.Name == typeDef.Name) &&
return (type.Original.Name == null || type.Original.Name == typeDef.FullName) &&
type.Methods.All(method => typeDef.Methods.Any(m => TestMethod(method, typeDef, m, mappings))) &&
type.Fields.All(field => typeDef.Fields.Any(f => TestField(field, typeDef, f, mappings))) &&
type.Properties.All(property => typeDef.Properties.Any(p => TestProperty(property, typeDef, p, mappings)));
}

private static void Compile(this MappedType type, TypeDefinition typeDef, Mappings mappings)
{
type.Original = new OriginalDescriptor { Name = typeDef.Name };
type.Original = new OriginalDescriptor { Name = typeDef.FullName };

foreach (var nested in type.Nested)
{
Expand All @@ -133,8 +134,11 @@ private static void Compile(this MappedType type, TypeDefinition typeDef, Mappin
);

nested.Compile(nestedDef, mappings);
mappings.Types.Add(nested);
}

type.Nested.Clear();

foreach (var property in type.Properties)
{
try
Expand Down Expand Up @@ -180,11 +184,11 @@ private static void Compile(this MappedType type, TypeDefinition typeDef, Mappin

public static void Compile(this Mappings mappings, ModuleDefinition moduleDef)
{
foreach (var type in mappings.Types)
foreach (var type in mappings.Types.ToList())
{
try
{
var typeDef = moduleDef.Types.Single(t => TestType(type, t, mappings));
var typeDef = moduleDef.GetAllTypes().Single(t => TestType(type, t, mappings));

type.Compile(typeDef, mappings);
}
Expand Down
145 changes: 84 additions & 61 deletions Reactor.Greenhouse/Generator.cs
Original file line number Diff line number Diff line change
@@ -1,23 +1,102 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Mono.Cecil;
using Mono.Cecil.Rocks;
using Reactor.OxygenFilter;

namespace Reactor.Greenhouse
{
public static class Generator
{
private static TypeAttributes IgnoreVisibility(this TypeAttributes typeAttributes)
{
return typeAttributes & ~TypeAttributes.VisibilityMask;
}

public static Mappings Generate(ModuleDefinition old, ModuleDefinition latest)
{
var matches = new Dictionary<TypeDefinition, SortedList<double, TypeDefinition>>();

var result = new Mappings();

foreach (var oldType in old.Types)
foreach (var oldType in old.GetAllTypes())
{
if (oldType.Name.StartsWith("<") || oldType.Namespace.StartsWith("GoogleMobileAds"))
continue;

void AddType(TypeDefinition type)
var list = new SortedList<double, TypeDefinition>(Comparer<double>.Create((x, y) => y.CompareTo(x)));
matches[oldType] = list;

var exact = latest.GetAllTypes().FirstOrDefault(x => x.FullName == oldType.FullName);
if (exact != null)
{
list.Add(double.MaxValue, exact);
continue;
}

if (oldType.IsEnum)
{
var first = oldType.Fields.Select(x => x.Name).ToArray();
var type = latest.GetAllTypes().SingleOrDefault(x => x.IsEnum && x.Fields.Select(f => f.Name).SequenceEqual(first));
if (type != null)
{
list.Add(double.MaxValue, type);
}

continue;
}

static bool Test(TypeReference typeReference)
{
return typeReference.IsGenericParameter || typeReference.Namespace != string.Empty || !typeReference.Name.IsObfuscated();
}

var methodNames = oldType.GetMethods().Select(x => x.Name).ToArray();
var fieldNames = oldType.Fields.Select(x => x.Name).ToArray();
var propertyNames = oldType.Properties.Select(x => x.Name).ToArray();

var methodSignatures = oldType.GetMethods().Where(x => Test(x.ReturnType) && x.Parameters.All(p => Test(p.ParameterType))).Select(x => x.GetSignature()).ToArray();
var fieldSignatures = oldType.Fields.Where(x => Test(x.FieldType) && (!x.FieldType.HasGenericParameters || x.FieldType.GenericParameters.All(Test))).Select(x => x.GetSignature()).ToArray();

var types = latest.GetAllTypes()
.Where(t => t.Attributes.IgnoreVisibility() == oldType.Attributes.IgnoreVisibility())
.ToArray();

foreach (var t in types)
{
var mapped = new MappedType(new OriginalDescriptor { Name = type.Name }, oldType.Name);
var points = 0d;
points += t.GetMethods().Count(m => !m.Name.IsObfuscated() && methodNames.Contains(m.Name));
points += t.Fields.Count(f => !f.Name.IsObfuscated() && fieldNames.Contains(f.Name)) * 2d;
points += t.Properties.Count(p => propertyNames.Contains((p.GetMethod?.Name ?? p.SetMethod.Name).Substring(4))) * 2d;

var fieldSignaturesPoints = fieldSignatures.Count(s => t.Fields.Any(f => f.GetSignature().ToString() == s.ToString()));
points += Math.Max(0, fieldSignaturesPoints - Math.Abs(t.Fields.Count - fieldSignaturesPoints)) / 2d;

var methodSignaturesPoints = methodSignatures.Count(s => t.GetMethods().Any(m => m.GetSignature().ToString() == s.ToString()));
points += Math.Max(0, methodSignaturesPoints - Math.Abs(t.GetMethods().Count() - methodSignaturesPoints) / 2d) / 2d;

if (points != 0)
{
list.TryAdd(points, t);
}
}
}

foreach (var (oldType, list) in matches)
{
foreach (var (points, type) in list)
{
if (matches.Where(x => x.Key != oldType).SelectMany(x => x.Value).Any(x => x.Value == type && x.Key > points))
{
continue;
}

list.Clear();
list.Add(double.MaxValue, type);

var mapped = new MappedType(new OriginalDescriptor { Name = type.FullName }, oldType.Name);

var i = 0;
foreach (var field in type.Fields)
Expand Down Expand Up @@ -67,68 +146,12 @@ void AddType(TypeDefinition type)

if (type.Name == oldType.Name || (!type.Name.IsObfuscated() && !mapped.Fields.Any() && !mapped.Methods.Any()))
{
return;
break;
}

result.Types.Add(mapped);
}

var exact = latest.Types.FirstOrDefault(x => x.FullName == oldType.FullName);
if (exact != null)
{
AddType(exact);
continue;
}

if (oldType.IsEnum)
{
var first = oldType.Fields.Select(x => x.Name).ToArray();
var type = latest.Types.SingleOrDefault(x => x.IsEnum && x.Fields.Select(f => f.Name).SequenceEqual(first));
if (type != null)
{
AddType(type);
}

continue;
}

static bool Test(TypeReference typeReference)
{
return typeReference.IsGenericParameter || typeReference.Namespace != string.Empty || !typeReference.Name.IsObfuscated();
}

var methods = oldType.Methods.Where(x => Test(x.ReturnType) && x.Parameters.All(p => Test(p.ParameterType))).Select(x => x.GetSignature()).ToArray();
var fields = oldType.Fields.Where(x => Test(x.FieldType) && (!x.FieldType.HasGenericParameters || x.FieldType.GenericParameters.All(Test))).Select(x => x.GetSignature()).ToArray();
var properties = oldType.Properties.Select(x => x.Name).ToArray();

var types = latest.Types
.Where(t => t.Attributes == oldType.Attributes)
.ToArray();

TypeDefinition winner = null;
var winnerPoints = -1;

foreach (var t in types)
{
var points = 0;
points += t.Properties.Count(p => properties.Contains((p.GetMethod?.Name ?? p.SetMethod.Name).Substring(4)));
points += fields.Count(s => t.Fields.Any(f => f.GetSignature().ToString() == s.ToString()));
points += methods.Count(s => t.Methods.Any(m => m.GetSignature().ToString() == s.ToString()));

if (points > winnerPoints)
{
winnerPoints = points;
winner = t;
}
else if (points == winnerPoints)
{
winner = null;
}
}

if (winner != null && winnerPoints > 0)
{
AddType(winner);
break;
}
}

Expand Down
2 changes: 1 addition & 1 deletion Reactor.Greenhouse/Mappings
Submodule Mappings updated 3 files
+1 −0 .gitignore
+14 −0 2020.12.9s.json
+0 −20 universal.json
8 changes: 4 additions & 4 deletions Reactor.Greenhouse/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,13 @@ private static async Task GenerateAsync(Game game, ModuleDefinition old)

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

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

generated.Compile(moduleDef);

Directory.CreateDirectory(Path.Combine("Mappings", "bin"));
await File.WriteAllTextAsync(Path.Combine("Mappings", "bin", game.Name.ToLower() + ".json"), JsonConvert.SerializeObject(generated));
Directory.CreateDirectory(Path.Combine("bin"));
await File.WriteAllTextAsync(Path.Combine("bin", game.Name.ToLower() + ".json"), JsonConvert.SerializeObject(generated));
}

private static void Apply(Mappings generated, string file)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<LangVersion>latest</LangVersion>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>

<Version>0.2.2</Version>
<Version>0.2.3</Version>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>https://github.com/NuclearPowered/Reactor.OxygenFilter</RepositoryUrl>
<PackageLicenseExpression>LGPL-3.0-or-later</PackageLicenseExpression>
Expand All @@ -17,7 +17,7 @@

<ProjectReference Include="..\Reactor.OxygenFilter\Reactor.OxygenFilter.csproj" />
<PackageReference Include="js6pak.Il2CppDumper" Version="6.4.20" />
<PackageReference Include="NuclearPowered.AssemblyUnhollower" Version="0.4.12" />
<PackageReference Include="NuclearPowered.AssemblyUnhollower" Version="0.4.13" />
</ItemGroup>

<ItemGroup Condition=" '$(TargetFramework)' == 'net472' ">
Expand Down
2 changes: 1 addition & 1 deletion Reactor.OxygenFilter/Mappings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public class Mappings

public MappedType Find(string name, Func<MappedType, string> predicate)
{
var split = name.Split('.').SelectMany(x => x.Split('+')).ToArray();
var split = name.Split('.', '+', '/').ToArray();

if (split.Length > 1)
{
Expand Down
5 changes: 0 additions & 5 deletions Reactor.OxygenFilter/ObfuscationMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,11 +143,6 @@ void MapType(MappedType type, TypeDefinition typeDef)
}
}
}

foreach (var nested in type.Nested)
{
MapType(nested, typeDef.NestedTypes.SingleOrDefault(x => x.Name == nested.Original.Name));
}
}

foreach (var type in Mappings.Types)
Expand Down
2 changes: 1 addition & 1 deletion Reactor.OxygenFilter/Reactor.OxygenFilter.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<TargetFrameworks>net472;netstandard2.0</TargetFrameworks>
<LangVersion>latest</LangVersion>

<Version>0.1.0</Version>
<Version>0.1.1</Version>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>https://github.com/NuclearPowered/Reactor.OxygenFilter</RepositoryUrl>
<PackageLicenseExpression>LGPL-3.0-or-later</PackageLicenseExpression>
Expand Down

0 comments on commit 4a527d5

Please sign in to comment.