mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-30 12:29:15 +00:00
重新设计
This commit is contained in:
@@ -2,8 +2,8 @@ package net.momirealms.craftengine.core.block;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import net.momirealms.craftengine.core.block.entity.render.element.BlockEntityElement;
|
||||
import net.momirealms.craftengine.core.block.entity.render.element.BlockEntityElementConfig;
|
||||
import net.momirealms.craftengine.core.block.entity.render.element.BlockEntityElementConfigs;
|
||||
@@ -16,54 +16,81 @@ import net.momirealms.craftengine.core.pack.ResourceLocation;
|
||||
import net.momirealms.craftengine.core.pack.model.generation.AbstractModelGenerator;
|
||||
import net.momirealms.craftengine.core.pack.model.generation.ModelGeneration;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.plugin.config.Config;
|
||||
import net.momirealms.craftengine.core.plugin.config.ConfigParser;
|
||||
import net.momirealms.craftengine.core.plugin.config.*;
|
||||
import net.momirealms.craftengine.core.plugin.context.event.EventFunctions;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedException;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
||||
import net.momirealms.craftengine.core.util.GsonHelper;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.MiscUtils;
|
||||
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||
import net.momirealms.craftengine.core.plugin.locale.TranslationManager;
|
||||
import net.momirealms.craftengine.core.util.*;
|
||||
import org.incendo.cloud.suggestion.Suggestion;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public abstract class AbstractBlockManager extends AbstractModelGenerator implements BlockManager {
|
||||
protected final BlockParser blockParser;
|
||||
// CraftEngine objects
|
||||
protected final BlockStateMappingParser blockStateMappingParser;
|
||||
// 根据id获取自定义方块
|
||||
protected final Map<Key, CustomBlock> byId = new HashMap<>();
|
||||
// Cached command suggestions
|
||||
// 缓存的指令建议
|
||||
protected final List<Suggestion> cachedSuggestions = new ArrayList<>();
|
||||
// Cached Namespace
|
||||
// 缓存的使用中的命名空间
|
||||
protected final Set<String> namespacesInUse = new HashSet<>();
|
||||
// for mod, real block id -> state models
|
||||
protected final Map<Key, JsonElement> modBlockStates = new HashMap<>();
|
||||
// A temporary map that stores the model path of a certain vanilla block state
|
||||
// 用于检测单个外观方块状态是否被绑定了不同模型
|
||||
protected final Map<Integer, JsonElement> tempVanillaBlockStateModels = new Int2ObjectOpenHashMap<>();
|
||||
// A temporary map used to detect whether the same block state corresponds to multiple models.
|
||||
protected final Map<Integer, Key> tempRegistryIdConflictMap = new Int2ObjectOpenHashMap<>();
|
||||
// A temporary map that converts the custom block registered on the server to the vanilla block ID.
|
||||
protected final Map<Integer, Integer> tempBlockAppearanceConvertor = new Int2IntOpenHashMap();
|
||||
// Used to store override information of json files
|
||||
// Map<方块类型, Map<方块状态NBT,模型>>,用于生成block state json
|
||||
protected final Map<Key, Map<String, JsonElement>> blockStateOverrides = new HashMap<>();
|
||||
// a reverted mapper
|
||||
// 用于生成mod使用的block state json
|
||||
protected final Map<Key, JsonElement> modBlockStateOverrides = new HashMap<>();
|
||||
// 根据外观查找真实状态,用于debug指令
|
||||
protected final Map<Integer, List<Integer>> appearanceToRealState = new Int2ObjectOpenHashMap<>();
|
||||
// 声音映射表,和使用了哪些视觉方块有关
|
||||
protected final Map<Key, Key> soundReplacements = new HashMap<>(512, 0.5f);
|
||||
// 用于note_block:0这样格式的自动分配
|
||||
protected final Map<Key, List<BlockStateWrapper>> blockStateArranger = new HashMap<>();
|
||||
// 全方块状态映射文件,用于网络包映射
|
||||
protected final int[] blockStateMappings;
|
||||
// 原版方块状态数量
|
||||
protected final int vanillaBlockStateCount;
|
||||
// 注册的大宝贝
|
||||
protected final DelegatingBlock[] customBlocks;
|
||||
protected final DelegatingBlockState[] customBlockStates;
|
||||
protected final Object[] customBlockHolders;
|
||||
// 自定义状态列表,会随着重载变化
|
||||
protected final ImmutableBlockState[] immutableBlockStates;
|
||||
// 原版方块的属性缓存
|
||||
protected final BlockSettings[] vanillaBlockSettings;
|
||||
|
||||
// client side block tags
|
||||
protected Map<Integer, List<String>> clientBoundTags = Map.of();
|
||||
protected Map<Integer, List<String>> previousClientBoundTags = Map.of();
|
||||
// Used to automatically arrange block states for strings such as minecraft:note_block:0
|
||||
protected Map<Key, List<Integer>> blockAppearanceArranger;
|
||||
protected Map<Key, List<Integer>> realBlockArranger;
|
||||
protected Map<Key, Integer> internalId2StateId;
|
||||
protected Map<Key, DelegatingBlock> registeredBlocks;
|
||||
|
||||
protected AbstractBlockManager(CraftEngine plugin) {
|
||||
protected AbstractBlockManager(CraftEngine plugin, int vanillaBlockStateCount, int customBlockCount) {
|
||||
super(plugin);
|
||||
this.vanillaBlockStateCount = vanillaBlockStateCount;
|
||||
this.blockParser = new BlockParser();
|
||||
this.blockStateMappingParser = new BlockStateMappingParser();
|
||||
this.customBlocks = new DelegatingBlock[customBlockCount];
|
||||
this.customBlockHolders = new Object[customBlockCount];
|
||||
this.customBlockStates = new DelegatingBlockState[customBlockCount];
|
||||
this.vanillaBlockSettings = new BlockSettings[vanillaBlockStateCount];
|
||||
this.immutableBlockStates = new ImmutableBlockState[customBlockCount];
|
||||
this.blockStateMappings = new int[customBlockCount + vanillaBlockStateCount];
|
||||
Arrays.fill(this.blockStateMappings, -1);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ImmutableBlockState getImmutableBlockStateUnsafe(int stateId) {
|
||||
return this.immutableBlockStates[stateId - this.vanillaBlockStateCount];
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public ImmutableBlockState getImmutableBlockState(int stateId) {
|
||||
if (!isVanillaBlockState(stateId)) {
|
||||
return this.immutableBlockStates[stateId - this.vanillaBlockStateCount];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -71,12 +98,15 @@ public abstract class AbstractBlockManager extends AbstractModelGenerator implem
|
||||
super.clearModelsToGenerate();
|
||||
this.clearCache();
|
||||
this.cachedSuggestions.clear();
|
||||
this.namespacesInUse.clear();
|
||||
this.blockStateOverrides.clear();
|
||||
this.modBlockStates.clear();
|
||||
this.modBlockStateOverrides.clear();
|
||||
this.byId.clear();
|
||||
this.previousClientBoundTags = this.clientBoundTags;
|
||||
this.clientBoundTags = new HashMap<>();
|
||||
this.soundReplacements.clear();
|
||||
this.blockStateArranger.clear();
|
||||
this.appearanceToRealState.clear();
|
||||
Arrays.fill(this.blockStateMappings, -1);
|
||||
Arrays.fill(this.immutableBlockStates, EmptyBlock.STATE);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -97,23 +127,39 @@ public abstract class AbstractBlockManager extends AbstractModelGenerator implem
|
||||
}
|
||||
|
||||
protected void addBlockInternal(Key id, CustomBlock customBlock) {
|
||||
this.byId.put(id, customBlock);
|
||||
// generate mod assets
|
||||
if (Config.generateModAssets()) {
|
||||
for (ImmutableBlockState state : customBlock.variantProvider().states()) {
|
||||
this.modBlockStates.put(getBlockOwnerId(state.customBlockState()), this.tempVanillaBlockStateModels.get(state.vanillaBlockState().registryId()));
|
||||
ExceptionCollector<LocalizedResourceConfigException> exceptionCollector = new ExceptionCollector<>();
|
||||
// 绑定外观状态等
|
||||
for (ImmutableBlockState state : customBlock.variantProvider().states()) {
|
||||
int internalId = state.customBlockState().registryId();
|
||||
int appearanceId = state.vanillaBlockState().registryId();
|
||||
int index = internalId - this.vanillaBlockStateCount;
|
||||
ImmutableBlockState previous = this.immutableBlockStates[index];
|
||||
// todo 应当提前判断位置
|
||||
if (previous != null && !previous.isEmpty()) {
|
||||
exceptionCollector.add(new LocalizedResourceConfigException("warning.config.block.state.bind_failed",
|
||||
state.toString(), previous.toString(), getBlockOwnerId(previous.customBlockState()).toString()));
|
||||
continue;
|
||||
}
|
||||
this.immutableBlockStates[index] = state;
|
||||
this.blockStateMappings[internalId] = appearanceId;
|
||||
this.appearanceToRealState.computeIfAbsent(appearanceId, k -> new IntArrayList()).add(internalId);
|
||||
// generate mod assets
|
||||
if (Config.generateModAssets()) {
|
||||
this.modBlockStateOverrides.put(getBlockOwnerId(state.customBlockState()), this.tempVanillaBlockStateModels.get(appearanceId));
|
||||
}
|
||||
}
|
||||
this.byId.put(id, customBlock);
|
||||
exceptionCollector.throwIfPresent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigParser parser() {
|
||||
return this.blockParser;
|
||||
public ConfigParser[] parsers() {
|
||||
return new ConfigParser[]{this.blockParser, this.blockStateMappingParser};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Key, JsonElement> modBlockStates() {
|
||||
return Collections.unmodifiableMap(this.modBlockStates);
|
||||
return Collections.unmodifiableMap(this.modBlockStateOverrides);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -126,13 +172,21 @@ public abstract class AbstractBlockManager extends AbstractModelGenerator implem
|
||||
return Collections.unmodifiableCollection(this.cachedSuggestions);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Key replaceSoundIfExist(Key id) {
|
||||
return this.soundReplacements.get(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Key, Key> soundReplacements() {
|
||||
return Collections.unmodifiableMap(this.soundReplacements);
|
||||
}
|
||||
|
||||
public Set<String> namespacesInUse() {
|
||||
return Collections.unmodifiableSet(this.namespacesInUse);
|
||||
}
|
||||
|
||||
protected void clearCache() {
|
||||
this.tempRegistryIdConflictMap.clear();
|
||||
this.tempBlockAppearanceConvertor.clear();
|
||||
this.tempVanillaBlockStateModels.clear();
|
||||
}
|
||||
|
||||
@@ -161,15 +215,55 @@ public abstract class AbstractBlockManager extends AbstractModelGenerator implem
|
||||
|
||||
protected abstract boolean isVanillaBlock(Key id);
|
||||
|
||||
protected abstract int getBlockRegistryId(Key id);
|
||||
|
||||
protected abstract String stateRegistryIdToStateSNBT(int id);
|
||||
|
||||
protected abstract Key getBlockOwnerId(int id);
|
||||
|
||||
protected abstract CustomBlock.Builder platformBuilder(Key id);
|
||||
|
||||
public class BlockParser implements ConfigParser {
|
||||
protected abstract void setVanillaBlockTags(Key id, List<String> tags);
|
||||
|
||||
public abstract int vanillaBlockStateCount();
|
||||
|
||||
public class BlockStateMappingParser implements SectionConfigParser {
|
||||
public static final String[] CONFIG_SECTION_NAME = new String[]{"block-state-mappings", "block-state-mapping"};
|
||||
|
||||
@Override
|
||||
public String[] sectionId() {
|
||||
return CONFIG_SECTION_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int loadingSequence() {
|
||||
return LoadingSequence.BLOCK_STATE_MAPPING;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseSection(Pack pack, Path path, Map<String, Object> section) throws LocalizedException {
|
||||
for (Map.Entry<String, Object> entry : section.entrySet()) {
|
||||
String before = entry.getKey();
|
||||
String after = entry.getValue().toString();
|
||||
// 先解析为唯一的wrapper
|
||||
BlockStateWrapper beforeState = createVanillaBlockState(before);
|
||||
BlockStateWrapper afterState = createVanillaBlockState(before);
|
||||
if (beforeState == null) {
|
||||
TranslationManager.instance().log("warning.config.block_state_mapping.invalid_state", path.toString(), before);
|
||||
return;
|
||||
}
|
||||
if (afterState == null) {
|
||||
TranslationManager.instance().log("warning.config.block_state_mapping.invalid_state", path.toString(), after);
|
||||
return;
|
||||
}
|
||||
int previous = AbstractBlockManager.this.blockStateMappings[beforeState.registryId()];
|
||||
if (previous != -1 && previous != afterState.registryId()) {
|
||||
TranslationManager.instance().log("warning.config.block_state_mapping.conflict", path.toString(), beforeState.toString(), afterState.toString(), BlockRegistryMirror.byId(previous).toString());
|
||||
return;
|
||||
}
|
||||
AbstractBlockManager.this.blockStateMappings[beforeState.registryId()] = afterState.registryId();
|
||||
AbstractBlockManager.this.blockStateArranger.computeIfAbsent(getBlockOwnerId(beforeState), k -> new ArrayList<>()).add(afterState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class BlockParser implements IdSectionConfigParser {
|
||||
public static final String[] CONFIG_SECTION_NAME = new String[]{"blocks", "block"};
|
||||
|
||||
@Override
|
||||
@@ -201,7 +295,7 @@ public abstract class AbstractBlockManager extends AbstractModelGenerator implem
|
||||
Object clientBoundTags = settings.get("client-bound-tags");
|
||||
if (clientBoundTags instanceof List<?> list) {
|
||||
List<String> clientSideTags = MiscUtils.getAsStringList(list).stream().filter(ResourceLocation::isValid).toList();
|
||||
AbstractBlockManager.this.clientBoundTags.put(getBlockRegistryId(id), clientSideTags);
|
||||
AbstractBlockManager.this.setVanillaBlockTags(id, clientSideTags);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -219,19 +313,16 @@ public abstract class AbstractBlockManager extends AbstractModelGenerator implem
|
||||
boolean singleState = !stateSection.containsKey("properties");
|
||||
// 单方块状态
|
||||
if (singleState) {
|
||||
int internalId = ResourceConfigUtils.getAsInt(ResourceConfigUtils.requireNonNullOrThrow(
|
||||
stateSection.get("id"), "warning.config.block.state.missing_real_id"), "id");
|
||||
int internalId = ResourceConfigUtils.getAsInt(ResourceConfigUtils.requireNonNullOrThrow(stateSection.get("id"), "warning.config.block.state.missing_real_id"), "id");
|
||||
// 获取原版外观的注册表id
|
||||
int appearanceId = pluginFormattedBlockStateToRegistryId(ResourceConfigUtils.requireNonEmptyStringOrThrow(
|
||||
stateSection.get("state"), "warning.config.block.state.missing_state"));
|
||||
BlockStateWrapper appearanceState = parsePluginFormattedBlockState(ResourceConfigUtils.requireNonEmptyStringOrThrow(stateSection.get("state"), "warning.config.block.state.missing_state"));
|
||||
Optional<BlockEntityElementConfig<? extends BlockEntityElement>[]> blockEntityRenderer = parseBlockEntityRender(stateSection.get("entity-renderer"));
|
||||
|
||||
// 为原版外观赋予外观模型并检查模型冲突
|
||||
this.arrangeModelForStateAndVerify(appearanceId, ResourceConfigUtils.get(stateSection, "model", "models"));
|
||||
this.arrangeModelForStateAndVerify(appearanceState, ResourceConfigUtils.get(stateSection, "model", "models"));
|
||||
// 设置参数
|
||||
properties = Map.of();
|
||||
appearances = Map.of("", new BlockStateAppearance(appearanceId, blockEntityRenderer));
|
||||
variants = Map.of("", new BlockStateVariant("", settings, getInternalBlockId(internalId, appearanceId)));
|
||||
appearances = Map.of("", new BlockStateAppearance(appearanceState, blockEntityRenderer));
|
||||
variants = Map.of("", new BlockStateVariant("", settings, getInternalBlockState(internalId)));
|
||||
}
|
||||
// 多方块状态
|
||||
else {
|
||||
@@ -239,10 +330,7 @@ public abstract class AbstractBlockManager extends AbstractModelGenerator implem
|
||||
appearances = parseBlockAppearances(ResourceConfigUtils.getAsMap(ResourceConfigUtils.requireNonNullOrThrow(stateSection.get("appearances"), "warning.config.block.state.missing_appearances"), "appearances"));
|
||||
variants = parseBlockVariants(
|
||||
ResourceConfigUtils.getAsMap(ResourceConfigUtils.requireNonNullOrThrow(stateSection.get("variants"), "warning.config.block.state.missing_variants"), "variants"),
|
||||
it -> {
|
||||
BlockStateAppearance blockStateAppearance = appearances.get(it);
|
||||
return blockStateAppearance == null ? -1 : blockStateAppearance.stateRegistryId();
|
||||
}, settings
|
||||
appearances::containsKey, settings
|
||||
);
|
||||
}
|
||||
|
||||
@@ -258,39 +346,35 @@ public abstract class AbstractBlockManager extends AbstractModelGenerator implem
|
||||
}
|
||||
|
||||
private Map<String, BlockStateVariant> parseBlockVariants(Map<String, Object> variantsSection,
|
||||
Function<String, Integer> appearanceValidator,
|
||||
Predicate<String> appearanceValidator,
|
||||
BlockSettings parentSettings) {
|
||||
Map<String, BlockStateVariant> variants = new HashMap<>();
|
||||
for (Map.Entry<String, Object> entry : variantsSection.entrySet()) {
|
||||
Map<String, Object> variantSection = ResourceConfigUtils.getAsMap(entry.getValue(), entry.getKey());
|
||||
String variantNBT = entry.getKey();
|
||||
String appearance = ResourceConfigUtils.requireNonEmptyStringOrThrow(variantSection.get("appearance"), "warning.config.block.state.variant.missing_appearance");
|
||||
int appearanceId = appearanceValidator.apply(appearance);
|
||||
if (appearanceId == -1) {
|
||||
if (!appearanceValidator.test(appearance)) {
|
||||
throw new LocalizedResourceConfigException("warning.config.block.state.variant.invalid_appearance", variantNBT, appearance);
|
||||
}
|
||||
int internalId = getInternalBlockId(ResourceConfigUtils.getAsInt(ResourceConfigUtils.requireNonNullOrThrow(variantSection.get("id"), "warning.config.block.state.missing_real_id"), "id"), appearanceId);
|
||||
BlockStateWrapper internalBlockState = getInternalBlockState(ResourceConfigUtils.getAsInt(ResourceConfigUtils.requireNonNullOrThrow(variantSection.get("id"), "warning.config.block.state.missing_real_id"), "id"));
|
||||
Map<String, Object> anotherSetting = ResourceConfigUtils.getAsMapOrNull(variantSection.get("settings"), "settings");
|
||||
variants.put(variantNBT, new BlockStateVariant(appearance, anotherSetting == null ? parentSettings : BlockSettings.ofFullCopy(parentSettings, anotherSetting), internalId));
|
||||
variants.put(variantNBT, new BlockStateVariant(appearance, anotherSetting == null ? parentSettings : BlockSettings.ofFullCopy(parentSettings, anotherSetting), internalBlockState));
|
||||
}
|
||||
return variants;
|
||||
}
|
||||
|
||||
private int getInternalBlockId(int internalId, int appearanceId) {
|
||||
Key baseBlock = getBlockOwnerId(appearanceId);
|
||||
Key internalBlockId = Key.of(Key.DEFAULT_NAMESPACE, baseBlock.value() + "_" + internalId);
|
||||
int internalBlockRegistryId = Optional.ofNullable(AbstractBlockManager.this.internalId2StateId.get(internalBlockId)).orElse(-1);
|
||||
if (internalBlockRegistryId == -1) {
|
||||
throw new LocalizedResourceConfigException("warning.config.block.state.invalid_real_id", internalBlockId.toString(), String.valueOf(availableAppearances(baseBlock) - 1));
|
||||
private BlockStateWrapper getInternalBlockState(int internalId) {
|
||||
if (internalId >= Config.serverSideBlocks()) {
|
||||
throw new LocalizedResourceConfigException("warning.config.block.state.invalid_real_id", BlockManager.createCustomBlockKey(internalId).asString(), String.valueOf(Config.serverSideBlocks() - 1));
|
||||
}
|
||||
return internalBlockRegistryId;
|
||||
return BlockRegistryMirror.byId(internalId + vanillaBlockStateCount());
|
||||
}
|
||||
|
||||
private Map<String, BlockStateAppearance> parseBlockAppearances(Map<String, Object> appearancesSection) {
|
||||
Map<String, BlockStateAppearance> appearances = new HashMap<>();
|
||||
for (Map.Entry<String, Object> entry : appearancesSection.entrySet()) {
|
||||
Map<String, Object> appearanceSection = ResourceConfigUtils.getAsMap(entry.getValue(), entry.getKey());
|
||||
int appearanceId = pluginFormattedBlockStateToRegistryId(ResourceConfigUtils.requireNonEmptyStringOrThrow(
|
||||
BlockStateWrapper appearanceId = parsePluginFormattedBlockState(ResourceConfigUtils.requireNonEmptyStringOrThrow(
|
||||
appearanceSection.get("state"), "warning.config.block.state.missing_state"));
|
||||
this.arrangeModelForStateAndVerify(appearanceId, ResourceConfigUtils.get(appearanceSection, "model", "models"));
|
||||
appearances.put(entry.getKey(), new BlockStateAppearance(appearanceId, parseBlockEntityRender(appearanceSection.get("entity-renderer"))));
|
||||
@@ -316,7 +400,7 @@ public abstract class AbstractBlockManager extends AbstractModelGenerator implem
|
||||
return properties;
|
||||
}
|
||||
|
||||
private void arrangeModelForStateAndVerify(int registryId, Object modelOrModels) {
|
||||
private void arrangeModelForStateAndVerify(BlockStateWrapper blockStateWrapper, Object modelOrModels) {
|
||||
// 如果没有配置models
|
||||
if (modelOrModels == null) {
|
||||
return;
|
||||
@@ -334,13 +418,13 @@ public abstract class AbstractBlockManager extends AbstractModelGenerator implem
|
||||
}
|
||||
}
|
||||
// 拆分方块id与属性
|
||||
String blockState = stateRegistryIdToStateSNBT(registryId);
|
||||
String blockState = blockStateWrapper.toString();
|
||||
Key blockId = Key.of(blockState.substring(blockState.indexOf('{') + 1, blockState.lastIndexOf('}')));
|
||||
String propertyNBT = blockState.substring(blockState.indexOf('[') + 1, blockState.lastIndexOf(']'));
|
||||
// 结合variants
|
||||
JsonElement combinedVariant = GsonHelper.combine(variants);
|
||||
Map<String, JsonElement> overrideMap = AbstractBlockManager.this.blockStateOverrides.computeIfAbsent(blockId, k -> new HashMap<>());
|
||||
AbstractBlockManager.this.tempVanillaBlockStateModels.put(registryId, combinedVariant);
|
||||
AbstractBlockManager.this.tempVanillaBlockStateModels.put(blockStateWrapper.registryId(), combinedVariant);
|
||||
JsonElement previous = overrideMap.get(propertyNBT);
|
||||
if (previous != null && !previous.equals(combinedVariant)) {
|
||||
throw new LocalizedResourceConfigException("warning.config.block.state.model.conflict", GsonHelper.get().toJson(combinedVariant), blockState, GsonHelper.get().toJson(previous));
|
||||
@@ -370,7 +454,7 @@ public abstract class AbstractBlockManager extends AbstractModelGenerator implem
|
||||
}
|
||||
|
||||
// 从方块外观的state里获取其原版方块的state id
|
||||
private int pluginFormattedBlockStateToRegistryId(String blockState) {
|
||||
private BlockStateWrapper parsePluginFormattedBlockState(String blockState) {
|
||||
// 五种合理情况
|
||||
// minecraft:note_block:10
|
||||
// note_block:10
|
||||
@@ -381,7 +465,7 @@ public abstract class AbstractBlockManager extends AbstractModelGenerator implem
|
||||
if (split.length >= 4) {
|
||||
throw new LocalizedResourceConfigException("warning.config.block.state.invalid_vanilla", blockState);
|
||||
}
|
||||
int registryId;
|
||||
BlockStateWrapper wrapper;
|
||||
String stateOrId = split[split.length - 1];
|
||||
boolean isId = false;
|
||||
int arrangerIndex = 0;
|
||||
@@ -401,14 +485,14 @@ public abstract class AbstractBlockManager extends AbstractModelGenerator implem
|
||||
// 获取原版方块的id
|
||||
Key block = split.length == 2 ? Key.of(split[0]) : Key.of(split[0], split[1]);
|
||||
try {
|
||||
List<Integer> arranger = blockAppearanceArranger.get(block);
|
||||
List<BlockStateWrapper> arranger =blockStateArranger.get(block);
|
||||
if (arranger == null) {
|
||||
throw new LocalizedResourceConfigException("warning.config.block.state.unavailable_vanilla", blockState);
|
||||
}
|
||||
if (arrangerIndex >= arranger.size()) {
|
||||
throw new LocalizedResourceConfigException("warning.config.block.state.invalid_vanilla_id", blockState, String.valueOf(arranger.size() - 1));
|
||||
}
|
||||
registryId = arranger.get(arrangerIndex);
|
||||
wrapper = arranger.get(arrangerIndex);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new LocalizedResourceConfigException("warning.config.block.state.invalid_vanilla", e, blockState);
|
||||
}
|
||||
@@ -418,9 +502,21 @@ public abstract class AbstractBlockManager extends AbstractModelGenerator implem
|
||||
if (packedBlockState == null) {
|
||||
throw new LocalizedResourceConfigException("warning.config.block.state.invalid_vanilla", blockState);
|
||||
}
|
||||
registryId = packedBlockState.registryId();
|
||||
wrapper = packedBlockState;
|
||||
}
|
||||
return registryId;
|
||||
return wrapper;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isVanillaBlockState(int id) {
|
||||
return id < this.vanillaBlockStateCount && id >= 0;
|
||||
}
|
||||
|
||||
public BlockParser blockParser() {
|
||||
return blockParser;
|
||||
}
|
||||
|
||||
public BlockStateMappingParser blockStateMappingParser() {
|
||||
return blockStateMappingParser;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,6 +61,7 @@ public abstract class AbstractCustomBlock implements CustomBlock {
|
||||
this.placementFunction = composite(placements);
|
||||
EntityBlockBehavior entityBlockBehavior = this.behavior.getEntityBehavior();
|
||||
boolean isEntityBlock = entityBlockBehavior != null;
|
||||
|
||||
for (Map.Entry<String, BlockStateVariant> entry : variantMapper.entrySet()) {
|
||||
String nbtString = entry.getKey();
|
||||
CompoundTag tag = BlockNbtParser.deserialize(this, nbtString);
|
||||
@@ -72,20 +73,12 @@ public abstract class AbstractCustomBlock implements CustomBlock {
|
||||
throw new LocalizedResourceConfigException("warning.config.block.state.property.invalid_format", nbtString);
|
||||
}
|
||||
BlockStateVariant blockStateVariant = entry.getValue();
|
||||
|
||||
BlockStateAppearance blockStateAppearance = appearances.getOrDefault(blockStateVariant.appearance(), BlockStateAppearance.INVALID);
|
||||
int stateId;
|
||||
// This should never happen
|
||||
if (blockStateAppearance.isInvalid()) {
|
||||
stateId = appearances.values().iterator().next().stateRegistryId();
|
||||
} else {
|
||||
stateId = blockStateAppearance.stateRegistryId();
|
||||
}
|
||||
BlockStateAppearance blockStateAppearance = appearances.get(blockStateVariant.appearance());
|
||||
// Late init states
|
||||
ImmutableBlockState state = possibleStates.getFirst();
|
||||
state.setSettings(blockStateVariant.settings());
|
||||
state.setVanillaBlockState(BlockRegistryMirror.stateByRegistryId(stateId));
|
||||
state.setCustomBlockState(BlockRegistryMirror.stateByRegistryId(blockStateVariant.internalRegistryId()));
|
||||
state.setVanillaBlockState(blockStateAppearance.blockState());
|
||||
state.setCustomBlockState(blockStateVariant.blockState());
|
||||
blockStateAppearance.blockEntityRenderer().ifPresent(state::setConstantRenderers);
|
||||
}
|
||||
|
||||
@@ -99,7 +92,6 @@ public abstract class AbstractCustomBlock implements CustomBlock {
|
||||
state.setBlockEntityType(entityBlockBehavior.blockEntityType());
|
||||
}
|
||||
}
|
||||
this.applyPlatformSettings();
|
||||
}
|
||||
|
||||
protected BlockBehavior setupBehavior(List<Map<String, Object>> behaviorConfig) {
|
||||
@@ -124,8 +116,6 @@ public abstract class AbstractCustomBlock implements CustomBlock {
|
||||
};
|
||||
}
|
||||
|
||||
protected abstract void applyPlatformSettings();
|
||||
|
||||
@Override
|
||||
public @Nullable LootTable<?> lootTable() {
|
||||
return this.lootTable;
|
||||
|
||||
@@ -16,7 +16,7 @@ import java.util.Optional;
|
||||
|
||||
public interface BlockManager extends Manageable, ModelGenerator {
|
||||
|
||||
ConfigParser parser();
|
||||
ConfigParser[] parsers();
|
||||
|
||||
Collection<ModelGeneration> modelsToGenerate();
|
||||
|
||||
@@ -35,9 +35,7 @@ public interface BlockManager extends Manageable, ModelGenerator {
|
||||
|
||||
Collection<Suggestion> cachedSuggestions();
|
||||
|
||||
Map<Key, Key> soundMapper();
|
||||
|
||||
int availableAppearances(Key blockType);
|
||||
Map<Key, Key> soundReplacements();
|
||||
|
||||
Key getBlockOwnerId(BlockStateWrapper state);
|
||||
|
||||
@@ -49,4 +47,11 @@ public interface BlockManager extends Manageable, ModelGenerator {
|
||||
|
||||
@Nullable
|
||||
BlockStateWrapper createBlockState(String blockState);
|
||||
|
||||
@Nullable
|
||||
BlockStateWrapper createVanillaBlockState(String blockState);
|
||||
|
||||
static Key createCustomBlockKey(int id) {
|
||||
return Key.of("craftengine", "custom_" + id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,14 +5,14 @@ public final class BlockRegistryMirror {
|
||||
private static BlockStateWrapper stoneState;
|
||||
|
||||
public static void init(BlockStateWrapper[] states, BlockStateWrapper state) {
|
||||
if (blockStates != null) throw new IllegalStateException("block states are already set");
|
||||
if (blockStates != null) throw new IllegalStateException("block states have already been set");
|
||||
blockStates = states;
|
||||
stoneState = state;
|
||||
}
|
||||
|
||||
public static BlockStateWrapper stateByRegistryId(int vanillaId) {
|
||||
if (vanillaId < 0) return stoneState;
|
||||
return blockStates[vanillaId];
|
||||
public static BlockStateWrapper byId(int stateId) {
|
||||
if (stateId < 0) return stoneState;
|
||||
return blockStates[stateId];
|
||||
}
|
||||
|
||||
public static int size() {
|
||||
|
||||
@@ -15,25 +15,20 @@ public final class BlockSounds {
|
||||
Land 0.3 1
|
||||
Destroy 1 1
|
||||
*/
|
||||
public static final SoundData EMPTY_SOUND = new SoundData(Key.of("minecraft:intentionally_empty"), SoundData.SoundValue.FIXED_1, SoundData.SoundValue.FIXED_1);
|
||||
public static final BlockSounds EMPTY = new BlockSounds(EMPTY_SOUND, EMPTY_SOUND, EMPTY_SOUND, EMPTY_SOUND, EMPTY_SOUND, EMPTY_SOUND, EMPTY_SOUND);
|
||||
public static final BlockSounds EMPTY = new BlockSounds(SoundData.EMPTY, SoundData.EMPTY, SoundData.EMPTY, SoundData.EMPTY, SoundData.EMPTY);
|
||||
|
||||
private final SoundData breakSound;
|
||||
private final SoundData stepSound;
|
||||
private final SoundData placeSound;
|
||||
private final SoundData hitSound;
|
||||
private final SoundData fallSound;
|
||||
private final SoundData landSound;
|
||||
private final SoundData destroySound;
|
||||
|
||||
public BlockSounds(SoundData breakSound, SoundData stepSound, SoundData placeSound, SoundData hitSound, SoundData fallSound, SoundData landSound, SoundData destroySound) {
|
||||
public BlockSounds(SoundData breakSound, SoundData stepSound, SoundData placeSound, SoundData hitSound, SoundData fallSound) {
|
||||
this.breakSound = breakSound;
|
||||
this.stepSound = stepSound;
|
||||
this.placeSound = placeSound;
|
||||
this.hitSound = hitSound;
|
||||
this.fallSound = fallSound;
|
||||
this.landSound = landSound;
|
||||
this.destroySound = destroySound;
|
||||
}
|
||||
|
||||
public static BlockSounds fromMap(Map<String, Object> map) {
|
||||
@@ -43,16 +38,10 @@ public final class BlockSounds {
|
||||
SoundData.create(map.getOrDefault("step", "minecraft:intentionally_empty"), SoundData.SoundValue.FIXED_0_15, SoundData.SoundValue.FIXED_1),
|
||||
SoundData.create(map.getOrDefault("place", "minecraft:intentionally_empty"), SoundData.SoundValue.FIXED_1, SoundData.SoundValue.FIXED_0_8),
|
||||
SoundData.create(map.getOrDefault("hit", "minecraft:intentionally_empty"), SoundData.SoundValue.FIXED_0_5, SoundData.SoundValue.FIXED_0_5),
|
||||
SoundData.create(map.getOrDefault("fall", "minecraft:intentionally_empty"), SoundData.SoundValue.FIXED_0_5, SoundData.SoundValue.FIXED_0_75),
|
||||
SoundData.create(map.getOrDefault("land", "minecraft:intentionally_empty"), SoundData.SoundValue.FIXED_0_3, SoundData.SoundValue.FIXED_1),
|
||||
SoundData.create(map.getOrDefault("destroy", "minecraft:intentionally_empty"), SoundData.SoundValue.FIXED_1, SoundData.SoundValue.FIXED_1)
|
||||
SoundData.create(map.getOrDefault("fall", "minecraft:intentionally_empty"), SoundData.SoundValue.FIXED_0_5, SoundData.SoundValue.FIXED_0_75)
|
||||
);
|
||||
}
|
||||
|
||||
public SoundData destroySound() {
|
||||
return destroySound;
|
||||
}
|
||||
|
||||
public SoundData breakSound() {
|
||||
return breakSound;
|
||||
}
|
||||
@@ -69,10 +58,6 @@ public final class BlockSounds {
|
||||
return hitSound;
|
||||
}
|
||||
|
||||
public SoundData landSound() {
|
||||
return landSound;
|
||||
}
|
||||
|
||||
public SoundData fallSound() {
|
||||
return fallSound;
|
||||
}
|
||||
|
||||
@@ -5,10 +5,5 @@ import net.momirealms.craftengine.core.block.entity.render.element.BlockEntityEl
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public record BlockStateAppearance(int stateRegistryId, Optional<BlockEntityElementConfig<? extends BlockEntityElement>[]> blockEntityRenderer) {
|
||||
public static final BlockStateAppearance INVALID = new BlockStateAppearance(-1, Optional.empty());
|
||||
|
||||
public boolean isInvalid() {
|
||||
return this.stateRegistryId < 0;
|
||||
}
|
||||
public record BlockStateAppearance(BlockStateWrapper blockState, Optional<BlockEntityElementConfig<? extends BlockEntityElement>[]> blockEntityRenderer) {
|
||||
}
|
||||
|
||||
@@ -3,12 +3,12 @@ package net.momirealms.craftengine.core.block;
|
||||
public class BlockStateVariant {
|
||||
private final String appearance;
|
||||
private final BlockSettings settings;
|
||||
private final int internalId;
|
||||
private final BlockStateWrapper blockState;
|
||||
|
||||
public BlockStateVariant(String appearance, BlockSettings settings, int internalId) {
|
||||
public BlockStateVariant(String appearance, BlockSettings settings, BlockStateWrapper blockState) {
|
||||
this.appearance = appearance;
|
||||
this.settings = settings;
|
||||
this.internalId = internalId;
|
||||
this.blockState = blockState;
|
||||
}
|
||||
|
||||
public String appearance() {
|
||||
@@ -19,7 +19,7 @@ public class BlockStateVariant {
|
||||
return settings;
|
||||
}
|
||||
|
||||
public int internalRegistryId() {
|
||||
return internalId;
|
||||
public BlockStateWrapper blockState() {
|
||||
return blockState;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
package net.momirealms.craftengine.core.block;
|
||||
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
|
||||
public interface BlockStateWrapper {
|
||||
|
||||
Object literalObject();
|
||||
|
||||
int registryId();
|
||||
|
||||
Key ownerId();
|
||||
}
|
||||
|
||||
@@ -32,9 +32,11 @@ public interface DelegatingBlock {
|
||||
*/
|
||||
ObjectHolder<BlockBehavior> behaviorDelegate();
|
||||
|
||||
// 其实是错误的做法
|
||||
@Deprecated
|
||||
boolean isNoteBlock();
|
||||
|
||||
// 其实是错误的做法
|
||||
@Deprecated
|
||||
boolean isTripwire();
|
||||
}
|
||||
|
||||
@@ -15,8 +15,4 @@ public final class EmptyBlock extends AbstractCustomBlock {
|
||||
INSTANCE = this;
|
||||
STATE = defaultState();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void applyPlatformSettings() {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,10 +16,6 @@ public final class InactiveCustomBlock extends AbstractCustomBlock {
|
||||
super(id, holder, Map.of(), Map.of(), Map.of(), BlockSettings.of(), Map.of(), List.of(), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void applyPlatformSettings() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImmutableBlockState getBlockState(CompoundTag nbt) {
|
||||
return this.cachedData.computeIfAbsent(nbt, k -> {
|
||||
|
||||
@@ -5,5 +5,7 @@ public enum PushReaction {
|
||||
DESTROY,
|
||||
BLOCK,
|
||||
IGNORE,
|
||||
PUSH_ONLY
|
||||
PUSH_ONLY;
|
||||
|
||||
public static final PushReaction[] VALUES = values();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package net.momirealms.craftengine.core.block.properties;
|
||||
|
||||
import com.google.common.base.MoreObjects;
|
||||
import net.momirealms.craftengine.core.block.ImmutableBlockState;
|
||||
import net.momirealms.craftengine.core.item.context.BlockPlaceContext;
|
||||
import net.momirealms.craftengine.core.util.Direction;
|
||||
|
||||
@@ -6,7 +6,7 @@ import net.momirealms.craftengine.core.loot.LootTable;
|
||||
import net.momirealms.craftengine.core.pack.LoadingSequence;
|
||||
import net.momirealms.craftengine.core.pack.Pack;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.plugin.config.ConfigParser;
|
||||
import net.momirealms.craftengine.core.plugin.config.IdSectionConfigParser;
|
||||
import net.momirealms.craftengine.core.plugin.context.event.EventFunctions;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
@@ -31,7 +31,7 @@ public abstract class AbstractFurnitureManager implements FurnitureManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigParser parser() {
|
||||
public IdSectionConfigParser parser() {
|
||||
return this.furnitureParser;
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ public abstract class AbstractFurnitureManager implements FurnitureManager {
|
||||
|
||||
protected abstract CustomFurniture.Builder furnitureBuilder();
|
||||
|
||||
public class FurnitureParser implements ConfigParser {
|
||||
public class FurnitureParser implements IdSectionConfigParser {
|
||||
public static final String[] CONFIG_SECTION_NAME = new String[] { "furniture" };
|
||||
|
||||
@Override
|
||||
|
||||
@@ -7,6 +7,7 @@ import net.momirealms.craftengine.core.pack.Pack;
|
||||
import net.momirealms.craftengine.core.pack.ResourceLocation;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.plugin.config.ConfigParser;
|
||||
import net.momirealms.craftengine.core.plugin.config.IdSectionConfigParser;
|
||||
import net.momirealms.craftengine.core.plugin.context.ContextHolder;
|
||||
import net.momirealms.craftengine.core.plugin.context.PlayerOptionalContext;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
||||
@@ -371,7 +372,7 @@ public abstract class AbstractFontManager implements FontManager {
|
||||
return this.fonts.computeIfAbsent(key, Font::new);
|
||||
}
|
||||
|
||||
public class EmojiParser implements ConfigParser {
|
||||
public class EmojiParser implements IdSectionConfigParser {
|
||||
public static final String[] CONFIG_SECTION_NAME = new String[] {"emoji", "emojis"};
|
||||
|
||||
@Override
|
||||
@@ -438,7 +439,7 @@ public abstract class AbstractFontManager implements FontManager {
|
||||
}
|
||||
}
|
||||
|
||||
public class ImageParser implements ConfigParser {
|
||||
public class ImageParser implements IdSectionConfigParser {
|
||||
public static final String[] CONFIG_SECTION_NAME = new String[] {"images", "image"};
|
||||
|
||||
@Override
|
||||
|
||||
@@ -22,6 +22,7 @@ import net.momirealms.craftengine.core.pack.model.select.TrimMaterialSelectPrope
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.plugin.config.Config;
|
||||
import net.momirealms.craftengine.core.plugin.config.ConfigParser;
|
||||
import net.momirealms.craftengine.core.plugin.config.IdSectionConfigParser;
|
||||
import net.momirealms.craftengine.core.plugin.context.PlayerOptionalContext;
|
||||
import net.momirealms.craftengine.core.plugin.context.event.EventFunctions;
|
||||
import net.momirealms.craftengine.core.plugin.context.event.EventTrigger;
|
||||
@@ -267,7 +268,7 @@ public abstract class AbstractItemManager<I> extends AbstractModelGenerator impl
|
||||
|
||||
protected abstract void registerArmorTrimPattern(Collection<Key> equipments);
|
||||
|
||||
public class EquipmentParser implements ConfigParser {
|
||||
public class EquipmentParser implements IdSectionConfigParser {
|
||||
public static final String[] CONFIG_SECTION_NAME = new String[] {"equipments", "equipment"};
|
||||
|
||||
@Override
|
||||
@@ -310,7 +311,7 @@ public abstract class AbstractItemManager<I> extends AbstractModelGenerator impl
|
||||
}
|
||||
}
|
||||
|
||||
public class ItemParser implements ConfigParser {
|
||||
public class ItemParser implements IdSectionConfigParser {
|
||||
public static final String[] CONFIG_SECTION_NAME = new String[] {"items", "item"};
|
||||
|
||||
private boolean isModernFormatRequired() {
|
||||
|
||||
@@ -6,6 +6,7 @@ import net.momirealms.craftengine.core.pack.Pack;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.plugin.config.Config;
|
||||
import net.momirealms.craftengine.core.plugin.config.ConfigParser;
|
||||
import net.momirealms.craftengine.core.plugin.config.IdSectionConfigParser;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.UniqueKey;
|
||||
@@ -120,7 +121,7 @@ public abstract class AbstractRecipeManager<T> implements RecipeManager<T> {
|
||||
return true;
|
||||
}
|
||||
|
||||
public class RecipeParser implements ConfigParser {
|
||||
public class RecipeParser implements IdSectionConfigParser {
|
||||
public static final String[] CONFIG_SECTION_NAME = new String[] {"recipes", "recipe"};
|
||||
|
||||
@Override
|
||||
|
||||
@@ -27,9 +27,7 @@ import net.momirealms.craftengine.core.pack.obfuscation.ObfA;
|
||||
import net.momirealms.craftengine.core.pack.revision.Revision;
|
||||
import net.momirealms.craftengine.core.pack.revision.Revisions;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.plugin.config.Config;
|
||||
import net.momirealms.craftengine.core.plugin.config.ConfigParser;
|
||||
import net.momirealms.craftengine.core.plugin.config.StringKeyConstructor;
|
||||
import net.momirealms.craftengine.core.plugin.config.*;
|
||||
import net.momirealms.craftengine.core.plugin.locale.I18NData;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedException;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
||||
@@ -374,6 +372,7 @@ public abstract class AbstractPackManager implements PackManager {
|
||||
plugin.saveResource("resources/internal/configuration/fix_client_visual.yml");
|
||||
plugin.saveResource("resources/internal/configuration/offset_chars.yml");
|
||||
plugin.saveResource("resources/internal/configuration/gui.yml");
|
||||
plugin.saveResource("resources/internal/configuration/mappings.yml");
|
||||
plugin.saveResource("resources/internal/resourcepack/assets/minecraft/textures/font/offset/space_split.png");
|
||||
plugin.saveResource("resources/internal/resourcepack/assets/minecraft/textures/font/gui/custom/item_browser.png");
|
||||
plugin.saveResource("resources/internal/resourcepack/assets/minecraft/textures/font/gui/custom/category.png");
|
||||
@@ -609,6 +608,7 @@ public abstract class AbstractPackManager implements PackManager {
|
||||
return cachedConfigs;
|
||||
}
|
||||
|
||||
// todo 本地化日志
|
||||
private void loadResourceConfigs(Predicate<ConfigParser> predicate) {
|
||||
long o1 = System.nanoTime();
|
||||
TreeMap<ConfigParser, List<CachedConfigSection>> cachedConfigs = this.updateCachedConfigFiles();
|
||||
@@ -619,34 +619,62 @@ public abstract class AbstractPackManager implements PackManager {
|
||||
if (!predicate.test(parser)) continue;
|
||||
long t1 = System.nanoTime();
|
||||
parser.preProcess();
|
||||
for (CachedConfigSection cached : entry.getValue()) {
|
||||
for (Map.Entry<String, Object> configEntry : cached.config().entrySet()) {
|
||||
String key = configEntry.getKey();
|
||||
Key id = Key.withDefaultNamespace(key, cached.pack().namespace());
|
||||
try {
|
||||
if (parser.supportsParsingObject()) {
|
||||
// do not apply templates
|
||||
parser.parseObject(cached.pack(), cached.filePath(), id, configEntry.getValue());
|
||||
} else {
|
||||
if (configEntry.getValue() instanceof Map<?, ?> configSection0) {
|
||||
Map<String, Object> config = castToMap(configSection0, false);
|
||||
if ((boolean) config.getOrDefault("debug", false)) {
|
||||
this.plugin.logger().info(GsonHelper.get().toJson(this.plugin.templateManager().applyTemplates(id, config)));
|
||||
}
|
||||
if ((boolean) config.getOrDefault("enable", true)) {
|
||||
parser.parseSection(cached.pack(), cached.filePath(), id, MiscUtils.castToMap(this.plugin.templateManager().applyTemplates(id, config), false));
|
||||
}
|
||||
} else {
|
||||
TranslationManager.instance().log("warning.config.structure.not_section", cached.filePath().toString(), cached.prefix() + "." + key, configEntry.getValue().getClass().getSimpleName());
|
||||
}
|
||||
switch (parser) {
|
||||
case SectionConfigParser configParser -> {
|
||||
for (CachedConfigSection cached : entry.getValue()) {
|
||||
try {
|
||||
configParser.parseSection(cached.pack(), cached.filePath(), cached.config());
|
||||
} catch (LocalizedException e) {
|
||||
printWarningRecursively(e, cached.filePath(), cached.prefix());
|
||||
} catch (Exception e) {
|
||||
this.plugin.logger().warn("Unexpected error loading file " + cached.filePath() + " - '" + parser.sectionId()[0] + "'. Please find the cause according to the stacktrace or seek developer help. Additional info: " + GsonHelper.get().toJson(cached.config()), e);
|
||||
}
|
||||
} catch (LocalizedException e) {
|
||||
printWarningRecursively(e, cached.filePath(), cached.prefix() + "." + key);
|
||||
} catch (Exception e) {
|
||||
this.plugin.logger().warn("Unexpected error loading file " + cached.filePath() + " - '" + parser.sectionId()[0] + "." + key + "'. Please find the cause according to the stacktrace or seek developer help. Additional info: " + GsonHelper.get().toJson(configEntry.getValue()), e);
|
||||
}
|
||||
}
|
||||
case IdObjectConfigParser configParser -> {
|
||||
for (CachedConfigSection cached : entry.getValue()) {
|
||||
for (Map.Entry<String, Object> configEntry : cached.config().entrySet()) {
|
||||
String key = configEntry.getKey();
|
||||
Key id = Key.withDefaultNamespace(key, cached.pack().namespace());
|
||||
try {
|
||||
configParser.parseObject(cached.pack(), cached.filePath(), id, configEntry.getValue());
|
||||
} catch (LocalizedException e) {
|
||||
printWarningRecursively(e, cached.filePath(), cached.prefix() + "." + key);
|
||||
} catch (Exception e) {
|
||||
this.plugin.logger().warn("Unexpected error loading file " + cached.filePath() + " - '" + parser.sectionId()[0] + "." + key + "'. Please find the cause according to the stacktrace or seek developer help. Additional info: " + GsonHelper.get().toJson(configEntry.getValue()), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
case IdSectionConfigParser configParser -> {
|
||||
for (CachedConfigSection cached : entry.getValue()) {
|
||||
for (Map.Entry<String, Object> configEntry : cached.config().entrySet()) {
|
||||
String key = configEntry.getKey();
|
||||
Key id = Key.withDefaultNamespace(key, cached.pack().namespace());
|
||||
try {
|
||||
if (configEntry.getValue() instanceof Map<?, ?> configSection0) {
|
||||
Map<String, Object> config = castToMap(configSection0, false);
|
||||
if ((boolean) config.getOrDefault("debug", false)) {
|
||||
this.plugin.logger().info(GsonHelper.get().toJson(this.plugin.templateManager().applyTemplates(id, config)));
|
||||
}
|
||||
if ((boolean) config.getOrDefault("enable", true)) {
|
||||
configParser.parseSection(cached.pack(), cached.filePath(), id, MiscUtils.castToMap(this.plugin.templateManager().applyTemplates(id, config), false));
|
||||
}
|
||||
} else {
|
||||
TranslationManager.instance().log("warning.config.structure.not_section", cached.filePath().toString(), cached.prefix() + "." + key, configEntry.getValue().getClass().getSimpleName());
|
||||
}
|
||||
} catch (LocalizedException e) {
|
||||
printWarningRecursively(e, cached.filePath(), cached.prefix() + "." + key);
|
||||
} catch (Exception e) {
|
||||
this.plugin.logger().warn("Unexpected error loading file " + cached.filePath() + " - '" + parser.sectionId()[0] + "." + key + "'. Please find the cause according to the stacktrace or seek developer help. Additional info: " + GsonHelper.get().toJson(configEntry.getValue()), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
default -> {
|
||||
}
|
||||
}
|
||||
|
||||
parser.postProcess();
|
||||
long t2 = System.nanoTime();
|
||||
this.plugin.logger().info("Loaded " + parser.sectionId()[0] + " in " + String.format("%.2f", ((t2 - t1) / 1_000_000.0)) + " ms");
|
||||
@@ -1722,7 +1750,7 @@ public abstract class AbstractPackManager implements PackManager {
|
||||
soundJson = new JsonObject();
|
||||
}
|
||||
|
||||
for (Map.Entry<Key, Key> mapper : plugin.blockManager().soundMapper().entrySet()) {
|
||||
for (Map.Entry<Key, Key> mapper : plugin.blockManager().soundReplacements().entrySet()) {
|
||||
Key originalKey = mapper.getKey();
|
||||
JsonObject empty = new JsonObject();
|
||||
empty.add("sounds", new JsonArray());
|
||||
|
||||
@@ -4,6 +4,7 @@ public final class LoadingSequence {
|
||||
private LoadingSequence() {}
|
||||
|
||||
public static final int TEMPLATE = 0;
|
||||
public static final int BLOCK_STATE_MAPPING = 5;
|
||||
public static final int GLOBAL_VAR = 10;
|
||||
public static final int LANG = 20;
|
||||
public static final int TRANSLATION = 30;
|
||||
|
||||
@@ -92,6 +92,8 @@ public abstract class CraftEngine implements Plugin {
|
||||
protected CraftEngine(Consumer<CraftEngine> reloadEventDispatcher) {
|
||||
instance = this;
|
||||
this.reloadEventDispatcher = reloadEventDispatcher;
|
||||
((Logger) LogManager.getRootLogger()).addFilter(new LogFilter());
|
||||
((Logger) LogManager.getRootLogger()).addFilter(new DisconnectLogFilter());
|
||||
}
|
||||
|
||||
public static CraftEngine instance() {
|
||||
@@ -105,9 +107,6 @@ public abstract class CraftEngine implements Plugin {
|
||||
RecipeDisplayTypes.init();
|
||||
SlotDisplayTypes.init();
|
||||
LegacyRecipeTypes.init();
|
||||
((Logger) LogManager.getRootLogger()).addFilter(new LogFilter());
|
||||
((Logger) LogManager.getRootLogger()).addFilter(new DisconnectLogFilter());
|
||||
this.config.load();
|
||||
}
|
||||
|
||||
public record ReloadResult(boolean success, long asyncTime, long syncTime) {
|
||||
@@ -281,7 +280,7 @@ public abstract class CraftEngine implements Plugin {
|
||||
// register furniture parser
|
||||
this.packManager.registerConfigSectionParser(this.furnitureManager.parser());
|
||||
// register block parser
|
||||
this.packManager.registerConfigSectionParser(this.blockManager.parser());
|
||||
this.packManager.registerConfigSectionParsers(this.blockManager.parsers());
|
||||
// register recipe parser
|
||||
this.packManager.registerConfigSectionParser(this.recipeManager.parser());
|
||||
// register category parser
|
||||
|
||||
@@ -44,6 +44,7 @@ public class Config {
|
||||
protected boolean checkUpdate;
|
||||
protected boolean metrics;
|
||||
protected boolean filterConfigurationPhaseDisconnect;
|
||||
protected Locale forcedLocale;
|
||||
|
||||
protected boolean debug$common;
|
||||
protected boolean debug$packet;
|
||||
@@ -123,7 +124,7 @@ public class Config {
|
||||
protected int block$predict_breaking_interval;
|
||||
protected double block$extended_interaction_range;
|
||||
protected boolean block$chunk_relighter;
|
||||
protected int block$serverside_blocks;
|
||||
protected int block$serverside_blocks = -1;
|
||||
|
||||
protected boolean recipe$enable;
|
||||
protected boolean recipe$disable_vanilla_recipes$all;
|
||||
@@ -177,7 +178,7 @@ public class Config {
|
||||
instance = this;
|
||||
}
|
||||
|
||||
public void load() {
|
||||
public boolean updateConfigCache() {
|
||||
// 文件不存在,则保存
|
||||
if (!Files.exists(this.configFilePath)) {
|
||||
this.plugin.saveResource("config.yml");
|
||||
@@ -195,13 +196,20 @@ public class Config {
|
||||
this.updateConfigVersion(configFileBytes);
|
||||
}
|
||||
}
|
||||
// 加载配置文件
|
||||
this.loadSettings();
|
||||
this.lastModified = lastModified;
|
||||
this.size = size;
|
||||
return true;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
this.plugin.logger().severe("Failed to load config.yml", e);
|
||||
this.plugin.logger().severe("Failed to update config.yml", e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void load() {
|
||||
boolean isUpdated = updateConfigCache();
|
||||
if (isUpdated) {
|
||||
loadFullSettings();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,9 +248,14 @@ public class Config {
|
||||
}
|
||||
}
|
||||
|
||||
private void loadSettings() {
|
||||
public void loadForcedLocale() {
|
||||
YamlDocument config = settings();
|
||||
plugin.translationManager().forcedLocale(TranslationManager.parseLocale(config.getString("forced-locale", "")));
|
||||
forcedLocale = TranslationManager.parseLocale(config.getString("forced-locale", ""));
|
||||
}
|
||||
|
||||
public void loadFullSettings() {
|
||||
YamlDocument config = settings();
|
||||
forcedLocale = TranslationManager.parseLocale(config.getString("forced-locale", ""));
|
||||
|
||||
// basics
|
||||
metrics = config.getBoolean("metrics", false);
|
||||
@@ -379,7 +392,7 @@ public class Config {
|
||||
equipment$sacrificed_vanilla_armor$humanoid_leggings = Key.of(config.getString("equipment.sacrificed-vanilla-armor.humanoid-leggings", "minecraft:trims/entity/humanoid_leggings/chainmail"));
|
||||
|
||||
// item
|
||||
item$client_bound_model = config.getBoolean("item.client-bound-model", false);
|
||||
item$client_bound_model = config.getBoolean("item.client-bound-model", true) && VersionHelper.PREMIUM;
|
||||
item$non_italic_tag = config.getBoolean("item.non-italic-tag", false);
|
||||
item$update_triggers$attack = config.getBoolean("item.update-triggers.attack", false);
|
||||
item$update_triggers$click_in_inventory = config.getBoolean("item.update-triggers.click-in-inventory", false);
|
||||
@@ -394,7 +407,10 @@ public class Config {
|
||||
block$predict_breaking_interval = Math.max(config.getInt("block.predict-breaking.interval", 10), 1);
|
||||
block$extended_interaction_range = Math.max(config.getDouble("block.predict-breaking.extended-interaction-range", 0.5), 0.0);
|
||||
block$chunk_relighter = config.getBoolean("block.chunk-relighter", true);
|
||||
block$serverside_blocks = config.getInt("block.serverside-blocks", 2000);
|
||||
if (firstTime) {
|
||||
block$serverside_blocks = config.getInt("block.serverside-blocks", 2000);
|
||||
if (block$serverside_blocks < 0) block$serverside_blocks = 0;
|
||||
}
|
||||
|
||||
// recipe
|
||||
recipe$enable = config.getBoolean("recipe.enable", true);
|
||||
@@ -445,6 +461,10 @@ public class Config {
|
||||
return MinecraftVersion.parse(version);
|
||||
}
|
||||
|
||||
public static Locale forcedLocale() {
|
||||
return instance.forcedLocale;
|
||||
}
|
||||
|
||||
public static String configVersion() {
|
||||
return instance.configVersion;
|
||||
}
|
||||
@@ -465,6 +485,10 @@ public class Config {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean debugBlock() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean debugFurniture() {
|
||||
return instance.debug$furniture;
|
||||
}
|
||||
|
||||
@@ -1,30 +1,13 @@
|
||||
package net.momirealms.craftengine.core.plugin.config;
|
||||
|
||||
import net.momirealms.craftengine.core.pack.Pack;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedException;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.Map;
|
||||
|
||||
public interface ConfigParser extends Comparable<ConfigParser> {
|
||||
|
||||
String[] sectionId();
|
||||
|
||||
default void parseSection(Pack pack, Path path, Key id, Map<String, Object> section) throws LocalizedException {
|
||||
this.parseObject(pack, path, id, section);
|
||||
}
|
||||
|
||||
default void parseObject(Pack pack, Path path, Key id, Object object) throws LocalizedException {
|
||||
}
|
||||
|
||||
int loadingSequence();
|
||||
|
||||
default boolean supportsParsingObject() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
default int compareTo(@NotNull ConfigParser another) {
|
||||
return Integer.compare(loadingSequence(), another.loadingSequence());
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package net.momirealms.craftengine.core.plugin.config;
|
||||
|
||||
import net.momirealms.craftengine.core.pack.Pack;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedException;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
public interface IdObjectConfigParser extends ConfigParser {
|
||||
|
||||
default void parseObject(Pack pack, Path path, Key id, Object object) throws LocalizedException {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package net.momirealms.craftengine.core.plugin.config;
|
||||
|
||||
import net.momirealms.craftengine.core.pack.Pack;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedException;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.Map;
|
||||
|
||||
public interface IdSectionConfigParser extends ConfigParser {
|
||||
|
||||
default void parseSection(Pack pack, Path path, Key id, Map<String, Object> section) throws LocalizedException {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package net.momirealms.craftengine.core.plugin.config;
|
||||
|
||||
import net.momirealms.craftengine.core.pack.Pack;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedException;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.Map;
|
||||
|
||||
public interface SectionConfigParser extends ConfigParser {
|
||||
|
||||
default void parseSection(Pack pack, Path path, Map<String, Object> section) throws LocalizedException {
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package net.momirealms.craftengine.core.plugin.config.template;
|
||||
import net.momirealms.craftengine.core.pack.LoadingSequence;
|
||||
import net.momirealms.craftengine.core.pack.Pack;
|
||||
import net.momirealms.craftengine.core.plugin.config.ConfigParser;
|
||||
import net.momirealms.craftengine.core.plugin.config.IdObjectConfigParser;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.MiscUtils;
|
||||
@@ -36,7 +37,7 @@ public class TemplateManagerImpl implements TemplateManager {
|
||||
return this.templateParser;
|
||||
}
|
||||
|
||||
public class TemplateParser implements ConfigParser {
|
||||
public class TemplateParser implements IdObjectConfigParser {
|
||||
public static final String[] CONFIG_SECTION_NAME = new String[] {"templates", "template"};
|
||||
|
||||
@Override
|
||||
@@ -49,11 +50,6 @@ public class TemplateManagerImpl implements TemplateManager {
|
||||
return LoadingSequence.TEMPLATE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsParsingObject() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseObject(Pack pack, Path path, Key id, Object obj) {
|
||||
if (templates.containsKey(id)) {
|
||||
|
||||
@@ -4,6 +4,7 @@ import net.momirealms.craftengine.core.pack.LoadingSequence;
|
||||
import net.momirealms.craftengine.core.pack.Pack;
|
||||
import net.momirealms.craftengine.core.plugin.Manageable;
|
||||
import net.momirealms.craftengine.core.plugin.config.ConfigParser;
|
||||
import net.momirealms.craftengine.core.plugin.config.IdObjectConfigParser;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedException;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -34,7 +35,7 @@ public class GlobalVariableManager implements Manageable {
|
||||
return this.parser;
|
||||
}
|
||||
|
||||
public class GlobalVariableParser implements ConfigParser {
|
||||
public class GlobalVariableParser implements IdObjectConfigParser {
|
||||
public static final String[] CONFIG_SECTION_NAME = new String[] {"global-variables", "global-variable"};
|
||||
|
||||
@Override
|
||||
@@ -47,11 +48,6 @@ public class GlobalVariableManager implements Manageable {
|
||||
return CONFIG_SECTION_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsParsingObject() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseObject(Pack pack, Path path, net.momirealms.craftengine.core.util.Key id, Object object) throws LocalizedException {
|
||||
if (object != null) {
|
||||
|
||||
@@ -12,6 +12,7 @@ import net.momirealms.craftengine.core.pack.LoadingSequence;
|
||||
import net.momirealms.craftengine.core.pack.Pack;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.plugin.config.ConfigParser;
|
||||
import net.momirealms.craftengine.core.plugin.config.IdSectionConfigParser;
|
||||
import net.momirealms.craftengine.core.plugin.context.ContextHolder;
|
||||
import net.momirealms.craftengine.core.plugin.context.PlayerOptionalContext;
|
||||
import net.momirealms.craftengine.core.plugin.gui.*;
|
||||
@@ -95,7 +96,7 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager {
|
||||
return Optional.ofNullable(this.byId.get(key));
|
||||
}
|
||||
|
||||
public class CategoryParser implements ConfigParser {
|
||||
public class CategoryParser implements IdSectionConfigParser {
|
||||
public static final String[] CONFIG_SECTION_NAME = new String[] {"categories", "category"};
|
||||
|
||||
@Override
|
||||
|
||||
@@ -50,8 +50,6 @@ public interface TranslationManager extends Manageable {
|
||||
return miniMessageTranslation(key, null);
|
||||
}
|
||||
|
||||
void forcedLocale(Locale locale);
|
||||
|
||||
String miniMessageTranslation(String key, @Nullable Locale locale);
|
||||
|
||||
default Component render(Component component) {
|
||||
|
||||
@@ -7,9 +7,7 @@ import net.momirealms.craftengine.core.pack.Pack;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.plugin.Plugin;
|
||||
import net.momirealms.craftengine.core.plugin.PluginProperties;
|
||||
import net.momirealms.craftengine.core.plugin.config.ConfigParser;
|
||||
import net.momirealms.craftengine.core.plugin.config.StringKeyConstructor;
|
||||
import net.momirealms.craftengine.core.plugin.config.TranslationConfigConstructor;
|
||||
import net.momirealms.craftengine.core.plugin.config.*;
|
||||
import net.momirealms.craftengine.core.plugin.text.minimessage.IndexedArgumentTag;
|
||||
import net.momirealms.craftengine.core.util.AdventureHelper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -38,7 +36,6 @@ public class TranslationManagerImpl implements TranslationManager {
|
||||
private final String langVersion;
|
||||
private final String[] supportedLanguages;
|
||||
private final Map<String, String> translationFallback = new LinkedHashMap<>();
|
||||
private Locale forcedLocale = null;
|
||||
private Locale selectedLocale = DEFAULT_LOCALE;
|
||||
private MiniMessageTranslationRegistry registry;
|
||||
private final Map<String, I18NData> clientLangData = new HashMap<>();
|
||||
@@ -67,11 +64,6 @@ public class TranslationManagerImpl implements TranslationManager {
|
||||
return new ConfigParser[] {this.langParser, this.i18nParser};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forcedLocale(Locale locale) {
|
||||
this.forcedLocale = locale;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delayedLoad() {
|
||||
this.clientLangData.values().forEach(I18NData::processTranslations);
|
||||
@@ -98,8 +90,8 @@ public class TranslationManagerImpl implements TranslationManager {
|
||||
}
|
||||
|
||||
private void setSelectedLocale() {
|
||||
if (this.forcedLocale != null) {
|
||||
this.selectedLocale = forcedLocale;
|
||||
if (Config.forcedLocale() != null) {
|
||||
this.selectedLocale = Config.forcedLocale();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -251,7 +243,7 @@ public class TranslationManagerImpl implements TranslationManager {
|
||||
}
|
||||
}
|
||||
|
||||
public class I18NParser implements ConfigParser {
|
||||
public class I18NParser implements IdSectionConfigParser {
|
||||
public static final String[] CONFIG_SECTION_NAME = new String[] {"i18n", "internationalization", "translation", "translations"};
|
||||
|
||||
@Override
|
||||
@@ -282,7 +274,7 @@ public class TranslationManagerImpl implements TranslationManager {
|
||||
}
|
||||
}
|
||||
|
||||
public class LangParser implements ConfigParser {
|
||||
public class LangParser implements IdSectionConfigParser {
|
||||
public static final String[] CONFIG_SECTION_NAME = new String[] {"lang", "language", "languages"};
|
||||
|
||||
@Override
|
||||
|
||||
@@ -11,6 +11,7 @@ public enum Debugger {
|
||||
FURNITURE(Config::debugFurniture),
|
||||
RESOURCE_PACK(Config::debugResourcePack),
|
||||
ITEM(Config::debugItem),
|
||||
BLOCK(Config::debugBlock),
|
||||
BLOCK_ENTITY(Config::debugBlockEntity);
|
||||
|
||||
private final Supplier<Boolean> condition;
|
||||
|
||||
@@ -97,6 +97,7 @@ public interface NetWorkUser {
|
||||
|
||||
void removeTrackedChunk(long chunkPos);
|
||||
|
||||
@Nullable
|
||||
IntIdentityList clientBlockList();
|
||||
|
||||
void setClientBlockList(IntIdentityList integers);
|
||||
|
||||
@@ -5,6 +5,7 @@ import net.momirealms.craftengine.core.pack.LoadingSequence;
|
||||
import net.momirealms.craftengine.core.pack.Pack;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.plugin.config.ConfigParser;
|
||||
import net.momirealms.craftengine.core.plugin.config.IdSectionConfigParser;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
||||
import net.momirealms.craftengine.core.util.*;
|
||||
|
||||
@@ -65,7 +66,7 @@ public abstract class AbstractSoundManager implements SoundManager {
|
||||
|
||||
protected abstract void registerSounds(Collection<Key> sounds);
|
||||
|
||||
public class SongParser implements ConfigParser {
|
||||
public class SongParser implements IdSectionConfigParser {
|
||||
public static final String[] CONFIG_SECTION_NAME = new String[] {"jukebox_songs", "jukebox_song", "jukebox-songs", "jukebox-song"};
|
||||
|
||||
@Override
|
||||
@@ -92,7 +93,7 @@ public abstract class AbstractSoundManager implements SoundManager {
|
||||
}
|
||||
}
|
||||
|
||||
public class SoundParser implements ConfigParser {
|
||||
public class SoundParser implements IdSectionConfigParser {
|
||||
public static final String[] CONFIG_SECTION_NAME = new String[] {"sounds", "sound"};
|
||||
|
||||
@Override
|
||||
|
||||
@@ -10,6 +10,7 @@ import java.util.Optional;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public record SoundData(Key id, SoundValue volume, SoundValue pitch) {
|
||||
public static final SoundData EMPTY = new SoundData(Key.of("minecraft:intentionally_empty"), SoundData.SoundValue.FIXED_1, SoundData.SoundValue.FIXED_1);
|
||||
|
||||
public static SoundData create(Object obj, SoundValue volume, SoundValue pitch) {
|
||||
if (obj instanceof String key) {
|
||||
|
||||
@@ -34,4 +34,6 @@ public enum Instrument {
|
||||
public String id() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public static final Instrument[] VALUES = Instrument.values();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user