forked from SteamWar/SteamWar
Implemented cursor manager for deduplicated cursor updating
This commit is contained in:
+29
-14
@@ -1,51 +1,66 @@
|
|||||||
package de.steamwar.bausystem.utils;
|
package de.steamwar.bausystem.utils.cursor;
|
||||||
|
|
||||||
|
import de.steamwar.bausystem.utils.RayTraceUtils;
|
||||||
import de.steamwar.entity.REntity;
|
import de.steamwar.entity.REntity;
|
||||||
import de.steamwar.entity.REntityServer;
|
import de.steamwar.entity.REntityServer;
|
||||||
import de.steamwar.entity.RFallingBlockEntity;
|
import de.steamwar.entity.RFallingBlockEntity;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.util.Vector;
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
|
@Getter
|
||||||
public class RCursor {
|
public class RCursor {
|
||||||
|
|
||||||
private Player owner;
|
private final REntityServer targetServer;
|
||||||
private REntityServer targetServer;
|
|
||||||
|
private final Player owner;
|
||||||
|
private final Material highlightMaterial;
|
||||||
|
@Setter
|
||||||
|
private Material cursorMaterial;
|
||||||
|
|
||||||
private RFallingBlockEntity cursorEntity;
|
private RFallingBlockEntity cursorEntity;
|
||||||
|
|
||||||
private Material highlightMaterial;
|
public RCursor(REntityServer targetServer, Player owner, Material highlightMaterial, Material cursorMaterial) {
|
||||||
private Material cursorMaterial;
|
|
||||||
|
|
||||||
public RCursor(REntityServer targetServer, Material highlightMaterial, Material cursorMaterial) {
|
|
||||||
this.targetServer = targetServer;
|
this.targetServer = targetServer;
|
||||||
|
this.owner = owner;
|
||||||
this.highlightMaterial = highlightMaterial;
|
this.highlightMaterial = highlightMaterial;
|
||||||
this.cursorMaterial = cursorMaterial;
|
this.cursorMaterial = cursorMaterial;
|
||||||
|
|
||||||
|
RCursorManager.getInstance().registerCursor(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void render() {
|
public void render() {
|
||||||
RayTraceUtils.RRayTraceResult rayTraceResult = RayTraceUtils.traceREntity(owner, owner.getLocation(), targetServer.getEntities());
|
RayTraceUtils.RRayTraceResult rayTraceResult = RayTraceUtils.traceREntity(owner, owner.getLocation(), targetServer.getEntities());
|
||||||
if(rayTraceResult == null) {
|
if (rayTraceResult == null) {
|
||||||
cursorEntity.die();
|
cursorEntity.die();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
REntity hitEntity = rayTraceResult.getHitEntity();
|
REntity hitEntity = rayTraceResult.getHitEntity() == cursorEntity ? null : rayTraceResult.getHitEntity();
|
||||||
|
|
||||||
|
|
||||||
Material activeCursorMaterial = hitEntity == null ? cursorMaterial : highlightMaterial;
|
Material activeCursorMaterial = hitEntity == null ? cursorMaterial : highlightMaterial;
|
||||||
Location activeCursorLocation = hitEntity == null ? rayTraceResult.getHitPosition().toLocation(owner.getWorld())
|
Location activeCursorLocation = hitEntity == null ? rayTraceResult.getHitPosition().toLocation(owner.getWorld())
|
||||||
: new Vector(hitEntity.getX(), hitEntity.getY(), hitEntity.getZ()).toLocation(owner.getWorld());
|
: new Vector(hitEntity.getX(), hitEntity.getY(), hitEntity.getZ()).toLocation(owner.getWorld());
|
||||||
|
|
||||||
if(cursorEntity == null) {
|
if (cursorEntity == null) {
|
||||||
cursorEntity = new RFallingBlockEntity(targetServer, activeCursorLocation, activeCursorMaterial);
|
cursorEntity = new RFallingBlockEntity(targetServer, activeCursorLocation, activeCursorMaterial);
|
||||||
}
|
cursorEntity.setNoGravity(true);
|
||||||
else if(cursorEntity.getMaterial() == activeCursorMaterial) {
|
} else if (cursorEntity.getMaterial() == activeCursorMaterial) {
|
||||||
cursorEntity.move(activeCursorLocation);
|
cursorEntity.move(activeCursorLocation);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
cursorEntity.die();
|
cursorEntity.die();
|
||||||
cursorEntity = new RFallingBlockEntity(targetServer, activeCursorLocation, activeCursorMaterial);
|
cursorEntity = new RFallingBlockEntity(targetServer, activeCursorLocation, activeCursorMaterial);
|
||||||
|
cursorEntity.setNoGravity(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void hide() {
|
||||||
|
if (cursorEntity != null) {
|
||||||
|
cursorEntity.die();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
package de.steamwar.bausystem.utils.cursor;
|
||||||
|
|
||||||
|
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||||
|
import de.steamwar.Reflection;
|
||||||
|
import de.steamwar.bausystem.BauSystem;
|
||||||
|
import de.steamwar.linkage.Linked;
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.lang.ref.SoftReference;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
|
@Linked
|
||||||
|
public class RCursorManager {
|
||||||
|
@Getter
|
||||||
|
private static RCursorManager instance;
|
||||||
|
|
||||||
|
private final Set<Player> calculationActive = new HashSet<>();
|
||||||
|
private final Map<Player, SoftReference<RCursor>> activeCursors = new HashMap<>();
|
||||||
|
|
||||||
|
public RCursorManager() {
|
||||||
|
if (instance == null) {
|
||||||
|
instance = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BiFunction<Player, Object, Object> function = (player, object) -> {
|
||||||
|
updateCursor(player);
|
||||||
|
return object;
|
||||||
|
};
|
||||||
|
|
||||||
|
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
||||||
|
Set<Player> playersWithActiveCursor = activeCursors.keySet();
|
||||||
|
|
||||||
|
playersWithActiveCursor.forEach(this::updateCursor);
|
||||||
|
}, 0);
|
||||||
|
|
||||||
|
Class<?> positionPacketClass = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundMovePlayerPacket$Pos");
|
||||||
|
Class<?> lookPacketClass = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundMovePlayerPacket$Rot");
|
||||||
|
Class<?> positionLookPacketClass = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundMovePlayerPacket$PosRot");
|
||||||
|
|
||||||
|
TinyProtocol.instance.addFilter(positionPacketClass, function);
|
||||||
|
TinyProtocol.instance.addFilter(lookPacketClass, function);
|
||||||
|
TinyProtocol.instance.addFilter(positionLookPacketClass, function);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void registerCursor(RCursor cursor) {
|
||||||
|
activeCursors.put(cursor.getOwner(), new SoftReference<>(cursor));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateCursor(Player player) {
|
||||||
|
synchronized (calculationActive) {
|
||||||
|
if (calculationActive.contains(player)) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
calculationActive.add(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SoftReference<RCursor> cursorRef = activeCursors.get(player);
|
||||||
|
RCursor cursor = cursorRef.get();
|
||||||
|
|
||||||
|
if (cursor == null) {
|
||||||
|
activeCursors.remove(player);
|
||||||
|
} else {
|
||||||
|
cursor.render();
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized (calculationActive) {
|
||||||
|
calculationActive.remove(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user