now based on YAVAPF!

This commit is contained in:
alterNERDtive 2022-07-11 12:08:53 +02:00
parent 9b9ab22e19
commit e150c0b55d
Signed by: alterNERDtive
GPG key ID: 547787A4FE6533F1
4 changed files with 124 additions and 109 deletions

View file

@ -13,6 +13,11 @@ jobs:
contents: write
steps:
- name: Install VoiceAttack
uses: alterNERDtive/setup-voiceattack-action@v1
with:
version: "1.10"
- name: Checkout source code
uses: actions/checkout@v2

View file

@ -1,3 +1,11 @@
# 0.1 (2021-03-24)
# devel
* initial release
## Changed
* Now based on [YAVAPF](https://alterNERDtive.github.io/YAVAPF)!
-----
# 0.1 (2021-03-24)
* initial release

View file

@ -28,14 +28,19 @@ using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using alterNERDtive.Yavapf;
using VoiceAttack;
namespace EliteScreenshots
{
/// <summary>
/// VoiceAttack plugin that automatically detects, converts and moves
/// screenshots created by Elite Dangerous in the background.
/// </summary>
public class EliteScreenshots
public class EliteScreenshots : VoiceAttackPlugin
{
private static readonly EliteScreenshots Plugin;
private static readonly string ScreenshotsDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyPictures), @"Frontier Developments\Elite Dangerous");
private static readonly string DefaultFormat = "%datetime%-%cmdr%-%system%-%body%";
private static readonly string DefaultOutputDirectory = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
@ -44,10 +49,19 @@ namespace EliteScreenshots
private static readonly Regex HighResRegex = new (@"^HighResScreenShot_\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2}.bmp$");
private static readonly Regex TokenRegex = new (@"%(?<token>[\w: \-\.]*)%");
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1306:Field names should begin with lower-case letter", Justification = "just cause")]
private static dynamic? VA;
private static FileSystemWatcher? fileWatcher;
static EliteScreenshots()
{
Plugin = new ()
{
Name = "EliteScreenshots",
Version = "0.2",
Info = string.Empty,
Guid = "{252490FD-2E6F-4703-900B-02ED98D717C2}",
};
}
private static FileSystemWatcher FileWatcher
{
get
@ -62,67 +76,91 @@ namespace EliteScreenshots
}
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1201:Elements should appear in the correct order", Justification = "nicer grouping")]
private static readonly Version VERSION = new ("0.1");
/// <summary>
/// The plugins display name, as required by the VoiceAttack plugin API.
/// </summary>
/// <returns>The display name.</returns>
public static string VA_DisplayName() => $"EliteScreenshots Plugin {VERSION}";
public static string VA_DisplayName() => Plugin.VaDisplayName();
/// <summary>
/// The plugins description, as required by the VoiceAttack plugin API.
/// </summary>
/// <returns>The description.</returns>
public static string VA_DisplayInfo() => VA_DisplayName();
public static string VA_DisplayInfo() => Plugin.VaDisplayName();
/// <summary>
/// The plugins GUID, as required by the VoiceAtatck plugin API.
/// </summary>
/// <returns>The GUID.</returns>
public static Guid VA_Id() => new Guid("{252490FD-2E6F-4703-900B-02ED98D717C2}");
public static Guid VA_Id() => Plugin.VaId();
/// <summary>
/// The Init method, as required by the VoiceAttack plugin API.
/// Runs when the plugin is initially loaded.
/// </summary>
/// <param name="vaProxy">The VoiceAttack proxy object.</param>
public static void VA_Init1(dynamic vaProxy)
public static void VA_Init1(dynamic vaProxy) => Plugin.VaInit1(vaProxy);
/// <summary>
/// The Invoke method, as required by the VoiceAttack plugin API.
/// Runs whenever a plugin context is invoked.
/// </summary>
/// <param name="vaProxy">The VoiceAttack proxy object.</param>
public static void VA_Invoke1(dynamic vaProxy) => Plugin.VaInvoke1(vaProxy);
/// <summary>
/// The Exit method, as required by the VoiceAttack plugin API.
/// Runs when VoiceAttack is shut down.
/// </summary>
/// <param name="vaProxy">The VoiceAttack proxy object.</param>
public static void VA_Exit1(dynamic vaProxy) => Plugin.VaExit1(vaProxy);
/// <summary>
/// The StopCommand method, as required by the VoiceAttack plugin API.
/// Runs whenever all commands are stopped using the “Stop All Commands”
/// button or action.
/// </summary>
public static void VA_StopCommand() => Plugin.VaStopCommand();
/// <summary>
/// Checks for old screenshots and starts watching the screenshots
/// directory for new files on Init.
/// </summary>
/// <param name="vaProxy">The <see cref="VoiceAttackInitProxyClass"/>
/// object.</param>
[Init]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "Required by plugin API")]
public static void Init(VoiceAttackInitProxyClass vaProxy)
{
VA = vaProxy;
VA.TextVariableChanged += new Action<string, string, string, Guid?>(TextVariableChanged);
VA.SetText("EliteScreenshots.version", VERSION.ToString());
Plugin.Log.LogLevel = LogLevel.INFO;
try
{
// inform about old shots
DirectoryInfo dirInfo = new DirectoryInfo(ScreenshotsDirectory);
DirectoryInfo dirInfo = new (ScreenshotsDirectory);
int standardCount = dirInfo.GetFiles().Where(file => StandardRegex.IsMatch(file.Name)).Count();
int highResCount = dirInfo.GetFiles().Where(file => HighResRegex.IsMatch(file.Name)).Count();
if (standardCount > 0 && highResCount > 0)
{
LogInfo($"There are {standardCount} old screenshots and {highResCount} old high res screenshots.");
Plugin.Log.Info($"There are {standardCount} old screenshots and {highResCount} old high res screenshots.");
}
else if (standardCount > 0)
{
LogInfo($"There are {standardCount} old screenshots.");
Plugin.Log.Info($"There are {standardCount} old screenshots.");
}
else if (highResCount > 0)
{
LogInfo($"There are {highResCount} old high res screenshots.");
Plugin.Log.Info($"There are {highResCount} old high res screenshots.");
}
if (standardCount > 0 || highResCount > 0)
{
LogInfo($"Run the “convertold” plugin context to convert them.");
Plugin.Log.Info($"Run the “convertold” plugin context to convert them.");
}
}
catch (Exception e)
{
LogError(e.Message);
Plugin.Log.Info(e.Message);
}
finally
{
@ -131,68 +169,54 @@ namespace EliteScreenshots
}
/// <summary>
/// The Invoke method, as required by the VoiceAttack plugin API.
/// Runs whenever a plugin context is invoked.
/// Converts and moves old screenshots.
/// </summary>
/// <param name="vaProxy">The VoiceAttack proxy object.</param>
public static void VA_Invoke1(dynamic vaProxy)
/// <param name="vaProxy">The <see cref="VoiceAttackInvokeProxyClass"/>
/// object.</param>
[Context("convertold")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "Required by plugin API")]
public static void ConvertOldShots(VoiceAttackInvokeProxyClass vaProxy)
{
VA = vaProxy;
try
DirectoryInfo dirInfo = new (ScreenshotsDirectory);
foreach (FileInfo fileInfo in dirInfo.GetFiles().Where(file => StandardRegex.IsMatch(file.Name)).ToList())
{
string context = VA.Context.ToLower();
if (context == "convertold")
{
ConvertOldShots();
}
else
{
LogError($"Invalid plugin context: '{context}'.");
}
ConvertAndMove(fileInfo.FullName, target: GetTargetFileName(fromFile: fileInfo.FullName));
}
catch (Exception e)
foreach (FileInfo fileInfo in dirInfo.GetFiles().Where(file => HighResRegex.IsMatch(file.Name)).ToList())
{
LogError(e.Message);
ConvertAndMove(fileInfo.FullName, target: GetTargetFileName(fromFile: fileInfo.FullName, highres: true), highres: true);
}
}
/// <summary>
/// The Exit method, as required by the VoiceAttack plugin API.
/// Runs when VoiceAttack is shut down.
/// Handles changes to configuration variables.
/// </summary>
/// <param name="vaProxy">The VoiceAttack proxy object.</param>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "required by VoiceAttack plugin API")]
public static void VA_Exit1(dynamic vaProxy)
/// <param name="name">The name of the variable.</param>
/// <param name="from">The old value.</param>
/// <param name="to">The new value.</param>
[String(@"^EliteScreenshots\.(format|outputDirectory)#")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "Required by plugin API")]
public static void ConfigurationChanged(string name, string from, string to)
{
}
if (name == "EliteScreenshots.format#")
{
// FIXXME: check if actually valid, error otherwise
// (or just give example output along with it?)
Plugin.Log.Info($"Output format changed to '{to}'.");
}
/// <summary>
/// The StopCommand method, as required by the VoiceAttack plugin API.
/// Runs whenever all commands are stopped using the “Stop All Commands”
/// button or action.
/// </summary>
public static void VA_StopCommand()
{
}
private static void LogError(string message)
{
VA!.WriteToLog($"ERROR | EliteScreenshots: {message}", "red");
}
private static void LogInfo(string message)
{
VA!.WriteToLog($"INFO | EliteScreenshots: {message}", "blue");
}
private static void LogWarn(string message)
{
VA!.WriteToLog($"WARN | EliteScreenshots: {message}", "yellow");
if (name == "EliteScreenshots.outputDirectory#")
{
// FIXXME check if it exists
Plugin.Log.Info($"Output directory changed to '{to}'.");
}
}
private static string GetTargetFileName(bool highres = false, string? fromFile = null)
{
StringBuilder sb = new StringBuilder(VA!.GetText("EliteScreenshots.format#") ?? DefaultFormat);
StringBuilder sb = new (Plugin.Get<string>("EliteScreenshots.format#") ?? DefaultFormat);
MatchCollection matches = TokenRegex.Matches(sb.ToString());
string token;
@ -205,14 +229,14 @@ namespace EliteScreenshots
value = token switch
{
"body" => VA!.GetText("Status body name") ?? "unknown",
"cmdr" => VA!.GetText("Name") ?? "unknown",
"body" => Plugin.Get<string>("Status body name") ?? "unknown",
"cmdr" => Plugin.Get<string>("Name") ?? "unknown",
"date" => DateTime.Now.ToString("yyyy-MM-dd"),
"datetime" => DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss"),
"shipname" => VA!.GetText("Ship name") ?? "unknown",
"system" => VA!.GetText("System name") ?? "unknown",
"shipname" => Plugin.Get<string>("Ship name") ?? "unknown",
"system" => Plugin.Get<string>("System name") ?? "unknown",
"time" => DateTime.Now.ToString("HH-mm-ss"),
"vehicle" => VA!.GetText("Status vehicle") ?? "unknown",
"vehicle" => Plugin.Get<string>("Status vehicle") ?? "unknown",
_ => $"%{token}%",
};
sb.Replace($"%{token}%", value);
@ -246,7 +270,7 @@ namespace EliteScreenshots
sb.Replace(c, '_');
}
string outputDirectory = VA!.GetText("EliteScreenshots.outputDirectory#") ?? DefaultOutputDirectory;
string outputDirectory = Plugin.Get<string>("EliteScreenshots.outputDirectory#") ?? DefaultOutputDirectory;
string targetFilename = Path.Combine(outputDirectory, $"{sb}{(highres ? "-highres" : string.Empty)}.png");
if (File.Exists(targetFilename))
@ -276,44 +300,13 @@ namespace EliteScreenshots
bm.Save(target, ImageFormat.Png);
}
LogInfo($"Saved{(highres ? " high resolution" : string.Empty)} screenshot to '{target}'.");
Plugin.Log.Info($"Saved{(highres ? " high resolution" : string.Empty)} screenshot to '{target}'.");
File.Delete(source);
return target;
}
private static void ConvertOldShots()
{
DirectoryInfo dirInfo = new (ScreenshotsDirectory);
foreach (FileInfo fileInfo in dirInfo.GetFiles().Where(file => StandardRegex.IsMatch(file.Name)).ToList())
{
ConvertAndMove(fileInfo.FullName, target: GetTargetFileName(fromFile: fileInfo.FullName));
}
foreach (FileInfo fileInfo in dirInfo.GetFiles().Where(file => HighResRegex.IsMatch(file.Name)).ToList())
{
ConvertAndMove(fileInfo.FullName, target: GetTargetFileName(fromFile: fileInfo.FullName, highres: true), highres: true);
}
}
private static void TextVariableChanged(string name, string from, string to, Guid? internalID = null)
{
if (name == "EliteScreenshots.format#")
{
// FIXXME: check if actually valid, error otherwise
// (or just give example output along with it?)
LogInfo($"Output format changed to '{to}'.");
}
if (name == "EliteScreenshots.outputDirectory#")
{
// FIXXME check if it exists
LogInfo($"Output directory changed to '{to}'.");
}
}
private static void FileChangedHandler(FileSystemEventArgs eventArgs)
{
string name = eventArgs.Name;
@ -339,7 +332,7 @@ namespace EliteScreenshots
}
catch (Exception e)
{
LogError(e.Message);
Plugin.Log.Error(e.Message);
}
}
}

View file

@ -40,6 +40,10 @@
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
<Reference Include="VoiceAttack">
<HintPath>C:\Program Files\VoiceAttack\VoiceAttack.exe</HintPath>
<Private>False</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="EliteScreenshots.cs" />
@ -60,8 +64,13 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<PackageReference Include="alterNERDtive.YAVAPF">
<Version>0.1.0</Version>
</PackageReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name="AfterBuild" Condition=" '$(Configuration)' == 'Release' ">
<ZipDirectory SourceDirectory="bin" DestinationFile="VoiceAttack-EliteScreenshots.zip" Overwrite="true" />
</Target>
</Project>
</Project>