Skip to content

Commit 86a4f60

Browse files
committed
[Fix]: 修复 5.2 dedicated server 启动
1 parent 87978ce commit 86a4f60

10 files changed

Lines changed: 58 additions & 18 deletions

File tree

.changelogs/5.2.1.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Qz-Miner 5.2.1
2+
3+
## 修复
4+
5+
- 修复 `5.2.0` 在 dedicated server 启动时无法应用玩家生命周期 Mixin、导致服务器直接退出的问题。
6+
- vanilla `respawnPlayer``onDisconnect` 恢复由 refmap 映射到生产 SRG 名;Forge 三参数登录与 Teleporter 跨维度 overload 显式兼容 MCP/SRG selector。
7+
8+
## 兼容性
9+
10+
- 不修改 5.2 已冻结的 packet discriminator/Side、wire、protocol、ordinal、code、mask 或 23-path 配置 schema。
11+
- 完整合法的 `5.2.x` stable、prerelease 与 dev 版本继续按既有 minor-family 策略互通;Qz-UILib 最低版本仍为 `4.6.0`,当前构建使用 `4.6.3:dev`
12+
13+
## 验证边界
14+
15+
- 已依据生产失败日志确认 `respawnPlayer` MCP 名未映射是直接根因;修复后 annotation processor 生成 `respawnPlayer -> func_72368_a``onDisconnect -> func_147231_a` refmap 条目。
16+
- 本地定向测试、`compileJava``test``check``build``git diff --check` 已通过,独立只读复核无 P0/P1/P2。
17+
- 修复包的 dedicated server 启动、登录、重生、切维度和断线运行态在发布前仍为 **INCOMPLETE**;CI、refmap 与构建成功不替代该证据。

.github/workflows/branch-ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ jobs:
103103
runs-on: ubuntu-24.04
104104
timeout-minutes: 90
105105
env:
106-
VERSION: 5.2.0-ci+${{ github.sha }}
106+
VERSION: 5.2.1-ci+${{ github.sha }}
107107
strategy:
108108
fail-fast: false
109109
max-parallel: 2
@@ -173,7 +173,7 @@ jobs:
173173
import zipfile
174174
from pathlib import Path
175175
176-
expected = f"5.2.0-ci+{os.environ['GITHUB_SHA']}"
176+
expected = f"5.2.1-ci+{os.environ['GITHUB_SHA']}"
177177
declaration = re.compile(
178178
r'^\s*public\s+static\s+final\s+String\s+VERSION\s*=\s*"([^"]+)"\s*;\s*$',
179179
re.MULTILINE,

build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ plugins {
44
id("com.gtnewhorizons.gtnhconvention")
55
}
66

7-
val buildVersion = providers.environmentVariable("VERSION").orElse("5.2.0-dev").get()
7+
val buildVersion = providers.environmentVariable("VERSION").orElse("5.2.1-dev").get()
88
version = buildVersion
99
extra["modVersion"] = buildVersion
1010

docs/反馈层/决策/network-version-compatibility.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ major.minor.patch[-prerelease][+build]
7171

7272
## 版本注入与证据边界
7373

74-
- 5.2 branch CI 由 runner 声明 `VERSION=5.2.0-ci+${{ github.sha }}`,并检查 generated `Tags.VERSION` 与主 JAR `Tags.class` 的 exact 值;两个 matrix leg 对同一 SHA 使用同一版本。
75-
- tag workflow 继续使用 tag 名注入 `VERSION`。本地未显式注入时固定使用合法的 `5.2.0-dev`,只作
74+
- 5.2 branch CI 由 runner 声明 `VERSION=5.2.1-ci+${{ github.sha }}`,并检查 generated `Tags.VERSION` 与主 JAR `Tags.class` 的 exact 值;两个 matrix leg 对同一 SHA 使用同一版本。
75+
- tag workflow 继续使用 tag 名注入 `VERSION`。本地未显式注入时固定使用合法的 `5.2.1-dev`,只作
7676
5.2 family 联调包而不是具体 patch artifact 证据;不通过设置环境变量、Maven Local、`flatDir`
7777
或 URL 旁路伪造发布制品可消费性。
7878
- GTNHGradle 的 Git version module 已关闭;`build.gradle.kts` 是唯一版本入口,将 runner-owned `VERSION`

docs/反馈层/错误预防.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@
9494
- patch、stable/pre/dev 互通意味着同一 minor 内必须同时冻结 discriminator/Side、字段/framing、
9595
protocol、ordinal、wire code、mode bit 与 schema;任何不兼容改变都升新 minor,不能用 dev qualifier
9696
规避。
97-
- branch CI 的版本须由 runner 注入并同时核对 generated constant 与主 JAR;本地 `5.2.0-dev` 联调包、
97+
- branch CI 的版本须由 runner 注入并同时核对 generated constant 与主 JAR;本地 `5.2.1-dev` 联调包、
9898
CI 尚未实际运行或仅有源码断言都不能冒充具体 5.2 patch artifact/运行态证据。
9999
- 决策:`决策/network-version-compatibility.md`
100100

@@ -118,6 +118,8 @@
118118

119119
## 构建与依赖环境
120120

121+
- 注入 vanilla 方法的 Mixin 不得在类级关闭 remap;MCP 名在开发环境可编译,但生产 dedicated server 使用 SRG 名,会在应用期以 critical injection failure 终止启动。标准 vanilla 目标交给 refmap;Forge 改签或新增且 annotation processor 无映射的 overload,才在 injector 级关闭 remap 并显式列出 MCP/SRG 双 selector。
122+
- `compileJava`、源码结构断言与普通 `build` 不能证明生产 Mixin selector 可应用;至少核对生成 refmap 的关键 MCP→SRG 条目,并把对应 dedicated server 启动 smoke test 独立记录为运行态证据。
121123
- 外部 1.7.10 mod 进 RFG dev runtime 优先依赖 `dev` classifier 或 MCP 变体,禁用无后缀发布 jar(保留 SRG 命名致运行时 `NoSuchMethodError: func_...`
122124
- 编译通过不能覆盖运行态命名问题;外部 mod 发布 jar 升级后至少跑一次对应 run task(`runClient21`/`runServer25`
123125
- JitPack 依赖放行必须按发布通道核验,不能机械要求所有仓库都有 Gradle module metadata。Qz-UILib 的 JitPack 组合发布通道以 Build API 身份、canonical POM/main/实际 `dev`/`sources` 及校验和、clean 显式 `:dev` consumer 为证据,`.module=404` 是预期;只有普通 Maven GMM 通道才要求已承诺的 `.module=200` 与变体身份。GitHub Release assets、Maven Local、`www`/query 旁路或非权威镜像不能替代;活动配置禁旧 group/`flatDir` fallback,GTNH Maven 非前置,已发布 tag 不移动

docs/控制律层/发布流程.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
- `gradle/gtnh-baselines.json` 是受支持 GTNH manifest 与预期 GregTech 版本的唯一机器清单;`gradle.properties``elytra.manifest.version` 是默认开发与唯一出包基线的权威,不在清单中另设 default。
1212
- tag 前必须由 `.github/workflows/branch-ci.yml` 从清单生成双基线 matrix;每项在独立只读 clean runner 上依次通过 `setupCIWorkspace`、精确依赖断言、`test``check``build`,稳定聚合门 `build` 阻断 plan 或任一基线失败。
1313
- 每个 5.2 patch 候选的 branch CI 仅在 `baseline` job 由 runner 声明与拟发布 tag patch 一致的
14-
`VERSION=X.Y.Z-ci+${{ github.sha }}`;当前开发 CI 使用 `VERSION=5.2.0-ci+${{ github.sha }}`
14+
`VERSION=X.Y.Z-ci+${{ github.sha }}`;当前开发 CI 使用 `VERSION=5.2.1-ci+${{ github.sha }}`
1515
每个 matrix leg 构建后都以 Python 标准库精确核对 generated `Tags.VERSION` 与主 JAR `Tags.class`
1616
两个 baseline 对同一 SHA 必须得到同一合法 5.2 dev 版本。
1717
- tag workflow 在 checkout、构建和 Release 副作用前通过 GitHub API 强制要求 `branch-ci.yml` 对 tag 的同一 SHA 存在 `push``success` 的运行;tag 早于 branch CI 时按预期 fail-closed,不等待、不跳过。
@@ -72,7 +72,7 @@ git push origin <tag>
7272
- 若未来要调整自动生成策略,应同步检查上游复用的 `release-tags.yml` 与本文件是否一致。
7373
- GitHub tag、Release、CI 或 Release assets 成功不等于对应发布通道的门禁已通过;任一必需证据未通过均暂停 Miner 发布。
7474
- branch CI 通过也不等于 tag 后 Release/assets 已创建;两者分别在 tag 前、tag 后核验。CI matrix 的运行证据只能在 push 后取得,本地验证不得伪报为 CI 证据。
75-
- 本地未显式注入时固定使用 `5.2.0-dev`,只用于 5.2 family 本地联调,不得写成当前 patch 的发布
75+
- 本地未显式注入时固定使用 `5.2.1-dev`,只用于 5.2 family 本地联调,不得写成当前 patch 的发布
7676
候选 artifact 证据。agent 不设置 `VERSION`,也不使用 Maven Local、`flatDir` 或 URL 旁路伪造
7777
5.2/Qz-UILib 制品可消费性。
7878
- 5.2 family 的兼容冻结与升 minor 条件见

docs/控制律层/稳定命令.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@
4545
- `runClient*`/`runServer*` 交用户执行;`verify-gtnh-baselines.ps1` 暂不授权给 agent。
4646
- 每个 5.2 patch 候选的 branch CI 使用与拟发布 tag patch 一致的 runner-owned
4747
`VERSION=X.Y.Z-ci+${{ github.sha }}`,并在 generated source 与主 JAR 中精确验证;当前开发 CI
48-
使用 `VERSION=5.2.0-ci+${{ github.sha }}`。本地 agent 不设置该变量;无注入 build 固定使用
49-
`5.2.0-dev`,只作为当前 5.2 family 的本地联调包,不能作为具体 patch 的发布候选 artifact 证据。
48+
使用 `VERSION=5.2.1-ci+${{ github.sha }}`。本地 agent 不设置该变量;无注入 build 固定使用
49+
`5.2.1-dev`,只作为当前 5.2 family 的本地联调包,不能作为具体 patch 的发布候选 artifact 证据。
5050

5151
## 双基线验证
5252

src/main/java/club/heiqi/qz_miner/mixins/early/MixinNetHandlerPlayServer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* 注入到 NetHandlerPlayServer.onDisconnect 中,
1414
* 在原版注销逻辑之前按 endpoint identity 销毁玩家实例。
1515
*/
16-
@Mixin(value = NetHandlerPlayServer.class, remap = false)
16+
@Mixin(NetHandlerPlayServer.class)
1717
public class MixinNetHandlerPlayServer {
1818

1919
@Inject(

src/main/java/club/heiqi/qz_miner/mixins/early/MixinServerConfigurationManager.java

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,16 @@
1313
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
1414

1515
/** 将玩家实例生命周期绑定到 vanilla 登录、重生和跨维度提交边界。 */
16-
@Mixin(value = ServerConfigurationManager.class, remap = false)
16+
@Mixin(ServerConfigurationManager.class)
1717
public class MixinServerConfigurationManager {
1818

1919
@Inject(
20-
method = "initializeConnectionToPlayer(Lnet/minecraft/network/NetworkManager;Lnet/minecraft/entity/player/EntityPlayerMP;Lnet/minecraft/network/NetHandlerPlayServer;)V",
20+
method = {
21+
"initializeConnectionToPlayer(Lnet/minecraft/network/NetworkManager;Lnet/minecraft/entity/player/EntityPlayerMP;Lnet/minecraft/network/NetHandlerPlayServer;)V",
22+
"func_72355_a(Lnet/minecraft/network/NetworkManager;Lnet/minecraft/entity/player/EntityPlayerMP;Lnet/minecraft/network/NetHandlerPlayServer;)V" },
2123
at = @At("RETURN"),
22-
require = 1)
24+
require = 1,
25+
remap = false)
2326
private void onLoginCommitted(NetworkManager networkManager, EntityPlayerMP player,
2427
NetHandlerPlayServer handler, CallbackInfo ci) {
2528
PlayerManager.onVanillaLoginCommitted(player);
@@ -44,18 +47,24 @@ private void onRespawnCommitted(EntityPlayerMP player, int dimension, boolean co
4447
}
4548

4649
@Inject(
47-
method = "transferPlayerToDimension(Lnet/minecraft/entity/player/EntityPlayerMP;ILnet/minecraft/world/Teleporter;)V",
50+
method = {
51+
"transferPlayerToDimension(Lnet/minecraft/entity/player/EntityPlayerMP;ILnet/minecraft/world/Teleporter;)V",
52+
"func_72356_a(Lnet/minecraft/entity/player/EntityPlayerMP;ILnet/minecraft/world/Teleporter;)V" },
4853
at = @At("HEAD"),
49-
require = 1)
54+
require = 1,
55+
remap = false)
5056
private void beforeDimensionChange(EntityPlayerMP player, int dimension, Teleporter teleporter,
5157
CallbackInfo ci) {
5258
PlayerManager.beforeVanillaDimensionChange(player);
5359
}
5460

5561
@Inject(
56-
method = "transferPlayerToDimension(Lnet/minecraft/entity/player/EntityPlayerMP;ILnet/minecraft/world/Teleporter;)V",
62+
method = {
63+
"transferPlayerToDimension(Lnet/minecraft/entity/player/EntityPlayerMP;ILnet/minecraft/world/Teleporter;)V",
64+
"func_72356_a(Lnet/minecraft/entity/player/EntityPlayerMP;ILnet/minecraft/world/Teleporter;)V" },
5765
at = @At("RETURN"),
58-
require = 1)
66+
require = 1,
67+
remap = false)
5968
private void onDimensionChangeCommitted(EntityPlayerMP player, int dimension, Teleporter teleporter,
6069
CallbackInfo ci) {
6170
PlayerManager.onVanillaDimensionChangeCommitted(player);

src/test/java/club/heiqi/qz_miner/mixins/ServerConfigurationManagerLifecycleMixinStructureTest.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,18 @@ public void loginRespawnAndDimensionUseCanonicalVanillaBoundaries() throws Excep
1616
"src/main/java/club/heiqi/qz_miner/mixins/early/MixinServerConfigurationManager.java").toPath()),
1717
StandardCharsets.UTF_8);
1818

19+
Assert.assertTrue(source.contains("@Mixin(ServerConfigurationManager.class)"));
1920
Assert.assertTrue(source.contains("initializeConnectionToPlayer(Lnet/minecraft/network/NetworkManager;"));
21+
Assert.assertTrue(source.contains("func_72355_a(Lnet/minecraft/network/NetworkManager;"));
2022
Assert.assertTrue(source.contains("PlayerManager.onVanillaLoginCommitted(player)"));
2123
Assert.assertTrue(source.contains(
2224
"respawnPlayer(Lnet/minecraft/entity/player/EntityPlayerMP;IZ)Lnet/minecraft/entity/player/EntityPlayerMP;"));
2325
Assert.assertTrue(source.contains("PlayerManager.beforeVanillaRespawn(player)"));
2426
Assert.assertTrue(source.contains("PlayerManager.onVanillaRespawnCommitted(player, cir.getReturnValue())"));
2527
Assert.assertTrue(source.contains(
2628
"transferPlayerToDimension(Lnet/minecraft/entity/player/EntityPlayerMP;ILnet/minecraft/world/Teleporter;)V"));
29+
Assert.assertTrue(source.contains(
30+
"func_72356_a(Lnet/minecraft/entity/player/EntityPlayerMP;ILnet/minecraft/world/Teleporter;)V"));
2731
Assert.assertTrue(source.contains("PlayerManager.beforeVanillaDimensionChange(player)"));
2832
Assert.assertTrue(source.contains("PlayerManager.onVanillaDimensionChangeCommitted(player)"));
2933
Assert.assertFalse("two-argument delegate must not be injected",
@@ -38,6 +42,14 @@ public void earlyLoaderAndConfigBothRegisterLifecycleMixin() throws Exception {
3842
Assert.assertTrue(config.contains("\"MixinServerConfigurationManager\""));
3943
}
4044

45+
@Test
46+
public void disconnectMixinAlsoRemapsVanillaMethodNames() throws Exception {
47+
String source = read(
48+
"src/main/java/club/heiqi/qz_miner/mixins/early/MixinNetHandlerPlayServer.java");
49+
Assert.assertTrue(source.contains("@Mixin(NetHandlerPlayServer.class)"));
50+
Assert.assertFalse(source.contains("remap = false"));
51+
}
52+
4153
private static String read(String path) throws Exception {
4254
return new String(Files.readAllBytes(new File(path).toPath()), StandardCharsets.UTF_8);
4355
}

0 commit comments

Comments
 (0)