Skip to content

Commit

Permalink
Make it possible for legacy config to be read on the client
Browse files Browse the repository at this point in the history
  • Loading branch information
mschae23 committed Nov 28, 2024
1 parent 600ba25 commit 731981f
Show file tree
Hide file tree
Showing 13 changed files with 199 additions and 75 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@
import net.minecraft.text.MutableText;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import de.mschae23.grindenchantments.config.legacy.DedicatedServerConfig;
import de.mschae23.grindenchantments.config.FilterConfig;
import de.mschae23.grindenchantments.config.legacy.v3.DedicatedServerConfigV3;
import de.mschae23.grindenchantments.cost.CostFunction;

public class GrindEnchantments {
Expand All @@ -47,7 +47,7 @@ public static ItemEnchantmentsComponent getEnchantments(ItemStack stack, FilterC
return filter.filter(EnchantmentHelper.getEnchantments(stack));
}

public static ItemStack addLevelCostComponent(ItemStack stack, IntSupplier cost, boolean canTakeItem, DedicatedServerConfig config) {
public static ItemStack addLevelCostComponent(ItemStack stack, IntSupplier cost, boolean canTakeItem, DedicatedServerConfigV3 config) {
if (!config.alternativeCostDisplay())
return stack;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,24 @@

package de.mschae23.grindenchantments;

import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import net.minecraft.registry.RegistryOps;
import java.util.Optional;
import net.minecraft.util.Identifier;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
import net.fabricmc.loader.api.FabricLoader;
import com.mojang.serialization.Codec;
import com.mojang.serialization.JsonOps;
import com.mojang.serialization.MapCodec;
import de.mschae23.config.api.ConfigIo;
import de.mschae23.config.api.ModConfig;
import de.mschae23.config.api.exception.ConfigException;
import de.mschae23.config.impl.ConfigUtil;
import de.mschae23.grindenchantments.config.legacy.v1.GrindEnchantmentsConfigV1;
import de.mschae23.grindenchantments.config.legacy.v2.GrindEnchantmentsConfigV2;
import de.mschae23.grindenchantments.config.legacy.GrindEnchantmentsConfigV3;
import de.mschae23.grindenchantments.config.legacy.v3.GrindEnchantmentsConfigV3;
import de.mschae23.grindenchantments.cost.CostFunctionType;
import de.mschae23.grindenchantments.event.ApplyLevelCostEvent;
import de.mschae23.grindenchantments.event.GrindstoneEvents;
Expand All @@ -45,36 +48,17 @@
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.Nullable;

public class GrindEnchantmentsMod implements ModInitializer {
public static final String MODID = "grindenchantments";
public static final Logger LOGGER = LogManager.getLogger("Grind Enchantments");

public static final Path CONFIG_PATH = Paths.get(MODID + ".json");

private static GrindEnchantmentsConfigV3 LEGACY_CONFIG = GrindEnchantmentsConfigV3.DEFAULT;

@Override
public void onInitialize() {
final GrindEnchantmentsConfigV3 legacyLatestConfigDefault = GrindEnchantmentsConfigV3.DEFAULT;
final int legacyLatestConfigVersion = legacyLatestConfigDefault.version();
@SuppressWarnings({"unchecked", "deprecation"})
final MapCodec<? extends ModConfig<GrindEnchantmentsConfigV3>>[] legacyConfigCodecs = new MapCodec[] {
GrindEnchantmentsConfigV1.TYPE_CODEC, GrindEnchantmentsConfigV2.TYPE_CODEC, GrindEnchantmentsConfigV3.TYPE_CODEC
};

final Codec<ModConfig<GrindEnchantmentsConfigV3>> legacyConfigCodec = ModConfig.createCodec(legacyLatestConfigVersion, version ->
getConfigType(0, legacyConfigCodecs, version));

// TODO Proper solution to client-side configs
// ClientLifecycleEvents.CLIENT_STARTED.register(client ->
// CONFIG = ConfigIo.initializeConfig(Paths.get(MODID + ".json"), LATEST_CONFIG_VERSION, LATEST_CONFIG_DEFAULT, CONFIG_CODEC,
// JsonOps.INSTANCE, LOGGER::info, LOGGER::error)
// );
ServerLifecycleEvents.SERVER_STARTING.register(server ->
LEGACY_CONFIG = ConfigIo.initializeConfig(Paths.get(MODID + ".json"), legacyLatestConfigVersion, legacyLatestConfigDefault, legacyConfigCodec,
RegistryOps.of(JsonOps.INSTANCE, server.getRegistryManager()), LOGGER::info, LOGGER::error)
);
LEGACY_CONFIG = readLegacyConfig().orElse(GrindEnchantmentsConfigV3.DEFAULT);

GrindEnchantmentsRegistries.init();
CostFunctionType.init();
Expand Down Expand Up @@ -111,6 +95,41 @@ public void onInitialize() {
return new ModConfig.Type<>(codecs.length + versionOffset, codecs[codecs.length - 1]);
}

@SuppressWarnings("deprecation")
private static Optional<GrindEnchantmentsConfigV3> readLegacyConfig() {
final GrindEnchantmentsConfigV3 legacyLatestConfigDefault = GrindEnchantmentsConfigV3.DEFAULT;
final int legacyLatestConfigVersion = legacyLatestConfigDefault.version();
@SuppressWarnings({"unchecked", "deprecation"})
final MapCodec<? extends ModConfig<GrindEnchantmentsConfigV3>>[] legacyConfigCodecs = new MapCodec[] {
GrindEnchantmentsConfigV1.TYPE_CODEC, GrindEnchantmentsConfigV2.TYPE_CODEC, GrindEnchantmentsConfigV3.TYPE_CODEC
};

final Codec<ModConfig<GrindEnchantmentsConfigV3>> legacyConfigCodec = ModConfig.createCodec(legacyLatestConfigVersion, version ->
getConfigType(0, legacyConfigCodecs, version));

// Unfortunately, this requires some manual work and usage of codec config API's internals

Path configPath = FabricLoader.getInstance().getConfigDir().resolve(Paths.get(MODID + ".json"));
@Nullable
GrindEnchantmentsConfigV3 config = null;

if (Files.exists(configPath) && Files.isRegularFile(configPath)) {
try (InputStream input = Files.newInputStream(configPath)) {
log(Level.INFO, "Reading legacy config.");

@SuppressWarnings("UnstableApiUsage")
ModConfig<GrindEnchantmentsConfigV3> readConfig = ConfigUtil.decodeConfig(input, legacyConfigCodec, JsonOps.INSTANCE);
config = readConfig.latest();
} catch (IOException e) {
log(Level.ERROR, "IO exception while trying to read config: " + e.getLocalizedMessage());
} catch (ConfigException e) {
log(Level.ERROR, e.getLocalizedMessage());
}
}

return Optional.ofNullable(config);
}

public static GrindEnchantmentsConfigV3 getConfig() {
return LEGACY_CONFIG;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,21 @@
import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import de.mschae23.config.api.ModConfig;
import de.mschae23.grindenchantments.config.legacy.ClientConfig;
import de.mschae23.grindenchantments.config.legacy.DedicatedServerConfig;
import de.mschae23.grindenchantments.config.legacy.v2.GrindEnchantmentsConfigV2;
import de.mschae23.grindenchantments.config.legacy.GrindEnchantmentsConfigV3;
import de.mschae23.grindenchantments.config.legacy.v3.ClientConfigV3;
import de.mschae23.grindenchantments.config.legacy.v3.DedicatedServerConfigV3;
import de.mschae23.grindenchantments.config.legacy.v3.GrindEnchantmentsConfigV3;

@Deprecated
@SuppressWarnings("DeprecatedIsStillUsed")
public record GrindEnchantmentsConfigV1(de.mschae23.grindenchantments.config.legacy.v1.DisenchantConfigV1 disenchant, MoveConfigV1 move, boolean allowCurses,
DedicatedServerConfig dedicatedServerConfig, ClientConfig clientConfig) implements ModConfig<GrindEnchantmentsConfigV3> {
public record GrindEnchantmentsConfigV1(DisenchantConfigV1 disenchant, MoveConfigV1 move, boolean allowCurses,
DedicatedServerConfigV3 dedicatedServerConfig, ClientConfigV3 clientConfig) implements ModConfig<GrindEnchantmentsConfigV3> {
public static final MapCodec<GrindEnchantmentsConfigV1> TYPE_CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group(
DisenchantConfigV1.CODEC.fieldOf("disenchant_to_book").forGetter(GrindEnchantmentsConfigV1::disenchant),
MoveConfigV1.CODEC.fieldOf("move_enchantments").forGetter(GrindEnchantmentsConfigV1::move),
Codec.BOOL.orElse(Boolean.FALSE).fieldOf("allow_removing_curses").forGetter(GrindEnchantmentsConfigV1::allowCurses),
DedicatedServerConfig.CODEC.orElse(DedicatedServerConfig.DEFAULT).fieldOf("dedicated_server_options").forGetter(GrindEnchantmentsConfigV1::dedicatedServerConfig),
ClientConfig.CODEC.fieldOf("client_options").forGetter(GrindEnchantmentsConfigV1::clientConfig)
DedicatedServerConfigV3.CODEC.orElse(DedicatedServerConfigV3.DEFAULT).fieldOf("dedicated_server_options").forGetter(GrindEnchantmentsConfigV1::dedicatedServerConfig),
ClientConfigV3.CODEC.fieldOf("client_options").forGetter(GrindEnchantmentsConfigV1::clientConfig)
).apply(instance, instance.stable(GrindEnchantmentsConfigV1::new)));

public static final Type<GrindEnchantmentsConfigV3, GrindEnchantmentsConfigV1> TYPE = new Type<>(1, TYPE_CODEC);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,32 +23,33 @@
import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import de.mschae23.config.api.ModConfig;
import de.mschae23.grindenchantments.config.legacy.ClientConfig;
import de.mschae23.grindenchantments.config.legacy.DedicatedServerConfig;
import de.mschae23.grindenchantments.config.DisenchantConfig;
import de.mschae23.grindenchantments.config.FilterAction;
import de.mschae23.grindenchantments.config.FilterConfig;
import de.mschae23.grindenchantments.config.legacy.GrindEnchantmentsConfigV3;
import de.mschae23.grindenchantments.config.MoveConfig;
import de.mschae23.grindenchantments.config.ResetRepairCostConfig;
import de.mschae23.grindenchantments.config.legacy.v3.ClientConfigV3;
import de.mschae23.grindenchantments.config.legacy.v3.DedicatedServerConfigV3;
import de.mschae23.grindenchantments.config.legacy.v3.FilterConfigV3;
import de.mschae23.grindenchantments.config.legacy.v3.GrindEnchantmentsConfigV3;
import de.mschae23.grindenchantments.config.legacy.v3.ResetRepairCostConfigV3;
import de.mschae23.grindenchantments.cost.FilterCostFunction;

@Deprecated
@SuppressWarnings("DeprecatedIsStillUsed")
public record GrindEnchantmentsConfigV2(DisenchantConfig disenchant, MoveConfig move, boolean allowCurses,
DedicatedServerConfig dedicatedServerConfig, ClientConfig clientConfig) implements ModConfig<GrindEnchantmentsConfigV3> {
DedicatedServerConfigV3 dedicatedServerConfig, ClientConfigV3 clientConfig) implements ModConfig<GrindEnchantmentsConfigV3> {
public static final MapCodec<GrindEnchantmentsConfigV2> TYPE_CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group(
DisenchantConfig.CODEC.fieldOf("disenchant_to_book").forGetter(GrindEnchantmentsConfigV2::disenchant),
MoveConfig.CODEC.fieldOf("move_enchantments").forGetter(GrindEnchantmentsConfigV2::move),
Codec.BOOL.orElse(Boolean.FALSE).fieldOf("allow_removing_curses").forGetter(GrindEnchantmentsConfigV2::allowCurses),
DedicatedServerConfig.CODEC.orElse(DedicatedServerConfig.DEFAULT).fieldOf("dedicated_server_options").forGetter(GrindEnchantmentsConfigV2::dedicatedServerConfig),
ClientConfig.CODEC.fieldOf("client_options").forGetter(GrindEnchantmentsConfigV2::clientConfig)
DedicatedServerConfigV3.CODEC.orElse(DedicatedServerConfigV3.DEFAULT).fieldOf("dedicated_server_options").forGetter(GrindEnchantmentsConfigV2::dedicatedServerConfig),
ClientConfigV3.CODEC.fieldOf("client_options").forGetter(GrindEnchantmentsConfigV2::clientConfig)
).apply(instance, instance.stable(GrindEnchantmentsConfigV2::new)));

public static final Type<GrindEnchantmentsConfigV3, GrindEnchantmentsConfigV2> TYPE = new Type<>(2, TYPE_CODEC);

public static final GrindEnchantmentsConfigV2 DEFAULT =
new GrindEnchantmentsConfigV2(DisenchantConfig.DEFAULT, MoveConfig.DEFAULT, false, DedicatedServerConfig.DEFAULT, ClientConfig.DEFAULT);
new GrindEnchantmentsConfigV2(DisenchantConfig.DEFAULT, MoveConfig.DEFAULT, false, DedicatedServerConfigV3.DEFAULT, ClientConfigV3.DEFAULT);

@Override
public Type<GrindEnchantmentsConfigV3, ?> type() {
Expand All @@ -62,8 +63,8 @@ public GrindEnchantmentsConfigV3 latest() {
new FilterCostFunction(this.disenchant.costFunction())),
new MoveConfig(this.move.enabled(),
new FilterCostFunction(this.move.costFunction())),
new ResetRepairCostConfig(false, ResetRepairCostConfig.DEFAULT.catalystItems(), ResetRepairCostConfig.DEFAULT.requiresEnchantment(), ResetRepairCostConfig.DEFAULT.costFunction()),
new FilterConfig(true, FilterConfig.ItemConfig.DEFAULT, FilterConfig.EnchantmentConfig.DEFAULT,
new ResetRepairCostConfigV3(false, ResetRepairCostConfigV3.DEFAULT.catalystItems(), ResetRepairCostConfig.DEFAULT.requiresEnchantment(), ResetRepairCostConfig.DEFAULT.costFunction()),
new FilterConfigV3(true, FilterConfigV3.ItemConfig.DEFAULT, FilterConfigV3.EnchantmentConfig.DEFAULT,
this.allowCurses ? FilterAction.ALLOW : FilterAction.IGNORE),
this.dedicatedServerConfig, this.clientConfig);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,16 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

package de.mschae23.grindenchantments.config.legacy;
package de.mschae23.grindenchantments.config.legacy.v3;

import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;

public record ClientConfig(boolean showLevelCost) {
public static final Codec<ClientConfig> CODEC = RecordCodecBuilder.create(instance -> instance.group(
Codec.BOOL.fieldOf("show_enchantment_cost").forGetter(ClientConfig::showLevelCost)
).apply(instance, instance.stable(ClientConfig::new)));
@Deprecated
public record ClientConfigV3(boolean showLevelCost) {
public static final Codec<ClientConfigV3> CODEC = RecordCodecBuilder.create(instance -> instance.group(
Codec.BOOL.fieldOf("show_enchantment_cost").forGetter(ClientConfigV3::showLevelCost)
).apply(instance, instance.stable(ClientConfigV3::new)));

public static final ClientConfig DEFAULT = new ClientConfig(true);
public static final ClientConfigV3 DEFAULT = new ClientConfigV3(true);
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,16 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

package de.mschae23.grindenchantments.config.legacy;
package de.mschae23.grindenchantments.config.legacy.v3;

import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;

public record DedicatedServerConfig(boolean alternativeCostDisplay) {
public static final Codec<DedicatedServerConfig> CODEC = RecordCodecBuilder.create(instance -> instance.group(
Codec.BOOL.fieldOf("alternative_cost_display_enabled").forGetter(DedicatedServerConfig::alternativeCostDisplay)
).apply(instance, instance.stable(DedicatedServerConfig::new)));
@Deprecated
public record DedicatedServerConfigV3(boolean alternativeCostDisplay) {
public static final Codec<DedicatedServerConfigV3> CODEC = RecordCodecBuilder.create(instance -> instance.group(
Codec.BOOL.fieldOf("alternative_cost_display_enabled").forGetter(DedicatedServerConfigV3::alternativeCostDisplay)
).apply(instance, instance.stable(DedicatedServerConfigV3::new)));

public static final DedicatedServerConfig DEFAULT = new DedicatedServerConfig(false);
public static final DedicatedServerConfigV3 DEFAULT = new DedicatedServerConfigV3(false);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* Copyright (C) 2024 mschae23
*
* This file is part of Grind enchantments.
*
* Grind enchantments is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

package de.mschae23.grindenchantments.config.legacy.v3;

import java.util.List;
import net.minecraft.util.Identifier;
import net.minecraft.util.dynamic.Codecs;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import de.mschae23.grindenchantments.config.FilterAction;

@Deprecated
public record FilterConfigV3(boolean enabled, ItemConfig item, EnchantmentConfig enchantment, FilterAction curses) {
public static final Codec<FilterConfigV3> CODEC = RecordCodecBuilder.create(instance -> instance.group(
Codec.BOOL.fieldOf("enabled").forGetter(FilterConfigV3::enabled),
ItemConfig.CODEC.fieldOf("item").forGetter(FilterConfigV3::item),
EnchantmentConfig.CODEC.fieldOf("enchantment").forGetter(FilterConfigV3::enchantment),
FilterAction.CODEC.fieldOf("cursed_enchantments").forGetter(FilterConfigV3::curses)
).apply(instance, instance.stable(FilterConfigV3::new)));

public static final FilterConfigV3 DEFAULT = new FilterConfigV3(true, ItemConfig.DEFAULT, EnchantmentConfig.DEFAULT, FilterAction.IGNORE);

public record ItemConfig(List<Identifier> items, FilterAction action) {
public static final Codec<ItemConfig> CODEC = RecordCodecBuilder.create(instance -> instance.group(
Codecs.listOrSingle(Identifier.CODEC).fieldOf("enchantments").forGetter(ItemConfig::items),
FilterAction.NON_IGNORE_CODEC.fieldOf("action").forGetter(ItemConfig::action)
).apply(instance, instance.stable(ItemConfig::new)));

public static final ItemConfig DEFAULT = new ItemConfig(List.of(), FilterAction.DENY);
}

public record EnchantmentConfig(List<Identifier> enchantments, FilterAction action) {
public static final Codec<EnchantmentConfig> CODEC = RecordCodecBuilder.create(instance -> instance.group(
Codecs.listOrSingle(Identifier.CODEC).fieldOf("enchantments").forGetter(EnchantmentConfig::enchantments),
FilterAction.CODEC.fieldOf("action").forGetter(EnchantmentConfig::action)
).apply(instance, instance.stable(EnchantmentConfig::new)));

public static final EnchantmentConfig DEFAULT = new EnchantmentConfig(List.of(), FilterAction.IGNORE);
}
}
Loading

0 comments on commit 731981f

Please sign in to comment.