Mirror von
https://github.com/GeyserMC/Geyser.git
synchronisiert 2024-11-19 14:30:17 +01:00
Merge branch 'master' of https://github.com/GeyserMC/Geyser into feature/configurate
Dieser Commit ist enthalten in:
Commit
a2e9e702b3
@ -0,0 +1,3 @@
|
|||||||
|
plugins {
|
||||||
|
id("geyser.base-conventions")
|
||||||
|
}
|
@ -1,3 +1,8 @@
|
|||||||
|
plugins {
|
||||||
|
id("geyser.platform-conventions")
|
||||||
|
id("geyser.modrinth-uploading-conventions")
|
||||||
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
api(projects.core)
|
api(projects.core)
|
||||||
|
|
||||||
|
@ -110,6 +110,21 @@ public class GeyserBungeePlugin extends Plugin implements GeyserPluginBootstrap
|
|||||||
if (geyser == null) {
|
if (geyser == null) {
|
||||||
return; // Config did not load properly!
|
return; // Config did not load properly!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// After Geyser initialize for parity with other platforms.
|
||||||
|
var sourceConverter = new CommandSourceConverter<>(
|
||||||
|
CommandSender.class,
|
||||||
|
id -> getProxy().getPlayer(id),
|
||||||
|
() -> getProxy().getConsole(),
|
||||||
|
BungeeCommandSource::new
|
||||||
|
);
|
||||||
|
CommandManager<GeyserCommandSource> cloud = new BungeeCommandManager<>(
|
||||||
|
this,
|
||||||
|
ExecutionCoordinator.simpleCoordinator(),
|
||||||
|
sourceConverter
|
||||||
|
);
|
||||||
|
this.commandRegistry = new CommandRegistry(geyser, cloud, false); // applying root permission would be a breaking change because we can't register permission defaults
|
||||||
|
|
||||||
// Big hack - Bungee does not provide us an event to listen to, so schedule a repeating
|
// Big hack - Bungee does not provide us an event to listen to, so schedule a repeating
|
||||||
// task that waits for a field to be filled which is set after the plugin enable
|
// task that waits for a field to be filled which is set after the plugin enable
|
||||||
// process is complete
|
// process is complete
|
||||||
@ -148,19 +163,6 @@ public class GeyserBungeePlugin extends Plugin implements GeyserPluginBootstrap
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.geyserLogger.setDebug(geyserConfig.debugMode());
|
this.geyserLogger.setDebug(geyserConfig.debugMode());
|
||||||
} else {
|
|
||||||
var sourceConverter = new CommandSourceConverter<>(
|
|
||||||
CommandSender.class,
|
|
||||||
id -> getProxy().getPlayer(id),
|
|
||||||
() -> getProxy().getConsole(),
|
|
||||||
BungeeCommandSource::new
|
|
||||||
);
|
|
||||||
CommandManager<GeyserCommandSource> cloud = new BungeeCommandManager<>(
|
|
||||||
this,
|
|
||||||
ExecutionCoordinator.simpleCoordinator(),
|
|
||||||
sourceConverter
|
|
||||||
);
|
|
||||||
this.commandRegistry = new CommandRegistry(geyser, cloud, false); // applying root permission would be a breaking change because we can't register permission defaults
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Force-disable query if enabled, or else Geyser won't enable
|
// Force-disable query if enabled, or else Geyser won't enable
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
plugins {
|
||||||
|
id("geyser.modded-conventions")
|
||||||
|
}
|
||||||
|
|
||||||
architectury {
|
architectury {
|
||||||
common("neoforge", "fabric")
|
common("neoforge", "fabric")
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
plugins {
|
||||||
|
id("geyser.modded-conventions")
|
||||||
|
id("geyser.modrinth-uploading-conventions")
|
||||||
|
}
|
||||||
|
|
||||||
architectury {
|
architectury {
|
||||||
platformSetupLoomIde()
|
platformSetupLoomIde()
|
||||||
fabric()
|
fabric()
|
||||||
|
@ -1,13 +1,18 @@
|
|||||||
// This is provided by "org.cloudburstmc.math.mutable" too, so yeet.
|
plugins {
|
||||||
// NeoForge's class loader is *really* annoying.
|
id("geyser.modded-conventions")
|
||||||
provided("org.cloudburstmc.math", "api")
|
id("geyser.modrinth-uploading-conventions")
|
||||||
provided("com.google.errorprone", "error_prone_annotations")
|
}
|
||||||
|
|
||||||
architectury {
|
architectury {
|
||||||
platformSetupLoomIde()
|
platformSetupLoomIde()
|
||||||
neoForge()
|
neoForge()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is provided by "org.cloudburstmc.math.mutable" too, so yeet.
|
||||||
|
// NeoForge's class loader is *really* annoying.
|
||||||
|
provided("org.cloudburstmc.math", "api")
|
||||||
|
provided("com.google.errorprone", "error_prone_annotations")
|
||||||
|
|
||||||
val includeTransitive: Configuration = configurations.getByName("includeTransitive")
|
val includeTransitive: Configuration = configurations.getByName("includeTransitive")
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
@ -82,6 +82,7 @@ public class GeyserNeoForgeBootstrap extends GeyserModBootstrap {
|
|||||||
);
|
);
|
||||||
GeyserNeoForgeCommandRegistry registry = new GeyserNeoForgeCommandRegistry(getGeyser(), cloud);
|
GeyserNeoForgeCommandRegistry registry = new GeyserNeoForgeCommandRegistry(getGeyser(), cloud);
|
||||||
this.setCommandRegistry(registry);
|
this.setCommandRegistry(registry);
|
||||||
|
// An auxiliary listener for registering undefined permissions belonging to commands. See javadocs for more info.
|
||||||
NeoForge.EVENT_BUS.addListener(EventPriority.LOWEST, registry::onPermissionGatherForUndefined);
|
NeoForge.EVENT_BUS.addListener(EventPriority.LOWEST, registry::onPermissionGatherForUndefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
plugins {
|
||||||
|
id("geyser.platform-conventions")
|
||||||
|
id("geyser.modrinth-uploading-conventions")
|
||||||
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
api(projects.core)
|
api(projects.core)
|
||||||
api(libs.erosion.bukkit.common) {
|
api(libs.erosion.bukkit.common) {
|
||||||
|
@ -181,7 +181,7 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserPluginBootst
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create command manager early so we can add Geyser extension commands
|
// Register commands after Geyser initialization, but before the server starts.
|
||||||
var sourceConverter = new CommandSourceConverter<>(
|
var sourceConverter = new CommandSourceConverter<>(
|
||||||
CommandSender.class,
|
CommandSender.class,
|
||||||
Bukkit::getPlayer,
|
Bukkit::getPlayer,
|
||||||
|
@ -2,6 +2,7 @@ import com.github.jengelman.gradle.plugins.shadow.transformers.Log4j2PluginsCach
|
|||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
application
|
application
|
||||||
|
id("geyser.platform-conventions")
|
||||||
}
|
}
|
||||||
|
|
||||||
val terminalConsoleVersion = "1.2.0"
|
val terminalConsoleVersion = "1.2.0"
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
plugins {
|
||||||
|
id("geyser.platform-conventions")
|
||||||
|
id("geyser.modrinth-uploading-conventions")
|
||||||
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
annotationProcessor(libs.velocity.api)
|
annotationProcessor(libs.velocity.api)
|
||||||
api(projects.core)
|
api(projects.core)
|
||||||
|
@ -111,6 +111,22 @@ public class GeyserVelocityPlugin implements GeyserPluginBootstrap {
|
|||||||
|
|
||||||
this.geyser = GeyserImpl.load(PlatformType.VELOCITY, this);
|
this.geyser = GeyserImpl.load(PlatformType.VELOCITY, this);
|
||||||
this.geyserInjector = new GeyserVelocityInjector(proxyServer);
|
this.geyserInjector = new GeyserVelocityInjector(proxyServer);
|
||||||
|
|
||||||
|
// We need to register commands here, rather than in onGeyserEnable which is invoked during the appropriate ListenerBoundEvent.
|
||||||
|
// Reason: players can connect after a listener is bound, and a player join locks registration to the cloud CommandManager.
|
||||||
|
var sourceConverter = new CommandSourceConverter<>(
|
||||||
|
CommandSource.class,
|
||||||
|
id -> proxyServer.getPlayer(id).orElse(null),
|
||||||
|
proxyServer::getConsoleCommandSource,
|
||||||
|
VelocityCommandSource::new
|
||||||
|
);
|
||||||
|
CommandManager<GeyserCommandSource> cloud = new VelocityCommandManager<>(
|
||||||
|
container,
|
||||||
|
proxyServer,
|
||||||
|
ExecutionCoordinator.simpleCoordinator(),
|
||||||
|
sourceConverter
|
||||||
|
);
|
||||||
|
this.commandRegistry = new CommandRegistry(geyser, cloud, false); // applying root permission would be a breaking change because we can't register permission defaults
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -124,20 +140,6 @@ public class GeyserVelocityPlugin implements GeyserPluginBootstrap {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.geyserLogger.setDebug(geyserConfig.debugMode());
|
this.geyserLogger.setDebug(geyserConfig.debugMode());
|
||||||
} else {
|
|
||||||
var sourceConverter = new CommandSourceConverter<>(
|
|
||||||
CommandSource.class,
|
|
||||||
id -> proxyServer.getPlayer(id).orElse(null),
|
|
||||||
proxyServer::getConsoleCommandSource,
|
|
||||||
VelocityCommandSource::new
|
|
||||||
);
|
|
||||||
CommandManager<GeyserCommandSource> cloud = new VelocityCommandManager<>(
|
|
||||||
container,
|
|
||||||
proxyServer,
|
|
||||||
ExecutionCoordinator.simpleCoordinator(),
|
|
||||||
sourceConverter
|
|
||||||
);
|
|
||||||
this.commandRegistry = new CommandRegistry(geyser, cloud, false); // applying root permission would be a breaking change because we can't register permission defaults
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GeyserImpl.start();
|
GeyserImpl.start();
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
plugins {
|
||||||
|
id("geyser.platform-conventions")
|
||||||
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
api(projects.core)
|
api(projects.core)
|
||||||
|
|
||||||
|
@ -12,9 +12,14 @@ repositories {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
// This is for the LibsAccessor.kt hack
|
||||||
// this is OK as long as the same version catalog is used in the main build and build-logic
|
// this is OK as long as the same version catalog is used in the main build and build-logic
|
||||||
// see https://github.com/gradle/gradle/issues/15383#issuecomment-779893192
|
// see https://github.com/gradle/gradle/issues/15383#issuecomment-779893192
|
||||||
implementation(files(libs.javaClass.superclass.protectionDomain.codeSource.location))
|
implementation(files(libs.javaClass.superclass.protectionDomain.codeSource.location))
|
||||||
|
|
||||||
|
// This is for applying plugins, and using the version from the libs.versions.toml
|
||||||
|
// Unfortunately they still need to be applied by their string name in the convention scripts.
|
||||||
|
implementation(libs.lombok)
|
||||||
implementation(libs.indra)
|
implementation(libs.indra)
|
||||||
implementation(libs.shadow)
|
implementation(libs.shadow)
|
||||||
implementation(libs.architectury.plugin)
|
implementation(libs.architectury.plugin)
|
||||||
|
@ -8,4 +8,4 @@ dependencyResolutionManagement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rootProject.name = "build-logic"
|
rootProject.name = "build-logic"
|
||||||
|
@ -3,9 +3,10 @@ plugins {
|
|||||||
id("net.kyori.indra")
|
id("net.kyori.indra")
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
val rootProperties: Map<String, *> = project.rootProject.properties
|
||||||
compileOnly("org.checkerframework", "checker-qual", "3.19.0")
|
group = rootProperties["group"] as String + "." + rootProperties["id"] as String
|
||||||
}
|
version = rootProperties["version"] as String
|
||||||
|
description = rootProperties["description"] as String
|
||||||
|
|
||||||
indra {
|
indra {
|
||||||
github("GeyserMC", "Geyser") {
|
github("GeyserMC", "Geyser") {
|
||||||
@ -20,18 +21,52 @@ indra {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks {
|
dependencies {
|
||||||
processResources {
|
compileOnly("org.checkerframework", "checker-qual", libs.checker.qual.get().version)
|
||||||
// Spigot, BungeeCord, Velocity, Fabric, ViaProxy, NeoForge
|
}
|
||||||
filesMatching(listOf("plugin.yml", "bungee.yml", "velocity-plugin.json", "fabric.mod.json", "viaproxy.yml", "META-INF/neoforge.mods.toml")) {
|
|
||||||
expand(
|
repositories {
|
||||||
"id" to "geyser",
|
// mavenLocal()
|
||||||
"name" to "Geyser",
|
|
||||||
"version" to project.version,
|
mavenCentral()
|
||||||
"description" to project.description,
|
|
||||||
"url" to "https://geysermc.org",
|
// Floodgate, Cumulus etc.
|
||||||
"author" to "GeyserMC"
|
maven("https://repo.opencollab.dev/main")
|
||||||
)
|
|
||||||
}
|
// Paper, Velocity
|
||||||
|
maven("https://repo.papermc.io/repository/maven-public")
|
||||||
|
|
||||||
|
// Spigot
|
||||||
|
maven("https://hub.spigotmc.org/nexus/content/repositories/snapshots") {
|
||||||
|
mavenContent { snapshotsOnly() }
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
// BungeeCord
|
||||||
|
maven("https://oss.sonatype.org/content/repositories/snapshots") {
|
||||||
|
mavenContent { snapshotsOnly() }
|
||||||
|
}
|
||||||
|
|
||||||
|
// NeoForge
|
||||||
|
maven("https://maven.neoforged.net/releases") {
|
||||||
|
mavenContent { releasesOnly() }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Minecraft
|
||||||
|
maven("https://libraries.minecraft.net") {
|
||||||
|
name = "minecraft"
|
||||||
|
mavenContent { releasesOnly() }
|
||||||
|
}
|
||||||
|
|
||||||
|
// ViaVersion
|
||||||
|
maven("https://repo.viaversion.com") {
|
||||||
|
name = "viaversion"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Jitpack for e.g. MCPL
|
||||||
|
maven("https://jitpack.io") {
|
||||||
|
content { includeGroupByRegex("com\\.github\\..*") }
|
||||||
|
}
|
||||||
|
|
||||||
|
// For Adventure snapshots
|
||||||
|
maven("https://s01.oss.sonatype.org/content/repositories/snapshots/")
|
||||||
|
}
|
||||||
|
@ -1,45 +0,0 @@
|
|||||||
repositories {
|
|
||||||
// mavenLocal()
|
|
||||||
|
|
||||||
mavenCentral()
|
|
||||||
|
|
||||||
// Floodgate, Cumulus etc.
|
|
||||||
maven("https://repo.opencollab.dev/main")
|
|
||||||
|
|
||||||
// Paper, Velocity
|
|
||||||
maven("https://repo.papermc.io/repository/maven-public")
|
|
||||||
|
|
||||||
// Spigot
|
|
||||||
maven("https://hub.spigotmc.org/nexus/content/repositories/snapshots") {
|
|
||||||
mavenContent { snapshotsOnly() }
|
|
||||||
}
|
|
||||||
|
|
||||||
// BungeeCord
|
|
||||||
maven("https://oss.sonatype.org/content/repositories/snapshots") {
|
|
||||||
mavenContent { snapshotsOnly() }
|
|
||||||
}
|
|
||||||
|
|
||||||
// NeoForge
|
|
||||||
maven("https://maven.neoforged.net/releases") {
|
|
||||||
mavenContent { releasesOnly() }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Minecraft
|
|
||||||
maven("https://libraries.minecraft.net") {
|
|
||||||
name = "minecraft"
|
|
||||||
mavenContent { releasesOnly() }
|
|
||||||
}
|
|
||||||
|
|
||||||
// ViaVersion
|
|
||||||
maven("https://repo.viaversion.com") {
|
|
||||||
name = "viaversion"
|
|
||||||
}
|
|
||||||
|
|
||||||
// Jitpack for e.g. MCPL
|
|
||||||
maven("https://jitpack.io") {
|
|
||||||
content { includeGroupByRegex("com\\.github\\..*") }
|
|
||||||
}
|
|
||||||
|
|
||||||
// For Adventure snapshots
|
|
||||||
maven("https://s01.oss.sonatype.org/content/repositories/snapshots/")
|
|
||||||
}
|
|
@ -2,11 +2,9 @@
|
|||||||
|
|
||||||
import net.fabricmc.loom.task.RemapJarTask
|
import net.fabricmc.loom.task.RemapJarTask
|
||||||
import org.gradle.kotlin.dsl.dependencies
|
import org.gradle.kotlin.dsl.dependencies
|
||||||
import org.gradle.kotlin.dsl.maven
|
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("geyser.build-logic")
|
id("geyser.platform-conventions")
|
||||||
id("geyser.publish-conventions")
|
|
||||||
id("architectury-plugin")
|
id("architectury-plugin")
|
||||||
id("dev.architectury.loom")
|
id("dev.architectury.loom")
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,20 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id("geyser.publish-conventions")
|
id("geyser.publish-conventions")
|
||||||
}
|
id("io.freefair.lombok")
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks {
|
||||||
|
processResources {
|
||||||
|
// Spigot, BungeeCord, Velocity, Fabric, ViaProxy, NeoForge
|
||||||
|
filesMatching(listOf("plugin.yml", "bungee.yml", "velocity-plugin.json", "fabric.mod.json", "viaproxy.yml", "META-INF/neoforge.mods.toml")) {
|
||||||
|
expand(
|
||||||
|
"id" to "geyser",
|
||||||
|
"name" to "Geyser",
|
||||||
|
"version" to project.version,
|
||||||
|
"description" to project.description,
|
||||||
|
"url" to "https://geysermc.org",
|
||||||
|
"author" to "GeyserMC"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,55 +1,5 @@
|
|||||||
plugins {
|
plugins {
|
||||||
`java-library`
|
|
||||||
// Ensure AP works in eclipse (no effect on other IDEs)
|
// Ensure AP works in eclipse (no effect on other IDEs)
|
||||||
eclipse
|
eclipse
|
||||||
id("geyser.build-logic")
|
id("geyser.base-conventions")
|
||||||
alias(libs.plugins.lombok) apply false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
allprojects {
|
|
||||||
group = properties["group"] as String + "." + properties["id"] as String
|
|
||||||
version = properties["version"] as String
|
|
||||||
description = properties["description"] as String
|
|
||||||
}
|
|
||||||
|
|
||||||
val basePlatforms = setOf(
|
|
||||||
projects.bungeecord,
|
|
||||||
projects.spigot,
|
|
||||||
projects.standalone,
|
|
||||||
projects.velocity,
|
|
||||||
projects.viaproxy
|
|
||||||
).map { it.dependencyProject }
|
|
||||||
|
|
||||||
val moddedPlatforms = setOf(
|
|
||||||
projects.fabric,
|
|
||||||
projects.neoforge,
|
|
||||||
projects.mod
|
|
||||||
).map { it.dependencyProject }
|
|
||||||
|
|
||||||
val modrinthPlatforms = setOf(
|
|
||||||
projects.bungeecord,
|
|
||||||
projects.fabric,
|
|
||||||
projects.neoforge,
|
|
||||||
projects.spigot,
|
|
||||||
projects.velocity
|
|
||||||
).map { it.dependencyProject }
|
|
||||||
|
|
||||||
subprojects {
|
|
||||||
apply {
|
|
||||||
plugin("java-library")
|
|
||||||
plugin("io.freefair.lombok")
|
|
||||||
plugin("geyser.build-logic")
|
|
||||||
}
|
|
||||||
|
|
||||||
when (this) {
|
|
||||||
in basePlatforms -> plugins.apply("geyser.platform-conventions")
|
|
||||||
in moddedPlatforms -> plugins.apply("geyser.modded-conventions")
|
|
||||||
else -> plugins.apply("geyser.base-conventions")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Not combined with platform-conventions as that also contains
|
|
||||||
// platforms which we cant publish to modrinth
|
|
||||||
if (modrinthPlatforms.contains(this)) {
|
|
||||||
plugins.apply("geyser.modrinth-uploading-conventions")
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,5 +1,6 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id("geyser.publish-conventions")
|
id("geyser.publish-conventions")
|
||||||
|
id("io.freefair.lombok")
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
@ -3,6 +3,7 @@ plugins {
|
|||||||
idea
|
idea
|
||||||
alias(libs.plugins.blossom)
|
alias(libs.plugins.blossom)
|
||||||
id("geyser.publish-conventions")
|
id("geyser.publish-conventions")
|
||||||
|
id("io.freefair.lombok")
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
@ -359,21 +359,6 @@ public class GeyserImpl implements GeyserApi, EventRegistrar {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String broadcastPort = System.getProperty("geyserBroadcastPort", "");
|
|
||||||
if (!broadcastPort.isEmpty()) {
|
|
||||||
int parsedPort;
|
|
||||||
try {
|
|
||||||
parsedPort = Integer.parseInt(broadcastPort);
|
|
||||||
if (parsedPort < 1 || parsedPort > 65535) {
|
|
||||||
throw new NumberFormatException("The broadcast port must be between 1 and 65535 inclusive!");
|
|
||||||
}
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
logger.error(String.format("Invalid broadcast port: %s! Defaulting to configured port.", broadcastPort + " (" + e.getMessage() + ")"));
|
|
||||||
parsedPort = config.bedrock().port();
|
|
||||||
}
|
|
||||||
config.bedrock().broadcastPort(parsedPort);
|
|
||||||
logger.info("Broadcast port set from system property: " + parsedPort);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (platformType != PlatformType.VIAPROXY) {
|
if (platformType != PlatformType.VIAPROXY) {
|
||||||
boolean floodgatePresent = bootstrap.testFloodgatePluginPresent();
|
boolean floodgatePresent = bootstrap.testFloodgatePluginPresent();
|
||||||
@ -389,6 +374,26 @@ public class GeyserImpl implements GeyserApi, EventRegistrar {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Now that the Bedrock port may have been changed, also check the broadcast port (configurable on all platforms)
|
||||||
|
String broadcastPort = System.getProperty("geyserBroadcastPort", "");
|
||||||
|
if (!broadcastPort.isEmpty()) {
|
||||||
|
try {
|
||||||
|
int parsedPort = Integer.parseInt(broadcastPort);
|
||||||
|
if (parsedPort < 1 || parsedPort > 65535) {
|
||||||
|
throw new NumberFormatException("The broadcast port must be between 1 and 65535 inclusive!");
|
||||||
|
}
|
||||||
|
config.bedrock().broadcastPort(parsedPort);
|
||||||
|
logger.info("Broadcast port set from system property: " + parsedPort);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
logger.error(String.format("Invalid broadcast port from system property: %s! Defaulting to configured port.", broadcastPort + " (" + e.getMessage() + ")"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// It's set to 0 only if no system property or manual config value was set
|
||||||
|
if (config.bedrock().broadcastPort() == 0) {
|
||||||
|
config.bedrock().broadcastPort(config.bedrock().port());
|
||||||
|
}
|
||||||
|
|
||||||
if (!(config instanceof GeyserPluginConfig)) {
|
if (!(config instanceof GeyserPluginConfig)) {
|
||||||
String remoteAddress = config.java().address();
|
String remoteAddress = config.java().address();
|
||||||
// Filters whether it is not an IP address or localhost, because otherwise it is not possible to find out an SRV entry.
|
// Filters whether it is not an IP address or localhost, because otherwise it is not possible to find out an SRV entry.
|
||||||
|
@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024 GeyserMC. http://geysermc.org
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* @author GeyserMC
|
||||||
|
* @link https://github.com/GeyserMC/Geyser
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.geysermc.geyser.erosion;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.util.concurrent.CancellationException;
|
||||||
|
|
||||||
|
public class ErosionCancellationException extends CancellationException {
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
}
|
@ -42,7 +42,6 @@ public final class GeyserboundHandshakePacketHandler extends AbstractGeyserbound
|
|||||||
public void handleHandshake(GeyserboundHandshakePacket packet) {
|
public void handleHandshake(GeyserboundHandshakePacket packet) {
|
||||||
boolean useTcp = packet.getTransportType().getSocketAddress() == null;
|
boolean useTcp = packet.getTransportType().getSocketAddress() == null;
|
||||||
GeyserboundPacketHandlerImpl handler = new GeyserboundPacketHandlerImpl(session, useTcp ? new GeyserErosionPacketSender(session) : new NettyPacketSender<>());
|
GeyserboundPacketHandlerImpl handler = new GeyserboundPacketHandlerImpl(session, useTcp ? new GeyserErosionPacketSender(session) : new NettyPacketSender<>());
|
||||||
session.setErosionHandler(handler);
|
|
||||||
if (!useTcp) {
|
if (!useTcp) {
|
||||||
if (session.getGeyser().getErosionUnixListener() == null) {
|
if (session.getGeyser().getErosionUnixListener() == null) {
|
||||||
session.disconnect("Erosion configurations using Unix socket handling are not supported on this hardware!");
|
session.disconnect("Erosion configurations using Unix socket handling are not supported on this hardware!");
|
||||||
@ -52,6 +51,7 @@ public final class GeyserboundHandshakePacketHandler extends AbstractGeyserbound
|
|||||||
} else {
|
} else {
|
||||||
handler.onConnect();
|
handler.onConnect();
|
||||||
}
|
}
|
||||||
|
session.setErosionHandler(handler);
|
||||||
session.ensureInEventLoop(() -> session.getChunkCache().clear());
|
session.ensureInEventLoop(() -> session.getChunkCache().clear());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,10 +171,10 @@ public final class GeyserboundPacketHandlerImpl extends AbstractGeyserboundPacke
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleHandshake(GeyserboundHandshakePacket packet) {
|
public void handleHandshake(GeyserboundHandshakePacket packet) {
|
||||||
this.close();
|
|
||||||
var handler = new GeyserboundHandshakePacketHandler(this.session);
|
var handler = new GeyserboundHandshakePacketHandler(this.session);
|
||||||
session.setErosionHandler(handler);
|
session.setErosionHandler(handler);
|
||||||
handler.handleHandshake(packet);
|
handler.handleHandshake(packet);
|
||||||
|
this.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -198,6 +198,17 @@ public final class GeyserboundPacketHandlerImpl extends AbstractGeyserboundPacke
|
|||||||
|
|
||||||
public void close() {
|
public void close() {
|
||||||
this.packetSender.close();
|
this.packetSender.close();
|
||||||
|
|
||||||
|
if (pendingLookup != null) {
|
||||||
|
pendingLookup.completeExceptionally(new ErosionCancellationException());
|
||||||
|
}
|
||||||
|
if (pendingBatchLookup != null) {
|
||||||
|
pendingBatchLookup.completeExceptionally(new ErosionCancellationException());
|
||||||
|
}
|
||||||
|
if (pickBlockLookup != null) {
|
||||||
|
pickBlockLookup.completeExceptionally(new ErosionCancellationException());
|
||||||
|
}
|
||||||
|
asyncPendingLookups.forEach(($, future) -> future.completeExceptionally(new ErosionCancellationException()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getNextTransactionId() {
|
public int getNextTransactionId() {
|
||||||
|
@ -35,6 +35,7 @@ import org.geysermc.erosion.packet.backendbound.BackendboundBatchBlockRequestPac
|
|||||||
import org.geysermc.erosion.packet.backendbound.BackendboundBlockRequestPacket;
|
import org.geysermc.erosion.packet.backendbound.BackendboundBlockRequestPacket;
|
||||||
import org.geysermc.erosion.packet.backendbound.BackendboundPickBlockPacket;
|
import org.geysermc.erosion.packet.backendbound.BackendboundPickBlockPacket;
|
||||||
import org.geysermc.erosion.util.BlockPositionIterator;
|
import org.geysermc.erosion.util.BlockPositionIterator;
|
||||||
|
import org.geysermc.geyser.erosion.ErosionCancellationException;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode;
|
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode;
|
||||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents;
|
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents;
|
||||||
@ -49,6 +50,8 @@ public class GeyserWorldManager extends WorldManager {
|
|||||||
var erosionHandler = session.getErosionHandler().getAsActive();
|
var erosionHandler = session.getErosionHandler().getAsActive();
|
||||||
if (erosionHandler == null) {
|
if (erosionHandler == null) {
|
||||||
return session.getChunkCache().getBlockAt(x, y, z);
|
return session.getChunkCache().getBlockAt(x, y, z);
|
||||||
|
} else if (session.isClosed()) {
|
||||||
|
throw new ErosionCancellationException();
|
||||||
}
|
}
|
||||||
CompletableFuture<Integer> future = new CompletableFuture<>(); // Boxes
|
CompletableFuture<Integer> future = new CompletableFuture<>(); // Boxes
|
||||||
erosionHandler.setPendingLookup(future);
|
erosionHandler.setPendingLookup(future);
|
||||||
@ -61,6 +64,8 @@ public class GeyserWorldManager extends WorldManager {
|
|||||||
var erosionHandler = session.getErosionHandler().getAsActive();
|
var erosionHandler = session.getErosionHandler().getAsActive();
|
||||||
if (erosionHandler == null) {
|
if (erosionHandler == null) {
|
||||||
return super.getBlockAtAsync(session, x, y, z);
|
return super.getBlockAtAsync(session, x, y, z);
|
||||||
|
} else if (session.isClosed()) {
|
||||||
|
return CompletableFuture.failedFuture(new ErosionCancellationException());
|
||||||
}
|
}
|
||||||
CompletableFuture<Integer> future = new CompletableFuture<>(); // Boxes
|
CompletableFuture<Integer> future = new CompletableFuture<>(); // Boxes
|
||||||
int transactionId = erosionHandler.getNextTransactionId();
|
int transactionId = erosionHandler.getNextTransactionId();
|
||||||
@ -74,6 +79,8 @@ public class GeyserWorldManager extends WorldManager {
|
|||||||
var erosionHandler = session.getErosionHandler().getAsActive();
|
var erosionHandler = session.getErosionHandler().getAsActive();
|
||||||
if (erosionHandler == null) {
|
if (erosionHandler == null) {
|
||||||
return super.getBlocksAt(session, iter);
|
return super.getBlocksAt(session, iter);
|
||||||
|
} else if (session.isClosed()) {
|
||||||
|
throw new ErosionCancellationException();
|
||||||
}
|
}
|
||||||
CompletableFuture<int[]> future = new CompletableFuture<>();
|
CompletableFuture<int[]> future = new CompletableFuture<>();
|
||||||
erosionHandler.setPendingBatchLookup(future);
|
erosionHandler.setPendingBatchLookup(future);
|
||||||
@ -124,6 +131,8 @@ public class GeyserWorldManager extends WorldManager {
|
|||||||
var erosionHandler = session.getErosionHandler().getAsActive();
|
var erosionHandler = session.getErosionHandler().getAsActive();
|
||||||
if (erosionHandler == null) {
|
if (erosionHandler == null) {
|
||||||
return super.getPickItemComponents(session, x, y, z, addNbtData);
|
return super.getPickItemComponents(session, x, y, z, addNbtData);
|
||||||
|
} else if (session.isClosed()) {
|
||||||
|
return CompletableFuture.failedFuture(new ErosionCancellationException());
|
||||||
}
|
}
|
||||||
CompletableFuture<Int2ObjectMap<byte[]>> future = new CompletableFuture<>();
|
CompletableFuture<Int2ObjectMap<byte[]>> future = new CompletableFuture<>();
|
||||||
erosionHandler.setPickBlockLookup(future);
|
erosionHandler.setPickBlockLookup(future);
|
||||||
|
@ -148,11 +148,6 @@ public final class GeyserServer {
|
|||||||
this.proxiedAddresses = null;
|
this.proxiedAddresses = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// It's set to 0 only if no system property or manual config value was set
|
|
||||||
if (geyser.config().bedrock().broadcastPort() == 0) {
|
|
||||||
geyser.config().bedrock().broadcastPort(geyser.config().bedrock().port());
|
|
||||||
}
|
|
||||||
|
|
||||||
this.broadcastPort = geyser.config().bedrock().broadcastPort();
|
this.broadcastPort = geyser.config().bedrock().broadcastPort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@ import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.Clien
|
|||||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundLightUpdatePacket;
|
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundLightUpdatePacket;
|
||||||
import io.netty.channel.EventLoop;
|
import io.netty.channel.EventLoop;
|
||||||
import org.geysermc.geyser.GeyserImpl;
|
import org.geysermc.geyser.GeyserImpl;
|
||||||
|
import org.geysermc.geyser.erosion.ErosionCancellationException;
|
||||||
import org.geysermc.geyser.registry.loader.RegistryLoaders;
|
import org.geysermc.geyser.registry.loader.RegistryLoaders;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
import org.geysermc.geyser.text.GeyserLocale;
|
import org.geysermc.geyser.text.GeyserLocale;
|
||||||
@ -87,6 +88,8 @@ public class PacketTranslatorRegistry<T> extends AbstractMappedRegistry<Class<?
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
translator.translate(session, packet);
|
translator.translate(session, packet);
|
||||||
|
} catch (ErosionCancellationException ex) {
|
||||||
|
GeyserImpl.getInstance().getLogger().debug("Caught ErosionCancellationException");
|
||||||
} catch (Throwable ex) {
|
} catch (Throwable ex) {
|
||||||
GeyserImpl.getInstance().getLogger().error(GeyserLocale.getLocaleStringLog("geyser.network.translator.packet.failed", packet.getClass().getSimpleName()), ex);
|
GeyserImpl.getInstance().getLogger().error(GeyserLocale.getLocaleStringLog("geyser.network.translator.packet.failed", packet.getClass().getSimpleName()), ex);
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
|
@ -38,6 +38,7 @@ import lombok.Getter;
|
|||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
import net.kyori.adventure.key.Key;
|
import net.kyori.adventure.key.Key;
|
||||||
|
import net.raphimc.minecraftauth.responsehandler.exception.MinecraftRequestException;
|
||||||
import net.raphimc.minecraftauth.step.java.StepMCProfile;
|
import net.raphimc.minecraftauth.step.java.StepMCProfile;
|
||||||
import net.raphimc.minecraftauth.step.java.StepMCToken;
|
import net.raphimc.minecraftauth.step.java.StepMCToken;
|
||||||
import net.raphimc.minecraftauth.step.java.session.StepFullJavaSession;
|
import net.raphimc.minecraftauth.step.java.session.StepFullJavaSession;
|
||||||
@ -64,6 +65,7 @@ import org.cloudburstmc.protocol.bedrock.data.ExperimentData;
|
|||||||
import org.cloudburstmc.protocol.bedrock.data.GamePublishSetting;
|
import org.cloudburstmc.protocol.bedrock.data.GamePublishSetting;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.GameRuleData;
|
import org.cloudburstmc.protocol.bedrock.data.GameRuleData;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.GameType;
|
import org.cloudburstmc.protocol.bedrock.data.GameType;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.data.LevelEvent;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.PlayerPermission;
|
import org.cloudburstmc.protocol.bedrock.data.PlayerPermission;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.SoundEvent;
|
import org.cloudburstmc.protocol.bedrock.data.SoundEvent;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.SpawnBiomeType;
|
import org.cloudburstmc.protocol.bedrock.data.SpawnBiomeType;
|
||||||
@ -83,6 +85,7 @@ import org.cloudburstmc.protocol.bedrock.packet.CreativeContentPacket;
|
|||||||
import org.cloudburstmc.protocol.bedrock.packet.EmoteListPacket;
|
import org.cloudburstmc.protocol.bedrock.packet.EmoteListPacket;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.GameRulesChangedPacket;
|
import org.cloudburstmc.protocol.bedrock.packet.GameRulesChangedPacket;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.ItemComponentPacket;
|
import org.cloudburstmc.protocol.bedrock.packet.ItemComponentPacket;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.LevelSoundEvent2Packet;
|
import org.cloudburstmc.protocol.bedrock.packet.LevelSoundEvent2Packet;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.PlayStatusPacket;
|
import org.cloudburstmc.protocol.bedrock.packet.PlayStatusPacket;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.SetTimePacket;
|
import org.cloudburstmc.protocol.bedrock.packet.SetTimePacket;
|
||||||
@ -127,6 +130,7 @@ import org.geysermc.geyser.entity.type.Tickable;
|
|||||||
import org.geysermc.geyser.entity.type.player.SessionPlayerEntity;
|
import org.geysermc.geyser.entity.type.player.SessionPlayerEntity;
|
||||||
import org.geysermc.geyser.entity.vehicle.ClientVehicle;
|
import org.geysermc.geyser.entity.vehicle.ClientVehicle;
|
||||||
import org.geysermc.geyser.erosion.AbstractGeyserboundPacketHandler;
|
import org.geysermc.geyser.erosion.AbstractGeyserboundPacketHandler;
|
||||||
|
import org.geysermc.geyser.erosion.ErosionCancellationException;
|
||||||
import org.geysermc.geyser.erosion.GeyserboundHandshakePacketHandler;
|
import org.geysermc.geyser.erosion.GeyserboundHandshakePacketHandler;
|
||||||
import org.geysermc.geyser.impl.camera.CameraDefinitions;
|
import org.geysermc.geyser.impl.camera.CameraDefinitions;
|
||||||
import org.geysermc.geyser.impl.camera.GeyserCameraData;
|
import org.geysermc.geyser.impl.camera.GeyserCameraData;
|
||||||
@ -226,6 +230,7 @@ import java.util.Queue;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.CompletionException;
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
import java.util.concurrent.ScheduledFuture;
|
import java.util.concurrent.ScheduledFuture;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
@ -254,7 +259,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
|||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@Setter
|
@Setter
|
||||||
private AbstractGeyserboundPacketHandler erosionHandler;
|
private volatile AbstractGeyserboundPacketHandler erosionHandler;
|
||||||
|
|
||||||
@Accessors(fluent = true)
|
@Accessors(fluent = true)
|
||||||
@Setter
|
@Setter
|
||||||
@ -565,13 +570,11 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
|||||||
/**
|
/**
|
||||||
* Caches current rain status.
|
* Caches current rain status.
|
||||||
*/
|
*/
|
||||||
@Setter
|
|
||||||
private boolean raining = false;
|
private boolean raining = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Caches current thunder status.
|
* Caches current thunder status.
|
||||||
*/
|
*/
|
||||||
@Setter
|
|
||||||
private boolean thunder = false;
|
private boolean thunder = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -868,7 +871,14 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
|||||||
return task.getAuthentication().handle((result, ex) -> {
|
return task.getAuthentication().handle((result, ex) -> {
|
||||||
if (ex != null) {
|
if (ex != null) {
|
||||||
geyser.getLogger().error("Failed to log in with Microsoft code!", ex);
|
geyser.getLogger().error("Failed to log in with Microsoft code!", ex);
|
||||||
disconnect(ex.toString());
|
if (ex instanceof CompletionException ce
|
||||||
|
&& ce.getCause() instanceof MinecraftRequestException mre
|
||||||
|
&& mre.getResponse().getStatusCode() == 404) {
|
||||||
|
// Player is trying to join with a Microsoft account that doesn't have Java Edition purchased
|
||||||
|
disconnect(GeyserLocale.getPlayerLocaleString("geyser.network.remote.invalid_account", locale()));
|
||||||
|
} else {
|
||||||
|
disconnect(ex.toString());
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1182,9 +1192,9 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
|||||||
tickThread.cancel(false);
|
tickThread.cancel(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
erosionHandler.close();
|
// Mark session as closed before cancelling erosion futures
|
||||||
|
|
||||||
closed = true;
|
closed = true;
|
||||||
|
erosionHandler.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1205,6 +1215,8 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
|||||||
eventLoop.execute(() -> {
|
eventLoop.execute(() -> {
|
||||||
try {
|
try {
|
||||||
runnable.run();
|
runnable.run();
|
||||||
|
} catch (ErosionCancellationException e) {
|
||||||
|
geyser.getLogger().debug("Caught ErosionCancellationException");
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
geyser.getLogger().error("Error thrown in " + this.bedrockUsername() + "'s event loop!", e);
|
geyser.getLogger().error("Error thrown in " + this.bedrockUsername() + "'s event loop!", e);
|
||||||
}
|
}
|
||||||
@ -1222,6 +1234,8 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
|||||||
if (!closed) {
|
if (!closed) {
|
||||||
runnable.run();
|
runnable.run();
|
||||||
}
|
}
|
||||||
|
} catch (ErosionCancellationException e) {
|
||||||
|
geyser.getLogger().debug("Caught ErosionCancellationException");
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
geyser.getLogger().error("Error thrown in " + this.bedrockUsername() + "'s event loop!", e);
|
geyser.getLogger().error("Error thrown in " + this.bedrockUsername() + "'s event loop!", e);
|
||||||
}
|
}
|
||||||
@ -1994,6 +2008,60 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a packet to update rain strength.
|
||||||
|
* Stops rain if strength is 0.
|
||||||
|
*
|
||||||
|
* @param strength value between 0 and 1
|
||||||
|
*/
|
||||||
|
public void updateRain(float strength) {
|
||||||
|
this.raining = strength > 0;
|
||||||
|
|
||||||
|
LevelEventPacket rainPacket = new LevelEventPacket();
|
||||||
|
rainPacket.setType(this.raining ? LevelEvent.START_RAINING : LevelEvent.STOP_RAINING);
|
||||||
|
rainPacket.setData((int) (strength * 65535));
|
||||||
|
rainPacket.setPosition(Vector3f.ZERO);
|
||||||
|
|
||||||
|
if (this.raining) {
|
||||||
|
sendUpstreamPacket(rainPacket);
|
||||||
|
} else {
|
||||||
|
// The bedrock client might ignore this packet if it is sent in the same tick as another rain packet
|
||||||
|
// https://github.com/GeyserMC/Geyser/issues/3679
|
||||||
|
scheduleInEventLoop(() -> {
|
||||||
|
if (!this.raining) {
|
||||||
|
sendUpstreamPacket(rainPacket);
|
||||||
|
}
|
||||||
|
}, 100, TimeUnit.MILLISECONDS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a packet to update thunderstorm strength.
|
||||||
|
* Stops thunderstorm if strength is 0.
|
||||||
|
*
|
||||||
|
* @param strength value between 0 and 1
|
||||||
|
*/
|
||||||
|
public void updateThunder(float strength) {
|
||||||
|
this.thunder = strength > 0;
|
||||||
|
|
||||||
|
LevelEventPacket thunderPacket = new LevelEventPacket();
|
||||||
|
thunderPacket.setType(this.thunder ? LevelEvent.START_THUNDERSTORM : LevelEvent.STOP_THUNDERSTORM);
|
||||||
|
thunderPacket.setData((int) (strength * 65535));
|
||||||
|
thunderPacket.setPosition(Vector3f.ZERO);
|
||||||
|
|
||||||
|
if (this.thunder) {
|
||||||
|
sendUpstreamPacket(thunderPacket);
|
||||||
|
} else {
|
||||||
|
// The bedrock client might ignore this packet if it is sent in the same tick as another thunderstorm packet
|
||||||
|
// https://github.com/GeyserMC/Geyser/issues/3679
|
||||||
|
scheduleInEventLoop(() -> {
|
||||||
|
if (!this.thunder) {
|
||||||
|
sendUpstreamPacket(thunderPacket);
|
||||||
|
}
|
||||||
|
}, 100, TimeUnit.MILLISECONDS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NonNull String bedrockUsername() {
|
public @NonNull String bedrockUsername() {
|
||||||
return authData.name();
|
return authData.name();
|
||||||
|
@ -33,7 +33,6 @@ import org.geysermc.erosion.Constants;
|
|||||||
import org.geysermc.floodgate.pluginmessage.PluginMessageChannels;
|
import org.geysermc.floodgate.pluginmessage.PluginMessageChannels;
|
||||||
import org.geysermc.geyser.api.network.AuthType;
|
import org.geysermc.geyser.api.network.AuthType;
|
||||||
import org.geysermc.geyser.entity.type.player.SessionPlayerEntity;
|
import org.geysermc.geyser.entity.type.player.SessionPlayerEntity;
|
||||||
import org.geysermc.geyser.erosion.GeyserboundHandshakePacketHandler;
|
|
||||||
import org.geysermc.geyser.level.JavaDimension;
|
import org.geysermc.geyser.level.JavaDimension;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
||||||
@ -57,11 +56,6 @@ public class JavaLoginTranslator extends PacketTranslator<ClientboundLoginPacket
|
|||||||
SessionPlayerEntity entity = session.getPlayerEntity();
|
SessionPlayerEntity entity = session.getPlayerEntity();
|
||||||
entity.setEntityId(packet.getEntityId());
|
entity.setEntityId(packet.getEntityId());
|
||||||
|
|
||||||
if (session.getErosionHandler().isActive()) {
|
|
||||||
session.getErosionHandler().close();
|
|
||||||
session.setErosionHandler(new GeyserboundHandshakePacketHandler(session));
|
|
||||||
}
|
|
||||||
|
|
||||||
PlayerSpawnInfo spawnInfo = packet.getCommonPlayerSpawnInfo();
|
PlayerSpawnInfo spawnInfo = packet.getCommonPlayerSpawnInfo();
|
||||||
JavaDimension newDimension = session.getRegistryCache().dimensions().byId(spawnInfo.getDimension());
|
JavaDimension newDimension = session.getRegistryCache().dimensions().byId(spawnInfo.getDimension());
|
||||||
|
|
||||||
|
@ -25,9 +25,6 @@
|
|||||||
|
|
||||||
package org.geysermc.geyser.translator.protocol.java;
|
package org.geysermc.geyser.translator.protocol.java;
|
||||||
|
|
||||||
import org.cloudburstmc.math.vector.Vector3f;
|
|
||||||
import org.cloudburstmc.protocol.bedrock.data.LevelEvent;
|
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket;
|
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.SetPlayerGameTypePacket;
|
import org.cloudburstmc.protocol.bedrock.packet.SetPlayerGameTypePacket;
|
||||||
import org.geysermc.geyser.entity.attribute.GeyserAttributeType;
|
import org.geysermc.geyser.entity.attribute.GeyserAttributeType;
|
||||||
import org.geysermc.geyser.entity.type.player.SessionPlayerEntity;
|
import org.geysermc.geyser.entity.type.player.SessionPlayerEntity;
|
||||||
@ -76,21 +73,11 @@ public class JavaRespawnTranslator extends PacketTranslator<ClientboundRespawnPa
|
|||||||
session.setGameMode(spawnInfo.getGameMode());
|
session.setGameMode(spawnInfo.getGameMode());
|
||||||
|
|
||||||
if (session.isRaining()) {
|
if (session.isRaining()) {
|
||||||
LevelEventPacket stopRainPacket = new LevelEventPacket();
|
session.updateRain(0);
|
||||||
stopRainPacket.setType(LevelEvent.STOP_RAINING);
|
|
||||||
stopRainPacket.setData(0);
|
|
||||||
stopRainPacket.setPosition(Vector3f.ZERO);
|
|
||||||
session.sendUpstreamPacket(stopRainPacket);
|
|
||||||
session.setRaining(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (session.isThunder()) {
|
if (session.isThunder()) {
|
||||||
LevelEventPacket stopThunderPacket = new LevelEventPacket();
|
session.updateThunder(0);
|
||||||
stopThunderPacket.setType(LevelEvent.STOP_THUNDERSTORM);
|
|
||||||
stopThunderPacket.setData(0);
|
|
||||||
stopThunderPacket.setPosition(Vector3f.ZERO);
|
|
||||||
session.sendUpstreamPacket(stopThunderPacket);
|
|
||||||
session.setThunder(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JavaDimension newDimension = session.getRegistryCache().dimensions().byId(spawnInfo.getDimension());
|
JavaDimension newDimension = session.getRegistryCache().dimensions().byId(spawnInfo.getDimension());
|
||||||
|
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024 GeyserMC. http://geysermc.org
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* @author GeyserMC
|
||||||
|
* @link https://github.com/GeyserMC/Geyser
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.geysermc.geyser.translator.protocol.java;
|
||||||
|
|
||||||
|
import org.geysermc.geyser.erosion.GeyserboundHandshakePacketHandler;
|
||||||
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
|
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
||||||
|
import org.geysermc.geyser.translator.protocol.Translator;
|
||||||
|
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundStartConfigurationPacket;
|
||||||
|
|
||||||
|
@Translator(packet = ClientboundStartConfigurationPacket.class)
|
||||||
|
public class JavaStartConfigurationTranslator extends PacketTranslator<ClientboundStartConfigurationPacket> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void translate(GeyserSession session, ClientboundStartConfigurationPacket packet) {
|
||||||
|
var erosionHandler = session.getErosionHandler();
|
||||||
|
if (erosionHandler.isActive()) {
|
||||||
|
// Set new handler before closing
|
||||||
|
session.setErosionHandler(new GeyserboundHandshakePacketHandler(session));
|
||||||
|
erosionHandler.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldExecuteInEventLoop() {
|
||||||
|
// Execute outside of event loop to cancel any pending erosion futures
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@ -25,7 +25,10 @@
|
|||||||
|
|
||||||
package org.geysermc.geyser.translator.protocol.java;
|
package org.geysermc.geyser.translator.protocol.java;
|
||||||
|
|
||||||
|
import net.kyori.adventure.text.TextComponent;
|
||||||
import net.kyori.adventure.text.TranslatableComponent;
|
import net.kyori.adventure.text.TranslatableComponent;
|
||||||
|
import net.kyori.adventure.text.TranslationArgument;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
import org.cloudburstmc.nbt.NbtMap;
|
import org.cloudburstmc.nbt.NbtMap;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.LevelEvent;
|
import org.cloudburstmc.protocol.bedrock.data.LevelEvent;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.LevelEventGenericPacket;
|
import org.cloudburstmc.protocol.bedrock.packet.LevelEventGenericPacket;
|
||||||
@ -55,16 +58,18 @@ public class JavaSystemChatTranslator extends PacketTranslator<ClientboundSystem
|
|||||||
if (component.arguments().size() == 2) {
|
if (component.arguments().size() == 2) {
|
||||||
// Hack FYI, but it allows Bedrock players to easily understand this information
|
// Hack FYI, but it allows Bedrock players to easily understand this information
|
||||||
// without it being covered up or saying the night is being slept through.
|
// without it being covered up or saying the night is being slept through.
|
||||||
int numPlayersSleeping = ((Number) component.arguments().get(0).value()).intValue();
|
Integer numPlayersSleeping = convertToInt(component.arguments().get(0));
|
||||||
int totalPlayersNeeded = ((Number) component.arguments().get(1).value()).intValue();
|
Integer totalPlayersNeeded = convertToInt(component.arguments().get(1));
|
||||||
LevelEventGenericPacket sleepInfoPacket = new LevelEventGenericPacket();
|
if (numPlayersSleeping != null && totalPlayersNeeded != null) {
|
||||||
sleepInfoPacket.setType(LevelEvent.SLEEPING_PLAYERS);
|
LevelEventGenericPacket sleepInfoPacket = new LevelEventGenericPacket();
|
||||||
sleepInfoPacket.setTag(NbtMap.builder()
|
sleepInfoPacket.setType(LevelEvent.SLEEPING_PLAYERS);
|
||||||
.putInt("ableToSleep", totalPlayersNeeded)
|
sleepInfoPacket.setTag(NbtMap.builder()
|
||||||
.putInt("overworldPlayerCount", totalPlayersNeeded)
|
.putInt("ableToSleep", totalPlayersNeeded)
|
||||||
.putInt("sleepingPlayerCount", numPlayersSleeping)
|
.putInt("overworldPlayerCount", totalPlayersNeeded)
|
||||||
.build());
|
.putInt("sleepingPlayerCount", numPlayersSleeping)
|
||||||
session.sendUpstreamPacket(sleepInfoPacket);
|
.build());
|
||||||
|
session.sendUpstreamPacket(sleepInfoPacket);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (component.key().equals("sleep.skipping_night")) {
|
} else if (component.key().equals("sleep.skipping_night")) {
|
||||||
LevelEventGenericPacket sleepInfoPacket = new LevelEventGenericPacket();
|
LevelEventGenericPacket sleepInfoPacket = new LevelEventGenericPacket();
|
||||||
@ -97,4 +102,19 @@ public class JavaSystemChatTranslator extends PacketTranslator<ClientboundSystem
|
|||||||
session.getUpstream().queuePostStartGamePacket(textPacket);
|
session.getUpstream().queuePostStartGamePacket(textPacket);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static @Nullable Integer convertToInt(TranslationArgument translationArgument) {
|
||||||
|
Object value = translationArgument.value();
|
||||||
|
if (value instanceof Number number) {
|
||||||
|
return number.intValue();
|
||||||
|
}
|
||||||
|
if (value instanceof TextComponent textComponent) {
|
||||||
|
try {
|
||||||
|
return Integer.parseInt(textComponent.content());
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,9 +33,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.level.notify.RespawnScreenV
|
|||||||
import org.geysermc.mcprotocollib.protocol.data.game.level.notify.ThunderStrengthValue;
|
import org.geysermc.mcprotocollib.protocol.data.game.level.notify.ThunderStrengthValue;
|
||||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundGameEventPacket;
|
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundGameEventPacket;
|
||||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.ServerboundClientCommandPacket;
|
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.ServerboundClientCommandPacket;
|
||||||
import org.cloudburstmc.math.vector.Vector3f;
|
|
||||||
import org.cloudburstmc.protocol.bedrock.data.GameRuleData;
|
import org.cloudburstmc.protocol.bedrock.data.GameRuleData;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.LevelEvent;
|
|
||||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType;
|
import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.*;
|
import org.cloudburstmc.protocol.bedrock.packet.*;
|
||||||
import org.geysermc.geyser.entity.type.player.PlayerEntity;
|
import org.geysermc.geyser.entity.type.player.PlayerEntity;
|
||||||
@ -48,9 +46,6 @@ import org.geysermc.geyser.util.EntityUtils;
|
|||||||
|
|
||||||
@Translator(packet = ClientboundGameEventPacket.class)
|
@Translator(packet = ClientboundGameEventPacket.class)
|
||||||
public class JavaGameEventTranslator extends PacketTranslator<ClientboundGameEventPacket> {
|
public class JavaGameEventTranslator extends PacketTranslator<ClientboundGameEventPacket> {
|
||||||
// Strength of rainstorms and thunderstorms is a 0-1 float on Java, while on Bedrock it is a 0-65535 int
|
|
||||||
private static final int MAX_STORM_STRENGTH = 65535;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void translate(GeyserSession session, ClientboundGameEventPacket packet) {
|
public void translate(GeyserSession session, ClientboundGameEventPacket packet) {
|
||||||
PlayerEntity entity = session.getPlayerEntity();
|
PlayerEntity entity = session.getPlayerEntity();
|
||||||
@ -65,42 +60,20 @@ public class JavaGameEventTranslator extends PacketTranslator<ClientboundGameEve
|
|||||||
// As a result many developers use these packets for the opposite of what their names implies
|
// As a result many developers use these packets for the opposite of what their names implies
|
||||||
// Behavior last verified with Java 1.19.4 and Bedrock 1.19.71
|
// Behavior last verified with Java 1.19.4 and Bedrock 1.19.71
|
||||||
case START_RAIN:
|
case START_RAIN:
|
||||||
LevelEventPacket stopRainPacket = new LevelEventPacket();
|
session.updateRain(0);
|
||||||
stopRainPacket.setType(LevelEvent.STOP_RAINING);
|
|
||||||
stopRainPacket.setData(0);
|
|
||||||
stopRainPacket.setPosition(Vector3f.ZERO);
|
|
||||||
session.sendUpstreamPacket(stopRainPacket);
|
|
||||||
session.setRaining(false);
|
|
||||||
break;
|
break;
|
||||||
case STOP_RAIN:
|
case STOP_RAIN:
|
||||||
LevelEventPacket startRainPacket = new LevelEventPacket();
|
session.updateRain(1);
|
||||||
startRainPacket.setType(LevelEvent.START_RAINING);
|
|
||||||
startRainPacket.setData(MAX_STORM_STRENGTH);
|
|
||||||
startRainPacket.setPosition(Vector3f.ZERO);
|
|
||||||
session.sendUpstreamPacket(startRainPacket);
|
|
||||||
session.setRaining(true);
|
|
||||||
break;
|
break;
|
||||||
case RAIN_STRENGTH:
|
case RAIN_STRENGTH:
|
||||||
float rainStrength = ((RainStrengthValue) packet.getValue()).getStrength();
|
|
||||||
boolean isCurrentlyRaining = rainStrength > 0f;
|
|
||||||
LevelEventPacket changeRainPacket = new LevelEventPacket();
|
|
||||||
changeRainPacket.setType(isCurrentlyRaining ? LevelEvent.START_RAINING : LevelEvent.STOP_RAINING);
|
|
||||||
// This is the rain strength on LevelEventType.START_RAINING, but can be any value on LevelEventType.STOP_RAINING
|
// This is the rain strength on LevelEventType.START_RAINING, but can be any value on LevelEventType.STOP_RAINING
|
||||||
changeRainPacket.setData((int) (rainStrength * MAX_STORM_STRENGTH));
|
float rainStrength = ((RainStrengthValue) packet.getValue()).getStrength();
|
||||||
changeRainPacket.setPosition(Vector3f.ZERO);
|
session.updateRain(rainStrength);
|
||||||
session.sendUpstreamPacket(changeRainPacket);
|
|
||||||
session.setRaining(isCurrentlyRaining);
|
|
||||||
break;
|
break;
|
||||||
case THUNDER_STRENGTH:
|
case THUNDER_STRENGTH:
|
||||||
// See above, same process
|
// See above, same process
|
||||||
float thunderStrength = ((ThunderStrengthValue) packet.getValue()).getStrength();
|
float thunderStrength = ((ThunderStrengthValue) packet.getValue()).getStrength();
|
||||||
boolean isCurrentlyThundering = thunderStrength > 0f;
|
session.updateThunder(thunderStrength);
|
||||||
LevelEventPacket changeThunderPacket = new LevelEventPacket();
|
|
||||||
changeThunderPacket.setType(isCurrentlyThundering ? LevelEvent.START_THUNDERSTORM : LevelEvent.STOP_THUNDERSTORM);
|
|
||||||
changeThunderPacket.setData((int) (thunderStrength * MAX_STORM_STRENGTH));
|
|
||||||
changeThunderPacket.setPosition(Vector3f.ZERO);
|
|
||||||
session.sendUpstreamPacket(changeThunderPacket);
|
|
||||||
session.setThunder(isCurrentlyThundering);
|
|
||||||
break;
|
break;
|
||||||
case CHANGE_GAMEMODE:
|
case CHANGE_GAMEMODE:
|
||||||
GameMode gameMode = (GameMode) packet.getValue();
|
GameMode gameMode = (GameMode) packet.getValue();
|
||||||
|
@ -291,10 +291,7 @@ public class JavaLevelEventTranslator extends PacketTranslator<ClientboundLevelE
|
|||||||
session.sendUpstreamPacket(soundEventPacket);
|
session.sendUpstreamPacket(soundEventPacket);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case PARTICLES_DRAGON_BLOCK_BREAK -> {
|
case PARTICLES_DRAGON_BLOCK_BREAK -> effectPacket.setType(ParticleType.DRAGON_DESTROY_BLOCK);
|
||||||
effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_GENERIC_SPAWN);
|
|
||||||
effectPacket.setData(61);
|
|
||||||
}
|
|
||||||
case PARTICLES_WATER_EVAPORATING -> {
|
case PARTICLES_WATER_EVAPORATING -> {
|
||||||
effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_EVAPORATE_WATER);
|
effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_EVAPORATE_WATER);
|
||||||
effectPacket.setPosition(pos.add(-0.5f, 0.5f, -0.5f));
|
effectPacket.setPosition(pos.add(-0.5f, 0.5f, -0.5f));
|
||||||
|
@ -28,11 +28,9 @@ package org.geysermc.geyser.util;
|
|||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
import org.cloudburstmc.math.vector.Vector3f;
|
import org.cloudburstmc.math.vector.Vector3f;
|
||||||
import org.cloudburstmc.math.vector.Vector3i;
|
import org.cloudburstmc.math.vector.Vector3i;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.LevelEvent;
|
|
||||||
import org.cloudburstmc.protocol.bedrock.data.PlayerActionType;
|
import org.cloudburstmc.protocol.bedrock.data.PlayerActionType;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.ChangeDimensionPacket;
|
import org.cloudburstmc.protocol.bedrock.packet.ChangeDimensionPacket;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.ChunkRadiusUpdatedPacket;
|
import org.cloudburstmc.protocol.bedrock.packet.ChunkRadiusUpdatedPacket;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket;
|
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.MobEffectPacket;
|
import org.cloudburstmc.protocol.bedrock.packet.MobEffectPacket;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.PlayerActionPacket;
|
import org.cloudburstmc.protocol.bedrock.packet.PlayerActionPacket;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.StopSoundPacket;
|
import org.cloudburstmc.protocol.bedrock.packet.StopSoundPacket;
|
||||||
@ -89,18 +87,8 @@ public class DimensionUtils {
|
|||||||
entityEffects.clear();
|
entityEffects.clear();
|
||||||
|
|
||||||
// Always reset weather, as it sometimes suddenly starts raining. See https://github.com/GeyserMC/Geyser/issues/3679
|
// Always reset weather, as it sometimes suddenly starts raining. See https://github.com/GeyserMC/Geyser/issues/3679
|
||||||
LevelEventPacket stopRainPacket = new LevelEventPacket();
|
session.updateRain(0);
|
||||||
stopRainPacket.setType(LevelEvent.STOP_RAINING);
|
session.updateThunder(0);
|
||||||
stopRainPacket.setData(0);
|
|
||||||
stopRainPacket.setPosition(Vector3f.ZERO);
|
|
||||||
session.sendUpstreamPacket(stopRainPacket);
|
|
||||||
session.setRaining(false);
|
|
||||||
LevelEventPacket stopThunderPacket = new LevelEventPacket();
|
|
||||||
stopThunderPacket.setType(LevelEvent.STOP_THUNDERSTORM);
|
|
||||||
stopThunderPacket.setData(0);
|
|
||||||
stopThunderPacket.setPosition(Vector3f.ZERO);
|
|
||||||
session.sendUpstreamPacket(stopThunderPacket);
|
|
||||||
session.setThunder(false);
|
|
||||||
|
|
||||||
finalizeDimensionSwitch(session, player);
|
finalizeDimensionSwitch(session, player);
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
# Gradle settings
|
# Gradle settings
|
||||||
org.gradle.jvmargs=-Xmx4G
|
org.gradle.jvmargs=-Xmx4G
|
||||||
org.gradle.daemon=false
|
org.gradle.daemon=false
|
||||||
|
org.gradle.configureondemand=true
|
||||||
org.gradle.parallel=true
|
org.gradle.parallel=true
|
||||||
org.gradle.caching=true
|
org.gradle.caching=true
|
||||||
org.gradle.vfs.watch=false
|
org.gradle.vfs.watch=false
|
||||||
|
@ -143,6 +143,7 @@ math = { group = "org.cloudburstmc.math", name = "immutable", version = "2.0" }
|
|||||||
bstats = { group = "org.bstats", name = "bstats-base", version.ref = "bstats"}
|
bstats = { group = "org.bstats", name = "bstats-base", version.ref = "bstats"}
|
||||||
|
|
||||||
# plugins
|
# plugins
|
||||||
|
lombok = { group = "io.freefair.gradle", name = "lombok-plugin", version.ref = "lombok" }
|
||||||
indra = { group = "net.kyori", name = "indra-common", version.ref = "indra" }
|
indra = { group = "net.kyori", name = "indra-common", version.ref = "indra" }
|
||||||
shadow = { group = "com.github.johnrengelman", name = "shadow", version.ref = "shadow" }
|
shadow = { group = "com.github.johnrengelman", name = "shadow", version.ref = "shadow" }
|
||||||
architectury-plugin = { group = "architectury-plugin", name = "architectury-plugin.gradle.plugin", version.ref = "architectury-plugin" }
|
architectury-plugin = { group = "architectury-plugin", name = "architectury-plugin.gradle.plugin", version.ref = "architectury-plugin" }
|
||||||
@ -150,7 +151,6 @@ architectury-loom = { group = "dev.architectury.loom", name = "dev.architectury.
|
|||||||
minotaur = { group = "com.modrinth.minotaur", name = "Minotaur", version.ref = "minotaur" }
|
minotaur = { group = "com.modrinth.minotaur", name = "Minotaur", version.ref = "minotaur" }
|
||||||
|
|
||||||
[plugins]
|
[plugins]
|
||||||
lombok = { id = "io.freefair.lombok", version.ref = "lombok" }
|
|
||||||
indra = { id = "net.kyori.indra", version.ref = "indra" }
|
indra = { id = "net.kyori.indra", version.ref = "indra" }
|
||||||
blossom = { id = "net.kyori.blossom", version.ref = "blossom" }
|
blossom = { id = "net.kyori.blossom", version.ref = "blossom" }
|
||||||
|
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren