Skip to content

Commit

Permalink
customizable registries (#25)
Browse files Browse the repository at this point in the history
* add a bit javadoc

Signed-off-by: Glease <[email protected]>

* customizable registries

Signed-off-by: Glease <[email protected]>

* add gui for customizing registries

* add a bit javadoc

Signed-off-by: Glease <[email protected]>

* spotless

Signed-off-by: Glease <[email protected]>

* remove debug statements

Signed-off-by: Glease <[email protected]>

* add notes on localization

Signed-off-by: Glease <[email protected]>

* update

* fix

* fix

---------

Signed-off-by: Glease <[email protected]>
Co-authored-by: Dream Master <[email protected]>
  • Loading branch information
Glease and Dream-Master authored Aug 7, 2024
1 parent 03e84e3 commit 3d150d9
Show file tree
Hide file tree
Showing 17 changed files with 1,387 additions and 11 deletions.
83 changes: 83 additions & 0 deletions src/main/java/com/gtnewhorizon/structurelib/ClientProxy.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,24 @@

import static com.gtnewhorizon.structurelib.StructureLib.RANDOM;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityClientPlayerMP;
import net.minecraft.client.gui.GuiNewChat;
import net.minecraft.client.particle.EntityFX;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.culling.Frustrum;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.client.resources.I18n;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
Expand All @@ -28,18 +32,27 @@
import net.minecraft.world.World;
import net.minecraftforge.client.event.RenderWorldLastEvent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.config.ConfigElement;
import net.minecraftforge.event.entity.EntityJoinWorldEvent;
import net.minecraftforge.event.world.WorldEvent;

import org.apache.commons.lang3.tuple.Pair;
import org.lwjgl.opengl.GL11;

import com.gtnewhorizon.structurelib.entity.fx.WeightlessParticleFX;
import com.gtnewhorizon.structurelib.net.RegistryOrderSyncMessage;
import com.gtnewhorizon.structurelib.net.SetChannelDataMessage;

import cpw.mods.fml.client.config.GuiConfig;
import cpw.mods.fml.client.event.ConfigChangedEvent;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.event.FMLLoadCompleteEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.eventhandler.EventPriority;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import cpw.mods.fml.common.gameevent.TickEvent.ClientTickEvent;
import cpw.mods.fml.common.gameevent.TickEvent.Phase;
import cpw.mods.fml.common.network.FMLNetworkEvent;

public class ClientProxy extends CommonProxy {

Expand Down Expand Up @@ -251,6 +264,47 @@ static void markTextureUsed(IIcon icon) {
((IStructureCompat) StructureLib.COMPAT).markTextureUsed(icon);
}

static void sendRegistryOrderToServer() {
if (FMLEventHandler.configSent) return;
FMLEventHandler.configSent = true;
for (String s : SortedRegistry.ALL_REGISTRIES.keySet()) {
Pair<List<String>, List<String>> registryOrder = ConfigurationHandler.INSTANCE.getRegistryOrder(s);
if (registryOrder == null || registryOrder.getKey().isEmpty() && registryOrder.getValue().isEmpty())
continue;
StructureLib.net
.sendToServer(new RegistryOrderSyncMessage(s, registryOrder.getKey(), registryOrder.getValue()));
}
}

@Override
public void loadComplete(FMLLoadCompleteEvent evt) {
super.loadComplete(evt);
for (Map.Entry<String, WeakReference<SortedRegistry<?>>> e : SortedRegistry.ALL_REGISTRIES.entrySet()) {
SortedRegistry<?> r = e.getValue().get();
if (r == null) continue;
Pair<List<String>, List<String>> p = ConfigurationHandler.INSTANCE.getRegistryOrder(e.getKey());
r.registerOrdering(getSPPlayerUUID(), p.getKey(), p.getValue());
}
}

public UUID getSPPlayerUUID() {
return EntityPlayer.func_146094_a(Minecraft.getMinecraft().getSession().func_148256_e());
}

public void displayConfigGUI(String category) {
ConfigElement<Object> element = new ConfigElement<>(
ConfigurationHandler.INSTANCE.getConfig().getCategory(category));
GuiConfig guiConfig = new GuiConfig(
null,
element.getChildElements(),
StructureLibAPI.MOD_ID,
null,
false,
false,
I18n.format(element.getLanguageKey()));
Minecraft.getMinecraft().displayGuiScreen(guiConfig);
}

private static class HintGroup {

private final List<HintParticleInfo> hints = new LinkedList<>();
Expand Down Expand Up @@ -439,12 +493,34 @@ public double getSquareDistanceTo(Vec3 point) {

public static class FMLEventHandler {

static boolean connected = false;
static boolean configSent = false;

private void resetPlayerLocation() {
lastPlayerPos.xCoord = Minecraft.getMinecraft().thePlayer.posX;
lastPlayerPos.yCoord = Minecraft.getMinecraft().thePlayer.posY;
lastPlayerPos.zCoord = Minecraft.getMinecraft().thePlayer.posZ;
}

@SubscribeEvent
public void onPlayerLogIn(FMLNetworkEvent.ClientConnectedToServerEvent e) {
connected = true;
configSent = false;
}

@SubscribeEvent
public void onPlayerLogOut(FMLNetworkEvent.ClientDisconnectionFromServerEvent e) {
connected = false;
}

@SubscribeEvent(priority = EventPriority.LOWEST)
public void onConfigChange(ConfigChangedEvent.PostConfigChangedEvent e) {
if (connected && e.modID.equals(StructureLibAPI.MOD_ID)) {
configSent = false;
sendRegistryOrderToServer();
}
}

@SubscribeEvent
public void onClientTick(ClientTickEvent e) {
if (e.phase == Phase.END && Minecraft.getMinecraft().thePlayer != null) {
Expand Down Expand Up @@ -488,6 +564,13 @@ public void onClientTick(ClientTickEvent e) {

public static class ForgeEventHandler {

@SubscribeEvent
public void onEntityJoinWorld(EntityJoinWorldEvent e) {
if (e.world.isRemote && e.entity instanceof EntityClientPlayerMP) {
sendRegistryOrderToServer();
}
}

@SubscribeEvent
public void onWorldLoad(WorldEvent.Load e) {
if (e.world.isRemote) {
Expand Down
31 changes: 31 additions & 0 deletions src/main/java/com/gtnewhorizon/structurelib/CommonProxy.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,23 @@
import net.minecraft.util.IChatComponent;
import net.minecraft.util.IIcon;
import net.minecraft.world.World;
import net.minecraftforge.common.MinecraftForge;

import com.gtnewhorizon.structurelib.net.ErrorHintParticleMessage;
import com.gtnewhorizon.structurelib.net.UpdateHintParticleMessage;

import cpw.mods.fml.common.event.FMLLoadCompleteEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import cpw.mods.fml.common.gameevent.TickEvent;

public class CommonProxy {

public CommonProxy() {
super();
MinecraftForge.EVENT_BUS.register(new ForgeEventHandler());
}

public void hintParticleTinted(World w, int x, int y, int z, IIcon[] icons, short[] RGBa) {}

public void hintParticleTinted(World w, int x, int y, int z, Block block, int meta, short[] RGBa) {}
Expand Down Expand Up @@ -70,6 +79,10 @@ public boolean markHintParticleError(EntityPlayer player, World w, int x, int y,
}
}

public void loadComplete(FMLLoadCompleteEvent e) {
ConfigurationHandler.INSTANCE.loadRegistryOrder();
}

private final Map<EntityPlayerMP, Map<Object, Long>> throttleMap = new WeakHashMap<>();

public void addThrottledChat(Object throttleKey, EntityPlayer player, IChatComponent text, short intervalRequired,
Expand All @@ -94,4 +107,22 @@ protected static void addThrottledChat(Object throttleKey, EntityPlayer player,
if (!forceUpdateLastSend) submap.put(throttleKey, now);
}
}

public void displayConfigGUI(String category) {}

public static class ForgeEventHandler {

private int ticksSinceLastPurge;

@SubscribeEvent
public void onServerTickEnd(TickEvent.ServerTickEvent e) {
if (e.phase != TickEvent.Phase.END) return;
if (++ticksSinceLastPurge < 20 * 60 * 10) return;
ticksSinceLastPurge = 0;
MinecraftServer server = MinecraftServer.getServer();
// it's hard to tell why server could be null in a server tick handler, but who knows?
if (server == null) return;
SortedRegistry.cleanup(server);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,26 @@
package com.gtnewhorizon.structurelib;

import java.io.File;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.minecraftforge.common.config.ConfigCategory;
import net.minecraftforge.common.config.Configuration;
import net.minecraftforge.common.config.Property;

import org.apache.commons.lang3.tuple.Pair;

import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;

import cpw.mods.fml.client.event.ConfigChangedEvent;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import cpw.mods.fml.relauncher.FMLLaunchHandler;

public enum ConfigurationHandler {

Expand All @@ -22,6 +33,7 @@ public enum ConfigurationHandler {
private int hintTransparency;
private int autoPlaceBudget;
private int autoPlaceInterval;
private Map<String, Pair<List<String>, List<String>>> registryOrders;

ConfigurationHandler() {
FMLCommonHandler.instance().bus().register(this);
Expand Down Expand Up @@ -86,8 +98,50 @@ private void loadConfig() {
+ "Note this relates to the wall clock, not in game ticks.\n"
+ "Value smaller than default is likely to be perceived as no minimal interval whatsoever.");

loadRegistryOrder();

saveConfig();
}

void loadRegistryOrder() {
loadRegistryOrderImpl();
setLanguageKeys();
saveConfig();
}

private void loadRegistryOrderImpl() {
registryOrders = new HashMap<>();
for (Map.Entry<String, WeakReference<SortedRegistry<?>>> e : SortedRegistry.ALL_REGISTRIES.entrySet()) {
SortedRegistry<?> r = e.getValue().get();
if (r == null) continue;
String category = "registries." + e.getKey();
if (FMLLaunchHandler.side().isClient()) {
// only meaningful on client, and would crash on server
config.setCategoryConfigEntryClass(category, RegistryOrderEntry.class);
}
Property pOrder = config.get(
category,
"ordering",
Iterables.toArray(r.getCurrentOrdering(), String.class),
"stuff not in this list will be automatically available after all entries listed here in their natural order, unless explicitly disabled in disabled config below.");
Property pDisable = config.get(category, "disabled", new String[0], "stuff in this list will be disabled");
List<String> all = Lists.newArrayList(r.getCurrentOrdering());
List<String> curVal = new ArrayList<>(Arrays.asList(pOrder.getStringList()));
List<String> disabled = new ArrayList<>(Arrays.asList(pDisable.getStringList()));
curVal.removeAll(disabled);
all.removeAll(disabled);
curVal.removeIf(s -> !all.remove(s));
curVal.addAll(all);
pOrder.set(curVal.toArray(new String[0]));
registryOrders.put(e.getKey(), Pair.of(curVal, disabled));
}
saveConfig();
}

private void saveConfig() {
if (config.hasChanged()) {
config.save();
config.load();
}
}

Expand Down Expand Up @@ -122,7 +176,12 @@ public int getAutoPlaceInterval() {
return autoPlaceInterval;
}

public Pair<List<String>, List<String>> getRegistryOrder(String name) {
return registryOrders.get(name);
}

Configuration getConfig() {
return config;
}

}
Loading

0 comments on commit 3d150d9

Please sign in to comment.