From 933ecded5d2b974d3f9eb66f46bb1ebf160a17be Mon Sep 17 00:00:00 2001 From: George Paton Date: Fri, 23 May 2025 13:16:08 +1000 Subject: [PATCH 1/4] send recipe JSON to all clients connecting to a server (does nothing in singleplayer, can be disabled via config) --- .../java/com/hbm/config/GeneralConfig.java | 3 + .../recipes/loader/SerializableRecipe.java | 143 ++++++++++-------- .../java/com/hbm/main/ModEventHandler.java | 40 ++++- .../java/com/hbm/packet/PacketDispatcher.java | 2 + .../toclient/SerializableRecipePacket.java | 76 ++++++++++ 5 files changed, 201 insertions(+), 63 deletions(-) create mode 100644 src/main/java/com/hbm/packet/toclient/SerializableRecipePacket.java diff --git a/src/main/java/com/hbm/config/GeneralConfig.java b/src/main/java/com/hbm/config/GeneralConfig.java index c21bd980d..ed0f1af67 100644 --- a/src/main/java/com/hbm/config/GeneralConfig.java +++ b/src/main/java/com/hbm/config/GeneralConfig.java @@ -38,6 +38,7 @@ public class GeneralConfig { public static boolean enableGuideBook = true; public static boolean enableSoundExtension = true; public static boolean enableMekanismChanges = true; + public static boolean enableServerRecipeSync = true; public static int normalSoundChannels = 200; public static boolean enableExpensiveMode = false; @@ -81,6 +82,8 @@ public class GeneralConfig { packetThreadingMaxCount = config.get(CATEGORY_GENERAL, "0.03_packetThreadingMaxCount", 1, "Maximum number of threads to create for packet threading. Must be greater than or equal to 0.02_packetThreadingCoreCount.").getInt(1); packetThreadingErrorBypass = config.get(CATEGORY_GENERAL, "0.04_packetThreadingErrorBypass", false, "Forces the bypassing of most packet threading errors, only enable this if directed to or if you know what you're doing.").getBoolean(false); + enableServerRecipeSync = config.get(CATEGORY_GENERAL, "0.05_enableServerRecipeSync", true, "Syncs any recipes customised via JSON to clients connecting to the server.").getBoolean(true); + enableDebugMode = config.get(CATEGORY_GENERAL, "1.00_enableDebugMode", false, "Enable debugging mode").getBoolean(false); enableMycelium = config.get(CATEGORY_GENERAL, "1.01_enableMyceliumSpread", false, "Allows glowing mycelium to spread").getBoolean(false); enablePlutoniumOre = config.get(CATEGORY_GENERAL, "1.02_enablePlutoniumNetherOre", false, "Enables plutonium ore generation in the nether").getBoolean(false); diff --git a/src/main/java/com/hbm/inventory/recipes/loader/SerializableRecipe.java b/src/main/java/com/hbm/inventory/recipes/loader/SerializableRecipe.java index 753fb048f..8247bff1a 100644 --- a/src/main/java/com/hbm/inventory/recipes/loader/SerializableRecipe.java +++ b/src/main/java/com/hbm/inventory/recipes/loader/SerializableRecipe.java @@ -1,15 +1,12 @@ package com.hbm.inventory.recipes.loader; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; +import java.io.*; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; +import java.util.Map; import com.google.gson.Gson; import com.google.gson.JsonArray; @@ -35,17 +32,19 @@ import net.minecraft.item.ItemStack; //the anti-spaghetti. this class provides so much functionality and saves so much time, i just love you, SerializableRecipe <3 public abstract class SerializableRecipe { - + public static final Gson gson = new Gson(); - public static List recipeHandlers = new ArrayList(); - public static List additionalListeners = new ArrayList(); - + public static List recipeHandlers = new ArrayList<>(); + public static List additionalListeners = new ArrayList<>(); + + public static Map recipeSyncHandlers = new HashMap<>(); + public boolean modified = false; - + /* * INIT */ - + public static void registerAllHandlers() { recipeHandlers.add(new PressRecipes()); recipeHandlers.add(new BlastFurnaceRecipes()); @@ -82,67 +81,90 @@ public abstract class SerializableRecipe { //AFTER Assembler recipeHandlers.add(new AnvilRecipes()); recipeHandlers.add(new PedestalRecipes()); - + recipeHandlers.add(new MatDistribution()); recipeHandlers.add(new CustomMachineRecipes()); //AFTER MatDistribution recipeHandlers.add(new ArcFurnaceRecipes()); } - + public static void initialize() { File recDir = new File(MainRegistry.configDir.getAbsolutePath() + File.separatorChar + "hbmRecipes"); - + if(!recDir.exists()) { if(!recDir.mkdir()) { throw new IllegalStateException("Unable to make recipe directory " + recDir.getAbsolutePath()); } } - + File info = new File(recDir.getAbsolutePath() + File.separatorChar + "REMOVE UNDERSCORE TO ENABLE RECIPE LOADING - RECIPES WILL RESET TO DEFAULT OTHERWISE"); try { info.createNewFile(); } catch(IOException e) { } - + MainRegistry.logger.info("Starting recipe init!"); - + for(SerializableRecipe recipe : recipeHandlers) { - + recipe.deleteRecipes(); - + File recFile = new File(recDir.getAbsolutePath() + File.separatorChar + recipe.getFileName()); - if(recFile.exists() && recFile.isFile()) { + if(recipeSyncHandlers.containsKey(recipe.getFileName())) { + MainRegistry.logger.info("Reading synced recipe file " + recipe.getFileName()); + InputStream stream = recipeSyncHandlers.get(recipe.getFileName()); + + try { + stream.reset(); + Reader reader = new InputStreamReader(stream); + recipe.readRecipeStream(reader); + recipe.modified = true; + } catch(IOException ex) { + MainRegistry.logger.error("Failed to reset synced recipe stream", ex); + } + } else if(recFile.exists() && recFile.isFile()) { MainRegistry.logger.info("Reading recipe file " + recFile.getName()); recipe.readRecipeFile(recFile); recipe.modified = true; } else { MainRegistry.logger.info("No recipe file found, registering defaults for " + recipe.getFileName()); recipe.registerDefaults(); - + for(IRecipeRegisterListener listener : additionalListeners) { listener.onRecipeLoad(recipe.getClass().getSimpleName()); } - + File recTemplate = new File(recDir.getAbsolutePath() + File.separatorChar + "_" + recipe.getFileName()); MainRegistry.logger.info("Writing template file " + recTemplate.getName()); recipe.writeTemplateFile(recTemplate); recipe.modified = false; } - + recipe.registerPost(); } - + MainRegistry.logger.info("Finished recipe init!"); } + public static void receiveRecipes(String filename, byte[] data) { + recipeSyncHandlers.put(filename, new ByteArrayInputStream(data)); + } + + public static void clearReceivedRecipes() { + boolean hasCleared = !recipeSyncHandlers.isEmpty(); + recipeSyncHandlers.clear(); + + if(hasCleared) initialize(); + } + /* * ABSTRACT */ - + /** The machine's (or process') name used for the recipe file */ public abstract String getFileName(); /** Return the list object holding all the recipes, usually an ArrayList or HashMap */ public abstract Object getRecipeObject(); /** Will use the supplied JsonElement (usually casts to JsonArray) from the over arching recipe array and adds the recipe to the recipe list object */ public abstract void readRecipe(JsonElement recipe); - /** Is given a single recipe from the recipe list object (a wrapper, Tuple, array, HashMap Entry, etc) and writes it to the current ongoing GSON stream + /** Is given a single recipe from the recipe list object (a wrapper, Tuple, array, HashMap Entry, etc) and writes it to the current ongoing GSON stream * @throws IOException */ public abstract void writeRecipe(Object recipe, JsonWriter writer) throws IOException; /** Registers the default recipes */ @@ -155,45 +177,45 @@ public abstract class SerializableRecipe { public String getComment() { return null; } - + /* * JSON R/W WRAPPERS */ - + public void writeTemplateFile(File template) { - + try { /* Get the recipe list object */ Object recipeObject = this.getRecipeObject(); List recipeList = new ArrayList(); - + /* Try to pry all recipes from our list */ if(recipeObject instanceof Collection) { recipeList.addAll((Collection) recipeObject); - + } else if(recipeObject instanceof HashMap) { recipeList.addAll(((HashMap) recipeObject).entrySet()); } - + if(recipeList.isEmpty()) throw new IllegalStateException("Error while writing recipes for " + this.getClass().getSimpleName() + ": Recipe list is either empty or in an unsupported format!"); - + JsonWriter writer = new JsonWriter(new FileWriter(template)); writer.setIndent(" "); //pretty formatting writer.beginObject(); //initial '{' - + if(this.getComment() != null) { writer.name("comment").value(this.getComment()); } - + writer.name("recipes").beginArray(); //all recipes are stored in an array called "recipes" - + for(Object recipe : recipeList) { writer.beginObject(); //begin object for a single recipe this.writeRecipe(recipe, writer); //serialize here writer.endObject(); //end recipe object } - + writer.endArray(); //end recipe array writer.endObject(); //final '}' writer.close(); @@ -201,22 +223,25 @@ public abstract class SerializableRecipe { ex.printStackTrace(); } } - + public void readRecipeFile(File file) { - try { - JsonObject json = gson.fromJson(new FileReader(file), JsonObject.class); - JsonArray recipes = json.get("recipes").getAsJsonArray(); - for(JsonElement recipe : recipes) { - this.readRecipe(recipe); - } + readRecipeStream(new FileReader(file)); } catch(FileNotFoundException ex) { } } - + + public void readRecipeStream(Reader reader) { + JsonObject json = gson.fromJson(reader, JsonObject.class); + JsonArray recipes = json.get("recipes").getAsJsonArray(); + for(JsonElement recipe : recipes) { + this.readRecipe(recipe); + } + } + /* * JSON IO UTIL */ - + public static AStack readAStack(JsonArray array) { try { String type = array.get(0).getAsString(); @@ -234,7 +259,7 @@ public abstract class SerializableRecipe { MainRegistry.logger.error("Error reading stack array " + array.toString()); return new ComparableStack(ModItems.nothing); } - + public static AStack[] readAStackArray(JsonArray array) { try { AStack[] items = new AStack[array.size()]; @@ -244,7 +269,7 @@ public abstract class SerializableRecipe { MainRegistry.logger.error("Error reading stack array " + array.toString()); return new AStack[0]; } - + public static void writeAStack(AStack astack, JsonWriter writer) throws IOException { writer.beginArray(); writer.setIndent(""); @@ -264,7 +289,7 @@ public abstract class SerializableRecipe { writer.endArray(); writer.setIndent(" "); } - + public static ItemStack readItemStack(JsonArray array) { try { Item item = (Item) Item.itemRegistry.getObject(array.get(0).getAsString()); @@ -275,7 +300,7 @@ public abstract class SerializableRecipe { MainRegistry.logger.error("Error reading stack array " + array.toString() + " - defaulting to NOTHING item!"); return new ItemStack(ModItems.nothing); } - + public static Pair readItemStackChance(JsonArray array) { try { Item item = (Item) Item.itemRegistry.getObject(array.get(0).getAsString()); @@ -287,7 +312,7 @@ public abstract class SerializableRecipe { MainRegistry.logger.error("Error reading stack array " + array.toString() + " - defaulting to NOTHING item!"); return new Pair(new ItemStack(ModItems.nothing), 1F); } - + public static ItemStack[] readItemStackArray(JsonArray array) { try { ItemStack[] items = new ItemStack[array.size()]; @@ -297,7 +322,7 @@ public abstract class SerializableRecipe { MainRegistry.logger.error("Error reading stack array " + array.toString()); return new ItemStack[0]; } - + public static Pair[] readItemStackArrayChance(JsonArray array) { try { Pair[] items = new Pair[array.size()]; @@ -307,7 +332,7 @@ public abstract class SerializableRecipe { MainRegistry.logger.error("Error reading stack array " + array.toString()); return new Pair[0]; } - + public static void writeItemStack(ItemStack stack, JsonWriter writer) throws IOException { writer.beginArray(); writer.setIndent(""); @@ -317,7 +342,7 @@ public abstract class SerializableRecipe { writer.endArray(); writer.setIndent(" "); } - + public static void writeItemStackChance(Pair stack, JsonWriter writer) throws IOException { writer.beginArray(); writer.setIndent(""); @@ -328,7 +353,7 @@ public abstract class SerializableRecipe { writer.endArray(); writer.setIndent(" "); } - + public static FluidStack readFluidStack(JsonArray array) { try { FluidType type = Fluids.fromName(array.get(0).getAsString()); @@ -339,7 +364,7 @@ public abstract class SerializableRecipe { MainRegistry.logger.error("Error reading fluid array " + array.toString()); return new FluidStack(Fluids.NONE, 0); } - + public static FluidStack[] readFluidArray(JsonArray array) { try { FluidStack[] fluids = new FluidStack[array.size()]; @@ -349,7 +374,7 @@ public abstract class SerializableRecipe { MainRegistry.logger.error("Error reading fluid array " + array.toString()); return new FluidStack[0]; } - + public static void writeFluidStack(FluidStack stack, JsonWriter writer) throws IOException { writer.beginArray(); writer.setIndent(""); @@ -359,12 +384,12 @@ public abstract class SerializableRecipe { writer.endArray(); writer.setIndent(" "); } - + public static boolean matchesIngredients(ItemStack[] inputs, AStack[] recipe) { List recipeList = new ArrayList(); for(AStack ingredient : recipe) recipeList.add(ingredient); - + for(int i = 0; i < inputs.length; i++) { ItemStack inputStack = inputs[i]; diff --git a/src/main/java/com/hbm/main/ModEventHandler.java b/src/main/java/com/hbm/main/ModEventHandler.java index 2d27eadb8..d587ebe4b 100644 --- a/src/main/java/com/hbm/main/ModEventHandler.java +++ b/src/main/java/com/hbm/main/ModEventHandler.java @@ -11,7 +11,6 @@ import com.hbm.config.RadiationConfig; import com.hbm.config.ServerConfig; import com.hbm.entity.mob.*; import com.hbm.entity.mob.ai.EntityAIFireGun; -import com.hbm.entity.mob.EntityCreeperTainted; import com.hbm.entity.projectile.EntityBulletBaseMK4; import com.hbm.entity.projectile.EntityBurningFOEQ; import com.hbm.entity.train.EntityRailCarBase; @@ -24,6 +23,7 @@ import com.hbm.handler.EntityEffectHandler; import com.hbm.hazard.HazardSystem; import com.hbm.interfaces.IBomb; import com.hbm.interfaces.Spaghetti; +import com.hbm.inventory.recipes.loader.SerializableRecipe; import com.hbm.handler.HTTPHandler; import com.hbm.handler.HbmKeybinds.EnumKeybind; import com.hbm.handler.neutron.NeutronNodeWorld; @@ -43,6 +43,7 @@ import com.hbm.lib.RefStrings; import com.hbm.packet.PacketDispatcher; import com.hbm.packet.toclient.PermaSyncPacket; import com.hbm.packet.toclient.PlayerInformPacket; +import com.hbm.packet.toclient.SerializableRecipePacket; import com.hbm.particle.helper.BlackPowderCreator; import com.hbm.potion.HbmPotion; import com.hbm.tileentity.machine.TileEntityMachineRadarNT; @@ -53,6 +54,8 @@ import com.hbm.uninos.UniNodespace; import com.hbm.util.*; import com.hbm.util.ArmorRegistry.HazardClass; import com.hbm.world.generator.TimedGenerator; + +import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.eventhandler.EventPriority; import cpw.mods.fml.common.eventhandler.SubscribeEvent; import cpw.mods.fml.common.gameevent.PlayerEvent; @@ -60,7 +63,9 @@ import cpw.mods.fml.common.gameevent.PlayerEvent.PlayerChangedDimensionEvent; import cpw.mods.fml.common.gameevent.TickEvent; import cpw.mods.fml.common.gameevent.TickEvent.Phase; import cpw.mods.fml.common.gameevent.TickEvent.WorldTickEvent; +import cpw.mods.fml.common.network.FMLNetworkEvent.ClientDisconnectionFromServerEvent; import cpw.mods.fml.relauncher.ReflectionHelper; +import cpw.mods.fml.relauncher.Side; import io.netty.buffer.ByteBuf; import io.netty.buffer.PooledByteBufAllocator; import net.minecraft.block.Block; @@ -113,6 +118,7 @@ import net.minecraftforge.event.world.WorldEvent; import org.apache.commons.lang3.math.NumberUtils; import org.apache.logging.log4j.Level; +import java.io.File; import java.lang.reflect.Field; import java.util.*; @@ -158,9 +164,35 @@ public class ModEventHandler { props.hasReceivedBook = true; } } + + if(GeneralConfig.enableServerRecipeSync && FMLCommonHandler.instance().getSide() == Side.SERVER && event.player instanceof EntityPlayerMP) { + File recDir = new File(MainRegistry.configDir.getAbsolutePath() + File.separatorChar + "hbmRecipes"); + + MainRegistry.logger.info("Sending recipes to client!"); + + boolean hasSent = false; + + for(SerializableRecipe recipe : SerializableRecipe.recipeHandlers) { + File recFile = new File(recDir.getAbsolutePath() + File.separatorChar + recipe.getFileName()); + if(recFile.exists() && recFile.isFile()) { + MainRegistry.logger.info("Sending recipe file: " + recFile.getName()); + PacketDispatcher.wrapper.sendTo(new SerializableRecipePacket(recFile), (EntityPlayerMP) event.player); + hasSent = true; + } + } + + if(hasSent) { + PacketDispatcher.wrapper.sendTo(new SerializableRecipePacket(true), (EntityPlayerMP) event.player); + } + } } } + @SubscribeEvent + public void onPlayerLeftClient(ClientDisconnectionFromServerEvent event) { + SerializableRecipe.clearReceivedRecipes(); + } + @SubscribeEvent public void onPlayerRespawn(PlayerEvent.PlayerRespawnEvent event) { @@ -657,13 +689,13 @@ public class ModEventHandler { if(event.phase == Phase.END) { int tickrate = Math.max(1, ServerConfig.ITEM_HAZARD_DROP_TICKRATE.get()); - + if(event.world.getTotalWorldTime() % tickrate == 0) { List loadedEntityList = new ArrayList(); loadedEntityList.addAll(event.world.loadedEntityList); // ConcurrentModificationException my balls - + for(Object e : loadedEntityList) { - + if(e instanceof EntityItem) { EntityItem item = (EntityItem) e; HazardSystem.updateDroppedItem(item); diff --git a/src/main/java/com/hbm/packet/PacketDispatcher.java b/src/main/java/com/hbm/packet/PacketDispatcher.java index b749cfdd3..6d82b2b28 100644 --- a/src/main/java/com/hbm/packet/PacketDispatcher.java +++ b/src/main/java/com/hbm/packet/PacketDispatcher.java @@ -69,6 +69,8 @@ public class PacketDispatcher { wrapper.registerMessage(BiomeSyncPacket.Handler.class, BiomeSyncPacket.class, i++, Side.CLIENT); //The not-so-convenient but not laggy one wrapper.registerMessage(BufPacket.Handler.class, BufPacket.class, i++, Side.CLIENT); + //Syncs server recipe configs to the client + wrapper.registerMessage(SerializableRecipePacket.Handler.class, SerializableRecipePacket.class, i++, Side.CLIENT); } } diff --git a/src/main/java/com/hbm/packet/toclient/SerializableRecipePacket.java b/src/main/java/com/hbm/packet/toclient/SerializableRecipePacket.java new file mode 100644 index 000000000..7992d9163 --- /dev/null +++ b/src/main/java/com/hbm/packet/toclient/SerializableRecipePacket.java @@ -0,0 +1,76 @@ +package com.hbm.packet.toclient; + +import java.io.*; +import java.nio.file.Files; + +import com.hbm.inventory.recipes.loader.SerializableRecipe; +import com.hbm.util.BufferUtil; + +import cpw.mods.fml.common.network.simpleimpl.IMessage; +import cpw.mods.fml.common.network.simpleimpl.IMessageHandler; +import cpw.mods.fml.common.network.simpleimpl.MessageContext; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import io.netty.buffer.ByteBuf; + +public class SerializableRecipePacket implements IMessage { + + private String filename; + private byte[] fileBytes; + + private boolean reinit; + + public SerializableRecipePacket() {} + + public SerializableRecipePacket(File recipeFile) { + try { + filename = recipeFile.getName(); + fileBytes = Files.readAllBytes(recipeFile.toPath()); + } catch(IOException ex) {} + } + + public SerializableRecipePacket(boolean reinit) { + this.reinit = reinit; + } + + @Override + public void fromBytes(ByteBuf buf) { + reinit = buf.readBoolean(); + if(reinit) return; + + filename = BufferUtil.readString(buf); + fileBytes = new byte[buf.readInt()]; + buf.readBytes(fileBytes); + } + + @Override + public void toBytes(ByteBuf buf) { + buf.writeBoolean(reinit); + if(reinit) return; + + BufferUtil.writeString(buf, filename); + buf.writeInt(fileBytes.length); + buf.writeBytes(fileBytes); + } + + public static class Handler implements IMessageHandler { + + @Override + @SideOnly(Side.CLIENT) + public IMessage onMessage(SerializableRecipePacket m, MessageContext ctx) { + try { + + // Only reinitialize after receiving all recipes + if(m.reinit) { + SerializableRecipe.initialize(); + return null; + } + + SerializableRecipe.receiveRecipes(m.filename, m.fileBytes); + + } catch (Exception x) { } + return null; + } + } + +} From 7d6289b228a5e841a257280bc8f8d070e7c4e9d8 Mon Sep 17 00:00:00 2001 From: George Paton Date: Mon, 26 May 2025 10:12:46 +1000 Subject: [PATCH 2/4] fix dummy blocks with detailed hitboxes not using them for clicks (interaction/breaking) --- .../java/com/hbm/blocks/BlockDummyable.java | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/main/java/com/hbm/blocks/BlockDummyable.java b/src/main/java/com/hbm/blocks/BlockDummyable.java index 75dd39c2f..fa604e66e 100644 --- a/src/main/java/com/hbm/blocks/BlockDummyable.java +++ b/src/main/java/com/hbm/blocks/BlockDummyable.java @@ -26,6 +26,8 @@ import net.minecraft.stats.StatList; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.MathHelper; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.Vec3; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; import net.minecraftforge.client.event.DrawBlockHighlightEvent; @@ -467,6 +469,33 @@ public abstract class BlockDummyable extends BlockContainer implements ICustomBl return AxisAlignedBB.getBoundingBox(aabb.minX, aabb.minY, aabb.minZ, aabb.maxX, aabb.maxY, aabb.maxZ).offset(x + 0.5, y + 0.5, z + 0.5); } + @Override + public MovingObjectPosition collisionRayTrace(World world, int x, int y, int z, Vec3 startVec, Vec3 endVec) { + if(!this.useDetailedHitbox()) { + return super.collisionRayTrace(world, x, y, z, startVec, endVec); + } + + int[] pos = this.findCore(world, x, y, z); + + if(pos == null) + return super.collisionRayTrace(world, x, y, z, startVec, endVec); + + x = pos[0]; + y = pos[1]; + z = pos[2]; + + for(AxisAlignedBB aabb :this.bounding) { + AxisAlignedBB boxlet = getAABBRotationOffset(aabb, x + 0.5, y, z + 0.5, ForgeDirection.getOrientation(world.getBlockMetadata(x, y, z) - offset).getRotation(ForgeDirection.UP)); + + MovingObjectPosition intercept = boxlet.calculateIntercept(startVec, endVec); + if(intercept != null) { + return new MovingObjectPosition(x, y, z, intercept.sideHit, intercept.hitVec); + } + } + + return null; + } + @Override public void setBlockBoundsBasedOnState(IBlockAccess world, int x, int y, int z) { if(!this.useDetailedHitbox()) { From 87a1c01fe72538b478b1830c97bd1966299ed228 Mon Sep 17 00:00:00 2001 From: George Paton Date: Fri, 30 May 2025 09:53:46 +1000 Subject: [PATCH 3/4] disable recipe sync by default, can be enabled by server operators --- src/main/java/com/hbm/config/GeneralConfig.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/hbm/config/GeneralConfig.java b/src/main/java/com/hbm/config/GeneralConfig.java index ed0f1af67..09900f007 100644 --- a/src/main/java/com/hbm/config/GeneralConfig.java +++ b/src/main/java/com/hbm/config/GeneralConfig.java @@ -38,7 +38,7 @@ public class GeneralConfig { public static boolean enableGuideBook = true; public static boolean enableSoundExtension = true; public static boolean enableMekanismChanges = true; - public static boolean enableServerRecipeSync = true; + public static boolean enableServerRecipeSync = false; public static int normalSoundChannels = 200; public static boolean enableExpensiveMode = false; @@ -82,7 +82,7 @@ public class GeneralConfig { packetThreadingMaxCount = config.get(CATEGORY_GENERAL, "0.03_packetThreadingMaxCount", 1, "Maximum number of threads to create for packet threading. Must be greater than or equal to 0.02_packetThreadingCoreCount.").getInt(1); packetThreadingErrorBypass = config.get(CATEGORY_GENERAL, "0.04_packetThreadingErrorBypass", false, "Forces the bypassing of most packet threading errors, only enable this if directed to or if you know what you're doing.").getBoolean(false); - enableServerRecipeSync = config.get(CATEGORY_GENERAL, "0.05_enableServerRecipeSync", true, "Syncs any recipes customised via JSON to clients connecting to the server.").getBoolean(true); + enableServerRecipeSync = config.get(CATEGORY_GENERAL, "0.05_enableServerRecipeSync", false, "Syncs any recipes customised via JSON to clients connecting to the server.").getBoolean(false); enableDebugMode = config.get(CATEGORY_GENERAL, "1.00_enableDebugMode", false, "Enable debugging mode").getBoolean(false); enableMycelium = config.get(CATEGORY_GENERAL, "1.01_enableMyceliumSpread", false, "Allows glowing mycelium to spread").getBoolean(false); From e6b84bd6d361ed890e4b786c56794a2530babe2f Mon Sep 17 00:00:00 2001 From: George Paton Date: Fri, 30 May 2025 09:54:39 +1000 Subject: [PATCH 4/4] fix guard on checkNBT --- src/main/java/com/hbm/items/ItemInventory.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/hbm/items/ItemInventory.java b/src/main/java/com/hbm/items/ItemInventory.java index 63c5083a7..dd897a66e 100644 --- a/src/main/java/com/hbm/items/ItemInventory.java +++ b/src/main/java/com/hbm/items/ItemInventory.java @@ -38,7 +38,7 @@ public abstract class ItemInventory implements IInventory { } public NBTTagCompound checkNBT(NBTTagCompound nbt) { - if(nbt == null || !nbt.hasNoTags()) { + if(nbt != null && !nbt.hasNoTags()) { Random random = new Random(); try {