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
5 changes: 0 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -264,11 +264,6 @@ jobs:
with:
dotnet-version: ${{ env.DOTNET_VERSION }}

- name: Install Linux Dependencies
run: |
sudo apt-get update
sudo apt-get install -y libgtk-3-dev libx11-dev

- name: Cache NuGet Packages
uses: actions/cache@v3
with:
Expand Down
3 changes: 0 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -234,9 +234,6 @@ jobs:
with:
dotnet-version: ${{ env.DOTNET_VERSION }}

- name: Install Linux Dependencies
run: sudo apt-get update && sudo apt-get install -y libgtk-3-dev libx11-dev

- name: Extract Build Info
id: buildinfo
run: |
Expand Down
110 changes: 110 additions & 0 deletions GenHub/GenHub.Core/Constants/AppUpdateConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,21 @@ public static class AppUpdateConstants
/// </summary>
public const int MaxHttpRetries = 3;

/// <summary>
/// Index for the Update tab in update notification views.
/// </summary>
public const int UpdateTabIndex = 0;

/// <summary>
/// Index for the Browse Builds tab in update notification views.
/// </summary>
public const int BrowseBuildsTabIndex = 1;

/// <summary>
/// Maximum valid tab index in update notification views.
/// </summary>
public const int MaxTabIndex = 1;

/// <summary>
/// Velopack directory name.
/// </summary>
Expand Down Expand Up @@ -153,6 +168,101 @@ public static class AppUpdateConstants
"3. Launch the installed version (will be in %LOCALAPPDATA%\\GenHub)\n\n" +
"Update available: v{1}";

/// <summary>
/// Update available notification title for release channel.
/// </summary>
public const string UpdateAvailableNotificationTitle = "Update Available";

/// <summary>
/// Update available notification title for branch subscriptions.
/// </summary>
public const string BranchUpdateAvailableNotificationTitle = "Branch Update Available";

/// <summary>
/// Update available notification title for PR subscriptions.
/// </summary>
public const string PrUpdateAvailableNotificationTitle = "PR Update Available";

/// <summary>
/// Update action button text.
/// </summary>
public const string UpdateAction = "Update";

/// <summary>
/// Title for the update in progress notification.
/// </summary>
public const string UpdatingAppNotificationTitle = "Updating GenHub";

/// <summary>
/// Starting update progress message.
/// </summary>
public const string UpdateStartingMessage = "Starting update...";

/// <summary>
/// Title for update failed notification.
/// </summary>
public const string UpdateFailedNotificationTitle = "Update Failed";

/// <summary>
/// Update failed notification body format string ({0}: error message).
/// </summary>
public const string UpdateFailedNotificationFormat = "Failed to install update: {0}";

/// <summary>
/// View updates action button text.
/// </summary>
public const string ViewUpdatesAction = "View Updates";

/// <summary>
/// Release update notification body format string ({0}: version).
/// </summary>
public const string ReleaseUpdateNotificationFormat = "A new version ({0}) is available.";

/// <summary>
/// Branch update notification body format string ({0}: version, {1}: branch name).
/// </summary>
public const string BranchUpdateNotificationFormat = "A new build ({0}) is available on branch '{1}'.";

/// <summary>
/// PR update notification body format string ({0}: version, {1}: PR number).
/// </summary>
public const string PrUpdateNotificationFormat = "A new build ({0}) is available for PR #{1}.";

/// <summary>
/// Sort option: sort by last updated date descending.
/// </summary>
public const string SortOptionLastUpdated = "Last Updated";

/// <summary>
/// Sort option: sort by pull request number descending.
/// </summary>
public const string SortOptionPrNumberDesc = "PR Number (Highest)";

/// <summary>
/// Sort option: sort by pull request number ascending.
/// </summary>
public const string SortOptionPrNumberAsc = "PR Number (Lowest)";

/// <summary>
/// Default interval in minutes for periodic update checks (30 minutes).
/// </summary>
public const int DefaultPeriodicUpdateCheckIntervalMinutes = 30;

/// <summary>
/// Minimum interval in minutes for periodic update checks (5 minutes).
/// </summary>
public const int MinPeriodicUpdateCheckIntervalMinutes = 5;

/// <summary>
/// Maximum interval in minutes for periodic update checks (10080 minutes / 7 days).
/// </summary>
public const int MaxPeriodicUpdateCheckIntervalMinutes = 10080;

/// <summary>
/// Increment step in minutes for periodic update check interval setting (5 minutes).
/// </summary>
public const int PeriodicUpdateCheckIntervalIncrementMinutes = 5;

/// <summary>
/// Delay before exit after applying update (5 seconds).
/// </summary>
Expand Down
22 changes: 16 additions & 6 deletions GenHub/GenHub.Core/Constants/CommandLineConstants.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
namespace GenHub.Core.Constants;

/// <summary>
/// Constants for command line arguments and URI schemes.
/// Constants for command line arguments and the <c>genhub://</c> URI scheme.
/// </summary>
/// <remarks>
/// Subscription links use <c>genhub://subscribe?url=&lt;absolute-url&gt;</c>.
/// Today <c>url</c> is a hosted GenHub <c>catalog.json</c>. Publisher Studio will also share
/// Provider Definition URLs via the same scheme; GenHub will detect payload type at fetch time.
/// </remarks>
public static class CommandLineConstants
{
/// <summary>
Expand All @@ -16,22 +21,27 @@ public static class CommandLineConstants
public const string LaunchProfileInlinePrefix = "--launch-profile=";

/// <summary>
/// URI scheme used for protocol handling.
/// Scheme name for custom protocol registration.
/// </summary>
public const string UriScheme = "genhub://";
public const string SchemeName = "genhub";

/// <summary>
/// Command for subscribing to a catalog via URI.
/// Custom URI scheme registered so OS/browser links can open GenHub.
/// </summary>
public const string UriScheme = SchemeName + "://";

/// <summary>
/// URI path segment for content subscription (<c>genhub://subscribe?url=...</c>).
/// </summary>
public const string SubscribeCommand = "subscribe";

/// <summary>
/// Full prefix for subscription URI.
/// Full prefix for subscription URIs (<c>genhub://subscribe</c>).
/// </summary>
public const string SubscribeUriPrefix = UriScheme + SubscribeCommand;

/// <summary>
/// Query parameter name for the catalog URL in a subscription URI.
/// Query parameter carrying the absolute URL of a catalog (or future provider definition).
/// </summary>
public const string SubscribeUrlParam = "?url=";
}
27 changes: 27 additions & 0 deletions GenHub/GenHub.Core/Constants/ContentConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,4 +94,31 @@ public static class ContentConstants
/// Maximum allowed size for the content catalog in bytes (10 MB).
/// </summary>
public const long MaxCatalogSizeBytes = 10 * ConversionConstants.BytesPerMegabyte;

/// <summary>
/// Shared resolver/display metadata key for map player counts.
/// Builtin and catalog publishers should set this so download cards can render a consistent badge.
/// </summary>
public const string PlayerCountMetadataKey = "playerCount";

/// <summary>
/// Shared resolver/display metadata key for content categories (AOA, Compstomp, ModDB category, etc.).
/// </summary>
public const string CategoryMetadataKey = "category";

/// <summary>
/// Display metadata key for a comma-separated list of included/required content names
/// (e.g. catalog ContentBundle dependencies resolved to friendly titles).
/// </summary>
public const string IncludesSummaryMetadataKey = "includesSummary";

/// <summary>
/// Number of recent releases and addons to eagerly preload extended details for.
/// </summary>
public const int PreloadRecentItemsLimit = 5;

/// <summary>
/// Maximum concurrent background requests when preloading recent item details.
/// </summary>
public const int PreloadConcurrencyLimit = 3;
}
10 changes: 10 additions & 0 deletions GenHub/GenHub.Core/Constants/DirectoryNames.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,14 @@ public static class DirectoryNames
/// Directory for storing tool workspaces.
/// </summary>
public const string ToolWorkspaces = "ToolWorkspaces";

/// <summary>
/// Directory for persistent Playwright browser profiles (cookies/storage for bot-protected sites).
/// </summary>
public const string BrowserProfiles = "BrowserProfiles";

/// <summary>
/// Directory for the app-owned Playwright Chromium runtime (not the system Chrome/Edge install).
/// </summary>
public const string BrowserRuntime = "BrowserRuntime";
}
3 changes: 2 additions & 1 deletion GenHub/GenHub.Core/Constants/IpcCommands.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ public static class IpcCommands
public const string LaunchProfilePrefix = "launch-profile:";

/// <summary>
/// Command prefix used to subscribe to a catalog via IPC.
/// Command prefix used to forward a subscribe URL to the primary instance
/// (<c>subscribe:&lt;absolute-url&gt;</c>). Same payload as <c>genhub://subscribe?url=...</c>.
/// </summary>
public const string SubscribePrefix = "subscribe:";
}
57 changes: 57 additions & 0 deletions GenHub/GenHub.Core/Constants/ModDBConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@ public static class ModDBConstants
/// <summary>ModDB website URL.</summary>
public const string PublisherWebsite = BaseUrl;

/// <summary>
/// On-disk Playwright browser profile name used to persist the Cloudflare clearance cookie so
/// the user only solves the bot challenge once per session (and across restarts until expiry).
/// </summary>
public const string BrowserProfileName = "moddb";

/// <summary>Short description for publisher card display.</summary>
public const string ShortDescription = "Community mods, maps, and content from ModDB";

Expand Down Expand Up @@ -184,6 +190,29 @@ public static class ModDBConstants
/// <summary>Value for filter parameter when enabled.</summary>
public const string FilterEnabledValue = "t";

// ===== Sort Values =====

/// <summary>Sort: Date descending (newest first).</summary>
public const string SortDateDesc = "date-desc";

/// <summary>Sort: Date ascending (oldest first).</summary>
public const string SortDateAsc = "date-asc";

/// <summary>Sort: Visits / Popularity descending.</summary>
public const string SortVisitDesc = "visit-desc";

/// <summary>Sort: Rating descending.</summary>
public const string SortRatingDesc = "rating-desc";

/// <summary>Sort: Name ascending (A-Z).</summary>
public const string SortNameAsc = "name-asc";

/// <summary>Sort: Name descending (Z-A).</summary>
public const string SortNameDesc = "name-desc";

/// <summary>Default sort value for ModDB searches and listings (newest first).</summary>
public const string DefaultSort = SortDateDesc;

// ===== Category Values =====

// Downloads Section - Releases
Expand Down Expand Up @@ -356,6 +385,34 @@ public static class ModDBConstants
/// <summary>Metadata key for original category.</summary>
public const string OriginalCategoryMetadataKey = "moddbCategory";

/// <summary>Metadata key for identifying if content is a mod.</summary>
public const string IsModMetadataKey = "IsMod";

/// <summary>Metadata key for parent mod URL.</summary>
public const string ParentModUrlMetadataKey = "ParentModUrl";

// ===== Playwright / Scraping Constants =====

/// <summary>Default timeout for page navigation (ms).</summary>
public const int DefaultGotoTimeout = 30000;

/// <summary>
/// Default timeout for waiting for a selector (ms). ModDB sits behind Cloudflare; the headed
/// browser persistent profile usually receives the clearance cookie after verification, but 15 s gives a safe margin
/// for manual challenge solves before the scraper parses whatever it has.
/// </summary>
public const int DefaultSelectorTimeout = 15000;

/// <summary>
/// How long (ms) the listing scrape waits for the user to solve a Cloudflare challenge in the
/// visible browser before giving up. Long enough for a manual "I am not a robot" click; the
/// page stays open after the deadline so the user can finish and retry.
/// </summary>
public const int VerificationWaitTimeoutMs = 120000;

/// <summary>Selector for content items in listing pages (Fallback).</summary>
public const string DefaultListItemSelector = "div.row.rowcontent, div.table tr";

// ===== Error Messages =====

/// <summary>Error message for invalid URL.</summary>
Expand Down
Loading
Loading