using Microsoft.VisualBasic; using static Microsoft.VisualBasic.CompilerServices.LikeOperator; using System; using System.Collections.Generic; using System.IO; using System.Resources; using System.Collections; using System.Linq; using Microsoft.WindowsAPICodePack.Dialogs; using Newtonsoft.Json.Linq; using System.Reflection; namespace SM64RomManager.LangRes_Collector { class Program { static void Main(string[] args) { var resFiles = new List(); var ofd = new CommonOpenFileDialog { IsFolderPicker = true }; string rootPath, outputPath; var myAppDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); var myConfigFilePath = Path.Combine(myAppDir, "FilterConfig.json"); var filterConfig = JObject.Parse(File.ReadAllText(myConfigFilePath)).ToObject(); var allLoadedAssemblies = AppDomain.CurrentDomain.GetAssemblies().Select(x => x.GetName()).ToArray(); var typeNameString = typeof(string).Name; // Get root path ofd.Title = "Root (repository) directory"; if (ofd.ShowDialog() == CommonFileDialogResult.Ok) rootPath = ofd.FileName; else return; // Get output path ofd.Title = "Output directory"; if (ofd.ShowDialog() == CommonFileDialogResult.Ok) outputPath = ofd.FileName; else return; // Collect files if (Directory.Exists(rootPath)) { foreach (var filePath in Directory.GetFiles(rootPath, string.Empty, SearchOption.AllDirectories)) { var fileName = Path.GetFileName(filePath); var copyFile = true; foreach (var blackFileName in filterConfig.FileNameBlackList) { if (copyFile && LikeString(fileName, blackFileName, CompareMethod.Binary)) copyFile = false; } foreach (var whiteFileName in filterConfig.FileNameWhiteList) { if (copyFile && !LikeString(fileName, whiteFileName, CompareMethod.Binary)) copyFile = false; } if (copyFile) resFiles.Add(filePath); } } // Create output path if not exists Directory.CreateDirectory(outputPath); // Copy and prepair files foreach (var resFileInput in resFiles) { var resReader = new ResXResourceReader(resFileInput) { UseResXDataNodes = true }; var propsToCopy = new Dictionary(); // Collect input properties foreach (DictionaryEntry kvp in resReader) { var propName = (string)kvp.Key; var useProp = true; // Check for blacklisted property names foreach (var blackPropName in filterConfig.PropNameBlackList) { if (useProp && LikeString(propName, blackPropName, CompareMethod.Binary)) useProp = false; } // Hold property to write later, if it's a string try { if (useProp && kvp.Value is ResXDataNode node && node.GetValue(allLoadedAssemblies) is string val) { if (!string.IsNullOrEmpty(val)) propsToCopy.Add(propName, val); } } catch(FileNotFoundException) { } } resReader.Close(); // Write output ResX file if (propsToCopy.Any()) { var resFileOutput = Path.Combine(outputPath, resFileInput.Replace(rootPath, outputPath)); var resFileOutputDir = Path.GetDirectoryName(resFileOutput); // Ensure the directory exists Directory.CreateDirectory(resFileOutputDir); // Open a ResXResourceWriter var resWriter = new ResXResourceWriter(resFileOutput); // Write all hold properties foreach (var kvp in propsToCopy) resWriter.AddResource(kvp.Key, kvp.Value); resWriter.Close(); } } } } }