XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFEServerManager

【Java】我的世界XFE服务器管理器

公开
关注 0 Fork 0 Star 0
UTF-8
package com.xfestudio.xfeservermanager.core.spi;

import com.xfestudio.xfeservermanager.api.spi.WorldStateCodecAdapter;
import com.xfestudio.xfeservermanager.api.spi.WorldStateCodecException;
import com.xfestudio.xfeservermanager.api.world.WorldStateKind;
import com.xfestudio.xfeservermanager.api.world.WorldStatePayload;
import com.xfestudio.xfeservermanager.api.world.WorldStateView;
import com.xfestudio.xfeservermanager.api.util.ApiChecks;
import java.util.Collection;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

/** Selects capture codecs by priority and restore codecs by their stable codec id. */
public final class WorldStateCodecRegistry {
    private static final Comparator<WorldStateCodecAdapter> ORDER = Comparator
            .comparingInt(WorldStateCodecAdapter::priority).reversed()
            .thenComparing(codec -> codec.getClass().getName());

    private final List<WorldStateCodecAdapter> codecs;
    private final Map<String, WorldStateCodecAdapter> byId;

    public WorldStateCodecRegistry(Collection<? extends WorldStateCodecAdapter> codecs) {
        this.codecs = codecs.stream().sorted(ORDER).map(codec -> (WorldStateCodecAdapter) codec).toList();
        Map<String, WorldStateCodecAdapter> index = new LinkedHashMap<>();
        for (WorldStateCodecAdapter codec : this.codecs) {
            String id = codec.codecId().trim().toLowerCase(Locale.ROOT);
            if (id.isEmpty()) {
                throw new IllegalArgumentException("Codec ids must not be blank");
            }
            if (index.putIfAbsent(id, codec) != null) {
                throw new IllegalArgumentException("Duplicate world state codec id " + id);
            }
        }
        this.byId = Map.copyOf(index);
    }

    public WorldStatePayload encode(WorldStateView state) throws WorldStateCodecException {
        for (WorldStateCodecAdapter codec : codecs) {
            if (codec.supports(state.kind(), state.resourceId())) {
                WorldStatePayload encoded = codec.encode(state);
                if (!encoded.codecId().equals(codec.codecId().trim().toLowerCase(Locale.ROOT))) {
                    throw new WorldStateCodecException("Codec returned a payload with a different codec id");
                }
                return encoded;
            }
        }
        throw new WorldStateCodecException(
                "No codec supports " + state.kind() + " state for " + state.resourceId());
    }

    public WorldStateView decode(
            WorldStatePayload payload, WorldStateKind expectedKind, String expectedResourceId)
            throws WorldStateCodecException {
        String normalizedResourceId = ApiChecks.lowerIdentifier(expectedResourceId, "expectedResourceId");
        WorldStateCodecAdapter codec = byId.get(payload.codecId());
        if (codec == null) {
            throw new WorldStateCodecException("Codec is not installed: " + payload.codecId());
        }
        WorldStateView decoded = codec.decode(payload, expectedKind, normalizedResourceId);
        if (decoded.kind() != expectedKind
                || !decoded.resourceId().equals(normalizedResourceId)) {
            throw new WorldStateCodecException("Decoded state does not match the requested target");
        }
        return decoded;
    }

    public List<WorldStateCodecAdapter> codecs() {
        return codecs;
    }
}