Skip to content

Commit

Permalink
Merge pull request #5 from Jaksuhn/auto-replays
Browse files Browse the repository at this point in the history
Auto replays
  • Loading branch information
CarnifexOptimus authored Mar 28, 2024
2 parents b2df35e + 4a89c93 commit 425ed73
Show file tree
Hide file tree
Showing 6 changed files with 138 additions and 2 deletions.
16 changes: 16 additions & 0 deletions BossMod/Config/ConfigNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,22 @@ public PropertySliderAttribute(float min, float max)
}
}

// attribute that specifies slider should be used for displaying float property
[AttributeUsage(AttributeTargets.Field)]
public class PropertyIntSliderAttribute : Attribute
{
public float Speed = 1;
public int Min;
public int Max;
public bool Logarithmic;

public PropertyIntSliderAttribute(int min, int max)
{
Min = min;
Max = max;
}
}

// base class for configuration nodes
public abstract class ConfigNode
{
Expand Down
26 changes: 26 additions & 0 deletions BossMod/Config/ConfigUI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ private void DrawNodes(List<UINode> nodes)
bool v => DrawProperty(props, n.Node, field, v),
Enum v => DrawProperty(props, n.Node, field, v),
float v => DrawProperty(props, n.Node, field, v),
int v => DrawProperty(props, n.Node, field, v),
GroupAssignment v => DrawProperty(props, n.Node, field, v),
_ => false
};
Expand Down Expand Up @@ -165,6 +166,31 @@ private bool DrawProperty(PropertyDisplayAttribute props, ConfigNode node, Field
return true;
}

private bool DrawProperty(PropertyDisplayAttribute props, ConfigNode node, FieldInfo member, int v)
{
var slider = member.GetCustomAttribute<PropertyIntSliderAttribute>();
if (slider != null)
{
var flags = ImGuiSliderFlags.None;
if (slider.Logarithmic)
flags |= ImGuiSliderFlags.Logarithmic;
if (ImGui.DragInt(props.Label, ref v, slider.Speed, slider.Min, slider.Max, "%d", flags))
{
member.SetValue(node, v);
node.NotifyModified();
}
}
else
{
if (ImGui.InputInt(props.Label, ref v))
{
member.SetValue(node, v);
node.NotifyModified();
}
}
return true;
}

private bool DrawProperty(PropertyDisplayAttribute props, ConfigNode node, FieldInfo member, GroupAssignment v)
{
var group = member.GetCustomAttribute<GroupDetailsAttribute>();
Expand Down
18 changes: 18 additions & 0 deletions BossMod/Framework/Plugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Dalamud.IoC;
using Dalamud.Plugin;
using Dalamud.Plugin.Services;
using FFXIVClientStructs.FFXIV.Client.Game;
using System;
using System.Reflection;

Expand Down Expand Up @@ -46,6 +47,7 @@ public Plugin(
Service.WindowSystem = new("vbm");
//Service.Device = pluginInterface.UiBuilder.Device;
Service.Condition.ConditionChange += OnConditionChanged;
Service.ClientState.TerritoryChanged += OnZoneChange;
MultiboxUnlock.Exec();
Network.IDScramble.Initialize();
Camera.Instance = new();
Expand Down Expand Up @@ -82,6 +84,7 @@ public Plugin(
public void Dispose()
{
Service.Condition.ConditionChange -= OnConditionChanged;
Service.ClientState.TerritoryChanged -= OnZoneChange;
_wndDebug.Dispose();
_wndReplay.Dispose();
_wndBossmodHints.Dispose();
Expand Down Expand Up @@ -160,5 +163,20 @@ private void OnConditionChanged(ConditionFlag flag, bool value)
{
Service.Log($"Condition chage: {flag}={value}");
}

private unsafe void OnZoneChange(ushort obj)
{
if (GameMain.Instance()->CurrentContentFinderConditionId != 0 && !_wndReplay.IsRecording() && Service.Config.Get<ReplayManagementConfig>().AutoRecord)
{
_wndReplay.StartRecording();
return;
}

if (_wndReplay.IsRecording() && Service.Config.Get<ReplayManagementConfig>().AutoStop)
{
_wndReplay.StopRecording();
return;
}
}
}
}
1 change: 1 addition & 0 deletions BossMod/Framework/Service.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public class Service
[PluginService] public static IFramework Framework { get; private set; }
[PluginService] public static ITextureProvider Texture { get; private set; }
[PluginService] public static ICommandManager CommandManager { get; private set; }
[PluginService] public static IDutyState DutyState { get; private set; }
[PluginService] public static DalamudPluginInterface PluginInterface { get; private set; }
#pragma warning restore CS8618

Expand Down
10 changes: 10 additions & 0 deletions BossMod/Replay/ReplayManagementConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@ public class ReplayManagementConfig : ConfigNode
[PropertyDisplay("Show replay management UI")]
public bool ShowUI = false;

[PropertyDisplay("Auto record replays on duty start")]
public bool AutoRecord = false;

[PropertyDisplay("Auto stop replays on duty end")]
public bool AutoStop = false;

[PropertyDisplay("Max replays to keep before removal")]
[PropertyIntSlider(0, 1000, Speed = 1f, Logarithmic = false)]
public int MaxReplays = 0;

[PropertyDisplay("Store server packets in the replay")]
public bool DumpServerPackets = false;

Expand Down
69 changes: 67 additions & 2 deletions BossMod/Replay/ReplayManagementWindow.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
using ImGuiNET;
using FFXIVClientStructs.FFXIV.Client.Game.UI;
using ImGuiNET;
using Lumina.Excel.GeneratedSheets;
using System;
using System.IO;
using System.Linq;

namespace BossMod
{
Expand Down Expand Up @@ -56,7 +59,7 @@ public override void Draw()
{
try
{
_recorder = new(_ws, _config.WorldLogFormat, true, _logDir, "World");
_recorder = new(_ws, _config.WorldLogFormat, true, _logDir, $"{GetPrefix()}");
}
catch (Exception ex)
{
Expand Down Expand Up @@ -86,12 +89,74 @@ public override void Draw()
_manager.Draw();
}

public void StartRecording()
{
if (_recorder == null)
{
try
{
if (_config.MaxReplays > 0)
{
var files = _logDir.GetFiles().OrderBy(f => f.LastWriteTime).ToList();
files.Take(files.Count - _config.MaxReplays).ToList().ForEach(f => f.Delete());
}
}
catch (Exception ex)
{
Service.Log($"Failed to delete old replays: {ex}");
}

try
{
_recorder = new(_ws, _config.WorldLogFormat, true, _logDir, $"{GetPrefix()}");
}
catch (Exception ex)
{
Service.Log($"Failed to start recording: {ex}");
}
}
}

public void StopRecording()
{
if (_recorder != null)
{
_recorder.Dispose();
_recorder = null;
}
}

public bool IsRecording() => _recorder != null;

public override void OnClose()
{
SetVisible(false);
}

private void ApplyConfig(object? sender, EventArgs args) => IsOpen = _config.ShowUI;
private void UpdateTitle() => WindowName = $"Replay recording: {(_recorder != null ? "in progress..." : "idle")}{_windowID}";
private static unsafe string GetPrefix()
{
var prefix = "World";
var row = Service.LuminaGameData!.GetExcelSheet<TerritoryType>()!.GetRow(Service.ClientState.TerritoryType);
if (row != null)
{
if (row.ContentFinderCondition.Value!.RowId != 0)
prefix = row.ContentFinderCondition.Value.Name.RawString;
else
prefix = row.PlaceName.Value?.NameNoArticle.RawString ?? prefix;
}

var cf = ContentsFinder.Instance();
var unrestricted = cf->IsUnrestrictedParty ? "U" : "";
var levelsync = cf->IsLevelSync ? "LS" : "";
var minilvl = cf->IsMinimalIL ? "MI" : "";
var noecho = cf->IsSilenceEcho ? "NE" : "";
var dfsettings = string.Join(", ", new[] { unrestricted, levelsync, minilvl, noecho }.Where(s => !string.IsNullOrEmpty(s)));
if (dfsettings != null)
prefix += $"_{dfsettings}";

return prefix;
}
}
}

0 comments on commit 425ed73

Please sign in to comment.