From 42f897c7654eb17e5e4af096f62fc9747eb61de4 Mon Sep 17 00:00:00 2001 From: 502y <53784463+502y@users.noreply.github.com> Date: Sat, 13 Jun 2026 23:57:48 +0800 Subject: [PATCH 01/12] =?UTF-8?q?feat(NS):=20=E6=B7=BB=E5=8A=A0=E8=AF=86?= =?UTF-8?q?=E5=88=AB=E7=A0=81=E7=A4=BA=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/packer/1.12.2.json | 3 +++ .../lang/en_us.lang | 0 .../lang/zh_cn.lang | 0 .../{ae2stuff => ae2stuff-CFPA-AE2 Stuff}/lang/en_us.lang | 0 .../{ae2stuff => ae2stuff-CFPA-AE2 Stuff}/lang/zh_cn.lang | 0 5 files changed, 3 insertions(+) rename projects/assets/ae2-stuff-unofficial/1.12.2/{ae2stuff => ae2stuff-CFPA-AE2 Stuff Unofficial}/lang/en_us.lang (100%) rename projects/assets/ae2-stuff-unofficial/1.12.2/{ae2stuff => ae2stuff-CFPA-AE2 Stuff Unofficial}/lang/zh_cn.lang (100%) rename projects/assets/ae2-stuff/1.12.2/{ae2stuff => ae2stuff-CFPA-AE2 Stuff}/lang/en_us.lang (100%) rename projects/assets/ae2-stuff/1.12.2/{ae2stuff => ae2stuff-CFPA-AE2 Stuff}/lang/zh_cn.lang (100%) diff --git a/config/packer/1.12.2.json b/config/packer/1.12.2.json index b084153c9137..e614cdc46241 100644 --- a/config/packer/1.12.2.json +++ b/config/packer/1.12.2.json @@ -50,5 +50,8 @@ "……": "\u22ef\u22ef" }, "destinationReplacement": {} + }, + "rules": { + "ae2-stuff": "displayName" } } \ No newline at end of file diff --git a/projects/assets/ae2-stuff-unofficial/1.12.2/ae2stuff/lang/en_us.lang b/projects/assets/ae2-stuff-unofficial/1.12.2/ae2stuff-CFPA-AE2 Stuff Unofficial/lang/en_us.lang similarity index 100% rename from projects/assets/ae2-stuff-unofficial/1.12.2/ae2stuff/lang/en_us.lang rename to projects/assets/ae2-stuff-unofficial/1.12.2/ae2stuff-CFPA-AE2 Stuff Unofficial/lang/en_us.lang diff --git a/projects/assets/ae2-stuff-unofficial/1.12.2/ae2stuff/lang/zh_cn.lang b/projects/assets/ae2-stuff-unofficial/1.12.2/ae2stuff-CFPA-AE2 Stuff Unofficial/lang/zh_cn.lang similarity index 100% rename from projects/assets/ae2-stuff-unofficial/1.12.2/ae2stuff/lang/zh_cn.lang rename to projects/assets/ae2-stuff-unofficial/1.12.2/ae2stuff-CFPA-AE2 Stuff Unofficial/lang/zh_cn.lang diff --git a/projects/assets/ae2-stuff/1.12.2/ae2stuff/lang/en_us.lang b/projects/assets/ae2-stuff/1.12.2/ae2stuff-CFPA-AE2 Stuff/lang/en_us.lang similarity index 100% rename from projects/assets/ae2-stuff/1.12.2/ae2stuff/lang/en_us.lang rename to projects/assets/ae2-stuff/1.12.2/ae2stuff-CFPA-AE2 Stuff/lang/en_us.lang diff --git a/projects/assets/ae2-stuff/1.12.2/ae2stuff/lang/zh_cn.lang b/projects/assets/ae2-stuff/1.12.2/ae2stuff-CFPA-AE2 Stuff/lang/zh_cn.lang similarity index 100% rename from projects/assets/ae2-stuff/1.12.2/ae2stuff/lang/zh_cn.lang rename to projects/assets/ae2-stuff/1.12.2/ae2stuff-CFPA-AE2 Stuff/lang/zh_cn.lang From b517fcd574e49bc8b7630185204a84af06466266 Mon Sep 17 00:00:00 2001 From: 502y <53784463+502y@users.noreply.github.com> Date: Sun, 14 Jun 2026 13:13:44 +0800 Subject: [PATCH 02/12] =?UTF-8?q?fix(NS):=20=E9=87=8D=E5=91=BD=E5=90=8Dide?= =?UTF-8?q?ntifier=E4=BB=A5=E9=81=BF=E5=85=8D=E7=A9=BA=E6=A0=BC=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lang/en_us.lang | 0 .../lang/zh_cn.lang | 0 .../lang/en_us.lang | 0 .../lang/zh_cn.lang | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename projects/assets/ae2-stuff-unofficial/1.12.2/{ae2stuff-CFPA-AE2 Stuff Unofficial => ae2stuff-CFPA-AE2_Stuff_Unofficial}/lang/en_us.lang (100%) rename projects/assets/ae2-stuff-unofficial/1.12.2/{ae2stuff-CFPA-AE2 Stuff Unofficial => ae2stuff-CFPA-AE2_Stuff_Unofficial}/lang/zh_cn.lang (100%) rename projects/assets/ae2-stuff/1.12.2/{ae2stuff-CFPA-AE2 Stuff => ae2stuff-CFPA-AE2_Stuff}/lang/en_us.lang (100%) rename projects/assets/ae2-stuff/1.12.2/{ae2stuff-CFPA-AE2 Stuff => ae2stuff-CFPA-AE2_Stuff}/lang/zh_cn.lang (100%) diff --git a/projects/assets/ae2-stuff-unofficial/1.12.2/ae2stuff-CFPA-AE2 Stuff Unofficial/lang/en_us.lang b/projects/assets/ae2-stuff-unofficial/1.12.2/ae2stuff-CFPA-AE2_Stuff_Unofficial/lang/en_us.lang similarity index 100% rename from projects/assets/ae2-stuff-unofficial/1.12.2/ae2stuff-CFPA-AE2 Stuff Unofficial/lang/en_us.lang rename to projects/assets/ae2-stuff-unofficial/1.12.2/ae2stuff-CFPA-AE2_Stuff_Unofficial/lang/en_us.lang diff --git a/projects/assets/ae2-stuff-unofficial/1.12.2/ae2stuff-CFPA-AE2 Stuff Unofficial/lang/zh_cn.lang b/projects/assets/ae2-stuff-unofficial/1.12.2/ae2stuff-CFPA-AE2_Stuff_Unofficial/lang/zh_cn.lang similarity index 100% rename from projects/assets/ae2-stuff-unofficial/1.12.2/ae2stuff-CFPA-AE2 Stuff Unofficial/lang/zh_cn.lang rename to projects/assets/ae2-stuff-unofficial/1.12.2/ae2stuff-CFPA-AE2_Stuff_Unofficial/lang/zh_cn.lang diff --git a/projects/assets/ae2-stuff/1.12.2/ae2stuff-CFPA-AE2 Stuff/lang/en_us.lang b/projects/assets/ae2-stuff/1.12.2/ae2stuff-CFPA-AE2_Stuff/lang/en_us.lang similarity index 100% rename from projects/assets/ae2-stuff/1.12.2/ae2stuff-CFPA-AE2 Stuff/lang/en_us.lang rename to projects/assets/ae2-stuff/1.12.2/ae2stuff-CFPA-AE2_Stuff/lang/en_us.lang diff --git a/projects/assets/ae2-stuff/1.12.2/ae2stuff-CFPA-AE2 Stuff/lang/zh_cn.lang b/projects/assets/ae2-stuff/1.12.2/ae2stuff-CFPA-AE2_Stuff/lang/zh_cn.lang similarity index 100% rename from projects/assets/ae2-stuff/1.12.2/ae2stuff-CFPA-AE2 Stuff/lang/zh_cn.lang rename to projects/assets/ae2-stuff/1.12.2/ae2stuff-CFPA-AE2_Stuff/lang/zh_cn.lang From e9ead46064c29c761bf748549c9ffe957a063dd1 Mon Sep 17 00:00:00 2001 From: 502y <53784463+502y@users.noreply.github.com> Date: Mon, 15 Jun 2026 09:29:58 +0800 Subject: [PATCH 03/12] fix(NS): modify regex --- .../lang/en_us.lang | 0 .../lang/zh_cn.lang | 0 .../lang/en_us.lang | 0 .../lang/zh_cn.lang | 0 src/Packer/Extensions/ContentExtension.cs | 7 ++++--- 5 files changed, 4 insertions(+), 3 deletions(-) rename projects/assets/ae2-stuff-unofficial/1.12.2/{ae2stuff-CFPA-AE2_Stuff_Unofficial => ae2stuff-CFPA-AE2 Stuff Unofficial}/lang/en_us.lang (100%) rename projects/assets/ae2-stuff-unofficial/1.12.2/{ae2stuff-CFPA-AE2_Stuff_Unofficial => ae2stuff-CFPA-AE2 Stuff Unofficial}/lang/zh_cn.lang (100%) rename projects/assets/ae2-stuff/1.12.2/{ae2stuff-CFPA-AE2_Stuff => ae2stuff-CFPA-AE2 Stuff}/lang/en_us.lang (100%) rename projects/assets/ae2-stuff/1.12.2/{ae2stuff-CFPA-AE2_Stuff => ae2stuff-CFPA-AE2 Stuff}/lang/zh_cn.lang (100%) diff --git a/projects/assets/ae2-stuff-unofficial/1.12.2/ae2stuff-CFPA-AE2_Stuff_Unofficial/lang/en_us.lang b/projects/assets/ae2-stuff-unofficial/1.12.2/ae2stuff-CFPA-AE2 Stuff Unofficial/lang/en_us.lang similarity index 100% rename from projects/assets/ae2-stuff-unofficial/1.12.2/ae2stuff-CFPA-AE2_Stuff_Unofficial/lang/en_us.lang rename to projects/assets/ae2-stuff-unofficial/1.12.2/ae2stuff-CFPA-AE2 Stuff Unofficial/lang/en_us.lang diff --git a/projects/assets/ae2-stuff-unofficial/1.12.2/ae2stuff-CFPA-AE2_Stuff_Unofficial/lang/zh_cn.lang b/projects/assets/ae2-stuff-unofficial/1.12.2/ae2stuff-CFPA-AE2 Stuff Unofficial/lang/zh_cn.lang similarity index 100% rename from projects/assets/ae2-stuff-unofficial/1.12.2/ae2stuff-CFPA-AE2_Stuff_Unofficial/lang/zh_cn.lang rename to projects/assets/ae2-stuff-unofficial/1.12.2/ae2stuff-CFPA-AE2 Stuff Unofficial/lang/zh_cn.lang diff --git a/projects/assets/ae2-stuff/1.12.2/ae2stuff-CFPA-AE2_Stuff/lang/en_us.lang b/projects/assets/ae2-stuff/1.12.2/ae2stuff-CFPA-AE2 Stuff/lang/en_us.lang similarity index 100% rename from projects/assets/ae2-stuff/1.12.2/ae2stuff-CFPA-AE2_Stuff/lang/en_us.lang rename to projects/assets/ae2-stuff/1.12.2/ae2stuff-CFPA-AE2 Stuff/lang/en_us.lang diff --git a/projects/assets/ae2-stuff/1.12.2/ae2stuff-CFPA-AE2_Stuff/lang/zh_cn.lang b/projects/assets/ae2-stuff/1.12.2/ae2stuff-CFPA-AE2 Stuff/lang/zh_cn.lang similarity index 100% rename from projects/assets/ae2-stuff/1.12.2/ae2stuff-CFPA-AE2_Stuff/lang/zh_cn.lang rename to projects/assets/ae2-stuff/1.12.2/ae2stuff-CFPA-AE2 Stuff/lang/zh_cn.lang diff --git a/src/Packer/Extensions/ContentExtension.cs b/src/Packer/Extensions/ContentExtension.cs index 7b07838e938c..c63dc85f332d 100644 --- a/src/Packer/Extensions/ContentExtension.cs +++ b/src/Packer/Extensions/ContentExtension.cs @@ -27,14 +27,15 @@ public static string GetNamespace(this string path) } - [GeneratedRegex(@"^[a-z0-9_.-]+$", RegexOptions.Singleline)] - internal static partial Regex ValidNamespaceRegex(); + [GeneratedRegex(@"^[a-z0-9_.-]+(?:-CFPA-[A-Za-z0-9_.\- ]+)?$", RegexOptions.Singleline)] + internal static partial Regex ValidNamespaceRegex(); /// /// 检查命名空间名称是否合法 /// /// - /// 合法的命名空间名称只包括小写字母、数字、_、.、- + /// 合法的命名空间名称只包括小写字母、数字、_、.、-; + /// 也允许在合法命名空间后追加 -CFPA- 与作者名,作者名可包含大小写英文字母、数字、-、_、. 和空格。 /// /// 待校验的命名空间名称 /// 若合法,返回 From 328fe6b7e09dc9957ffbcfb298569135e08e54ff Mon Sep 17 00:00:00 2001 From: 502y <53784463+502y@users.noreply.github.com> Date: Sun, 21 Jun 2026 19:58:30 +0800 Subject: [PATCH 04/12] =?UTF-8?q?feat(NS):=20=E6=94=B9=E4=B8=BAlocal-confi?= =?UTF-8?q?g=E5=AD=98=E5=82=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lang/en_us.lang | 0 .../lang/zh_cn.lang | 0 .../1.12.2/ae2stuff/local-config.json | 10 ++++++++++ .../lang/en_us.lang | 0 .../lang/zh_cn.lang | 0 .../assets/ae2-stuff/1.12.2/ae2stuff/local-config.json | 9 +++++++++ src/Packer/Extensions/ContentExtension.cs | 7 +++---- 7 files changed, 22 insertions(+), 4 deletions(-) rename projects/assets/ae2-stuff-unofficial/1.12.2/{ae2stuff-CFPA-AE2 Stuff Unofficial => ae2stuff}/lang/en_us.lang (100%) rename projects/assets/ae2-stuff-unofficial/1.12.2/{ae2stuff-CFPA-AE2 Stuff Unofficial => ae2stuff}/lang/zh_cn.lang (100%) create mode 100644 projects/assets/ae2-stuff-unofficial/1.12.2/ae2stuff/local-config.json rename projects/assets/ae2-stuff/1.12.2/{ae2stuff-CFPA-AE2 Stuff => ae2stuff}/lang/en_us.lang (100%) rename projects/assets/ae2-stuff/1.12.2/{ae2stuff-CFPA-AE2 Stuff => ae2stuff}/lang/zh_cn.lang (100%) create mode 100644 projects/assets/ae2-stuff/1.12.2/ae2stuff/local-config.json diff --git a/projects/assets/ae2-stuff-unofficial/1.12.2/ae2stuff-CFPA-AE2 Stuff Unofficial/lang/en_us.lang b/projects/assets/ae2-stuff-unofficial/1.12.2/ae2stuff/lang/en_us.lang similarity index 100% rename from projects/assets/ae2-stuff-unofficial/1.12.2/ae2stuff-CFPA-AE2 Stuff Unofficial/lang/en_us.lang rename to projects/assets/ae2-stuff-unofficial/1.12.2/ae2stuff/lang/en_us.lang diff --git a/projects/assets/ae2-stuff-unofficial/1.12.2/ae2stuff-CFPA-AE2 Stuff Unofficial/lang/zh_cn.lang b/projects/assets/ae2-stuff-unofficial/1.12.2/ae2stuff/lang/zh_cn.lang similarity index 100% rename from projects/assets/ae2-stuff-unofficial/1.12.2/ae2stuff-CFPA-AE2 Stuff Unofficial/lang/zh_cn.lang rename to projects/assets/ae2-stuff-unofficial/1.12.2/ae2stuff/lang/zh_cn.lang diff --git a/projects/assets/ae2-stuff-unofficial/1.12.2/ae2stuff/local-config.json b/projects/assets/ae2-stuff-unofficial/1.12.2/ae2stuff/local-config.json new file mode 100644 index 000000000000..3b442bc98d81 --- /dev/null +++ b/projects/assets/ae2-stuff-unofficial/1.12.2/ae2stuff/local-config.json @@ -0,0 +1,10 @@ +{ + "inclusionDomains": [], + "exclusionDomains": [], + "exclusionPaths": [], + "inclusionPaths": [], + "characterReplacement": {}, + "destinationReplacement": {}, + "namespaceDiscriminator": "AE2 Stuff" + +} \ No newline at end of file diff --git a/projects/assets/ae2-stuff/1.12.2/ae2stuff-CFPA-AE2 Stuff/lang/en_us.lang b/projects/assets/ae2-stuff/1.12.2/ae2stuff/lang/en_us.lang similarity index 100% rename from projects/assets/ae2-stuff/1.12.2/ae2stuff-CFPA-AE2 Stuff/lang/en_us.lang rename to projects/assets/ae2-stuff/1.12.2/ae2stuff/lang/en_us.lang diff --git a/projects/assets/ae2-stuff/1.12.2/ae2stuff-CFPA-AE2 Stuff/lang/zh_cn.lang b/projects/assets/ae2-stuff/1.12.2/ae2stuff/lang/zh_cn.lang similarity index 100% rename from projects/assets/ae2-stuff/1.12.2/ae2stuff-CFPA-AE2 Stuff/lang/zh_cn.lang rename to projects/assets/ae2-stuff/1.12.2/ae2stuff/lang/zh_cn.lang diff --git a/projects/assets/ae2-stuff/1.12.2/ae2stuff/local-config.json b/projects/assets/ae2-stuff/1.12.2/ae2stuff/local-config.json new file mode 100644 index 000000000000..d43ba847df81 --- /dev/null +++ b/projects/assets/ae2-stuff/1.12.2/ae2stuff/local-config.json @@ -0,0 +1,9 @@ +{ + "inclusionDomains": [], + "exclusionDomains": [], + "exclusionPaths": [], + "inclusionPaths": [], + "characterReplacement": {}, + "destinationReplacement": {}, + "namespaceDiscriminator": "AE2 Stuff Unofficial" +} \ No newline at end of file diff --git a/src/Packer/Extensions/ContentExtension.cs b/src/Packer/Extensions/ContentExtension.cs index c63dc85f332d..7b07838e938c 100644 --- a/src/Packer/Extensions/ContentExtension.cs +++ b/src/Packer/Extensions/ContentExtension.cs @@ -27,15 +27,14 @@ public static string GetNamespace(this string path) } - [GeneratedRegex(@"^[a-z0-9_.-]+(?:-CFPA-[A-Za-z0-9_.\- ]+)?$", RegexOptions.Singleline)] - internal static partial Regex ValidNamespaceRegex(); + [GeneratedRegex(@"^[a-z0-9_.-]+$", RegexOptions.Singleline)] + internal static partial Regex ValidNamespaceRegex(); /// /// 检查命名空间名称是否合法 /// /// - /// 合法的命名空间名称只包括小写字母、数字、_、.、-; - /// 也允许在合法命名空间后追加 -CFPA- 与作者名,作者名可包含大小写英文字母、数字、-、_、. 和空格。 + /// 合法的命名空间名称只包括小写字母、数字、_、.、- /// /// 待校验的命名空间名称 /// 若合法,返回 From 98faeba8316924957b398ced24b76b67d9bd75f2 Mon Sep 17 00:00:00 2001 From: 502y <53784463+502y@users.noreply.github.com> Date: Sun, 21 Jun 2026 20:09:28 +0800 Subject: [PATCH 05/12] feat(NS): forget to modify namespaceDiscriminator --- config/packer/1.12.2.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/packer/1.12.2.json b/config/packer/1.12.2.json index e614cdc46241..0ad5575ab60b 100644 --- a/config/packer/1.12.2.json +++ b/config/packer/1.12.2.json @@ -51,7 +51,7 @@ }, "destinationReplacement": {} }, - "rules": { + "namespaceDiscriminator": { "ae2-stuff": "displayName" } } \ No newline at end of file From 76dba2d594c1c35a1a5a916c902fb2a346ada981 Mon Sep 17 00:00:00 2001 From: 502y <53784463+502y@users.noreply.github.com> Date: Tue, 23 Jun 2026 11:25:38 +0800 Subject: [PATCH 06/12] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20local-config.json?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- projects/assets/ae2-stuff/1.12.2/ae2stuff/local-config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/assets/ae2-stuff/1.12.2/ae2stuff/local-config.json b/projects/assets/ae2-stuff/1.12.2/ae2stuff/local-config.json index d43ba847df81..2a2cd96ed1a5 100644 --- a/projects/assets/ae2-stuff/1.12.2/ae2stuff/local-config.json +++ b/projects/assets/ae2-stuff/1.12.2/ae2stuff/local-config.json @@ -5,5 +5,5 @@ "inclusionPaths": [], "characterReplacement": {}, "destinationReplacement": {}, - "namespaceDiscriminator": "AE2 Stuff Unofficial" + "namespaceDiscriminator": "AE2 Stuff" } \ No newline at end of file From 0014e854efcef5ce020091bb404db725c0fa7e7f Mon Sep 17 00:00:00 2001 From: 502y <53784463+502y@users.noreply.github.com> Date: Tue, 23 Jun 2026 11:25:51 +0800 Subject: [PATCH 07/12] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20local-config.json?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ae2-stuff-unofficial/1.12.2/ae2stuff/local-config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/assets/ae2-stuff-unofficial/1.12.2/ae2stuff/local-config.json b/projects/assets/ae2-stuff-unofficial/1.12.2/ae2stuff/local-config.json index 3b442bc98d81..51a67d3edf7d 100644 --- a/projects/assets/ae2-stuff-unofficial/1.12.2/ae2stuff/local-config.json +++ b/projects/assets/ae2-stuff-unofficial/1.12.2/ae2stuff/local-config.json @@ -5,6 +5,6 @@ "inclusionPaths": [], "characterReplacement": {}, "destinationReplacement": {}, - "namespaceDiscriminator": "AE2 Stuff" + "namespaceDiscriminator": "AE2 Stuff Unofficial" } \ No newline at end of file From c9716f8f4054ea9dd8709f4fbd94769a9581951b Mon Sep 17 00:00:00 2001 From: 502y <53784463+502y@users.noreply.github.com> Date: Thu, 25 Jun 2026 22:30:24 +0800 Subject: [PATCH 08/12] feat(NS): modify to new file --- config/packer/namespace-discriminator.json | 12 ++++++++++++ .../1.12.2/ae2stuff/local-config.json | 10 ---------- .../ae2-stuff/1.12.2/ae2stuff/local-config.json | 9 --------- 3 files changed, 12 insertions(+), 19 deletions(-) create mode 100644 config/packer/namespace-discriminator.json delete mode 100644 projects/assets/ae2-stuff-unofficial/1.12.2/ae2stuff/local-config.json delete mode 100644 projects/assets/ae2-stuff/1.12.2/ae2stuff/local-config.json diff --git a/config/packer/namespace-discriminator.json b/config/packer/namespace-discriminator.json new file mode 100644 index 000000000000..5e907ddb1446 --- /dev/null +++ b/config/packer/namespace-discriminator.json @@ -0,0 +1,12 @@ +[ + { + "namespace": "ae2stuff", + "operator": "displayName", + "effectScope": { + "ae2-stuff": "AE2 Stuff", + "ae2-stuff-unofficial": "AE2 Stuff Unofficial" + }, + "isFabric": false, + "versionScope": ["1.12.2"] + } +] \ No newline at end of file diff --git a/projects/assets/ae2-stuff-unofficial/1.12.2/ae2stuff/local-config.json b/projects/assets/ae2-stuff-unofficial/1.12.2/ae2stuff/local-config.json deleted file mode 100644 index 51a67d3edf7d..000000000000 --- a/projects/assets/ae2-stuff-unofficial/1.12.2/ae2stuff/local-config.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "inclusionDomains": [], - "exclusionDomains": [], - "exclusionPaths": [], - "inclusionPaths": [], - "characterReplacement": {}, - "destinationReplacement": {}, - "namespaceDiscriminator": "AE2 Stuff Unofficial" - -} \ No newline at end of file diff --git a/projects/assets/ae2-stuff/1.12.2/ae2stuff/local-config.json b/projects/assets/ae2-stuff/1.12.2/ae2stuff/local-config.json deleted file mode 100644 index 2a2cd96ed1a5..000000000000 --- a/projects/assets/ae2-stuff/1.12.2/ae2stuff/local-config.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "inclusionDomains": [], - "exclusionDomains": [], - "exclusionPaths": [], - "inclusionPaths": [], - "characterReplacement": {}, - "destinationReplacement": {}, - "namespaceDiscriminator": "AE2 Stuff" -} \ No newline at end of file From 51f194f2cea2a63302de8d81977b3d45fa293791 Mon Sep 17 00:00:00 2001 From: 502y <53784463+502y@users.noreply.github.com> Date: Thu, 25 Jun 2026 23:48:16 +0800 Subject: [PATCH 09/12] fix(NS): modify to new file --- config/packer/1.12.2.json | 3 --- 1 file changed, 3 deletions(-) diff --git a/config/packer/1.12.2.json b/config/packer/1.12.2.json index 0ad5575ab60b..b084153c9137 100644 --- a/config/packer/1.12.2.json +++ b/config/packer/1.12.2.json @@ -50,8 +50,5 @@ "……": "\u22ef\u22ef" }, "destinationReplacement": {} - }, - "namespaceDiscriminator": { - "ae2-stuff": "displayName" } } \ No newline at end of file From 85f645de89c4a2868e24a29511b2bf14307bb683 Mon Sep 17 00:00:00 2001 From: 502y <53784463+502y@users.noreply.github.com> Date: Fri, 26 Jun 2026 20:25:59 +0800 Subject: [PATCH 10/12] =?UTF-8?q?=E4=BC=98=E5=8C=96=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E6=A0=87=E6=B3=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/packer/namespace-discriminator.json | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/config/packer/namespace-discriminator.json b/config/packer/namespace-discriminator.json index 5e907ddb1446..5360d8c1d706 100644 --- a/config/packer/namespace-discriminator.json +++ b/config/packer/namespace-discriminator.json @@ -6,7 +6,10 @@ "ae2-stuff": "AE2 Stuff", "ae2-stuff-unofficial": "AE2 Stuff Unofficial" }, - "isFabric": false, - "versionScope": ["1.12.2"] + "versionScope": { + "forge": [ + "1.12.2" + ] + } } ] \ No newline at end of file From a2641ee3bfe9aef478f4e29838e427e74ac69182 Mon Sep 17 00:00:00 2001 From: 502y <53784463+502y@users.noreply.github.com> Date: Thu, 2 Jul 2026 09:45:03 +0800 Subject: [PATCH 11/12] Update config/packer/namespace-discriminator.json Co-authored-by: SlimeSB <86453765+SlimeSB@users.noreply.github.com> --- config/packer/namespace-discriminator.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/packer/namespace-discriminator.json b/config/packer/namespace-discriminator.json index 5360d8c1d706..0f989d3b643f 100644 --- a/config/packer/namespace-discriminator.json +++ b/config/packer/namespace-discriminator.json @@ -2,7 +2,7 @@ { "namespace": "ae2stuff", "operator": "displayName", - "effectScope": { + "mappingRule": { "ae2-stuff": "AE2 Stuff", "ae2-stuff-unofficial": "AE2 Stuff Unofficial" }, From 74f4826d2ce89b1a663b595b6042f8dc7016d1a9 Mon Sep 17 00:00:00 2001 From: 502y <53784463+502y@users.noreply.github.com> Date: Sun, 5 Jul 2026 21:47:36 +0800 Subject: [PATCH 12/12] =?UTF-8?q?AI=E7=BC=96=E5=86=99=E7=9A=84packer?= =?UTF-8?q?=E6=94=B9=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Packer/Helpers/ConfigHelpers.cs | 26 ++++++ src/Packer/Helpers/EnumerationHelper.cs | 40 ++++++++- src/Packer/Helpers/ManifestHelpers.cs | 94 +++++++++++++++++++++ src/Packer/Models/GroupedPackManifest.cs | 25 ++++++ src/Packer/Models/NamespaceDiscriminator.cs | 48 +++++++++++ src/Packer/Models/PackTargetPlatform.cs | 23 +++++ src/Packer/Program.cs | 16 +++- 7 files changed, 267 insertions(+), 5 deletions(-) create mode 100644 src/Packer/Helpers/ManifestHelpers.cs create mode 100644 src/Packer/Models/GroupedPackManifest.cs create mode 100644 src/Packer/Models/NamespaceDiscriminator.cs create mode 100644 src/Packer/Models/PackTargetPlatform.cs diff --git a/src/Packer/Helpers/ConfigHelpers.cs b/src/Packer/Helpers/ConfigHelpers.cs index 08b15468bc18..8cef4c0f1080 100644 --- a/src/Packer/Helpers/ConfigHelpers.cs +++ b/src/Packer/Helpers/ConfigHelpers.cs @@ -55,6 +55,32 @@ public static Config RetrieveConfig(string configTemplate, string version) new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase })!; } + /// + /// 从仓库根目录获取命名空间区分配置 + /// + /// 配置文件位置 + /// 文件不存在时返回空列表;文件存在但内容非法时抛出异常,宁可打包失败也不发出错误的包 + public static List RetrieveNamespaceDiscriminators( + string path = "./config/packer/namespace-discriminator.json") + { + var file = new FileInfo(path); + if (!file.Exists) + { + Log.Information("未找到命名空间区分配置({0}),跳过命名空间区分。", path); + return new List(); + } + + file.FullName.LogToDebug("读取文件:{0}"); + + using var stream = file.OpenRead(); + var result = JsonSerializer.Deserialize>( + stream, + new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }); + if (result is null) + throw new InvalidDataException($"The discriminator file {path} cannot have null content."); + return result; + } + /// /// 从给定的命名空间获取策略内容 /// diff --git a/src/Packer/Helpers/EnumerationHelper.cs b/src/Packer/Helpers/EnumerationHelper.cs index 1736b21a19f6..c40b0fd9c452 100644 --- a/src/Packer/Helpers/EnumerationHelper.cs +++ b/src/Packer/Helpers/EnumerationHelper.cs @@ -1,9 +1,11 @@ using Packer.Extensions; using Packer.Models; +using Serilog; using System; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Text.RegularExpressions; namespace Packer.Helpers { @@ -11,7 +13,8 @@ internal static class EnumerationHelper { public static IEnumerable EnumerateUnmerged(IEnumerable targetModIdentifiers, Config config, - IEnumerable acceptableVersions) + IEnumerable acceptableVersions, + IReadOnlyCollection? namespaceDiscriminators = null) { return // ./projects/assets/... @@ -25,14 +28,45 @@ where targetModIdentifiers.Count() == 0 // 未提供 let versionedDirectory = acceptableVersions.Select(version => modDirectory.GetDirectories(version).FirstOrDefault()) .FirstOrDefault(_ => _ is not null) where versionedDirectory is not null - // .../-CFPA- + // .../ from namespaceDirectory in versionedDirectory.EnumerateDirectories() let namespaceName = namespaceDirectory.Name where !config.Base.ExclusionNamespaces.Contains(namespaceName) // 没有被明确排除 where namespaceName.ValidateNamespace() // 不是非法名称 + // 命名空间区分:若命中规则,将 assets// 改写为 assets/-CFPA-<区分名>/ + let discriminatedNamespaceName = ResolveDiscriminatedNamespaceName(namespaceDiscriminators, + namespaceName, + modIdentifier) // .../* from provider in namespaceDirectory.EnumerateProviders(config) - select provider; + select discriminatedNamespaceName is null + ? provider + : provider.ReplaceDestination($"^assets/{Regex.Escape(namespaceName)}(?=/)", + $"assets/{discriminatedNamespaceName.Replace("$", "$$")}"); + } + + /// + /// 解析(命名空间, 项目)应使用的区分后名称。传入的规则应已按当前打包平台过滤。 + /// + /// 适用于当前平台的命名空间区分规则 + /// 原始命名空间 + /// CurseForge 项目 slug + /// 命中规则时返回 <namespace>-CFPA-<区分名>;否则返回 (保持原名) + private static string? ResolveDiscriminatedNamespaceName(IReadOnlyCollection? namespaceDiscriminators, + string namespaceName, + string modIdentifier) + { + var matchedDiscriminator = namespaceDiscriminators? + .FirstOrDefault(entry => entry.Namespace == namespaceName); + if (matchedDiscriminator is null) return null; + + if (!matchedDiscriminator.MappingRule.TryGetValue(modIdentifier, out var discriminatedName)) + { + Log.Warning("命名空间 {0}(项目 {1})命中了区分规则,但 mappingRule 未包含该项目;保留原始命名空间。", + namespaceName, modIdentifier); + return null; + } + return $"{namespaceName}-CFPA-{discriminatedName}"; } public static IEnumerable PostProcess(this IEnumerable providers, Config config) diff --git a/src/Packer/Helpers/ManifestHelpers.cs b/src/Packer/Helpers/ManifestHelpers.cs new file mode 100644 index 000000000000..6a45dd4320a8 --- /dev/null +++ b/src/Packer/Helpers/ManifestHelpers.cs @@ -0,0 +1,94 @@ +using Packer.Models; +using Packer.Models.Providers; +using Serilog; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text.Encodings.Web; +using System.Text.Json; + +namespace Packer.Helpers +{ + /// + /// 组合包 Manifest.json 的生成工具 + /// + internal static class ManifestHelpers + { + private static readonly JsonSerializerOptions manifestSerializerOptions = new() + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase, + WriteIndented = true, + Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping + }; + + /// + /// 生成组合包根目录的 Manifest.json 提供器 + /// + /// 当前版本的全局配置 + /// 已按当前目标平台过滤的命名空间区分规则 + /// 可接受版本(当前版本 + 回退版本),用于解析被排除模组的命名空间 + /// 同一命名空间存在多条适用规则 + public static TextFile BuildGroupedPackManifest(Config config, + IReadOnlyCollection applicableDiscriminators, + IEnumerable acceptableVersions) + { + var blackList = config.Base.ExclusionNamespaces + .Concat(EnumerateNamespacesOfExcludedMods(config.Base.ExclusionMods, acceptableVersions)) + .Distinct() + .OrderBy(namespaceName => namespaceName, StringComparer.Ordinal) + .ToList(); + + var rules = new Dictionary(); + foreach (var discriminator in applicableDiscriminators + .OrderBy(entry => entry.Namespace, StringComparer.Ordinal)) + { + if (!rules.TryAdd(discriminator.Namespace, discriminator.Operator)) + throw new InvalidDataException( + $"Duplicate discriminator entries for namespace {discriminator.Namespace} " + + "matching the current pack version."); + } + + var manifest = new GroupedPackManifest { BlackList = blackList, Rules = rules }; + var manifestContent = JsonSerializer.Serialize(manifest, manifestSerializerOptions); + + Log.Information("已生成 Manifest.json:{0} 个黑名单命名空间,{1} 条区分规则", + blackList.Count, rules.Count); + + return new TextFile(manifestContent, "Manifest.json"); + } + + /// + /// 将被排除模组(CurseForge slug)解析为其在可接受版本下提供的全部命名空间。
+ /// 取各版本目录的并集:客户端缓存可能包含由旧包(含回退版本内容)安装的命名空间, + /// 多删缓存是无害的空操作,漏删则会残留脏数据。 + ///
+ private static IEnumerable EnumerateNamespacesOfExcludedMods( + IEnumerable exclusionMods, + IEnumerable acceptableVersions) + { + foreach (var projectSlug in exclusionMods) + { + var projectDirectory = new DirectoryInfo(Path.Combine("./projects/assets", projectSlug)); + if (!projectDirectory.Exists) + { + Log.Warning("被排除的模组 {0} 在 projects/assets 下不存在,跳过其黑名单解析。", projectSlug); + continue; + } + + var namespaceNames = acceptableVersions + .SelectMany(version => projectDirectory.GetDirectories(version)) + .SelectMany(versionedDirectory => versionedDirectory.EnumerateDirectories()) + .Select(namespaceDirectory => namespaceDirectory.Name) + .Distinct() + .ToList(); + + if (namespaceNames.Count == 0) + Log.Warning("被排除的模组 {0} 在可接受版本下没有任何命名空间目录。", projectSlug); + + foreach (var namespaceName in namespaceNames) + yield return namespaceName; + } + } + } +} diff --git a/src/Packer/Models/GroupedPackManifest.cs b/src/Packer/Models/GroupedPackManifest.cs new file mode 100644 index 000000000000..655a4af99d02 --- /dev/null +++ b/src/Packer/Models/GroupedPackManifest.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; + +#nullable disable + +namespace Packer.Models +{ + /// + /// 组合包根目录的 Manifest.json,供客户端增量下载、维护本地缓存时使用。 + /// + public class GroupedPackManifest + { + /// + /// 客户端应从本地缓存清除的命名空间(原始名), + /// 来自 与 + /// 解析出的命名空间 + /// + public List BlackList { get; set; } + + /// + /// 从原始命名空间到区分标识符(author / displayName / 文件路径)的映射, + /// 即 的透传 + /// + public Dictionary Rules { get; set; } + } +} diff --git a/src/Packer/Models/NamespaceDiscriminator.cs b/src/Packer/Models/NamespaceDiscriminator.cs new file mode 100644 index 000000000000..c0e18c3bd6b4 --- /dev/null +++ b/src/Packer/Models/NamespaceDiscriminator.cs @@ -0,0 +1,48 @@ +using System.Collections.Generic; + +// 与 Config.cs 一致:要null就抛异常吧(逃) +#nullable disable + +namespace Packer.Models +{ + /// + /// 命名空间区分规则。当多个 CurseForge 项目共用同一命名空间时, + /// 组合包依据该规则将命名空间改写为 <namespace>-CFPA-<区分名>, + /// 使各变体分别打包;客户端按 从本地模组元数据计算区分名。
+ /// 对应 config/packer/namespace-discriminator.json 中的一个条目。 + ///
+ public class NamespaceDiscriminator + { + /// + /// 被区分的原始命名空间(不含识别段) + /// + public string Namespace { get; set; } + + /// + /// 客户端计算区分名所用的标识符: + /// "author"(authors 字典序第一个)、"displayName", + /// 或一个文件路径(表示对模组内该文件取 MD5)。 + /// 原样写入 Manifest.json 的 rules。 + /// + public string Operator { get; set; } + + /// + /// 从 CurseForge 项目 slug 到区分名的映射;仅打包器重命名时使用,不写入 Manifest.json + /// + public Dictionary MappingRule { get; set; } + + /// + /// 规则生效范围:键为加载器名(forge / fabric),值为游戏版本列表 + /// + public Dictionary> VersionScope { get; set; } + + /// + /// 判断该规则是否适用于给定的打包目标平台 + /// + /// 当前打包的目标平台 + public bool AppliesTo(PackTargetPlatform targetPlatform) + => VersionScope is not null + && VersionScope.TryGetValue(targetPlatform.Loader, out var gameVersions) + && gameVersions.Contains(targetPlatform.GameVersion); + } +} diff --git a/src/Packer/Models/PackTargetPlatform.cs b/src/Packer/Models/PackTargetPlatform.cs new file mode 100644 index 000000000000..ebca5f527539 --- /dev/null +++ b/src/Packer/Models/PackTargetPlatform.cs @@ -0,0 +1,23 @@ +namespace Packer.Models +{ + /// + /// 打包目标平台:加载器 + 游戏版本,从打包版本字符串(即配置文件名)解析。
+ /// 例:"1.16-fabric" → (fabric, 1.16);"1.12.2" → (forge, 1.12.2)。 + ///
+ /// 加载器名,与 namespace-discriminator.json 中 versionScope 的键对应 + /// 游戏版本,与 versionScope 值列表中的项对应 + public record PackTargetPlatform(string Loader, string GameVersion) + { + private const string FabricSuffix = "-fabric"; + + /// + /// 从打包版本字符串解析目标平台。 + /// 以 -fabric 结尾视为 fabric,其余视为 forge。 + /// + /// 打包版本字符串,即 + public static PackTargetPlatform FromPackVersion(string packVersion) + => packVersion.EndsWith(FabricSuffix) + ? new PackTargetPlatform("fabric", packVersion[..^FabricSuffix.Length]) + : new PackTargetPlatform("forge", packVersion); + } +} diff --git a/src/Packer/Program.cs b/src/Packer/Program.cs index 1d9e99c2555b..2efc0c97413d 100644 --- a/src/Packer/Program.cs +++ b/src/Packer/Program.cs @@ -72,16 +72,28 @@ public static async Task Main(string version, bool increment = false, bool group { string packName = $"./Minecraft-Mod-Language-Modpack-{config.Base.Version}-namespaced.zip"; Log.Information("组合包:{0}", packName); + + var acceptableVersions = config.Base.FallbackVersions.Prepend(config.Base.Version).ToList(); + var targetPlatform = PackTargetPlatform.FromPackVersion(config.Base.Version); + var applicableDiscriminators = ConfigHelpers.RetrieveNamespaceDiscriminators() + .Where(discriminator => discriminator.AppliesTo(targetPlatform)) + .ToList(); + Log.Information("目标平台 {0} {1},适用的命名空间区分规则:{2} 条", + targetPlatform.Loader, targetPlatform.GameVersion, applicableDiscriminators.Count); + var query = - EnumerationHelper.EnumerateUnmerged(targetModIdentifiers, config, config.Base.FallbackVersions.Prepend(config.Base.Version)) + EnumerationHelper.EnumerateUnmerged(targetModIdentifiers, config, acceptableVersions, applicableDiscriminators) .MergeDeep() .PostProcess(config); - + + var manifestFile = ManifestHelpers.BuildGroupedPackManifest(config, applicableDiscriminators, acceptableVersions); + await using var stream = File.Create(packName); using (var archive = new ZipArchive(stream, ZipArchiveMode.Update, leaveOpen: true)) { await archive.WriteDirect(initialFiles); + await archive.WriteDirect([manifestFile]); await archive.WriteGrouped(query); } //var md5 = stream.ComputeMD5();