Compare commits

..
11 Commits
Author SHA1 Message Date
Caedis caec163702 Revert #231 (#261) 2026-09-04 14:09:25 +00:00
Glease 673f832c2d fix PacketTeleport sanitizer false positive (#253) 2026-09-03 07:00:46 +02:00
Eldrinn Elantey ce11a2dcf2 Fix night vision deactivating after dimension change via portal (#231) 2026-09-02 15:09:32 +00:00
vcwdfca 68e209203c Fix Player inventory cannot be shown when the EnderIO fluid conduit tier is lower than Ender (#255) 2026-09-02 15:03:02 +00:00
0715f8b536 remove direct getStackInSlot exploit (#245)
Co-authored-by: Martin Robertz <[email protected]>
Co-authored-by: attempt0 <[email protected]>
2026-09-02 09:38:29 +00:00
boubou19 d356dddedb Temporary revert #256 and #257 (#258) 2026-08-31 15:40:19 +02:00
June 604b47a394 Update en_US.lang (#257) 2026-08-29 23:34:49 -04:00
June 42dc1f43aa Update TileReservoir.java (#256)
it did not make sense previously. was worse than one vanilla water source
2026-08-29 20:47:05 -02:30
Elyspio cbeec42e47 Fix client NPE when placing wireless powered lights on dedicated servers (#252) 2026-08-21 18:16:23 +02:00
boubou19andgithub-actions[bot] 046ad7441d Cache more enum .values() (#249)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-08-11 02:53:48 +02:00
boubou19andMartin Robertz 8750005be5 Cache enum .values() (#248)
Co-authored-by: Martin Robertz <[email protected]>
2026-08-10 21:03:55 +02:00
32 changed files with 284 additions and 160 deletions

No files matched your search

+15 -15
View File
@@ -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')
}
+10 -10
View File
@@ -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
View File
@@ -17,7 +17,7 @@ pluginManagement {
}
plugins {
id 'com.gtnewhorizons.gtnhsettingsconvention' version '2.0.27'
id 'com.gtnewhorizons.gtnhsettingsconvention' version '2.0.29'
}
@@ -771,7 +771,7 @@ public class BlockConduitBundle extends BlockEio
bundle.setFacadeId(facadeID);
bundle.setFacadeMetadata(facadeMeta);
bundle.setFacadeType(FacadeType.values()[facadeType]);
bundle.setFacadeType(FacadeType.VALUES[facadeType]);
if (!world.isRemote) {
ConduitUtil.playPlaceSound(facadeID.stepSound, world, x, y, z);
}
@@ -41,6 +41,8 @@ public class ItemConduitFacade extends Item implements IAdvancedTooltipProvider,
BASIC,
HARDENED;
public static final FacadeType[] VALUES = values();
public String getUnlocName(Item me) {
return this == BASIC ? me.getUnlocalizedName() : me.getUnlocalizedName() + ".hardened";
}
@@ -69,14 +71,14 @@ public class ItemConduitFacade extends Item implements IAdvancedTooltipProvider,
@Override
@SideOnly(Side.CLIENT)
public void getSubItems(Item item, CreativeTabs p_150895_2_, List<ItemStack> list) {
for (FacadeType t : FacadeType.values()) {
for (FacadeType t : FacadeType.VALUES) {
list.add(new ItemStack(item, 1, t.ordinal()));
}
}
@Override
public String getUnlocalizedName(ItemStack stack) {
return FacadeType.values()[stack.getItemDamage()].getUnlocName(this);
return FacadeType.VALUES[stack.getItemDamage()].getUnlocName(this);
}
@Override
@@ -87,7 +89,7 @@ public class ItemConduitFacade extends Item implements IAdvancedTooltipProvider,
@Override
@SideOnly(Side.CLIENT)
public void registerIcons(IIconRegister IIconRegister) {
icons = new IIcon[FacadeType.values().length];
icons = new IIcon[FacadeType.VALUES.length];
icons[0] = itemIcon = IIconRegister.registerIcon("enderio:conduitFacade");
icons[1] = IIconRegister.registerIcon("enderio:conduitFacadeHardened");
overlayIcon = IIconRegister.registerIcon("enderio:conduitFacadeOverlay");
@@ -131,7 +133,7 @@ public class ItemConduitFacade extends Item implements IAdvancedTooltipProvider,
facadeMeta = PainterUtil.adjustFacadeMetadata(facadeID, facadeMeta, side);
bundle.setFacadeId(facadeID);
bundle.setFacadeMetadata(facadeMeta);
bundle.setFacadeType(FacadeType.values()[itemStack.getItemDamage()]);
bundle.setFacadeType(FacadeType.VALUES[itemStack.getItemDamage()]);
ConduitUtil.playPlaceSound(facadeID.stepSound, world, x, y, z);
if (!player.capabilities.isCreativeMode) {
itemStack.stackSize--;
@@ -184,8 +184,8 @@ public abstract class AbstractGasConduit extends AbstractConduit implements IGas
String key = "extRM." + dir.name();
if (nbtRoot.hasKey(key)) {
short ord = nbtRoot.getShort(key);
if (ord >= 0 && ord < RedstoneControlMode.values().length) {
extractionModes.put(dir, RedstoneControlMode.values()[ord]);
if (ord >= 0 && ord < RedstoneControlMode.VALUES.length) {
extractionModes.put(dir, RedstoneControlMode.VALUES[ord]);
}
}
key = "extSC." + dir.name();
@@ -284,6 +284,8 @@ public class LiquidSettings extends BaseSettingsPanel {
rsB.onGuiInit();
colorB.onGuiInit();
gui.getContainer().setInventorySlotsVisible(true);
if (!isEnder) {
return;
}
@@ -295,7 +297,6 @@ public class LiquidSettings extends BaseSettingsPanel {
roundRobinB.onGuiInit();
roundRobinB.setSelected(eConduit.isRoundRobin(gui.getDir()));
gui.getContainer().setInventorySlotsVisible(true);
if (isFilterVisible()) {
addFilterTooltips();
@@ -152,7 +152,7 @@ public class ItemConduit extends AbstractConduit implements IItemConduit {
@Override
protected void readTypeSettings(ForgeDirection dir, NBTTagCompound dataRoot) {
setExtractionSignalColor(dir, DyeColor.VALUES[dataRoot.getShort("extractionSignalColor")]);
setExtractionRedstoneMode(RedstoneControlMode.values()[dataRoot.getShort("extractionRedstoneMode")], dir);
setExtractionRedstoneMode(RedstoneControlMode.VALUES[dataRoot.getShort("extractionRedstoneMode")], dir);
setInputColor(dir, DyeColor.VALUES[dataRoot.getShort("inputColor")]);
setOutputColor(dir, DyeColor.VALUES[dataRoot.getShort("outputColor")]);
setSelfFeedEnabled(dir, dataRoot.getBoolean("selfFeed"));
@@ -837,8 +837,8 @@ public class ItemConduit extends AbstractConduit implements IItemConduit {
key = "extRM." + dir.name();
if (nbtRoot.hasKey(key)) {
short ord = nbtRoot.getShort(key);
if (ord >= 0 && ord < RedstoneControlMode.values().length) {
extractionModes.put(dir, RedstoneControlMode.values()[ord]);
if (ord >= 0 && ord < RedstoneControlMode.VALUES.length) {
extractionModes.put(dir, RedstoneControlMode.VALUES[ord]);
}
}
key = "extSC." + dir.name();
@@ -203,7 +203,7 @@ public abstract class AbstractLiquidConduit extends AbstractConduit implements I
@Override
protected void readTypeSettings(ForgeDirection dir, NBTTagCompound dataRoot) {
setExtractionSignalColor(dir, DyeColor.VALUES[dataRoot.getShort("extractionSignalColor")]);
setExtractionRedstoneMode(RedstoneControlMode.values()[dataRoot.getShort("extractionRedstoneMode")], dir);
setExtractionRedstoneMode(RedstoneControlMode.VALUES[dataRoot.getShort("extractionRedstoneMode")], dir);
}
@Override
@@ -239,8 +239,8 @@ public abstract class AbstractLiquidConduit extends AbstractConduit implements I
String key = "extRM." + dir.name();
if (nbtRoot.hasKey(key)) {
short ord = nbtRoot.getShort(key);
if (ord >= 0 && ord < RedstoneControlMode.values().length) {
extractionModes.put(dir, RedstoneControlMode.values()[ord]);
if (ord >= 0 && ord < RedstoneControlMode.VALUES.length) {
extractionModes.put(dir, RedstoneControlMode.VALUES[ord]);
}
}
key = "extSC." + dir.name();
@@ -40,7 +40,7 @@ public class PacketExtractMode extends AbstractConduitPacket<IExtractor>
public void fromBytes(ByteBuf buf) {
super.fromBytes(buf);
dir = ForgeDirections.DIRECTIONS[buf.readShort()];
mode = RedstoneControlMode.values()[buf.readShort()];
mode = RedstoneControlMode.VALUES[buf.readShort()];
color = DyeColor.VALUES[buf.readShort()];
}
@@ -209,7 +209,7 @@ public class PowerConduit extends AbstractConduit implements IPowerConduit {
@Override
protected void readTypeSettings(ForgeDirection dir, NBTTagCompound dataRoot) {
setExtractionSignalColor(dir, DyeColor.VALUES[dataRoot.getShort("extractionSignalColor")]);
setExtractionRedstoneMode(RedstoneControlMode.values()[dataRoot.getShort("extractionRedstoneMode")], dir);
setExtractionRedstoneMode(RedstoneControlMode.VALUES[dataRoot.getShort("extractionRedstoneMode")], dir);
}
@Override
@@ -253,8 +253,8 @@ public class PowerConduit extends AbstractConduit implements IPowerConduit {
String key = "pRsMode." + dir.name();
if (nbtRoot.hasKey(key)) {
short ord = nbtRoot.getShort(key);
if (ord >= 0 && ord < RedstoneControlMode.values().length) {
rsModes.put(dir, RedstoneControlMode.values()[ord]);
if (ord >= 0 && ord < RedstoneControlMode.VALUES.length) {
rsModes.put(dir, RedstoneControlMode.VALUES[ord]);
}
}
key = "pRsCol." + dir.name();
@@ -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() {
@@ -29,6 +29,7 @@ public class BlockEndermanSkull extends BlockEio implements IInfusionStabiliser
TORMENTED("tormented", false),
REANIMATED_TORMENTED("reanimatedTormented", true);
public static final SkullType[] VALUES = values();
final String name;
final boolean showEyes;
@@ -74,8 +75,8 @@ public class BlockEndermanSkull extends BlockEio implements IInfusionStabiliser
public IIcon getIcon(int side, int meta) {
ForgeDirection orint = ForgeDirection.getOrientation(side);
if (orint == ForgeDirection.NORTH) {
meta = MathHelper.clamp_int(meta, 0, SkullType.values().length - 1);
return SkullType.values()[meta].showEyes ? frontIconEyes : frontIcon;
meta = MathHelper.clamp_int(meta, 0, SkullType.VALUES.length - 1);
return SkullType.VALUES[meta].showEyes ? frontIconEyes : frontIcon;
}
if (orint == ForgeDirection.UP || orint == ForgeDirection.DOWN || orint == ForgeDirection.SOUTH) {
return topIcon;
@@ -472,10 +472,10 @@ public abstract class AbstractMachineEntity extends TileEntityEio
}
int rsContr = nbtRoot.getInteger("redstoneControlMode");
if (rsContr < 0 || rsContr >= RedstoneControlMode.values().length) {
if (rsContr < 0 || rsContr >= RedstoneControlMode.VALUES.length) {
rsContr = 0;
}
redstoneControlMode = RedstoneControlMode.values()[rsContr];
redstoneControlMode = RedstoneControlMode.VALUES[rsContr];
if (nbtRoot.hasKey("hasFaces")) {
for (ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) {
@@ -46,7 +46,7 @@ public class PacketRedstoneMode implements IMessage, IMessageHandler<PacketRedst
y = buf.readInt();
z = buf.readInt();
short ordinal = buf.readShort();
mode = RedstoneControlMode.values()[ordinal];
mode = RedstoneControlMode.VALUES[ordinal];
}
@Override
@@ -19,6 +19,8 @@ public enum RedstoneControlMode implements ICycleEnum {
OFF(IconEIO.REDSTONE_MODE_WITHOUT_SIGNAL),
NEVER(IconEIO.REDSTONE_MODE_NEVER);
public static final RedstoneControlMode[] VALUES = values();
private final IWidgetIcon icon;
RedstoneControlMode(IWidgetIcon icon) {
@@ -63,20 +65,20 @@ public enum RedstoneControlMode implements ICycleEnum {
public RedstoneControlMode next() {
int ord = ordinal();
if (ord == values().length - 1) {
if (ord == VALUES.length - 1) {
ord = 0;
} else {
ord++;
}
return values()[ord];
return VALUES[ord];
}
public RedstoneControlMode previous() {
int ord = ordinal();
ord--;
if (ord < 0) {
ord = values().length - 1;
ord = VALUES.length - 1;
}
return values()[ord];
return VALUES[ord];
}
}
@@ -26,6 +26,7 @@ public class BlockItemBuffer extends ItemBlockWithMetadata {
OMNI(true, true, false),
CREATIVE(true, true, true);
public static final Type[] VALUES = values();
final boolean hasInventory;
final boolean hasPower;
final boolean isCreative;
@@ -60,14 +61,14 @@ public class BlockItemBuffer extends ItemBlockWithMetadata {
@Override
@SideOnly(Side.CLIENT)
public void getSubItems(Item item, CreativeTabs tab, List<ItemStack> list) {
for (Type type : Type.values()) {
for (Type type : Type.VALUES) {
list.add(new ItemStack(item, 1, type.ordinal()));
}
}
@Override
public String getUnlocalizedName(ItemStack stack) {
return Type.values()[stack.getItemDamage()].getUnlocalizedName();
return Type.VALUES[stack.getItemDamage()].getUnlocalizedName();
}
@Override
@@ -78,7 +79,7 @@ public class BlockItemBuffer extends ItemBlockWithMetadata {
TileEntity te = world.getTileEntity(x, y, z);
if (te instanceof TileBuffer) {
TileBuffer buffer = ((TileBuffer) te);
Type t = Type.values()[metadata];
Type t = Type.VALUES[metadata];
buffer.setHasInventory(t.hasInventory);
buffer.setHasPower(t.hasPower);
buffer.setCreative(t.isCreative);
@@ -882,12 +882,12 @@ public class TileCapBank extends TileEntityEio
}
if (nbtRoot.hasKey("inputControlMode")) {
inputControlMode = RedstoneControlMode.values()[nbtRoot.getShort("inputControlMode")];
inputControlMode = RedstoneControlMode.VALUES[nbtRoot.getShort("inputControlMode")];
} else {
inputControlMode = RedstoneControlMode.IGNORE;
}
if (nbtRoot.hasKey("outputControlMode")) {
outputControlMode = RedstoneControlMode.values()[nbtRoot.getShort("outputControlMode")];
outputControlMode = RedstoneControlMode.VALUES[nbtRoot.getShort("outputControlMode")];
} else {
outputControlMode = RedstoneControlMode.IGNORE;
}
@@ -115,8 +115,8 @@ public class NetworkState {
buf.readInt(),
buf.readInt(),
buf.readInt(),
RedstoneControlMode.values()[buf.readShort()],
RedstoneControlMode.values()[buf.readShort()],
RedstoneControlMode.VALUES[buf.readShort()],
RedstoneControlMode.VALUES[buf.readShort()],
buf.readBoolean() ? BlockCoord.readFromBuf(buf) : null,
buf.readFloat(),
buf.readFloat());
@@ -39,8 +39,8 @@ public class PacketGuiChange extends PacketCapBank<PacketGuiChange, IMessage> {
super.fromBytes(buf);
maxSend = buf.readInt();
maxRec = buf.readInt();
inputMode = RedstoneControlMode.values()[buf.readShort()];
outputMode = RedstoneControlMode.values()[buf.readShort()];
inputMode = RedstoneControlMode.VALUES[buf.readShort()];
outputMode = RedstoneControlMode.VALUES[buf.readShort()];
}
@Override
@@ -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;
}
}
@@ -826,7 +826,7 @@ public class TileHyperCube extends TileEntityEio
recieveBuffer.readFromNBT(nbtRoot);
if (nbtRoot.hasKey("rsMode")) {
redstoneControlMode = RedstoneControlMode.values()[nbtRoot.getShort("rsMode")];
redstoneControlMode = RedstoneControlMode.VALUES[nbtRoot.getShort("rsMode")];
} else {
redstoneControlMode = RedstoneControlMode.IGNORE;
}
@@ -31,6 +31,7 @@ public class BlockItemElectricLight extends ItemBlockWithMetadata implements IRe
WIRELESS("item.itemWirelessLight", false, true, true),
WIRELESS_INV("item.itemWirelessLightInverted", true, true, true);
public static final Type[] VALUES = values();
final String unlocName;
final boolean isInverted;
final boolean isPowered;
@@ -52,14 +53,14 @@ public class BlockItemElectricLight extends ItemBlockWithMetadata implements IRe
@Override
public String getUnlocalizedName(ItemStack par1ItemStack) {
int meta = par1ItemStack.getItemDamage();
meta = MathHelper.clamp_int(meta, 0, Type.values().length - 1);
return Type.values()[meta].unlocName;
meta = MathHelper.clamp_int(meta, 0, Type.VALUES.length - 1);
return Type.VALUES[meta].unlocName;
}
@Override
@SideOnly(Side.CLIENT)
public void getSubItems(Item par1, CreativeTabs par2CreativeTabs, List<ItemStack> par3List) {
for (Type type : Type.values()) {
for (Type type : Type.VALUES) {
par3List.add(new ItemStack(this, 1, type.ordinal()));
}
}
@@ -76,7 +77,7 @@ public class BlockItemElectricLight extends ItemBlockWithMetadata implements IRe
if (te instanceof TileElectricLight) {
TileElectricLight el = ((TileElectricLight) te);
el.setFace(onFace);
Type t = Type.values()[metadata];
Type t = Type.VALUES[metadata];
el.setInverted(t.isInverted);
el.setRequiresPower(t.isPowered);
el.setWireless(t.isWireless);
@@ -378,10 +378,10 @@ public class TileVacuumChest extends TileEntityEio
}
int rsContr = nbtRoot.getInteger("redstoneControlMode");
if (rsContr < 0 || rsContr >= RedstoneControlMode.values().length) {
if (rsContr < 0 || rsContr >= RedstoneControlMode.VALUES.length) {
rsContr = 0;
}
redstoneControlMode = RedstoneControlMode.values()[rsContr];
redstoneControlMode = RedstoneControlMode.VALUES[rsContr];
}
@Override
@@ -24,7 +24,10 @@ public class WirelessChargedLocation {
* use (unless ~4B changes happen in between). Do this instead directly updating so that WirelessChargedLocation
* can be used while the TileEntity is still in construction (or loading).
*/
this.lastChangeCount = EnderIO.proxy.wirelessChargerController.getChangeCount() - 1;
// The controller only exists on the server (created in FMLServerAboutToStartEvent), so it is null on
// clients connected to a dedicated server. Chargers are only queried server-side, so stay inert there.
WirelessChargerController wcc = EnderIO.proxy.wirelessChargerController;
this.lastChangeCount = wcc == null ? 0 : wcc.getChangeCount() - 1;
}
private void updateChargers() {
@@ -41,7 +44,8 @@ public class WirelessChargedLocation {
}
private void checkChangeCount() {
if (lastChangeCount != EnderIO.proxy.wirelessChargerController.getChangeCount()) {
WirelessChargerController wcc = EnderIO.proxy.wirelessChargerController;
if (wcc != null && lastChangeCount != wcc.getChangeCount()) {
updateChargers();
}
}
@@ -10,6 +10,7 @@ public enum FrankenSkull {
SKELETAL_CONTRACTOR("skullSkeletalContractor", "enderio:skullSkeletalContractor", false),
GUARDIAN_DIODE("skullGuardianDiode", "enderio:skullGuardianDiode", false);
public static final FrankenSkull[] VALUES = values();
public final String unlocalisedName;
public final String iconKey;
public final boolean isAnimated;
@@ -30,7 +30,7 @@ public class ItemFrankenSkull extends Item {
setMaxDamage(0);
setCreativeTab(EnderIOTab.tabEnderIO);
setUnlocalizedName(ModObject.itemFrankenSkull.unlocalisedName);
icons = new IIcon[FrankenSkull.values().length];
icons = new IIcon[FrankenSkull.VALUES.length];
}
private void init() {
@@ -48,20 +48,20 @@ public class ItemFrankenSkull extends Item {
@SideOnly(Side.CLIENT)
public void registerIcons(IIconRegister IIconRegister) {
for (int i = 0; i < icons.length; i++) {
icons[i] = IIconRegister.registerIcon(FrankenSkull.values()[i].iconKey);
icons[i] = IIconRegister.registerIcon(FrankenSkull.VALUES[i].iconKey);
}
}
@Override
public String getUnlocalizedName(ItemStack par1ItemStack) {
int i = MathHelper.clamp_int(par1ItemStack.getItemDamage(), 0, FrankenSkull.values().length - 1);
return FrankenSkull.values()[i].unlocalisedName;
int i = MathHelper.clamp_int(par1ItemStack.getItemDamage(), 0, FrankenSkull.VALUES.length - 1);
return FrankenSkull.VALUES[i].unlocalisedName;
}
@Override
@SideOnly(Side.CLIENT)
public void getSubItems(Item par1, CreativeTabs par2CreativeTabs, List<ItemStack> par3List) {
for (int j = 0; j < FrankenSkull.values().length; ++j) {
for (int j = 0; j < FrankenSkull.VALUES.length; ++j) {
par3List.add(new ItemStack(par1, 1, j));
}
}
@@ -69,7 +69,7 @@ public class ItemFrankenSkull extends Item {
@Override
@SideOnly(Side.CLIENT)
public boolean hasEffect(ItemStack par1ItemStack, int pass) {
int meta = MathHelper.clamp_int(par1ItemStack.getItemDamage(), 0, FrankenSkull.values().length - 1);
return FrankenSkull.values()[meta].isAnimated;
int meta = MathHelper.clamp_int(par1ItemStack.getItemDamage(), 0, FrankenSkull.VALUES.length - 1);
return FrankenSkull.VALUES[meta].isAnimated;
}
}
@@ -31,7 +31,7 @@ public class ItemMachinePart extends Item {
setCreativeTab(EnderIOTab.tabEnderIO);
setUnlocalizedName(ModObject.itemMachinePart.unlocalisedName);
icons = new IIcon[MachinePart.values().length];
icons = new IIcon[MachinePart.VALUES.length];
}
private void init() {
@@ -41,29 +41,29 @@ public class ItemMachinePart extends Item {
@Override
@SideOnly(Side.CLIENT)
public IIcon getIconFromDamage(int damage) {
damage = MathHelper.clamp_int(damage, 0, MachinePart.values().length - 1);
damage = MathHelper.clamp_int(damage, 0, MachinePart.VALUES.length - 1);
return icons[damage];
}
@Override
@SideOnly(Side.CLIENT)
public void registerIcons(IIconRegister IIconRegister) {
int numParts = MachinePart.values().length;
int numParts = MachinePart.VALUES.length;
for (int i = 0; i < numParts; i++) {
icons[i] = IIconRegister.registerIcon(MachinePart.values()[i].iconKey);
icons[i] = IIconRegister.registerIcon(MachinePart.VALUES[i].iconKey);
}
}
@Override
public String getUnlocalizedName(ItemStack par1ItemStack) {
int i = MathHelper.clamp_int(par1ItemStack.getItemDamage(), 0, MachinePart.values().length - 1);
return MachinePart.values()[i].unlocalisedName;
int i = MathHelper.clamp_int(par1ItemStack.getItemDamage(), 0, MachinePart.VALUES.length - 1);
return MachinePart.VALUES[i].unlocalisedName;
}
@Override
@SideOnly(Side.CLIENT)
public void getSubItems(Item par1, CreativeTabs par2CreativeTabs, List<ItemStack> par3List) {
for (int j = 0; j < MachinePart.values().length; ++j) {
for (int j = 0; j < MachinePart.VALUES.length; ++j) {
par3List.add(new ItemStack(par1, 1, j));
}
}
@@ -13,6 +13,7 @@ public enum MachinePart {
SOUL_MACHINE_CHASSIS("soulMachineChassi"),
END_STEEL_MACHINE_CHASSIS("endSteelMachineChassi");
public static final MachinePart[] VALUES = values();
public final String unlocalisedName;
public final String iconKey;
public final String oreDict;
@@ -24,7 +25,7 @@ public enum MachinePart {
}
public static void registerOres(Item item) {
for (MachinePart m : values()) {
for (MachinePart m : VALUES) {
OreDictionary.registerOre(m.oreDict, new ItemStack(item, 1, m.ordinal()));
}
}
@@ -26,27 +26,33 @@ public class PacketUtil {
if (!(container instanceof IContainerWithTileEntity)) {
Log.LOGGER.warn(
Log.securityMarker,
"Player {} tried to send {} while not opening correct GUI. Target TileEntity at {}, {}, {}",
"Player {} tried to send {} while not opening correct GUI. Target TileEntity {} at {}, {}, {} in {}. Current container {}",
player.getGameProfile(),
messageClass.getSimpleName(),
receivedTile,
receivedTile.xCoord,
receivedTile.yCoord,
receivedTile.zCoord);
receivedTile.zCoord,
receivedTile.getWorldObj().provider.dimensionId,
container);
return true;
}
TileEntity expectedTile = ((IContainerWithTileEntity) container).getTileEntity();
if (receivedTile != expectedTile) {
Log.LOGGER.warn(
Log.securityMarker,
"Player {} tried to send {} which attempts to modify setting of TileEntity at {}, {}, {}. Expected: {}, {}, {}",
"Player {} tried to send {} which attempts to modify setting of TileEntity at {}, {}, {} in {}. Expected: {}, {}, {} in {}. Current container {}",
player.getGameProfile(),
messageClass.getSimpleName(),
receivedTile.xCoord,
receivedTile.yCoord,
receivedTile.zCoord,
receivedTile.getWorldObj().provider.dimensionId,
expectedTile.xCoord,
expectedTile.yCoord,
expectedTile.zCoord);
expectedTile.zCoord,
expectedTile.getWorldObj().provider.dimensionId,
container);
return true;
}
return false;
@@ -59,9 +59,19 @@ public class PacketTeleport extends MessageTileEntity<TileTelePad>
@Override
public IMessage onMessage(PacketTeleport message, MessageContext ctx) {
World world = ctx.side.isClient() ? EnderIO.proxy.getClientWorld() : message.getWorld(ctx);
boolean isClient = ctx.side.isClient();
World world = isClient ? EnderIO.proxy.getClientWorld() : message.getWorld(ctx);
TileTelePad te = message.getTileEntity(world);
if (PacketUtil.isInvalidPacketForGui(ctx, te, getClass())) return null;
if (te == null) return null;
if (!isClient) {
// BEGIN is the only type of PacketTeleport that originates from a TE GUI
if (message.type == Type.BEGIN && PacketUtil.isInvalidPacketForGui(ctx, te, getClass())) {
return null;
}
// TELEPORT is never sent to server
if (message.type == Type.TELEPORT) return null;
// other types are sent in background without a gui, so no checks
}
Entity e = world.getEntityByID(message.entityId);
switch (message.type) {
case BEGIN: