Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,15 @@ indent_size = 2
[*.cs]
max_line_length = 140

# Transitional analyzer levels while legacy filesystem/settings migration is in progress.
dotnet_diagnostic.CS0618.severity = suggestion
dotnet_diagnostic.IO0002.severity = suggestion
dotnet_diagnostic.IO0003.severity = suggestion
dotnet_diagnostic.IO0004.severity = suggestion
dotnet_diagnostic.IO0005.severity = suggestion
dotnet_diagnostic.IO0006.severity = suggestion
dotnet_diagnostic.IO0007.severity = suggestion

#### Core EditorConfig Options ####

# Indentation and spacing
Expand Down
7 changes: 2 additions & 5 deletions WheelWizard.Test/Features/MiiDbServiceTests.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using NSubstitute.ExceptionExtensions;
using Testably.Abstractions;
using WheelWizard.Shared;
using WheelWizard.WiiManagement.MiiManagement;
using WheelWizard.WiiManagement.MiiManagement.Domain.Mii;
Expand All @@ -9,16 +8,14 @@ namespace WheelWizard.Test.Features
public class MiiDbServiceTests
{
private readonly IMiiRepositoryService _repositoryService;
private readonly IRandomSystem _randomSystemService;
private readonly MiiDbService _service;

// --- Test Setup ---

public MiiDbServiceTests()
{
_repositoryService = Substitute.For<IMiiRepositoryService>();
_randomSystemService = Substitute.For<IRandomSystem>();
_service = new(_repositoryService, _randomSystemService);
_service = new(_repositoryService);
}

// --- Helper Methods ---
Expand Down Expand Up @@ -188,7 +185,7 @@ public void GetAllMiis_ShouldSkipInvalidBlocks_AndReturnOnlyValidMiis()
Assert.True(mii1Result.IsSuccess, "Setup Failed: Could not create valid Mii");
var mii1Bytes = GetSerializedBytes(mii1Result.Value);
var invalidBytesShort = new byte[10]; // Invalid length
var invalidBytesNull = (byte[])null; // Null entry (if possible from repo)
byte[]? invalidBytesNull = null; // Null entry (if possible from repo)
// Simulate a block that's the right size but contains garbage data causing deserialization failure
var potentiallyBadBytes = new byte[MiiSerializer.MiiBlockSize];
_repositoryService.LoadAllBlocks().Returns([invalidBytesShort, mii1Bytes, potentiallyBadBytes, invalidBytesNull!]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ public class LicenseProfile : PlayerProfileBase
public required uint TotalRaceCount { get; set; }
public required uint TotalWinCount { get; set; }
public List<FriendProfile> Friends { get; set; } = [];
public LicenseStatistics Statistics { get; set; }
public LicenseStatistics Statistics { get; set; } = new();
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using Testably.Abstractions;
using WheelWizard.Shared.MessageTranslations;
using WheelWizard.Shared.MessageTranslations;
using WheelWizard.WiiManagement.MiiManagement.Domain.Mii;

namespace WheelWizard.WiiManagement.MiiManagement;
Expand Down Expand Up @@ -55,7 +54,7 @@ public interface IMiiDbService
bool Exists();
}

public class MiiDbService(IMiiRepositoryService repository, IRandomSystem randomSystem) : IMiiDbService
public class MiiDbService(IMiiRepositoryService repository) : IMiiDbService
{
public List<Mii> GetAllMiis()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ public interface IMiiRepositoryService

public class MiiRepositoryServiceService(IFileSystem fileSystem) : IMiiRepositoryService
{
private readonly IFileSystem _fileSystem;
private const int MiiLength = 74;
private const int MaxMiiSlots = 100;
private const int CrcOffset = 0x1F1DE;
Expand Down
3 changes: 0 additions & 3 deletions WheelWizard/Helpers/Humanizer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,6 @@ public static string HumanizeTimeSpan(TimeSpan timeSpan)
}

return ReplaceDynamic(Phrases.Time_Seconds_x, timeSpan.Seconds)!;

// internal method to simplify the pluralization of words
string P(int count) => Math.Abs(count) != 1 ? "s" : "";
}

public static string HumanizeSeconds(int seconds) => HumanizeTimeSpan(TimeSpan.FromSeconds(seconds));
Expand Down
9 changes: 5 additions & 4 deletions WheelWizard/Services/Installation/ModInstallation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -135,10 +135,11 @@ public static void ProcessFile(string file, string destinationDirectory, Progres
});

// Normalize entry path by removing empty folder segments
var entryKey = entry.Key ?? string.Empty;
var sanitizedKey = string.Join(
Path.DirectorySeparatorChar.ToString(),
entry
.Key.Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)
entryKey
.Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)
.Where(segment => !string.IsNullOrWhiteSpace(segment))
);

Expand Down Expand Up @@ -176,7 +177,7 @@ public static void ProcessFile(string file, string destinationDirectory, Progres
}
}

private static IArchive OpenArchive(string filePath, string extension)
private static IArchive? OpenArchive(string filePath, string extension)
{
try
{
Expand All @@ -201,7 +202,7 @@ private static IArchive OpenArchive(string filePath, string extension)
/// </summary>
public static async Task InstallModFromFileAsync(string filePath, string givenModName, string author = "-1", int modID = -1)
{
ProgressWindow progressWindow = null;
ProgressWindow? progressWindow = null;
try
{
if (!File.Exists(filePath))
Expand Down
8 changes: 4 additions & 4 deletions WheelWizard/Services/ModManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ public void RemoveMod(Mod mod)
OnPropertyChanged(nameof(Mods));
}

private void Mod_PropertyChanged(object sender, PropertyChangedEventArgs e)
private void Mod_PropertyChanged(object? sender, PropertyChangedEventArgs e)
{
if (_isBatchUpdating)
return;
Expand Down Expand Up @@ -161,7 +161,7 @@ private async Task CombineFilesIntoSingleModAsync(string[] filePaths)
.SetPlaceholderText("Enter mod name...")
.SetValidation(ValidateModName)
.ShowDialog();
if (!IsValidName(modName))
if (string.IsNullOrWhiteSpace(modName) || !IsValidName(modName))
return;

var tempZipPath = Path.Combine(Path.GetTempPath(), $"{modName}.zip");
Expand Down Expand Up @@ -230,7 +230,7 @@ public void ToggleAllMods(bool enable)
// TODO: Use this validation method when refactoring the ModManager
public OperationResult ValidateModName(string? oldName, string newName)
{
newName = newName?.Trim();
newName = (newName ?? string.Empty).Trim();
if (string.IsNullOrWhiteSpace(newName))
return Fail("Mod name cannot be empty.");

Expand Down Expand Up @@ -423,7 +423,7 @@ private void ErrorOccurred(string? errorMessage)
new MessageBoxWindow()
.SetMessageType(MessageBoxWindow.MessageType.Error)
.SetTitleText("An error occurred")
.SetInfoText(errorMessage)
.SetInfoText(errorMessage ?? "An unknown error occurred.")
.Show();
}

Expand Down
28 changes: 4 additions & 24 deletions WheelWizard/Services/Storage/FilePickerHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ public static async Task<List<string>> OpenFilePickerAsync(
var storageProvider = Application.Current?.ApplicationLifetime as IClassicDesktopStyleApplicationLifetime;
if (storageProvider == null)
return [];
if (storageProvider.MainWindow?.StorageProvider == null)
return [];

var options = new FilePickerOpenOptions
{
Expand Down Expand Up @@ -71,37 +73,15 @@ public static async Task<List<string>> OpenFilePickerAsync(
return null;
}

public static async Task<List<string>> OpenMultipleFilesAsync(string title, IEnumerable<FilePickerFileType> fileTypes)
{
var storageProvider = Application.Current?.ApplicationLifetime as IClassicDesktopStyleApplicationLifetime;
if (storageProvider == null)
return null;

var topLevel = TopLevel.GetTopLevel(storageProvider.MainWindow);
if (topLevel?.StorageProvider == null)
return [];

var files = await topLevel.StorageProvider.OpenFilePickerAsync(
new()
{
Title = title,
AllowMultiple = true,
FileTypeFilter = fileTypes.ToList(),
}
);

return files?.Select(TryResolveLocalPath).Where(path => !string.IsNullOrWhiteSpace(path)).Select(path => path!).ToList() ?? [];
}

public static async Task<IReadOnlyList<IStorageFolder?>> SelectFolderAsync(string title, IStorageFolder? suggestedStartLocation = null)
{
var storageProvider = Application.Current?.ApplicationLifetime as IClassicDesktopStyleApplicationLifetime;
if (storageProvider == null)
return null;
return [];

var topLevel = TopLevel.GetTopLevel(storageProvider.MainWindow);
if (topLevel?.StorageProvider == null)
return null;
return [];

var folders = await topLevel.StorageProvider.OpenFolderPickerAsync(
new()
Expand Down
2 changes: 1 addition & 1 deletion WheelWizard/Utilities/Mockers/MockingDataFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ public abstract class MockingDataFactory<T, U>
public static U Instance { get; } = new();
public abstract T Create(int? seed = null);

protected virtual string DictionaryKeyGenerator(T value) => value.ToString();
protected virtual string DictionaryKeyGenerator(T value) => value is null ? string.Empty : value.ToString() ?? string.Empty;

public T[] CreateMultiple(int count = 5, int? seed = null)
{
Expand Down
2 changes: 2 additions & 0 deletions WheelWizard/Utilities/RepeatedTasks/RepeatedTaskManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ public void Start()
_timer.Start();

// Run the initial execution
#pragma warning disable CS4014
ExecuteAndNotifyAsync();
#pragma warning restore CS4014
}

public void Stop()
Expand Down
2 changes: 1 addition & 1 deletion WheelWizard/Views/Components/MultiColoredIcon.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ private void UpdateDrawingColors()
var originalDrawing = IconData;
if (originalDrawing?.Drawing is not DrawingGroup originalGroup)
{
ProcessedIconData = originalDrawing;
ProcessedIconData = originalDrawing ?? new DrawingImage();
return;
}

Expand Down
4 changes: 2 additions & 2 deletions WheelWizard/Views/Converters/NullToBoolConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ namespace WheelWizard.Views.Converters;

public class NullToBoolConverter : IValueConverter
{
public object Convert(object? value, Type targetType, object parameter, CultureInfo culture) => value != null;
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) => value != null;

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) =>
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) =>
Avalonia.Data.BindingOperations.DoNothing;
}
3 changes: 2 additions & 1 deletion WheelWizard/Views/Pages/FriendsPage.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ private void PopulateSortingList()
ListOrderCondition.WINS => Common.Attribute_Wins,
ListOrderCondition.TOTAL_RACES => Common.Attribute_RacesPlayed,
ListOrderCondition.IS_ONLINE => Common.Attribute_IsOnline,
_ => Common.State_Unknown,
};

SortByDropdown.Items.Add(name);
Expand Down Expand Up @@ -393,7 +394,7 @@ private void SaveMii_OnClick(object sender, RoutedEventArgs e)

#region PropertyChanged

public event PropertyChangedEventHandler? PropertyChanged;
public new event PropertyChangedEventHandler? PropertyChanged;

protected virtual void OnPropertyChanged(string propertyName)
{
Expand Down
20 changes: 12 additions & 8 deletions WheelWizard/Views/Pages/MiiListPage.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -191,15 +191,15 @@ private void ReloadMiiList()
MiiList.Children.Add(addBlock);
}

private async void DeleteMii_OnClick(object? sender, RoutedEventArgs e) => DeleteMii(GetSelectedMiis());
private void DeleteMii_OnClick(object? sender, RoutedEventArgs e) => DeleteMii(GetSelectedMiis());

private async void EditMii_OnClick(object? sender, RoutedEventArgs e) => EditMii(GetSelectedMiis()[0]);
private void EditMii_OnClick(object? sender, RoutedEventArgs e) => EditMii(GetSelectedMiis()[0]);

private async void FavMii_OnClick(object? sender, RoutedEventArgs e) => ToggleFavorite(GetSelectedMiis());
private void FavMii_OnClick(object? sender, RoutedEventArgs e) => ToggleFavorite(GetSelectedMiis());

private async void ExportMii_OnClick(object? sender, RoutedEventArgs e) => ExportMultipleMiiFiles(GetSelectedMiis());
private void ExportMii_OnClick(object? sender, RoutedEventArgs e) => ExportMultipleMiiFiles(GetSelectedMiis());

private async void DuplicateMii_OnClick(object? sender, RoutedEventArgs e) => DuplicateMii(GetSelectedMiis());
private void DuplicateMii_OnClick(object? sender, RoutedEventArgs e) => DuplicateMii(GetSelectedMiis());

private async void ImportMii_OnClick(object? sender, RoutedEventArgs e)
{
Expand Down Expand Up @@ -246,7 +246,7 @@ private async void ImportMii_OnClick(object? sender, RoutedEventArgs e)
ReloadMiiList();
}

private async void ToggleFavorite(Mii[] miis)
private void ToggleFavorite(Mii[] miis)
{
var allFavorite = miis.All(m => m.IsFavorite);

Expand All @@ -267,7 +267,7 @@ private async void ToggleFavorite(Mii[] miis)
ReloadMiiList();
}

private async void ExportMultipleMiiFiles(Mii[] miis)
private void ExportMultipleMiiFiles(Mii[] miis)
{
if (miis.Length == 0)
{
Expand Down Expand Up @@ -513,7 +513,11 @@ private class MyCommand(Action command) : ICommand

public void Execute(object? parameter) => command.Invoke();

public event EventHandler? CanExecuteChanged;
public event EventHandler? CanExecuteChanged
{
add { }
remove { }
}
}

#endregion
Expand Down
4 changes: 2 additions & 2 deletions WheelWizard/Views/Pages/RoomDetailsPage.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ private static OperationResult<string> NormalizeFriendCode(string friendCode)
return formatted;
}

private void RoomsDetailPage_Unloaded(object sender, RoutedEventArgs e)
private void RoomsDetailPage_Unloaded(object? sender, RoutedEventArgs e)
{
RRLiveRooms.Instance.Unsubscribe(this);
}
Expand All @@ -241,7 +241,7 @@ private void PlayerView_SelectionChanged(object? sender, SelectionChangedEventAr

#region PropertyChanged

public event PropertyChangedEventHandler? PropertyChanged;
public new event PropertyChangedEventHandler? PropertyChanged;

protected virtual void OnPropertyChanged(string propertyName)
{
Expand Down
9 changes: 5 additions & 4 deletions WheelWizard/Views/Pages/RoomsPage.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,13 @@ private void PerformSearch(string? query)
if (isStringEmpty)
return;

var safeQuery = query ?? string.Empty;
Players.Clear();
var matchingPlayers = Rooms
.SelectMany(r => r.Players)
.Where(p =>
p.Name.Contains(query, StringComparison.OrdinalIgnoreCase)
|| p.FriendCode.Contains(query, StringComparison.OrdinalIgnoreCase)
(p.Name?.Contains(safeQuery, StringComparison.OrdinalIgnoreCase) ?? false)
|| (p.FriendCode?.Contains(safeQuery, StringComparison.OrdinalIgnoreCase) ?? false)
)
.Distinct()
.ToList();
Expand All @@ -90,7 +91,7 @@ private void PerformSearch(string? query)
PlayerListItemCount.Text = matchingPlayers.Count.ToString();
}

private void RoomsPage_Unloaded(object sender, RoutedEventArgs e)
private void RoomsPage_Unloaded(object? sender, RoutedEventArgs e)
{
RRLiveRooms.Instance.Unsubscribe(this);
}
Expand Down Expand Up @@ -135,7 +136,7 @@ private void PlayerView_SelectionChanged(object? sender, SelectionChangedEventAr

#region PropertyChanged

public event PropertyChangedEventHandler? PropertyChanged;
public new event PropertyChangedEventHandler? PropertyChanged;

protected virtual void OnPropertyChanged(string propertyName)
{
Expand Down
9 changes: 7 additions & 2 deletions WheelWizard/Views/Pages/Settings/VideoSettings.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ private void LoadSettings()
var finalResolution = SettingsService.Get<int>(SettingsService.INTERNAL_RESOLUTION);
foreach (RadioButton radioButton in ResolutionStackPanel.Children)
{
radioButton.IsChecked = (radioButton.Tag.ToString() == finalResolution.ToString());
var tag = radioButton.Tag?.ToString();
radioButton.IsChecked = string.Equals(tag, finalResolution.ToString(), StringComparison.Ordinal);
}
}

Expand All @@ -73,7 +74,8 @@ private void UpdateResolution(object? sender, RoutedEventArgs e)
{
if (sender is RadioButton radioButton && radioButton.IsChecked == true)
{
SettingsService.Set(SettingsService.INTERNAL_RESOLUTION, int.Parse(radioButton.Tag.ToString()!));
if (int.TryParse(radioButton.Tag?.ToString(), out var resolution))
SettingsService.Set(SettingsService.INTERNAL_RESOLUTION, resolution);
}
}

Expand All @@ -100,6 +102,9 @@ private void RemoveBlur_OnClick(object? sender, RoutedEventArgs e)
private void RendererDropdown_OnSelectionChanged(object? sender, SelectionChangedEventArgs e)
{
var selectedDisplayName = RendererDropdown.SelectedItem?.ToString();
if (string.IsNullOrWhiteSpace(selectedDisplayName))
return;

if (SettingValues.GFXRenderers.TryGetValue(selectedDisplayName, out var actualValue))
{
SettingsService.Set(SettingsService.GFX_BACKEND, actualValue);
Expand Down
Loading