Revert "Full Folia async support"

This reverts commit 73e862a782.
This commit is contained in:
Axionize committed 2024-12-14 14:13:38 -05:00
1 parent 73e862a782
commit b447154d52
9 files changed
+86 -151

No files matched your search

@@ -8,10 +8,10 @@ import io.github.retrooper.packetevents.util.folia.FoliaScheduler;
import io.github.retrooper.packetevents.util.folia.RegionScheduler;
import me.caseload.knockbacksync.Base;
import me.caseload.knockbacksync.BukkitBase;
import me.caseload.knockbacksync.async.AsyncOperation;
import me.caseload.knockbacksync.async.FoliaOperation;
import me.caseload.knockbacksync.listener.bukkit.BukkitPlayerKnockbackListener;
import me.caseload.knockbacksync.world.raytrace.FluidHandling;
import me.caseload.knockbacksync.world.raytrace.RayTraceResult;
import org.bukkit.Bukkit;
import org.bukkit.FluidCollisionMode;
import org.bukkit.Location;
import org.bukkit.World;
@@ -32,7 +32,7 @@ public class FoliaWorld extends SpigotWorld {
}
@Override
public AsyncOperation<WrappedBlockState> getBlockStateAt(int x, int y, int z) {
public WrappedBlockState getBlockStateAt(int x, int y, int z) {
Location location = new Location(super.world, x, y, z);
CompletableFuture<WrappedBlockState> future = new CompletableFuture<>();
@@ -41,37 +41,49 @@ public class FoliaWorld extends SpigotWorld {
future.complete(SpigotConversionUtil.fromBukkitBlockData(block.getBlockData()));
});
return new FoliaOperation<>(future);
try {
return future.get(); // Wait for the result
} catch (Exception e) {
e.printStackTrace();
return null; // Handle error appropriately
}
}
@Override
public AsyncOperation<RayTraceResult> rayTraceBlocks(Vector3d start, Vector3d direction, double maxDistance, FluidHandling fluidHandling, boolean ignorePassableBlocks) {
public RayTraceResult rayTraceBlocks(Vector3d start, Vector3d direction, double maxDistance, FluidHandling fluidHandling, boolean ignorePassableBlocks) {
Location location = new Location(super.world, start.getX(), start.getY(), start.getZ());
CompletableFuture<RayTraceResult> future = new CompletableFuture<>();
// Yes this code is bad; I know it's bad. We did not design this plugin around Folia, too bad!
scheduler.execute(plugin, location, () -> {
Vector startVec = new Vector(start.getX(), start.getY(), start.getZ());
Vector directionVec = new Vector(direction.getX(), direction.getY(), direction.getZ());
// Existing 1.13+ code using world.rayTraceBlocks
Vector startVec = new Vector(start.getX(), start.getY(), start.getZ());
Vector directionVec = new Vector(direction.getX(), direction.getY(), direction.getZ());
FluidCollisionMode fluidMode = (fluidHandling == FluidHandling.NONE) ? FluidCollisionMode.NEVER :
(fluidHandling == FluidHandling.SOURCE_ONLY) ? FluidCollisionMode.SOURCE_ONLY :
FluidCollisionMode.ALWAYS;
FluidCollisionMode fluidMode = (fluidHandling == FluidHandling.NONE) ? FluidCollisionMode.NEVER :
(fluidHandling == FluidHandling.SOURCE_ONLY) ? FluidCollisionMode.SOURCE_ONLY :
FluidCollisionMode.ALWAYS;
org.bukkit.util.RayTraceResult result = super.world.rayTraceBlocks(startVec.toLocation(super.world), directionVec, maxDistance, fluidMode, ignorePassableBlocks);
org.bukkit.util.RayTraceResult result = super.world.rayTraceBlocks(startVec.toLocation(super.world), directionVec, maxDistance, fluidMode, ignorePassableBlocks);
if (result == null) {
future.complete(null);
return;
}
if (result == null) {
future.complete(null);
return;
}
future.complete(new RayTraceResult(
new Vector3d(result.getHitPosition().getX(), result.getHitPosition().getY(), result.getHitPosition().getZ()),
getBlockFaceFrom(result.getHitBlockFace()),
new Vector3i(result.getHitBlock().getX(), result.getHitBlock().getY(), result.getHitBlock().getY()),
result.getHitBlock() != null ? SpigotConversionUtil.fromBukkitBlockData(result.getHitBlock().getBlockData()) : null
));
future.complete(new RayTraceResult(
new Vector3d(result.getHitPosition().getX(), result.getHitPosition().getY(), result.getHitPosition().getZ()),
getBlockFaceFrom(result.getHitBlockFace()),
new Vector3i(result.getHitBlock().getX(), result.getHitBlock().getY(), result.getHitBlock().getY()),
result.getHitBlock() != null ? SpigotConversionUtil.fromBukkitBlockData(result.getHitBlock().getBlockData()) : null
));
});
return new FoliaOperation<>(future);
try {
return future.get(); // Wait for the result
} catch (Exception e) {
e.printStackTrace();
return null; // Handle error appropriately
}
}
}
@@ -7,8 +7,6 @@ import com.github.retrooper.packetevents.protocol.world.states.WrappedBlockState
import com.github.retrooper.packetevents.util.Vector3d;
import com.github.retrooper.packetevents.util.Vector3i;
import io.github.retrooper.packetevents.util.SpigotConversionUtil;
import me.caseload.knockbacksync.async.AsyncOperation;
import me.caseload.knockbacksync.async.SyncOperation;
import me.caseload.knockbacksync.world.raytrace.FluidHandling;
import me.caseload.knockbacksync.world.raytrace.RayTraceResult;
import org.bukkit.Bukkit;
@@ -80,18 +78,18 @@ public class SpigotWorld implements PlatformWorld {
}
@Override
public AsyncOperation<WrappedBlockState> getBlockStateAt(int x, int y, int z) {
public WrappedBlockState getBlockStateAt(int x, int y, int z) {
Block block = world.getBlockAt(x, y, z);
return new SyncOperation<>(SpigotConversionUtil.fromBukkitBlockData(block.getBlockData()));
return SpigotConversionUtil.fromBukkitBlockData(block.getBlockData());
}
@Override
public AsyncOperation<WrappedBlockState> getBlockStateAt(Vector3d loc) {
public WrappedBlockState getBlockStateAt(Vector3d loc) {
return getBlockStateAt((int) Math.floor(loc.x), (int) Math.floor(loc.y), (int) Math.floor(loc.z));
}
@Override
public AsyncOperation<RayTraceResult> rayTraceBlocks(Vector3d start, Vector3d direction, double maxDistance, FluidHandling fluidHandling, boolean ignorePassableBlocks) {
public RayTraceResult rayTraceBlocks(Vector3d start, Vector3d direction, double maxDistance, FluidHandling fluidHandling, boolean ignorePassableBlocks) {
if (PacketEvents.getAPI().getServerManager().getVersion().isNewerThan(ServerVersion.V_1_12_2)) {
Vector startVec = new Vector(start.getX(), start.getY(), start.getZ());
Vector directionVec = new Vector(direction.getX(), direction.getY(), direction.getZ());
@@ -104,12 +102,12 @@ public class SpigotWorld implements PlatformWorld {
if (result == null) return null;
return new SyncOperation<>(new RayTraceResult(
return new RayTraceResult(
new Vector3d(result.getHitPosition().getX(), result.getHitPosition().getY(), result.getHitPosition().getZ()),
getBlockFaceFrom(result.getHitBlockFace()),
new Vector3i(result.getHitBlock().getX(), result.getHitBlock().getY(), result.getHitBlock().getZ()),
result.getHitBlock() != null ? SpigotConversionUtil.fromBukkitBlockData(result.getHitBlock().getBlockData()) : null
));
);
// Only tested on 1.12.2
} else {
try {
@@ -132,14 +130,14 @@ public class SpigotWorld implements PlatformWorld {
Object hitDirection = hitResult.getClass().getField("direction").get(hitResult);
Object hitBlock = hitResult.getClass().getField("e").get(hitResult); // e = BlockHitResult
return new SyncOperation<>(new RayTraceResult(
return new RayTraceResult(
hitPosition,
getHitBlockFace(hitDirection),
new Vector3i((int) hitBlock.getClass().getField("x").get(hitBlock),
(int) hitBlock.getClass().getField("y").get(hitBlock),
(int) hitBlock.getClass().getField("z").get(hitBlock)),
hitBlock != null ? WrappedBlockState.getByString(hitBlock.getClass().getField("type").get(hitBlock).toString()) : null
));
);
} catch (Exception e) {
e.printStackTrace();
return null; // Return null if there was an error during ray tracing
@@ -1,9 +0,0 @@
package me.caseload.knockbacksync.async;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
// Platform-agnostic interface
public interface AsyncOperation<T> {
CompletableFuture<T> asFuture();
}
@@ -1,18 +0,0 @@
package me.caseload.knockbacksync.async;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
// Async implementation for Folia
public class FoliaOperation<T> implements AsyncOperation<T> {
private final CompletableFuture<T> future;
public FoliaOperation(CompletableFuture<T> future) {
this.future = future;
}
@Override
public CompletableFuture<T> asFuture() {
return future;
}
}
@@ -1,17 +0,0 @@
package me.caseload.knockbacksync.async;
import java.util.concurrent.CompletableFuture;
// Paper/Fabric implementation
public class SyncOperation<T> implements AsyncOperation<T> {
private final T result;
public SyncOperation(T result) {
this.result = result;
}
@Override
public CompletableFuture<T> asFuture() {
return CompletableFuture.completedFuture(result);
}
}
@@ -8,8 +8,6 @@ import me.caseload.knockbacksync.manager.PlayerDataManager;
import me.caseload.knockbacksync.player.PlatformPlayer;
import me.caseload.knockbacksync.player.PlayerData;
import java.util.concurrent.CompletableFuture;
public abstract class PlayerKnockbackListener {
public void onPlayerVelocity(PlatformPlayer victim, Vector3d velocity) {
@@ -23,35 +21,31 @@ public abstract class PlayerKnockbackListener {
if (victimPlayerData.getNotNullPing() < PlayerData.PING_OFFSET)
return;
victimPlayerData.getDistanceToGround().asFuture()
.thenCompose(distanceToGround -> {
if (distanceToGround <= 0)
return CompletableFuture.completedFuture(null);
double distanceToGround = victimPlayerData.getDistanceToGround();
if (distanceToGround <= 0)
return; // minecraft already does the work for us
return victim.getWorld().getBlockStateAt(victim.getLocation()).asFuture()
.thenAccept(blockState -> {
if (victim.isGliding() ||
blockState.getType() == StateTypes.WATER ||
blockState.getType() == StateTypes.LAVA ||
blockState.getType() == StateTypes.COBWEB ||
blockState.getType() == StateTypes.SCAFFOLDING)
return;
WrappedBlockState blockState = victim.getWorld().getBlockStateAt(victim.getLocation());
if (victim.isGliding() ||
blockState.getType() == StateTypes.WATER ||
blockState.getType() == StateTypes.LAVA ||
blockState.getType() == StateTypes.COBWEB ||
blockState.getType() == StateTypes.SCAFFOLDING)
return;
Vector3d adjustedVelocity;
if (victimPlayerData.isOnGroundClientSide(velocity.getY(), distanceToGround)) {
Integer damageTicks = victimPlayerData.getLastDamageTicks();
if (damageTicks != null && damageTicks > 8)
return;
Vector3d adjustedVelocity;
if (victimPlayerData.isOnGroundClientSide(velocity.getY(), distanceToGround)) {
Integer damageTicks = victimPlayerData.getLastDamageTicks();
if (damageTicks != null && damageTicks > 8)
return;
adjustedVelocity = velocity.withY(victimPlayerData.getVerticalVelocity());
}
else if (victimPlayerData.isOffGroundSyncEnabled())
adjustedVelocity = velocity.withY(victimPlayerData.getCompensatedOffGroundVelocity());
else
return;
adjustedVelocity = velocity.withY(victimPlayerData.getVerticalVelocity()); // Should be impossible to produce a NPE in this context
}
else if (victimPlayerData.isOffGroundSyncEnabled())
adjustedVelocity = velocity.withY(victimPlayerData.getCompensatedOffGroundVelocity());
else
return;
victim.setVelocity(adjustedVelocity);
});
});
victim.setVelocity(adjustedVelocity);
}
}
@@ -16,9 +16,6 @@ import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerWi
import lombok.Getter;
import lombok.Setter;
import me.caseload.knockbacksync.Base;
import me.caseload.knockbacksync.async.AsyncOperation;
import me.caseload.knockbacksync.async.FoliaOperation;
import me.caseload.knockbacksync.async.SyncOperation;
import me.caseload.knockbacksync.command.subcommand.ToggleOffGroundSubcommand;
import me.caseload.knockbacksync.event.KBSyncEventHandler;
import me.caseload.knockbacksync.event.events.ToggleOnOffEvent;
@@ -34,7 +31,6 @@ import org.jetbrains.annotations.Nullable;
import java.lang.reflect.Field;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentLinkedQueue;
@Getter
@@ -235,35 +231,23 @@ public class PlayerData {
*
* @return The distance to the ground in blocks
*/
public AsyncOperation<Double> getDistanceToGround() {
public double getDistanceToGround() {
double collisionDist = 5;
PlatformWorld world = platformPlayer.getWorld();
Vector3d[] corners = getBBCorners();
// Start with the first corner
CompletableFuture<Double> future = processCorner(world, corners, 0, 5.0);
for (Vector3d corner : getBBCorners()) {
RayTraceResult result = world.rayTraceBlocks(corner, new Vector3d(0, -1, 0), 5, FluidHandling.NONE, true);
return new FoliaOperation<>(future);
}
if (result == null || result.getHitBlock() == null)
continue;
private CompletableFuture<Double> processCorner(PlatformWorld world, Vector3d[] corners, int index, double currentMin) {
if (index >= corners.length) {
return CompletableFuture.completedFuture(currentMin - 1);
collisionDist = Math.min(collisionDist, corner.getY() - result.getHitBlockPosition().getY());
}
return world.rayTraceBlocks(corners[index], new Vector3d(0, -1, 0), 5, FluidHandling.NONE, true)
.asFuture()
.thenCompose(result -> {
double newMin = currentMin;
if (result != null && result.getHitBlock() != null) {
newMin = Math.min(currentMin, corners[index].getY() - result.getHitBlockPosition().getY());
}
// Process next corner
return processCorner(world, corners, index + 1, newMin);
});
return collisionDist - 1;
}
/**
* Gets the corners of the Player's bounding box.
*
@@ -2,12 +2,13 @@ package me.caseload.knockbacksync.world;
import com.github.retrooper.packetevents.protocol.world.states.WrappedBlockState;
import com.github.retrooper.packetevents.util.Vector3d;
import me.caseload.knockbacksync.async.AsyncOperation;
import me.caseload.knockbacksync.world.raytrace.FluidHandling;
import me.caseload.knockbacksync.world.raytrace.RayTraceResult;
public interface PlatformWorld {
AsyncOperation<WrappedBlockState> getBlockStateAt(int x, int y, int z);
AsyncOperation<WrappedBlockState> getBlockStateAt(Vector3d loc);
AsyncOperation<RayTraceResult> rayTraceBlocks(Vector3d start, Vector3d direction, double maxDistance, FluidHandling fluidHandling, boolean ignorePassableBlocks);
WrappedBlockState getBlockStateAt(int x, int y, int z);
WrappedBlockState getBlockStateAt(Vector3d loc);
RayTraceResult rayTraceBlocks(Vector3d start, Vector3d direction, double maxDistance, FluidHandling fluidHandling, boolean ignorePassableBlocks);
}
@@ -4,8 +4,6 @@ import com.github.retrooper.packetevents.protocol.world.BlockFace;
import com.github.retrooper.packetevents.protocol.world.states.WrappedBlockState;
import com.github.retrooper.packetevents.util.Vector3d;
import com.github.retrooper.packetevents.util.Vector3i;
import me.caseload.knockbacksync.async.AsyncOperation;
import me.caseload.knockbacksync.async.SyncOperation;
import me.caseload.knockbacksync.world.raytrace.FluidHandling;
import me.caseload.knockbacksync.world.raytrace.RayTraceResult;
import net.minecraft.core.BlockPos;
@@ -19,8 +17,6 @@ import net.minecraft.world.phys.HitResult;
import net.minecraft.world.phys.Vec3;
import net.minecraft.world.phys.shapes.CollisionContext;
import java.util.concurrent.CompletableFuture;
public class FabricWorld implements PlatformWorld {
private final Level world;
@@ -29,18 +25,18 @@ public class FabricWorld implements PlatformWorld {
}
@Override
public AsyncOperation<WrappedBlockState> getBlockStateAt(int x, int y, int z) {
public WrappedBlockState getBlockStateAt(int x, int y, int z) {
BlockState blockState = this.world.getBlockState(new BlockPos(x, y, z));
return new SyncOperation<>(WrappedBlockState.getByGlobalId(Block.BLOCK_STATE_REGISTRY.getId(blockState)));
return WrappedBlockState.getByGlobalId(Block.BLOCK_STATE_REGISTRY.getId(blockState));
}
@Override
public AsyncOperation<WrappedBlockState> getBlockStateAt(Vector3d loc) {
public WrappedBlockState getBlockStateAt(Vector3d loc) {
return getBlockStateAt((int) Math.floor(loc.x), (int) Math.floor(loc.x), (int) Math.floor(loc.x));
}
@Override
public AsyncOperation<RayTraceResult> rayTraceBlocks(Vector3d start, Vector3d direction, double maxDistance, FluidHandling fluidHandling, boolean ignorePassableBlocks) {
public RayTraceResult rayTraceBlocks(Vector3d start, Vector3d direction, double maxDistance, FluidHandling fluidHandling, boolean ignorePassableBlocks) {
Vec3 startVec = new Vec3(start.getX(), start.getY(), start.getZ());
Vec3 endVec = startVec.add(direction.getX() * maxDistance, direction.getY() * maxDistance, direction.getZ() * maxDistance);
@@ -54,21 +50,15 @@ public class FabricWorld implements PlatformWorld {
CollisionContext.empty()
));
if (result.getType() == HitResult.Type.MISS) {
return new SyncOperation<>(null);
}
if (result.getType() == HitResult.Type.MISS) return null;
Vec3 hitLocation = result.getLocation();
BlockPos blockPos = result.getBlockPos();
// Since we're in Fabric, we can just get the block state synchronously
WrappedBlockState blockState = getBlockStateAt(blockPos.getX(), blockPos.getY(), blockPos.getZ()).asFuture().join();
return new SyncOperation<>(new RayTraceResult(
return new RayTraceResult(
new Vector3d(hitLocation.x, hitLocation.y, hitLocation.z),
BlockFace.getBlockFaceByValue(result.getDirection().ordinal()),
new Vector3i(blockPos.getX(), blockPos.getY(), blockPos.getZ()),
blockState
));
getBlockStateAt(blockPos.getX(), blockPos.getY(), blockPos.getZ())
);
}
}