dniym / IllegalStack

A spigot based plugin dedicated to fixing glitches and exploits that have made it into final Minecraft releases.
GNU General Public License v3.0
146 stars 36 forks source link

False positives for rail/carpet dupe #30

Closed KrisBigK closed 1 year ago

KrisBigK commented 4 years ago

image

image

image (The plugin counts this as a dupe when the piston retracts)

Here are three examples that won't cause the rail/carpet to dupe in vanilla when the piston is activated, while the plugin still counts it as a dupe. I'm on an 1.12.2 server and this makes it troublesome and somewhat annoying to build certain redstone contraptions that requre moving carpets/rails (obviously without duping them).

dniym commented 4 years ago

Rail and carpet duping setups vary wildly between versions of Minecraft. Some of them work in one major version, but not another. Some of them work in minor version updates. Sometimes they’re directional, sometimes not. IllegalStack protects a wide range of versions from 1.8 to present.

Sorting out exactly which carpet / rail dupe works in each specific version and what direction they work in is a big task that is very version specific.

Rail/carpet duping exists in one form or another in every version of Minecraft from 1.12 up to the present 1.15 build.

Adding extra detection for the direction or what specific pulse length would not only greatly increase the amount of code needed it would also increase the load on the server as this would have to be checked and verified each and every time the piston moved.

It is much more efficient to block all rails and carpets being moved across these versions than trying to specifically code around each variant.

KrisBigK commented 4 years ago

As rail(carpet) dupers generate duped rails in the form of entities, I think a better workaround would be to remove a single rail item (e.g. from an entity consisting of a stack of rails or for a dedicated duper, simply remove the single item that it generates) per moved rail in a certain area when it gets moved by a piston in the same tick that the item is generated. This also prevents it from being picked up by hopper minecarts. This should still allow rails to be moved in an intended way as long as they don't pop off. The drawback of this would be to lose your rail if it pops off when moved by a piston.

dniym commented 4 years ago

As rail dupers generate duped rails in the form of an entity, I think a better workaround would be to remove a single rail item entity per moved rail (carpet) in a certain area when it gets moved by a piston in the same tick that the item is generated, which prevents it from being picked up by hopper minecarts. This should still allow rails to be moved in an intended way as long as they don't pop off.

That’s a good idea in theory, however; when the dupe happens there’s no event fired not, a block break event, not even an entity spawn event. Thus the only way to detect that would be to scan the entire chunk for entities nearby every single time the piston extends or retracts. This is not efficient and could get ultra laggy when several of these machines were moving at the same time.

KrisBigK commented 4 years ago

I believe that when blocks get moved by a piston, they should go into a temporary list? If that's the case, only the list would be needed to scan for rails then.

dniym commented 4 years ago

When a block is moved it totally does go into a list, thats how we can detect/modify which blocks are moved. However when this bug happens (a carpet / rail dupe) an entity is created (DROPPED_ITEM) with a type (Material=CARPET) or rail. This does not happen normally as no block is actually broken so we can't detect WHY the rail/carpet dropped item was created, so IllegalStack can't cancel / or remove the invalid item when it appears because it's undetectable from a coding standpoint.

So any time a machine capable of possibly producing a carpet / rail dupe is triggered it would be required to scan the entire chunk, and scan every single entity, AND then check the distance from each entity to the moved block to see if it was possible it came from that piston.

But then hoppers and hopper minecarts could scoop them up then you've got to check for hoppers in the vicinity or at least the distance from a hopper to the machine provided they're in the same chunk. Distance checks are very expensive as far as cpu usage goes so one of these machines built as a flying machine or one that just runs constantly is going to put a constant cpu drain looking for a potential duped carpet/rail.

If you don't do a distance check then it would just eat any dropped carpet / rail it found on the ground anywhere in the chunk.

Then players would just build the duper on a chunk border and part of the dupes would fly off into another chunk and avoid being detected. So you would have to also check nearby chunks, further increasing the calculations and loads.

If you didn't do expensive distance checks there would be no way to tell if the carpet/rail on the ground came from the machine or not, thus if a player dropped a carpet/rail and the machine activated the dropped item would get deleted because there's no way to tell if the item came from the machine or from a block being broken, or if it was dropped by a player.

Preventing the duped item from ever entering the world is far more efficient than trying to scan for and remove one that may or may not have already made it into the world.

mhtvsSFrpHdE commented 4 years ago

@dniym Then maybe an extra module can hack into this case;
to allow the rail and carpet can only be break by player

I see people creating a plugin that does the thing:

Combining those I think we just simply deny any rail or carpet to natural drop
(no matter piston or anything), delete them directly,
and if that was broken by a player, put it into the inventory
(Also be deleted, but add to inventory via player break event asynchronous)

I looking for more information later.
So finally we should have a bunch of working duplicator pistons,
and also normal Redstone machines that allow for running (not remove pistons).
But they do not generate any rail or carpet able to pick up
The player can only retrieve these via hand or specified tool to break
Not via pick up drop, but add into inventory directly

If no inventory space left, cancel the break event
and send notification about inventory space.
(coreprotect plugin have a demonstration in inspector mode)

Call this

PreventRailDupe: false
PreventRailDupeGen2 : true
mhtvsSFrpHdE commented 4 years ago

image

mhtvsSFrpHdE commented 4 years ago

More reference

The "Drop item goes into the player's inventory directly without drop" plugin https://www.spigotmc.org/resources/autopickup.70157

The "Cancel break event if no inventory space left"
coreprotect plugin have a inspector mode /co i, when on,
any block can't place and canceled. https://www.spigotmc.org/resources/coreprotect.8631

The plugin can detect fast break(maybe just a demo about capture break event) https://www.spigotmc.org/resources/horizon-powerful-cheat-detection-in-new-era-1-8-1-12-1-13-1-14.65830/

mhtvsSFrpHdE commented 4 years ago

Fake code

The ban rails or carpets drop part

capture item drop event;

scan item list;

# Confiscate
remove any rails or carpets before they can pickup by player;

The retrieve rails or carpets part

capture player break event;

if break block is NOT rail or carpet:
    do nothing;
else:
    get player inventory space

    if no inventory space left:
        cancel this break event;
        send notification about no inventory space left can't pick up;
    else:
        # Rail or carpet block break is ONE at a time
        add ONE rail or ONE carpet into the player inventory;

These two part of code should run asynchronously,
this make sure duplicator can't generate any related item that player able to pick up.
But they can still run normally as in single player game.
This also allow some strange useful redstone machine to run(I know one of them).

dniym commented 4 years ago

Combining those I think we just simply deny any rail or carpet to natural drop (no matter piston or anything), delete them directly,

great idea but you can't detect them being created by the machine which is the entire problem, so they're in the world without plugins being able to detect what created them.

thus you would have to deny the spawning of the item which may or may not be detectable, then check it against the moved piston potential dupe machine and delete/cancel it.

mhtvsSFrpHdE commented 4 years ago

The async not mean something multi thread optimize,
it's just say that the two part of code don't affect each other, and work simultaneously

mhtvsSFrpHdE commented 4 years ago

Combining those I think we just simply deny any rail or carpet to natural drop (no matter piston or anything), delete them directly,

great idea but you can't detect them being created by the machine which is the entire problem, so they're in the world without plugins being able to detect what created them.

thus you would have to deny the spawning of the item which may or may not be detectable, then check it against the moved piston potential dupe machine and delete/cancel it.

@dniym Forget the machines, just deny ANY of them to be dropped?
Any time, any place, any form, to prevent them become items drop on ground.
Erase them, unless is player dig on them...but still erase, add back to inventory use another event

mhtvsSFrpHdE commented 4 years ago

@dniym Wait, you means, if machine generated a rail drop, it will not trigger a event?

That would be very trouble.

mhtvsSFrpHdE commented 4 years ago

When a block is moved it totally does go into a list, thats how we can detect/modify which blocks are moved. However when this bug happens (a carpet / rail dupe) an entity is created (DROPPED_ITEM) with a type (Material=CARPET) or rail. This does not happen normally as no block is actually broken so we can't detect WHY the rail/carpet dropped item was created, so IllegalStack can't cancel / or remove the invalid item when it appears because it's undetectable from a coding standpoint.

This says... we can't confirm what is actually broken,
but how about deny ANY of them, I don't care who caused this cursed rail appears here,
I just erase it to prevent player or anything to pick up it. Erase ALL of them

And provide a way to let player retrieve their rail the event way

I would say, at least for rail and carpet,
unless someone try to dupe, they have no reason to be dropped to the ground

dniym commented 4 years ago

@dniym Wait, you means, if machine generated a rail drop, it will not trigger a event?

That would be very trouble.

it does not trigger an event when the dupe occurs no, if the block breaks then yes the event triggers normally.

dniym commented 4 years ago

When a block is moved it totally does go into a list, thats how we can detect/modify which blocks are moved. However when this bug happens (a carpet / rail dupe) an entity is created (DROPPED_ITEM) with a type (Material=CARPET) or rail. This does not happen normally as no block is actually broken so we can't detect WHY the rail/carpet dropped item was created, so IllegalStack can't cancel / or remove the invalid item when it appears because it's undetectable from a coding standpoint.

This says... we can't confirm what is actually broken, but how about deny ANY of them, I don't care who caused this cursed rail appears here, I just erase it to prevent player or anything to pick up it. Erase ALL of them

And provide a way to let player retrieve their rail the event way

I would say, at least for rail and carpet, unless someone try to dupe, they have no reason to be dropped to the ground

The absolute only way to achieve this would be to check whenever an entity is spawned check its type, and if its a rail or carpet then destroy the entity. THEN whenever a block of that type is broken allow the item to spawn. Also when TNT explodes and breaks the block under it, it would trigger this.

As far as the grand scheme of things is concerned for the vast majority of the servers I think the best option is to block them.. I may do some testing to see if preventing them from ever spawning is feasible but that is a lot of different avenues to have to maintain for a redstone mechanic that can be worked around.

KrisBigK commented 4 years ago

Redstone-wise an alternative that I’m willing to accept is to make rails only pushable/pullable directly by a piston and unaffected by slime blocks. But I’m not sure whether a duplicator can be created without the use of slime blocks.

mhtvsSFrpHdE commented 4 years ago

@dniym So we should be able to detect the spawn(item drop) in the end...
Right, TNT and block under it will also destroy the rail block, but unimportant.

Just tell the player "avoid breaking it without hand digging, or it will disappear"
is totally acceptable.

mhtvsSFrpHdE commented 4 years ago

Well... I'm not pretty sure my explain is clear and easy to understand or not I'm not native English speaker
I'm thinking there are the following situations:

These 3 situation would lead to "an entity" that refers an item drop able to pick, right? If this entity is rail or carpet, destroy it, no mater how it spawns.
Just don't let them to spawn.

The absolute only way to achieve this would be to check whenever an entity is spawned check its type, and if its a rail or carpet then destroy the entity.

Yes, destroy them.

THEN whenever a block of that type is broken allow the item to spawn.

No, destroy them too and don't need to check conditions for performance,
because it seems we can't ensure we can detect all of that.

Also when TNT explodes and breaks the block under it, it would trigger this.

Destroy them as before mentioned

Until here, what is your idea?
This perhaps can allow any machine to run but effectively prevented item dupe?

dniym commented 1 year ago

IllegalStack version 2.8 is now out, if you are still experiencing this issue please open a new ticket.