赵松乔 发表于 2026-3-5 16:20:21

无法读档

### 游戏信息

游戏版本:                0.97a-RC11

### 系统信息

操作系统:Microsoft Windows 11 专业版

版本:10.0.22621 暂缺 Build 22621

总可用内存:`31.85G`


Java版本:`1.7.0_79`

Java路径:E:\Starsector\jre


虚拟机参数:java.exe -XX:CompilerThreadPriority=1 -XX:+CompilerThreadHintNoPreempt -Djava.library.path=native\\windows -XX:+UseG1GC -Xms4096m -Xmx4096m -Xss2048k -XX:PermSize=192m -XX:MaxPermSize=192m -classpath janino.jar;commons-compiler.jar;commons-compiler-jdk.jar;starfarer.api.jar;starfarer_obf.jar;jogg-0.0.7.jar;jorbis-0.0.15.jar;json.jar;lwjgl.jar;jinput.jar;log4j-1.2.9.jar;lwjgl_util.jar;fs.sound_obf.jar;fs.common_obf.jar;xstream-1.4.10.jar -Dcom.fs.starfarer.settings.paths.saves=..\\saves -Dcom.fs.starfarer.settings.paths.screenshots=..\\screenshots -Dcom.fs.starfarer.settings.paths.mods=..\\mods -Dcom.fs.starfarer.settings.paths.logs=. com.fs.starfarer.StarfarerLauncher

堆栈初始大小(`-Xms`):`4096m`

堆栈最大大小(`-Xmx`):`4096m`


### Mod信息

|Mod名称                           |Mod版本   |已启用   |
|-|-|-|
|LazyLib                         |2.8b    |是       |
|zz GraphicsLib                  |1.9.0   |是       |
|MagicLib                        |1.4.6   |是       |
|AEF-阿瓦隆远征队                      |Ver:0.5.3-Sub:1 (进入英仙座 intoPersean)|是       |
|Console Commands                |2024.10.04|是       |
|Diable Avionics - Seal balance patch.|1.0.1   |是       |
|Diable Avionics - Seal ed.      |1.0.0   |是       |
|HMI反派势力                         |0.0.5c|是       |
|Lukas的随手之作                      |2.5.14|是       |
|LunaLib                         |1.8.7   |是       |
|势力争霸                 |0.11.3c |是       |
|布莱顿联盟                           |0.0.3d|是       |
|海盗拓展                |1.8.3   |是       |
|风险矿业公司                        |0.3.8   |是       |
|Diamond                         |1.699   |否       |
|Luddic Enhancement            |1.2.6e|否       |
|Luddic Enhancement IED          |1.2.6a|否       |
|zzz Mikohime Additionals Settings|1.1.1   |否       |
|卢德骑士团                           |1.3.6   |否       |
|星际帝国     |2.6.4   |否       |
|普拉斯里蒂废品大师               |0.6.8   |否       |
|沃尔科夫工业集团                   |1.6.3a|否       |

(以上内容由 远行星号 报错信息收集工具 自动生成,生成工具版本 `1.1.2`).


赵松乔 发表于 2026-3-5 16:21:25

求大佬解救 {:tieba_01:}{:tieba_01:}

fniess 发表于 2026-3-5 16:48:43

看起来是AEF-阿瓦隆远征队的问题,你可以尝试一下更新mod,但我估计你这个档应该没救了

赵松乔 发表于 2026-3-5 16:54:13

fniess 发表于 2026-3-5 16:48
看起来是AEF-阿瓦隆远征队的问题,你可以尝试一下更新mod,但我估计你这个档应该没救了 ...

{:tieba_39:}好吧

赵松乔 发表于 2026-3-5 17:11:03

找了找问题 已经解决了

人质救星Fuze 发表于 2026-3-5 17:12:49

赵松乔 发表于 2026-3-5 16:54
好吧

去存档里找到对应存档位的campaign.xml
把<st>Avali_AeroponicTube</st>批量全部删除试试

MAJOR_Kai 发表于 2026-3-5 17:13:10

本帖最后由 MAJOR_Kai 于 2026-3-5 12:33 编辑

    看上去是气培模块那个船插导致的空指针异常, 马上去修复。

# 26.03.05 #
PS: 漏洞已修复。

赵松乔 发表于 2026-3-5 17:15:10

E:\Starsector\mods\avali_explorer_v0.5.3s1\data\hullmods 下的Avali_AeroponicTube.java出错了 【变量重名冲突:advanceInCampaign方法的入参是FleetMemberAPI member,但方法内循环又定义了for (FleetMemberAPI member : ...),重名导致对象引用混乱,触发空指针。】【非空检查顺序颠倒:先获取player.getCargo()、clock.getDay(),再检查player == null,如果player为空,提前执行的代码直接报错。】【未做多层非空判断:没有检查player.getFleetData()、member.getVariant()、member.getHullSpec()是否为空,任意一个为空都会触发空指针。】

赵松乔 发表于 2026-3-5 17:15:55

package data.hullmods;
import com.fs.starfarer.api.Global;
import com.fs.starfarer.api.combat.ShipAPI;
import com.fs.starfarer.api.campaign.CargoAPI;
import com.fs.starfarer.api.fleet.FleetMemberAPI;
import com.fs.starfarer.api.combat.BaseHullMod;
import com.fs.starfarer.api.combat.ShipAPI.HullSize;
import com.fs.starfarer.api.campaign.CampaignFleetAPI;
import com.fs.starfarer.api.combat.MutableShipStatsAPI;
import com.fs.starfarer.api.campaign.CampaignClockAPI;
import com.fs.starfarer.api.impl.campaign.ids.Commodities;
import java.util.Map;
import java.util.HashMap;

public class Avali_AeroponicTube extends BaseHullMod{
    // delivery_date = 3, 10, 17, 24;
    // refresh_date = 7, 14, 21, 28;
    // food_get = 180, 70, 30;
    private boolean refreshed = true;
    // 关键修复:使用无泛型的HashMap,并在获取值时强制转换为Float
    private static Map storage = new HashMap();
   
    static {
      storage.put(HullSize.DESTROYER, 100f);
      storage.put(HullSize.CRUISER, 250f);
      storage.put(HullSize.CAPITAL_SHIP, 600f);
    }    //舰船级别降低载货, 护卫舰禁用

    @Override
    public void applyEffectsBeforeShipCreation(HullSize hullSize, MutableShipStatsAPI stats, String id) {
      // 非空检查+判空返回
      if (stats == null || !storage.containsKey(hullSize)) return;
      // 强制转换为Float,解决类型转换错误
      float mod = ((Float) storage.get(hullSize)).floatValue();
      if (stats.getVariant() != null && stats.getVariant().getHullSpec() != null) {
            mod = Math.min(stats.getVariant().getHullSpec().getCargo(), mod);
      }
      stats.getCargoMod().modifyFlat(id, -1f * mod);
    }    //载货量降低最小值

    @Override
    public void advanceInCampaign(FleetMemberAPI member, float amount) {
      // 第一步先做全量非空检查,空则直接返回(解决核心空指针)
      CampaignFleetAPI player = Global.getSector().getPlayerFleet();
      if (player == null) return;
      if (player.getFleetData() == null || player.getFleetData().getMembersListCopy() == null) return;
      CargoAPI cargo = player.getCargo();
      if (cargo == null) return;
      CampaignClockAPI clock = Global.getSector().getClock();
      if (clock == null) return;
      
      int days = clock.getDay();
      int B_class = 0;
      int C_class = 0;
      int D_class = 0;

      // 解决变量重名:把循环内的member改为fm,避免和入参冲突
      for (FleetMemberAPI fm : player.getFleetData().getMembersListCopy()) {
            // 多层非空检查,避免任意对象为空
            if (fm == null || fm.isMothballed()) continue;
            if (fm.getVariant() == null || !fm.getVariant().hasHullMod("Avali_AeroponicTube")) continue;
            if (fm.getHullSpec() == null || fm.getHullSpec().getHullSize() == null) continue;
            
            HullSize hullSize = fm.getHullSpec().getHullSize();
            if (hullSize == HullSize.CAPITAL_SHIP) B_class++;
            else if (hullSize == HullSize.CRUISER) C_class++;
            else if (hullSize == HullSize.DESTROYER) D_class++;
      }    //统计舰船 级别-数量

      // 计算食物产量,避免负数
      float foodTotal = (float)B_class*180f + (float)C_class*70f + (float)D_class*30f;
      float FoodToGet = Math.min(Math.max(foodTotal, 0f), cargo.getSpaceLeft());
      
      // 生产+刷新逻辑
      if ((days == 3 || days == 10 || days == 17 || days == 24) && refreshed){
            cargo.addCommodity(Commodities.FOOD, FoodToGet);
            this.refreshed = false;
      } else if (days == 7 || days == 14 || days == 21 || days == 28 ){
            this.refreshed = true;
      }
    }    //执行获取, 获取刷新

    @Override
    public boolean isApplicableToShip(ShipAPI ship) {
      if (ship == null || ship.getVariant() == null) return false;
      return ship.getVariant().getHullSize() != HullSize.FRIGATE;
    }

    @Override
    public String getUnapplicableReason(ShipAPI ship) {
      if (ship == null || ship.getVariant() == null) return null;
      if (ship.getVariant().getHullSize() == HullSize.FRIGATE){
            return "不适用于护卫舰";
      }
      return null;
    }

    @Override
    public String getDescriptionParam(int index, ShipAPI.HullSize hullSize) {
      if (index == 0) { return "600/250/100/护卫舰禁用"; }
      if (index == 1) { return "3/10/17/24"; }
      if (index == 2) { return "180/70/30/护卫舰禁用"; }
      if (index == 3) { return "到达载货上限将停止生产"; }
      return null;
    }
}

赵松乔 发表于 2026-3-5 17:16:35

新代码 用编译器替换一下 游戏又能完了 美滋滋
{:tieba_35:}{:tieba_35:}

MAJOR_Kai 发表于 2026-3-5 17:35:07

赵松乔 发表于 2026-3-5 12:15
package data.hullmods;
import com.fs.starfarer.api.Global;
import com.fs.starfarer.api.combat.ShipAP ...

    哈哈,好思路,但是检测不用加的这么麻烦。

                if ( Global.getSector() != null
                && Global.getSector().getPlayerFleet() !=null
                && Global.getSector().getPlayerFleet().getCargo() != null ) {

就行了{:tieba_35:}
页: [1]
查看完整版本: 无法读档