Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions Bloxstrap/Integrations/LaunchHistory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using System.Text.Json;

namespace Bloxstrap.Integrations
{
/// <summary>
/// Keeps the last few launches (mode and time) next to Bloxstrap's own data, so the
/// settings window can show when Roblox or Studio was last opened.
/// </summary>
public static class LaunchHistory
{
private const int MaxEntries = 20;

private static string FilePath => Path.Combine(Paths.Base, "LaunchHistory.json");

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Delete launch history when the user discards data

When uninstalling with “Keep my settings and mods” disabled, Installer.DoUninstall(false) deletes the known settings, state, logs, and modifications but never deletes this new file. For installations with more than three top-level files, line 317 of Installer.cs also prevents removal of the entire base directory, so LaunchHistory.json and its usage timestamps remain after uninstall; add it to the non-keep-data cleanup sequence.

Useful? React with 👍 / 👎.


public record Entry(LaunchMode Mode, DateTime LaunchedAt);

public static IReadOnlyList<Entry> Load()
{
try
{
if (!File.Exists(FilePath))
return Array.Empty<Entry>();

return JsonSerializer.Deserialize<List<Entry>>(File.ReadAllText(FilePath)) ?? new List<Entry>();
}
catch (Exception ex)
{
App.Logger.WriteException("LaunchHistory::Load", ex);
return Array.Empty<Entry>();
}
}

public static void Record(LaunchMode mode)
{
var entries = Load().Prepend(new Entry(mode, DateTime.UtcNow)).Take(MaxEntries).ToList();

try
{
File.WriteAllText(FilePath, JsonSerializer.Serialize(entries));
Comment on lines +35 to +39

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Serialize history updates across launcher processes

Record performs an unprotected read-modify-write on a file shared by every Bloxstrap process. If Player and Studio launches begin concurrently, both processes can load the same previous list and the later write can overwrite the earlier entry, or one write can fail with a sharing violation and be silently reduced to a log message; protect the complete load-and-write operation with an interprocess lock.

Useful? React with 👍 / 👎.

}
catch (Exception ex)
{
App.Logger.WriteException("LaunchHistory::Record", ex);
}
}
}
}
2 changes: 2 additions & 0 deletions Bloxstrap/LaunchHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,13 @@ public static void ProcessNextAction(NextAction action, bool isUnfinishedInstall

case NextAction.LaunchRoblox:
App.Logger.WriteLine(LOG_IDENT, "Opening Roblox");
Integrations.LaunchHistory.Record(LaunchMode.Player);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Record launches initiated through launch arguments

The history hook exists only in ProcessNextAction, but website protocol invocations and the -player, -studio, and local-place CLI flows use the ProcessLaunchArgs branch at lines 69–72, which calls LaunchRoblox directly. Those are primary launch paths, so they never create or update LaunchHistory.json; recording needs to occur on a shared path used by every Roblox and Studio launch.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Record history only after a successful launch

This records the launch before LaunchRoblox performs any validation or starts a process. If Windows Media Foundation is unavailable, the user declines the existing-launch confirmation, bootstrapper setup fails, or a UAC prompt is cancelled, the history still reports that Roblox was opened; the same issue applies to the Studio call below. Record the entry only after the Roblox process has successfully started.

Useful? React with 👍 / 👎.

LaunchRoblox(LaunchMode.Player);
break;

case NextAction.LaunchRobloxStudio:
App.Logger.WriteLine(LOG_IDENT, "Opening Roblox Studio");
Integrations.LaunchHistory.Record(LaunchMode.Studio);
LaunchRoblox(LaunchMode.Studio);
break;

Expand Down
Loading