• 欢迎加入MineBBS QQ讨论群:点击查看所有的官方讨论群
  • 我们将于近期对服务器进行迁移,服务可能中断至多2日。请各位安排好自己的访问计划,造成不便敬请谅解!
  • MineBBS入站考试已经上线!想要成为【正式会员】解锁更多功能吗?快来参与吧!【点我去看】
资源图标

原生 Atlas-plus -- 真正的实时卫星地图 v1.0.1

完成注册/登录后下载
版权类型
原创
版权链接
https://github.com/Maskviva/Atlas-plus
语言支持
中文(简体)
前置组件
Levilamina-Rust-Loader v1.0.0+(https://www.minebbs.com/resources/levilamina-rust-loader-levilamina-rust.17046/
适配版本(基岩)
  1. 26.x
[MD] # Atlas-plus 一个**实时**的 Minecraft **基岩版专用服务器**俯视地图,以 [LeviLamina](https://github.com/LiteLDev/LeviLamina) Rust 插件的形式实现。 [/MD]
[MD] Atlas-plus 用两种方式渲染世界,并把它们融合在一起: - **磁盘引导(bootstrap)**——启用时,读取一次世界的 LevelDB(严格只读),把整个已探索的世界渲染成底图。 - **实时层**——之后直接从正在运行的服务器内存中读取方块,**不必等待存档**,持续保持有变化的区域是最新的,并显示实时玩家标记。 地图由一个内置的小型 Web 服务器提供。**没有任何数据是走普通 HTTP 拉取的**:浏览器只打开一条 WebSocket 连接,地图清单、玩家坐标、瓦片图像变化时都由服务器主动推送下去——所以没有轮询,浏览器也没有任何东西可以缓存成旧数据。瓦片仍然会以和磁盘版 [Atlas] 相同的格式写入磁盘,所以任何读取 Atlas 瓦片的工具都能读这些文件。 > **对 TPS 友好是设计原则。** 实时层每个周期扫描的区块数有硬性上限,默认只关心每个玩家附近的几个区块,加上被世界变化事件标记的区块。画面静止时不产生任何额外开销。 --- ## 特性 - 🗺️ **磁盘完整底图** + 玩家所在处的**实时更新**。 - ⚡ **开销有界**——无论哪种更新模式,每周期扫描的区块数都有一个硬上限。 - 🎛️ **可配置的更新策略**:就近玩家、世界变化事件、两者结合、全范围扫描,或关闭。 - 🖼️ **Minecraft 风格的 canvas 地图查看器**——自包含的单页地图,只推像素,不会出现空白帧。 - 🧭 平移 / 缩放 / 网格 / 维度切换 / 出生点标记 / 实时玩家标记。 - 🔌 **一切实时数据都走同一条 WebSocket**——地图清单、玩家坐标、**以及瓦片图像**,变化时都通过 `/ws` 推下去(瓦片以二进制 PNG 帧的形式)。没有 HTTP 轮询,浏览器也从不通过 HTTP 拉取瓦片,所以根本没有东西可以被缓存成旧版本。连接会自动重连,重连后会立刻收到一次完整的当前状态回放。 - 🛠️ **管理员命令**——`/atlas url | status`。 - 📦 零外部依赖服务——手写的 HTTP + WebSocket 服务器,原生 JS 查看器,前端无需构建步骤。 --- ## 环境要求 - 一台 LeviLamina 基岩版服务器。 - LeviLamina 的 **Rust 加载器**插件(`levilamina-rust-loader`),用于加载 Rust `.dll` 插件。 - 若要从源码构建:需要 Rust 工具链(stable)以及能访问 crates.io 的网络。 --- ## 安装 **方式 A——直接使用编译好的文件。** 把 `atlas_plus.dll` 和 `manifest.json` 放进服务器 `mods/` 下的某个文件夹(或你的加载器识别 Rust 插件的位置),与 Rust 加载器放在一起,然后启动服务器。 **方式 B——从源码构建。** ```bash git clone https://github.com/Maskviva/Atlas-plus cd Atlas-plus cargo build --release # → target/release/atlas_plus.dll (Windows /你的 BDS 所在平台) ``` 把 `target/release/atlas_plus.dll` 和 `manifest.json` 一起打包分发。`manifest.json` 声明了对 `levilamina-rust-loader` 的依赖,所以加载器必须已安装。 首次运行时,Atlas-plus 会写出一份填满默认值的 `plugins/Atlas-plus/config.json`。修改它之后,重启插件(或重启服务器)即可生效。 --- ## 快速开始 1. 安装好插件后启动服务器。 2. 在控制台留意 `Atlas-plus live map: http://<host>:8899/` 这一行。 3. 打开这个地址。页面会立刻通过 WebSocket 建立连接;底图会在后台从磁盘流式加载进来,玩家附近的区域会随你观察实时更新。 4. 游戏内用 `/atlas status` 查看状态,或修改 `config.json` 后重启来调整行为。 --- ## `/atlas` 命令 `atlas` 是 Atlas-plus 的管理命令(任何玩家都能执行,它只用于查看状态)。 | 命令 | 作用 | | --- | --- | | `/atlas url` | 打印实时地图的访问地址。 | | `/atlas status` | 显示在线玩家数、启用的维度、更新模式、渲染版本号,以及地图地址。 | 配置的修改会在插件下一次启用时生效(重载插件或重启服务器)——**没有**运行时修改配置的命令。 --- ## 配置项 `plugins/Atlas-plus/config.json`——首次运行时会写出默认值。未识别的键会被忽略。 ### Web 服务器 | 字段 | 默认值 | 说明 | | --- | --- | --- | | `http_bind` | `"0.0.0.0"` | Web 服务器(以及 WebSocket)绑定的网卡地址。 | | `http_port` | `8899` | 地图地址为 `http://<host>:<port>/`;实时数据的连接地址为 `ws://<host>:<port>/ws`。 | | `http_workers` | `3` | 极轻量的 HTTP 工作线程数;2–4 就够用。每条打开的 WebSocket 连接会在这个线程池之外单独起一个线程。 | | `out_dir` | `"plugins/Atlas-plus/map"` | 瓦片 / `map.json` / 查看器页面写到磁盘的位置(保留是为了和 Atlas 瓦片格式兼容,也方便你自己额外用别的方式提供服务;内置查看器本身**不会**读取这里的文件——它走 WebSocket)。 | | `world_name` | `"Atlas-plus (live)"` | 显示在查看器里的世界名。 | ### 渲染范围 | 字段 | 默认值 | 说明 | | --- | --- | --- | | `dimensions` | `[0]` | `0` 主世界,`1` 下界,`2` 末地。 | | `render_radius_chunks` | `6` | 每个玩家周围的实时方形范围——**仅在 `update_mode: "full"` 时生效**。 | | `pinned_areas` | `[]` | 始终保持刷新的区域,例如出生点:`[{ "dim":0, "x":0, "z":0, "radius_chunks":6 }]`。请用 `tickingarea` 让这些区块保持加载。 | ### 磁盘引导(启用时执行一次,在后台进行) | 字段 | 默认值 | 说明 | | --- | --- | --- | | `bootstrap` | `true` | 读取磁盘上的世界并渲染已探索的地图。**只读**——绝不写入数据库。 | | `world_dir` | `null` | 世界文件夹(包含 `db/`、`level.dat`)。`null` = 从 `server.properties` 自动检测。 | | `bootstrap_radius_chunks` | `null` | 把引导范围限制在出生点 + pinned 区域周围的这个区块半径内。`null` = 整个世界。超大世界建议设置,以控制解码时的内存占用。 | | `bootstrap_throttle_ms` | `10` | 每批 region 之间的暂停时间,让引导过程平缓地进行。 | ### 实时更新策略 | `update_mode` | 行为 | | --- | --- | | `"nearby+events"`(默认) | 每个玩家**最近的 4 个区块**保持刷新,加上任何被世界变化事件触碰到的区块。 | | `"nearby"` | 只刷新每个玩家最近的 4 个区块。 | | `"events"` | 只刷新被事件触碰到的区块(空闲时几乎零开销)。 | | `"full"` | 持续轮转刷新每个玩家周围整个 `render_radius_chunks` 方形范围(开销最大)。 | | `"off"` | 不进行实时扫描(仅有引导底图 + 玩家标记)。 | **覆盖的事件:** 玩家**放置 / 破坏 / 交互**方块,以及**火焰蔓延**——这些是加载器暴露出来的世界变化事件。TNT 等爆炸、生物破坏地形、红石都**不会**触发加载器事件;实际使用中这些情况大多发生在玩家附近,默认模式里 `nearby` 的那一半会顺带覆盖到结果。无论哪种模式,剩余的扫描预算都会缓慢轮转覆盖 pinned 区域。 ### 扫描节奏(服务器线程开销) | 字段 | 默认值 | 说明 | | --- | --- | --- | | `chunks_per_cycle` | `6` | 每个周期扫描区块数的**硬上限**,对所有模式都生效。是控制 TPS 影响的主要旋钮。 | | `cycle_interval_ms` | `250` | 周期之间的间隔。如果感觉到卡顿(tick lag)就调大它。 | ### 扫描深度 / 正确性 | 字段 | 默认值 | 说明 | | --- | --- | --- | | `slab_height` | `16` | 每次 `scan_region` 调用扫描的纵向切片高度。 | | `scan_top` / `scan_bottom` | `null` | 覆盖扫描的 Y 范围(对所有维度生效)。把 `scan_top` 设成你实际建筑的最高高度是提速最明显的单项设置——但超过这个高度的东西不会显示。 | | `use_height_cache` | `true` | 记住每个区块表面的高度,让重复扫描从接近顶部的位置开始。建议保持开启。 | | `rebuild_headroom` | `16` | 在缓存的顶部高度之上再向上多扫这么多格,让小的新建筑无需完整重扫就能显示。 | | `full_rescan_every` | `16` | 每扫描第 N 次就强制对该区块做一次全范围重扫(用于捕捉非常高的新建筑)。 | ### 渲染器 | 字段 | 默认值 | 说明 | | --- | --- | --- | | `flush_interval_ms` | `1000` | 两次瓦片刷新之间的最小间隔(防抖)——同时也是变化的瓦片被推送到连接上的频率。玩家标记的更新独立于此,更新更快。 | | `max_regions` | `48` | 保留在内存中的 512×512 region 缓冲区数量上限(超出后按最久未用淘汰)。每个约 2 MB,用来控制内存占用。被淘汰的瓦片会在淘汰前先刷新到磁盘和连接上。 | --- ## 工作原理 启用时,一个后台线程会用一个小型的纯 Rust 只读读取器(SST 表 + WAL 重放,Mojang 的原始 deflate 格式)读取磁盘上的 LevelDB,计算每个已探索区块的表面,按 region 分组、节流地把它们发给渲染器,作为底图。 LeviLamina 的每个回调都运行在服务器线程上,所以实时扫描循环用 `schedule_after` 在服务器线程上自我调度节奏,并直接调用 `scan_region`(这是读取实时方块唯一安全的方式)。每个周期它会根据 `update_mode` 决定要重扫哪些区块,最多扫描 `chunks_per_cycle` 个区块,并把表面数据交给一个**后台渲染器**线程。实时扫描器已经画过的区块,不会被(更旧的)引导数据覆盖。没有被加载的区块,通过 API 读到的会是空气;Atlas-plus 会检测出"全部是空气"的扫描结果,遇到这种情况会保留已有像素而不是把它们擦除。 渲染器持有像素缓冲区,防抖之后会对发生变化的 region 做地形阴影处理、把它们的 PNG 瓦片写入磁盘(用于和 Atlas 瓦片格式兼容)——而真正让浏览器既不闪烁、又不可能被缓存耍的关键在于:**把刚好变化的那些瓦片以二进制帧的形式推送到 WebSocket 上**(一个包含维度/缩放级别/瓦片坐标的小头部,后面跟着原始 PNG 字节)。更新后的地图清单,以及玩家移动时的坐标,都以 JSON 文本帧的形式走同一条连接推送下去。浏览器根本没有任何 HTTP 请求可以从缓存里应付过去——瓦片像素抵达页面的唯一途径,就是通过一条打开的连接被主动推送。一个刚连上(或重新连上)的浏览器会立刻收到一次完整状态的回放:当前清单、玩家列表,以及服务器当前持有的每一张瓦片,一次性追上进度,而不用等下一次变化发生。 **瓦片规格:** 缩放级别 0 是每个 32×32 区块的 region 对应一张 512×512 的图像(瓦片坐标 = region 坐标,1 像素 = 1 格方块);更高的缩放级别是 2×2 降采样。磁盘上 `out_dir` 里的副本使用和磁盘版 Atlas 相同的 `tiles/<维度>/<缩放级别>/<rx>_<rz>.png` 目录结构,方便与其他工具兼容——但内置查看器本身从不通过 HTTP 把它们读回来。 --- ## 查看器 查看器是一个自包含的、Minecraft 风格的世界地图页面,served 在你的 `out_dir` 根目录(`index.html` + `map-viewer.js`)。在任意浏览器中打开 `http://<host>:<port>/` 即可——无需构建步骤,无外部资源依赖。页面加载后会打开 `ws://<host>:<port>/ws`,并通过这一条连接接收地图清单、玩家坐标,以及每一张瓦片图像;瓦片帧用 `createImageBitmap` 解码,直接画到 `<canvas>` 上。连接断开时会自动重连(有短暂的退避延迟),重连后会收到一次完整当前状态的回放。它也可以通过 `<iframe>` 指向被服务的 `index.html`,嵌入到别的页面里。 --- ## 性能调优 - **服务器感觉卡顿?** 调低 `chunks_per_cycle` 和/或调高 `cycle_interval_ms`(这个上限在所有模式下都生效)。把 `scan_top` 设成你实际建筑的最高高度;保持 `use_height_cache` 开启。默认的 `update_mode` 已经很轻量——`"events"` 在空闲时几乎零开销,`"off"` 则完全停止实时扫描。 - **变化显示得太慢?** 调高 `chunks_per_cycle` 和/或调低 `cycle_interval_ms`。在 `"full"` 模式下,也可以调低 `render_radius_chunks`。还可以调低 `flush_interval_ms`,让变化的瓦片更快推送到浏览器。 - **世界很大,引导过程吃内存?** 设置 `bootstrap_radius_chunks`(例如 `128`)。 - **高层建筑偶尔在顶部缺失?** 调低 `full_rescan_every`,或调高 `rebuild_headroom`(也可以直接设置明确的 `scan_top`)。 --- ## 说明与已知限制 - 基于加载器安全层 `levilamina-rust-loader` API 编写(v1.0.0 / ABI v4)。如果加载器版本不同导致无法编译或加载,请对齐版本。 - 有意**没有**设置 `panic = "abort"`——加载器会用 `catch_unwind` 包裹插件入口点,如果设置了 abort,一次 panic 会直接带崩整个服务器。 - 磁盘引导读取的是服务器正在打开使用的数据库。对数据库本身是安全的(只读),但如果存档正好在读取过程中落地,可能导致这次读取失败;这种情况会被记录到日志,地图会转为仅靠实时层继续填充。 - WebSocket 的握手和帧编解码是手写的一个小型 RFC 6455 实现(加载器本身不提供 WebSocket 支持,没有现成的可以依赖)——没有使用外部 crate,也没有 TLS。如果你需要 `wss://`,请把它放在反向代理后面。 - 与 Mojang 或 Microsoft 无关联。 --- ## 构建 ```bash cargo build --release ``` 依赖项:`levilamina-rust-loader`(通过 git 引入的 Rust 加载器 crate)、`image`(仅 PNG 功能)、`serde` / `serde_json`,以及 `flate2`(供 LevelDB 读取器使用)。未设置 `panic = "abort"`。 --- ## 许可证 本仓库采用 Apache-2.0 开源协议。 [Atlas]: https://www.minebbs.com/resources/atlasmap.17092/ [/MD]
作者
Maskviva
下载
17
查看
381
首次发布
最后更新

评分

0.00 星 0 次评分

Maskviva 的其他资源

最新更新

  1. 适配ll-rust-loader 26.20.2

    适配ll-rust-loader 26.20.2
后退
顶部 底部