Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

0.0.1.1 - forged #13

Merged
merged 14 commits into from
Oct 6, 2024
60 changes: 34 additions & 26 deletions common/src/main/java/glitchcore/config/ConfigSync.java
Original file line number Diff line number Diff line change
@@ -1,36 +1,44 @@
package glitchcore.config;

import glitchcore.core.GlitchCore;
import glitchcore.network.PacketHandler;
import glitchcore.network.SyncConfigPacket;
import glitchcore.util.Environment;
import net.minecraft.resources.ResourceLocation;

import java.util.HashMap;
import java.util.Map;
import net.minecraft.resources.ResourceLocation;
import java.util.concurrent.atomic.AtomicBoolean;

public class ConfigSync {
private static final ResourceLocation CONFIG_SYNC_CHANNEL = new ResourceLocation("glitchcorefabric", "config_sync");
private static final Map<String, Config> CONFIGS_BY_PATH = new HashMap<>();
private static boolean inited = false;
/**
* Enables sync between server and client for your config.
* NOTE: This function works only on fabric, you need to implement it yourself
* if you want to use it on forge
*
* @param config your config.
*/
public static void register(Config config) {
if (!inited) {
initSyncs();
inited = true;
private static ResourceLocation configSyncChannel;
public static PacketHandler packetHandler;
public static final Map<String, Config> CONFIGS_BY_PATH = new HashMap<>();
private static AtomicBoolean inited = new AtomicBoolean();

/**
* Enables sync between server and client for your config.
*
* @param config your config.
*/
public static void register(Config config) {
if (inited.compareAndSet(false, true))
{
configSyncChannel = new ResourceLocation(GlitchCore.MOD_ID, "config_sync");
packetHandler = new PacketHandler(configSyncChannel);
packetHandler.register(new ResourceLocation(GlitchCore.MOD_ID, "config_sync_packet"),
new SyncConfigPacket());
initFabric();
}
String relative = Environment.getConfigPath().relativize(config.getPath()).toString();
CONFIGS_BY_PATH.put(relative, config);
}

private static void initFabric() {}

public static void reload(String path, String toml) {
var config = CONFIGS_BY_PATH.get(path);
config.parse(toml);
config.load();
}
String relative = Environment.getConfigPath().relativize(config.getPath()).toString();
CONFIGS_BY_PATH.put(relative, config);
}
private static void initSyncs() {
throw new UnsupportedOperationException();
}
private static void reload(String path, String toml) {
var config = CONFIGS_BY_PATH.get(path);
config.parse(toml);
config.load();
}
}
46 changes: 46 additions & 0 deletions common/src/main/java/glitchcore/network/SyncConfigPacket.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*******************************************************************************
* Copyright 2023, the Glitchfiend Team.
* All rights reserved.
******************************************************************************/
package glitchcore.network;

import glitchcore.config.ConfigSync;
import net.minecraft.network.FriendlyByteBuf;

import java.nio.charset.StandardCharsets;

public class SyncConfigPacket implements CustomPacket<SyncConfigPacket>
{
private String path;
private byte[] data;

public SyncConfigPacket(String path, byte[] data)
{
this.path = path;
this.data = data;
}

public SyncConfigPacket() {}

@Override
public void encode(FriendlyByteBuf buf)
{
buf.writeUtf(this.path);
buf.writeByteArray(this.data);
}

@Override
public SyncConfigPacket decode(FriendlyByteBuf buf)
{
return new SyncConfigPacket(buf.readUtf(), buf.readByteArray());
}

@Override
public void handle(SyncConfigPacket data, Context context)
{
if (context.isServerSide())
return;

ConfigSync.reload(data.path, new String(data.data, StandardCharsets.UTF_8));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.npc.VillagerData;
import net.minecraft.world.entity.npc.VillagerProfession;

public class GlitchCoreFabric implements ModInitializer
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,19 @@
******************************************************************************/
package glitchcore.fabric.core;

import glitchcore.config.Config;
import glitchcore.config.ConfigSync;
import glitchcore.event.EventManager;
import glitchcore.event.client.ItemTooltipEvent;
import glitchcore.event.client.LevelRenderEvent;
import glitchcore.event.client.RegisterColorsEvent;
import glitchcore.event.client.RegisterParticleSpritesEvent;
import glitchcore.event.player.PlayerInteractEvent;
import glitchcore.fabric.GlitchCoreInitializer;
import glitchcore.util.Environment;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.item.v1.ItemTooltipCallback;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents;
import net.fabricmc.fabric.api.client.particle.v1.ParticleFactoryRegistry;
import net.fabricmc.fabric.api.client.rendering.v1.ColorProviderRegistry;
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents;
Expand All @@ -31,6 +35,16 @@ public class GlitchCoreFabricClient implements ClientModInitializer
public void onInitializeClient()
{
// GlitchCore initialization
ClientPlayConnectionEvents.DISCONNECT.register((handler, client) -> {
if (!ConfigSync.CONFIGS_BY_PATH.isEmpty())
{
ConfigSync.CONFIGS_BY_PATH.forEach((path, config) -> {
config.parse(Config.readToml(Environment.getConfigPath().resolve(path)));
config.load();
});
}
});

ItemTooltipCallback.EVENT.register((stack, context, lines) -> {
EventManager.fire(new ItemTooltipEvent(stack, lines));
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
******************************************************************************/
package glitchcore.fabric.mixin.client;

import glitchcore.core.GlitchCore;
import glitchcore.event.EventManager;
import glitchcore.event.client.RenderTooltipEvent;
import glitchcore.fabric.gui.IExtendedGuiGraphics;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,32 @@

import glitchcore.config.Config;
import glitchcore.config.ConfigSync;
import glitchcore.core.GlitchCore;
import glitchcore.util.Environment;
import glitchcore.network.PacketHandler;
import glitchcore.network.SyncConfigPacket;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import net.fabricmc.fabric.api.event.Event;
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs;
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
import net.minecraft.resources.ResourceLocation;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow;

@Mixin(value = ConfigSync.class, remap = false)
public class MixinConfigSync {
@Shadow
@Final
private static ResourceLocation CONFIG_SYNC_CHANNEL;
@Shadow
@Final
private static Map<String, Config> CONFIGS_BY_PATH;
@Shadow
public static PacketHandler packetHandler;
@Shadow
@Final
public static Map<String, Config> CONFIGS_BY_PATH;

@Overwrite
public static void initSyncs() {
var earlyPhase = new ResourceLocation("glitchcore", "early");
ServerPlayConnectionEvents.JOIN.addPhaseOrdering(earlyPhase, Event.DEFAULT_PHASE);

// the server sends packets to the player
ServerPlayConnectionEvents.JOIN.register(earlyPhase, (handler, sender, server) -> {
CONFIGS_BY_PATH.forEach((path, confik) -> {
var packet = PacketByteBufs.create();
packet.writeUtf(path);
packet.writeByteArray(confik.encode().getBytes(StandardCharsets.UTF_8));

sender.sendPacket(CONFIG_SYNC_CHANNEL, packet);
});
});
}
@Overwrite
public static void initFabric()
{
ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> {
CONFIGS_BY_PATH.forEach((path, config) -> {
packetHandler.sendToPlayer(new SyncConfigPacket(path,
config.encode().getBytes(StandardCharsets.UTF_8)), handler.getPlayer());
});
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
import net.minecraft.client.renderer.blockentity.BlockEntityRenderers;
import net.minecraft.client.renderer.entity.EntityRendererProvider;
import net.minecraft.client.renderer.entity.EntityRenderers;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.level.block.Block;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@

import glitchcore.config.Config;
import glitchcore.config.ConfigSync;
import glitchcore.core.GlitchCore;
import glitchcore.util.Environment;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking.PlayChannelHandler;
Expand All @@ -15,37 +12,41 @@
import net.minecraft.client.multiplayer.ClientPacketListener;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.resources.ResourceLocation;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.nio.charset.StandardCharsets;
import java.util.Map;

@Mixin(value = ConfigSync.class, remap = false)
public class MixinConfigSyncClient {

@Shadow
private static ResourceLocation CONFIG_SYNC_CHANNEL;
@Shadow
private static Map<String, Config> CONFIGS_BY_PATH;
@Shadow
private static void reload(String path, String toml) {/*dummy body*/}
@Shadow
private static ResourceLocation configSyncChannel;
@Final
@Shadow
public static Map<String, Config> CONFIGS_BY_PATH;

@Shadow
public static void reload(String path, String toml) {/*dummy body*/}

@SuppressWarnings("all")
@Inject(method="initSyncs", at=@At(value="TAIL"))
private static void onInitSyncs(CallbackInfo ci) {
ClientPlayNetworking.registerGlobalReceiver(CONFIG_SYNC_CHANNEL, new PlayChannelHandler() {
@Override
public void receive(Minecraft client, ClientPacketListener handler, FriendlyByteBuf buf,
PacketSender responseSender) {
reload(buf.readUtf(), new String(buf.readByteArray(), StandardCharsets.UTF_8));
}
});
ClientPlayConnectionEvents.DISCONNECT.register((handler, client) -> {
CONFIGS_BY_PATH.forEach((path, confik) -> {
confik.parse(Config.readToml(Environment.getConfigPath().resolve(path)));
confik.load();
});
});
}
@Inject(method = "initFabric", at = @At(value = "TAIL"))
private static void onInitSyncs(CallbackInfo ci) {
ClientPlayNetworking.registerGlobalReceiver(configSyncChannel, new PlayChannelHandler() {
@Override
public void receive(Minecraft client, ClientPacketListener handler, FriendlyByteBuf buf,
PacketSender responseSender) {
reload(buf.readUtf(), new String(buf.readByteArray(), StandardCharsets.UTF_8));
}
});
ClientPlayConnectionEvents.DISCONNECT.register((handler, client) -> {
CONFIGS_BY_PATH.forEach((path, confik) -> {
confik.parse(Config.readToml(Environment.getConfigPath().resolve(path)));
confik.load();
});
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import glitchcore.network.PacketHandler;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
import net.fabricmc.fabric.api.networking.v1.FabricPacket;
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
import net.minecraft.resources.ResourceLocation;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
Expand Down
4 changes: 0 additions & 4 deletions forge/src/main/java/glitchcore/forge/GlitchCoreForge.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@
package glitchcore.forge;

import glitchcore.core.GlitchCore;
import glitchcore.event.Event;
import glitchcore.event.EventManager;
import glitchcore.event.RegistryEvent;
import glitchcore.forge.handlers.RegistryEventHandler;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.fml.common.Mod;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
******************************************************************************/
package glitchcore.forge.handlers;

import glitchcore.core.GlitchCore;
import glitchcore.event.EventManager;
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package glitchcore.forge.handlers;

import glitchcore.config.ConfigSync;
import glitchcore.network.SyncConfigPacket;
import net.minecraft.server.level.ServerPlayer;
import net.minecraftforge.event.entity.player.PlayerEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;

import java.nio.charset.StandardCharsets;

@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.FORGE)
public class PlayerLoggedInEventHandler
{

@SubscribeEvent
public static void onJoin(PlayerEvent.PlayerLoggedInEvent e)
{
if (ConfigSync.CONFIGS_BY_PATH.isEmpty()) return;
ConfigSync.CONFIGS_BY_PATH.forEach((path, config) -> {
ConfigSync.packetHandler.sendToPlayer(new SyncConfigPacket(path,
config.encode().getBytes(StandardCharsets.UTF_8)), (ServerPlayer) e.getEntity());
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package glitchcore.forge.handlers;

import glitchcore.config.Config;
import glitchcore.config.ConfigSync;
import glitchcore.util.Environment;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.ClientPlayerNetworkEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;

@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.FORGE, value = Dist.CLIENT)
public class PlayerQuitClientEventHandler
{
@SubscribeEvent
public static void onQuit(ClientPlayerNetworkEvent.LoggingOut e)
{
if (!ConfigSync.CONFIGS_BY_PATH.isEmpty())
{
ConfigSync.CONFIGS_BY_PATH.forEach((path, config) -> {
config.parse(Config.readToml(Environment.getConfigPath().resolve(path)));
config.load();
});
}
}
}
Loading