2024-06-26 14:45:54 -04:00
|
|
|
|
using dnlib.DotNet;
|
2024-12-31 13:46:44 -05:00
|
|
|
|
using ReCodeItLib.Utils;
|
2024-06-12 20:16:12 -04:00
|
|
|
|
|
2024-12-31 13:46:44 -05:00
|
|
|
|
namespace ReCodeItLib.ReMapper;
|
2024-06-12 20:16:12 -04:00
|
|
|
|
|
2024-06-22 01:27:34 -04:00
|
|
|
|
internal static class SPTPublicizer
|
|
|
|
|
{
|
2024-11-02 22:08:27 -04:00
|
|
|
|
public static void PublicizeClasses(ModuleDefMD definition, bool isLauncher = false)
|
2024-06-22 01:27:34 -04:00
|
|
|
|
{
|
2024-06-26 14:45:54 -04:00
|
|
|
|
var types = definition.GetTypes();
|
2024-12-31 10:10:40 -05:00
|
|
|
|
|
2025-01-02 02:29:02 -05:00
|
|
|
|
var publicizeTasks = new List<Task>();
|
2024-06-22 01:27:34 -04:00
|
|
|
|
foreach (var type in types)
|
|
|
|
|
{
|
|
|
|
|
if (type.IsNested) continue; // Nested types are handled when publicizing the parent type
|
2024-12-31 04:48:12 -05:00
|
|
|
|
|
2025-01-02 02:29:02 -05:00
|
|
|
|
publicizeTasks.Add(
|
|
|
|
|
Task.Factory.StartNew(() =>
|
|
|
|
|
{
|
|
|
|
|
PublicizeType(type, isLauncher);
|
|
|
|
|
})
|
|
|
|
|
);
|
2024-06-22 01:27:34 -04:00
|
|
|
|
}
|
2025-01-02 02:29:02 -05:00
|
|
|
|
|
|
|
|
|
while (!publicizeTasks.TrueForAll(t => t.Status == TaskStatus.RanToCompletion))
|
|
|
|
|
{
|
|
|
|
|
Logger.DrawProgressBar(publicizeTasks.Where(t => t.IsCompleted)!.Count() + 1, publicizeTasks.Count, 50);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Task.WaitAll(publicizeTasks.ToArray());
|
2024-06-22 01:27:34 -04:00
|
|
|
|
}
|
|
|
|
|
|
2024-11-02 22:08:27 -04:00
|
|
|
|
private static void PublicizeType(TypeDef type, bool isLauncher)
|
2024-06-22 01:27:34 -04:00
|
|
|
|
{
|
|
|
|
|
// if (type.CustomAttributes.Any(a => a.AttributeType.Name ==
|
|
|
|
|
// nameof(CompilerGeneratedAttribute))) { return; }
|
2024-11-02 22:08:27 -04:00
|
|
|
|
|
2024-06-22 01:27:34 -04:00
|
|
|
|
if (!type.IsNested && !type.IsPublic || type.IsNested && !type.IsNestedPublic)
|
|
|
|
|
{
|
2024-07-02 19:01:46 -04:00
|
|
|
|
if (!type.Interfaces.Any(i => i.Interface.Name == "IEffect"))
|
|
|
|
|
{
|
|
|
|
|
type.Attributes &= ~TypeAttributes.VisibilityMask; // Remove all visibility mask attributes
|
|
|
|
|
type.Attributes |= type.IsNested ? TypeAttributes.NestedPublic : TypeAttributes.Public; // Apply a public visibility attribute
|
|
|
|
|
}
|
2024-06-22 01:27:34 -04:00
|
|
|
|
}
|
2024-11-02 22:08:27 -04:00
|
|
|
|
|
|
|
|
|
if (type.IsSealed && !isLauncher)
|
2024-06-22 01:27:34 -04:00
|
|
|
|
{
|
|
|
|
|
type.Attributes &= ~TypeAttributes.Sealed; // Remove the Sealed attribute if it exists
|
|
|
|
|
}
|
2024-11-02 22:08:27 -04:00
|
|
|
|
|
2024-06-22 01:27:34 -04:00
|
|
|
|
foreach (var method in type.Methods)
|
|
|
|
|
{
|
|
|
|
|
PublicizeMethod(method);
|
|
|
|
|
}
|
2024-11-02 22:08:27 -04:00
|
|
|
|
|
2024-06-22 01:27:34 -04:00
|
|
|
|
foreach (var property in type.Properties)
|
|
|
|
|
{
|
|
|
|
|
if (property.GetMethod != null) PublicizeMethod(property.GetMethod);
|
|
|
|
|
if (property.SetMethod != null) PublicizeMethod(property.SetMethod);
|
|
|
|
|
}
|
2024-07-02 19:01:46 -04:00
|
|
|
|
|
|
|
|
|
foreach (var nestedType in type.NestedTypes)
|
2024-06-22 01:27:34 -04:00
|
|
|
|
{
|
2024-11-02 22:08:27 -04:00
|
|
|
|
PublicizeType(nestedType, isLauncher);
|
2024-06-22 01:27:34 -04:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-26 14:45:54 -04:00
|
|
|
|
private static void PublicizeMethod(MethodDef method)
|
2024-06-22 01:27:34 -04:00
|
|
|
|
{
|
|
|
|
|
if (method.IsCompilerControlled /*|| method.CustomAttributes.Any(a => a.AttributeType.Name == nameof(CompilerGeneratedAttribute))*/)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (method.IsPublic) return;
|
|
|
|
|
|
|
|
|
|
// if (!CanPublicizeMethod(method)) return;
|
|
|
|
|
|
|
|
|
|
// Workaround to not publicize a specific method so the game doesn't crash
|
|
|
|
|
if (method.Name == "TryGetScreen") return;
|
|
|
|
|
|
|
|
|
|
method.Attributes &= ~MethodAttributes.MemberAccessMask;
|
|
|
|
|
method.Attributes |= MethodAttributes.Public;
|
|
|
|
|
}
|
2024-06-12 20:16:12 -04:00
|
|
|
|
}
|