using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using ReCodeIt.Models; using ReCodeIt.ReMapper; using ReCodeIt.Utils; namespace ReCodeIt.CrossCompiler; public class ReCodeItCrossCompiler { public ReCodeItCrossCompiler() { Remapper = new(this); } private ReCodeItRemapper Remapper { get; } public CrossCompilerSettings Settings => DataProvider.Settings.CrossCompiler; public CrossCompilerProjectModel ActiveProject => ProjectManager.ActiveProject; /// /// Key: Remapped name, value: old name /// public Dictionary ChangedTypes { get; set; } = []; public void StartRemap() { ChangedTypes.Clear(); Remapper.InitializeRemap( ActiveProject.RemapModels, ActiveProject.OriginalAssemblyPath, ActiveProject.RemappedAssemblyPath, true); if (ActiveProject == null) { Logger.Log("ERROR: No Cross Compiler Project is loaded, create or load one first.", ConsoleColor.Red); return; } if (ActiveProject.ReCodeItProjectPath == string.Empty) { Logger.Log("ERROR: No ReCodeIt Project directory is set. (Project Creation Failed)", ConsoleColor.Red); return; } Logger.Log("-----------------------------------------------", ConsoleColor.Yellow); Logger.Log($"Cross patch remap result", ConsoleColor.Yellow); Logger.Log($"Changed {ChangedTypes.Count} types", ConsoleColor.Yellow); Logger.Log($"Original assembly path: {ActiveProject.OriginalAssemblyPath}", ConsoleColor.Yellow); Logger.Log($"Original assembly hash: {ActiveProject.OriginalAssemblyHash}", ConsoleColor.Yellow); Logger.Log($"Original patched assembly path: {ActiveProject.RemappedAssemblyPath}", ConsoleColor.Yellow); Logger.Log($"Original patched assembly hash: {ActiveProject.RemappedAssemblyHash}", ConsoleColor.Yellow); Logger.Log("-----------------------------------------------", ConsoleColor.Yellow); } public void StartCrossCompile() { AnalyzeSourceFiles(); } private void AnalyzeSourceFiles() { foreach (var file in ProjectManager.AllProjectSourceFiles) { AnalyzeSourcefile(file); } } private void AnalyzeSourcefile(string file) { var source = LoadSourceFile(file); var syntaxTree = CSharpSyntaxTree.ParseText(source); var root = syntaxTree.GetCompilationUnitRoot(); var identifiers = root.DescendantNodes() .OfType() .Where(id => ActiveProject.ChangedTypes.ContainsKey(id.Identifier.Text)); if (!identifiers.Any()) { return; } Logger.Log($"found {identifiers.Count()} objects to change in file {Path.GetFileNameWithoutExtension(file)}"); // Replace "RigClass" with "NewRigClass" var newRoot = root.ReplaceNodes(identifiers, (oldNode, newNode) => SyntaxFactory.IdentifierName(ActiveProject.ChangedTypes[oldNode.Identifier.Text]) .WithLeadingTrivia(oldNode.GetLeadingTrivia()) .WithTrailingTrivia(oldNode.GetTrailingTrivia())); } /// /// Loads a source file from disk /// /// /// private string LoadSourceFile(string path) { return File.ReadAllText(path); } }