diff --git a/src/StormworksLuaExtract/Helpers/BackupFileHelper.cs b/src/StormworksLuaExtract/Helpers/BackupFileHelper.cs new file mode 100644 index 0000000..6186e49 --- /dev/null +++ b/src/StormworksLuaExtract/Helpers/BackupFileHelper.cs @@ -0,0 +1,21 @@ +using System; +using System.IO; +using StormworksLuaExtract.Models; + +namespace StormworksLuaExtract.Helpers +{ + public static class BackupFileHelper + { + public static bool BackupFile(string originalContent, string originalFileName) + { + var backupFileName = $"{Path.GetFileNameWithoutExtension(originalFileName)} {DateTime.Now:yyyy-MM-dd HH-mm-ss}{Path.GetExtension(originalFileName)}"; + var backupFilePath = Path.Join(Statics.LocalBackupDirectory, backupFileName); + var success = FileHelper.TryWriteFile(backupFilePath, originalContent); + + if (success) + Console.WriteLine($"Wrote backup to {backupFilePath}"); + + return success; + } + } +} diff --git a/src/StormworksLuaExtract/Helpers/ScriptExtractHelper.cs b/src/StormworksLuaExtract/Helpers/ScriptExtractHelper.cs index 2d874cd..9cb6f43 100644 --- a/src/StormworksLuaExtract/Helpers/ScriptExtractHelper.cs +++ b/src/StormworksLuaExtract/Helpers/ScriptExtractHelper.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Net; using System.Text.RegularExpressions; using StormworksLuaExtract.Models; @@ -23,18 +24,28 @@ public static IEnumerable ExtractScriptsFromMicrocontrollerXml(string var matches = Regex.Matches(xml, Statics.ObjectMatchPattern()); foreach (Match match in matches) { - var element = match.Groups["element"].Value; - - // The script is printed twice in the XML, once under a Path.GetFileNameWithoutExtension(VehicleXmlPath); - public string ObjectId { get; } + public string LuaFilePath { get; } - public string Script { get; } + public string LuaFileName => Path.GetFileName(LuaFilePath); - public string MicrocontrollerName { get; } + public string ObjectId { get; } - public LuaScript(string microcontrollerXmlPath, string luaFilePath, string objectId, string script) + public LuaScript(string vehicleXmlPath, string luaFilePath, string objectId) { - MicrocontrollerXmlPath = microcontrollerXmlPath; + VehicleXmlPath = vehicleXmlPath; LuaFilePath = luaFilePath; ObjectId = objectId; - Script = script; - - MicrocontrollerName = MicrocontrollerXmlPath.Split(Path.DirectorySeparatorChar).Last().Replace(".xml", string.Empty); } } } \ No newline at end of file diff --git a/src/StormworksLuaExtract/Program.cs b/src/StormworksLuaExtract/Program.cs index 2347ab3..fedce1e 100644 --- a/src/StormworksLuaExtract/Program.cs +++ b/src/StormworksLuaExtract/Program.cs @@ -10,7 +10,7 @@ public static void Main() var builder = new ContainerBuilder(); builder.RegisterType().AsSelf(); - builder.RegisterType().AsSelf(); + builder.RegisterType().AsSelf(); builder.RegisterType().AsSelf(); builder.RegisterType().AsSelf(); diff --git a/src/StormworksLuaExtract/Services/ApplicationService.cs b/src/StormworksLuaExtract/Services/ApplicationService.cs index 42830c1..bb65764 100644 --- a/src/StormworksLuaExtract/Services/ApplicationService.cs +++ b/src/StormworksLuaExtract/Services/ApplicationService.cs @@ -10,26 +10,30 @@ namespace StormworksLuaExtract.Services { public class ApplicationService { - private readonly MicrocontrollersWatchService _microcontrollersWatchService; + private readonly VehiclesWatchService _vehiclesWatchService; private readonly LocalLuaToXmlWriteService _localLuaToXmlWriteService; private readonly XmlToLocalLuaWriteService _xmlToLocalLuaWriteService; private readonly List _luaScripts = new List(); + private readonly List _ignoreNextLuaUpdatePaths = new List(); + + private string _ignoreNextVehicleUpdatePath; public ApplicationService( - MicrocontrollersWatchService microcontrollersWatchService, + VehiclesWatchService vehiclesWatchService, LocalLuaToXmlWriteService localLuaToXmlWriteService, XmlToLocalLuaWriteService xmlToLocalLuaWriteService) { - _microcontrollersWatchService = microcontrollersWatchService; + _vehiclesWatchService = vehiclesWatchService; _localLuaToXmlWriteService = localLuaToXmlWriteService; _xmlToLocalLuaWriteService = xmlToLocalLuaWriteService; - _microcontrollersWatchService.MicrocontrollerAdded += MicrocontrollerAdded; - _microcontrollersWatchService.MicrocontrollerDeleted += MicrocontrollerDeleted; + _vehiclesWatchService.MicrocontrollerAdded += VehicleAdded; + _vehiclesWatchService.MicrocontrollerDeleted += VehicleDeleted; + _vehiclesWatchService.MicrocontrollerChanged += VehicleChanged; } public void Run() { - _microcontrollersWatchService.StartWatching(); + _vehiclesWatchService.StartWatching(); if (!Directory.Exists(Statics.MicrocontrollerPath)) { @@ -57,27 +61,70 @@ public void Run() private void WriteExistingMicrocontrollerScripts() { foreach (var xmlFilePath in Directory.GetFiles(Statics.MicrocontrollerPath, "*.xml")) - AddMicrocontrollerXmlFile(xmlFilePath); + AddVehicleXmlFile(xmlFilePath); } - private void MicrocontrollerAdded(string xmlfilepath) => - AddMicrocontrollerXmlFile(xmlfilepath); + private void VehicleAdded(string xmlfilepath) => + AddVehicleXmlFile(xmlfilepath); + + private void VehicleDeleted(string xmlfilepath) => + _luaScripts.Where(s => s.VehicleXmlPath == xmlfilepath).ToList().ForEach(s => _luaScripts.Remove(s)); + + private void VehicleChanged(string xmlfilepath) + { + if (xmlfilepath == _ignoreNextVehicleUpdatePath) + { + _ignoreNextVehicleUpdatePath = null; + return; + } + + var savedVehicleScripts = ScriptExtractHelper.ExtractScriptsFromMicrocontrollerXml(xmlfilepath).ToList(); + + var previouslyExtractedScripts = _luaScripts.Where(ls => ls.VehicleXmlPath == xmlfilepath).ToList(); + var newScripts = savedVehicleScripts.Where(vs => previouslyExtractedScripts.All(nvs => nvs.ObjectId != vs.ObjectId)); + var deletedScripts = previouslyExtractedScripts.Where(vs => savedVehicleScripts.All(nvs => nvs.ObjectId != vs.ObjectId)).ToList(); + + foreach (var newScript in newScripts) + { + _luaScripts.Add(newScript); + _ignoreNextLuaUpdatePaths.Add(newScript.LuaFilePath); + _xmlToLocalLuaWriteService.WriteVehicleLuaScriptToFile(newScript); + } - private void MicrocontrollerDeleted(string xmlfilepath) => - _luaScripts.Where(s => s.MicrocontrollerXmlPath == xmlfilepath).ToList().ForEach(s => _luaScripts.Remove(s)); + foreach (var deletedScript in deletedScripts) + { + _luaScripts.Remove(deletedScript); + var deletedScriptContent = FileHelper.NoTouchReadFile(deletedScript.LuaFilePath); + if (BackupFileHelper.BackupFile(deletedScriptContent, deletedScript.LuaFileName)) + File.Delete(deletedScript.LuaFilePath); + } + + foreach (var existingScript in previouslyExtractedScripts.Except(deletedScripts)) + { + _ignoreNextLuaUpdatePaths.Add(existingScript.LuaFilePath); + if (!_xmlToLocalLuaWriteService.WriteVehicleLuaScriptToFile(existingScript)) + _ignoreNextLuaUpdatePaths.Remove(existingScript.LuaFilePath); + } + } - private void AddMicrocontrollerXmlFile(string xmlFilePath) + private void AddVehicleXmlFile(string xmlFilePath) { - var xmlFileScripts = ScriptExtractHelper.ExtractScriptsFromMicrocontrollerXml(xmlFilePath); - foreach (var script in xmlFileScripts) + var luaScripts = ScriptExtractHelper.ExtractScriptsFromMicrocontrollerXml(xmlFilePath); + foreach (var script in luaScripts) { _luaScripts.Add(script); - _xmlToLocalLuaWriteService.WriteMicrocontrollerLuaScriptsToFiles(script); + _xmlToLocalLuaWriteService.WriteVehicleLuaScriptToFile(script); } } private async void LocalLuaFileChanged(object sender, FileSystemEventArgs e) { + if (_ignoreNextLuaUpdatePaths.Contains(e.FullPath)) + { + _ignoreNextLuaUpdatePaths.Remove(e.FullPath); + return; + } + var luaScript = _luaScripts.FirstOrDefault(ls => ls.LuaFilePath == e.FullPath); if (luaScript == null) return; @@ -86,6 +133,8 @@ private async void LocalLuaFileChanged(object sender, FileSystemEventArgs e) Console.WriteLine($"Lua file '{e.Name}' changed."); + _ignoreNextVehicleUpdatePath = luaScript.VehicleXmlPath; + _localLuaToXmlWriteService.WriteScriptToMicrocontroller(luaScript); } } diff --git a/src/StormworksLuaExtract/Services/LocalLuaToXmlWriteService.cs b/src/StormworksLuaExtract/Services/LocalLuaToXmlWriteService.cs index 29d9926..91dbc44 100644 --- a/src/StormworksLuaExtract/Services/LocalLuaToXmlWriteService.cs +++ b/src/StormworksLuaExtract/Services/LocalLuaToXmlWriteService.cs @@ -1,6 +1,5 @@ using System; using System.IO; -using System.Linq; using System.Net; using System.Text.RegularExpressions; using StormworksLuaExtract.Helpers; @@ -14,9 +13,9 @@ public void WriteScriptToMicrocontroller(LuaScript luaScript) { Console.WriteLine($"Local lua file '{luaScript.LuaFilePath}' object ID {luaScript.ObjectId} script changed."); - if (!File.Exists(luaScript.MicrocontrollerXmlPath)) + if (!File.Exists(luaScript.VehicleXmlPath)) { - Console.WriteLine($"Target microprocessor file '{luaScript.MicrocontrollerXmlPath}' not found."); + Console.WriteLine($"Target vehicle file '{luaScript.VehicleXmlPath}' not found."); return; } @@ -26,38 +25,33 @@ public void WriteScriptToMicrocontroller(LuaScript luaScript) newScript = WebUtility.HtmlEncode(newScript); - var currentScripts = ScriptExtractHelper.ExtractScriptsFromMicrocontrollerXml(luaScript.MicrocontrollerXmlPath).ToList(); - var currentScript = currentScripts.FirstOrDefault(s => s.ObjectId == luaScript.ObjectId); - + var currentScript = ScriptExtractHelper.GetScriptFromXmlFile(luaScript.VehicleXmlPath, luaScript.ObjectId); if (currentScript == null) { - Console.WriteLine($"Failed to find the Lua object with ID {luaScript.ObjectId} in microprocessor file '{luaScript.MicrocontrollerXmlPath}'."); + Console.WriteLine($"Failed to find the Lua object with ID {luaScript.ObjectId} in vehicle file '{luaScript.VehicleXmlPath}'."); return; } - if (currentScript.Script == newScript) + if (currentScript == newScript) { - Console.WriteLine($"Script {luaScript.ObjectId} hasn't changed compared to the microcontroller XML."); + Console.WriteLine($"Script {luaScript.ObjectId} hasn't changed compared to the vehicle XML."); return; } - var currentXml = FileHelper.NoTouchReadFile(luaScript.MicrocontrollerXmlPath); + var currentXml = FileHelper.NoTouchReadFile(luaScript.VehicleXmlPath); // Backup - var backupFilePath = Path.Join(Statics.LocalBackupDirectory, $"{luaScript.MicrocontrollerName} {DateTime.Now:yyyy-MM-dd HH-mm-ss}.xml"); - if (!FileHelper.TryWriteFile(backupFilePath, currentXml)) + if (!BackupFileHelper.BackupFile(currentXml, luaScript.VehicleName)) return; - Console.WriteLine($"Wrote backup to {backupFilePath}"); - var pattern = Statics.ObjectMatchPattern(luaScript.ObjectId); - var newXml = Regex.Replace(currentXml, pattern, "<${element} id=\"${id}\" script='" + newScript + "'>"); + var newXml = Regex.Replace(currentXml, pattern, ""); // Overwrite - if (!FileHelper.TryWriteFile(luaScript.MicrocontrollerXmlPath, newXml)) + if (!FileHelper.TryWriteFile(luaScript.VehicleXmlPath, newXml)) return; - Console.WriteLine($"Updated microcontroller {luaScript.MicrocontrollerName} XML with new script with ID {luaScript.ObjectId}."); + Console.WriteLine($"Updated vehicle {luaScript.VehicleName} XML with new script with ID {luaScript.ObjectId}."); } } } diff --git a/src/StormworksLuaExtract/Services/MicrocontrollersWatchService.cs b/src/StormworksLuaExtract/Services/VehiclesWatchService.cs similarity index 64% rename from src/StormworksLuaExtract/Services/MicrocontrollersWatchService.cs rename to src/StormworksLuaExtract/Services/VehiclesWatchService.cs index 3c4c849..0dd0925 100644 --- a/src/StormworksLuaExtract/Services/MicrocontrollersWatchService.cs +++ b/src/StormworksLuaExtract/Services/VehiclesWatchService.cs @@ -6,17 +6,19 @@ namespace StormworksLuaExtract.Services { - public class MicrocontrollersWatchService + public class VehiclesWatchService { public delegate void MicrocontrollerChangedHandler(string xmlFilePath); public event MicrocontrollerChangedHandler MicrocontrollerAdded; public event MicrocontrollerChangedHandler MicrocontrollerDeleted; + public event MicrocontrollerChangedHandler MicrocontrollerChanged; public void StartWatching() { var processorsXmlWatcher = new BufferedFileSystemWatcher(Statics.MicrocontrollerPath, "*.xml"); processorsXmlWatcher.Created += MicrocontrollerXmlFileAdded; + processorsXmlWatcher.Changed += MicrocontrollerXmlFileChanged; processorsXmlWatcher.Deleted += MicrocontrollerXmlFileDeleted; } @@ -24,14 +26,23 @@ private async void MicrocontrollerXmlFileAdded(object sender, FileSystemEventArg { await Task.Delay(Constants.ReadWriteTimeoutInMilliseconds); - Console.WriteLine($"Microcontroller XML file created: {e.Name}"); + Console.WriteLine($"Vehicle XML file created: {e.Name}"); MicrocontrollerAdded?.Invoke(e.FullPath); } + private async void MicrocontrollerXmlFileChanged(object sender, FileSystemEventArgs e) + { + await Task.Delay(Constants.ReadWriteTimeoutInMilliseconds); + + Console.WriteLine($"Microcontroller XML file changed: {e.Name}"); + + MicrocontrollerChanged?.Invoke(e.FullPath); + } + private void MicrocontrollerXmlFileDeleted(object sender, FileSystemEventArgs e) { - Console.WriteLine($"Microcontroller XML file deleted: {e.Name}"); + Console.WriteLine($"Vehicle XML file deleted: {e.Name}"); MicrocontrollerDeleted?.Invoke(e.FullPath); } diff --git a/src/StormworksLuaExtract/Services/XmlToLocalLuaWriteService.cs b/src/StormworksLuaExtract/Services/XmlToLocalLuaWriteService.cs index e305b73..f8bac9b 100644 --- a/src/StormworksLuaExtract/Services/XmlToLocalLuaWriteService.cs +++ b/src/StormworksLuaExtract/Services/XmlToLocalLuaWriteService.cs @@ -7,32 +7,32 @@ namespace StormworksLuaExtract.Services { public class XmlToLocalLuaWriteService { - public void WriteMicrocontrollerLuaScriptsToFiles(LuaScript luaScript) + public bool WriteVehicleLuaScriptToFile(LuaScript luaScript) { - Console.WriteLine($"Extracting Lua scripts from microcontroller '{luaScript.MicrocontrollerXmlPath}'"); - + Console.WriteLine($"Extracting Lua scripts from vehicle '{luaScript.VehicleXmlPath}'"); + + var vehicleXmlScript = ScriptExtractHelper.GetScriptFromXmlFile(luaScript.VehicleXmlPath, luaScript.ObjectId); + if (File.Exists(luaScript.LuaFilePath)) { - var currentScript = FileHelper.NoTouchReadFile(luaScript.LuaFilePath); + var currentLocalScript = FileHelper.NoTouchReadFile(luaScript.LuaFilePath); - if (currentScript == luaScript.Script) + if (currentLocalScript == vehicleXmlScript) { - Console.WriteLine($"Nothing changed for script {luaScript.ObjectId} from microcontroller {luaScript.MicrocontrollerName}."); - return; + Console.WriteLine($"Nothing changed for script {luaScript.ObjectId} from vehicle {luaScript.VehicleName}."); + return false; } // Backup - var backupFilePath = Path.Join(Statics.LocalBackupDirectory, $"{luaScript.MicrocontrollerName}_{luaScript.ObjectId} {DateTime.Now:yyyy-MM-dd HH-mm-ss}.lua"); - if (!FileHelper.TryWriteFile(backupFilePath, currentScript)) - return; - - Console.WriteLine($"Wrote backup to {backupFilePath}"); + if (!BackupFileHelper.BackupFile($"{luaScript.VehicleName}_{luaScript.ObjectId}", luaScript.VehicleName)) + return false; } + + FileHelper.TryWriteFile(luaScript.LuaFilePath, vehicleXmlScript); + Console.WriteLine($"Wrote script {luaScript.ObjectId} from vehicle {luaScript.VehicleName} to {luaScript.LuaFilePath}."); - FileHelper.TryWriteFile(luaScript.LuaFilePath, luaScript.Script); - - Console.WriteLine($"Wrote script {luaScript.ObjectId} from microcontroller {luaScript.MicrocontrollerName} to {luaScript.LuaFilePath}."); + return true; } } }