mirror of
https://github.com/GTNewHorizons/EnderIO.git
synced 2026-10-25 20:22:23 +00:00
remove direct getStackInSlot exploit (#245)
Co-authored-by: Martin Robertz <dream-master@gmx.net> Co-authored-by: attempt0 <nanolify@gmail.com>
This commit is contained in:
6 files changed
+188
-94
No files matched your search
+15
-15
@@ -2,26 +2,26 @@
|
||||
|
||||
dependencies {
|
||||
api('com.github.GTNewHorizons:EnderCore:0.5.14:dev') {transitive = false}
|
||||
compileOnly('com.github.GTNewHorizons:ForestryMC:4.11.32:dev')
|
||||
compileOnly('com.github.GTNewHorizons:NotEnoughItems:2.8.118-GTNH:dev')
|
||||
api("com.github.GTNewHorizons:GTNHLib:0.11.35:dev")
|
||||
compileOnly('com.github.GTNewHorizons:ForestryMC:4.11.37:dev')
|
||||
compileOnly('com.github.GTNewHorizons:NotEnoughItems:2.8.129-GTNH:dev')
|
||||
api("com.github.GTNewHorizons:GTNHLib:0.11.44:dev")
|
||||
compileOnly('com.github.GTNewHorizons:BuildCraft:7.1.63:dev')
|
||||
api('curse.maven:cofh-lib-220333:2388748') // https://www.curseforge.com/minecraft/mc-mods/cofh-lib/files/2388748
|
||||
shadowImplementation('cglib:cglib-nodep:3.3.0')
|
||||
api("com.github.GTNewHorizons:TinkersConstruct:1.14.96-GTNH:dev")
|
||||
api("com.github.GTNewHorizons:TinkersConstruct:1.14.106-GTNH:dev")
|
||||
|
||||
devOnlyNonPublishable('com.github.GTNewHorizons:waila:1.19.31:dev') {transitive = false}
|
||||
devOnlyNonPublishable('com.github.GTNewHorizons:waila:1.19.34:dev') {transitive = false}
|
||||
compileOnly('ganymedes01.etfuturum:Et-Futurum-Requiem:2.6.48-GTNH:dev') {transitive = false}
|
||||
runtimeOnlyNonPublishable('com.github.GTNewHorizons:WAILAPlugins:0.7.2:dev') {transitive = false}
|
||||
compileOnly("com.github.GTNewHorizons:Backhand:1.8.13:dev") { transitive = false }
|
||||
compileOnly("com.github.GTNewHorizons:Backhand:1.8.14:dev") { transitive = false }
|
||||
compileOnly('com.github.GTNewHorizons:Applied-Energistics-2-Unofficial:rv3-beta-999-GTNH:api') {transitive = false}
|
||||
compileOnly('com.github.GTNewHorizons:Baubles-Expanded:2.2.21-GTNH:dev') {transitive = false}
|
||||
compileOnly('com.github.GTNewHorizons:GT5-Unofficial:5.09.54.73:dev') {transitive = false}
|
||||
compileOnly("com.github.GTNewHorizons:ModularUI2:2.3.85-1.7.10:dev") {transitive = false}
|
||||
compileOnly('com.github.GTNewHorizons:Railcraft:9.17.30:dev') {transitive = false}
|
||||
compileOnly('com.github.GTNewHorizons:StorageDrawers:2.2.26-GTNH:api') {transitive = false}
|
||||
compileOnly('com.github.GTNewHorizons:Chisel:2.17.31-GTNH:dev') {transitive = false}
|
||||
compileOnly('com.github.GTNewHorizons:OpenComputers:1.12.55-GTNH:api') {transitive = false}
|
||||
compileOnly('com.github.GTNewHorizons:Baubles-Expanded:2.2.22-GTNH:dev') {transitive = false}
|
||||
compileOnly('com.github.GTNewHorizons:GT5-Unofficial:5.09.54.122:dev') {transitive = false}
|
||||
compileOnly("com.github.GTNewHorizons:ModularUI2:2.3.88-1.7.10:dev") {transitive = false}
|
||||
compileOnly('com.github.GTNewHorizons:Railcraft:9.17.31:dev') {transitive = false}
|
||||
compileOnly('com.github.GTNewHorizons:StorageDrawers:2.2.29-GTNH:api') {transitive = false}
|
||||
compileOnly('com.github.GTNewHorizons:Chisel:2.17.32-GTNH:dev') {transitive = false}
|
||||
compileOnly('com.github.GTNewHorizons:OpenComputers:1.12.59-GTNH:api') {transitive = false}
|
||||
compileOnly('curse.maven:minefactory-reloaded-66672:2366150') // https://www.curseforge.com/minecraft/mc-mods/minefactory-reloaded/files/2366150
|
||||
compileOnly('thaumcraft:Thaumcraft:1.7.10-4.2.3.5:dev')
|
||||
compileOnly('curse.maven:ee3-65509:2305023') // https://www.curseforge.com/minecraft/mc-mods/ee3/files/2305023
|
||||
@@ -29,7 +29,7 @@ dependencies {
|
||||
compileOnly(rfg.deobf('curse.maven:mekanism-268560:2475797')) // https://www.curseforge.com/minecraft/mc-mods/mekanism/files/2475797
|
||||
compileOnly(rfg.deobf('maven.modrinth:immibis-microblocks:59.1.2')) // https://modrinth.com/mod/immibis-microblocks/version/59.1.2
|
||||
|
||||
compileOnlyApi('com.github.GTNewHorizons:Angelica:2.1.60:api') {transitive = false}
|
||||
compileOnly("com.github.GTNewHorizons:Hodgepodge:2.7.179:dev")
|
||||
compileOnlyApi('com.github.GTNewHorizons:Angelica:2.2.8:api') {transitive = false}
|
||||
compileOnly("com.github.GTNewHorizons:Hodgepodge:2.7.194:dev")
|
||||
compileOnly('curse.maven:automagy-222153:2285272')
|
||||
}
|
||||
@@ -1,12 +1,12 @@
|
||||
#This file is generated by updateDaemonJvm
|
||||
toolchainUrl.FREE_BSD.AARCH64=https\://api.foojay.io/disco/v3.0/ids/97d46b5ff4df0bf61e95652a190a5567/redirect
|
||||
toolchainUrl.FREE_BSD.X86_64=https\://api.foojay.io/disco/v3.0/ids/9ef54a08e06b0754cee9fc95ed3a3134/redirect
|
||||
toolchainUrl.LINUX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/97d46b5ff4df0bf61e95652a190a5567/redirect
|
||||
toolchainUrl.LINUX.X86_64=https\://api.foojay.io/disco/v3.0/ids/9ef54a08e06b0754cee9fc95ed3a3134/redirect
|
||||
toolchainUrl.MAC_OS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/1df82b76031285ef2e6a4f59ffe9299d/redirect
|
||||
toolchainUrl.MAC_OS.X86_64=https\://api.foojay.io/disco/v3.0/ids/c7d5be6a02945ac2e045048ee54a7d32/redirect
|
||||
toolchainUrl.UNIX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/97d46b5ff4df0bf61e95652a190a5567/redirect
|
||||
toolchainUrl.UNIX.X86_64=https\://api.foojay.io/disco/v3.0/ids/9ef54a08e06b0754cee9fc95ed3a3134/redirect
|
||||
toolchainUrl.WINDOWS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/643f404f769811f5f265fd66f7af5d89/redirect
|
||||
toolchainUrl.WINDOWS.X86_64=https\://api.foojay.io/disco/v3.0/ids/38256085a73e137cb4937ea9c4807fec/redirect
|
||||
toolchainUrl.FREE_BSD.AARCH64=https\://api.foojay.io/disco/v3.0/ids/539ea72837c6244075f8ee037babc29e/redirect
|
||||
toolchainUrl.FREE_BSD.X86_64=https\://api.foojay.io/disco/v3.0/ids/876dbbf00bf4ef6190f7da074cee903a/redirect
|
||||
toolchainUrl.LINUX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/539ea72837c6244075f8ee037babc29e/redirect
|
||||
toolchainUrl.LINUX.X86_64=https\://api.foojay.io/disco/v3.0/ids/876dbbf00bf4ef6190f7da074cee903a/redirect
|
||||
toolchainUrl.MAC_OS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/9064f22734b42ac03e85df04b632e167/redirect
|
||||
toolchainUrl.MAC_OS.X86_64=https\://api.foojay.io/disco/v3.0/ids/4d0277c49991306ac78048580fe34bcf/redirect
|
||||
toolchainUrl.UNIX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/539ea72837c6244075f8ee037babc29e/redirect
|
||||
toolchainUrl.UNIX.X86_64=https\://api.foojay.io/disco/v3.0/ids/876dbbf00bf4ef6190f7da074cee903a/redirect
|
||||
toolchainUrl.WINDOWS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/a9fa3b809e484a1e1ac4308a5dda661a/redirect
|
||||
toolchainUrl.WINDOWS.X86_64=https\://api.foojay.io/disco/v3.0/ids/aa99913fa6d767d899ffc96082da01ca/redirect
|
||||
toolchainVersion=25
|
||||
+1
-1
@@ -17,7 +17,7 @@ pluginManagement {
|
||||
}
|
||||
|
||||
plugins {
|
||||
id 'com.gtnewhorizons.gtnhsettingsconvention' version '2.0.27'
|
||||
id 'com.gtnewhorizons.gtnhsettingsconvention' version '2.0.29'
|
||||
}
|
||||
|
||||
|
||||
@@ -597,6 +597,11 @@ public final class Config {
|
||||
|
||||
public static float fusedQuartzExplosionResistance = 2000.0f;
|
||||
|
||||
public static boolean enchanterOutputEnableBlockRestriction = false;
|
||||
public static boolean enchanterOutputAllowlistAsDenylist = false;
|
||||
public static String[] enchanterOutputFilterlist = new String[] { "minecraft:hopper",
|
||||
"EnderIO:blockConduitBundle" };
|
||||
|
||||
public static void load(FMLPreInitializationEvent event) {
|
||||
PacketHandler.INSTANCE
|
||||
.registerMessage(PacketConfigSync.class, PacketConfigSync.class, PacketHandler.nextID(), Side.CLIENT);
|
||||
@@ -2978,6 +2983,22 @@ public final class Config {
|
||||
0.0f,
|
||||
Float.MAX_VALUE,
|
||||
"How blast resistant the three Fused Quartz blocks should be.");
|
||||
|
||||
enchanterOutputEnableBlockRestriction = config.getBoolean(
|
||||
"enchanterOutputEnableBlockRestriction",
|
||||
sectionMisc.name,
|
||||
enchanterOutputEnableBlockRestriction,
|
||||
"Enable restricting the valid blocks that are allowed to pull from the output slot of an Enchanter, to prevent dupes");
|
||||
enchanterOutputAllowlistAsDenylist = config.getBoolean(
|
||||
"enchanterOutputAllowlistAsDenylist",
|
||||
sectionMisc.name,
|
||||
enchanterOutputAllowlistAsDenylist,
|
||||
"Treat the list of blocks allowed to pull from an Enchanter's output slot as a denylist instead (if you know only some specific blocks bypass inventory APIs)");
|
||||
enchanterOutputFilterlist = config.getStringList(
|
||||
"enchanterOutputFilterlist",
|
||||
sectionMisc.name,
|
||||
enchanterOutputFilterlist,
|
||||
"These blocks are allowed/denied from pulling from the output slot of an Enchanter (default is allowlist)");
|
||||
}
|
||||
|
||||
public static void checkYetaAccess() {
|
||||
|
||||
@@ -68,6 +68,11 @@ public class ContainerEnchanter extends ContainerEnderTileEntity<TileEnchanter>
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getStack() {
|
||||
return te.getOutput();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPickupFromSlot(EntityPlayer player, ItemStack stack) {
|
||||
if (!player.capabilities.isCreativeMode) {
|
||||
|
||||
@@ -2,8 +2,6 @@ package crazypants.enderio.machine.enchanter;
|
||||
|
||||
import static crazypants.enderio.EnderIO.hasAutomagy;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import net.minecraft.enchantment.EnchantmentData;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.init.Items;
|
||||
@@ -11,16 +9,21 @@ import net.minecraft.inventory.ISidedInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
|
||||
import com.gtnewhorizon.gtnhlib.geometry.CubeIterator;
|
||||
|
||||
import cpw.mods.fml.common.registry.GameRegistry;
|
||||
import crazypants.enderio.Log;
|
||||
import crazypants.enderio.ModObject;
|
||||
import crazypants.enderio.TileEntityEio;
|
||||
import crazypants.enderio.config.Config;
|
||||
import crazypants.enderio.machine.obelisk.xp.TileExperienceObelisk;
|
||||
import crazypants.enderio.xp.ExperienceContainer;
|
||||
import crazypants.enderio.xp.XpUtil;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
import tuhljin.automagy.tiles.TileEntityJarXP;
|
||||
|
||||
public class TileEnchanter extends TileEntityEio implements ISidedInventory {
|
||||
@@ -28,6 +31,8 @@ public class TileEnchanter extends TileEntityEio implements ISidedInventory {
|
||||
private final ItemStack[] inv = new ItemStack[3];
|
||||
private byte[] stacksizes = new byte[2];
|
||||
|
||||
private IntList cachedXPsources = new IntArrayList();
|
||||
|
||||
private short facing = (short) ForgeDirection.NORTH.ordinal();
|
||||
|
||||
public void setFacing(short s) {
|
||||
@@ -65,6 +70,9 @@ public class TileEnchanter extends TileEntityEio implements ISidedInventory {
|
||||
root.setTag("Items", itemList);
|
||||
root.setByteArray("SizeCache", stacksizes);
|
||||
root.setShort("facing", facing);
|
||||
root.setIntArray(
|
||||
"XpCache",
|
||||
(cachedXPsources.size() <= 200 ? cachedXPsources : cachedXPsources.subList(0, 200)).toIntArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -82,6 +90,11 @@ public class TileEnchanter extends TileEntityEio implements ISidedInventory {
|
||||
stacksizes = root.getByteArray("SizeCache");
|
||||
if (stacksizes == null || stacksizes.length < 2) stacksizes = new byte[2];
|
||||
facing = root.getShort("facing");
|
||||
cachedXPsources.clear();
|
||||
int[] xpcache = root.getIntArray("XpCache");
|
||||
if (xpcache != null) {
|
||||
cachedXPsources.addAll(IntList.of(xpcache));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -96,9 +109,10 @@ public class TileEnchanter extends TileEntityEio implements ISidedInventory {
|
||||
|
||||
@Override
|
||||
public ItemStack getStackInSlot(int slot) {
|
||||
if (slot < 0 || slot >= inv.length) {
|
||||
if (slot < 0 || slot > inv.length - 1) {
|
||||
return null;
|
||||
}
|
||||
if (slot == 2 && !doesCraftHaveXP()) return null;
|
||||
return inv[slot];
|
||||
}
|
||||
|
||||
@@ -130,69 +144,97 @@ public class TileEnchanter extends TileEntityEio implements ISidedInventory {
|
||||
return result;
|
||||
}
|
||||
|
||||
// part of the next method
|
||||
public boolean absorbXP(int amt) {
|
||||
if (inv[2] == null || amt <= 0 || inv[2].stackSize < amt) return true;
|
||||
public boolean doesCraftHaveXP() {
|
||||
if (inv[2] == null) return false;
|
||||
int LV = getCurrentEnchantmentCost();
|
||||
if (LV == 0) return false;
|
||||
int xpCost = XpUtil.getExperienceForLevel(LV * amt);
|
||||
int xp;
|
||||
absorb: {
|
||||
ArrayList<ExperienceContainer> obelisksToEmpty = new ArrayList<>();
|
||||
if (true) {
|
||||
CubeIterator iter = new CubeIterator(8);
|
||||
while (iter.hasNext()) {
|
||||
iter.next();
|
||||
if (worldObj.getTileEntity(
|
||||
iter.n + xCoord,
|
||||
iter.l + yCoord,
|
||||
iter.m + zCoord) instanceof TileExperienceObelisk obelisk) {
|
||||
ExperienceContainer cont = obelisk.getContainer();
|
||||
xp = cont.getExperienceTotal();
|
||||
if (xp >= xpCost) {
|
||||
if (!worldObj.isRemote) {
|
||||
obelisksToEmpty.forEach(o -> o.drain(null, Integer.MAX_VALUE, true));
|
||||
cont.drain(null, Integer.MAX_VALUE, true);
|
||||
cont.addExperience(Math.max(0, xp - xpCost));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
xpCost -= xp;
|
||||
obelisksToEmpty.add(cont);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hasAutomagy) {
|
||||
ArrayList<TileEntityJarXP> jarsToEmpty = new ArrayList<>();
|
||||
CubeIterator iter = new CubeIterator(8);
|
||||
while (iter.hasNext()) {
|
||||
iter.next();
|
||||
if (worldObj.getTileEntity(
|
||||
iter.n + xCoord,
|
||||
iter.l + yCoord,
|
||||
iter.m + zCoord) instanceof TileEntityJarXP jar) {
|
||||
xp = jar.getXP();
|
||||
if (xp >= xpCost) {
|
||||
if (!worldObj.isRemote) {
|
||||
obelisksToEmpty.forEach(o -> o.drain(null, Integer.MAX_VALUE, true));
|
||||
jarsToEmpty.forEach(j -> j.setXP(0));
|
||||
jar.setXP(xp - xpCost);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
xpCost -= xp;
|
||||
jarsToEmpty.add(jar);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (LV == 0) return true;
|
||||
return checkAndCacheXPSources(XpUtil.getExperienceForLevel(LV));
|
||||
}
|
||||
|
||||
// checks AND drains XP; returns true if xp is NOT sufficient
|
||||
private boolean checkAndCacheXPSources(int xpCost) {
|
||||
if (drainFromCache(xpCost, false)) return true;
|
||||
cachedXPsources.clear();
|
||||
int xp;
|
||||
CubeIterator iter;
|
||||
iter = new CubeIterator(8);
|
||||
while (iter.hasNext()) {
|
||||
iter.next();
|
||||
int x = iter.n + xCoord;
|
||||
int y = iter.l + yCoord;
|
||||
int z = iter.m + zCoord;
|
||||
if (!worldObj.blockExists(x, y, z)) continue;
|
||||
final TileEntity te = worldObj.getTileEntity(x, y, z);
|
||||
if (te instanceof TileExperienceObelisk obelisk) {
|
||||
ExperienceContainer cont = obelisk.getContainer();
|
||||
xp = cont.getExperienceTotal();
|
||||
if (xp != 0) cachedXPsources.add(((iter.n & 0xff) << 16) + ((iter.l & 0xff) << 8) + (iter.m & 0xff));
|
||||
if (xp >= xpCost) return true;
|
||||
xpCost -= xp;
|
||||
} else if (hasAutomagy && te instanceof TileEntityJarXP jar) {
|
||||
xp = jar.getXP();
|
||||
if (xp != 0) cachedXPsources.add(((iter.n & 0xff) << 16) + ((iter.l & 0xff) << 8) + (iter.m & 0xff));
|
||||
if (xp >= xpCost) return true;
|
||||
xpCost -= xp;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean drainFromCache(int xpCost, boolean actual) {
|
||||
ExperienceContainer cont;
|
||||
int len = cachedXPsources.size();
|
||||
if (len == 0) return false;
|
||||
for (int ind = 0; ind < len; ind++) {
|
||||
int nlm = cachedXPsources.getInt(ind);
|
||||
int z = (byte) nlm + zCoord;
|
||||
int y = (byte) (nlm >>= 8) + yCoord;
|
||||
int x = (byte) (nlm >>= 8) + xCoord;
|
||||
if (!worldObj.blockExists(x, y, z)) continue;
|
||||
TileEntity te = worldObj.getTileEntity(x, y, z);
|
||||
if (te instanceof TileExperienceObelisk obelisk) {
|
||||
cont = obelisk.getContainer();
|
||||
int xp = cont.getExperienceTotal();
|
||||
if (xp == 0) continue;
|
||||
if (actual) cont.drain(null, Integer.MAX_VALUE, true);
|
||||
int ebx = xp - xpCost;
|
||||
if (ebx < 0) {
|
||||
xpCost = -ebx;
|
||||
continue;
|
||||
}
|
||||
if (actual) cont.addExperience(ebx);
|
||||
return true;
|
||||
}
|
||||
if (hasAutomagy && te instanceof TileEntityJarXP jar) {
|
||||
int xp = jar.getXP();
|
||||
if (xp == 0) continue;
|
||||
int ebx = xp - xpCost; // 5head JIT optimization
|
||||
if (ebx < 0) {
|
||||
xpCost = -ebx;
|
||||
if (actual) jar.setXP(0);
|
||||
continue;
|
||||
}
|
||||
if (actual) jar.setXP(ebx);
|
||||
return true;
|
||||
}
|
||||
cachedXPsources.removeInt(ind);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// part of the next method
|
||||
private boolean absorbXP(int amt) {
|
||||
if (inv[2] == null) return false;
|
||||
int LV = getCurrentEnchantmentCost();
|
||||
if (LV == 0) return true;
|
||||
int xpCost = XpUtil.getExperienceForLevel(LV * amt);
|
||||
if (!checkAndCacheXPSources(xpCost)) return false;
|
||||
return drainFromCache(xpCost, !worldObj.isRemote);
|
||||
}
|
||||
|
||||
// checks AND drains XP; returns false if xp is not sufficient
|
||||
// also removes the items from the other two slots when automation does the recipe
|
||||
public boolean checkAndDrainXP(int amt) {
|
||||
if (absorbXP(amt)) return true;
|
||||
private boolean checkAndDrainXP(int amt) {
|
||||
if (!absorbXP(amt)) return false;
|
||||
EnchantmentData enchData = getCurrentEnchantmentData();
|
||||
EnchanterRecipe recipe = getCurrentEnchantmentRecipe();
|
||||
ItemStack curStack = inv[1];
|
||||
@@ -212,7 +254,7 @@ public class TileEnchanter extends TileEntityEio implements ISidedInventory {
|
||||
if (!worldObj.isRemote) {
|
||||
worldObj.playSoundEffect(xCoord + 0.5d, yCoord + 0.5d, zCoord + 0.5d, "random.anvil_land", 0.2f, 1.0f);
|
||||
}
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -222,6 +264,15 @@ public class TileEnchanter extends TileEntityEio implements ISidedInventory {
|
||||
|
||||
@Override
|
||||
public void setInventorySlotContents(int slot, ItemStack contents) {
|
||||
if (slot == 2) {
|
||||
if (inv[2] == null || inv[2].stackSize <= 0
|
||||
|| contents != null && contents.stackSize > 0
|
||||
&& contents.getItem() == Items.enchanted_book
|
||||
&& contents.stackSize == inv[2].stackSize)
|
||||
return;
|
||||
if (checkAndDrainXP(1)) Log.warn("Potentially duped books at: " + xCoord + " " + yCoord + " " + zCoord);
|
||||
// return;
|
||||
} ;
|
||||
if (contents == null) {
|
||||
inv[slot] = contents;
|
||||
} else {
|
||||
@@ -240,10 +291,11 @@ public class TileEnchanter extends TileEntityEio implements ISidedInventory {
|
||||
output = new ItemStack(Items.enchanted_book);
|
||||
Items.enchanted_book.addEnchantment(output, enchantment);
|
||||
}
|
||||
setOutput(output);
|
||||
|
||||
if (inv[0] != null) stacksizes[0] = (byte) inv[0].stackSize;
|
||||
if (inv[1] != null) stacksizes[1] = (byte) inv[1].stackSize;
|
||||
|
||||
setOutput(output);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -388,18 +440,34 @@ public class TileEnchanter extends TileEntityEio implements ISidedInventory {
|
||||
markDirty();
|
||||
}
|
||||
|
||||
public ItemStack getOutput() {
|
||||
return inv[2];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getAccessibleSlotsFromSide(int side) {
|
||||
return side == 0 ? new int[] { 2 } : new int[] { 0, 1 };
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canInsertItem(int p_102007_1_, ItemStack p_102007_2_, int p_102007_3_) {
|
||||
return true;
|
||||
public boolean canInsertItem(int slot, ItemStack p_102007_2_, int p_102007_3_) {
|
||||
return slot == 0 || slot == 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canExtractItem(int p_102008_1_, ItemStack p_102008_2_, int p_102008_3_) {
|
||||
return true;
|
||||
public boolean canExtractItem(int slot, ItemStack p_102008_2_, int p_102008_3_) {
|
||||
return slot == 2 ? isAllowedBlockBeneath() : true;
|
||||
}
|
||||
|
||||
public boolean isAllowedBlockBeneath() {
|
||||
if (!Config.enchanterOutputEnableBlockRestriction) return true;
|
||||
var blockBeneath = worldObj.getBlock(this.xCoord, this.yCoord - 1, this.zCoord);
|
||||
for (String blocknam : Config.enchanterOutputFilterlist) {
|
||||
String[] splitname = blocknam.split(":", 1);
|
||||
if (GameRegistry.findBlock(splitname[0], splitname[1]) != blockBeneath) continue;
|
||||
return !Config.enchanterOutputAllowlistAsDenylist;
|
||||
}
|
||||
return Config.enchanterOutputAllowlistAsDenylist;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user