Skip to content

Commit 6422b98

Browse files
Piston bugfix (#713)
* Test potential origin of bug It could be possible that cancelling these events has some adverse effects. * Disable old fix * Disable another potential origin * debug messages for monitoring * Potentially detect more piston events * fix events * detect processing * Test potential fix * Update IWorldHandler.java * Try to catch problems in the WorldHandler * Update IWorldHandler.java * Use NMS code to fix pistons * Update IWorldHandler.java * Remove old fixes and 1.21 implementation Also removed debug messages * Missed a debug message * Fix unintentional wildcard imports
1 parent 936a87a commit 6422b98

File tree

5 files changed

+85
-36
lines changed

5 files changed

+85
-36
lines changed

Movecraft/src/main/java/net/countercraft/movecraft/async/rotation/RotationTask.java

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -114,15 +114,6 @@ protected void execute() {
114114
MovecraftLocation newLocation = MathUtils.rotateVec(rotation,originalLocation.subtract(originPoint)).add(originPoint);
115115
newHitBox.add(newLocation);
116116

117-
//Prevent piston bug
118-
if (originalLocation.toBukkit(getCraft().getWorld()).getBlock().getType().equals(Material.MOVING_PISTON)) {
119-
failed = true;
120-
failMessage = (String.format(I18nSupport.getInternationalisedString("Translation - Failed Craft is obstructed")
121-
+ " @ %d,%d,%d,%s", originalLocation.getX(), originalLocation.getY(), originalLocation.getZ(),
122-
originalLocation.toBukkit(craft.getWorld()).getBlock().getType()));
123-
break;
124-
}
125-
126117
Material oldMaterial = originalLocation.toBukkit(w).getBlock().getType();
127118
//prevent chests collision
128119
if (Tags.CHESTS.contains(oldMaterial) && !checkChests(oldMaterial, newLocation)) {

Movecraft/src/main/java/net/countercraft/movecraft/async/translation/TranslationTask.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@
55
import net.countercraft.movecraft.MovecraftLocation;
66
import net.countercraft.movecraft.async.AsyncTask;
77
import net.countercraft.movecraft.config.Settings;
8-
import net.countercraft.movecraft.craft.*;
8+
import net.countercraft.movecraft.craft.ChunkManager;
9+
import net.countercraft.movecraft.craft.Craft;
10+
import net.countercraft.movecraft.craft.CraftManager;
11+
import net.countercraft.movecraft.craft.SinkingCraft;
12+
import net.countercraft.movecraft.craft.SubCraft;
913
import net.countercraft.movecraft.craft.type.CraftType;
1014
import net.countercraft.movecraft.events.CraftCollisionEvent;
1115
import net.countercraft.movecraft.events.CraftCollisionExplosionEvent;
@@ -24,8 +28,8 @@
2428
import net.countercraft.movecraft.util.Tags;
2529
import net.countercraft.movecraft.util.hitboxes.HitBox;
2630
import net.countercraft.movecraft.util.hitboxes.MutableHitBox;
27-
import net.countercraft.movecraft.util.hitboxes.SolidHitBox;
2831
import net.countercraft.movecraft.util.hitboxes.SetHitBox;
32+
import net.countercraft.movecraft.util.hitboxes.SolidHitBox;
2933
import net.kyori.adventure.key.Key;
3034
import org.bukkit.Bukkit;
3135
import org.bukkit.Location;
@@ -166,11 +170,6 @@ protected void execute() throws InterruptedException, ExecutionException {
166170
newHitBox.add(newLocation);
167171
continue;
168172
}
169-
//Prevent piston bug
170-
if (oldLocation.toBukkit(world).getBlock().getType().equals(Material.MOVING_PISTON))
171-
fail(String.format(I18nSupport.getInternationalisedString("Translation - Failed Craft is obstructed")
172-
+ " @ %d,%d,%d,%s", oldLocation.getX(), oldLocation.getY(), oldLocation.getZ(),
173-
oldLocation.toBukkit(craft.getWorld()).getBlock().getType()));
174173

175174
final Material testMaterial = newLocation.toBukkit(world).getBlock().getType();
176175

Movecraft/src/main/java/net/countercraft/movecraft/listener/BlockListener.java

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,11 @@
4242
import org.bukkit.event.block.BlockFormEvent;
4343
import org.bukkit.event.block.BlockFromToEvent;
4444
import org.bukkit.event.block.BlockPhysicsEvent;
45+
import org.bukkit.event.block.BlockPistonEvent;
4546
import org.bukkit.event.block.BlockPistonExtendEvent;
46-
import org.bukkit.event.block.BlockRedstoneEvent;
47+
import org.bukkit.event.block.BlockPistonRetractEvent;
4748
import org.bukkit.event.block.BlockPlaceEvent;
49+
import org.bukkit.event.block.BlockRedstoneEvent;
4850
import org.bukkit.event.entity.ItemSpawnEvent;
4951
import org.bukkit.event.inventory.InventoryMoveItemEvent;
5052
import org.bukkit.material.Attachable;
@@ -123,30 +125,41 @@ public void onRedstoneEvent(@NotNull BlockRedstoneEvent e) {
123125
}
124126

125127
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
126-
public void onPistonEvent(@NotNull BlockPistonExtendEvent e) {
128+
public void onPistonExtendEvent(@NotNull BlockPistonExtendEvent e) {
129+
onPistonEvent(e);
130+
}
131+
132+
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
133+
public void onPistonRetractEvent(@NotNull BlockPistonRetractEvent e) {
134+
onPistonEvent(e);
135+
}
136+
137+
public void onPistonEvent(@NotNull BlockPistonEvent e) {
127138
Block block = e.getBlock();
128139
Location location = block.getLocation();
129140
MovecraftLocation loc = MathUtils.bukkit2MovecraftLoc(location);
130141
for (Craft craft : MathUtils.craftsNearLocFast(CraftManager.getInstance().getCrafts(), location)) {
131142
if (!craft.getHitBox().contains(loc))
132143
continue;
133144

134-
if (!craft.isNotProcessing())
135-
e.setCancelled(true); // prevent pistons on cruising crafts
136-
145+
if (!craft.isNotProcessing())
146+
e.setCancelled(true); // prevent pistons on cruising crafts
147+
if (!(e instanceof BlockPistonExtendEvent))
148+
return;
137149
// merge piston extensions to craft
138-
if (craft.getType().getBoolProperty(CraftType.MERGE_PISTON_EXTENSIONS))
150+
if (craft.getType().getBoolProperty(CraftType.MERGE_PISTON_EXTENSIONS))
139151
continue;
140152

141-
BitmapHitBox hitBox = new BitmapHitBox();
142-
for (Block b : e.getBlocks()) {
143-
Vector dir = e.getDirection().getDirection();
144-
hitBox.add(new MovecraftLocation(b.getX() + dir.getBlockX(), b.getY() + dir.getBlockY(), b.getZ() + dir.getBlockZ()));
145-
}
146-
craft.setHitBox(craft.getHitBox().union(hitBox));
153+
BitmapHitBox hitBox = new BitmapHitBox();
154+
for (Block b : ((BlockPistonExtendEvent) e).getBlocks()) {
155+
Vector dir = e.getDirection().getDirection();
156+
hitBox.add(new MovecraftLocation(b.getX() + dir.getBlockX(), b.getY() + dir.getBlockY(), b.getZ() + dir.getBlockZ()));
157+
}
158+
craft.setHitBox(craft.getHitBox().union(hitBox));
147159
}
148160
}
149161

162+
150163
// prevent hoppers on cruising crafts
151164
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
152165
public void onHopperEvent(@NotNull InventoryMoveItemEvent e) {

v1_20/src/main/java/net/countercraft/movecraft/compat/v1_20/IWorldHandler.java

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,23 @@
88
import net.countercraft.movecraft.util.MathUtils;
99
import net.countercraft.movecraft.util.UnsafeUtils;
1010
import net.minecraft.core.BlockPos;
11+
import net.minecraft.core.Direction;
1112
import net.minecraft.server.level.ServerLevel;
1213
import net.minecraft.world.inventory.AbstractContainerMenu;
1314
import net.minecraft.world.inventory.ContainerLevelAccess;
15+
import net.minecraft.world.level.BlockEventData;
1416
import net.minecraft.world.level.Level;
1517
import net.minecraft.world.level.block.Block;
1618
import net.minecraft.world.level.block.Blocks;
19+
import net.minecraft.world.level.block.DirectionalBlock;
1720
import net.minecraft.world.level.block.Rotation;
1821
import net.minecraft.world.level.block.entity.BlockEntity;
1922
import net.minecraft.world.level.block.entity.BlockEntityTicker;
23+
import net.minecraft.world.level.block.piston.PistonBaseBlock;
24+
import net.minecraft.world.level.block.piston.PistonMovingBlockEntity;
25+
import net.minecraft.world.level.block.state.BlockBehaviour;
2026
import net.minecraft.world.level.block.state.BlockState;
27+
import net.minecraft.world.level.block.state.properties.DirectionProperty;
2128
import net.minecraft.world.level.chunk.LevelChunk;
2229
import net.minecraft.world.level.chunk.LevelChunkSection;
2330
import net.minecraft.world.ticks.LevelChunkTicks;
@@ -163,10 +170,12 @@ public void translateCraft(@NotNull Craft craft, @NotNull MovecraftLocation disp
163170

164171
//get the nextTick to move with the tile
165172
ScheduledTick tickHere = tickProvider.getNextTick(nativeWorld, position);
166-
if (tickHere != null) {
173+
while (tickHere != null) {
174+
ScheduledTick tickToRemove = tickHere;
167175
((LevelChunkTicks) nativeWorld.getChunkAt(position).getBlockTicks()).removeIf(
168-
(Predicate<ScheduledTick>) scheduledTick -> scheduledTick.equals(tickHere));
176+
(Predicate<ScheduledTick>) scheduledTick -> scheduledTick.equals(tickToRemove));
169177
ticks.add(new TickHolder(tickHere, position));
178+
tickHere = tickProvider.getNextTick(nativeWorld, position);
170179
}
171180

172181
}
@@ -213,6 +222,24 @@ public void translateCraft(@NotNull Craft craft, @NotNull MovecraftLocation disp
213222

214223
@Nullable
215224
private BlockEntity removeBlockEntity(@NotNull Level world, @NotNull BlockPos position) {
225+
BlockEntity testEntity = world.getChunkAt(position).getBlockEntity(position);
226+
//Prevents moving pistons by locking up by forcing their movement to finish
227+
if (testEntity instanceof PistonMovingBlockEntity)
228+
{
229+
BlockState oldState;
230+
if (((PistonMovingBlockEntity) testEntity).isSourcePiston() && testEntity.getBlockState().getBlock() instanceof PistonBaseBlock) {
231+
if (((PistonMovingBlockEntity) testEntity).getMovedState().is(Blocks.PISTON))
232+
oldState = Blocks.PISTON.defaultBlockState()
233+
.setValue(PistonBaseBlock.FACING, ((PistonMovingBlockEntity) testEntity).getMovedState().getValue(PistonBaseBlock.FACING));
234+
else
235+
oldState = Blocks.STICKY_PISTON.defaultBlockState()
236+
.setValue(PistonBaseBlock.FACING, ((PistonMovingBlockEntity) testEntity).getMovedState().getValue(PistonBaseBlock.FACING));
237+
} else
238+
oldState = ((PistonMovingBlockEntity) testEntity).getMovedState();
239+
((PistonMovingBlockEntity) testEntity).finalTick();
240+
setBlockFast(world, position, oldState);
241+
return world.getBlockEntity(position);
242+
}
216243
return world.getChunkAt(position).blockEntities.remove(position);
217244
}
218245

v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/IWorldHandler.java

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@
99
import net.countercraft.movecraft.util.UnsafeUtils;
1010
import net.minecraft.core.BlockPos;
1111
import net.minecraft.server.level.ServerLevel;
12-
import net.minecraft.world.inventory.AbstractContainerMenu;
13-
import net.minecraft.world.inventory.ContainerLevelAccess;
1412
import net.minecraft.world.level.Level;
1513
import net.minecraft.world.level.block.Block;
1614
import net.minecraft.world.level.block.Blocks;
1715
import net.minecraft.world.level.block.Rotation;
1816
import net.minecraft.world.level.block.entity.BlockEntity;
17+
import net.minecraft.world.level.block.piston.PistonBaseBlock;
18+
import net.minecraft.world.level.block.piston.PistonMovingBlockEntity;
1919
import net.minecraft.world.level.block.state.BlockState;
2020
import net.minecraft.world.level.chunk.LevelChunk;
2121
import net.minecraft.world.level.chunk.LevelChunkSection;
@@ -26,13 +26,14 @@
2626
import org.bukkit.block.data.BlockData;
2727
import org.bukkit.craftbukkit.CraftWorld;
2828
import org.bukkit.craftbukkit.block.data.CraftBlockData;
29-
import org.bukkit.craftbukkit.inventory.CraftInventoryView;
30-
import org.bukkit.inventory.InventoryView;
3129
import org.jetbrains.annotations.NotNull;
3230
import org.jetbrains.annotations.Nullable;
3331

34-
import java.lang.reflect.Field;
35-
import java.util.*;
32+
import java.util.ArrayList;
33+
import java.util.Collection;
34+
import java.util.HashMap;
35+
import java.util.List;
36+
import java.util.Map;
3637
import java.util.function.Predicate;
3738

3839
@SuppressWarnings("unused")
@@ -208,6 +209,24 @@ public void translateCraft(@NotNull Craft craft, @NotNull MovecraftLocation disp
208209

209210
@Nullable
210211
private BlockEntity removeBlockEntity(@NotNull Level world, @NotNull BlockPos position) {
212+
BlockEntity testEntity = world.getChunkAt(position).getBlockEntity(position);
213+
//Prevents moving pistons by locking up by forcing their movement to finish
214+
if (testEntity instanceof PistonMovingBlockEntity)
215+
{
216+
BlockState oldState;
217+
if (((PistonMovingBlockEntity) testEntity).isSourcePiston() && testEntity.getBlockState().getBlock() instanceof PistonBaseBlock) {
218+
if (((PistonMovingBlockEntity) testEntity).getMovedState().is(Blocks.PISTON))
219+
oldState = Blocks.PISTON.defaultBlockState()
220+
.setValue(PistonBaseBlock.FACING, ((PistonMovingBlockEntity) testEntity).getMovedState().getValue(PistonBaseBlock.FACING));
221+
else
222+
oldState = Blocks.STICKY_PISTON.defaultBlockState()
223+
.setValue(PistonBaseBlock.FACING, ((PistonMovingBlockEntity) testEntity).getMovedState().getValue(PistonBaseBlock.FACING));
224+
} else
225+
oldState = ((PistonMovingBlockEntity) testEntity).getMovedState();
226+
((PistonMovingBlockEntity) testEntity).finalTick();
227+
setBlockFast(world, position, oldState);
228+
return world.getBlockEntity(position);
229+
}
211230
return world.getChunkAt(position).blockEntities.remove(position);
212231
}
213232

0 commit comments

Comments
 (0)