From a5379d290c0076df808175b5ae862eaadf7aded1 Mon Sep 17 00:00:00 2001
From: chylex <contact@chylex.com>
Date: Wed, 4 Apr 2018 23:13:44 +0200
Subject: [PATCH] Add resource hotswap for easier debugging

---
 Core/FormBrowser.cs       |  4 +++
 Resources/PostBuild.ps1   | 12 ++++++--
 Resources/ScriptLoader.cs | 65 ++++++++++++++++++++++++++++++++++++++-
 3 files changed, 77 insertions(+), 4 deletions(-)

diff --git a/Core/FormBrowser.cs b/Core/FormBrowser.cs
index e0b1c273..3d301107 100644
--- a/Core/FormBrowser.cs
+++ b/Core/FormBrowser.cs
@@ -297,6 +297,10 @@ public void ReinjectCustomCSS(string css){
         }
 
         public void ReloadToTweetDeck(){
+            #if DEBUG
+            Resources.ScriptLoader.HotSwap();
+            #endif
+
             browser.ReloadToTweetDeck();
             AnalyticsFile.BrowserReloads.Trigger();
         }
diff --git a/Resources/PostBuild.ps1 b/Resources/PostBuild.ps1
index 66564dbb..d35be1a0 100644
--- a/Resources/PostBuild.ps1
+++ b/Resources/PostBuild.ps1
@@ -1,6 +1,7 @@
 Param(
   [Parameter(Mandatory = $True, Position = 1)][string] $targetDir,
-  [Parameter(Mandatory = $True, Position = 2)][string] $projectDir
+  [Parameter(Mandatory = $True, Position = 2)][string] $projectDir,
+  [Parameter(Position = 3)][string] $version = ""
 )
 
 $ErrorActionPreference = "Stop"
@@ -8,14 +9,19 @@ $ErrorActionPreference = "Stop"
 try{
   Write-Host "------------------------------"
   
-  $version = (Get-Item (Join-Path $targetDir "TweetDuck.exe")).VersionInfo.FileVersion
+  if ($version.Equals("")){
+    $version = (Get-Item (Join-Path $targetDir "TweetDuck.exe")).VersionInfo.FileVersion
+  }
+  
   Write-Host "TweetDuck version" $version
   
   Write-Host "------------------------------"
   
   # Cleanup
   
-  Remove-Item -Path (Join-Path $targetDir "locales\*.pak") -Exclude "en-US.pak"
+  if (Test-Path (Join-Path $targetDir "locales")){
+    Remove-Item -Path (Join-Path $targetDir "locales\*.pak") -Exclude "en-US.pak"
+  }
   
   # Copy resources
   
diff --git a/Resources/ScriptLoader.cs b/Resources/ScriptLoader.cs
index 9e4e920b..c30c0ed7 100644
--- a/Resources/ScriptLoader.cs
+++ b/Resources/ScriptLoader.cs
@@ -5,14 +5,77 @@
 using System.Windows.Forms;
 using TweetDuck.Core.Controls;
 using TweetDuck.Core.Other;
+#if DEBUG
+using System.Diagnostics;
+#endif
 
 namespace TweetDuck.Resources{
     static class ScriptLoader{
         private const string UrlPrefix = "td:";
+
+        #if DEBUG
+        private static readonly string HotSwapProjectRoot = FixPathSlash(Path.GetFullPath(Path.Combine(Program.ProgramPath, "../../../")));
+        private static readonly string HotSwapTargetDir = FixPathSlash(Path.Combine(HotSwapProjectRoot, "bin", "tmp"));
+        private static readonly string HotSwapRebuildScript = Path.Combine(HotSwapProjectRoot, "Resources", "PostBuild.ps1");
+        
+        // TODO figure out hotswap support for plugins and scripts/plugins.* files
+
+        static ScriptLoader(){
+            if (File.Exists(HotSwapRebuildScript)){
+                Debug.WriteLine("Activating resource hot swap");
+
+                ResetHotSwap();
+                Application.ApplicationExit += (sender, args) => ResetHotSwap();
+            }
+        }
+
+        public static void HotSwap(){
+            if (!File.Exists(HotSwapRebuildScript)){
+                Debug.WriteLine("Failed resource hot swap, missing rebuild script: "+HotSwapRebuildScript);
+                return;
+            }
+            
+            ResetHotSwap();
+            Directory.CreateDirectory(HotSwapTargetDir);
+
+            using(Process process = Process.Start(new ProcessStartInfo{
+                FileName = "powershell",
+                Arguments = $"-ExecutionPolicy Unrestricted -File \"{HotSwapRebuildScript}\" \"{HotSwapTargetDir}\\\" \"{HotSwapProjectRoot}\\\" \"{Program.VersionTag}\"",
+                WindowStyle = ProcessWindowStyle.Hidden
+            })){
+                // ReSharper disable once PossibleNullReferenceException
+                if (!process.WaitForExit(8000)){
+                    Debug.WriteLine("Failed resource hot swap, script did not finish in time");
+                }
+                else if (process.ExitCode != 0){
+                    Debug.WriteLine("Failed resource hot swap, script exited with code "+process.ExitCode);
+                }
+            }
+        }
+
+        private static void ResetHotSwap(){
+            try{
+                Directory.Delete(HotSwapTargetDir, true);
+            }catch(DirectoryNotFoundException){}
+        }
+
+        private static string FixPathSlash(string path){
+            return path.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)+'\\';
+        }
+        #endif
         
         public static string LoadResource(string name, bool silent = false, Control sync = null){
             try{
-                string contents = File.ReadAllText(Path.Combine(Program.ScriptPath, name), Encoding.UTF8);
+                string path = Program.ScriptPath;
+
+                #if DEBUG
+                if (Directory.Exists(HotSwapTargetDir)){
+                    path = Path.Combine(HotSwapTargetDir, "scripts");
+                    Debug.WriteLine("Hot swap active, redirecting "+name);
+                }
+                #endif
+
+                string contents = File.ReadAllText(Path.Combine(path, name), Encoding.UTF8);
                 int separator;
 
                 // first line can be either: