Rename project to MoonBridge and expose standalone Bukkit API

This commit is contained in:
layue13 committed 2026-09-27 22:39:16 +08:00
1 parent 21011d51bd
commit 64152878d0
193 files changed
+934 -783

No files matched your search

+1 -1
View File
@@ -1,4 +1,4 @@
name: Verify StrataProxy
name: Verify MoonBridge
on:
pull_request:
+9 -3
View File
@@ -1,4 +1,4 @@
# StrataProxy
# MoonBridge
面向 Minecraft 1.7.10 Forge 的玩家会话代理:登录认证、协议转发、跨后端转服,以及供插件使用的玩家、服务器目录、富文本、命令补全、类型化事件和 Channel 消息服务。后端插件共享认证连接,通过 channel 与 proxy 或其他 backend 通信。空岛分配、实例唤醒和 Ban 数据存储由插件实现。
@@ -17,13 +17,19 @@
```powershell
.\gradlew.bat check :proxy-core:installDist
.\proxy-core\build\install\strataproxy\bin\strataproxy.bat --config .\proxy-core\build\install\strataproxy\config\strataproxy.yml
.\proxy-core\build\install\moonbridge\bin\moonbridge.bat --config .\proxy-core\build\install\moonbridge\config\moonbridge.yml
```
默认配置为 `OFFLINE`,仅监听 `127.0.0.1:25577`,后端为 `127.0.0.1:25565`。公开部署使用 `ONLINE_BUNGEE`,并限制玩家直连后端。详见[运行配置](docs/operations.md)。
## 后端插件开发
服务器安装 `moonbridge-backend-bukkit` JAR(插件名 `MoonBridgeBackend`)。业务插件以 `compileOnly` / `provided` 依赖 `uk.potatolab:backend-bukkit-api:0.1.0-SNAPSHOT`,通过 `BukkitMessagingService` 获取共享消息服务;无需依赖宿主实现或创建网络连接。API 和完整接入示例见[后端插件接入](docs/backend-channel-design.md#后端插件接入)。
本次改名统一使用 `dev.moonbridge` 包名、`moonbridge` 启动命令和 `moonbridge.yml` 配置文件。现有插件需要重新编译,Bukkit 插件依赖声明和宿主配置目录改用 `MoonBridgeBackend`。历史验收记录保留当时的名称与构件路径。
## 验证状态
`StrataProxyBackend` 后端宿主已通过两个真实 Uranium / Java 8 服务端的注册、通信、主线程回调、插件停用、重连及注销/租约验收,见[后端宿主验收记录](smoke/results/2026-09-27-backend-host.md)。这是无玩家、隔离服务端上的功能验收,不代表生产容量测试。
`MoonBridgeBackend` 后端宿主与独立 API 已通过两个真实 Uranium / Java 8 服务端的注册、通信、主线程回调、插件停用、重连及注销/租约验收,见[改名与独立 API 验收记录](smoke/results/2026-09-27-moonbridge-api.md)。这是无玩家、隔离服务端上的功能验收,不代表生产容量测试。
已完成当前 Prism 整合包的真实 Mojang 认证、连续 20 次转服、历史 DNS/Agent 发行包烟测及同条件流量对照,见[验收记录](benchmarks/results/2026-09-26-prism-pack.md)。验收覆盖单玩家与本机后端;生产容量需按部署环境测量。已知 Uranium 候选服登录停滞的调查见[记录](smoke/results/2026-09-26-uranium-login-stalls.md)及 [Uranium #585](https://git.nest.potatolab.uk:8443/TDLM/Uranium/issues/585)。
+74
View File
@@ -0,0 +1,74 @@
import java.io.DataInputStream
import java.util.jar.JarFile
plugins {
`java-library`
`maven-publish`
}
java {
toolchain.languageVersion.set(JavaLanguageVersion.of(25))
withSourcesJar()
withJavadocJar()
}
tasks.withType<JavaCompile>().configureEach {
options.release.set(8)
options.encoding = "UTF-8"
}
dependencies {
api(project(":messaging-api"))
// Consumers compile with their server API; the running server supplies Bukkit.
compileOnly("org.spigotmc:spigot-api:1.8-R0.1-SNAPSHOT") { isTransitive = false }
}
val verifyApiJar = tasks.register("verifyApiJar") {
group = "verification"
dependsOn(tasks.jar)
val apiJar = tasks.jar.flatMap { it.archiveFile }
inputs.file(apiJar)
doLast {
JarFile(apiJar.get().asFile).use { archive ->
val entries = archive.entries().asSequence().toList()
val classes = entries.filter { it.name.endsWith(".class") }
check(classes.map { it.name } == listOf("dev/moonbridge/bukkit/BukkitMessagingService.class")) {
"Bukkit API artifact must contain only the public service contract"
}
check(entries.none { it.name == "plugin.yml" }) { "API is not a deployable plugin" }
classes.forEach { entry ->
DataInputStream(archive.getInputStream(entry)).use { input ->
input.readInt()
input.readUnsignedShort()
check(input.readUnsignedShort() == 52) { "Bukkit API must target Java 8" }
}
}
}
}
}
tasks.named("check") { dependsOn(verifyApiJar) }
publishing {
publications {
create<MavenPublication>("bukkitApi") {
from(components["java"])
artifactId = "backend-bukkit-api"
pom {
name.set("MoonBridge Bukkit API")
description.set("Java 8 service contract for plugins using the shared MoonBridge backend host.")
}
}
}
repositories {
maven {
name = "giteaPackages"
url = uri(providers.environmentVariable("MAVEN_URL")
.orElse("https://git.nest.potatolab.uk:8443/api/packages/layue13/maven").get())
credentials {
username = providers.environmentVariable("MAVEN_USER").orElse("NONE").get()
password = providers.environmentVariable("MAVEN_PASSWORD").orElse("NONE").get()
}
}
}
}
@@ -1,9 +1,9 @@
package dev.strataproxy.bukkit;
package dev.moonbridge.bukkit;
import dev.strataproxy.messaging.Messaging;
import dev.moonbridge.messaging.Messaging;
import org.bukkit.plugin.Plugin;
/** Shared service provided by the StrataProxyBackend Bukkit plugin. */
/** Shared service provided by the MoonBridgeBackend Bukkit plugin. */
public interface BukkitMessagingService {
/**
* Returns this enabled plugin's owned messaging scope. Repeated lookups for
+8 -8
View File
@@ -18,7 +18,7 @@ tasks.withType<JavaCompile>().configureEach {
}
dependencies {
api(project(":messaging-api"))
api(project(":backend-bukkit-api"))
implementation(project(":backend-channel-client"))
compileOnly("org.spigotmc:spigot-api:1.8-R0.1-SNAPSHOT") { isTransitive = false }
testImplementation("org.spigotmc:spigot-api:1.8-R0.1-SNAPSHOT") { isTransitive = false }
@@ -34,7 +34,7 @@ tasks.withType<Test>().configureEach { useJUnitPlatform() }
// One provider owns the API classes, codec and transport. Consumers use compileOnly
// and plugin.yml depend, so Bukkit resolves the same service class identity.
tasks.jar {
archiveBaseName.set("strataproxy-backend-bukkit")
archiveBaseName.set("moonbridge-backend-bukkit")
dependsOn(configurations.runtimeClasspath)
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
from({ configurations.runtimeClasspath.get().filter { it.extension == "jar" }.map { zipTree(it) } })
@@ -51,11 +51,11 @@ val verifyHostJar = tasks.register("verifyHostJar") {
val entries = archive.entries().asSequence().toList()
val names = entries.map { it.name }
listOf("plugin.yml", "config.yml",
"dev/strataproxy/bukkit/BukkitMessagingService.class",
"dev/strataproxy/messaging/Message.class",
"dev/strataproxy/messaging/internal/LocalMessaging.class",
"dev/strataproxy/messaging/protocol/MessageCodec.class",
"dev/strataproxy/backendchannel/BackendChannelClient.class").forEach {
"dev/moonbridge/bukkit/BukkitMessagingService.class",
"dev/moonbridge/messaging/Message.class",
"dev/moonbridge/messaging/internal/LocalMessaging.class",
"dev/moonbridge/messaging/protocol/MessageCodec.class",
"dev/moonbridge/backendchannel/BackendChannelClient.class").forEach {
check(names.count { name -> name == it } == 1) { "Host jar must contain exactly one $it" }
}
check(names.none { it.startsWith("org/bukkit/") }) { "Bukkit API must remain server-provided" }
@@ -78,7 +78,7 @@ publishing {
from(components["java"])
artifactId = "backend-bukkit"
pom {
name.set("StrataProxy Backend Host")
name.set("MoonBridge Backend Host")
description.set("Java 8 shared channel messaging service for Bukkit and Uranium plugins.")
}
}
@@ -1,6 +1,6 @@
package dev.strataproxy.bukkit;
package dev.moonbridge.bukkit;
import dev.strataproxy.backendchannel.BackendChannelClient;
import dev.moonbridge.backendchannel.BackendChannelClient;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.server.PluginDisableEvent;
@@ -15,7 +15,7 @@ import java.util.concurrent.Executor;
import java.util.concurrent.RejectedExecutionException;
/** One process-level authenticated transport shared by all dependent plugins. */
public final class StrataProxyBackendPlugin extends JavaPlugin implements Listener {
public final class MoonBridgeBackendPlugin extends JavaPlugin implements Listener {
private volatile boolean stopping;
private BackendChannelClient client;
private OwnedMessagingService service;
@@ -37,10 +37,10 @@ public final class StrataProxyBackendPlugin extends JavaPlugin implements Listen
service = new OwnedMessagingService(client::messaging, this::mainThreadExecutor);
getServer().getServicesManager().register(BukkitMessagingService.class, service, this, ServicePriority.Normal);
getServer().getPluginManager().registerEvents(this, this);
getLogger().info("Shared StrataProxy messaging service started; registration runs asynchronously");
getLogger().info("Shared MoonBridge messaging service started; registration runs asynchronously");
} catch (RuntimeException failure) {
// Do not include configuration values or authentication peer data.
getLogger().severe("Cannot start StrataProxy messaging: " + failure.getClass().getSimpleName());
getLogger().severe("Cannot start MoonBridge messaging: " + failure.getClass().getSimpleName());
getServer().getPluginManager().disablePlugin(this);
} finally {
if (secret != null) Arrays.fill(secret, (byte) 0);
@@ -1,6 +1,6 @@
package dev.strataproxy.bukkit;
package dev.moonbridge.bukkit;
import dev.strataproxy.messaging.Messaging;
import dev.moonbridge.messaging.Messaging;
import org.bukkit.plugin.Plugin;
import java.util.ArrayList;
@@ -26,7 +26,7 @@ final class OwnedMessagingService implements BukkitMessagingService, AutoCloseab
@Override public synchronized Messaging forPlugin(Plugin owner) {
Objects.requireNonNull(owner, "owner");
if (closed) throw new IllegalStateException("StrataProxy messaging host is disabled");
if (closed) throw new IllegalStateException("MoonBridge messaging host is disabled");
if (!owner.isEnabled()) throw new IllegalStateException("Message owner is not enabled");
Messaging existing = owners.get(owner);
if (existing != null) return existing;
+1 -1
View File
@@ -1,5 +1,5 @@
# Install exactly one host plugin per backend. Consumer plugins depend on
# StrataProxyBackend and obtain BukkitMessagingService from ServicesManager.
# MoonBridgeBackend and obtain BukkitMessagingService from ServicesManager.
proxyHost: "127.0.0.1"
proxyPort: 28081
instanceId: "island-a"
+3 -3
View File
@@ -1,5 +1,5 @@
name: StrataProxyBackend
main: dev.strataproxy.bukkit.StrataProxyBackendPlugin
name: MoonBridgeBackend
main: dev.moonbridge.bukkit.MoonBridgeBackendPlugin
version: 0.1.0
description: Shared backend host for StrataProxy
description: Shared backend host for MoonBridge
load: STARTUP
@@ -1,7 +1,7 @@
package dev.strataproxy.bukkit;
package dev.moonbridge.bukkit;
import dev.strataproxy.messaging.MessageChannel;
import dev.strataproxy.messaging.Messaging;
import dev.moonbridge.messaging.MessageChannel;
import dev.moonbridge.messaging.Messaging;
import org.bukkit.plugin.Plugin;
import org.junit.jupiter.api.Test;
+1 -1
View File
@@ -35,7 +35,7 @@ publishing {
from(components["java"])
artifactId = "backend-channel-client"
pom {
name.set("StrataProxy Backend Channel Client")
name.set("MoonBridge Backend Channel Client")
description.set("Java 8-compatible backend control channel SDK.")
}
}
@@ -1,14 +1,14 @@
package dev.strataproxy.backendchannel;
package dev.moonbridge.backendchannel;
import dev.strataproxy.messaging.Endpoint;
import dev.strataproxy.messaging.Message;
import dev.strataproxy.messaging.MessageKind;
import dev.strataproxy.messaging.Messaging;
import dev.strataproxy.messaging.MessagingException;
import dev.strataproxy.messaging.PublishResult;
import dev.strataproxy.messaging.SendResult;
import dev.strataproxy.messaging.internal.LocalMessaging;
import dev.strataproxy.messaging.protocol.MessageCodec;
import dev.moonbridge.messaging.Endpoint;
import dev.moonbridge.messaging.Message;
import dev.moonbridge.messaging.MessageKind;
import dev.moonbridge.messaging.Messaging;
import dev.moonbridge.messaging.MessagingException;
import dev.moonbridge.messaging.PublishResult;
import dev.moonbridge.messaging.SendResult;
import dev.moonbridge.messaging.internal.LocalMessaging;
import dev.moonbridge.messaging.protocol.MessageCodec;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
@@ -1,4 +1,4 @@
package dev.strataproxy.backendchannel;
package dev.moonbridge.backendchannel;
import java.io.DataInputStream;
import java.io.DataOutputStream;
@@ -1,4 +1,4 @@
package dev.strataproxy.backendchannel;
package dev.moonbridge.backendchannel;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -1,10 +1,10 @@
package dev.strataproxy.backendchannel;
package dev.moonbridge.backendchannel;
import dev.strataproxy.messaging.Endpoint;
import dev.strataproxy.messaging.Message;
import dev.strataproxy.messaging.MessageKind;
import dev.strataproxy.messaging.MessageChannel;
import dev.strataproxy.messaging.protocol.MessageCodec;
import dev.moonbridge.messaging.Endpoint;
import dev.moonbridge.messaging.Message;
import dev.moonbridge.messaging.MessageKind;
import dev.moonbridge.messaging.MessageChannel;
import dev.moonbridge.messaging.protocol.MessageCodec;
import org.junit.jupiter.api.Test;
import javax.crypto.Mac;
@@ -85,7 +85,7 @@ class BackendChannelClientTest {
BackendChannelClient client = new BackendChannelClient("127.0.0.1", server.getLocalPort(), "backend-1", "island-a",
"tcp://127.0.0.1:25565", "gen-1", "key-1", secret, 10_000L, 100L, 500L);
dev.strataproxy.messaging.Messaging messaging = client.messaging("test-plugin");
dev.moonbridge.messaging.Messaging messaging = client.messaging("test-plugin");
MessageChannel channel = messaging.channel("backend:echo");
channel.onRequest(message -> CompletableFuture.completedFuture(
(new String(message.payload(), StandardCharsets.UTF_8) + "!").getBytes(StandardCharsets.UTF_8)));
@@ -128,7 +128,7 @@ class BackendChannelClientTest {
});
BackendChannelClient client = new BackendChannelClient("127.0.0.1", server.getLocalPort(), "slow-peer", "island-slow",
"tcp://127.0.0.1:25570", "gen-slow", "key-1", secret);
dev.strataproxy.messaging.Messaging messaging = client.messaging("slow-test");
dev.moonbridge.messaging.Messaging messaging = client.messaging("slow-test");
try {
assertTrue(client.awaitRegistered(5, TimeUnit.SECONDS));
byte[] payload = new byte[Message.MAX_PAYLOAD_BYTES];
@@ -172,7 +172,7 @@ class BackendChannelClientTest {
if (afterExpiry.operationId != 129L) {
assertTrue(afterExpiry.operationId >= 1L && afterExpiry.operationId <= 128L);
assertEquals(MessageCodec.Response.Type.ERROR, afterExpiry.type);
assertEquals(dev.strataproxy.messaging.MessagingException.Code.TIMED_OUT, afterExpiry.errorCode);
assertEquals(dev.moonbridge.messaging.MessagingException.Code.TIMED_OUT, afterExpiry.errorCode);
}
} while (afterExpiry.operationId != 129L);
assertEquals(MessageCodec.Response.Type.REPLY, afterExpiry.type);
@@ -185,7 +185,7 @@ class BackendChannelClientTest {
});
BackendChannelClient client = new BackendChannelClient("127.0.0.1", server.getLocalPort(), "hang-backend", "island-hang",
"tcp://127.0.0.1:25571", "gen-hang", "key-1", secret);
dev.strataproxy.messaging.Messaging messaging = client.messaging("hang-test");
dev.moonbridge.messaging.Messaging messaging = client.messaging("hang-test");
java.util.concurrent.atomic.AtomicInteger calls = new java.util.concurrent.atomic.AtomicInteger();
messaging.channel("test:hang").onRequest(message -> {
int call = calls.incrementAndGet();
@@ -240,7 +240,7 @@ class BackendChannelClientTest {
});
BackendChannelClient client = new BackendChannelClient("127.0.0.1", server.getLocalPort(), "reconnect-backend", "island-reconnect",
"tcp://127.0.0.1:25572", "gen-reconnect", "key-1", secret, 10_000L, 25L, 100L);
dev.strataproxy.messaging.Messaging messaging = client.messaging("reconnect-test");
dev.moonbridge.messaging.Messaging messaging = client.messaging("reconnect-test");
try {
assertTrue(client.awaitRegistered(5, TimeUnit.SECONDS));
CompletableFuture<Message> old = messaging.channel("test:reconnect")
+1 -1
View File
@@ -1,4 +1,4 @@
package dev.strataproxy.core.session;
package dev.moonbridge.core.session;
import com.sun.management.ThreadMXBean;
import io.netty.buffer.ByteBuf;
+8 -8
View File
@@ -1,12 +1,12 @@
package dev.strataproxy.core.session;
package dev.moonbridge.core.session;
import dev.strataproxy.api.PlacementDecision;
import dev.strataproxy.api.PlayerView;
import dev.strataproxy.api.TransferStatus;
import dev.strataproxy.core.backend.BackendId;
import dev.strataproxy.core.backend.BackendOwner;
import dev.strataproxy.core.backend.BackendRegistration;
import dev.strataproxy.core.backend.InMemoryBackendCatalog;
import dev.moonbridge.api.PlacementDecision;
import dev.moonbridge.api.PlayerView;
import dev.moonbridge.api.TransferStatus;
import dev.moonbridge.core.backend.BackendId;
import dev.moonbridge.core.backend.BackendOwner;
import dev.moonbridge.core.backend.BackendRegistration;
import dev.moonbridge.core.backend.InMemoryBackendCatalog;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
+5 -5
View File
@@ -1,9 +1,9 @@
package dev.strataproxy.core.session;
package dev.moonbridge.core.session;
import dev.strataproxy.core.protocol.MinecraftFrameDecoder;
import dev.strataproxy.core.protocol.ProtocolProfile;
import dev.strataproxy.core.protocol.ProtocolVarInt;
import dev.strataproxy.core.relay.RawRelay;
import dev.moonbridge.core.protocol.MinecraftFrameDecoder;
import dev.moonbridge.core.protocol.ProtocolProfile;
import dev.moonbridge.core.protocol.ProtocolVarInt;
import dev.moonbridge.core.relay.RawRelay;
import io.netty.bootstrap.Bootstrap;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
+2 -2
View File
@@ -7,7 +7,7 @@ param(
$ErrorActionPreference = "Stop"
$repoRoot = Split-Path -Parent $PSScriptRoot
$installLib = Join-Path $repoRoot "proxy-core\build\install\strataproxy\lib"
$installLib = Join-Path $repoRoot "proxy-core\build\install\moonbridge\lib"
$classes = Join-Path $PSScriptRoot "build"
Push-Location $repoRoot
@@ -19,7 +19,7 @@ try {
& javac -cp "$installLib\*" -d $classes (Join-Path $PSScriptRoot "CipherBenchmark.java")
if ($LASTEXITCODE -ne 0) { throw "javac failed with exit code $LASTEXITCODE" }
& java -cp "$classes;$installLib\*" dev.strataproxy.core.session.CipherBenchmark `
& java -cp "$classes;$installLib\*" dev.moonbridge.core.session.CipherBenchmark `
$Bytes $Iterations $Warmup $Rounds
if ($LASTEXITCODE -ne 0) { throw "benchmark failed with exit code $LASTEXITCODE" }
} finally {
+2 -2
View File
@@ -11,7 +11,7 @@ param(
$ErrorActionPreference = "Stop"
$repoRoot = Split-Path -Parent $PSScriptRoot
$installLib = Join-Path $repoRoot "proxy-core\build\install\strataproxy\lib"
$installLib = Join-Path $repoRoot "proxy-core\build\install\moonbridge\lib"
$classes = Join-Path $PSScriptRoot "build"
Push-Location $repoRoot
@@ -23,7 +23,7 @@ try {
& javac -cp "$installLib\*" -d $classes (Join-Path $PSScriptRoot "ProxySessionBenchmark.java")
if ($LASTEXITCODE -ne 0) { throw "javac failed with exit code $LASTEXITCODE" }
& java -cp "$classes;$installLib\*" dev.strataproxy.core.session.ProxySessionBenchmark `
& java -cp "$classes;$installLib\*" dev.moonbridge.core.session.ProxySessionBenchmark `
--connections $Connections --messages $Messages --warmup $Warmup --payload $Payload --repeats $Repeats `
--window $Window --mode $Mode --command-interceptor $CommandInterceptor
if ($LASTEXITCODE -ne 0) { throw "benchmark failed with exit code $LASTEXITCODE" }
+2 -2
View File
@@ -9,7 +9,7 @@ param(
$ErrorActionPreference = "Stop"
$repoRoot = Split-Path -Parent $PSScriptRoot
$installLib = Join-Path $repoRoot "proxy-core\build\install\strataproxy\lib"
$installLib = Join-Path $repoRoot "proxy-core\build\install\moonbridge\lib"
$classes = Join-Path $PSScriptRoot "build"
Push-Location $repoRoot
@@ -21,7 +21,7 @@ try {
& javac -cp "$installLib\*" -d $classes (Join-Path $PSScriptRoot "RelayBenchmark.java")
if ($LASTEXITCODE -ne 0) { throw "javac failed with exit code $LASTEXITCODE" }
& java -cp "$classes;$installLib\*" dev.strataproxy.core.session.RelayBenchmark `
& java -cp "$classes;$installLib\*" dev.moonbridge.core.session.RelayBenchmark `
--connections $Connections --messages $Messages --warmup $Warmup --payload $Payload --repeats $Repeats --window $Window
if ($LASTEXITCODE -ne 0) { throw "benchmark failed with exit code $LASTEXITCODE" }
}
+4 -4
View File
@@ -1,6 +1,6 @@
plugins {
id("strataproxy.java-library-conventions") apply false
id("strataproxy.application-conventions") apply false
id("moonbridge.java-library-conventions") apply false
id("moonbridge.application-conventions") apply false
}
allprojects {
@@ -11,11 +11,11 @@ allprojects {
tasks.register("check") {
group = "verification"
dependsOn(":proxy-plugin-api:check", ":messaging-api:check", ":messaging-protocol:check",
":backend-channel-client:check", ":backend-bukkit:check", ":proxy-core:check")
":backend-channel-client:check", ":backend-bukkit-api:check", ":backend-bukkit:check", ":proxy-core:check")
}
tasks.register("publish") {
group = "publishing"
dependsOn(":proxy-plugin-api:publish", ":messaging-api:publish", ":messaging-protocol:publish",
":backend-channel-client:publish", ":backend-bukkit:publish")
":backend-channel-client:publish", ":backend-bukkit-api:publish", ":backend-bukkit:publish")
}
+8 -8
View File
@@ -5,10 +5,10 @@
## 模块
- `proxy-plugin-api` 定义插件外部接口:生命周期、玩家/服务器只读视图、后端注册、类型化事件、初始选服、命令和转服。核心实现位于 `proxy-core`;可选发现器位于 `plugins/`。
- `ProxyMain` 读取严格 YAML 配置,先注册静态后端,再加载配置启用的插件,连接插件选服回调,最后启动 Netty 监听器。插件以 `META-INF/services/dev.strataproxy.api.Plugin` 声明,通过独立类加载器加载。
- `ProxyMain` 读取严格 YAML 配置,先注册静态后端,再加载配置启用的插件,连接插件选服回调,最后启动 Netty 监听器。插件以 `META-INF/services/dev.moonbridge.api.Plugin` 声明,通过独立类加载器加载。
- 核心支持 Minecraft 1.7.10(协议 5)登录和转发。`OFFLINE` 信任客户端提交的名字;`ONLINE_BUNGEE` 在代理执行加密与会话验证,并将身份转发给受信任的旧版 Bungee 后端。
入口可从 [`ProxyMain`](../proxy-core/src/main/java/dev/strataproxy/app/ProxyMain.java)、[`ProxySessionListener`](../proxy-core/src/main/java/dev/strataproxy/core/session/ProxySessionListener.java) 和 [`PluginHost`](../proxy-core/src/main/java/dev/strataproxy/core/plugin/PluginHost.java) 追踪。
入口可从 [`ProxyMain`](../proxy-core/src/main/java/dev/moonbridge/app/ProxyMain.java)、[`ProxySessionListener`](../proxy-core/src/main/java/dev/moonbridge/core/session/ProxySessionListener.java) 和 [`PluginHost`](../proxy-core/src/main/java/dev/moonbridge/core/plugin/PluginHost.java) 追踪。
## 会话与连接生命周期
@@ -28,7 +28,7 @@ flowchart LR
F --> G[PLAY / Forge 握手与转发]
```
普通转发沿用协议 5 帧边界,不重新编码普通帧。前后端通道绑定同一 Netty EventLoop,会话控制状态在该循环串行变更。Keep Alive ID 由代理转换并跟踪未完成请求;必要的玩家实体 ID 数据包在转服后改写。通道不可写时通过暂停对端读取施加背压。实现见 [`Session`](../proxy-core/src/main/java/dev/strataproxy/core/session/Session.java)、[`RawRelay`](../proxy-core/src/main/java/dev/strataproxy/core/relay/RawRelay.java) 与 [`KeepAliveBridge`](../proxy-core/src/main/java/dev/strataproxy/core/session/KeepAliveBridge.java)。
普通转发沿用协议 5 帧边界,不重新编码普通帧。前后端通道绑定同一 Netty EventLoop,会话控制状态在该循环串行变更。Keep Alive ID 由代理转换并跟踪未完成请求;必要的玩家实体 ID 数据包在转服后改写。通道不可写时通过暂停对端读取施加背压。实现见 [`Session`](../proxy-core/src/main/java/dev/moonbridge/core/session/Session.java)、[`RawRelay`](../proxy-core/src/main/java/dev/moonbridge/core/relay/RawRelay.java) 与 [`KeepAliveBridge`](../proxy-core/src/main/java/dev/moonbridge/core/session/KeepAliveBridge.java)。
## 后端目录与发现所有权
@@ -40,7 +40,7 @@ flowchart LR
## 转服、并发与错误边界
转服先在旧后端保持服务的同时连接并登录候选后端。普通后端在 Join Game 后可进入切换;Forge 候选后端要等待客户端 Forge 握手链路切换及 Join Game,再进行世界切换。交接期间客户端与旧后端帧分别进入有上限的缓冲区;切换前失败时尽可能恢复旧链路并回放暂存帧,成功时改用候选链路并清理旧链路。候选连接失败不会立即破坏旧链路;Forge 客户端切换包写出后若目标拒绝或超时,旧链路无法安全恢复,代理会关闭会话。`NETWORK_READY` 只表示协议握手和代理发出的世界切换已完成,不表示目标服插件或玩法世界已准备好。接口定义见 [`Players`](../proxy-plugin-api/src/main/java/dev/strataproxy/api/Players.java)、状态见 [`TransferStatus`](../proxy-plugin-api/src/main/java/dev/strataproxy/api/TransferStatus.java)。
转服先在旧后端保持服务的同时连接并登录候选后端。普通后端在 Join Game 后可进入切换;Forge 候选后端要等待客户端 Forge 握手链路切换及 Join Game,再进行世界切换。交接期间客户端与旧后端帧分别进入有上限的缓冲区;切换前失败时尽可能恢复旧链路并回放暂存帧,成功时改用候选链路并清理旧链路。候选连接失败不会立即破坏旧链路;Forge 客户端切换包写出后若目标拒绝或超时,旧链路无法安全恢复,代理会关闭会话。`NETWORK_READY` 只表示协议握手和代理发出的世界切换已完成,不表示目标服插件或玩法世界已准备好。接口定义见 [`Players`](../proxy-plugin-api/src/main/java/dev/moonbridge/api/Players.java)、状态见 [`TransferStatus`](../proxy-plugin-api/src/main/java/dev/moonbridge/api/TransferStatus.java)。
主要并发和失败界限:
@@ -61,7 +61,7 @@ flowchart LR
## 相关源码
- 插件 API:[`PluginContext`](../proxy-plugin-api/src/main/java/dev/strataproxy/api/PluginContext.java)、[`Servers`](../proxy-plugin-api/src/main/java/dev/strataproxy/api/Servers.java)、[`Players`](../proxy-plugin-api/src/main/java/dev/strataproxy/api/Players.java)
- 会话和转服:[`Session`](../proxy-core/src/main/java/dev/strataproxy/core/session/Session.java)、[`TransferCandidate`](../proxy-core/src/main/java/dev/strataproxy/core/session/TransferCandidate.java)、[`TransferFrameBuffer`](../proxy-core/src/main/java/dev/strataproxy/core/session/TransferFrameBuffer.java)
- 目录:[`BackendCatalog`](../proxy-core/src/main/java/dev/strataproxy/core/backend/BackendCatalog.java)、[`InMemoryBackendCatalog`](../proxy-core/src/main/java/dev/strataproxy/core/backend/InMemoryBackendCatalog.java)
- 后端控制通道:[`BackendControlService`](../proxy-core/src/main/java/dev/strataproxy/core/control/BackendControlService.java)
- 插件 API:[`PluginContext`](../proxy-plugin-api/src/main/java/dev/moonbridge/api/PluginContext.java)、[`Servers`](../proxy-plugin-api/src/main/java/dev/moonbridge/api/Servers.java)、[`Players`](../proxy-plugin-api/src/main/java/dev/moonbridge/api/Players.java)
- 会话和转服:[`Session`](../proxy-core/src/main/java/dev/moonbridge/core/session/Session.java)、[`TransferCandidate`](../proxy-core/src/main/java/dev/moonbridge/core/session/TransferCandidate.java)、[`TransferFrameBuffer`](../proxy-core/src/main/java/dev/moonbridge/core/session/TransferFrameBuffer.java)
- 目录:[`BackendCatalog`](../proxy-core/src/main/java/dev/moonbridge/core/backend/BackendCatalog.java)、[`InMemoryBackendCatalog`](../proxy-core/src/main/java/dev/moonbridge/core/backend/InMemoryBackendCatalog.java)
- 后端控制通道:[`BackendControlService`](../proxy-core/src/main/java/dev/moonbridge/core/control/BackendControlService.java)
+24 -4
View File
@@ -25,19 +25,39 @@ flowchart LR
## 后端插件接入
在 Bukkit/Uranium 后端安装一次 `backend-bukkit` 生成的 `strataproxy-backend-bukkit` JAR,插件名为 `StrataProxyBackend`。配置唯一的实例 ID、后端名称、代理控制地址、游戏地址与凭据。宿主异步建立连接,不在启动主线程等待网络。
在 Bukkit/Uranium 后端安装一次 `backend-bukkit` 生成的 `moonbridge-backend-bukkit` JAR,插件名为 `MoonBridgeBackend`。配置唯一的实例 ID、后端名称、代理控制地址、游戏地址与凭据。宿主异步建立连接,不在启动主线程等待网络。
消费者 `plugin.yml` 声明:
```yaml
depend: [StrataProxyBackend]
depend: [MoonBridgeBackend]
```
消费者仅将 `uk.potatolab:backend-bukkit` 作为 `compileOnly` / `provided` 依赖,不将 API、SDK 或宿主实现重新打包进自己的 JAR,确保各插件使用同一服务类。
消费者依赖独立的 `uk.potatolab:backend-bukkit-api:0.1.0-SNAPSHOT`,它传递依赖平台无关的 `messaging-api`。`backend-bukkit` 是部署到服务器的宿主实现,`backend-channel-client` 是其他平台实现宿主时使用的传输 SDK,普通业务插件不依赖它们。
Gradle 示例(Bukkit API 仍由业务插件按目标服务器版本自行声明):
```kotlin
repositories {
maven("https://git.nest.potatolab.uk:8443/api/packages/layue13/maven")
}
dependencies {
compileOnly("uk.potatolab:backend-bukkit-api:0.1.0-SNAPSHOT")
}
```
Maven 使用同一坐标并设置 `<scope>provided</scope>`。本地发行包的 `backend-api/` 也包含编译所需的两个 API JAR。不要把 API、SDK 或宿主实现重新打包进业务插件 JAR,也不要把 API JAR 单独放进服务器 `plugins/`;运行时由 `MoonBridgeBackend` 提供同一份 API 类和服务实现。
```java
import dev.moonbridge.bukkit.BukkitMessagingService;
import dev.moonbridge.messaging.Endpoint;
import dev.moonbridge.messaging.MessageChannel;
import dev.moonbridge.messaging.Messaging;
// 在业务插件的 onEnable 中取得服务;plugin.yml 声明 depend。
BukkitMessagingService service = getServer().getServicesManager()
.load(BukkitMessagingService.class);
if (service == null) throw new IllegalStateException("MoonBridgeBackend service is unavailable");
Messaging messaging = service.forPlugin(this);
MessageChannel channel = messaging.channel("islands:control");
@@ -80,7 +100,7 @@ Proxy 为每个插件管理独立的 scope,在停用时自动撤销。项目
## 配置与部署
代理在 `backendChannel.listen` 启动独立监听器。配置示例见 [strataproxy-channel.example.yml](../proxy-core/src/main/resources/config/strataproxy-channel.example.yml)。每个实例的 `secret` 至少 32 个 UTF-8 字节,`allowedHosts` 限制其广告游戏地址;`allowedNamespaces` 控制发送,`allowedReceiveNamespaces` 控制接收,未配置接收列表时继承发送列表,显式空列表表示禁止该方向的所有消息。跨后端路由同时检查源发送权限与目的接收权限。
代理在 `backendChannel.listen` 启动独立监听器。配置示例见 [moonbridge-channel.example.yml](../proxy-core/src/main/resources/config/moonbridge-channel.example.yml)。每个实例的 `secret` 至少 32 个 UTF-8 字节,`allowedHosts` 限制其广告游戏地址;`allowedNamespaces` 控制发送,`allowedReceiveNamespaces` 控制接收,未配置接收列表时继承发送列表,显式空列表表示禁止该方向的所有消息。跨后端路由同时检查源发送权限与目的接收权限。
实例的游戏地址必须是代理实际可达的 `tcp://host:port`。Docker 中使用容器服务名,容器间不要使用 `127.0.0.1`。仅将玩家端口公开,控制端口放在私有网络。不要把真实凭据写入镜像或提交到仓库。
+9 -9
View File
@@ -4,14 +4,14 @@
## 配置和启动
默认配置模板为 [`strataproxy.yml`](../proxy-core/src/main/resources/config/strataproxy.yml)。发行包将示例配置放在 `config/`;自有插件 JAR 可放在 `plugins.directory` 指向的目录。相对 `plugins.directory` 从所选配置文件所在目录解析;`plugins.enabled` 以插件实现类全名为键,空映射不启用外部插件。插件可用设置由各插件在启动时校验。
默认配置模板为 [`moonbridge.yml`](../proxy-core/src/main/resources/config/moonbridge.yml)。发行包将示例配置放在 `config/`;自有插件 JAR 可放在 `plugins.directory` 指向的目录。相对 `plugins.directory` 从所选配置文件所在目录解析;`plugins.enabled` 以插件实现类全名为键,空映射不启用外部插件。插件可用设置由各插件在启动时校验。
本地安装发行包并启动:
```powershell
.\gradlew.bat :proxy-core:installDist
.\proxy-core\build\install\strataproxy\bin\strataproxy.bat --validate-config .\proxy-core\build\install\strataproxy\config\strataproxy.yml
.\proxy-core\build\install\strataproxy\bin\strataproxy.bat --config .\proxy-core\build\install\strataproxy\config\strataproxy.yml
.\proxy-core\build\install\moonbridge\bin\moonbridge.bat --validate-config .\proxy-core\build\install\moonbridge\config\moonbridge.yml
.\proxy-core\build\install\moonbridge\bin\moonbridge.bat --config .\proxy-core\build\install\moonbridge\config\moonbridge.yml
```
`--validate-config` 校验核心 YAML、静态后端注册和服务器列表图标;它不会加载插件,所以不会验证已启用插件的设置、后端连通性或登录流程。未知核心配置键会报错。
@@ -22,7 +22,7 @@
```yaml
status:
motd: "StrataProxy"
motd: "MoonBridge"
maxPlayers: 100
# icon: "server-icon.png"
```
@@ -42,7 +42,7 @@ status:
## 可选后端发现
后端控制通道示例见 [`strataproxy-channel.example.yml`](../proxy-core/src/main/resources/config/strataproxy-channel.example.yml),使用独立监听端口接收实例注册、心跳和双向消息;使用方法与限制见[后端控制通道](backend-channel-design.md)。
后端控制通道示例见 [`moonbridge-channel.example.yml`](../proxy-core/src/main/resources/config/moonbridge-channel.example.yml),使用独立监听端口接收实例注册、心跳和双向消息;使用方法与限制见[后端控制通道](backend-channel-design.md)。
Docker 容器间的监听、服务名和地址配置见[配置与部署](backend-channel-design.md#配置与部署);`sh smoke/container-channel.sh` 可运行跨容器烟测。
@@ -62,10 +62,10 @@ Docker 容器间的监听、服务名和地址配置见[配置与部署](backend
现有测试可用于定位行为范围:
- 登录、认证和协议:`proxy-core/src/test/java/dev/strataproxy/core/auth/` 与 `proxy-core/src/test/java/dev/strataproxy/core/protocol/`
- 会话、断开、转服与缓冲:`proxy-core/src/test/java/dev/strataproxy/core/session/`,重点包括 `SessionTransferTest`、`SessionTransferDispatchTest`、`TransferFrameBufferTest`
- 插件生命周期、访问检查和 API:`proxy-core/src/test/java/dev/strataproxy/core/plugin/PluginHostTest.java`、`proxy-core/src/test/java/dev/strataproxy/core/session/ProxySessionListenerTest.java`、`proxy-core/src/test/java/dev/strataproxy/app/ProxyConfigurationTest.java` 与 `proxy-plugin-api/src/test/`
- 控制通道:`proxy-core/src/test/java/dev/strataproxy/core/control/` 与 `backend-channel-client/src/test/`
- 登录、认证和协议:`proxy-core/src/test/java/dev/moonbridge/core/auth/` 与 `proxy-core/src/test/java/dev/moonbridge/core/protocol/`
- 会话、断开、转服与缓冲:`proxy-core/src/test/java/dev/moonbridge/core/session/`,重点包括 `SessionTransferTest`、`SessionTransferDispatchTest`、`TransferFrameBufferTest`
- 插件生命周期、访问检查和 API:`proxy-core/src/test/java/dev/moonbridge/core/plugin/PluginHostTest.java`、`proxy-core/src/test/java/dev/moonbridge/core/session/ProxySessionListenerTest.java`、`proxy-core/src/test/java/dev/moonbridge/app/ProxyConfigurationTest.java` 与 `proxy-plugin-api/src/test/`
- 控制通道:`proxy-core/src/test/java/dev/moonbridge/core/control/` 与 `backend-channel-client/src/test/`
仓库另有本地 Uranium 协议探针和 Prism Forge 客户端记录,见 [`smoke/results`](../smoke/results/2026-09-25-local-uranium.md)、[转服记录](../smoke/results/2026-09-25-local-uranium-transfer.md) 和 [真实客户端记录](../smoke/results/2026-09-25-prism-forge-client.md)。这些记录支持其明确写出的单机环境、软件版本和探针路径。已知也出现过真实 Forge 客户端转服候选后端登录停滞,见[调查记录](../smoke/results/2026-09-26-uranium-login-stalls.md);已有成功样例不构成稳定性或生产验收。
+1 -1
View File
@@ -44,7 +44,7 @@ CompletionStage<DisconnectResult> disconnect(PlayerIdentity player, String reaso
```yaml
status:
motd: "StrataProxy"
motd: "MoonBridge"
maxPlayers: 100
# icon: "server-icon.png"
```
+4 -4
View File
@@ -1,12 +1,12 @@
# 插件开发
插件依赖 `proxy-plugin-api`,不依赖 `proxy-core` 或 Netty。入口实现 `dev.strataproxy.api.Plugin`,提供公开无参构造器,在 JAR 的 `META-INF/services/dev.strataproxy.api.Plugin` 中声明实现类,并由配置中的 `plugins.enabled` 显式启用。
插件依赖 `proxy-plugin-api`,不依赖 `proxy-core` 或 Netty。入口实现 `dev.moonbridge.api.Plugin`,提供公开无参构造器,在 JAR 的 `META-INF/services/dev.moonbridge.api.Plugin` 中声明实现类,并由配置中的 `plugins.enabled` 显式启用。
## 生命周期和线程
`onLoad(PluginContext)` 获得 `players()`、`servers()`、`commands()`、`events()`、SLF4J `logger()` 和不可变 `settings()`。宿主在所有插件加载后调用 `onEnable()`;插件全部启用成功后、监听器启动前冻结事件订阅。事件订阅只能在 `onLoad` 或 `onEnable` 注册,运行期间可以随时撤销。初始化失败会终止启动并回收已创建的注册。
事件通过 `PluginContext.events()` 提供的 `dev.strataproxy.api.event.Events` 订阅。所有事件都使用同一 sealed `Event<R>`、`EventListener<E, R>` 和 `Events.subscribe` 方法;监听器返回 `CompletionStage<R>`。无结果事件使用 `Event<Void>`,准入事件返回 `AccessDecision`。数据库客户端、缓存和外部任务的生命周期由插件管理;返回 `CompletionStage` 表达异步结果,避免在回调里 `join()` 等待另一个任务。各连接的准入检查可以并发,插件共享数据必须支持并发访问。
事件通过 `PluginContext.events()` 提供的 `dev.moonbridge.api.event.Events` 订阅。所有事件都使用同一 sealed `Event<R>`、`EventListener<E, R>` 和 `Events.subscribe` 方法;监听器返回 `CompletionStage<R>`。无结果事件使用 `Event<Void>`,准入事件返回 `AccessDecision`。数据库客户端、缓存和外部任务的生命周期由插件管理;返回 `CompletionStage` 表达异步结果,避免在回调里 `join()` 等待另一个任务。各连接的准入检查可以并发,插件共享数据必须支持并发访问。
关闭或插件失败时,宿主移除该插件的事件订阅、后端与命令注册。关闭时,宿主先终止未决访问请求并停止接收新回调,再逆序调用 `onDisable()`。所有关闭钩子共享 10 秒期限;插件忽略中断时仍可能继续运行,因此插件必须自行停止数据库/调度器等资源。随后关闭类加载器。当前没有插件热卸载或热加载入口。
@@ -70,7 +70,7 @@ context.commands().register("where", command -> {
## 统一类型化事件
`PluginContext.events()` 返回 `dev.strataproxy.api.event.Events`。事件统一使用泛型结果和异步监听器:
`PluginContext.events()` 返回 `dev.moonbridge.api.event.Events`。事件统一使用泛型结果和异步监听器:
```java
sealed interface Event<R> {}
@@ -133,6 +133,6 @@ context.events().subscribe(PlayerDisconnectedEvent.class, event ->
统一事件模型让准入决策和会话通知共享同一类型、监听器、订阅表与派发实现,同时保留各类事件所需的运行策略。准入阶段执行有序且失败关闭的结果聚合;生命周期通知异步 FIFO 尽力交付并与会话处理隔离。没有 PLAY 包事件。目前没有事件 API 的专门基准,不能据此宣称性能收益或无开销。
源码入口:[`PluginContext`](../proxy-plugin-api/src/main/java/dev/strataproxy/api/PluginContext.java)、[`Events`](../proxy-plugin-api/src/main/java/dev/strataproxy/api/event/Events.java)、[`AccessDecision`](../proxy-plugin-api/src/main/java/dev/strataproxy/api/AccessDecision.java)。
源码入口:[`PluginContext`](../proxy-plugin-api/src/main/java/dev/moonbridge/api/PluginContext.java)、[`Events`](../proxy-plugin-api/src/main/java/dev/moonbridge/api/event/Events.java)、[`AccessDecision`](../proxy-plugin-api/src/main/java/dev/moonbridge/api/AccessDecision.java)。
富文本构造、MiniMessage 和异步命令补全示例见[消息与命令补全](messages-and-completion.md)。
+1 -1
View File
@@ -113,7 +113,7 @@ PR 的 `.gitea/workflows/verify.yml` 独立运行 `gradlew check`,不使用 Ma
## 后端宿主真实服务端验收
`smoke/backend-uranium.ps1` 将已经接受 EULA 的 Uranium 发行包中的服务端 JAR、运行库和 EULA 复制到全新隔离目录,启动两个 Java 8 后端及实际 Java 25 Proxy。它安装 `StrataProxyBackend`、两个独立的 Bukkit 业务插件和一个外部 Proxy 验收插件,通过正式插件 API 检查注册与消息服务;不会复制或修改原有世界、模组、插件及凭据。
`smoke/backend-uranium.ps1` 将已经接受 EULA 的 Uranium 发行包中的服务端 JAR、运行库和 EULA 复制到全新隔离目录,启动两个 Java 8 后端及实际 Java 25 Proxy。它安装 `MoonBridgeBackend`、两个独立的 Bukkit 业务插件和一个外部 Proxy 验收插件,通过正式插件 API 检查注册与消息服务;不会复制或修改原有世界、模组、插件及凭据。Bukkit 业务插件只使用发行包 `backend-api/` 中的 API JAR 和服务器 Bukkit API 编译,编译路径不包含宿主及传输 SDK,并在实际插件加载器下验证服务类身份一致。
```powershell
.\gradlew.bat check :proxy-core:installDist
+1 -1
View File
@@ -33,7 +33,7 @@ publishing {
from(components["java"])
artifactId = "messaging-api"
pom {
name.set("StrataProxy Messaging API")
name.set("MoonBridge Messaging API")
description.set("Java 8-compatible shared message envelope and channel API.")
}
}
@@ -1,4 +1,4 @@
package dev.strataproxy.messaging;
package dev.moonbridge.messaging;
import java.util.Objects;
@@ -1,4 +1,4 @@
package dev.strataproxy.messaging;
package dev.moonbridge.messaging;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
@@ -1,4 +1,4 @@
package dev.strataproxy.messaging;
package dev.moonbridge.messaging;
import java.time.Duration;
import java.util.concurrent.CompletionStage;
@@ -1,4 +1,4 @@
package dev.strataproxy.messaging;
package dev.moonbridge.messaging;
import java.util.concurrent.CompletionStage;
@@ -1,4 +1,4 @@
package dev.strataproxy.messaging;
package dev.moonbridge.messaging;
/** Transport-level message semantics, independent of the application payload. */
public enum MessageKind {
@@ -1,4 +1,4 @@
package dev.strataproxy.messaging;
package dev.moonbridge.messaging;
/**
* Messaging facade owned by one plugin scope. Closing the facade removes only this owner's subscriptions and
@@ -1,4 +1,4 @@
package dev.strataproxy.messaging;
package dev.moonbridge.messaging;
/** A failure with a stable messaging-layer category. */
public class MessagingException extends RuntimeException {
@@ -1,4 +1,4 @@
package dev.strataproxy.messaging;
package dev.moonbridge.messaging;
import java.util.Collections;
import java.util.LinkedHashMap;
@@ -1,4 +1,4 @@
package dev.strataproxy.messaging;
package dev.moonbridge.messaging;
import java.util.Objects;
import java.util.UUID;
@@ -1,4 +1,4 @@
package dev.strataproxy.messaging;
package dev.moonbridge.messaging;
/**
* Delivery status reported for one event destination. These are transport/queue observations, not proof
@@ -1,4 +1,4 @@
package dev.strataproxy.messaging;
package dev.moonbridge.messaging;
/** Handle for one local listener or request handler. Closing it is idempotent and unregisters only this handle. */
public interface Subscription extends AutoCloseable {
@@ -1,16 +1,16 @@
package dev.strataproxy.messaging.internal;
package dev.moonbridge.messaging.internal;
import dev.strataproxy.messaging.Endpoint;
import dev.strataproxy.messaging.Message;
import dev.strataproxy.messaging.MessageChannel;
import dev.strataproxy.messaging.MessageHandler;
import dev.strataproxy.messaging.MessageKind;
import dev.strataproxy.messaging.Messaging;
import dev.strataproxy.messaging.MessagingException;
import dev.strataproxy.messaging.PublishResult;
import dev.strataproxy.messaging.SendReceipt;
import dev.strataproxy.messaging.SendResult;
import dev.strataproxy.messaging.Subscription;
import dev.moonbridge.messaging.Endpoint;
import dev.moonbridge.messaging.Message;
import dev.moonbridge.messaging.MessageChannel;
import dev.moonbridge.messaging.MessageHandler;
import dev.moonbridge.messaging.MessageKind;
import dev.moonbridge.messaging.Messaging;
import dev.moonbridge.messaging.MessagingException;
import dev.moonbridge.messaging.PublishResult;
import dev.moonbridge.messaging.SendReceipt;
import dev.moonbridge.messaging.SendResult;
import dev.moonbridge.messaging.Subscription;
import java.time.Duration;
import java.util.ArrayList;
@@ -375,7 +375,7 @@ public final class LocalMessaging implements AutoCloseable {
try {
completionExecutor.execute(task);
} catch (RejectedExecutionException rejected) {
Thread fallback = new Thread(task, "strataproxy-message-completion");
Thread fallback = new Thread(task, "moonbridge-message-completion");
fallback.setDaemon(true);
fallback.start();
}
@@ -1,14 +1,14 @@
package dev.strataproxy.messaging.internal;
package dev.moonbridge.messaging.internal;
import dev.strataproxy.messaging.Endpoint;
import dev.strataproxy.messaging.Message;
import dev.strataproxy.messaging.MessageKind;
import dev.strataproxy.messaging.Messaging;
import dev.strataproxy.messaging.MessagingException;
import dev.strataproxy.messaging.PublishResult;
import dev.strataproxy.messaging.SendResult;
import dev.strataproxy.messaging.SendReceipt;
import dev.strataproxy.messaging.Subscription;
import dev.moonbridge.messaging.Endpoint;
import dev.moonbridge.messaging.Message;
import dev.moonbridge.messaging.MessageKind;
import dev.moonbridge.messaging.Messaging;
import dev.moonbridge.messaging.MessagingException;
import dev.moonbridge.messaging.PublishResult;
import dev.moonbridge.messaging.SendResult;
import dev.moonbridge.messaging.SendReceipt;
import dev.moonbridge.messaging.Subscription;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
+1 -1
View File
@@ -34,7 +34,7 @@ publishing {
from(components["java"])
artifactId = "messaging-protocol"
pom {
name.set("StrataProxy Messaging Protocol")
name.set("MoonBridge Messaging Protocol")
description.set("Java 8-compatible message wire codec shared by proxy and backend clients.")
}
}
@@ -1,11 +1,11 @@
package dev.strataproxy.messaging.protocol;
package dev.moonbridge.messaging.protocol;
import dev.strataproxy.messaging.Endpoint;
import dev.strataproxy.messaging.Message;
import dev.strataproxy.messaging.MessageKind;
import dev.strataproxy.messaging.MessagingException;
import dev.strataproxy.messaging.PublishResult;
import dev.strataproxy.messaging.SendResult;
import dev.moonbridge.messaging.Endpoint;
import dev.moonbridge.messaging.Message;
import dev.moonbridge.messaging.MessageKind;
import dev.moonbridge.messaging.MessagingException;
import dev.moonbridge.messaging.PublishResult;
import dev.moonbridge.messaging.SendResult;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -1,10 +1,10 @@
package dev.strataproxy.messaging.protocol;
package dev.moonbridge.messaging.protocol;
import dev.strataproxy.messaging.Endpoint;
import dev.strataproxy.messaging.Message;
import dev.strataproxy.messaging.MessageKind;
import dev.strataproxy.messaging.PublishResult;
import dev.strataproxy.messaging.SendResult;
import dev.moonbridge.messaging.Endpoint;
import dev.moonbridge.messaging.Message;
import dev.moonbridge.messaging.MessageKind;
import dev.moonbridge.messaging.PublishResult;
import dev.moonbridge.messaging.SendResult;
import org.junit.jupiter.api.Test;
import java.io.ByteArrayOutputStream;
+4 -4
View File
@@ -5,12 +5,12 @@ plugins {
gradlePlugin {
plugins {
register("javaLibraryConventions") {
id = "strataproxy.java-library-conventions"
implementationClass = "StrataProxyJavaLibraryConventionsPlugin"
id = "moonbridge.java-library-conventions"
implementationClass = "MoonBridgeJavaLibraryConventionsPlugin"
}
register("applicationConventions") {
id = "strataproxy.application-conventions"
implementationClass = "StrataProxyApplicationConventionsPlugin"
id = "moonbridge.application-conventions"
implementationClass = "MoonBridgeApplicationConventionsPlugin"
}
}
}
@@ -2,9 +2,9 @@ import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.plugins.ApplicationPlugin
class StrataProxyApplicationConventionsPlugin : Plugin<Project> {
class MoonBridgeApplicationConventionsPlugin : Plugin<Project> {
override fun apply(project: Project) {
project.plugins.apply(StrataProxyJavaLibraryConventionsPlugin::class.java)
project.plugins.apply(MoonBridgeJavaLibraryConventionsPlugin::class.java)
project.plugins.apply(ApplicationPlugin::class.java)
}
}
@@ -8,7 +8,7 @@ import org.gradle.kotlin.dsl.dependencies
import org.gradle.kotlin.dsl.withType
import org.gradle.api.plugins.JavaPluginExtension
class StrataProxyJavaLibraryConventionsPlugin : Plugin<Project> {
class MoonBridgeJavaLibraryConventionsPlugin : Plugin<Project> {
override fun apply(project: Project) {
project.plugins.apply(JavaLibraryPlugin::class.java)
+17 -13
View File
@@ -1,7 +1,7 @@
import org.gradle.api.tasks.Exec
plugins {
id("strataproxy.application-conventions")
id("moonbridge.application-conventions")
}
val runtimeJavaHome = System.getProperty("java.home")
@@ -26,49 +26,49 @@ dependencies {
val installedDistSmokeTest = tasks.register<Exec>("installedDistSmokeTest") {
group = "verification"
description = "Runs the installed StrataProxy distribution in --validate-config mode."
description = "Runs the installed MoonBridge distribution in --validate-config mode."
dependsOn(tasks.named("installDist"))
val installDir = layout.buildDirectory.dir("install/strataproxy")
val installDir = layout.buildDirectory.dir("install/moonbridge")
inputs.dir(installDir)
environment("JAVA_HOME", runtimeJavaHome)
doFirst {
val windows = System.getProperty("os.name").lowercase().contains("windows")
val script = installDir.get().file("bin/" + if (windows) "strataproxy.bat" else "strataproxy").asFile
val config = installDir.get().file("config/strataproxy.yml").asFile
val script = installDir.get().file("bin/" + if (windows) "moonbridge.bat" else "moonbridge").asFile
val config = installDir.get().file("config/moonbridge.yml").asFile
commandLine(script.absolutePath, "--validate-config", config.absolutePath)
}
}
val installedDistHelpSmokeTest = tasks.register<Exec>("installedDistHelpSmokeTest") {
group = "verification"
description = "Runs the installed StrataProxy distribution help command."
description = "Runs the installed MoonBridge distribution help command."
dependsOn(tasks.named("installDist"))
val installDir = layout.buildDirectory.dir("install/strataproxy")
val installDir = layout.buildDirectory.dir("install/moonbridge")
inputs.dir(installDir)
environment("JAVA_HOME", runtimeJavaHome)
doFirst {
val windows = System.getProperty("os.name").lowercase().contains("windows")
val script = installDir.get().file("bin/" + if (windows) "strataproxy.bat" else "strataproxy").asFile
val script = installDir.get().file("bin/" + if (windows) "moonbridge.bat" else "moonbridge").asFile
commandLine(script.absolutePath, "--help")
}
}
val installedDistVersionSmokeTest = tasks.register<Exec>("installedDistVersionSmokeTest") {
group = "verification"
description = "Runs the installed StrataProxy distribution version command."
description = "Runs the installed MoonBridge distribution version command."
dependsOn(tasks.named("installDist"))
val installDir = layout.buildDirectory.dir("install/strataproxy")
val installDir = layout.buildDirectory.dir("install/moonbridge")
inputs.dir(installDir)
environment("JAVA_HOME", runtimeJavaHome)
doFirst {
val windows = System.getProperty("os.name").lowercase().contains("windows")
val script = installDir.get().file("bin/" + if (windows) "strataproxy.bat" else "strataproxy").asFile
val script = installDir.get().file("bin/" + if (windows) "moonbridge.bat" else "moonbridge").asFile
commandLine(script.absolutePath, "--version")
}
}
@@ -80,8 +80,8 @@ tasks.named("check") {
}
application {
mainClass.set("dev.strataproxy.app.ProxyMain")
applicationName = "strataproxy"
mainClass.set("dev.moonbridge.app.ProxyMain")
applicationName = "moonbridge"
}
distributions {
@@ -102,6 +102,10 @@ distributions {
from(project(":backend-bukkit").tasks.named("jar")) {
into("backend-host")
}
from(listOf(project(":backend-bukkit-api").tasks.named("jar"),
project(":messaging-api").tasks.named("jar"))) {
into("backend-api")
}
}
}
}
@@ -1,4 +1,4 @@
package dev.strataproxy.app;
package dev.moonbridge.app;
import io.netty.util.NetUtil;
import java.net.InetAddress;
@@ -54,7 +54,7 @@ public record ProxyConfiguration(String listen, Authentication authentication, L
/** User-facing server list values; icon validation needs the config file location and happens in the loader. */
public record Status(String motd, Integer maxPlayers, String icon) {
public Status {
motd = motd == null ? "StrataProxy" : motd;
motd = motd == null ? "MoonBridge" : motd;
if (motd.codePointCount(0, motd.length()) > 1024) {
throw new IllegalArgumentException("status.motd must contain at most 1024 Unicode code points");
}
@@ -1,9 +1,9 @@
package dev.strataproxy.app;
package dev.moonbridge.app;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import dev.strataproxy.core.protocol.ServerListStatus;
import dev.moonbridge.core.protocol.ServerListStatus;
import javax.imageio.ImageIO;
import java.io.ByteArrayInputStream;
@@ -1,10 +1,10 @@
package dev.strataproxy.app;
package dev.moonbridge.app;
import dev.strataproxy.core.backend.InMemoryBackendCatalog;
import dev.strataproxy.core.control.BackendControlService;
import dev.strataproxy.core.auth.MojangSessionVerifier;
import dev.strataproxy.core.plugin.PluginHost;
import dev.strataproxy.core.session.ProxySessionListener;
import dev.moonbridge.core.backend.InMemoryBackendCatalog;
import dev.moonbridge.core.control.BackendControlService;
import dev.moonbridge.core.auth.MojangSessionVerifier;
import dev.moonbridge.core.plugin.PluginHost;
import dev.moonbridge.core.session.ProxySessionListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -28,12 +28,12 @@ public final class ProxyMain {
static int run(String[] arguments) {
try {
if (arguments.length == 1 && arguments[0].equals("--help")) {
System.out.println("Usage: strataproxy [--config <file>] | --validate-config <file> | --version");
System.out.println("Usage: moonbridge [--config <file>] | --validate-config <file> | --version");
return 0;
}
if (arguments.length == 1 && arguments[0].equals("--version")) {
String version = ProxyMain.class.getPackage().getImplementationVersion();
System.out.println("StrataProxy " + (version == null ? "development" : version));
System.out.println("MoonBridge " + (version == null ? "development" : version));
return 0;
}
if (arguments.length == 2 && arguments[0].equals("--validate-config")) {
@@ -48,7 +48,7 @@ public final class ProxyMain {
}
Path configPath;
if (arguments.length == 0) {
configPath = Path.of("config", "strataproxy.yml");
configPath = Path.of("config", "moonbridge.yml");
} else if (arguments.length == 2 && arguments[0].equals("--config")) {
configPath = Path.of(arguments[1]);
} else {
@@ -58,7 +58,7 @@ public final class ProxyMain {
runProxy(configPath);
return 0;
} catch (Exception failure) {
LOGGER.error("StrataProxy failed", failure);
LOGGER.error("MoonBridge failed", failure);
return 1;
}
}
@@ -73,7 +73,7 @@ public final class ProxyMain {
Duration eventTimeout = Duration.ofSeconds(configuration.plugins().eventTimeoutSeconds());
ExecutorService verifierWorkers = configuration.authentication() == ProxyConfiguration.Authentication.ONLINE_BUNGEE
? Executors.newFixedThreadPool(2, task -> {
Thread thread = new Thread(task, "strataproxy-session-verify");
Thread thread = new Thread(task, "moonbridge-session-verify");
thread.setDaemon(true);
return thread;
}) : null;
@@ -109,7 +109,7 @@ public final class ProxyMain {
finally { if (verifierWorkers != null) verifierWorkers.shutdownNow(); }
}
}
}, "strataproxy-shutdown");
}, "moonbridge-shutdown");
Runtime.getRuntime().addShutdownHook(shutdown);
try {
serverChannel.closeFuture().sync();
@@ -1,9 +1,9 @@
package dev.strataproxy.app;
package dev.moonbridge.app;
import dev.strataproxy.core.backend.BackendCatalog;
import dev.strataproxy.core.backend.BackendId;
import dev.strataproxy.core.backend.BackendOwner;
import dev.strataproxy.core.backend.BackendRegistration;
import dev.moonbridge.core.backend.BackendCatalog;
import dev.moonbridge.core.backend.BackendId;
import dev.moonbridge.core.backend.BackendOwner;
import dev.moonbridge.core.backend.BackendRegistration;
import java.net.URI;
import java.util.Objects;
@@ -1,4 +1,4 @@
package dev.strataproxy.core.auth;
package dev.moonbridge.core.auth;
import java.util.Arrays;
@@ -1,4 +1,4 @@
package dev.strataproxy.core.auth;
package dev.moonbridge.core.auth;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
@@ -1,4 +1,4 @@
package dev.strataproxy.core.auth;
package dev.moonbridge.core.auth;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
@@ -1,4 +1,4 @@
package dev.strataproxy.core.auth;
package dev.moonbridge.core.auth;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
@@ -1,7 +1,7 @@
package dev.strataproxy.core.auth;
package dev.moonbridge.core.auth;
import dev.strataproxy.core.protocol.ProtocolException;
import dev.strataproxy.core.protocol.ProtocolVarInt;
import dev.moonbridge.core.protocol.ProtocolException;
import dev.moonbridge.core.protocol.ProtocolVarInt;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import java.nio.charset.StandardCharsets;
@@ -1,7 +1,7 @@
package dev.strataproxy.core.auth;
package dev.moonbridge.core.auth;
import dev.strataproxy.core.protocol.ProtocolException;
import dev.strataproxy.core.protocol.ProtocolVarInt;
import dev.moonbridge.core.protocol.ProtocolException;
import dev.moonbridge.core.protocol.ProtocolVarInt;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
@@ -1,4 +1,4 @@
package dev.strataproxy.core.auth;
package dev.moonbridge.core.auth;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -1,4 +1,4 @@
package dev.strataproxy.core.auth;
package dev.moonbridge.core.auth;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
@@ -1,4 +1,4 @@
package dev.strataproxy.core.auth;
package dev.moonbridge.core.auth;
/** A bounded property returned by the session server, with optional Mojang signature. */
public record ProfileProperty(String name, String value, String signature) {
@@ -1,4 +1,4 @@
package dev.strataproxy.core.auth;
package dev.moonbridge.core.auth;
import java.util.Optional;
import java.util.concurrent.CompletionStage;
@@ -1,4 +1,4 @@
package dev.strataproxy.core.auth;
package dev.moonbridge.core.auth;
import java.util.UUID;
import java.util.List;
@@ -1,4 +1,4 @@
package dev.strataproxy.core.backend;
package dev.moonbridge.core.backend;
import java.util.List;
import java.util.Optional;
@@ -1,4 +1,4 @@
package dev.strataproxy.core.backend;
package dev.moonbridge.core.backend;
import java.util.Objects;
@@ -1,4 +1,4 @@
package dev.strataproxy.core.backend;
package dev.moonbridge.core.backend;
import java.util.Objects;
@@ -1,4 +1,4 @@
package dev.strataproxy.core.backend;
package dev.moonbridge.core.backend;
import java.util.Objects;
@@ -1,4 +1,4 @@
package dev.strataproxy.core.backend;
package dev.moonbridge.core.backend;
import java.net.URI;
import java.util.Map;
@@ -1,4 +1,4 @@
package dev.strataproxy.core.backend;
package dev.moonbridge.core.backend;
import java.net.URI;
import java.util.Objects;
@@ -1,4 +1,4 @@
package dev.strataproxy.core.backend;
package dev.moonbridge.core.backend;
import java.util.ArrayList;
import java.util.LinkedHashMap;
@@ -1,8 +1,8 @@
package dev.strataproxy.core.control;
package dev.moonbridge.core.control;
import dev.strataproxy.messaging.Message;
import dev.strataproxy.messaging.PublishResult;
import dev.strataproxy.messaging.SendResult;
import dev.moonbridge.messaging.Message;
import dev.moonbridge.messaging.PublishResult;
import dev.moonbridge.messaging.SendResult;
import java.time.Duration;
import java.util.concurrent.CompletionStage;
@@ -1,19 +1,19 @@
package dev.strataproxy.core.control;
package dev.moonbridge.core.control;
import dev.strataproxy.app.ProxyConfiguration;
import dev.strataproxy.core.backend.BackendCatalog;
import dev.strataproxy.core.backend.BackendHandle;
import dev.strataproxy.core.backend.BackendId;
import dev.strataproxy.core.backend.BackendOwner;
import dev.strataproxy.core.backend.BackendRegistration;
import dev.strataproxy.messaging.Endpoint;
import dev.strataproxy.messaging.Message;
import dev.strataproxy.messaging.MessageKind;
import dev.strataproxy.messaging.MessagingException;
import dev.strataproxy.messaging.PublishResult;
import dev.strataproxy.messaging.SendResult;
import dev.strataproxy.messaging.internal.LocalMessaging;
import dev.strataproxy.messaging.protocol.MessageCodec;
import dev.moonbridge.app.ProxyConfiguration;
import dev.moonbridge.core.backend.BackendCatalog;
import dev.moonbridge.core.backend.BackendHandle;
import dev.moonbridge.core.backend.BackendId;
import dev.moonbridge.core.backend.BackendOwner;
import dev.moonbridge.core.backend.BackendRegistration;
import dev.moonbridge.messaging.Endpoint;
import dev.moonbridge.messaging.Message;
import dev.moonbridge.messaging.MessageKind;
import dev.moonbridge.messaging.MessagingException;
import dev.moonbridge.messaging.PublishResult;
import dev.moonbridge.messaging.SendResult;
import dev.moonbridge.messaging.internal.LocalMessaging;
import dev.moonbridge.messaging.protocol.MessageCodec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -78,13 +78,13 @@ public final class BackendControlService implements BackendChannelTransport, Aut
private final Map<String, Lease> byBackend = new HashMap<>();
private final Semaphore connectionSlots;
private final ScheduledExecutorService timer = Executors.newSingleThreadScheduledExecutor(
Thread.ofVirtual().name("strataproxy-control-timer", 0).factory());
Thread.ofVirtual().name("moonbridge-control-timer", 0).factory());
private final SecureRandom random = new SecureRandom();
private final AtomicLong nextEpoch = new AtomicLong();
private final AtomicLong globalQueuedBytes = new AtomicLong();
private final Semaphore writeTasks = new Semaphore(MAX_WRITE_TASKS);
private final ThreadPoolExecutor routingWorkers = new ThreadPoolExecutor(2, 2, 0L, TimeUnit.MILLISECONDS,
new ArrayBlockingQueue<>(512), namedFactory("strataproxy-control-routing"),
new ArrayBlockingQueue<>(512), namedFactory("moonbridge-control-routing"),
new ThreadPoolExecutor.AbortPolicy());
private volatile boolean closed;
private ServerSocket listener;
@@ -104,7 +104,7 @@ public final class BackendControlService implements BackendChannelTransport, Aut
server.bind(configuration.listenAddress(), 32);
listener = server;
timer.scheduleAtFixedRate(this::expireLeases, 1, 1, TimeUnit.SECONDS);
Thread.ofVirtual().name("strataproxy-control-accept").start(this::acceptLoop);
Thread.ofVirtual().name("moonbridge-control-accept").start(this::acceptLoop);
LOGGER.info("Backend control listening on {}", server.getLocalSocketAddress());
} catch (RuntimeException | IOException failure) {
server.close();
@@ -125,7 +125,7 @@ public final class BackendControlService implements BackendChannelTransport, Aut
socket.close();
continue;
}
Thread.ofVirtual().name("strataproxy-control-peer").start(() -> {
Thread.ofVirtual().name("moonbridge-control-peer").start(() -> {
try { serve(socket); }
finally { connectionSlots.release(); }
});
@@ -562,7 +562,7 @@ public final class BackendControlService implements BackendChannelTransport, Aut
operationTimeout.cancel(false);
connection.requestSlots.release();
});
Thread.ofVirtual().name("strataproxy-control-write").start(() -> {
Thread.ofVirtual().name("moonbridge-control-write").start(() -> {
try {
boolean written = connection.writeFrame(() -> {
long remainingNanos = deadline - System.nanoTime();
@@ -635,7 +635,7 @@ public final class BackendControlService implements BackendChannelTransport, Aut
AtomicBoolean writeStarted = new AtomicBoolean();
java.util.concurrent.atomic.AtomicReference<ScheduledFuture<?>> flushTimeout =
new java.util.concurrent.atomic.AtomicReference<>();
Thread.ofVirtual().name("strataproxy-control-write").start(() -> {
Thread.ofVirtual().name("moonbridge-control-write").start(() -> {
try {
connection.writeFrame(() -> {
if (deadline - System.nanoTime() <= 0) return null;
@@ -1,6 +1,6 @@
package dev.strataproxy.core.event;
package dev.moonbridge.core.event;
import dev.strataproxy.api.event.Event;
import dev.moonbridge.api.event.Event;
import java.util.concurrent.CompletionStage;
@@ -1,13 +1,13 @@
package dev.strataproxy.core.forwarding;
package dev.moonbridge.core.forwarding;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import dev.strataproxy.core.auth.ProfileProperty;
import dev.strataproxy.core.auth.VerifiedProfile;
import dev.strataproxy.core.protocol.MinecraftHandshake;
import dev.strataproxy.core.protocol.ProtocolProfile;
import dev.moonbridge.core.auth.ProfileProperty;
import dev.moonbridge.core.auth.VerifiedProfile;
import dev.moonbridge.core.protocol.MinecraftHandshake;
import dev.moonbridge.core.protocol.ProtocolProfile;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
@@ -1,6 +1,6 @@
package dev.strataproxy.core.plugin;
package dev.moonbridge.core.plugin;
import dev.strataproxy.api.event.Event;
import dev.moonbridge.api.event.Event;
import java.time.Duration;
import java.util.ArrayDeque;
@@ -28,7 +28,7 @@ import java.util.function.Supplier;
/** Runs typed listener chains with bounded work and no plugin callbacks on the publisher thread. */
final class AsyncEventDispatcher implements AutoCloseable {
private static final ThreadFactory CANCELLATIONS = Thread.ofVirtual()
.name("strataproxy-plugin-event-cancel-", 0).factory();
.name("moonbridge-plugin-event-cancel-", 0).factory();
private final Duration timeout;
private final ThreadPoolExecutor workers;
private final ScheduledExecutorService timer;
@@ -1,4 +1,4 @@
package dev.strataproxy.core.plugin;
package dev.moonbridge.core.plugin;
import java.time.Duration;
@@ -1,50 +1,50 @@
package dev.strataproxy.core.plugin;
package dev.moonbridge.core.plugin;
import dev.strataproxy.api.AccessDecision;
import dev.strataproxy.api.MessageResult;
import dev.strataproxy.api.DisconnectResult;
import dev.strataproxy.api.event.ConnectionAdmissionEvent;
import dev.strataproxy.api.event.Event;
import dev.strataproxy.api.event.EventListener;
import dev.strataproxy.api.event.EventSubscription;
import dev.strataproxy.api.event.Events;
import dev.strataproxy.api.event.PlayerAdmissionEvent;
import dev.strataproxy.api.event.PlayerDisconnectedEvent;
import dev.strataproxy.api.event.ServerConnectedEvent;
import dev.strataproxy.messaging.Endpoint;
import dev.strataproxy.messaging.Message;
import dev.strataproxy.messaging.MessageKind;
import dev.strataproxy.messaging.Messaging;
import dev.strataproxy.messaging.MessagingException;
import dev.strataproxy.messaging.PublishResult;
import dev.strataproxy.messaging.SendResult;
import dev.strataproxy.messaging.internal.LocalMessaging;
import dev.strataproxy.api.InitialPlacementHandler;
import dev.strataproxy.api.CommandHandler;
import dev.strataproxy.api.CommandCompleter;
import dev.strataproxy.api.CommandCompletion;
import dev.strataproxy.api.CommandInvocation;
import dev.strataproxy.api.CommandRegistration;
import dev.strataproxy.api.Commands;
import dev.strataproxy.api.PlacementDecision;
import dev.strataproxy.api.PlayerIdentity;
import dev.strataproxy.api.PlayerView;
import dev.strataproxy.api.Players;
import dev.strataproxy.api.Plugin;
import dev.strataproxy.api.PluginContext;
import dev.strataproxy.api.ServerDefinition;
import dev.strataproxy.api.ServerRegistration;
import dev.strataproxy.api.ServerView;
import dev.strataproxy.api.Servers;
import dev.strataproxy.api.TransferResult;
import dev.moonbridge.api.AccessDecision;
import dev.moonbridge.api.MessageResult;
import dev.moonbridge.api.DisconnectResult;
import dev.moonbridge.api.event.ConnectionAdmissionEvent;
import dev.moonbridge.api.event.Event;
import dev.moonbridge.api.event.EventListener;
import dev.moonbridge.api.event.EventSubscription;
import dev.moonbridge.api.event.Events;
import dev.moonbridge.api.event.PlayerAdmissionEvent;
import dev.moonbridge.api.event.PlayerDisconnectedEvent;
import dev.moonbridge.api.event.ServerConnectedEvent;
import dev.moonbridge.messaging.Endpoint;
import dev.moonbridge.messaging.Message;
import dev.moonbridge.messaging.MessageKind;
import dev.moonbridge.messaging.Messaging;
import dev.moonbridge.messaging.MessagingException;
import dev.moonbridge.messaging.PublishResult;
import dev.moonbridge.messaging.SendResult;
import dev.moonbridge.messaging.internal.LocalMessaging;
import dev.moonbridge.api.InitialPlacementHandler;
import dev.moonbridge.api.CommandHandler;
import dev.moonbridge.api.CommandCompleter;
import dev.moonbridge.api.CommandCompletion;
import dev.moonbridge.api.CommandInvocation;
import dev.moonbridge.api.CommandRegistration;
import dev.moonbridge.api.Commands;
import dev.moonbridge.api.PlacementDecision;
import dev.moonbridge.api.PlayerIdentity;
import dev.moonbridge.api.PlayerView;
import dev.moonbridge.api.Players;
import dev.moonbridge.api.Plugin;
import dev.moonbridge.api.PluginContext;
import dev.moonbridge.api.ServerDefinition;
import dev.moonbridge.api.ServerRegistration;
import dev.moonbridge.api.ServerView;
import dev.moonbridge.api.Servers;
import dev.moonbridge.api.TransferResult;
import net.kyori.adventure.text.Component;
import dev.strataproxy.core.backend.BackendCatalog;
import dev.strataproxy.core.backend.BackendId;
import dev.strataproxy.core.backend.BackendOwner;
import dev.strataproxy.core.backend.BackendRegistration;
import dev.strataproxy.core.backend.BackendView;
import dev.strataproxy.core.control.BackendChannelTransport;
import dev.strataproxy.core.event.EventDispatcher;
import dev.moonbridge.core.backend.BackendCatalog;
import dev.moonbridge.core.backend.BackendId;
import dev.moonbridge.core.backend.BackendOwner;
import dev.moonbridge.core.backend.BackendRegistration;
import dev.moonbridge.core.backend.BackendView;
import dev.moonbridge.core.control.BackendChannelTransport;
import dev.moonbridge.core.event.EventDispatcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -100,7 +100,7 @@ public final class PluginHost implements AutoCloseable, EventDispatcher {
private static final int MAX_COMPLETION_CANDIDATES_SCANNED = 4096;
private static final Duration COMMAND_COMPLETION_TIMEOUT = Duration.ofSeconds(1);
private static final ThreadFactory PLAYER_COMPLETION_THREADS = Thread.ofVirtual()
.name("strataproxy-plugin-player-", 0).factory();
.name("moonbridge-plugin-player-", 0).factory();
private static final Executor PLAYER_COMPLETIONS = task -> PLAYER_COMPLETION_THREADS.newThread(task).start();
private final BackendCatalog catalog;
private final Players players;
@@ -176,15 +176,15 @@ public final class PluginHost implements AutoCloseable, EventDispatcher {
throw new IllegalArgumentException("callback executor sizes must be positive");
}
this.callbacks = new ThreadPoolExecutor(callbackThreads, callbackThreads, 0, TimeUnit.MILLISECONDS,
new ArrayBlockingQueue<>(callbackQueueCapacity), namedThreads("strataproxy-plugin-callback"),
new ArrayBlockingQueue<>(callbackQueueCapacity), namedThreads("moonbridge-plugin-callback"),
new ThreadPoolExecutor.AbortPolicy());
this.commandWorkers = new ThreadPoolExecutor(callbackThreads, callbackThreads, 0, TimeUnit.MILLISECONDS,
new ArrayBlockingQueue<>(callbackQueueCapacity), namedThreads("strataproxy-plugin-command"),
new ArrayBlockingQueue<>(callbackQueueCapacity), namedThreads("moonbridge-plugin-command"),
new ThreadPoolExecutor.AbortPolicy());
this.backendWorkers = new ThreadPoolExecutor(2, 2, 0, TimeUnit.MILLISECONDS,
new ArrayBlockingQueue<>(128), namedThreads("strataproxy-plugin-backend"),
new ArrayBlockingQueue<>(128), namedThreads("moonbridge-plugin-backend"),
new ThreadPoolExecutor.AbortPolicy());
this.timer = new ScheduledThreadPoolExecutor(1, namedThreads("strataproxy-plugin-timeout"));
this.timer = new ScheduledThreadPoolExecutor(1, namedThreads("moonbridge-plugin-timeout"));
this.timer.setRemoveOnCancelPolicy(true);
this.admissionPolicy = new AsyncEventDispatcher.EventPolicy<>(AccessDecision::allow,
decision -> decision instanceof AccessDecision.Allowed || decision instanceof AccessDecision.Denied,
@@ -194,9 +194,9 @@ public final class PluginHost implements AutoCloseable, EventDispatcher {
ignored -> false, true, (event, failure) -> LOGGER.warn("Plugin event listener failed for {}",
event.getClass().getName(), failure), 129, true);
this.admissionEvents = new AsyncEventDispatcher(eventTimeout, accessThreads, accessQueueCapacity,
timer, namedThreads("strataproxy-plugin-admission"));
timer, namedThreads("moonbridge-plugin-admission"));
this.notificationEvents = new AsyncEventDispatcher(eventTimeout, 1, 128,
timer, namedThreads("strataproxy-plugin-notification"));
timer, namedThreads("moonbridge-plugin-notification"));
this.localMessaging = new LocalMessaging(Endpoint.proxy(), new HostMessagingOutbound(), backendWorkers, timer);
}
@@ -709,7 +709,7 @@ public final class PluginHost implements AutoCloseable, EventDispatcher {
loaded.plugin.onDisable();
return null;
});
Thread.ofVirtual().name("strataproxy-plugin-disable-" + loaded.owner.id()).start(stop);
Thread.ofVirtual().name("moonbridge-plugin-disable-" + loaded.owner.id()).start(stop);
try {
stop.get(remaining, TimeUnit.NANOSECONDS);
} catch (TimeoutException timeout) {
@@ -1166,10 +1166,10 @@ public final class PluginHost implements AutoCloseable, EventDispatcher {
}
private final class PluginServerRegistration implements ServerRegistration {
private final dev.strataproxy.core.backend.BackendHandle handle;
private final dev.moonbridge.core.backend.BackendHandle handle;
private boolean active = true;
private PluginServerRegistration(dev.strataproxy.core.backend.BackendHandle handle) {
private PluginServerRegistration(dev.moonbridge.core.backend.BackendHandle handle) {
this.handle = handle;
}
@@ -1,4 +1,4 @@
package dev.strataproxy.core.plugin;
package dev.moonbridge.core.plugin;
/** Indicates a plugin failed while receiving its initial context. */
public final class PluginLoadException extends RuntimeException {
@@ -1,4 +1,4 @@
package dev.strataproxy.core.plugin;
package dev.moonbridge.core.plugin;
/** Indicates the bounded plugin callback executor is full. */
public final class PluginOverloadedException extends RuntimeException {
@@ -1,4 +1,4 @@
package dev.strataproxy.core.protocol;
package dev.moonbridge.core.protocol;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
@@ -1,4 +1,4 @@
package dev.strataproxy.core.protocol;
package dev.moonbridge.core.protocol;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
@@ -1,4 +1,4 @@
package dev.strataproxy.core.protocol;
package dev.moonbridge.core.protocol;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
@@ -1,4 +1,4 @@
package dev.strataproxy.core.protocol;
package dev.moonbridge.core.protocol;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
@@ -1,4 +1,4 @@
package dev.strataproxy.core.protocol;
package dev.moonbridge.core.protocol;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
@@ -1,4 +1,4 @@
package dev.strataproxy.core.protocol;
package dev.moonbridge.core.protocol;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
@@ -1,4 +1,4 @@
package dev.strataproxy.core.protocol;
package dev.moonbridge.core.protocol;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
@@ -1,4 +1,4 @@
package dev.strataproxy.core.protocol;
package dev.moonbridge.core.protocol;
import io.netty.buffer.ByteBuf;
@@ -1,4 +1,4 @@
package dev.strataproxy.core.protocol;
package dev.moonbridge.core.protocol;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
@@ -1,4 +1,4 @@
package dev.strataproxy.core.protocol;
package dev.moonbridge.core.protocol;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.ComponentLike;
@@ -1,4 +1,4 @@
package dev.strataproxy.core.protocol;
package dev.moonbridge.core.protocol;
/** Invalid or truncated Minecraft protocol data. */
public final class ProtocolException extends RuntimeException {
@@ -1,4 +1,4 @@
package dev.strataproxy.core.protocol;
package dev.moonbridge.core.protocol;
/** Wire limits and packet rules for one explicitly supported Minecraft protocol. */
public record ProtocolProfile(
@@ -1,4 +1,4 @@
package dev.strataproxy.core.protocol;
package dev.moonbridge.core.protocol;
import io.netty.buffer.ByteBuf;
import java.nio.charset.StandardCharsets;
@@ -1,4 +1,4 @@
package dev.strataproxy.core.protocol;
package dev.moonbridge.core.protocol;
import io.netty.buffer.ByteBuf;
@@ -1,4 +1,4 @@
package dev.strataproxy.core.protocol;
package dev.moonbridge.core.protocol;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
@@ -55,7 +55,7 @@ public final class ServerListStatus {
}
public static ServerListStatus defaultStatus() {
return new ServerListStatus("StrataProxy", 100, null);
return new ServerListStatus("MoonBridge", 100, null);
}
public String motd() { return motd; }
@@ -1,6 +1,6 @@
package dev.strataproxy.core.relay;
package dev.moonbridge.core.relay;
import dev.strataproxy.core.protocol.ProtocolProfile;
import dev.moonbridge.core.protocol.ProtocolProfile;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFutureListener;
@@ -1,8 +1,8 @@
package dev.strataproxy.core.session;
package dev.moonbridge.core.session;
import dev.strataproxy.api.AccessDecision;
import dev.strataproxy.api.event.ConnectionAdmissionEvent;
import dev.strataproxy.core.event.EventDispatcher;
import dev.moonbridge.api.AccessDecision;
import dev.moonbridge.api.event.ConnectionAdmissionEvent;
import dev.moonbridge.core.event.EventDispatcher;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
@@ -1,6 +1,6 @@
package dev.strataproxy.core.session;
package dev.moonbridge.core.session;
import dev.strataproxy.core.relay.RawRelay;
import dev.moonbridge.core.relay.RawRelay;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.channel.ChannelHandlerContext;
@@ -1,8 +1,8 @@
package dev.strataproxy.core.session;
package dev.moonbridge.core.session;
import dev.strataproxy.core.protocol.Minecraft1710PlayPackets;
import dev.strataproxy.core.protocol.ProtocolProfile;
import dev.strataproxy.core.protocol.ProtocolVarInt;
import dev.moonbridge.core.protocol.Minecraft1710PlayPackets;
import dev.moonbridge.core.protocol.ProtocolProfile;
import dev.moonbridge.core.protocol.ProtocolVarInt;
import io.netty.buffer.ByteBuf;
import java.util.OptionalInt;
@@ -1,7 +1,7 @@
package dev.strataproxy.core.session;
package dev.moonbridge.core.session;
import dev.strataproxy.core.protocol.Minecraft1710PlayPackets;
import dev.strataproxy.core.relay.RawRelay;
import dev.moonbridge.core.protocol.Minecraft1710PlayPackets;
import dev.moonbridge.core.relay.RawRelay;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
Loaded 100 of 193 files, more files were not shown because too many files have changed in this diff. Show more