GTNH-Web-Map

[!INFO] Git Commit: e0cb1f3 | Updated: 2026-10-02

GTNH-Web-Map(GWM)是 Dynmap 的 1.7.10 Forge 分支,作者 Ranzu(fork 自 mikeprimm 的上游 Dynmap),仓库 GTNewHorizons/GTNH-Web-Map。它的定位是"服务端浏览器地图插件":把服务端渲染好的世界地图通过内嵌 Jetty 服务器以 HTTP 暴露给浏览器,并针对 GTNH 整合包中数十个模组预置了方块渲染规则。仓库 README.md 首段原文:“a server side addon which adds a browser accessible shared map for your players”,以及 “GWM is only available as a Forge mod at this time”。

内容统计:0 方块、0 物品、0 TileEntity、0 实体、0 配方——grep 全仓 GameRegistry.registerBlock / registerItem / TileEntity.register / EntityRegistry.register 均 0 命中。这是一个纯基础设施 mod,全部产出是 1 台 HTTP 服务器 + 5 条指令 + 一套渲染管线。

命名与注册约定(审计要点)

七个身份字符串中有六个与分类名/目录名不同,必须逐一区分:

# 身份 值 来源
1 FML modid Dynmap forge/DynmapMod.java:34 @Mod(modid = "Dynmap", name = "Dynmap", version = Tags.GRADLETOKEN_VERSION)
2 FML coremod modid 无 全仓 grep -rln 'IFMLLoadingPlugin' --include=*.java src/ 0 命中;gradle.properties 的 coreModClass = 为空
3 资源域名 无(mod 自身无 assets/) git ls-files 'src/main/resources/assets/*' 0 命中。assets/ 只存在于纹理包内部,见 纹理包
4 注册域名 同 modid(Dynmap) @Mod 注解即注册
5 分类 / 目录 gtnh-web-map / gtnh-web-map relation.md
6 源码根包 org.dynmap gradle.properties:14 modGroup = org.dynmap;全部 342 个 .java 位于 org/dynmap/**
7 jar 名 gtnh-web-map-<version>.jar gradle.properties:10 modId = gtnh-web-map;customArchiveBaseName 保持注释状态(gradle.properties 内 # customArchiveBaseName =)

[!WARNING] modid ≠ 分类名。 FML 实际注册的 modid 是 Dynmap(首字母大写),不是 gtnh-web-map。安装时 config/命令上下文中的目录名、jar 名用的是 gtnh-web-map(gradle.properties 的 modId),而 FML 识别用的是 Dynmap。 仓库内 src/main/resources/mcmod.info:3 写的是 "modid": "gtnh-web-map",与 @Mod 注解不一致;gradle.properties 的注释说明 mcmod.info 由插件按 modId 填充,故仓库内这份是模板/遗留物。FML 以 @Mod 注解为准。

@Mod 类数量 = 1:forge/DynmapMod.java:34 是全仓唯一的 @Mod 注解(grep -rn '^@Mod' --include=*.java src/main/java 仅 1 命中),不存在第二个 @Mod 类。

语言构成

语言 数量 说明
Java 342 个 .java 全部 mod 逻辑
PHP 30 extracted/web/,网页端与 standalone/ 直连数据库实现
JavaScript 29 extracted/web/js/,含 jQuery 与 Leaflet
CSS 7 extracted/web/css/
HTML 3 index.html / login.html / inactive.html

无 Scala、无 Kotlin、无 TypeScript。这一点由仓库自带的 CI 断言:! grep -E -r 'import scala\.' src/main/java(.github/workflows/test-scala-presence.yml)——该 job 在检出 import scala. 时失败。本地以两种方式交叉验证均无命中:① 同一 grep 无输出;② git ls-files | grep -i scala 仅命中该 CI 文件自身。

[!NOTE] dev.json 中列有 org.scala-lang:scala-library:2.10.2 与 scala-compiler:2.10.2,但那是 FML 启动器依赖,不是本 mod 的源码语言。

版本与 Minecraft 版本

  • Minecraft 1.7.10 / Forge 10.13.4.1614(gradle.properties:24 minecraftVersion = 1.7.10、:27 forgeVersion = 10.13.4.1614)。这是真实 Gradle 构建(RetroFuturaGradle,settings.gradle 引入 com.gtnewhorizons.gtnhsettingsconvention 2.0.24),不是反编译 jar,因此不适用"无 gradle 文件"例外。
  • 版本号无法从本地仓库确定:本地 clone 是浅克隆(git rev-parse --is-shallow-repository = true,git rev-list --count HEAD = 1),且 .git/refs/tags/ 为空、git tag 无输出。Tags.java(generateGradleTokenClass = org.dynmap.Tags)由构建期生成,仓库内不存在,因此 @Mod(version = Tags.GRADLETOKEN_VERSION) 的实际取值无法从源码读出。

[!CAUTION] 本条目刻意不使用 git describe 作为版本闸门。 该仓库有 124 个 tag,且分属两套互不兼容的版本序列:

  • 上游 Dynmap 继承标签:0.1a…2.4、v1.9.1 等。其中 v1.9.1 指向 2435ed1,提交日期 2013-12-05(“Strip version check”)——距 HEAD 有 12 年。
  • 本 fork 自身标签:0.1a…0.4-alpha-28、0.4-beta-1。时间上最近的是 0.4-beta-1(ae324ff611,2026-06-09)。

HEAD e0cb1f3 提交于 2026-07-18,晚于 0.4-beta-1,即处于 0.4-beta-1 之后的开发态。数值更大的 2.4 / v1.9.1 属于上游 Dynmap 历史,不是本 fork 的版本。若误用 git describe,会得到形如 v1.9.1-<N>-ge0cb1f3 的结果(本地浅克隆下则直接 fatal: No names found),在 1.7.10 树上极易被误读为 “1.9.1 版本”。此处只声明"HEAD 晚于 0.4-beta-1",不断言具体版本字符串。

依赖关系

dependencies.gradle 中无一条 FML 硬依赖声明——@Mod 注解不含 dependencies 字段(DynmapMod.java:34),mcmod.info 的 dependencies 为空数组。

级别 构件 说明
内嵌(shaded) Jetty 9.4.26.v20200117 共 9 个构件(dependencies.gradle:35-64)、json-simple:1.1.1、snakeyaml 2.2、owasp-java-html-sanitizer:20180219.1 经 shadowImplementation 打入 jar 并重定位
仅编译期(软) GT5-Unofficial 5.09.52.594、Applied-Energistics-2-Unofficial、ServerUtilities 2.3.0、GTNHLib 0.11.9(dependencies.gradle:69-80,均为 compileOnly) 无一在 @Mod 中声明为硬前置
已声明但源码未使用 ModularUI 1.3.4、ModularUI2 2.3.73-1.7.10(dependencies.gradle:81-82,配置为 api,即会被发布为运行时依赖) 全仓 grep -rn 'ModularUI' --include=*.java src/main/java 0 命中。仅作事实记录
仅编译期未使用 GTNHLib(dependencies.gradle:78-80) 全仓 grep -rn 'gtnhlib|GTNHLib' --include=*.java src/main/java 0 命中
开发运行时(不发布) 26 条 runtimeOnlyNonPublishable(dependencies.gradle:84-110):Postea、EndlessIDs、NEI、ServerUtilities、Hodgepodge、GT5、IC2、Railcraft、ArchitectureCraft、Chisel、EnderIO、Thaumcraft、AE2、ForgeMultipart、CarpentersBlocks、EnderStorage、Jabba、Catwalks、Tinkers’ Construct、OpenComputers、Forestry、Binnie、Botania、LogisticsPipes、ProjectRed、Nuclear-Control 仅用于 dev 运行环境;dependencies.gradle:112 的 StorageDrawers 与 :114 的 ForgeEssentials 两条均已被注释
运行时探测 serverutilities 全仓唯一带字面量 modid 的 Loader.isModLoaded(...) 调用仅 2 处(forge/DynmapMod.java:141、forge/GwmConfig.java:15),modid 均为 serverutilities

源码层面的实际依赖面很窄:全仓第三方包导入仅 gregtech.*(12 处,用于 GregTechSupport)与 serverutils.*(8 处,集中于 ServerUtilitiesClaimedChunksMarkers),其余为 org.(1339)、java.(841)、net.(122)、javax.(81)、cpw.(36)、com.(9,仅 Guava/Gson/authlib)。

无 Forge 网络通道:grep -rn 'SimpleNetworkWrapper\|NetworkRegistry\|FMLEmbeddedChannel' --include=*.java src/main/java 0 命中。@NetworkCheckHandler(DynmapMod.java:151-154)无条件 return true,不做任何版本协商。客户端取图完全走 HTTP。

与 gtnh-web-map-client 的关系

本 mod 是 gtnh-web-map-client(modid gwmclient)的服务端对端。 二者是不同的仓库(/Users/evlos/a/mirror/GTNH-Web-Map/ 与 /Users/evlos/a/mirror/GTNH-Web-Map-Client/),本 mod 全仓搜索 GTNH-Web-Map-Client / web-map-client / webmapclient 0 命中——配对纯靠约定俗成的 URL 契约:

客户端(gwmclient) 值 本 mod 对应
RemoteConfiguration.baseUrl 默认 http://127.0.0.1:8123 webserver-port 默认 8123(DynmapCore.java:880)
Config.java:20 配置项 remote.baseUrl,同默认值 同上
TileLoaderUrl.java:74 RemoteConfiguration.baseUrl + "/tiles/" 由 servlet/MapStorageResourceHandler 提供

客户端是纯客户端 mod,其仓库 README.md 自述 “Not currently in a usable state.”——故该配对当前不构成可用功能。两者无源码级依赖,本条目不描述客户端行为,详见 gtnh-web-map-client 分类。

指令列表

5 条指令在 DynmapPlugin.onEnable()(forge/DynmapPlugin.java:1369)中全部实际注册(:1471-1475),分派链为 DynmapCommandHandler.processCommand(:2032)→ DynmapPlugin.onCommand(:1513)→ DynmapCore.processCommand(DynmapCore.java:1411)。

  • /dynmap - 渲染控制主入口,22 个子指令(帮助表)/ 24 个(运行时权限集)
  • /dmap - 地图与世界配置的增删改,16 个子命令
  • /dmarker - 标记管理,白名单 33 项,权限命名空间 marker.*
  • /dynmapexp - 导出 OBJ 3D 模型,8 个子命令
  • /gwm - 本 fork 专用,4 个子命令(1 无条件 + 3 条件注册)

配置列表

Web 与 API 列表

渲染与地图列表

集成列表

标记与存储列表

已核实的不一致

以下均为行为记录,仓库中未找到任何注释表明这些省略是有意为之,故不判定为缺陷:

  1. 帮助表缺项:/dynmap reload 可用(DynmapCore.java:1653,调用 getServer().reload(),权限亦已登记于 :1143)但未列入 commandinfo 帮助表(:1185-1290 内 0 命中);/dmap 的 perspectivelist / shaderlist / lightinglist / blocklist 与 /dynmapexp 的 purge / info 同此。
  2. MicrosoftSQLMapStorage(1133 行)无法启用:工厂 DynmapCore.java:430-449 无 mssql 分支,全仓除自身文件外无引用。
  3. modid 与 mcmod.info 不一致:@Mod 为 Dynmap,mcmod.info:3 为 gtnh-web-map。
  4. 包名拼写 storage/sqllte/(少一个 i)——目录与包名原文如此。
  5. 空 catch 块 99 处(跨 31 个文件),按异常类型分布:IOException 54、NumberFormatException 18、SQLException 8、InterruptedException 5、Exception 3、InvocationTargetException 3,其余 8 种各 1。抽查确认为资源 close、配置解析回退、反射实例化回退等良性模式。另有 5 处 catch (Throwable) 全部位于 common/DynmapListenerManager.java:72/87/102/118/134,且每处都带 throwable 记录 warning(监听器隔离,非静默吞异常)。

相关条目