Skip to content

Commit

Permalink
Improve booster status reports
Browse files Browse the repository at this point in the history
  • Loading branch information
Citrinate committed Apr 10, 2024
1 parent 1d8a793 commit b8460ae
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 19 deletions.
41 changes: 26 additions & 15 deletions BoosterManager/Boosters/BoosterQueue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ internal sealed class BoosterQueue : IDisposable {
internal int BoosterDelay = 0; // Delay, in seconds, added to all booster crafts
private readonly BoosterDatabase? BoosterDatabase;
internal event Action? OnBoosterInfosUpdated;
internal event Action? OnBoosterFinishedCheck;
private float BoosterInfosUpdateBackOffMultiplier = 1.0F;

internal BoosterQueue(Bot bot) {
Expand Down Expand Up @@ -244,8 +245,8 @@ void handler() {
OnBoosterInfosUpdated += handler;
}

private Booster? GetNextCraftableBooster(BoosterType type, bool getLast = false) {
HashSet<Booster> uncraftedBoosters = GetBoosters(type, wasCrafted: false);
private Booster? GetNextCraftableBooster(BoosterType type, bool getLast = false, HashSet<uint>? filterGameIDs = null) {
HashSet<Booster> uncraftedBoosters = GetBoosters(type, wasCrafted: false, filterGameIDs: filterGameIDs);
if (uncraftedBoosters.Count == 0) {
return null;
}
Expand All @@ -258,15 +259,13 @@ void handler() {
return orderedUncraftedBoosters.First();
}

internal bool CheckIfFinished(BoosterType type) {
bool doneCrafting = GetNumBoosters(type, wasCrafted: true) > 0 && GetNumBoosters(type, wasCrafted: false) == 0;
if (!doneCrafting) {
internal bool CheckIfFinished(BoosterType type, HashSet<uint>? filterGameIDs = null) {
OnBoosterFinishedCheck?.Invoke();

if (!IsFinishedCrafting(type)) {
return false;
}

if (type == BoosterType.OneTime) {
BoosterHandler.GeneralReporter.Report(Bot, String.Format(Strings.BoosterCreationFinished, GetNumBoosters(BoosterType.OneTime)));
}
ClearCraftedBoosters(type);

return true;
Expand Down Expand Up @@ -312,13 +311,13 @@ internal HashSet<uint> RemoveBoosters(HashSet<uint>? gameIDs = null, int? timeLi
return removedGameIDs;
}

internal string? GetShortStatus() {
Booster? lastOneTimeBooster = GetNextCraftableBooster(BoosterType.OneTime, getLast: true);
internal string? GetShortStatus(HashSet<uint>? filterGameIDs = null) {
Booster? lastOneTimeBooster = GetNextCraftableBooster(BoosterType.OneTime, getLast: true, filterGameIDs: filterGameIDs);
if (lastOneTimeBooster == null) {
return null;
}

return String.Format(Strings.QueueStatusShort, GetNumBoosters(BoosterType.OneTime), String.Format("{0:N0}", GetGemsNeeded(BoosterType.OneTime)), String.Format("~{0:t}", lastOneTimeBooster.GetAvailableAtTime(BoosterDelay)));
return String.Format(Strings.QueueStatusShort, GetNumBoosters(BoosterType.OneTime, filterGameIDs: filterGameIDs), String.Format("{0:N0}", GetGemsNeeded(BoosterType.OneTime, filterGameIDs: filterGameIDs)), String.Format("~{0:t}", lastOneTimeBooster.GetAvailableAtTime(BoosterDelay)));
}

internal string GetStatus() {
Expand All @@ -332,40 +331,52 @@ internal string GetStatus() {
}

HashSet<string> responses = new HashSet<string>();

// Not enough gems
if (GetGemsNeeded(BoosterType.Any, wasCrafted: false) > GetAvailableGems()) {
responses.Add(String.Format("{0} :steamsad:", Strings.QueueStatusNotEnoughGems));

if (nextBooster.Info.Price > GetAvailableGems()) {
responses.Add(String.Format(Strings.QueueStatusGemsNeeded, String.Format("{0:N0}", nextBooster.Info.Price - GetAvailableGems())));
}

if (GetNumBoosters(BoosterType.Any, wasCrafted: false) > 1) {
responses.Add(String.Format(Strings.QueueStatusTotalGemsNeeded, String.Format("{0:N0}", GetGemsNeeded(BoosterType.Any, wasCrafted: false) - GetAvailableGems())));
}
}

// One time booster status
if (GetNumBoosters(BoosterType.OneTime) > 0) {
Booster? lastOneTimeBooster = GetNextCraftableBooster(BoosterType.OneTime, getLast: true);
if (lastOneTimeBooster != null) {
responses.Add(String.Format(Strings.QueueStatusOneTimeBoosters, GetNumBoosters(BoosterType.OneTime, wasCrafted: true), GetNumBoosters(BoosterType.OneTime), String.Format("~{0:t}", lastOneTimeBooster.GetAvailableAtTime(BoosterDelay)), String.Format("{0:N0}", GetGemsNeeded(BoosterType.OneTime, wasCrafted: false))));
responses.Add(String.Format(Strings.QueueStatusOneTimeBoosterList, String.Join(", ", GetBoosterIDs(BoosterType.OneTime, wasCrafted: false))));
}
}

// Permanent booster status
if (GetNumBoosters(BoosterType.Permanent) > 0) {
responses.Add(String.Format(Strings.QueueStatusPermanentBoosters, String.Format("{0:N0}", GetGemsNeeded(BoosterType.Permanent)), String.Join(", ", GetBoosterIDs(BoosterType.Permanent))));
}

// Next booster to be crafted
if (DateTime.Now > nextBooster.GetAvailableAtTime(BoosterDelay)) {
responses.Add(String.Format(Strings.QueueStatusNextBoosterCraftingNow, nextBooster.Info.Name, nextBooster.GameID));
} else {
responses.Add(String.Format(Strings.QueueStatusNextBoosterCraftingLater, String.Format("{0:t}", nextBooster.GetAvailableAtTime(BoosterDelay)), nextBooster.Info.Name, nextBooster.GameID));
}

responses.Add("");

return String.Join(Environment.NewLine, responses);
}

private bool FilterBoosterByType(Booster booster, BoosterType type) => type == BoosterType.Any || booster.Type == type;
private HashSet<Booster> GetBoosters(BoosterType type, bool? wasCrafted = null) => Boosters.Values.Where(booster => (wasCrafted == null || booster.WasCrafted == wasCrafted) && FilterBoosterByType(booster, type)).ToHashSet<Booster>();
private HashSet<uint> GetBoosterIDs(BoosterType type, bool? wasCrafted = null) => GetBoosters(type, wasCrafted).Select(booster => booster.GameID).ToHashSet<uint>();
internal int GetNumBoosters(BoosterType type, bool? wasCrafted = null) => GetBoosters(type, wasCrafted).Count;
internal int GetGemsNeeded(BoosterType type, bool? wasCrafted = null) => GetBoosters(type, wasCrafted).Sum(booster => (int) booster.Info.Price);
private HashSet<Booster> GetBoosters(BoosterType type, bool? wasCrafted = null, HashSet<uint>? filterGameIDs = null) => Boosters.Values.Where(booster => (filterGameIDs == null || filterGameIDs.Contains(booster.GameID)) && (wasCrafted == null || booster.WasCrafted == wasCrafted) && FilterBoosterByType(booster, type)).ToHashSet<Booster>();
private HashSet<uint> GetBoosterIDs(BoosterType type, bool? wasCrafted = null, HashSet<uint>? filterGameIDs = null) => GetBoosters(type, wasCrafted, filterGameIDs).Select(booster => booster.GameID).ToHashSet<uint>();
internal int GetNumBoosters(BoosterType type, bool? wasCrafted = null, HashSet<uint>? filterGameIDs = null) => GetBoosters(type, wasCrafted, filterGameIDs).Count;
internal int GetGemsNeeded(BoosterType type, bool? wasCrafted = null, HashSet<uint>? filterGameIDs = null) => GetBoosters(type, wasCrafted, filterGameIDs).Sum(booster => (int) booster.Info.Price);
internal bool IsFinishedCrafting(BoosterType type, HashSet<uint>? filterGameIDs = null) => GetNumBoosters(type, wasCrafted: true, filterGameIDs) > 0 && GetNumBoosters(type, wasCrafted: false, filterGameIDs) == 0;
internal void ForceUpdateBoosterInfos() => OnBoosterInfosUpdated -= ForceUpdateBoosterInfos;
private static int GetMillisecondsFromNow(DateTime then) => Math.Max(0, (int) (then - DateTime.Now).TotalMilliseconds);
private void UpdateTimer(DateTime then) => Timer.Change(GetMillisecondsFromNow(then), Timeout.Infinite);
Expand Down
16 changes: 12 additions & 4 deletions BoosterManager/Handlers/BoosterHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,9 @@ internal string ScheduleBoosters(HashSet<uint> gameIDs, StatusReporter craftingR
BoosterQueue.AddBooster(gameID, BoosterType.OneTime);
}

void handler() {
void infoHandler() {
try {
string? message = BoosterQueue.GetShortStatus();
string? message = BoosterQueue.GetShortStatus(gameIDs);
if (message == null) {
craftingReporter.Report(Bot, Strings.BoostersUncraftable);

Expand All @@ -76,12 +76,20 @@ void handler() {

craftingReporter.Report(Bot, message);
} finally {
BoosterQueue.OnBoosterInfosUpdated -= handler;
BoosterQueue.OnBoosterInfosUpdated -= infoHandler;
}
}

void finishedHandler() {
if (BoosterQueue.IsFinishedCrafting(BoosterType.OneTime, gameIDs)) {
craftingReporter.Report(Bot, String.Format(Strings.BoosterCreationFinished, BoosterQueue.GetNumBoosters(BoosterType.OneTime, filterGameIDs: gameIDs)));
BoosterQueue.OnBoosterFinishedCheck -= finishedHandler;
}
}

GeneralReporter.Update(craftingReporter);
BoosterQueue.OnBoosterInfosUpdated += handler;
BoosterQueue.OnBoosterInfosUpdated += infoHandler;
BoosterQueue.OnBoosterFinishedCheck += finishedHandler;
BoosterQueue.Start();

return Commands.FormatBotResponse(Bot, String.Format(Strings.BoosterCreationStarting, gameIDs.Count));
Expand Down

0 comments on commit b8460ae

Please sign in to comment.