Conversation
…alization (#115, #131, #167, #238, #242, #251, #254, #255, #259) FASTER/Models/ArmaMod.cs, FASTER/Models/SteamWebApi.cs - #167: Show one-time warning after 3 failed retries if Steam API Key is invalid; check response.IsSuccessStatusCode in ApiCall() so errors propagate to retry logic with a meaningful reason FASTER/Models/BasicCfg.cs - #251/#115: PerfPreset getter always returns "Custom" so JSON deserialization called the setter and reset MaxMsgSend to 256 on every profile clone; fixed with [Newtonsoft.Json.JsonIgnore] FASTER/ViewModel/DeploymentViewModel.cs - #254: LinkMod/DeleteLink called Directory.Delete(path, true) on symlinks, which destroyed the source mod folder; now checks FileAttributes.ReparsePoint - #131: DeployAll() crashed when InstallPath didn't exist; added guard + user-facing error message; added UnauthorizedAccessException handler with Developer Mode / run-as-Admin guidance FASTER/ViewModel/SteamUpdaterViewModel.cs - #242: mod.Status was set to NotComplete in the early cancellation path before any download started - #259: Task.Factory.StartNew(async ()=>) returns Task<Task>; missing .Unwrap() caused ContinueWith to fire instantly instead of after async work; converted lambda to async + await, added .Unwrap() - #238: NullReferenceException accessing SteamClient.Credentials.Username after SteamClient was nulled; save username before disposal Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
FASTER/Models/ServerCfg.cs - #246: Wrap LogObjectNotFound, SkipDescriptionParsing, ignoreMissionLoadErrors inside a class AdvancedOptions { }; block in server.cfg output FASTER/Models/BasicCfg.cs - #230: Add configurable language setting (default "English") with RaisePropertyChanged; replace hardcoded language="English" in ProcessFile() FASTER/Models/ServerProfile.cs - #231: Add HugePages (bool), BePath (string), ExThreads (int 0-7), LoadMissionToMemory (bool), LimitFPS (int), EnableSteamLogs (bool) properties with conditional inclusion in GetCommandLine() FASTER/ViewModel/ProfileViewModel.cs - #230: Expose Languages observable collection from BasicCfgArrays - #231: Add SelectBePath() folder picker FASTER/Views/Profile.xaml, FASTER/Views/Profile.xaml.cs - #230: Language ComboBox in Performance tab - #231: Controls for HugePages, BePath, ExThreads, LoadMissionToMemory, LimitFPS, EnableSteamLogs FASTER/ViewModel/ModsViewModel.cs, FASTER/Views/Mods.xaml, FASTER/Views/Mods.xaml.cs - #198: Add PurgeAndReinstallMod(), PurgeAndReinstallSelectedMods(), PurgeAndReinstallAll() — delete mod folder and mark for re-download - #258: Make CheckForUpdates() async with 300ms delay between mods to avoid Steam rate limiting Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…reorder, purge unused mods (#209, #216, #217, #229, #241) FASTER/Models/ServerCfg.cs - #217: Add AntiFlood settings block (enabled, cycleTime, cycleLimit, cycleHardLimit, enableKick) output in server.cfg under class AntiFlood {} - #229: Add missionHTTPDownloadBaseURL setting with conditional output FASTER/Models/ServerProfile.cs - #241: Add KeysFolder property with -keysFolder="..." in GetCommandLine() - #216: Add MoveProfileUp()/MoveProfileDown() for profile list reordering FASTER/ViewModel/ProfileViewModel.cs - #241: Add SelectKeysFolder() folder picker FASTER/Views/Profile.xaml, FASTER/Views/Profile.xaml.cs - #217: AntiFlood Expander with CheckBox + 3 NumericUpDowns + kick CheckBox - #229: TextBox for MissionHTTPDownloadBaseURL in missions section - #241: KeysFolder TextBox + folder browse button FASTER/MainWindow.xaml.cs - #216: Wrap each profile toggle in a DockPanel with ▲/▼ reorder buttons; add GetProfileToggleButtons() and GetSelectedProfileToggleButton() helpers FASTER/ViewModel/ModsViewModel.cs, FASTER/Views/Mods.xaml, FASTER/Views/Mods.xaml.cs - #209: Add PurgeUnusedMods() — cross-reference all profiles, prompt confirmation, delete mod folders not referenced by any profile Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
FASTER/Models/Logger.cs (new) - Static Logger class: writes timestamped entries to %AppData%\FASTER\faster.log when enableDebugLog setting is true FASTER/Properties/Settings.settings, FASTER/Properties/Settings.Designer.cs - Add enableDebugLog boolean setting (default: false) FASTER/Views/Settings.xaml, FASTER/Views/Settings.xaml.cs - Add "Enable Debug Logging" checkbox and "Open Log File" button in the Program Settings panel FASTER/ViewModel/ModsViewModel.cs - Log calls in CheckForUpdates (per-mod), PurgeAndReinstallMod (path + delete result), PurgeAndReinstallAll (staging dir, each deleted folder, each reset mod) FASTER/ViewModel/DeploymentViewModel.cs - Log calls in DeployAll (install path, each mod link), LinkMod (symlink creation, reparse point check, errors with detail) FASTER/ViewModel/SteamUpdaterViewModel.cs - Log calls in SteamLogin (each step, errors with stack trace), RunModsUpdater (login result, per-mod task start/end), DownloadForMultiple (SetupAsync/VerifyAsync/DownloadAsync steps, file verification events, exceptions with full stack traces) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…se (#239) .github/workflows/codeql-analysis.yml, .github/workflows/release.yml - #239: Add missing DOTNET_VERSION: '8.0.x' env var (was referenced by actions/setup-dotnet but never defined, causing workflow failures) .github/workflows/build.yml (new) - Add standalone build workflow that triggers on push/PR to master for fast build verification without depending on CodeQL .github/workflows/release.yml - Add permissions: contents: write to release job (required for GITHUB_TOKEN to create releases on forks) - Replace unmaintained andelf/nightly-release@main with softprops/action-gh-release@v2 - Add pre-step to delete existing nightly release + tag before recreating - Handle empty changelog gracefully (exit 0 instead of exit 1 when no tags) - Truncate changelog to 20k chars to avoid env var size limit (32766 max) global.json - Change rollForward from latestFeature to latestMajor so builds succeed with .NET SDK versions newer than 8.0.0 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
SonarCloud rule S2696 flags writing to static fields from instance methods. Extracted _apiKeyWarningShown write into TryShowApiKeyWarning() static method so the field is only accessed from static context. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
FASTER/Models/ServerProfile.cs - S2365: FilteredProfileMods returned new List<>(_profileMods) copying the collection; changed return type to IReadOnlyList<ProfileMod> and return _profileMods.AsReadOnly() to avoid the copy FASTER/Views/Mods.xaml.cs - CS8602/SonarCloud: await on nullable Task (from ?. operator) can throw NullReferenceException when DataContext is null; replaced with 'if (DataContext is ModsViewModel vm) await vm.Method()' pattern for CheckForUpdates_Click, PurgeAndReinstallAll_Click, PurgeUnusedMods_Click Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ash logging FASTER/Models/SteamWebApi.cs - S2699: Replace throw new Exception() with throw new HttpRequestException() so callers can catch a specific type instead of base Exception FASTER/ViewModel/SteamUpdaterViewModel.cs - S3776: Extract inner async lambda from RunModsUpdater into ProcessModDownloadAsync(ArmaMod mod) private method, reducing cognitive complexity from 36 to well below the 25 limit FASTER/App.xaml.cs - Add AppDomain.UnhandledException, DispatcherUnhandledException and TaskScheduler.UnobservedTaskException handlers that write to the debug log file — captures silent fatal crashes (e.g. native exceptions from BytexDigital.Steam during DownloadAsync) that bypass try/catch Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fix for Performance preset for server profiles not copied over
#PR1 bug fixes
#PR2 Community-PRs
#PR3 Features
#PR4 Debug Logging
#PR5 CI/CD
Outer try block had no catch/finally and referenced an out-of-scope `ex` variable. Replaced the stray IsAnonymous check with a proper catch block to restore error logging without changing other logic.
Reformat DownloadModAsync and DownloadModContentAsync for consistent indentation and block grouping, and tidy related logging/messages. Also replace the null-conditional access to savedUsername (SteamClient?.Credentials.Username) with direct access (SteamClient.Credentials.Username). No functional changes intended beyond formatting and this direct credential lookup.
Replace comparisons like 'IsChecked == true' with 'IsChecked.GetValueOrDefault()' in MainWindow.xaml.cs. This handles nullable IsChecked values explicitly (treating null as false), removes redundant equality checks, and eliminates nullable-related warnings.
This change adds bounded log growth to the app logger by rotating faster.log to faster.log.old when it exceeds 10 MB. The old backup is replaced with the newest rollover, keeping total on-disk log usage capped. It also adds NUnit coverage for both rotation and non-rotation cases to ensure the logging behavior is stable.
Delete FASTERTests/Models/LoggerTests.cs due to unable to access settings from Tests. Will work on adding it back in when i can
The release workflow now appends a warning when changelog output is truncated to stay under environment variable limits, while pointing users to the full commit history. This keeps release notes readable without losing context, and includes minor alignment cleanup in the workflow variables.
Adds a nullable annotation to the PropertyChanged event in ArmaMod to satisfy C# nullability checks and avoid warnings.
Update various model and view-model event declarations to use nullable `PropertyChangedEventHandler` annotations where appropriate. Also prevents nullable reference warnings in C# builds.
Key Features AddedAntiFlood settings: cycle time, limit, hard limit, enable kick Critical FixesSymlink recursive-delete data-loss risk Code QualitySonarCloud static analysis fixes (8 issues resolved) Community ContributionsIntegrates 11 community pull requests (#198, #230, #231, #246, #252, #258, #261, #262, #263, #264, #265) Core Changes
A lightweight, opt-in logging framework: New Logger static class that logs to %APPDATA%/FASTER/faster.log with 10 MB rotation Rationale: Enables troubleshooting in production without verbose console output; essential for distributed server deployments.
Support for Arma's flood mitigation): Five new server config properties: AntiFloodEnabled, AntiFloodCycleTime, AntiFloodCycleLimit, AntiFloodCycleHardLimit, AntiFloodEnableKick Rationale: Allows server operators to tune anti-flood behavior per profile, addressing community requests.
Three new operations in the Mods UI: Deletes all mod folders in staging directory Purge & Reinstall Selected Context menu option: right-click mods → "Purge & Reinstall" Purge Unused Mods Scans profiles to find mods not assigned to any server Rationale: Addresses mod corruption/partial-download issues without manual file system operations. Other ChangesCritical Bug Fixes
Code Quality & Refactoring
New Server Profile OptionsCommand-line flag support added to -
UI/UX ImprovementsPerformance tab scrolling: Wrapped Performance Settings in to prevent overflow Merge Readiness and Risk AssessmentStatus: Ready to merge with minor observations Code quality: Solid. Refactoring is conservative and well-motivated. Error handling is comprehensive. Breaking Changes & Compatibility AnalysisThe PR is fully backward-compatible. New features are optional and disabled by default. Existing profiles and deployments will continue to work without modification. 1. Symlink Deletion SafetyThe Data-Loss Risk & The Fix Problem (Previous Behavior): The original code naively called How It Works: Symlinks: FileAttributes.ReparsePoint detects symlinks. Deleting a symlink with recursive=false removes only the symlink, not the target Migration Impact: ✅ None Existing symlinks work unchanged; this just makes deletion safer 2. Advanced Options Refactoring (ServerCfg)Cosmetic Config Change (lines 964–965, ServerCfg.cs): Migration Impact:
Summary: Backward Compatibility
|
Replace floating action versions with exact commit SHAs for reproducible CI. Updated .github/workflows/publish.yml to use vedantmgoyal9/winget-releaser@4ffc7888... and .github/workflows/release.yml to use kzrnm/get-net-sdk-project-versions-action@c33b25a7.... This pins the actions to known commits while keeping existing settings (identifier, installers-regex, proj-path) unchanged.
- Bump kzrnm/get-net-sdk-project-versions-action to v3.1.0 - Bump softprops/action-gh-release to v3.0.3 for both the tagged and nightly release steps (was on v2.6.2, now unmaintained) - Replace archived actions/create-release@v1 and actions/upload-release-asset@v1 with softprops/action-gh-release, which now handles both release creation and asset upload in one step for tagged releases too - Fix vedantmgoyal2009/winget-releaser reference to the maintainer's current repo (vedantmgoyal9/winget-releaser) after their GitHub username change; pinned to commit SHA instead of floating @v2 All actions pinned to verified commit SHAs (confirmed via git ls-remote) per SonarCloud's supply-chain security rule.
Update the Autoupdater.NET.Official package reference from 1.9.2 to 1.9.3 to pull in the latest upstream fixes and improvements.
Adds a Dependabot configuration to monitor GitHub Actions dependencies
Updates the Dependabot workflow to run GitHub Actions checks on a monthly schedule and adds NuGet package monitoring for the Faster project. This also adds CI labeling for action updates and clearer dependency grouping for both ecosystems.
Refresh the bug report issue template to use the current FASTER version example (1.9g) instead of the older 1.8b value.
The SteamCMD automation section now includes the Arma 3 Performance branch alongside Stable and DLCs, keeping the documentation aligned with the supported server install and update options.
This change updates the Dependabot workflow to check for GitHub Actions and NuGet updates weekly instead of monthly, on Mondays. It also removes the `ci` label from GitHub Actions dependency PRs to keep the labeling aligned with the current workflow.
Update the Azure DevOps pipeline to current tooling and CI practices. This includes switching to Windows 2022, restoring/building the solution with .NET 8, checking out submodules, replacing legacy SonarCloud tasks with v4, running tests with coverage, and publishing pipeline artifacts with the newer task syntax.
This change groups minor and patch updates for both GitHub Actions and NuGet in Dependabot, reducing PR noise from routine dependency bumps. It also updates the NuGet package directory to the repository root while keeping the existing labels and commit-message prefixes intact.
|
| feedsToUse: 'select' | ||
|
|
||
| - task: SonarCloudPrepare@1 | ||
| - task: SonarCloudPrepare@4 |
| projects: 'FASTERTests/FASTERTests.csproj' | ||
| arguments: '--configuration $(buildConfiguration) --no-restore --no-build --collect:"Code Coverage"' | ||
|
|
||
| - task: SonarCloudAnalyze@4 |
|
|
||
| - task: SonarCloudAnalyze@4 | ||
|
|
||
| - task: SonarCloudPublish@4 |
|
i swear ive never needed to pin so many versions like what the heck sonar |




Description
This release brings
AntiFloodserver configuration, anin-app debug logging system,mod purge/reinstall tooling, several critical bug fixes, and integrates a number of community-contributed pull requests.Motivation and Context
Consolidates a large batch of accumulated improvements on the
feature/Update-1.9branch, including fixes for symlink handling, async deadlocks, and NullReferenceExceptions that could affect mod downloads and deployment, alongside new profile settings requested by the community.How Has This Been Tested?
Built and run locally via Visual Studio; manually verified mod purge/reinstall flows, AntiFlood settings persistence, debug log toggle and log file viewer, and Performance tab scrolling. CI build/CodeQL workflows updated and passing.
Screenshots (if appropriate):
Types of changes
Checklist:
Highlights
AntiFlood (cycle time/limit/hard limit/enable kick),missionHTTPDownloadBaseURL,keysFolder,bePath,hugePages,loadMissionToMemory,enableSteamLogs,limitFPS,exThreadsS2696,S2365,S2699,S3237,S2259,S7637,S1125,S1135)Community contributions
Includes and integrates PRs #198, #230, #231, #246, #252, #258, #261, #262, #263, #264, #265
Huge thanks to @diaversoand @YetheSamartaka
Checklist for document updates: