mirror of
https://github.com/HibiscusMC/HMCCosmetics.git
synced 2025-12-23 00:49:28 +00:00
Changed to use PacketEvents
This commit is contained in:
@@ -7,7 +7,7 @@ repositories {
|
|||||||
maven("https://papermc.io/repo/repository/maven-public/")
|
maven("https://papermc.io/repo/repository/maven-public/")
|
||||||
maven("https://oss.sonatype.org/content/repositories/snapshots")
|
maven("https://oss.sonatype.org/content/repositories/snapshots")
|
||||||
maven("https://jitpack.io")
|
maven("https://jitpack.io")
|
||||||
maven("https://repo.dmulloy2.net/repository/public/")
|
// maven("https://repo.dmulloy2.net/repository/public/")
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@@ -15,5 +15,5 @@ dependencies {
|
|||||||
compileOnly("com.mojang:authlib:1.5.25")
|
compileOnly("com.mojang:authlib:1.5.25")
|
||||||
compileOnly("org.spigotmc:spigot:1.16.5-R0.1-SNAPSHOT")
|
compileOnly("org.spigotmc:spigot:1.16.5-R0.1-SNAPSHOT")
|
||||||
compileOnly("org.jetbrains:annotations:22.0.0")
|
compileOnly("org.jetbrains:annotations:22.0.0")
|
||||||
compileOnly("com.comphenix.protocol:ProtocolLib:4.7.0")
|
// compileOnly("com.comphenix.protocol:ProtocolLib:4.7.0")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
package io.github.fisher2911.nms;
|
|
||||||
|
|
||||||
import com.comphenix.protocol.PacketType;
|
|
||||||
import com.comphenix.protocol.events.PacketContainer;
|
|
||||||
import com.comphenix.protocol.wrappers.WrappedDataWatcher;
|
|
||||||
|
|
||||||
public class ArmorStandPackets_1_16_R3 {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
package io.github.fisher2911.nms;
|
|
||||||
|
|
||||||
import com.comphenix.protocol.PacketType;
|
|
||||||
import com.comphenix.protocol.events.PacketContainer;
|
|
||||||
|
|
||||||
public class DestroyPacket_1_16_R3 {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,139 +1,120 @@
|
|||||||
package io.github.fisher2911.nms;
|
package io.github.fisher2911.nms;
|
||||||
|
|
||||||
import com.comphenix.protocol.PacketType;
|
|
||||||
import com.comphenix.protocol.events.PacketContainer;
|
|
||||||
import com.comphenix.protocol.reflect.StructureModifier;
|
|
||||||
import com.comphenix.protocol.wrappers.EnumWrappers;
|
|
||||||
import com.comphenix.protocol.wrappers.PlayerInfoData;
|
|
||||||
import com.comphenix.protocol.wrappers.WrappedChatComponent;
|
|
||||||
import com.comphenix.protocol.wrappers.WrappedDataWatcher;
|
|
||||||
import com.comphenix.protocol.wrappers.WrappedGameProfile;
|
|
||||||
import com.mojang.authlib.GameProfile;
|
|
||||||
import com.mojang.authlib.properties.Property;
|
|
||||||
import org.bukkit.GameMode;
|
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.craftbukkit.v1_16_R3.entity.CraftPlayer;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class PacketHelper_1_16_R3 implements PacketHelper {
|
public class PacketHelper_1_16_R3 implements PacketHelper {
|
||||||
|
|
||||||
@Override
|
// @Override
|
||||||
public PacketContainer getPlayerSpawnPacket(final Location location, UUID uuid, final int entityId) {
|
// public PacketContainer getPlayerSpawnPacket(final Location location, UUID uuid, final int entityId) {
|
||||||
final PacketContainer spawnPacket = new PacketContainer(PacketType.Play.Server.NAMED_ENTITY_SPAWN);
|
// final PacketContainer spawnPacket = new PacketContainer(PacketType.Play.Server.NAMED_ENTITY_SPAWN);
|
||||||
spawnPacket.getUUIDs().write(0, uuid);
|
// spawnPacket.getUUIDs().write(0, uuid);
|
||||||
spawnPacket.getIntegers().write(0, entityId);
|
// spawnPacket.getIntegers().write(0, entityId);
|
||||||
spawnPacket.getDoubles().
|
// spawnPacket.getDoubles().
|
||||||
write(0, location.getX()).
|
// write(0, location.getX()).
|
||||||
write(1, location.getY()).
|
// write(1, location.getY()).
|
||||||
write(2, location.getZ());
|
// write(2, location.getZ());
|
||||||
spawnPacket.getBytes().write(0, (byte)(((location.getYaw() * 256.0F) / 360.0F)));
|
// spawnPacket.getBytes().write(0, (byte)(((location.getYaw() * 256.0F) / 360.0F)));
|
||||||
|
//
|
||||||
return spawnPacket;
|
// return spawnPacket;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public PacketContainer getPlayerInfoPacket(final Player player, final UUID uuid) {
|
// public PacketContainer getPlayerInfoPacket(final Player player, final UUID uuid) {
|
||||||
final GameProfile profile = this.getCopyProfile(player, uuid);
|
// final GameProfile profile = this.getCopyProfile(player, uuid);
|
||||||
final PacketContainer playerInfoPacket = new PacketContainer(PacketType.Play.Server.PLAYER_INFO);
|
// final PacketContainer playerInfoPacket = new PacketContainer(PacketType.Play.Server.PLAYER_INFO);
|
||||||
final StructureModifier<EnumWrappers.PlayerInfoAction> action = playerInfoPacket.getPlayerInfoAction();
|
// final StructureModifier<EnumWrappers.PlayerInfoAction> action = playerInfoPacket.getPlayerInfoAction();
|
||||||
final StructureModifier<List<PlayerInfoData>> infoData = playerInfoPacket.getPlayerInfoDataLists();
|
// final StructureModifier<List<PlayerInfoData>> infoData = playerInfoPacket.getPlayerInfoDataLists();
|
||||||
|
//
|
||||||
final List<PlayerInfoData> playerInfoData = new ArrayList<>();
|
// final List<PlayerInfoData> playerInfoData = new ArrayList<>();
|
||||||
|
//
|
||||||
playerInfoData.add(new PlayerInfoData(WrappedGameProfile
|
// playerInfoData.add(new PlayerInfoData(WrappedGameProfile
|
||||||
.fromHandle(profile),
|
// .fromHandle(profile),
|
||||||
0,
|
// 0,
|
||||||
EnumWrappers.NativeGameMode.fromBukkit(GameMode.CREATIVE),
|
// EnumWrappers.NativeGameMode.fromBukkit(GameMode.CREATIVE),
|
||||||
WrappedChatComponent.fromText(profile.getName())));
|
// WrappedChatComponent.fromText(profile.getName())));
|
||||||
|
//
|
||||||
action.write(0, EnumWrappers.PlayerInfoAction.ADD_PLAYER);
|
// action.write(0, EnumWrappers.PlayerInfoAction.ADD_PLAYER);
|
||||||
infoData.write(0, playerInfoData);
|
// infoData.write(0, playerInfoData);
|
||||||
|
//
|
||||||
return playerInfoPacket;
|
// return playerInfoPacket;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public PacketContainer getPlayerRemovePacket(final Player player, final UUID uuid, final int entityId) {
|
// public PacketContainer getPlayerRemovePacket(final Player player, final UUID uuid, final int entityId) {
|
||||||
final PacketContainer playerPacket = new PacketContainer(PacketType.Play.Server.PLAYER_INFO);
|
// final PacketContainer playerPacket = new PacketContainer(PacketType.Play.Server.PLAYER_INFO);
|
||||||
final StructureModifier<EnumWrappers.PlayerInfoAction> action = playerPacket.getPlayerInfoAction();
|
// final StructureModifier<EnumWrappers.PlayerInfoAction> action = playerPacket.getPlayerInfoAction();
|
||||||
final StructureModifier<List<PlayerInfoData>> infoData = playerPacket.getPlayerInfoDataLists();
|
// final StructureModifier<List<PlayerInfoData>> infoData = playerPacket.getPlayerInfoDataLists();
|
||||||
|
//
|
||||||
final List<PlayerInfoData> playerInfoData = new ArrayList<>();
|
// final List<PlayerInfoData> playerInfoData = new ArrayList<>();
|
||||||
|
//
|
||||||
final GameProfile profile = this.getCopyProfile(player, uuid);
|
// final GameProfile profile = this.getCopyProfile(player, uuid);
|
||||||
|
//
|
||||||
playerInfoData.add(new PlayerInfoData(WrappedGameProfile
|
// playerInfoData.add(new PlayerInfoData(WrappedGameProfile
|
||||||
.fromHandle(profile),
|
// .fromHandle(profile),
|
||||||
0,
|
// 0,
|
||||||
EnumWrappers.NativeGameMode.fromBukkit(GameMode.CREATIVE),
|
// EnumWrappers.NativeGameMode.fromBukkit(GameMode.CREATIVE),
|
||||||
WrappedChatComponent.fromText("")));
|
// WrappedChatComponent.fromText("")));
|
||||||
|
//
|
||||||
action.write(0, EnumWrappers.PlayerInfoAction.REMOVE_PLAYER);
|
// action.write(0, EnumWrappers.PlayerInfoAction.REMOVE_PLAYER);
|
||||||
infoData.write(0, playerInfoData);
|
// infoData.write(0, playerInfoData);
|
||||||
|
//
|
||||||
return playerPacket;
|
// return playerPacket;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public PacketContainer getPlayerOverlayPacket(final int entityId) {
|
// public PacketContainer getPlayerOverlayPacket(final int entityId) {
|
||||||
final PacketContainer metaContainer = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
|
// final PacketContainer metaContainer = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
|
||||||
|
//
|
||||||
WrappedDataWatcher metaData = new WrappedDataWatcher();
|
// WrappedDataWatcher metaData = new WrappedDataWatcher();
|
||||||
|
//
|
||||||
final WrappedDataWatcher.Serializer byteSerializer = WrappedDataWatcher.Registry.get(Byte.class);
|
// final WrappedDataWatcher.Serializer byteSerializer = WrappedDataWatcher.Registry.get(Byte.class);
|
||||||
|
//
|
||||||
final byte mask = 0x01 | 0x02 | 0x04 | 0x08 | 0x010 | 0x020 | 0x40;
|
// final byte mask = 0x01 | 0x02 | 0x04 | 0x08 | 0x010 | 0x020 | 0x40;
|
||||||
|
//
|
||||||
metaData.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(16, byteSerializer), mask);
|
// metaData.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(16, byteSerializer), mask);
|
||||||
|
//
|
||||||
metaContainer.getIntegers().write(0, entityId);
|
// metaContainer.getIntegers().write(0, entityId);
|
||||||
metaContainer.getWatchableCollectionModifier().write(0, metaData.getWatchableObjects());
|
// metaContainer.getWatchableCollectionModifier().write(0, metaData.getWatchableObjects());
|
||||||
return metaContainer;
|
// return metaContainer;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
private GameProfile getCopyProfile(final Player player, final UUID uuid) {
|
// private GameProfile getCopyProfile(final Player player, final UUID uuid) {
|
||||||
final GameProfile playerProfile = ((CraftPlayer) player).getProfile();
|
// final GameProfile playerProfile = ((CraftPlayer) player).getProfile();
|
||||||
final GameProfile profile = new GameProfile(
|
// final GameProfile profile = new GameProfile(
|
||||||
uuid,
|
// uuid,
|
||||||
player.getDisplayName()
|
// player.getDisplayName()
|
||||||
);
|
// );
|
||||||
|
//
|
||||||
profile.getProperties().removeAll("textures");
|
// profile.getProperties().removeAll("textures");
|
||||||
Property textureProperty = playerProfile.getProperties().get("textures").iterator().next();
|
// Property textureProperty = playerProfile.getProperties().get("textures").iterator().next();
|
||||||
String texture = textureProperty.getValue();
|
// String texture = textureProperty.getValue();
|
||||||
String signature = textureProperty.getSignature();
|
// String signature = textureProperty.getSignature();
|
||||||
profile.getProperties().put("textures", new Property("textures", texture, signature));
|
// profile.getProperties().put("textures", new Property("textures", texture, signature));
|
||||||
|
//
|
||||||
return profile;
|
// return profile;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public PacketContainer getArmorStandMeta(final int armorStandId) {
|
// public PacketContainer getArmorStandMeta(final int armorStandId) {
|
||||||
final PacketContainer metaContainer = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
|
// final PacketContainer metaContainer = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
|
||||||
|
//
|
||||||
WrappedDataWatcher metaData = new WrappedDataWatcher();
|
// WrappedDataWatcher metaData = new WrappedDataWatcher();
|
||||||
|
//
|
||||||
final WrappedDataWatcher.Serializer byteSerializer = WrappedDataWatcher.Registry.get(Byte.class);
|
// final WrappedDataWatcher.Serializer byteSerializer = WrappedDataWatcher.Registry.get(Byte.class);
|
||||||
|
//
|
||||||
metaData.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(0, byteSerializer), (byte) (0x20));
|
// metaData.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(0, byteSerializer), (byte) (0x20));
|
||||||
metaData.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(14, byteSerializer), (byte) (0x10));
|
// metaData.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(14, byteSerializer), (byte) (0x10));
|
||||||
|
//
|
||||||
metaContainer.getIntegers().write(0, armorStandId);
|
// metaContainer.getIntegers().write(0, armorStandId);
|
||||||
metaContainer.getWatchableCollectionModifier().write(0, metaData.getWatchableObjects());
|
// metaContainer.getWatchableCollectionModifier().write(0, metaData.getWatchableObjects());
|
||||||
return metaContainer;
|
// return metaContainer;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public PacketContainer getDestroyPacket(final int entityId) {
|
// public PacketContainer getDestroyPacket(final int entityId) {
|
||||||
final PacketContainer destroyPacket = new PacketContainer(
|
// final PacketContainer destroyPacket = new PacketContainer(
|
||||||
PacketType.Play.Server.ENTITY_DESTROY);
|
// PacketType.Play.Server.ENTITY_DESTROY);
|
||||||
destroyPacket.getIntegerArrays().write(0, new int[]{entityId});
|
// destroyPacket.getIntegerArrays().write(0, new int[]{entityId});
|
||||||
|
//
|
||||||
return destroyPacket;
|
// return destroyPacket;
|
||||||
}
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ repositories {
|
|||||||
maven("https://papermc.io/repo/repository/maven-public/")
|
maven("https://papermc.io/repo/repository/maven-public/")
|
||||||
maven("https://oss.sonatype.org/content/repositories/snapshots")
|
maven("https://oss.sonatype.org/content/repositories/snapshots")
|
||||||
maven("https://jitpack.io")
|
maven("https://jitpack.io")
|
||||||
maven("https://repo.dmulloy2.net/repository/public/")
|
// maven("https://repo.dmulloy2.net/repository/public/")
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@@ -19,5 +19,5 @@ dependencies {
|
|||||||
compileOnly("com.mojang:authlib:1.5.25")
|
compileOnly("com.mojang:authlib:1.5.25")
|
||||||
compileOnly("org.spigotmc:spigot:1.17-R0.1-SNAPSHOT")
|
compileOnly("org.spigotmc:spigot:1.17-R0.1-SNAPSHOT")
|
||||||
compileOnly("org.jetbrains:annotations:22.0.0")
|
compileOnly("org.jetbrains:annotations:22.0.0")
|
||||||
compileOnly("com.comphenix.protocol:ProtocolLib:4.7.0")
|
// compileOnly("com.comphenix.protocol:ProtocolLib:4.7.0")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,140 +1,120 @@
|
|||||||
package io.github.fisher2911.nms;
|
package io.github.fisher2911.nms;
|
||||||
|
|
||||||
import com.comphenix.protocol.PacketType;
|
|
||||||
import com.comphenix.protocol.events.PacketContainer;
|
|
||||||
import com.comphenix.protocol.reflect.StructureModifier;
|
|
||||||
import com.comphenix.protocol.wrappers.EnumWrappers;
|
|
||||||
import com.comphenix.protocol.wrappers.PlayerInfoData;
|
|
||||||
import com.comphenix.protocol.wrappers.WrappedChatComponent;
|
|
||||||
import com.comphenix.protocol.wrappers.WrappedDataWatcher;
|
|
||||||
import com.comphenix.protocol.wrappers.WrappedGameProfile;
|
|
||||||
import com.mojang.authlib.GameProfile;
|
|
||||||
import com.mojang.authlib.properties.Property;
|
|
||||||
import org.bukkit.GameMode;
|
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.craftbukkit.libs.it.unimi.dsi.fastutil.ints.IntArrayList;
|
|
||||||
import org.bukkit.craftbukkit.v1_17_R1.entity.CraftPlayer;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class PacketHelper_1_17_R1 implements PacketHelper {
|
public class PacketHelper_1_17_R1 implements PacketHelper {
|
||||||
|
|
||||||
@Override
|
// @Override
|
||||||
public PacketContainer getPlayerSpawnPacket(final Location location, UUID uuid, final int entityId) {
|
// public PacketContainer getPlayerSpawnPacket(final Location location, UUID uuid, final int entityId) {
|
||||||
final PacketContainer spawnPacket = new PacketContainer(PacketType.Play.Server.NAMED_ENTITY_SPAWN);
|
// final PacketContainer spawnPacket = new PacketContainer(PacketType.Play.Server.NAMED_ENTITY_SPAWN);
|
||||||
spawnPacket.getUUIDs().write(0, uuid);
|
// spawnPacket.getUUIDs().write(0, uuid);
|
||||||
spawnPacket.getIntegers().write(0, entityId);
|
// spawnPacket.getIntegers().write(0, entityId);
|
||||||
spawnPacket.getDoubles().
|
// spawnPacket.getDoubles().
|
||||||
write(0, location.getX()).
|
// write(0, location.getX()).
|
||||||
write(1, location.getY()).
|
// write(1, location.getY()).
|
||||||
write(2, location.getZ());
|
// write(2, location.getZ());
|
||||||
spawnPacket.getBytes().write(0, (byte)(((location.getYaw() * 256.0F) / 360.0F)));
|
// spawnPacket.getBytes().write(0, (byte)(((location.getYaw() * 256.0F) / 360.0F)));
|
||||||
|
//
|
||||||
return spawnPacket;
|
// return spawnPacket;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public PacketContainer getPlayerInfoPacket(final Player player, final UUID uuid) {
|
// public PacketContainer getPlayerInfoPacket(final Player player, final UUID uuid) {
|
||||||
final GameProfile profile = this.getCopyProfile(player, uuid);
|
// final GameProfile profile = this.getCopyProfile(player, uuid);
|
||||||
final PacketContainer playerInfoPacket = new PacketContainer(PacketType.Play.Server.PLAYER_INFO);
|
// final PacketContainer playerInfoPacket = new PacketContainer(PacketType.Play.Server.PLAYER_INFO);
|
||||||
final StructureModifier<EnumWrappers.PlayerInfoAction> action = playerInfoPacket.getPlayerInfoAction();
|
// final StructureModifier<EnumWrappers.PlayerInfoAction> action = playerInfoPacket.getPlayerInfoAction();
|
||||||
final StructureModifier<List<PlayerInfoData>> infoData = playerInfoPacket.getPlayerInfoDataLists();
|
// final StructureModifier<List<PlayerInfoData>> infoData = playerInfoPacket.getPlayerInfoDataLists();
|
||||||
|
//
|
||||||
final List<PlayerInfoData> playerInfoData = new ArrayList<>();
|
// final List<PlayerInfoData> playerInfoData = new ArrayList<>();
|
||||||
|
//
|
||||||
playerInfoData.add(new PlayerInfoData(WrappedGameProfile
|
// playerInfoData.add(new PlayerInfoData(WrappedGameProfile
|
||||||
.fromHandle(profile),
|
// .fromHandle(profile),
|
||||||
0,
|
// 0,
|
||||||
EnumWrappers.NativeGameMode.fromBukkit(GameMode.CREATIVE),
|
// EnumWrappers.NativeGameMode.fromBukkit(GameMode.CREATIVE),
|
||||||
WrappedChatComponent.fromText(profile.getName())));
|
// WrappedChatComponent.fromText(profile.getName())));
|
||||||
|
//
|
||||||
action.write(0, EnumWrappers.PlayerInfoAction.ADD_PLAYER);
|
// action.write(0, EnumWrappers.PlayerInfoAction.ADD_PLAYER);
|
||||||
infoData.write(0, playerInfoData);
|
// infoData.write(0, playerInfoData);
|
||||||
|
//
|
||||||
return playerInfoPacket;
|
// return playerInfoPacket;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public PacketContainer getPlayerRemovePacket(final Player player, final UUID uuid, final int entityId) {
|
// public PacketContainer getPlayerRemovePacket(final Player player, final UUID uuid, final int entityId) {
|
||||||
final PacketContainer playerPacket = new PacketContainer(PacketType.Play.Server.PLAYER_INFO);
|
// final PacketContainer playerPacket = new PacketContainer(PacketType.Play.Server.PLAYER_INFO);
|
||||||
final StructureModifier<EnumWrappers.PlayerInfoAction> action = playerPacket.getPlayerInfoAction();
|
// final StructureModifier<EnumWrappers.PlayerInfoAction> action = playerPacket.getPlayerInfoAction();
|
||||||
final StructureModifier<List<PlayerInfoData>> infoData = playerPacket.getPlayerInfoDataLists();
|
// final StructureModifier<List<PlayerInfoData>> infoData = playerPacket.getPlayerInfoDataLists();
|
||||||
|
//
|
||||||
final List<PlayerInfoData> playerInfoData = new ArrayList<>();
|
// final List<PlayerInfoData> playerInfoData = new ArrayList<>();
|
||||||
|
//
|
||||||
final GameProfile profile = this.getCopyProfile(player, uuid);
|
// final GameProfile profile = this.getCopyProfile(player, uuid);
|
||||||
|
//
|
||||||
playerInfoData.add(new PlayerInfoData(WrappedGameProfile
|
// playerInfoData.add(new PlayerInfoData(WrappedGameProfile
|
||||||
.fromHandle(profile),
|
// .fromHandle(profile),
|
||||||
0,
|
// 0,
|
||||||
EnumWrappers.NativeGameMode.fromBukkit(GameMode.CREATIVE),
|
// EnumWrappers.NativeGameMode.fromBukkit(GameMode.CREATIVE),
|
||||||
WrappedChatComponent.fromText("")));
|
// WrappedChatComponent.fromText("")));
|
||||||
|
//
|
||||||
action.write(0, EnumWrappers.PlayerInfoAction.REMOVE_PLAYER);
|
// action.write(0, EnumWrappers.PlayerInfoAction.REMOVE_PLAYER);
|
||||||
infoData.write(0, playerInfoData);
|
// infoData.write(0, playerInfoData);
|
||||||
|
//
|
||||||
return playerPacket;
|
// return playerPacket;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public PacketContainer getPlayerOverlayPacket(final int entityId) {
|
// public PacketContainer getPlayerOverlayPacket(final int entityId) {
|
||||||
final PacketContainer metaContainer = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
|
// final PacketContainer metaContainer = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
|
||||||
|
//
|
||||||
WrappedDataWatcher metaData = new WrappedDataWatcher();
|
// WrappedDataWatcher metaData = new WrappedDataWatcher();
|
||||||
|
//
|
||||||
final WrappedDataWatcher.Serializer byteSerializer = WrappedDataWatcher.Registry.get(Byte.class);
|
// final WrappedDataWatcher.Serializer byteSerializer = WrappedDataWatcher.Registry.get(Byte.class);
|
||||||
|
//
|
||||||
final byte mask = 0x01 | 0x02 | 0x04 | 0x08 | 0x010 | 0x020 | 0x40;
|
// final byte mask = 0x01 | 0x02 | 0x04 | 0x08 | 0x010 | 0x020 | 0x40;
|
||||||
|
//
|
||||||
metaData.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(17, byteSerializer), mask);
|
// metaData.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(17, byteSerializer), mask);
|
||||||
|
//
|
||||||
metaContainer.getIntegers().write(0, entityId);
|
// metaContainer.getIntegers().write(0, entityId);
|
||||||
metaContainer.getWatchableCollectionModifier().write(0, metaData.getWatchableObjects());
|
// metaContainer.getWatchableCollectionModifier().write(0, metaData.getWatchableObjects());
|
||||||
return metaContainer;
|
// return metaContainer;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
private GameProfile getCopyProfile(final Player player, final UUID uuid) {
|
// private GameProfile getCopyProfile(final Player player, final UUID uuid) {
|
||||||
final GameProfile playerProfile = ((CraftPlayer) player).getProfile();
|
// final GameProfile playerProfile = ((CraftPlayer) player).getProfile();
|
||||||
final GameProfile profile = new GameProfile(
|
// final GameProfile profile = new GameProfile(
|
||||||
uuid,
|
// uuid,
|
||||||
player.getDisplayName()
|
// player.getDisplayName()
|
||||||
);
|
// );
|
||||||
|
//
|
||||||
profile.getProperties().removeAll("textures");
|
// profile.getProperties().removeAll("textures");
|
||||||
Property textureProperty = playerProfile.getProperties().get("textures").iterator().next();
|
// Property textureProperty = playerProfile.getProperties().get("textures").iterator().next();
|
||||||
String texture = textureProperty.getValue();
|
// String texture = textureProperty.getValue();
|
||||||
String signature = textureProperty.getSignature();
|
// String signature = textureProperty.getSignature();
|
||||||
profile.getProperties().put("textures", new Property("textures", texture, signature));
|
// profile.getProperties().put("textures", new Property("textures", texture, signature));
|
||||||
|
//
|
||||||
return profile;
|
// return profile;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public PacketContainer getArmorStandMeta(final int armorStandId) {
|
// public PacketContainer getArmorStandMeta(final int armorStandId) {
|
||||||
final PacketContainer metaContainer = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
|
// final PacketContainer metaContainer = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
|
||||||
|
//
|
||||||
WrappedDataWatcher metaData = new WrappedDataWatcher();
|
// WrappedDataWatcher metaData = new WrappedDataWatcher();
|
||||||
|
//
|
||||||
final WrappedDataWatcher.Serializer byteSerializer = WrappedDataWatcher.Registry.get(Byte.class);
|
// final WrappedDataWatcher.Serializer byteSerializer = WrappedDataWatcher.Registry.get(Byte.class);
|
||||||
|
//
|
||||||
metaData.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(0, byteSerializer), (byte) (0x20));
|
// metaData.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(0, byteSerializer), (byte) (0x20));
|
||||||
metaData.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(15, byteSerializer), (byte) (0x10));
|
// metaData.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(15, byteSerializer), (byte) (0x10));
|
||||||
|
//
|
||||||
metaContainer.getIntegers().write(0, armorStandId);
|
// metaContainer.getIntegers().write(0, armorStandId);
|
||||||
metaContainer.getWatchableCollectionModifier().write(0, metaData.getWatchableObjects());
|
// metaContainer.getWatchableCollectionModifier().write(0, metaData.getWatchableObjects());
|
||||||
return metaContainer;
|
// return metaContainer;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public PacketContainer getDestroyPacket(final int entityId) {
|
// public PacketContainer getDestroyPacket(final int entityId) {
|
||||||
final PacketContainer destroyPacket = new PacketContainer(
|
// final PacketContainer destroyPacket = new PacketContainer(
|
||||||
PacketType.Play.Server.ENTITY_DESTROY);
|
// PacketType.Play.Server.ENTITY_DESTROY);
|
||||||
destroyPacket.getModifier().write(0, new IntArrayList(new int[]{entityId}));
|
// destroyPacket.getModifier().write(0, new IntArrayList(new int[]{entityId}));
|
||||||
|
//
|
||||||
return destroyPacket;
|
// return destroyPacket;
|
||||||
}
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ repositories {
|
|||||||
maven("https://papermc.io/repo/repository/maven-public/")
|
maven("https://papermc.io/repo/repository/maven-public/")
|
||||||
maven("https://oss.sonatype.org/content/repositories/snapshots")
|
maven("https://oss.sonatype.org/content/repositories/snapshots")
|
||||||
maven("https://jitpack.io")
|
maven("https://jitpack.io")
|
||||||
maven("https://repo.dmulloy2.net/repository/public/")
|
// maven("https://repo.dmulloy2.net/repository/public/")
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@@ -19,5 +19,5 @@ dependencies {
|
|||||||
compileOnly("com.mojang:authlib:1.5.25")
|
compileOnly("com.mojang:authlib:1.5.25")
|
||||||
compileOnly("org.spigotmc:spigot:1.18-R0.1-SNAPSHOT")
|
compileOnly("org.spigotmc:spigot:1.18-R0.1-SNAPSHOT")
|
||||||
compileOnly("org.jetbrains:annotations:22.0.0")
|
compileOnly("org.jetbrains:annotations:22.0.0")
|
||||||
compileOnly("com.comphenix.protocol:ProtocolLib:4.7.0")
|
// compileOnly("com.comphenix.protocol:ProtocolLib:4.7.0")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,139 +1,119 @@
|
|||||||
package io.github.fisher2911.nms;
|
package io.github.fisher2911.nms;
|
||||||
|
|
||||||
import com.comphenix.protocol.PacketType;
|
|
||||||
import com.comphenix.protocol.events.PacketContainer;
|
|
||||||
import com.comphenix.protocol.reflect.StructureModifier;
|
|
||||||
import com.comphenix.protocol.wrappers.EnumWrappers;
|
|
||||||
import com.comphenix.protocol.wrappers.PlayerInfoData;
|
|
||||||
import com.comphenix.protocol.wrappers.WrappedChatComponent;
|
|
||||||
import com.comphenix.protocol.wrappers.WrappedDataWatcher;
|
|
||||||
import com.comphenix.protocol.wrappers.WrappedGameProfile;
|
|
||||||
import com.mojang.authlib.GameProfile;
|
|
||||||
import com.mojang.authlib.properties.Property;
|
|
||||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
|
||||||
import org.bukkit.GameMode;
|
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.craftbukkit.v1_18_R1.entity.CraftPlayer;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class PacketHelper_1_18_R1 implements PacketHelper {
|
public class PacketHelper_1_18_R1 implements PacketHelper {
|
||||||
|
|
||||||
@Override
|
// @Override
|
||||||
public PacketContainer getPlayerSpawnPacket(final Location location, UUID uuid, final int entityId) {
|
// public PacketContainer getPlayerSpawnPacket(final Location location, UUID uuid, final int entityId) {
|
||||||
final PacketContainer spawnPacket = new PacketContainer(PacketType.Play.Server.NAMED_ENTITY_SPAWN);
|
// final PacketContainer spawnPacket = new PacketContainer(PacketType.Play.Server.NAMED_ENTITY_SPAWN);
|
||||||
spawnPacket.getUUIDs().write(0, uuid);
|
// spawnPacket.getUUIDs().write(0, uuid);
|
||||||
spawnPacket.getIntegers().write(0, entityId);
|
// spawnPacket.getIntegers().write(0, entityId);
|
||||||
spawnPacket.getDoubles().
|
// spawnPacket.getDoubles().
|
||||||
write(0, location.getX()).
|
// write(0, location.getX()).
|
||||||
write(1, location.getY()).
|
// write(1, location.getY()).
|
||||||
write(2, location.getZ());
|
// write(2, location.getZ());
|
||||||
spawnPacket.getBytes().write(0, (byte)(((location.getYaw() * 256.0F) / 360.0F)));
|
// spawnPacket.getBytes().write(0, (byte)(((location.getYaw() * 256.0F) / 360.0F)));
|
||||||
|
//
|
||||||
return spawnPacket;
|
// return spawnPacket;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public PacketContainer getPlayerInfoPacket(final Player player, final UUID uuid) {
|
// public PacketContainer getPlayerInfoPacket(final Player player, final UUID uuid) {
|
||||||
final GameProfile profile = this.getCopyProfile(player, uuid);
|
// final GameProfile profile = this.getCopyProfile(player, uuid);
|
||||||
final PacketContainer playerInfoPacket = new PacketContainer(PacketType.Play.Server.PLAYER_INFO);
|
// final PacketContainer playerInfoPacket = new PacketContainer(PacketType.Play.Server.PLAYER_INFO);
|
||||||
final StructureModifier<EnumWrappers.PlayerInfoAction> action = playerInfoPacket.getPlayerInfoAction();
|
// final StructureModifier<EnumWrappers.PlayerInfoAction> action = playerInfoPacket.getPlayerInfoAction();
|
||||||
final StructureModifier<List<PlayerInfoData>> infoData = playerInfoPacket.getPlayerInfoDataLists();
|
// final StructureModifier<List<PlayerInfoData>> infoData = playerInfoPacket.getPlayerInfoDataLists();
|
||||||
|
//
|
||||||
final List<PlayerInfoData> playerInfoData = new ArrayList<>();
|
// final List<PlayerInfoData> playerInfoData = new ArrayList<>();
|
||||||
|
//
|
||||||
playerInfoData.add(new PlayerInfoData(WrappedGameProfile
|
// playerInfoData.add(new PlayerInfoData(WrappedGameProfile
|
||||||
.fromHandle(profile),
|
// .fromHandle(profile),
|
||||||
0,
|
// 0,
|
||||||
EnumWrappers.NativeGameMode.fromBukkit(GameMode.SURVIVAL),
|
// EnumWrappers.NativeGameMode.fromBukkit(GameMode.SURVIVAL),
|
||||||
WrappedChatComponent.fromText(profile.getName())));
|
// WrappedChatComponent.fromText(profile.getName())));
|
||||||
|
//
|
||||||
action.write(0, EnumWrappers.PlayerInfoAction.ADD_PLAYER);
|
// action.write(0, EnumWrappers.PlayerInfoAction.ADD_PLAYER);
|
||||||
infoData.write(0, playerInfoData);
|
// infoData.write(0, playerInfoData);
|
||||||
|
//
|
||||||
return playerInfoPacket;
|
// return playerInfoPacket;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public PacketContainer getPlayerRemovePacket(final Player player, final UUID uuid, final int entityId) {
|
// public PacketContainer getPlayerRemovePacket(final Player player, final UUID uuid, final int entityId) {
|
||||||
final PacketContainer playerPacket = new PacketContainer(PacketType.Play.Server.PLAYER_INFO);
|
// final PacketContainer playerPacket = new PacketContainer(PacketType.Play.Server.PLAYER_INFO);
|
||||||
final StructureModifier<EnumWrappers.PlayerInfoAction> action = playerPacket.getPlayerInfoAction();
|
// final StructureModifier<EnumWrappers.PlayerInfoAction> action = playerPacket.getPlayerInfoAction();
|
||||||
final StructureModifier<List<PlayerInfoData>> infoData = playerPacket.getPlayerInfoDataLists();
|
// final StructureModifier<List<PlayerInfoData>> infoData = playerPacket.getPlayerInfoDataLists();
|
||||||
|
//
|
||||||
final List<PlayerInfoData> playerInfoData = new ArrayList<>();
|
// final List<PlayerInfoData> playerInfoData = new ArrayList<>();
|
||||||
|
//
|
||||||
final GameProfile profile = this.getCopyProfile(player, uuid);
|
// final GameProfile profile = this.getCopyProfile(player, uuid);
|
||||||
|
//
|
||||||
playerInfoData.add(new PlayerInfoData(WrappedGameProfile
|
// playerInfoData.add(new PlayerInfoData(WrappedGameProfile
|
||||||
.fromHandle(profile),
|
// .fromHandle(profile),
|
||||||
0,
|
// 0,
|
||||||
EnumWrappers.NativeGameMode.fromBukkit(GameMode.CREATIVE),
|
// EnumWrappers.NativeGameMode.fromBukkit(GameMode.CREATIVE),
|
||||||
WrappedChatComponent.fromText("")));
|
// WrappedChatComponent.fromText("")));
|
||||||
|
//
|
||||||
action.write(0, EnumWrappers.PlayerInfoAction.REMOVE_PLAYER);
|
// action.write(0, EnumWrappers.PlayerInfoAction.REMOVE_PLAYER);
|
||||||
infoData.write(0, playerInfoData);
|
// infoData.write(0, playerInfoData);
|
||||||
|
//
|
||||||
return playerPacket;
|
// return playerPacket;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public PacketContainer getPlayerOverlayPacket(final int entityId) {
|
// public PacketContainer getPlayerOverlayPacket(final int entityId) {
|
||||||
final PacketContainer metaContainer = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
|
// final PacketContainer metaContainer = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
|
||||||
|
//
|
||||||
WrappedDataWatcher metaData = new WrappedDataWatcher();
|
// WrappedDataWatcher metaData = new WrappedDataWatcher();
|
||||||
|
//
|
||||||
final WrappedDataWatcher.Serializer byteSerializer = WrappedDataWatcher.Registry.get(Byte.class);
|
// final WrappedDataWatcher.Serializer byteSerializer = WrappedDataWatcher.Registry.get(Byte.class);
|
||||||
|
//
|
||||||
final byte mask = 0x01 | 0x02 | 0x04 | 0x08 | 0x010 | 0x020 | 0x40;
|
// final byte mask = 0x01 | 0x02 | 0x04 | 0x08 | 0x010 | 0x020 | 0x40;
|
||||||
|
//
|
||||||
metaData.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(17, byteSerializer), mask);
|
// metaData.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(17, byteSerializer), mask);
|
||||||
|
//
|
||||||
metaContainer.getIntegers().write(0, entityId);
|
// metaContainer.getIntegers().write(0, entityId);
|
||||||
metaContainer.getWatchableCollectionModifier().write(0, metaData.getWatchableObjects());
|
// metaContainer.getWatchableCollectionModifier().write(0, metaData.getWatchableObjects());
|
||||||
return metaContainer;
|
// return metaContainer;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
private GameProfile getCopyProfile(final Player player, final UUID uuid) {
|
// private GameProfile getCopyProfile(final Player player, final UUID uuid) {
|
||||||
final GameProfile playerProfile = ((CraftPlayer) player).getProfile();
|
// final GameProfile playerProfile = ((CraftPlayer) player).getProfile();
|
||||||
final GameProfile profile = new GameProfile(
|
// final GameProfile profile = new GameProfile(
|
||||||
uuid,
|
// uuid,
|
||||||
player.getDisplayName()
|
// player.getDisplayName()
|
||||||
);
|
// );
|
||||||
|
//
|
||||||
profile.getProperties().removeAll("textures");
|
// profile.getProperties().removeAll("textures");
|
||||||
Property textureProperty = playerProfile.getProperties().get("textures").iterator().next();
|
// Property textureProperty = playerProfile.getProperties().get("textures").iterator().next();
|
||||||
String texture = textureProperty.getValue();
|
// String texture = textureProperty.getValue();
|
||||||
String signature = textureProperty.getSignature();
|
// String signature = textureProperty.getSignature();
|
||||||
profile.getProperties().put("textures", new Property("textures", texture, signature));
|
// profile.getProperties().put("textures", new Property("textures", texture, signature));
|
||||||
|
//
|
||||||
return profile;
|
// return profile;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public PacketContainer getArmorStandMeta(final int armorStandId) {
|
// public PacketContainer getArmorStandMeta(final int armorStandId) {
|
||||||
final PacketContainer metaContainer = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
|
// final PacketContainer metaContainer = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
|
||||||
|
//
|
||||||
WrappedDataWatcher metaData = new WrappedDataWatcher();
|
// WrappedDataWatcher metaData = new WrappedDataWatcher();
|
||||||
|
//
|
||||||
final WrappedDataWatcher.Serializer byteSerializer = WrappedDataWatcher.Registry.get(Byte.class);
|
// final WrappedDataWatcher.Serializer byteSerializer = WrappedDataWatcher.Registry.get(Byte.class);
|
||||||
|
//
|
||||||
metaData.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(0, byteSerializer), (byte) (0x20));
|
// metaData.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(0, byteSerializer), (byte) (0x20));
|
||||||
metaData.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(15, byteSerializer), (byte) (0x10));
|
// metaData.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(15, byteSerializer), (byte) (0x10));
|
||||||
|
//
|
||||||
metaContainer.getIntegers().write(0, armorStandId);
|
// metaContainer.getIntegers().write(0, armorStandId);
|
||||||
metaContainer.getWatchableCollectionModifier().write(0, metaData.getWatchableObjects());
|
// metaContainer.getWatchableCollectionModifier().write(0, metaData.getWatchableObjects());
|
||||||
return metaContainer;
|
// return metaContainer;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public PacketContainer getDestroyPacket(final int entityId) {
|
// public PacketContainer getDestroyPacket(final int entityId) {
|
||||||
final PacketContainer destroyPacket = new PacketContainer(
|
// final PacketContainer destroyPacket = new PacketContainer(
|
||||||
PacketType.Play.Server.ENTITY_DESTROY);
|
// PacketType.Play.Server.ENTITY_DESTROY);
|
||||||
destroyPacket.getModifier().write(0, new IntArrayList(new int[]{entityId}));
|
// destroyPacket.getModifier().write(0, new IntArrayList(new int[]{entityId}));
|
||||||
|
//
|
||||||
return destroyPacket;
|
// return destroyPacket;
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|||||||
109
build.gradle.kts
109
build.gradle.kts
@@ -1,112 +1,3 @@
|
|||||||
|
|
||||||
//import net.minecrell.pluginyml.bukkit.BukkitPluginDescription
|
|
||||||
//
|
|
||||||
plugins {
|
plugins {
|
||||||
id("java")
|
id("java")
|
||||||
}
|
}
|
||||||
// id("com.github.johnrengelman.shadow") version "7.1.1"
|
|
||||||
// id("net.minecrell.plugin-yml.bukkit") version "0.5.1"
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//group = "io.github.fisher2911"
|
|
||||||
//version = "1.7.1"
|
|
||||||
//description = "Intuitive, easy-to-use cosmetics plugin, designed for servers using resource packs.\n"
|
|
||||||
//
|
|
||||||
//repositories {
|
|
||||||
// mavenCentral()
|
|
||||||
// maven("https://papermc.io/repo/repository/maven-public/")
|
|
||||||
// maven("https://repo.mattstudios.me/artifactory/public/")
|
|
||||||
// maven("https://jitpack.io")
|
|
||||||
// maven("https://repo.dmulloy2.net/repository/public/")
|
|
||||||
// maven("https://repo.extendedclip.com/content/repositories/placeholderapi/")
|
|
||||||
// maven("https://mvnrepository.com/artifact/com.zaxxer/HikariCP")
|
|
||||||
// maven("https://repo.jeff-media.de/maven2/")
|
|
||||||
// maven("https://oss.sonatype.org/content/repositories/snapshots")
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//dependencies {
|
|
||||||
// compileOnly("com.mojang:authlib:1.5.25")
|
|
||||||
// compileOnly("org.spigotmc:spigot:1.17-R0.1-SNAPSHOT")
|
|
||||||
// compileOnly("org.jetbrains:annotations:22.0.0")
|
|
||||||
// compileOnly("com.comphenix.protocol:ProtocolLib:4.7.0")
|
|
||||||
// compileOnly("me.clip:placeholderapi:2.11.1")
|
|
||||||
// compileOnly("com.github.oraxen:oraxen:-SNAPSHOT")
|
|
||||||
// compileOnly("com.github.LoneDev6:API-ItemsAdder:2.5.4")
|
|
||||||
// implementation("net.kyori:adventure-api:4.9.3")
|
|
||||||
// implementation("net.kyori:adventure-text-minimessage:4.10.0-SNAPSHOT")
|
|
||||||
// implementation("net.kyori:adventure-platform-bukkit:4.0.1")
|
|
||||||
// implementation("dev.triumphteam:triumph-gui:3.1.1")
|
|
||||||
// implementation("me.mattstudios.utils:matt-framework:1.4.6")
|
|
||||||
// implementation("org.spongepowered:configurate-yaml:4.1.2")
|
|
||||||
// implementation("org.bstats:bstats-bukkit:2.2.1")
|
|
||||||
// implementation("com.zaxxer:HikariCP:5.0.0")
|
|
||||||
// implementation("com.j256.ormlite:ormlite-jdbc:6.1")
|
|
||||||
// implementation("com.j256.ormlite:ormlite-core:6.1")
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//tasks {
|
|
||||||
// build {
|
|
||||||
// dependsOn(shadowJar)
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// compileJava {
|
|
||||||
// options.encoding = Charsets.UTF_8.name()
|
|
||||||
// options.release.set(16)
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// shadowJar {
|
|
||||||
// relocate("dev.triumphteam.gui", "io.github.fisher2911.hmccosmetics.gui")
|
|
||||||
// relocate("me.mattstudios.mf", "io.github.fisher2911.hmccosmetics.mf")
|
|
||||||
// relocate("net.kyori.adventure.text.minimessage", "io.github.fisher2911.hmccosmetics.adventure.minimessage")
|
|
||||||
// relocate("net.kyori.adventure.platform", "io.github.fisher2911.hmccosmetics.adventure.platform")
|
|
||||||
// relocate("org.spongepowered.configurate", "io.github.fisher2911.hmccosmetics.configurate")
|
|
||||||
// relocate("org.bstats", "io.github.fisher2911.hmccosmetics.bstats")
|
|
||||||
// relocate("com.zaxxer.hikaricp", "io.github.fisher2911.hmccosmetics.hikaricp")
|
|
||||||
// relocate("com.j256.ormlite", "io.github.fisher2911.hmccosmetics.ormlite")
|
|
||||||
// archiveFileName.set("HMCCosmetics.jar")
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// javadoc {
|
|
||||||
// options.encoding = Charsets.UTF_8.name()
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// processResources {
|
|
||||||
// filteringCharset = Charsets.UTF_8.name()
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//java {
|
|
||||||
// toolchain.languageVersion.set(JavaLanguageVersion.of(16))
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//bukkit {
|
|
||||||
// load = BukkitPluginDescription.PluginLoadOrder.STARTUP
|
|
||||||
// main = "io.github.fisher2911.hmccosmetics.HMCCosmetics"
|
|
||||||
// apiVersion = "1.17"
|
|
||||||
// name = "HMCCosmetics"
|
|
||||||
// authors = listOf("MasterOfTheFish")
|
|
||||||
// softDepend = listOf("Multiverse", "PlaceholderAPI", "Oraxen", "ItemsAdder")
|
|
||||||
// depend = listOf("ProtocolLib")
|
|
||||||
// permissions {
|
|
||||||
// register("hmccosmetics.cmd.default") {
|
|
||||||
// default = BukkitPluginDescription.Permission.Default.OP
|
|
||||||
// description = "Permission to execute the default command."
|
|
||||||
// }
|
|
||||||
// register("hmccosmetics.cmd.dye") {
|
|
||||||
// default = BukkitPluginDescription.Permission.Default.OP
|
|
||||||
// description = "Permission to dye armor."
|
|
||||||
// }
|
|
||||||
// register("hmccosmetics.cmd.reload") {
|
|
||||||
// default = BukkitPluginDescription.Permission.Default.OP
|
|
||||||
// description = "Permission to use the reload command."
|
|
||||||
// }
|
|
||||||
// register("hmccosmetics.cmd.set") {
|
|
||||||
// default = BukkitPluginDescription.Permission.Default.OP
|
|
||||||
// description = "Permission to set other users' cosmetics."
|
|
||||||
// }
|
|
||||||
// register("hmccosmetics.cmd.wardrobe") {
|
|
||||||
// default = BukkitPluginDescription.Permission.Default.OP
|
|
||||||
// description = "Permission to view the wardrobe"
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
@@ -22,22 +22,24 @@ repositories {
|
|||||||
maven("https://repo.jeff-media.de/maven2/")
|
maven("https://repo.jeff-media.de/maven2/")
|
||||||
maven("https://repo.citizensnpcs.co")
|
maven("https://repo.citizensnpcs.co")
|
||||||
maven("https://mvn.lumine.io/repository/maven-public")
|
maven("https://mvn.lumine.io/repository/maven-public")
|
||||||
|
maven("https://jitpack.io/")
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(project(":1.16"))
|
// implementation(project(":1.16"))
|
||||||
implementation(project(":1.17"))
|
// implementation(project(":1.17"))
|
||||||
implementation(project(":1.18"))
|
// implementation(project(":1.18"))
|
||||||
implementation(project(":nms"))
|
// implementation(project(":nms"))
|
||||||
compileOnly("com.mojang:authlib:1.5.25")
|
compileOnly("com.mojang:authlib:1.5.25")
|
||||||
compileOnly("org.spigotmc:spigot:1.16.5-R0.1-SNAPSHOT")
|
compileOnly("org.spigotmc:spigot:1.16.5-R0.1-SNAPSHOT")
|
||||||
compileOnly("org.jetbrains:annotations:22.0.0")
|
compileOnly("org.jetbrains:annotations:22.0.0")
|
||||||
compileOnly("com.comphenix.protocol:ProtocolLib:4.7.0")
|
// compileOnly("com.comphenix.protocol:ProtocolLib:4.7.0")
|
||||||
compileOnly("me.clip:placeholderapi:2.11.1")
|
compileOnly("me.clip:placeholderapi:2.11.1")
|
||||||
compileOnly("com.github.oraxen:oraxen:-SNAPSHOT")
|
compileOnly("com.github.oraxen:oraxen:-SNAPSHOT")
|
||||||
compileOnly("com.github.LoneDev6:API-ItemsAdder:2.5.4")
|
compileOnly("com.github.LoneDev6:API-ItemsAdder:2.5.4")
|
||||||
compileOnly("net.citizensnpcs:citizens-main:2.0.29-SNAPSHOT")
|
compileOnly("net.citizensnpcs:citizens-main:2.0.29-SNAPSHOT")
|
||||||
compileOnly("com.ticxo.modelengine:api:R2.4.1:")
|
compileOnly("com.ticxo.modelengine:api:R2.4.1:")
|
||||||
|
implementation("com.github.retrooper.packetevents:spigot:2.0-SNAPSHOT")
|
||||||
implementation("net.kyori:adventure-api:4.10.0")
|
implementation("net.kyori:adventure-api:4.10.0")
|
||||||
implementation ("net.kyori:adventure-text-minimessage:4.10.0-SNAPSHOT")
|
implementation ("net.kyori:adventure-text-minimessage:4.10.0-SNAPSHOT")
|
||||||
implementation("net.kyori:adventure-platform-bukkit:4.0.1")
|
implementation("net.kyori:adventure-platform-bukkit:4.0.1")
|
||||||
@@ -68,6 +70,7 @@ tasks {
|
|||||||
relocate("org.bstats", "io.github.fisher2911.hmccosmetics.bstats")
|
relocate("org.bstats", "io.github.fisher2911.hmccosmetics.bstats")
|
||||||
relocate("com.zaxxer.hikaricp", "io.github.fisher2911.hmccosmetics.hikaricp")
|
relocate("com.zaxxer.hikaricp", "io.github.fisher2911.hmccosmetics.hikaricp")
|
||||||
relocate("com.j256.ormlite", "io.github.fisher2911.hmccosmetics.ormlite")
|
relocate("com.j256.ormlite", "io.github.fisher2911.hmccosmetics.ormlite")
|
||||||
|
relocate("com.github.retrooper.packetevents", "io.github.fisher2911.hmccosmetics.packetevents")
|
||||||
archiveFileName.set("HMCCosmetics.jar")
|
archiveFileName.set("HMCCosmetics.jar")
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@@ -100,8 +103,8 @@ bukkit {
|
|||||||
apiVersion = "1.16"
|
apiVersion = "1.16"
|
||||||
name = "HMCCosmetics"
|
name = "HMCCosmetics"
|
||||||
authors = listOf("MasterOfTheFish")
|
authors = listOf("MasterOfTheFish")
|
||||||
softDepend = listOf("Multiverse", "PlaceholderAPI", "Oraxen", "ItemsAdder", "Citizens", "ModelEngine")
|
softDepend = listOf("Multiverse", "PlaceholderAPI", "Oraxen", "ItemsAdder", "Citizens", "ModelEngine", "packetevents")
|
||||||
depend = listOf("ProtocolLib")
|
// depend = listOf("ProtocolLib")
|
||||||
permissions {
|
permissions {
|
||||||
register("hmccosmetics.cmd.default") {
|
register("hmccosmetics.cmd.default") {
|
||||||
default = BukkitPluginDescription.Permission.Default.OP
|
default = BukkitPluginDescription.Permission.Default.OP
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package io.github.fisher2911.hmccosmetics;
|
package io.github.fisher2911.hmccosmetics;
|
||||||
|
|
||||||
import com.comphenix.protocol.ProtocolLibrary;
|
import com.github.retrooper.packetevents.PacketEvents;
|
||||||
import com.comphenix.protocol.ProtocolManager;
|
|
||||||
import io.github.fisher2911.hmccosmetics.command.CosmeticsCommand;
|
import io.github.fisher2911.hmccosmetics.command.CosmeticsCommand;
|
||||||
import io.github.fisher2911.hmccosmetics.concurrent.Threads;
|
import io.github.fisher2911.hmccosmetics.concurrent.Threads;
|
||||||
import io.github.fisher2911.hmccosmetics.config.Settings;
|
import io.github.fisher2911.hmccosmetics.config.Settings;
|
||||||
@@ -12,8 +11,8 @@ import io.github.fisher2911.hmccosmetics.database.DatabaseFactory;
|
|||||||
import io.github.fisher2911.hmccosmetics.gui.ArmorItem;
|
import io.github.fisher2911.hmccosmetics.gui.ArmorItem;
|
||||||
import io.github.fisher2911.hmccosmetics.gui.CosmeticsMenu;
|
import io.github.fisher2911.hmccosmetics.gui.CosmeticsMenu;
|
||||||
import io.github.fisher2911.hmccosmetics.gui.Token;
|
import io.github.fisher2911.hmccosmetics.gui.Token;
|
||||||
import io.github.fisher2911.hmccosmetics.hook.HookManager;
|
|
||||||
import io.github.fisher2911.hmccosmetics.hook.CitizensHook;
|
import io.github.fisher2911.hmccosmetics.hook.CitizensHook;
|
||||||
|
import io.github.fisher2911.hmccosmetics.hook.HookManager;
|
||||||
import io.github.fisher2911.hmccosmetics.hook.item.ItemsAdderHook;
|
import io.github.fisher2911.hmccosmetics.hook.item.ItemsAdderHook;
|
||||||
import io.github.fisher2911.hmccosmetics.listener.ClickListener;
|
import io.github.fisher2911.hmccosmetics.listener.ClickListener;
|
||||||
import io.github.fisher2911.hmccosmetics.listener.CosmeticFixListener;
|
import io.github.fisher2911.hmccosmetics.listener.CosmeticFixListener;
|
||||||
@@ -28,6 +27,13 @@ import io.github.fisher2911.hmccosmetics.message.Messages;
|
|||||||
import io.github.fisher2911.hmccosmetics.message.Translation;
|
import io.github.fisher2911.hmccosmetics.message.Translation;
|
||||||
import io.github.fisher2911.hmccosmetics.task.TaskManager;
|
import io.github.fisher2911.hmccosmetics.task.TaskManager;
|
||||||
import io.github.fisher2911.hmccosmetics.user.UserManager;
|
import io.github.fisher2911.hmccosmetics.user.UserManager;
|
||||||
|
import io.github.retrooper.packetevents.factory.spigot.SpigotPacketEventsBuilder;
|
||||||
|
import me.mattstudios.mf.base.CommandManager;
|
||||||
|
import me.mattstudios.mf.base.CompletionHandler;
|
||||||
|
import org.bstats.bukkit.Metrics;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
import org.bukkit.scheduler.BukkitTask;
|
||||||
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
@@ -38,18 +44,10 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import me.mattstudios.mf.base.CommandManager;
|
|
||||||
import me.mattstudios.mf.base.CompletionHandler;
|
|
||||||
import org.bstats.bukkit.Metrics;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
|
||||||
import org.bukkit.scheduler.BukkitTask;
|
|
||||||
|
|
||||||
public class HMCCosmetics extends JavaPlugin {
|
public class HMCCosmetics extends JavaPlugin {
|
||||||
|
|
||||||
public static final Path PLUGIN_FOLDER = Paths.get("plugins", "HMCCosmetics");
|
public static final Path PLUGIN_FOLDER = Paths.get("plugins", "HMCCosmetics");
|
||||||
|
|
||||||
private ProtocolManager protocolManager;
|
|
||||||
private TaskManager taskManager;
|
private TaskManager taskManager;
|
||||||
private Settings settings;
|
private Settings settings;
|
||||||
private UserManager userManager;
|
private UserManager userManager;
|
||||||
@@ -62,12 +60,18 @@ public class HMCCosmetics extends JavaPlugin {
|
|||||||
|
|
||||||
private BukkitTask saveTask;
|
private BukkitTask saveTask;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoad() {
|
||||||
|
PacketEvents.setAPI(SpigotPacketEventsBuilder.build(this));
|
||||||
|
PacketEvents.getAPI().getSettings().debug(true);
|
||||||
|
PacketEvents.getAPI().load();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
|
PacketEvents.getAPI().init();
|
||||||
final int pluginId = 13873;
|
final int pluginId = 13873;
|
||||||
final Metrics metrics = new Metrics(this, pluginId);
|
final Metrics metrics = new Metrics(this, pluginId);
|
||||||
|
|
||||||
this.protocolManager = ProtocolLibrary.getProtocolManager();
|
|
||||||
this.taskManager = new TaskManager(this);
|
this.taskManager = new TaskManager(this);
|
||||||
this.taskManager.start();
|
this.taskManager.start();
|
||||||
this.settings = new Settings(this);
|
this.settings = new Settings(this);
|
||||||
@@ -106,6 +110,7 @@ public class HMCCosmetics extends JavaPlugin {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDisable() {
|
public void onDisable() {
|
||||||
|
PacketEvents.getAPI().terminate();
|
||||||
this.saveTask.cancel();
|
this.saveTask.cancel();
|
||||||
this.database.saveAll();
|
this.database.saveAll();
|
||||||
this.messageHandler.close();
|
this.messageHandler.close();
|
||||||
@@ -237,10 +242,6 @@ public class HMCCosmetics extends JavaPlugin {
|
|||||||
return cosmeticsMenu;
|
return cosmeticsMenu;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProtocolManager getProtocolManager() {
|
|
||||||
return protocolManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Database getDatabase() {
|
public Database getDatabase() {
|
||||||
return database;
|
return database;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,111 +0,0 @@
|
|||||||
package io.github.fisher2911.hmccosmetics.api;
|
|
||||||
|
|
||||||
import io.github.fisher2911.hmccosmetics.gui.ArmorItem;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import org.bukkit.Color;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrapper for ArmorItem used internally for convenience and safety
|
|
||||||
*/
|
|
||||||
public class CosmeticItem {
|
|
||||||
|
|
||||||
private final ArmorItem armorItem;
|
|
||||||
|
|
||||||
public CosmeticItem(final ArmorItem armorItem) {
|
|
||||||
this.armorItem = armorItem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param itemStack the {@link org.bukkit.inventory.ItemStack} display item
|
|
||||||
* @param id the id of the item
|
|
||||||
* @param type the cosmetic item type
|
|
||||||
* @param dyeable whether the item can be dyed
|
|
||||||
* @param rgb from Bukkit's {@link Color#asRGB()}
|
|
||||||
*/
|
|
||||||
|
|
||||||
public CosmeticItem(
|
|
||||||
final ItemStack itemStack,
|
|
||||||
final String name,
|
|
||||||
final String id,
|
|
||||||
final ItemStack locked,
|
|
||||||
final ItemStack applied,
|
|
||||||
final String permission,
|
|
||||||
final ArmorItem.Type type,
|
|
||||||
final boolean dyeable,
|
|
||||||
final int rgb) {
|
|
||||||
this.armorItem = new ArmorItem(itemStack, name, id, locked, applied, permission, type, dyeable, rgb);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param material the {@link org.bukkit.Material} display item
|
|
||||||
* @param id the id of the item
|
|
||||||
* @param type the cosmetic item type
|
|
||||||
* @param dyeable whether the item can be dyed
|
|
||||||
* @param rgb from Bukkit's {@link Color#asRGB()}
|
|
||||||
*/
|
|
||||||
|
|
||||||
public CosmeticItem(
|
|
||||||
final Material material,
|
|
||||||
final String name,
|
|
||||||
final String id,
|
|
||||||
final Material locked,
|
|
||||||
final Material applied,
|
|
||||||
final String permission,
|
|
||||||
final ArmorItem.Type type,
|
|
||||||
final boolean dyeable,
|
|
||||||
final int rgb
|
|
||||||
) {
|
|
||||||
this.armorItem = new ArmorItem(material, name, id, new ItemStack(locked), new ItemStack(applied), permission, type, dyeable, rgb);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param itemStack the {@link org.bukkit.inventory.ItemStack} display item
|
|
||||||
* @param id the id of the item
|
|
||||||
* @param type the cosmetic item type
|
|
||||||
*/
|
|
||||||
|
|
||||||
public CosmeticItem(final ItemStack itemStack, final String name, final String id, final ItemStack locked, final ItemStack applied, final ArmorItem.Type type) {
|
|
||||||
this(itemStack, name, id, locked, applied, "", type, false, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param material the {@link org.bukkit.Material} display item
|
|
||||||
* @param id the id of the item
|
|
||||||
* @param type the cosmetic item type
|
|
||||||
*/
|
|
||||||
|
|
||||||
public CosmeticItem(final Material material, final Material locked, final Material applied, final String name, final String id, final ArmorItem.Type type) {
|
|
||||||
this(material, name, id, locked, applied, "", type, false, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ItemStack getItemStack(final ArmorItem.Status status) {
|
|
||||||
return this.armorItem.getItemStack(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ItemStack getItemStack() {
|
|
||||||
return this.armorItem.getItemStack();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getId() {
|
|
||||||
return this.armorItem.getId();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ArmorItem.Type getType() {
|
|
||||||
return this.armorItem.getType();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isDyeable() {
|
|
||||||
return this.armorItem.isDyeable();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getColor() {
|
|
||||||
return this.armorItem.getDye();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ArmorItem getArmorItem() {
|
|
||||||
return this.armorItem;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
package io.github.fisher2911.hmccosmetics.api;
|
|
||||||
|
|
||||||
import io.github.fisher2911.hmccosmetics.HMCCosmetics;
|
|
||||||
import io.github.fisher2911.hmccosmetics.gui.ArmorItem;
|
|
||||||
import io.github.fisher2911.hmccosmetics.user.User;
|
|
||||||
import io.github.fisher2911.hmccosmetics.user.UserManager;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.UUID;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
public class HMCCosmeticsAPI {
|
|
||||||
|
|
||||||
private static final HMCCosmetics plugin;
|
|
||||||
|
|
||||||
static {
|
|
||||||
plugin = HMCCosmetics.getPlugin(HMCCosmetics.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This will attempt to get the {@link io.github.fisher2911.hmccosmetics.api.CosmeticItem} that
|
|
||||||
* the user is wearing. It returns an empty {@link io.github.fisher2911.hmccosmetics.api.CosmeticItem}
|
|
||||||
* if the user is not found, or if the user is not wearing a cosmetic
|
|
||||||
*
|
|
||||||
* @param uuid the uuid of the user
|
|
||||||
* @param type the type of cosmetic being retrieved
|
|
||||||
* @return the current cosmetic of the player
|
|
||||||
*/
|
|
||||||
public static CosmeticItem getUserCurrentItem(final UUID uuid, final ArmorItem.Type type) {
|
|
||||||
final Optional<User> userOptional = plugin.getUserManager().get(uuid);
|
|
||||||
if (userOptional.isEmpty()) {
|
|
||||||
return new CosmeticItem(ArmorItem.empty(type));
|
|
||||||
}
|
|
||||||
return new CosmeticItem(userOptional.get().getPlayerArmor().getItem(type));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param uuid the uuid of the user whose cosmetic is being set
|
|
||||||
* @param cosmeticItem the cosmetic being set
|
|
||||||
* @return true if the cosmetic was set, or else false
|
|
||||||
*/
|
|
||||||
public static boolean setCosmeticItem(final UUID uuid, final CosmeticItem cosmeticItem) {
|
|
||||||
final UserManager userManager = plugin.getUserManager();
|
|
||||||
final Optional<User> userOptional = userManager.get(uuid);
|
|
||||||
if (userOptional.isEmpty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
userManager.setItem(userOptional.get(), cosmeticItem.getArmorItem());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param id the id of the cosmetic item being retrieved
|
|
||||||
* @return null if the cosmetic was not found, or a copy of the cosmetic item
|
|
||||||
*/
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public static CosmeticItem getCosmeticFromId(final String id) {
|
|
||||||
final ArmorItem armorItem = plugin.getCosmeticManager().getArmorItem(id);
|
|
||||||
if (armorItem == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return new CosmeticItem(armorItem.copy());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param uuid the uuid of the user whose armor stand id is being retrieved
|
|
||||||
* @return the armor stand id, or -1 if the user is not found
|
|
||||||
*/
|
|
||||||
|
|
||||||
public static int getUserArmorStandId(final UUID uuid) {
|
|
||||||
final Optional<User> userOptional = plugin.getUserManager().get(uuid);
|
|
||||||
if (userOptional.isEmpty()) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return userOptional.get().getArmorStandId();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
package io.github.fisher2911.hmccosmetics.api.event;
|
|
||||||
|
|
||||||
import io.github.fisher2911.hmccosmetics.api.CosmeticItem;
|
|
||||||
import io.github.fisher2911.hmccosmetics.user.BaseUser;
|
|
||||||
import io.github.fisher2911.hmccosmetics.user.User;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when a user changes their equipped cosmetic
|
|
||||||
*/
|
|
||||||
public class CosmeticChangeEvent extends CosmeticItemEvent {
|
|
||||||
|
|
||||||
private final BaseUser user;
|
|
||||||
private CosmeticItem removed;
|
|
||||||
|
|
||||||
public CosmeticChangeEvent(
|
|
||||||
final CosmeticItem cosmeticItem,
|
|
||||||
final CosmeticItem removed,
|
|
||||||
final BaseUser user) {
|
|
||||||
super(cosmeticItem);
|
|
||||||
this.removed = removed;
|
|
||||||
this.user = user;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BaseUser getUser() {
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CosmeticItem getRemoved() {
|
|
||||||
return removed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRemoved(final CosmeticItem removed) {
|
|
||||||
this.removed = removed;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
package io.github.fisher2911.hmccosmetics.api.event;
|
|
||||||
|
|
||||||
import io.github.fisher2911.hmccosmetics.api.CosmeticItem;
|
|
||||||
import org.bukkit.event.Cancellable;
|
|
||||||
import org.bukkit.event.Event;
|
|
||||||
import org.bukkit.event.HandlerList;
|
|
||||||
|
|
||||||
public abstract class CosmeticItemEvent extends Event implements Cancellable {
|
|
||||||
|
|
||||||
private static final HandlerList HANDLERS = new HandlerList();
|
|
||||||
|
|
||||||
private CosmeticItem cosmeticItem;
|
|
||||||
private boolean cancelled;
|
|
||||||
|
|
||||||
public CosmeticItemEvent(final CosmeticItem cosmeticItem) {
|
|
||||||
this.cosmeticItem = cosmeticItem;
|
|
||||||
this.cancelled = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static HandlerList getHandlerList() {
|
|
||||||
return HANDLERS;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CosmeticItem getCosmeticItem() {
|
|
||||||
return this.cosmeticItem;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCosmeticItem(final CosmeticItem cosmeticItem) {
|
|
||||||
this.cosmeticItem = cosmeticItem;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isCancelled() {
|
|
||||||
return this.cancelled;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setCancelled(final boolean cancelled) {
|
|
||||||
this.cancelled = cancelled;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public HandlerList getHandlers() {
|
|
||||||
return HANDLERS;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,454 +0,0 @@
|
|||||||
package io.github.fisher2911.hmccosmetics.command;
|
|
||||||
|
|
||||||
import io.github.fisher2911.hmccosmetics.HMCCosmetics;
|
|
||||||
import io.github.fisher2911.hmccosmetics.config.CosmeticSettings;
|
|
||||||
import io.github.fisher2911.hmccosmetics.config.Settings;
|
|
||||||
import io.github.fisher2911.hmccosmetics.config.WardrobeSettings;
|
|
||||||
import io.github.fisher2911.hmccosmetics.cosmetic.CosmeticManager;
|
|
||||||
import io.github.fisher2911.hmccosmetics.gui.ArmorItem;
|
|
||||||
import io.github.fisher2911.hmccosmetics.gui.CosmeticsMenu;
|
|
||||||
import io.github.fisher2911.hmccosmetics.gui.Token;
|
|
||||||
import io.github.fisher2911.hmccosmetics.hook.HookManager;
|
|
||||||
import io.github.fisher2911.hmccosmetics.hook.CitizensHook;
|
|
||||||
import io.github.fisher2911.hmccosmetics.message.Message;
|
|
||||||
import io.github.fisher2911.hmccosmetics.message.MessageHandler;
|
|
||||||
import io.github.fisher2911.hmccosmetics.message.Messages;
|
|
||||||
import io.github.fisher2911.hmccosmetics.message.Placeholder;
|
|
||||||
import io.github.fisher2911.hmccosmetics.task.TaskChain;
|
|
||||||
import io.github.fisher2911.hmccosmetics.user.User;
|
|
||||||
import io.github.fisher2911.hmccosmetics.user.UserManager;
|
|
||||||
import io.github.fisher2911.hmccosmetics.user.Wardrobe;
|
|
||||||
import io.github.fisher2911.hmccosmetics.util.StringUtils;
|
|
||||||
import me.mattstudios.mf.annotations.Command;
|
|
||||||
import me.mattstudios.mf.annotations.Completion;
|
|
||||||
import me.mattstudios.mf.annotations.Default;
|
|
||||||
import me.mattstudios.mf.annotations.Permission;
|
|
||||||
import me.mattstudios.mf.annotations.SubCommand;
|
|
||||||
import me.mattstudios.mf.base.CommandBase;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Color;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
@Command("cosmetics")
|
|
||||||
public class CosmeticsCommand extends CommandBase {
|
|
||||||
|
|
||||||
private final HMCCosmetics plugin;
|
|
||||||
private final UserManager userManager;
|
|
||||||
private final MessageHandler messageHandler;
|
|
||||||
private final CosmeticsMenu cosmeticsMenu;
|
|
||||||
private final CosmeticManager cosmeticManager;
|
|
||||||
private final Settings settings;
|
|
||||||
private final CosmeticSettings cosmeticSettings;
|
|
||||||
|
|
||||||
public CosmeticsCommand(final HMCCosmetics plugin) {
|
|
||||||
this.plugin = plugin;
|
|
||||||
this.userManager = this.plugin.getUserManager();
|
|
||||||
this.messageHandler = this.plugin.getMessageHandler();
|
|
||||||
this.cosmeticsMenu = this.plugin.getCosmeticsMenu();
|
|
||||||
this.cosmeticManager = this.plugin.getCosmeticManager();
|
|
||||||
this.settings = this.plugin.getSettings();
|
|
||||||
this.cosmeticSettings = this.settings.getCosmeticSettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Default
|
|
||||||
@Permission(io.github.fisher2911.hmccosmetics.message.Permission.DEFAULT_COMMAND)
|
|
||||||
public void defaultCommand(final Player player) {
|
|
||||||
this.defaultCommand(player, this.cosmeticSettings.getDefaultMenu());
|
|
||||||
}
|
|
||||||
|
|
||||||
@SubCommand("menu")
|
|
||||||
@Permission(io.github.fisher2911.hmccosmetics.message.Permission.DEFAULT_COMMAND)
|
|
||||||
public void defaultCommand(final Player player, @Completion("#menus") @me.mattstudios.mf.annotations.Optional String menu) {
|
|
||||||
final Optional<User> optionalUser = this.userManager.get(player.getUniqueId());
|
|
||||||
if (menu == null) menu = this.cosmeticSettings.getDefaultMenu();
|
|
||||||
if (optionalUser.isEmpty()) {
|
|
||||||
this.cosmeticsMenu.openMenu(menu, player);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final User user = optionalUser.get();
|
|
||||||
final Wardrobe wardrobe = user.getWardrobe();
|
|
||||||
if (wardrobe.isActive() &&
|
|
||||||
!this.settings.getWardrobeSettings().inDistanceOfWardrobe(wardrobe.getCurrentLocation(), player.getLocation())) {
|
|
||||||
wardrobe.setActive(false);
|
|
||||||
wardrobe.despawnFakePlayer(player, userManager);
|
|
||||||
this.messageHandler.sendMessage(
|
|
||||||
player,
|
|
||||||
Messages.CLOSED_WARDROBE
|
|
||||||
);
|
|
||||||
}
|
|
||||||
this.cosmeticsMenu.openMenu(menu, player);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SubCommand("reload")
|
|
||||||
@Permission(io.github.fisher2911.hmccosmetics.message.Permission.RELOAD_COMMAND)
|
|
||||||
public void reloadCommand(final CommandSender sender) {
|
|
||||||
Bukkit.getScheduler().runTaskAsynchronously(
|
|
||||||
this.plugin,
|
|
||||||
() -> {
|
|
||||||
this.plugin.reload();
|
|
||||||
this.messageHandler.sendMessage(
|
|
||||||
sender,
|
|
||||||
Messages.RELOADED
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SubCommand("dye")
|
|
||||||
@Permission(io.github.fisher2911.hmccosmetics.message.Permission.DYE_COMMAND)
|
|
||||||
public void dyeArmor(
|
|
||||||
final Player player,
|
|
||||||
@Completion("#types") String typeString,
|
|
||||||
final @me.mattstudios.mf.annotations.Optional String dyeColor
|
|
||||||
) {
|
|
||||||
|
|
||||||
final Optional<User> optionalUser = this.userManager.get(player.getUniqueId());
|
|
||||||
|
|
||||||
if (optionalUser.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
final ArmorItem.Type type = ArmorItem.Type.valueOf(typeString.toUpperCase());
|
|
||||||
|
|
||||||
final User user = optionalUser.get();
|
|
||||||
|
|
||||||
if (dyeColor == null) {
|
|
||||||
this.cosmeticsMenu.openDyeSelectorGui(user, type);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final ArmorItem armorItem = user.getPlayerArmor().getItem(type);
|
|
||||||
|
|
||||||
this.setDyeColor(dyeColor, armorItem, player);
|
|
||||||
|
|
||||||
this.userManager.setItem(user, armorItem);
|
|
||||||
|
|
||||||
this.messageHandler.sendMessage(
|
|
||||||
player,
|
|
||||||
Messages.SET_DYE_COLOR,
|
|
||||||
Map.of(Placeholder.ITEM, StringUtils.formatArmorItemType(typeString))
|
|
||||||
);
|
|
||||||
|
|
||||||
} catch (final IllegalArgumentException exception) {
|
|
||||||
this.messageHandler.sendMessage(
|
|
||||||
player,
|
|
||||||
Messages.INVALID_TYPE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SubCommand("help") // WORK IN PROGRESS (WIP)
|
|
||||||
@Permission(io.github.fisher2911.hmccosmetics.message.Permission.HELP_COMMAND)
|
|
||||||
public void helpCommand(final CommandSender sender) {
|
|
||||||
this.messageHandler.sendMessage(
|
|
||||||
sender,
|
|
||||||
Messages.HELP_COMMAND
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SubCommand("add")
|
|
||||||
@Permission(io.github.fisher2911.hmccosmetics.message.Permission.SET_COSMETIC_COMMAND)
|
|
||||||
public void setCommand(
|
|
||||||
final CommandSender sender,
|
|
||||||
@Completion("#players") final Player player,
|
|
||||||
@Completion("#ids") final String id,
|
|
||||||
final @me.mattstudios.mf.annotations.Optional String dyeColor
|
|
||||||
) {
|
|
||||||
final Optional<User> userOptional = this.userManager.get(player.getUniqueId());
|
|
||||||
|
|
||||||
if (userOptional.isEmpty()) {
|
|
||||||
this.messageHandler.sendMessage(
|
|
||||||
sender,
|
|
||||||
Messages.INVALID_USER
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final User user = userOptional.get();
|
|
||||||
final ArmorItem armorItem = this.plugin.getCosmeticManager().getArmorItem(id);
|
|
||||||
|
|
||||||
if (armorItem == null) {
|
|
||||||
this.messageHandler.sendMessage(
|
|
||||||
sender,
|
|
||||||
Messages.ITEM_NOT_FOUND
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dyeColor != null) {
|
|
||||||
this.setDyeColor(dyeColor, armorItem, player);
|
|
||||||
}
|
|
||||||
|
|
||||||
final Message setMessage = Messages.getSetMessage(armorItem.getType());
|
|
||||||
final Message setOtherMessage = Messages.getSetOtherMessage(armorItem.getType());
|
|
||||||
this.userManager.setItem(user, armorItem);
|
|
||||||
this.messageHandler.sendMessage(
|
|
||||||
player,
|
|
||||||
setMessage
|
|
||||||
);
|
|
||||||
this.messageHandler.sendMessage(
|
|
||||||
sender,
|
|
||||||
setOtherMessage,
|
|
||||||
Map.of(Placeholder.PLAYER, player.getName(),
|
|
||||||
Placeholder.TYPE, id)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SubCommand("remove")
|
|
||||||
@Permission(io.github.fisher2911.hmccosmetics.message.Permission.SET_COSMETIC_COMMAND)
|
|
||||||
public void removeCommand(final CommandSender sender,
|
|
||||||
@Completion("#players") final Player player, @Completion("#types") String typeString) {
|
|
||||||
final Optional<User> userOptional = this.userManager.get(player.getUniqueId());
|
|
||||||
|
|
||||||
if (userOptional.isEmpty()) {
|
|
||||||
this.messageHandler.sendMessage(
|
|
||||||
sender,
|
|
||||||
Messages.INVALID_USER
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final User user = userOptional.get();
|
|
||||||
|
|
||||||
try {
|
|
||||||
final ArmorItem.Type type = ArmorItem.Type.valueOf(typeString.toUpperCase());
|
|
||||||
|
|
||||||
final Message setOtherMessage = Messages.getSetOtherMessage(type);
|
|
||||||
this.userManager.removeItem(user, type);
|
|
||||||
this.messageHandler.sendMessage(
|
|
||||||
sender,
|
|
||||||
setOtherMessage,
|
|
||||||
Map.of(Placeholder.PLAYER, player.getName(),
|
|
||||||
Placeholder.TYPE, "none")
|
|
||||||
);
|
|
||||||
} catch (final IllegalArgumentException exception) {
|
|
||||||
this.messageHandler.sendMessage(player, Messages.INVALID_TYPE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SubCommand("wardrobe")
|
|
||||||
@Permission(io.github.fisher2911.hmccosmetics.message.Permission.WARDROBE)
|
|
||||||
public void openWardrobe(Player player, @me.mattstudios.mf.annotations.Optional final Player other) {
|
|
||||||
if (other != null) {
|
|
||||||
if (!player.hasPermission(io.github.fisher2911.hmccosmetics.message.Permission.OPEN_OTHER_WARDROBE)) {
|
|
||||||
this.messageHandler.sendMessage(
|
|
||||||
player,
|
|
||||||
Messages.NO_PERMISSION
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.messageHandler.sendMessage(
|
|
||||||
player,
|
|
||||||
Messages.OPENED_OTHER_WARDROBE,
|
|
||||||
Map.of(Placeholder.PLAYER, other.getName())
|
|
||||||
);
|
|
||||||
player = other;
|
|
||||||
}
|
|
||||||
final Optional<User> optionalUser = this.plugin.getUserManager().get(player.getUniqueId());
|
|
||||||
if (optionalUser.isEmpty()) return;
|
|
||||||
|
|
||||||
final User user = optionalUser.get();
|
|
||||||
|
|
||||||
final Wardrobe wardrobe = user.getWardrobe();
|
|
||||||
if (wardrobe.isActive()) {
|
|
||||||
this.messageHandler.sendMessage(
|
|
||||||
player,
|
|
||||||
Messages.WARDROBE_ALREADY_OPEN
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final WardrobeSettings settings = this.settings.getWardrobeSettings();
|
|
||||||
|
|
||||||
final boolean inDistanceOfStatic = settings.inDistanceOfStatic(player.getLocation());
|
|
||||||
|
|
||||||
if (!settings.isPortable() && !inDistanceOfStatic) {
|
|
||||||
this.messageHandler.sendMessage(
|
|
||||||
player,
|
|
||||||
Messages.NOT_NEAR_WARDROBE
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (settings.isPortable() && !inDistanceOfStatic) {
|
|
||||||
if (!player.hasPermission(io.github.fisher2911.hmccosmetics.message.Permission.PORTABLE_WARDROBE)) {
|
|
||||||
this.messageHandler.sendMessage(
|
|
||||||
player,
|
|
||||||
Messages.CANNOT_USE_PORTABLE_WARDROBE
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
wardrobe.setCurrentLocation(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
wardrobe.setActive(true);
|
|
||||||
settings.playOpenSound(player);
|
|
||||||
|
|
||||||
final Player finalPlayer = player;
|
|
||||||
new TaskChain(this.plugin).
|
|
||||||
chain(() -> {
|
|
||||||
wardrobe.spawnFakePlayer(finalPlayer);
|
|
||||||
}, true).
|
|
||||||
chain(() -> {
|
|
||||||
// this.cosmeticsMenu.openDefault(finalPlayer);
|
|
||||||
this.messageHandler.sendMessage(
|
|
||||||
finalPlayer,
|
|
||||||
Messages.OPENED_WARDROBE
|
|
||||||
);
|
|
||||||
}).execute();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final String NPC_APPLY = "apply";
|
|
||||||
public static final String NPC_REMOVE = "remove";
|
|
||||||
|
|
||||||
@SubCommand("npc")
|
|
||||||
@Permission(io.github.fisher2911.hmccosmetics.message.Permission.SET_COSMETIC_COMMAND)
|
|
||||||
public void applyNpc(
|
|
||||||
final CommandSender sender,
|
|
||||||
@Completion("#npc-args") final String arg,
|
|
||||||
@Completion("#npcs") final Integer npcId,
|
|
||||||
@Completion("#types") final String typeStr,
|
|
||||||
@me.mattstudios.mf.annotations.Optional @Completion("#ids") final String itemId
|
|
||||||
) {
|
|
||||||
final CitizensHook citizensHook = HookManager.getInstance().getCitizensHook();
|
|
||||||
if (citizensHook == null) {
|
|
||||||
this.messageHandler.sendMessage(
|
|
||||||
sender,
|
|
||||||
Messages.HOOK_NOT_ENABLED,
|
|
||||||
Map.of(Placeholder.TYPE, "Citizens")
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (npcId == null) {
|
|
||||||
this.messageHandler.sendMessage(
|
|
||||||
sender,
|
|
||||||
new Message("illegal-npc-id", "<red>" + "Invalid NPC id specified: " + npcId)
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final ArmorItem armorItem = this.plugin.getCosmeticManager().getArmorItem(itemId);
|
|
||||||
if (armorItem == null) {
|
|
||||||
this.messageHandler.sendMessage(
|
|
||||||
sender,
|
|
||||||
Messages.ITEM_NOT_FOUND
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
switch (arg.toLowerCase(Locale.ROOT)) {
|
|
||||||
case NPC_APPLY -> {
|
|
||||||
this.setNpcCosmetic(citizensHook, sender, npcId, armorItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
case NPC_REMOVE -> {
|
|
||||||
try {
|
|
||||||
final ArmorItem.Type type = ArmorItem.Type.valueOf(typeStr);
|
|
||||||
this.setNpcCosmetic(citizensHook, sender, npcId, ArmorItem.empty(type, "none"));
|
|
||||||
|
|
||||||
} catch (final IllegalArgumentException exception) {
|
|
||||||
this.messageHandler.sendMessage(
|
|
||||||
sender,
|
|
||||||
Messages.INVALID_TYPE,
|
|
||||||
Map.of(Placeholder.TYPE, typeStr)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SubCommand("hide")
|
|
||||||
public void hide(final Player player) {
|
|
||||||
final Optional<User> optionalUser = this.userManager.get(player.getUniqueId());
|
|
||||||
if (optionalUser.isEmpty()) return;
|
|
||||||
final User user = optionalUser.get();
|
|
||||||
if (user.isHidden()) {
|
|
||||||
user.setHidden(false);
|
|
||||||
this.messageHandler.sendMessage(
|
|
||||||
player,
|
|
||||||
Messages.SHOWN_COSMETICS
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
user.setHidden(true);
|
|
||||||
this.messageHandler.sendMessage(
|
|
||||||
player,
|
|
||||||
Messages.HID_COSMETICS
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SubCommand("token")
|
|
||||||
@Permission(io.github.fisher2911.hmccosmetics.message.Permission.GIVE_TOKEN)
|
|
||||||
public void token(
|
|
||||||
final CommandSender sender,
|
|
||||||
@Completion("#tokens") final String tokenId,
|
|
||||||
@Completion("#players") @me.mattstudios.mf.annotations.Optional Player giveTo) {
|
|
||||||
if (!(sender instanceof Player) && giveTo == null) {
|
|
||||||
this.messageHandler.sendMessage(
|
|
||||||
sender,
|
|
||||||
Messages.MUST_BE_PLAYER
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (giveTo == null) {
|
|
||||||
giveTo = ((Player) sender);
|
|
||||||
}
|
|
||||||
final Token token = this.cosmeticManager.getToken(tokenId);
|
|
||||||
if (token == null) {
|
|
||||||
this.messageHandler.sendMessage(
|
|
||||||
sender,
|
|
||||||
Messages.ITEM_NOT_FOUND
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
giveTo.getInventory().addItem(token.getItemStack().clone());
|
|
||||||
final String tokenName = token.getArmorItem().getName();
|
|
||||||
this.messageHandler.sendMessage(
|
|
||||||
sender,
|
|
||||||
Messages.GAVE_TOKEN,
|
|
||||||
Map.of(Placeholder.ID, tokenName,
|
|
||||||
Placeholder.PLAYER, giveTo.getDisplayName())
|
|
||||||
);
|
|
||||||
this.messageHandler.sendMessage(
|
|
||||||
giveTo,
|
|
||||||
Messages.RECEIVED_TOKEN,
|
|
||||||
Map.of(Placeholder.ID, tokenName)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setNpcCosmetic(final CitizensHook hook, final CommandSender sender, final int npcId, final ArmorItem item) {
|
|
||||||
final boolean isSet = hook.setNpcCosmetic(npcId, item);
|
|
||||||
if (!isSet) {
|
|
||||||
this.messageHandler.sendMessage(
|
|
||||||
sender,
|
|
||||||
Messages.NPC_NOT_FOUND,
|
|
||||||
Map.of(Placeholder.ID, String.valueOf(npcId))
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.messageHandler.sendMessage(
|
|
||||||
sender,
|
|
||||||
Messages.SET_NPC_COSMETIC,
|
|
||||||
Map.of(Placeholder.TYPE, item.getType().toString(),
|
|
||||||
Placeholder.ITEM, item.getId(),
|
|
||||||
Placeholder.ID, String.valueOf(npcId))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setDyeColor(final String dyeColor, final ArmorItem armorItem, final CommandSender sender) {
|
|
||||||
try {
|
|
||||||
final java.awt.Color awtColor = java.awt.Color.decode(dyeColor);
|
|
||||||
Color color = Color.fromRGB(awtColor.getRed(), awtColor.getGreen(), awtColor.getBlue());
|
|
||||||
armorItem.setDye(color.asRGB());
|
|
||||||
} catch (final NumberFormatException exception) {
|
|
||||||
this.messageHandler.sendMessage(
|
|
||||||
sender,
|
|
||||||
Messages.INVALID_COLOR,
|
|
||||||
Map.of(Placeholder.ITEM, dyeColor)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
package io.github.fisher2911.hmccosmetics.concurrent;
|
|
||||||
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
|
|
||||||
public class Threads {
|
|
||||||
|
|
||||||
private static final Threads INSTANCE;
|
|
||||||
|
|
||||||
static {
|
|
||||||
INSTANCE = new Threads();
|
|
||||||
}
|
|
||||||
|
|
||||||
private final ExecutorService service;
|
|
||||||
|
|
||||||
private Threads() {
|
|
||||||
this.service = Executors.newFixedThreadPool(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Threads getInstance() {
|
|
||||||
return INSTANCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void execute(final Runnable runnable) {
|
|
||||||
this.service.execute(runnable);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onDisable() {
|
|
||||||
this.service.shutdownNow().forEach(Runnable::run);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,281 +0,0 @@
|
|||||||
package io.github.fisher2911.hmccosmetics.config;
|
|
||||||
|
|
||||||
import dev.triumphteam.gui.guis.GuiItem;
|
|
||||||
import io.github.fisher2911.hmccosmetics.HMCCosmetics;
|
|
||||||
import io.github.fisher2911.hmccosmetics.cosmetic.CosmeticManager;
|
|
||||||
import io.github.fisher2911.hmccosmetics.gui.ArmorItem;
|
|
||||||
import io.github.fisher2911.hmccosmetics.gui.CosmeticGui;
|
|
||||||
import io.github.fisher2911.hmccosmetics.message.Message;
|
|
||||||
import io.github.fisher2911.hmccosmetics.message.MessageHandler;
|
|
||||||
import io.github.fisher2911.hmccosmetics.message.Placeholder;
|
|
||||||
import io.github.fisher2911.hmccosmetics.user.User;
|
|
||||||
import io.github.fisher2911.hmccosmetics.user.UserManager;
|
|
||||||
import io.github.fisher2911.hmccosmetics.util.Utils;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.inventory.ClickType;
|
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
|
||||||
import org.spongepowered.configurate.ConfigurateException;
|
|
||||||
import org.spongepowered.configurate.ConfigurationNode;
|
|
||||||
import org.spongepowered.configurate.serialize.SerializationException;
|
|
||||||
import org.spongepowered.configurate.serialize.TypeSerializer;
|
|
||||||
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public class ActionSerializer implements TypeSerializer<List<CosmeticGuiAction>> {
|
|
||||||
|
|
||||||
public static final ActionSerializer INSTANCE = new ActionSerializer();
|
|
||||||
private static final HMCCosmetics plugin;
|
|
||||||
|
|
||||||
private static final String OPEN_MENU = "open-menu";
|
|
||||||
private static final String SET_ITEMS = "set-items";
|
|
||||||
private static final String REMOVE_COSMETICS = "remove-cosmetics";
|
|
||||||
private static final String SET_COSMETICS = "set-cosmetics";
|
|
||||||
private static final String SEND_MESSAGE = "send-message";
|
|
||||||
private static final String SEND_MESSAGES = "send-messages";
|
|
||||||
private static final String SEND_COMMAND = "send-command";
|
|
||||||
private static final String SEND_COMMANDS = "send-commands";
|
|
||||||
private static final String SOUND = "sound";
|
|
||||||
|
|
||||||
static {
|
|
||||||
plugin = HMCCosmetics.getPlugin(HMCCosmetics.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
private ActionSerializer() {
|
|
||||||
}
|
|
||||||
|
|
||||||
private ConfigurationNode nonVirtualNode(final ConfigurationNode source, final Object... path)
|
|
||||||
throws SerializationException {
|
|
||||||
if (!source.hasChild(path)) {
|
|
||||||
throw new SerializationException(
|
|
||||||
"Required field " + Arrays.toString(path) + " was not present in node");
|
|
||||||
}
|
|
||||||
|
|
||||||
return source.node(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<CosmeticGuiAction> deserialize(final Type type, final ConfigurationNode source) {
|
|
||||||
return this.deserialize(type, new ArrayList<>(), source, CosmeticGuiAction.When.ALL);
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<CosmeticGuiAction> deserialize(
|
|
||||||
final Type type,
|
|
||||||
final List<CosmeticGuiAction> consumers,
|
|
||||||
final ConfigurationNode source,
|
|
||||||
final CosmeticGuiAction.When when) {
|
|
||||||
final var children = source.childrenMap();
|
|
||||||
for (final var entry : children.entrySet()) {
|
|
||||||
final String clickType = entry.getKey().toString();
|
|
||||||
try {
|
|
||||||
final CosmeticGuiAction.When nextWhen = CosmeticGuiAction.When.valueOf(clickType.toUpperCase());
|
|
||||||
this.deserialize(type, consumers, entry.getValue(), nextWhen);
|
|
||||||
} catch (final IllegalArgumentException exception) {
|
|
||||||
consumers.add(this.parseAction(entry.getValue(), clickType.toUpperCase(Locale.ROOT), when));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return consumers;
|
|
||||||
}
|
|
||||||
|
|
||||||
private CosmeticGuiAction parseAction(
|
|
||||||
final ConfigurationNode node,
|
|
||||||
final String clickType,
|
|
||||||
final CosmeticGuiAction.When when
|
|
||||||
) {
|
|
||||||
final ConfigurationNode openMenuNode = node.node(OPEN_MENU);
|
|
||||||
final ConfigurationNode setItemsNode = node.node(SET_ITEMS);
|
|
||||||
final ConfigurationNode removeItemsNode = node.node(REMOVE_COSMETICS);
|
|
||||||
final ConfigurationNode setCosmeticsNode = node.node(SET_COSMETICS);
|
|
||||||
final ConfigurationNode soundNode = node.node(SOUND);
|
|
||||||
|
|
||||||
final String openMenu = openMenuNode.getString();
|
|
||||||
|
|
||||||
final List<ArmorItem.Type> removeCosmeticTypes = this.loadRemoveTypes(removeItemsNode);
|
|
||||||
final List<String> setCosmetics = this.loadSetCosmetics(setCosmeticsNode);
|
|
||||||
|
|
||||||
final ClickType click = Utils.stringToEnum(clickType, ClickType.class, ClickType.UNKNOWN);
|
|
||||||
final Map<Integer, GuiItem> setItems = this.loadSetItems(setItemsNode);
|
|
||||||
|
|
||||||
final Consumer<Player> messageConsumer = this.loadMessages(node, plugin);
|
|
||||||
final SoundData soundData = this.loadSoundData(soundNode);
|
|
||||||
|
|
||||||
return new CosmeticGuiAction(
|
|
||||||
when,
|
|
||||||
event -> {
|
|
||||||
if (click != ClickType.UNKNOWN && event.getClick() != click) return;
|
|
||||||
if (!(event.getWhoClicked() instanceof final Player player)) return;
|
|
||||||
|
|
||||||
if (soundData != null) {
|
|
||||||
soundData.play(player);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (openMenu != null) plugin.getCosmeticsMenu().openMenu(openMenu, event.getWhoClicked());
|
|
||||||
messageConsumer.accept(player);
|
|
||||||
final UserManager userManager = plugin.getUserManager();
|
|
||||||
final Optional<User> optionalUser = userManager.get(player.getUniqueId());
|
|
||||||
if (optionalUser.isEmpty()) return;
|
|
||||||
final User user = optionalUser.get();
|
|
||||||
final CosmeticManager cosmeticManager = plugin.getCosmeticManager();
|
|
||||||
for (final String id : setCosmetics) {
|
|
||||||
final ArmorItem armorItem = cosmeticManager.getArmorItem(id);
|
|
||||||
if (armorItem == null) continue;
|
|
||||||
userManager.setItem(user, armorItem);
|
|
||||||
}
|
|
||||||
for (final ArmorItem.Type type : removeCosmeticTypes) {
|
|
||||||
userManager.removeItem(user, type);
|
|
||||||
}
|
|
||||||
final CosmeticGui gui = user.getOpenGui();
|
|
||||||
if (gui != null) {
|
|
||||||
for (final var entry : setItems.entrySet()) {
|
|
||||||
final GuiItem item = entry.getValue();
|
|
||||||
gui.updateItem(entry.getKey(), item, user, player);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Map<Integer, GuiItem> loadSetItems(final ConfigurationNode node) {
|
|
||||||
if (node.virtual()) return Collections.emptyMap();
|
|
||||||
final Map<Integer, GuiItem> setItems = new HashMap<>();
|
|
||||||
try {
|
|
||||||
for (final var entry : node.childrenMap().entrySet()) {
|
|
||||||
if (!(entry.getKey() instanceof final Integer slot)) continue;
|
|
||||||
final var key = entry.getValue();
|
|
||||||
final GuiItem guiItem = ArmorItemSerializer.INSTANCE.deserialize(GuiItem.class, key);
|
|
||||||
if (guiItem == null) continue;
|
|
||||||
setItems.put(slot, guiItem);
|
|
||||||
}
|
|
||||||
} catch (final SerializationException exception) {
|
|
||||||
HMCCosmetics.getPlugin(HMCCosmetics.class).getLogger().severe(
|
|
||||||
"Error loading set-items"
|
|
||||||
);
|
|
||||||
return Collections.emptyMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
return setItems;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final String CONSOLE = "console";
|
|
||||||
private static final String PLAYER = "player";
|
|
||||||
|
|
||||||
private Consumer<Player> loadMessages(final ConfigurationNode source, final HMCCosmetics plugin) {
|
|
||||||
final ConfigurationNode messageNode = source.node(SEND_MESSAGE);
|
|
||||||
final ConfigurationNode messagesNode = source.node(SEND_MESSAGES);
|
|
||||||
final ConfigurationNode commandNode = source.node(SEND_COMMAND);
|
|
||||||
final ConfigurationNode commandsNode = source.node(SEND_COMMANDS);
|
|
||||||
|
|
||||||
final List<String> messages = new ArrayList<>();
|
|
||||||
final List<String> commands = new ArrayList<>();
|
|
||||||
|
|
||||||
final String message = messageNode.getString();
|
|
||||||
if (message != null) messages.add(message);
|
|
||||||
final String command = commandNode.getString();
|
|
||||||
if (command != null) commands.add(command);
|
|
||||||
|
|
||||||
for (final var node : messagesNode.childrenList()) {
|
|
||||||
final String listMessage = node.getString();
|
|
||||||
if (listMessage == null) continue;
|
|
||||||
messages.add(listMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (final var node : commandsNode.childrenList()) {
|
|
||||||
final String commandMessage = node.getString();
|
|
||||||
if (commandMessage == null) continue;
|
|
||||||
commands.add(commandMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
return player -> {
|
|
||||||
final String playerName = player.getName();
|
|
||||||
final Map<String, String> placeholders = Map.of(Placeholder.PLAYER, playerName);
|
|
||||||
final MessageHandler messageHandler = plugin.getMessageHandler();
|
|
||||||
for (final String sendMessage : messages) {
|
|
||||||
messageHandler.sendMessage(
|
|
||||||
player,
|
|
||||||
new Message("", sendMessage),
|
|
||||||
placeholders
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (final String sendCommand : commands) {
|
|
||||||
final String[] parts = sendCommand.split(":");
|
|
||||||
if (parts.length < 2) {
|
|
||||||
Bukkit.dispatchCommand(
|
|
||||||
Bukkit.getConsoleSender(),
|
|
||||||
sendCommand.replace(Placeholder.PLAYER, playerName)
|
|
||||||
);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
final String sender = parts[0];
|
|
||||||
final String commandToSend = parts[1];
|
|
||||||
|
|
||||||
if (sender.equalsIgnoreCase(CONSOLE)) {
|
|
||||||
Bukkit.dispatchCommand(
|
|
||||||
Bukkit.getConsoleSender(),
|
|
||||||
commandToSend.replace(Placeholder.PLAYER, playerName)
|
|
||||||
);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
player.chat("/" + commandToSend.replace(Placeholder.PLAYER, playerName));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<ArmorItem.Type> loadRemoveTypes(final ConfigurationNode node) {
|
|
||||||
try {
|
|
||||||
final List<String> typeStrings = node.getList(String.class);
|
|
||||||
if (typeStrings == null) return new ArrayList<>();
|
|
||||||
return typeStrings.stream().map(
|
|
||||||
string -> {
|
|
||||||
try {
|
|
||||||
return ArmorItem.Type.valueOf(string.toUpperCase(Locale.ROOT));
|
|
||||||
} catch (final IllegalArgumentException exception) {
|
|
||||||
plugin.getLogger().severe(string + " is not a valid cosmetic type.");
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
).
|
|
||||||
filter(type -> type != null).
|
|
||||||
collect(Collectors.toList());
|
|
||||||
} catch (final SerializationException exception) {
|
|
||||||
exception.printStackTrace();
|
|
||||||
}
|
|
||||||
return new ArrayList<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
private SoundData loadSoundData(final ConfigurationNode node) {
|
|
||||||
try {
|
|
||||||
return SoundSerializer.INSTANCE.deserialize(SoundData.class, node);
|
|
||||||
} catch (final ConfigurateException exception) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<String> loadSetCosmetics(final ConfigurationNode node) {
|
|
||||||
try {
|
|
||||||
return node.getList(String.class);
|
|
||||||
} catch (final ConfigurateException exception) {
|
|
||||||
return new ArrayList<>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void serialize(final Type type, @Nullable final List<CosmeticGuiAction> obj, final ConfigurationNode node) throws SerializationException {
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,150 +0,0 @@
|
|||||||
package io.github.fisher2911.hmccosmetics.config;
|
|
||||||
|
|
||||||
import dev.triumphteam.gui.components.GuiAction;
|
|
||||||
import dev.triumphteam.gui.guis.GuiItem;
|
|
||||||
import io.github.fisher2911.hmccosmetics.gui.ArmorItem;
|
|
||||||
import io.github.fisher2911.hmccosmetics.gui.BalloonItem;
|
|
||||||
import io.github.fisher2911.hmccosmetics.gui.WrappedGuiItem;
|
|
||||||
import io.github.fisher2911.hmccosmetics.util.StringUtils;
|
|
||||||
import io.github.fisher2911.hmccosmetics.util.Utils;
|
|
||||||
import io.github.fisher2911.hmccosmetics.util.builder.ItemBuilder;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
|
||||||
import org.spongepowered.configurate.ConfigurationNode;
|
|
||||||
import org.spongepowered.configurate.serialize.SerializationException;
|
|
||||||
import org.spongepowered.configurate.serialize.TypeSerializer;
|
|
||||||
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public class ArmorItemSerializer implements TypeSerializer<WrappedGuiItem> {
|
|
||||||
|
|
||||||
public static final ArmorItemSerializer INSTANCE = new ArmorItemSerializer();
|
|
||||||
|
|
||||||
private ArmorItemSerializer() {
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final String NAME = "name";
|
|
||||||
private static final String LOCKED_LORE = "locked-lore";
|
|
||||||
private static final String APPLIED_LORE = "applied-lore";
|
|
||||||
private static final String LOCKED_ITEM = "locked-item";
|
|
||||||
private static final String APPLIED_ITEM = "applied-item";
|
|
||||||
private static final String PERMISSION = "permission";
|
|
||||||
private static final String TYPE = "type";
|
|
||||||
private static final String ACTION = "action";
|
|
||||||
private static final String ID = "id";
|
|
||||||
private static final String DYEABLE = "dyeable";
|
|
||||||
private static final String BALLOON_MODEL_ID = "balloon";
|
|
||||||
|
|
||||||
private ConfigurationNode nonVirtualNode(final ConfigurationNode source, final Object... path)
|
|
||||||
throws SerializationException {
|
|
||||||
if (!source.hasChild(path)) {
|
|
||||||
throw new SerializationException(
|
|
||||||
"Required field " + Arrays.toString(path) + " was not present in node");
|
|
||||||
}
|
|
||||||
|
|
||||||
return source.node(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public WrappedGuiItem deserialize(final Type type, final ConfigurationNode source)
|
|
||||||
throws SerializationException {
|
|
||||||
final ConfigurationNode nameNode = source.node(NAME);
|
|
||||||
final ConfigurationNode lockedLoreNode = source.node(LOCKED_LORE);
|
|
||||||
final ConfigurationNode appliedLoreNode = source.node(APPLIED_LORE);
|
|
||||||
final ConfigurationNode lockedItemNode = source.node(LOCKED_ITEM);
|
|
||||||
final ConfigurationNode appliedItemNode = source.node(APPLIED_ITEM);
|
|
||||||
final ConfigurationNode permissionNode = source.node(PERMISSION);
|
|
||||||
final ConfigurationNode typeNode = source.node(TYPE);
|
|
||||||
final ConfigurationNode actionNode = source.node(ACTION);
|
|
||||||
final ConfigurationNode idNode = source.node(ID);
|
|
||||||
final ConfigurationNode dyeableNode = source.node(DYEABLE);
|
|
||||||
final ConfigurationNode balloonModelIdNode = source.node(BALLOON_MODEL_ID);
|
|
||||||
|
|
||||||
final ItemStack itemStack = Utils.replaceIfNull(
|
|
||||||
ItemSerializer.INSTANCE.deserialize(ItemStack.class, source),
|
|
||||||
new ItemStack(Material.AIR)
|
|
||||||
);
|
|
||||||
ItemStack lockedItem = ItemSerializer.INSTANCE.deserialize(ItemStack.class, lockedItemNode);
|
|
||||||
if (lockedItem == null) {
|
|
||||||
final List<String> lockedLore = Utils.replaceIfNull(lockedLoreNode.getList(String.class),
|
|
||||||
new ArrayList<String>()).
|
|
||||||
stream().map(StringUtils::parseStringToString).collect(Collectors.toList());
|
|
||||||
lockedItem = ItemBuilder.from(itemStack.clone()).lore(lockedLore).build();
|
|
||||||
}
|
|
||||||
ItemStack appliedItem = ItemSerializer.INSTANCE.deserialize(ItemStack.class, appliedItemNode);
|
|
||||||
if (appliedItem == null) {
|
|
||||||
final List<String> appliedLore = Utils.replaceIfNull(appliedLoreNode.getList(String.class),
|
|
||||||
new ArrayList<String>()).
|
|
||||||
stream().map(StringUtils::parseStringToString).collect(Collectors.toList());
|
|
||||||
appliedItem = ItemBuilder.from(itemStack.clone()).lore(appliedLore).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
final boolean dyeable = dyeableNode.getBoolean();
|
|
||||||
|
|
||||||
final List<CosmeticGuiAction> actions = ActionSerializer.INSTANCE.deserialize(GuiAction.class, actionNode);
|
|
||||||
|
|
||||||
try {
|
|
||||||
final ArmorItem.Type cosmeticType = ArmorItem.Type.valueOf(
|
|
||||||
Utils.replaceIfNull(
|
|
||||||
typeNode.getString(), ""
|
|
||||||
).toUpperCase(Locale.ROOT)
|
|
||||||
);
|
|
||||||
|
|
||||||
final String permission = permissionNode.getString();
|
|
||||||
|
|
||||||
if (cosmeticType == ArmorItem.Type.BALLOON) {
|
|
||||||
return new BalloonItem(
|
|
||||||
itemStack,
|
|
||||||
actions,
|
|
||||||
Utils.replaceIfNull(nameNode.getString(), ""),
|
|
||||||
Utils.replaceIfNull(idNode.getString(), ""),
|
|
||||||
lockedItem,
|
|
||||||
appliedItem,
|
|
||||||
permission,
|
|
||||||
cosmeticType,
|
|
||||||
dyeable,
|
|
||||||
-1,
|
|
||||||
balloonModelIdNode.getString()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new ArmorItem(
|
|
||||||
itemStack,
|
|
||||||
actions,
|
|
||||||
Utils.replaceIfNull(nameNode.getString(), ""),
|
|
||||||
Utils.replaceIfNull(idNode.getString(), ""),
|
|
||||||
lockedItem,
|
|
||||||
appliedItem,
|
|
||||||
permission,
|
|
||||||
cosmeticType,
|
|
||||||
dyeable,
|
|
||||||
-1
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
} catch (final IllegalArgumentException exception) {
|
|
||||||
final GuiItem guiItem = dev.triumphteam.gui.builder.item.ItemBuilder.from(itemStack).asGuiItem();
|
|
||||||
final GuiAction<InventoryClickEvent> guiAction = event -> {
|
|
||||||
for (final CosmeticGuiAction action : actions) {
|
|
||||||
action.execute(event, CosmeticGuiAction.When.ALL);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
guiItem.setAction(guiAction);
|
|
||||||
return new WrappedGuiItem(guiItem, guiAction);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void serialize(final Type type, @Nullable final WrappedGuiItem obj, final ConfigurationNode node) throws SerializationException {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
package io.github.fisher2911.hmccosmetics.config;
|
|
||||||
|
|
||||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
|
||||||
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
public class CosmeticGuiAction {
|
|
||||||
|
|
||||||
private final When when;
|
|
||||||
private final Consumer<InventoryClickEvent> consumer;
|
|
||||||
|
|
||||||
public CosmeticGuiAction(final When when, final Consumer<InventoryClickEvent> consumer) {
|
|
||||||
this.when = when;
|
|
||||||
this.consumer = consumer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void execute(final InventoryClickEvent event, final When when) {
|
|
||||||
if (this.when != When.ALL && this.when != when) return;
|
|
||||||
consumer.accept(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum When {
|
|
||||||
|
|
||||||
EQUIP,
|
|
||||||
REMOVE,
|
|
||||||
ALL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,124 +0,0 @@
|
|||||||
package io.github.fisher2911.hmccosmetics.config;
|
|
||||||
|
|
||||||
import io.github.fisher2911.hmccosmetics.gui.CosmeticsMenu;
|
|
||||||
import io.github.fisher2911.hmccosmetics.util.Utils;
|
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
|
||||||
import org.bukkit.inventory.EquipmentSlot;
|
|
||||||
import org.bukkit.util.Vector;
|
|
||||||
import org.spongepowered.configurate.objectmapping.ConfigSerializable;
|
|
||||||
|
|
||||||
@ConfigSerializable
|
|
||||||
public class CosmeticSettings {
|
|
||||||
|
|
||||||
private static final String DEFAULT_MENU = "default-menu";
|
|
||||||
private static final String COSMETIC_SETTINGS_PATH = "cosmetic-settings";
|
|
||||||
private static final String REQUIRE_EMPTY_HELMET_PATH = "require-empty-helmet";
|
|
||||||
private static final String REQUIRE_EMPTY_OFF_HAND_PATH = "require-empty-off-hand";
|
|
||||||
private static final String REQUIRE_EMPTY_CHEST_PLATE_PATH = "require-empty-chest-plate";
|
|
||||||
private static final String REQUIRE_EMPTY_PANTS_PATH = "require-empty-pants";
|
|
||||||
private static final String REQUIRE_EMPTY_BOOTS_PATH = "require-empty-boots";
|
|
||||||
private static final String BALLOON_OFFSET = "balloon-offset";
|
|
||||||
|
|
||||||
private static final transient String LOOK_DOWN_PITCH_PATH = "look-down-backpack-remove";
|
|
||||||
private static final String VIEW_DISTANCE_PATH = "view-distance";
|
|
||||||
|
|
||||||
private String defaultMenu;
|
|
||||||
private boolean requireEmptyHelmet;
|
|
||||||
private boolean requireEmptyOffHand;
|
|
||||||
private boolean requireEmptyChestPlate;
|
|
||||||
private boolean requireEmptyPants;
|
|
||||||
private boolean requireEmptyBoots;
|
|
||||||
private int lookDownPitch;
|
|
||||||
private int viewDistance;
|
|
||||||
private Vector balloonOffset;
|
|
||||||
|
|
||||||
public void load(final FileConfiguration config) {
|
|
||||||
this.defaultMenu = Utils.replaceIf(config.getString(DEFAULT_MENU), CosmeticsMenu.DEFAULT_MAIN_MENU, null, "");
|
|
||||||
this.requireEmptyHelmet = config.getBoolean(COSMETIC_SETTINGS_PATH + "." + REQUIRE_EMPTY_HELMET_PATH);
|
|
||||||
this.requireEmptyOffHand = config.getBoolean(COSMETIC_SETTINGS_PATH + "." + REQUIRE_EMPTY_OFF_HAND_PATH);
|
|
||||||
this.requireEmptyChestPlate = config.getBoolean(COSMETIC_SETTINGS_PATH + "." + REQUIRE_EMPTY_CHEST_PLATE_PATH);
|
|
||||||
this.requireEmptyPants = config.getBoolean(COSMETIC_SETTINGS_PATH + "." + REQUIRE_EMPTY_PANTS_PATH);
|
|
||||||
this.requireEmptyBoots = config.getBoolean(COSMETIC_SETTINGS_PATH + "." + REQUIRE_EMPTY_BOOTS_PATH);
|
|
||||||
|
|
||||||
this.lookDownPitch = config.getInt(COSMETIC_SETTINGS_PATH + "." + LOOK_DOWN_PITCH_PATH);
|
|
||||||
this.viewDistance = config.getInt(COSMETIC_SETTINGS_PATH + "." + VIEW_DISTANCE_PATH);
|
|
||||||
|
|
||||||
final var balloonSection = config.getConfigurationSection(COSMETIC_SETTINGS_PATH + "." + BALLOON_OFFSET);
|
|
||||||
|
|
||||||
if (balloonSection != null) {
|
|
||||||
this.balloonOffset = loadVector(balloonSection);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Vector loadVector(final ConfigurationSection section) {
|
|
||||||
return new Vector(section.getDouble("x"), section.getDouble("y"), section.getDouble("z"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isRequireEmptyHelmet() {
|
|
||||||
return requireEmptyHelmet;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRequireEmptyHelmet(final boolean requireEmptyHelmet) {
|
|
||||||
this.requireEmptyHelmet = requireEmptyHelmet;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isRequireEmptyOffHand() {
|
|
||||||
return requireEmptyOffHand;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRequireEmptyOffHand(final boolean requireEmptyOffHand) {
|
|
||||||
this.requireEmptyOffHand = requireEmptyOffHand;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isRequireEmptyChestPlate() {
|
|
||||||
return requireEmptyChestPlate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRequireEmptyChestPlate(final boolean requireEmptyChestPlate) {
|
|
||||||
this.requireEmptyChestPlate = requireEmptyChestPlate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isRequireEmptyPants() {
|
|
||||||
return requireEmptyPants;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRequireEmptyPants(final boolean requireEmptyPants) {
|
|
||||||
this.requireEmptyPants = requireEmptyPants;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isRequireEmptyBoots() {
|
|
||||||
return requireEmptyBoots;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRequireEmptyBoots(final boolean requireEmptyBoots) {
|
|
||||||
this.requireEmptyBoots = requireEmptyBoots;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Vector getBalloonOffset() {
|
|
||||||
return balloonOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getLookDownPitch() {
|
|
||||||
return lookDownPitch;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getViewDistance() {
|
|
||||||
return viewDistance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDefaultMenu() {
|
|
||||||
return defaultMenu;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean requireEmpty(final EquipmentSlot slot) {
|
|
||||||
return switch (slot) {
|
|
||||||
case OFF_HAND -> this.isRequireEmptyOffHand();
|
|
||||||
case HEAD -> this.isRequireEmptyHelmet();
|
|
||||||
case CHEST -> this.isRequireEmptyChestPlate();
|
|
||||||
case LEGS -> this.isRequireEmptyPants();
|
|
||||||
case FEET -> this.isRequireEmptyBoots();
|
|
||||||
default -> false;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,133 +0,0 @@
|
|||||||
package io.github.fisher2911.hmccosmetics.config;
|
|
||||||
|
|
||||||
import com.google.common.collect.BiMap;
|
|
||||||
import com.google.common.collect.HashBiMap;
|
|
||||||
import dev.triumphteam.gui.guis.GuiItem;
|
|
||||||
import io.github.fisher2911.hmccosmetics.HMCCosmetics;
|
|
||||||
import io.github.fisher2911.hmccosmetics.gui.ArmorItem;
|
|
||||||
import io.github.fisher2911.hmccosmetics.gui.ColorItem;
|
|
||||||
import io.github.fisher2911.hmccosmetics.gui.DyeSelectorGui;
|
|
||||||
import io.github.fisher2911.hmccosmetics.gui.WrappedGuiItem;
|
|
||||||
import org.bukkit.Color;
|
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
|
||||||
import org.spongepowered.configurate.ConfigurationNode;
|
|
||||||
import org.spongepowered.configurate.serialize.SerializationException;
|
|
||||||
import org.spongepowered.configurate.serialize.TypeSerializer;
|
|
||||||
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class DyeGuiSerializer implements TypeSerializer<DyeSelectorGui> {
|
|
||||||
|
|
||||||
public static final DyeGuiSerializer INSTANCE = new DyeGuiSerializer();
|
|
||||||
private static final HMCCosmetics plugin;
|
|
||||||
private static final String TITLE = "title";
|
|
||||||
private static final String ROWS = "rows";
|
|
||||||
private static final String ITEMS = "items";
|
|
||||||
private static final String COSMETICS_SLOTS = "cosmetics-slots";
|
|
||||||
private static final String SET_COLOR = "set-color";
|
|
||||||
private static final String RED = "red";
|
|
||||||
private static final String GREEN = "green";
|
|
||||||
private static final String BLUE = "blue";
|
|
||||||
|
|
||||||
static {
|
|
||||||
plugin = HMCCosmetics.getPlugin(HMCCosmetics.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
private DyeGuiSerializer() {
|
|
||||||
}
|
|
||||||
|
|
||||||
private ConfigurationNode nonVirtualNode(final ConfigurationNode source, final Object... path)
|
|
||||||
throws SerializationException {
|
|
||||||
if (!source.hasChild(path)) {
|
|
||||||
throw new SerializationException(
|
|
||||||
"Required field " + Arrays.toString(path) + " was not present in node");
|
|
||||||
}
|
|
||||||
return source.node(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DyeSelectorGui deserialize(final Type type, final ConfigurationNode source)
|
|
||||||
throws SerializationException {
|
|
||||||
final ConfigurationNode titleNode = this.nonVirtualNode(source, TITLE);
|
|
||||||
final ConfigurationNode rowsNode = this.nonVirtualNode(source, ROWS);
|
|
||||||
final ConfigurationNode itemsNode = source.node(ITEMS);
|
|
||||||
final ConfigurationNode cosmeticSlotsNode = source.node(COSMETICS_SLOTS);
|
|
||||||
|
|
||||||
final Map<Integer, GuiItem> guiItemMap = new HashMap<>();
|
|
||||||
|
|
||||||
final var itemMap = itemsNode.childrenMap();
|
|
||||||
final var cosmeticSlotsMap = cosmeticSlotsNode.childrenMap();
|
|
||||||
|
|
||||||
for (final var entry : itemMap.entrySet()) {
|
|
||||||
if (!(entry.getKey() instanceof final Integer slot)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
final var node = entry.getValue();
|
|
||||||
|
|
||||||
final WrappedGuiItem guiItem = ArmorItemSerializer.INSTANCE.deserialize(
|
|
||||||
GuiItem.class,
|
|
||||||
node
|
|
||||||
);
|
|
||||||
|
|
||||||
final ConfigurationNode colorNode = node.node(SET_COLOR);
|
|
||||||
|
|
||||||
if (colorNode.virtual()) {
|
|
||||||
guiItemMap.put(slot, guiItem);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
final int red = colorNode.node(RED).getInt();
|
|
||||||
final int green = colorNode.node(GREEN).getInt();
|
|
||||||
final int blue = colorNode.node(BLUE).getInt();
|
|
||||||
|
|
||||||
guiItemMap.put(slot,
|
|
||||||
new ColorItem(guiItem.getItemStack(), guiItem.getAction(), Color.fromRGB(red, green, blue))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
final BiMap<Integer, ArmorItem.Type> cosmeticSlots = HashBiMap.create();
|
|
||||||
int selectedCosmetic = -1;
|
|
||||||
for (final var entry : cosmeticSlotsMap.entrySet()) {
|
|
||||||
if (!(entry.getKey() instanceof final Integer slot)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
selectedCosmetic = selectedCosmetic == -1 ? slot : selectedCosmetic;
|
|
||||||
|
|
||||||
final var node = entry.getValue();
|
|
||||||
|
|
||||||
final String typeStr = node.getString();
|
|
||||||
|
|
||||||
try {
|
|
||||||
final ArmorItem.Type itemType = ArmorItem.Type.valueOf(typeStr);
|
|
||||||
cosmeticSlots.put(slot, itemType);
|
|
||||||
} catch (final IllegalArgumentException | NullPointerException exception) {
|
|
||||||
plugin.getLogger().severe(typeStr + " is not a valid ArmorItem type in DyeGui!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String title = titleNode.getString();
|
|
||||||
|
|
||||||
if (title == null) {
|
|
||||||
title = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
return new DyeSelectorGui(
|
|
||||||
plugin,
|
|
||||||
title,
|
|
||||||
rowsNode.getInt(),
|
|
||||||
guiItemMap,
|
|
||||||
cosmeticSlots,
|
|
||||||
selectedCosmetic);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void serialize(final Type type, @Nullable final DyeSelectorGui obj, final ConfigurationNode node) throws SerializationException {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
package io.github.fisher2911.hmccosmetics.config;
|
|
||||||
|
|
||||||
import dev.triumphteam.gui.guis.GuiItem;
|
|
||||||
import io.github.fisher2911.hmccosmetics.HMCCosmetics;
|
|
||||||
import io.github.fisher2911.hmccosmetics.gui.CosmeticGui;
|
|
||||||
import io.github.fisher2911.hmccosmetics.message.Adventure;
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
|
||||||
import org.spongepowered.configurate.ConfigurationNode;
|
|
||||||
import org.spongepowered.configurate.serialize.SerializationException;
|
|
||||||
import org.spongepowered.configurate.serialize.TypeSerializer;
|
|
||||||
|
|
||||||
public class GuiSerializer implements TypeSerializer<CosmeticGui> {
|
|
||||||
|
|
||||||
public static final GuiSerializer INSTANCE = new GuiSerializer();
|
|
||||||
private static final HMCCosmetics plugin;
|
|
||||||
private static final String TITLE = "title";
|
|
||||||
private static final String ROWS = "rows";
|
|
||||||
private static final String ITEMS = "items";
|
|
||||||
|
|
||||||
static {
|
|
||||||
plugin = HMCCosmetics.getPlugin(HMCCosmetics.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
private GuiSerializer() {
|
|
||||||
}
|
|
||||||
|
|
||||||
private ConfigurationNode nonVirtualNode(final ConfigurationNode source, final Object... path)
|
|
||||||
throws SerializationException {
|
|
||||||
if (!source.hasChild(path)) {
|
|
||||||
throw new SerializationException(
|
|
||||||
"Required field " + Arrays.toString(path) + " was not present in node");
|
|
||||||
}
|
|
||||||
return source.node(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CosmeticGui deserialize(final Type type, final ConfigurationNode source)
|
|
||||||
throws SerializationException {
|
|
||||||
final ConfigurationNode titleNode = this.nonVirtualNode(source, TITLE);
|
|
||||||
final ConfigurationNode rowsNode = this.nonVirtualNode(source, ROWS);
|
|
||||||
final ConfigurationNode itemsNode = source.node(ITEMS);
|
|
||||||
|
|
||||||
final var childrenMap = itemsNode.childrenMap();
|
|
||||||
|
|
||||||
final Map<Integer, GuiItem> guiItemMap = new HashMap<>();
|
|
||||||
|
|
||||||
for (final var entry : childrenMap.entrySet()) {
|
|
||||||
if (!(entry.getKey() instanceof final Integer slot)) continue;
|
|
||||||
final GuiItem guiItem = ArmorItemSerializer.INSTANCE.deserialize(
|
|
||||||
GuiItem.class,
|
|
||||||
entry.getValue()
|
|
||||||
);
|
|
||||||
|
|
||||||
guiItemMap.put(slot, guiItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
String title = titleNode.getString();
|
|
||||||
|
|
||||||
if (title == null) {
|
|
||||||
title = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
return new CosmeticGui(plugin,
|
|
||||||
title,
|
|
||||||
rowsNode.getInt(),
|
|
||||||
guiItemMap);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void serialize(final Type type, @Nullable final CosmeticGui obj, final ConfigurationNode node) throws SerializationException {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,191 +0,0 @@
|
|||||||
package io.github.fisher2911.hmccosmetics.config;
|
|
||||||
|
|
||||||
import io.github.fisher2911.hmccosmetics.gui.WrappedGuiItem;
|
|
||||||
import io.github.fisher2911.hmccosmetics.hook.HookManager;
|
|
||||||
import io.github.fisher2911.hmccosmetics.util.Keys;
|
|
||||||
import io.github.fisher2911.hmccosmetics.util.StringUtils;
|
|
||||||
import io.github.fisher2911.hmccosmetics.util.Utils;
|
|
||||||
import io.github.fisher2911.hmccosmetics.util.builder.ColorBuilder;
|
|
||||||
import io.github.fisher2911.hmccosmetics.util.builder.ItemBuilder;
|
|
||||||
import io.github.fisher2911.hmccosmetics.util.builder.SkullBuilder;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Color;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.NamespacedKey;
|
|
||||||
import org.bukkit.OfflinePlayer;
|
|
||||||
import org.bukkit.Registry;
|
|
||||||
import org.bukkit.enchantments.Enchantment;
|
|
||||||
import org.bukkit.inventory.ItemFlag;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
|
||||||
import org.spongepowered.configurate.ConfigurationNode;
|
|
||||||
import org.spongepowered.configurate.serialize.SerializationException;
|
|
||||||
import org.spongepowered.configurate.serialize.TypeSerializer;
|
|
||||||
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public class ItemSerializer implements TypeSerializer<ItemStack> {
|
|
||||||
|
|
||||||
public static final ItemSerializer INSTANCE = new ItemSerializer();
|
|
||||||
private static final String MATERIAL = "material";
|
|
||||||
private static final String AMOUNT = "amount";
|
|
||||||
private static final String NAME = "name";
|
|
||||||
private static final String UNBREAKABLE = "unbreakable";
|
|
||||||
private static final String GLOWING = "glowing";
|
|
||||||
private static final String LORE = "lore";
|
|
||||||
private static final String MODEL_DATA = "model-data";
|
|
||||||
private static final String ENCHANTS = "enchants";
|
|
||||||
private static final String ITEM_FLAGS = "item-flags";
|
|
||||||
private static final String TEXTURE = "texture";
|
|
||||||
private static final String OWNER = "owner";
|
|
||||||
private static final String COLOR = "color";
|
|
||||||
private static final String RED = "red";
|
|
||||||
private static final String GREEN = "green";
|
|
||||||
private static final String BLUE = "blue";
|
|
||||||
|
|
||||||
private ItemSerializer() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ItemStack deserialize(final Type type, final ConfigurationNode source)
|
|
||||||
throws SerializationException {
|
|
||||||
final ConfigurationNode materialNode = source.node(MATERIAL);
|
|
||||||
final ConfigurationNode amountNode = source.node(AMOUNT);
|
|
||||||
final ConfigurationNode nameNode = source.node(NAME);
|
|
||||||
final ConfigurationNode unbreakableNode = source.node(UNBREAKABLE);
|
|
||||||
final ConfigurationNode glowingNode = source.node(GLOWING);
|
|
||||||
final ConfigurationNode loreNode = source.node(LORE);
|
|
||||||
final ConfigurationNode modelDataNode = source.node(MODEL_DATA);
|
|
||||||
final ConfigurationNode enchantsNode = source.node(ENCHANTS);
|
|
||||||
final ConfigurationNode itemFlagsNode = source.node(ITEM_FLAGS);
|
|
||||||
final ConfigurationNode textureNode = source.node(TEXTURE);
|
|
||||||
final ConfigurationNode ownerNode = source.node(OWNER);
|
|
||||||
final ConfigurationNode colorNode = source.node(COLOR);
|
|
||||||
final ConfigurationNode redNode = colorNode.node(RED);
|
|
||||||
final ConfigurationNode greenNode = colorNode.node(GREEN);
|
|
||||||
final ConfigurationNode blueNode = colorNode.node(BLUE);
|
|
||||||
|
|
||||||
final String materialString = Utils.replaceIfNull(materialNode.getString(), "");
|
|
||||||
final int amount = amountNode.getInt();
|
|
||||||
|
|
||||||
ItemStack itemStack;
|
|
||||||
|
|
||||||
try {
|
|
||||||
itemStack = new ItemStack(Material.valueOf(materialString.toUpperCase()), amount);
|
|
||||||
} catch (final IllegalArgumentException exception) {
|
|
||||||
itemStack = HookManager.getInstance().getItemHooks().getItemStack(materialString);
|
|
||||||
if (itemStack == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final String name = StringUtils.parseStringToString(Utils.replaceIfNull(nameNode.getString(), ""));
|
|
||||||
|
|
||||||
final boolean unbreakable = unbreakableNode.getBoolean();
|
|
||||||
final boolean glowing = glowingNode.getBoolean();
|
|
||||||
|
|
||||||
final List<String> lore = Utils.replaceIfNull(loreNode.getList(String.class),
|
|
||||||
new ArrayList<String>()).
|
|
||||||
stream().map(StringUtils::parseStringToString).collect(Collectors.toList());
|
|
||||||
|
|
||||||
final int modelData = modelDataNode.getInt();
|
|
||||||
|
|
||||||
final Set<ItemFlag> itemFlags = Utils.replaceIfNull(itemFlagsNode.getList(String.class),
|
|
||||||
new ArrayList<String>()).
|
|
||||||
stream().map(flag -> {
|
|
||||||
try {
|
|
||||||
return ItemFlag.valueOf(flag.toUpperCase());
|
|
||||||
} catch (final Exception ignored) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}).collect(Collectors.toSet());
|
|
||||||
final String texture = textureNode.getString();
|
|
||||||
final String owner = ownerNode.getString();
|
|
||||||
|
|
||||||
final Color color;
|
|
||||||
|
|
||||||
if (colorNode.virtual()) {
|
|
||||||
color = null;
|
|
||||||
} else {
|
|
||||||
color = Color.fromRGB(redNode.getInt(), greenNode.getInt(), blueNode.getInt());
|
|
||||||
}
|
|
||||||
|
|
||||||
final Map<Enchantment, Integer> enchantments =
|
|
||||||
Utils.replaceIfNull(enchantsNode.getList(String.class),
|
|
||||||
new ArrayList<String>()).
|
|
||||||
stream().
|
|
||||||
collect(Collectors.toMap(enchantmentString -> {
|
|
||||||
|
|
||||||
if (!enchantmentString.contains(":")) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
final NamespacedKey namespacedKey = NamespacedKey.minecraft(
|
|
||||||
enchantmentString.
|
|
||||||
split(":")[0].
|
|
||||||
toLowerCase());
|
|
||||||
return Registry.ENCHANTMENT.get(namespacedKey);
|
|
||||||
|
|
||||||
}, enchantmentString -> {
|
|
||||||
if (!enchantmentString.contains(":")) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
return Integer.parseInt(enchantmentString.split(":")[1]);
|
|
||||||
} catch (final NumberFormatException exception) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
final ItemBuilder itemBuilder;
|
|
||||||
|
|
||||||
if (itemStack.getType() == Material.PLAYER_HEAD) {
|
|
||||||
itemBuilder = SkullBuilder.create();
|
|
||||||
|
|
||||||
if (texture != null) {
|
|
||||||
((SkullBuilder) itemBuilder).texture(texture);
|
|
||||||
} else if (owner != null) {
|
|
||||||
final OfflinePlayer player = Bukkit.getOfflinePlayer(owner);
|
|
||||||
((SkullBuilder) itemBuilder).owner(player);
|
|
||||||
}
|
|
||||||
} else if (ColorBuilder.canBeColored(itemStack)) {
|
|
||||||
itemBuilder = ColorBuilder.from(itemStack);
|
|
||||||
if (color != null) {
|
|
||||||
((ColorBuilder) itemBuilder).color(color);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
itemBuilder = ItemBuilder.from(itemStack);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (itemStack.getItemMeta() != null && !itemStack.getItemMeta().hasCustomModelData()) {
|
|
||||||
itemBuilder.modelData(modelData);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!lore.isEmpty()) itemBuilder.lore(lore);
|
|
||||||
if (!name.isBlank()) itemBuilder.name(name);
|
|
||||||
|
|
||||||
itemStack = itemBuilder.
|
|
||||||
amount(amount).
|
|
||||||
unbreakable(unbreakable).
|
|
||||||
glow(glowing).
|
|
||||||
enchants(enchantments, true).
|
|
||||||
itemFlags(itemFlags).
|
|
||||||
build();
|
|
||||||
|
|
||||||
Keys.setKey(itemStack);
|
|
||||||
|
|
||||||
return itemStack;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void serialize(final Type type, @Nullable final ItemStack obj, final ConfigurationNode node) throws SerializationException {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
package io.github.fisher2911.hmccosmetics.config;
|
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.World;
|
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
|
||||||
import org.spongepowered.configurate.ConfigurationNode;
|
|
||||||
import org.spongepowered.configurate.serialize.SerializationException;
|
|
||||||
import org.spongepowered.configurate.serialize.TypeSerializer;
|
|
||||||
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
|
|
||||||
public class LocationSerializer implements TypeSerializer<Location> {
|
|
||||||
|
|
||||||
public static final LocationSerializer INSTANCE = new LocationSerializer();
|
|
||||||
|
|
||||||
private static final String WORLD = "world";
|
|
||||||
private static final String X = "x";
|
|
||||||
private static final String Y = "y";
|
|
||||||
private static final String Z = "z";
|
|
||||||
private static final String PITCH = "pitch";
|
|
||||||
private static final String YAW = "yaw";
|
|
||||||
|
|
||||||
|
|
||||||
private LocationSerializer() {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public Location deserialize(final Type type, final ConfigurationNode source) throws SerializationException {
|
|
||||||
final World world = Bukkit.getWorld(source.node(WORLD).getString());
|
|
||||||
if (world == null) return null;
|
|
||||||
return new Location(
|
|
||||||
world,
|
|
||||||
source.node(X).getDouble(),
|
|
||||||
source.node(Y).getDouble(),
|
|
||||||
source.node(Z).getDouble(),
|
|
||||||
source.node(YAW).getFloat(),
|
|
||||||
source.node(PITCH).getFloat()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void serialize(final Type type, @Nullable final Location obj, final ConfigurationNode node) throws SerializationException {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
package io.github.fisher2911.hmccosmetics.config;
|
|
||||||
|
|
||||||
import io.github.fisher2911.hmccosmetics.HMCCosmetics;
|
|
||||||
|
|
||||||
public class Settings {
|
|
||||||
|
|
||||||
private final HMCCosmetics plugin;
|
|
||||||
private final CosmeticSettings cosmeticSettings;
|
|
||||||
private final WardrobeSettings wardrobeSettings;
|
|
||||||
|
|
||||||
public Settings(final HMCCosmetics plugin) {
|
|
||||||
this.plugin = plugin;
|
|
||||||
this.cosmeticSettings = new CosmeticSettings();
|
|
||||||
this.wardrobeSettings = new WardrobeSettings(this.plugin);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void load() {
|
|
||||||
this.plugin.saveDefaultConfig();
|
|
||||||
this.plugin.reloadConfig();
|
|
||||||
this.cosmeticSettings.load(this.plugin.getConfig());
|
|
||||||
this.wardrobeSettings.load();
|
|
||||||
}
|
|
||||||
|
|
||||||
public CosmeticSettings getCosmeticSettings() {
|
|
||||||
return cosmeticSettings;
|
|
||||||
}
|
|
||||||
|
|
||||||
public WardrobeSettings getWardrobeSettings() {
|
|
||||||
return wardrobeSettings;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
package io.github.fisher2911.hmccosmetics.config;
|
|
||||||
|
|
||||||
import com.comphenix.protocol.events.PacketContainer;
|
|
||||||
import com.comphenix.protocol.wrappers.EnumWrappers;
|
|
||||||
import com.comphenix.protocol.wrappers.MinecraftKey;
|
|
||||||
import io.github.fisher2911.hmccosmetics.packet.PacketManager;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
public class SoundData {
|
|
||||||
|
|
||||||
private final String name;
|
|
||||||
private final EnumWrappers.SoundCategory soundCategory;
|
|
||||||
private final float volume;
|
|
||||||
private final float pitch;
|
|
||||||
|
|
||||||
public SoundData(final String name, final EnumWrappers.SoundCategory soundCategory, final float volume, final float pitch) {
|
|
||||||
this.name = name;
|
|
||||||
this.soundCategory = soundCategory;
|
|
||||||
this.volume = volume;
|
|
||||||
this.pitch = pitch;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getVolume() {
|
|
||||||
return volume;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getPitch() {
|
|
||||||
return pitch;
|
|
||||||
}
|
|
||||||
|
|
||||||
public EnumWrappers.SoundCategory getSoundCategory() {
|
|
||||||
return soundCategory;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void play(final Player player) {
|
|
||||||
final PacketContainer soundPacket = PacketManager.getSoundPacket(
|
|
||||||
player,
|
|
||||||
player.getLocation(),
|
|
||||||
this.getKey(this.name),
|
|
||||||
this.volume,
|
|
||||||
this.pitch,
|
|
||||||
this.soundCategory
|
|
||||||
);
|
|
||||||
|
|
||||||
PacketManager.sendPacket(player, soundPacket);
|
|
||||||
}
|
|
||||||
|
|
||||||
private MinecraftKey getKey(final String string) {
|
|
||||||
if (!string.contains(":")) {
|
|
||||||
return new MinecraftKey(string);
|
|
||||||
}
|
|
||||||
|
|
||||||
final String[] parts = string.split(":");
|
|
||||||
|
|
||||||
return new MinecraftKey(parts[0], parts[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
package io.github.fisher2911.hmccosmetics.config;
|
|
||||||
|
|
||||||
import com.comphenix.protocol.wrappers.EnumWrappers;
|
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
|
||||||
import org.spongepowered.configurate.ConfigurationNode;
|
|
||||||
import org.spongepowered.configurate.serialize.SerializationException;
|
|
||||||
import org.spongepowered.configurate.serialize.TypeSerializer;
|
|
||||||
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
|
|
||||||
public class SoundSerializer implements TypeSerializer<SoundData> {
|
|
||||||
|
|
||||||
public static final SoundSerializer INSTANCE = new SoundSerializer();
|
|
||||||
|
|
||||||
private SoundSerializer() {}
|
|
||||||
|
|
||||||
private static final String SOUND_NAME = "name";
|
|
||||||
private static final String SOUND_VOLUME = "volume";
|
|
||||||
private static final String SOUND_PITCH = "pitch";
|
|
||||||
private static final String SOUND_CATEGORY = "category";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SoundData deserialize(final Type type, final ConfigurationNode node) throws SerializationException {
|
|
||||||
final ConfigurationNode soundNameNode = node.node(SOUND_NAME);
|
|
||||||
final ConfigurationNode volumeNode = node.node(SOUND_VOLUME);
|
|
||||||
final ConfigurationNode pitchNode = node.node(SOUND_PITCH);
|
|
||||||
final ConfigurationNode categoryNode = node.node(SOUND_CATEGORY);
|
|
||||||
|
|
||||||
final SoundData soundData;
|
|
||||||
|
|
||||||
final String soundName = soundNameNode.getString();
|
|
||||||
final String category = categoryNode.getString();
|
|
||||||
final int volume = volumeNode.getInt();
|
|
||||||
final int pitch = pitchNode.getInt();
|
|
||||||
if (soundName == null || category == null) {
|
|
||||||
soundData = null;
|
|
||||||
} else {
|
|
||||||
soundData = new SoundData(
|
|
||||||
soundName,
|
|
||||||
EnumWrappers.SoundCategory.valueOf(category),
|
|
||||||
volume,
|
|
||||||
pitch
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return soundData;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void serialize(final Type type, @Nullable final SoundData obj, final ConfigurationNode node) throws SerializationException {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
package io.github.fisher2911.hmccosmetics.config;
|
|
||||||
|
|
||||||
import io.github.fisher2911.hmccosmetics.gui.CosmeticGui;
|
|
||||||
import io.github.fisher2911.hmccosmetics.gui.TokenGui;
|
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
|
||||||
import org.spongepowered.configurate.ConfigurationNode;
|
|
||||||
import org.spongepowered.configurate.serialize.SerializationException;
|
|
||||||
import org.spongepowered.configurate.serialize.TypeSerializer;
|
|
||||||
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
|
|
||||||
public class TokenGuiSerializer implements TypeSerializer<TokenGui> {
|
|
||||||
|
|
||||||
public static final TokenGuiSerializer INSTANCE = new TokenGuiSerializer();
|
|
||||||
private static final String TOKEN_SLOT = "token-slot";
|
|
||||||
private static final String COSMETIC_SLOT = "cosmetic-slot";
|
|
||||||
|
|
||||||
private TokenGuiSerializer() {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TokenGui deserialize(final Type type, final ConfigurationNode source) throws SerializationException {
|
|
||||||
final CosmeticGui cosmeticGui = GuiSerializer.INSTANCE.deserialize(CosmeticGui.class, source);
|
|
||||||
final ConfigurationNode tokenSlotNode = source.node(TOKEN_SLOT);
|
|
||||||
final ConfigurationNode cosmeticSlotNode = source.node(COSMETIC_SLOT);
|
|
||||||
|
|
||||||
return new TokenGui(
|
|
||||||
cosmeticGui,
|
|
||||||
tokenSlotNode.getInt(),
|
|
||||||
cosmeticSlotNode.getInt()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void serialize(final Type type, @Nullable final TokenGui obj, final ConfigurationNode node) throws SerializationException {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
package io.github.fisher2911.hmccosmetics.config;
|
|
||||||
|
|
||||||
import io.github.fisher2911.hmccosmetics.HMCCosmetics;
|
|
||||||
import io.github.fisher2911.hmccosmetics.cosmetic.CosmeticManager;
|
|
||||||
import io.github.fisher2911.hmccosmetics.gui.ArmorItem;
|
|
||||||
import io.github.fisher2911.hmccosmetics.gui.Token;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.spongepowered.configurate.ConfigurateException;
|
|
||||||
import org.spongepowered.configurate.ConfigurationNode;
|
|
||||||
import org.spongepowered.configurate.yaml.YamlConfigurationLoader;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class TokenLoader {
|
|
||||||
|
|
||||||
private static final String FILE_NAME = "tokens.yml";
|
|
||||||
private static final String TOKEN_PATH = "tokens";
|
|
||||||
private static final String ID_PATH = "id";
|
|
||||||
private static final String COMMANDS_PATH = "commands";
|
|
||||||
private final HMCCosmetics plugin;
|
|
||||||
private final CosmeticManager cosmeticManager;
|
|
||||||
|
|
||||||
public TokenLoader(final HMCCosmetics plugin) {
|
|
||||||
this.plugin = plugin;
|
|
||||||
this.cosmeticManager = this.plugin.getCosmeticManager();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void load() {
|
|
||||||
final Path path = Path.of(this.plugin.getDataFolder().getPath(), FILE_NAME);
|
|
||||||
final File file = path.toFile();
|
|
||||||
if (!file.exists()) {
|
|
||||||
this.plugin.saveResource(FILE_NAME, false);
|
|
||||||
}
|
|
||||||
final YamlConfigurationLoader loader = YamlConfigurationLoader.
|
|
||||||
builder().
|
|
||||||
defaultOptions(opts -> opts.serializers(build -> build.register(ItemStack.class, ItemSerializer.INSTANCE))).
|
|
||||||
path(path).
|
|
||||||
build();
|
|
||||||
try {
|
|
||||||
final ConfigurationNode source = loader.load().node(TOKEN_PATH);
|
|
||||||
for (final var entry : source.childrenMap().entrySet()) {
|
|
||||||
final var node = entry.getValue();
|
|
||||||
final String id = node.node(ID_PATH).getString();
|
|
||||||
final ItemStack itemStack = node.get(ItemStack.class);
|
|
||||||
final ArmorItem armorItem = this.cosmeticManager.getArmorItem(id);
|
|
||||||
if (armorItem == null) {
|
|
||||||
this.plugin.getLogger().severe("Could not find armor item for token: " + id + " with id: " + id);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
final List<String> commands = node.node(COMMANDS_PATH).getList(String.class);
|
|
||||||
this.cosmeticManager.addToken(new Token(itemStack, armorItem, commands));
|
|
||||||
}
|
|
||||||
} catch (final ConfigurateException exception) {
|
|
||||||
this.plugin.getLogger().severe("Error loading tokens!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,165 +0,0 @@
|
|||||||
package io.github.fisher2911.hmccosmetics.config;
|
|
||||||
|
|
||||||
import com.comphenix.protocol.events.PacketListener;
|
|
||||||
import io.github.fisher2911.hmccosmetics.HMCCosmetics;
|
|
||||||
import io.github.fisher2911.hmccosmetics.gui.CosmeticGui;
|
|
||||||
import io.github.fisher2911.hmccosmetics.gui.DyeSelectorGui;
|
|
||||||
import io.github.fisher2911.hmccosmetics.gui.WrappedGuiItem;
|
|
||||||
import io.github.fisher2911.hmccosmetics.util.Utils;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.Sound;
|
|
||||||
import org.bukkit.World;
|
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.spongepowered.configurate.ConfigurateException;
|
|
||||||
import org.spongepowered.configurate.ConfigurationNode;
|
|
||||||
import org.spongepowered.configurate.yaml.YamlConfigurationLoader;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
|
|
||||||
public class WardrobeSettings {
|
|
||||||
|
|
||||||
private static final String WARDROBE_PATH = "wardrobe";
|
|
||||||
private static final String DISABLE_ON_DAMAGE_PATH = "disable-on-damage";
|
|
||||||
private static final String DISPLAY_RADIUS_PATH = "display-radius";
|
|
||||||
private static final String PORTABLE_PATH = "portable";
|
|
||||||
private static final String ALWAYS_DISPLAY_PATH = "always-display";
|
|
||||||
private static final String STATIC_RADIUS_PATH = "static-radius";
|
|
||||||
private static final String ROTATION_SPEED_PATH = "rotation-speed";
|
|
||||||
private static final String SPAWN_DELAY_PATH = "spawn-delay";
|
|
||||||
private static final String DESPAWN_DELAY_PATH = "despawn-delay";
|
|
||||||
private static final String APPLY_COSMETICS_ON_CLOSE = "apply-cosmetics-on-close";
|
|
||||||
private static final String OPEN_SOUND = "open-sound";
|
|
||||||
private static final String CLOSE_SOUND = "close-sound";
|
|
||||||
private static final String STATIC_LOCATION_PATH = "wardrobe-location";
|
|
||||||
private static final String VIEWER_LOCATION_PATH = "viewer-location";
|
|
||||||
private static final String LEAVE_LOCATION_PATH = "leave-location";
|
|
||||||
|
|
||||||
private final HMCCosmetics plugin;
|
|
||||||
|
|
||||||
private boolean disableOnDamage;
|
|
||||||
private int displayRadius;
|
|
||||||
private boolean portable;
|
|
||||||
private boolean alwaysDisplay;
|
|
||||||
private int staticRadius;
|
|
||||||
private int rotationSpeed;
|
|
||||||
private int spawnDelay;
|
|
||||||
private int despawnDelay;
|
|
||||||
private boolean applyCosmeticsOnClose;
|
|
||||||
private SoundData openSound;
|
|
||||||
private SoundData closeSound;
|
|
||||||
private Location wardrobeLocation;
|
|
||||||
private Location viewerLocation;
|
|
||||||
private Location leaveLocation;
|
|
||||||
|
|
||||||
public WardrobeSettings(final HMCCosmetics plugin) {
|
|
||||||
this.plugin = plugin;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void load() {
|
|
||||||
final File file = Path.of(this.plugin.getDataFolder().getPath(), "config.yml").toFile();
|
|
||||||
final YamlConfigurationLoader loader = YamlConfigurationLoader.
|
|
||||||
builder().
|
|
||||||
path(file.toPath()).
|
|
||||||
defaultOptions(opts ->
|
|
||||||
opts.serializers(build -> {
|
|
||||||
build.register(SoundData.class, SoundSerializer.INSTANCE);
|
|
||||||
build.register(Location.class, LocationSerializer.INSTANCE);
|
|
||||||
}))
|
|
||||||
.build();
|
|
||||||
try {
|
|
||||||
final var source = loader.load().node(WARDROBE_PATH);
|
|
||||||
this.disableOnDamage = source.node(DISABLE_ON_DAMAGE_PATH).getBoolean();
|
|
||||||
this.displayRadius = source.node(DISPLAY_RADIUS_PATH).getInt();
|
|
||||||
this.portable = source.node(PORTABLE_PATH).getBoolean();
|
|
||||||
this.staticRadius = source.node(STATIC_RADIUS_PATH).getInt();
|
|
||||||
this.alwaysDisplay = source.node(ALWAYS_DISPLAY_PATH).getBoolean();
|
|
||||||
this.rotationSpeed = source.node(ROTATION_SPEED_PATH).getInt();
|
|
||||||
this.spawnDelay = source.node(SPAWN_DELAY_PATH).getInt();
|
|
||||||
this.despawnDelay = source.node(DESPAWN_DELAY_PATH).getInt();
|
|
||||||
this.applyCosmeticsOnClose = source.node(APPLY_COSMETICS_ON_CLOSE).getBoolean();
|
|
||||||
this.openSound = source.node(OPEN_SOUND).get(SoundData.class);
|
|
||||||
this.closeSound = source.node(CLOSE_SOUND).get(SoundData.class);
|
|
||||||
this.wardrobeLocation = source.node(STATIC_LOCATION_PATH).get(Location.class);
|
|
||||||
this.viewerLocation = source.node(VIEWER_LOCATION_PATH).get(Location.class);
|
|
||||||
this.leaveLocation = Utils.replaceIfNull(source.node(LEAVE_LOCATION_PATH).get(Location.class), this.viewerLocation);
|
|
||||||
} catch (final ConfigurateException exception) {
|
|
||||||
this.plugin.getLogger().severe("Error loading wardrobe settings");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getDisableOnDamage() {
|
|
||||||
return disableOnDamage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getDisplayRadius() {
|
|
||||||
return displayRadius;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isPortable() {
|
|
||||||
return portable;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isAlwaysDisplay() {
|
|
||||||
return alwaysDisplay;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getStaticRadius() {
|
|
||||||
return staticRadius;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getRotationSpeed() {
|
|
||||||
return rotationSpeed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSpawnDelay() {
|
|
||||||
return spawnDelay;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getDespawnDelay() {
|
|
||||||
return despawnDelay;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isApplyCosmeticsOnClose() {
|
|
||||||
return applyCosmeticsOnClose;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Location getWardrobeLocation() {
|
|
||||||
return this.wardrobeLocation.clone();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Location getViewerLocation() {
|
|
||||||
return viewerLocation;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Location getLeaveLocation() {
|
|
||||||
return leaveLocation;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void playOpenSound(final Player player) {
|
|
||||||
if (this.openSound == null) return;
|
|
||||||
this.openSound.play(player);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void playCloseSound(final Player player) {
|
|
||||||
if (this.closeSound == null) return;
|
|
||||||
this.closeSound.play(player);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean inDistanceOfWardrobe(final Location wardrobeLocation, final Location playerLocation) {
|
|
||||||
if (this.displayRadius == -1) return true;
|
|
||||||
if (!wardrobeLocation.getWorld().equals(playerLocation.getWorld())) return false;
|
|
||||||
return playerLocation.distanceSquared(wardrobeLocation) <= this.displayRadius * this.displayRadius;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean inDistanceOfStatic(final Location location) {
|
|
||||||
if (this.wardrobeLocation == null) return false;
|
|
||||||
if (this.staticRadius == -1) return false;
|
|
||||||
if (!this.wardrobeLocation.getWorld().equals(location.getWorld())) return false;
|
|
||||||
return this.wardrobeLocation.distanceSquared(location) <= this.staticRadius * this.staticRadius;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
package io.github.fisher2911.hmccosmetics.cosmetic;
|
|
||||||
|
|
||||||
import io.github.fisher2911.hmccosmetics.gui.ArmorItem;
|
|
||||||
import io.github.fisher2911.hmccosmetics.gui.Token;
|
|
||||||
import io.github.fisher2911.hmccosmetics.util.Keys;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.bukkit.persistence.PersistentDataType;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class CosmeticManager {
|
|
||||||
|
|
||||||
private final Map<String, Token> tokenMap;
|
|
||||||
private final Map<String, ArmorItem> armorItemMap;
|
|
||||||
|
|
||||||
public CosmeticManager(final Map<String, Token> tokenMap, final Map<String, ArmorItem> armorItemMap) {
|
|
||||||
this.tokenMap = tokenMap;
|
|
||||||
this.armorItemMap = armorItemMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public ArmorItem getArmorItem(final String id) {
|
|
||||||
return this.armorItemMap.get(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addArmorItem(final ArmorItem armorItem) {
|
|
||||||
this.armorItemMap.put(armorItem.getId(), armorItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Collection<ArmorItem> getAllArmorItems() {
|
|
||||||
return this.armorItemMap.values();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, ArmorItem> getArmorItemMap() {
|
|
||||||
return armorItemMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public Token getToken(final String id) {
|
|
||||||
return this.tokenMap.get(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addToken(final Token token) {
|
|
||||||
this.tokenMap.put(token.getId(), token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Collection<Token> getAllTokens() {
|
|
||||||
return this.tokenMap.values();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, Token> getTokenMap() {
|
|
||||||
return this.tokenMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public Token getToken(final ItemStack itemStack) {
|
|
||||||
final String id = Keys.getValue(itemStack, Keys.TOKEN_KEY, PersistentDataType.STRING);
|
|
||||||
if (id == null) return null;
|
|
||||||
return this.tokenMap.get(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isToken(final ItemStack itemStack) {
|
|
||||||
return Keys.hasKey(itemStack, Keys.TOKEN_KEY, PersistentDataType.STRING);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clearTokens() {
|
|
||||||
this.tokenMap.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -6,9 +6,9 @@ import com.j256.ormlite.support.ConnectionSource;
|
|||||||
import com.j256.ormlite.table.TableUtils;
|
import com.j256.ormlite.table.TableUtils;
|
||||||
import io.github.fisher2911.hmccosmetics.HMCCosmetics;
|
import io.github.fisher2911.hmccosmetics.HMCCosmetics;
|
||||||
import io.github.fisher2911.hmccosmetics.concurrent.Threads;
|
import io.github.fisher2911.hmccosmetics.concurrent.Threads;
|
||||||
import io.github.fisher2911.hmccosmetics.database.dao.ArmorItemDAO;
|
import io.github.fisher2911.hmccosmetics.dao.ArmorItemDAO;
|
||||||
import io.github.fisher2911.hmccosmetics.database.dao.CitizenDAO;
|
import io.github.fisher2911.hmccosmetics.dao.CitizenDAO;
|
||||||
import io.github.fisher2911.hmccosmetics.database.dao.UserDAO;
|
import io.github.fisher2911.hmccosmetics.dao.UserDAO;
|
||||||
import io.github.fisher2911.hmccosmetics.gui.ArmorItem;
|
import io.github.fisher2911.hmccosmetics.gui.ArmorItem;
|
||||||
import io.github.fisher2911.hmccosmetics.inventory.PlayerArmor;
|
import io.github.fisher2911.hmccosmetics.inventory.PlayerArmor;
|
||||||
import io.github.fisher2911.hmccosmetics.user.EntityIds;
|
import io.github.fisher2911.hmccosmetics.user.EntityIds;
|
||||||
@@ -20,11 +20,8 @@ import org.bukkit.entity.Entity;
|
|||||||
|
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Random;
|
|
||||||
import java.util.SplittableRandom;
|
import java.util.SplittableRandom;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.ThreadLocalRandom;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public class Database {
|
public class Database {
|
||||||
|
|||||||
@@ -1,122 +0,0 @@
|
|||||||
package io.github.fisher2911.hmccosmetics.database.dao;
|
|
||||||
|
|
||||||
import com.j256.ormlite.field.DatabaseField;
|
|
||||||
import com.j256.ormlite.table.DatabaseTable;
|
|
||||||
import io.github.fisher2911.hmccosmetics.cosmetic.CosmeticManager;
|
|
||||||
import io.github.fisher2911.hmccosmetics.gui.ArmorItem;
|
|
||||||
import java.util.Objects;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
@DatabaseTable(tableName = "armor_items")
|
|
||||||
public class ArmorItemDAO {
|
|
||||||
|
|
||||||
@DatabaseField(columnName = "uuid", useGetSet = true, uniqueCombo = true)
|
|
||||||
private String uuid;
|
|
||||||
|
|
||||||
@DatabaseField
|
|
||||||
private String id;
|
|
||||||
|
|
||||||
@DatabaseField(id = true, useGetSet = true, columnName = "artificial_id")
|
|
||||||
private String artificialId;
|
|
||||||
|
|
||||||
@DatabaseField(uniqueCombo = true)
|
|
||||||
private String type;
|
|
||||||
|
|
||||||
@DatabaseField(columnName = "color")
|
|
||||||
private int rgbDye;
|
|
||||||
|
|
||||||
public ArmorItemDAO(final String id, final String type, final int rgbDye) {
|
|
||||||
this.id = id;
|
|
||||||
this.artificialId = this.getArtificialId();
|
|
||||||
this.type = type;
|
|
||||||
this.rgbDye = rgbDye;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ArmorItemDAO() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ArmorItemDAO fromArmorItem(final ArmorItem armorItem) {
|
|
||||||
return new ArmorItemDAO(armorItem.getId(), armorItem.getType().toString(), armorItem.getDye());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public ArmorItem toArmorItem(final CosmeticManager cosmeticManager) {
|
|
||||||
final ArmorItem armorItem = cosmeticManager.getArmorItem(this.id);
|
|
||||||
if (armorItem == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
final ArmorItem copy = armorItem.copy();
|
|
||||||
copy.setDye(this.rgbDye);
|
|
||||||
return copy;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUuid() {
|
|
||||||
return uuid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUuid(final String uuid) {
|
|
||||||
this.uuid = uuid;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ORMLite does not allow more than one primary key (WHYYYY???????????)
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public String getArtificialId() {
|
|
||||||
return this.uuid + "-" + this.type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setArtificialId(final String artificialId) {
|
|
||||||
this.artificialId = artificialId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setId(final String id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getType() {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setType(final String type) {
|
|
||||||
this.type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getRgbDye() {
|
|
||||||
return rgbDye;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRgbDye(final int rgbDye) {
|
|
||||||
this.rgbDye = rgbDye;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(final Object o) {
|
|
||||||
if (this == o) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (o == null || getClass() != o.getClass()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
final ArmorItemDAO that = (ArmorItemDAO) o;
|
|
||||||
return Objects.equals(getUuid(), that.getUuid()) && Objects.equals(getType(),
|
|
||||||
that.getType());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hash(getUuid(), getType());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "ArmorItemDAO{" +
|
|
||||||
"uuid='" + uuid + '\'' +
|
|
||||||
", id='" + id + '\'' +
|
|
||||||
", type='" + type + '\'' +
|
|
||||||
", rgbDye=" + rgbDye +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
package io.github.fisher2911.hmccosmetics.database.dao;
|
|
||||||
|
|
||||||
import com.j256.ormlite.field.DatabaseField;
|
|
||||||
import com.j256.ormlite.table.DatabaseTable;
|
|
||||||
import io.github.fisher2911.hmccosmetics.cosmetic.CosmeticManager;
|
|
||||||
import io.github.fisher2911.hmccosmetics.gui.ArmorItem;
|
|
||||||
import io.github.fisher2911.hmccosmetics.inventory.PlayerArmor;
|
|
||||||
import io.github.fisher2911.hmccosmetics.user.EntityIds;
|
|
||||||
import io.github.fisher2911.hmccosmetics.user.NPCUser;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
@DatabaseTable(tableName = "citizen")
|
|
||||||
public class CitizenDAO {
|
|
||||||
|
|
||||||
@DatabaseField(id = true)
|
|
||||||
private int citizensId;
|
|
||||||
|
|
||||||
public CitizenDAO() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public CitizenDAO(final int citizensId) {
|
|
||||||
this.citizensId = citizensId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCitizensId(final int citizensId) {
|
|
||||||
this.citizensId = citizensId;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public NPCUser toUser(
|
|
||||||
final CosmeticManager cosmeticManager,
|
|
||||||
final EntityIds entityIds,
|
|
||||||
final List<ArmorItemDAO> armorItems
|
|
||||||
) {
|
|
||||||
final PlayerArmor playerArmor = PlayerArmor.empty();
|
|
||||||
|
|
||||||
for (final ArmorItemDAO armorItemDao : armorItems) {
|
|
||||||
final ArmorItem armorItem = armorItemDao.toArmorItem(cosmeticManager);
|
|
||||||
if (armorItem == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
playerArmor.setItem(armorItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new NPCUser(this.citizensId, playerArmor, entityIds);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(final Object o) {
|
|
||||||
if (this == o) return true;
|
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
|
||||||
final CitizenDAO that = (CitizenDAO) o;
|
|
||||||
return citizensId == that.citizensId;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hash(citizensId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
package io.github.fisher2911.hmccosmetics.database.dao;
|
|
||||||
|
|
||||||
import com.j256.ormlite.field.DatabaseField;
|
|
||||||
import com.j256.ormlite.table.DatabaseTable;
|
|
||||||
import io.github.fisher2911.hmccosmetics.cosmetic.CosmeticManager;
|
|
||||||
import io.github.fisher2911.hmccosmetics.gui.ArmorItem;
|
|
||||||
import io.github.fisher2911.hmccosmetics.inventory.PlayerArmor;
|
|
||||||
import io.github.fisher2911.hmccosmetics.user.EntityIds;
|
|
||||||
import io.github.fisher2911.hmccosmetics.user.User;
|
|
||||||
import io.github.fisher2911.hmccosmetics.user.Wardrobe;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
@DatabaseTable(tableName = "user")
|
|
||||||
public class UserDAO {
|
|
||||||
|
|
||||||
@DatabaseField(id = true)
|
|
||||||
private UUID uuid;
|
|
||||||
|
|
||||||
public UserDAO() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public UserDAO(final UUID uuid) {
|
|
||||||
this.uuid = uuid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUuid(final UUID uuid) {
|
|
||||||
this.uuid = uuid;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public User toUser(
|
|
||||||
final CosmeticManager cosmeticManager,
|
|
||||||
final EntityIds entityIds,
|
|
||||||
final List<ArmorItemDAO> armorItems,
|
|
||||||
final Wardrobe wardrobe
|
|
||||||
) {
|
|
||||||
final PlayerArmor playerArmor = PlayerArmor.empty();
|
|
||||||
|
|
||||||
for (final ArmorItemDAO armorItemDao : armorItems) {
|
|
||||||
final ArmorItem armorItem = armorItemDao.toArmorItem(cosmeticManager);
|
|
||||||
if (armorItem == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
playerArmor.setItem(armorItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new User(this.uuid, playerArmor, wardrobe, entityIds);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "UserDAO{" +
|
|
||||||
"uuid=" + uuid +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(final Object o) {
|
|
||||||
if (this == o) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (o == null || getClass() != o.getClass()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
final UserDAO userDAO = (UserDAO) o;
|
|
||||||
return Objects.equals(uuid, userDAO.uuid);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hash(uuid);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,13 +1,8 @@
|
|||||||
package io.github.fisher2911.hmccosmetics.gui;
|
package io.github.fisher2911.hmccosmetics.gui;
|
||||||
|
|
||||||
import com.comphenix.protocol.wrappers.EnumWrappers;
|
|
||||||
import dev.triumphteam.gui.components.GuiAction;
|
import dev.triumphteam.gui.components.GuiAction;
|
||||||
import io.github.fisher2911.hmccosmetics.config.CosmeticGuiAction;
|
import io.github.fisher2911.hmccosmetics.config.CosmeticGuiAction;
|
||||||
import io.github.fisher2911.hmccosmetics.util.builder.ColorBuilder;
|
import io.github.fisher2911.hmccosmetics.util.builder.ColorBuilder;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.bukkit.Color;
|
import org.bukkit.Color;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||||
@@ -16,6 +11,9 @@ import org.bukkit.inventory.ItemStack;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class ArmorItem extends WrappedGuiItem {
|
public class ArmorItem extends WrappedGuiItem {
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
@@ -338,13 +336,13 @@ public class ArmorItem extends WrappedGuiItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static Type fromWrapper(EnumWrappers.ItemSlot slot) {
|
public static Type fromWrapper(EquipmentSlot slot) {
|
||||||
return switch (slot) {
|
return switch (slot) {
|
||||||
case HEAD -> Type.HAT;
|
case HEAD -> Type.HAT;
|
||||||
case CHEST -> Type.CHEST_PLATE;
|
case CHEST -> Type.CHEST_PLATE;
|
||||||
case LEGS -> Type.PANTS;
|
case LEGS -> Type.PANTS;
|
||||||
case FEET -> Type.BOOTS;
|
case FEET -> Type.BOOTS;
|
||||||
case OFFHAND -> Type.OFF_HAND;
|
case OFF_HAND -> Type.OFF_HAND;
|
||||||
default -> null;
|
default -> null;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,34 +1,14 @@
|
|||||||
package io.github.fisher2911.hmccosmetics.listener;
|
package io.github.fisher2911.hmccosmetics.listener;
|
||||||
|
|
||||||
import io.github.fisher2911.hmccosmetics.HMCCosmetics;
|
import io.github.fisher2911.hmccosmetics.HMCCosmetics;
|
||||||
import io.github.fisher2911.hmccosmetics.user.Equipment;
|
|
||||||
import io.github.fisher2911.hmccosmetics.user.User;
|
|
||||||
import io.github.fisher2911.hmccosmetics.user.UserManager;
|
import io.github.fisher2911.hmccosmetics.user.UserManager;
|
||||||
|
|
||||||
import java.util.EnumMap;
|
|
||||||
import java.util.EnumSet;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.bukkit.BanList;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.block.Block;
|
|
||||||
import org.bukkit.entity.HumanEntity;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.block.Action;
|
|
||||||
import org.bukkit.event.inventory.ClickType;
|
|
||||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
|
||||||
import org.bukkit.event.inventory.InventoryCloseEvent;
|
|
||||||
import org.bukkit.event.inventory.InventoryDragEvent;
|
|
||||||
import org.bukkit.event.player.PlayerInteractEvent;
|
|
||||||
import org.bukkit.inventory.EquipmentSlot;
|
import org.bukkit.inventory.EquipmentSlot;
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import java.util.EnumSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
public class ClickListener implements Listener {
|
public class ClickListener implements Listener {
|
||||||
|
|
||||||
@@ -77,86 +57,86 @@ public class ClickListener implements Listener {
|
|||||||
this.userManager = this.plugin.getUserManager();
|
this.userManager = this.plugin.getUserManager();
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
// @EventHandler
|
||||||
public void onArmorSlotClick(final InventoryClickEvent event) {
|
// public void onArmorSlotClick(final InventoryClickEvent event) {
|
||||||
final int slot = event.getSlot();
|
// final int slot = event.getSlot();
|
||||||
if (!(event.getWhoClicked() instanceof final Player player)) return;
|
// if (!(event.getWhoClicked() instanceof final Player player)) return;
|
||||||
if (slot >= 36 && slot <= 40) {
|
// if (slot >= 36 && slot <= 40) {
|
||||||
this.fixInventory(player);
|
// this.fixInventory(player);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@EventHandler
|
// @EventHandler
|
||||||
public void onBlockClick(final PlayerInteractEvent event) {
|
// public void onBlockClick(final PlayerInteractEvent event) {
|
||||||
if (event.getAction() != Action.RIGHT_CLICK_BLOCK) return;
|
// if (event.getAction() != Action.RIGHT_CLICK_BLOCK) return;
|
||||||
final Player player = event.getPlayer();
|
// final Player player = event.getPlayer();
|
||||||
final Block block = event.getClickedBlock();
|
// final Block block = event.getClickedBlock();
|
||||||
if (block != null && block.getType().isInteractable() && !player.isSneaking()) return;
|
// if (block != null && block.getType().isInteractable() && !player.isSneaking()) return;
|
||||||
final ItemStack clickedWith = event.getItem();
|
// final ItemStack clickedWith = event.getItem();
|
||||||
if (clickedWith == null) return;
|
// if (clickedWith == null) return;
|
||||||
this.checkFix(player, -1, clickedWith);
|
// this.checkFix(player, -1, clickedWith);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@EventHandler
|
// @EventHandler
|
||||||
public void onShiftClick(final InventoryClickEvent event) {
|
// public void onShiftClick(final InventoryClickEvent event) {
|
||||||
if (event.getClick() != ClickType.SHIFT_LEFT &&
|
// if (event.getClick() != ClickType.SHIFT_LEFT &&
|
||||||
event.getClick() != ClickType.SHIFT_RIGHT) return;
|
// event.getClick() != ClickType.SHIFT_RIGHT) return;
|
||||||
if (!(event.getWhoClicked() instanceof final Player player)) return;
|
// if (!(event.getWhoClicked() instanceof final Player player)) return;
|
||||||
final ItemStack clicked = event.getCurrentItem();
|
// final ItemStack clicked = event.getCurrentItem();
|
||||||
if (clicked == null) return;
|
// if (clicked == null) return;
|
||||||
this.checkFix(player, -1, clicked);
|
// this.checkFix(player, -1, clicked);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@EventHandler
|
// @EventHandler
|
||||||
public void onCosmeticClick(final InventoryDragEvent event) {
|
// public void onCosmeticClick(final InventoryDragEvent event) {
|
||||||
final HumanEntity player = event.getWhoClicked();
|
// final HumanEntity player = event.getWhoClicked();
|
||||||
if (!(player instanceof Player)) {
|
// if (!(player instanceof Player)) {
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
// this.fixInventory((Player) player);
|
//// this.fixInventory((Player) player);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@EventHandler
|
// @EventHandler
|
||||||
public void onInventoryClose(final InventoryCloseEvent event) {
|
// public void onInventoryClose(final InventoryCloseEvent event) {
|
||||||
final HumanEntity player = event.getPlayer();
|
// final HumanEntity player = event.getPlayer();
|
||||||
this.userManager.get(player.getUniqueId()).ifPresent(this::doRunnable);
|
// this.userManager.get(player.getUniqueId()).ifPresent(this::doRunnable);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
private void fixInventory(final Player player) {
|
// private void fixInventory(final Player player) {
|
||||||
final Optional<User> optionalUser = this.userManager.get(player.getUniqueId());
|
// final Optional<User> optionalUser = this.userManager.get(player.getUniqueId());
|
||||||
|
//
|
||||||
if (optionalUser.isEmpty()) {
|
// if (optionalUser.isEmpty()) {
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
this.doRunnable(optionalUser.get());
|
// this.doRunnable(optionalUser.get());
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
private void doRunnable(final User user) {
|
// private void doRunnable(final User user) {
|
||||||
Bukkit.getScheduler().runTaskLaterAsynchronously(
|
// Bukkit.getScheduler().runTaskLaterAsynchronously(
|
||||||
this.plugin, () -> this.userManager.updateCosmetics(user),
|
// this.plugin, () -> this.userManager.updateCosmetics(user),
|
||||||
1);
|
// 1);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
private void checkFix(final Player player, final int clickedSlot, final ItemStack itemStack) {
|
// private void checkFix(final Player player, final int clickedSlot, final ItemStack itemStack) {
|
||||||
final EquipmentSlot slot = this.getArmorSlot(itemStack.getType());
|
// final EquipmentSlot slot = this.getArmorSlot(itemStack.getType());
|
||||||
if (slot == null) return;
|
// if (slot == null) return;
|
||||||
final ItemStack wearing = player.getEquipment().getItem(slot);
|
// final ItemStack wearing = player.getEquipment().getItem(slot);
|
||||||
if (wearing == null) return;
|
// if (wearing == null) return;
|
||||||
if (wearing.getType() == Material.AIR || (clickedSlot >= 39 && clickedSlot <= 40)) {
|
// if (wearing.getType() == Material.AIR || (clickedSlot >= 39 && clickedSlot <= 40)) {
|
||||||
this.fixInventory(player);
|
// this.fixInventory(player);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Nullable
|
// @Nullable
|
||||||
private EquipmentSlot getArmorSlot(final Material material) {
|
// private EquipmentSlot getArmorSlot(final Material material) {
|
||||||
for (final EquipmentSlot slot : EquipmentSlot.values()) {
|
// for (final EquipmentSlot slot : EquipmentSlot.values()) {
|
||||||
final Set<Material> armorItems = ARMOR_ITEMS.get(slot);
|
// final Set<Material> armorItems = ARMOR_ITEMS.get(slot);
|
||||||
if (armorItems == null) continue;
|
// if (armorItems == null) continue;
|
||||||
if (material == null) continue;
|
// if (material == null) continue;
|
||||||
if (armorItems.contains(material)) return slot;
|
// if (armorItems.contains(material)) return slot;
|
||||||
}
|
// }
|
||||||
return null;
|
// return null;
|
||||||
}
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,46 +1,346 @@
|
|||||||
package io.github.fisher2911.hmccosmetics.listener;
|
package io.github.fisher2911.hmccosmetics.listener;
|
||||||
|
|
||||||
|
import com.github.retrooper.packetevents.PacketEvents;
|
||||||
|
import com.github.retrooper.packetevents.event.PacketListenerAbstract;
|
||||||
|
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||||
|
import com.github.retrooper.packetevents.event.PacketSendEvent;
|
||||||
|
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||||
|
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientClickWindow;
|
||||||
|
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerWindowItems;
|
||||||
import io.github.fisher2911.hmccosmetics.HMCCosmetics;
|
import io.github.fisher2911.hmccosmetics.HMCCosmetics;
|
||||||
|
import io.github.fisher2911.hmccosmetics.config.CosmeticSettings;
|
||||||
|
import io.github.fisher2911.hmccosmetics.gui.ArmorItem;
|
||||||
|
import io.github.fisher2911.hmccosmetics.inventory.PlayerArmor;
|
||||||
|
import io.github.fisher2911.hmccosmetics.message.Placeholder;
|
||||||
|
import io.github.fisher2911.hmccosmetics.message.Translation;
|
||||||
|
import io.github.fisher2911.hmccosmetics.packet.PacketManager;
|
||||||
|
import io.github.fisher2911.hmccosmetics.task.DelayedTask;
|
||||||
|
import io.github.fisher2911.hmccosmetics.task.TaskManager;
|
||||||
|
import io.github.fisher2911.hmccosmetics.user.Equipment;
|
||||||
|
import io.github.fisher2911.hmccosmetics.user.User;
|
||||||
import io.github.fisher2911.hmccosmetics.user.UserManager;
|
import io.github.fisher2911.hmccosmetics.user.UserManager;
|
||||||
|
import io.github.fisher2911.hmccosmetics.util.Utils;
|
||||||
|
import io.github.fisher2911.hmccosmetics.util.builder.ItemBuilder;
|
||||||
|
import io.github.retrooper.packetevents.util.SpigotDataHelper;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
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.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.block.BlockPlaceEvent;
|
import org.bukkit.event.block.BlockPlaceEvent;
|
||||||
|
import org.bukkit.event.inventory.ClickType;
|
||||||
|
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||||
import org.bukkit.event.player.PlayerSwapHandItemsEvent;
|
import org.bukkit.event.player.PlayerSwapHandItemsEvent;
|
||||||
|
import org.bukkit.inventory.EntityEquipment;
|
||||||
import org.bukkit.inventory.EquipmentSlot;
|
import org.bukkit.inventory.EquipmentSlot;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.spigotmc.event.entity.EntityMountEvent;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.EnumSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
public class CosmeticFixListener implements Listener {
|
public class CosmeticFixListener implements Listener {
|
||||||
|
|
||||||
private final HMCCosmetics plugin;
|
private final HMCCosmetics plugin;
|
||||||
private final UserManager userManager;
|
private final UserManager userManager;
|
||||||
|
private final CosmeticSettings settings;
|
||||||
|
private final TaskManager taskManager;
|
||||||
|
|
||||||
public CosmeticFixListener(final HMCCosmetics plugin) {
|
public CosmeticFixListener(final HMCCosmetics plugin) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
this.userManager = this.plugin.getUserManager();
|
this.userManager = this.plugin.getUserManager();
|
||||||
|
this.settings = this.plugin.getSettings().getCosmeticSettings();
|
||||||
|
this.taskManager = this.plugin.getTaskManager();
|
||||||
|
this.registerPacketListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
final Map<EquipmentSlot, Set<Material>> ARMOR_ITEMS = Map.of(
|
||||||
|
EquipmentSlot.HEAD, EnumSet.of(
|
||||||
|
Material.LEATHER_HELMET,
|
||||||
|
Material.CHAINMAIL_HELMET,
|
||||||
|
Material.IRON_HELMET,
|
||||||
|
Material.GOLDEN_HELMET,
|
||||||
|
Material.DIAMOND_HELMET,
|
||||||
|
Material.NETHERITE_HELMET,
|
||||||
|
Material.TURTLE_HELMET
|
||||||
|
),
|
||||||
|
EquipmentSlot.CHEST, EnumSet.of(
|
||||||
|
Material.LEATHER_CHESTPLATE,
|
||||||
|
Material.CHAINMAIL_CHESTPLATE,
|
||||||
|
Material.IRON_CHESTPLATE,
|
||||||
|
Material.GOLDEN_CHESTPLATE,
|
||||||
|
Material.DIAMOND_CHESTPLATE,
|
||||||
|
Material.NETHERITE_CHESTPLATE,
|
||||||
|
Material.ELYTRA
|
||||||
|
),
|
||||||
|
EquipmentSlot.LEGS, EnumSet.of(
|
||||||
|
Material.LEATHER_LEGGINGS,
|
||||||
|
Material.CHAINMAIL_LEGGINGS,
|
||||||
|
Material.IRON_LEGGINGS,
|
||||||
|
Material.GOLDEN_LEGGINGS,
|
||||||
|
Material.DIAMOND_LEGGINGS,
|
||||||
|
Material.NETHERITE_LEGGINGS
|
||||||
|
),
|
||||||
|
EquipmentSlot.FEET, EnumSet.of(
|
||||||
|
Material.LEATHER_BOOTS,
|
||||||
|
Material.CHAINMAIL_BOOTS,
|
||||||
|
Material.IRON_BOOTS,
|
||||||
|
Material.GOLDEN_BOOTS,
|
||||||
|
Material.DIAMOND_BOOTS,
|
||||||
|
Material.NETHERITE_BOOTS
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
public void registerPacketListeners() {
|
||||||
|
this.registerMenuChangeListener();
|
||||||
|
this.registerInventoryClickListener();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void registerClickAirListener() {
|
||||||
|
// PacketEvents.getAPI().getEventManager().registerListener(
|
||||||
|
// new PacketListener() {
|
||||||
|
// @Override
|
||||||
|
// public void onPacketReceive(PacketReceiveEvent event) {
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
// }.asAbstract(PacketListenerPriority.HIGHEST, false, true)
|
||||||
|
// );
|
||||||
|
// ProtocolLibrary.getProtocolManager().addPacketListener(
|
||||||
|
// new PacketAdapter(this.plugin, ListenerPriority.MONITOR, PacketType.Play.Client.BLOCK_PLACE) {
|
||||||
|
// @Override
|
||||||
|
// public void onPacketReceiving(PacketEvent event) {
|
||||||
|
// final Player player = event.getPlayer();
|
||||||
|
// final Optional<User> optionalUser = CosmeticFixListener.this.userManager.get(player.getUniqueId());
|
||||||
|
// if (optionalUser.isEmpty()) return;
|
||||||
|
// final ItemStack inHand = player.getInventory().getItemInMainHand();
|
||||||
|
// if (inHand == null || inHand.getType() == Material.AIR) return;
|
||||||
|
// final EquipmentSlot slot = getArmorSlot(inHand.getType());
|
||||||
|
// if (slot == null) {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// final ArmorItem.Type type = ArmorItem.Type.fromEquipmentSlot(slot);
|
||||||
|
// if (type == null) {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// final User user = optionalUser.get();
|
||||||
|
// final Location location = player.getLocation();
|
||||||
|
// taskManager.submit(() -> {
|
||||||
|
// final EntityEquipment entityEquipment = player.getEquipment();
|
||||||
|
// final Equipment equipment;
|
||||||
|
// if (entityEquipment == null) {
|
||||||
|
// equipment = Equipment.fromEntityEquipment(player.getEquipment());
|
||||||
|
// } else {
|
||||||
|
// equipment = new Equipment();
|
||||||
|
// }
|
||||||
|
// equipment.setItem(
|
||||||
|
// slot,
|
||||||
|
// getCosmeticItem(
|
||||||
|
// user.getPlayerArmor().getItem(type),
|
||||||
|
// inHand,
|
||||||
|
// ArmorItem.Status.APPLIED,
|
||||||
|
// slot
|
||||||
|
// )
|
||||||
|
// );
|
||||||
|
// final List<Pair<EnumWrappers.ItemSlot, ItemStack>> items = getItemList(player, user, equipment, Set.of(type));
|
||||||
|
// for (final Player p : Bukkit.getOnlinePlayers()) {
|
||||||
|
// if (!settings.isInViewDistance(location, p.getLocation())) continue;
|
||||||
|
// sendUpdatePacket(
|
||||||
|
// user.getEntityId(),
|
||||||
|
// p,
|
||||||
|
// items
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// );
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onEntityMount(final EntityMountEvent event) {
|
public void onShiftClick(final InventoryClickEvent event) {
|
||||||
if (!(event.getEntity() instanceof final Player player)) {
|
if (event.getClick() != ClickType.SHIFT_LEFT && event.getClick() != ClickType.SHIFT_RIGHT) return;
|
||||||
return;
|
if (!(event.getWhoClicked() instanceof final Player player)) return;
|
||||||
|
final int clickedSlot = event.getSlot();
|
||||||
|
final ItemStack clicked = event.getCurrentItem();
|
||||||
|
if (clicked == null) return;
|
||||||
|
final EquipmentSlot slot = this.getArmorSlot(clicked.getType());
|
||||||
|
if (slot == null) return;
|
||||||
|
final Optional<User> user = this.userManager.get(player.getUniqueId());
|
||||||
|
if (user.isEmpty()) return;
|
||||||
|
final ArmorItem.Type type = ArmorItem.Type.fromWrapper(slot);
|
||||||
|
if (type == null) return;
|
||||||
|
final EntityEquipment equipment = player.getEquipment();
|
||||||
|
final ItemStack current;
|
||||||
|
if (equipment == null) {
|
||||||
|
current = new ItemStack(Material.AIR);
|
||||||
|
} else {
|
||||||
|
current = equipment.getItem(slot);
|
||||||
}
|
}
|
||||||
this.fixCosmetics(player);
|
updateOnClick(
|
||||||
|
player,
|
||||||
|
slot,
|
||||||
|
user.get(),
|
||||||
|
type,
|
||||||
|
current
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
private void registerInventoryClickListener() {
|
||||||
|
PacketEvents.getAPI().getEventManager().registerListener(
|
||||||
|
new PacketListenerAbstract() {
|
||||||
|
@Override
|
||||||
|
public void onPacketReceive(PacketReceiveEvent event) {
|
||||||
|
if (event.getPacketType() != PacketType.Play.Client.CLICK_WINDOW) return;
|
||||||
|
final WrapperPlayClientClickWindow packet = new WrapperPlayClientClickWindow(event);
|
||||||
|
if (packet.getWindowId() != 0) return;
|
||||||
|
if (!(event.getPlayer() instanceof final Player player)) return;
|
||||||
|
final Optional<User> optionalUser = userManager.get(player.getUniqueId());
|
||||||
|
if (optionalUser.isEmpty()) return;
|
||||||
|
final User user = optionalUser.get();
|
||||||
|
int slotClicked = packet.getSlot();
|
||||||
|
final WrapperPlayClientClickWindow.WindowClickType clickType = packet.getWindowClickType();
|
||||||
|
EquipmentSlot slot = getPacketArmorSlot(slotClicked);
|
||||||
|
if (slot == null) return;
|
||||||
|
final EntityEquipment entityEquipment = player.getEquipment();
|
||||||
|
if (entityEquipment == null) return;
|
||||||
|
final ItemStack current = Utils.replaceIfNull(entityEquipment.getItem(slot), new ItemStack(Material.AIR));
|
||||||
|
final ArmorItem.Type type = ArmorItem.Type.fromEquipmentSlot(slot);
|
||||||
|
if (type == null) return;
|
||||||
|
updateOnClick(
|
||||||
|
player,
|
||||||
|
slot,
|
||||||
|
user,
|
||||||
|
type,
|
||||||
|
current
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateOnClick(final Player player, final EquipmentSlot slot, final User user, final ArmorItem.Type type, final ItemStack current) {
|
||||||
|
taskManager.submit(() -> {
|
||||||
|
final Location location = player.getLocation();
|
||||||
|
final Equipment equipment = Equipment.fromEntityEquipment(player.getEquipment());
|
||||||
|
final ItemStack cosmetic = getCosmeticItem(
|
||||||
|
user.getPlayerArmor().getItem(type),
|
||||||
|
current,
|
||||||
|
ArmorItem.Status.APPLIED,
|
||||||
|
slot
|
||||||
|
);
|
||||||
|
if (cosmetic != null && cosmetic.getType() != Material.AIR) equipment.setItem(slot, cosmetic);
|
||||||
|
|
||||||
|
final List<com.github.retrooper.packetevents.protocol.player.Equipment> items =
|
||||||
|
getItemList(user, equipment, Set.of(type));
|
||||||
|
for (final Player other : Bukkit.getOnlinePlayers()) {
|
||||||
|
if (!settings.isInViewDistance(location, other.getLocation())) continue;
|
||||||
|
sendUpdatePacket(
|
||||||
|
user.getEntityId(),
|
||||||
|
other,
|
||||||
|
items
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void registerMenuChangeListener() {
|
||||||
|
PacketEvents.getAPI().getEventManager().registerListener(
|
||||||
|
new PacketListenerAbstract() {
|
||||||
|
@Override
|
||||||
|
public void onPacketSend(PacketSendEvent event) {
|
||||||
|
if (event.getPacketType() != PacketType.Play.Server.WINDOW_ITEMS) return;
|
||||||
|
final WrapperPlayServerWindowItems packet = new WrapperPlayServerWindowItems(event);
|
||||||
|
if (!(event.getPlayer() instanceof final Player player)) return;
|
||||||
|
final Optional<User> optionalUser = userManager.get(player.getUniqueId());
|
||||||
|
if (optionalUser.isEmpty()) return;
|
||||||
|
final User user = optionalUser.get();
|
||||||
|
if (packet.getWindowId() != 0) return;
|
||||||
|
final List<com.github.retrooper.packetevents.protocol.item.ItemStack> itemStacks = packet.getItems();
|
||||||
|
final int size = itemStacks.size();
|
||||||
|
final PlayerArmor playerArmor = user.getPlayerArmor();
|
||||||
|
for (final ArmorItem armorItem : playerArmor.getArmorItems()) {
|
||||||
|
final ArmorItem.Type type = armorItem.getType();
|
||||||
|
final EquipmentSlot slot = type.getSlot();
|
||||||
|
if (slot == null) continue;
|
||||||
|
final int packetSlot = getPacketArmorSlot(slot);
|
||||||
|
if (packetSlot == -1) continue;
|
||||||
|
if (packetSlot >= size) continue;
|
||||||
|
final ItemStack current = SpigotDataHelper.toBukkitItemStack(itemStacks.get(packetSlot));
|
||||||
|
final com.github.retrooper.packetevents.protocol.item.ItemStack setTo =
|
||||||
|
SpigotDataHelper.fromBukkitItemStack(getCosmeticItem(
|
||||||
|
armorItem,
|
||||||
|
current,
|
||||||
|
ArmorItem.Status.APPLIED,
|
||||||
|
slot
|
||||||
|
));
|
||||||
|
itemStacks.set(packetSlot, setTo);
|
||||||
|
}
|
||||||
|
packet.setItems(itemStacks);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// @EventHandler
|
||||||
|
// public void onBlockClick(final PlayerInteractEvent event) {
|
||||||
|
// if (event.getAction() != Action.RIGHT_CLICK_BLOCK) return;
|
||||||
|
// final Player player = event.getPlayer();
|
||||||
|
// final Block block = event.getClickedBlock();
|
||||||
|
// if (block != null && block.getType().isInteractable() && !player.isSneaking()) return;
|
||||||
|
// final ItemStack clickedWith = event.getItem();
|
||||||
|
// if (clickedWith == null) return;
|
||||||
|
// this.checkFix(player, -1, clickedWith);
|
||||||
|
// }
|
||||||
|
|
||||||
|
private int getPacketArmorSlot(final EquipmentSlot slot) {
|
||||||
|
return switch (slot) {
|
||||||
|
case HEAD -> 5;
|
||||||
|
case CHEST -> 6;
|
||||||
|
case LEGS -> 7;
|
||||||
|
case FEET -> 8;
|
||||||
|
case OFF_HAND -> 45;
|
||||||
|
default -> -1;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public EquipmentSlot getPacketArmorSlot(final int slot) {
|
||||||
|
return switch (slot) {
|
||||||
|
case 5 -> EquipmentSlot.HEAD;
|
||||||
|
case 6 -> EquipmentSlot.CHEST;
|
||||||
|
case 7 -> EquipmentSlot.LEGS;
|
||||||
|
case 8 -> EquipmentSlot.FEET;
|
||||||
|
case 45 -> EquipmentSlot.OFF_HAND;
|
||||||
|
default -> null;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// @EventHandler
|
||||||
|
// public void onEntityMount(final EntityMountEvent event) {
|
||||||
|
// if (!(event.getEntity() instanceof final Player player)) {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// this.fixCosmetics(player);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
|
||||||
public void onOffhandSwap(final PlayerSwapHandItemsEvent event) {
|
public void onOffhandSwap(final PlayerSwapHandItemsEvent event) {
|
||||||
final ItemStack offHand = event.getOffHandItem();
|
final ItemStack offHand = event.getOffHandItem();
|
||||||
if (offHand != null && offHand.getType() != Material.AIR) {
|
if (offHand != null && offHand.getType() != Material.AIR) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.fixCosmetics(event.getPlayer());
|
final Player player = event.getPlayer();
|
||||||
|
this.fixOffHand(player, new ItemStack(Material.AIR));
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(ignoreCancelled = true)
|
|
||||||
|
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
|
||||||
public void onBlockPlace(final BlockPlaceEvent event) {
|
public void onBlockPlace(final BlockPlaceEvent event) {
|
||||||
if (event.getHand() != EquipmentSlot.OFF_HAND) {
|
if (event.getHand() != EquipmentSlot.OFF_HAND) {
|
||||||
return;
|
return;
|
||||||
@@ -51,7 +351,60 @@ public class CosmeticFixListener implements Listener {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.fixCosmetics(event.getPlayer());
|
this.fixOffHand(event.getPlayer(), new ItemStack(Material.AIR));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fixOffHand(final Player player, final ItemStack current) {
|
||||||
|
final Optional<User> optionalUser = this.userManager.get(player.getUniqueId());
|
||||||
|
if (optionalUser.isEmpty()) return;
|
||||||
|
final User user = optionalUser.get();
|
||||||
|
final ArmorItem.Type type = ArmorItem.Type.OFF_HAND;
|
||||||
|
final ArmorItem armorItem = user.getPlayerArmor().getItem(type);
|
||||||
|
this.taskManager.submit(new DelayedTask(() -> this.sendUpdatePacket(
|
||||||
|
player.getEntityId(),
|
||||||
|
player,
|
||||||
|
armorItem,
|
||||||
|
current,
|
||||||
|
type
|
||||||
|
), 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<com.github.retrooper.packetevents.protocol.player.Equipment> getItemList(
|
||||||
|
final User user,
|
||||||
|
final Equipment equipment,
|
||||||
|
final Set<ArmorItem.Type> ignored
|
||||||
|
) {
|
||||||
|
final PlayerArmor armor = user.getPlayerArmor();
|
||||||
|
final List<com.github.retrooper.packetevents.protocol.player.Equipment> items = new ArrayList<>();
|
||||||
|
for (final ArmorItem.Type type : ArmorItem.Type.values()) {
|
||||||
|
final EquipmentSlot slot = type.getSlot();
|
||||||
|
if (slot == null) continue;
|
||||||
|
if (ignored.contains(type)) {
|
||||||
|
items.add(this.getEquipment(equipment.getItem(slot), slot));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
final ItemStack wearing = Utils.replaceIfNull(equipment.getItem(slot), new ItemStack(Material.AIR));
|
||||||
|
final ItemStack itemStack = this.getCosmeticItem(
|
||||||
|
armor.getItem(type),
|
||||||
|
wearing,
|
||||||
|
ArmorItem.Status.APPLIED,
|
||||||
|
slot
|
||||||
|
);
|
||||||
|
if (itemStack.getType() != Material.AIR) items.add(this.getEquipment(itemStack, slot));
|
||||||
|
}
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private EquipmentSlot getArmorSlot(final Material material) {
|
||||||
|
for (final EquipmentSlot slot : EquipmentSlot.values()) {
|
||||||
|
final Set<Material> armorItems = ARMOR_ITEMS.get(slot);
|
||||||
|
if (armorItems == null) continue;
|
||||||
|
if (material == null) continue;
|
||||||
|
if (armorItems.contains(material)) return slot;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fixCosmetics(final Player player) {
|
private void fixCosmetics(final Player player) {
|
||||||
@@ -59,4 +412,67 @@ public class CosmeticFixListener implements Listener {
|
|||||||
() -> this.userManager.updateCosmetics(player.getUniqueId()), 2);
|
() -> this.userManager.updateCosmetics(player.getUniqueId()), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void sendUpdatePacket(
|
||||||
|
final int entityId,
|
||||||
|
final Player other,
|
||||||
|
final ArmorItem armorItem,
|
||||||
|
final ItemStack wearing,
|
||||||
|
final ArmorItem.Type type) {
|
||||||
|
final EquipmentSlot slot = type.getSlot();
|
||||||
|
final ItemStack itemStack = this.getCosmeticItem(armorItem, wearing, ArmorItem.Status.APPLIED, slot);
|
||||||
|
final List<com.github.retrooper.packetevents.protocol.player.Equipment> itemList = new ArrayList<>();
|
||||||
|
itemList.add(this.getEquipment(itemStack, slot));
|
||||||
|
this.sendUpdatePacket(entityId, other, itemList);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendUpdatePacket(
|
||||||
|
final int entityId,
|
||||||
|
final Player other,
|
||||||
|
List<com.github.retrooper.packetevents.protocol.player.Equipment> items) {
|
||||||
|
PacketManager.sendEquipmentPacket(
|
||||||
|
items,
|
||||||
|
entityId,
|
||||||
|
other
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private com.github.retrooper.packetevents.protocol.player.Equipment getEquipment(
|
||||||
|
final ItemStack itemStack,
|
||||||
|
final EquipmentSlot slot
|
||||||
|
) {
|
||||||
|
return new com.github.retrooper.packetevents.protocol.player.Equipment(
|
||||||
|
PacketManager.fromBukkitSlot(slot),
|
||||||
|
SpigotDataHelper.fromBukkitItemStack(itemStack)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ItemStack getCosmeticItem(
|
||||||
|
final ArmorItem armorItem,
|
||||||
|
final ItemStack wearing,
|
||||||
|
final ArmorItem.Status status,
|
||||||
|
final EquipmentSlot slot
|
||||||
|
) {
|
||||||
|
final Map<String, String> placeholders = Map.of(Placeholder.ALLOWED, Translation.TRUE,
|
||||||
|
Placeholder.ENABLED, Translation.TRUE);
|
||||||
|
|
||||||
|
if (armorItem.isEmpty()) return wearing;
|
||||||
|
|
||||||
|
ItemStack itemStack = ItemBuilder.from(armorItem.getItemStack(status)).
|
||||||
|
namePlaceholders(placeholders).
|
||||||
|
lorePlaceholders(placeholders).
|
||||||
|
build();
|
||||||
|
|
||||||
|
if (wearing == null) return itemStack;
|
||||||
|
|
||||||
|
final boolean isAir = wearing.getType().isAir();
|
||||||
|
final boolean requireEmpty = settings.requireEmpty(slot);
|
||||||
|
|
||||||
|
if (!isAir && requireEmpty) {
|
||||||
|
return wearing;
|
||||||
|
}
|
||||||
|
|
||||||
|
return itemStack;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,252 +1,467 @@
|
|||||||
package io.github.fisher2911.hmccosmetics.packet;
|
package io.github.fisher2911.hmccosmetics.packet;
|
||||||
|
|
||||||
import com.comphenix.protocol.PacketType;
|
import com.github.retrooper.packetevents.PacketEvents;
|
||||||
import com.comphenix.protocol.ProtocolLibrary;
|
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
|
||||||
import com.comphenix.protocol.ProtocolManager;
|
import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes;
|
||||||
import com.comphenix.protocol.events.PacketContainer;
|
import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
|
||||||
import com.comphenix.protocol.wrappers.EnumWrappers;
|
import com.github.retrooper.packetevents.protocol.player.Equipment;
|
||||||
import com.comphenix.protocol.wrappers.MinecraftKey;
|
import com.github.retrooper.packetevents.protocol.player.EquipmentSlot;
|
||||||
import com.comphenix.protocol.wrappers.Pair;
|
import com.github.retrooper.packetevents.protocol.player.UserProfile;
|
||||||
import com.comphenix.protocol.wrappers.WrappedDataWatcher;
|
import com.github.retrooper.packetevents.util.Vector3d;
|
||||||
import io.github.fisher2911.nms.PacketHelper;
|
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerAttachEntity;
|
||||||
import io.github.fisher2911.nms.PacketHelper_1_16_R3;
|
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerDestroyEntities;
|
||||||
import io.github.fisher2911.nms.PacketHelper_1_17_R1;
|
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityEquipment;
|
||||||
import io.github.fisher2911.nms.PacketHelper_1_18_R1;
|
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityHeadLook;
|
||||||
|
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityMetadata;
|
||||||
|
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityRelativeMove;
|
||||||
|
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityRotation;
|
||||||
|
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityTeleport;
|
||||||
|
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPlayerInfo;
|
||||||
|
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSetPassengers;
|
||||||
|
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSpawnLivingEntity;
|
||||||
|
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSpawnPlayer;
|
||||||
|
import io.github.retrooper.packetevents.util.SpigotDataHelper;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.entity.EntityType;
|
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class PacketManager {
|
public class PacketManager {
|
||||||
|
//
|
||||||
|
// private static final PacketHelper PACKET_HELPER;
|
||||||
|
//
|
||||||
|
// static {
|
||||||
|
// final String version = Bukkit.getVersion();
|
||||||
|
// if (version.contains("1.16")) {
|
||||||
|
// PACKET_HELPER = new PacketHelper_1_16_R3();
|
||||||
|
// } else if (version.contains("1.17")) {
|
||||||
|
// PACKET_HELPER = new PacketHelper_1_17_R1();
|
||||||
|
// } else if (version.contains("1.18")) {
|
||||||
|
// PACKET_HELPER = new PacketHelper_1_18_R1();
|
||||||
|
// } else {
|
||||||
|
// PACKET_HELPER = null;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
private static final PacketHelper PACKET_HELPER;
|
public static void sendArmorStandMetaContainer(final int armorStandId, final Collection<? extends Player> sendTo) {
|
||||||
|
sendArmorStandMetaContainer(armorStandId, sendTo.toArray(new Player[0]));
|
||||||
static {
|
|
||||||
final String version = Bukkit.getVersion();
|
|
||||||
if (version.contains("1.16")) {
|
|
||||||
PACKET_HELPER = new PacketHelper_1_16_R3();
|
|
||||||
} else if (version.contains("1.17")) {
|
|
||||||
PACKET_HELPER = new PacketHelper_1_17_R1();
|
|
||||||
} else if (version.contains("1.18")) {
|
|
||||||
PACKET_HELPER = new PacketHelper_1_18_R1();
|
|
||||||
} else {
|
|
||||||
PACKET_HELPER = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void sendArmorStandMetaContainer(final int armorStandId, final Player... sendTo) {
|
||||||
|
for (final Player p : sendTo) {
|
||||||
|
PacketEvents.getAPI().getPlayerManager().sendPacket(p, new WrapperPlayServerEntityMetadata(
|
||||||
|
armorStandId,
|
||||||
|
List.of(
|
||||||
|
new EntityData(0, EntityDataTypes.BYTE, (byte) 0x20),
|
||||||
|
new EntityData(15, EntityDataTypes.BYTE, (byte) 0x10)
|
||||||
|
)
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PacketContainer getArmorStandMetaContainer(final int armorStandId) {
|
public static void sendEntitySpawnPacket(
|
||||||
if (PACKET_HELPER == null)
|
|
||||||
throw new IllegalStateException("This cannot be used in version: " + Bukkit.getVersion());
|
|
||||||
return PACKET_HELPER.getArmorStandMeta(armorStandId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PacketContainer getEntitySpawnPacket(
|
|
||||||
final Location location,
|
|
||||||
final int entityId,
|
|
||||||
final EntityType entityType) {
|
|
||||||
return getEntitySpawnPacket(location, entityId, entityType, UUID.randomUUID());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PacketContainer getEntitySpawnPacket(
|
|
||||||
final Location location,
|
final Location location,
|
||||||
final int entityId,
|
final int entityId,
|
||||||
final EntityType entityType,
|
final EntityType entityType,
|
||||||
final UUID uuid) {
|
final Collection<? extends Player> sendTo) {
|
||||||
final PacketContainer packet = new PacketContainer(PacketType.Play.Server.SPAWN_ENTITY);
|
sendEntitySpawnPacket(location, entityId, entityType, sendTo.toArray(new Player[0]));
|
||||||
|
|
||||||
// Entity ID
|
|
||||||
packet.getIntegers().write(0, entityId);
|
|
||||||
// Entity Type
|
|
||||||
// packet.getIntegers().write(6, 78);
|
|
||||||
// Set location
|
|
||||||
packet.getDoubles().write(0, location.getX());
|
|
||||||
packet.getDoubles().write(1, location.getY());
|
|
||||||
packet.getDoubles().write(2, location.getZ());
|
|
||||||
// Set yaw pitch
|
|
||||||
packet.getIntegers().write(4, (int) location.getPitch());
|
|
||||||
packet.getIntegers().write(5, (int) location.getYaw());
|
|
||||||
// Set UUID
|
|
||||||
packet.getUUIDs().write(0, uuid);
|
|
||||||
|
|
||||||
packet.getEntityTypeModifier().write(0, entityType);
|
|
||||||
|
|
||||||
return packet;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PacketContainer getInvisibilityPacket(final int entityId) {
|
public static void sendEntitySpawnPacket(
|
||||||
final PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
|
|
||||||
packet.getIntegers().write(0, entityId);
|
|
||||||
|
|
||||||
WrappedDataWatcher metaData = new WrappedDataWatcher();
|
|
||||||
|
|
||||||
final WrappedDataWatcher.Serializer byteSerializer = WrappedDataWatcher.Registry.get(Byte.class);
|
|
||||||
|
|
||||||
metaData.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(0, byteSerializer), (byte) (0x20));
|
|
||||||
|
|
||||||
packet.getWatchableCollectionModifier().write(0, metaData.getWatchableObjects());
|
|
||||||
return packet;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PacketContainer getTeleportPacket(final int entityId, final Location location) {
|
|
||||||
final PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_TELEPORT);
|
|
||||||
packet.getIntegers().write(0, entityId);
|
|
||||||
packet.getDoubles().write(0, location.getX()).write(1, location.getY()).write(2, location.getZ());
|
|
||||||
return packet;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PacketContainer getMovePacket(final int entityId, final Location from, final Location to) {
|
|
||||||
final PacketContainer packet = new PacketContainer(PacketType.Play.Server.REL_ENTITY_MOVE);
|
|
||||||
final short x = (short) ((to.getX() * 32 - from.getX() * 32) * 128);
|
|
||||||
final short y = (short) ((to.getY() * 32 - from.getY() * 32) * 128);
|
|
||||||
final short z = (short) ((to.getZ() * 32 - from.getZ() * 32) * 128);
|
|
||||||
packet.getIntegers().write(0, entityId);
|
|
||||||
packet.getShorts().write(0, x).write(1, y).write(2, y);
|
|
||||||
return packet;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PacketContainer getLeashPacket(final int balloonId, final int entityId) {
|
|
||||||
final PacketContainer packet = new PacketContainer(PacketType.Play.Server.ATTACH_ENTITY);
|
|
||||||
packet.getIntegers().write(0, balloonId).write(1, entityId);
|
|
||||||
return packet;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PacketContainer getEquipmentPacket(
|
|
||||||
final List<Pair<EnumWrappers.ItemSlot, ItemStack>> equipmentList,
|
|
||||||
final int entityId
|
|
||||||
) {
|
|
||||||
|
|
||||||
final PacketContainer armorPacket = new PacketContainer(
|
|
||||||
PacketType.Play.Server.ENTITY_EQUIPMENT);
|
|
||||||
armorPacket.getIntegers().write(0, entityId);
|
|
||||||
|
|
||||||
try {
|
|
||||||
armorPacket.getSlotStackPairLists().write(0, equipmentList);
|
|
||||||
// for some reason ProtocolLib throws an error the first time this is called
|
|
||||||
} catch (final NullPointerException ignored) {}
|
|
||||||
|
|
||||||
return armorPacket;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PacketContainer getRotationPacket(final int entityId, final Location location) {
|
|
||||||
final PacketContainer rotationPacket = new PacketContainer(
|
|
||||||
PacketType.Play.Server.ENTITY_HEAD_ROTATION);
|
|
||||||
|
|
||||||
rotationPacket.getIntegers().write(0, entityId);
|
|
||||||
rotationPacket.getBytes().write(0, (byte) (location.getYaw() * 256 / 360));
|
|
||||||
|
|
||||||
return rotationPacket;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PacketContainer getLookPacket(final int entityId, final Location location) {
|
|
||||||
final PacketContainer rotationPacket = new PacketContainer(
|
|
||||||
PacketType.Play.Server.ENTITY_LOOK);
|
|
||||||
|
|
||||||
rotationPacket.getIntegers().write(0, entityId);
|
|
||||||
rotationPacket.getBytes().write(0, (byte) (location.getYaw() * 256 / 360));
|
|
||||||
// rotationPacket.getBytes().write(1, (byte) (location.getPitch() * 256 / 360));
|
|
||||||
|
|
||||||
return rotationPacket;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PacketContainer getRidingPacket(final int mountId, final int passengerId) {
|
|
||||||
final PacketContainer ridingPacket = new PacketContainer(PacketType.Play.Server.MOUNT);
|
|
||||||
ridingPacket.
|
|
||||||
getIntegers().
|
|
||||||
write(0, mountId);
|
|
||||||
ridingPacket.getIntegerArrays().write(0, new int[]{passengerId});
|
|
||||||
|
|
||||||
return ridingPacket;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PacketContainer getEntityDestroyPacket(final int entityId) {
|
|
||||||
return PACKET_HELPER.getDestroyPacket(entityId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PacketContainer getSoundPacket(
|
|
||||||
final Player player,
|
|
||||||
final Location location,
|
final Location location,
|
||||||
final MinecraftKey name,
|
final int entityId,
|
||||||
final float volume,
|
final EntityType entityType,
|
||||||
final float pitch,
|
final Player... sendTo) {
|
||||||
final EnumWrappers.SoundCategory soundCategory
|
sendEntitySpawnPacket(location, entityId, entityType, UUID.randomUUID());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendEntitySpawnPacket(
|
||||||
|
final Location location,
|
||||||
|
final int entityId,
|
||||||
|
final EntityType entityType,
|
||||||
|
final UUID uuid,
|
||||||
|
final Collection<? extends Player> sendTo) {
|
||||||
|
sendEntitySpawnPacket(location, entityId, entityType, uuid, sendTo.toArray(new Player[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendEntitySpawnPacket(
|
||||||
|
final Location location,
|
||||||
|
final int entityId,
|
||||||
|
final EntityType entityType,
|
||||||
|
final UUID uuid,
|
||||||
|
final Player... sendTo) {
|
||||||
|
for (final Player p : sendTo) {
|
||||||
|
PacketEvents.getAPI().getPlayerManager().sendPacket(p, new WrapperPlayServerSpawnLivingEntity(
|
||||||
|
entityId,
|
||||||
|
uuid,
|
||||||
|
entityType,
|
||||||
|
new Vector3d(location.getX(), location.getY(), location.getZ()),
|
||||||
|
location.getYaw(),
|
||||||
|
location.getPitch(),
|
||||||
|
0f,
|
||||||
|
Vector3d.zero(),
|
||||||
|
Collections.emptyList()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendInvisibilityPacket(final int entityId, final Collection<? extends Player> sendTo) {
|
||||||
|
sendInvisibilityPacket(entityId, sendTo.toArray(new Player[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendInvisibilityPacket(final int entityId, final Player... sendTo) {
|
||||||
|
for (final Player p : sendTo) {
|
||||||
|
PacketEvents.getAPI().getPlayerManager().sendPacket(p, new WrapperPlayServerEntityMetadata(
|
||||||
|
entityId,
|
||||||
|
List.of(new EntityData(0, EntityDataTypes.BYTE, (byte) 0x20))
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendTeleportPacket(
|
||||||
|
final int entityId,
|
||||||
|
final Location location,
|
||||||
|
boolean onGround,
|
||||||
|
final Collection<? extends Player> sendTo
|
||||||
) {
|
) {
|
||||||
final var manager = ProtocolLibrary.getProtocolManager();
|
sendTeleportPacket(entityId, location, onGround, sendTo.toArray(new Player[0]));
|
||||||
final var packet = manager.createPacket(PacketType.Play.Server.CUSTOM_SOUND_EFFECT);
|
}
|
||||||
|
|
||||||
packet.getMinecraftKeys()
|
public static void sendTeleportPacket(
|
||||||
.write(
|
final int entityId,
|
||||||
0,
|
final Location location,
|
||||||
name
|
boolean onGround,
|
||||||
);
|
final Player... sendTo
|
||||||
|
) {
|
||||||
|
for (final Player p : sendTo) {
|
||||||
|
PacketEvents.getAPI().getPlayerManager().sendPacket(p, new WrapperPlayServerEntityTeleport(
|
||||||
|
entityId,
|
||||||
|
new Vector3d(location.getX(), location.getY(), location.getZ()),
|
||||||
|
location.getYaw(),
|
||||||
|
location.getPitch(),
|
||||||
|
onGround
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
packet.getSoundCategories()
|
public static void sendMovePacket(
|
||||||
.write(0, EnumWrappers.SoundCategory.valueOf(soundCategory.name()));
|
final int entityId,
|
||||||
|
final Location from,
|
||||||
|
final Location to,
|
||||||
|
final boolean onGround,
|
||||||
|
final Collection<? extends Player> sendTo
|
||||||
|
) {
|
||||||
|
sendMovePacket(entityId, from, to, onGround, sendTo.toArray(new Player[0]));
|
||||||
|
}
|
||||||
|
|
||||||
packet.getIntegers()
|
public static void sendMovePacket(
|
||||||
.write(0, location.getBlockX() * 8)
|
final int entityId,
|
||||||
.write(
|
final Location from,
|
||||||
1, location.getBlockY() * 8
|
final Location to,
|
||||||
|
final boolean onGround,
|
||||||
|
final Player... sendTo
|
||||||
|
) {
|
||||||
|
for (final Player p : sendTo) {
|
||||||
|
PacketEvents.getAPI().getPlayerManager().sendPacket(p, new WrapperPlayServerEntityRelativeMove(
|
||||||
|
entityId,
|
||||||
|
to.getX() - from.getX(),
|
||||||
|
to.getY() - from.getY(),
|
||||||
|
to.getZ() - from.getZ(),
|
||||||
|
onGround
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendLeashPacket(
|
||||||
|
final int balloonId,
|
||||||
|
final int entityId,
|
||||||
|
final Collection<? extends Player> sendTo
|
||||||
|
) {
|
||||||
|
sendLeashPacket(balloonId, entityId, sendTo.toArray(new Player[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendLeashPacket(
|
||||||
|
final int balloonId,
|
||||||
|
final int entityId,
|
||||||
|
final Player... sendTo
|
||||||
|
) {
|
||||||
|
for (final Player p : sendTo) {
|
||||||
|
PacketEvents.getAPI().getPlayerManager().sendPacket(p, new WrapperPlayServerAttachEntity(
|
||||||
|
balloonId,
|
||||||
|
entityId,
|
||||||
|
true
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendEquipmentPacket(
|
||||||
|
final List<Equipment> equipmentList,
|
||||||
|
final int entityId,
|
||||||
|
final Collection<? extends Player> sendTo
|
||||||
|
) {
|
||||||
|
sendEquipmentPacket(equipmentList, entityId, sendTo.toArray(new Player[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendEquipmentPacket(
|
||||||
|
final List<Equipment> equipmentList,
|
||||||
|
final int entityId,
|
||||||
|
final Player... sendTo
|
||||||
|
) {
|
||||||
|
for (final Equipment equipment : equipmentList) {
|
||||||
|
final ItemStack itemStack = SpigotDataHelper.toBukkitItemStack(equipment.getItem());
|
||||||
|
}
|
||||||
|
for (final Player p : sendTo) {
|
||||||
|
PacketEvents.getAPI().getPlayerManager().sendPacket(p, new WrapperPlayServerEntityEquipment(
|
||||||
|
entityId,
|
||||||
|
equipmentList
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendRotationPacket(
|
||||||
|
final int entityId,
|
||||||
|
final Location location,
|
||||||
|
final boolean onGround,
|
||||||
|
final Collection<? extends Player> sendTo
|
||||||
|
) {
|
||||||
|
sendRotationPacket(entityId, location, onGround, sendTo.toArray(new Player[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendRotationPacket(
|
||||||
|
final int entityId,
|
||||||
|
final Location location,
|
||||||
|
final boolean onGround,
|
||||||
|
final Player... sendTo
|
||||||
|
) {
|
||||||
|
for (final Player p : sendTo) {
|
||||||
|
PacketEvents.getAPI().getPlayerManager().sendPacket(p, new WrapperPlayServerEntityRotation(
|
||||||
|
entityId,
|
||||||
|
location.getYaw(),
|
||||||
|
location.getPitch(),
|
||||||
|
onGround
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendLookPacket(
|
||||||
|
final int entityId,
|
||||||
|
final Location location,
|
||||||
|
final Collection<? extends Player> sendTo
|
||||||
|
) {
|
||||||
|
sendLookPacket(entityId, location, sendTo.toArray(new Player[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendLookPacket(
|
||||||
|
final int entityId,
|
||||||
|
final Location location,
|
||||||
|
final Player... sendTo
|
||||||
|
) {
|
||||||
|
for (final Player p : sendTo) {
|
||||||
|
PacketEvents.getAPI().getPlayerManager().sendPacket(p, new WrapperPlayServerEntityHeadLook(
|
||||||
|
entityId,
|
||||||
|
location.getYaw()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendRidingPacket(
|
||||||
|
final int mountId,
|
||||||
|
final int passengerId,
|
||||||
|
final Collection<? extends Player> sendTo
|
||||||
|
) {
|
||||||
|
sendRidingPacket(mountId, passengerId, sendTo.toArray(new Player[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendRidingPacket(
|
||||||
|
final int mountId,
|
||||||
|
final int passengerId,
|
||||||
|
final Player... sendTo
|
||||||
|
) {
|
||||||
|
for (final Player p : sendTo) {
|
||||||
|
PacketEvents.getAPI().getPlayerManager().sendPacket(p, new WrapperPlayServerSetPassengers(
|
||||||
|
mountId,
|
||||||
|
new int[]{passengerId}
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendEntityDestroyPacket(final int entityId, final Collection<? extends Player> sendTo) {
|
||||||
|
sendEntityDestroyPacket(entityId, sendTo.toArray(new Player[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendEntityDestroyPacket(final int entityId, final Player... sendTo) {
|
||||||
|
for (final Player p : sendTo) {
|
||||||
|
PacketEvents.getAPI().getPlayerManager().sendPacket(p, new WrapperPlayServerDestroyEntities(entityId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// public static void sendSoundPacket(
|
||||||
|
// final Player player,
|
||||||
|
// final Location location,
|
||||||
|
// final MinecraftKey name,
|
||||||
|
// final float volume,
|
||||||
|
// final float pitch,
|
||||||
|
// final EnumWrappers.SoundCategory soundCategory,
|
||||||
|
// final Player...sendTo
|
||||||
|
// ) {
|
||||||
|
// final var packet = new WrapperPlayServerSoundEffect(
|
||||||
|
//
|
||||||
|
// );
|
||||||
|
// final var manager = ProtocolLibrary.getProtocolManager();
|
||||||
|
// final var packet = manager.createPacket(PacketType.Play.Server.CUSTOM_SOUND_EFFECT);
|
||||||
|
//
|
||||||
|
// packet.getMinecraftKeys()
|
||||||
|
// .write(
|
||||||
|
// 0,
|
||||||
|
// name
|
||||||
|
// );
|
||||||
|
//
|
||||||
|
// packet.getSoundCategories()
|
||||||
|
// .write(0, EnumWrappers.SoundCategory.valueOf(soundCategory.name()));
|
||||||
|
//
|
||||||
|
// packet.getIntegers()
|
||||||
|
// .write(0, location.getBlockX() * 8)
|
||||||
|
// .write(
|
||||||
|
// 1, location.getBlockY() * 8
|
||||||
|
// )
|
||||||
|
// .write(2, location.getBlockZ() * 8);
|
||||||
|
//
|
||||||
|
// packet.getFloat()
|
||||||
|
// .write(0, volume)
|
||||||
|
// .write(1, pitch);
|
||||||
|
//
|
||||||
|
// return packet;
|
||||||
|
// }
|
||||||
|
|
||||||
|
public static void sendFakePlayerSpawnPacket(
|
||||||
|
final Location location,
|
||||||
|
final UUID uuid,
|
||||||
|
final int entityId,
|
||||||
|
final Collection<? extends Player> sendTo
|
||||||
|
) {
|
||||||
|
sendFakePlayerSpawnPacket(location, uuid, entityId, sendTo.toArray(new Player[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendFakePlayerSpawnPacket(
|
||||||
|
final Location location,
|
||||||
|
final UUID uuid,
|
||||||
|
final int entityId,
|
||||||
|
final Player... sendTo
|
||||||
|
) {
|
||||||
|
for (final Player p : sendTo) {
|
||||||
|
PacketEvents.getAPI().getPlayerManager().sendPacket(p, new WrapperPlayServerSpawnPlayer(
|
||||||
|
entityId,
|
||||||
|
uuid,
|
||||||
|
new com.github.retrooper.packetevents.protocol.world.Location(
|
||||||
|
location.getX(),
|
||||||
|
location.getY(),
|
||||||
|
location.getZ(),
|
||||||
|
location.getYaw(),
|
||||||
|
location.getPitch()
|
||||||
)
|
)
|
||||||
.write(2, location.getBlockZ() * 8);
|
));
|
||||||
|
|
||||||
packet.getFloat()
|
|
||||||
.write(0, volume)
|
|
||||||
.write(1, pitch);
|
|
||||||
|
|
||||||
return packet;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PacketContainer getFakePlayerSpawnPacket(final Location location, final UUID uuid, final int entityId) throws IllegalStateException {
|
|
||||||
if (PACKET_HELPER == null)
|
|
||||||
throw new IllegalStateException("This cannot be used in version: " + Bukkit.getVersion());
|
|
||||||
return PACKET_HELPER.getPlayerSpawnPacket(location, uuid, entityId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PacketContainer getFakePlayerInfoPacket(final Player player, final UUID uuid) throws IllegalStateException {
|
|
||||||
if (PACKET_HELPER == null)
|
|
||||||
throw new IllegalStateException("This cannot be used in version: " + Bukkit.getVersion());
|
|
||||||
return PACKET_HELPER.getPlayerInfoPacket(player, uuid);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PacketContainer getPlayerOverlayPacket(final int playerId) throws IllegalStateException {
|
|
||||||
if (PACKET_HELPER == null)
|
|
||||||
throw new IllegalStateException("This cannot be used in version: " + Bukkit.getVersion());
|
|
||||||
return PACKET_HELPER.getPlayerOverlayPacket(playerId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PacketContainer getRemovePlayerPacket(final Player player, final UUID uuid, final int entityId) {
|
|
||||||
if (PACKET_HELPER == null)
|
|
||||||
throw new IllegalStateException("This cannot be used in version: " + Bukkit.getVersion());
|
|
||||||
return PACKET_HELPER.getPlayerRemovePacket(player, uuid, entityId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PacketContainer getSpectatePacket(final int entityId) {
|
|
||||||
final PacketContainer packetContainer = new PacketContainer(PacketType.Play.Server.CAMERA);
|
|
||||||
packetContainer.getIntegers().write(0, entityId);
|
|
||||||
return packetContainer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void sendPacket(final Player to, final PacketContainer... packets) {
|
|
||||||
final ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager();
|
|
||||||
try {
|
|
||||||
for (final PacketContainer packet : packets) {
|
|
||||||
protocolManager.sendServerPacket(to, packet);
|
|
||||||
}
|
|
||||||
} catch (final InvocationTargetException exception) {
|
|
||||||
exception.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void sendPacketToOnline(final PacketContainer... packets) {
|
public static void sendFakePlayerInfoPacket(
|
||||||
for (final Player player : Bukkit.getOnlinePlayers()) {
|
final Player player,
|
||||||
sendPacket(player, packets);
|
final UUID uuid,
|
||||||
|
final Collection<? extends Player> sendTo
|
||||||
|
) {
|
||||||
|
sendFakePlayerInfoPacket(player, uuid, sendTo.toArray(new Player[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendFakePlayerInfoPacket(
|
||||||
|
final Player player,
|
||||||
|
final UUID uuid,
|
||||||
|
final Player... sendTo
|
||||||
|
) {
|
||||||
|
for (final Player p : sendTo) {
|
||||||
|
PacketEvents.getAPI().getPlayerManager().sendPacket(p, new WrapperPlayServerPlayerInfo(
|
||||||
|
WrapperPlayServerPlayerInfo.Action.ADD_PLAYER,
|
||||||
|
new WrapperPlayServerPlayerInfo.PlayerData(
|
||||||
|
Component.empty(),
|
||||||
|
new UserProfile(
|
||||||
|
uuid,
|
||||||
|
player.getDisplayName()
|
||||||
|
),
|
||||||
|
com.github.retrooper.packetevents.protocol.player.GameMode.SURVIVAL,
|
||||||
|
0
|
||||||
|
)
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void sendPlayerOverlayPacket(
|
||||||
|
final int playerId,
|
||||||
|
final Collection<? extends Player> sendTo
|
||||||
|
) {
|
||||||
|
sendPlayerOverlayPacket(playerId, sendTo.toArray(new Player[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendPlayerOverlayPacket(
|
||||||
|
final int playerId,
|
||||||
|
final Player... sendTo
|
||||||
|
) {
|
||||||
|
final byte mask = 0x01 | 0x02 | 0x04 | 0x08 | 0x010 | 0x020 | 0x40;
|
||||||
|
for (final Player p : sendTo) {
|
||||||
|
PacketEvents.getAPI().getPlayerManager().sendPacket(p, new WrapperPlayServerEntityMetadata(
|
||||||
|
playerId,
|
||||||
|
List.of(
|
||||||
|
new EntityData(17, EntityDataTypes.BYTE, mask),
|
||||||
|
new EntityData(15, EntityDataTypes.BYTE, (byte) 0x10)
|
||||||
|
)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendRemovePlayerPacket(
|
||||||
|
final Player player,
|
||||||
|
final UUID uuid,
|
||||||
|
final Collection<? extends Player> sendTo
|
||||||
|
) {
|
||||||
|
sendRemovePlayerPacket(player, uuid, sendTo.toArray(new Player[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendRemovePlayerPacket(
|
||||||
|
final Player player,
|
||||||
|
final UUID uuid,
|
||||||
|
final Player... sendTo
|
||||||
|
) {
|
||||||
|
for (final Player p : sendTo) {
|
||||||
|
PacketEvents.getAPI().getPlayerManager().sendPacket(p, new WrapperPlayServerPlayerInfo(
|
||||||
|
WrapperPlayServerPlayerInfo.Action.REMOVE_PLAYER,
|
||||||
|
new WrapperPlayServerPlayerInfo.PlayerData(
|
||||||
|
Component.empty(),
|
||||||
|
new UserProfile(
|
||||||
|
uuid,
|
||||||
|
player.getDisplayName()
|
||||||
|
),
|
||||||
|
com.github.retrooper.packetevents.protocol.player.GameMode.SURVIVAL,
|
||||||
|
0
|
||||||
|
)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendSpectatePacket(final int entityId) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static EquipmentSlot fromBukkitSlot(final org.bukkit.inventory.EquipmentSlot slot) {
|
||||||
|
return switch (slot) {
|
||||||
|
case HEAD -> EquipmentSlot.HELMET;
|
||||||
|
case CHEST -> EquipmentSlot.CHESTPLATE;
|
||||||
|
case LEGS -> EquipmentSlot.LEGGINGS;
|
||||||
|
case FEET -> EquipmentSlot.BOOTS;
|
||||||
|
case HAND -> EquipmentSlot.MAINHAND;
|
||||||
|
case OFF_HAND -> EquipmentSlot.OFFHAND;
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,10 @@ public class TaskManager {
|
|||||||
this.tasks.add(task);
|
this.tasks.add(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void submit(final Runnable runnable) {
|
||||||
|
this.submit(new ImmediateTask(runnable));
|
||||||
|
}
|
||||||
|
|
||||||
public void end() {
|
public void end() {
|
||||||
this.timer.cancel();
|
this.timer.cancel();
|
||||||
for (final Task task : this.tasks) {
|
for (final Task task : this.tasks) {
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
package io.github.fisher2911.hmccosmetics.user;
|
package io.github.fisher2911.hmccosmetics.user;
|
||||||
|
|
||||||
import com.comphenix.protocol.events.PacketContainer;
|
|
||||||
import com.comphenix.protocol.wrappers.EnumWrappers;
|
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
|
||||||
import com.comphenix.protocol.wrappers.Pair;
|
import com.github.retrooper.packetevents.protocol.item.type.ItemTypes;
|
||||||
|
import com.github.retrooper.packetevents.protocol.player.EquipmentSlot;
|
||||||
import io.github.fisher2911.hmccosmetics.config.CosmeticSettings;
|
import io.github.fisher2911.hmccosmetics.config.CosmeticSettings;
|
||||||
import io.github.fisher2911.hmccosmetics.config.Settings;
|
import io.github.fisher2911.hmccosmetics.config.Settings;
|
||||||
import io.github.fisher2911.hmccosmetics.gui.ArmorItem;
|
import io.github.fisher2911.hmccosmetics.gui.ArmorItem;
|
||||||
@@ -12,19 +13,17 @@ import io.github.fisher2911.hmccosmetics.hook.ModelEngineHook;
|
|||||||
import io.github.fisher2911.hmccosmetics.hook.entity.BalloonEntity;
|
import io.github.fisher2911.hmccosmetics.hook.entity.BalloonEntity;
|
||||||
import io.github.fisher2911.hmccosmetics.inventory.PlayerArmor;
|
import io.github.fisher2911.hmccosmetics.inventory.PlayerArmor;
|
||||||
import io.github.fisher2911.hmccosmetics.packet.PacketManager;
|
import io.github.fisher2911.hmccosmetics.packet.PacketManager;
|
||||||
|
import io.github.retrooper.packetevents.util.SpigotDataHelper;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.entity.EntityType;
|
import org.bukkit.entity.EntityType;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@@ -101,7 +100,7 @@ public abstract class BaseUser<T> {
|
|||||||
final HookManager hookManager = HookManager.getInstance();
|
final HookManager hookManager = HookManager.getInstance();
|
||||||
if (!hookManager.isEnabled(ModelEngineHook.class)) return;
|
if (!hookManager.isEnabled(ModelEngineHook.class)) return;
|
||||||
this.balloon.remove();
|
this.balloon.remove();
|
||||||
PacketManager.sendPacketToOnline(PacketManager.getEntityDestroyPacket(this.getBalloonId()));
|
PacketManager.sendEntityDestroyPacket(this.getBalloonId(), Bukkit.getOnlinePlayers());
|
||||||
this.viewingBalloon.clear();
|
this.viewingBalloon.clear();
|
||||||
this.balloon.setAlive(false);
|
this.balloon.setAlive(false);
|
||||||
}
|
}
|
||||||
@@ -110,7 +109,7 @@ public abstract class BaseUser<T> {
|
|||||||
final HookManager hookManager = HookManager.getInstance();
|
final HookManager hookManager = HookManager.getInstance();
|
||||||
if (!hookManager.isEnabled(ModelEngineHook.class)) return;
|
if (!hookManager.isEnabled(ModelEngineHook.class)) return;
|
||||||
this.balloon.removePlayerFromModel(other);
|
this.balloon.removePlayerFromModel(other);
|
||||||
PacketManager.sendPacket(other, PacketManager.getEntityDestroyPacket(this.getBalloonId()));
|
PacketManager.sendEntityDestroyPacket(this.getBalloonId(), other);
|
||||||
this.viewingBalloon.remove(other.getUniqueId());
|
this.viewingBalloon.remove(other.getUniqueId());
|
||||||
if (this.viewingBalloon.isEmpty()) {
|
if (this.viewingBalloon.isEmpty()) {
|
||||||
this.despawnBalloon();
|
this.despawnBalloon();
|
||||||
@@ -134,19 +133,10 @@ public abstract class BaseUser<T> {
|
|||||||
this.balloon.addPlayerToModel(other, id);
|
this.balloon.addPlayerToModel(other, id);
|
||||||
}
|
}
|
||||||
this.updateBalloon(other, location, settings);
|
this.updateBalloon(other, location, settings);
|
||||||
PacketManager.sendPacket(
|
final int balloonId = this.getBalloonId();
|
||||||
other,
|
PacketManager.sendEntitySpawnPacket(actual, balloonId, EntityTypes.PUFFERFISH, other);
|
||||||
PacketManager.getEntitySpawnPacket(
|
PacketManager.sendInvisibilityPacket(balloonId, other);
|
||||||
actual,
|
PacketManager.sendLeashPacket(balloonId, this.getEntityId(), other);
|
||||||
this.getBalloonId(),
|
|
||||||
this.balloon.getType()
|
|
||||||
),
|
|
||||||
PacketManager.getInvisibilityPacket(this.getBalloonId()),
|
|
||||||
PacketManager.getLeashPacket(
|
|
||||||
this.getBalloonId(),
|
|
||||||
this.getEntityId()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void updateBalloon(final Player other, final Location location, final CosmeticSettings settings) {
|
protected void updateBalloon(final Player other, final Location location, final CosmeticSettings settings) {
|
||||||
@@ -162,16 +152,13 @@ public abstract class BaseUser<T> {
|
|||||||
this.balloon.setVelocity(actual.clone().subtract(previous.clone()).toVector());
|
this.balloon.setVelocity(actual.clone().subtract(previous.clone()).toVector());
|
||||||
// hookManager.getModelEngineHook().updateModel(this.balloon);
|
// hookManager.getModelEngineHook().updateModel(this.balloon);
|
||||||
this.balloon.updateModel();
|
this.balloon.updateModel();
|
||||||
PacketManager.sendPacket(
|
final int balloonId = this.getBalloonId();
|
||||||
other,
|
PacketManager.sendTeleportPacket(balloonId, actual, false, other);
|
||||||
PacketManager.getTeleportPacket(this.getBalloonId(), actual),
|
PacketManager.sendLeashPacket(balloonId, this.getEntityId(), other);
|
||||||
PacketManager.getLeashPacket(this.getBalloonId(), this.getEntityId())
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void spawnArmorStand(final Player other, final Location location) {
|
private void spawnArmorStand(final Player other, final Location location) {
|
||||||
final PacketContainer packet = PacketManager.getEntitySpawnPacket(location, this.getArmorStandId(), EntityType.ARMOR_STAND);
|
PacketManager.sendEntitySpawnPacket(location, this.getArmorStandId(), EntityTypes.ARMOR_STAND, other);
|
||||||
PacketManager.sendPacket(other, packet);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateOutsideCosmetics(final Settings settings) {
|
public void updateOutsideCosmetics(final Settings settings) {
|
||||||
@@ -183,7 +170,7 @@ public abstract class BaseUser<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void updateOutsideCosmetics(final Player other, final Location location, final Settings settings) {
|
public void updateOutsideCosmetics(final Player other, final Location location, final Settings settings) {
|
||||||
final boolean inViewDistance = this.isInViewDistance(location, other.getLocation(), settings.getCosmeticSettings());
|
final boolean inViewDistance = settings.getCosmeticSettings().isInViewDistance(location, other.getLocation());
|
||||||
final boolean shouldShow = shouldShow(other);
|
final boolean shouldShow = shouldShow(other);
|
||||||
final UUID otherUUID = other.getUniqueId();
|
final UUID otherUUID = other.getUniqueId();
|
||||||
final boolean hasBackpack = !this.playerArmor.getItem(ArmorItem.Type.BACKPACK).isEmpty();
|
final boolean hasBackpack = !this.playerArmor.getItem(ArmorItem.Type.BACKPACK).isEmpty();
|
||||||
@@ -212,40 +199,37 @@ public abstract class BaseUser<T> {
|
|||||||
this.despawnBalloon(other);
|
this.despawnBalloon(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<Pair<EnumWrappers.ItemSlot, ItemStack>> equipmentList = new ArrayList<>();
|
final List<com.github.retrooper.packetevents.protocol.player.Equipment> equipment = new ArrayList<>();
|
||||||
final boolean hidden = !this.shouldShow(other);
|
final boolean hidden = !this.shouldShow(other);
|
||||||
if (hidden) {
|
final int lookDownPitch = settings.getCosmeticSettings().getLookDownPitch();
|
||||||
equipmentList.add(new Pair<>(EnumWrappers.ItemSlot.HEAD,
|
final boolean isLookingDown =
|
||||||
new ItemStack(Material.AIR)
|
this.id.equals(other.getUniqueId()) && lookDownPitch
|
||||||
|
!= -1 &&
|
||||||
|
this.isFacingDown(location, lookDownPitch);
|
||||||
|
if (hidden || isLookingDown) {
|
||||||
|
equipment.add(new com.github.retrooper.packetevents.protocol.player.Equipment(
|
||||||
|
EquipmentSlot.HELMET,
|
||||||
|
new com.github.retrooper.packetevents.protocol.item.ItemStack.Builder().
|
||||||
|
type(ItemTypes.AIR).
|
||||||
|
build()
|
||||||
));
|
));
|
||||||
} else {
|
} else {
|
||||||
equipmentList.add(new Pair<>(EnumWrappers.ItemSlot.HEAD,
|
final com.github.retrooper.packetevents.protocol.item.ItemStack itemStack =
|
||||||
this.playerArmor.getBackpack().getItemStack(ArmorItem.Status.APPLIED)
|
SpigotDataHelper.fromBukkitItemStack(this.playerArmor.getBackpack().getItemStack(ArmorItem.Status.APPLIED));
|
||||||
|
equipment.add(new com.github.retrooper.packetevents.protocol.player.Equipment(
|
||||||
|
EquipmentSlot.HELMET,
|
||||||
|
itemStack
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
final int armorStandId = this.getArmorStandId();
|
final int armorStandId = this.getArmorStandId();
|
||||||
final PacketContainer armorPacket = PacketManager.getEquipmentPacket(equipmentList, armorStandId);
|
PacketManager.sendEquipmentPacket(equipment, armorStandId, other);
|
||||||
final PacketContainer rotationPacket = PacketManager.getRotationPacket(armorStandId, location);
|
PacketManager.sendRotationPacket(armorStandId, location, false, other);
|
||||||
final PacketContainer ridingPacket = PacketManager.getRidingPacket(this.getEntityId(), armorStandId);
|
PacketManager.sendRidingPacket(this.getEntityId(), armorStandId, other);
|
||||||
final PacketContainer armorStandMetaContainer = PacketManager.getArmorStandMetaContainer(armorStandId);
|
PacketManager.sendArmorStandMetaContainer(armorStandId, other);
|
||||||
|
|
||||||
PacketManager.sendPacket(other, armorPacket, armorStandMetaContainer, rotationPacket, ridingPacket);
|
|
||||||
|
|
||||||
if (hidden) return;
|
if (hidden) return;
|
||||||
this.updateBalloon(other, location, settings.getCosmeticSettings());
|
this.updateBalloon(other, location, settings.getCosmeticSettings());
|
||||||
|
|
||||||
final int lookDownPitch = settings.getCosmeticSettings().getLookDownPitch();
|
|
||||||
|
|
||||||
if (lookDownPitch != -1 &&
|
|
||||||
this.isFacingDown(location, lookDownPitch)) {
|
|
||||||
equipmentList.set(0, new Pair<>(EnumWrappers.ItemSlot.HEAD,
|
|
||||||
new ItemStack(Material.AIR)
|
|
||||||
));
|
|
||||||
|
|
||||||
if (!this.id.equals(other.getUniqueId())) return;
|
|
||||||
PacketManager.sendPacket(other, PacketManager.getEquipmentPacket(equipmentList, armorStandId));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasBalloon() {
|
private boolean hasBalloon() {
|
||||||
@@ -255,22 +239,17 @@ public abstract class BaseUser<T> {
|
|||||||
|
|
||||||
public abstract boolean shouldShow(final Player other);
|
public abstract boolean shouldShow(final Player other);
|
||||||
|
|
||||||
protected boolean isInViewDistance(final Location location, final Location other, final CosmeticSettings settings) {
|
|
||||||
if (!Objects.equals(other.getWorld(), location.getWorld())) return false;
|
|
||||||
return !(other.distanceSquared(location) > settings.getViewDistance() * settings.getViewDistance());
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean isFacingDown(final Location location, final int pitchLimit) {
|
protected boolean isFacingDown(final Location location, final int pitchLimit) {
|
||||||
return location.getPitch() > pitchLimit;
|
return location.getPitch() > pitchLimit;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void despawnAttached(final Player other) {
|
public void despawnAttached(final Player other) {
|
||||||
PacketManager.sendPacket(other, PacketManager.getEntityDestroyPacket(this.getArmorStandId()));
|
PacketManager.sendEntityDestroyPacket(this.getArmorStandId(), other);
|
||||||
this.viewingArmorStand.remove(other.getUniqueId());
|
this.viewingArmorStand.remove(other.getUniqueId());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void despawnAttached() {
|
public void despawnAttached() {
|
||||||
PacketManager.sendPacketToOnline(PacketManager.getEntityDestroyPacket(this.getArmorStandId()));
|
PacketManager.sendEntityDestroyPacket(this.getArmorStandId(), Bukkit.getOnlinePlayers());
|
||||||
this.viewingArmorStand.clear();
|
this.viewingArmorStand.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
package io.github.fisher2911.hmccosmetics.user;
|
package io.github.fisher2911.hmccosmetics.user;
|
||||||
|
|
||||||
import com.comphenix.protocol.wrappers.EnumWrappers;
|
|
||||||
import com.comphenix.protocol.wrappers.Pair;
|
|
||||||
import com.comphenix.protocol.wrappers.WrappedDataWatcher;
|
|
||||||
import io.github.fisher2911.hmccosmetics.HMCCosmetics;
|
import io.github.fisher2911.hmccosmetics.HMCCosmetics;
|
||||||
import io.github.fisher2911.hmccosmetics.api.CosmeticItem;
|
import io.github.fisher2911.hmccosmetics.api.CosmeticItem;
|
||||||
import io.github.fisher2911.hmccosmetics.api.event.CosmeticChangeEvent;
|
import io.github.fisher2911.hmccosmetics.api.event.CosmeticChangeEvent;
|
||||||
@@ -18,6 +15,7 @@ import io.github.fisher2911.hmccosmetics.message.Translation;
|
|||||||
import io.github.fisher2911.hmccosmetics.packet.PacketManager;
|
import io.github.fisher2911.hmccosmetics.packet.PacketManager;
|
||||||
import io.github.fisher2911.hmccosmetics.task.InfiniteTask;
|
import io.github.fisher2911.hmccosmetics.task.InfiniteTask;
|
||||||
import io.github.fisher2911.hmccosmetics.util.builder.ItemBuilder;
|
import io.github.fisher2911.hmccosmetics.util.builder.ItemBuilder;
|
||||||
|
import io.github.retrooper.packetevents.util.SpigotDataHelper;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@@ -49,7 +47,6 @@ public class UserManager {
|
|||||||
|
|
||||||
public void add(final User user) {
|
public void add(final User user) {
|
||||||
this.userMap.put(user.getId(), user);
|
this.userMap.put(user.getId(), user);
|
||||||
this.updateCosmetics(user);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Optional<User> get(final UUID uuid) {
|
public Optional<User> get(final UUID uuid) {
|
||||||
@@ -78,11 +75,11 @@ public class UserManager {
|
|||||||
|
|
||||||
public void startTeleportTask() {
|
public void startTeleportTask() {
|
||||||
// throws an error on first load of registry if this isn't here
|
// throws an error on first load of registry if this isn't here
|
||||||
WrappedDataWatcher.Registry.get(Byte.class);
|
// WrappedDataWatcher.Registry.get(Byte.class);
|
||||||
this.plugin.getTaskManager().submit(new InfiniteTask(
|
this.plugin.getTaskManager().submit(new InfiniteTask(
|
||||||
() -> {
|
() -> {
|
||||||
for (final User user : this.userMap.values()) {
|
for (final User user : this.userMap.values()) {
|
||||||
user.updateOutsideCosmetics(this.plugin.getSettings());
|
// user.updateOutsideCosmetics(this.plugin.getSettings());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
@@ -92,7 +89,8 @@ public class UserManager {
|
|||||||
for (final User user : this.userMap.values()) {
|
for (final User user : this.userMap.values()) {
|
||||||
final Player p = user.getPlayer();
|
final Player p = user.getPlayer();
|
||||||
if (p == null) continue;
|
if (p == null) continue;
|
||||||
user.updateOutsideCosmetics(player, p.getLocation(), this.settings);
|
// user.updateOutsideCosmetics(player, p.getLocation(), this.settings);
|
||||||
|
player.sendMessage("Resending cosmetics");
|
||||||
this.updateCosmetics(user, player);
|
this.updateCosmetics(user, player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -101,16 +99,14 @@ public class UserManager {
|
|||||||
this.get(uuid).ifPresent(this::updateCosmetics);
|
this.get(uuid).ifPresent(this::updateCosmetics);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateCosmetics(final BaseUser user) {
|
public void updateCosmetics(final BaseUser<?> user) {
|
||||||
for (final Player player : Bukkit.getOnlinePlayers()) {
|
for (final Player player : Bukkit.getOnlinePlayers()) {
|
||||||
this.updateCosmetics(user, player);
|
this.updateCosmetics(user, player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateCosmetics(final BaseUser user, final Player other) {
|
public void updateCosmetics(final BaseUser<?> user, final Player other) {
|
||||||
// final Player player = user.getPlayer();
|
|
||||||
final Equipment equipment = user.getEquipment();
|
final Equipment equipment = user.getEquipment();
|
||||||
|
|
||||||
for (final ArmorItem.Type type : ArmorItem.Type.values()) {
|
for (final ArmorItem.Type type : ArmorItem.Type.values()) {
|
||||||
if (type.getSlot() == null) continue;
|
if (type.getSlot() == null) continue;
|
||||||
this.sendUpdatePacket(
|
this.sendUpdatePacket(
|
||||||
@@ -123,7 +119,7 @@ public class UserManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void sendUpdatePacket(
|
private void sendUpdatePacket(
|
||||||
final BaseUser user,
|
final BaseUser<?> user,
|
||||||
final Player other,
|
final Player other,
|
||||||
final Equipment equipment,
|
final Equipment equipment,
|
||||||
final ArmorItem.Type type) {
|
final ArmorItem.Type type) {
|
||||||
@@ -131,14 +127,14 @@ public class UserManager {
|
|||||||
final EquipmentSlot slot = type.getSlot();
|
final EquipmentSlot slot = type.getSlot();
|
||||||
final ItemStack itemStack = this.getCosmeticItem(user, equipment, playerArmor.getItem(type), ArmorItem.Status.APPLIED, slot);
|
final ItemStack itemStack = this.getCosmeticItem(user, equipment, playerArmor.getItem(type), ArmorItem.Status.APPLIED, slot);
|
||||||
if (itemStack != null && itemStack.equals(equipment.getItem(slot))) return;
|
if (itemStack != null && itemStack.equals(equipment.getItem(slot))) return;
|
||||||
final List<Pair<EnumWrappers.ItemSlot, ItemStack>> itemList = new ArrayList<>();
|
final List<com.github.retrooper.packetevents.protocol.player.Equipment> itemList = new ArrayList<>();
|
||||||
itemList.add(new Pair<>(EnumWrappers.ItemSlot.valueOf(slot.toString().replace("_", "")), itemStack));
|
itemList.add(new com.github.retrooper.packetevents.protocol.player.Equipment(
|
||||||
PacketManager.sendPacket(
|
PacketManager.fromBukkitSlot(slot), SpigotDataHelper.fromBukkitItemStack(itemStack)
|
||||||
other,
|
));
|
||||||
PacketManager.getEquipmentPacket(
|
PacketManager.sendEquipmentPacket(
|
||||||
itemList,
|
itemList,
|
||||||
user.getEntityId()
|
user.getEntityId(),
|
||||||
)
|
other
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package io.github.fisher2911.hmccosmetics.user;
|
package io.github.fisher2911.hmccosmetics.user;
|
||||||
|
|
||||||
import com.comphenix.protocol.events.PacketContainer;
|
|
||||||
import io.github.fisher2911.hmccosmetics.HMCCosmetics;
|
import io.github.fisher2911.hmccosmetics.HMCCosmetics;
|
||||||
import io.github.fisher2911.hmccosmetics.config.WardrobeSettings;
|
import io.github.fisher2911.hmccosmetics.config.WardrobeSettings;
|
||||||
import io.github.fisher2911.hmccosmetics.gui.ArmorItem;
|
import io.github.fisher2911.hmccosmetics.gui.ArmorItem;
|
||||||
@@ -16,7 +15,6 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
@@ -89,28 +87,18 @@ public class Wardrobe extends User {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final PacketContainer playerSpawnPacket = PacketManager.getFakePlayerSpawnPacket(
|
|
||||||
this.currentLocation,
|
|
||||||
this.getId(),
|
|
||||||
this.getEntityId()
|
|
||||||
);
|
|
||||||
final PacketContainer playerInfoPacket = PacketManager.getFakePlayerInfoPacket(
|
|
||||||
viewer,
|
|
||||||
this.getId()
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
Bukkit.getScheduler().runTaskLaterAsynchronously(
|
Bukkit.getScheduler().runTaskLaterAsynchronously(
|
||||||
this.plugin,
|
this.plugin,
|
||||||
() -> {
|
() -> {
|
||||||
PacketManager.sendPacket(viewer, playerInfoPacket, playerSpawnPacket);
|
final int entityId = this.getEntityId();
|
||||||
|
PacketManager.sendFakePlayerSpawnPacket(this.currentLocation, this.getId(), entityId, viewer);
|
||||||
|
PacketManager.sendFakePlayerInfoPacket(viewer, this.getId(), viewer);
|
||||||
this.updateOutsideCosmetics(viewer, this.currentLocation, plugin.getSettings());
|
this.updateOutsideCosmetics(viewer, this.currentLocation, plugin.getSettings());
|
||||||
PacketManager.sendPacket(
|
PacketManager.sendLookPacket(entityId, this.currentLocation, viewer);
|
||||||
viewer,
|
PacketManager.sendRotationPacket(entityId, this.currentLocation, true, viewer);
|
||||||
PacketManager.getLookPacket(this.getEntityId(), this.currentLocation),
|
PacketManager.sendPlayerOverlayPacket(entityId, viewer);
|
||||||
PacketManager.getRotationPacket(this.getEntityId(), this.currentLocation),
|
|
||||||
PacketManager.getPlayerOverlayPacket(this.getEntityId())
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
settings.getSpawnDelay()
|
settings.getSpawnDelay()
|
||||||
);
|
);
|
||||||
@@ -125,13 +113,9 @@ public class Wardrobe extends User {
|
|||||||
Bukkit.getScheduler().runTaskLaterAsynchronously(
|
Bukkit.getScheduler().runTaskLaterAsynchronously(
|
||||||
this.plugin,
|
this.plugin,
|
||||||
() -> {
|
() -> {
|
||||||
PacketManager.sendPacket(
|
final int entityId = this.getEntityId();
|
||||||
viewer,
|
PacketManager.sendEntityDestroyPacket(entityId, viewer);
|
||||||
PacketManager.getEntityDestroyPacket(this.getEntityId()),
|
PacketManager.sendRemovePlayerPacket(viewer, this.id, viewer);
|
||||||
PacketManager.getRemovePlayerPacket(viewer, this.id, this.getEntityId())
|
|
||||||
// for spectator packets
|
|
||||||
// PacketManager.getEntityDestroyPacket(this.viewerId)
|
|
||||||
);
|
|
||||||
this.despawnAttached();
|
this.despawnAttached();
|
||||||
this.despawnBalloon();
|
this.despawnBalloon();
|
||||||
this.showPlayer(this.plugin.getUserManager());
|
this.showPlayer(this.plugin.getUserManager());
|
||||||
@@ -170,19 +154,17 @@ public class Wardrobe extends User {
|
|||||||
private void startSpinTask(final Player player) {
|
private void startSpinTask(final Player player) {
|
||||||
final AtomicInteger data = new AtomicInteger();
|
final AtomicInteger data = new AtomicInteger();
|
||||||
final int rotationSpeed = this.plugin.getSettings().getWardrobeSettings().getRotationSpeed();
|
final int rotationSpeed = this.plugin.getSettings().getWardrobeSettings().getRotationSpeed();
|
||||||
|
final int entityId = this.getEntityId();
|
||||||
final Task task = new SupplierTask(
|
final Task task = new SupplierTask(
|
||||||
() -> {
|
() -> {
|
||||||
if (this.currentLocation == null) return;
|
if (this.currentLocation == null) return;
|
||||||
final Location location = this.currentLocation.clone();
|
final Location location = this.currentLocation.clone();
|
||||||
final int yaw = data.get();
|
final int yaw = data.get();
|
||||||
location.setYaw(yaw);
|
location.setYaw(yaw);
|
||||||
PacketManager.sendPacket(player, PacketManager.getLookPacket(this.getEntityId(), location));
|
PacketManager.sendLookPacket(entityId, location, player);
|
||||||
this.updateOutsideCosmetics(player, location, this.plugin.getSettings());
|
this.updateOutsideCosmetics(player, location, this.plugin.getSettings());
|
||||||
location.setYaw(this.getNextYaw(yaw - 30, rotationSpeed));
|
location.setYaw(this.getNextYaw(yaw - 30, rotationSpeed));
|
||||||
PacketManager.sendPacket(
|
PacketManager.sendRotationPacket(entityId, location, true, player);
|
||||||
player,
|
|
||||||
PacketManager.getRotationPacket(this.getEntityId(), location)
|
|
||||||
);
|
|
||||||
data.set(this.getNextYaw(yaw, rotationSpeed));
|
data.set(this.getNextYaw(yaw, rotationSpeed));
|
||||||
},
|
},
|
||||||
() -> !this.spawned || this.currentLocation == null
|
() -> !this.spawned || this.currentLocation == null
|
||||||
|
|||||||
@@ -1,74 +0,0 @@
|
|||||||
package io.github.fisher2911.hmccosmetics.util;
|
|
||||||
|
|
||||||
import io.github.fisher2911.hmccosmetics.HMCCosmetics;
|
|
||||||
import org.bukkit.NamespacedKey;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
|
||||||
import org.bukkit.persistence.PersistentDataType;
|
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
|
||||||
|
|
||||||
public class Keys {
|
|
||||||
|
|
||||||
static HMCCosmetics plugin = HMCCosmetics.getPlugin(HMCCosmetics.class);
|
|
||||||
public static final NamespacedKey ITEM_KEY = new NamespacedKey(plugin, "cosmetic");
|
|
||||||
public static final NamespacedKey TOKEN_KEY = new NamespacedKey(plugin, "token-key");
|
|
||||||
|
|
||||||
public static void setKey(final ItemStack itemStack) {
|
|
||||||
final ItemMeta itemMeta = itemStack.getItemMeta();
|
|
||||||
|
|
||||||
if (itemMeta == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
itemMeta.getPersistentDataContainer().set(ITEM_KEY, PersistentDataType.BYTE, (byte) 1);
|
|
||||||
|
|
||||||
itemStack.setItemMeta(itemMeta);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T, Z> void setKey(
|
|
||||||
final ItemStack itemStack,
|
|
||||||
final NamespacedKey key,
|
|
||||||
final PersistentDataType<T, Z> type,
|
|
||||||
final Z value) {
|
|
||||||
final ItemMeta itemMeta = itemStack.getItemMeta();
|
|
||||||
|
|
||||||
if (itemMeta == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
itemMeta.getPersistentDataContainer().set(key, type, value);
|
|
||||||
|
|
||||||
itemStack.setItemMeta(itemMeta);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean hasKey(final ItemStack itemStack) {
|
|
||||||
final ItemMeta itemMeta = itemStack.getItemMeta();
|
|
||||||
|
|
||||||
if (itemMeta == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return itemMeta.getPersistentDataContainer().has(ITEM_KEY, PersistentDataType.BYTE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T, Z> boolean hasKey(final ItemStack itemStack, final NamespacedKey key, final PersistentDataType<T, Z> type) {
|
|
||||||
final ItemMeta itemMeta = itemStack.getItemMeta();
|
|
||||||
|
|
||||||
if (itemMeta == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return itemMeta.getPersistentDataContainer().has(key, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public static <T, Z> Z getValue(final ItemStack itemStack, final NamespacedKey key, final PersistentDataType<T, Z> type) {
|
|
||||||
final ItemMeta itemMeta = itemStack.getItemMeta();
|
|
||||||
|
|
||||||
if (itemMeta == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return itemMeta.getPersistentDataContainer().get(key, type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
package io.github.fisher2911.hmccosmetics.util;
|
|
||||||
|
|
||||||
import io.github.fisher2911.hmccosmetics.HMCCosmetics;
|
|
||||||
import io.github.fisher2911.hmccosmetics.message.Adventure;
|
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
|
|
||||||
public class StringUtils {
|
|
||||||
|
|
||||||
private static final HMCCosmetics plugin;
|
|
||||||
|
|
||||||
static {
|
|
||||||
plugin = HMCCosmetics.getPlugin(HMCCosmetics.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param parsed message to be parsed
|
|
||||||
* @return MiniMessage parsed string
|
|
||||||
*/
|
|
||||||
|
|
||||||
public static Component parse(final String parsed) {
|
|
||||||
return Adventure.MINI_MESSAGE.deserialize(parsed);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String parseStringToString(final String parsed) {
|
|
||||||
return Adventure.SERIALIZER.serialize(Adventure.MINI_MESSAGE.deserialize(parsed));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String formatArmorItemType(String type) {
|
|
||||||
type = type.toLowerCase();
|
|
||||||
final String[] parts = type.split(" ");
|
|
||||||
|
|
||||||
final String firstPart = parts[0].substring(0, 1).toUpperCase() + parts[0].substring(1);
|
|
||||||
|
|
||||||
if (parts.length == 1) {
|
|
||||||
return firstPart;
|
|
||||||
}
|
|
||||||
|
|
||||||
return firstPart + parts[1].substring(0, 1).toUpperCase() + parts[1].substring(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,110 +0,0 @@
|
|||||||
package io.github.fisher2911.hmccosmetics.util;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
import java.util.function.Function;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
public class Utils {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param original Object to be checked if null
|
|
||||||
* @param replacement Object returned if original is null
|
|
||||||
* @return original if not null, otherwise replacement
|
|
||||||
*/
|
|
||||||
|
|
||||||
public static <T> T replaceIfNull(final @Nullable T original, final @NotNull T replacement) {
|
|
||||||
return replaceIfNull(original, replacement, t -> {
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> T replaceIf(final @Nullable T original, final T replacement, final @Nullable T... checks) {
|
|
||||||
for (final T check : checks) {
|
|
||||||
if (original == check) return replacement;
|
|
||||||
}
|
|
||||||
return original;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param original Object to be checked if null
|
|
||||||
* @param replacement Object returned if original is null
|
|
||||||
* @param consumer accepts the original object, can be used for logging
|
|
||||||
* @return original if not null, otherwise replacement
|
|
||||||
*/
|
|
||||||
|
|
||||||
public static <T> T replaceIfNull(final @Nullable T original, final T replacement,
|
|
||||||
final @NotNull Consumer<T> consumer) {
|
|
||||||
if (original == null) {
|
|
||||||
consumer.accept(replacement);
|
|
||||||
return replacement;
|
|
||||||
}
|
|
||||||
consumer.accept(original);
|
|
||||||
return original;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param t object being checked
|
|
||||||
* @param consumer accepted if t is not null
|
|
||||||
* @param <T> type
|
|
||||||
*/
|
|
||||||
|
|
||||||
public static <T> void doIfNotNull(final @Nullable T t, final @NotNull Consumer<T> consumer) {
|
|
||||||
if (t == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
consumer.accept(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param t object being checked
|
|
||||||
* @param function applied if t is not null
|
|
||||||
* @param <T> type
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
|
|
||||||
public static <T> Optional<T> returnIfNotNull(final @Nullable T t,
|
|
||||||
final @NotNull Function<T, T> function) {
|
|
||||||
if (t == null) {
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
return Optional.of(function.apply(t));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param enumAsString Enum value as a string to be parsed
|
|
||||||
* @param enumClass enum type enumAsString is to be converted to
|
|
||||||
* @param defaultEnum default value to be returned
|
|
||||||
* @return enumAsString as an enum, or default enum if it could not be parsed
|
|
||||||
*/
|
|
||||||
|
|
||||||
public static <E extends Enum<E>> E stringToEnum(final @NotNull String enumAsString,
|
|
||||||
final @NotNull Class<E> enumClass,
|
|
||||||
E defaultEnum) {
|
|
||||||
return stringToEnum(enumAsString, enumClass, defaultEnum, e -> {
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param enumAsString Enum value as a string to be parsed
|
|
||||||
* @param enumClass enum type enumAsString is to be converted to
|
|
||||||
* @param defaultEnum default value to be returned
|
|
||||||
* @param consumer accepts the returned enum, can be used for logging
|
|
||||||
* @return enumAsString as an enum, or default enum if it could not be parsed
|
|
||||||
*/
|
|
||||||
|
|
||||||
public static <E extends Enum<E>> E stringToEnum(final @NotNull String enumAsString,
|
|
||||||
@NotNull final Class<E> enumClass,
|
|
||||||
final E defaultEnum,
|
|
||||||
final @NotNull Consumer<E> consumer) {
|
|
||||||
try {
|
|
||||||
final E value = Enum.valueOf(enumClass, enumAsString);
|
|
||||||
consumer.accept(value);
|
|
||||||
return value;
|
|
||||||
} catch (final IllegalArgumentException exception) {
|
|
||||||
consumer.accept(defaultEnum);
|
|
||||||
return defaultEnum;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
package io.github.fisher2911.hmccosmetics.util.builder;
|
|
||||||
|
|
||||||
import org.bukkit.Color;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
|
||||||
import org.bukkit.inventory.meta.LeatherArmorMeta;
|
|
||||||
import org.bukkit.inventory.meta.PotionMeta;
|
|
||||||
|
|
||||||
public class ColorBuilder extends ItemBuilder {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param material ItemStack material
|
|
||||||
*/
|
|
||||||
|
|
||||||
ColorBuilder(final Material material) {
|
|
||||||
super(material);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param itemStack ItemStack
|
|
||||||
*/
|
|
||||||
|
|
||||||
ColorBuilder(final ItemStack itemStack) {
|
|
||||||
super(itemStack);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param material ItemStack material
|
|
||||||
* @return this
|
|
||||||
* @throws IllegalArgumentException thrown if itemStack's type can not change color
|
|
||||||
*/
|
|
||||||
|
|
||||||
public static ColorBuilder from(final Material material) throws IllegalArgumentException {
|
|
||||||
if (!canBeColored(material)) {
|
|
||||||
throw new IllegalArgumentException(material.name() + " is not leather armor!");
|
|
||||||
}
|
|
||||||
return new ColorBuilder(material);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param itemStack ItemStack
|
|
||||||
* @return this
|
|
||||||
* @throws IllegalArgumentException thrown if itemStack's type can not change color
|
|
||||||
*/
|
|
||||||
|
|
||||||
public static ColorBuilder from(final ItemStack itemStack) throws IllegalArgumentException {
|
|
||||||
final Material material = itemStack.getType();
|
|
||||||
if (!canBeColored(itemStack)) {
|
|
||||||
throw new IllegalArgumentException(material.name() + " is not leather armor!");
|
|
||||||
}
|
|
||||||
return new ColorBuilder(itemStack);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean canBeColored(final Material material) {
|
|
||||||
return canBeColored(new ItemStack(material));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean canBeColored(final ItemStack itemStack) {
|
|
||||||
final ItemMeta itemMeta = itemStack.getItemMeta();
|
|
||||||
|
|
||||||
return (itemMeta instanceof LeatherArmorMeta ||
|
|
||||||
itemMeta instanceof PotionMeta);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param color armor color
|
|
||||||
* @return this
|
|
||||||
*/
|
|
||||||
|
|
||||||
public ColorBuilder color(final Color color) {
|
|
||||||
if (this.itemMeta instanceof final PotionMeta meta) {
|
|
||||||
meta.setColor(color);
|
|
||||||
}
|
|
||||||
if (this.itemMeta instanceof final LeatherArmorMeta meta) {
|
|
||||||
meta.setColor(color);
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,255 +0,0 @@
|
|||||||
package io.github.fisher2911.hmccosmetics.util.builder;
|
|
||||||
|
|
||||||
import io.github.fisher2911.hmccosmetics.message.Placeholder;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.enchantments.Enchantment;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.inventory.ItemFlag;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
|
||||||
|
|
||||||
public class ItemBuilder {
|
|
||||||
|
|
||||||
protected Material material;
|
|
||||||
protected int amount;
|
|
||||||
protected ItemMeta itemMeta;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param material builder material
|
|
||||||
*/
|
|
||||||
|
|
||||||
ItemBuilder(final Material material) {
|
|
||||||
this.material = material;
|
|
||||||
this.itemMeta = Bukkit.getItemFactory().getItemMeta(material);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param itemStack builder ItemStack
|
|
||||||
*/
|
|
||||||
|
|
||||||
ItemBuilder(final ItemStack itemStack) {
|
|
||||||
this.material = itemStack.getType();
|
|
||||||
this.itemMeta = itemStack.hasItemMeta() ? itemStack.getItemMeta()
|
|
||||||
: Bukkit.getItemFactory().getItemMeta(this.material);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param material builder material
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
|
|
||||||
public static ItemBuilder from(final Material material) {
|
|
||||||
return new ItemBuilder(material);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param itemStack builder ItemStack
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
|
|
||||||
public static ItemBuilder from(final ItemStack itemStack) {
|
|
||||||
return new ItemBuilder(itemStack);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param amount ItemStack amount
|
|
||||||
* @return this
|
|
||||||
*/
|
|
||||||
|
|
||||||
public ItemBuilder amount(final int amount) {
|
|
||||||
this.amount = Math.min(Math.max(1, amount), 64);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param name ItemStack name
|
|
||||||
* @return this
|
|
||||||
*/
|
|
||||||
|
|
||||||
public ItemBuilder name(final String name) {
|
|
||||||
if (this.itemMeta == null) {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
this.itemMeta.setDisplayName(name);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets placeholders to the item's name
|
|
||||||
*
|
|
||||||
* @param placeholders placeholders
|
|
||||||
*/
|
|
||||||
|
|
||||||
public ItemBuilder namePlaceholders(final Map<String, String> placeholders) {
|
|
||||||
if (this.itemMeta == null) {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
final String name = Placeholder.
|
|
||||||
applyPlaceholders(this.itemMeta.getDisplayName(), placeholders);
|
|
||||||
this.itemMeta.setDisplayName(name);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param lore ItemStack lore
|
|
||||||
* @return this
|
|
||||||
*/
|
|
||||||
|
|
||||||
public ItemBuilder lore(final List<String> lore) {
|
|
||||||
if (this.itemMeta == null) {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
this.itemMeta.setLore(lore);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets placeholders to the item's lore
|
|
||||||
*
|
|
||||||
* @param placeholders placeholders
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
public ItemBuilder lorePlaceholders(final Map<String, String> placeholders) {
|
|
||||||
if (this.itemMeta == null) {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
final List<String> lore = new ArrayList<>();
|
|
||||||
|
|
||||||
final List<String> previousLore = this.itemMeta.getLore();
|
|
||||||
|
|
||||||
if (previousLore == null) {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (final String line : previousLore) {
|
|
||||||
lore.add(Placeholder.applyPlaceholders(
|
|
||||||
line, placeholders
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
this.itemMeta.setLore(lore);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ItemBuilder papiPlaceholders(final Player player) {
|
|
||||||
this.lorePapiPlaceholders(player);
|
|
||||||
this.namePapiPlaceholders(player);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void lorePapiPlaceholders(final Player player) {
|
|
||||||
if (this.itemMeta == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final List<String> newLore = new ArrayList<>();
|
|
||||||
|
|
||||||
final List<String> lore = this.itemMeta.getLore();
|
|
||||||
|
|
||||||
if (lore == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (final String line : this.itemMeta.getLore()) {
|
|
||||||
newLore.add(Placeholder.applyPapiPlaceholders(player, line));
|
|
||||||
}
|
|
||||||
|
|
||||||
this.itemMeta.setLore(newLore);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void namePapiPlaceholders(final Player player) {
|
|
||||||
if (this.itemMeta == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.itemMeta.setDisplayName(
|
|
||||||
Placeholder.applyPapiPlaceholders(
|
|
||||||
player,
|
|
||||||
this.itemMeta.getDisplayName()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param unbreakable whether the ItemStack is unbreakable
|
|
||||||
* @return this
|
|
||||||
*/
|
|
||||||
|
|
||||||
public ItemBuilder unbreakable(final boolean unbreakable) {
|
|
||||||
if (this.itemMeta == null) {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
this.itemMeta.setUnbreakable(unbreakable);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ItemBuilder glow(final boolean glow) {
|
|
||||||
if (this.itemMeta == null) {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
if (glow) {
|
|
||||||
this.itemMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
|
|
||||||
this.itemMeta.addEnchant(Enchantment.LUCK, 1, true);
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param enchantments enchants to be added to the ItemStack
|
|
||||||
* @param ignoreLeveLRestrictions whether to ignore enchantment level restrictions
|
|
||||||
* @return this
|
|
||||||
*/
|
|
||||||
|
|
||||||
public ItemBuilder enchants(final Map<Enchantment, Integer> enchantments,
|
|
||||||
boolean ignoreLeveLRestrictions) {
|
|
||||||
if (this.itemMeta == null) {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
enchantments.forEach((enchantment, level) -> this.itemMeta.addEnchant(enchantment, level,
|
|
||||||
ignoreLeveLRestrictions));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param itemFlags ItemStack ItemFlags
|
|
||||||
* @return this
|
|
||||||
*/
|
|
||||||
|
|
||||||
public ItemBuilder itemFlags(final Set<ItemFlag> itemFlags) {
|
|
||||||
if (this.itemMeta == null) {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
this.itemMeta.addItemFlags(itemFlags.toArray(new ItemFlag[0]));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param modelData ItemStack modelData
|
|
||||||
* @return this
|
|
||||||
*/
|
|
||||||
|
|
||||||
public ItemBuilder modelData(final int modelData) {
|
|
||||||
if (this.itemMeta == null) {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
this.itemMeta.setCustomModelData(modelData);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return built ItemStack
|
|
||||||
*/
|
|
||||||
|
|
||||||
public ItemStack build() {
|
|
||||||
final ItemStack itemStack = new ItemStack(this.material, Math.max(this.amount, 1));
|
|
||||||
itemStack.setItemMeta(itemMeta);
|
|
||||||
return itemStack;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
package io.github.fisher2911.hmccosmetics.util.builder;
|
|
||||||
|
|
||||||
import com.mojang.authlib.GameProfile;
|
|
||||||
import com.mojang.authlib.properties.Property;
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.util.UUID;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.OfflinePlayer;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.bukkit.inventory.meta.SkullMeta;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Some parts taken from https://github.com/TriumphTeam/triumph-gui/blob/master/core/src/main/java/dev/triumphteam/gui/builder/item/SkullBuilder.java
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class SkullBuilder extends ItemBuilder {
|
|
||||||
|
|
||||||
private static final Field PROFILE_FIELD;
|
|
||||||
|
|
||||||
static {
|
|
||||||
Field field;
|
|
||||||
|
|
||||||
try {
|
|
||||||
final SkullMeta skullMeta = (SkullMeta) new ItemStack(
|
|
||||||
Material.PLAYER_HEAD).getItemMeta();
|
|
||||||
field = skullMeta.getClass().getDeclaredField("profile");
|
|
||||||
field.setAccessible(true);
|
|
||||||
} catch (NoSuchFieldException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
field = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
PROFILE_FIELD = field;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param material The material
|
|
||||||
*/
|
|
||||||
|
|
||||||
SkullBuilder(final Material material) {
|
|
||||||
super(material);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new SkullBuilder instance
|
|
||||||
*
|
|
||||||
* @return this
|
|
||||||
*/
|
|
||||||
|
|
||||||
public static SkullBuilder create() {
|
|
||||||
return new SkullBuilder(Material.PLAYER_HEAD);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param player skull owner
|
|
||||||
* @return this
|
|
||||||
*/
|
|
||||||
public SkullBuilder owner(final OfflinePlayer player) {
|
|
||||||
if (this.itemMeta instanceof final SkullMeta skullMeta) {
|
|
||||||
skullMeta.setOwningPlayer(player);
|
|
||||||
this.itemMeta = skullMeta;
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param texture skull texture
|
|
||||||
* @return this
|
|
||||||
*/
|
|
||||||
|
|
||||||
public SkullBuilder texture(@NotNull final String texture) {
|
|
||||||
if (PROFILE_FIELD == null) {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
final SkullMeta skullMeta = (SkullMeta) this.itemMeta;
|
|
||||||
final GameProfile profile = new GameProfile(UUID.randomUUID(), null);
|
|
||||||
profile.getProperties().put("textures", new Property("textures", texture));
|
|
||||||
|
|
||||||
try {
|
|
||||||
PROFILE_FIELD.set(skullMeta, profile);
|
|
||||||
} catch (IllegalArgumentException | IllegalAccessException ex) {
|
|
||||||
ex.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.itemMeta = skullMeta;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -11,12 +11,12 @@ repositories {
|
|||||||
maven("https://papermc.io/repo/repository/maven-public/")
|
maven("https://papermc.io/repo/repository/maven-public/")
|
||||||
maven("https://oss.sonatype.org/content/repositories/snapshots")
|
maven("https://oss.sonatype.org/content/repositories/snapshots")
|
||||||
maven("https://jitpack.io")
|
maven("https://jitpack.io")
|
||||||
maven("https://repo.dmulloy2.net/repository/public/")
|
// maven("https://repo.dmulloy2.net/repository/public/")
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compileOnly("com.mojang:authlib:1.5.25")
|
compileOnly("com.mojang:authlib:1.5.25")
|
||||||
compileOnly("org.spigotmc:spigot:1.18-R0.1-SNAPSHOT")
|
// compileOnly("org.spigotmc:spigot:1.18-R0.1-SNAPSHOT")
|
||||||
compileOnly("org.jetbrains:annotations:22.0.0")
|
compileOnly("org.jetbrains:annotations:22.0.0")
|
||||||
compileOnly("com.comphenix.protocol:ProtocolLib:4.7.0")
|
// compileOnly("com.comphenix.protocol:ProtocolLib:4.7.0")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,13 @@
|
|||||||
package io.github.fisher2911.nms;
|
package io.github.fisher2911.nms;
|
||||||
|
|
||||||
import com.comphenix.protocol.events.PacketContainer;
|
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public interface PacketHelper {
|
public interface PacketHelper {
|
||||||
|
|
||||||
PacketContainer getPlayerSpawnPacket(final Location location, UUID uuid, final int entityId);
|
// PacketContainer getPlayerSpawnPacket(final Location location, UUID uuid, final int entityId);
|
||||||
PacketContainer getPlayerInfoPacket(final Player player, final UUID uuid);
|
// PacketContainer getPlayerInfoPacket(final Player player, final UUID uuid);
|
||||||
PacketContainer getPlayerRemovePacket(final Player player, final UUID uuid, final int entityId);
|
// PacketContainer getPlayerRemovePacket(final Player player, final UUID uuid, final int entityId);
|
||||||
PacketContainer getPlayerOverlayPacket(final int entityId);
|
// PacketContainer getPlayerOverlayPacket(final int entityId);
|
||||||
PacketContainer getDestroyPacket(final int entityId);
|
// PacketContainer getDestroyPacket(final int entityId);
|
||||||
PacketContainer getArmorStandMeta(final int armorStandId);
|
// PacketContainer getArmorStandMeta(final int armorStandId);
|
||||||
// PacketContainer getGuiOpenPacket(final Player player);
|
// PacketContainer getGuiOpenPacket(final Player player);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,4 @@
|
|||||||
rootProject.name = "HMCCosmetics"
|
rootProject.name = "HMCCosmetics"
|
||||||
include(
|
include(
|
||||||
"common",
|
"common"
|
||||||
"nms",
|
|
||||||
"1.16",
|
|
||||||
"1.17",
|
|
||||||
"1.18"
|
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user