Skip to content
Draft
2 changes: 2 additions & 0 deletions H2MLauncher.Core/Matchmaking/IMatchmakingHub.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ public interface IMatchmakingHub

Task<bool> SearchMatch(MatchSearchCriteria searchPreferences, string playlistId);

Task<bool> SearchMatchCustom(MatchSearchCriteria searchPreferences, CustomPlaylist customPlaylist);

Task<bool> UpdateSearchSession(MatchSearchCriteria searchPreferences, List<ServerPing> serverPings);
}
}
9 changes: 6 additions & 3 deletions H2MLauncher.Core/Matchmaking/MatchmakingService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -291,10 +291,13 @@ public async Task<bool> EnterMatchmakingAsync(Playlist playlist, MatchmakingPref

SearchAttempts = 0;

bool success = await Hub.SearchMatch(initialSearchCriteria, playlist.Id);
bool success = playlist is CustomPlaylist customPlaylist
? await Hub.SearchMatchCustom(initialSearchCriteria, customPlaylist)
: await Hub.SearchMatch(initialSearchCriteria, playlist.Id);

if (!success)
{
_logger.LogDebug("Could not enter matchmaking for playlist '{playlist}'", playlist.Id);
_logger.LogDebug("Could not enter matchmaking for playlist '{playlist}'", playlist.Name);
return false;
}

Expand All @@ -310,7 +313,7 @@ public async Task<bool> EnterMatchmakingAsync(Playlist playlist, MatchmakingPref

MatchSearchCriteriaChanged?.Invoke(_currentMetadata.SearchPreferences);

_logger.LogInformation("Entered matchmaking queue for playlist '{playlist}'", playlist.Id);
_logger.LogInformation("Entered matchmaking queue for playlist '{playlist}'", playlist.Name);

return true;
}
Expand Down
16 changes: 16 additions & 0 deletions H2MLauncher.Core/Matchmaking/Models/CustomPlaylist.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System.Diagnostics.CodeAnalysis;

using H2MLauncher.Core.Models;

namespace H2MLauncher.Core.Matchmaking.Models;

public record CustomPlaylist : Playlist
{
public required new List<ServerConnectionDetails> Servers
{
get => base.Servers ?? [];
init => base.Servers = value;
}

public override bool IsCustom { get; } = true;
}
42 changes: 42 additions & 0 deletions H2MLauncher.Core/Matchmaking/Models/CustomPlaylistInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using System.Diagnostics.CodeAnalysis;

using H2MLauncher.Core.Models;

namespace H2MLauncher.Core.Matchmaking.Models
{
/// <summary>
/// Info about a custom playlist that is stored.
/// </summary>
public record CustomPlaylistInfo()
{
/// <summary>
/// A unique identifier for this playlist.
/// </summary>
public required string Id { get; init; }

/// <summary>
/// Name of this playlist.
/// </summary>
public required string Name { get; init; }

/// <summary>
/// The servers in this playlist.
/// </summary>
public required HashSet<ServerConnectionDetails> Servers { get; init; }

/// <summary>
/// When this playlist was created.
/// </summary>
public DateTimeOffset CreatedAt { get; init; }


[SetsRequiredMembers]
public CustomPlaylistInfo(string name, IEnumerable<ServerConnectionDetails> servers) : this()
{
Id = Guid.NewGuid().ToString();
Name = name;
Servers = [.. servers];
CreatedAt = DateTimeOffset.Now;
}
}
}
10 changes: 8 additions & 2 deletions H2MLauncher.Core/Matchmaking/Models/Playlist.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using H2MLauncher.Core.Models;
using System.Text.Json.Serialization;

using H2MLauncher.Core.Models;

namespace H2MLauncher.Core.Matchmaking.Models
{
Expand All @@ -18,12 +20,16 @@ public record Playlist

public List<ServerConnectionDetails>? Servers { get; init; } = [];

[JsonIgnore]
public int ServerCount
{
get => Servers?.Count ?? _serverCount;
init => _serverCount = ServerCount;
}

public int? CurrentPlayerCount { get; init; }

public int CurrentPlayerCount { get; init; }
[JsonIgnore]
public virtual bool IsCustom { get; } = false;
}
}
5 changes: 4 additions & 1 deletion H2MLauncher.Core/Settings/H2MLauncherSettings.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using H2MLauncher.Core.Models;
using H2MLauncher.Core.Matchmaking.Models;
using H2MLauncher.Core.Models;
using H2MLauncher.Core.Social.Player;

namespace H2MLauncher.Core.Settings
Expand All @@ -17,6 +18,8 @@ public record H2MLauncherSettings

public List<RecentPlayerInfo> RecentPlayers { get; init; } = [];

public List<CustomPlaylistInfo> CustomPlaylists { get; init; } = [];

public ServerFilterSettings ServerFilter { get; init; } = new();

public bool AutomaticGameDetection { get; init; } = true;
Expand Down
10 changes: 10 additions & 0 deletions H2MLauncher.Core/Utilities/ServerConnectionDetailsExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using H2MLauncher.Core.Models;

namespace H2MLauncher.Core.Utilities
{
public static class ServerConnectionDetailsExtensions
{
public static ServerConnectionDetails ToServerConnectionDetails(this IServerConnectionDetails value)
=> new(value.Ip, value.Port);
}
}
31 changes: 31 additions & 0 deletions H2MLauncher.UI/Converters/DelegateValueConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System.Globalization;
using System.Windows.Data;

namespace H2MLauncher.UI.Converters;

public class DelegateValueConverter<T> : IValueConverter
{
private readonly Func<T, object?> _convert;
private readonly Func<object?, T>? _convertBack;
private readonly Func<object?, object?> _fallback;
public DelegateValueConverter(Func<T, object?> convert, Func<object?, T>? convertBack = null, Func<object?, object?>? fallback = null)
{
_convert = convert;
_convertBack = convertBack;
_fallback = fallback ?? (_ => null);
}

public object? Convert(object? value, Type targetType, object parameter, CultureInfo culture)
{
return value is T specificValue
? _convert(specificValue)
: _fallback(value);
}

public object? ConvertBack(object? value, Type targetType, object parameter, CultureInfo culture)
{
return _convertBack is not null
? (object?)_convertBack(value)
: throw new NotImplementedException();
}
}
25 changes: 25 additions & 0 deletions H2MLauncher.UI/Converters/TypeToBooleanConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System.Globalization;
using System.Windows.Data;

namespace H2MLauncher.UI.Converters;

public class TypeToBooleanConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null || parameter == null)
{
return false;
}

Type dataType = value.GetType();
Type? expectedType = parameter as Type;

return expectedType is not null && expectedType.IsAssignableFrom(dataType);
}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
22 changes: 22 additions & 0 deletions H2MLauncher.UI/Converters/TypeToVisibilityConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System.Globalization;
using System.Windows;
using System.Windows.Data;

namespace H2MLauncher.UI.Converters;

public class TypeToVisibilityConverter : IValueConverter
{
private readonly TypeToBooleanConverter _typeBooleanConverter = new();

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return _typeBooleanConverter.Convert(value, targetType, parameter, culture) is true
? Visibility.Visible
: Visibility.Collapsed;
}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
3 changes: 0 additions & 3 deletions H2MLauncher.UI/Dialog/Views/CustomizationDialogView.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,6 @@
<Setter Property="MaxWidth" Value="400" />
</Style>




<Style x:Key="{x:Type ComboBox}" TargetType="{x:Type ComboBox}">
<Setter Property="SnapsToDevicePixels" Value="true" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
Expand Down
Loading
Loading