SteamWar/BauSystem2.0
Archiviert
12
0

Add TraceTNTClickListener
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful

Signed-off-by: yoyosource <yoyosource@nidido.de>
Dieser Commit ist enthalten in:
yoyosource 2022-08-06 17:24:48 +02:00
Ursprung 3be33adb00
Commit b22fabe8cd
8 geänderte Dateien mit 222 neuen und 39 gelöschten Zeilen

Datei anzeigen

@ -25,6 +25,7 @@ import de.steamwar.bausystem.features.simulator.gui.SimulatorSelectionGUI;
import de.steamwar.bausystem.linkage.LinkageType; import de.steamwar.bausystem.linkage.LinkageType;
import de.steamwar.bausystem.linkage.Linked; import de.steamwar.bausystem.linkage.Linked;
import de.steamwar.bausystem.utils.ItemUtils; import de.steamwar.bausystem.utils.ItemUtils;
import de.steamwar.bausystem.utils.RayTraceUtils;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.FluidCollisionMode; import org.bukkit.FluidCollisionMode;
import org.bukkit.GameMode; import org.bukkit.GameMode;
@ -56,41 +57,7 @@ public class TNTSimulatorListener implements Listener {
} }
static RayTraceResult trace(Player player, Location to, TNTSimulator simulator) { static RayTraceResult trace(Player player, Location to, TNTSimulator simulator) {
if (player.getGameMode() == GameMode.SPECTATOR) { return RayTraceUtils.trace(player, to, simulator.getEntities());
return null;
}
Location startPos = to.clone().add(0.0, player.getEyeHeight(), 0.0);
Vector direction = to.getDirection();
RayTraceResult blocks = player.getWorld().rayTraceBlocks(startPos, direction, 10.0, FluidCollisionMode.NEVER, true);
Entity nearestHitEntity = null;
RayTraceResult nearestHitResult = null;
double nearestDistanceSq = Double.MAX_VALUE;
for (Entity entity : simulator.getEntities()) {
BoundingBox boundingBox = entity.getBoundingBox();
RayTraceResult hitResult = boundingBox.rayTrace(startPos.toVector(), direction, 10.0);
if (hitResult != null) {
double distanceSq = startPos.toVector().distanceSquared(hitResult.getHitPosition());
if (distanceSq < nearestDistanceSq) {
nearestHitEntity = entity;
nearestHitResult = hitResult;
nearestDistanceSq = distanceSq;
}
}
}
RayTraceResult entities = nearestHitEntity == null ? null : new RayTraceResult(nearestHitResult.getHitPosition(), nearestHitEntity, nearestHitResult.getHitBlockFace());
if (blocks == null) {
return entities;
} else if (entities == null) {
return blocks;
} else {
Vector startVec = startPos.toVector();
double blockHitDistance = startVec.distance(blocks.getHitPosition());
double entityHitDistanceSquared = startVec.distanceSquared(entities.getHitPosition());
return entityHitDistanceSquared < blockHitDistance * blockHitDistance ? entities : blocks;
}
} }
@EventHandler @EventHandler

Datei anzeigen

@ -20,6 +20,7 @@
package de.steamwar.bausystem.features.tracer; package de.steamwar.bausystem.features.tracer;
import de.steamwar.bausystem.shared.AbstractEntity; import de.steamwar.bausystem.shared.AbstractEntity;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
public interface AbstractTraceEntity extends AbstractEntity { public interface AbstractTraceEntity extends AbstractEntity {
@ -27,4 +28,6 @@ public interface AbstractTraceEntity extends AbstractEntity {
void display(Player player, boolean exploded, int ticks); void display(Player player, boolean exploded, int ticks);
boolean hide(Player player, boolean always); boolean hide(Player player, boolean always);
Entity getBukkitEntity();
} }

Datei anzeigen

@ -0,0 +1,66 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2022 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.tracer;
import com.comphenix.tinyprotocol.Reflection;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.features.tracer.show.TraceShowManager;
import de.steamwar.bausystem.linkage.LinkageType;
import de.steamwar.bausystem.linkage.Linked;
import de.steamwar.bausystem.utils.ProtocolAPI;
import de.steamwar.bausystem.utils.RayTraceUtils;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.util.RayTraceResult;
import java.util.HashSet;
import java.util.Set;
@Linked(LinkageType.PLAIN)
public class TraceTNTClickListener {
private static final Class<?> useEntity = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInUseEntity");
{
Set<Player> playerSet = new HashSet<>();
ProtocolAPI.setIncomingHandler(useEntity, (player, o) -> {
if (!playerSet.add(player)) return o;
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
RayTraceResult rayTraceResult = RayTraceUtils.trace(player, player.getLocation(), TraceShowManager.getEntities(player));
if (rayTraceResult == null) return;
if (rayTraceResult.getHitEntity() == null) return;
TNTPosition tntPosition = TraceShowManager.getTNTPosition(player, rayTraceResult.getHitEntity());
if (tntPosition == null) return;
BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_HEADER", player);
BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_FUSE_TIME", player, tntPosition.getFuseTicks());
BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_POSITION_X", player, tntPosition.getLocation().getX() + "");
BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_POSITION_Y", player, tntPosition.getLocation().getY() + "");
BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_POSITION_Z", player, tntPosition.getLocation().getZ() + "");
BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_VELOCITY_X", player, tntPosition.getVelocity().getX() + "");
BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_VELOCITY_Y", player, tntPosition.getVelocity().getY() + "");
BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_VELOCITY_Z", player, tntPosition.getVelocity().getZ() + "");
playerSet.remove(player);
}, 1);
return o;
});
}
}

Datei anzeigen

@ -0,0 +1,31 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2022 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.tracer.show;
import de.steamwar.bausystem.features.tracer.TNTPosition;
import de.steamwar.bausystem.shared.ShowMode;
import org.bukkit.entity.Entity;
import java.util.List;
public interface EntityTraceShowMode extends ShowMode<TNTPosition> {
List<Entity> getEntities();
TNTPosition getTNTPosition(Entity entity);
}

Datei anzeigen

@ -4,12 +4,15 @@ import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.features.tracer.TNTPosition; import de.steamwar.bausystem.features.tracer.TNTPosition;
import de.steamwar.bausystem.shared.ShowMode; import de.steamwar.bausystem.shared.ShowMode;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerQuitEvent;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
public class TraceShowManager implements Listener { public class TraceShowManager implements Listener {
@ -31,6 +34,28 @@ public class TraceShowManager implements Listener {
traceShowMode.hide(); traceShowMode.hide();
} }
public static List<Entity> getEntities(Player player) {
ShowMode<TNTPosition> showMode = showModes.get(player);
if (showMode == null) {
return Collections.emptyList();
}
if (showMode instanceof EntityTraceShowMode) {
return ((EntityTraceShowMode) showMode).getEntities();
}
return Collections.emptyList();
}
public static TNTPosition getTNTPosition(Player player, Entity entity) {
ShowMode<TNTPosition> showMode = showModes.get(player);
if (showMode == null) {
return null;
}
if (showMode instanceof EntityTraceShowMode) {
return ((EntityTraceShowMode) showMode).getTNTPosition(entity);
}
return null;
}
public static void reshow() { public static void reshow() {
Map<Player, ShowMode<TNTPosition>> current = new HashMap<>(showModes); Map<Player, ShowMode<TNTPosition>> current = new HashMap<>(showModes);
current.forEach(TraceShowManager::show); current.forEach(TraceShowManager::show);

Datei anzeigen

@ -21,19 +21,22 @@ package de.steamwar.bausystem.features.tracer.show.mode;
import de.steamwar.bausystem.features.tracer.AbstractTraceEntity; import de.steamwar.bausystem.features.tracer.AbstractTraceEntity;
import de.steamwar.bausystem.features.tracer.TNTPosition; import de.steamwar.bausystem.features.tracer.TNTPosition;
import de.steamwar.bausystem.features.tracer.show.EntityTraceShowMode;
import de.steamwar.bausystem.features.tracer.show.ShowModeParameter; import de.steamwar.bausystem.features.tracer.show.ShowModeParameter;
import de.steamwar.bausystem.shared.RoundedPosition; import de.steamwar.bausystem.shared.RoundedPosition;
import de.steamwar.bausystem.shared.ShowMode;
import de.steamwar.bausystem.utils.FlatteningWrapper; import de.steamwar.bausystem.utils.FlatteningWrapper;
import de.steamwar.bausystem.utils.NMSWrapper; import de.steamwar.bausystem.utils.NMSWrapper;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.util.Consumer; import org.bukkit.util.Consumer;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
public abstract class FactoredEntityShowMode implements ShowMode<TNTPosition> { public abstract class FactoredEntityShowMode implements EntityTraceShowMode {
private int factor; private int factor;
@ -42,6 +45,7 @@ public abstract class FactoredEntityShowMode implements ShowMode<TNTPosition> {
private final Map<RoundedPosition, AbstractTraceEntity> tntEntityMap = new HashMap<>(); private final Map<RoundedPosition, AbstractTraceEntity> tntEntityMap = new HashMap<>();
private final Map<RoundedPosition, AbstractTraceEntity> updateEntityMap = new HashMap<>(); private final Map<RoundedPosition, AbstractTraceEntity> updateEntityMap = new HashMap<>();
private final Map<Entity, TNTPosition> tntPositionMap = new HashMap<>();
protected FactoredEntityShowMode(Player player, ShowModeParameter showModeParameter, int factor) { protected FactoredEntityShowMode(Player player, ShowModeParameter showModeParameter, int factor) {
this.player = player; this.player = player;
@ -57,6 +61,7 @@ public abstract class FactoredEntityShowMode implements ShowMode<TNTPosition> {
} }
RoundedPosition roundedPosition = new RoundedPosition(position, factor); RoundedPosition roundedPosition = new RoundedPosition(position, factor);
AbstractTraceEntity entity = tntEntityMap.computeIfAbsent(roundedPosition, pos -> createEntity(player, position.getLocation(), true)); AbstractTraceEntity entity = tntEntityMap.computeIfAbsent(roundedPosition, pos -> createEntity(player, position.getLocation(), true));
tntPositionMap.put(entity.getBukkitEntity(), position);
entity.display(player, position.isExploded(), showModeParameter.isTicks() ? position.getFuseTicks() : -1); entity.display(player, position.isExploded(), showModeParameter.isTicks() ? position.getFuseTicks() : -1);
return; return;
} }
@ -81,6 +86,7 @@ public abstract class FactoredEntityShowMode implements ShowMode<TNTPosition> {
RoundedPosition roundedPosition = new RoundedPosition(position, factor); RoundedPosition roundedPosition = new RoundedPosition(position, factor);
AbstractTraceEntity entity = tntEntityMap.computeIfAbsent(roundedPosition, pos -> createEntity(player, position.getLocation(), true)); AbstractTraceEntity entity = tntEntityMap.computeIfAbsent(roundedPosition, pos -> createEntity(player, position.getLocation(), true));
tntPositionMap.put(entity.getBukkitEntity(), position);
entity.display(player, position.isExploded(), showModeParameter.isTicks() ? position.getFuseTicks() : -1); entity.display(player, position.isExploded(), showModeParameter.isTicks() ? position.getFuseTicks() : -1);
applyOnPosition(position, updatePointPosition -> { applyOnPosition(position, updatePointPosition -> {
@ -120,9 +126,20 @@ public abstract class FactoredEntityShowMode implements ShowMode<TNTPosition> {
@Override @Override
public void hide() { public void hide() {
tntPositionMap.clear();
tntEntityMap.forEach((roundedPosition, abstractTraceEntity) -> abstractTraceEntity.hide(player, true)); tntEntityMap.forEach((roundedPosition, abstractTraceEntity) -> abstractTraceEntity.hide(player, true));
tntEntityMap.clear(); tntEntityMap.clear();
updateEntityMap.forEach((roundedPosition, abstractTraceEntity) -> abstractTraceEntity.hide(player, true)); updateEntityMap.forEach((roundedPosition, abstractTraceEntity) -> abstractTraceEntity.hide(player, true));
updateEntityMap.clear(); updateEntityMap.clear();
} }
@Override
public List<Entity> getEntities() {
return new ArrayList<>(tntPositionMap.keySet());
}
@Override
public TNTPosition getTNTPosition(Entity entity) {
return tntPositionMap.get(entity);
}
} }

Datei anzeigen

@ -49,8 +49,8 @@ public class TNTClickListener implements Listener {
BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_POSITION_Y", event.getPlayer(), tntPrimed.getLocation().getY() + ""); BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_POSITION_Y", event.getPlayer(), tntPrimed.getLocation().getY() + "");
BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_POSITION_Z", event.getPlayer(), tntPrimed.getLocation().getZ() + ""); BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_POSITION_Z", event.getPlayer(), tntPrimed.getLocation().getZ() + "");
BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_VELOCITY_X", event.getPlayer(), tntPrimed.getVelocity().getX() + ""); BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_VELOCITY_X", event.getPlayer(), tntPrimed.getVelocity().getX() + "");
BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_VELOCITY_Y", event.getPlayer(), tntPrimed.getVelocity().getX() + ""); BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_VELOCITY_Y", event.getPlayer(), tntPrimed.getVelocity().getY() + "");
BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_VELOCITY_Z", event.getPlayer(), tntPrimed.getVelocity().getX() + ""); BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_VELOCITY_Z", event.getPlayer(), tntPrimed.getVelocity().getZ() + "");
BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_COUNT", event.getPlayer(), count + ""); BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_COUNT", event.getPlayer(), count + "");
} }
} }

Datei anzeigen

@ -0,0 +1,74 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2022 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.utils;
import lombok.experimental.UtilityClass;
import org.bukkit.FluidCollisionMode;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.util.BoundingBox;
import org.bukkit.util.RayTraceResult;
import org.bukkit.util.Vector;
import java.util.List;
@UtilityClass
public class RayTraceUtils {
public static RayTraceResult trace(Player player, Location to, List<Entity> entityList) {
if (player.getGameMode() == GameMode.SPECTATOR) {
return null;
}
Location startPos = to.clone().add(0.0, player.getEyeHeight(), 0.0);
Vector direction = to.getDirection();
RayTraceResult blocks = player.getWorld().rayTraceBlocks(startPos, direction, 10.0, FluidCollisionMode.NEVER, true);
Entity nearestHitEntity = null;
RayTraceResult nearestHitResult = null;
double nearestDistanceSq = Double.MAX_VALUE;
for (Entity entity : entityList) {
BoundingBox boundingBox = entity.getBoundingBox();
RayTraceResult hitResult = boundingBox.rayTrace(startPos.toVector(), direction, 10.0);
if (hitResult != null) {
double distanceSq = startPos.toVector().distanceSquared(hitResult.getHitPosition());
if (distanceSq < nearestDistanceSq) {
nearestHitEntity = entity;
nearestHitResult = hitResult;
nearestDistanceSq = distanceSq;
}
}
}
RayTraceResult entities = nearestHitEntity == null ? null : new RayTraceResult(nearestHitResult.getHitPosition(), nearestHitEntity, nearestHitResult.getHitBlockFace());
if (blocks == null) {
return entities;
} else if (entities == null) {
return blocks;
} else {
Vector startVec = startPos.toVector();
double blockHitDistance = startVec.distance(blocks.getHitPosition());
double entityHitDistanceSquared = startVec.distanceSquared(entities.getHitPosition());
return entityHitDistanceSquared < blockHitDistance * blockHitDistance ? entities : blocks;
}
}
}