diff --git a/CURRENT_VERSION b/CURRENT_VERSION
new file mode 100644
index 0000000..09f0887
--- /dev/null
+++ b/CURRENT_VERSION
@@ -0,0 +1 @@
+v0.1.0.3116-Beta
diff --git a/RELEASE_NOTES.Template.xml b/RELEASE_NOTES.Template.xml
new file mode 100644
index 0000000..08847d3
--- /dev/null
+++ b/RELEASE_NOTES.Template.xml
@@ -0,0 +1,9 @@
+
+ 0.0.0.#BuildNo#
+ Beta
+ #Timestamp#
+ https://github.com/anoyetta-academy/kagami/releases/download/#Tag#/#ArchiveFileName#
+
+ descriptions...
+
+
diff --git a/RELEASE_NOTES.xml b/RELEASE_NOTES.xml
new file mode 100644
index 0000000..a5e6ab5
--- /dev/null
+++ b/RELEASE_NOTES.xml
@@ -0,0 +1,31 @@
+
+
+ kagami
+
+
+
+
+ 0.1.0.3116
+ Beta
+ 2019-07-05T16:24:43.9716721+09:00
+ https://github.com/anoyetta-academy/kagami/releases/download/v0.1.0.3116-Beta/kagami_v0_1_0_3116_Beta.zip
+
+ * Beta1
+ * 範囲スキルが重複してしまう場合がある不具合を修正した
+ * スキルが抜けてしまう場合がある不具合を修正した
+ * アクションのソート順をタイムスタンプ順から発生順に変更した
+ * isActiveフラグが機能していなかった不具合を修正した
+ * ログファイルのファイル名の書式を変更した
+ * ログファイルの出力タイミングを変更した
+ * encount の終了時に onEndEncounter イベントを発生させるようにした
+ * PCをターゲットまたはフォーカスターゲットしたときそのPCのアクションをキャプチャーするようにした
+
+
+
diff --git a/git_merge_into_master.ps1 b/git_merge_into_master.ps1
new file mode 100644
index 0000000..3414695
--- /dev/null
+++ b/git_merge_into_master.ps1
@@ -0,0 +1,23 @@
+$cd = Split-Path -Parent $MyInvocation.MyCommand.Path
+Set-Location $cd
+
+# version
+$tag = $(Get-Content .\CURRENT_VERSION).Trim("\r").Trim("\n")
+Write-Output ("-> " + $tag)
+
+'-> commit'
+git commit -a -m $tag
+
+'-> checkout master'
+git checkout master
+
+'-> merge develop into master'
+git merge develop -m ("Merge branch develop " + $tag) --no-ff
+
+Write-Output ("-> tag " + $tag)
+git tag $tag
+
+git checkout develop
+
+'done!'
+pause
diff --git a/git_pull.ps1 b/git_pull.ps1
new file mode 100644
index 0000000..775673d
--- /dev/null
+++ b/git_pull.ps1
@@ -0,0 +1,8 @@
+'-> pull master'
+git pull origin master
+
+'-> pull develop'
+git pull origin develop
+
+'done!'
+pause
diff --git a/git_push.ps1 b/git_push.ps1
new file mode 100644
index 0000000..6b2f104
--- /dev/null
+++ b/git_push.ps1
@@ -0,0 +1,8 @@
+'-> push master'
+git push origin master --tags
+
+'-> push develop'
+git push origin develop --tags
+
+'done!'
+pause
diff --git a/make.ps1 b/make.ps1
new file mode 100644
index 0000000..f8ff50f
--- /dev/null
+++ b/make.ps1
@@ -0,0 +1,164 @@
+# DebugMode?
+$isDebug = $false
+#$isDebug = $true
+
+function EndMake() {
+ if (!$isDebug) {
+ Stop-Transcript | Out-Null
+ }
+
+ ''
+ Read-Host "終了するには何かキーを教えてください..."
+ exit
+}
+
+function GetBuildNo(
+ [datetime]$timestamp) {
+ return ([int]($timestamp.ToString("yy")) + $timestamp.Month + $timestamp.Day).ToString("00") + $timestamp.ToString("HH")
+}
+
+# 現在のディレクトリを取得する
+$cd = Split-Path -Parent $MyInvocation.MyCommand.Path
+Set-Location $cd
+
+if (!$isDebug) {
+ Start-Transcript make.log | Out-Null
+}
+
+# target
+$targetClientDirectory = Get-Item .\source\kagami
+$targetDirectories = @($targetClientDirectory)
+$depolyDirectory = ".\source\deploy"
+
+# tools
+$msbuild = "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\MSBuild\Current\Bin\MSBuild.exe"
+
+# バージョンを取得する
+## ビルド番号を決定する
+$timestamp = Get-Date
+$buildNo = GetBuildNo($timestamp)
+
+## リリースノートを取得する
+if ($isDebug) {
+ if (Test-Path .\RELEASE_NOTES.bak) {
+ Copy-Item -Force .\RELEASE_NOTES.bak .\RELEASE_NOTES.xml
+ }
+}
+$releaseNotesXML = [xml] (Get-Content .\RELEASE_NOTES.xml -Encoding utf8)
+if ($releaseNotesXML -eq $null) {
+ EndMake
+}
+$lastestNote = $releaseNotesXML.release_notes.note | Select-Object -Last 1
+
+## バージョン番号を決定する
+$version = $lastestNote.version.Replace("#BuildNo#", $buildNo)
+$channel = $lastestNote.channel
+$tag = ("v" + $version + "-" + $channel)
+
+## アプリケーション名を取得する
+$appName = $releaseNotesXML.release_notes.name
+
+## アーカイブファイル名を決定する
+$archiveFileName = $appName + "_v" + $version.Replace(".", "_") + "_" + $channel + ".zip"
+
+## リリースノートを置換する
+$content = Get-Content .\RELEASE_NOTES.xml -Encoding utf8
+$content = $content.Replace("#BuildNo#", $buildNo)
+$content = $content.Replace("#Timestamp#", $timestamp.ToString("o"))
+$content = $content.Replace("#ArchiveFileName#", $archiveFileName)
+$content = $content.Replace("#Tag#", $tag)
+Copy-Item -Force .\RELEASE_NOTES.xml .\RELEASE_NOTES.bak
+$content | Out-File -FilePath .\RELEASE_NOTES.xml -Encoding utf8
+
+Write-Output "***"
+Write-Output ("*** " + $appName + " v" + $version + " " + $channel + " ***")
+Write-Output "***"
+
+# Version.cs を上書きする
+$content = Get-Content .\source\tools\Version.master.cs -Encoding utf8
+$content = $content.Replace("#VERSION#", $version)
+$content = $content.Replace("#CHANNEL#", $channel)
+foreach ($d in $targetDirectories) {
+ $content | Out-File -FilePath (Join-Path $d "Version.cs") -Encoding utf8
+}
+
+'-> Build'
+# Delete Release Directory
+foreach ($d in $targetDirectories) {
+ $out = Join-Path $d "bin\Release\*"
+ if (Test-Path $out) {
+ Remove-Item -Recurse -Force $out
+ }
+}
+
+$target = Get-Item .\source\*.sln
+& $msbuild $target /nologo /v:minimal /t:Clean /p:Configuration=Release
+Start-Sleep -m 100
+
+'-> Build Client'
+$target = Get-Item $targetClientDirectory\*.csproj
+& $msbuild $target /nologo /v:minimal /t:Build /p:Configuration=Release | Write-Output
+Start-Sleep -m 100
+
+# Successed? build
+foreach ($d in $targetDirectories) {
+ $out = Join-Path $d "bin\Release"
+ if (!(Test-Path $out)) {
+ EndMake
+ }
+}
+
+foreach ($d in $targetDirectories) {
+ # pdb を削除する
+ # Remove-Item -Force (Join-Path $d "bin\Release\*.pdb")
+
+ # app.config を削除する
+ $targets = @(
+ (Join-Path $d "bin\Release\RINGS.exe.config"),
+ (Join-Path $d "bin\Release\aframe.Updater.exe.config"))
+
+ foreach ($t in $targets) {
+ if (Test-Path $t) {
+ Remove-Item -Force $t
+ }
+ }
+}
+
+'-> Deploy'
+# deploy ディレクトリを作る
+if (!(Test-Path $depolyDirectory)) {
+ New-Item -ItemType Directory $depolyDirectory >$null
+}
+
+$deployBase = Join-Path $depolyDirectory $archiveFileName.Replace(".zip", "")
+if (Test-Path $deployBase) {
+ Get-ChildItem -Path $deployBase -Recurse | Remove-Item -Force -Recurse
+ Remove-Item -Recurse -Force $deployBase
+}
+
+$deployClient = $deployBase
+New-Item -ItemType Directory $deployClient >$null
+
+# client を配置する
+'-> Deploy Client'
+Copy-Item -Force -Recurse $targetClientDirectory\bin\Release\* $deployClient
+
+# client をアーカイブする
+'-> Archive Client'
+Compress-Archive -Force $deployClient\* $deployBase\..\$archiveFileName
+Get-ChildItem -Path $deployBase -Recurse | Remove-Item -Force -Recurse
+Remove-Item -Recurse -Force $deployBase
+
+if (!$isDebug) {
+ if (Test-Path .\RELEASE_NOTES.bak) {
+ Remove-Item -Force .\RELEASE_NOTES.bak
+ }
+}
+
+$tag | Out-File .\CURRENT_VERSION -Encoding utf8
+
+Write-Output "***"
+Write-Output ("*** " + $appName + " v" + $version + " " + $channel + ", Completed! ***")
+Write-Output "***"
+
+EndMake
diff --git a/source/Thirdparty/FFXIV_ACT_Plugin/FFXIV_ACT_Plugin.dll b/source/Thirdparty/FFXIV_ACT_Plugin/FFXIV_ACT_Plugin.dll
new file mode 100644
index 0000000..da7356a
Binary files /dev/null and b/source/Thirdparty/FFXIV_ACT_Plugin/FFXIV_ACT_Plugin.dll differ
diff --git a/source/Thirdparty/FFXIV_ACT_Plugin/SDK/.gitignore b/source/Thirdparty/FFXIV_ACT_Plugin/SDK/.gitignore
new file mode 100644
index 0000000..a57582c
--- /dev/null
+++ b/source/Thirdparty/FFXIV_ACT_Plugin/SDK/.gitignore
@@ -0,0 +1 @@
+/src
diff --git a/source/Thirdparty/FFXIV_ACT_Plugin/SDK/FFXIV_ACT_Plugin.Common.dll b/source/Thirdparty/FFXIV_ACT_Plugin/SDK/FFXIV_ACT_Plugin.Common.dll
new file mode 100644
index 0000000..0651c0e
Binary files /dev/null and b/source/Thirdparty/FFXIV_ACT_Plugin/SDK/FFXIV_ACT_Plugin.Common.dll differ
diff --git a/source/Thirdparty/FFXIV_ACT_Plugin/SDK/FFXIV_ACT_Plugin.Config.dll b/source/Thirdparty/FFXIV_ACT_Plugin/SDK/FFXIV_ACT_Plugin.Config.dll
new file mode 100644
index 0000000..6228932
Binary files /dev/null and b/source/Thirdparty/FFXIV_ACT_Plugin/SDK/FFXIV_ACT_Plugin.Config.dll differ
diff --git a/source/Thirdparty/FFXIV_ACT_Plugin/SDK/FFXIV_ACT_Plugin.LogFile.dll b/source/Thirdparty/FFXIV_ACT_Plugin/SDK/FFXIV_ACT_Plugin.LogFile.dll
new file mode 100644
index 0000000..0d65fea
Binary files /dev/null and b/source/Thirdparty/FFXIV_ACT_Plugin/SDK/FFXIV_ACT_Plugin.LogFile.dll differ
diff --git a/source/Thirdparty/FFXIV_ACT_Plugin/SDK/FFXIV_ACT_Plugin.Memory.dll b/source/Thirdparty/FFXIV_ACT_Plugin/SDK/FFXIV_ACT_Plugin.Memory.dll
new file mode 100644
index 0000000..ad2fd42
Binary files /dev/null and b/source/Thirdparty/FFXIV_ACT_Plugin/SDK/FFXIV_ACT_Plugin.Memory.dll differ
diff --git a/source/Thirdparty/FFXIV_ACT_Plugin/SDK/FFXIV_ACT_Plugin.Network.dll b/source/Thirdparty/FFXIV_ACT_Plugin/SDK/FFXIV_ACT_Plugin.Network.dll
new file mode 100644
index 0000000..4ac90d5
Binary files /dev/null and b/source/Thirdparty/FFXIV_ACT_Plugin/SDK/FFXIV_ACT_Plugin.Network.dll differ
diff --git a/source/Thirdparty/FFXIV_ACT_Plugin/SDK/FFXIV_ACT_Plugin.Overlay.dll b/source/Thirdparty/FFXIV_ACT_Plugin/SDK/FFXIV_ACT_Plugin.Overlay.dll
new file mode 100644
index 0000000..763159a
Binary files /dev/null and b/source/Thirdparty/FFXIV_ACT_Plugin/SDK/FFXIV_ACT_Plugin.Overlay.dll differ
diff --git a/source/Thirdparty/FFXIV_ACT_Plugin/SDK/FFXIV_ACT_Plugin.Parse.dll b/source/Thirdparty/FFXIV_ACT_Plugin/SDK/FFXIV_ACT_Plugin.Parse.dll
new file mode 100644
index 0000000..125a697
Binary files /dev/null and b/source/Thirdparty/FFXIV_ACT_Plugin/SDK/FFXIV_ACT_Plugin.Parse.dll differ
diff --git a/source/Thirdparty/FFXIV_ACT_Plugin/SDK/FFXIV_ACT_Plugin.Resource.dll b/source/Thirdparty/FFXIV_ACT_Plugin/SDK/FFXIV_ACT_Plugin.Resource.dll
new file mode 100644
index 0000000..fb456c8
Binary files /dev/null and b/source/Thirdparty/FFXIV_ACT_Plugin/SDK/FFXIV_ACT_Plugin.Resource.dll differ
diff --git a/source/Thirdparty/FFXIV_ACT_Plugin/SDK/_dummy b/source/Thirdparty/FFXIV_ACT_Plugin/SDK/_dummy
new file mode 100644
index 0000000..e69de29
diff --git a/source/deploy/kagami_v0_1_0_3116_Beta.zip b/source/deploy/kagami_v0_1_0_3116_Beta.zip
new file mode 100644
index 0000000..d76b14d
Binary files /dev/null and b/source/deploy/kagami_v0_1_0_3116_Beta.zip differ
diff --git a/source/kagami.Core/Helpers/FFXIVPluginHelper.cs b/source/kagami.Core/Helpers/FFXIVPluginHelper.cs
index 75b5ce9..9904129 100644
--- a/source/kagami.Core/Helpers/FFXIVPluginHelper.cs
+++ b/source/kagami.Core/Helpers/FFXIVPluginHelper.cs
@@ -1,11 +1,12 @@
using System;
using System.Diagnostics;
using System.Linq;
-using System.Reflection;
using System.Threading;
using Advanced_Combat_Tracker;
+using FFXIV_ACT_Plugin.Common;
+using FFXIV_ACT_Plugin.Common.Models;
using kagami.Helpers.Common;
-
+
namespace kagami.Helpers
{
public class FFXIVPluginHelper
@@ -22,102 +23,147 @@ private FFXIVPluginHelper()
#endregion Singleton
- private ThreadWorker attachWorker;
-
- private dynamic ffxivPlugin;
- private dynamic ffxivPluginConfig;
- private dynamic ffxivPluginLogParse;
+ private ThreadWorker pluginSubscriber;
+ private ThreadWorker combatantSubscriber;
- public Process FFXIVProcess => this.ffxivPluginConfig?.Process;
+ private dynamic plugin;
+ private IDataRepository DataRepository { get; set; }
+ private IDataSubscription DataSubscription { get; set; }
+
+ public Process FFXIVProcess => this.DataRepository?.GetCurrentFFXIVProcess();
- public string FFXIVPluginLanguage => (this.ffxivPluginLogParse?.Settings?.LanguageID ?? 0) switch
- {
- 1 => "English",
- 2 => "French",
- 3 => "German",
- 4 => "Japanese",
- _ => "English",
- };
+ public string FFXIVPluginLanguage => this.DataRepository?.GetSelectedLanguageID().ToString();
private static readonly double AttachSubscribeInterval = 3000;
+ private static readonly double CombatantSubscribeInterval = 500;
public void Start()
{
- this.attachWorker = new ThreadWorker(() =>
+ this.pluginSubscriber = new ThreadWorker(() =>
{
if (ActGlobals.oFormActMain == null)
{
return;
}
- if (this.ffxivPlugin == null)
- {
- this.ffxivPlugin = (
- from x in ActGlobals.oFormActMain.ActPlugins
- where
- x.pluginFile.Name.ToUpper().Contains("FFXIV_ACT_Plugin".ToUpper()) &&
- x.lblPluginStatus.Text.ToUpper().Contains("FFXIV Plugin Started.".ToUpper())
- select
- x.pluginObj).FirstOrDefault();
- }
-
- if (this.ffxivPlugin != null &&
- this.ffxivPluginConfig == null)
- {
- var fi = this.ffxivPlugin.GetType().GetField(
- "_Memory",
- BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Instance);
- var memory = fi?.GetValue(this.ffxivPlugin);
- if (memory == null)
- {
- return;
- }
-
- fi = memory.GetType().GetField(
- "_config",
- BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Instance);
- this.ffxivPluginConfig = fi?.GetValue(memory);
-
- Logger.Info("FFXIV_ACT_Plugin.Config attached.");
- }
-
- if (this.ffxivPlugin != null &&
- this.ffxivPluginLogParse == null)
- {
- var fi = this.ffxivPlugin.GetType().GetField(
- "_LogParse",
- BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Instance);
-
- this.ffxivPluginLogParse = fi?.GetValue(this.ffxivPlugin);
-
- Logger.Info("FFXIV_ACT_Plugin.LogParse attached.");
+ if (this.plugin != null)
+ {
+ return;
}
- if (this.ffxivPlugin != null &&
- this.ffxivPluginConfig != null &&
- this.ffxivPluginLogParse != null)
- {
- Thread.Sleep(TimeSpan.FromMilliseconds(AttachSubscribeInterval));
- }
+ var ffxivPlugin = (
+ from x in ActGlobals.oFormActMain.ActPlugins
+ where
+ x.pluginFile.Name.ToUpper().Contains("FFXIV_ACT_Plugin".ToUpper()) &&
+ x.lblPluginStatus.Text.ToUpper().Contains("FFXIV Plugin Started.".ToUpper())
+ select
+ x.pluginObj).FirstOrDefault();
+
+ if (ffxivPlugin != null)
+ {
+ this.plugin = ffxivPlugin;
+ this.DataRepository = this.plugin.DataRepository;
+ this.DataSubscription = this.plugin.DataSubscription;
+
+ Logger.Info("FFXIV_ACT_Plugin attached.");
+ }
},
AttachSubscribeInterval,
- "FFXIV_ACT_Plugin Subscriber",
+ "FFXIV_ACT_Plugin subscriber",
ThreadPriority.Lowest);
- this.attachWorker.Run();
+ this.pluginSubscriber.Run();
+
+ this.combatantSubscriber = new ThreadWorker(
+ this.DoRefreshCombatant,
+ CombatantSubscribeInterval,
+ "Combatant subscriber",
+ ThreadPriority.Lowest);
+
+ this.combatantSubscriber.Run();
}
public void Stop()
{
- if (this.attachWorker != null)
+ if (this.pluginSubscriber != null)
{
- this.attachWorker.Abort();
- this.attachWorker = null;
+ this.pluginSubscriber.Abort();
+ this.pluginSubscriber = null;
}
- this.ffxivPlugin = null;
- this.ffxivPluginConfig = null;
- this.ffxivPluginLogParse = null;
+ if (this.combatantSubscriber != null)
+ {
+ this.combatantSubscriber.Abort();
+ this.combatantSubscriber = null;
+ }
+
+ this.plugin = null;
+ this.DataRepository = null;
+ this.DataSubscription = null;
}
+
+ public Combatant CurrentPlayer { get; private set; }
+
+ public Combatant CurrentTarget { get; private set; }
+
+ public Combatant CurrentFocusTarget { get; private set; }
+
+ private void DoRefreshCombatant()
+ {
+ this.CurrentPlayer = this.DataRepository?.GetCombatantList().FirstOrDefault();
+ this.CurrentTarget = this.DataRepository?.GetCombatantByOverlayType(OverlayType.Target);
+ this.CurrentFocusTarget = this.DataRepository?.GetCombatantByOverlayType(OverlayType.FocusTarget);
+ }
+ }
+
+ public static class CombatantExtensions
+ {
+ public static Job GetJob(
+ this Combatant c)
+ => (Job)Enum.ToObject(typeof(Job), c.Job);
+ }
+
+ public enum Job
+ {
+ Unknown = -1,
+ ADV = 0,
+ GLA = 1,
+ PUG = 2,
+ MRD = 3,
+ LNC = 4,
+ ARC = 5,
+ CNJ = 6,
+ THM = 7,
+ CRP = 8,
+ BSM = 9,
+ ARM = 10,
+ GSM = 11,
+ LTW = 12,
+ WVR = 13,
+ ALC = 14,
+ CUL = 15,
+ MIN = 16,
+ BOT = 17,
+ FSH = 18,
+ PLD = 19,
+ MNK = 20,
+ WAR = 21,
+ DRG = 22,
+ BRD = 23,
+ WHM = 24,
+ BLM = 25,
+ ACN = 26,
+ SMN = 27,
+ SCH = 28,
+ ROG = 29,
+ NIN = 30,
+ MCH = 31,
+ DRK = 32,
+ AST = 33,
+ SAM = 34,
+ RDM = 35,
+ BLU = 36,
+ GNB = 37,
+ DNC = 38,
}
-}
+}
diff --git a/source/kagami.Core/Helpers/SharlayanHelper.cs b/source/kagami.Core/Helpers/SharlayanHelper.cs
index 1e9f643..7ef1123 100644
--- a/source/kagami.Core/Helpers/SharlayanHelper.cs
+++ b/source/kagami.Core/Helpers/SharlayanHelper.cs
@@ -95,11 +95,12 @@ private void DetectFFXIVProcess()
MemoryHandler.Instance.SetProcess(
model,
- ffxivLanguage);
+ gameLanguage: ffxivLanguage,
+ useLocalCache: false);
Logger.Info("Sharlayan attached.");
}
}
}
}
-}
+}
diff --git a/source/kagami.Core/KagamiAddonCore.cs b/source/kagami.Core/KagamiAddonCore.cs
index 2d3e5b3..c4de371 100644
--- a/source/kagami.Core/KagamiAddonCore.cs
+++ b/source/kagami.Core/KagamiAddonCore.cs
@@ -75,13 +75,10 @@ private void Initialize()
FFXIVPluginHelper.Instance.Start();
SharlayanHelper.Instance.Start();
- // Actionリストを取得しておく
- var a = SharlayanHelper.Instance.GetActionInfo(0);
-
await Task.Delay(100);
XIVLogSubscriber.Instance.Start();
});
}
}
-}
+}
diff --git a/source/kagami.Core/KagamiOverlay.cs b/source/kagami.Core/KagamiOverlay.cs
index d264b19..6393ec4 100644
--- a/source/kagami.Core/KagamiOverlay.cs
+++ b/source/kagami.Core/KagamiOverlay.cs
@@ -39,16 +39,17 @@ private void Config_PropertyChanged(object sender, PropertyChangedEventArgs e)
private static readonly int LongInterval = 3000;
private volatile bool isUpdating = false;
private long previousSeq = 0;
+ private bool previousStats = false;
protected override async void Update()
{
try
- {
- if (this.isUpdating)
- {
- return;
- }
-
+ {
+ if (this.isUpdating)
+ {
+ return;
+ }
+
this.isUpdating = true;
if (!this.Config.IsDesignMode)
@@ -68,31 +69,58 @@ protected override async void Update()
else
{
this.timer.Interval = LongInterval;
- }
-
- if (this.previousSeq != ActionEchoesModel.Instance.Seq ||
- this.Config.IsDesignMode)
- {
+ }
+
+ var stats = ActionEchoesModel.Instance.GetEncounterStats();
+ var isNeedsSave = false;
+
+ lock (this)
+ {
+ if (!this.Config.IsDesignMode &&
+ this.previousSeq == ActionEchoesModel.Instance.Seq &&
+ this.previousStats == stats)
+ {
+ return;
+ }
+
this.previousSeq = ActionEchoesModel.Instance.Seq;
- var json = await ActionEchoesModel.Instance.ParseJsonAsync();
-
- var updateScript =
- $"var model =\n{ json };\n\n" +
- "document.dispatchEvent(new CustomEvent('onActionUpdated', { detail: model }));\n";
-
- this.Overlay?.Renderer?.Browser?.GetMainFrame()?.ExecuteJavaScript(
- updateScript,
- null,
- 0);
- }
+ if (this.previousStats != stats)
+ {
+ this.previousStats = stats;
+ isNeedsSave = !stats;
+ }
+ }
+
+ var json = await ActionEchoesModel.Instance.ParseJsonAsync();
+
+ var updateScript =
+ $"var model =\n{ json };\n\n" +
+ "document.dispatchEvent(new CustomEvent('onActionUpdated', { detail: model }));\n";
+
+ this.Overlay?.Renderer?.Browser?.GetMainFrame()?.ExecuteJavaScript(
+ updateScript,
+ null,
+ 0);
+
+ if (isNeedsSave)
+ {
+ var script = "document.dispatchEvent(new CustomEvent('onEndEncounter', null));\n";
+ this.Overlay?.Renderer?.Browser?.GetMainFrame()?.ExecuteJavaScript(
+ script,
+ null,
+ 0);
+
+ await ActionEchoesModel.Instance.SaveLogAsync();
+ ActionEchoesModel.Instance.Clear();
+ }
}
catch (Exception ex)
{
this.Log(LogLevel.Error, "Update: {0} {1}", this.Name, ex.ToString());
}
finally
- {
+ {
this.isUpdating = false;
}
}
diff --git a/source/kagami.Core/KagamiOverlayConfig.cs b/source/kagami.Core/KagamiOverlayConfig.cs
index 89c23a0..81511ec 100644
--- a/source/kagami.Core/KagamiOverlayConfig.cs
+++ b/source/kagami.Core/KagamiOverlayConfig.cs
@@ -51,6 +51,22 @@ public bool IsDesignMode
set => this.SetProperty(ref this.isDesignMode, value);
}
+ private bool isEnableTargetCapture = true;
+
+ public bool IsEnableTargetCapture
+ {
+ get => this.isEnableTargetCapture;
+ set => this.SetProperty(ref this.isEnableTargetCapture, value);
+ }
+
+ private bool isEnableFocusTargetCapture = true;
+
+ public bool IsEnableFocusTargetCapture
+ {
+ get => this.isEnableFocusTargetCapture;
+ set => this.SetProperty(ref this.isEnableFocusTargetCapture, value);
+ }
+
private int bufferSizeOfActionEcho = 30;
public int BufferSizeOfActionEcho
@@ -125,4 +141,4 @@ protected virtual bool SetProperty(
#endregion INotifyPropertyChanged
}
-}
+}
diff --git a/source/kagami.Core/Models/ActionEchoesModel.cs b/source/kagami.Core/Models/ActionEchoesModel.cs
index cfd7f71..ffb98d4 100644
--- a/source/kagami.Core/Models/ActionEchoesModel.cs
+++ b/source/kagami.Core/Models/ActionEchoesModel.cs
@@ -82,7 +82,7 @@ from x in source
x.Timestamp <= this.Time &&
x.Timestamp >= this.Time.AddSeconds(this.Config.BufferSizeOfActionEcho * -1)
orderby
- x.Timestamp descending
+ x.Seq descending
select
x).ToArray();
@@ -108,6 +108,9 @@ public void Add(ActionEchoModel model)
}
}
+ public bool GetEncounterStats()
+ => ActGlobals.oFormActMain?.ActiveZone?.ActiveEncounter?.Active ?? false;
+
public async Task ParseJsonAsync() => await Task.Run(() =>
{
var data = this.Config.IsDesignMode ? CreateDesignModeDataModel() : this;
@@ -115,16 +118,17 @@ public async Task ParseJsonAsync() => await Task.Run(() =>
if (!this.Config.IsDesignMode)
{
- if (ActGlobals.oFormActMain?.ActiveZone?.ActiveEncounter != null)
+ var encounter = ActGlobals.oFormActMain?.ActiveZone?.ActiveEncounter;
+ if (encounter != null)
{
- var dpsList = ActGlobals.oFormActMain.ActiveZone.ActiveEncounter.GetAllies();
+ var dpsList = encounter.GetAllies();
var dps = dpsList.FirstOrDefault(x =>
x.Name == this.PlayerName ||
x.Name == "YOU");
this.EncDPS = Math.Round(dps?.EncDPS ?? 0);
this.Duration = dps?.Duration ?? TimeSpan.Zero;
- this.IsActive = true;
+ this.IsActive = encounter.Active;
}
else
{
@@ -148,8 +152,6 @@ public async Task ParseJsonAsync() => await Task.Run(() =>
return json;
});
- private int takeCount;
-
public async Task SaveLogAsync()
{
if (this.echoes.Count < 1)
@@ -161,10 +163,16 @@ public async Task SaveLogAsync()
lock (this)
{
- this.takeCount++;
+ var encounter = ActGlobals.oFormActMain?.ActiveZone?.ActiveEncounter;
+ var zone = !string.IsNullOrEmpty(encounter?.ZoneName) ?
+ encounter?.ZoneName :
+ this.Zone;
+ var title = !string.IsNullOrEmpty(encounter?.Title) ?
+ encounter?.Title :
+ "UNKNOWN";
fileName =
- $"{DateTime.Now:yyyy-MM-dd_HHmmss}.{this.PlayerName}[{this.PlayerJob}].{this.Zone}.{this.takeCount}.json";
+ $"{DateTime.Now:yyMMdd_HHmmss}_{this.PlayerName}[{this.PlayerJob}]_{zone}({title}).json";
// 無効な文字を取り除く
fileName = string.Concat(fileName.Where(c => !Path.GetInvalidFileNameChars().Contains(c)));
diff --git a/source/kagami.Core/Version.cs b/source/kagami.Core/Version.cs
index ace4b19..6c92775 100644
--- a/source/kagami.Core/Version.cs
+++ b/source/kagami.Core/Version.cs
@@ -1,4 +1,4 @@
-using System.Reflection;
+using System.Reflection;
-[assembly: AssemblyVersion("0.0.11.0")]
-[assembly: AssemblyConfiguration("Alpha")]
+[assembly: AssemblyVersion("0.1.0.3116")]
+[assembly: AssemblyConfiguration("Beta")]
diff --git a/source/kagami.Core/Views/KagamiConfigView.xaml b/source/kagami.Core/Views/KagamiConfigView.xaml
index c221e83..3890c76 100644
--- a/source/kagami.Core/Views/KagamiConfigView.xaml
+++ b/source/kagami.Core/Views/KagamiConfigView.xaml
@@ -90,6 +90,8 @@
+
+
diff --git a/source/kagami.Core/XIVLogSubscriber.cs b/source/kagami.Core/XIVLogSubscriber.cs
index 788382c..1fe2bf6 100644
--- a/source/kagami.Core/XIVLogSubscriber.cs
+++ b/source/kagami.Core/XIVLogSubscriber.cs
@@ -75,17 +75,21 @@ public void ClearBuffer()
}
private static readonly int LongSleep = 3000;
+ private static readonly byte PC = 1;
private Regex networkAbilityRegex;
private Regex defeatedRegex;
- private string previousPlayerName;
+ private string previousActorName;
+ /*
private static readonly string ChangedZoneLog = "01:Changed Zone to";
private static readonly string ChangedPrimaryPlayerLog = "02:Changed primary player";
+ */
- private volatile string previousActionKey = string.Empty;
+ private volatile string previousActionID = string.Empty;
+ private DateTime previousActionTimestamp = DateTime.MinValue;
- private async void StoreLog()
+ private void StoreLog()
{
if (this.Config == null)
{
@@ -102,28 +106,49 @@ private async void StoreLog()
return;
}
- var player = SharlayanHelper.Instance.GetCurrentPlayer();
- if (player == null ||
- string.IsNullOrEmpty(player.Name))
+ var player = FFXIVPluginHelper.Instance.CurrentPlayer;
+ var target = FFXIVPluginHelper.Instance.CurrentTarget;
+ var focus = FFXIVPluginHelper.Instance.CurrentFocusTarget;
+
+ if (string.IsNullOrEmpty(player?.Name) &&
+ string.IsNullOrEmpty(target?.Name) &&
+ string.IsNullOrEmpty(focus?.Name))
{
interval = LongSleep;
return;
}
- if (this.previousPlayerName != player.Name)
+ var actor = player;
+ if (focus != null &&
+ focus.type == PC)
+ {
+ actor = focus;
+ }
+ else
+ {
+ if (target != null &&
+ target.type == PC)
+ {
+ actor = target;
+ }
+ }
+
+ if (this.previousActorName != actor.Name)
{
- this.previousPlayerName = player.Name;
+ this.previousActorName = actor.Name;
// 15:10078E31:Anoyetta Anon:A5:サモン:
// 16:10078E31:Anoyetta Anon:B1:ミアズラ:
this.networkAbilityRegex = new Regex(
- $" (15|16):[0-9a-fA-F]+:{player.Name}:(?[0-9a-fA-F]+):(?.+?):[0-9a-fA-F]",
+ $" (15|16):[0-9a-fA-F]+:{actor.Name}:(?[0-9a-fA-F]+):(?.+?):[0-9a-fA-F]",
RegexOptions.Compiled | RegexOptions.IgnoreCase);
// 19:Anoyetta Anon was defeated by ガルーダ.
this.defeatedRegex = new Regex(
- $" 19:{player.Name} was defeated by",
+ $" 19:{actor.Name} was defeated by",
RegexOptions.Compiled | RegexOptions.IgnoreCase);
+
+ ActionEchoesModel.Instance.Clear();
}
if (this.networkAbilityRegex == null ||
@@ -133,8 +158,8 @@ private async void StoreLog()
return;
}
- ActionEchoesModel.Instance.PlayerName = player.Name;
- ActionEchoesModel.Instance.PlayerJob = player.Job.ToString();
+ ActionEchoesModel.Instance.PlayerName = actor.Name;
+ ActionEchoesModel.Instance.PlayerJob = actor.GetJob().ToString();
while (this.LogInfoQueue.TryDequeue(out LogLineEventArgs e))
{
@@ -151,49 +176,43 @@ private async void StoreLog()
try
{
- if (line.Contains(ChangedZoneLog) ||
- line.Contains(ChangedPrimaryPlayerLog) ||
- this.defeatedRegex.IsMatch(line))
- {
- await ActionEchoesModel.Instance.SaveLogAsync();
- ActionEchoesModel.Instance.Clear();
- continue;
- }
-
var match = this.networkAbilityRegex.Match(line);
if (!match.Success)
{
continue;
}
- var timestamp = line.Substring(0, 15).TrimEnd();
+ var t = line.Substring(0, 15)
+ .TrimEnd()
+ .Replace("[", string.Empty)
+ .Replace("]", string.Empty);
+ if (!DateTime.TryParse(t, out DateTime timestamp))
+ {
+ timestamp = DateTime.Now;
+ }
+
var actionID = match.Groups["ActionID"].ToString();
var actionName = match.Groups["ActionName"].ToString();
- var actionKey = $"{timestamp}-{actionID}-{actionName}";
if (string.Equals(
- this.previousActionKey,
- actionKey,
+ actionID,
+ this.previousActionID,
StringComparison.OrdinalIgnoreCase))
- {
- continue;
+ {
+ if ((timestamp - this.previousActionTimestamp)
+ < TimeSpan.FromMilliseconds(200))
+ {
+ continue;
+ }
}
- this.previousActionKey = actionKey;
+ this.previousActionID = actionID;
+ this.previousActionTimestamp = timestamp;
var echo = new ActionEchoModel();
-
- if (DateTime.TryParse(timestamp, out DateTime d))
- {
- echo.Timestamp = d;
- }
- else
- {
- echo.Timestamp = DateTime.Now;
- }
-
+ echo.Timestamp = timestamp;
echo.Source = line;
- echo.Actor = player.Name;
+ echo.Actor = actor.Name;
if (uint.TryParse(actionID, NumberStyles.HexNumber, NumberFormatInfo.CurrentInfo, out uint i))
{
diff --git a/source/kagami.Core/kagami.Core.csproj b/source/kagami.Core/kagami.Core.csproj
index e7c9fc9..dbf5127 100644
--- a/source/kagami.Core/kagami.Core.csproj
+++ b/source/kagami.Core/kagami.Core.csproj
@@ -13,6 +13,7 @@
{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
4
true
+ None
true
@@ -38,6 +39,10 @@
..\Thirdparty\ACT\Advanced Combat Tracker.exe
False
+
+ ..\..\..\..\ACT.ProvokeAssistant\source\ThirdPaty\SDK\FFXIV_ACT_Plugin.Common.dll
+ True
+
..\Thirdparty\OverlayPlugin\HtmlRenderer.dll
@@ -151,6 +156,12 @@
PreserveNewest
+
+ PreserveNewest
+
+
+ PreserveNewest
+
PreserveNewest
@@ -190,6 +201,9 @@
PreserveNewest
+
+ PreserveNewest
+
PreserveNewest
@@ -202,6 +216,9 @@
PreserveNewest
+
+ PreserveNewest
+
PreserveNewest
@@ -381,7 +398,9 @@
-
-
+ @echo off
+copy /y $(ProjectDir)..\kagami\Version.cs $(ProjectDir)>nul
+
+
\ No newline at end of file
diff --git a/source/kagami.Core/resources/kagami/job_icons/DNC.png b/source/kagami.Core/resources/kagami/job_icons/DNC.png
new file mode 100644
index 0000000..29f1e20
Binary files /dev/null and b/source/kagami.Core/resources/kagami/job_icons/DNC.png differ
diff --git a/source/kagami.Core/resources/kagami/job_icons/GNB.png b/source/kagami.Core/resources/kagami/job_icons/GNB.png
new file mode 100644
index 0000000..022e9c3
Binary files /dev/null and b/source/kagami.Core/resources/kagami/job_icons/GNB.png differ
diff --git a/source/kagami.Core/resources/kagami/job_icons/svg/DNC.svg b/source/kagami.Core/resources/kagami/job_icons/svg/DNC.svg
new file mode 100644
index 0000000..06621d2
--- /dev/null
+++ b/source/kagami.Core/resources/kagami/job_icons/svg/DNC.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/source/kagami.Core/resources/kagami/job_icons/svg/GNB.svg b/source/kagami.Core/resources/kagami/job_icons/svg/GNB.svg
new file mode 100644
index 0000000..f636af9
--- /dev/null
+++ b/source/kagami.Core/resources/kagami/job_icons/svg/GNB.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/source/kagami/FodyWeavers.xml b/source/kagami/FodyWeavers.xml
new file mode 100644
index 0000000..28f6ebf
--- /dev/null
+++ b/source/kagami/FodyWeavers.xml
@@ -0,0 +1,10 @@
+
+
+
+ Overlay*
+ HtmlRenderer
+ Xilium.CefGlue
+ FFXIV_ACT_*
+
+
+
diff --git a/source/kagami/FodyWeavers.xsd b/source/kagami/FodyWeavers.xsd
new file mode 100644
index 0000000..8ac6e92
--- /dev/null
+++ b/source/kagami/FodyWeavers.xsd
@@ -0,0 +1,111 @@
+
+
+
+
+
+
+
+
+
+
+
+ A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks
+
+
+
+
+ A list of assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks.
+
+
+
+
+ A list of unmanaged 32 bit assembly names to include, delimited with line breaks.
+
+
+
+
+ A list of unmanaged 64 bit assembly names to include, delimited with line breaks.
+
+
+
+
+ The order of preloaded assemblies, delimited with line breaks.
+
+
+
+
+
+ This will copy embedded files to disk before loading them into memory. This is helpful for some scenarios that expected an assembly to be loaded from a physical file.
+
+
+
+
+ Controls if .pdbs for reference assemblies are also embedded.
+
+
+
+
+ Embedded assemblies are compressed by default, and uncompressed when they are loaded. You can turn compression off with this option.
+
+
+
+
+ As part of Costura, embedded assemblies are no longer included as part of the build. This cleanup can be turned off.
+
+
+
+
+ Costura by default will load as part of the module initialization. This flag disables that behavior. Make sure you call CosturaUtility.Initialize() somewhere in your code.
+
+
+
+
+ Costura will by default use assemblies with a name like 'resources.dll' as a satellite resource and prepend the output path. This flag disables that behavior.
+
+
+
+
+ A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with |
+
+
+
+
+ A list of assembly names to include from the default action of "embed all Copy Local references", delimited with |.
+
+
+
+
+ A list of unmanaged 32 bit assembly names to include, delimited with |.
+
+
+
+
+ A list of unmanaged 64 bit assembly names to include, delimited with |.
+
+
+
+
+ The order of preloaded assemblies, delimited with |.
+
+
+
+
+
+
+
+ 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.
+
+
+
+
+ A comma-separated list of error codes that can be safely ignored in assembly verification.
+
+
+
+
+ 'false' to turn off automatic generation of the XML Schema file.
+
+
+
+
+
\ No newline at end of file
diff --git a/source/kagami/KagamiAddon.cs b/source/kagami/KagamiAddon.cs
index 67ea639..97547da 100644
--- a/source/kagami/KagamiAddon.cs
+++ b/source/kagami/KagamiAddon.cs
@@ -11,6 +11,7 @@ public class KagamiAddon :
{
static KagamiAddon()
{
+ CosturaUtility.Initialize();
AssemblyResolver.Initialize();
}
diff --git a/source/kagami/Version.cs b/source/kagami/Version.cs
index ace4b19..6c92775 100644
--- a/source/kagami/Version.cs
+++ b/source/kagami/Version.cs
@@ -1,4 +1,4 @@
-using System.Reflection;
+using System.Reflection;
-[assembly: AssemblyVersion("0.0.11.0")]
-[assembly: AssemblyConfiguration("Alpha")]
+[assembly: AssemblyVersion("0.1.0.3116")]
+[assembly: AssemblyConfiguration("Beta")]
diff --git a/source/kagami/kagami.csproj b/source/kagami/kagami.csproj
index a5e874e..25d9019 100644
--- a/source/kagami/kagami.csproj
+++ b/source/kagami/kagami.csproj
@@ -13,6 +13,7 @@
{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
4
true
+ None
true
@@ -82,6 +83,9 @@
ResXFileCodeGenerator
Resources.Designer.cs
+
+ Designer
+
SettingsSingleFileGenerator
Settings.Designer.cs
@@ -97,6 +101,9 @@
3.0.2.4
+
+ 4.0.0
+
3.5.0
@@ -113,44 +120,28 @@
5.0.4
+
+
+
- @echo off
-
-if exist $(TargetDir)bin\. (
- rmdir /q /s $(TargetDir)bin
-)
-
+
+
@echo off
-move Overlay*.dll ..\
-move HtmlRenderer.dll ..\
-move Xilium.CefGlue.dll ..\
-
-mkdir $(TargetDir)bin
-move $(TargetDir)*.dll $(TargetDir)bin\
-move $(TargetDir)bin\kagami.dll $(TargetDir)
-xcopy /e /y $(TargetDir)resources $(TargetDir)..\resources\
-rmdir /s /q $(TargetDir)resources
+move /y $(TargetDir)Overlay*.dll $(TargetDir)..\>nul
+move /y $(TargetDir)HtmlRenderer.dll $(TargetDir)..\>nul
+move /y $(TargetDir)Xilium.CefGlue.dll $(TargetDir)..\>nul
-rmdir /s /q $(TargetDir)de
-rmdir /s /q $(TargetDir)es
-rmdir /s /q $(TargetDir)fr
-rmdir /s /q $(TargetDir)hu
-rmdir /s /q $(TargetDir)it
-rmdir /s /q $(TargetDir)ja-JP
-rmdir /s /q $(TargetDir)pt-BR
-rmdir /s /q $(TargetDir)ro
-rmdir /s /q $(TargetDir)ru
-rmdir /s /q $(TargetDir)sv
-rmdir /s /q $(TargetDir)zh-Hans
-rmdir /s /q $(TargetDir)ko-KR
+xcopy /e /y $(TargetDir)resources $(TargetDir)..\resources\>nul
+rmdir /s /q $(TargetDir)resources>nul
if $(ConfigurationName)==Release (
- del /q $(TargetDir)*.pdb
- del /q $(TargetDir)*.xml
- del /q $(TargetDir)..\*.dll
+ for /F %25%25a in ('dir /AD /B /W *') do rd /S /Q %25%25a>nul
+ del /q $(TargetDir)*.xml>nul
+ del /q $(TargetDir)\..\*.dll>nul
+ del /q $(TargetDir)\FFXIV*.dll>nul
)