#nullable enable using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Text; namespace Reactor.Networking; /// /// Represents a Reactor.Protocol mod. /// public readonly struct Mod : IEquatable { /// /// Initializes a new instance of the struct. /// /// The id of the mod. /// The version of the mod. /// The flags of the mod. /// The name of the mod. public Mod(string id, string version, ModFlags flags, string? name = null) { Id = id; Version = version; Flags = flags; Name = name; } /// /// Gets the id of the mod. /// public string Id { get; } /// /// Gets the version of the mod. /// public string Version { get; } /// /// Gets the flags of the mod. /// public ModFlags Flags { get; } /// /// Gets the name of the mod. /// public string? Name { get; } /// /// Gets a value indicating whether the mod is required on all clients. /// public bool IsRequiredOnAllClients => (Flags & ModFlags.RequireOnAllClients) != 0; /// public bool Equals(Mod other) { return Id == other.Id && Version == other.Version; } /// public override bool Equals(object? obj) { return obj is Mod other && Equals(other); } /// public static bool operator ==(Mod left, Mod right) { return left.Equals(right); } /// public static bool operator !=(Mod left, Mod right) { return !(left == right); } /// public override int GetHashCode() { return HashCode.Combine(Id, Version); } /// public override string ToString() { return $"{Name ?? Id} ({Version})"; } internal static bool Validate(IReadOnlyCollection clientMods, IReadOnlyCollection hostMods, [NotNullWhen(false)] out string? reason) { var clientMissing = hostMods.Where(mod => mod.IsRequiredOnAllClients && !clientMods.Contains(mod)).ToArray(); var hostMissing = clientMods.Where(mod => mod.IsRequiredOnAllClients && !hostMods.Contains(mod)).ToArray(); if (clientMissing.Length != 0 || hostMissing.Length != 0) { var message = new StringBuilder(); if (clientMissing.Length != 0) { message.Append("You are missing: "); message.AppendJoin(", ", clientMissing.Select(x => x.ToString())); message.AppendLine(); } if (hostMissing.Length != 0) { message.Append("Host is missing: "); message.AppendJoin(", ", hostMissing.Select(x => x.ToString())); message.AppendLine(); } reason = message.ToString(); return false; } reason = null; return true; } }