namespace DorkNet.Server.Compat; /// Resolves a client-build key (e.g. december_2020_12_18) /// to its . Built once at startup from all /// registered instances. /// /// Singleton — the version-key → generation mapping is fixed at /// boot time, and the registry is read on every request by the /// version-detection middleware. /// public sealed class VersionRegistry { private readonly Dictionary _byKey; /// The set of version keys this deployment is willing to /// serve. Comes from DorkNet:SupportedVersions in config. /// Anything else gets a 426 from the middleware. public IReadOnlySet SupportedVersionKeys { get; } /// Falls back to this when a request arrives without an /// X-DorkNet-Version header — set via /// DorkNet:DefaultClientVersion in config. Empty/null means /// "no fallback; reject headerless requests". Set during the /// transition window where the old client mod doesn't yet stamp /// the header. public string? DefaultVersionKey { get; } public VersionRegistry( IEnumerable plugins, IReadOnlySet supportedVersionKeys, string? defaultVersionKey) { _byKey = new Dictionary(StringComparer.OrdinalIgnoreCase); foreach (var plugin in plugins) { foreach (var key in plugin.VersionKeys) { if (_byKey.ContainsKey(key)) throw new InvalidOperationException( $"VersionPlugin collision: '{key}' is claimed by more than one IVersionPlugin. " + $"Each version key maps to exactly one plugin."); _byKey[key] = new ClientVersion(key, plugin.Generation); } } SupportedVersionKeys = supportedVersionKeys; DefaultVersionKey = defaultVersionKey; } /// Resolve a version key (case-insensitive) to its /// , or /// if no plugin claims it. The middleware decides whether unknown /// → reject or → fall back to . public ClientVersion Resolve(string? key) { if (string.IsNullOrWhiteSpace(key)) return ClientVersion.Unknown; return _byKey.TryGetValue(key, out var v) ? v : ClientVersion.Unknown; } /// True when the given version key is in /// . Used by the middleware to /// 426 cross-version connection attempts (e.g. a March client /// hitting a server configured for December only). public bool IsSupported(string key) => SupportedVersionKeys.Contains(key); /// Every known plugin-registered version key, for /// diagnostic responses and admin tooling. public IEnumerable AllKnown => _byKey.Values; }