MyTown2 集成(已失效)

结论先行

MyTown2 集成在当前源码中永远不会被加载。 Class.forName 请求的类名与实际类名不符(包名和类名都不对), 必然抛 ClassNotFoundException,被 catch 后回退到 HEMyTown2IntegrationDummy——该 Dummy 对任何人都返回 true。

后果:其他玩家的 MyTown2 地皮范围内,水体方块仍可被放置 / 扩散。

缺陷现场

server/mytown2/HEMyTown2Integration.java:12-28:

public static HEMyTown2Integration getInstance() {
    if (instance == null) {
        if (Loader.isModLoaded(HETags.MyTown2_MODID)) {
            try {
                instance = Class.forName("com.sinthoras.hydroenergy.server.HEMyTown2Implementation")
                        .asSubclass(HEMyTown2Integration.class).newInstance();
            } catch (Exception e) {
                HE.warn("Could not initialize MyTown2 Integration. Pretending MyTown2 is not loaded!");
                instance = new HEMyTown2IntegrationDummy();
            }
        } else {
            instance = new HEMyTown2IntegrationDummy();
        }
    }
    return instance;
}

三处不一致

项 Class.forName 请求的 实际存在的类 一致?
包名 com.sinthoras.hydroenergy.server com.sinthoras.hydroenergy.server.mytown2 ❌ 缺 .mytown2
类名 HEMyTown2Implementation HEMyTown2IntegrationImplementation ❌ 缺 Integration
构造器 无参 newInstance() 无参 ✅

实测(grep '^package')三个类的真实全限定名:

文件 FQN
server/mytown2/HEMyTown2Integration.java com.sinthoras.hydroenergy.server.mytown2.HEMyTown2Integration(抽象基类)
server/mytown2/HEMyTown2IntegrationImplementation.java com.sinthoras.hydroenergy.server.mytown2.HEMyTown2IntegrationImplementation
server/mytown2/HEMyTown2IntegrationDummy.java com.sinthoras.hydroenergy.server.mytown2.HEMyTown2IntegrationDummy

正确写法应为 Class.forName("com.sinthoras.hydroenergy.server.mytown2.HEMyTown2IntegrationImplementation")。

📌 注意请求串把类名和包名都写错了,不是单纯的包名笔误。

Dummy 的行为

server/mytown2/HEMyTown2IntegrationDummy.java(全文):

public class HEMyTown2IntegrationDummy extends HEMyTown2Integration {

    public boolean hasPlayerModificationRightsForChunk(String residentName, int dimension, int chunkX, int chunkZ) {
        return true;
    }
}

忽略全部 4 个参数,恒返回 true —— 即「所有人对所有区块都有修改权」。

影响链

唯一的调用点在 server/HEBlockQueue.java:112-122:

boolean[] permissionsChecked = new boolean[HEConfig.maxDams];
boolean[] hasPermissions = new boolean[HEConfig.maxDams];
...
while (!blockStack.isEmpty()) {
    QueueEntry entry = blockStack.pop();
    int waterId = entry.waterBlock.getWaterId();
    if (permissionsChecked[waterId] == false) {
        hasPermissions[waterId] = HEMyTown2Integration.getInstance().hasPlayerModificationRightsForChunk(
                HEServer.instance.getOwnerName(waterId),
                chunk.worldObj.provider.dimensionId,
                chunk.xPosition,
                chunk.zPosition);
        permissionsChecked[waterId] = true;
    }

hasPermissions[waterId] 用于决定水体方块能否在该区块被放置 / 保留。 由于恒为 true,MyTown2 的地皮保护对水体完全不生效。

⚠️ 注意权限检查用的 residentName 是 HEServer.instance.getOwnerName(waterId),即水坝主人的名字, 不是当前操作玩家的名字——即便集成修好,它检查的也是 「坝主人能否改这个区块」,而非「谁点的右键」。

本应生效的实现

server/mytown2/HEMyTown2IntegrationImplementation.java(全文):

package com.sinthoras.hydroenergy.server.mytown2;

import mytown.entities.TownBlock;
import mytown.new_datasource.MyTownUniverse;

public class HEMyTown2IntegrationImplementation extends HEMyTown2Integration {

    public boolean hasPlayerModificationRightsForChunk(String residentName, int dimension, int chunkX, int chunkZ) {
        TownBlock chunk = MyTownUniverse.instance.blocks.get(dimension, chunkX, chunkZ);
        if (chunk == null) {
            return true;
        }
        return chunk.getTown().residentsMap.contains(residentName);
    }
}

逻辑本身合理:无人占领 → 放行;否则要求该居民在 town 的 residentsMap 中。 它 import 的是 mytown.*(MyTown2 的真实包),说明作者当初是按 MyTown2 写的。

⚠️ 该类直接 import MyTown2 的类。这正是它必须用 Class.forName 延迟加载的原因—— 没装 MyTown2 时直接引用会导致 NoClassDefFoundError。 类名写错使这套延迟加载机制从未成功执行过一次。

门控

项 值 行
检测的 modid HETags.MyTown2_MODID = "MyTown2"(区分大小写) HETags.java:38
检测方式 Loader.isModLoaded("MyTown2") HEMyTown2Integration.java:14
单例缓存 private static HEMyTown2Integration instance HEMyTown2Integration.java:10
线程安全 无,getInstance() 未同步 HEMyTown2Integration.java:12

MyTown2 是否在本 wiki 收录范围

data/relation.md 有 mytown2 分类行(驼峰转小写,源码目录为 MyTown2), 但 data/mytown2/ 目录尚未建立——该分类在本 wiki 尚未收录完成。

因此本页不复述 MyTown2 的功能,只记录本 mod 侧的集成代码与缺陷。 跨分类链接见 分类页。

关联