维度之桥

维度之桥

DimensionBridge安全地将玩家从Fabric命令方块传输到已注册的Velocity后端服务器。它仅限服务端,支持协议限制的目的地,且无需客户端模组。

Minecraft 模组

需要在代理端安装 Velocity 插件 - 点击此处下载

DimensionBridge 由一个 Velocity 插件和一个配套的服务端 Fabric 模组组成。命令方块可以通过 /dimensionbridge transfer 发出经授权的传送请求。Velocity 在连接玩家之前,会验证源服务器、目标服务器、玩家、客户端协议、冷却时间以及授权窗口。

它专为传送门、维度门、维度旅行、大厅菜单以及其他沉浸式服务器切换而设计。普通玩家无需访问 /server 命令或任何桥接权限。

因此,这是一种让玩家从一个服务器传送到另一个不同服务器的安全方式,并且你还可以高度配置哪些"传送路线"可用。

例如:玩家可以从大厅服务器传送到任何世界服务器。但从世界服务器-1,他只能返回大厅;而从世界服务器-2,他可以返回大厅服务器以及世界服务器-2a。通过这种方式,你可以搭建复杂的服务器架构。

另一个过滤选项是,你可以根据 Minecraft 协议限制对某些服务器的访问。例如,你的大厅服务器可能对任何 Minecraft 版本开放,但它作为一个中心枢纽,玩家只能从它连接到符合其当前 Minecraft 版本的服务器。

想象一个电话亭,你走进去,它只显示你能用当前 Minecraft 版本拨打的号码。使用不同版本的另一位玩家会看到不同的号码。

其选项几乎是无限的,而且它本身也是一个安全特性,因为即使玩家获取到关于你的基础设施和服务器架构的一些信息,他也无法使用这些命令,因为它们绑定在模组/管理员(op)级别,而普通传送门则在用户级别使用命令。

请告诉我你对使用此模组的想法。

我是在观看《比尔和泰德畅游鬼门关》时产生这个想法的,想要有一种安全的方式在服务器/时间段之间切换。

此致,

Jan

DimensionBridge – 安装、配置与命令指南

1. 概述

DimensionBridge 是一个仅服务端的桥梁,连接 Fabric 后端服务器和 Velocity 代理。它允许命令方块、服务器控制台以及具有适当权限的命令源将玩家传送到已注册的 Velocity 服务器。

玩家无需访问 Velocity 的 /server 命令或任何桥接权限。因此,受保护的目标服务器可以仅通过经批准的传送门、电话亭或其他命令方块装置来访问。

架构

Minecraft 客户端
       │
       ▼
Velocity 代理
└─ DimensionBridge Velocity 插件
       │  频道: dimensionbridge:transfer
       ▼
Fabric 后端
└─ DimensionBridge Fabric 模组
   └─ 命令方块: dimensionbridge transfer <目标> <服务器>

不需要客户端模组。


2. 支持的版本

针对每个原生 Fabric 服务器版本都构建了单独的 JAR 文件:

1.20.1  1.20.2  1.20.3  1.20.4  1.20.5  1.20.6
1.21    1.21.1  1.21.2  1.21.3  1.21.4  1.21.5
1.21.6  1.21.7  1.21.8  1.21.9  1.21.10 1.21.11
26.1    26.1.1  26.1.2  26.2

始终使用与该后端服务器原生版本完全匹配的 Fabric JAR 文件。在选择后端 JAR 时,通过 ViaVersion 转换的客户端版本不相关。

运行时 Java 版本

Minecraft 版本 Java
1.20.1–1.20.4 17
1.20.5–1.21.11 21
26.1–26.2 25
当前 Velocity 插件 25

3. 要求

Velocity

  • 一个 Velocity 代理;
  • Java 25;
  • 每个后端都在 velocity.toml 中注册;
  • 可选:使用 LuckPerms 进行权限管理。

Fabric 后端

  • 与 Minecraft 版本匹配的 Fabric Loader;
  • 与 Minecraft 版本匹配的 Fabric API;
  • 匹配的 DimensionBridge Fabric JAR;
  • 在 server.properties 中启用命令方块:
enable-command-block=true

修改 server.properties 后需要完全重启服务器。


4. 下载源代码

如果你有兴趣参与,请联系我。


5. 安装 Velocity 插件

  1. 完全停止 Velocity。
  2. 将 Velocity JAR 复制到:
velocity/plugins/dimensionbridge-velocity-<版本号>.jar
  1. 启动 Velocity。
  2. 首次启动会创建:
plugins/dimensionbridge/dimensionbridge.properties
  1. 编辑该文件。之后你可以使用 /dimensionbridge reload 重新加载它。

代理控制台应显示类似以下消息:

DimensionBridge loaded. Channel: dimensionbridge:transfer

6. 安装 Fabric 后端模组

对每个后端服务器重复以下步骤:

  1. 完全停止后端。
  2. 将精确匹配的 Fabric JAR 复制到 mods 目录中。
  3. 确保已安装 Fabric API。
  4. 在 mods 目录中仅保留一个 DimensionBridge JAR。
  5. 启动后端。
  6. 首次启动会创建:
config/dimensionbridge-fabric.properties
  1. 编辑该文件并重启后端。

后端控制台应显示类似以下消息:

DimensionBridge backend <版本号> loaded. Channel: dimensionbridge:transfer

Fabric 配置目前没有重新加载命令。对 dimensionbridge-fabric.properties 的更改需要重启后端。


7. Fabric 配置

文件:

config/dimensionbridge-fabric.properties

大厅示例:

allowed-destinations=hauptwelt,hardcore,vanilla

游戏服务器示例,仅允许返回大厅:

allowed-destinations=lobby

允许所有语法上有效的目标:

allowed-destinations=*

allowed-destinations

这是单个 Fabric 后端的本地允许列表。只有当请求的目标在此处被允许时,传送负载才会被发送到 Velocity。

  • 多个名称用逗号分隔;
  • 名称规范化为小写;
  • 名称可以包含小写字母、数字、_ 和 -;
  • * 允许所有语法上有效的目标,由 Velocity 随后接受。

出于安全考虑,尽可能使用较窄的允许列表,而不是 *。


8. Velocity 配置

文件:

plugins/dimensionbridge/dimensionbridge.properties

使用服务器 lobby、hauptwelt、hardcore 和 vanilla 的完整示例:

# 服务器名称必须与 velocity.toml 完全匹配。
# * 允许任何来源或协议。

initial-servers=lobby
deny-unlisted-targets=true
cooldown-ms=2500
authorization-window-ms=5000
bypass-permission=dimensionbridge.bypass

destinations=lobby,hauptwelt,hardcore,vanilla

destination.lobby.display-name=Lobby
destination.lobby.protected=false
destination.lobby.allowed-sources=*
destination.lobby.allowed-protocols=*

destination.hauptwelt.display-name=Main World
destination.hauptwelt.protected=true
destination.hauptwelt.allowed-sources=lobby
destination.hauptwelt.allowed-protocols=MINECRAFT_1_20

destination.hardcore.display-name=Hardcore
destination.hardcore.protected=true
destination.hardcore.allowed-sources=lobby
destination.hardcore.allowed-protocols=MINECRAFT_1_20

destination.vanilla.display-name=Vanilla
destination.vanilla.protected=true
destination.vanilla.allowed-sources=lobby
destination.vanilla.allowed-protocols=MINECRAFT_26_2

全局设置

initial-servers

允许作为初始代理登录服务器的服务器列表,以逗号分隔。

initial-servers=lobby

deny-unlisted-targets

deny-unlisted-targets=true
  • true:未在 destinations 下列出的服务器将被拒绝;
  • false:未列出的服务器不受 DimensionBridge 的保护规则约束。

对于封闭的传送门网络,请使用 true。

cooldown-ms

同一玩家的两次桥接请求之间的延迟:

cooldown-ms=2500

允许范围:0 到 60,000 毫秒。

authorization-window-ms

DimensionBridge 发起的 Velocity 连接请求保持授权的时间窗口:

authorization-window-ms=5000

允许范围:500 到 60,000 毫秒。该值应长于正常的代理到后端连接尝试时间。

bypass-permission

绕过所有 DimensionBridge 保护检查的权限:

bypass-permission=dimensionbridge.bypass

仅授予可信的管理员。

目标定义

destinations 中的每个条目都需要四个属性:

destinations=lobby,hauptwelt

destination.hauptwelt.display-name=Main World
destination.hauptwelt.protected=true
destination.hauptwelt.allowed-sources=lobby
destination.hauptwelt.allowed-protocols=MINECRAFT_1_20

display-name

在玩家消息中显示的人类可读名称。

protected

  • true:进入目标需要有效的 DimensionBridge 授权。除非玩家拥有绕过权限,否则直接通过 /server 连接将被拒绝。
  • false:当协议规则匹配时,允许正常连接。

大厅通常应使用 protected=false,以确保初始登录和返回传送的可靠性。

allowed-sources

可以请求此目标的后端服务器:

destination.hauptwelt.allowed-sources=lobby

多个来源:

destination.hauptwelt.allowed-sources=lobby,hardcore

允许所有来源:

destination.lobby.allowed-sources=*

allowed-protocols

此目标接受的 Velocity 客户端协议名称:

destination.hauptwelt.allowed-protocols=MINECRAFT_1_20

多个协议:

destination.hauptwelt.allowed-protocols=MINECRAFT_1_20,MINECRAFT_1_21

允许所有协议:

destination.lobby.allowed-protocols=*

Minecraft 1.20 和 1.20.1 共享 MINECRAFT_1_20 协议组。

使用此命令获取已连接客户端的精确 Velocity 名称:

/dimensionbridge protocol <玩家>

9. 权限

dimensionbridge.admin

允许玩家使用 DimensionBridge 的管理性 Velocity 命令。

dimensionbridge.bypass

绕过目标、来源、协议和传送门授权检查。仅授予可信的管理员。

velocity.command.server

控制 Velocity 正常的 /server 命令。当传送应仅通过传送门发生时,可以拒绝普通玩家使用:

/lp group default permission set velocity.command.server false

管理员可以保留此权限:

/lp group admin permission set velocity.command.server true

DimensionBridge 不需要 velocity.command.server。

后端命令权限

dimensionbridge transfer 在 Fabric 上仅对控制台、命令方块以及具有管理员/命令等级 2 的来源可用。普通玩家无法使用它。不要授予普通玩家操作员或管理员权限。


10. 命令参考

Fabric 后端

传送玩家

/dimensionbridge transfer <目标> <Velocity 服务器名称>

在命令方块中省略开头的斜杠:

dimensionbridge transfer @p hauptwelt

示例:

# 最近的玩家
dimensionbridge transfer @p hauptwelt

# 三格内的最近玩家
dimensionbridge transfer @p[distance=..3,limit=1,sort=nearest] hauptwelt

# 一格宽、三格高的亭子内的所有玩家
dimensionbridge transfer @a[x=10,y=64,z=5,dx=0,dy=2,dz=0] hauptwelt

# 仅未被标记为战斗状态的玩家
dimensionbridge transfer @a[x=10,y=64,z=5,distance=..2,tag=!inCombat] hauptwelt

# 返回大厅
dimensionbridge transfer @p[distance=..3,limit=1,sort=nearest] lobby

Velocity

帮助

/dimensionbridge
/db

重新加载 Velocity 配置

/dimensionbridge reload
/db reload

此命令仅重新加载 Velocity 配置。

显示活动配置

/dimensionbridge info
/db info

输出显示配置路径和已加载的目标。

显示客户端协议

/dimensionbridge protocol
/dimensionbridge protocol <玩家>

当玩家省略名称时,命令显示该玩家自身的协议。


11. 基本功能测试

命令方块设置:

脉冲
无条件
需要红石

命令:

dimensionbridge transfer @p[distance=..3,limit=1,sort=nearest] hauptwelt

站在距离命令方块不超过三格的位置并按下按钮。

为排除半径因素:

dimensionbridge transfer @p hauptwelt

命令方块的上次输出应类似于:

DimensionBridge: sent 1 transfer request(s) to 'hauptwelt'.

当前模组可能以德语显示此消息;数字和目标名称是关键部分。


12. 示例:大厅电话亭

通往主世界的电话亭

dimensionbridge transfer @p[distance=..3,limit=1,sort=nearest] hauptwelt

通往极限模式世界的电话亭

dimensionbridge transfer @p[distance=..3,limit=1,sort=nearest] hardcore

通往原版世界的电话亭

dimensionbridge transfer @p[distance=..3,limit=1,sort=nearest] vanilla

每个游戏服务器上的返回电话亭

dimensionbridge transfer @p[distance=..3,limit=1,sort=nearest] lobby

该后端上的 Fabric 允许列表也必须允许该目标。


13. 示例:闪烁效果和倒计时

运行一次:

scoreboard objectives add dimensionTarget dummy
scoreboard objectives add dimensionTimer dummy

主世界启动按钮

脉冲命令方块:

scoreboard players set @p[distance=..3,limit=1,sort=nearest] dimensionTarget 1

后续连锁命令方块:

scoreboard players set @p[distance=..3,limit=1,sort=nearest] dimensionTimer 60

60 刻约为三秒。

重复效果命令方块

重复、无条件、始终活动:

execute as @a[scores={dimensionTimer=1..}] at @s run particle minecraft:portal ~ ~1 ~ 0.3 0.8 0.3 0.1 10 force

后续连锁命令方块,全部始终活动:

execute as @a[scores={dimensionTimer=1..}] at @s run particle minecraft:reverse_portal ~ ~1 ~ 0.45 0.9 0.45 0.08 5 force
execute as @a[scores={dimensionTimer=1..}] run title @s actionbar {"text":"Opening dimension …","color":"aqua","italic":true}
execute as @a[scores={dimensionTimer=60}] at @s run playsound minecraft:block.beacon.activate master @s ~ ~ ~ 0.8 0.7
execute as @a[scores={dimensionTimer=20}] at @s run playsound minecraft:block.respawn_anchor.charge master @s ~ ~ ~ 0.8 1.3

传送必须在计时器值 1 被移除之前运行:

dimensionbridge transfer @a[scores={dimensionTimer=1,dimensionTarget=1}] hauptwelt

然后:

scoreboard players remove @a[scores={dimensionTimer=2..}] dimensionTimer 1
scoreboard players reset @a[scores={dimensionTimer=1}] dimensionTarget
scoreboard players reset @a[scores={dimensionTimer=1}] dimensionTimer

14. 示例:使用 /trigger 的可点击聊天菜单

运行一次:

scoreboard objectives add dimension trigger
scoreboard objectives add dimensionTarget dummy
scoreboard objectives add dimensionTimer dummy

在显示菜单前为玩家启用触发器:

scoreboard players enable @p[distance=..3,limit=1,sort=nearest] dimension

使用原生 Minecraft 1.20.1 大厅的文本组件语法示例:

tellraw @p[distance=..3,limit=1,sort=nearest] [{"text":"☎ Select dimension\n","color":"gold","bold":true},{"text":"[ Main World ]","color":"green","clickEvent":{"action":"run_command","value":"/trigger dimension set 1"}},{"text":"\n"},{"text":"[ Hardcore ]","color":"red","clickEvent":{"action":"run_command","value":"/trigger dimension set 2"}},{"text":"\n"},{"text":"[ Vanilla ]","color":"aqua","clickEvent":{"action":"run_command","value":"/trigger dimension set 3"}}]

JSON 文本组件语法可能会随 Minecraft 版本而变化。请使用执行命令方块的服务器原生版本所支持的语法。

存储所选目标:

execute as @a[scores={dimension=1}] run scoreboard players set @s dimensionTarget 1
execute as @a[scores={dimension=2}] run scoreboard players set @s dimensionTarget 2
execute as @a[scores={dimension=3}] run scoreboard players set @s dimensionTarget 3
scoreboard players set @a[scores={dimension=1..3}] dimensionTimer 60
scoreboard players reset @a[scores={dimension=1..3}] dimension

在计时器值为 1 时传送:

dimensionbridge transfer @a[scores={dimensionTimer=1,dimensionTarget=1}] hauptwelt
dimensionbridge transfer @a[scores={dimensionTimer=1,dimensionTarget=2}] hardcore
dimensionbridge transfer @a[scores={dimensionTimer=1,dimensionTarget=3}] vanilla

15. 故障排除

命令方块无反应

检查:

enable-command-block=true

另外:

  • 将命令方块设置为脉冲、无条件、需要红石;
  • 确保按钮为命令方块供电;
  • 启用并查看命令方块的上次输出;
  • 简化选择器以进行测试:
dimensionbridge transfer @p hauptwelt

"未知或不完整的命令"

可能的原因:

  • 为原生 Minecraft 版本选择了错误的 Fabric JAR;
  • DimensionBridge 未加载;
  • 缺少 Fabric API;
  • 安装后后端未完全重启。

"目标未在本地允许"

目标缺失于:

config/dimensionbridge-fabric.properties

示例:

allowed-destinations=hauptwelt,hardcore,vanilla

之后重启后端。

"未知的维度标识符或目标"

目标缺失于 Velocity 的 destinations 列表或其目标属性块缺失。

"目标服务器未在代理中注册"

服务器名称与 velocity.toml 中的条目不完全匹配。

"此传送门无法选择此目标"

当前后端缺失于 destination.<目标>.allowed-sources。

版本被拒绝

检查实际客户端协议:

/dimensionbridge protocol <玩家>

在 allowed-protocols 中使用显示的常量。

直接 /server 被拒绝

对于 protected=true 的目标,这是预期的。请使用传送门,或有意将 dimensionbridge.bypass 授予管理员。

配置更改未生效

  • Velocity 配置:/dimensionbridge reload
  • Fabric 配置:完全重启后端

没有负载到达 Velocity

验证:

  • 所选玩家当前已连接到发送后端;
  • 代理和后端上安装了匹配的 DimensionBridge 版本;
  • 双方都使用频道 dimensionbridge:transfer;
  • 没有安装旧的 TelephoneBridge 或重复的 DimensionBridge JAR。

16. 推荐的安全配置

Velocity:

deny-unlisted-targets=true

游戏世界:

destination.hauptwelt.protected=true
destination.hardcore.protected=true
destination.vanilla.protected=true

大厅:

destination.lobby.protected=false

LuckPerms:

/lp group default permission set velocity.command.server false

保持 Fabric 允许列表较窄:

# 大厅
allowed-destinations=hauptwelt,hardcore,vanilla
# 游戏世界
allowed-destinations=lobby

17. 更新

  1. 停止代理和所有后端。
  2. 移除旧的 DimensionBridge JAR 文件。
  3. 安装新的 Velocity JAR。
  4. 安装与每个后端精确原生 Minecraft 版本匹配的 JAR。
  5. 切勿同时加载两个 DimensionBridge 版本。
  6. 备份配置文件。
  7. 重启代理和后端。
  8. 测试 /dimensionbridge info 和一次基本的命令方块传送。