1
0
mirror of https://github.com/GeyserMC/Geyser.git synced 2026-01-04 15:31:36 +00:00

Switch config system to Configurate (#5010)

* Start implementing Configurate config system

* More development

* Start migrating to Gson only

* Progress

* Update usage of WebUtils

* Most things now use Gson for JSON

* Allow tests to succeed by using new Gson version

* Use slightly cleaner version for Version deserializer

* Work around older Gson versions without record support

* GeyserCustomSkullConfiguration uses Configurate

* Fix regression in properties get

* New config used in core

* The configuration is gone. Long live the config.

* More changes and migrations away from Jackson

* Improve node ordering when updating configs

* typo

* Better check for ignoring non-configurate configs for considering comment moving

* Ensure metrics UUID is valid

* Initial advanced config

* Remove Jackson; finish config value placements

* Remove duplicate relocate declarations

* Let annotations work

* Renaming to PluginSpecific

* Use global bStats config where possible

* Fix test

* Re-introduce asterisk behavior in configs

* Remove GeyserPluginBootstrap as it's no longer necessary

* Remove old config.yml file

* Update Xbox achievement comment

* Apply suggestions from code review

Co-authored-by: chris <github@onechris.mozmail.com>

* No need to remove values anymore

* Fix: disable bstats relocation on platforms where it is not needed

* ensure it builds

* Update custom unavailable slot comment

Co-authored-by: chris <github@onechris.mozmail.com>

* Update cooldown image

* Logger message for direct-compression still being enabled

* oops

* More explicit RuntimeException message

Co-authored-by: Konicai <71294714+Konicai@users.noreply.github.com>

* Constant for 'system' locale

* Better config JSON encoding (something is broken with Cloudflare; we'll figure it out

* Fix broadcast port default

* Add this file too

* Update configurate branch

* fix build

* Fix: Allow using custom config file on Standalone, add relocation comment

* Move config loading to GeyserBootstrap interface

* Add and rename some config options, add section notes (#5390)

* Add and rename some config options, add section notes

* adjust message

* Update core/src/main/java/org/geysermc/geyser/command/defaults/ConnectionTestCommand.java

Co-authored-by: Eclipse <eclipse@eclipseisoffline.xyz>

* Update core/src/main/java/org/geysermc/geyser/configuration/GeyserConfig.java

Co-authored-by: Eclipse <eclipse@eclipseisoffline.xyz>

* Update ConfigLoader.java

* Update AdvancedConfig.java

* clarify that we're talking about the HAProxy protocol

* rename config option to use-haproxy-protocol

* remove ominous warning sign on xbox auth warning

* adjust wording

---------

Co-authored-by: Eclipse <eclipse@eclipseisoffline.xyz>

* Back to one config file

* Some minor touchups

* Configurate: Sectionification (#5904)

* Init: config sections

* Start on adding tests, move migrations over to ConfigMigrations class

* Get rid of auth section again, rename that one config option, fix mtu migration

* Move custom skulls config options to the bottom of the gameplay settings

* Add more tests

* Rename and migrate proxy-protocol-whitelisted-ips to haproxy-protocol-whitelisted-ips

* Add automatic downloading of the GeyserOptionalPack

* Revert "Add automatic downloading of the GeyserOptionalPack"

This reverts commit 65b96208fb.

* Add more invalid config tests

* Warn about emote-offhand-workaround removal

* Add automatic loading of the GeyserOptionalPack (feature/configurate) (#5964)

* Add automatic downloading of the GeyserOptionalPack

* Warn about including the OptionalPack from extensions when Geyser is already including it instead of throwing.

* Copy optional pack instead of downloading

---------

Co-authored-by: onebeastchris <github@onechris.mozmail.com>

* Remove unused variable

* Start warning users not running Java 21

* Update tests, temporarily remove NumericRanges test

* Remove duplicate advanced section from Geyser dump

* Address some "reviews"

* yeet md5 hash from geyser dump

* Add info about number of resource packs / amount of mappings into Geyser dump

* Re-enable invalid config loading test

* Fix: allow-custom-skulls migration

* Fix test

* Add "enable-emotes" configuration option

* Rename "emotes-enabled" to "show-emotes"

* Only enable integrated pack when optional pack isn't present

* Update integrated pack

* Exclude jackson annotations, remove leftover debug print

* Remove one-time config migration warnings as we don't have access to the logger at that stage

* Throw more detailed descriptive error when loading resource packs from the "packs" folder, add another legacy config test

* Fix NeoForge's fun module conflict

* Re-add warning about moved functionality, fix Geyser-ViaProxy

This reverts commit fbadfa574a.

* oops

* Move GeyserLegacyPingPassthrough to separate thread to avoid Standalone command locking issues

---------

Co-authored-by: Konicai <71294714+Konicai@users.noreply.github.com>
Co-authored-by: chris <github@onechris.mozmail.com>
Co-authored-by: Eclipse <eclipse@eclipseisoffline.xyz>
Co-authored-by: Aurora <auroranova8756@gmail.com>
This commit is contained in:
Camotoy
2025-11-18 11:55:12 -05:00
committed by GitHub
parent 48bf0942e9
commit 765128ce42
157 changed files with 8006 additions and 2670 deletions

View File

@@ -31,11 +31,13 @@ import lombok.Setter;
import net.minecraft.server.MinecraftServer;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.geysermc.geyser.FloodgateKeyLoader;
import org.geysermc.geyser.GeyserBootstrap;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.GeyserLogger;
import org.geysermc.geyser.api.util.PlatformType;
import org.geysermc.geyser.command.CommandRegistry;
import org.geysermc.geyser.configuration.GeyserConfiguration;
import org.geysermc.geyser.configuration.GeyserPluginConfig;
import org.geysermc.geyser.dump.BootstrapDumpInfo;
import org.geysermc.geyser.level.WorldManager;
import org.geysermc.geyser.ping.GeyserLegacyPingPassthrough;
@@ -43,14 +45,10 @@ import org.geysermc.geyser.ping.IGeyserPingPassthrough;
import org.geysermc.geyser.platform.mod.platform.GeyserModPlatform;
import org.geysermc.geyser.platform.mod.world.GeyserModWorldManager;
import org.geysermc.geyser.text.GeyserLocale;
import org.geysermc.geyser.util.FileUtils;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.SocketAddress;
import java.nio.file.Path;
import java.util.UUID;
@RequiredArgsConstructor
public abstract class GeyserModBootstrap implements GeyserBootstrap {
@@ -69,7 +67,7 @@ public abstract class GeyserModBootstrap implements GeyserBootstrap {
@Setter
private CommandRegistry commandRegistry;
private GeyserModConfiguration geyserConfig;
private GeyserPluginConfig geyserConfig;
private GeyserModInjector geyserInjector;
private final GeyserModLogger geyserLogger = new GeyserModLogger();
private IGeyserPingPassthrough geyserPingPassthrough;
@@ -80,12 +78,11 @@ public abstract class GeyserModBootstrap implements GeyserBootstrap {
instance = this;
dataFolder = this.platform.dataFolder(this.platform.configPath());
GeyserLocale.init(this);
if (!loadConfig()) {
geyserConfig = loadConfig(GeyserPluginConfig.class);
if (geyserConfig == null) {
return;
}
this.geyserLogger.setDebug(geyserConfig.isDebugMode());
GeyserConfiguration.checkGeyserConfiguration(geyserConfig, geyserLogger);
this.geyser = GeyserImpl.load(this.platform.platformType(), this);
this.geyser = GeyserImpl.load(this);
}
public void onGeyserEnable() {
@@ -95,16 +92,15 @@ public abstract class GeyserModBootstrap implements GeyserBootstrap {
}
if (GeyserImpl.getInstance().isReloading()) {
if (!loadConfig()) {
geyserConfig = loadConfig(GeyserPluginConfig.class);
if (geyserConfig == null) {
return;
}
this.geyserLogger.setDebug(geyserConfig.isDebugMode());
GeyserConfiguration.checkGeyserConfiguration(geyserConfig, geyserLogger);
}
GeyserImpl.start();
if (geyserConfig.isLegacyPingPassthrough()) {
if (!geyserConfig.motd().integratedPingPassthrough()) {
this.geyserPingPassthrough = GeyserLegacyPingPassthrough.init(geyser);
} else {
this.geyserPingPassthrough = new ModPingPassthrough(server, geyserLogger);
@@ -145,7 +141,12 @@ public abstract class GeyserModBootstrap implements GeyserBootstrap {
}
@Override
public GeyserModConfiguration getGeyserConfig() {
public @NonNull PlatformType platformType() {
return this.platform.platformType();
}
@Override
public GeyserPluginConfig config() {
return geyserConfig;
}
@@ -199,12 +200,7 @@ public abstract class GeyserModBootstrap implements GeyserBootstrap {
@Override
public int getServerPort() {
if (isServer()) {
return ((GeyserServerPortGetter) server).geyser$getServerPort();
} else {
// Set in the IntegratedServerMixin
return geyserConfig.getRemote().port();
}
return ((GeyserServerPortGetter) server).geyser$getServerPort();
}
public abstract boolean isServer();
@@ -214,31 +210,23 @@ public abstract class GeyserModBootstrap implements GeyserBootstrap {
return this.platform.testFloodgatePluginPresent(this);
}
private Path floodgateKeyPath;
public void loadFloodgate(Path floodgateDataFolder) {
floodgateKeyPath = FloodgateKeyLoader.getKeyPath(geyserConfig, floodgateDataFolder, dataFolder, geyserLogger);
}
@Override
public Path getFloodgateKeyPath() {
return floodgateKeyPath;
}
@Nullable
@Override
public InputStream getResourceOrNull(String resource) {
return this.platform.resolveResource(resource);
}
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
private boolean loadConfig() {
try {
if (!dataFolder.toFile().exists()) {
//noinspection ResultOfMethodCallIgnored
dataFolder.toFile().mkdir();
}
File configFile = FileUtils.fileOrCopiedFromResource(dataFolder.resolve("config.yml").toFile(), "config.yml",
(x) -> x.replaceAll("generateduuid", UUID.randomUUID().toString()), this);
this.geyserConfig = FileUtils.loadConfig(configFile, GeyserModConfiguration.class);
return true;
} catch (IOException ex) {
geyserLogger.error(GeyserLocale.getLocaleStringLog("geyser.config.failed"), ex);
ex.printStackTrace();
return false;
}
}
@Override
public @NonNull String getServerPlatform() {
return server.getServerModName();

View File

@@ -1,48 +0,0 @@
/*
* Copyright (c) 2019-2022 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.platform.mod;
import com.fasterxml.jackson.annotation.JsonIgnore;
import org.geysermc.geyser.FloodgateKeyLoader;
import org.geysermc.geyser.configuration.GeyserJacksonConfiguration;
import java.nio.file.Path;
public class GeyserModConfiguration extends GeyserJacksonConfiguration {
@JsonIgnore
private Path floodgateKeyPath;
public void loadFloodgate(GeyserModBootstrap geyser, Path floodgateDataFolder) {
Path geyserDataFolder = geyser.getConfigFolder();
floodgateKeyPath = FloodgateKeyLoader.getKeyPath(this, floodgateDataFolder, geyserDataFolder, geyser.getGeyserLogger());
}
@Override
public Path getFloodgateKeyPath() {
return floodgateKeyPath;
}
}

View File

@@ -96,7 +96,7 @@ public class GeyserModInjector extends GeyserInjector {
int index = ch.pipeline().names().indexOf("encoder");
String baseName = index != -1 ? "encoder" : "outbound_config";
if (bootstrap.getGeyserConfig().isDisableCompression()) {
if (bootstrap.config().advanced().java().disableCompression()) {
ch.pipeline().addAfter(baseName, "geyser-compression-disabler", new GeyserModCompressionDisabler());
}
}
@@ -125,7 +125,7 @@ public class GeyserModInjector extends GeyserInjector {
childHandler = (ChannelInitializer<Channel>) childHandlerField.get(handler);
break;
} catch (Exception e) {
if (bootstrap.getGeyserConfig().isDebugMode()) {
if (bootstrap.config().debugMode()) {
bootstrap.getGeyserLogger().debug("The handler " + name + " isn't a ChannelInitializer. THIS ERROR IS SAFE TO IGNORE!");
e.printStackTrace();
}

View File

@@ -34,7 +34,7 @@ import org.geysermc.geyser.util.VersionCheckUtils;
public final class GeyserModUpdateListener {
public static void onPlayReady(ServerPlayer player) {
// We could just not register the listener, but, this allows config reloading
if (GeyserImpl.getInstance().getConfig().isNotifyOnNewBedrockUpdate()) {
if (GeyserImpl.getInstance().config().notifyOnNewBedrockUpdate()) {
// Should be creating this in the supplier, but we need it for the permission check.
// Not a big deal currently because ModCommandSource doesn't load locale, so don't need to try to wait for it.
ModCommandSource source = new ModCommandSource(player.createCommandSourceStack());

View File

@@ -56,14 +56,13 @@ public class IntegratedServerMixin implements GeyserServerPortGetter {
// If the LAN is opened, starts Geyser.
GeyserModBootstrap instance = GeyserModBootstrap.getInstance();
instance.setServer((MinecraftServer) (Object) this);
instance.getGeyserConfig().getRemote().setPort(port);
instance.onGeyserEnable();
// Ensure player locale has been loaded, in case it's different from Java system language
GeyserLocale.loadGeyserLocale(this.minecraft.options.languageCode);
// Give indication that Geyser is loaded
Objects.requireNonNull(this.minecraft.player);
this.minecraft.player.displayClientMessage(Component.literal(GeyserLocale.getPlayerLocaleString("geyser.core.start",
this.minecraft.options.languageCode, "localhost", String.valueOf(GeyserImpl.getInstance().bedrockListener().port()))), false);
this.minecraft.player.displayClientMessage(Component.literal(GeyserLocale.getPlayerLocaleString("geyser.core.start.ip_suppressed",
this.minecraft.options.languageCode, String.valueOf(GeyserImpl.getInstance().bedrockListener().port()))), false);
}
}