From d2253915d872d95ea4bf521fffa12c2b4e821e5b Mon Sep 17 00:00:00 2001 From: devoreofox <232652342+devoreofox@users.noreply.github.com> Date: Thu, 9 Jul 2026 12:45:12 -0300 Subject: [PATCH 1/2] Reorganize Provider pathing --- Silkstring/Plugin.cs | 1 + .../Variables/{ => Providers}/CombatVariablesProvider.cs | 2 +- .../Variables/{ => Providers}/CurrencyVariablesProvider.cs | 2 +- .../Variables/{ => Providers}/EmoteVariablesProvider.cs | 2 +- .../Variables/{ => Providers}/PlayerVariableProvider.cs | 2 +- .../Services/Variables/{ => Providers}/UserVariableProvider.cs | 2 +- .../Variables/{ => Providers}/VitalsVariablesProvider.cs | 2 +- Tests/UserVariableProviderTests.cs | 2 +- 8 files changed, 8 insertions(+), 7 deletions(-) rename Silkstring/Services/Variables/{ => Providers}/CombatVariablesProvider.cs (93%) rename Silkstring/Services/Variables/{ => Providers}/CurrencyVariablesProvider.cs (91%) rename Silkstring/Services/Variables/{ => Providers}/EmoteVariablesProvider.cs (97%) rename Silkstring/Services/Variables/{ => Providers}/PlayerVariableProvider.cs (95%) rename Silkstring/Services/Variables/{ => Providers}/UserVariableProvider.cs (93%) rename Silkstring/Services/Variables/{ => Providers}/VitalsVariablesProvider.cs (96%) diff --git a/Silkstring/Plugin.cs b/Silkstring/Plugin.cs index c8beeef..1dde2fb 100644 --- a/Silkstring/Plugin.cs +++ b/Silkstring/Plugin.cs @@ -11,6 +11,7 @@ using ECommons; using Silkstring.Services; using Silkstring.Services.Variables; +using Silkstring.Services.Variables.Providers; using Silkstring.UI; using Silkstring.Windows; diff --git a/Silkstring/Services/Variables/CombatVariablesProvider.cs b/Silkstring/Services/Variables/Providers/CombatVariablesProvider.cs similarity index 93% rename from Silkstring/Services/Variables/CombatVariablesProvider.cs rename to Silkstring/Services/Variables/Providers/CombatVariablesProvider.cs index 935c035..15e46cf 100644 --- a/Silkstring/Services/Variables/CombatVariablesProvider.cs +++ b/Silkstring/Services/Variables/Providers/CombatVariablesProvider.cs @@ -2,7 +2,7 @@ using Dalamud.Game.ClientState.Conditions; using Dalamud.Plugin.Services; -namespace Silkstring.Services.Variables; +namespace Silkstring.Services.Variables.Providers; public sealed class CombatVariablesProvider : IVariableProvider { diff --git a/Silkstring/Services/Variables/CurrencyVariablesProvider.cs b/Silkstring/Services/Variables/Providers/CurrencyVariablesProvider.cs similarity index 91% rename from Silkstring/Services/Variables/CurrencyVariablesProvider.cs rename to Silkstring/Services/Variables/Providers/CurrencyVariablesProvider.cs index 6d386dd..7c78ec5 100644 --- a/Silkstring/Services/Variables/CurrencyVariablesProvider.cs +++ b/Silkstring/Services/Variables/Providers/CurrencyVariablesProvider.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using FFXIVClientStructs.FFXIV.Client.Game; -namespace Silkstring.Services.Variables; +namespace Silkstring.Services.Variables.Providers; public sealed class CurrencyVariablesProvider : IVariableProvider { diff --git a/Silkstring/Services/Variables/EmoteVariablesProvider.cs b/Silkstring/Services/Variables/Providers/EmoteVariablesProvider.cs similarity index 97% rename from Silkstring/Services/Variables/EmoteVariablesProvider.cs rename to Silkstring/Services/Variables/Providers/EmoteVariablesProvider.cs index b306399..316fb76 100644 --- a/Silkstring/Services/Variables/EmoteVariablesProvider.cs +++ b/Silkstring/Services/Variables/Providers/EmoteVariablesProvider.cs @@ -4,7 +4,7 @@ using FFXIVClientStructs.FFXIV.Client.Game.Character; using Lumina.Excel.Sheets; -namespace Silkstring.Services.Variables; +namespace Silkstring.Services.Variables.Providers; public sealed class EmoteVariablesProvider : IVariableProvider { diff --git a/Silkstring/Services/Variables/PlayerVariableProvider.cs b/Silkstring/Services/Variables/Providers/PlayerVariableProvider.cs similarity index 95% rename from Silkstring/Services/Variables/PlayerVariableProvider.cs rename to Silkstring/Services/Variables/Providers/PlayerVariableProvider.cs index 875d2d3..97bb81f 100644 --- a/Silkstring/Services/Variables/PlayerVariableProvider.cs +++ b/Silkstring/Services/Variables/Providers/PlayerVariableProvider.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using Dalamud.Plugin.Services; -namespace Silkstring.Services.Variables; +namespace Silkstring.Services.Variables.Providers; public sealed class PlayerVariableProvider : IVariableProvider { diff --git a/Silkstring/Services/Variables/UserVariableProvider.cs b/Silkstring/Services/Variables/Providers/UserVariableProvider.cs similarity index 93% rename from Silkstring/Services/Variables/UserVariableProvider.cs rename to Silkstring/Services/Variables/Providers/UserVariableProvider.cs index 52032b3..976a8b7 100644 --- a/Silkstring/Services/Variables/UserVariableProvider.cs +++ b/Silkstring/Services/Variables/Providers/UserVariableProvider.cs @@ -3,7 +3,7 @@ using System.Linq; using Silkstring.Models; -namespace Silkstring.Services.Variables; +namespace Silkstring.Services.Variables.Providers; public sealed class UserVariableProvider : IVariableProvider { diff --git a/Silkstring/Services/Variables/VitalsVariablesProvider.cs b/Silkstring/Services/Variables/Providers/VitalsVariablesProvider.cs similarity index 96% rename from Silkstring/Services/Variables/VitalsVariablesProvider.cs rename to Silkstring/Services/Variables/Providers/VitalsVariablesProvider.cs index a0b91f8..187b549 100644 --- a/Silkstring/Services/Variables/VitalsVariablesProvider.cs +++ b/Silkstring/Services/Variables/Providers/VitalsVariablesProvider.cs @@ -2,7 +2,7 @@ using Dalamud.Plugin.Services; using ECommons.DalamudServices.Legacy; -namespace Silkstring.Services.Variables; +namespace Silkstring.Services.Variables.Providers; public sealed class VitalsVariablesProvider : IVariableProvider { diff --git a/Tests/UserVariableProviderTests.cs b/Tests/UserVariableProviderTests.cs index 19e4b3b..c8e9e4b 100644 --- a/Tests/UserVariableProviderTests.cs +++ b/Tests/UserVariableProviderTests.cs @@ -1,6 +1,6 @@ using Silkstring.Models; using Silkstring.Services; -using Silkstring.Services.Variables; +using Silkstring.Services.Variables.Providers; public class UserVariableProviderTests { From b0ed0e55c9f40c0c58a687fcd2900564e5536d8a Mon Sep 17 00:00:00 2001 From: devoreofox <232652342+devoreofox@users.noreply.github.com> Date: Thu, 9 Jul 2026 13:17:14 -0300 Subject: [PATCH 2/2] Add time variables and documentation --- CHANGELOG.md | 6 ++++ README.md | 7 ++++- Silkstring/Plugin.cs | 1 + .../Providers/TimeVariablesProvider.cs | 30 +++++++++++++++++++ 4 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 Silkstring/Services/Variables/Providers/TimeVariablesProvider.cs diff --git a/CHANGELOG.md b/CHANGELOG.md index 700a337..3bbdba8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## v1.6.1.0 - 2026-07-09 +### Added +- Time variables: your aliases can now react to the clock. `{time}` shows your local time (like 3:45 PM), `{time24}` shows it in 24-hour form (15:45), and `{date}`, `{day}`, `{hour}`, and `{minute}` fill in the rest. `{daypart}` gives morning, afternoon, evening, or night, so a venue greeter can open with something like `Good {daypart}, welcome in!` +- `{utc}` and `{utcdate}` give the UTC (server) time and date, handy for lining things up with people in other time zones +- The 24-hour and date variables are made to be compared in conditions, so you can gate lines by the clock, for example `:if {time24} >= 17:00` to switch to an evening greeting. Use `{time}` for showing the time and `{time24}` (or `{hour}`) when comparing it + ## v1.6.0.0 - 2026-07-09 ### Added - Emote variables: `{emoting}` tells you whether you are holding an emote or pose, `{emote}` gives its name, and `{pose}` gives the pose number. They appear in the Variables tab alongside the other built-ins diff --git a/README.md b/README.md index cd29810..cd4dc87 100644 --- a/README.md +++ b/README.md @@ -87,7 +87,9 @@ Variables let you insert live game values into a line using curly brace syntax. /say I am {character}, a level {level} {job} from {world}! ``` -Silkstring includes variables for your character, job, HP and MP, combat state, target, currency, emote and pose state, and more, and the list keeps growing. For the full, always-current list with live values, open the Variables tab of the help window (`/silkstring help`). The command tester at the top of that window shows resolved output as you type. +Silkstring includes variables for your character, job, HP and MP, combat state, target, currency, emote and pose state, the time and date, and more, and the list keeps growing. For the full, always-current list with live values, open the Variables tab of the help window (`/silkstring help`). The command tester at the top of that window shows resolved output as you type. + +The time variables come in two flavors: `{time}` (like 3:45 PM) is for showing the time, while `{time24}` (like 15:45), `{date}`, `{hour}`, and `{minute}` are made for comparing, so you can gate lines by the clock (see Conditionals below). There is also `{daypart}`, which is simply morning, afternoon, evening, or night, and `{utc}` and `{utcdate}` for UTC (server) time. You can also define your own variables with `/silkstring variables` and use them just like the built-in ones (see User Variables below). @@ -135,8 +137,11 @@ A condition compares values with `==`, `!=`, `<`, `>`, `<=`, `>=`, and you can c :if {incombat} && {hpp} < 50 :if {job} == WHM || {job} == SCH :if {0} == on +:if {time24} >= 17:00 || {time24} <= 05:00 ``` +That last line reacts to the clock: because `{time24}` and `{date}` are written with leading zeros (like 09:00 and 2026-07-09), they sort in the right order and can be compared with `<`, `>`, `<=`, and `>=`. This is why `{time24}` is the one to compare against, while `{time}` (like 3:45 PM) is just for showing. + Text comparisons are case-insensitive, and numbers compare as numbers. The `:if`, `:else`, and `:endif` lines are never sent to chat, and the alias editor warns you if a block is left open or a condition cannot be understood. You can also pause between lines with `:wait`, followed by a number of seconds: diff --git a/Silkstring/Plugin.cs b/Silkstring/Plugin.cs index 1dde2fb..1c9f3f7 100644 --- a/Silkstring/Plugin.cs +++ b/Silkstring/Plugin.cs @@ -73,6 +73,7 @@ public Plugin() new CombatVariablesProvider(Condition, TargetManager), new CurrencyVariablesProvider(), new EmoteVariablesProvider(ClientState, DataManager), + new TimeVariablesProvider(), ]; var reserved = builtIn.SelectMany(p => p.GetVariables()).Select(v => v.Name).ToHashSet(StringComparer.OrdinalIgnoreCase); diff --git a/Silkstring/Services/Variables/Providers/TimeVariablesProvider.cs b/Silkstring/Services/Variables/Providers/TimeVariablesProvider.cs new file mode 100644 index 0000000..d79855b --- /dev/null +++ b/Silkstring/Services/Variables/Providers/TimeVariablesProvider.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; + +namespace Silkstring.Services.Variables.Providers; + +public sealed class TimeVariablesProvider : IVariableProvider +{ + public IEnumerable GetVariables() + { + yield return new("time", "Current local time, for example 3:45 PM (display only, do not compare)", "Time", () => DateTime.Now.ToString("h:mm tt")); + yield return new("time24", "Current local time in 24-hour form, for example 15:45 (compares with < <= > >=)", "Time", () => DateTime.Now.ToString("HH:mm")); + yield return new("hour", "Current hour of the day, 0 to 23", "Time", () => DateTime.Now.Hour.ToString()); + yield return new("minute", "Current minute, 00 to 59", "Time", () => DateTime.Now.Minute.ToString("D2")); + yield return new("date", "Current local date, for example 2026-07-09 (compares chronologically)", "Time", () => DateTime.Now.ToString("yyyy-MM-dd")); + yield return new("day", "Current day of the week, for example Thursday", "Time", () => DateTime.Now.DayOfWeek.ToString()); + yield return new("daypart", "morning, afternoon, evening, or night", "Time", DayPart); + yield return new("utc", "Current UTC (server) time in 24-hour form, for example 19:45", "Time", () => DateTime.UtcNow.ToString("HH:mm")); + yield return new("utcdate", "Current UTC (server) date, for example 2026-07-09", "Time", () => DateTime.UtcNow.ToString("yyyy-MM-dd")); + } + + private static string DayPart() + { + var h = DateTime.Now.Hour; + if (h < 5) return "night"; + if (h < 12) return "morning"; + if (h < 17) return "afternoon"; + if (h < 21) return "evening"; + return "night"; + } +}