147 lines
5.8 KiB
C#
147 lines
5.8 KiB
C#
using System.Reflection;
|
|
using Mono.Cecil;
|
|
using Mono.Cecil.Cil;
|
|
|
|
public class Program
|
|
{
|
|
public static void Main(string[] args)
|
|
{
|
|
string dllPath = ".";
|
|
if (args.Length != 0)
|
|
{
|
|
Console.WriteLine(args[0]);
|
|
dllPath = args[0];
|
|
}
|
|
if (dllPath.EndsWith("/"))
|
|
dllPath = $"{dllPath}GodotTools.ProjectEditor.dll";
|
|
else if (!dllPath.EndsWith("GodotTools.ProjectEditor.dll"))
|
|
dllPath = $"{dllPath}/GodotTools.ProjectEditor.dll";
|
|
|
|
if (!File.Exists(dllPath))
|
|
{
|
|
Console.WriteLine(dllPath);
|
|
Console.WriteLine("GodotTools.ProjectEditor.dll not found");
|
|
return;
|
|
}
|
|
|
|
string backupPath = $"{dllPath}.bak";
|
|
if (!File.Exists(backupPath))
|
|
File.Copy(dllPath, backupPath);
|
|
string? version = Assembly.GetEntryAssembly()?
|
|
.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?
|
|
.InformationalVersion;
|
|
AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly(dllPath, new ReaderParameters { });
|
|
TypeDefinition targetType = assembly.MainModule.Types.First(t => t.Name == "ProjectUtils");
|
|
MethodDefinition method = targetType.Methods.First(m => m.Name == "EnsureGodotSdkIsUpToDate");
|
|
|
|
|
|
|
|
TypeReference? stringType = assembly.MainModule.ImportReference(typeof(string));
|
|
VariableDefinition? root = method.Body.Variables.FirstOrDefault(t => t.VariableType.FullName == "Microsoft.Build.Construction.ProjectRootElement");
|
|
|
|
|
|
TypeDefinition msBuildProjectTypeDef = assembly.MainModule.GetType("GodotTools.ProjectEditor.MSBuildProject");
|
|
TypeDefinition projectGeneratorTypeDef = assembly.MainModule.GetType("GodotTools.ProjectEditor.ProjectGenerator");
|
|
|
|
MethodDefinition? msBuildProjectGetRoot = msBuildProjectTypeDef.Methods
|
|
.FirstOrDefault(m => m.Name == "get_Root");
|
|
MethodDefinition? projectGeneratorGetGodotSdk = projectGeneratorTypeDef.Methods
|
|
.FirstOrDefault(m => m.Name == "get_GodotSdkAttrValue");
|
|
|
|
MethodDefinition? msBuildProjectSetHasUnsavedChanges = msBuildProjectTypeDef.Methods
|
|
.FirstOrDefault(m => m.Name == "set_HasUnsavedChanges");
|
|
|
|
|
|
MethodReference? preGetSdk = method.Body.Instructions
|
|
.Select(i => i.Operand)
|
|
.OfType<MethodReference>()
|
|
.FirstOrDefault(m => m.Name == "get_Sdk");
|
|
|
|
|
|
MethodReference? preSetSdk = method.Body.Instructions
|
|
.Select(i => i.Operand)
|
|
.OfType<MethodReference>()
|
|
.FirstOrDefault(m => m.Name == "set_Sdk");
|
|
|
|
|
|
method.Body.Instructions.Clear();
|
|
method.Body.ExceptionHandlers.Clear();
|
|
method.Body.Variables.Clear();
|
|
ILProcessor il = method.Body.GetILProcessor();
|
|
|
|
|
|
|
|
//VariableDefinition root = new VariableDefinition(projectRootElementTypeDef);
|
|
method.Body.Variables.Add(root);
|
|
VariableDefinition godotSdk = new VariableDefinition(stringType);
|
|
method.Body.Variables.Add(godotSdk);
|
|
method.Body.InitLocals = true;
|
|
il.Append(il.Create(OpCodes.Ldarg_0));
|
|
il.Append(il.Create(OpCodes.Callvirt, msBuildProjectGetRoot));
|
|
il.Append(il.Create(OpCodes.Stloc_0));
|
|
|
|
il.Append(il.Create(OpCodes.Call, projectGeneratorGetGodotSdk));
|
|
il.Append(il.Create(OpCodes.Stloc_1));
|
|
|
|
il.Append(il.Create(OpCodes.Ldloc_0));
|
|
il.Append(il.Create(OpCodes.Callvirt, preGetSdk));
|
|
|
|
|
|
il.Append(il.Create(OpCodes.Call, method.Module
|
|
.ImportReference(
|
|
typeof(string).GetMethod("IsNullOrEmpty", [typeof(string)]))
|
|
)
|
|
);
|
|
|
|
Instruction setSdk = il.Create(OpCodes.Nop);
|
|
il.Append(il.Create(OpCodes.Brtrue_S, setSdk));
|
|
|
|
il.Append(il.Create(OpCodes.Ldloc_0));
|
|
il.Append(il.Create(OpCodes.Callvirt, preGetSdk));
|
|
il.Append(il.Create(OpCodes.Callvirt, method.Module
|
|
.ImportReference(typeof(string).GetMethod("Trim", Type.EmptyTypes)))
|
|
);
|
|
il.Append(il.Create(OpCodes.Ldloc_1));
|
|
il.Append(il.Create(OpCodes.Ldc_I4_5));
|
|
il.Append(il.Create(OpCodes.Callvirt, method.Module
|
|
.ImportReference(
|
|
typeof(string).GetMethod("Equals", [typeof(string), typeof(StringComparison)]))
|
|
)
|
|
);
|
|
|
|
Instruction notMatch = il.Create(OpCodes.Nop);
|
|
il.Append(il.Create(OpCodes.Brfalse_S, notMatch));
|
|
il.Append(il.Create(OpCodes.Ret));
|
|
il.Append(notMatch);
|
|
|
|
il.Append(il.Create(OpCodes.Ldloc_0));
|
|
il.Append(il.Create(OpCodes.Callvirt, preGetSdk));
|
|
il.Append(il.Create(OpCodes.Callvirt, method.Module
|
|
.ImportReference(typeof(string).GetMethod("Trim", Type.EmptyTypes)))
|
|
);
|
|
il.Append(il.Create(OpCodes.Ldstr, $"Polonium.Sdk/{version}"));
|
|
il.Append(il.Create(OpCodes.Ldc_I4_5));
|
|
il.Append(il.Create(OpCodes.Callvirt, method.Module
|
|
.ImportReference(
|
|
typeof(string).GetMethod("Equals", [typeof(string), typeof(StringComparison)]))
|
|
)
|
|
);
|
|
il.Append(il.Create(OpCodes.Brfalse_S, setSdk));
|
|
il.Append(il.Create(OpCodes.Ret));
|
|
il.Append(setSdk);
|
|
il.Append(il.Create(OpCodes.Ldloc_0));
|
|
il.Append(il.Create(OpCodes.Ldloc_1));
|
|
il.Append(il.Create(OpCodes.Callvirt, preSetSdk));
|
|
|
|
il.Append(il.Create(OpCodes.Ldarg_0));
|
|
il.Append(il.Create(OpCodes.Ldc_I4_1));
|
|
il.Append(il.Create(OpCodes.Callvirt, msBuildProjectSetHasUnsavedChanges));
|
|
|
|
il.Append(il.Create(OpCodes.Ret));
|
|
|
|
|
|
|
|
assembly.Write($"{dllPath}.2.dll");
|
|
File.Replace($"{dllPath}.2.dll", dllPath, null);
|
|
}
|
|
} |