环境信息
- Minecraft: 1.20.1 (Forge 47.4.20)
- 跨越 (kuayue): 1.0.2
- 依赖: Create 0.5.1.j、kasuga_lib 1.20.1-0.22.1-create
- 场景: 多人服务器(专用服务端),列车碰撞
问题描述
列车碰撞后服务器崩溃,控制台报错:
java.lang.IndexOutOfBoundsException: Index 1 out of bounds for length 1
at java.util.ArrayList.get(ArrayList.java:427)
at willow.train.kuayue.systems.train_extension.TrainAdditionalData.totalWeight(TrainAdditionalData.java:138)
at willow.train.kuayue.systems.train_extension.conductor.ConductorHelper.momentumExchange(ConductorHelper.java:416)
at com.simibubi.create.content.trains.entity.Train.handler$zio000$onCrash(Train.java:2408)
at com.simibubi.create.content.trains.entity.Train.collideWithOtherTrains(Train.java:615)
at com.simibubi.create.content.trains.entity.Train.tick(Train.java:400)
根因分析
TrainAdditionalData.totalWeight()(TrainAdditionalData.java:133-142)按索引访问 Create 的 Train.carriages:
public float totalWeight() {
Train t = Create.RAILWAYS.trains.get(train);
for (CarriageAdditionalData data : carriages) { // 遍历 kuayue 自己的列表
result += ExtensionHelper.getDynamicWeight(t.carriages.get(i), data.blockCount); // 却按下标取 Create 的列表
i++;
}
return result;
}
当 kuayue 侧 TrainAdditionalData.carriages 记录数 多于 Create 侧 Train.carriages 实际车厢数时,t.carriages.get(i) 越界崩溃。
经解析存档 data/train_extension_store.dat 与 data/create_tracks.dat 对比,问题列车在 kuayue 存档中残留了 2 条 车厢记录,而 Create 中该列车只剩 1 节 车厢。
数据不同步的原因
TrainAdditionalData 只在 kuayue 自身流程中更新(组车 MixinStationBlockEntity.onSetContraption、连挂 mergeTrainExtensionData、解挂 divideTrainExtensionData),但 Create 的 Train.carriages 还会在脱轨/碰撞损毁时被 Create 直接删除车厢,此时 kuayue 数据不会同步裁剪,两列表从此失配。之后任何一次碰撞(momentumExchange)都会触发崩溃。
另外 divideTrainExtensionData(ConductorHelper.java:911)的边界判断:
if(carriageIndex < 0 || carriageIndex >= allCarriages.size() - 1) return;
直接 return 也会留下已失配的数据。
相关代码位置
TrainAdditionalData.java:138 — totalWeight() 越界点
ConductorHelper.java:416 — momentumExchange() 调用处
ExtensionHelper.java:57 — isCarriageOverweighted 同类无边界隐患
ConductorHelper.java:911 — divideTrainExtensionData 失配隐患
建议修复
- 防御性:
totalWeight()(及 ExtensionHelper.getCarriageWeight)改为按下标取两列表长度的较小值,或增加越界保护。
- 根治:在 Create 删除
Train.carriages 车厢(脱轨/损毁)时同步裁剪 TrainAdditionalData.carriages,保持两列表一致。
环境信息
问题描述
列车碰撞后服务器崩溃,控制台报错:
根因分析
TrainAdditionalData.totalWeight()(TrainAdditionalData.java:133-142)按索引访问 Create 的Train.carriages:当 kuayue 侧
TrainAdditionalData.carriages记录数 多于 Create 侧Train.carriages实际车厢数时,t.carriages.get(i)越界崩溃。经解析存档
data/train_extension_store.dat与data/create_tracks.dat对比,问题列车在 kuayue 存档中残留了 2 条 车厢记录,而 Create 中该列车只剩 1 节 车厢。数据不同步的原因
TrainAdditionalData只在 kuayue 自身流程中更新(组车MixinStationBlockEntity.onSetContraption、连挂mergeTrainExtensionData、解挂divideTrainExtensionData),但 Create 的Train.carriages还会在脱轨/碰撞损毁时被 Create 直接删除车厢,此时 kuayue 数据不会同步裁剪,两列表从此失配。之后任何一次碰撞(momentumExchange)都会触发崩溃。另外
divideTrainExtensionData(ConductorHelper.java:911)的边界判断:直接
return也会留下已失配的数据。相关代码位置
TrainAdditionalData.java:138—totalWeight()越界点ConductorHelper.java:416—momentumExchange()调用处ExtensionHelper.java:57—isCarriageOverweighted同类无边界隐患ConductorHelper.java:911—divideTrainExtensionData失配隐患建议修复
totalWeight()(及ExtensionHelper.getCarriageWeight)改为按下标取两列表长度的较小值,或增加越界保护。Train.carriages车厢(脱轨/损毁)时同步裁剪TrainAdditionalData.carriages,保持两列表一致。