├── images
└── manager-sc.png
├── SIT.Manager
├── Assets
│ ├── bg3.png
│ ├── sit-logo-5.png
│ ├── StayInTarkov.jpg
│ ├── Stay-In-Tarkov-512.ico
│ ├── Stay-In-Tarkov-512.png
│ └── SIT_server_240329_v2.png
├── Resources
│ ├── Aki.Common.dll
│ └── Aki.Reflection.dll
├── Exceptions
│ ├── AccountNotFoundException.cs
│ ├── TarkovException.cs
│ ├── IncorrectAccountPasswordException.cs
│ └── UsernameTakenException.cs
├── Models
│ ├── PageNavigation.cs
│ ├── Mirrors.cs
│ ├── Location
│ │ ├── Props.cs
│ │ ├── MaxItemCountInLocation.cs
│ │ ├── Banner.cs
│ │ ├── NonWaveGroupScenario.cs
│ │ ├── Bundle.cs
│ │ ├── Support.cs
│ │ ├── ColliderParams.cs
│ │ ├── MinMaxBot.cs
│ │ ├── MatchMakerMinPlayersByWaitTime.cs
│ │ ├── Position.cs
│ │ ├── BotLocationModifier.cs
│ │ ├── SpawnPointParam.cs
│ │ ├── AirdropParameter.cs
│ │ ├── Exit.cs
│ │ ├── Wave.cs
│ │ └── BossLocationSpawn.cs
│ ├── BarNotification.cs
│ ├── NavigationItem.cs
│ ├── Play
│ │ ├── DeleteServerMessage.cs
│ │ ├── ConnectedServerRequestMessage.cs
│ │ ├── CreateServerDialogResult.cs
│ │ ├── ServerConnectMessage.cs
│ │ ├── ServerDisconnectMessage.cs
│ │ ├── CreateCharacterDialogResult.cs
│ │ └── TarkovLaunchConfig.cs
│ ├── Installation
│ │ ├── InstallProcessStateRequestMessage.cs
│ │ ├── RequestedInstallOperation.cs
│ │ ├── InstallStep.cs
│ │ ├── InstallProcessStateChangedMessage.cs
│ │ ├── ProgressInstallMessage.cs
│ │ ├── InstallationRunningMessage.cs
│ │ ├── SitInstallVersion.cs
│ │ └── InstallProcessState.cs
│ ├── Messages
│ │ └── PageNavigationMessage.cs
│ ├── ValidationRule.cs
│ ├── TarkovEdition.cs
│ ├── ActionNotification.cs
│ ├── ConsoleText.cs
│ ├── Aki
│ │ ├── AkiServerInfo.cs
│ │ ├── AkiServer.cs
│ │ ├── AkiCharacter.cs
│ │ └── AkiMiniProfile.cs
│ ├── DiagnosticsOptions.cs
│ ├── Gitea
│ │ ├── GiteaAsset.cs
│ │ ├── GiteaRelease.cs
│ │ └── GiteaAuthor.cs
│ ├── ModInfo.cs
│ ├── Tools
│ │ └── PortCheckerResponse.cs
│ ├── Github
│ │ ├── GithubAsset.cs
│ │ ├── GithubAuthor.cs
│ │ ├── GithubUploader.cs
│ │ └── GithubRelease.cs
│ └── Config
│ │ ├── LinuxConfig.cs
│ │ └── ManagerConfig.cs
├── Services
│ ├── Caching
│ │ ├── EvictedEventArgs.cs
│ │ ├── CachingService.cs
│ │ ├── CacheValue.cs
│ │ ├── ICachingProvider.cs
│ │ ├── CacheEntry.cs
│ │ └── InMemoryCachingProvider.cs
│ ├── ActionNotificationService.cs
│ ├── BarNotificationService.cs
│ ├── Install
│ │ └── EFTGameFinder.cs
│ ├── PickerDialogService.cs
│ ├── ManagedProcesses
│ │ └── ManagedProcess.cs
│ └── ManagerConfigService.cs
├── Interfaces
│ ├── ICachingService.cs
│ ├── IManagerConfigService.cs
│ ├── IActionNotificationService.cs
│ ├── IDiagnosticService.cs
│ ├── ManagedProcesses
│ │ ├── IManagedProcess.cs
│ │ ├── IAkiServerService.cs
│ │ └── ITarkovClientService.cs
│ ├── IAppUpdaterService.cs
│ ├── IPickerDialogService.cs
│ ├── IVersionService.cs
│ ├── IBarNotificationService.cs
│ ├── IAkiServerRequestingService.cs
│ ├── ILocalizationService.cs
│ ├── IFileService.cs
│ └── IModService.cs
├── ViewModels
│ ├── SettingsPageViewModel.cs
│ ├── Dialogs
│ │ └── SelectLogsDialogViewModel.cs
│ ├── CrashWindowViewModel.cs
│ ├── Play
│ │ ├── LoginDialogViewModel.cs
│ │ ├── CreateCharacterDialogViewModel.cs
│ │ └── CreateServerDialogViewModel.cs
│ ├── ToolsPageViewModel.cs
│ ├── Installation
│ │ ├── CompleteViewModel.cs
│ │ └── InstallationViewModelBase.cs
│ ├── UpdatePageViewModel.cs
│ ├── Settings
│ │ ├── SettingsViewModelBase.cs
│ │ ├── SptAkiViewModel.cs
│ │ ├── EftViewModel.cs
│ │ └── LinuxViewModel.cs
│ └── PlayPageViewModel.cs
├── Views
│ ├── Play
│ │ ├── ServerSummaryView.axaml.cs
│ │ ├── CharacterSummaryView.axaml.cs
│ │ ├── ServerSelectionView.axaml.cs
│ │ ├── CharacterSelectionView.axaml.cs
│ │ ├── DirectConnectView.axaml.cs
│ │ ├── LoginDialogView.axaml.cs
│ │ ├── CreateCharacterDialogView.axaml.cs
│ │ ├── CreateServerDialogView.axaml.cs
│ │ ├── CreateServerDialogView.axaml
│ │ ├── LoginDialogView.axaml
│ │ ├── CreateCharacterDialogView.axaml
│ │ ├── ServerSelectionView.axaml
│ │ ├── CharacterSelectionView.axaml
│ │ └── CharacterSummaryView.axaml
│ ├── CrashWindow.axaml.cs
│ ├── ToolsPage.axaml.cs
│ ├── MainView.axaml.cs
│ ├── ModsPage.axaml.cs
│ ├── PlayPage.axaml.cs
│ ├── SettingsPage.axaml.cs
│ ├── UpdatePage.axaml.cs
│ ├── InstallPage.axaml.cs
│ ├── Settings
│ │ ├── EftView.axaml.cs
│ │ ├── LinuxView.axaml.cs
│ │ ├── SptAkiView.axaml.cs
│ │ ├── LauncherView.axaml.cs
│ │ ├── LauncherView.axaml
│ │ └── SptAkiView.axaml
│ ├── LocationEditorView.axaml.cs
│ ├── Tools
│ │ ├── GeneralToolsView.axaml.cs
│ │ └── NetworkToolsView.axaml.cs
│ ├── Installation
│ │ ├── CompleteView.axaml.cs
│ │ ├── PatchView.axaml.cs
│ │ ├── SelectView.axaml.cs
│ │ ├── InstallView.axaml.cs
│ │ ├── ConfigureSitView.axaml.cs
│ │ ├── ConfigureServerView.axaml.cs
│ │ ├── CompleteView.axaml
│ │ └── InstallView.axaml
│ ├── Dialogs
│ │ ├── SelectLogsDialog.axaml.cs
│ │ └── SelectLogsDialog.axaml
│ ├── ToolsPage.axaml
│ ├── MainWindow.axaml
│ ├── PlayPage.axaml
│ ├── SettingsPage.axaml
│ ├── CrashWindow.axaml
│ ├── ServerPage.axaml.cs
│ ├── MainWindow.axaml.cs
│ ├── InstallPage.axaml
│ └── UpdatePage.axaml
├── CrashApp.axaml.cs
├── Theme
│ ├── Assists
│ │ └── Observable.cs
│ ├── Styles
│ │ ├── SelectableTextBlock.axaml
│ │ ├── Border.axaml
│ │ ├── TextBlock.axaml
│ │ └── Button.axaml
│ ├── Controls
│ │ ├── Card.axaml.cs
│ │ ├── ActivatableUserControl.cs
│ │ ├── LoadingSpinner.axaml.cs
│ │ ├── LoadingSpinner.axaml
│ │ └── Card.axaml
│ ├── Theme.axaml
│ └── Palette.axaml
├── Native
│ ├── Linux
│ │ ├── Managers
│ │ │ ├── Vkd3DManager.cs
│ │ │ ├── DxvkManager.cs
│ │ │ ├── Dgvoodoo2Manager.cs
│ │ │ ├── DxvkNvapiManager.cs
│ │ │ └── D3DExtrasManager.cs
│ │ └── DllManager.cs
│ └── Windows
│ │ └── WindowsApi.cs
├── Extentions
│ ├── ObservableCollectionExtentions.cs
│ ├── HttpClientExtentions.cs
│ └── StreamExtensions.cs
├── CrashApp.axaml
├── Converters
│ └── ColorJsonConverter.cs
└── App.axaml
├── Directory.Build.props
├── SIT.Manager.Desktop
├── Properties
│ └── launchSettings.json
├── AssemblyInfo.cs
├── appsettings.json
├── app.manifest
├── Program.cs
└── SIT.Manager.Desktop.csproj
├── LICENSE
├── .github
└── workflows
│ ├── dotnet-desktop.yml
│ └── Create-Release.yml
├── SIT.Manager.sln
└── .gitattributes
/images/manager-sc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stayintarkov/SIT.Manager.Avalonia/HEAD/images/manager-sc.png
--------------------------------------------------------------------------------
/SIT.Manager/Assets/bg3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stayintarkov/SIT.Manager.Avalonia/HEAD/SIT.Manager/Assets/bg3.png
--------------------------------------------------------------------------------
/SIT.Manager/Assets/sit-logo-5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stayintarkov/SIT.Manager.Avalonia/HEAD/SIT.Manager/Assets/sit-logo-5.png
--------------------------------------------------------------------------------
/SIT.Manager/Assets/StayInTarkov.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stayintarkov/SIT.Manager.Avalonia/HEAD/SIT.Manager/Assets/StayInTarkov.jpg
--------------------------------------------------------------------------------
/SIT.Manager/Resources/Aki.Common.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stayintarkov/SIT.Manager.Avalonia/HEAD/SIT.Manager/Resources/Aki.Common.dll
--------------------------------------------------------------------------------
/SIT.Manager/Assets/Stay-In-Tarkov-512.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stayintarkov/SIT.Manager.Avalonia/HEAD/SIT.Manager/Assets/Stay-In-Tarkov-512.ico
--------------------------------------------------------------------------------
/SIT.Manager/Assets/Stay-In-Tarkov-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stayintarkov/SIT.Manager.Avalonia/HEAD/SIT.Manager/Assets/Stay-In-Tarkov-512.png
--------------------------------------------------------------------------------
/SIT.Manager/Resources/Aki.Reflection.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stayintarkov/SIT.Manager.Avalonia/HEAD/SIT.Manager/Resources/Aki.Reflection.dll
--------------------------------------------------------------------------------
/SIT.Manager/Assets/SIT_server_240329_v2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stayintarkov/SIT.Manager.Avalonia/HEAD/SIT.Manager/Assets/SIT_server_240329_v2.png
--------------------------------------------------------------------------------
/SIT.Manager/Exceptions/AccountNotFoundException.cs:
--------------------------------------------------------------------------------
1 | namespace SIT.Manager.Exceptions;
2 |
3 | public class AccountNotFoundException : TarkovException
4 | {
5 | }
6 |
--------------------------------------------------------------------------------
/SIT.Manager/Exceptions/TarkovException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace SIT.Manager.Exceptions;
4 |
5 | public class TarkovException : Exception
6 | {
7 | }
8 |
--------------------------------------------------------------------------------
/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 | enable
4 | 11.0.2
5 |
6 |
7 |
--------------------------------------------------------------------------------
/SIT.Manager/Exceptions/IncorrectAccountPasswordException.cs:
--------------------------------------------------------------------------------
1 | namespace SIT.Manager.Exceptions;
2 |
3 | public class IncorrectAccountPasswordException : TarkovException
4 | {
5 | }
6 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/PageNavigation.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace SIT.Manager.Models;
4 |
5 | public record PageNavigation(Type TargetPage, bool SuppressTransition = false);
6 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/Mirrors.cs:
--------------------------------------------------------------------------------
1 | namespace SIT.Manager.Models;
2 |
3 | public class Mirrors
4 | {
5 | public string Link { get; set; }
6 | public string Hash { get; set; }
7 | }
8 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/Location/Props.cs:
--------------------------------------------------------------------------------
1 | namespace SIT.Manager.Models.Location;
2 |
3 | public class Props
4 | {
5 | public Position? Center { get; set; }
6 | public double Radius { get; set; }
7 | }
8 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/BarNotification.cs:
--------------------------------------------------------------------------------
1 | using FluentAvalonia.UI.Controls;
2 |
3 | namespace SIT.Manager.Models;
4 |
5 | public record BarNotification(string Title, string Message, InfoBarSeverity Severity, int Delay);
6 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/Location/MaxItemCountInLocation.cs:
--------------------------------------------------------------------------------
1 | namespace SIT.Manager.Models.Location;
2 |
3 | public class MaxItemCountInLocation
4 | {
5 | public string? TemplateId { get; set; }
6 | public int Value { get; set; }
7 | }
8 |
--------------------------------------------------------------------------------
/SIT.Manager/Services/Caching/EvictedEventArgs.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace SIT.Manager.Services.Caching;
4 |
5 | public class EvictedEventArgs(string key) : EventArgs
6 | {
7 | public string Key { get; private set; } = key;
8 | }
9 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/NavigationItem.cs:
--------------------------------------------------------------------------------
1 | using FluentAvalonia.UI.Controls;
2 | using System;
3 |
4 | namespace SIT.Manager.Models;
5 |
6 | public record NavigationItem(string Name, string ToolTip, Symbol Icon, Type NavigationTarget, string? Tag = null);
7 |
--------------------------------------------------------------------------------
/SIT.Manager.Desktop/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "profiles": {
3 | "SIT.Manager.Desktop": {
4 | "commandName": "Project"
5 | },
6 | "WSL": {
7 | "commandName": "WSL2",
8 | "distributionName": ""
9 | }
10 | }
11 | }
--------------------------------------------------------------------------------
/SIT.Manager/Models/Play/DeleteServerMessage.cs:
--------------------------------------------------------------------------------
1 | using CommunityToolkit.Mvvm.Messaging.Messages;
2 | using System;
3 |
4 | namespace SIT.Manager.Models.Play;
5 |
6 | public class DeleteServerMessage(Uri serverUri) : ValueChangedMessage(serverUri)
7 | {
8 | }
9 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/Installation/InstallProcessStateRequestMessage.cs:
--------------------------------------------------------------------------------
1 | using CommunityToolkit.Mvvm.Messaging.Messages;
2 |
3 | namespace SIT.Manager.Models.Installation;
4 |
5 | public class InstallProcessStateRequestMessage : RequestMessage
6 | {
7 | }
8 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/Installation/RequestedInstallOperation.cs:
--------------------------------------------------------------------------------
1 | namespace SIT.Manager.Models.Installation;
2 |
3 | public enum RequestedInstallOperation
4 | {
5 | None,
6 | InstallSit,
7 | InstallServer,
8 | UpdateSit,
9 | UpdateServer
10 | }
11 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/Play/ConnectedServerRequestMessage.cs:
--------------------------------------------------------------------------------
1 | using CommunityToolkit.Mvvm.Messaging.Messages;
2 | using SIT.Manager.Models.Aki;
3 |
4 | namespace SIT.Manager.Models.Play;
5 |
6 | public class ConnectedServerRequestMessage : RequestMessage
7 | {
8 | }
9 |
--------------------------------------------------------------------------------
/SIT.Manager/Interfaces/ICachingService.cs:
--------------------------------------------------------------------------------
1 | using SIT.Manager.Services.Caching;
2 |
3 | namespace SIT.Manager.Interfaces;
4 |
5 | public interface ICachingService
6 | {
7 | public ICachingProvider InMemory { get; }
8 | public ICachingProvider OnDisk { get; }
9 | }
10 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/Play/CreateServerDialogResult.cs:
--------------------------------------------------------------------------------
1 | using FluentAvalonia.UI.Controls;
2 | using System;
3 |
4 | namespace SIT.Manager.Models.Play;
5 |
6 | public record CreateServerDialogResult(ContentDialogResult DialogResult,
7 | Uri ServerUri,
8 | string ServerNickname);
9 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/Messages/PageNavigationMessage.cs:
--------------------------------------------------------------------------------
1 | using CommunityToolkit.Mvvm.Messaging.Messages;
2 |
3 | namespace SIT.Manager.Models.Messages;
4 |
5 | public class PageNavigationMessage(PageNavigation pageNavigation) : ValueChangedMessage(pageNavigation)
6 | {
7 | }
8 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/Play/ServerConnectMessage.cs:
--------------------------------------------------------------------------------
1 | using CommunityToolkit.Mvvm.Messaging.Messages;
2 | using SIT.Manager.Models.Aki;
3 |
4 | namespace SIT.Manager.Models.Play;
5 |
6 | public class ServerConnectMessage(AkiServer server) : ValueChangedMessage(server)
7 | {
8 | }
9 |
--------------------------------------------------------------------------------
/SIT.Manager/ViewModels/SettingsPageViewModel.cs:
--------------------------------------------------------------------------------
1 | using CommunityToolkit.Mvvm.ComponentModel;
2 |
3 | namespace SIT.Manager.ViewModels;
4 |
5 | public partial class SettingsPageViewModel : ObservableObject
6 | {
7 | public SettingsPageViewModel()
8 | {
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/Play/ServerDisconnectMessage.cs:
--------------------------------------------------------------------------------
1 | using CommunityToolkit.Mvvm.Messaging.Messages;
2 | using SIT.Manager.Models.Aki;
3 |
4 | namespace SIT.Manager.Models.Play;
5 |
6 | public class ServerDisconnectMessage(AkiServer server) : ValueChangedMessage(server)
7 | {
8 | }
9 |
--------------------------------------------------------------------------------
/SIT.Manager/Exceptions/UsernameTakenException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace SIT.Manager.Exceptions;
8 | public class UsernameTakenException : Exception
9 | {
10 | }
11 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/Installation/InstallStep.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace SIT.Manager.Models.Installation;
4 |
5 | public class InstallStep(Type installView, string header)
6 | {
7 | public Type InstallationView { get; } = installView;
8 | public string Header { get; } = header;
9 | }
10 |
--------------------------------------------------------------------------------
/SIT.Manager/Views/Play/ServerSummaryView.axaml.cs:
--------------------------------------------------------------------------------
1 | using SIT.Manager.Theme.Controls;
2 |
3 | namespace SIT.Manager.Views.Play;
4 |
5 | public partial class ServerSummaryView : ActivatableUserControl
6 | {
7 | public ServerSummaryView()
8 | {
9 | InitializeComponent();
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/Location/Banner.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json.Serialization;
2 |
3 | namespace SIT.Manager.Models.Location;
4 |
5 | public class Banner
6 | {
7 | [JsonPropertyName("id")]
8 | public string? Id { get; set; }
9 | [JsonPropertyName("pic")]
10 | public Bundle? Pic { get; set; }
11 | }
12 |
--------------------------------------------------------------------------------
/SIT.Manager/Views/Play/CharacterSummaryView.axaml.cs:
--------------------------------------------------------------------------------
1 | using SIT.Manager.Theme.Controls;
2 |
3 | namespace SIT.Manager.Views.Play;
4 |
5 | public partial class CharacterSummaryView : ActivatableUserControl
6 | {
7 | public CharacterSummaryView()
8 | {
9 | InitializeComponent();
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/Location/NonWaveGroupScenario.cs:
--------------------------------------------------------------------------------
1 | namespace SIT.Manager.Models.Location;
2 |
3 | public class NonWaveGroupScenario
4 | {
5 | public int Chance { get; set; }
6 | public bool Enabled { get; set; }
7 | public int MaxToBeGroup { get; set; }
8 | public int MinToBeGroup { get; set; }
9 | }
10 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/ValidationRule.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace SIT.Manager.Models;
4 |
5 | public class ValidationRule
6 | {
7 | public string Name { get; init; } = string.Empty;
8 | public Func? Check { get; init; } = null;
9 | public string ErrorMessage { get; init; } = string.Empty;
10 | }
11 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/Location/Bundle.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json.Serialization;
2 |
3 | namespace SIT.Manager.Models.Location;
4 |
5 | public class Bundle
6 | {
7 | [JsonPropertyName("path")]
8 | public string? Path { get; set; }
9 | [JsonPropertyName("rcid")]
10 | public string? Rcid { get; set; }
11 | }
12 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/Play/CreateCharacterDialogResult.cs:
--------------------------------------------------------------------------------
1 | using FluentAvalonia.UI.Controls;
2 |
3 | namespace SIT.Manager.Models.Play;
4 |
5 | public record CreateCharacterDialogResult(ContentDialogResult DialogResult,
6 | string Username,
7 | string Password,
8 | bool SaveLogin,
9 | TarkovEdition TarkovEdition);
10 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/Installation/InstallProcessStateChangedMessage.cs:
--------------------------------------------------------------------------------
1 | using CommunityToolkit.Mvvm.Messaging.Messages;
2 |
3 | namespace SIT.Manager.Models.Installation;
4 |
5 | public class InstallProcessStateChangedMessage(InstallProcessState installProcessState) : ValueChangedMessage(installProcessState)
6 | {
7 | }
8 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/Location/Support.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace SIT.Manager.Models.Location;
4 |
5 | public class Support
6 | {
7 | public string? BossEscortAmount { get; set; }
8 | public List? BossEscortDifficult { get; set; }
9 | public string? BossEscortType { get; set; }
10 | }
11 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/TarkovEdition.cs:
--------------------------------------------------------------------------------
1 | namespace SIT.Manager.Models;
2 |
3 | public struct TarkovEdition(string edition, string? description = null)
4 | {
5 | private readonly string _description = description ?? string.Empty;
6 | public string Edition { get; } = edition;
7 | public readonly string Description => _description;
8 | }
9 |
--------------------------------------------------------------------------------
/SIT.Manager/Views/CrashWindow.axaml.cs:
--------------------------------------------------------------------------------
1 | using Avalonia.Controls;
2 | using SIT.Manager.ViewModels;
3 |
4 | namespace SIT.Manager.Views;
5 | public partial class CrashWindow : Window
6 | {
7 | public CrashWindow()
8 | {
9 | InitializeComponent();
10 | this.DataContext = new CrashWindowViewModel();
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/Location/ColliderParams.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json.Serialization;
2 |
3 | namespace SIT.Manager.Models.Location;
4 |
5 | public class ColliderParams
6 | {
7 | [JsonPropertyName("_parent")]
8 | public string? Parent { get; set; }
9 | [JsonPropertyName("_props")]
10 | public Props? Props { get; set; }
11 | }
12 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/Play/TarkovLaunchConfig.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace SIT.Manager.Models.Play;
4 |
5 | [Serializable]
6 | public struct TarkovLaunchConfig
7 | {
8 | private const string GAME_VERSION = "live";
9 |
10 | public string BackendUrl { get; init; }
11 | public readonly string Version => GAME_VERSION;
12 | }
13 |
--------------------------------------------------------------------------------
/SIT.Manager/CrashApp.axaml.cs:
--------------------------------------------------------------------------------
1 | using Avalonia;
2 | using Avalonia.Markup.Xaml;
3 |
4 | namespace SIT.Manager;
5 |
6 | public sealed partial class CrashApp : Application
7 | {
8 | public CrashApp()
9 | {
10 |
11 | }
12 |
13 | public override void Initialize()
14 | {
15 | AvaloniaXamlLoader.Load(this);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/SIT.Manager/ViewModels/Dialogs/SelectLogsDialogViewModel.cs:
--------------------------------------------------------------------------------
1 | using CommunityToolkit.Mvvm.ComponentModel;
2 | using SIT.Manager.Models;
3 |
4 | namespace SIT.Manager.ViewModels.Dialogs;
5 |
6 | public partial class SelectLogsDialogViewModel : ObservableObject
7 | {
8 | [ObservableProperty]
9 | private DiagnosticsOptions _selectedOptions = new();
10 | }
11 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/Location/MinMaxBot.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json.Serialization;
2 |
3 | namespace SIT.Manager.Models.Location;
4 |
5 | public class MinMaxBot
6 | {
7 | public string? WildSpawnType { get; set; }
8 | [JsonPropertyName("max")]
9 | public int Max { get; set; }
10 | [JsonPropertyName("min")]
11 | public int Min { get; set; }
12 | }
13 |
--------------------------------------------------------------------------------
/SIT.Manager/Theme/Assists/Observable.cs:
--------------------------------------------------------------------------------
1 | using Avalonia.Reactive;
2 | using System;
3 |
4 | namespace SIT.Manager.Theme.Assists;
5 |
6 | public static class Observable
7 | {
8 | public static IDisposable Subscribe(this IObservable source, Action action)
9 | {
10 | return source.Subscribe(new AnonymousObserver(action));
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/Location/MatchMakerMinPlayersByWaitTime.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json.Serialization;
2 |
3 | namespace SIT.Manager.Models.Location;
4 |
5 | public class MatchMakerMinPlayersByWaitTime
6 | {
7 | [JsonPropertyName("minPlayers")]
8 | public int MinPlayers { get; set; }
9 | [JsonPropertyName("time")]
10 | public int Time { get; set; }
11 | }
12 |
--------------------------------------------------------------------------------
/SIT.Manager.Desktop/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.Versioning;
3 |
4 | [assembly: AssemblyDescription("")]
5 | [assembly: AssemblyCopyright("Copyright © StayInTarkov 2024")]
6 | [assembly: AssemblyTrademark("")]
7 | [assembly: AssemblyCulture("")]
8 | [assembly: SupportedOSPlatform("windows")]
9 | [assembly: SupportedOSPlatform("linux")]
10 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/Location/Position.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json.Serialization;
2 |
3 | namespace SIT.Manager.Models.Location;
4 |
5 | public class Position
6 | {
7 | [JsonPropertyName("x")]
8 | public double X { get; set; }
9 | [JsonPropertyName("y")]
10 | public double Y { get; set; }
11 | [JsonPropertyName("z")]
12 | public double Z { get; set; }
13 | }
14 |
--------------------------------------------------------------------------------
/SIT.Manager/Native/Linux/Managers/Vkd3DManager.cs:
--------------------------------------------------------------------------------
1 | using SIT.Manager.Native.Linux;
2 | using System.Collections.Generic;
3 |
4 | namespace SIT.Manager.Native.Linux.Managers;
5 |
6 | public class Vkd3DManager() : DllManager("VKD3D",
7 | [
8 | "d3d12",
9 | "d3d12core"
10 | ],
11 | "vkd3d",
12 | "https://api.github.com/repos/lutris/vkd3d/releases");
13 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/ActionNotification.cs:
--------------------------------------------------------------------------------
1 | namespace SIT.Manager.Models;
2 |
3 | public class ActionNotification(string actionText, double progressPercentage, bool showActionPanel = true)
4 | {
5 | public string ActionText { get; set; } = actionText;
6 | public double ProgressPercentage { get; set; } = progressPercentage;
7 | public bool ShowActionPanel { get; set; } = showActionPanel;
8 | }
9 |
--------------------------------------------------------------------------------
/SIT.Manager/Interfaces/IManagerConfigService.cs:
--------------------------------------------------------------------------------
1 | using SIT.Manager.Models.Config;
2 | using System;
3 |
4 | namespace SIT.Manager.Interfaces;
5 |
6 | public interface IManagerConfigService
7 | {
8 | ManagerConfig Config { get; }
9 |
10 | void UpdateConfig(ManagerConfig config, bool shouldSave = true, bool? saveAccount = false);
11 | event EventHandler? ConfigChanged;
12 | }
13 |
--------------------------------------------------------------------------------
/SIT.Manager/Native/Linux/Managers/DxvkManager.cs:
--------------------------------------------------------------------------------
1 | using SIT.Manager.Native.Linux;
2 | using System.Collections.Generic;
3 |
4 | namespace SIT.Manager.Native.Linux.Managers;
5 |
6 | public class DxvkManager() : DllManager("DXVK",
7 | [
8 | "dxgi",
9 | "d3d11",
10 | "d3d10core",
11 | "d3d9"
12 | ],
13 | "dxvk",
14 | "https://api.github.com/repos/lutris/dxvk/releases");
15 |
--------------------------------------------------------------------------------
/SIT.Manager/Views/ToolsPage.axaml.cs:
--------------------------------------------------------------------------------
1 | using Avalonia.Controls;
2 | using Microsoft.Extensions.DependencyInjection;
3 | using SIT.Manager.ViewModels;
4 |
5 | namespace SIT.Manager.Views;
6 |
7 | public partial class ToolsPage : UserControl
8 | {
9 | public ToolsPage()
10 | {
11 | InitializeComponent();
12 | this.DataContext = App.Current.Services.GetService();
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/SIT.Manager/Views/MainView.axaml.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.DependencyInjection;
2 | using SIT.Manager.Theme.Controls;
3 | using SIT.Manager.ViewModels;
4 |
5 | namespace SIT.Manager.Views;
6 |
7 | public partial class MainView : ActivatableUserControl
8 | {
9 | public MainView()
10 | {
11 | InitializeComponent();
12 | DataContext = App.Current.Services.GetService();
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/SIT.Manager/ViewModels/CrashWindowViewModel.cs:
--------------------------------------------------------------------------------
1 | using CommunityToolkit.Mvvm.Input;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace SIT.Manager.ViewModels;
9 | public partial class CrashWindowViewModel
10 | {
11 | [RelayCommand]
12 | private void ExitLauncher()
13 | {
14 | Environment.Exit(-1);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/SIT.Manager/Views/ModsPage.axaml.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.DependencyInjection;
2 | using SIT.Manager.Theme.Controls;
3 | using SIT.Manager.ViewModels;
4 |
5 | namespace SIT.Manager.Views;
6 |
7 | public partial class ModsPage : ActivatableUserControl
8 | {
9 | public ModsPage()
10 | {
11 | DataContext = App.Current.Services.GetService();
12 | InitializeComponent();
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/SIT.Manager/Views/PlayPage.axaml.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.DependencyInjection;
2 | using SIT.Manager.Theme.Controls;
3 | using SIT.Manager.ViewModels;
4 |
5 | namespace SIT.Manager.Views;
6 |
7 | public partial class PlayPage : ActivatableUserControl
8 | {
9 | public PlayPage()
10 | {
11 | InitializeComponent();
12 | DataContext = App.Current.Services.GetService();
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/SIT.Manager/Views/SettingsPage.axaml.cs:
--------------------------------------------------------------------------------
1 | using Avalonia.Controls;
2 | using Microsoft.Extensions.DependencyInjection;
3 | using SIT.Manager.ViewModels;
4 |
5 | namespace SIT.Manager.Views;
6 |
7 | public partial class SettingsPage : UserControl
8 | {
9 | public SettingsPage()
10 | {
11 | InitializeComponent();
12 | this.DataContext = App.Current.Services.GetService();
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/SIT.Manager/Interfaces/IActionNotificationService.cs:
--------------------------------------------------------------------------------
1 | using SIT.Manager.Models;
2 | using System;
3 |
4 | namespace SIT.Manager.Interfaces;
5 |
6 | public interface IActionNotificationService
7 | {
8 | event EventHandler? ActionNotificationReceived;
9 |
10 | void StartActionNotification();
11 | void StopActionNotification();
12 | void UpdateActionNotification(ActionNotification notification);
13 | }
14 |
--------------------------------------------------------------------------------
/SIT.Manager/Views/UpdatePage.axaml.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.DependencyInjection;
2 | using SIT.Manager.Theme.Controls;
3 | using SIT.Manager.ViewModels;
4 |
5 | namespace SIT.Manager.Views;
6 |
7 | public partial class UpdatePage : ActivatableUserControl
8 | {
9 | public UpdatePage()
10 | {
11 | InitializeComponent();
12 | DataContext = App.Current.Services.GetService();
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/SIT.Manager/Views/InstallPage.axaml.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.DependencyInjection;
2 | using SIT.Manager.Theme.Controls;
3 | using SIT.Manager.ViewModels;
4 |
5 | namespace SIT.Manager.Views;
6 |
7 | public partial class InstallPage : ActivatableUserControl
8 | {
9 | public InstallPage()
10 | {
11 | InitializeComponent();
12 | DataContext = App.Current.Services.GetService();
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/SIT.Manager/Views/Settings/EftView.axaml.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.DependencyInjection;
2 | using SIT.Manager.Theme.Controls;
3 | using SIT.Manager.ViewModels.Settings;
4 |
5 | namespace SIT.Manager.Views.Settings;
6 |
7 | public partial class EftView : ActivatableUserControl
8 | {
9 | public EftView()
10 | {
11 | InitializeComponent();
12 | DataContext = App.Current.Services.GetService();
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/SIT.Manager/Interfaces/IDiagnosticService.cs:
--------------------------------------------------------------------------------
1 | using SIT.Manager.Models;
2 | using System.IO;
3 | using System.Threading.Tasks;
4 |
5 | namespace SIT.Manager.Interfaces;
6 | public interface IDiagnosticService
7 | {
8 | public Task CleanseLogFile(string fileData, bool bleachIt);
9 | public Task GetLogFile(string logFilePath, bool bleachIt);
10 | public Task GenerateDiagnosticReport(DiagnosticsOptions options);
11 | }
12 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/ConsoleText.cs:
--------------------------------------------------------------------------------
1 | using Avalonia.Media;
2 | using CommunityToolkit.Mvvm.ComponentModel;
3 |
4 | namespace SIT.Manager.Models;
5 |
6 | public partial class ConsoleText : ObservableObject
7 | {
8 | public SolidColorBrush TextColor { get; set; } = new SolidColorBrush(Colors.White);
9 | [ObservableProperty]
10 | private FontFamily _textFont = FontFamily.Default;
11 | public string Message { get; set; } = string.Empty;
12 | }
13 |
--------------------------------------------------------------------------------
/SIT.Manager/Views/LocationEditorView.axaml.cs:
--------------------------------------------------------------------------------
1 | using Avalonia.Controls;
2 | using Microsoft.Extensions.DependencyInjection;
3 | using SIT.Manager.ViewModels;
4 |
5 | namespace SIT.Manager.Views;
6 |
7 | public partial class LocationEditorView : UserControl
8 | {
9 | public LocationEditorView()
10 | {
11 | this.DataContext = App.Current.Services.GetService();
12 | InitializeComponent();
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/SIT.Manager/Views/Settings/LinuxView.axaml.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.DependencyInjection;
2 | using SIT.Manager.Theme.Controls;
3 | using SIT.Manager.ViewModels.Settings;
4 |
5 | namespace SIT.Manager.Views.Settings;
6 | public partial class LinuxView : ActivatableUserControl
7 | {
8 | public LinuxView()
9 | {
10 | InitializeComponent();
11 | DataContext = App.Current.Services.GetService();
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/SIT.Manager/Views/Tools/GeneralToolsView.axaml.cs:
--------------------------------------------------------------------------------
1 | using Avalonia.Controls;
2 | using Microsoft.Extensions.DependencyInjection;
3 | using SIT.Manager.ViewModels.Tools;
4 |
5 | namespace SIT.Manager.Views.Tools;
6 | public partial class GeneralToolsView : UserControl
7 | {
8 | public GeneralToolsView()
9 | {
10 | InitializeComponent();
11 | this.DataContext = App.Current.Services.GetService();
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/SIT.Manager/Theme/Styles/SelectableTextBlock.axaml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
12 |
13 |
--------------------------------------------------------------------------------
/SIT.Manager/Views/Settings/SptAkiView.axaml.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.DependencyInjection;
2 | using SIT.Manager.Theme.Controls;
3 | using SIT.Manager.ViewModels.Settings;
4 |
5 | namespace SIT.Manager.Views.Settings;
6 |
7 | public partial class SptAkiView : ActivatableUserControl
8 | {
9 | public SptAkiView()
10 | {
11 | InitializeComponent();
12 | DataContext = App.Current.Services.GetService();
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/SIT.Manager/Views/Installation/CompleteView.axaml.cs:
--------------------------------------------------------------------------------
1 | using Avalonia.Controls;
2 | using Microsoft.Extensions.DependencyInjection;
3 | using SIT.Manager.ViewModels.Installation;
4 |
5 | namespace SIT.Manager.Views.Installation;
6 |
7 | public partial class CompleteView : UserControl
8 | {
9 | public CompleteView()
10 | {
11 | InitializeComponent();
12 | this.DataContext = App.Current.Services.GetService();
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/SIT.Manager/Views/Settings/LauncherView.axaml.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.DependencyInjection;
2 | using SIT.Manager.Theme.Controls;
3 | using SIT.Manager.ViewModels.Settings;
4 |
5 | namespace SIT.Manager.Views.Settings;
6 |
7 | public partial class LauncherView : ActivatableUserControl
8 | {
9 | public LauncherView()
10 | {
11 | InitializeComponent();
12 | DataContext = App.Current.Services.GetService();
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/Installation/ProgressInstallMessage.cs:
--------------------------------------------------------------------------------
1 | using CommunityToolkit.Mvvm.Messaging.Messages;
2 |
3 | namespace SIT.Manager.Models.Installation;
4 |
5 | ///
6 | /// Message to inform the InstallPage whether to progress the stepper to the next value
7 | ///
8 | /// True goes forawrd a step; False goes back a step
9 | public class ProgressInstallMessage(bool value) : ValueChangedMessage(value)
10 | {
11 | }
12 |
--------------------------------------------------------------------------------
/SIT.Manager/Views/Installation/PatchView.axaml.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.DependencyInjection;
2 | using SIT.Manager.Theme.Controls;
3 | using SIT.Manager.ViewModels.Installation;
4 |
5 | namespace SIT.Manager.Views.Installation;
6 |
7 | public partial class PatchView : ActivatableUserControl
8 | {
9 | public PatchView()
10 | {
11 | InitializeComponent();
12 | this.DataContext = App.Current.Services.GetService();
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/SIT.Manager/Extentions/ObservableCollectionExtentions.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Collections.ObjectModel;
3 |
4 | namespace SIT.Manager.Extentions;
5 |
6 | public static class ObservableCollectionExtentions
7 | {
8 | public static void AddRange(this ObservableCollection collection, IEnumerable values)
9 | {
10 | foreach (var item in values)
11 | {
12 | collection.Add(item);
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/SIT.Manager/Views/Installation/SelectView.axaml.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.DependencyInjection;
2 | using SIT.Manager.Theme.Controls;
3 | using SIT.Manager.ViewModels.Installation;
4 |
5 | namespace SIT.Manager.Views.Installation;
6 |
7 | public partial class SelectView : ActivatableUserControl
8 | {
9 | public SelectView()
10 | {
11 | InitializeComponent();
12 | this.DataContext = App.Current.Services.GetService();
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/SIT.Manager/Views/Installation/InstallView.axaml.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.DependencyInjection;
2 | using SIT.Manager.Theme.Controls;
3 | using SIT.Manager.ViewModels.Installation;
4 |
5 | namespace SIT.Manager.Views.Installation;
6 |
7 | public partial class InstallView : ActivatableUserControl
8 | {
9 | public InstallView()
10 | {
11 | InitializeComponent();
12 | this.DataContext = App.Current.Services.GetService();
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/SIT.Manager/Views/Tools/NetworkToolsView.axaml.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.DependencyInjection;
2 | using SIT.Manager.Theme.Controls;
3 | using SIT.Manager.ViewModels.Tools;
4 |
5 | namespace SIT.Manager.Views.Tools;
6 |
7 | public partial class NetworkToolsView : ActivatableUserControl
8 | {
9 | public NetworkToolsView()
10 | {
11 | InitializeComponent();
12 | DataContext = App.Current.Services.GetRequiredService();
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/SIT.Manager/Views/Play/ServerSelectionView.axaml.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.DependencyInjection;
2 | using SIT.Manager.Theme.Controls;
3 | using SIT.Manager.ViewModels.Play;
4 |
5 | namespace SIT.Manager.Views.Play;
6 |
7 | public partial class ServerSelectionView : ActivatableUserControl
8 | {
9 | public ServerSelectionView()
10 | {
11 | InitializeComponent();
12 | DataContext = App.Current.Services.GetService();
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/SIT.Manager/Views/Play/CharacterSelectionView.axaml.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.DependencyInjection;
2 | using SIT.Manager.Theme.Controls;
3 | using SIT.Manager.ViewModels.Play;
4 |
5 | namespace SIT.Manager.Views.Play;
6 |
7 | public partial class CharacterSelectionView : ActivatableUserControl
8 | {
9 | public CharacterSelectionView()
10 | {
11 | InitializeComponent();
12 | DataContext = App.Current.Services.GetService();
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/SIT.Manager/Views/Installation/ConfigureSitView.axaml.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.DependencyInjection;
2 | using SIT.Manager.Theme.Controls;
3 | using SIT.Manager.ViewModels.Installation;
4 |
5 | namespace SIT.Manager.Views.Installation;
6 |
7 | public partial class ConfigureSitView : ActivatableUserControl
8 | {
9 | public ConfigureSitView()
10 | {
11 | InitializeComponent();
12 | this.DataContext = App.Current.Services.GetService();
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/Installation/InstallationRunningMessage.cs:
--------------------------------------------------------------------------------
1 | using CommunityToolkit.Mvvm.Messaging.Messages;
2 |
3 | namespace SIT.Manager.Models.Installation;
4 |
5 | ///
6 | /// Message to inform whether there is an install running, so we can disable things like navigation to prevent users
7 | /// from screwing up the install process
8 | ///
9 | ///
10 | public class InstallationRunningMessage(bool value) : ValueChangedMessage(value)
11 | {
12 | }
13 |
--------------------------------------------------------------------------------
/SIT.Manager/Views/Installation/ConfigureServerView.axaml.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.DependencyInjection;
2 | using SIT.Manager.Theme.Controls;
3 | using SIT.Manager.ViewModels.Installation;
4 |
5 | namespace SIT.Manager.Views.Installation;
6 |
7 | public partial class ConfigureServerView : ActivatableUserControl
8 | {
9 | public ConfigureServerView()
10 | {
11 | InitializeComponent();
12 | this.DataContext = App.Current.Services.GetService();
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/Aki/AkiServerInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Text.Json.Serialization;
3 |
4 | namespace SIT.Manager.Models.Aki;
5 |
6 | public class AkiServerInfo
7 | {
8 | [JsonPropertyName("name")]
9 | public string Name { get; init; } = string.Empty;
10 | [JsonPropertyName("editions")]
11 | public string[] Editions { get; init; } = [];
12 | [JsonPropertyName("profileDescriptions")]
13 | public Dictionary Descriptions { get; init; } = [];
14 | }
15 |
--------------------------------------------------------------------------------
/SIT.Manager/Native/Linux/Managers/Dgvoodoo2Manager.cs:
--------------------------------------------------------------------------------
1 | using SIT.Manager.Native.Linux;
2 |
3 | namespace SIT.Manager.Native.Linux.Managers;
4 |
5 | public class Dgvoodoo2Manager() : DllManager("dgvodoo2",
6 | [
7 | "d3dimm",
8 | "ddraw",
9 | "glide",
10 | "glide2x",
11 | "glide3x",
12 | ],
13 | "dgvoodoo2",
14 | "https://api.github.com/repos/lutris/dgvoodoo2/releases",
15 | ["dgVoodoo/dgVoodoo.conf"]); // TODO: Implement this, probs somewhere in the appdata folder of the prefix
16 |
--------------------------------------------------------------------------------
/SIT.Manager/ViewModels/Play/LoginDialogViewModel.cs:
--------------------------------------------------------------------------------
1 | using CommunityToolkit.Mvvm.ComponentModel;
2 |
3 | namespace SIT.Manager.ViewModels.Play;
4 |
5 | public partial class LoginDialogViewModel : ObservableObject
6 | {
7 | [ObservableProperty]
8 | private string _username;
9 |
10 | [ObservableProperty]
11 | private string _password = string.Empty;
12 |
13 | [ObservableProperty]
14 | private bool _rememberMe = false;
15 |
16 | public LoginDialogViewModel(string username)
17 | {
18 | Username = username;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/SIT.Manager/Native/Linux/Managers/DxvkNvapiManager.cs:
--------------------------------------------------------------------------------
1 | using SIT.Manager.Native.Linux;
2 |
3 | namespace SIT.Manager.Native.Linux.Managers;
4 |
5 | public class DxvkNvapiManager() : DllManager("DXVK-NVAPI",
6 | [
7 | "nvapi",
8 | "nvapi64",
9 | "nvml"
10 | ],
11 | "dxvk-nvapi",
12 | "https://api.github.com/repos/lutris/dxvk-nvapi/releases");
13 | // TODO: dlss_dlls = ("nvngx", "_nvngx")
14 | // I (jubiman) cannot test this as I have an AMD GPU.
15 | // Please someone that is on Linux with an NVIDIA GPU implement and test this.
16 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/DiagnosticsOptions.cs:
--------------------------------------------------------------------------------
1 | using CommunityToolkit.Mvvm.ComponentModel;
2 |
3 | namespace SIT.Manager.Models;
4 |
5 | public partial class DiagnosticsOptions : ObservableObject
6 | {
7 | [ObservableProperty]
8 | private bool _includeClientLog = true;
9 | [ObservableProperty]
10 | public bool _includeServerLog = true;
11 | [ObservableProperty]
12 | public bool _includeDiagnosticLog = true;
13 | [ObservableProperty]
14 | public bool _includeHttpJson = true;
15 | [ObservableProperty]
16 | public bool _includeManagerLog = true;
17 | }
18 |
--------------------------------------------------------------------------------
/SIT.Manager/Services/Caching/CachingService.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.DependencyInjection;
2 | using SIT.Manager.Interfaces;
3 | using System;
4 |
5 | namespace SIT.Manager.Services.Caching;
6 |
7 | public class CachingService(IServiceProvider provider) : ICachingService
8 | {
9 | private const string CACHE_PATH = "Cache";
10 | public ICachingProvider InMemory { get; } = ActivatorUtilities.CreateInstance(provider, CACHE_PATH);
11 | public ICachingProvider OnDisk { get; } = ActivatorUtilities.CreateInstance(provider, CACHE_PATH);
12 | }
13 |
--------------------------------------------------------------------------------
/SIT.Manager/Theme/Controls/Card.axaml.cs:
--------------------------------------------------------------------------------
1 | using Avalonia;
2 | using Avalonia.Controls;
3 |
4 | namespace SIT.Manager.Theme.Controls;
5 |
6 | public class Card : ContentControl
7 | {
8 | public static readonly StyledProperty InsideClippingProperty =
9 | AvaloniaProperty.Register(nameof(InsideClipping), true);
10 |
11 | ///
12 | /// Get or set the inside border clipping.
13 | ///
14 | public bool InsideClipping
15 | {
16 | get => GetValue(InsideClippingProperty);
17 | set => SetValue(InsideClippingProperty, value);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/Location/BotLocationModifier.cs:
--------------------------------------------------------------------------------
1 | namespace SIT.Manager.Models.Location;
2 |
3 | public class BotLocationModifier
4 | {
5 | public float AccuracySpeed { get; set; }
6 | public float DistToActivate { get; set; }
7 | public float DistToPersueAxemanCoef { get; set; }
8 | public float DistToSleep { get; set; }
9 | public float GainSight { get; set; }
10 | public float KhorovodChance { get; set; }
11 | public float MagnetPower { get; set; }
12 | public float MarksmanAccuratyCoef { get; set; }
13 | public float Scattering { get; set; }
14 | public float VisibleDistance { get; set; }
15 | }
16 |
--------------------------------------------------------------------------------
/SIT.Manager/Services/Caching/CacheValue.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace SIT.Manager.Services.Caching;
8 | public class CacheValue(T? value, bool hasValue)
9 | {
10 | public bool HasValue { get { return hasValue; } }
11 | public T? Value { get { return value; } }
12 | public static CacheValue Null { get; } = new(default, true);
13 | public static CacheValue NoValue { get; } = new(default, false);
14 | public override string ToString()
15 | {
16 | return Value?.ToString() ?? "null";
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/Installation/SitInstallVersion.cs:
--------------------------------------------------------------------------------
1 | using SIT.Manager.Models.Github;
2 | using System.Collections.Generic;
3 |
4 | namespace SIT.Manager.Models.Installation;
5 |
6 | public class SitInstallVersion
7 | {
8 | public bool IsAvailable { get; set; } = false;
9 | public bool DowngradeRequired { get; set; } = false;
10 | public string EftVersion { get; set; } = string.Empty;
11 | public string SitVersion { get; set; } = string.Empty;
12 | public bool IsDeveloperVersion => Release.Prerelease;
13 | public GithubRelease Release { get; set; } = new();
14 | public Dictionary DownloadMirrors { get; set; } = [];
15 | }
16 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/Location/SpawnPointParam.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace SIT.Manager.Models.Location;
4 |
5 | public class SpawnPointParam
6 | {
7 | public string? BotZoneName { get; set; }
8 | public List? Categories { get; set; }
9 | public ColliderParams? ColliderParams { get; set; }
10 | public int CorePointId { get; set; }
11 | public int DelayToCanSpawnSec { get; set; }
12 | public string? Id { get; set; }
13 | public string? Infiltration { get; set; }
14 | public Position? Position { get; set; }
15 | public double Rotation { get; set; }
16 | public List? Sides { get; set; }
17 | }
18 |
--------------------------------------------------------------------------------
/SIT.Manager/CrashApp.axaml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/SIT.Manager/Interfaces/ManagedProcesses/IManagedProcess.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace SIT.Manager.Interfaces.ManagedProcesses;
4 |
5 | public interface IManagedProcess
6 | {
7 | string ExecutableDirectory { get; }
8 | string ExecutableFilePath { get; }
9 | RunningState State { get; }
10 | event EventHandler? RunningStateChanged;
11 | ///
12 | /// Clear the cache for the process.
13 | ///
14 | void ClearCache();
15 | void Stop();
16 | void Start(string? arguments = null);
17 | }
18 |
19 | public enum RunningState
20 | {
21 | NotRunning,
22 | Starting,
23 | Running,
24 | StoppedUnexpectedly
25 | }
26 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/Location/AirdropParameter.cs:
--------------------------------------------------------------------------------
1 | namespace SIT.Manager.Models.Location;
2 |
3 | public class AirdropParameter
4 | {
5 | public int AirdropPointDeactivateDistance { get; set; }
6 | public int MinPlayersCountToSpawnAirdrop { get; set; }
7 | public double PlaneAirdropChance { get; set; }
8 | public int PlaneAirdropCooldownMax { get; set; }
9 | public int PlaneAirdropCooldownMin { get; set; }
10 | public int PlaneAirdropEnd { get; set; }
11 | public int PlaneAirdropMax { get; set; }
12 | public int PlaneAirdropStartMax { get; set; }
13 | public int PlaneAirdropStartMin { get; set; }
14 | public int UnsuccessfulTryPenalty { get; set; }
15 | }
16 |
--------------------------------------------------------------------------------
/SIT.Manager/Views/Play/DirectConnectView.axaml.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.DependencyInjection;
2 | using SIT.Manager.Theme.Controls;
3 | using SIT.Manager.ViewModels.Play;
4 |
5 | namespace SIT.Manager.Views.Play;
6 |
7 | public partial class DirectConnectView : ActivatableUserControl
8 | {
9 | public DirectConnectView()
10 | {
11 | InitializeComponent();
12 | DataContext = App.Current.Services.GetService();
13 | if (DataContext is DirectConnectViewModel dataContext)
14 | {
15 | AddressBox.LostFocus += (o, e) => { if (!dataContext.ManagerConfig.HideIpAddress) AddressBox.RevealPassword = true; };
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/Location/Exit.cs:
--------------------------------------------------------------------------------
1 | namespace SIT.Manager.Models.Location;
2 |
3 | public class Exit
4 | {
5 | public int Chance { get; set; }
6 | public int Count { get; set; }
7 | public string? EntryPoints { get; set; }
8 | public bool EventAvailable { get; set; }
9 | public int ExfiltrationTime { get; set; }
10 | public string? ExfiltrationType { get; set; }
11 | public string? Id { get; set; }
12 | public int MaxTime { get; set; }
13 | public int MinTime { get; set; }
14 | public string? Name { get; set; }
15 | public string? PassageRequirement { get; set; }
16 | public int PlayersCount { get; set; }
17 | public string? RequirementTip { get; set; }
18 | }
19 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/Aki/AkiServer.cs:
--------------------------------------------------------------------------------
1 | using CommunityToolkit.Mvvm.ComponentModel;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Text.Json.Serialization;
5 |
6 | namespace SIT.Manager.Models.Aki;
7 |
8 | public partial class AkiServer(Uri address) : ObservableObject
9 | {
10 | [JsonPropertyName("Address")]
11 | public Uri Address { get; } = address;
12 | [JsonPropertyName("Characters")]
13 | public List Characters { get; init; } = [];
14 | [JsonPropertyName("Nickname")]
15 | public string Nickname { get; set; } = string.Empty;
16 | [JsonIgnore]
17 | public string Name { get; internal set; } = string.Empty;
18 | [JsonIgnore]
19 | public int Ping { get; internal set; } = -1;
20 | }
21 |
--------------------------------------------------------------------------------
/SIT.Manager.Desktop/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | // global filter settings
4 | "LogLevel": {
5 | "Default": "Information"
6 | },
7 | // provider level settings
8 | "File": {
9 | "BasePath": "Logs",
10 | "FileAccessMode": "KeepOpenAndAutoFlush",
11 | "FileEncodingName": "utf-8",
12 | "DateFormat": "yyyyMMdd",
13 | "CounterFormat": "000",
14 | "MaxFileSize": 10485760,
15 | "IncludeScopes": true,
16 | "MaxQueueSize": 100,
17 | "Files": [
18 | // a simple log file definition which inherits all settings from the provider (will produce files like "Manager-000.log")
19 | {
20 | "Path": "Manager-.log"
21 | }
22 | ]
23 | }
24 | }
25 | }
--------------------------------------------------------------------------------
/SIT.Manager/Models/Gitea/GiteaAsset.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text.Json.Serialization;
3 |
4 | namespace SIT.Manager.Models.Gitea;
5 |
6 | public class GiteaAsset
7 | {
8 | [JsonPropertyName("browser_download_url")]
9 | public required string BrowserDownloadUrl { get; set; }
10 | [JsonPropertyName("created_at")]
11 | public DateTime CreatedAt { get; set; }
12 | [JsonPropertyName("download_count")]
13 | public int DownloadCount { get; set; }
14 | [JsonPropertyName("id")]
15 | public int Id { get; set; }
16 | [JsonPropertyName("name")]
17 | public required string Name { get; set; }
18 | [JsonPropertyName("size")]
19 | public int Size { get; set; }
20 | [JsonPropertyName("uuid")]
21 | public string? UUID { get; set; }
22 | }
23 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/ModInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace SIT.Manager.Models;
4 |
5 | public class ModInfo
6 | {
7 | public string Name { get; set; } = string.Empty;
8 | public string Author { get; set; } = string.Empty;
9 | public string SupportedVersion { get; set; } = string.Empty;
10 | public string ModVersion { get; set; } = string.Empty;
11 | public string PortVersion { get; set; } = string.Empty;
12 | public string Description { get; set; } = string.Empty;
13 | public string ModUrl { get; set; } = string.Empty;
14 | public bool RequiresFiles { get; set; }
15 | public List PluginFiles { get; set; } = [];
16 | public List ConfigFiles { get; set; } = [];
17 | public List PatcherFiles { get; set; } = [];
18 | }
19 |
--------------------------------------------------------------------------------
/SIT.Manager/Views/Play/LoginDialogView.axaml.cs:
--------------------------------------------------------------------------------
1 | using FluentAvalonia.UI.Controls;
2 | using SIT.Manager.ViewModels.Play;
3 | using System;
4 | using System.Threading.Tasks;
5 |
6 | namespace SIT.Manager.Views.Play;
7 |
8 | public partial class LoginDialogView : ContentDialog
9 | {
10 | private readonly LoginDialogViewModel dc;
11 |
12 | protected override Type StyleKeyOverride => typeof(ContentDialog);
13 |
14 | public LoginDialogView(string username)
15 | {
16 | dc = new LoginDialogViewModel(username);
17 | DataContext = dc;
18 |
19 | InitializeComponent();
20 | }
21 |
22 | public new Task<(ContentDialogResult, string, bool)> ShowAsync()
23 | {
24 | return ShowAsync(null).ContinueWith(t => (t.Result, dc.Password, dc.RememberMe));
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/SIT.Manager/Converters/ColorJsonConverter.cs:
--------------------------------------------------------------------------------
1 | using Avalonia.Media;
2 | using System;
3 | using System.Text.Json;
4 | using System.Text.Json.Serialization;
5 |
6 | namespace SIT.Manager.Converters;
7 |
8 | public class ColorJsonConverter : JsonConverter
9 | {
10 | public override Color Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
11 | {
12 | string colorString = reader.GetString() ?? Colors.White.ToString();
13 | Color color = Color.Parse(colorString);
14 | return color;
15 | }
16 |
17 | public override void Write(Utf8JsonWriter writer, Color value, JsonSerializerOptions options)
18 | {
19 | string colorString = $"#{value.A:X2}{value.R:X2}{value.G:X2}{value.B:X2}";
20 | writer.WriteStringValue(colorString);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/SIT.Manager/Interfaces/ManagedProcesses/IAkiServerService.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 |
4 | namespace SIT.Manager.Interfaces.ManagedProcesses;
5 |
6 | public interface IAkiServerService : IManagedProcess
7 | {
8 | event EventHandler? OutputDataReceived;
9 | event EventHandler? ServerStarted;
10 |
11 | bool IsStarted { get; }
12 | int ServerLineLimit { get; }
13 |
14 | ///
15 | /// Gets all the output which would have gone to the OutputDataReceived event
16 | /// if there are no event listeners attached.
17 | ///
18 | /// An array of all the strings which weren't sent to the OutputDataReceived as there was no listeners
19 | string[] GetCachedServerOutput();
20 | bool IsUnhandledInstanceRunning();
21 | }
22 |
--------------------------------------------------------------------------------
/SIT.Manager/Views/Dialogs/SelectLogsDialog.axaml.cs:
--------------------------------------------------------------------------------
1 | using FluentAvalonia.UI.Controls;
2 | using SIT.Manager.Models;
3 | using SIT.Manager.ViewModels.Dialogs;
4 | using System;
5 | using System.Threading.Tasks;
6 |
7 | namespace SIT.Manager.Views.Dialogs;
8 |
9 | public partial class SelectLogsDialog : ContentDialog
10 | {
11 |
12 | readonly SelectLogsDialogViewModel dc;
13 |
14 | protected override Type StyleKeyOverride => typeof(ContentDialog);
15 |
16 | public SelectLogsDialog()
17 | {
18 | dc = new SelectLogsDialogViewModel();
19 | this.DataContext = dc;
20 | InitializeComponent();
21 | }
22 |
23 | public new Task<(ContentDialogResult, DiagnosticsOptions)> ShowAsync()
24 | {
25 | return this.ShowAsync(null).ContinueWith(t => (t.Result, dc.SelectedOptions));
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/SIT.Manager/ViewModels/ToolsPageViewModel.cs:
--------------------------------------------------------------------------------
1 | using Avalonia.Controls;
2 | using Avalonia.Controls.ApplicationLifetimes;
3 | using Avalonia.Platform.Storage;
4 | using CommunityToolkit.Mvvm.ComponentModel;
5 | using CommunityToolkit.Mvvm.Input;
6 | using CommunityToolkit.Mvvm.Messaging;
7 | using FluentAvalonia.UI.Controls;
8 | using SIT.Manager.Interfaces;
9 | using SIT.Manager.Interfaces.ManagedProcesses;
10 | using SIT.Manager.Models;
11 | using SIT.Manager.Models.Messages;
12 | using SIT.Manager.Services;
13 | using SIT.Manager.Views;
14 | using SIT.Manager.Views.Dialogs;
15 | using System;
16 | using System.Collections.Generic;
17 | using System.IO;
18 | using System.Linq;
19 | using System.Threading.Tasks;
20 |
21 | namespace SIT.Manager.ViewModels;
22 |
23 | public partial class ToolsPageViewModel : ObservableRecipient
24 | {
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/Aki/AkiCharacter.cs:
--------------------------------------------------------------------------------
1 | using CommunityToolkit.Mvvm.ComponentModel;
2 | using System.Text.Json.Serialization;
3 |
4 | namespace SIT.Manager.Models.Aki;
5 |
6 | public class AkiCharacter : ObservableObject
7 | {
8 | [JsonPropertyName("Username")]
9 | public string Username { get; init; } = string.Empty;
10 | [JsonPropertyName("Password")]
11 | public string Password { get; init; } = string.Empty;
12 | [JsonPropertyName("ProfileID")]
13 | public string ProfileID { get; internal set; } = string.Empty;
14 | [JsonPropertyName("Edition")]
15 | public string Edition { get; internal set; } = "Edge of Darkness";
16 |
17 | public AkiCharacter(string username, string password)
18 | {
19 | Username = username;
20 | Password = password;
21 | }
22 |
23 | public AkiCharacter()
24 | {
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/SIT.Manager/App.axaml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/SIT.Manager/Theme/Styles/Border.axaml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
8 |
10 |
11 |
12 |
13 |
14 |
15 |
23 |
24 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/Location/Wave.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json.Serialization;
2 |
3 | namespace SIT.Manager.Models.Location;
4 |
5 | public class Wave
6 | {
7 | [JsonIgnore]
8 | public int Name { get; set; }
9 | public string? BotPreset { get; set; }
10 | public string? BotSide { get; set; }
11 | public string? SpawnPoints { get; set; }
12 | public string? WildSpawnType { get; set; }
13 | [JsonPropertyName("isPlayers")]
14 | public bool IsPlayers { get; set; }
15 | [JsonPropertyName("number")]
16 | public int Number { get; set; }
17 | [JsonPropertyName("slots_max")]
18 | public int SlotsMax { get; set; }
19 | [JsonPropertyName("slots_min")]
20 | public int SlotsMin { get; set; }
21 | [JsonPropertyName("time_max")]
22 | public int TimeMax { get; set; }
23 | [JsonPropertyName("time_min")]
24 | public int TimeMin { get; set; }
25 | }
26 |
--------------------------------------------------------------------------------
/SIT.Manager/Interfaces/IAppUpdaterService.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 |
4 | namespace SIT.Manager.Interfaces;
5 |
6 | public interface IAppUpdaterService
7 | {
8 | ///
9 | /// Check if there is an update available for SIT.Manager if the user allows checking for updates in ManagerConfig
10 | ///
11 | /// true if an update is available, otherwise false
12 | Task CheckForUpdate();
13 | ///
14 | /// Download, extract and then replace the current manager with the newsest version
15 | ///
16 | /// true if the update was successfully applied; otherwise false
17 | Task Update(IProgress progress);
18 | ///
19 | /// Restarts the current app
20 | ///
21 | ///
22 | void RestartApp();
23 | }
24 |
--------------------------------------------------------------------------------
/SIT.Manager/Views/ToolsPage.axaml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/Aki/AkiMiniProfile.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json.Serialization;
2 |
3 | namespace SIT.Manager.Models.Aki;
4 |
5 | public class AkiMiniProfile
6 | {
7 | [JsonPropertyName("username")]
8 | public string Username { get; init; } = string.Empty;
9 | [JsonPropertyName("nickname")]
10 | public string Nickname { get; init; } = string.Empty;
11 | [JsonPropertyName("side")]
12 | public string Side { get; init; } = string.Empty;
13 | [JsonPropertyName("currlvl")]
14 | public int CurrentLevel { get; init; } = -1;
15 | [JsonPropertyName("currexp")]
16 | public int CurrentExperience { get; init; } = -1;
17 | [JsonPropertyName("prevexp")]
18 | public int PreviousExperience { get; init; } = -1;
19 | [JsonPropertyName("nextlvl")]
20 | public int NextExperience { get; init; } = -1;
21 | [JsonPropertyName("maxlvl")]
22 | public int MaxLevel { get; init; } = -1;
23 | }
24 |
--------------------------------------------------------------------------------
/SIT.Manager/Views/MainWindow.axaml:
--------------------------------------------------------------------------------
1 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/SIT.Manager/Interfaces/ManagedProcesses/ITarkovClientService.cs:
--------------------------------------------------------------------------------
1 | using SIT.Manager.Models.Aki;
2 | using System.Threading.Tasks;
3 |
4 | namespace SIT.Manager.Interfaces.ManagedProcesses;
5 |
6 | public interface ITarkovClientService : IManagedProcess
7 | {
8 | ///
9 | /// Clear just the EFT local cache.
10 | ///
11 | void ClearLocalCache();
12 | ///
13 | /// Connect to the SPT-AKI server and launch Escape from Tarkov
14 | ///
15 | /// The EFT character we are trying to login as
16 | /// true if successfully logged in and launched otherwise false
17 | Task ConnectToServer(AkiServer server, AkiCharacter character);
18 | Task CreateCharacter(AkiServer server, string username, string password, bool rememberLogin);
19 | Task CreateCharacter(AkiServer server);
20 | }
21 |
--------------------------------------------------------------------------------
/SIT.Manager/Services/Caching/ICachingProvider.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Threading.Tasks;
4 |
5 | namespace SIT.Manager.Services.Caching;
6 | public interface ICachingProvider
7 | {
8 | event EventHandler? Evicted;
9 |
10 | bool Add(string key, T value, TimeSpan? expiryTime = null);
11 | void Clear(string prefix = "");
12 | bool Exists(string key);
13 | CacheValue Get(string key);
14 | IEnumerable GetAllKeys(string prefix);
15 | int GetCount(string prefix = "");
16 | CacheValue GetOrCompute(string key, Func computor, TimeSpan? expiryTime = null);
17 | Task> GetOrComputeAsync(string key, Func> computor, TimeSpan? expiryTime = null);
18 | bool Remove(string key);
19 | int RemoveByPrefix(string prefix);
20 | bool TryGet(string key, out CacheValue cacheValue);
21 | }
22 |
--------------------------------------------------------------------------------
/SIT.Manager/Theme/Theme.axaml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/Tools/PortCheckerResponse.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json.Serialization;
2 |
3 | namespace SIT.Manager.Models.Tools;
4 |
5 | public class PortCheckerResponse
6 | {
7 | [JsonPropertyName("akiSuccess")] public bool AkiSuccess { get; init; } = false;
8 | [JsonPropertyName("natSuccess")] public bool NatSuccess { get; init; } = false;
9 | [JsonPropertyName("relaySuccess")] public bool RelaySuccess { get; init; } = false;
10 |
11 | [JsonPropertyName("portsUsed")] public PortCheckerPorts PortsUsed { get; init; } = new();
12 |
13 | [JsonPropertyName("ipAddress")] public string? IpAddress { get; init; } = string.Empty;
14 | }
15 |
16 | public class PortCheckerPorts
17 | {
18 | [JsonPropertyName("akiPort")] public string AkiPort { get; set; } = "6969";
19 | [JsonPropertyName("relayPort")] public string RelayPort { get; set; } = "6970";
20 | [JsonPropertyName("natPort")] public string NatPort { get; set; } = "6971";
21 | }
22 |
--------------------------------------------------------------------------------
/SIT.Manager/Views/PlayPage.axaml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/SIT.Manager.Desktop/app.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
9 |
10 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/SIT.Manager/Interfaces/IPickerDialogService.cs:
--------------------------------------------------------------------------------
1 | using Avalonia.Platform.Storage;
2 | using System.Threading.Tasks;
3 |
4 | namespace SIT.Manager.Interfaces;
5 |
6 | public interface IPickerDialogService
7 | {
8 | ///
9 | /// Get a single directory from the user using the directory picker dialog
10 | ///
11 | /// IStorageFolder the user selected or null
12 | Task GetDirectoryFromPickerAsync();
13 | ///
14 | /// Get a single file from the user using the file open picker dialog
15 | ///
16 | /// IStorageFile the user selected or null
17 | Task GetFileFromPickerAsync();
18 | ///
19 | /// Get a file from the user using the save file picker dialog
20 | ///
21 | /// IStorageFile the user selected or null
22 | Task GetFileSaveFromPickerAsync(string defaultFileExtension = "", string suggestedFileName = "");
23 | }
24 |
--------------------------------------------------------------------------------
/SIT.Manager/Interfaces/IVersionService.cs:
--------------------------------------------------------------------------------
1 | namespace SIT.Manager.Interfaces;
2 |
3 | public interface IVersionService
4 | {
5 | ///
6 | /// Checks and returns the installed SPT-AKI version string
7 | ///
8 | /// The base SPT-AKI server path to check.
9 | string GetSptAkiVersion(string path);
10 | ///
11 | /// Checks and returns the installed EFT version string
12 | ///
13 | /// The base EFT path to check.
14 | string GetEFTVersion(string path);
15 | ///
16 | /// Checks and returns the installed SIT version string
17 | ///
18 | /// The base EFT path to check.
19 | string GetSITVersion(string path);
20 | ///
21 | /// Checks and returns the installed SIT Mod version string
22 | ///
23 | /// The base SPT-AKI server path to check.
24 | string GetSitModVersion(string path);
25 | }
26 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/Location/BossLocationSpawn.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Text.Json.Serialization;
3 |
4 | namespace SIT.Manager.Models.Location;
5 |
6 | public class BossLocationSpawn
7 | {
8 | [JsonIgnore]
9 | public int Name { get; set; }
10 | public int BossChance { get; set; }
11 | public string? BossDifficult { get; set; }
12 | public string? BossEscortAmount { get; set; }
13 | public string? BossEscortDifficult { get; set; }
14 | public string? BossEscortType { get; set; }
15 | public string? BossName { get; set; }
16 | public bool BossPlayer { get; set; }
17 | public string? BossZone { get; set; }
18 | public int Delay { get; set; }
19 | public bool ForceSpawn { get; set; }
20 | public bool IgnoreMaxBots { get; set; }
21 | public bool RandomTimeSpawn { get; set; }
22 | public List? Supports { get; set; }
23 | public int Time { get; set; }
24 | public string? TriggerId { get; set; }
25 | public string? TriggerName { get; set; }
26 | }
27 |
--------------------------------------------------------------------------------
/SIT.Manager/Views/Play/CreateCharacterDialogView.axaml.cs:
--------------------------------------------------------------------------------
1 | using FluentAvalonia.UI.Controls;
2 | using SIT.Manager.Models;
3 | using SIT.Manager.Models.Play;
4 | using SIT.Manager.ViewModels.Play;
5 | using System;
6 | using System.Threading.Tasks;
7 |
8 | namespace SIT.Manager.Views.Play;
9 |
10 | public partial class CreateCharacterDialogView : ContentDialog
11 | {
12 | private readonly CreateCharacterDialogViewModel dc;
13 |
14 | protected override Type StyleKeyOverride => typeof(ContentDialog);
15 |
16 | public CreateCharacterDialogView(string username, string password, bool rememberLogin, TarkovEdition[] editions)
17 | {
18 | dc = new CreateCharacterDialogViewModel(username, password, rememberLogin, editions);
19 | DataContext = dc;
20 | InitializeComponent();
21 | }
22 |
23 | public new Task ShowAsync()
24 | {
25 | return ShowAsync(null).ContinueWith(t => new CreateCharacterDialogResult(t.Result, dc.Username, dc.Password, dc.SaveLoginDetails, dc.SelectedEdition));
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/SIT.Manager/Interfaces/IBarNotificationService.cs:
--------------------------------------------------------------------------------
1 | using FluentAvalonia.UI.Controls;
2 | using SIT.Manager.Models;
3 | using System;
4 |
5 | namespace SIT.Manager.Interfaces;
6 |
7 | public interface IBarNotificationService
8 | {
9 | event EventHandler? BarNotificationReceived;
10 |
11 | ///
12 | /// Shows a notification over the main window
13 | ///
14 | /// Title of the message
15 | /// The message to show
16 | /// The to display
17 | /// The delay (in seconds) before removing the InfoBar
18 | void Show(string title, string message, InfoBarSeverity severity = InfoBarSeverity.Informational, int delay = 5);
19 | void ShowError(string title, string message, int delay = 5);
20 | void ShowInformational(string title, string message, int delay = 5);
21 | void ShowSuccess(string title, string message, int delay = 5);
22 | void ShowWarning(string title, string message, int delay = 5);
23 | }
24 |
--------------------------------------------------------------------------------
/SIT.Manager/Theme/Controls/ActivatableUserControl.cs:
--------------------------------------------------------------------------------
1 | using Avalonia;
2 | using Avalonia.Controls;
3 | using CommunityToolkit.Mvvm.ComponentModel;
4 |
5 | namespace SIT.Manager.Theme.Controls;
6 |
7 | public class ActivatableUserControl : UserControl
8 | {
9 | public ObservableRecipient? ViewModel => DataContext is ObservableRecipient dc ? dc : default;
10 |
11 | public ActivatableUserControl()
12 | {
13 | }
14 |
15 | protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
16 | {
17 | base.OnAttachedToVisualTree(e);
18 |
19 | OnActivated();
20 | if (ViewModel != null)
21 | {
22 | ViewModel.IsActive = true;
23 | }
24 | }
25 |
26 | protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
27 | {
28 | base.OnDetachedFromVisualTree(e);
29 |
30 | OnDeactivated();
31 | if (ViewModel != null)
32 | {
33 | ViewModel.IsActive = false;
34 | }
35 | }
36 |
37 | protected virtual void OnActivated() { }
38 |
39 | protected virtual void OnDeactivated() { }
40 | }
41 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 Stay In Tarkov
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/SIT.Manager/Views/Play/CreateServerDialogView.axaml.cs:
--------------------------------------------------------------------------------
1 | using FluentAvalonia.UI.Controls;
2 | using SIT.Manager.Interfaces;
3 | using SIT.Manager.Models.Play;
4 | using SIT.Manager.ViewModels.Play;
5 | using System;
6 | using System.Threading.Tasks;
7 |
8 | namespace SIT.Manager.Views.Play;
9 |
10 | public partial class CreateServerDialogView : ContentDialog
11 | {
12 | private const string DEFAULT_SERVER_ADDRESS = "http://127.0.0.1:6969";
13 |
14 | private readonly CreateServerDialogViewModel dc;
15 |
16 | protected override Type StyleKeyOverride => typeof(ContentDialog);
17 |
18 | public CreateServerDialogView(ILocalizationService localizationService, bool isEdit, string serverNickname, string currentServerAddress = DEFAULT_SERVER_ADDRESS)
19 | {
20 | dc = new CreateServerDialogViewModel(currentServerAddress, serverNickname, isEdit, localizationService);
21 | DataContext = dc;
22 | InitializeComponent();
23 | }
24 |
25 | public new Task ShowAsync()
26 | {
27 | return ShowAsync(null).ContinueWith(t => new CreateServerDialogResult(t.Result, dc.ServerUri, dc.ServerNickname));
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/SIT.Manager/ViewModels/Installation/CompleteViewModel.cs:
--------------------------------------------------------------------------------
1 | using CommunityToolkit.Mvvm.Input;
2 | using CommunityToolkit.Mvvm.Messaging;
3 | using SIT.Manager.Models;
4 | using SIT.Manager.Models.Installation;
5 | using SIT.Manager.Models.Messages;
6 | using SIT.Manager.Views;
7 |
8 | namespace SIT.Manager.ViewModels.Installation;
9 |
10 | public partial class CompleteViewModel : InstallationViewModelBase
11 | {
12 | public CompleteViewModel() : base()
13 | {
14 | Messenger.Send(new InstallationRunningMessage(false));
15 | }
16 |
17 | [RelayCommand]
18 | private void Reset()
19 | {
20 | PageNavigation pageNavigation;
21 | if (CurrentInstallProcessState.RequestedInstallOperation == RequestedInstallOperation.InstallServer || CurrentInstallProcessState.RequestedInstallOperation == RequestedInstallOperation.UpdateServer)
22 | {
23 | pageNavigation = new(typeof(ServerPage), false);
24 | }
25 | else
26 | {
27 | pageNavigation = new(typeof(PlayPage), false);
28 | }
29 |
30 | CurrentInstallProcessState = new();
31 | ProgressInstall();
32 |
33 | Messenger.Send(new PageNavigationMessage(pageNavigation));
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/SIT.Manager/Theme/Styles/TextBlock.axaml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
19 |
20 |
25 |
26 |
31 |
32 |
--------------------------------------------------------------------------------
/SIT.Manager/Interfaces/IAkiServerRequestingService.cs:
--------------------------------------------------------------------------------
1 | using SIT.Manager.Models.Aki;
2 | using SIT.Manager.Services;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.IO;
6 | using System.Threading;
7 | using System.Threading.Tasks;
8 |
9 | namespace SIT.Manager.Interfaces;
10 | public interface IAkiServerRequestingService
11 | {
12 | public Task GetPingAsync(AkiServer akiServer, CancellationToken cancellationToken = default);
13 | public Task GetAkiServerAsync(Uri serverAddresss, bool fetchInformation = true, CancellationToken cancellationToken = default);
14 | public Task> GetMiniProfilesAsync(AkiServer server, CancellationToken cancellationToken = default);
15 | public Task<(string, AkiLoginStatus)> LoginAsync(AkiServer server, AkiCharacter character, CancellationToken cancellationToken = default);
16 | public Task<(string, AkiLoginStatus)> RegisterCharacterAsync(AkiServer server, AkiCharacter character, CancellationToken cancellationToken = default);
17 | public Task GetAkiServerInfoAsync(AkiServer server, CancellationToken cancellationToken = default);
18 | public Task GetAkiServerImage(AkiServer server, string assetPath, CancellationToken cancellationToken = default);
19 | }
20 |
--------------------------------------------------------------------------------
/SIT.Manager.Desktop/Program.cs:
--------------------------------------------------------------------------------
1 | using Avalonia;
2 | using Avalonia.Controls;
3 | using SIT.Manager.Views;
4 | using System;
5 | using System.IO;
6 |
7 | namespace SIT.Manager.Desktop;
8 |
9 | class Program
10 | {
11 | // Initialization code. Don't use any Avalonia, third-party APIs or any
12 | // SynchronizationContext-reliant code before AppMain is called: things aren't initialized
13 | // yet and stuff might break.
14 | [STAThread]
15 | public static void Main(string[] args)
16 | {
17 | AppBuilder aB = BuildAvaloniaApp(args);
18 | try
19 | {
20 | aB.StartWithClassicDesktopLifetime(args);
21 | }
22 | catch (Exception ex)
23 | {
24 | File.WriteAllText("crash.log", ex.ToString());
25 | CrashApp crashApp = new();
26 | crashApp.RunWithMainWindow();
27 | }
28 | }
29 |
30 | // Avalonia configuration, don't remove; also used by visual designer.
31 | public static AppBuilder BuildAvaloniaApp(string[] args)
32 | => AppBuilder.Configure(() => new App(args))
33 | .UsePlatformDetect()
34 | .WithInterFont()
35 | .LogToTrace();
36 |
37 | public static AppBuilder BuildAvaloniaApp() => BuildAvaloniaApp([]);
38 | }
39 |
--------------------------------------------------------------------------------
/SIT.Manager/Services/ActionNotificationService.cs:
--------------------------------------------------------------------------------
1 | using SIT.Manager.Interfaces;
2 | using SIT.Manager.Models;
3 | using System;
4 |
5 | namespace SIT.Manager.Services;
6 |
7 | public class ActionNotificationService : IActionNotificationService
8 | {
9 | private bool _isShowingNotification = false;
10 |
11 | public event EventHandler? ActionNotificationReceived;
12 |
13 | public void StartActionNotification()
14 | {
15 | if (_isShowingNotification)
16 | {
17 | return;
18 | }
19 | _isShowingNotification = true;
20 |
21 | ActionNotificationReceived?.Invoke(this, new ActionNotification(string.Empty, 0, true));
22 | }
23 |
24 | public void StopActionNotification()
25 | {
26 | if (!_isShowingNotification)
27 | {
28 | return;
29 | }
30 | _isShowingNotification = false;
31 |
32 | ActionNotificationReceived?.Invoke(this, new ActionNotification(string.Empty, 0, false));
33 | }
34 |
35 | public void UpdateActionNotification(ActionNotification notification)
36 | {
37 | if (!_isShowingNotification)
38 | {
39 | return;
40 | }
41 | ActionNotificationReceived?.Invoke(this, notification);
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/Github/GithubAsset.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text.Json.Serialization;
3 |
4 | namespace SIT.Manager.Models.Github;
5 |
6 | public class GithubAsset
7 | {
8 | [JsonPropertyName("url")]
9 | public string? Url { get; set; }
10 | [JsonPropertyName("browser_download_url")]
11 | public required string BrowserDownloadUrl { get; set; }
12 | [JsonPropertyName("id")]
13 | public int Id { get; set; }
14 | [JsonPropertyName("node_id")]
15 | public string? NodeId { get; set; }
16 | [JsonPropertyName("name")]
17 | public required string Name { get; set; }
18 | [JsonPropertyName("label")]
19 | public string? Label { get; set; }
20 | [JsonPropertyName("state")]
21 | public string? State { get; set; }
22 | [JsonPropertyName("content_type")]
23 | public string? ContentType { get; set; }
24 | [JsonPropertyName("size")]
25 | public int Size { get; set; }
26 | [JsonPropertyName("download_count")]
27 | public int DownloadCount { get; set; }
28 | [JsonPropertyName("created_at")]
29 | public DateTime CreatedAt { get; set; }
30 | [JsonPropertyName("updated_at")]
31 | public DateTime UpdatedAt { get; set; }
32 | [JsonPropertyName("uploader")]
33 | public GithubUploader? Uploader { get; set; }
34 | }
35 |
--------------------------------------------------------------------------------
/SIT.Manager/Theme/Controls/LoadingSpinner.axaml.cs:
--------------------------------------------------------------------------------
1 | using Avalonia;
2 | using Avalonia.Controls;
3 |
4 | namespace SIT.Manager.Theme.Controls;
5 |
6 | public partial class LoadingSpinner : UserControl
7 | {
8 | public static new readonly StyledProperty HeightProperty =
9 | AvaloniaProperty.Register(nameof(Height), defaultValue: 150);
10 |
11 | public new int Height
12 | {
13 | get { return GetValue(HeightProperty); }
14 | set { SetValue(HeightProperty, value); }
15 | }
16 |
17 | public static new readonly StyledProperty WidthProperty =
18 | AvaloniaProperty.Register(nameof(Width), defaultValue: 150);
19 |
20 | public new int Width
21 | {
22 | get { return GetValue(WidthProperty); }
23 | set { SetValue(WidthProperty, value); }
24 | }
25 |
26 | public static readonly StyledProperty StrokeWidthProperty =
27 | AvaloniaProperty.Register(nameof(StrokeWidth), defaultValue: 16);
28 |
29 | public int StrokeWidth
30 | {
31 | get { return GetValue(StrokeWidthProperty); }
32 | set { SetValue(StrokeWidthProperty, value); }
33 | }
34 |
35 | public LoadingSpinner()
36 | {
37 | InitializeComponent();
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/SIT.Manager/Views/SettingsPage.axaml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/SIT.Manager/Views/CrashWindow.axaml:
--------------------------------------------------------------------------------
1 |
14 |
15 |
20 | Something crashed your launcher :/
21 |
22 |
27 | We've created a log called "crash.log"
28 | if you wish to report this issue to us
29 |
30 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/SIT.Manager/Services/BarNotificationService.cs:
--------------------------------------------------------------------------------
1 | using FluentAvalonia.UI.Controls;
2 | using SIT.Manager.Interfaces;
3 | using SIT.Manager.Models;
4 | using System;
5 |
6 | namespace SIT.Manager.Services;
7 |
8 | public class BarNotificationService : IBarNotificationService
9 | {
10 | public event EventHandler? BarNotificationReceived;
11 |
12 | public BarNotificationService() { }
13 |
14 | public void Show(string title, string message, InfoBarSeverity severity = InfoBarSeverity.Informational, int delay = 5)
15 | {
16 | BarNotification newNotification = new(title, message, severity, delay);
17 | BarNotificationReceived?.Invoke(this, newNotification);
18 | }
19 |
20 | public void ShowError(string title, string message, int delay = 5)
21 | {
22 | Show(title, message, InfoBarSeverity.Error, delay);
23 | }
24 |
25 | public void ShowInformational(string title, string message, int delay = 5)
26 | {
27 | Show(title, message, InfoBarSeverity.Informational, delay);
28 | }
29 |
30 | public void ShowSuccess(string title, string message, int delay = 5)
31 | {
32 | Show(title, message, InfoBarSeverity.Success, delay);
33 | }
34 |
35 | public void ShowWarning(string title, string message, int delay = 5)
36 | {
37 | Show(title, message, InfoBarSeverity.Warning, delay);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/Installation/InstallProcessState.cs:
--------------------------------------------------------------------------------
1 | using CommunityToolkit.Mvvm.ComponentModel;
2 | using SIT.Manager.Models.Github;
3 |
4 | namespace SIT.Manager.Models.Installation;
5 |
6 | public partial class InstallProcessState : ObservableObject
7 | {
8 | // General / Shared Settings
9 | [ObservableProperty]
10 | private RequestedInstallOperation _requestedInstallOperation = RequestedInstallOperation.None;
11 | [ObservableProperty]
12 | private GithubRelease _requestedVersion = new();
13 |
14 | // EFT Install Settings
15 | [ObservableProperty]
16 | private bool _usingBsgInstallPath = false;
17 | [ObservableProperty]
18 | private string _bsgInstallPath = string.Empty;
19 | [ObservableProperty]
20 | private string _eftInstallPath = string.Empty;
21 | [ObservableProperty]
22 | private string _eftVersion = string.Empty;
23 | [ObservableProperty]
24 | private string _sitVersion = string.Empty;
25 | [ObservableProperty]
26 | private string _downloadMirrorUrl = string.Empty;
27 | [ObservableProperty]
28 | private bool _copyEftSettings = true;
29 |
30 | // SPT-AKI Install Settings
31 | [ObservableProperty]
32 | private string _sptAkiInstallPath = string.Empty;
33 | [ObservableProperty]
34 | private string _sptAkiVersion = string.Empty;
35 | [ObservableProperty]
36 | private string _sitModVersion = string.Empty;
37 | }
38 |
--------------------------------------------------------------------------------
/SIT.Manager/Views/Installation/CompleteView.axaml:
--------------------------------------------------------------------------------
1 |
11 |
14 |
16 |
19 |
24 |
25 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/.github/workflows/dotnet-desktop.yml:
--------------------------------------------------------------------------------
1 | name: Build
2 |
3 | on:
4 | push:
5 | branches: [ "master" ]
6 | pull_request:
7 | branches: [ "master" ]
8 |
9 | jobs:
10 | build:
11 | strategy:
12 | matrix:
13 | os: [ "win-x64", "linux-x64" ]
14 |
15 | runs-on: ubuntu-latest
16 |
17 | env:
18 | Solution_Name: SIT.Manager.sln
19 |
20 | steps:
21 | - name: Checkout
22 | uses: actions/checkout@v4
23 |
24 | - name: Setup .NET 8.0
25 | uses: actions/setup-dotnet@v4
26 | with:
27 | dotnet-version: 8.0.x
28 |
29 | - name: Get build date
30 | id: build
31 | shell: pwsh
32 | run: |
33 | $CurrentTime = Get-Date -Format 'yyMM'
34 | $BuildTime = Get-Date -Format 'ddHH'
35 | Write-Output "NOW=$CurrentTime" >> $env:GITHUB_OUTPUT
36 | Write-Output "VERSION=$BuildTime" >> $env:GITHUB_OUTPUT
37 |
38 | - name: Build Debug
39 | run: dotnet build SIT.Manager.Desktop/SIT.Manager.Desktop.csproj --configuration Debug -r ${{ matrix.os }} -p:BuildNumber=${{ steps.build.outputs.NOW }} -p:RevisionNumber=${{ steps.build.outputs.VERSION }}
40 |
41 | - name: Upload a Build Artifact
42 | uses: actions/upload-artifact@v4.3.1
43 | with:
44 | name: ${{ matrix.os }}
45 | path: ${{ github.workspace }}/SIT.Manager.Desktop/bin/Debug/net8.0/${{ matrix.os }}/*
46 | if-no-files-found: error
47 | retention-days: 3
48 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/Gitea/GiteaRelease.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text.Json.Serialization;
4 |
5 | namespace SIT.Manager.Models.Gitea;
6 |
7 | public class GiteaRelease
8 | {
9 | [JsonPropertyName("assets")]
10 | public required List Assets { get; set; }
11 | [JsonPropertyName("author")]
12 | public GiteaAuthor? Author { get; set; }
13 | [JsonPropertyName("body")]
14 | public string? Body { get; set; }
15 | [JsonPropertyName("created_at")]
16 | public DateTime CreatedAt { get; set; }
17 | [JsonPropertyName("draft")]
18 | public bool Draft { get; set; }
19 | [JsonPropertyName("html_url")]
20 | public string? HtmlUrl { get; set; }
21 | [JsonPropertyName("id")]
22 | public int Id { get; set; }
23 | [JsonPropertyName("name")]
24 | public required string Name { get; set; }
25 | [JsonPropertyName("prerelease")]
26 | public bool Prerelease { get; set; }
27 | [JsonPropertyName("published_at")]
28 | public DateTime PublishedAt { get; set; }
29 | [JsonPropertyName("tag_name")]
30 | public string? TagName { get; set; }
31 | [JsonPropertyName("tarball_url")]
32 | public string? TarballUrl { get; set; }
33 | [JsonPropertyName("target_commitish")]
34 | public string? TargetCommitish { get; set; }
35 | [JsonPropertyName("url")]
36 | public string? Url { get; set; }
37 | [JsonPropertyName("zipball_url")]
38 | public string? ZipballUrl { get; set; }
39 | }
40 |
--------------------------------------------------------------------------------
/SIT.Manager/Native/Windows/WindowsApi.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 |
4 | namespace SIT.Manager.Native.Windows;
5 |
6 | public static class WindowsApi
7 | {
8 | [DllImport("user32.dll", SetLastError = true)]
9 | public static extern nint SetParent(nint hWndChild, nint hWndNewParent);
10 |
11 | [DllImport("user32.dll", SetLastError = true)]
12 | public static extern uint GetWindowLongPtr(nint hWnd, int nIndex);
13 |
14 | [DllImport("user32.dll", SetLastError = true, EntryPoint = "SetWindowLong")]
15 | private static extern uint SetWindowLong32b(nint hWnd, int nIndex, uint value);
16 |
17 | [DllImport("user32.dll", SetLastError = true, EntryPoint = "SetWindowLongPtr")]
18 | private static extern nint SetWindowLong64b(nint hWnd, int nIndex, nint value);
19 |
20 | [DllImport("user32.dll", EntryPoint = "SetWindowLongPtr")]
21 | private static extern nint SetWindowLongPtr64(HandleRef hWnd, int nIndex, nint dwNewLong);
22 |
23 | [DllImport("user32.dll", EntryPoint = "SetWindowLong")]
24 | private static extern int SetWindowLong32(HandleRef hWnd, int nIndex, int dwNewLong);
25 |
26 | public static nint SetWindowLongPtr(HandleRef hWnd, int nIndex, nint dwNewLong)
27 | {
28 | if (nint.Size == 8)
29 | {
30 | return SetWindowLongPtr64(hWnd, nIndex, dwNewLong);
31 | }
32 | else
33 | {
34 | return new nint(SetWindowLong32(hWnd, nIndex, dwNewLong.ToInt32()));
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/SIT.Manager/Views/Play/CreateServerDialogView.axaml:
--------------------------------------------------------------------------------
1 |
15 |
16 |
17 |
21 |
22 |
26 |
27 |
--------------------------------------------------------------------------------
/SIT.Manager/Native/Linux/Managers/D3DExtrasManager.cs:
--------------------------------------------------------------------------------
1 | using SIT.Manager.Native.Linux;
2 | using System.Collections.Generic;
3 |
4 | namespace SIT.Manager.Native.Linux.Managers;
5 |
6 | public class D3DExtrasManager() : DllManager("D3DExtras",
7 | [
8 | "d3dx10_33",
9 | "d3dx10_34",
10 | "d3dx10_35",
11 | "d3dx10_36",
12 | "d3dx10_37",
13 | "d3dx10_38",
14 | "d3dx10_39",
15 | "d3dx10_40",
16 | "d3dx10_41",
17 | "d3dx10_42",
18 | "d3dx10_43",
19 | "d3dx10",
20 | "d3dx11_42",
21 | "d3dx11_43",
22 | "d3dx9_24",
23 | "d3dx9_25",
24 | "d3dx9_26",
25 | "d3dx9_27",
26 | "d3dx9_28",
27 | "d3dx9_29",
28 | "d3dx9_30",
29 | "d3dx9_31",
30 | "d3dx9_32",
31 | "d3dx9_33",
32 | "d3dx9_34",
33 | "d3dx9_35",
34 | "d3dx9_36",
35 | "d3dx9_37",
36 | "d3dx9_38",
37 | "d3dx9_39",
38 | "d3dx9_40",
39 | "d3dx9_41",
40 | "d3dx9_42",
41 | "d3dx9_43",
42 | "d3dcompiler_33",
43 | "d3dcompiler_34",
44 | "d3dcompiler_35",
45 | "d3dcompiler_36",
46 | "d3dcompiler_37",
47 | "d3dcompiler_38",
48 | "d3dcompiler_39",
49 | "d3dcompiler_40",
50 | "d3dcompiler_41",
51 | "d3dcompiler_42",
52 | "d3dcompiler_43",
53 | "d3dcompiler_46",
54 | "d3dcompiler_47"
55 | ],
56 | "d3dextras",
57 | "https://api.github.com/repos/lutris/d3d_extras/releases");
58 |
--------------------------------------------------------------------------------
/SIT.Manager/ViewModels/Installation/InstallationViewModelBase.cs:
--------------------------------------------------------------------------------
1 | using CommunityToolkit.Mvvm.ComponentModel;
2 | using CommunityToolkit.Mvvm.Messaging;
3 | using SIT.Manager.Models.Installation;
4 |
5 | namespace SIT.Manager.ViewModels.Installation;
6 |
7 | public partial class InstallationViewModelBase : ObservableRecipient
8 | {
9 | [ObservableProperty]
10 | private InstallProcessState _currentInstallProcessState;
11 |
12 | protected bool IsServerInstall => CurrentInstallProcessState.RequestedInstallOperation == RequestedInstallOperation.InstallServer || CurrentInstallProcessState.RequestedInstallOperation == RequestedInstallOperation.UpdateServer;
13 | protected bool IsSitInstall => CurrentInstallProcessState.RequestedInstallOperation == RequestedInstallOperation.InstallSit || CurrentInstallProcessState.RequestedInstallOperation == RequestedInstallOperation.UpdateSit;
14 |
15 | public InstallationViewModelBase()
16 | {
17 | try
18 | {
19 | CurrentInstallProcessState = Messenger.Send();
20 | }
21 | catch
22 | {
23 | CurrentInstallProcessState = new();
24 | }
25 | }
26 |
27 | protected void ProgressInstall()
28 | {
29 | WeakReferenceMessenger.Default.Send(new InstallProcessStateChangedMessage(CurrentInstallProcessState));
30 | WeakReferenceMessenger.Default.Send(new ProgressInstallMessage(true));
31 | }
32 |
33 | protected void RegressInstall()
34 | {
35 | WeakReferenceMessenger.Default.Send(new ProgressInstallMessage(false));
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/SIT.Manager/Extentions/HttpClientExtentions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Net.Http;
4 | using System.Threading;
5 | using System.Threading.Tasks;
6 |
7 | namespace SIT.Manager.Extentions;
8 |
9 | ///
10 | /// Source: https://gist.github.com/dalexsoto/9fd3c5bdbe9f61a717d47c5843384d11
11 | ///
12 | internal static class HttpClientExtentions
13 | {
14 | public static async Task DownloadAsync(this HttpClient client, Stream destination, string url, IProgress progressReporter, CancellationToken cancellationToken = default)
15 | {
16 | using HttpResponseMessage response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
17 | response.EnsureSuccessStatusCode();
18 | using Stream contentStream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
19 | long? contentLength = response.Content.Headers.ContentLength;
20 | if (!contentLength.HasValue)
21 | {
22 | await contentStream.CopyToAsync(destination, cancellationToken).ConfigureAwait(false);
23 | }
24 | else
25 | {
26 | double totalLength = contentLength.Value;
27 | Progress reportWrapper = new(br =>
28 | {
29 | double currentValue = br;
30 | progressReporter.Report(currentValue / totalLength * 100);
31 | });
32 | await contentStream.CopyToAsync(destination, 65535, reportWrapper, cancellationToken).ConfigureAwait(false);
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/SIT.Manager/Interfaces/ILocalizationService.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Globalization;
4 |
5 | namespace SIT.Manager.Interfaces;
6 |
7 | public interface ILocalizationService
8 | {
9 | CultureInfo DefaultLocale { get; }
10 |
11 | event EventHandler? LocalizationChanged;
12 |
13 | ///
14 | /// Function that loads the Available Localizations when program starts.
15 | ///
16 | List GetAvailableLocalizations();
17 | ///
18 | /// Changes the localization based on your culture info. This specific function changes it inside of Settings. And mainly changes all dynamic Resources in pages.
19 | ///
20 | /// the current culture
21 | void Translate(CultureInfo cultureInfo);
22 | ///
23 | /// Changes the localization in .cs files that contains strings that you cannot change inside the page.
24 | /// Functions contain neat parameters that help modify source strings, like in C#, but inside a Resource file.
25 | /// Example will be: Your path is %1. %1 → path. | Output: Your path is: C:\Users\...
26 | /// where % is the definition of parameter, and 1…n is the hierarchy of parameters passed to the function.
27 | ///
28 | /// string that you are accessing in Localization\*culture-info*.axaml file
29 | /// parameters in hierarchy, example: %1, %2, %3, "10", "20, "30" | output: 10, 20, 30
30 | string TranslateSource(string key, params string[] replaces);
31 | }
32 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/Config/LinuxConfig.cs:
--------------------------------------------------------------------------------
1 | using CommunityToolkit.Mvvm.ComponentModel;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.IO;
5 |
6 | namespace SIT.Manager.Models.Config;
7 |
8 | public partial class LinuxConfig : ObservableObject
9 | {
10 | public static readonly string BaseDir = AppContext.BaseDirectory;
11 | public static readonly string RuntimeDir = Path.Combine(BaseDir, "runtime");
12 |
13 | [ObservableProperty]
14 | public string _winePrefix = string.Empty;
15 | [ObservableProperty]
16 | public string _wineRunner = string.Empty;
17 | [ObservableProperty]
18 | public Dictionary _wineEnv = [];
19 | [ObservableProperty]
20 | public bool _isDXVKEnabled = true;
21 | [ObservableProperty]
22 | public bool _isVKD3DEnabled = false;
23 | [ObservableProperty]
24 | public bool _isD3DExtrasEnabled = false;
25 | [ObservableProperty]
26 | public bool _isDXVK_NVAPIEnabled = false;
27 | [ObservableProperty]
28 | public bool _isDGVoodoo2Enabled = false;
29 | [ObservableProperty]
30 | public bool _isEsyncEnabled = true;
31 | [ObservableProperty]
32 | public bool _isFsyncEnabled = false;
33 | [ObservableProperty]
34 | public bool _isWineFsrEnabled = false;
35 | [ObservableProperty]
36 | public bool _isMangoHudEnabled = false;
37 | [ObservableProperty]
38 | public bool _isGameModeEnabled = false;
39 |
40 | static LinuxConfig()
41 | {
42 | // make directories if they don't exist
43 | if (!Directory.Exists(RuntimeDir))
44 | {
45 | Directory.CreateDirectory(RuntimeDir);
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/SIT.Manager/Views/Play/LoginDialogView.axaml:
--------------------------------------------------------------------------------
1 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/SIT.Manager/Theme/Styles/Button.axaml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
12 |
13 |
14 |
15 |
16 |
19 |
20 |
23 |
24 |
25 |
33 |
34 |
37 |
38 |
41 |
42 |
45 |
46 |
--------------------------------------------------------------------------------
/SIT.Manager/ViewModels/Play/CreateCharacterDialogViewModel.cs:
--------------------------------------------------------------------------------
1 | using CommunityToolkit.Mvvm.ComponentModel;
2 | using SIT.Manager.Extentions;
3 | using SIT.Manager.Models;
4 | using System.Collections.ObjectModel;
5 | using System.ComponentModel.DataAnnotations;
6 | using System.Linq;
7 |
8 | namespace SIT.Manager.ViewModels.Play;
9 |
10 | public partial class CreateCharacterDialogViewModel : ObservableValidator
11 | {
12 | [ObservableProperty]
13 | private bool _saveLoginDetails = false;
14 |
15 | private string _username = string.Empty;
16 | private string _password = string.Empty;
17 |
18 | [Required]
19 | public string Username
20 | {
21 | get => _username;
22 | set
23 | {
24 | SetProperty(ref _username, value, true);
25 | OnPropertyChanged(nameof(CanCreateCharacter));
26 | }
27 | }
28 |
29 | [Required]
30 | public string Password
31 | {
32 | get => _password;
33 | set
34 | {
35 | SetProperty(ref _password, value, true);
36 | OnPropertyChanged(nameof(CanCreateCharacter));
37 | }
38 | }
39 |
40 | [ObservableProperty]
41 | private TarkovEdition _selectedEdition;
42 |
43 | public ObservableCollection Editions { get; } = [];
44 |
45 | public bool CanCreateCharacter => !HasErrors;
46 |
47 | public CreateCharacterDialogViewModel(string username, string password, bool rememberLogin, TarkovEdition[] editions)
48 | {
49 | Username = username;
50 | Password = password;
51 | SaveLoginDetails = rememberLogin;
52 |
53 | Editions.AddRange(editions);
54 | SelectedEdition = Editions.First();
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/Github/GithubAuthor.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json.Serialization;
2 |
3 | namespace SIT.Manager.Models.Github;
4 |
5 | public class GithubAuthor
6 | {
7 | [JsonPropertyName("login")]
8 | public string? Login { get; set; }
9 | [JsonPropertyName("id")]
10 | public int Id { get; set; }
11 | [JsonPropertyName("node_id")]
12 | public string? NodeId { get; set; }
13 | [JsonPropertyName("avatar_url")]
14 | public string? AvatarUrl { get; set; }
15 | [JsonPropertyName("gravatar_id")]
16 | public string? GravatarId { get; set; }
17 | [JsonPropertyName("url")]
18 | public string? Url { get; set; }
19 | [JsonPropertyName("html_url")]
20 | public string? HtmlUrl { get; set; }
21 | [JsonPropertyName("followers_url")]
22 | public string? FollowersUrl { get; set; }
23 | [JsonPropertyName("following_url")]
24 | public string? FollowingUrl { get; set; }
25 | [JsonPropertyName("gists_url")]
26 | public string? GistsUrl { get; set; }
27 | [JsonPropertyName("starred_url")]
28 | public string? StarredUrl { get; set; }
29 | [JsonPropertyName("subscriptions_url")]
30 | public string? SubscriptionsUrl { get; set; }
31 | [JsonPropertyName("organizations_url")]
32 | public string? OrganizationsUrl { get; set; }
33 | [JsonPropertyName("repos_url")]
34 | public string? ReposUrl { get; set; }
35 | [JsonPropertyName("events_url")]
36 | public string? EventsUrl { get; set; }
37 | [JsonPropertyName("received_events_url")]
38 | public string? ReceivedEventsUrl { get; set; }
39 | [JsonPropertyName("type")]
40 | public string? Type { get; set; }
41 | [JsonPropertyName("site_admin")]
42 | public bool SiteAdmin { get; set; }
43 | }
44 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/Github/GithubUploader.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json.Serialization;
2 |
3 | namespace SIT.Manager.Models.Github;
4 |
5 | public class GithubUploader
6 | {
7 | [JsonPropertyName("login")]
8 | public string? Login { get; set; }
9 | [JsonPropertyName("id")]
10 | public int Id { get; set; }
11 | [JsonPropertyName("node_id")]
12 | public string? NodeId { get; set; }
13 | [JsonPropertyName("avatar_url")]
14 | public string? AvatarUrl { get; set; }
15 | [JsonPropertyName("gravatar_id")]
16 | public string? GravatarId { get; set; }
17 | [JsonPropertyName("url")]
18 | public string? Url { get; set; }
19 | [JsonPropertyName("html_url")]
20 | public string? HtmlUrl { get; set; }
21 | [JsonPropertyName("followers_url")]
22 | public string? FollowersUrl { get; set; }
23 | [JsonPropertyName("following_url")]
24 | public string? FollowingUrl { get; set; }
25 | [JsonPropertyName("gists_url")]
26 | public string? GistsUrl { get; set; }
27 | [JsonPropertyName("starred_url")]
28 | public string? StarredUrl { get; set; }
29 | [JsonPropertyName("subscriptions_url")]
30 | public string? SubscriptionsUrl { get; set; }
31 | [JsonPropertyName("organizations_url")]
32 | public string? OrganizationsUrl { get; set; }
33 | [JsonPropertyName("repos_url")]
34 | public string? ReposUrl { get; set; }
35 | [JsonPropertyName("events_url")]
36 | public string? EventsUrl { get; set; }
37 | [JsonPropertyName("received_events_url")]
38 | public string? ReceivedEventsUrl { get; set; }
39 | [JsonPropertyName("type")]
40 | public string? Type { get; set; }
41 | [JsonPropertyName("site_admin")]
42 | public bool SiteAdmin { get; set; }
43 | }
44 |
--------------------------------------------------------------------------------
/SIT.Manager/Views/ServerPage.axaml.cs:
--------------------------------------------------------------------------------
1 | using Avalonia;
2 | using Avalonia.Controls;
3 | using Microsoft.Extensions.DependencyInjection;
4 | using SIT.Manager.Theme.Controls;
5 | using SIT.Manager.ViewModels;
6 |
7 | namespace SIT.Manager.Views;
8 |
9 | public partial class ServerPage : ActivatableUserControl
10 | {
11 | private bool _autoScroll = true;
12 | private readonly ScrollViewer? _consoleLogScroller;
13 |
14 | public ServerPage()
15 | {
16 | DataContext = App.Current.Services.GetService();
17 |
18 | InitializeComponent();
19 | _consoleLogScroller = this.FindControl("ConsoleLogScroller");
20 | }
21 |
22 | private void ConsoleLogScroller_ScrollChanged(object? sender, ScrollChangedEventArgs e)
23 | {
24 | // User scroll event : set or unset auto-scroll mode
25 | if (e.ExtentDelta == Vector.Zero)
26 | {
27 | // Content unchanged : user scroll event
28 | if (_consoleLogScroller?.Offset.Y == _consoleLogScroller?.ScrollBarMaximum.Y)
29 | {
30 | // Scroll bar is in bottom
31 | // Set auto-scroll mode
32 | _autoScroll = true;
33 | }
34 | else
35 | {
36 | // Scroll bar isn't in bottom
37 | // Unset auto-scroll mode
38 | _autoScroll = false;
39 | }
40 | }
41 |
42 | // Content scroll event : auto-scroll eventually
43 | if (_autoScroll && e.ExtentDelta != Vector.Zero)
44 | {
45 | // Content changed and auto-scroll mode set
46 | // Autoscroll
47 | _consoleLogScroller?.ScrollToEnd();
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/Github/GithubRelease.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text.Json.Serialization;
4 |
5 | namespace SIT.Manager.Models.Github;
6 |
7 | public class GithubRelease
8 | {
9 | [JsonPropertyName("url")]
10 | public string? Url { get; set; }
11 | [JsonPropertyName("html_url")]
12 | public string HtmlUrl { get; set; } = string.Empty;
13 | [JsonPropertyName("assets_url")]
14 | public string? AssetsUrl { get; set; }
15 | [JsonPropertyName("upload_url")]
16 | public string? UploadUrl { get; set; }
17 | [JsonPropertyName("tarball_url")]
18 | public string? TarballUrl { get; set; }
19 | [JsonPropertyName("zipball_url")]
20 | public string? ZipballUrl { get; set; }
21 | [JsonPropertyName("id")]
22 | public int Id { get; set; }
23 | [JsonPropertyName("node_id")]
24 | public string? NodeId { get; set; }
25 | [JsonPropertyName("tag_name")]
26 | public string TagName { get; set; } = string.Empty;
27 | [JsonPropertyName("target_commitish")]
28 | public string? TargetCommitish { get; set; }
29 | [JsonPropertyName("name")]
30 | public string Name { get; set; } = string.Empty;
31 | [JsonPropertyName("body")]
32 | public string Body { get; set; } = string.Empty;
33 | [JsonPropertyName("draft")]
34 | public bool Draft { get; set; }
35 | [JsonPropertyName("prerelease")]
36 | public bool Prerelease { get; set; } = false;
37 | [JsonPropertyName("created_at")]
38 | public DateTime CreatedAt { get; set; }
39 | [JsonPropertyName("published_at")]
40 | public DateTime PublishedAt { get; set; }
41 | [JsonPropertyName("author")]
42 | public GithubAuthor? Author { get; set; }
43 | [JsonPropertyName("assets")]
44 | public List Assets { get; set; } = [];
45 | }
46 |
--------------------------------------------------------------------------------
/SIT.Manager/Views/Dialogs/SelectLogsDialog.axaml:
--------------------------------------------------------------------------------
1 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/SIT.Manager.Desktop/SIT.Manager.Desktop.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | app.manifest
4 | true
5 | enable
6 | WinExe
7 | true
8 | False
9 | true
10 |
12 | net8.0
13 | CopyUsed
14 | ../SIT.Manager/Assets/Stay-In-Tarkov-512.ico
15 |
16 |
17 |
18 | SIT.Manager
19 | StayInTarkov
20 | SIT.Manager
21 |
22 |
23 |
24 |
25 | $(Version)
26 | 0
27 | $(Version)
28 | 0
29 | 2.3.$(BuildNumber).$(RevisionNumber)
30 |
31 |
32 |
33 |
34 | PreserveNewest
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/Gitea/GiteaAuthor.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text.Json.Serialization;
3 |
4 | namespace SIT.Manager.Models.Gitea;
5 |
6 | public class GiteaAuthor
7 | {
8 | [JsonPropertyName("active")]
9 | public bool Active { get; set; }
10 | [JsonPropertyName("avatar_url")]
11 | public string? AvatarUrl { get; set; }
12 | [JsonPropertyName("created")]
13 | public DateTime Created { get; set; }
14 | [JsonPropertyName("description")]
15 | public string? Description { get; set; }
16 | [JsonPropertyName("email")]
17 | public string? Email { get; set; }
18 | [JsonPropertyName("followers_count")]
19 | public int FollowersCount { get; set; }
20 | [JsonPropertyName("following_count")]
21 | public int FollowingCount { get; set; }
22 | [JsonPropertyName("full_name")]
23 | public string? FullName { get; set; }
24 | [JsonPropertyName("id")]
25 | public int Id { get; set; }
26 | [JsonPropertyName("is_admin")]
27 | public bool IsAdmin { get; set; }
28 | [JsonPropertyName("language")]
29 | public string? Language { get; set; }
30 | [JsonPropertyName("last_login")]
31 | public DateTime LastLogin { get; set; }
32 | [JsonPropertyName("location")]
33 | public string? Location { get; set; }
34 | [JsonPropertyName("login")]
35 | public string? Login { get; set; }
36 | [JsonPropertyName("login_name")]
37 | public string? LoginName { get; set; }
38 | [JsonPropertyName("prohibit_login")]
39 | public bool ProhibitLogin { get; set; }
40 | [JsonPropertyName("restricted")]
41 | public bool Restricted { get; set; }
42 | [JsonPropertyName("starred_repos_count")]
43 | public int StarredReposCount { get; set; }
44 | [JsonPropertyName("visibility")]
45 | public string? Visibility { get; set; }
46 | [JsonPropertyName("website")]
47 | public string? Website { get; set; }
48 | }
49 |
--------------------------------------------------------------------------------
/SIT.Manager/Services/Install/EFTGameFinder.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Win32;
2 | using System.IO;
3 |
4 | namespace SIT.Manager.Services.Install;
5 |
6 | internal static class EFTGameFinder
7 | {
8 | private static bool CheckGameIsValid(string path)
9 | {
10 | bool validGame = false;
11 | try
12 | {
13 | if (!string.IsNullOrEmpty(path))
14 | {
15 | validGame = LC1A(path);
16 | validGame = LC2B(path) && validGame;
17 | validGame = LC3C(path) && validGame;
18 | }
19 | }
20 | catch { }
21 | return validGame;
22 | }
23 |
24 | private static string GetGameExePath()
25 | {
26 | using (RegistryKey? key = Registry.LocalMachine.OpenSubKey(@"Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\EscapeFromTarkov"))
27 | {
28 | if (key != null)
29 | {
30 | return key.GetValue("DisplayIcon")?.ToString() ?? string.Empty;
31 | }
32 | }
33 | return string.Empty;
34 | }
35 |
36 | private static bool LC1A(string gfp)
37 | {
38 | FileInfo fiGFP = new(gfp);
39 | return (fiGFP.Exists && fiGFP.Length >= 647 * 1000);
40 | }
41 |
42 | private static bool LC2B(string gfp)
43 | {
44 | FileInfo fiBE = new(gfp.Replace(".exe", "_BE.exe"));
45 | return (fiBE.Exists && fiBE.Length >= 1024000);
46 | }
47 |
48 | private static bool LC3C(string gfp)
49 | {
50 | DirectoryInfo diBattlEye = new(gfp.Replace("EscapeFromTarkov.exe", "BattlEye"));
51 | return (diBattlEye.Exists);
52 | }
53 |
54 | public static string FindOfficialGamePath()
55 | {
56 | string gamePath = GetGameExePath();
57 | if (CheckGameIsValid(gamePath))
58 | {
59 | return gamePath;
60 | }
61 | return string.Empty;
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/SIT.Manager/Services/Caching/CacheEntry.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Text.Json;
6 | using System.Text.Json.Serialization;
7 | using System.Threading.Tasks;
8 |
9 | namespace SIT.Manager.Services.Caching;
10 | internal class CacheEntry
11 | {
12 | private object _cacheValue;
13 | public string Key { get; private set; }
14 | public DateTime ExpiryDate { get; private set; }
15 | public DateTime LastAccess { get; private set; } = default;
16 | public DateTime LastModified { get; private set; } = DateTime.Now;
17 | public object Value
18 | {
19 | get
20 | {
21 | LastAccess = DateTime.UtcNow;
22 | return _cacheValue;
23 | }
24 | set
25 | {
26 | _cacheValue = value;
27 | LastAccess = DateTime.UtcNow;
28 | LastModified = DateTime.UtcNow;
29 | }
30 | }
31 |
32 | [JsonConstructor]
33 | public CacheEntry(string key, object value, DateTime expiryDate)
34 | {
35 | this.Key = key;
36 | this._cacheValue = value;
37 | this.ExpiryDate = expiryDate;
38 | }
39 |
40 | public T GetValue()
41 | {
42 | object val = Value;
43 |
44 | Type type = typeof(T);
45 | Type? underlying = Nullable.GetUnderlyingType(type);
46 | if(type.IsPrimitive)
47 | {
48 | if(underlying == null)
49 | {
50 | return (T) Convert.ChangeType(val, type);
51 | }
52 | else
53 | {
54 | return (T) Convert.ChangeType(val, underlying);
55 | }
56 | }
57 |
58 | if(val.GetType() == typeof(JsonElement))
59 | {
60 | JsonElement jsonElement = (JsonElement) val;
61 | return jsonElement.Deserialize();
62 | }
63 |
64 | return (T) val;
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/SIT.Manager/ViewModels/UpdatePageViewModel.cs:
--------------------------------------------------------------------------------
1 | using CommunityToolkit.Mvvm.ComponentModel;
2 | using CommunityToolkit.Mvvm.Messaging;
3 | using SIT.Manager.Interfaces;
4 | using SIT.Manager.Models.Installation;
5 | using System;
6 | using System.Threading.Tasks;
7 |
8 | namespace SIT.Manager.ViewModels;
9 |
10 | public partial class UpdatePageViewModel : ObservableRecipient
11 | {
12 | private readonly IAppUpdaterService _appUpdaterService;
13 |
14 | private readonly Progress _updateProgress;
15 |
16 | [ObservableProperty]
17 | private double _updateProgressPercentage;
18 |
19 | [ObservableProperty]
20 | private bool _hasError = false;
21 |
22 | public UpdatePageViewModel(IAppUpdaterService appUpdaterService)
23 | {
24 | _appUpdaterService = appUpdaterService;
25 |
26 | _updateProgress = new Progress(prog => UpdateProgressPercentage = prog);
27 | }
28 |
29 | private async Task DoUpdateApp()
30 | {
31 | Messenger.Send(new InstallationRunningMessage(true));
32 | await Task.Delay(500);
33 |
34 | #if DEBUG
35 | // For debug builds don't actually allow the app to be updated and instead just mimic the action
36 | for (int i = 0; i < 100; i++)
37 | {
38 | UpdateProgressPercentage = i;
39 | await Task.Delay(Random.Shared.Next(1000));
40 | }
41 | Messenger.Send(new InstallationRunningMessage(false));
42 | #else
43 | bool updateResult = await _appUpdaterService.Update(_updateProgress);
44 | if (updateResult)
45 | {
46 | _appUpdaterService.RestartApp();
47 | }
48 | else
49 | {
50 | HasError = true;
51 | Messenger.Send(new InstallationRunningMessage(false));
52 | }
53 | #endif
54 | }
55 |
56 | protected override async void OnActivated()
57 | {
58 | base.OnActivated();
59 | await DoUpdateApp();
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/SIT.Manager/Services/PickerDialogService.cs:
--------------------------------------------------------------------------------
1 | using Avalonia.Controls;
2 | using Avalonia.Platform.Storage;
3 | using SIT.Manager.Interfaces;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Threading.Tasks;
7 |
8 | namespace SIT.Manager.Services;
9 |
10 | public class PickerDialogService(Window target) : IPickerDialogService
11 | {
12 | private readonly Window _target = target;
13 |
14 | public async Task GetDirectoryFromPickerAsync()
15 | {
16 | try
17 | {
18 | IReadOnlyList folders = await _target.StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions()
19 | {
20 | AllowMultiple = false
21 | });
22 |
23 | if (folders.Count != 0)
24 | {
25 | return folders[0];
26 | }
27 | }
28 | catch (ArgumentException)
29 | {
30 | // The likely reason is the folder selected doesn't exist so we should just be able to return null as with other things.
31 | }
32 | return null;
33 | }
34 |
35 | public async Task GetFileFromPickerAsync()
36 | {
37 | IReadOnlyList files = await _target.StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions()
38 | {
39 | AllowMultiple = false
40 | });
41 |
42 | if (files.Count != 0)
43 | {
44 | return files[0];
45 | }
46 | return null;
47 | }
48 |
49 | public async Task GetFileSaveFromPickerAsync(string defaultFileExtension = "", string suggestedFileName = "")
50 | {
51 | IStorageFile? file = await _target.StorageProvider.SaveFilePickerAsync(new FilePickerSaveOptions()
52 | {
53 | DefaultExtension = defaultFileExtension,
54 | SuggestedFileName = suggestedFileName
55 | });
56 | return file;
57 | }
58 |
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/SIT.Manager/Theme/Palette.axaml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
6 |
7 |
9 |
11 |
13 |
15 |
16 |
17 |
19 |
21 |
23 |
25 |
27 |
29 |
31 |
33 |
34 |
35 |
36 |
37 |
38 | #20AFAFAF
39 | #10AFAFAF
40 | #000000
41 | #DB162F
42 | #060606
43 | #FFFCFF
44 | #4D8B31
45 | #E98A15
46 |
47 |
--------------------------------------------------------------------------------
/SIT.Manager/Views/MainWindow.axaml.cs:
--------------------------------------------------------------------------------
1 | using Avalonia.Media;
2 | using FluentAvalonia.UI.Windowing;
3 | using Microsoft.Extensions.DependencyInjection;
4 | using SIT.Manager.Interfaces;
5 | using SIT.Manager.Interfaces.ManagedProcesses;
6 | using System;
7 |
8 | namespace SIT.Manager.Views;
9 |
10 | public partial class MainWindow : AppWindow
11 | {
12 | public MainWindow()
13 | {
14 | InitializeComponent();
15 | TitleBar.BackgroundColor = new Color(0xFF, 0x00, 0x00, 0x00);
16 | TitleBar.ForegroundColor = new Color(0xFF, 0xFF, 0xFF, 0xFF);
17 | TitleBar.InactiveBackgroundColor = new Color(0xFF, 0x00, 0x00, 0x00);
18 | TitleBar.InactiveForegroundColor = new Color(0xFF, 0xFF, 0xFF, 0xFF);
19 | TitleBar.ButtonBackgroundColor = new Color(0xFF, 0x00, 0x00, 0x00);
20 | TitleBar.ButtonForegroundColor = new Color(0xFF, 0xFF, 0xFF, 0xFF);
21 | TitleBar.ButtonHoverBackgroundColor = new Color(0xFF, 0x11, 0x11, 0x11);
22 | TitleBar.ButtonHoverForegroundColor = new Color(0xFF, 0xFF, 0xFF, 0xFF);
23 | TitleBar.ButtonPressedBackgroundColor = new Color(0xFF, 0x21, 0x21, 0x21);
24 | TitleBar.ButtonPressedForegroundColor = new Color(0xFF, 0xFF, 0xFF, 0xFF);
25 | TitleBar.ButtonInactiveBackgroundColor = new Color(0xFF, 0x00, 0x00, 0x00);
26 | TitleBar.ButtonInactiveForegroundColor = new Color(0xFF, 0xFF, 0xFF, 0xFF);
27 | }
28 |
29 | private void Window_Closed(object? sender, EventArgs e)
30 | {
31 | IAkiServerService? akiServerService = App.Current.Services.GetService();
32 | IManagerConfigService? managerConfig = App.Current.Services.GetService();
33 |
34 | bool serverProcessRunning = akiServerService?.State == RunningState.Running || akiServerService?.State == RunningState.Starting;
35 | if (serverProcessRunning && (!managerConfig?.Config.CloseAfterLaunch ?? true))
36 | {
37 | akiServerService?.Stop();
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/SIT.Manager/Extentions/StreamExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.IO.Compression;
5 | using System.Linq;
6 | using System.Text;
7 | using System.Threading;
8 | using System.Threading.Tasks;
9 |
10 | namespace SIT.Manager.Extentions;
11 | public static class StreamExtensions
12 | {
13 | public static async Task CopyToAsync(this Stream source, Stream destination, ushort bufferSize, IProgress progressReporter, CancellationToken cancellationToken = default)
14 | {
15 | ArgumentNullException.ThrowIfNull(source, nameof(source));
16 | ArgumentNullException.ThrowIfNull(destination, nameof(destination));
17 | if (!source.CanRead)
18 | throw new InvalidOperationException($"'{nameof(source)}' is not readable.");
19 | if (!destination.CanWrite)
20 | throw new InvalidOperationException($"'{nameof(destination)}' is not writable.");
21 |
22 | byte[] dataBuffer = new byte[bufferSize];
23 | long totalReadBytes = 0;
24 | int bytesRead;
25 | while ((bytesRead = await source.ReadAsync(dataBuffer, cancellationToken).ConfigureAwait(false)) > 0)
26 | {
27 | await destination.WriteAsync(dataBuffer.AsMemory(0, bytesRead), cancellationToken).ConfigureAwait(false);
28 | totalReadBytes += bytesRead;
29 | progressReporter.Report(totalReadBytes);
30 | }
31 | }
32 |
33 | public static async Task InflateAsync(this Stream zlibDataSource, CancellationToken cancellationToken = default)
34 | {
35 | MemoryStream ms = new();
36 | using ZLibStream inflateStream = new(zlibDataSource, CompressionMode.Decompress);
37 | await inflateStream.CopyToAsync(ms, cancellationToken);
38 | ms.Seek(0, SeekOrigin.Begin);
39 | return ms;
40 | }
41 |
42 | public static async Task ReadAsStringAsync(this Stream stream, CancellationToken cancellationToken = default)
43 | => await new StreamReader(stream).ReadToEndAsync(cancellationToken);
44 | }
45 |
--------------------------------------------------------------------------------
/SIT.Manager/ViewModels/Play/CreateServerDialogViewModel.cs:
--------------------------------------------------------------------------------
1 | using CommunityToolkit.Mvvm.ComponentModel;
2 | using SIT.Manager.Interfaces;
3 | using System;
4 | using System.ComponentModel.DataAnnotations;
5 |
6 | namespace SIT.Manager.ViewModels.Play;
7 |
8 | public partial class CreateServerDialogViewModel : ObservableValidator
9 | {
10 | private readonly ILocalizationService _localizationService;
11 |
12 | [ObservableProperty]
13 | private string _serverNickname = string.Empty;
14 |
15 | private string _serverAddress = string.Empty;
16 |
17 | [CustomValidation(typeof(CreateServerDialogViewModel), nameof(ValidateAddress))]
18 | [Required]
19 | public string ServerAddress
20 | {
21 | get => _serverAddress;
22 | set
23 | {
24 | SetProperty(ref _serverAddress, value, true);
25 | OnPropertyChanged(nameof(CanCreateServer));
26 | }
27 | }
28 |
29 | public Uri ServerUri => ValidateAddress(ServerAddress, new ValidationContext(this)) == ValidationResult.Success ? new(ServerAddress) : new Uri("http://127.0.0.1");
30 |
31 | public bool CanCreateServer => !HasErrors;
32 |
33 | public string AddOrEditTitle { get; }
34 |
35 | public CreateServerDialogViewModel(string currentServerAddress, string serverNickname, bool isEdit, ILocalizationService localizationService)
36 | {
37 | _localizationService = localizationService;
38 |
39 | ServerAddress = currentServerAddress;
40 | ServerNickname = serverNickname;
41 |
42 | if (isEdit)
43 | {
44 | AddOrEditTitle = _localizationService.TranslateSource("CreateServerDialogViewEditTitle");
45 | }
46 | else
47 | {
48 | AddOrEditTitle = _localizationService.TranslateSource("CreateServerDialogViewAddTitle");
49 | }
50 | }
51 |
52 | public static ValidationResult? ValidateAddress(string serverAddress, ValidationContext context)
53 | {
54 | CreateServerDialogViewModel vm = (CreateServerDialogViewModel) context.ObjectInstance;
55 |
56 | vm.ClearErrors();
57 | return Uri.IsWellFormedUriString(serverAddress, UriKind.Absolute) ? ValidationResult.Success : new("Uri is not in a valid format.");
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/SIT.Manager/ViewModels/Settings/SettingsViewModelBase.cs:
--------------------------------------------------------------------------------
1 | using Avalonia.Platform.Storage;
2 | using CommunityToolkit.Mvvm.ComponentModel;
3 | using SIT.Manager.Interfaces;
4 | using SIT.Manager.Models.Config;
5 | using System.ComponentModel;
6 | using System.IO;
7 | using System.Threading.Tasks;
8 |
9 | namespace SIT.Manager.ViewModels.Settings;
10 |
11 | public partial class SettingsViewModelBase : ObservableRecipient
12 | {
13 | protected readonly IManagerConfigService _configsService;
14 | protected readonly IPickerDialogService _pickerDialogService;
15 |
16 | [ObservableProperty]
17 | private ManagerConfig _config = new();
18 |
19 | protected SettingsViewModelBase(IManagerConfigService configService, IPickerDialogService pickerDialogService)
20 | {
21 | _configsService = configService;
22 | _pickerDialogService = pickerDialogService;
23 | }
24 |
25 | private void Config_PropertyChanged(object? sender, PropertyChangedEventArgs e)
26 | {
27 | _configsService.UpdateConfig(Config);
28 | }
29 |
30 | ///
31 | /// Gets the path containing the required filename based on the folder picker selection from a user
32 | ///
33 | /// The filename to look for in the user specified directory
34 | /// The path if the file exists, otherwise an empty string
35 | protected async Task GetPathLocation(string filename)
36 | {
37 | IStorageFolder? directorySelected = await _pickerDialogService.GetDirectoryFromPickerAsync();
38 | if (directorySelected != null)
39 | {
40 | if (File.Exists(Path.Combine(directorySelected.Path.LocalPath, filename)))
41 | {
42 | return directorySelected.Path.LocalPath;
43 | }
44 | }
45 | return string.Empty;
46 | }
47 |
48 | protected override void OnActivated()
49 | {
50 | base.OnActivated();
51 |
52 | Config = _configsService.Config;
53 | Config.PropertyChanged += Config_PropertyChanged;
54 | }
55 |
56 | protected override void OnDeactivated()
57 | {
58 | base.OnDeactivated();
59 | Config.PropertyChanged -= Config_PropertyChanged;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/SIT.Manager/Native/Linux/DllManager.cs:
--------------------------------------------------------------------------------
1 | using SIT.Manager.Models.Config;
2 | using SIT.Manager.Native.Linux.Managers;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 |
7 | namespace SIT.Manager.Native.Linux;
8 |
9 | public abstract class DllManager(string component, IEnumerable dlls, string baseDir, string releaseUrl, IEnumerable? managedAppDataFiles = null)
10 | {
11 | public readonly string Component = component;
12 | protected string BaseDir = baseDir;
13 | protected IEnumerable? ManagedAppDataFiles = managedAppDataFiles; // TODO: implement this
14 | protected string ReleaseUrl = releaseUrl; // TODO: do something with this
15 |
16 | private static readonly Dictionary Managers = new()
17 | {
18 | { "IsDXVKEnabled", new DxvkManager() },
19 | { "IsVKD3DEnabled", new Vkd3DManager() },
20 | { "IsD3DExtrasEnabled", new D3DExtrasManager() },
21 | // // TODO: implement these \/ \/ \/
22 | { "IsDXVK_NVAPIEnabled", new DxvkNvapiManager() },
23 | { "IsDGVoodoo2Enabled", new Dgvoodoo2Manager() }
24 | };
25 |
26 | private string GetDllOverrideString()
27 | {
28 | return dlls.Aggregate("", (current, dll) => current + "," + dll).Remove(0, 1);
29 | }
30 |
31 | public static string GetDllOverride(LinuxConfig config)
32 | {
33 | // Collect every DLL override string from every manager and collect them per Mode if the setting is enabled
34 | // Then all dlls with the same mode are grouped together and separated by a comma with the last one ending with an = sign and then the mode and a semicolon
35 | // Example: "d3d9=,d3d10,d3d10core,d3d11,d3d12,dxgi=n;other_dlls,...,="
36 | // If no DLLs are enabled for a mode, it will be omitted
37 | StringBuilder sb = new();
38 | foreach (KeyValuePair manager in Managers.Where(manager =>
39 | config.GetType().GetProperty(manager.Key)?.GetValue(config) is true))
40 | {
41 | sb.Append(manager.Value.GetDllOverrideString());
42 | }
43 | string result = sb.ToString();
44 |
45 | return string.IsNullOrEmpty(result) ? "winemenubuilder=" : result + "=n;winemenubuilder=";
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/SIT.Manager/Views/InstallPage.axaml:
--------------------------------------------------------------------------------
1 |
12 |
13 |
17 |
18 |
19 |
20 |
23 |
24 |
25 |
26 |
27 |
34 |
35 |
36 |
41 |
42 |
43 |
44 |
45 |
46 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/SIT.Manager/Views/UpdatePage.axaml:
--------------------------------------------------------------------------------
1 |
11 |
14 |
18 |
20 |
22 |
24 |
25 |
26 |
32 |
40 |
46 |
47 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/SIT.Manager/Views/Play/CreateCharacterDialogView.axaml:
--------------------------------------------------------------------------------
1 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/SIT.Manager/Views/Play/ServerSelectionView.axaml:
--------------------------------------------------------------------------------
1 |
12 |
14 |
16 |
17 |
18 |
24 |
25 |
26 |
30 |
31 |
36 |
37 |
38 |
39 |
42 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/SIT.Manager/Services/ManagedProcesses/ManagedProcess.cs:
--------------------------------------------------------------------------------
1 | using SIT.Manager.Interfaces;
2 | using SIT.Manager.Interfaces.ManagedProcesses;
3 | using System;
4 | using System.Diagnostics;
5 | using System.IO;
6 |
7 | namespace SIT.Manager.Services.ManagedProcesses;
8 |
9 | public abstract class ManagedProcess(IBarNotificationService barNotificationService, IManagerConfigService configService) : IManagedProcess
10 | {
11 | protected readonly IBarNotificationService _barNotificationService = barNotificationService;
12 | protected readonly IManagerConfigService _configService = configService;
13 |
14 | protected abstract string EXECUTABLE_NAME { get; }
15 | protected Process? _process;
16 | protected bool _stopRequest = false;
17 | public abstract string ExecutableDirectory { get; }
18 | public string ExecutableFilePath => !string.IsNullOrEmpty(ExecutableDirectory) ? Path.Combine(ExecutableDirectory, EXECUTABLE_NAME) : string.Empty;
19 |
20 | public RunningState State { get; protected set; } = RunningState.NotRunning;
21 |
22 | public event EventHandler? RunningStateChanged;
23 | protected virtual void ExitedEvent(object? sender, EventArgs e)
24 | {
25 | RunningState newState = State == RunningState.Running && !_stopRequest ? RunningState.StoppedUnexpectedly : RunningState.NotRunning;
26 | _stopRequest = false;
27 | UpdateRunningState(newState);
28 | }
29 |
30 | protected void UpdateRunningState(RunningState newState)
31 | {
32 | State = newState;
33 | //It's 3am, this probably sucks, idk anymore
34 | RunningStateChanged?.Invoke(this, State);
35 | }
36 |
37 | public abstract void ClearCache();
38 |
39 | public abstract void Start(string? arguments);
40 |
41 | public virtual void Stop()
42 | {
43 | if (State == RunningState.NotRunning || _process == null || _process.HasExited)
44 | {
45 | return;
46 | }
47 |
48 | _stopRequest = true;
49 |
50 | bool closed = false;
51 | // Stop the server process
52 | if (_process.CloseMainWindow())
53 | {
54 | closed = _process.WaitForExit(TimeSpan.FromSeconds(5));
55 | }
56 |
57 | if (!closed)
58 | {
59 | _process.Kill();
60 | _process.WaitForExit(TimeSpan.FromSeconds(5));
61 | }
62 |
63 | //This seems to cause the deadlock?
64 | //_process.Close();
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/SIT.Manager/Services/Caching/InMemoryCachingProvider.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.Logging;
2 | using System;
3 |
4 | namespace SIT.Manager.Services.Caching;
5 |
6 | internal class InMemoryCachingProvider(string cachePath, ILogger logger) : CachingProviderBase(cachePath)
7 | {
8 | private const string RESTORE_FILE_NAME = "memoryCache.dat";
9 |
10 | private readonly ILogger _logger = logger;
11 |
12 | protected override string RestoreFileName => RESTORE_FILE_NAME;
13 |
14 | public override CacheValue Get(string key)
15 | {
16 | ArgumentException.ThrowIfNullOrWhiteSpace(key, nameof(key));
17 |
18 | if (!_cacheMap.TryGetValue(key, out CacheEntry? cacheEntry))
19 | return CacheValue.NoValue;
20 |
21 | if (cacheEntry.ExpiryDate < DateTime.UtcNow)
22 | {
23 | if (Remove(cacheEntry.Key))
24 | OnEvictedTenant(new EvictedEventArgs(cacheEntry.Key));
25 | return CacheValue.NoValue;
26 | }
27 |
28 | try
29 | {
30 | T value = cacheEntry.GetValue();
31 | return new CacheValue(value, true);
32 | }
33 | catch (Exception ex)
34 | {
35 | _logger.LogError(ex, "An error occured while casting value to generic");
36 | return CacheValue.NoValue;
37 | }
38 | }
39 |
40 | public override bool Add(string key, T value, TimeSpan? expiryTime = null)
41 | {
42 | ArgumentException.ThrowIfNullOrWhiteSpace(key, nameof(key));
43 | ArgumentNullException.ThrowIfNull(value, nameof(value));
44 |
45 | DateTime expiryDate = DateTime.UtcNow + (expiryTime ?? TimeSpan.FromMinutes(15));
46 | CacheEntry cacheEntry = new(key, value, expiryDate);
47 | if (expiryDate < DateTime.UtcNow)
48 | {
49 | if (Remove(cacheEntry.Key))
50 | OnEvictedTenant(new EvictedEventArgs(cacheEntry.Key));
51 | return false;
52 | }
53 |
54 | if (_cacheMap.TryAdd(cacheEntry.Key, cacheEntry))
55 | return true;
56 |
57 | if (!_cacheMap.TryGetValue(cacheEntry.Key, out CacheEntry? existingEntry) || existingEntry.ExpiryDate < DateTime.UtcNow)
58 | return false;
59 |
60 | _cacheMap.AddOrUpdate(cacheEntry.Key, cacheEntry, (_, _) => cacheEntry);
61 |
62 | return true;
63 | }
64 |
65 | protected override void SaveKeysToFile(string restoreFileName)
66 | {
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/SIT.Manager/Services/ManagerConfigService.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.Logging;
2 | using SIT.Manager.Converters;
3 | using SIT.Manager.Interfaces;
4 | using SIT.Manager.Models.Config;
5 | using System;
6 | using System.IO;
7 | using System.Text.Json;
8 |
9 | namespace SIT.Manager.Services;
10 |
11 | internal sealed class ManagerConfigService : IManagerConfigService
12 | {
13 | private readonly ILogger _logger;
14 |
15 | private readonly JsonSerializerOptions _jsonSerializationOptions = new()
16 | {
17 | Converters = {
18 | new ColorJsonConverter()
19 | },
20 | WriteIndented = true
21 | };
22 |
23 | private ManagerConfig _config = new();
24 | public ManagerConfig Config
25 | {
26 | get => _config;
27 | private set { _config = value; }
28 | }
29 |
30 | public event EventHandler? ConfigChanged;
31 |
32 | public ManagerConfigService(ILogger logger)
33 | {
34 | _logger = logger;
35 | Load();
36 | }
37 |
38 | private void Load()
39 | {
40 | try
41 | {
42 | string managerConfigPath = Path.Combine(AppContext.BaseDirectory, "ManagerConfig.json");
43 | if (!File.Exists(managerConfigPath))
44 | {
45 | return;
46 | }
47 | string json = File.ReadAllText(managerConfigPath);
48 | Config = JsonSerializer.Deserialize(json, _jsonSerializationOptions) ?? new ManagerConfig();
49 | }
50 | catch (Exception ex)
51 | {
52 | _logger.LogError(ex, "Failed to load ManagerConfig");
53 | }
54 | }
55 |
56 |
57 | public void UpdateConfig(ManagerConfig config, bool shouldSave = true, bool? saveAccount = null)
58 | {
59 | Config = config;
60 | saveAccount ??= config.RememberLogin;
61 |
62 | if (shouldSave)
63 | {
64 | ManagerConfig newLauncherConfig = Config;
65 | if (!saveAccount.Value)
66 | {
67 | newLauncherConfig.Username = string.Empty;
68 | newLauncherConfig.Password = string.Empty;
69 | }
70 |
71 | string managerConfigPath = Path.Combine(AppContext.BaseDirectory, "ManagerConfig.json");
72 | File.WriteAllText(managerConfigPath, JsonSerializer.Serialize(newLauncherConfig, _jsonSerializationOptions));
73 | }
74 |
75 | ConfigChanged?.Invoke(this, Config);
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/SIT.Manager/ViewModels/PlayPageViewModel.cs:
--------------------------------------------------------------------------------
1 | using Avalonia.Controls;
2 | using CommunityToolkit.Mvvm.ComponentModel;
3 | using CommunityToolkit.Mvvm.Messaging;
4 | using SIT.Manager.Interfaces;
5 | using SIT.Manager.Models.Aki;
6 | using SIT.Manager.Models.Play;
7 | using SIT.Manager.Services.Caching;
8 | using SIT.Manager.Views.Play;
9 | using System;
10 |
11 | namespace SIT.Manager.ViewModels;
12 |
13 | public partial class PlayPageViewModel : ObservableRecipient,
14 | IRecipient,
15 | IRecipient,
16 | IRecipient
17 | {
18 | private const string SELECTED_TAB_INDEX_CACHE_KEY = "LastSelectedPlayPageTabIndex";
19 |
20 | private readonly ICachingService _cachingService;
21 |
22 | private AkiServer? _connectedServer;
23 |
24 | [ObservableProperty]
25 | private UserControl _playControl;
26 |
27 | [ObservableProperty]
28 | private int _selectedTabIndex = 0;
29 |
30 | public PlayPageViewModel(ICachingService cachingService)
31 | {
32 | _cachingService = cachingService;
33 |
34 | CacheValue indexValue = _cachingService.OnDisk.GetOrCompute(SELECTED_TAB_INDEX_CACHE_KEY, (key) =>
35 | {
36 | return SelectedTabIndex;
37 | });
38 | SelectedTabIndex = indexValue.Value;
39 |
40 | PlayControl = new ServerSelectionView();
41 | }
42 |
43 | partial void OnSelectedTabIndexChanged(int value)
44 | {
45 | if (_cachingService.OnDisk.Exists(SELECTED_TAB_INDEX_CACHE_KEY))
46 | {
47 | _cachingService.OnDisk.Remove(SELECTED_TAB_INDEX_CACHE_KEY);
48 | }
49 | _cachingService.OnDisk.Add(SELECTED_TAB_INDEX_CACHE_KEY, value);
50 | }
51 |
52 | public void Receive(ServerConnectMessage message)
53 | {
54 | _connectedServer = message.Value;
55 | PlayControl = new CharacterSelectionView();
56 | }
57 |
58 | public void Receive(ConnectedServerRequestMessage message)
59 | {
60 | if (_connectedServer != null)
61 | {
62 | message.Reply(_connectedServer);
63 | }
64 | else
65 | {
66 | throw new Exception("_connectedServer is null when it shouldn't be");
67 | }
68 | }
69 |
70 | public void Receive(ServerDisconnectMessage message)
71 | {
72 | _connectedServer = null;
73 | PlayControl = new ServerSelectionView();
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/SIT.Manager.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.8.34511.84
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SIT.Manager", "SIT.Manager\SIT.Manager.csproj", "{FEEAAEDB-6BCE-4F98-B5E5-69419CECB22B}"
7 | EndProject
8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SIT.Manager.Desktop", "SIT.Manager.Desktop\SIT.Manager.Desktop.csproj", "{CAC18D21-706F-473E-9537-D1C4E9BF51A9}"
9 | EndProject
10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{AEF8FAE3-A8D1-43BA-B5B2-8C4CF98FCFD1}"
11 | ProjectSection(SolutionItems) = preProject
12 | .editorconfig = .editorconfig
13 | .gitattributes = .gitattributes
14 | .gitignore = .gitignore
15 | LICENSE = LICENSE
16 | README.md = README.md
17 | EndProjectSection
18 | EndProject
19 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Workflows", "Workflows", "{54A55723-88D1-42F4-B737-AFF0EBB7BA66}"
20 | ProjectSection(SolutionItems) = preProject
21 | .github\workflows\Create-Release.yml = .github\workflows\Create-Release.yml
22 | .github\workflows\dotnet-desktop.yml = .github\workflows\dotnet-desktop.yml
23 | EndProjectSection
24 | EndProject
25 | Global
26 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
27 | Debug|Any CPU = Debug|Any CPU
28 | Release|Any CPU = Release|Any CPU
29 | EndGlobalSection
30 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
31 | {FEEAAEDB-6BCE-4F98-B5E5-69419CECB22B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
32 | {FEEAAEDB-6BCE-4F98-B5E5-69419CECB22B}.Debug|Any CPU.Build.0 = Debug|Any CPU
33 | {FEEAAEDB-6BCE-4F98-B5E5-69419CECB22B}.Release|Any CPU.ActiveCfg = Release|Any CPU
34 | {FEEAAEDB-6BCE-4F98-B5E5-69419CECB22B}.Release|Any CPU.Build.0 = Release|Any CPU
35 | {CAC18D21-706F-473E-9537-D1C4E9BF51A9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
36 | {CAC18D21-706F-473E-9537-D1C4E9BF51A9}.Debug|Any CPU.Build.0 = Debug|Any CPU
37 | {CAC18D21-706F-473E-9537-D1C4E9BF51A9}.Release|Any CPU.ActiveCfg = Release|Any CPU
38 | {CAC18D21-706F-473E-9537-D1C4E9BF51A9}.Release|Any CPU.Build.0 = Release|Any CPU
39 | EndGlobalSection
40 | GlobalSection(SolutionProperties) = preSolution
41 | HideSolutionNode = FALSE
42 | EndGlobalSection
43 | GlobalSection(NestedProjects) = preSolution
44 | {54A55723-88D1-42F4-B737-AFF0EBB7BA66} = {AEF8FAE3-A8D1-43BA-B5B2-8C4CF98FCFD1}
45 | EndGlobalSection
46 | GlobalSection(ExtensibilityGlobals) = postSolution
47 | SolutionGuid = {6991F7CC-2839-4976-8BE4-548D13A42A22}
48 | EndGlobalSection
49 | EndGlobal
50 |
--------------------------------------------------------------------------------
/SIT.Manager/Models/Config/ManagerConfig.cs:
--------------------------------------------------------------------------------
1 | using Avalonia.Media;
2 | using CommunityToolkit.Mvvm.ComponentModel;
3 | using SIT.Manager.Models.Aki;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Globalization;
7 |
8 | namespace SIT.Manager.Models.Config;
9 |
10 | public partial class ManagerConfig : ObservableObject
11 | {
12 | // Launcher Settings
13 | [ObservableProperty]
14 | private Color? _accentColor = Color.FromRgb(0x7f, 0x7f, 0x7f);
15 | [ObservableProperty]
16 | public bool _minimizeAfterLaunch = false;
17 | [ObservableProperty]
18 | public bool _closeAfterLaunch = false;
19 | [ObservableProperty]
20 | public string _currentLanguageSelected = CultureInfo.CurrentCulture.Name;
21 | [ObservableProperty]
22 | public bool _enableTestMode = false;
23 | [ObservableProperty]
24 | public bool _hideIpAddress = true;
25 | [ObservableProperty]
26 | private DateTime _lastManagerUpdateCheckTime = DateTime.MinValue;
27 | [ObservableProperty]
28 | public bool _lookForUpdates = true;
29 |
30 | // Linux specific settings
31 | [ObservableProperty]
32 | public LinuxConfig _linuxConfig = new();
33 |
34 | // Mods settings
35 | [ObservableProperty]
36 | public bool _acceptedModsDisclaimer = false;
37 | public string ModCollectionVersion { get; set; } = string.Empty;
38 | public Dictionary InstalledMods { get; set; } = [];
39 |
40 | // SIT settings
41 | [ObservableProperty]
42 | public string _sitEftInstallPath = string.Empty;
43 | [ObservableProperty]
44 | public string _sitTarkovVersion = string.Empty;
45 | [ObservableProperty]
46 | public string _sitVersion = string.Empty;
47 | [ObservableProperty]
48 | private DateTime _lastSitUpdateCheckTime = DateTime.MinValue;
49 | [ObservableProperty]
50 | public string _lastServer = "http://127.0.0.1:6969";
51 | [ObservableProperty]
52 | public string _username = string.Empty;
53 | [ObservableProperty]
54 | public string _password = string.Empty;
55 | [ObservableProperty]
56 | public bool _rememberLogin = false;
57 | public List BookmarkedServers { get; set; } = [];
58 |
59 | // SPT-AKI settings
60 | [ObservableProperty]
61 | public string _akiServerPath = string.Empty;
62 | [ObservableProperty]
63 | public string _sptAkiVersion = string.Empty;
64 | [ObservableProperty]
65 | public string _sitModVersion = string.Empty;
66 | [ObservableProperty]
67 | private Color _consoleFontColor = Colors.LightBlue;
68 | [ObservableProperty]
69 | public string _consoleFontFamily = "Consolas";
70 | }
71 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/SIT.Manager/Views/Play/CharacterSelectionView.axaml:
--------------------------------------------------------------------------------
1 |
11 |
13 |
15 |
16 |
20 |
21 |
25 |
26 |
30 |
31 |
32 |
33 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/SIT.Manager/Interfaces/IFileService.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading;
3 | using System.Threading.Tasks;
4 |
5 | namespace SIT.Manager.Services;
6 |
7 | public interface IFileService
8 | {
9 | Task CopyDirectory(string source, string destination, IProgress? progress = null);
10 | Task CopyFileAsync(string source, string destination, CancellationToken cancellationToken = default);
11 | ///
12 | /// Downloads a file and report progress if enabled
13 | ///
14 | /// The name of the file to be downloaded.
15 | /// The path (not including the filename) to download to.
16 | /// The URL to download from.
17 | /// Report progress of the download
18 | ///
19 | Task DownloadFile(string fileName, string filePath, string fileUrl, IProgress progress);
20 | ///
21 | /// Downloads a file and show a progress bar if enabled
22 | ///
23 | /// The name of the file to be downloaded.
24 | /// The path (not including the filename) to download to.
25 | /// The URL to download from.
26 | /// If a progress bar should show the status.
27 | ///
28 | Task DownloadFile(string fileName, string filePath, string fileUrl, bool showProgress = false);
29 | ///
30 | /// Extracts a Zip archive
31 | ///
32 | /// The file to extract
33 | /// The destination to extract to
34 | /// Optional report progress of the archive extraction
35 | ///
36 | Task ExtractArchive(string filePath, string destination, IProgress? progress = null);
37 | ///
38 | /// Open the system file manager at the path requested, if the directory doesn't exist then do nothing
39 | ///
40 | /// Path to open file manager at
41 | Task OpenDirectoryAsync(string path);
42 | ///
43 | /// Open the requested file in the default system handler, if the file doesn't exist do nothing.
44 | ///
45 | /// The path of the file to open
46 | Task OpenFileAsync(string path);
47 | ///
48 | /// Ensure that the file at the target path has executable permissions
49 | ///
50 | /// The path to the file
51 | ///
52 | Task SetFileAsExecutable(string filePath);
53 | }
54 |
--------------------------------------------------------------------------------
/.github/workflows/Create-Release.yml:
--------------------------------------------------------------------------------
1 | name: Create Release
2 |
3 | on:
4 | workflow_dispatch:
5 |
6 | jobs:
7 | build:
8 | strategy:
9 | matrix:
10 | os: [ "win-x64", "linux-x64" ]
11 |
12 | runs-on: ubuntu-latest
13 |
14 | env:
15 | DeploymentDirectory: deployment
16 |
17 | steps:
18 | - name: Checkout
19 | uses: actions/checkout@v4
20 |
21 | - name: Setup .NET 8.0
22 | uses: actions/setup-dotnet@v4
23 | with:
24 | dotnet-version: 8.0.x
25 |
26 | - name: Get build date
27 | id: build
28 | shell: pwsh
29 | run: |
30 | $CurrentTime = Get-Date -Format 'yyMM'
31 | $BuildTime = Get-Date -Format 'ddHH'
32 | Write-Output "NOW=$CurrentTime" >> $env:GITHUB_OUTPUT
33 | Write-Output "VERSION=$BuildTime" >> $env:GITHUB_OUTPUT
34 |
35 | - name: Build Published Version
36 | run: dotnet publish SIT.Manager.Desktop/SIT.Manager.Desktop.csproj -c Release -r ${{ matrix.os }} -p:BuildNumber=${{ steps.build.outputs.NOW }} -p:RevisionNumber=${{ steps.build.outputs.VERSION }} -o ${{ env.DeploymentDirectory }}
37 |
38 | - name: Upload Artifact
39 | id: artifact-upload
40 | uses: actions/upload-artifact@v4
41 | with:
42 | name: ${{ matrix.os }}
43 | path: ${{ env.DeploymentDirectory }}
44 | if-no-files-found: error
45 | retention-days: 3
46 |
47 | release:
48 | needs: build
49 |
50 | runs-on: ubuntu-latest
51 |
52 | steps:
53 | - name: Get Windows Artifact
54 | uses: actions/download-artifact@v4
55 | with:
56 | name: win-x64
57 | path: win_extracted
58 |
59 | - name: Get Linux Artifact
60 | uses: actions/download-artifact@v4
61 | with:
62 | name: linux-x64
63 | path: linux_extracted
64 |
65 | - name: Tar Linux Artifact
66 | run: find linux_extracted -printf "%P\n" | tar -czf linux-x64.tar.gz --no-recursion -C linux_extracted -T -
67 |
68 | - name: Zip Windows Artifact
69 | run: |
70 | cd win_extracted
71 | zip -r ../win-x64.zip *
72 | cd ..
73 |
74 | # Get the build version for tagging the release
75 | - name: Get Release Version
76 | id: tag
77 | run: |
78 | VersionString=`strings win_extracted/SIT.Manager.exe | egrep -m 1 '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$'`
79 | echo "MANAGER_VERSION=$VersionString" >> $GITHUB_OUTPUT
80 |
81 | - name: Generate Release Draft
82 | uses: softprops/action-gh-release@v2
83 | with:
84 | draft: true
85 | generate_release_notes: true
86 | files: |
87 | win-x64.zip
88 | linux-x64.tar.gz
89 | tag_name: ${{ steps.tag.outputs.MANAGER_VERSION }}
90 |
--------------------------------------------------------------------------------
/SIT.Manager/Theme/Controls/LoadingSpinner.axaml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
24 |
25 |
71 |
72 |
73 |
--------------------------------------------------------------------------------
/SIT.Manager/Interfaces/IModService.cs:
--------------------------------------------------------------------------------
1 | using SIT.Manager.Models;
2 | using System.Collections.Generic;
3 | using System.Threading.Tasks;
4 |
5 | namespace SIT.Manager.Interfaces;
6 |
7 | public interface IModService
8 | {
9 | ///
10 | /// Array of recommended mod install names.
11 | ///
12 | string[] RecommendedModInstalls { get; }
13 | ///
14 | /// The currently loaded list of mods which we have available to install/uninstall
15 | ///
16 | List ModList { get; }
17 |
18 | ///
19 | /// Automatically updates installed mods that are outdated.
20 | ///
21 | /// of that are outdated.
22 | Task AutoUpdate(List outdatedMods);
23 | ///
24 | /// Clears the locally downloaded cache of mods which will force a refresh of available mods.
25 | ///
26 | void ClearCache();
27 | ///
28 | /// Download the collection of ported and compatible (probably) SIT mods.
29 | ///
30 | ///
31 | Task DownloadModsCollection();
32 | ///
33 | /// Downloads (unless it's cached already) and installs the latest configuration manager from GitHub
34 | ///
35 | /// Base location of where the EFT install is to put the mod
36 | /// True if it was successfully installed; otherwise False
37 | Task InstallConfigurationManager(string targetPath);
38 | ///
39 | /// Install a mod into the given target location
40 | ///
41 | /// Base location of where the EFT install is to put the mod
42 | /// The meta data for the mod we want to install
43 | /// Supress notifications of the mods installation status
44 | /// Supress the warning about a mods compatibility
45 | /// True if it was successfully installed; otherwise False
46 | Task InstallMod(string targetPath, ModInfo mod, bool suppressNotification = false, bool suppressCompatibilityWarning = false);
47 | ///
48 | /// Load the master list of mods into memory so we know what mods are available
49 | ///
50 | ///
51 | Task LoadMasterModList();
52 | ///
53 | /// Uninstall a mod from the given target location
54 | ///
55 | /// The meta data for the mod we want to uninstall
56 | /// The target location to search where the mod is installed
57 | ///
58 | Task UninstallMod(string targetPath, ModInfo mod);
59 | }
60 |
--------------------------------------------------------------------------------
/SIT.Manager/Views/Play/CharacterSummaryView.axaml:
--------------------------------------------------------------------------------
1 |
11 |
12 |
13 |
14 |
20 |
21 |
27 |
28 |
29 |
31 |
32 |
35 |
36 |
37 |
39 |
40 |
42 |
44 |
50 |
52 |
53 |
54 |
55 |
64 |
65 |
73 |
74 |
75 |
76 |
--------------------------------------------------------------------------------
/SIT.Manager/Theme/Controls/Card.axaml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
43 |
46 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
60 |
61 |
--------------------------------------------------------------------------------
/SIT.Manager/ViewModels/Settings/SptAkiViewModel.cs:
--------------------------------------------------------------------------------
1 | using Avalonia.Media;
2 | using CommunityToolkit.Mvvm.ComponentModel;
3 | using CommunityToolkit.Mvvm.Input;
4 | using SIT.Manager.Interfaces;
5 | using System.Collections.Generic;
6 | using System.Linq;
7 | using System.Threading.Tasks;
8 |
9 | namespace SIT.Manager.ViewModels.Settings;
10 |
11 | public partial class SptAkiViewModel : SettingsViewModelBase
12 | {
13 | private readonly IBarNotificationService _barNotificationService;
14 | private readonly ILocalizationService _localizationService;
15 | private readonly IVersionService _versionService;
16 |
17 | [ObservableProperty]
18 | private FontFamily _selectedConsoleFontFamily = FontFamily.Default;
19 |
20 | [ObservableProperty]
21 | private List _installedFonts;
22 |
23 | public IAsyncRelayCommand ChangeAkiServerLocationCommand { get; }
24 |
25 | public SptAkiViewModel(IBarNotificationService barNotificationService,
26 | IManagerConfigService configService,
27 | ILocalizationService localizationService,
28 | IPickerDialogService pickerDialogService,
29 | IVersionService versionService) : base(configService, pickerDialogService)
30 | {
31 | _barNotificationService = barNotificationService;
32 | _localizationService = localizationService;
33 | _versionService = versionService;
34 |
35 | List installedFonts = [.. FontManager.Current.SystemFonts];
36 | installedFonts.Add(FontFamily.Parse("Bender"));
37 | InstalledFonts = [.. installedFonts.OrderBy(x => x.Name)];
38 |
39 | ChangeAkiServerLocationCommand = new AsyncRelayCommand(ChangeAkiServerLocation);
40 | }
41 |
42 | private async Task ChangeAkiServerLocation()
43 | {
44 | string targetPath = await GetPathLocation("Aki.Server.exe");
45 | if (!string.IsNullOrEmpty(targetPath))
46 | {
47 | Config.AkiServerPath = targetPath;
48 | Config.SptAkiVersion = _versionService.GetSptAkiVersion(targetPath);
49 | Config.SitModVersion = _versionService.GetSitModVersion(targetPath);
50 | _barNotificationService.ShowInformational(_localizationService.TranslateSource("SettingsPageViewModelConfigTitle"), _localizationService.TranslateSource("SettingsPageViewModelConfigInformationSPTAKIDescription", targetPath));
51 | }
52 | else
53 | {
54 | _barNotificationService.ShowError(_localizationService.TranslateSource("SettingsPageViewModelErrorTitle"), _localizationService.TranslateSource("SettingsPageViewModelConfigErrorSPTAKI"));
55 | }
56 | }
57 |
58 | protected override void OnActivated()
59 | {
60 | base.OnActivated();
61 |
62 | SelectedConsoleFontFamily = InstalledFonts.FirstOrDefault(x => x.Name == Config.ConsoleFontFamily, FontFamily.Parse("Bender"));
63 | }
64 |
65 | partial void OnSelectedConsoleFontFamilyChanged(FontFamily value)
66 | {
67 | Config.ConsoleFontFamily = value.Name;
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/SIT.Manager/Views/Settings/LauncherView.axaml:
--------------------------------------------------------------------------------
1 |
11 |
12 |
13 |
14 |
17 |
20 |
23 |
26 |
29 |
30 |
31 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
52 |
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/SIT.Manager/Views/Installation/InstallView.axaml:
--------------------------------------------------------------------------------
1 |
10 |
14 |
16 |
17 |
23 |
31 |
38 |
39 |
40 |
46 |
54 |
61 |
62 |
63 |
69 |
77 |
84 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/SIT.Manager/Views/Settings/SptAkiView.axaml:
--------------------------------------------------------------------------------
1 |
11 |
12 |
13 |
14 |
15 |
16 |
21 |
26 |
27 |
28 |
30 |
31 |
33 |
34 |
35 |
37 |
38 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
58 |
59 |
60 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
77 |
78 |
79 |
80 |
81 |
82 |
--------------------------------------------------------------------------------
/SIT.Manager/ViewModels/Settings/EftViewModel.cs:
--------------------------------------------------------------------------------
1 | using CommunityToolkit.Mvvm.ComponentModel;
2 | using CommunityToolkit.Mvvm.Input;
3 | using FluentAvalonia.UI.Controls;
4 | using SIT.Manager.Interfaces;
5 | using System.IO;
6 | using System.Threading.Tasks;
7 |
8 | namespace SIT.Manager.ViewModels.Settings;
9 |
10 | public partial class EftViewModel : SettingsViewModelBase
11 | {
12 | private readonly IBarNotificationService _barNotificationService;
13 | private readonly IInstallerService _installerService;
14 | private readonly ILocalizationService _localizationService;
15 | private readonly IVersionService _versionService;
16 |
17 | [ObservableProperty]
18 | private string _bsgEftInstallPath;
19 |
20 | [ObservableProperty]
21 | private string _sitEftInstallPath;
22 |
23 | public IAsyncRelayCommand ChangeInstallLocationCommand { get; }
24 |
25 | public EftViewModel(IBarNotificationService barNotificationService,
26 | IInstallerService installerService,
27 | IManagerConfigService configService,
28 | ILocalizationService localizationService,
29 | IPickerDialogService pickerDialogService,
30 | IVersionService versionService) : base(configService, pickerDialogService)
31 | {
32 | _barNotificationService = barNotificationService;
33 | _installerService = installerService;
34 | _localizationService = localizationService;
35 | _versionService = versionService;
36 |
37 | BsgEftInstallPath = Path.GetDirectoryName(_installerService.GetEFTInstallPath()) ?? _localizationService.TranslateSource("EftViewModelBsgEftInstallPathMissing");
38 | SitEftInstallPath = _configsService.Config.SitEftInstallPath;
39 |
40 | ChangeInstallLocationCommand = new AsyncRelayCommand(ChangeInstallLocation);
41 | }
42 |
43 | private async Task ChangeInstallLocation()
44 | {
45 | string targetPath = await GetPathLocation("EscapeFromTarkov.exe");
46 | if (!string.IsNullOrEmpty(targetPath))
47 | {
48 | if (targetPath == BsgEftInstallPath)
49 | {
50 | // Using the same location as the current BSG install and we don't want this the same as the SIT install.
51 | await new ContentDialog()
52 | {
53 | Title = _localizationService.TranslateSource("ConfigureSitViewModelLocationSelectionErrorTitle"),
54 | Content = _localizationService.TranslateSource("ConfigureSitViewModelLocationSelectionErrorDescription"),
55 | PrimaryButtonText = _localizationService.TranslateSource("ConfigureSitViewModelLocationSelectionErrorOk")
56 | }.ShowAsync();
57 | return;
58 | }
59 |
60 | SitEftInstallPath = targetPath;
61 |
62 | Config.SitEftInstallPath = targetPath;
63 | Config.SitTarkovVersion = _versionService.GetEFTVersion(targetPath);
64 | Config.SitVersion = _versionService.GetSITVersion(targetPath);
65 |
66 | _barNotificationService.ShowInformational(_localizationService.TranslateSource("SettingsPageViewModelConfigTitle"), _localizationService.TranslateSource("SettingsPageViewModelConfigInformationEFTDescription", targetPath));
67 | }
68 | else
69 | {
70 | _barNotificationService.ShowError(_localizationService.TranslateSource("SettingsPageViewModelErrorTitle"), _localizationService.TranslateSource("SettingsPageViewModelConfigErrorEFTDescription"));
71 | }
72 | }
73 |
74 | protected override void OnActivated()
75 | {
76 | base.OnActivated();
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/SIT.Manager/ViewModels/Settings/LinuxViewModel.cs:
--------------------------------------------------------------------------------
1 | using Avalonia.Platform.Storage;
2 | using CommunityToolkit.Mvvm.ComponentModel;
3 | using CommunityToolkit.Mvvm.Input;
4 | using SIT.Manager.Interfaces;
5 | using SIT.Manager.Models.Config;
6 | using System.Collections.Generic;
7 | using System.ComponentModel;
8 | using System.IO;
9 | using System.Threading.Tasks;
10 |
11 | namespace SIT.Manager.ViewModels.Settings;
12 |
13 | public partial class LinuxViewModel : SettingsViewModelBase
14 | {
15 | // TODO: Check which services are needed for this ViewModel.
16 | private readonly IBarNotificationService _barNotificationService;
17 | private readonly ILocalizationService _localizationService;
18 |
19 | [ObservableProperty]
20 | private LinuxConfig _linuxConfig = new();
21 |
22 | // DXVK Versions TODO
23 | [ObservableProperty]
24 | private List _dxvkVersions = [];
25 |
26 | public IAsyncRelayCommand ChangePrefixLocationCommand { get; }
27 | public IAsyncRelayCommand ChangeRunnerLocationCommand { get; }
28 |
29 | public LinuxViewModel(IBarNotificationService barNotificationService,
30 | IManagerConfigService configService,
31 | ILocalizationService localizationService,
32 | IPickerDialogService pickerDialogService) : base(configService, pickerDialogService)
33 | {
34 | _barNotificationService = barNotificationService;
35 | _localizationService = localizationService;
36 |
37 | ChangePrefixLocationCommand = new AsyncRelayCommand(ChangePrefixLocation);
38 | ChangeRunnerLocationCommand = new AsyncRelayCommand(ChangeRunnerLocation);
39 | }
40 |
41 | [RelayCommand]
42 | private void AddEnv()
43 | {
44 | LinuxConfig.WineEnv.Add("", "");
45 | }
46 |
47 | [RelayCommand]
48 | private void DeleteEnv()
49 | {
50 | // TODO: get the selected item and remove it from the dictionary
51 | }
52 |
53 | private async Task ChangePrefixLocation()
54 | {
55 | IStorageFolder? newPath = await _pickerDialogService.GetDirectoryFromPickerAsync();
56 | if (newPath != null)
57 | {
58 | LinuxConfig.WinePrefix = newPath.Path.AbsolutePath;
59 | }
60 | else
61 | {
62 | _barNotificationService.ShowError(_localizationService.TranslateSource("SettingsPageViewModelErrorTitle"), _localizationService.TranslateSource("LinuxSettingsPageViewModelConfigErrorPrefix"));
63 | }
64 | }
65 |
66 | private async Task ChangeRunnerLocation()
67 | {
68 | string newPath = await GetPathLocation(Path.Combine("bin", "wine"));
69 | if (!string.IsNullOrEmpty(newPath))
70 | {
71 | LinuxConfig.WineRunner = Path.Combine(newPath, "bin", "wine");
72 | }
73 | else
74 | {
75 | _barNotificationService.ShowError(_localizationService.TranslateSource("SettingsPageViewModelErrorTitle"), _localizationService.TranslateSource("LinuxSettingsPageViewModelConfigErrorRunner"));
76 | }
77 | }
78 |
79 | private void LinuxConfig_PropertyChanged(object? sender, PropertyChangedEventArgs e)
80 | {
81 | _configsService.UpdateConfig(_configsService.Config);
82 | }
83 |
84 | protected override void OnActivated()
85 | {
86 | base.OnActivated();
87 |
88 | LinuxConfig = _configsService.Config.LinuxConfig;
89 |
90 | LinuxConfig.PropertyChanged += LinuxConfig_PropertyChanged;
91 | }
92 |
93 | protected override void OnDeactivated()
94 | {
95 | base.OnDeactivated();
96 | LinuxConfig.PropertyChanged -= LinuxConfig_PropertyChanged;
97 | }
98 | }
99 |
--------------------------------------------------------------------------------