From 89b0c0d63f50a89654b626a7996eb2144ae40451 Mon Sep 17 00:00:00 2001
From: thedarkcolour <30441001+thedarkcolour@users.noreply.github.com>
Date: Tue, 14 Nov 2023 00:07:01 -0800
Subject: [PATCH] Ex Deorum 1.9
---
build.gradle | 2 +-
changelog.md | 6 +++
.../exdeorum/client/ClientHandler.java | 21 ++++++++-
.../exdeorum/event/ClientsideCode.java | 30 ++++++++++++
.../exdeorum/event/EventHandler.java | 47 +++++++++++++++++--
.../exdeorum/item/HammerItem.java | 23 ++++++---
.../network/ClientMessageHandler.java | 7 +++
.../exdeorum/network/NetworkHandler.java | 5 ++
.../exdeorum/network/PlayerDataMessage.java | 36 ++++++++++++++
.../exdeorum/recipe/RecipeUtil.java | 14 ++++++
src/main/resources/coremods.js | 2 +-
11 files changed, 180 insertions(+), 13 deletions(-)
create mode 100644 src/main/java/thedarkcolour/exdeorum/event/ClientsideCode.java
create mode 100644 src/main/java/thedarkcolour/exdeorum/network/PlayerDataMessage.java
diff --git a/build.gradle b/build.gradle
index 454dbe86..4560ae5f 100644
--- a/build.gradle
+++ b/build.gradle
@@ -5,7 +5,7 @@ plugins {
id 'org.spongepowered.mixin' version '0.7.+'
}
-version = '1.8'
+version = '1.9'
group = 'thedarkcolour.exdeorum'
base {
archivesName = 'exdeorum'
diff --git a/changelog.md b/changelog.md
index 2dad9595..2cd2f1c7 100644
--- a/changelog.md
+++ b/changelog.md
@@ -1,3 +1,9 @@
+## Ex Deorum 1.9
+- Fixed incompatibility with SkyblockBuilder where player would not receive torch/watering can and Ex Deorum advancements
+- Fixed error message printing while patching the End Portal method
+- Fixed several issues with hammers in LAN and server worlds
+- Fixed hammer recipes with tag ingredients not functioning
+
## Ex Deorum 1.8
- Added a config option to limit the number of sieve drops from sieving moss. May be useful when playing with mods that add a lot of different saplings.
- Added compatibility with Ars Nouveau's saplings and Sourceberries to the sieve.
diff --git a/src/main/java/thedarkcolour/exdeorum/client/ClientHandler.java b/src/main/java/thedarkcolour/exdeorum/client/ClientHandler.java
index de0cac89..68bbbafa 100644
--- a/src/main/java/thedarkcolour/exdeorum/client/ClientHandler.java
+++ b/src/main/java/thedarkcolour/exdeorum/client/ClientHandler.java
@@ -35,6 +35,8 @@ import net.minecraftforge.client.event.RegisterClientReloadListenersEvent;
import net.minecraftforge.client.event.RegisterShadersEvent;
import net.minecraftforge.client.event.ScreenEvent;
import net.minecraftforge.common.MinecraftForge;
+import net.minecraftforge.event.TagsUpdatedEvent;
+import net.minecraftforge.eventbus.api.Event;
import net.minecraftforge.fml.event.config.ModConfigEvent;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
@@ -45,6 +47,7 @@ import thedarkcolour.exdeorum.client.ter.InfestedLeavesRenderer;
import thedarkcolour.exdeorum.client.ter.SieveRenderer;
import thedarkcolour.exdeorum.config.EConfig;
import thedarkcolour.exdeorum.network.ClientMessageHandler;
+import thedarkcolour.exdeorum.recipe.RecipeUtil;
import thedarkcolour.exdeorum.registry.EBlockEntities;
import thedarkcolour.exdeorum.registry.EFluids;
import thedarkcolour.exdeorum.registry.EWorldPresets;
@@ -52,6 +55,8 @@ import thedarkcolour.exdeorum.registry.EWorldPresets;
import java.io.IOException;
public class ClientHandler {
+ public static boolean needsRecipeCacheRefresh;
+
public static void register() {
var modBus = FMLJavaModLoadingContext.get().getModEventBus();
var fmlBus = MinecraftForge.EVENT_BUS;
@@ -60,10 +65,18 @@ public class ClientHandler {
modBus.addListener(ClientHandler::registerRenderers);
modBus.addListener(ClientHandler::registerShaders);
modBus.addListener(ClientHandler::addClientReloadListeners);
+ modBus.addListener(ClientHandler::onConfigChanged);
fmlBus.addListener(ClientHandler::onPlayerRespawn);
fmlBus.addListener(ClientHandler::onPlayerLogout);
- modBus.addListener(ClientHandler::onConfigChanged);
fmlBus.addListener(ClientHandler::onScreenOpen);
+ fmlBus.addListener(ClientHandler::onTagsUpdated);
+ }
+
+ private static void onTagsUpdated(TagsUpdatedEvent event) {
+ if (needsRecipeCacheRefresh && Minecraft.getInstance().getConnection() != null) {
+ RecipeUtil.reload(Minecraft.getInstance().getConnection().getRecipeManager());
+ needsRecipeCacheRefresh = false;
+ }
}
private static void addClientReloadListeners(RegisterClientReloadListenersEvent event) {
@@ -84,6 +97,12 @@ public class ClientHandler {
private static void onPlayerLogout(ClientPlayerNetworkEvent.LoggingOut event) {
ClientMessageHandler.isInVoidWorld = false;
+ needsRecipeCacheRefresh = false;
+
+ // Only null when logging in
+ if (Minecraft.getInstance().level != null) {
+ RecipeUtil.unload();
+ }
}
private static void onConfigChanged(ModConfigEvent.Reloading event) {
diff --git a/src/main/java/thedarkcolour/exdeorum/event/ClientsideCode.java b/src/main/java/thedarkcolour/exdeorum/event/ClientsideCode.java
new file mode 100644
index 00000000..f8f48f2a
--- /dev/null
+++ b/src/main/java/thedarkcolour/exdeorum/event/ClientsideCode.java
@@ -0,0 +1,30 @@
+/*
+ * Ex Deorum
+ * Copyright (c) 2023 thedarkcolour
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package thedarkcolour.exdeorum.event;
+
+import net.minecraft.client.Minecraft;
+import net.minecraft.world.entity.player.Player;
+import net.minecraft.world.level.Level;
+
+// necessary to avoid EventBus loading LocalPlayer through its ASM transformations
+class ClientsideCode {
+ static Player getLocalPlayer() {
+ return Minecraft.getInstance().player;
+ }
+}
diff --git a/src/main/java/thedarkcolour/exdeorum/event/EventHandler.java b/src/main/java/thedarkcolour/exdeorum/event/EventHandler.java
index 89712b97..16dfa8cd 100644
--- a/src/main/java/thedarkcolour/exdeorum/event/EventHandler.java
+++ b/src/main/java/thedarkcolour/exdeorum/event/EventHandler.java
@@ -29,6 +29,7 @@ import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.util.Unit;
+import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.GameRules;
@@ -36,18 +37,23 @@ import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.levelgen.Heightmap;
import net.minecraft.world.level.levelgen.XoroshiroRandomSource;
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
+import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.ClientChatEvent;
import net.minecraftforge.common.ForgeMod;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.AddReloadListenerEvent;
+import net.minecraftforge.event.OnDatapackSyncEvent;
import net.minecraftforge.event.entity.player.PlayerEvent;
import net.minecraftforge.event.level.LevelEvent;
import net.minecraftforge.fluids.FluidInteractionRegistry;
+import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.fml.InterModComms;
import net.minecraftforge.fml.ModList;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.event.lifecycle.InterModEnqueueEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
+import net.minecraftforge.fml.loading.FMLEnvironment;
+import org.jetbrains.annotations.Nullable;
import thedarkcolour.exdeorum.ExDeorum;
import thedarkcolour.exdeorum.blockentity.LavaCrucibleBlockEntity;
import thedarkcolour.exdeorum.client.CompostColors;
@@ -56,6 +62,7 @@ import thedarkcolour.exdeorum.compat.top.ExDeorumTopCompat;
import thedarkcolour.exdeorum.config.EConfig;
import thedarkcolour.exdeorum.item.HammerItem;
import thedarkcolour.exdeorum.item.WateringCanItem;
+import thedarkcolour.exdeorum.network.ClientMessageHandler;
import thedarkcolour.exdeorum.network.NetworkHandler;
import thedarkcolour.exdeorum.recipe.RecipeUtil;
import thedarkcolour.exdeorum.registry.EFluids;
@@ -63,15 +70,21 @@ import thedarkcolour.exdeorum.registry.EItems;
import thedarkcolour.exdeorum.tag.EBiomeTags;
import thedarkcolour.exdeorum.voidworld.VoidChunkGenerator;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Set;
+import java.util.UUID;
+
public final class EventHandler {
public static void register() {
var fmlBus = MinecraftForge.EVENT_BUS;
var modBus = FMLJavaModLoadingContext.get().getModEventBus();
fmlBus.addListener(EventHandler::onPlayerLogin);
+ fmlBus.addListener(EventHandler::onDataSynced);
fmlBus.addListener(EventHandler::addReloadListeners);
- modBus.addListener(EventHandler::interModEnqueue);
fmlBus.addListener(EventHandler::createSpawnTree);
+ modBus.addListener(EventHandler::interModEnqueue);
modBus.addListener(EventHandler::onCommonSetup);
if (ExDeorum.DEBUG) {
@@ -154,9 +167,38 @@ public final class EventHandler {
});
}
+ private static void onDataSynced(OnDatapackSyncEvent event) {
+ UUID excludedUUID = null;
+
+ if (FMLEnvironment.dist == Dist.CLIENT) {
+ // since event code is turned into ASM, we need this to prevent ASM trying to load the LocalPlayer class
+ Player player = DistExecutor.unsafeCallWhenOn(Dist.CLIENT, () -> ClientsideCode::getLocalPlayer);;
+ if (player == null) {
+ return;
+ } else {
+ excludedUUID = player.getUUID();
+ }
+ }
+
+ // A player who is first connecting isn't yet included in the server's player list, so include them.
+ Set players = new HashSet<>(event.getPlayerList().getPlayers());
+ if (event.getPlayer() != null) {
+ players.add(event.getPlayer());
+ }
+
+ for (var player : players) {
+ if (!player.getUUID().equals(excludedUUID)) {
+ NetworkHandler.sendRecipeCacheReset(player);
+ }
+ }
+ }
+
private static void onPlayerLogin(PlayerEvent.PlayerLoggedInEvent event) {
if (event.getEntity() instanceof ServerPlayer player) {
- if (player.serverLevel().getChunkSource().getGenerator() instanceof VoidChunkGenerator) {
+ var generator = player.serverLevel().getChunkSource().getGenerator();
+
+ // tries to account for other SkyBlock generator mods like SkyBlockBuilder
+ if (generator instanceof VoidChunkGenerator || generator.getClass().getName().toLowerCase(Locale.ROOT).contains("skyblock")) {
NetworkHandler.sendVoidWorld(player);
var advancement = player.server.getAdvancements().getAdvancement(new ResourceLocation(ExDeorum.ID, "core/root"));
@@ -188,7 +230,6 @@ public final class EventHandler {
var recipes = event.getServerResources().getRecipeManager();
event.addListener((prepBarrier, resourceManager, prepProfiler, reloadProfiler, backgroundExecutor, gameExecutor) -> {
return prepBarrier.wait(Unit.INSTANCE).thenRunAsync(() -> {
- HammerItem.refreshValidBlocks(recipes);
RecipeUtil.reload(recipes);
LavaCrucibleBlockEntity.putDefaultHeatValues();
}, gameExecutor);
diff --git a/src/main/java/thedarkcolour/exdeorum/item/HammerItem.java b/src/main/java/thedarkcolour/exdeorum/item/HammerItem.java
index 49a41ff5..21055a26 100644
--- a/src/main/java/thedarkcolour/exdeorum/item/HammerItem.java
+++ b/src/main/java/thedarkcolour/exdeorum/item/HammerItem.java
@@ -28,32 +28,41 @@ import net.minecraft.world.item.crafting.RecipeManager;
import net.minecraft.world.item.crafting.RecipeType;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
+import net.minecraftforge.common.util.Lazy;
import org.jetbrains.annotations.Nullable;
+import thedarkcolour.exdeorum.recipe.RecipeUtil;
import thedarkcolour.exdeorum.registry.EItems;
-import thedarkcolour.exdeorum.registry.ERecipeTypes;
import java.util.Set;
public class HammerItem extends DiggerItem {
- public static final Set VALID_BLOCKS = new ObjectOpenHashSet<>();
+ public static Lazy> validBlocks = Lazy.of(HammerItem::computeValidBlocks);
public HammerItem(Tier tier, Properties properties) {
super(1.0f, -2.8f, tier, null, properties);
}
- public static void refreshValidBlocks(RecipeManager recipes) {
- VALID_BLOCKS.clear();
- for (var recipe : recipes.byType(ERecipeTypes.HAMMER.get()).values()) {
+ public static Set computeValidBlocks() {
+ var hammerRecipes = RecipeUtil.getCachedHammerRecipes();
+ var validBlocks = new ObjectOpenHashSet(hammerRecipes.size());
+
+ for (var recipe : hammerRecipes) {
for (var item : recipe.getIngredient().getItems()) {
if (item.getItem() instanceof BlockItem blockItem) {
- VALID_BLOCKS.add(blockItem.getBlock());
+ validBlocks.add(blockItem.getBlock());
}
}
}
+
+ return validBlocks;
+ }
+
+ public static void refreshValidBlocks(RecipeManager recipes) {
+ validBlocks = Lazy.of(HammerItem::computeValidBlocks);
}
protected Set getValidBlocks() {
- return VALID_BLOCKS;
+ return validBlocks.get();
}
@Override
diff --git a/src/main/java/thedarkcolour/exdeorum/network/ClientMessageHandler.java b/src/main/java/thedarkcolour/exdeorum/network/ClientMessageHandler.java
index e0370c60..6fdbffd8 100644
--- a/src/main/java/thedarkcolour/exdeorum/network/ClientMessageHandler.java
+++ b/src/main/java/thedarkcolour/exdeorum/network/ClientMessageHandler.java
@@ -19,6 +19,8 @@
package thedarkcolour.exdeorum.network;
import net.minecraft.client.Minecraft;
+import thedarkcolour.exdeorum.client.ClientHandler;
+import thedarkcolour.exdeorum.recipe.RecipeUtil;
public class ClientMessageHandler {
public static boolean isInVoidWorld;
@@ -32,4 +34,9 @@ public class ClientMessageHandler {
level.clientLevelData.isFlat = true;
}
}
+
+ public static void reloadClientRecipeCache() {
+ //RecipeUtil.reload(Minecraft.getInstance().level.getRecipeManager());
+ ClientHandler.needsRecipeCacheRefresh = true;
+ }
}
diff --git a/src/main/java/thedarkcolour/exdeorum/network/NetworkHandler.java b/src/main/java/thedarkcolour/exdeorum/network/NetworkHandler.java
index 5491075d..077d5799 100644
--- a/src/main/java/thedarkcolour/exdeorum/network/NetworkHandler.java
+++ b/src/main/java/thedarkcolour/exdeorum/network/NetworkHandler.java
@@ -35,12 +35,17 @@ public final class NetworkHandler {
public static void register() {
CHANNEL.registerMessage(0, VoidWorldMessage.class, VoidWorldMessage::encode, VoidWorldMessage::decode, VoidWorldMessage::handle);
+ CHANNEL.registerMessage(1, PlayerDataMessage.class, (msg, buffer) -> {}, buffer -> new PlayerDataMessage(), PlayerDataMessage::handle);
}
public static void sendVoidWorld(ServerPlayer pPlayer) {
CHANNEL.sendTo(new VoidWorldMessage(), pPlayer.connection.connection, NetworkDirection.PLAY_TO_CLIENT);
}
+ public static void sendRecipeCacheReset(ServerPlayer player) {
+ CHANNEL.sendTo(new PlayerDataMessage(), player.connection.connection, NetworkDirection.PLAY_TO_CLIENT);
+ }
+
static void handle(Supplier ctxSupplier, Consumer handler) {
var ctx = ctxSupplier.get();
ctx.enqueueWork(() -> handler.accept(ctx));
diff --git a/src/main/java/thedarkcolour/exdeorum/network/PlayerDataMessage.java b/src/main/java/thedarkcolour/exdeorum/network/PlayerDataMessage.java
new file mode 100644
index 00000000..f9be33c7
--- /dev/null
+++ b/src/main/java/thedarkcolour/exdeorum/network/PlayerDataMessage.java
@@ -0,0 +1,36 @@
+/*
+ * Ex Deorum
+ * Copyright (c) 2023 thedarkcolour
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package thedarkcolour.exdeorum.network;
+
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.fml.DistExecutor;
+import net.minecraftforge.network.NetworkEvent;
+
+import java.util.function.Supplier;
+
+// Server -> Client
+// Fired whenever a player joins an LAN world or dedicated server to load the recipe caches
+// Also fired whenever those servers reload data
+public class PlayerDataMessage {
+ public void handle(Supplier ctxSupplier) {
+ NetworkHandler.handle(ctxSupplier, ctx -> {
+ DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> ClientMessageHandler::reloadClientRecipeCache);
+ });
+ }
+}
diff --git a/src/main/java/thedarkcolour/exdeorum/recipe/RecipeUtil.java b/src/main/java/thedarkcolour/exdeorum/recipe/RecipeUtil.java
index 82c2d998..dfa4abfd 100644
--- a/src/main/java/thedarkcolour/exdeorum/recipe/RecipeUtil.java
+++ b/src/main/java/thedarkcolour/exdeorum/recipe/RecipeUtil.java
@@ -47,6 +47,7 @@ import net.minecraftforge.common.util.Lazy;
import net.minecraftforge.fluids.FluidStack;
import org.jetbrains.annotations.Nullable;
import thedarkcolour.exdeorum.compat.PreferredOres;
+import thedarkcolour.exdeorum.item.HammerItem;
import thedarkcolour.exdeorum.recipe.barrel.BarrelCompostRecipe;
import thedarkcolour.exdeorum.recipe.barrel.BarrelMixingRecipe;
import thedarkcolour.exdeorum.recipe.crucible.CrucibleRecipe;
@@ -77,6 +78,15 @@ public final class RecipeUtil {
lavaCrucibleRecipeCache = loadSimpleRecipeCache(recipes, ERecipeTypes.LAVA_CRUCIBLE);
waterCrucibleRecipeCache = loadSimpleRecipeCache(recipes, ERecipeTypes.WATER_CRUCIBLE);
hammerRecipeCache = loadSimpleRecipeCache(recipes, ERecipeTypes.HAMMER);
+ HammerItem.refreshValidBlocks(recipes);
+ }
+
+ public static void unload() {
+ SIEVE_RECIPE_CACHE.invalidateAll();
+ barrelCompostRecipeCache = null;
+ lavaCrucibleRecipeCache = null;
+ waterCrucibleRecipeCache = null;
+ hammerRecipeCache = null;
}
private static Lazy