Skip to content

Commit

Permalink
Implement config sync
Browse files Browse the repository at this point in the history
  • Loading branch information
mschae23 committed Nov 30, 2024
1 parent 564a08d commit 4593ba5
Show file tree
Hide file tree
Showing 23 changed files with 395 additions and 51 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@
import net.minecraft.util.Identifier;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
import net.fabricmc.fabric.api.client.networking.v1.ClientConfigurationConnectionEvents;
import net.fabricmc.fabric.api.client.networking.v1.ClientConfigurationNetworking;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry;
import net.fabricmc.fabric.api.networking.v1.ServerConfigurationConnectionEvents;
Expand All @@ -54,6 +56,7 @@
import de.mschae23.grindenchantments.config.legacy.v2.GrindEnchantmentsConfigV2;
import de.mschae23.grindenchantments.config.legacy.v3.GrindEnchantmentsConfigV3;
import de.mschae23.grindenchantments.config.sync.ServerConfigS2CPayload;
import de.mschae23.grindenchantments.cost.CostFunction;
import de.mschae23.grindenchantments.cost.CostFunctionType;
import de.mschae23.grindenchantments.event.ApplyLevelCostEvent;
import de.mschae23.grindenchantments.event.GrindstoneEvents;
Expand All @@ -71,10 +74,10 @@ public class GrindEnchantmentsMod implements ModInitializer {
public static final String MODID = "grindenchantments";
public static final Logger LOGGER = LogManager.getLogger("Grind Enchantments");

private static ClientConfig CLIENT_CONFIG = ClientConfig.DEFAULT;
@Nullable
private static ServerConfig SERVER_CONFIG = null;
@Nullable
private static ClientConfig CLIENT_CONFIG = null;
private static ServerConfig LOCAL_SERVER_CONFIG = ServerConfig.DEFAULT;

@Override
public void onInitialize() {
Expand All @@ -91,26 +94,39 @@ public void onInitialize() {
ServerLifecycleEvents.SERVER_STOPPING.register(server -> SERVER_CONFIG = null);

// Multiplayer
PayloadTypeRegistry.configurationS2C().register(ServerConfigS2CPayload.ID, ServerConfigS2CPayload.CODEC);
PayloadTypeRegistry.configurationS2C().register(ServerConfigS2CPayload.ID,
ServerConfigS2CPayload.createPacketCodec(CostFunction.createPacketCodec()));

ClientLifecycleEvents.CLIENT_STARTED.register(client -> {
CLIENT_CONFIG = GrindEnchantmentsMod.initializeClientConfig();
LOCAL_SERVER_CONFIG = GrindEnchantmentsMod.initializeServerConfig(RegistryWrapper.WrapperLookup.of(
Stream.of(GrindEnchantmentsRegistries.COST_FUNCTION)));

ClientConfigurationNetworking.registerGlobalReceiver(ServerConfigS2CPayload.ID, (payload, context) -> {
//noinspection resource
context.client().execute(() -> {
log(Level.INFO, "Received server config");
// TODO
// log(Level.DEBUG, payload.config());
SERVER_CONFIG = payload.config();
});
});
ClientPlayConnectionEvents.INIT.register((handler, client2) -> {
if (SERVER_CONFIG != null) {
SERVER_CONFIG.validateRegistryEntries(handler.getRegistryManager());
}
});
});
ServerConfigurationConnectionEvents.CONFIGURE.register((handler, server) -> {
if (ServerConfigurationNetworking.canSend(handler, ServerConfigS2CPayload.ID)) {
log(Level.INFO, "Sent server config");
ServerConfigurationNetworking.send(handler, new ServerConfigS2CPayload());
ServerConfigurationNetworking.send(handler, new ServerConfigS2CPayload(SERVER_CONFIG != null ? SERVER_CONFIG : LOCAL_SERVER_CONFIG));
}
});

// Set server config to null when joining a world, so that it is known whether the server sent its config
ClientConfigurationConnectionEvents.INIT.register((handler, client) -> SERVER_CONFIG = null);
// Set server config to null when leaving the world too, for the same reason
ClientConfigurationConnectionEvents.DISCONNECT.register((handler, client) -> SERVER_CONFIG = null);
ClientPlayConnectionEvents.DISCONNECT.register((handler, client) -> SERVER_CONFIG = null);

DisenchantOperation disenchant = new DisenchantOperation();
MoveOperation move = new MoveOperation();
ResetRepairCostOperation resetRepairCost = new ResetRepairCostOperation();
Expand All @@ -134,11 +150,13 @@ public void onInitialize() {
}

public static ServerConfig getServerConfig() {
return SERVER_CONFIG == null ? ServerConfig.DEFAULT : SERVER_CONFIG;
return SERVER_CONFIG == null ?
CLIENT_CONFIG.useLocalIfUnsynced() ? LOCAL_SERVER_CONFIG : ServerConfig.DISABLED
: SERVER_CONFIG;
}

public static ClientConfig getClientConfig() {
return CLIENT_CONFIG == null ? ClientConfig.DEFAULT : CLIENT_CONFIG;
return CLIENT_CONFIG;
}

public static <C extends ModConfig<C>> ModConfig.Type<C, ? extends ModConfig<C>> getConfigType(ModConfig.Type<C, ? extends ModConfig<C>>[] versions, int version) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@
import de.mschae23.config.api.ModConfig;
import de.mschae23.grindenchantments.GrindEnchantmentsMod;

public record ClientConfig(boolean showLevelCost, boolean useDefaultIfUnsynced) implements ModConfig<ClientConfig> {
public record ClientConfig(boolean showLevelCost, boolean useLocalIfUnsynced) implements ModConfig<ClientConfig> {
public static final MapCodec<ClientConfig> TYPE_CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group(
Codec.BOOL.fieldOf("show_enchantment_cost").forGetter(ClientConfig::showLevelCost),
Codec.BOOL.fieldOf("use_default_server_config_if_unsynced").forGetter(ClientConfig::useDefaultIfUnsynced)
Codec.BOOL.fieldOf("use_local_server_config_if_unsynced").forGetter(ClientConfig::useLocalIfUnsynced)
).apply(instance, instance.stable(ClientConfig::new)));

public static final ModConfig.Type<ClientConfig, ClientConfig> TYPE = new ModConfig.Type<>(4, TYPE_CODEC);
Expand All @@ -53,4 +53,12 @@ public ClientConfig latest() {
public boolean shouldUpdate() {
return true;
}

@Override
public String toString() {
return "ClientConfig{" +
"showLevelCost=" + this.showLevelCost +
", useLocalIfUnsynced=" + this.useLocalIfUnsynced +
'}';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@

package de.mschae23.grindenchantments.config;

import net.minecraft.network.PacketByteBuf;
import net.minecraft.network.codec.PacketCodec;
import net.minecraft.network.codec.PacketCodecs;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;

Expand All @@ -27,5 +30,16 @@ public record DedicatedServerConfig(boolean alternativeCostDisplay) {
Codec.BOOL.fieldOf("alternative_cost_display_enabled").forGetter(DedicatedServerConfig::alternativeCostDisplay)
).apply(instance, instance.stable(DedicatedServerConfig::new)));

public static final PacketCodec<PacketByteBuf, DedicatedServerConfig> PACKET_CODEC = PacketCodecs.BOOLEAN.xmap(
DedicatedServerConfig::new, DedicatedServerConfig::alternativeCostDisplay).cast();

public static final DedicatedServerConfig DEFAULT = new DedicatedServerConfig(false);
public static final DedicatedServerConfig DISABLED = new DedicatedServerConfig(false);

@Override
public String toString() {
return "DedicatedServerConfig{" +
"alternativeCostDisplay=" + this.alternativeCostDisplay +
'}';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@

package de.mschae23.grindenchantments.config;

import net.minecraft.network.PacketByteBuf;
import net.minecraft.network.codec.PacketCodec;
import net.minecraft.network.codec.PacketCodecs;
import de.mschae23.grindenchantments.cost.CostFunction;
import de.mschae23.grindenchantments.cost.CountLevelsCostFunction;
import de.mschae23.grindenchantments.cost.CountMinPowerCostFunction;
import de.mschae23.grindenchantments.cost.FilterCostFunction;
import de.mschae23.grindenchantments.cost.TransformCostFunction;
Expand All @@ -30,9 +34,30 @@ public record DisenchantConfig(boolean enabled, boolean consumeItem, CostFunctio
public static final Codec<DisenchantConfig> CODEC = RecordCodecBuilder.create(instance -> instance.group(
Codec.BOOL.fieldOf("enabled").forGetter(DisenchantConfig::enabled),
Codec.BOOL.fieldOf("consume_enchanted_item").forGetter(DisenchantConfig::consumeItem),
CostFunction.TYPE_CODEC.fieldOf("cost_function").forGetter(DisenchantConfig::costFunction)
CostFunction.CODEC.fieldOf("cost_function").forGetter(DisenchantConfig::costFunction)
).apply(instance, instance.stable(DisenchantConfig::new)));

public static final DisenchantConfig DEFAULT = new DisenchantConfig(true, false,
new FilterCostFunction(new TransformCostFunction(new CountMinPowerCostFunction(), 0.3, 8.0)));

public static final DisenchantConfig DISABLED = new DisenchantConfig(false, false,
new CountLevelsCostFunction(1.0, 1.0));

public static PacketCodec<PacketByteBuf, DisenchantConfig> createPacketCodec(PacketCodec<PacketByteBuf, CostFunction> costFunctionCodec) {
return PacketCodec.tuple(
PacketCodecs.BOOLEAN, DisenchantConfig::enabled,
PacketCodecs.BOOLEAN, DisenchantConfig::consumeItem,
costFunctionCodec, DisenchantConfig::costFunction,
DisenchantConfig::new
);
}

@Override
public String toString() {
return "DisenchantConfig{" +
"enabled=" + this.enabled +
", consumeItem=" + this.consumeItem +
", costFunction=" + this.costFunction +
'}';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@

package de.mschae23.grindenchantments.config;

import net.minecraft.network.PacketByteBuf;
import net.minecraft.network.codec.PacketCodec;
import net.minecraft.network.codec.PacketCodecs;
import net.minecraft.util.StringIdentifiable;
import com.mojang.serialization.Codec;

Expand All @@ -30,6 +33,8 @@ public enum FilterAction implements StringIdentifiable {
public static final Codec<FilterAction> CODEC = StringIdentifiable.createCodec(FilterAction::values);
public static final Codec<FilterAction> NON_IGNORE_CODEC = StringIdentifiable.createCodec(() -> new FilterAction[] { ALLOW, DENY, });

public static final PacketCodec<PacketByteBuf, FilterAction> PACKET_CODEC = PacketCodecs.indexed(i -> values()[i], FilterAction::ordinal).cast();

private final String name;

FilterAction(String name) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
import net.minecraft.component.type.ItemEnchantmentsComponent;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.item.Item;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.network.codec.PacketCodec;
import net.minecraft.network.codec.PacketCodecs;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.registry.RegistryWrapper;
Expand All @@ -47,6 +50,17 @@ public record FilterConfig(boolean enabled, ItemConfig item, EnchantmentConfig e
).apply(instance, instance.stable(FilterConfig::new)));

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

public static PacketCodec<PacketByteBuf, FilterConfig> createPacketCodec() {
return PacketCodec.tuple(
PacketCodecs.BOOLEAN, FilterConfig::enabled,
ItemConfig.createPacketCodec(), FilterConfig::item,
EnchantmentConfig.createPacketCodec(), FilterConfig::enchantment,
FilterAction.PACKET_CODEC, FilterConfig::curses,
FilterConfig::new
);
}

private boolean shouldDeny(ItemEnchantmentsComponent.Builder builder) {
if (this.curses == FilterAction.DENY) {
Expand Down Expand Up @@ -111,6 +125,16 @@ public void validateRegistryEntries(RegistryWrapper.WrapperLookup wrapperLookup)
this.enchantment.validateRegistryEntries(wrapperLookup);
}

@Override
public String toString() {
return "FilterConfig{" +
"enabled=" + this.enabled +
", item=" + this.item +
", enchantment=" + this.enchantment +
", curses=" + this.curses +
'}';
}

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),
Expand All @@ -119,6 +143,14 @@ public record ItemConfig(List<Identifier> items, FilterAction action) {

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

public static PacketCodec<PacketByteBuf, ItemConfig> createPacketCodec() {
return PacketCodec.tuple(
Identifier.PACKET_CODEC.collect(PacketCodecs.toList()), ItemConfig::items,
FilterAction.PACKET_CODEC, ItemConfig::action,
ItemConfig::new
);
}

public void validateRegistryEntries(RegistryWrapper.WrapperLookup wrapperLookup) {
Optional<? extends RegistryWrapper.Impl<Item>> registryWrapperOpt = wrapperLookup.getOptional(RegistryKeys.ITEM);

Expand All @@ -135,6 +167,14 @@ public void validateRegistryEntries(RegistryWrapper.WrapperLookup wrapperLookup)
.map(Identifier::toString)
.forEach(item -> GrindEnchantmentsMod.log(Level.WARN, "Filter config contains unknown item: " + item));
}

@Override
public String toString() {
return "ItemConfig{" +
"items=" + this.items +
", action=" + this.action +
'}';
}
}

public record EnchantmentConfig(List<Identifier> enchantments, FilterAction action) {
Expand All @@ -145,6 +185,14 @@ public record EnchantmentConfig(List<Identifier> enchantments, FilterAction acti

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

public static PacketCodec<PacketByteBuf, EnchantmentConfig> createPacketCodec() {
return PacketCodec.tuple(
Identifier.PACKET_CODEC.collect(PacketCodecs.toList()), EnchantmentConfig::enchantments,
FilterAction.PACKET_CODEC, EnchantmentConfig::action,
EnchantmentConfig::new
);
}

public void validateRegistryEntries(RegistryWrapper.WrapperLookup wrapperLookup) {
Optional<? extends RegistryWrapper.Impl<Enchantment>> registryWrapperOpt = wrapperLookup.getOptional(RegistryKeys.ENCHANTMENT);

Expand All @@ -161,5 +209,13 @@ public void validateRegistryEntries(RegistryWrapper.WrapperLookup wrapperLookup)
.map(Identifier::toString)
.forEach(item -> GrindEnchantmentsMod.log(Level.WARN, "Filter config contains unknown enchantment: " + item));
}

@Override
public String toString() {
return "EnchantmentConfig{" +
"enchantments=" + this.enchantments +
", action=" + this.action +
'}';
}
}
}
30 changes: 26 additions & 4 deletions src/main/java/de/mschae23/grindenchantments/config/MoveConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,43 @@

package de.mschae23.grindenchantments.config;

import net.minecraft.network.PacketByteBuf;
import net.minecraft.network.codec.PacketCodec;
import net.minecraft.network.codec.PacketCodecs;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import de.mschae23.grindenchantments.cost.CostFunction;
import de.mschae23.grindenchantments.cost.CountLevelsCostFunction;
import de.mschae23.grindenchantments.cost.FilterCostFunction;
import de.mschae23.grindenchantments.cost.TransformCostFunction;
import de.mschae23.grindenchantments.cost.FirstEnchantmentCostFunction;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import de.mschae23.grindenchantments.cost.TransformCostFunction;

public record MoveConfig(boolean enabled, CostFunction costFunction) {
public static final Codec<MoveConfig> CODEC = RecordCodecBuilder.create(instance -> instance.group(
Codec.BOOL.fieldOf("enabled").forGetter(MoveConfig::enabled),
CostFunction.TYPE_CODEC.fieldOf("cost_function").forGetter(MoveConfig::costFunction)
CostFunction.CODEC.fieldOf("cost_function").forGetter(MoveConfig::costFunction)
).apply(instance, instance.stable(MoveConfig::new)));

public static final MoveConfig DEFAULT = new MoveConfig(true,
new FilterCostFunction(new FirstEnchantmentCostFunction(new TransformCostFunction(
new CountLevelsCostFunction(3.0, 8.0), 0.5, 0.5))));

public static final MoveConfig DISABLED = new MoveConfig(false,
new CountLevelsCostFunction(1.0, 1.0));

public static PacketCodec<PacketByteBuf, MoveConfig> createPacketCodec(PacketCodec<PacketByteBuf, CostFunction> costFunctionCodec) {
return PacketCodec.tuple(
PacketCodecs.BOOLEAN, MoveConfig::enabled,
costFunctionCodec, MoveConfig::costFunction,
MoveConfig::new
);
}

@Override
public String toString() {
return "MoveConfig{" +
"enabled=" + this.enabled +
", costFunction=" + this.costFunction +
'}';
}
}
Loading

0 comments on commit 4593ba5

Please sign in to comment.