2021-08-31 10:42:42 +02:00
|
|
|
/*
|
2020-08-26 18:24:44 +02:00
|
|
|
This file is a part of the SteamWar software.
|
2021-08-31 10:42:42 +02:00
|
|
|
|
|
|
|
Copyright (C) 2021 SteamWar.de-Serverteam
|
2020-08-26 18:24:44 +02:00
|
|
|
|
|
|
|
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/>.
|
2021-08-31 10:42:42 +02:00
|
|
|
*/
|
2020-08-26 18:24:44 +02:00
|
|
|
|
2021-08-31 10:42:42 +02:00
|
|
|
package de.steamwar.fightsystem.utils;
|
2019-12-27 11:05:12 +01:00
|
|
|
|
2021-09-18 14:30:32 +02:00
|
|
|
import com.comphenix.tinyprotocol.Reflection;
|
2021-09-30 17:32:32 +02:00
|
|
|
import de.steamwar.fightsystem.fight.Fight;
|
|
|
|
import de.steamwar.fightsystem.fight.FightTeam;
|
2021-08-31 12:09:34 +02:00
|
|
|
import de.steamwar.fightsystem.listener.Recording;
|
|
|
|
import de.steamwar.fightsystem.record.GlobalRecorder;
|
2021-09-28 13:08:10 +02:00
|
|
|
import de.steamwar.fightsystem.record.REntity;
|
2021-09-30 17:32:32 +02:00
|
|
|
import org.bukkit.*;
|
2019-12-27 11:05:12 +01:00
|
|
|
import org.bukkit.attribute.Attribute;
|
|
|
|
import org.bukkit.attribute.AttributeInstance;
|
2021-09-30 17:32:32 +02:00
|
|
|
import org.bukkit.boss.BarColor;
|
|
|
|
import org.bukkit.boss.BarStyle;
|
|
|
|
import org.bukkit.boss.BossBar;
|
2019-12-27 11:05:12 +01:00
|
|
|
import org.bukkit.entity.Player;
|
2021-08-31 11:19:56 +02:00
|
|
|
import org.bukkit.event.EventHandler;
|
2021-08-31 12:09:34 +02:00
|
|
|
import org.bukkit.event.EventPriority;
|
2021-08-31 11:19:56 +02:00
|
|
|
import org.bukkit.event.Listener;
|
|
|
|
import org.bukkit.event.player.PlayerPickupArrowEvent;
|
|
|
|
import org.bukkit.event.player.PlayerSwapHandItemsEvent;
|
2021-08-31 10:42:42 +02:00
|
|
|
import org.bukkit.scoreboard.Team;
|
2019-12-27 11:05:12 +01:00
|
|
|
|
2021-09-28 13:08:10 +02:00
|
|
|
import java.lang.reflect.Field;
|
|
|
|
import java.lang.reflect.ParameterizedType;
|
2021-10-01 11:53:41 +02:00
|
|
|
import java.util.HashMap;
|
|
|
|
import java.util.Map;
|
2021-09-28 13:08:10 +02:00
|
|
|
import java.util.UUID;
|
|
|
|
|
2021-08-31 10:42:42 +02:00
|
|
|
public class BountifulWrapper9 implements BountifulWrapper.IBountifulWrapper {
|
2021-09-18 14:30:32 +02:00
|
|
|
|
|
|
|
private static final Class<?> enumHand = Reflection.getClass("{nms}.EnumHand");
|
|
|
|
private static final Object mainHand = enumHand.getEnumConstants()[0];
|
|
|
|
private static final Reflection.FieldAccessor<?> blockPlaceHand = Reflection.getField(Recording.blockPlacePacket, enumHand, 0);
|
|
|
|
|
2021-10-01 11:53:41 +02:00
|
|
|
public BountifulWrapper9() {
|
|
|
|
for(FightUI.BossBarType type : FightUI.BossBarType.values()) {
|
|
|
|
barMap.put(type, Bukkit.createBossBar(type.name(), BarColor.WHITE, BarStyle.SOLID));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-18 14:30:32 +02:00
|
|
|
@Override
|
|
|
|
public boolean mainHand(Object packet) {
|
|
|
|
return blockPlaceHand.get(packet) == mainHand;
|
|
|
|
}
|
|
|
|
|
2021-08-31 10:42:42 +02:00
|
|
|
@Override
|
2021-09-18 14:30:32 +02:00
|
|
|
public boolean bowInHand(boolean mainHand, Player p) {
|
|
|
|
return (mainHand ? p.getInventory().getItemInMainHand() : p.getInventory().getItemInOffHand()).getType() == Material.BOW;
|
2021-08-31 10:42:42 +02:00
|
|
|
}
|
2019-12-27 11:05:12 +01:00
|
|
|
|
2021-08-31 10:42:42 +02:00
|
|
|
@Override
|
|
|
|
public void setAttackSpeed(Player player) {
|
2019-12-27 11:05:12 +01:00
|
|
|
AttributeInstance attribute = player.getAttribute(Attribute.GENERIC_ATTACK_SPEED);
|
|
|
|
attribute.setBaseValue(16);
|
|
|
|
}
|
2021-08-31 10:42:42 +02:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public void setNametagVisibility(Team team) {
|
|
|
|
team.setOption(Team.Option.NAME_TAG_VISIBILITY, Team.OptionStatus.FOR_OWN_TEAM);
|
|
|
|
}
|
2021-08-31 11:19:56 +02:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public Listener newDenyArrowPickupListener() {
|
|
|
|
return new Listener() {
|
|
|
|
@EventHandler
|
|
|
|
public void onArrowPickup(PlayerPickupArrowEvent e){
|
|
|
|
e.setCancelled(true);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Listener newDenyHandSwapListener() {
|
|
|
|
return new Listener() {
|
|
|
|
@EventHandler
|
|
|
|
public void onSwapItems(PlayerSwapHandItemsEvent event) {
|
|
|
|
event.setCancelled(true);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
2021-08-31 12:09:34 +02:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public void recordHandItems(Player player) {
|
|
|
|
GlobalRecorder.getInstance().item(player, Recording.disarmNull(player.getInventory().getItemInMainHand()), "MAINHAND");
|
|
|
|
GlobalRecorder.getInstance().item(player, Recording.disarmNull(player.getInventory().getItemInOffHand()), "OFFHAND");
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Listener newHandSwapRecorder() {
|
|
|
|
return new Listener() {
|
|
|
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
|
|
|
public void onItemSwap(PlayerSwapHandItemsEvent e){
|
|
|
|
if(Recording.isNotSent(e.getPlayer()))
|
|
|
|
return;
|
|
|
|
|
|
|
|
Player player = e.getPlayer();
|
|
|
|
GlobalRecorder.getInstance().item(player, Recording.disarmNull(e.getMainHandItem()), "MAINHAND");
|
|
|
|
GlobalRecorder.getInstance().item(player, Recording.disarmNull(e.getOffHandItem()), "OFFHAND");
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void spawnParticle(World world, String particleName, double x, double y, double z) {
|
|
|
|
world.spawnParticle(Particle.valueOf(particleName), x, y, z, 1);
|
|
|
|
}
|
2021-09-28 13:08:10 +02:00
|
|
|
|
|
|
|
|
|
|
|
private static final Class<?> dataWatcherObject = Reflection.getClass("{nms}.DataWatcherObject");
|
|
|
|
private static final Class<?> dataWatcherRegistry = Reflection.getClass("{nms}.DataWatcherRegistry");
|
|
|
|
private static final Class<?> dataWatcherSerializer = Reflection.getClass("{nms}.DataWatcherSerializer");
|
|
|
|
private static final Reflection.ConstructorInvoker dataWatcherObjectConstructor = Reflection.getConstructor(dataWatcherObject, int.class, dataWatcherSerializer);
|
|
|
|
@Override
|
|
|
|
public Object getDataWatcherObject(int index, Class<?> type) {
|
2021-09-28 18:25:45 +02:00
|
|
|
for(Field field : dataWatcherRegistry.getFields()) {
|
|
|
|
if(dataWatcherSerializer.isAssignableFrom(field.getType()) && type.equals(((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0])) {
|
2021-09-28 13:08:10 +02:00
|
|
|
try {
|
|
|
|
return dataWatcherObjectConstructor.invoke(index, field.get(null));
|
|
|
|
} catch (IllegalAccessException e) {
|
|
|
|
throw new SecurityException("Could not get field", e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
throw new SecurityException("Could not find Serializer for " + type.getName());
|
|
|
|
}
|
|
|
|
|
2021-09-28 18:25:45 +02:00
|
|
|
private static final Class<?> item = Reflection.getClass("{nms}.DataWatcher$Item");
|
2021-09-28 13:08:10 +02:00
|
|
|
private static final Reflection.ConstructorInvoker itemConstructor = Reflection.getConstructor(item, dataWatcherObject, Object.class);
|
|
|
|
@Override
|
|
|
|
public Object getDataWatcherItem(Object dwo, Object value) {
|
|
|
|
return itemConstructor.invoke(dwo, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
private static final Reflection.FieldAccessor<Double> teleportX = Reflection.getField(REntity.teleportPacket, double.class, 0);
|
|
|
|
private static final Reflection.FieldAccessor<Double> teleportY = Reflection.getField(REntity.teleportPacket, double.class, 1);
|
|
|
|
private static final Reflection.FieldAccessor<Double> teleportZ = Reflection.getField(REntity.teleportPacket, double.class, 2);
|
|
|
|
@Override
|
|
|
|
public void setTeleportPacketPosition(Object packet, double x, double y, double z) {
|
|
|
|
teleportX.set(packet, x);
|
|
|
|
teleportY.set(packet, y);
|
|
|
|
teleportZ.set(packet, z);
|
|
|
|
}
|
|
|
|
|
|
|
|
private static final Reflection.FieldAccessor<UUID> spawnUUID = Reflection.getField(REntity.spawnPacket, UUID.class, 0);
|
|
|
|
@Override
|
|
|
|
public void setSpawnPacketUUID(Object packet, UUID uuid) {
|
|
|
|
spawnUUID.set(packet, uuid);
|
|
|
|
}
|
|
|
|
|
|
|
|
private static final Class<?> enumItemSlot = Reflection.getClass("{nms}.EnumItemSlot");
|
2021-09-28 18:25:45 +02:00
|
|
|
private static final Reflection.FieldAccessor<?> equipmentSlot = Reflection.getField(REntity.equipmentPacket, enumItemSlot, 0);
|
2021-09-28 13:08:10 +02:00
|
|
|
private static final Object[] itemSlots = enumItemSlot.getEnumConstants();
|
|
|
|
@Override
|
|
|
|
public void setEquipmentPacketSlot(Object packet, String slot) {
|
|
|
|
switch(slot){
|
|
|
|
case "HEAD":
|
|
|
|
equipmentSlot.set(packet, itemSlots[5]);
|
|
|
|
break;
|
|
|
|
case "CHEST":
|
|
|
|
equipmentSlot.set(packet, itemSlots[4]);
|
|
|
|
break;
|
|
|
|
case "LEGS":
|
|
|
|
equipmentSlot.set(packet, itemSlots[3]);
|
|
|
|
break;
|
|
|
|
case "FEET":
|
|
|
|
equipmentSlot.set(packet, itemSlots[2]);
|
|
|
|
break;
|
|
|
|
case "OFFHAND":
|
|
|
|
equipmentSlot.set(packet, itemSlots[1]);
|
|
|
|
break;
|
|
|
|
case "MAINHAND":
|
|
|
|
default:
|
|
|
|
equipmentSlot.set(packet, itemSlots[0]);
|
|
|
|
}
|
|
|
|
}
|
2021-09-30 17:32:32 +02:00
|
|
|
|
2021-10-01 11:53:41 +02:00
|
|
|
private final Map<FightUI.BossBarType, BossBar> barMap = new HashMap<>();
|
2021-09-30 17:32:32 +02:00
|
|
|
@Override
|
|
|
|
public void setBossbar(double leftBlueProgress, double leftRedProgress, String leftBlueText, String leftRedText) {
|
2021-10-01 11:53:41 +02:00
|
|
|
setupTeamBar(Fight.getBlueTeam(), barMap.get(FightUI.BossBarType.BLUE_LEFT), leftBlueProgress, leftBlueText);
|
|
|
|
setupTeamBar(Fight.getRedTeam(), barMap.get(FightUI.BossBarType.RED_LEFT), leftRedProgress, leftRedText);
|
2021-09-30 17:32:32 +02:00
|
|
|
}
|
|
|
|
|
2021-10-01 11:53:41 +02:00
|
|
|
private void setupTeamBar(FightTeam team, BossBar bar, double progress, String title) {
|
2021-09-30 17:32:32 +02:00
|
|
|
BarColor color = chat2bar(team.getColor());
|
|
|
|
if(bar.getColor() != color)
|
|
|
|
bar.setColor(color);
|
|
|
|
|
|
|
|
if(bar.getProgress() != progress)
|
|
|
|
bar.setProgress(progress);
|
2021-10-01 11:53:41 +02:00
|
|
|
|
|
|
|
bar.setTitle(title);
|
2021-09-30 17:32:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
private BarColor chat2bar(ChatColor color) {
|
|
|
|
switch(color) {
|
|
|
|
case DARK_BLUE:
|
|
|
|
case DARK_AQUA:
|
|
|
|
case BLUE:
|
|
|
|
case AQUA:
|
|
|
|
return BarColor.BLUE;
|
|
|
|
case GREEN:
|
|
|
|
case DARK_GREEN:
|
|
|
|
return BarColor.GREEN;
|
|
|
|
case DARK_RED:
|
|
|
|
case RED:
|
|
|
|
return BarColor.RED;
|
|
|
|
case DARK_PURPLE:
|
|
|
|
return BarColor.PURPLE;
|
|
|
|
case GOLD:
|
|
|
|
case YELLOW:
|
|
|
|
return BarColor.YELLOW;
|
|
|
|
case LIGHT_PURPLE:
|
|
|
|
return BarColor.PINK;
|
|
|
|
case BLACK:
|
|
|
|
case WHITE:
|
|
|
|
case GRAY:
|
|
|
|
case DARK_GRAY:
|
|
|
|
default:
|
|
|
|
return BarColor.WHITE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2021-10-01 11:53:41 +02:00
|
|
|
public void removeFromBar(Player player, FightUI.BossBarType type) {
|
|
|
|
barMap.get(type).removePlayer(player);
|
2021-09-30 17:32:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2021-10-01 11:53:41 +02:00
|
|
|
public void addToBar(Player player, FightUI.BossBarType type) {
|
|
|
|
barMap.get(type).addPlayer(player);
|
2021-09-30 17:32:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void broadcastBossbar() {
|
|
|
|
// Handled by Spigot BossBarAPI
|
|
|
|
}
|
2019-12-27 11:05:12 +01:00
|
|
|
}
|