diff --git a/core/src/main/java/org/geysermc/geyser/configuration/GeyserConfig.java b/core/src/main/java/org/geysermc/geyser/configuration/GeyserConfig.java index e9074ceae..f3a98db10 100644 --- a/core/src/main/java/org/geysermc/geyser/configuration/GeyserConfig.java +++ b/core/src/main/java/org/geysermc/geyser/configuration/GeyserConfig.java @@ -31,6 +31,7 @@ import org.geysermc.geyser.api.network.AuthType; import org.geysermc.geyser.api.network.BedrockListener; import org.geysermc.geyser.api.network.RemoteServer; import org.geysermc.geyser.network.GameProtocol; +import org.geysermc.geyser.text.AsteriskSerializer; import org.geysermc.geyser.util.CooldownUtils; import org.spongepowered.configurate.interfaces.meta.Exclude; import org.spongepowered.configurate.interfaces.meta.Field; @@ -200,6 +201,7 @@ public interface GeyserConfig { Generally, you should only uncomment and change this if you want to limit what IPs can connect to your server.""") @NonNull @DefaultString("0.0.0.0") + @AsteriskSerializer.Asterisk String address(); @Override diff --git a/core/src/main/java/org/geysermc/geyser/configuration/GeyserRemoteConfig.java b/core/src/main/java/org/geysermc/geyser/configuration/GeyserRemoteConfig.java index 5c48c6b2f..67496e5a1 100644 --- a/core/src/main/java/org/geysermc/geyser/configuration/GeyserRemoteConfig.java +++ b/core/src/main/java/org/geysermc/geyser/configuration/GeyserRemoteConfig.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.configuration; +import org.geysermc.geyser.text.AsteriskSerializer; import org.spongepowered.configurate.interfaces.meta.defaults.DefaultNumeric; import org.spongepowered.configurate.interfaces.meta.defaults.DefaultString; import org.spongepowered.configurate.interfaces.meta.range.NumericRange; @@ -44,6 +45,7 @@ public interface GeyserRemoteConfig extends GeyserConfig { @Override @Comment("The IP address of the Java Edition server.") @DefaultString("127.0.0.1") + @AsteriskSerializer.Asterisk String address(); @Override diff --git a/core/src/main/java/org/geysermc/geyser/dump/DumpInfo.java b/core/src/main/java/org/geysermc/geyser/dump/DumpInfo.java index 489d9d86a..acb326d70 100644 --- a/core/src/main/java/org/geysermc/geyser/dump/DumpInfo.java +++ b/core/src/main/java/org/geysermc/geyser/dump/DumpInfo.java @@ -40,13 +40,17 @@ import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.api.GeyserApi; import org.geysermc.geyser.api.extension.Extension; import org.geysermc.geyser.configuration.AdvancedConfig; -import org.geysermc.geyser.configuration.GeyserConfig; import org.geysermc.geyser.network.GameProtocol; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.AsteriskSerializer; import org.geysermc.geyser.util.CpuUtils; import org.geysermc.geyser.util.FileUtils; import org.geysermc.geyser.util.WebUtils; +import org.spongepowered.configurate.CommentedConfigurationNode; +import org.spongepowered.configurate.ConfigurationNode; +import org.spongepowered.configurate.ConfigurationOptions; +import org.spongepowered.configurate.interfaces.InterfaceDefaultOptions; +import org.spongepowered.configurate.serialize.SerializationException; import java.io.File; import java.io.IOException; @@ -73,8 +77,8 @@ public class DumpInfo { private final Locale systemLocale; private final String systemEncoding; private final GitInfo gitInfo; - private final GeyserConfig config; - private final AdvancedConfig advancedConfig; + private Object config; + private Object advancedConfig; private final Object2IntMap userPlatforms; private final int connectionAttempts; private final HashInfo hashInfo; @@ -94,8 +98,24 @@ public class DumpInfo { this.gitInfo = new GitInfo(GeyserImpl.BUILD_NUMBER, GeyserImpl.COMMIT.substring(0, 7), GeyserImpl.COMMIT, GeyserImpl.BRANCH, GeyserImpl.REPOSITORY); - this.config = geyser.config(); - this.advancedConfig = geyser.config().advanced(); + try { + // Workaround for JsonAdapter not being allowed on methods + ConfigurationOptions options = InterfaceDefaultOptions.addTo(ConfigurationOptions.defaults(), builder -> + builder.addProcessor(AsteriskSerializer.Asterisk.class, String.class, AsteriskSerializer.CONFIGURATE_SERIALIZER)) + .shouldCopyDefaults(false); + + ConfigurationNode configNode = CommentedConfigurationNode.root(options); + configNode.set(geyser.config()); + this.config = configNode.get(geyser.config().getClass()); + + ConfigurationNode advancedConfigNode = CommentedConfigurationNode.root(options); + advancedConfigNode.set(geyser.config().advanced()); + this.advancedConfig = advancedConfigNode.get(AdvancedConfig.class); + } catch (SerializationException e) { + if (geyser.config().debugMode()) { + e.printStackTrace(); + } + } String md5Hash = "unknown"; String sha256Hash = "unknown"; @@ -110,7 +130,7 @@ public class DumpInfo { //noinspection UnstableApiUsage sha256Hash = byteSource.hash(Hashing.sha256()).toString(); } catch (Exception e) { - if (this.config.debugMode()) { + if (geyser.config().debugMode()) { e.printStackTrace(); } } diff --git a/core/src/main/java/org/geysermc/geyser/ping/GeyserPingInfo.java b/core/src/main/java/org/geysermc/geyser/ping/GeyserPingInfo.java index cff46d834..853fa6187 100644 --- a/core/src/main/java/org/geysermc/geyser/ping/GeyserPingInfo.java +++ b/core/src/main/java/org/geysermc/geyser/ping/GeyserPingInfo.java @@ -25,9 +25,16 @@ package org.geysermc.geyser.ping; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonParseException; +import com.google.gson.annotations.JsonAdapter; import lombok.Data; import org.checkerframework.checker.nullness.qual.Nullable; +import java.lang.reflect.Type; + /** * The structure of this class and its nested classes are specifically * designed for the format received by {@link GeyserLegacyPingPassthrough}. @@ -36,6 +43,7 @@ import org.checkerframework.checker.nullness.qual.Nullable; public class GeyserPingInfo { @Nullable + @JsonAdapter(DescriptionDeserializer.class) private String description; private Players players; @@ -69,4 +77,14 @@ public class GeyserPingInfo { this.online = online; } } + + /** + * So GSON does not complain how we are treating Description - it will be converted to a proper Component later. + */ + private static final class DescriptionDeserializer implements JsonDeserializer { + @Override + public String deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { + return json.toString(); + } + } } diff --git a/core/src/main/java/org/geysermc/geyser/text/AsteriskSerializer.java b/core/src/main/java/org/geysermc/geyser/text/AsteriskSerializer.java index 325eaccae..b34db2b99 100644 --- a/core/src/main/java/org/geysermc/geyser/text/AsteriskSerializer.java +++ b/core/src/main/java/org/geysermc/geyser/text/AsteriskSerializer.java @@ -29,7 +29,13 @@ import com.google.gson.JsonElement; import com.google.gson.JsonPrimitive; import com.google.gson.JsonSerializationContext; import com.google.gson.JsonSerializer; +import org.spongepowered.configurate.objectmapping.meta.Processor; +import org.spongepowered.configurate.serialize.SerializationException; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; import java.lang.reflect.Type; import java.net.InetAddress; @@ -47,7 +53,7 @@ public class AsteriskSerializer implements JsonSerializer { return new JsonPrimitive("***"); } - private boolean isSensitiveIp(String ip) { + private static boolean isSensitiveIp(String ip) { for (String address : NON_SENSITIVE_ADDRESSES) { if (address.equalsIgnoreCase(ip)) { return false; @@ -65,4 +71,21 @@ public class AsteriskSerializer implements JsonSerializer { return true; } + + public static Processor.Factory CONFIGURATE_SERIALIZER = (data, fieldType) -> (value, destination) -> { + if (showSensitive || !isSensitiveIp(value)) { + return; + } + try { + destination.set("***"); + } catch (SerializationException e) { + throw new RuntimeException(e); // Error over silently printing an IP address. + } + }; + + @Target({ElementType.FIELD, ElementType.METHOD}) + @Retention(RetentionPolicy.RUNTIME) + public @interface Asterisk { + + } }