using System.Reflection; using FinalFactory.Rendezvous.Contracts; namespace FinalFactory.Rendezvous.Server.Operations; internal static class ReleaseCompatibility { private static readonly Assembly ServerAssembly = typeof(ReleaseCompatibility).Assembly; internal static string MinimumClientVersion => Metadata("RendezvousMinimumClientVersion"); internal static int MaximumClientMajorVersion => MetadataInteger("RendezvousMaximumClientMajorVersion"); internal static int UdpContractVersion => MetadataInteger("RendezvousUdpContractVersion"); internal static int ConnectionTicketFormatVersion => MetadataInteger("RendezvousConnectionTicketFormatVersion"); internal static int LiteNetLibMajorVersion => MetadataInteger("RendezvousLiteNetLibMajorVersion"); internal static OperatorCompatibilityResponse CreateResponse() => new() { ServerVersion = ServerAssembly .GetCustomAttribute()? .InformationalVersion.Split('+', 2)[0] ?? ServerAssembly.GetName().Version?.ToString(3) ?? "unknown", MinimumClientVersion = MinimumClientVersion, MaximumClientMajorVersion = MaximumClientMajorVersion, HttpContractVersions = [ContractLimits.ContractVersion], UdpContractVersions = [UdpContractVersion], ConnectionTicketFormatVersions = [ConnectionTicketFormatVersion], LiteNetLibMajorVersion = LiteNetLibMajorVersion, GameplayProtocolCompatibility = "exact-per-tenant", }; private static string Metadata(string key) => ServerAssembly .GetCustomAttributes() .Single(attribute => string.Equals(attribute.Key, key, StringComparison.Ordinal)) .Value ?? throw new InvalidOperationException($"Assembly metadata {key} has no value."); private static int MetadataInteger(string key) => int.Parse( Metadata(key), System.Globalization.CultureInfo.InvariantCulture); }