Skip to content

Commit

Permalink
Merge pull request #45 from MaxWasUnavailable/feat_lobbydiff-unknown
Browse files Browse the repository at this point in the history
Feat lobbydiff unknown
  • Loading branch information
legoandmars authored Feb 18, 2024
2 parents b30c7fc + 1682ea0 commit 72f762d
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 37 deletions.
7 changes: 6 additions & 1 deletion LobbyCompatibility/Enums/LobbyDiffResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@ public enum LobbyDiffResult
Incompatible,

/// <summary>
/// Mod list does not exist, and lobby might be compatible.
/// Mod list is compatible, except for unknown mods.
/// </summary>
PresumedCompatible,

/// <summary>
/// Mod list information is not available, server does not have LobbyCompatibility installed, or other unknown cause.
/// Also applies to vanilla lobbies.
/// </summary>
Unknown
Expand Down
50 changes: 30 additions & 20 deletions LobbyCompatibility/Features/LobbyHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,11 @@ namespace LobbyCompatibility.Features;
/// </summary>
internal static class LobbyHelper
{
public static LobbyDiff LatestLobbyDiff { get; private set; } = new(new List<PluginDiff>());
public static Dictionary<string, string> LatestLobbyRequestStringFilters = new();
public static LobbyDistanceFilter? LatestLobbyRequestDistanceFilter;

private static Dictionary<ulong, LobbyDiff> _lobbyDiffCache { get; set; } = new();
private static List<PluginInfoRecord>? _clientPlugins;
public static LobbyDiff LatestLobbyDiff { get; private set; } = new(new List<PluginDiff>());
private static Dictionary<ulong, LobbyDiff> LobbyDiffCache { get; } = new();

/// <summary>
/// Get a <see cref="LobbyDiff" /> from a <see cref="Lobby" />.
Expand All @@ -35,7 +34,7 @@ internal static class LobbyHelper
/// <returns> The <see cref="LobbyDiff" />. </returns>
internal static LobbyDiff GetLobbyDiff(Lobby lobby, string? lobbyPluginString)
{
if (_lobbyDiffCache.TryGetValue(lobby.Id, out var cachedLobbyDiff))
if (LobbyDiffCache.TryGetValue(lobby.Id, out var cachedLobbyDiff))
return cachedLobbyDiff;

var lobbyPlugins = PluginHelper
Expand Down Expand Up @@ -106,10 +105,12 @@ internal static LobbyDiff GetLobbyDiff(Lobby lobby, string? lobbyPluginString)
clientPlugin.Version, null));
}

LatestLobbyDiff = new LobbyDiff(pluginDiffs);
var lobbyCompatibilityPresent = lobbyPlugins.Any();

LatestLobbyDiff = new LobbyDiff(pluginDiffs, lobbyCompatibilityPresent);

// Add to cache to avoid making multiple unnecessary GetData() calls
_lobbyDiffCache.Add(lobby.Id, LatestLobbyDiff);
LobbyDiffCache.Add(lobby.Id, LatestLobbyDiff);

return LatestLobbyDiff;
}
Expand Down Expand Up @@ -151,17 +152,16 @@ public static string GetCompatibilityHeader(PluginDiffResult pluginDiffResult)
/// <param name="filteredLobbies"> A custom list of lobbies, with special search filters applied. </param>
/// <param name="currentFilter"> The <see cref="ModdedLobbyFilter" /> to filter the lobbies against. </param>
/// <returns> A <see cref="Lobby" /> array with the <see cref="ModdedLobbyFilter" /> applied. </returns>
public static Lobby[] FilterLobbies(Lobby[] normalLobbies, Lobby[]? filteredLobbies, ModdedLobbyFilter currentFilter)
public static Lobby[] FilterLobbies(Lobby[] normalLobbies, Lobby[]? filteredLobbies,
ModdedLobbyFilter currentFilter)
{
List<Lobby> allLobbies = new();

if (filteredLobbies != null)
{
// Remove duplicate "normal" lobbies if they were also caught by the hashfilter
normalLobbies = normalLobbies
.Where(lobby => !filteredLobbies.Any(check => lobby.Equals(check)))
.ToArray();
}

if (currentFilter == ModdedLobbyFilter.VanillaAndUnknownOnly)
{
Expand All @@ -173,11 +173,13 @@ public static Lobby[] FilterLobbies(Lobby[] normalLobbies, Lobby[]? filteredLobb
// Add only lobbies that are vanilla/unknown
allLobbies.AddRange(FilterLobbiesByDiffResult(normalLobbies, LobbyDiffResult.Unknown));
}
else if (filteredLobbies != null && (currentFilter == ModdedLobbyFilter.CompatibleFirst || currentFilter == ModdedLobbyFilter.CompatibleOnly))
else if (filteredLobbies != null && currentFilter is ModdedLobbyFilter.CompatibleFirst or ModdedLobbyFilter.CompatibleOnly)
{
// Lobbies returned by the hashfilter are not 100% going to always be compatible, so we'll still need to filter them
var (compatibleFilteredLobbies, otherFilteredLobbies) = SplitLobbiesByDiffResult(filteredLobbies, LobbyDiffResult.Compatible);
var (compatibleNormalLobbies, otherNormalLobbies) = SplitLobbiesByDiffResult(normalLobbies, LobbyDiffResult.Compatible);
var (compatibleFilteredLobbies, otherFilteredLobbies) =
SplitLobbiesByDiffResult(filteredLobbies, LobbyDiffResult.Compatible);
var (compatibleNormalLobbies, otherNormalLobbies) =
SplitLobbiesByDiffResult(normalLobbies, LobbyDiffResult.Compatible);

// Add filtered lobbies that are 100% compatible first, then any extra compatible lobbies not caught by the hashfilter
allLobbies.AddRange(compatibleFilteredLobbies);
Expand All @@ -193,7 +195,7 @@ public static Lobby[] FilterLobbies(Lobby[] normalLobbies, Lobby[]? filteredLobb
else if (filteredLobbies == null && currentFilter == ModdedLobbyFilter.CompatibleOnly)
{
// Handle the special case where we're sorting for compatible only and nothing comes up, so we need to force return nothing
allLobbies = new();
allLobbies = new List<Lobby>();
}
else
{
Expand All @@ -205,12 +207,17 @@ public static Lobby[] FilterLobbies(Lobby[] normalLobbies, Lobby[]? filteredLobb
}

/// <summary>
/// Splits a <see cref="Lobby" /> IEnumerable into two arrays based on of it matches <see cref="LobbyDiffResult" /> or not.
/// Splits a <see cref="Lobby" /> IEnumerable into two arrays based on of it matches <see cref="LobbyDiffResult" /> or
/// not.
/// </summary>
/// <param name="lobbies"> The lobbies. </param>
/// <param name="filteredLobbyDiffResult"> The <see cref="LobbyDiffResult" /> to match against. </param>
/// <returns> A tuple containing two <see cref="Lobby"/> IEnumerables. matchedLobbies contains the lobbies that match the LobbyDiffResult, and unmatchedLobbies contains everything else. </returns>
private static (IEnumerable<Lobby> matchedLobbies, IEnumerable<Lobby> unmatchedLobbies) SplitLobbiesByDiffResult(IEnumerable<Lobby> lobbies, LobbyDiffResult filteredLobbyDiffResult)
/// <returns>
/// A tuple containing two <see cref="Lobby" /> IEnumerables. matchedLobbies contains the lobbies that match the
/// LobbyDiffResult, and unmatchedLobbies contains everything else.
/// </returns>
private static (IEnumerable<Lobby> matchedLobbies, IEnumerable<Lobby> unmatchedLobbies) SplitLobbiesByDiffResult(
IEnumerable<Lobby> lobbies, LobbyDiffResult filteredLobbyDiffResult)
{
List<Lobby> matchedLobbies = new();
List<Lobby> unmatchedLobbies = new();
Expand All @@ -233,11 +240,14 @@ private static (IEnumerable<Lobby> matchedLobbies, IEnumerable<Lobby> unmatchedL
/// <param name="lobbies"> The lobbies. </param>
/// <param name="filteredLobbyDiffResult"> The <see cref="LobbyDiffResult" /> to match against. </param>
/// <returns> A filtered <see cref="Lobby" /> IEnumerable. </returns>
private static IEnumerable<Lobby> FilterLobbiesByDiffResult(IEnumerable<Lobby> lobbies, LobbyDiffResult filteredLobbyDiffResult)
=> SplitLobbiesByDiffResult(lobbies, filteredLobbyDiffResult).matchedLobbies;
private static IEnumerable<Lobby> FilterLobbiesByDiffResult(IEnumerable<Lobby> lobbies,
LobbyDiffResult filteredLobbyDiffResult)
{
return SplitLobbiesByDiffResult(lobbies, filteredLobbyDiffResult).matchedLobbies;
}

/// <summary>
/// Gets the error message for when no lobbies are found using a <see cref="ModdedLobbyFilter"/>.
/// Gets the error message for when no lobbies are found using a <see cref="ModdedLobbyFilter" />.
/// </summary>
/// <param name="moddedLobbyFilter"> The <see cref="ModdedLobbyFilter" /> to get the error message for. </param>
public static string GetEmptyLobbyListString(ModdedLobbyFilter moddedLobbyFilter)
Expand All @@ -249,4 +259,4 @@ public static string GetEmptyLobbyListString(ModdedLobbyFilter moddedLobbyFilter
_ => "No available servers to join."
};
}
}
}
11 changes: 7 additions & 4 deletions LobbyCompatibility/Features/PluginHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -198,12 +198,15 @@ internal static bool MatchesTargetRequirements(IEnumerable<PluginInfoRecord> tar
}

/// <summary>
/// Checks if client is allowed to join vanilla lobbies.
/// Checks if client is allowed to join vanilla or unknown lobbies.
/// </summary>
/// <returns> True if client is allowed to join vanilla lobbies, false otherwise. </returns>
/// <returns> True if client is allowed to join vanilla or unknown lobbies, false otherwise. </returns>
/// <remarks> This means the client is allowed to have unknown or clientside mods. </remarks>
internal static bool CanJoinVanillaLobbies()
{
return GetAllPluginInfo().All(plugin => plugin.CompatibilityLevel is CompatibilityLevel.ClientOnly or null);
return GetAllPluginInfo().All(plugin =>
plugin.CompatibilityLevel != CompatibilityLevel.Everyone &&
plugin.CompatibilityLevel != CompatibilityLevel.ClientOptional);
}

/// <summary>
Expand Down Expand Up @@ -284,4 +287,4 @@ private static string GetRequiredPluginsChecksum()

return _cachedChecksum = stringBuilder.ToString();
}
}
}
23 changes: 11 additions & 12 deletions LobbyCompatibility/Models/LobbyDiff.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ namespace LobbyCompatibility.Models;
/// Container for diffs between lobby and client plugins.
/// </summary>
/// <param name="PluginDiffs"> The diffs between the lobby and client plugins. </param>
public record LobbyDiff(List<PluginDiff> PluginDiffs)
/// <param name="LobbyCompatibilityPresent"> Whether or not the lobby has this mod installed. </param>
public record LobbyDiff(List<PluginDiff> PluginDiffs, bool LobbyCompatibilityPresent = true)
{
private LobbyDiffResult? _cachedResult;

Expand All @@ -30,20 +31,18 @@ internal LobbyDiffResult GetModdedLobbyType()
if (_cachedResult != null)
return (LobbyDiffResult)_cachedResult;

if (PluginDiffs.Count == 0)
{
_cachedResult = LobbyDiffResult.Unknown;
return LobbyDiffResult.Unknown;
}
if (!LobbyCompatibilityPresent)
return (LobbyDiffResult)(_cachedResult = LobbyDiffResult.Unknown);

var unknownFound = PluginDiffs.Any(pluginDiff => pluginDiff.PluginDiffResult == PluginDiffResult.Unknown);

if (PluginDiffs.Any(pluginDiff => pluginDiff.PluginDiffResult != PluginDiffResult.Compatible &&
pluginDiff.PluginDiffResult != PluginDiffResult.Unknown))
{
_cachedResult = LobbyDiffResult.Incompatible;
return LobbyDiffResult.Incompatible;
}
return (LobbyDiffResult)(_cachedResult = LobbyDiffResult.Incompatible);

if (unknownFound)
return (LobbyDiffResult)(_cachedResult = LobbyDiffResult.PresumedCompatible);

_cachedResult = LobbyDiffResult.Compatible;
return LobbyDiffResult.Compatible;
return (LobbyDiffResult)(_cachedResult = LobbyDiffResult.Compatible);
}
}

0 comments on commit 72f762d

Please sign in to comment.