MapArt 可以把 PNG、JPG、GIF、BMP 或 WEBP 图片转换为 Minecraft 填充地图。玩家可以通过命令或游戏内 GUI 选择图片,也可以使用插件自带的网页上传服务。
本仓库不是原作者发布的官方源码。源码由用户提供的 MapArt-1.1.1-folia-v7.jar 重建,并针对 Folia 的 Region/Entity 调度、并发访问和资源生命周期进行了修复。完整来源与许可证说明见 NOTICE.md。
- 启动时只检测一次 Folia,并缓存结果。
- Paper 与 Folia 的任务全部经过统一调度封装。
- 玩家、背包、GUI 和地图创建回到对应 Entity/Global 上下文。
- 非全局 Entity 调度至少延迟 1 tick。
- 地图创建 Future 在物品真正发放后才返回成功。
- 背包空间不足时提前终止,避免只创建部分地图。
- 共享 Map、会话表和 Token 表使用并发集合。
- 地图 ID 使用完整
int,避免高 ID 被short截断后冲突。 - 图片路径使用真实路径校验,阻止
../与符号链接逃逸。 - 上传请求体有服务端大小限制,HTTP 工作线程池有明确上限。
- 图片解码前读取尺寸,降低压缩图片导致内存耗尽的风险。
- 重复任务、HTTP 服务、渲染线程和会话缓存在关闭时显式释放。
/mapart reload需要mapart.admin,并根据真实结果返回成功或失败。
| 项目 | 状态 | 说明 |
|---|---|---|
| Java | 必须为 21 或更高 | class 版本为 Java 21(65) |
| Paper | 支持 | 使用 Paper 1.21.1 API 编译 |
| Purpur | 支持 | 需要基于兼容的 Paper 1.21.x |
| Folia | 静态兼容 | 已完成调度与线程归属审查,仍建议在目标构建上压测 |
| Spigot/CraftBukkit | 不支持 | 使用了 Paper/Folia 调度 API |
仓库中没有使用以下 Folia 不可用事件:PlayerRespawnEvent、PlayerTeleportEvent、PlayerChangedWorldEvent、WorldLoadEvent、WorldUnloadEvent。
folia-supported: true只允许插件在 Folia 上加载,不等于已经覆盖所有运行时场景。当前产物尚未在真实 Folia 集群上完成多人跨 Region 压力测试。
- 从 Releases 下载
MapArt-1.1.1-folia-fixed.jar。 - 将 JAR 放入服务器的
plugins/目录。 - 使用 Java 21 启动 Paper、Purpur 或 Folia 1.21.x。
- 首次启动后编辑
plugins/MapArt/config.yml。 - 修改配置后执行
/mapart reload,涉及 Java 或服务端版本的变更应完整重启服务器。
升级前建议备份:
plugins/MapArt/config.yml
plugins/MapArt/images/
plugins/MapArt/maps/
| 命令 | 权限 | 说明 |
|---|---|---|
/mapart |
mapart.use |
打开地图画 GUI |
/mapart gui |
mapart.use |
打开地图画 GUI |
/mapart upload |
mapart.use |
创建 5 分钟有效的网页上传链接 |
/mapart apply <图片> [scale|tile] |
mapart.use |
创建单张缩放地图或平铺地图 |
/mapart clear |
mapart.use |
清除玩家背包中的填充地图 |
/mapart info |
mapart.use |
查看背包中的填充地图数量 |
/mapart list [mine|global|all] |
mapart.use |
列出个人、全局或全部图片 |
/mapart reload |
mapart.admin |
重载配置并重启网页上传服务 |
别名:/ma
language: zh_cn
max-image-width: 2048
max-image-height: 2048
map-size: 128
async-processing: true
max-concurrent-tasks: 4
web-server:
enabled: true
host: "0.0.0.0"
port: 8080
public-url: "https://map.example.com"
max-upload-size-mb: 10生产环境不要直接把内置 HTTP 端口暴露到公网。建议在 Nginx、Caddy 或其他反向代理后提供 HTTPS,并将 public-url 设置为玩家实际访问的 HTTPS 地址。配置字段、范围和目录结构见 配置文档。
flowchart LR
A["命令或 GUI 请求"] --> B["异步验证路径与读取图片"]
B --> C["有界线程池渲染 128x128 像素数据"]
C --> D["至少 1 tick 后进入玩家 Entity 上下文"]
D --> E["检查背包并创建 MapView 与物品"]
E --> F["异步原子写入 maps/*.dat"]
E --> G["回玩家 Entity 上下文发送结果"]
线程边界、所有权与关闭流程见 Folia 线程模型。
- 每名玩家只保留一个有效 Token,新 Token 会使旧 Token 失效。
- Token 5 分钟过期并且只能消费一次。
- 服务端限制请求体与实际文件大小,不能依赖浏览器端校验绕过。
- 扩展名、文件魔数、ImageIO 解码结果和图片尺寸会分别校验。
- 上传文件使用服务器生成的随机文件名,不使用客户端文件名落盘。
- 上传线程和等待队列都有上限,关闭或重载时会停止。
内置服务不是通用文件托管系统。公网部署仍应增加反向代理限流、防火墙和访问日志。
原插件保留了以下出站请求:
- 版本检查:
https://dreamark.club/api/versions.php - 匿名心跳:
https://tlm.dreamark.club/api/heartbeat.php
心跳会在服务器目录的 DreamArk/server-uuid.txt 保存随机 UUID,并定期发送该 UUID。修复版没有新增遥测字段。对隐私或出站网络有严格要求的部署者,应在上线前审查 TelemetryManager.java 和 VersionChecker.java,并通过防火墙控制访问。
要求:
- JDK 21
- Maven 3.9+
- 可访问 PaperMC Maven 仓库
git clone https://github.com/mcxqk/MapArt-Folia-Fix.git
cd MapArt-Folia-Fix
mvn clean package输出文件:
target/MapArt-1.1.1-folia-fixed.jar
每次推送和 Pull Request 都会执行 GitHub Actions 构建,并上传未发布的构建产物。
- Java 21
javac -Xlint:all:零错误、零警告。 - 核心烟雾测试:图片尺寸拒绝、Token 单次消费、地图数据定长持久化。
- 静态扫描:业务代码无直接旧版
BukkitScheduler调用。 - 静态扫描:无同步
teleport,无上述 5 个 Folia 不可用事件。 - JAR 内容检查:不包含 Paper API 或其他服务端依赖。
- 配置资源检查:UTF-8 中文注释、作者
xWtree、网站github.com/mcxqk。
tile模式一次最多创建 36 张地图,因为发放前要求玩家背包有足够空位。- Minecraft 地图像素固定为 128×128,其他
map-size值会回退到 128。 - GUI 图片文件扫描是异步的,图片很多时打开页面会稍有延迟。
- 地图数据文件必须正好为 16,384 字节,损坏文件会被忽略并保留给管理员检查。
- 目标 Folia/Paper 版本升级后,应重新检查调度 API 与 Region 所有权行为。
提交前请阅读 CONTRIBUTING.md。涉及 Folia 的改动必须说明入口线程、真实所有者、跨线程携带的数据和资源终止方式。
安全问题请按 SECURITY.md 私下报告,不要先公开可利用细节。
所提供 JAR 中没有 LICENSE 文件,本仓库因此不擅自指定 GPL、MIT 或其他许可证。公开可读不代表自动授予复制、分发或再许可权。详情见 NOTICE.md。