Applied Energistics 2

Applied Energistics 2

137M Downloads

Ae2 / Extra utilities duplication glitch

Eidelmaim opened this issue ยท 15 comments

commented

i am not sure which of the 2 mods is causing this to happen so i decided to post in both mod autors githubs... please see the following video showing the duplication glitch in action. i have witnessed this glitch in both the FTB Infinity evolved mod pack... and on a private mod pack created by my team.

mod versions :
appliedenergistics2-rv2-stable-10
extrautilities-1.2.12

https://www.youtube.com/watch?v=jdTOY3UPktA&feature=youtu.be

commented

Same with:

  • appliedenergistics2-rv3-beta-5.jar
  • extrautilities-1.2.12

I even connected the endercollector to a chest and chest to an import bus.
So timing goes like this:

  1. Item inserted into chest
  2. Item imported into ME and formed to plane
  3. Item collected and Goto 1
commented

I doubt this is on the side of AE2.

Just by observation, I would guess the following is happening.
XU chooses an item entity, inserts it into the adjacent inventory, without marking the entity as dead.
AE2 will then immediately spit out the item again, causing minecraft to stack it together with the existing entity and loop forever. This is probably done to prevent respawning the item, should it not be able to store it and have a slightly better performance due to this.

I could even imagine that this works with other mods. Maybe the Open Crate from Botania?
Sadly I do not have the time currently to test it.

commented

Nope, that not working with Open Crate, Dispenser, Dropper and Item Dropper from OpenBlocks

commented

After testing more, This is what is happening: http://goo.gl/iWfkAB
The formation plane facing the ender collector is set to a priority of 1, is set to drop items and is inside the range of the ender collector. The second formation plane (middle, facing left) is set to a priority of zero, and is set to place blocks. The top plane is the annihilation plane. It does not matter what the inventory the ender collector is placing into, as long as it has room to accept the duplicated item.

This does not happen with/when:

  • Any item dropping block (Non-formation plane) and an ender collector.
  • The formation plane and any other block that picks up items.
  • A formation plane and ender collector where the formation plane is NOT inside of the range of the ender collector.
commented

I think I've found where the issue is: https://github.com/AppliedEnergistics/Applied-Energistics-2/blob/ac45095cb452d417f686e3c6e51ebb5d307a6a62/src/main/java/appeng/parts/automation/PartFormationPlane.java

(I apologize this is probably the incorrect way to reference a portion of code)

Lines 537 ... 541:

                        if( !w.spawnEntityInWorld( result ) )
                        {
                            result.setDead();
                            worked = false;
                        }

Lines 553 ... 562:

        if( worked )
        {
            final IAEItemStack out = input.copy();
            out.decStackSize( maxStorage );
            if( out.getStackSize() == 0 )
            {
                return null;
            }
            return out;
        }

Here's what ExtraUtilities appears to be doing:

  • It is listening to the onEntityJoinWorld event, it does a couple of checks, if everything is fine it will run it'll have the specific collector run it's own grabEntity function.
  • This function will simulate the item being inserted to the machine the Ender Collector is connected to.
  • If the item is successful put into the container it prevents the event from happening with event.setCanceled(true) . Looks like the event cancel might actually be related to Arrow entities.
  • Something is causing line AE's line 537 to fail and sets worked = false.
  • If worked is false the items are not deducted from AE's network and as a result there are now an extra copy of the item in existence.
commented

I do not see anything wrong with it. All it does is "we could not spawn the entity, report that nothing was spawned". Which would cause it to try the next storage option or finally leave it inside the interface. Otherwise formation planes would void items.

So it looks like something (could be XU, could be not) prevents spawning them for whatever reasons.
But instead of considering it as dead entity or similar, they try to spawn it again under their control, for example to be able to stack them together instead of creating a new entity. Which will of course dupe them.

commented

Alternatively it's possible to keep the spawnEntity check as well:

                        if( !w.spawnEntityInWorld( result ) && !result.isDead )

If the entity was spawned and it's now dead then it seems safe to assume a mod consumed the item.

commented

@ZeekDaGeek good job! Thank you very much.

commented

The problem is that "being server friendly" is really not a possible option for minecraft. It could actually be way better, but this would require that forge has to introduce some conventions/documentations, but way too many devs would ignore them and therefore cause way more issues than before.

Just adding the check for !isDead means, if something would prevent the spawning and set the entity to dead, it will prevent us from backtracking and cause the destruction of items. Which actually should be stored somewhere else. Like a backup drive somewhere.

commented

The point of the Ender Collector is to be "Server Friendly". It's designed to prevent the Entity from spawning in the world and instantly places them into the container it's attached to. Instead it creates particles from where the item would have spawned on the client side as it moves the item into the container. If it allows the item to spawn for any length of time i think it prevents it's designed intent.

I can't seem to find a single instance of a dropper type item that checks if world.spawnEntityInWorld(itemStack) is true. Is there an actual risk of losing items?

https://github.com/Vazkii/Botania/search?q=spawnEntityInWorld
https://github.com/OpenMods/OpenBlocks/search?q=spawnEntityInWorld
https://github.com/skyboy/MineFactoryReloaded/search?q=spawnEntityInWorld

I've been running a world with the following changes applied and it completely prevents the duplication glitch:

Lines 537 ... 541:

                        if( !w.spawnEntityInWorld( result ) )
                        {
                            result.setDead();
                            worked = false;
                        }

CHANGED TO

                        if (!w.isRemote)
                            w.spawnEntityInWorld(result);

Edit:
Showing things visually is usually very helpful.

Before: https://gfycat.com/WillingFaroffCero
After: https://gfycat.com/PoisedCelebratedAsianporcupine

commented

I'm not an Extra Utilities developer or anything, not really here to defend the item's intended purpose or if it's actually functional. At the moment there's a dupe bug on my server and I wanted it fixed and I'm just sharing my method of fixing it.

Let's say the reason an item is dying because the chunk is protected and any items dropped get instantly killed the player should realize that and stop. Kind of a "Oops you dropped your items in lava, maybe you should stop throwing them into lava."

You're also offering more protection with that check then a Vanilla dispenser outputting an item. If you drop items where you shouldn't be dropping items then you shouldn't be coddled.

commented

Also you could take the other side of the argument and say a mod is trying to destroy items around it for a specific reason, Applied Energistics is giving those items more protection than they would ever have otherwise. AE is preventing a mod from doing it's intended feature by giving it more protection than any other standard method of dropping items would give it.

commented

Honestly destruction of items should be favoured over duplicating them (even if Extra Utilities' "server friendly" block is kind of at fault for expecting mods to check for isDead before restoring). If an event handler for EntityJoinWorldEvent cancels the event and calls entity.setDead() then it seems pretty clear to me that they want the item gone, and gone for real.

As it stands you're protecting against an unrealistic case of an event handler stopping items from spawning, instead of protecting against the case that items are being duplicated, which is actually happening in reality. Adding the check for !entity.isDead is the only viable solution that would do both, prevent duplication and destruction.

commented

we have applied @ZeekDaGeek fix to our server and all is well now, tested extensivly with many players and it will not duplicate. well done Zeek