using System; using System.Linq; using System.Reflection; using System.Text.RegularExpressions; // Runs against the compiled, minified export, never against the shared MINER test build. // Match signatures instead of MDK-renamed identifiers; fail if the signature is ambiguous. internal static class VerifyPackedRole { static readonly BindingFlags Static = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly; static readonly Type[] SettingsArguments = { typeof(string), typeof(string), typeof(string) }; public static int Main(string[] args) { try { if (args.Length != 1 || !new[] { "fleet", "miner", "marker", "watchdog" }.Contains(args[0])) throw new ArgumentException("Supply the expected export role."); var expected = args[0]; var entry = typeof(PackedVerification.Program); var selector = entry.GetMethods(Static).Single(m => m.ReturnType == typeof(string) && m.GetParameters().Length == 0); var actual = (string)selector.Invoke(null, null); Require(actual == expected, "Export initializes as " + actual + "; expected " + expected + "."); var settings = entry.GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic) .Single(t => t.GetConstructor(SettingsArguments) != null); var create = settings.GetConstructor(SettingsArguments); var blank = create.Invoke(new object[] { "", actual, "check-id" }); var roleField = settings.GetFields(BindingFlags.Public | BindingFlags.Instance) .Single(f => f.FieldType == typeof(string) && (string)f.GetValue(blank) == actual); var template = settings.GetMethods(Static).Single(m => m.ReturnType == typeof(string) && m.GetParameters().Select(p => p.ParameterType).SequenceEqual(new[] { typeof(string), typeof(string) })); var generated = (string)template.Invoke(null, new object[] { actual, "check-id" }); Require(!Regex.IsMatch(generated, @"(?im)^\s*(Role|角色)\s*="), "Generated configuration still exposes a role parameter."); var localized = create.Invoke(new object[] { generated, actual, "fallback-id" }); Require((string)roleField.GetValue(localized) == expected, "Generated configuration has the wrong role."); Require(settings.GetFields(BindingFlags.Public | BindingFlags.Instance) .Any(f => f.FieldType == typeof(string) && (string)f.GetValue(localized) == "check-id"), "Generated configuration lost its ID."); var existing = create.Invoke(new object[] { "[System]\nRole=" + expected + "\nId=existing-id\n", actual, "fallback-id" }); Require((string)roleField.GetValue(existing) == expected, "Existing configuration cannot load its role."); foreach (var oldValue in new[] { "miner", "fleet", "marker", "watchdog", "", "not-a-role" }) { var old = create.Invoke(new object[] { "[System]\nRole=" + oldValue + "\nId=check-id\n", actual, "fallback-id" }); Require((string)roleField.GetValue(old) == expected, "Legacy role changed the compiled identity."); } var mixed = create.Invoke(new object[] { "[System]\nRole=invalid\n[系统]\n角色=legacy\n", actual, "check-id" }); Require((string)roleField.GetValue(mixed) == expected, "Legacy Chinese/English role aliases changed the compiled identity."); Console.WriteLine("Packed role verified: " + expected + " (compiled identity, role-free template, default/localized/existing configuration, ignored legacy roles)."); return 0; } catch (Exception e) { Console.Error.WriteLine("Packed role verification failed: " + e.GetBaseException().Message); return 1; } } static void Require(bool condition, string message) { if (!condition) throw new InvalidOperationException(message); } }