Skip to content

Commit

Permalink
Merge branch 'bi-directional-update'
Browse files Browse the repository at this point in the history
  • Loading branch information
Rene-Sackers committed May 19, 2019
2 parents ce57119 + f13c90e commit 6b5944b
Show file tree
Hide file tree
Showing 9 changed files with 154 additions and 71 deletions.
21 changes: 21 additions & 0 deletions src/StormworksLuaExtract/Helpers/BackupFileHelper.cs
Original file line number Diff line number Diff line change
@@ -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;
}
}
}
29 changes: 20 additions & 9 deletions src/StormworksLuaExtract/Helpers/ScriptExtractHelper.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text.RegularExpressions;
using StormworksLuaExtract.Models;

Expand All @@ -23,18 +24,28 @@ public static IEnumerable<LuaScript> 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 <object item, and once under a <c33 item
if (element != "object")
continue;

var objectId = match.Groups["id"].Value;
var script = match.Groups["script"].Value;
script = System.Net.WebUtility.HtmlDecode(script);

yield return new LuaScript(microcontrollerXmlFilePath, GetLuaFilePath(microcontrollerXmlFilePath, objectId), objectId, script);
yield return new LuaScript(microcontrollerXmlFilePath, GetLuaFilePath(microcontrollerXmlFilePath, objectId), objectId);
}
}

public static string GetScriptFromXmlFile(string xmlFile, string objectId)
{
string xml;
try
{
xml = FileHelper.NoTouchReadFile(xmlFile);
}
catch
{
return null;
}

var match = Regex.Match(xml, Statics.ObjectMatchPattern(objectId));
var script = match.Groups["script"].Value;

return WebUtility.HtmlDecode(script);
}

private static string GetLuaFilePath(string xmlFilePath, string scriptObjectId)
Expand Down
2 changes: 1 addition & 1 deletion src/StormworksLuaExtract/Models/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
{
public static class Constants
{
public const int ReadWriteTimeoutInMilliseconds = 2000;
public const int ReadWriteTimeoutInMilliseconds = 1000;
}
}
17 changes: 7 additions & 10 deletions src/StormworksLuaExtract/Models/LuaScript.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,21 @@ namespace StormworksLuaExtract.Models
{
public class LuaScript
{
public string MicrocontrollerXmlPath { get; }
public string VehicleXmlPath { get; }

public string LuaFilePath { get; }
public string VehicleName => 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);
}
}
}
2 changes: 1 addition & 1 deletion src/StormworksLuaExtract/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public static void Main()
var builder = new ContainerBuilder();

builder.RegisterType<ApplicationService>().AsSelf();
builder.RegisterType<MicrocontrollersWatchService>().AsSelf();
builder.RegisterType<VehiclesWatchService>().AsSelf();
builder.RegisterType<LocalLuaToXmlWriteService>().AsSelf();
builder.RegisterType<XmlToLocalLuaWriteService>().AsSelf();

Expand Down
79 changes: 64 additions & 15 deletions src/StormworksLuaExtract/Services/ApplicationService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<LuaScript> _luaScripts = new List<LuaScript>();
private readonly List<string> _ignoreNextLuaUpdatePaths = new List<string>();

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))
{
Expand Down Expand Up @@ -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;
Expand All @@ -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);
}
}
Expand Down
28 changes: 11 additions & 17 deletions src/StormworksLuaExtract/Services/LocalLuaToXmlWriteService.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Text.RegularExpressions;
using StormworksLuaExtract.Helpers;
Expand All @@ -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;
}

Expand All @@ -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, "<object id=\"${id}\" script='" + newScript + "'>");

// 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}.");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,32 +6,43 @@

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;
}

private async void MicrocontrollerXmlFileAdded(object sender, FileSystemEventArgs e)
{
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);
}
Expand Down
Loading

0 comments on commit 6b5944b

Please sign in to comment.