1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-10-24 02:17:39 +00:00

Replace Forge Config port with a NYI version

While it is a really nice library, it ends up being a bit overkill for
our needs - we don't need config syncing or anything. By NIHing our own,
we can drop one dependency and ease the updating burden a little.

Closes #1296
This commit is contained in:
Jonathan Coates
2023-03-14 22:47:34 +00:00
parent a74089d8ae
commit e96ac35d67
16 changed files with 828 additions and 215 deletions

View File

@@ -14,6 +14,7 @@ import dan200.computercraft.api.pocket.PocketUpgradeSerialiser;
import dan200.computercraft.api.turtle.TurtleUpgradeSerialiser;
import dan200.computercraft.shared.ModRegistry;
import dan200.computercraft.shared.config.ConfigSpec;
import dan200.computercraft.shared.platform.ForgeConfigFile;
import dan200.computercraft.shared.details.FluidData;
import dan200.computercraft.shared.peripheral.generic.methods.EnergyMethods;
import dan200.computercraft.shared.peripheral.generic.methods.FluidMethods;
@@ -38,8 +39,8 @@ public final class ComputerCraft {
public ComputerCraft() {
ModRegistry.register();
ModLoadingContext.get().registerConfig(ModConfig.Type.SERVER, ConfigSpec.serverSpec);
ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, ConfigSpec.clientSpec);
ModLoadingContext.get().registerConfig(ModConfig.Type.SERVER, ((ForgeConfigFile) ConfigSpec.serverSpec).spec());
ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, ((ForgeConfigFile) ConfigSpec.clientSpec).spec());
NetworkHandler.setup();
}
@@ -83,11 +84,21 @@ public final class ComputerCraft {
@SubscribeEvent
public static void sync(ModConfigEvent.Loading event) {
ConfigSpec.sync(event.getConfig());
syncConfig(event.getConfig());
}
@SubscribeEvent
public static void sync(ModConfigEvent.Reloading event) {
ConfigSpec.sync(event.getConfig());
syncConfig(event.getConfig());
}
private static void syncConfig(ModConfig config) {
if (!config.getModId().equals(ComputerCraftAPI.MOD_ID)) return;
if (config.getType() == ModConfig.Type.SERVER && ((ForgeConfigFile) ConfigSpec.serverSpec).spec().isLoaded()) {
ConfigSpec.syncServer();
} else if (config.getType() == ModConfig.Type.CLIENT) {
ConfigSpec.syncClient();
}
}
}

View File

@@ -0,0 +1,187 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.platform;
import dan200.computercraft.shared.config.ConfigFile;
import dan200.computercraft.shared.util.Trie;
import net.minecraftforge.common.ForgeConfigSpec;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Stream;
/**
* A {@link ConfigFile} which wraps Forge's config implementation.
*/
public final class ForgeConfigFile implements ConfigFile {
private final ForgeConfigSpec spec;
private final Trie<String, ConfigFile.Entry> entries;
public ForgeConfigFile(ForgeConfigSpec spec, Trie<String, Entry> entries) {
this.spec = spec;
this.entries = entries;
}
public ForgeConfigSpec spec() {
return spec;
}
@Override
public Stream<Entry> entries() {
return entries.children();
}
@Nullable
@Override
public Entry getEntry(String path) {
return entries.getValue(SPLITTER.split(path));
}
/**
* Wraps {@link ForgeConfigSpec.Builder} into our own config builder abstraction.
*/
static class Builder extends ConfigFile.Builder {
private final ForgeConfigSpec.Builder builder = new ForgeConfigSpec.Builder();
private final Trie<String, ConfigFile.Entry> entries = new Trie<>();
private void translation(String name) {
builder.translation(getTranslation(name));
}
@Override
public ConfigFile.Builder comment(String comment) {
builder.comment(comment);
return this;
}
@Override
public void push(String name) {
translation(name);
builder.push(name);
super.push(name);
}
@Override
public void pop() {
var path = new ArrayList<>(groupStack);
entries.setValue(path, new GroupImpl(path, entries.getChild(path)));
builder.pop();
super.pop();
}
@Override
public ConfigFile.Builder worldRestart() {
builder.worldRestart();
return this;
}
private <T> ConfigFile.Value<T> defineValue(ForgeConfigSpec.ConfigValue<T> value) {
var wrapped = new ValueImpl<>(value);
entries.setValue(value.getPath(), wrapped);
return wrapped;
}
@Override
public <T> ConfigFile.Value<T> define(String path, T defaultValue) {
translation(path);
return defineValue(builder.define(path, defaultValue));
}
@Override
public ConfigFile.Value<Boolean> define(String path, boolean defaultValue) {
translation(path);
return defineValue(builder.define(path, defaultValue));
}
@Override
public ConfigFile.Value<Integer> defineInRange(String path, int defaultValue, int min, int max) {
translation(path);
return defineValue(builder.defineInRange(path, defaultValue, min, max));
}
@Override
public <T> ConfigFile.Value<List<? extends T>> defineList(String path, List<? extends T> defaultValue, Predicate<Object> elementValidator) {
translation(path);
return defineValue(builder.defineList(path, defaultValue, elementValidator));
}
@Override
public <V extends Enum<V>> ConfigFile.Value<V> defineEnum(String path, V defaultValue) {
translation(path);
return defineValue(builder.defineEnum(path, defaultValue));
}
@Override
public ConfigFile build(Runnable onChange) {
var spec = builder.build();
entries.stream().forEach(x -> {
if (x instanceof ValueImpl<?> value) value.owner = spec;
if (x instanceof GroupImpl value) value.owner = spec;
});
return new ForgeConfigFile(spec, entries);
}
}
private static final class GroupImpl implements ConfigFile.Group {
private final List<String> path;
private final Trie<String, ConfigFile.Entry> entries;
private @Nullable ForgeConfigSpec owner;
private GroupImpl(List<String> path, Trie<String, ConfigFile.Entry> entries) {
this.path = path;
this.entries = entries;
}
@Override
public String translationKey() {
if (owner == null) throw new IllegalStateException("Config has not been built yet");
return owner.getLevelTranslationKey(path);
}
@Override
public String comment() {
if (owner == null) throw new IllegalStateException("Config has not been built yet");
return owner.getLevelComment(path);
}
@Override
public Stream<Entry> children() {
return entries.children();
}
}
private static final class ValueImpl<T> implements ConfigFile.Value<T> {
private final ForgeConfigSpec.ConfigValue<T> value;
private @Nullable ForgeConfigSpec owner;
private ValueImpl(ForgeConfigSpec.ConfigValue<T> value) {
this.value = value;
}
private ForgeConfigSpec.ValueSpec spec() {
if (owner == null) throw new IllegalStateException("Config has not been built yet");
return owner.getSpec().get(value.getPath());
}
@Override
public T get() {
return value.get();
}
@Override
public String translationKey() {
return spec().getTranslationKey();
}
@Override
public String comment() {
return spec().getComment();
}
}
}

View File

@@ -14,6 +14,7 @@ import dan200.computercraft.api.network.wired.WiredElement;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.impl.Peripherals;
import dan200.computercraft.shared.Capabilities;
import dan200.computercraft.shared.config.ConfigFile;
import dan200.computercraft.shared.network.NetworkMessage;
import dan200.computercraft.shared.network.client.ClientNetworkContext;
import dan200.computercraft.shared.network.container.ContainerData;
@@ -78,6 +79,11 @@ import java.util.function.*;
@AutoService(dan200.computercraft.impl.PlatformHelper.class)
public class PlatformHelperImpl implements PlatformHelper {
@Override
public ConfigFile.Builder createConfigBuilder() {
return new ForgeConfigFile.Builder();
}
@Override
public <T> ResourceLocation getRegistryKey(ResourceKey<Registry<T>> registry, T object) {
var key = RegistryManager.ACTIVE.getRegistry(registry).getKey(object);