Skip to content

Commit 3ad418c

Browse files
committed
Remove capturing lambdas from acting as a fake player
1 parent 9cfd091 commit 3ad418c

File tree

3 files changed

+63
-35
lines changed

3 files changed

+63
-35
lines changed

src/main/java/mekanism/common/base/MekFakePlayer.java

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,30 @@ public UUID getUUID() {
5454
return this.emulatingUUID == null ? super.getUUID() : this.emulatingUUID;
5555
}
5656

57+
public void cleanupFakePlayer(ServerLevel world) {
58+
emulatingUUID = null;
59+
//don't keep reference to the World, note we set it to the overworld to avoid any potential null pointers
60+
setServerLevel(world.getServer().overworld());
61+
}
62+
63+
@SuppressWarnings("WeakerAccess")
64+
public static MekFakePlayer setupFakePlayer(ServerLevel world) {
65+
MekFakePlayer actual = INSTANCE == null ? null : INSTANCE.get();
66+
if (actual == null) {
67+
actual = new MekFakePlayer(world);
68+
INSTANCE = new WeakReference<>(actual);
69+
}
70+
MekFakePlayer player = actual;
71+
player.setServerLevel(world);
72+
return player;
73+
}
74+
75+
public static MekFakePlayer setupFakePlayer(ServerLevel world, double x, double y, double z) {
76+
MekFakePlayer player = setupFakePlayer(world);
77+
player.setPosRaw(x, y, z);
78+
return player;
79+
}
80+
5781
/**
5882
* Acquire a Fake Player and call a function which makes use of the player. Afterwards, the Fake Player's world is nulled out to prevent GC issues. Emulated UUID is
5983
* also reset.
@@ -68,17 +92,9 @@ public UUID getUUID() {
6892
*/
6993
@SuppressWarnings("WeakerAccess")
7094
public static <R> R withFakePlayer(ServerLevel world, Function<MekFakePlayer, R> fakePlayerConsumer) {
71-
MekFakePlayer actual = INSTANCE == null ? null : INSTANCE.get();
72-
if (actual == null) {
73-
actual = new MekFakePlayer(world);
74-
INSTANCE = new WeakReference<>(actual);
75-
}
76-
MekFakePlayer player = actual;
77-
player.setServerLevel(world);
95+
MekFakePlayer player = setupFakePlayer(world);
7896
R result = fakePlayerConsumer.apply(player);
79-
player.emulatingUUID = null;
80-
//don't keep reference to the World, note we set it to the overworld to avoid any potential null pointers
81-
player.setServerLevel(world.getServer().overworld());
97+
player.cleanupFakePlayer(world);
8298
return result;
8399
}
84100

src/main/java/mekanism/common/tile/laser/TileEntityBasicLaser.java

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -294,23 +294,7 @@ protected boolean onUpdateServer() {
294294
diggingProgress = diggingProgress.plusEqual(remainingEnergy);
295295
if (diggingProgress.compareTo(MekanismConfig.general.laserEnergyNeededPerHardness.get().multiply(hardness)) >= 0) {
296296
if (MekanismConfig.general.aestheticWorldDamage.get()) {
297-
MekFakePlayer.withFakePlayer((ServerLevel) level, to.x(), to.y(), to.z(), dummy -> {
298-
dummy.setEmulatingUUID(getOwnerUUID());//pretend to be the owner
299-
BlockEvent.BreakEvent event = new BlockEvent.BreakEvent(level, hitPos, hitState, dummy);
300-
if (!NeoForge.EVENT_BUS.post(event).isCanceled()) {
301-
if (hitState.getBlock() instanceof TntBlock && hitState.isFlammable(level, hitPos, result.getDirection())) {
302-
//Convert TNT that can be lit on fire into a tnt entity
303-
//Note: We don't mark the fake player as the igniter as then when the tnt explodes if it hits a player
304-
// there will be a crash as our fake player's level will be null
305-
hitState.onCaughtFire(level, hitPos, result.getDirection(), null);
306-
level.removeBlock(hitPos, false);
307-
} else {
308-
//Use the disassembler as the item to break the block with as that is marked as being the correct tool for drops
309-
handleBreakBlock(hitState, hitPos, dummy, ItemAtomicDisassembler.fullyChargedStack());
310-
}
311-
}
312-
return null;
313-
});
297+
withFakePlayer((ServerLevel) level, to.x(), to.y(), to.z(), hitPos, hitState, result.getDirection());
314298
}
315299
diggingProgress = FloatingLong.ZERO;
316300
} else {
@@ -334,6 +318,25 @@ protected boolean onUpdateServer() {
334318
return sendUpdatePacket;
335319
}
336320

321+
private void withFakePlayer(ServerLevel level, double x, double y, double z, BlockPos hitPos, BlockState hitState, Direction hitSide) {
322+
MekFakePlayer dummy = MekFakePlayer.setupFakePlayer(level, x, y, z);
323+
dummy.setEmulatingUUID(getOwnerUUID());//pretend to be the owner
324+
BlockEvent.BreakEvent event = new BlockEvent.BreakEvent(level, hitPos, hitState, dummy);
325+
if (!NeoForge.EVENT_BUS.post(event).isCanceled()) {
326+
if (hitState.getBlock() instanceof TntBlock && hitState.isFlammable(level, hitPos, hitSide)) {
327+
//Convert TNT that can be lit on fire into a tnt entity
328+
//Note: We don't mark the fake player as the igniter as then when the tnt explodes if it hits a player
329+
// there will be a crash as our fake player's level will be null
330+
hitState.onCaughtFire(level, hitPos, hitSide, null);
331+
level.removeBlock(hitPos, false);
332+
} else {
333+
//Use the disassembler as the item to break the block with as that is marked as being the correct tool for drops
334+
handleBreakBlock(hitState, hitPos, dummy, ItemAtomicDisassembler.fullyChargedStack());
335+
}
336+
}
337+
dummy.cleanupFakePlayer(level);
338+
}
339+
337340
/**
338341
* Based off of Player#hurtCurrentlyUsedShield
339342
*/

src/main/java/mekanism/common/tile/machine/TileEntityDigitalMiner.java

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -563,7 +563,7 @@ private boolean setReplace(BlockState state, BlockPos pos, @Nullable MinerFilter
563563
missingStack = new ItemStack(replaceTarget);
564564
return false;
565565
}
566-
BlockState newState = withFakePlayer(fakePlayer -> StackUtils.getStateForPlacement(stack, pos, fakePlayer));
566+
BlockState newState = getStateForPlacement(stack, pos);
567567
if (newState == null || !newState.canSurvive(level, pos)) {
568568
//If the spot is not a valid position for the block, then we return that we were unsuccessful
569569
return false;
@@ -576,14 +576,19 @@ private boolean setReplace(BlockState state, BlockPos pos, @Nullable MinerFilter
576576
}
577577

578578
private boolean canMine(BlockState state, BlockPos pos) {
579-
return withFakePlayer(dummy -> !NeoForge.EVENT_BUS.post(new BlockEvent.BreakEvent(level, pos, state, dummy)).isCanceled());
579+
MekFakePlayer dummy = MekFakePlayer.setupFakePlayer((ServerLevel) level, this.worldPosition.getX(), this.worldPosition.getY(), this.worldPosition.getZ())
580+
dummy.setEmulatingUUID(getOwnerUUID());//pretend to be the owner
581+
boolean canMine = !NeoForge.EVENT_BUS.post(new BlockEvent.BreakEvent(level, pos, state, dummy)).isCanceled();
582+
dummy.cleanupFakePlayer((ServerLevel) level);
583+
return canMine;
580584
}
581585

582-
private <R> R withFakePlayer(Function<MekFakePlayer, R> fakePlayerConsumer) {
583-
return MekFakePlayer.withFakePlayer((ServerLevel) level, this.worldPosition.getX(), this.worldPosition.getY(), this.worldPosition.getZ(), dummy -> {
584-
dummy.setEmulatingUUID(getOwnerUUID());//pretend to be the owner
585-
return fakePlayerConsumer.apply(dummy);
586-
});
586+
private BlockState getStateForPlacement(ItemStack stack, BlockPos pos) {
587+
MekFakePlayer dummy = MekFakePlayer.setupFakePlayer((ServerLevel) level, this.worldPosition.getX(), this.worldPosition.getY(), this.worldPosition.getZ())
588+
dummy.setEmulatingUUID(getOwnerUUID());//pretend to be the owner
589+
BlockState result = StackUtils.getStateForPlacement(stack, pos, dummy);
590+
dummy.cleanupFakePlayer((ServerLevel) level);
591+
return result;
587592
}
588593

589594
private ItemStack getReplace(Item replaceTarget, Predicate<Item> replaceStackMatches) {
@@ -1283,7 +1288,11 @@ private List<ItemStack> getDrops(BlockState state, BlockPos pos) {
12831288
stack.enchant(Enchantments.SILK_TOUCH, 1);
12841289
}
12851290
ServerLevel level = (ServerLevel) getWorldNN();
1286-
return withFakePlayer(fakePlayer -> Block.getDrops(state, level, pos, WorldUtils.getTileEntity(level, pos), fakePlayer, stack));
1291+
MekFakePlayer dummy = MekFakePlayer.setupFakePlayer(level, this.worldPosition.getX(), this.worldPosition.getY(), this.worldPosition.getZ())
1292+
dummy.setEmulatingUUID(getOwnerUUID());//pretend to be the owner
1293+
List<ItemStack> drops = Block.getDrops(state, level, pos, WorldUtils.getTileEntity(level, pos), dummy, stack);
1294+
dummy.cleanupFakePlayer(level);
1295+
return drops;
12871296
}
12881297

12891298
//Methods relating to IComputerTile

0 commit comments

Comments
 (0)