Skip to content

[BUG]列车碰撞后服务器崩溃:IndexOutOfBoundsException (TrainAdditionalData.totalWeight 列表不同步) #149

Description

@LingshijunRenzy

环境信息

  • 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.datdata/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:138totalWeight() 越界点
  • ConductorHelper.java:416momentumExchange() 调用处
  • ExtensionHelper.java:57isCarriageOverweighted 同类无边界隐患
  • ConductorHelper.java:911divideTrainExtensionData 失配隐患

建议修复

  1. 防御性totalWeight()(及 ExtensionHelper.getCarriageWeight)改为按下标取两列表长度的较小值,或增加越界保护。
  2. 根治:在 Create 删除 Train.carriages 车厢(脱轨/损毁)时同步裁剪 TrainAdditionalData.carriages,保持两列表一致。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions