More changes and migrations away from Jackson

This commit is contained in:
Camotoy 2024-07-09 12:26:27 -04:00
parent c095c276ef
commit ab4cc97b38
No known key found for this signature in database
GPG key ID: 7EEFB66FE798081F
22 changed files with 65 additions and 172 deletions

View file

@ -39,7 +39,7 @@ import static org.spongepowered.configurate.NodePath.path;
import static org.spongepowered.configurate.transformation.TransformAction.remove;
import static org.spongepowered.configurate.transformation.TransformAction.rename;
public final class ConfigLoaderTemp {
public final class ConfigLoader {
private static final String HEADER = """
--------------------------------
Geyser Configuration File
@ -132,4 +132,7 @@ public final class ConfigLoaderTemp {
return config;
}
private ConfigLoader() {
}
}

View file

@ -1,50 +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.configuration;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import java.io.IOException;
public enum EmoteOffhandWorkaroundOption {
NO_EMOTES,
EMOTES_AND_OFFHAND,
DISABLED;
public static class Deserializer extends JsonDeserializer<EmoteOffhandWorkaroundOption> {
@Override
public EmoteOffhandWorkaroundOption deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
String value = p.getValueAsString();
return switch (value) {
case "no-emotes" -> NO_EMOTES;
case "emotes-and-offhand" -> EMOTES_AND_OFFHAND;
default -> DISABLED;
};
}
}
}

View file

@ -25,6 +25,7 @@
package org.geysermc.geyser.dump;
import com.google.gson.annotations.JsonAdapter;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.geysermc.geyser.GeyserImpl;
@ -55,7 +56,7 @@ public class BootstrapDumpInfo {
@AllArgsConstructor
public static class ListenerInfo {
@AsteriskSerializer.Asterisk(isIp = true)
@JsonAdapter(value = AsteriskSerializer.class)
public String ip;
public int port;
}

View file

@ -25,9 +25,6 @@
package org.geysermc.geyser.ping;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonSetter;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.Data;
import org.checkerframework.checker.nullness.qual.Nullable;
@ -36,7 +33,6 @@ import org.checkerframework.checker.nullness.qual.Nullable;
* designed for the format received by {@link GeyserLegacyPingPassthrough}.
*/
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class GeyserPingInfo {
@Nullable
@ -58,13 +54,7 @@ public class GeyserPingInfo {
this.players = new Players(maxPlayers, onlinePlayers);
}
@JsonSetter("description")
void setDescription(JsonNode description) {
this.description = description.toString();
}
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public static class Players {
private int max;

View file

@ -64,7 +64,7 @@ public class CustomSkullRegistryPopulator {
GeyserBootstrap bootstrap = GeyserImpl.getInstance().getBootstrap();
Path skullConfigPath = bootstrap.getConfigFolder().resolve("custom-skulls.yml");
File skullConfigFile = FileUtils.fileOrCopiedFromResource(skullConfigPath.toFile(), "custom-skulls.yml", Function.identity(), bootstrap);
skullConfig = FileUtils.loadConfigNew(skullConfigFile, GeyserCustomSkullConfiguration.class);
skullConfig = FileUtils.loadConfig(skullConfigFile, GeyserCustomSkullConfiguration.class);
} catch (IOException e) {
GeyserImpl.getInstance().getLogger().severe(GeyserLocale.getLocaleStringLog("geyser.config.failed"), e);
return;

View file

@ -25,76 +25,26 @@
package org.geysermc.geyser.text;
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import java.io.IOException;
import java.io.Serial;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.Optional;
public class AsteriskSerializer extends StdSerializer<Object> implements ContextualSerializer {
@Serial
private static final long serialVersionUID = 1L;
import java.lang.reflect.Type;
import java.net.InetAddress;
public class AsteriskSerializer implements JsonSerializer<String> {
public static final String[] NON_SENSITIVE_ADDRESSES = {"", "0.0.0.0", "localhost", "127.0.0.1", "auto", "unknown"};
public static boolean showSensitive = false;
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JsonSerialize(using = AsteriskSerializer.class)
public @interface Asterisk {
String value() default "***";
/**
* If true, this value will be shown if {@link #showSensitive} is true, or if the IP is determined to not be a public IP
*
* @return true if this should be analyzed and treated as an IP
*/
boolean isIp() default false;
}
String asterisk;
boolean isIp;
@SuppressWarnings("unused") // Used by Jackson for Geyser dumps
public AsteriskSerializer() {
super(Object.class);
}
public AsteriskSerializer(String asterisk, boolean isIp) {
super(Object.class);
this.asterisk = asterisk;
this.isIp = isIp;
}
@Override
public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty property) {
Optional<Asterisk> anno = Optional.ofNullable(property)
.map(prop -> prop.getAnnotation(Asterisk.class));
return new AsteriskSerializer(anno.map(Asterisk::value).orElse(null), anno.map(Asterisk::isIp).orElse(false));
}
@Override
public void serialize(Object obj, JsonGenerator gen, SerializerProvider prov) throws IOException {
if (isIp && (showSensitive || !isSensitiveIp((String) obj))) {
gen.writeObject(obj);
return;
public JsonElement serialize(String src, Type typeOfSrc, JsonSerializationContext context) {
if (showSensitive || !isSensitiveIp(src)) {
return new JsonPrimitive(src);
}
gen.writeString(asterisk);
return new JsonPrimitive("***");
}
private boolean isSensitiveIp(String ip) {
@ -103,6 +53,16 @@ public class AsteriskSerializer extends StdSerializer<Object> implements Context
return false;
}
}
try {
InetAddress address = InetAddress.getByName(ip);
if (address.isSiteLocalAddress() || address.isLoopbackAddress()) {
return false;
}
} catch (Exception e) {
// Ignore
}
return true;
}
}

View file

@ -25,11 +25,6 @@
package org.geysermc.geyser.util;
import com.fasterxml.jackson.annotation.JsonSetter;
import com.fasterxml.jackson.annotation.Nulls;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import org.geysermc.geyser.GeyserBootstrap;
import org.geysermc.geyser.GeyserImpl;
import org.spongepowered.configurate.ConfigurationNode;
@ -51,26 +46,8 @@ import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class FileUtils {
/**
* Load the given YAML file into the given class
*
* @param src File to load
* @param valueType Class to load file into
* @param <T> the type
* @return The data as the given class
* @throws IOException if the config could not be loaded
*/
public final class FileUtils {
public static <T> T loadConfig(File src, Class<T> valueType) throws IOException {
ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory())
// Allow inference of single values as arrays
.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
.setDefaultSetterInfo(JsonSetter.Value.forValueNulls(Nulls.AS_EMPTY));
return objectMapper.readValue(src, valueType);
}
public static <T> T loadConfigNew(File src, Class<T> valueType) throws IOException {
YamlConfigurationLoader loader = YamlConfigurationLoader.builder()
.file(src)
.build();
@ -257,4 +234,7 @@ public class FileUtils {
throw new RuntimeException(e);
}
}
private FileUtils() {
}
}

View file

@ -25,7 +25,6 @@
package org.geysermc.geyser.util;
import com.fasterxml.jackson.databind.JsonNode;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.stream.JsonReader;
@ -34,7 +33,11 @@ import org.geysermc.geyser.GeyserImpl;
import javax.naming.directory.Attribute;
import javax.naming.directory.InitialDirContext;
import java.io.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
@ -69,7 +72,7 @@ public class WebUtils {
}
/**
* Makes a web request to the given URL and returns the body as a {@link JsonNode}.
* Makes a web request to the given URL and returns the body as a {@link JsonObject}.
*
* @param reqURL URL to fetch
* @return the response as JSON