mirror of
https://github.com/GeyserMC/Geyser.git
synced 2026-01-06 15:41:50 +00:00
Back to one config file
This commit is contained in:
@@ -191,7 +191,7 @@ public class GeyserBungeeInjector extends GeyserInjector implements Listener {
|
||||
}
|
||||
initChannel.invoke(channelInitializer, ch);
|
||||
|
||||
if (bootstrap.config().advanced().disableCompression()) {
|
||||
if (bootstrap.config().disableCompression()) {
|
||||
ch.pipeline().addAfter(PipelineUtils.PACKET_ENCODER, "geyser-compression-disabler",
|
||||
new GeyserBungeeCompressionDisabler());
|
||||
}
|
||||
|
||||
@@ -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.config().advanced().disableCompression()) {
|
||||
if (bootstrap.config().disableCompression()) {
|
||||
ch.pipeline().addAfter(baseName, "geyser-compression-disabler", new GeyserModCompressionDisabler());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ public class GeyserSpigotInjector extends GeyserInjector {
|
||||
int index = ch.pipeline().names().indexOf("encoder");
|
||||
String baseName = index != -1 ? "encoder" : "outbound_config";
|
||||
|
||||
if (bootstrap.config().advanced().disableCompression() && GeyserSpigotCompressionDisabler.ENABLED) {
|
||||
if (bootstrap.config().disableCompression() && GeyserSpigotCompressionDisabler.ENABLED) {
|
||||
ch.pipeline().addAfter(baseName, "geyser-compression-disabler", new GeyserSpigotCompressionDisabler());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -293,7 +293,7 @@ public class GeyserStandaloneBootstrap implements GeyserBootstrap {
|
||||
|
||||
@Override
|
||||
public Path getFloodgateKeyPath() {
|
||||
return Path.of(geyserConfig.advanced().floodgateKeyFile());
|
||||
return Path.of(geyserConfig.floodgateKeyFile());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -128,7 +128,7 @@ public class GeyserVelocityInjector extends GeyserInjector {
|
||||
protected void initChannel(@NonNull Channel ch) throws Exception {
|
||||
initChannel.invoke(channelInitializer, ch);
|
||||
|
||||
if (bootstrap.config().advanced().disableCompression() && GeyserVelocityCompressionDisabler.ENABLED) {
|
||||
if (bootstrap.config().disableCompression() && GeyserVelocityCompressionDisabler.ENABLED) {
|
||||
ch.pipeline().addAfter("minecraft-encoder", "geyser-compression-disabler",
|
||||
new GeyserVelocityCompressionDisabler());
|
||||
}
|
||||
|
||||
@@ -266,7 +266,7 @@ public class GeyserViaProxyPlugin extends ViaProxyPlugin implements GeyserBootst
|
||||
|
||||
@Override
|
||||
public Path getFloodgateKeyPath() {
|
||||
return new File(ROOT_FOLDER, geyserConfig.advanced().floodgateKeyFile()).toPath();
|
||||
return new File(ROOT_FOLDER, geyserConfig.floodgateKeyFile()).toPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -45,7 +45,7 @@ public class FloodgateKeyLoader {
|
||||
}
|
||||
}
|
||||
|
||||
Path floodgateKey = geyserDataFolder.resolve(config.advanced().floodgateKeyFile());
|
||||
Path floodgateKey = geyserDataFolder.resolve(config.floodgateKeyFile());
|
||||
|
||||
if (!Files.exists(floodgateKey)) {
|
||||
logger.error(GeyserLocale.getLocaleStringLog("geyser.bootstrap.floodgate.not_installed"));
|
||||
|
||||
@@ -316,7 +316,7 @@ public class GeyserImpl implements GeyserApi, EventRegistrar {
|
||||
logger.warning("If you do not know what this is, open the Geyser config, and set \"use-haproxy-protocol\" under the \"java\" section to \"false\".");
|
||||
}
|
||||
|
||||
if (config.advanced().disableXboxAuth()) {
|
||||
if (config.disableXboxAuth()) {
|
||||
logger.error("XBOX AUTHENTICATION IS DISABLED ON THIS GEYSER INSTANCE!");
|
||||
logger.error("While this allows using Bedrock edition proxies, it also opens up the ability for hackers to connect with any username they choose.");
|
||||
logger.error("To change this, set \"disable-xbox-auth\" to \"false\" in Geyser's config-advanced.yml file.");
|
||||
@@ -430,7 +430,7 @@ public class GeyserImpl implements GeyserApi, EventRegistrar {
|
||||
logger.debug("Found SRV record \"" + remoteAddress + ":" + remotePort + "\"");
|
||||
}
|
||||
}
|
||||
} else if (!config.advanced().useDirectConnection()) {
|
||||
} else if (!config.useDirectConnection()) {
|
||||
logger.warning("The use-direct-connection config option is deprecated. Please reach out to us on Discord if there's a reason it needs to be disabled.");
|
||||
}
|
||||
|
||||
@@ -448,7 +448,7 @@ public class GeyserImpl implements GeyserApi, EventRegistrar {
|
||||
|
||||
BedrockDimension.changeBedrockNetherId(config.netherRoofWorkaround()); // Apply End dimension ID workaround to Nether
|
||||
|
||||
int bedrockThreadCount = Integer.getInteger("Geyser.BedrockNetworkThreads", config.advanced().bedrockNetworkThreadCount());
|
||||
int bedrockThreadCount = Integer.getInteger("Geyser.BedrockNetworkThreads", config.bedrockNetworkThreadCount());
|
||||
if (bedrockThreadCount == -1) {
|
||||
// Copy the code from Netty's default thread count fallback
|
||||
bedrockThreadCount = Math.max(1, SystemPropertyUtil.getInt("io.netty.eventLoopThreads", NettyRuntime.availableProcessors() * 2));
|
||||
|
||||
@@ -1,146 +0,0 @@
|
||||
/*
|
||||
* 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.configuration;
|
||||
|
||||
import org.geysermc.geyser.Constants;
|
||||
import org.spongepowered.configurate.interfaces.meta.defaults.DefaultBoolean;
|
||||
import org.spongepowered.configurate.interfaces.meta.defaults.DefaultNumeric;
|
||||
import org.spongepowered.configurate.interfaces.meta.defaults.DefaultString;
|
||||
import org.spongepowered.configurate.objectmapping.ConfigSerializable;
|
||||
import org.spongepowered.configurate.objectmapping.meta.Comment;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@ConfigSerializable
|
||||
public interface AdvancedConfig {
|
||||
// Cannot be type File yet because we may want to hide it in plugin instances.
|
||||
@Comment("""
|
||||
Floodgate uses encryption to ensure use from authorized sources.
|
||||
This should point to the public key generated by Floodgate (BungeeCord, Spigot or Velocity)
|
||||
You can ignore this when not using Floodgate.
|
||||
If you're using a plugin version of Floodgate on the same server, the key will automatically be picked up from Floodgate.""")
|
||||
@DefaultString("key.pem")
|
||||
String floodgateKeyFile();
|
||||
|
||||
@Comment("""
|
||||
The maximum number of custom skulls to be displayed per player. Increasing this may decrease performance on weaker devices.
|
||||
Setting this to -1 will cause all custom skulls to be displayed regardless of distance or number.""")
|
||||
@DefaultNumeric(128)
|
||||
int maxVisibleCustomSkulls();
|
||||
|
||||
@Comment("The radius in blocks around the player in which custom skulls are displayed.")
|
||||
@DefaultNumeric(32)
|
||||
int customSkullRenderDistance();
|
||||
|
||||
@Comment("""
|
||||
Specify how many days player skin images will be cached to disk to save downloading them from the internet.
|
||||
A value of 0 is disabled. (Default: 0)""")
|
||||
int cacheImages();
|
||||
|
||||
@Comment("""
|
||||
Which item to use to mark unavailable slots in a Bedrock player inventory. Examples of this are the 2x2 crafting grid while in creative,
|
||||
or custom inventory menus with sizes different from the usual 3x9. A barrier block is the default item.
|
||||
This config option can be set to any Bedrock item identifier. If you want to set this to a custom item, make sure that you specify the item in the following format: "geyser_custom:<mapping-name>"
|
||||
""")
|
||||
@DefaultString("minecraft:barrier")
|
||||
String unusableSpaceBlock();
|
||||
|
||||
@Comment("""
|
||||
Geyser updates the Scoreboard after every Scoreboard packet, but when Geyser tries to handle
|
||||
a lot of scoreboard packets per second, this can cause serious lag.
|
||||
This option allows you to specify after how many Scoreboard packets per seconds
|
||||
the Scoreboard updates will be limited to four updates per second.""")
|
||||
@DefaultNumeric(20)
|
||||
int scoreboardPacketThreshold();
|
||||
|
||||
@Comment("""
|
||||
Whether Geyser should send team names in command suggestions.
|
||||
Disable this if you have a lot of teams used that you don't need as suggestions.
|
||||
""")
|
||||
@DefaultBoolean(true)
|
||||
boolean addTeamSuggestions();
|
||||
|
||||
@Comment("""
|
||||
The internet supports a maximum MTU of 1492 but could cause issues with packet fragmentation.
|
||||
1400 is the default.""")
|
||||
@DefaultNumeric(1400)
|
||||
int mtu();
|
||||
|
||||
@Comment("""
|
||||
This option can only be changed if SO_REUSEPORT is available on the system (Linux / macOS only).
|
||||
When this option is available, it is possible to modify how many times Geyser re-binds to the same port,
|
||||
thereby improving performance on multi-core systems with a lot of incoming connections.
|
||||
""")
|
||||
@DefaultNumeric(1)
|
||||
int listenCount();
|
||||
|
||||
@Comment("""
|
||||
This option specifies the amount of network threads in the Bedrock network event loop group.
|
||||
When set to -1, this count will be automatically determined based on the amount of available processors.""")
|
||||
@DefaultNumeric(-1)
|
||||
int bedrockNetworkThreadCount();
|
||||
|
||||
@Comment("""
|
||||
Whether to connect directly into the Java server without creating a TCP connection.
|
||||
This should only be disabled if a plugin that interfaces with packets or the network does not work correctly with Geyser.
|
||||
If enabled, the remote address and port sections are ignored.
|
||||
If disabled, expect performance decrease and latency increase.
|
||||
""")
|
||||
@DefaultBoolean(true)
|
||||
@PluginSpecific
|
||||
boolean useDirectConnection();
|
||||
|
||||
@Comment("""
|
||||
Whether Geyser should attempt to disable packet compression (from the Java Server to Geyser) for Bedrock players.
|
||||
This should be a benefit as there is no need to compress data when Java packets aren't being handled over the network.
|
||||
This requires use-direct-connection to be true.
|
||||
""")
|
||||
@DefaultBoolean(true)
|
||||
@PluginSpecific
|
||||
boolean disableCompression();
|
||||
|
||||
@Comment("""
|
||||
This option disables the auth step Geyser performs for connecting Bedrock players.
|
||||
It can be used to allow connections from ProxyPass and WaterdogPE. In these cases, make sure that users
|
||||
cannot directly connect to this Geyser instance. See https://www.spigotmc.org/wiki/firewall-guide/ for
|
||||
assistance - and use UDP instead of TCP.
|
||||
Disabling Xbox authentication for other use-cases is NOT SUPPORTED, as it allows anyone to spoof usernames,
|
||||
and is therefore a security risk. All Floodgate functionality (including skin uploading and account linking) will also not work when Xbox auth is disabled.
|
||||
""")
|
||||
// if u have offline mode enabled pls be safe
|
||||
boolean disableXboxAuth();
|
||||
|
||||
@Comment("The bstats metrics uuid. Do not touch!")
|
||||
@ExcludePlatform(platforms = {"BungeeCord", "Spigot", "Velocity"}) // bStats platform versions used
|
||||
default UUID metricsUuid() {
|
||||
return UUID.randomUUID();
|
||||
}
|
||||
|
||||
@Comment("Do not touch!")
|
||||
default int version() {
|
||||
return Constants.ADVANCED_CONFIG_VERSION;
|
||||
}
|
||||
}
|
||||
@@ -26,27 +26,22 @@
|
||||
package org.geysermc.geyser.configuration;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.checkerframework.common.returnsreceiver.qual.This;
|
||||
import org.geysermc.geyser.Constants;
|
||||
import org.geysermc.geyser.GeyserBootstrap;
|
||||
import org.geysermc.geyser.api.util.PlatformType;
|
||||
import org.geysermc.geyser.text.GeyserLocale;
|
||||
import org.spongepowered.configurate.CommentedConfigurationNode;
|
||||
import org.spongepowered.configurate.ConfigurationNode;
|
||||
import org.spongepowered.configurate.NodePath;
|
||||
import org.spongepowered.configurate.interfaces.InterfaceDefaultOptions;
|
||||
import org.spongepowered.configurate.objectmapping.meta.Processor;
|
||||
import org.spongepowered.configurate.transformation.ConfigurationTransformation;
|
||||
import org.spongepowered.configurate.yaml.NodeStyle;
|
||||
import org.spongepowered.configurate.yaml.YamlConfigurationLoader;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Stream;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.checkerframework.common.returnsreceiver.qual.This;
|
||||
import org.geysermc.geyser.GeyserBootstrap;
|
||||
import org.geysermc.geyser.api.util.PlatformType;
|
||||
import org.geysermc.geyser.text.GeyserLocale;
|
||||
import org.spongepowered.configurate.CommentedConfigurationNode;
|
||||
import org.spongepowered.configurate.interfaces.InterfaceDefaultOptions;
|
||||
import org.spongepowered.configurate.objectmapping.meta.Processor;
|
||||
import org.spongepowered.configurate.transformation.ConfigurationTransformation;
|
||||
import org.spongepowered.configurate.yaml.NodeStyle;
|
||||
import org.spongepowered.configurate.yaml.YamlConfigurationLoader;
|
||||
|
||||
import static org.spongepowered.configurate.NodePath.path;
|
||||
import static org.spongepowered.configurate.transformation.TransformAction.remove;
|
||||
@@ -67,15 +62,6 @@ public final class ConfigLoader {
|
||||
In most cases, especially with server hosting providers, further hosting-specific configuration is required.
|
||||
--------------------------------""";
|
||||
|
||||
private static final String ADVANCED_HEADER = """
|
||||
--------------------------------
|
||||
Geyser ADVANCED Configuration File
|
||||
|
||||
In most cases, you do *not* need to mess with this file to get Geyser running.
|
||||
Tread with caution.
|
||||
--------------------------------
|
||||
""";
|
||||
|
||||
/**
|
||||
* Only nullable for testing.
|
||||
*/
|
||||
@@ -138,7 +124,7 @@ public final class ConfigLoader {
|
||||
}
|
||||
|
||||
private <T extends GeyserConfig> T load0(Class<T> configClass) throws IOException {
|
||||
var loader = createLoader(configFile, HEADER);
|
||||
var loader = createLoader(configFile);
|
||||
|
||||
CommentedConfigurationNode node = loader.load();
|
||||
boolean originallyEmpty = !configFile.exists() || node.isNull();
|
||||
@@ -216,29 +202,17 @@ public final class ConfigLoader {
|
||||
CommentedConfigurationNode newRoot = CommentedConfigurationNode.root(loader.defaultOptions());
|
||||
newRoot.set(config);
|
||||
|
||||
// Create the path in a way that Standalone changing the config name will be fine.
|
||||
int extensionIndex = configFile.getName().lastIndexOf(".");
|
||||
File advancedConfigPath = new File(configFile.getParent(), configFile.getName().substring(0, extensionIndex) + "-advanced" + configFile.getName().substring(extensionIndex));
|
||||
AdvancedConfig advancedConfig = null;
|
||||
|
||||
if (originallyEmpty || currentVersion != newVersion) {
|
||||
|
||||
if (!originallyEmpty && currentVersion > 4) {
|
||||
// Only copy comments over if the file already existed, and we are going to replace it
|
||||
|
||||
// Second case: Version 4 is pre-configurate where there were commented out nodes.
|
||||
// These get treated as comments on lower nodes, which produces very undesirable results.
|
||||
|
||||
ConfigurationCommentMover.moveComments(node, newRoot);
|
||||
} else if (currentVersion <= 4) {
|
||||
advancedConfig = migrateToAdvancedConfig(advancedConfigPath, node);
|
||||
}
|
||||
|
||||
loader.save(newRoot);
|
||||
}
|
||||
if (advancedConfig == null) {
|
||||
advancedConfig = loadAdvancedConfig(advancedConfigPath);
|
||||
}
|
||||
|
||||
if (transformer != null) {
|
||||
// We transform AFTER saving so that these specific transformations aren't applied to file.
|
||||
@@ -246,8 +220,6 @@ public final class ConfigLoader {
|
||||
config = newRoot.get(configClass);
|
||||
}
|
||||
|
||||
config.advanced(advancedConfig);
|
||||
|
||||
if (this.bootstrap != null) { // Null for testing only.
|
||||
this.bootstrap.getGeyserLogger().setDebug(config.debugMode());
|
||||
}
|
||||
@@ -255,53 +227,7 @@ public final class ConfigLoader {
|
||||
return config;
|
||||
}
|
||||
|
||||
private AdvancedConfig migrateToAdvancedConfig(File file, ConfigurationNode configRoot) throws IOException {
|
||||
Stream<NodePath> copyFromOldConfig = Stream.of("max-visible-custom-skulls", "custom-skull-render-distance", "scoreboard-packet-threshold", "mtu",
|
||||
"floodgate-key-file", "use-direct-connection", "disable-compression", "disableXboxAuth")
|
||||
.map(NodePath::path);
|
||||
|
||||
var loader = createLoader(file, ADVANCED_HEADER);
|
||||
|
||||
CommentedConfigurationNode advancedNode = CommentedConfigurationNode.root(loader.defaultOptions());
|
||||
copyFromOldConfig.forEach(path -> {
|
||||
ConfigurationNode node = configRoot.node(path);
|
||||
if (!node.virtual()) {
|
||||
advancedNode.node(path).mergeFrom(node);
|
||||
configRoot.removeChild(path);
|
||||
}
|
||||
});
|
||||
|
||||
ConfigurationNode metricsUuid = configRoot.node("metrics", "uuid");
|
||||
if (!metricsUuid.virtual()) {
|
||||
advancedNode.node("metrics-uuid").set(metricsUuid.get(UUID.class));
|
||||
}
|
||||
|
||||
advancedNode.node("version").set(Constants.ADVANCED_CONFIG_VERSION);
|
||||
|
||||
AdvancedConfig advancedConfig = advancedNode.get(AdvancedConfig.class);
|
||||
// Ensure all fields get populated
|
||||
CommentedConfigurationNode newNode = CommentedConfigurationNode.root(loader.defaultOptions());
|
||||
newNode.set(advancedConfig);
|
||||
loader.save(newNode);
|
||||
return advancedConfig;
|
||||
}
|
||||
|
||||
private AdvancedConfig loadAdvancedConfig(File file) throws IOException {
|
||||
var loader = createLoader(file, ADVANCED_HEADER);
|
||||
if (file.exists()) {
|
||||
ConfigurationNode node = loader.load();
|
||||
return node.get(AdvancedConfig.class);
|
||||
} else {
|
||||
ConfigurationNode node = CommentedConfigurationNode.root(loader.defaultOptions());
|
||||
node.node("version").set(Constants.ADVANCED_CONFIG_VERSION);
|
||||
AdvancedConfig advancedConfig = node.get(AdvancedConfig.class);
|
||||
node.set(advancedConfig);
|
||||
loader.save(node);
|
||||
return advancedConfig;
|
||||
}
|
||||
}
|
||||
|
||||
private YamlConfigurationLoader createLoader(File file, String header) {
|
||||
private YamlConfigurationLoader createLoader(File file) {
|
||||
return YamlConfigurationLoader.builder()
|
||||
.file(file)
|
||||
.indent(2)
|
||||
@@ -313,7 +239,7 @@ public final class ConfigLoader {
|
||||
}
|
||||
})
|
||||
.shouldCopyDefaults(false) // If we use ConfigurationNode#get(type, default), do not write the default back to the node.
|
||||
.header(header)
|
||||
.header(ConfigLoader.HEADER)
|
||||
.serializers(builder -> builder.register(new LowercaseEnumSerializer())))
|
||||
.build();
|
||||
}
|
||||
|
||||
@@ -25,6 +25,9 @@
|
||||
|
||||
package org.geysermc.geyser.configuration;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.geysermc.geyser.Constants;
|
||||
import org.geysermc.geyser.api.network.AuthType;
|
||||
@@ -35,7 +38,6 @@ import org.geysermc.geyser.text.AsteriskSerializer;
|
||||
import org.geysermc.geyser.text.GeyserLocale;
|
||||
import org.geysermc.geyser.util.CooldownUtils;
|
||||
import org.spongepowered.configurate.interfaces.meta.Exclude;
|
||||
import org.spongepowered.configurate.interfaces.meta.Field;
|
||||
import org.spongepowered.configurate.interfaces.meta.defaults.DefaultBoolean;
|
||||
import org.spongepowered.configurate.interfaces.meta.defaults.DefaultNumeric;
|
||||
import org.spongepowered.configurate.interfaces.meta.defaults.DefaultString;
|
||||
@@ -43,9 +45,6 @@ import org.spongepowered.configurate.interfaces.meta.range.NumericRange;
|
||||
import org.spongepowered.configurate.objectmapping.ConfigSerializable;
|
||||
import org.spongepowered.configurate.objectmapping.meta.Comment;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@ConfigSerializable
|
||||
public interface GeyserConfig {
|
||||
@Comment("Settings related to networking for the Bedrock listener.")
|
||||
@@ -188,16 +187,6 @@ public interface GeyserConfig {
|
||||
@ExcludePlatform(platforms = {"BungeeCord", "Spigot", "Velocity"}) // bStats platform versions used
|
||||
boolean enableMetrics();
|
||||
|
||||
/**
|
||||
* A separate config file added to this class manually.
|
||||
*/
|
||||
@Field
|
||||
@NonNull
|
||||
AdvancedConfig advanced();
|
||||
|
||||
@Field
|
||||
void advanced(AdvancedConfig config);
|
||||
|
||||
@ConfigSerializable
|
||||
interface BedrockConfig extends BedrockListener {
|
||||
@Override
|
||||
@@ -220,6 +209,7 @@ public interface GeyserConfig {
|
||||
@Override
|
||||
@Comment("""
|
||||
The port to broadcast to Bedrock clients with the MOTD that they should use to connect to the server.
|
||||
A value of 0 will broadcast the port specified above.
|
||||
DO NOT change this unless Geyser runs on a different port than the one that is used to connect.""")
|
||||
@DefaultNumeric(0)
|
||||
@NumericRange(from = 0, to = 65535)
|
||||
@@ -325,6 +315,109 @@ public interface GeyserConfig {
|
||||
}
|
||||
}
|
||||
|
||||
// Cannot be type File yet because we may want to hide it in plugin instances.
|
||||
@Comment("""
|
||||
Floodgate uses encryption to ensure use from authorized sources.
|
||||
This should point to the public key generated by Floodgate (BungeeCord, Spigot or Velocity)
|
||||
You can ignore this when not using Floodgate.
|
||||
If you're using a plugin version of Floodgate on the same server, the key will automatically be picked up from Floodgate.""")
|
||||
@DefaultString("key.pem")
|
||||
String floodgateKeyFile();
|
||||
|
||||
@Comment("""
|
||||
The maximum number of custom skulls to be displayed per player. Increasing this may decrease performance on weaker devices.
|
||||
Setting this to -1 will cause all custom skulls to be displayed regardless of distance or number.""")
|
||||
@DefaultNumeric(128)
|
||||
int maxVisibleCustomSkulls();
|
||||
|
||||
@Comment("The radius in blocks around the player in which custom skulls are displayed.")
|
||||
@DefaultNumeric(32)
|
||||
int customSkullRenderDistance();
|
||||
|
||||
@Comment("""
|
||||
Specify how many days player skin images will be cached to disk to save downloading them from the internet.
|
||||
A value of 0 is disabled. (Default: 0)""")
|
||||
int cacheImages();
|
||||
|
||||
@Comment("""
|
||||
Which item to use to mark unavailable slots in a Bedrock player inventory. Examples of this are the 2x2 crafting grid while in creative,
|
||||
or custom inventory menus with sizes different from the usual 3x9. A barrier block is the default item.
|
||||
This config option can be set to any Bedrock item identifier. If you want to set this to a custom item, make sure that you specify the item in the following format: "geyser_custom:<mapping-name>"
|
||||
""")
|
||||
@DefaultString("minecraft:barrier")
|
||||
String unusableSpaceBlock();
|
||||
|
||||
@Comment("""
|
||||
Geyser updates the Scoreboard after every Scoreboard packet, but when Geyser tries to handle
|
||||
a lot of scoreboard packets per second, this can cause serious lag.
|
||||
This option allows you to specify after how many Scoreboard packets per seconds
|
||||
the Scoreboard updates will be limited to four updates per second.""")
|
||||
@DefaultNumeric(20)
|
||||
int scoreboardPacketThreshold();
|
||||
|
||||
@Comment("""
|
||||
Whether Geyser should send team names in command suggestions.
|
||||
Disable this if you have a lot of teams used that you don't need as suggestions.
|
||||
""")
|
||||
@DefaultBoolean(true)
|
||||
boolean addTeamSuggestions();
|
||||
|
||||
@Comment("""
|
||||
The internet supports a maximum MTU of 1492 but could cause issues with packet fragmentation.
|
||||
1400 is the default.""")
|
||||
@DefaultNumeric(1400)
|
||||
int mtu();
|
||||
|
||||
@Comment("""
|
||||
This option can only be changed if SO_REUSEPORT is available on the system (Linux / macOS only).
|
||||
When this option is available, it is possible to modify how many times Geyser re-binds to the same port,
|
||||
thereby improving performance on multi-core systems with a lot of incoming connections.
|
||||
""")
|
||||
@DefaultNumeric(1)
|
||||
int listenCount();
|
||||
|
||||
@Comment("""
|
||||
This option specifies the amount of network threads in the Bedrock network event loop group.
|
||||
When set to -1, this count will be automatically determined based on the amount of available processors.""")
|
||||
@DefaultNumeric(-1)
|
||||
int bedrockNetworkThreadCount();
|
||||
|
||||
@Comment("""
|
||||
Whether to connect directly into the Java server without creating a TCP connection.
|
||||
This should only be disabled if a plugin that interfaces with packets or the network does not work correctly with Geyser.
|
||||
If enabled, the remote address and port sections are ignored.
|
||||
If disabled, expect performance decrease and latency increase.
|
||||
""")
|
||||
@DefaultBoolean(true)
|
||||
@PluginSpecific
|
||||
boolean useDirectConnection();
|
||||
|
||||
@Comment("""
|
||||
Whether Geyser should attempt to disable packet compression (from the Java Server to Geyser) for Bedrock players.
|
||||
This should be a benefit as there is no need to compress data when Java packets aren't being handled over the network.
|
||||
This requires use-direct-connection to be true.
|
||||
""")
|
||||
@DefaultBoolean(true)
|
||||
@PluginSpecific
|
||||
boolean disableCompression();
|
||||
|
||||
@Comment("""
|
||||
This option disables the auth step Geyser performs for connecting Bedrock players.
|
||||
It can be used to allow connections from ProxyPass and WaterdogPE. In these cases, make sure that users
|
||||
cannot directly connect to this Geyser instance. See https://www.spigotmc.org/wiki/firewall-guide/ for
|
||||
assistance - and use UDP instead of TCP.
|
||||
Disabling Xbox authentication for other use-cases is NOT SUPPORTED, as it allows anyone to spoof usernames,
|
||||
and is therefore a security risk. All Floodgate functionality (including skin uploading and account linking) will also not work when Xbox auth is disabled.
|
||||
""")
|
||||
// if u have offline mode enabled pls be safe
|
||||
boolean disableXboxAuth();
|
||||
|
||||
@Comment("The bstats metrics uuid. Do not touch!")
|
||||
@ExcludePlatform(platforms = {"BungeeCord", "Spigot", "Velocity"}) // bStats platform versions used
|
||||
default UUID metricsUuid() {
|
||||
return UUID.randomUUID();
|
||||
}
|
||||
|
||||
@Comment("Do not change!")
|
||||
@SuppressWarnings("unused")
|
||||
default int configVersion() {
|
||||
|
||||
@@ -113,7 +113,7 @@ public class DumpInfo {
|
||||
this.config = toGson(configNode);
|
||||
|
||||
ConfigurationNode advancedConfigNode = CommentedConfigurationNode.root(options);
|
||||
advancedConfigNode.set(geyser.config().advanced());
|
||||
advancedConfigNode.set(geyser.config());
|
||||
this.advancedConfig = toGson(advancedConfigNode);
|
||||
} catch (SerializationException e) {
|
||||
e.printStackTrace();
|
||||
|
||||
@@ -50,7 +50,7 @@ public abstract class GeyserInjector {
|
||||
* @param bootstrap the bootstrap of the Geyser instance.
|
||||
*/
|
||||
public void initializeLocalChannel(GeyserBootstrap bootstrap) {
|
||||
if (!bootstrap.config().advanced().useDirectConnection()) {
|
||||
if (!bootstrap.config().useDirectConnection()) {
|
||||
bootstrap.getGeyserLogger().debug("Disabling direct injection!");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ public final class GeyserServer {
|
||||
|
||||
public GeyserServer(GeyserImpl geyser, int threadCount) {
|
||||
this.geyser = geyser;
|
||||
this.listenCount = Bootstraps.isReusePortAvailable() ? Integer.getInteger("Geyser.ListenCount", geyser.config().advanced().listenCount()) : 1;
|
||||
this.listenCount = Bootstraps.isReusePortAvailable() ? Integer.getInteger("Geyser.ListenCount", geyser.config().listenCount()) : 1;
|
||||
GeyserImpl.getInstance().getLogger().debug("Listen thread count: " + listenCount);
|
||||
this.group = TRANSPORT.eventLoopGroupFactory().apply(listenCount, new DefaultThreadFactory("GeyserServer", true));
|
||||
this.childGroup = TRANSPORT.eventLoopGroupFactory().apply(threadCount, new DefaultThreadFactory("GeyserServerChild", true));
|
||||
@@ -220,7 +220,7 @@ public final class GeyserServer {
|
||||
|
||||
GeyserServerInitializer serverInitializer = new GeyserServerInitializer(this.geyser);
|
||||
playerGroup = serverInitializer.getEventLoopGroup();
|
||||
this.geyser.getLogger().debug("Setting MTU to " + this.geyser.config().advanced().mtu());
|
||||
this.geyser.getLogger().debug("Setting MTU to " + this.geyser.config().mtu());
|
||||
|
||||
int rakPacketLimit = positivePropOrDefault("Geyser.RakPacketLimit", DEFAULT_PACKET_LIMIT);
|
||||
this.geyser.getLogger().debug("Setting RakNet packet limit to " + rakPacketLimit);
|
||||
@@ -235,7 +235,7 @@ public final class GeyserServer {
|
||||
.channelFactory(RakChannelFactory.server(TRANSPORT.datagramChannelClass()))
|
||||
.group(group, childGroup)
|
||||
.option(RakChannelOption.RAK_HANDLE_PING, true)
|
||||
.option(RakChannelOption.RAK_MAX_MTU, this.geyser.config().advanced().mtu())
|
||||
.option(RakChannelOption.RAK_MAX_MTU, this.geyser.config().mtu())
|
||||
.option(RakChannelOption.RAK_PACKET_LIMIT, rakPacketLimit)
|
||||
.option(RakChannelOption.RAK_GLOBAL_PACKET_LIMIT, rakGlobalPacketLimit)
|
||||
.option(RakChannelOption.RAK_SEND_COOKIE, rakSendCookie)
|
||||
|
||||
@@ -81,7 +81,7 @@ import static org.geysermc.geyser.scoreboard.UpdateType.REMOVE;
|
||||
public final class Scoreboard {
|
||||
private static final boolean SHOW_SCOREBOARD_LOGS = Boolean.parseBoolean(System.getProperty("Geyser.ShowScoreboardLogs", "true"));
|
||||
private static final boolean ADD_TEAM_SUGGESTIONS = Boolean.parseBoolean(
|
||||
System.getProperty("Geyser.AddTeamSuggestions", String.valueOf(GeyserImpl.getInstance().config().advanced().addTeamSuggestions()))
|
||||
System.getProperty("Geyser.AddTeamSuggestions", String.valueOf(GeyserImpl.getInstance().config().addTeamSuggestions()))
|
||||
);
|
||||
|
||||
private final GeyserSession session;
|
||||
|
||||
@@ -47,7 +47,7 @@ public final class ScoreboardUpdater extends Thread {
|
||||
|
||||
static {
|
||||
GeyserConfig config = GeyserImpl.getInstance().config();
|
||||
FIRST_SCORE_PACKETS_PER_SECOND_THRESHOLD = Math.min(config.advanced().scoreboardPacketThreshold(), SECOND_SCORE_PACKETS_PER_SECOND_THRESHOLD);
|
||||
FIRST_SCORE_PACKETS_PER_SECOND_THRESHOLD = Math.min(config.scoreboardPacketThreshold(), SECOND_SCORE_PACKETS_PER_SECOND_THRESHOLD);
|
||||
DEBUG_ENABLED = config.debugMode();
|
||||
}
|
||||
|
||||
|
||||
@@ -66,11 +66,11 @@ public class SkullCache {
|
||||
|
||||
public SkullCache(GeyserSession session) {
|
||||
this.session = session;
|
||||
this.maxVisibleSkulls = session.getGeyser().config().advanced().maxVisibleCustomSkulls();
|
||||
this.maxVisibleSkulls = session.getGeyser().config().maxVisibleCustomSkulls();
|
||||
this.cullingEnabled = this.maxVisibleSkulls != -1;
|
||||
|
||||
// Normal skulls are not rendered beyond 64 blocks
|
||||
int distance = Math.min(session.getGeyser().config().advanced().customSkullRenderDistance(), 64);
|
||||
int distance = Math.min(session.getGeyser().config().customSkullRenderDistance(), 64);
|
||||
this.skullRenderDistanceSquared = distance * distance;
|
||||
}
|
||||
|
||||
|
||||
@@ -144,7 +144,7 @@ public class SkinProvider {
|
||||
|
||||
public static void registerCacheImageTask(GeyserImpl geyser) {
|
||||
// Schedule Daily Image Expiry if we are caching them
|
||||
if (geyser.config().advanced().cacheImages() > 0) {
|
||||
if (geyser.config().cacheImages() > 0) {
|
||||
geyser.getScheduledThread().scheduleAtFixedRate(() -> {
|
||||
File cacheFolder = GeyserImpl.getInstance().getBootstrap().getConfigFolder().resolve("cache").resolve("images").toFile();
|
||||
if (!cacheFolder.exists()) {
|
||||
@@ -152,7 +152,7 @@ public class SkinProvider {
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
final long expireTime = ((long) GeyserImpl.getInstance().config().advanced().cacheImages()) * ((long)1000 * 60 * 60 * 24);
|
||||
final long expireTime = ((long) GeyserImpl.getInstance().config().cacheImages()) * ((long)1000 * 60 * 60 * 24);
|
||||
for (File imageFile : Objects.requireNonNull(cacheFolder.listFiles())) {
|
||||
if (imageFile.lastModified() < System.currentTimeMillis() - expireTime) {
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
@@ -422,7 +422,7 @@ public class SkinProvider {
|
||||
GeyserImpl.getInstance().getLogger().debug("Downloaded " + imageUrl);
|
||||
|
||||
// Write to cache if we are allowed
|
||||
if (GeyserImpl.getInstance().config().advanced().cacheImages() > 0) {
|
||||
if (GeyserImpl.getInstance().config().cacheImages() > 0) {
|
||||
imageFile.getParentFile().mkdirs();
|
||||
try {
|
||||
ImageIO.write(image, "png", imageFile);
|
||||
|
||||
@@ -314,7 +314,7 @@ public class InventoryUtils {
|
||||
|
||||
private static ItemDefinition getUnusableSpaceBlockDefinition(int protocolVersion) {
|
||||
ItemMappings mappings = Registries.ITEMS.forVersion(protocolVersion);
|
||||
String unusableSpaceBlock = GeyserImpl.getInstance().config().advanced().unusableSpaceBlock();
|
||||
String unusableSpaceBlock = GeyserImpl.getInstance().config().unusableSpaceBlock();
|
||||
ItemDefinition itemDefinition = mappings.getDefinition(unusableSpaceBlock);
|
||||
|
||||
if (itemDefinition == null) {
|
||||
|
||||
@@ -66,7 +66,7 @@ public class LoginEncryptionUtils {
|
||||
|
||||
geyser.getLogger().debug(String.format("Is player data signed? %s", result.signed()));
|
||||
|
||||
if (!result.signed() && !session.getGeyser().config().advanced().disableXboxAuth()) {
|
||||
if (!result.signed() && !session.getGeyser().config().disableXboxAuth()) {
|
||||
session.disconnect(GeyserLocale.getLocaleStringLog("geyser.network.remote.invalid_xbox_account"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ public final class ProvidedMetricsPlatform implements MetricsPlatform {
|
||||
|
||||
@Override
|
||||
public String serverUuid() {
|
||||
return GeyserImpl.getInstance().config().advanced().metricsUuid().toString();
|
||||
return GeyserImpl.getInstance().config().metricsUuid().toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -51,9 +51,8 @@ public class GeyserMockContext {
|
||||
|
||||
var geyserImpl = context.mock(GeyserImpl.class);
|
||||
var config = context.mock(GeyserConfig.class);
|
||||
when(config.advanced()).thenReturn(context.mock(AdvancedConfig.class));
|
||||
|
||||
when(config.advanced().scoreboardPacketThreshold()).thenReturn(1_000);
|
||||
when(config.scoreboardPacketThreshold()).thenReturn(1_000);
|
||||
|
||||
when(geyserImpl.config()).thenReturn(config);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user