Skip to content

Commit

Permalink
Amethyst task scheduler 😳 (startup/shutdown, update/delete)
Browse files Browse the repository at this point in the history
  • Loading branch information
KimihikoAkayasaki committed Mar 12, 2023
1 parent 9c5cda7 commit cdd6a88
Show file tree
Hide file tree
Showing 15 changed files with 631 additions and 100 deletions.
6 changes: 3 additions & 3 deletions Amethyst/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public App()
$"Amethyst_{DateTime.Now:yyyyMMdd-HHmmss.ffffff}.log"));

// Create an empty file for checking for crashes
Interfacing.CrashFile = new FileInfo(Path.Join(Interfacing.GetProgramLocation().DirectoryName, ".crash"));
Interfacing.CrashFile = new FileInfo(Path.Join(Interfacing.ProgramLocation.DirectoryName, ".crash"));
Interfacing.CrashFile.Create(); // Create the file

try
Expand Down Expand Up @@ -151,7 +151,7 @@ public App()

// Create the strings directory in case it doesn't exist yet
Directory.CreateDirectory(Path.Join(
Interfacing.GetProgramLocation().DirectoryName, "Assets", "Strings"));
Interfacing.ProgramLocation.DirectoryName, "Assets", "Strings"));

// Load language resources
Interfacing.LoadJsonStringResourcesEnglish();
Expand All @@ -160,7 +160,7 @@ public App()
// Setup string hot reload watchdog
ResourceWatcher = new FileSystemWatcher
{
Path = Path.Join(Interfacing.GetProgramLocation().DirectoryName, "Assets", "Strings"),
Path = Path.Join(Interfacing.ProgramLocation.DirectoryName, "Assets", "Strings"),
NotifyFilter = NotifyFilters.CreationTime | NotifyFilters.FileName |
NotifyFilters.LastWrite | NotifyFilters.DirectoryName,
IncludeSubdirectories = true,
Expand Down
7 changes: 7 additions & 0 deletions Amethyst/Assets/Strings/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,13 @@
"/SharedStrings/PluginUpdates/Statuses/Downloading": "Downloading {0} v{1}...",
"/SharedStrings/PluginUpdates/Statuses/Error": "Error updating {0}!",

"/PluginStore/Titles/Installing/Setup": "Installing {0}...",
"/PluginStore/Titles/Installing/Error": "Error installing {0}!",
"/PluginStore/Titles/Installing/Success": "Installed {0}!",
"/PluginStore/Captions/Installing/Downloading": "Downloading the plugin package...",
"/PluginStore/Captions/Installing/Error": "Couldn't install the plugin due to an error. Please try again later.",
"/PluginStore/Captions/Installing/Success": "Plugin installed! Amethyst should load it the next time it opens.",

"/CrashHandler/Content/AlreadyRunning": "Looks like the app is already running\nand you've tried to launch a second instance,\nthis action is not currently supported.\n\nPlease check if the app isn't opened.\nIf problem persists, press the 'Force Exit' button.",
"/CrashHandler/Content/Crash/NoPlugins": "There were no appropriate plugins available to load and use in Amethyst.\n\nPlease check if you have all dependencies installed, like proper Service or Framework Runtime and other dependency libraries needed by your plugins.",
"/CrashHandler/Content/Crash/NoDevices": "There were no appropriate device plugins available to load and use for body tracking.\n\nPlease check if you have all dependencies installed, like proper Kinect SDK / Runtime and other dependency libraries needed by your devices.",
Expand Down
10 changes: 5 additions & 5 deletions Amethyst/Classes/AppSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -255,12 +255,12 @@ tracker.OrientationTrackingOption is JointRotationTrackingOption.SoftwareCalcula
Logger.Info("Checking out the default configuration settings...");
(bool ExtraTrackers, bool Valid) defaultSettings = (false, false); // Invalid for now!

if (File.Exists(Path.Join(Interfacing.GetProgramLocation().DirectoryName, "defaults.json")))
if (File.Exists(Path.Join(Interfacing.ProgramLocation.DirectoryName, "defaults.json")))
try
{
// Parse the loaded json
var jsonHead = JsonObject.Parse(File.ReadAllText(
Path.Join(Interfacing.GetProgramLocation().DirectoryName, "defaults.json")));
Path.Join(Interfacing.ProgramLocation.DirectoryName, "defaults.json")));

if (!jsonHead.ContainsKey("ExtraTrackers"))
// Invalid configuration file, don't proceed further!
Expand Down Expand Up @@ -366,7 +366,7 @@ tracker.OrientationTrackingOption is JointRotationTrackingOption.SoftwareCalcula

// Optionally fix the selected language / select a new one
var resourcePath = Path.Join(
Interfacing.GetProgramLocation().DirectoryName,
Interfacing.ProgramLocation.DirectoryName,
"Assets", "Strings", AppLanguage + ".json");

// If there's no specified language, fallback to {system}
Expand All @@ -377,7 +377,7 @@ tracker.OrientationTrackingOption is JointRotationTrackingOption.SoftwareCalcula

Logger.Warn($"No language specified! Trying with the system one: \"{AppLanguage}\"!");
resourcePath = Path.Join(
Interfacing.GetProgramLocation().DirectoryName, "Assets", "Strings", AppLanguage + ".json");
Interfacing.ProgramLocation.DirectoryName, "Assets", "Strings", AppLanguage + ".json");
}

// If the specified language doesn't exist somehow, fallback to 'en'
Expand All @@ -387,7 +387,7 @@ tracker.OrientationTrackingOption is JointRotationTrackingOption.SoftwareCalcula

AppLanguage = "en"; // Change to english
resourcePath = Path.Join(
Interfacing.GetProgramLocation().DirectoryName,
Interfacing.ProgramLocation.DirectoryName,
"Assets", "Strings", AppLanguage + ".json");
}

Expand Down
20 changes: 7 additions & 13 deletions Amethyst/Classes/Interfacing.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,15 +93,9 @@ public static bool

public static bool IsServiceEndpointPresent => ServiceEndpointStatusCode == 0;

public static FileInfo GetProgramLocation()
{
return new FileInfo(Assembly.GetExecutingAssembly().Location);
}
public static FileInfo ProgramLocation => new(Assembly.GetExecutingAssembly().Location);

public static DirectoryInfo GetAppDataTempDir()
{
return Directory.CreateDirectory(Path.GetTempPath() + "Amethyst");
}
public static DirectoryInfo AppDataTempDir => Directory.CreateDirectory(Path.GetTempPath() + "Amethyst");

public static string GetAppDataFileDir(string relativeFilePath)
{
Expand All @@ -128,7 +122,7 @@ public static void Fail(string message)
IsExitHandled = true;

// Find the crash handler and show it with a custom message
var hPath = Path.Combine(GetProgramLocation().DirectoryName!, "K2CrashHandler", "K2CrashHandler.exe");
var hPath = Path.Combine(ProgramLocation.DirectoryName!, "K2CrashHandler", "K2CrashHandler.exe");
if (File.Exists(hPath)) Process.Start(hPath, new[] { "message", message });
else Logger.Warn("Crash handler exe (./K2CrashHandler/K2CrashHandler.exe) not found!");

Expand Down Expand Up @@ -469,7 +463,7 @@ public static string GetLocalizedLanguageName(string languageKey)
{
// Load the locales.json from Assets/Strings/
var resourcePath = Path.Join(
GetProgramLocation().DirectoryName,
ProgramLocation.DirectoryName,
"Assets", "Strings", "locales.json");

// If the specified language doesn't exist somehow, fallback to 'en'
Expand Down Expand Up @@ -517,7 +511,7 @@ public static void LoadJsonStringResources(string languageKey)
Logger.Info($"Searching for language resources with key \"{languageKey}\"...");

var resourcePath = Path.Join(
GetProgramLocation().DirectoryName,
ProgramLocation.DirectoryName,
"Assets", "Strings", languageKey + ".json");

// If the specified language doesn't exist somehow, fallback to 'en'
Expand All @@ -527,7 +521,7 @@ public static void LoadJsonStringResources(string languageKey)
$"\"{resourcePath}\", falling back to 'en' (en.json)!");

resourcePath = Path.Join(
GetProgramLocation().DirectoryName,
ProgramLocation.DirectoryName,
"Assets", "Strings", "en.json");
}

Expand Down Expand Up @@ -564,7 +558,7 @@ public static void LoadJsonStringResourcesEnglish()
Logger.Info("Searching for shared (English) language resources...");

var resourcePath = Path.Join(
GetProgramLocation().DirectoryName,
ProgramLocation.DirectoryName,
"Assets", "Strings", "en.json");

// If failed again, just give up
Expand Down
18 changes: 12 additions & 6 deletions Amethyst/MVVM/PluginHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
using static Amethyst.Classes.Interfacing;
using Windows.Media.Protection.PlayReady;
using Windows.Storage;
using Amethyst.Schedulers;

namespace Amethyst.MVVM;

Expand Down Expand Up @@ -248,7 +249,7 @@ public void RequestExit(string message, bool fatal = false)
// Launch the crash handler if fatal
if (fatal)
{
var hPath = Path.Combine(GetProgramLocation().DirectoryName!, "K2CrashHandler", "K2CrashHandler.exe");
var hPath = Path.Combine(ProgramLocation.DirectoryName!, "K2CrashHandler", "K2CrashHandler.exe");
if (File.Exists(hPath)) Process.Start(hPath, new[] { "plugin_message", message, Guid });
else Logger.Warn("Crash handler exe (./K2CrashHandler/K2CrashHandler.exe) not found!");
}
Expand All @@ -271,8 +272,6 @@ public class LoadAttemptedPlugin : INotifyPropertyChanged
private RestClient GithubClient => _githubClient ??= new RestClient(
UpdateEndpoint ?? $"{Website?.TrimEnd('/')}/releases/download/latest/");

private RestClient ApiClient { get; } = new("https://api.github.com");

public string Name { get; init; } = "[UNKNOWN]";
public string Guid { get; init; } = "[INVALID]";
public string Error { get; init; }
Expand Down Expand Up @@ -558,10 +557,17 @@ public async Task<bool> ExecuteUpdates()
}

// Rename the downloaded zip to $({Folder}.Name).next.zip
File.Move(Path.Join(Folder, UpdateData.Download),
Path.Join(Folder, $"{new DirectoryInfo(Folder).Name}.next.zip"), true);
var updateZip = Path.Join(Folder, $"{new DirectoryInfo(Folder).Name}.next.zip");
File.Move(Path.Join(Folder, UpdateData.Download), updateZip, true);

// No files to download, switch to update error
// Register the update in the Amethyst task scheduler
StartupController.Controller.StartupTasks.Add(new StartupUpdateTask
{
Name = $"Update {Name} to version {UpdateData.Version}",
Priority = true, PluginFolder = Folder, UpdatePackage = updateZip
});

// Everything's fine, show the restart notice
Shared.Main.PluginsUpdatePendingInfoBar.Message = string.Format(LocalizedJsonString(
"/SharedStrings/PluginUpdates/Headers/Restart"), Name);

Expand Down
70 changes: 70 additions & 0 deletions Amethyst/MVVM/StorePlugin.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using Amethyst.Classes;
using Microsoft.UI.Xaml.Controls;

namespace Amethyst.MVVM;

public class StorePlugin : INotifyPropertyChanged
{
public string Name { get; set; }
public bool Official { get; set; } = false;

public bool Installing { get; set; } = false;
public bool InstallSuccess { get; set; } = false;
public bool InstallError { get; set; } = false;

public IEnumerable<Contributor> Contributors { get; set; }
public PluginRepository Repository { get; set; }
public PluginRelease LatestRelease { get; set; }

public event PropertyChangedEventHandler PropertyChanged;

// MVVM stuff
public string TrimString(string s, int l)
{
return s?[..Math.Min(s.Length, l)] +
(s?.Length > l ? "..." : "");
}

public double BoolToOpacity(bool value)
{
return value ? 1.0 : 0.0;
}

public void OnPropertyChanged(string propName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
}

public string FormatResourceString(string resourceName)
{
return string.Format(Interfacing.LocalizedJsonString(resourceName), Name);
}

public class PluginRepository
{
public string Name { get; set; }
public string FullName { get; set; }