非法 base64 字符 5b 保存自定义对象时出错

Illegal base64 character 5b Error when saving a custom object

我正在为我的世界 1.17 版编写一个 spigot 插件,并且刚刚学会了如何将序列化对象保存到 config.yml。我发现我也可以创建自定义可序列化对象,所以我做到了(我需要一个用于我的权限插件)。 现在,当我保存对象时,它保存了这个:

!!binary |-
    rO0ABXNyABpvcmcuYnVra2l0LnV0aWwuaW8uV3JhcHBlcvJQR+zxEm8FAgABTAADbWFwdAAPTGphdmEvdXRpbC9NYXA7eHBzcgA3Y29tLmdvb2dsZS5jb21tb24uY29sbGVjdC5JbW11dGFibGVCaU1hcCRTZXJpYWxpemVkRm9ybQAAAAAAAAAAAgAAeHIANWNvbS5nb29nbGUuY29tbW9uLmNvbGxlY3QuSW1tdXRhYmxlTWFwJFNlcmlhbGl6ZWRGb3JtAAAAAAAAAAACAAJbAARrZXlzdAATW0xqYXZhL2xhbmcvT2JqZWN0O1sABnZhbHVlc3EAfgAFeHB1cgATW0xqYXZhLmxhbmcuT2JqZWN0O5DOWJ8QcylsAgAAeHAAAAABdAACPT11cQB+AAcAAAABdAAnbmV0Lm5pbHVzbmlsdXMucGx1Z2luLnBlcm1pc3Npb25zLkdyb3Vw

我认为这是正确的,但是当我尝试反序列化它时出现此错误:

java.lang.IllegalArgumentException: Illegal base64 character 5b

Full Error:
 Could not pass event PlayerJoinEvent to CES-1.17 v1.0
org.bukkit.event.EventException: null
        at org.bukkit.plugin.java.JavaPluginLoader.execute(JavaPluginLoader.java:310) ~[spigot-1.17.jar:3159-Spigot-f773da8-887bc05]
        at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:70) ~[spigot-1.17.jar:3159-Spigot-f773da8-887bc05]
        at org.bukkit.plugin.SimplePluginManager.fireEvent(SimplePluginManager.java:589) ~[spigot-1.17.jar:3159-Spigot-f773da8-887bc05]
        at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:576) ~[spigot-1.17.jar:3159-Spigot-f773da8-887bc05]
        at net.minecraft.server.players.PlayerList.a(PlayerList.java:274) ~[spigot-1.17.jar:3159-Spigot-f773da8-887bc05]
        at net.minecraft.server.network.LoginListener.a(LoginListener.java:192) ~[spigot-1.17.jar:3159-Spigot-f773da8-887bc05]
        at net.minecraft.server.network.LoginListener.c(LoginListener.java:179) ~[spigot-1.17.jar:3159-Spigot-f773da8-887bc05]
        at net.minecraft.server.network.LoginListener.tick(LoginListener.java:74) ~[spigot-1.17.jar:3159-Spigot-f773da8-887bc05]
        at net.minecraft.network.NetworkManager.a(NetworkManager.java:246) ~[spigot-1.17.jar:3159-Spigot-f773da8-887bc05]
        at net.minecraft.server.network.ServerConnection.c(ServerConnection.java:172) ~[spigot-1.17.jar:3159-Spigot-f773da8-887bc05]
        at net.minecraft.server.MinecraftServer.b(MinecraftServer.java:1319) ~[spigot-1.17.jar:3159-Spigot-f773da8-887bc05]
        at net.minecraft.server.dedicated.DedicatedServer.b(DedicatedServer.java:436) ~[spigot-1.17.jar:3159-Spigot-f773da8-887bc05]
        at net.minecraft.server.MinecraftServer.a(MinecraftServer.java:1200) ~[spigot-1.17.jar:3159-Spigot-f773da8-887bc05]
        at net.minecraft.server.MinecraftServer.x(MinecraftServer.java:1027) ~[spigot-1.17.jar:3159-Spigot-f773da8-887bc05]
        at net.minecraft.server.MinecraftServer.lambda[=11=](MinecraftServer.java:307) ~[spigot-1.17.jar:3159-Spigot-f773da8-887bc05]
        at java.lang.Thread.run(Thread.java:831) [?:?]
Caused by: java.lang.IllegalArgumentException: Illegal base64 character 5b
        at java.util.Base64$Decoder.decode0(Base64.java:847) ~[?:?]
        at java.util.Base64$Decoder.decode(Base64.java:566) ~[?:?]
        at java.util.Base64$Decoder.decode(Base64.java:589) ~[?:?]
        at net.nilusnilus.plugin.main.config.CustomConfig.getSerialized(CustomConfig.java:101) ~[?:?]
        at net.nilusnilus.plugin.events.PlayerJoinEvent.onPlayerJoin(PlayerJoinEvent.java:35) ~[?:?]
        at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
        at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:78) ~[?:?]
        at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
        at java.lang.reflect.Method.invoke(Method.java:567) ~[?:?]
        at org.bukkit.plugin.java.JavaPluginLoader.execute(JavaPluginLoader.java:306) ~[spigot-1.17.jar:3159-Spigot-f773da8-887bc05]
        ... 15 more

PLayerJoinEvent 代码:

package net.nilusnilus.plugin.events;

import net.nilusnilus.plugin.main.Util;
import net.nilusnilus.plugin.main.config.ConfigHandler;
import net.nilusnilus.plugin.main.config.CustomConfig;
import net.nilusnilus.plugin.permissions.Group;
import net.nilusnilus.plugin.permissions.GroupLoader;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;

public class PlayerJoinEvent implements Listener {

    private GroupLoader groupLoader;

    public PlayerJoinEvent(GroupLoader groupLoader) {
        this.groupLoader = groupLoader;
    }

    @EventHandler
    public void onPlayerJoin(org.bukkit.event.player.PlayerJoinEvent event) {
        String join_message = ConfigHandler.join_message;
        CustomConfig players = ConfigHandler.players;
        Player player = event.getPlayer();
        String path = String.valueOf(player.getUniqueId());

        event.setJoinMessage(Util.format(join_message, true, "<player>", event.getPlayer().getDisplayName()));


        if(!players.contains(String.valueOf(player.getUniqueId()))) {
            Group defaultGroup = groupLoader.getDefault();
            players.setSerialized(path + ".group", defaultGroup);
        }

        Group group = (Group) players.getSerialized(path + ".group");
        player.setDisplayName(group.getPrefix() + player.getDisplayName());

    }

}

自定义配置代码:

package net.nilusnilus.plugin.main.config;

import net.nilusnilus.plugin.main.Main;
import net.nilusnilus.plugin.main.Util;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.util.io.BukkitObjectInputStream;
import org.bukkit.util.io.BukkitObjectOutputStream;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.Base64;

public class CustomConfig {

    private Main plugin;
    private File file;
    private FileConfiguration config;
    private String name;

    public CustomConfig(Main plugin, String name) {
        this.plugin = plugin;
        this.name = name;

        init();
    }

    private void init() {
        file = new File(plugin.getDataFolder(), name);

        // Check if the files doesn't exist
        if(!file.exists()) {
            try {
                /*
                * If it doesn't try copy the same file inside the resources folder
                * to the plugin data folder.
                */

                plugin.saveResource(name, false);
            } catch(Exception e) {
                /*
                * If there is no premade file, create a blank one.
                */

                try {
                    file.createNewFile();
                } catch (IOException ioException) {
                    ioException.printStackTrace();
                }
            }
        }

        // At the end, parse the file into an FileConfiguration object.

        config = YamlConfiguration.loadConfiguration(file);
    }

    public FileConfiguration get() {
        return config;
    }

    public void save() {
        try {
            config.save(file);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void set(String path, Object value) {
        config.set(path, value);

        save();
    }

    public Object get(String path) {
        return config.get(path);
    }

    public String getString(String path, boolean formatColor) {
        if(!formatColor) {
            return config.getString(path);
        } else {
            return Util.formatColor(config.getString(path));
        }
    }

    public boolean getBoolean(String path) {
        return config.getBoolean(path);
    }

    public boolean contains(String path) {
        return config.contains(path);
    }

    public Object getSerialized(String path) {
        try {
            String encoded = config.getString(path);
            byte[] deserialized = Base64.getDecoder().decode(encoded);

            ByteArrayInputStream inputStream1 = new ByteArrayInputStream(deserialized);
            BukkitObjectInputStream inputStream = new BukkitObjectInputStream(inputStream1);

            return inputStream.readObject();
        } catch(IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }

        return null;
    }

    public void setSerialized(String path, Object value) {
        try {
            ByteArrayOutputStream outputStream1 = new ByteArrayOutputStream();
            BukkitObjectOutputStream outputStream = new BukkitObjectOutputStream(outputStream1);

            outputStream.writeObject(value);
            outputStream.flush();

            byte[] serialized = outputStream1.toByteArray();
            String encoded = Base64.getEncoder().encodeToString(serialized);

            config.set(path, serialized);
            save();
        } catch(IOException e) {
            e.printStackTrace();
        }
    }

}

所以我尝试使用其他解码方法,如 Base64.getMimeDecoder() 或 Base64.getUrlDecoder() 但它仍然不起作用。经过一些谷歌搜索后,我发现当 byte[] 不是 4 的倍数时,Base64 会抛出这个错误。但这一切都没有给我一个解决方法的线索。

我认为问题是你需要改变

config.set(path, serialized);

config.set(path, encoded);