├── 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 | 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 | 40 | 41 | -------------------------------------------------------------------------------- /SIT.Manager/Views/Play/ServerSelectionView.axaml: -------------------------------------------------------------------------------- 1 | 12 | 14 | 16 | 17 | 18 | 24 | 25 | 26 | 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 | 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 |