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
78 changes: 78 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,14 @@ jobs:
echo "file_version=0.0.0.0" >> $GITHUB_OUTPUT
fi

if [[ "${GITHUB_REF}" == refs/tags/* ]] && [ "${GITHUB_REF_NAME}" != "nightly" ]; then
echo "release_tag=${GITHUB_REF_NAME}" >> $GITHUB_OUTPUT
echo "asset_suffix=${GITHUB_REF_NAME}" >> $GITHUB_OUTPUT
else
echo "release_tag=nightly" >> $GITHUB_OUTPUT
echo "asset_suffix=nightly" >> $GITHUB_OUTPUT
fi

- name: Inject telemetry key
shell: bash
run: |
Expand Down Expand Up @@ -380,6 +388,74 @@ jobs:
shell: pwsh
run: Compress-Archive -Path build-avalonia/* -DestinationPath SubathonManager_${{ matrix.runtime }}_${{ steps.avars.outputs.suffix }}.zip

- name: Build Windows installer
if: matrix.runtime == 'win-x64'
shell: pwsh
run: |
$ErrorActionPreference = 'Stop'

function Find-Iscc {
$hit = @(
"${env:ProgramFiles(x86)}\Inno Setup 6\ISCC.exe",
"${env:ProgramFiles}\Inno Setup 6\ISCC.exe"
) | Where-Object { Test-Path $_ } | Select-Object -First 1
if ($hit) { return $hit }
return (Get-Command ISCC.exe -ErrorAction SilentlyContinue).Source
}

$iscc = Find-Iscc
if (-not $iscc) {
choco install innosetup --no-progress -y
$iscc = Find-Iscc
}
if (-not $iscc) { throw 'Inno Setup compiler (ISCC.exe) not found' }
Write-Host "ISCC: $iscc"

Copy-Item LICENSE installer\windows\LICENSE.txt -Force

$assetSuffix = "${{ steps.avars.outputs.asset_suffix }}"
$localSuffix = "${{ steps.avars.outputs.suffix }}"
$asset = "SubathonManager_${{ matrix.runtime }}_$assetSuffix.zip"
$url = "https://github.com/${{ github.repository }}/releases/download/${{ steps.avars.outputs.release_tag }}/$asset"
$appVer = $localSuffix -replace '^v', ''

$size = (Get-ChildItem build-avalonia -Recurse -File |
Measure-Object -Property Length -Sum).Sum
Write-Host "Installer payload size: $size bytes"

$isccArgs = @(
'/Qp'
"/DAppVer=$appVer"
"/DFileVer=${{ steps.avars.outputs.file_version }}"
"/DZipUrl=$url"
"/DZipName=$asset"
"/DZipSize=$size"
'/Oinstaller-out'
)

if ($assetSuffix -eq $localSuffix -and $assetSuffix -ne 'nightly') {
$sha = (Get-FileHash $asset -Algorithm SHA256).Hash
$isccArgs += "/DZipSha256=$sha"
Write-Host "Installer sha256: $sha"
} else {
Write-Host "Installer sha256: (not pinned; nightly asset rotates)"
}
Write-Host "Installer payload: $url"

$isccArgs += 'installer\windows\SubathonManager.iss'
& $iscc @isccArgs
if ($LASTEXITCODE -ne 0) { throw "ISCC failed with exit code $LASTEXITCODE" }

Get-ChildItem installer-out

- name: Upload Windows installer
if: matrix.runtime == 'win-x64'
uses: actions/upload-artifact@v7
with:
name: SubathonManager_win-x64_Setup_${{ steps.avars.outputs.suffix }}
path: installer-out/*.exe
retention-days: 3

- name: Resolve Nextcloud upload path
shell: bash
run: |
Expand Down Expand Up @@ -737,6 +813,7 @@ jobs:
with:
files: |
dist/*.zip
dist/*.exe
*.sb
*.streamDeckPlugin
env:
Expand Down Expand Up @@ -768,6 +845,7 @@ jobs:
prerelease: true
files: |
dist/*.zip
dist/*.exe
*.sb
*.streamDeckPlugin
token: ${{ secrets.GITHUB_TOKEN }}
Expand Down
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ riderModule.iml
exports/
imports/
cache/
external/mixitup/

*.smo
*.smw
Expand Down Expand Up @@ -234,3 +235,7 @@ coverage-local/
# Stream Deck plugin packaging stuff
*.streamDeckPlugin
external/streamdeck/**/images/

# Windows installer build output
installer/windows/LICENSE.txt
installer-out/
5 changes: 2 additions & 3 deletions SubathonManager.Core/AppServices.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
using System.Reflection;
using System.Runtime.InteropServices;
using Microsoft.Extensions.Logging;
using Updatum;
using StageKit.Updatum;

namespace SubathonManager.Core;

Expand Down Expand Up @@ -99,8 +99,7 @@ public static async Task<bool> InstallUpdate(UpdatumDownloadedAsset? asset, ILog
return false;

try {
await AppUpdater.InstallUpdateAsync(asset);
return true;
return await AppUpdater.InstallUpdateAsync(asset);
}
catch (Exception ex) {
logger?.LogWarning(ex, "Failed to install update");
Expand Down
2 changes: 2 additions & 0 deletions SubathonManager.Core/Enums/EnumExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ public class EventTypeMetaAttribute : EnumMetaAttribute {
public bool IsOther { get; init; }
public bool HasValueConfig { get; init; } = true;

public bool HasCommissionData{ get; init; }

public SubathonEventSource Source { get; set; } = SubathonEventSource.Unknown;
}

Expand Down
40 changes: 40 additions & 0 deletions SubathonManager.Core/Enums/MixItUpTrigger.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
namespace SubathonManager.Core.Enums;

public enum MixItUpTrigger {
[EnumMeta(Label = "Subathon Event", Order = 0,
Description = "Any subathon event (subs, donations, orders, etc.), and commands if enabled")]
SubathonEvent,

[EnumMeta(Label = "Timer Paused", Order = 1, Description = "The subathon timer was paused")]
TimerPaused,

[EnumMeta(Label = "Timer Resumed", Order = 2, Description = "The subathon timer was resumed")]
TimerResumed,

[EnumMeta(Label = "Timer Locked", Order = 3, Description = "The subathon was locked")]
TimerLocked,

[EnumMeta(Label = "Timer Unlocked", Order = 4, Description = "The subathon was unlocked")]
TimerUnlocked,

[EnumMeta(Label = "Multiplier Started", Order = 5, Description = "A multiplier started")]
MultiplierStarted,

[EnumMeta(Label = "Multiplier Ended", Order = 6, Description = "A multiplier ended or was stopped")]
MultiplierEnded,

[EnumMeta(Label = "Goal Completed", Order = 7, Description = "A goal was reached")]
GoalCompleted,

[EnumMeta(Label = "Wheel Spin Start", Order = 8, Description = "A wheel spin started")]
WheelSpinStart,

[EnumMeta(Label = "Wheel Spin End", Order = 9, Description = "A wheel spin landed on a result")]
WheelSpinEnd,

[EnumMeta(Label = "Prompt Started", Order = 10, Description = "A prompt run started")]
PromptStarted,

[EnumMeta(Label = "Prompt Ended", Order = 11, Description = "A prompt run completed, expired or was cancelled")]
PromptEnded
}
5 changes: 4 additions & 1 deletion SubathonManager.Core/Enums/ProcessSearch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,8 @@ public enum ProcessSearch {
StreamerBot,

[ProcessSearchMeta(QueryNames = ["Stream Deck", "StreamDeck"])]
StreamDeck
StreamDeck,

[ProcessSearchMeta(QueryNames = ["MixItUp", "Mix It Up"])]
MixItUp
}
6 changes: 6 additions & 0 deletions SubathonManager.Core/Enums/ScheduleItemKind.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace SubathonManager.Core.Enums;

public enum ScheduleItemKind {
Event,
Task
}
10 changes: 7 additions & 3 deletions SubathonManager.Core/Enums/SubathonEventSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ public enum SubathonEventSource {
SourceOrder = 42, Visible = false, TrueSource = KoFi, Order = 41)]
KoFiTunnel,

[EventSourceMeta(Description = "Dev Tunnels", SourceGroup = SubathonSourceGroup.ExternalSoftware, SourceOrder = 904,
Visible = false, Order = 903)]
[EventSourceMeta(Description = "Dev Tunnels", SourceGroup = SubathonSourceGroup.ExternalSoftware, SourceOrder = 994,
Visible = false, Order = 993)]
DevTunnels,

[EventSourceMeta(Description = "FourthWall", SourceGroup = SubathonSourceGroup.ExternalService, SourceOrder = 62,
Expand Down Expand Up @@ -104,7 +104,11 @@ public enum SubathonEventSource {

[EventSourceMeta(Description = "VTube Studio", SourceGroup = SubathonSourceGroup.ExternalSoftware,
SourceOrder = 905, Order = 904, Visible = false)]
VTubeStudio
VTubeStudio,

[EventSourceMeta(Description = "Mix It Up", SourceGroup = SubathonSourceGroup.ExternalSoftware,
SourceOrder = 904, Order = 903, Visible = false, IsExternalSource = true)]
MixItUp
}

[ExcludeFromCodeCoverage]
Expand Down
14 changes: 9 additions & 5 deletions SubathonManager.Core/Enums/SubathonEventType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -114,15 +114,15 @@ public enum SubathonEventType {
YouTubeRedirect,

[EventTypeMeta(Label = "Shop Order", Source = SubathonEventSource.KoFi, IsOrder = true, IsExternal = true,
Order = 3)]
HasCommissionData = true, Order = 3)]
KoFiShopOrder,

[EventTypeMeta(Label = "Commission", Source = SubathonEventSource.KoFi, IsOrder = true, IsExternal = true,
Order = 4)]
HasCommissionData = true, Order = 4)]
KoFiCommissionOrder,

[EventTypeMeta(Label = "Shop Order", Source = SubathonEventSource.FourthWall, IsOrder = true, IsExternal = true,
Order = 3)]
HasCommissionData = true, Order = 3)]
FourthWallOrder,

[EventTypeMeta(Label = "Donation", Source = SubathonEventSource.FourthWall, IsCurrencyDonation = true,
Expand All @@ -135,7 +135,7 @@ public enum SubathonEventType {
FourthWallMembership,

[EventTypeMeta(Label = "Gift Order", Source = SubathonEventSource.FourthWall, IsOrder = true, IsExternal = true,
Order = 4)]
HasCommissionData = true, Order = 4)]
FourthWallGiftOrder,

[Obsolete]
Expand Down Expand Up @@ -175,7 +175,7 @@ public enum SubathonEventType {

// dynamic GoAffPro order type, meta is site id
[GoAffProTypeMeta(Label = "GoAffPro Order", Source = SubathonEventSource.GoAffPro, IsOrder = true, Order = 1,
Enabled = true)]
HasCommissionData = true, Enabled = true)]
GoAffProOrder,

[Obsolete]
Expand Down Expand Up @@ -271,6 +271,10 @@ public static bool IsOrder(this SubathonEventType? value) {
return value.Meta()?.IsOrder == true;
}

public static bool IsOrderWitCommission(this SubathonEventType? value) {
return value.Meta()?.IsOrder == true && value.Meta()?.HasCommissionData == true;
}

public static bool IsEvent(this SubathonEventType? value) {
return value.Meta()?.IsGenericEvent == true;
}
Expand Down
6 changes: 6 additions & 0 deletions SubathonManager.Core/Events/IntegrationEvents.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Diagnostics.CodeAnalysis;
using SubathonManager.Core.Enums;
using SubathonManager.Core.Objects;

namespace SubathonManager.Core.Events;
Expand All @@ -8,12 +9,17 @@ public static class IntegrationEvents {
public static event Action<IntegrationConnection>? ConnectionUpdated; // status, src, acc name, service
public static event Action<Dictionary<string, string>>? FourthWallMembershipsSynced;
public static event Action? DevTunnelLegacyNotification;
public static event Action<SubathonEventSource>? ExternalSourceSeen;

public static void RaiseConnectionUpdate(IntegrationConnection connection) {
Utils.UpdateConnection(connection);
ConnectionUpdated?.Invoke(connection);
}

public static void RaiseExternalSourceSeen(SubathonEventSource source) {
ExternalSourceSeen?.Invoke(source);
}

public static void RaiseFourthWallMembershipsSynced(Dictionary<string, string> synced) {
FourthWallMembershipsSynced?.Invoke(synced);
}
Expand Down
12 changes: 12 additions & 0 deletions SubathonManager.Core/Events/ScheduleEvents.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System.Diagnostics.CodeAnalysis;

namespace SubathonManager.Core.Events;

[ExcludeFromCodeCoverage]
public static class ScheduleEvents {
public static event Action<object?>? ScheduleChanged;

public static void RaiseScheduleChanged(object? source) {
ScheduleChanged?.Invoke(source);
}
}
5 changes: 5 additions & 0 deletions SubathonManager.Core/Events/SubathonEvents.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public static event Action<SubathonEvent, bool>?
SubathonEventProcessed; // Run through queue, processed or not to subathon

public static event Action<List<SubathonEvent>>? SubathonEventsDeleted;
public static event Action<Guid, SubathonEventType, string>? SubathonEventCancelled;
public static event Action<SubathonData, DateTime>? SubathonDataUpdate;

public static event Action<List<SubathonGoal>, long, GoalsType>? SubathonGoalListUpdated;
Expand Down Expand Up @@ -77,6 +78,10 @@ public static void RaiseSubathonEventsDeleted(List<SubathonEvent> subathonEvent)
SubathonEventsDeleted?.Invoke(subathonEvent);
}

public static void RaiseSubathonEventCancelled(Guid id, SubathonEventType type, string reference) {
SubathonEventCancelled?.Invoke(id, type, reference);
}

public static void RaiseSubathonEventCreated(SubathonEvent subathonEvent) {
SubathonEventCreated?.Invoke(subathonEvent);
}
Expand Down
Loading
Loading