| @ -0,0 +1,146 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.IO; | ||||
| using System.Linq; | ||||
| using System.Text.Json; | ||||
| using EpicGames.UHT.Types; | ||||
| using UnrealSharpScriptGenerator.Model; | ||||
|  | ||||
| namespace UnrealSharpScriptGenerator.Utilities; | ||||
|  | ||||
| public static class PluginUtilities | ||||
| { | ||||
|     public static readonly Dictionary<UhtPackage, ProjectDirInfo> PluginInfo = new(); | ||||
|      | ||||
|     private static readonly Dictionary<string, string> ExtractedEngineModules = new(); | ||||
|  | ||||
|     static PluginUtilities() | ||||
|     { | ||||
|         string? projectDirectory = Program.Factory.Session.ProjectDirectory; | ||||
|         string pluginDirectory = Path.Combine(projectDirectory!, "Plugins"); | ||||
|         DirectoryInfo pluginDirInfo = new DirectoryInfo(pluginDirectory); | ||||
|          | ||||
|         IEnumerable<(string DirectoryName, string FullName)> files = pluginDirInfo.GetFiles("*.uplugin", SearchOption.AllDirectories) | ||||
|             .Select(x => x.DirectoryName!) | ||||
|             .Select(x => (DirectoryName: x, ConfigPath: Path.Combine(x, "Config"))) | ||||
|             .Select(x => (x.DirectoryName, ConfigDir: new DirectoryInfo(x.ConfigPath))) | ||||
|             .Where(x => x.ConfigDir.Exists) | ||||
|             .SelectMany(x => x.ConfigDir.GetFiles("*.ExtractedModules.json", SearchOption.AllDirectories), | ||||
|                 (x, y) => (x.DirectoryName, FileInfo: y)) | ||||
|             .Select(x => (x.DirectoryName, x.FileInfo.FullName)); | ||||
|          | ||||
|         foreach ((string pluginDir, string pluginFile) in files) | ||||
|         { | ||||
|             using FileStream fileStream = File.OpenRead(pluginFile); | ||||
|             try | ||||
|             { | ||||
|                 List<string>? manifest = JsonSerializer.Deserialize<List<string>>(fileStream); | ||||
|                 foreach (string module in manifest!) | ||||
|                 { | ||||
|                     ExtractedEngineModules.Add($"/Script/{module}", pluginDir); | ||||
|                 } | ||||
|             } | ||||
|             catch (JsonException e) | ||||
|             { | ||||
|                 Console.WriteLine($"Error reading {pluginFile}: {e.Message}"); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public static ProjectDirInfo FindOrAddProjectInfo(this UhtPackage package) | ||||
|     { | ||||
|         if (PluginInfo.TryGetValue(package, out ProjectDirInfo plugin)) | ||||
|         { | ||||
|             return plugin; | ||||
|         } | ||||
|  | ||||
|         ProjectDirInfo info; | ||||
|         HashSet<string> dependencies = []; | ||||
|         if (package.IsPartOfEngine()) | ||||
|         { | ||||
|             if (ExtractedEngineModules.TryGetValue(package.SourceName, out string? pluginPath)) | ||||
|             { | ||||
|                 DirectoryInfo pluginDir = new(pluginPath); | ||||
|                 info = new ProjectDirInfo(pluginDir.Name, pluginPath, dependencies); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 info = new ProjectDirInfo("Engine", Program.EngineGluePath, dependencies);  | ||||
|             } | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|  | ||||
|             string baseDirectory = package.GetModule().BaseDirectory; | ||||
|             DirectoryInfo? currentDirectory = new DirectoryInfo(baseDirectory); | ||||
|  | ||||
|             FileInfo? projectFile = null; | ||||
|             while (currentDirectory is not null) | ||||
|             { | ||||
|                 FileInfo[] foundFiles = currentDirectory.GetFiles("*.*", SearchOption.TopDirectoryOnly); | ||||
|                 projectFile = foundFiles.FirstOrDefault(f => | ||||
|                     f.Extension.Equals(".uplugin", StringComparison.OrdinalIgnoreCase) || | ||||
|                     f.Extension.Equals(".uproject", StringComparison.OrdinalIgnoreCase)); | ||||
|  | ||||
|                 if (projectFile is not null) | ||||
|                 { | ||||
|                     break; | ||||
|                 } | ||||
|  | ||||
|                 currentDirectory = currentDirectory.Parent; | ||||
|             } | ||||
|  | ||||
|             if (projectFile is null) | ||||
|             { | ||||
|                 throw new InvalidOperationException( | ||||
|                     $"Could not find .uplugin or .uproject file for package {package.SourceName} in {baseDirectory}"); | ||||
|             } | ||||
|             info = new ProjectDirInfo(Path.GetFileNameWithoutExtension(projectFile.Name), currentDirectory!.FullName, dependencies); | ||||
|         } | ||||
|  | ||||
|         PluginInfo.Add(package, info); | ||||
|          | ||||
|         foreach (UhtHeaderFile header in package.GetHeaderFiles()) | ||||
|         { | ||||
|             HashSet<UhtHeaderFile> referencedHeaders = header.References.ReferencedHeaders; | ||||
|             referencedHeaders.UnionWith(header.ReferencedHeadersNoLock); | ||||
|              | ||||
|             foreach (UhtHeaderFile refHeader in referencedHeaders) | ||||
|             { | ||||
|                 foreach (UhtPackage refPackage in refHeader.GetPackages()) | ||||
|                 { | ||||
|                     if (refPackage == package) | ||||
|                     { | ||||
|                         continue; | ||||
|                     } | ||||
|  | ||||
|                     if (refPackage.IsPartOfEngine()) | ||||
|                     { | ||||
|                         if (!ExtractedEngineModules.TryGetValue(refPackage.SourceName, out string? pluginPath)) | ||||
|                         { | ||||
|                             continue; | ||||
|                         } | ||||
|  | ||||
|                         if (info.IsPartOfEngine) | ||||
|                         { | ||||
|                             DirectoryInfo pluginDir = new(pluginPath); | ||||
|                             info = new ProjectDirInfo(pluginDir.Name, pluginPath, dependencies); | ||||
|                             PluginInfo[package] = info; | ||||
|                         } | ||||
|                     } | ||||
|                      | ||||
|                      | ||||
|                     ProjectDirInfo projectInfo = refPackage.FindOrAddProjectInfo(); | ||||
|                     if (info.GlueCsProjPath == projectInfo.GlueCsProjPath) | ||||
|                     { | ||||
|                         continue; | ||||
|                     } | ||||
|                      | ||||
|                     dependencies.Add(projectInfo.GlueCsProjPath); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         return info; | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user