mirror of
https://github.com/HibiscusMC/HMCCosmetics.git
synced 2025-12-19 15:09:19 +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://oss.sonatype.org/content/repositories/snapshots")
|
||||
maven("https://jitpack.io")
|
||||
maven("https://repo.dmulloy2.net/repository/public/")
|
||||
// maven("https://repo.dmulloy2.net/repository/public/")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@@ -15,5 +15,5 @@ dependencies {
|
||||
compileOnly("com.mojang:authlib:1.5.25")
|
||||
compileOnly("org.spigotmc:spigot:1.16.5-R0.1-SNAPSHOT")
|
||||
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;
|
||||
|
||||
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 {
|
||||
|
||||
@Override
|
||||
public PacketContainer getPlayerSpawnPacket(final Location location, UUID uuid, final int entityId) {
|
||||
final PacketContainer spawnPacket = new PacketContainer(PacketType.Play.Server.NAMED_ENTITY_SPAWN);
|
||||
spawnPacket.getUUIDs().write(0, uuid);
|
||||
spawnPacket.getIntegers().write(0, entityId);
|
||||
spawnPacket.getDoubles().
|
||||
write(0, location.getX()).
|
||||
write(1, location.getY()).
|
||||
write(2, location.getZ());
|
||||
spawnPacket.getBytes().write(0, (byte)(((location.getYaw() * 256.0F) / 360.0F)));
|
||||
|
||||
return spawnPacket;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PacketContainer getPlayerInfoPacket(final Player player, final UUID uuid) {
|
||||
final GameProfile profile = this.getCopyProfile(player, uuid);
|
||||
final PacketContainer playerInfoPacket = new PacketContainer(PacketType.Play.Server.PLAYER_INFO);
|
||||
final StructureModifier<EnumWrappers.PlayerInfoAction> action = playerInfoPacket.getPlayerInfoAction();
|
||||
final StructureModifier<List<PlayerInfoData>> infoData = playerInfoPacket.getPlayerInfoDataLists();
|
||||
|
||||
final List<PlayerInfoData> playerInfoData = new ArrayList<>();
|
||||
|
||||
playerInfoData.add(new PlayerInfoData(WrappedGameProfile
|
||||
.fromHandle(profile),
|
||||
0,
|
||||
EnumWrappers.NativeGameMode.fromBukkit(GameMode.CREATIVE),
|
||||
WrappedChatComponent.fromText(profile.getName())));
|
||||
|
||||
action.write(0, EnumWrappers.PlayerInfoAction.ADD_PLAYER);
|
||||
infoData.write(0, playerInfoData);
|
||||
|
||||
return playerInfoPacket;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PacketContainer getPlayerRemovePacket(final Player player, final UUID uuid, final int entityId) {
|
||||
final PacketContainer playerPacket = new PacketContainer(PacketType.Play.Server.PLAYER_INFO);
|
||||
final StructureModifier<EnumWrappers.PlayerInfoAction> action = playerPacket.getPlayerInfoAction();
|
||||
final StructureModifier<List<PlayerInfoData>> infoData = playerPacket.getPlayerInfoDataLists();
|
||||
|
||||
final List<PlayerInfoData> playerInfoData = new ArrayList<>();
|
||||
|
||||
final GameProfile profile = this.getCopyProfile(player, uuid);
|
||||
|
||||
playerInfoData.add(new PlayerInfoData(WrappedGameProfile
|
||||
.fromHandle(profile),
|
||||
0,
|
||||
EnumWrappers.NativeGameMode.fromBukkit(GameMode.CREATIVE),
|
||||
WrappedChatComponent.fromText("")));
|
||||
|
||||
action.write(0, EnumWrappers.PlayerInfoAction.REMOVE_PLAYER);
|
||||
infoData.write(0, playerInfoData);
|
||||
|
||||
return playerPacket;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PacketContainer getPlayerOverlayPacket(final int entityId) {
|
||||
final PacketContainer metaContainer = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
|
||||
|
||||
WrappedDataWatcher metaData = new WrappedDataWatcher();
|
||||
|
||||
final WrappedDataWatcher.Serializer byteSerializer = WrappedDataWatcher.Registry.get(Byte.class);
|
||||
|
||||
final byte mask = 0x01 | 0x02 | 0x04 | 0x08 | 0x010 | 0x020 | 0x40;
|
||||
|
||||
metaData.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(16, byteSerializer), mask);
|
||||
|
||||
metaContainer.getIntegers().write(0, entityId);
|
||||
metaContainer.getWatchableCollectionModifier().write(0, metaData.getWatchableObjects());
|
||||
return metaContainer;
|
||||
}
|
||||
|
||||
private GameProfile getCopyProfile(final Player player, final UUID uuid) {
|
||||
final GameProfile playerProfile = ((CraftPlayer) player).getProfile();
|
||||
final GameProfile profile = new GameProfile(
|
||||
uuid,
|
||||
player.getDisplayName()
|
||||
);
|
||||
|
||||
profile.getProperties().removeAll("textures");
|
||||
Property textureProperty = playerProfile.getProperties().get("textures").iterator().next();
|
||||
String texture = textureProperty.getValue();
|
||||
String signature = textureProperty.getSignature();
|
||||
profile.getProperties().put("textures", new Property("textures", texture, signature));
|
||||
|
||||
return profile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PacketContainer getArmorStandMeta(final int armorStandId) {
|
||||
final PacketContainer metaContainer = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
|
||||
|
||||
WrappedDataWatcher metaData = new WrappedDataWatcher();
|
||||
|
||||
final WrappedDataWatcher.Serializer byteSerializer = WrappedDataWatcher.Registry.get(Byte.class);
|
||||
|
||||
metaData.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(0, byteSerializer), (byte) (0x20));
|
||||
metaData.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(14, byteSerializer), (byte) (0x10));
|
||||
|
||||
metaContainer.getIntegers().write(0, armorStandId);
|
||||
metaContainer.getWatchableCollectionModifier().write(0, metaData.getWatchableObjects());
|
||||
return metaContainer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PacketContainer getDestroyPacket(final int entityId) {
|
||||
final PacketContainer destroyPacket = new PacketContainer(
|
||||
PacketType.Play.Server.ENTITY_DESTROY);
|
||||
destroyPacket.getIntegerArrays().write(0, new int[]{entityId});
|
||||
|
||||
return destroyPacket;
|
||||
}
|
||||
// @Override
|
||||
// public PacketContainer getPlayerSpawnPacket(final Location location, UUID uuid, final int entityId) {
|
||||
// final PacketContainer spawnPacket = new PacketContainer(PacketType.Play.Server.NAMED_ENTITY_SPAWN);
|
||||
// spawnPacket.getUUIDs().write(0, uuid);
|
||||
// spawnPacket.getIntegers().write(0, entityId);
|
||||
// spawnPacket.getDoubles().
|
||||
// write(0, location.getX()).
|
||||
// write(1, location.getY()).
|
||||
// write(2, location.getZ());
|
||||
// spawnPacket.getBytes().write(0, (byte)(((location.getYaw() * 256.0F) / 360.0F)));
|
||||
//
|
||||
// return spawnPacket;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public PacketContainer getPlayerInfoPacket(final Player player, final UUID uuid) {
|
||||
// final GameProfile profile = this.getCopyProfile(player, uuid);
|
||||
// final PacketContainer playerInfoPacket = new PacketContainer(PacketType.Play.Server.PLAYER_INFO);
|
||||
// final StructureModifier<EnumWrappers.PlayerInfoAction> action = playerInfoPacket.getPlayerInfoAction();
|
||||
// final StructureModifier<List<PlayerInfoData>> infoData = playerInfoPacket.getPlayerInfoDataLists();
|
||||
//
|
||||
// final List<PlayerInfoData> playerInfoData = new ArrayList<>();
|
||||
//
|
||||
// playerInfoData.add(new PlayerInfoData(WrappedGameProfile
|
||||
// .fromHandle(profile),
|
||||
// 0,
|
||||
// EnumWrappers.NativeGameMode.fromBukkit(GameMode.CREATIVE),
|
||||
// WrappedChatComponent.fromText(profile.getName())));
|
||||
//
|
||||
// action.write(0, EnumWrappers.PlayerInfoAction.ADD_PLAYER);
|
||||
// infoData.write(0, playerInfoData);
|
||||
//
|
||||
// return playerInfoPacket;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public PacketContainer getPlayerRemovePacket(final Player player, final UUID uuid, final int entityId) {
|
||||
// final PacketContainer playerPacket = new PacketContainer(PacketType.Play.Server.PLAYER_INFO);
|
||||
// final StructureModifier<EnumWrappers.PlayerInfoAction> action = playerPacket.getPlayerInfoAction();
|
||||
// final StructureModifier<List<PlayerInfoData>> infoData = playerPacket.getPlayerInfoDataLists();
|
||||
//
|
||||
// final List<PlayerInfoData> playerInfoData = new ArrayList<>();
|
||||
//
|
||||
// final GameProfile profile = this.getCopyProfile(player, uuid);
|
||||
//
|
||||
// playerInfoData.add(new PlayerInfoData(WrappedGameProfile
|
||||
// .fromHandle(profile),
|
||||
// 0,
|
||||
// EnumWrappers.NativeGameMode.fromBukkit(GameMode.CREATIVE),
|
||||
// WrappedChatComponent.fromText("")));
|
||||
//
|
||||
// action.write(0, EnumWrappers.PlayerInfoAction.REMOVE_PLAYER);
|
||||
// infoData.write(0, playerInfoData);
|
||||
//
|
||||
// return playerPacket;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public PacketContainer getPlayerOverlayPacket(final int entityId) {
|
||||
// final PacketContainer metaContainer = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
|
||||
//
|
||||
// WrappedDataWatcher metaData = new WrappedDataWatcher();
|
||||
//
|
||||
// final WrappedDataWatcher.Serializer byteSerializer = WrappedDataWatcher.Registry.get(Byte.class);
|
||||
//
|
||||
// final byte mask = 0x01 | 0x02 | 0x04 | 0x08 | 0x010 | 0x020 | 0x40;
|
||||
//
|
||||
// metaData.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(16, byteSerializer), mask);
|
||||
//
|
||||
// metaContainer.getIntegers().write(0, entityId);
|
||||
// metaContainer.getWatchableCollectionModifier().write(0, metaData.getWatchableObjects());
|
||||
// return metaContainer;
|
||||
// }
|
||||
//
|
||||
// private GameProfile getCopyProfile(final Player player, final UUID uuid) {
|
||||
// final GameProfile playerProfile = ((CraftPlayer) player).getProfile();
|
||||
// final GameProfile profile = new GameProfile(
|
||||
// uuid,
|
||||
// player.getDisplayName()
|
||||
// );
|
||||
//
|
||||
// profile.getProperties().removeAll("textures");
|
||||
// Property textureProperty = playerProfile.getProperties().get("textures").iterator().next();
|
||||
// String texture = textureProperty.getValue();
|
||||
// String signature = textureProperty.getSignature();
|
||||
// profile.getProperties().put("textures", new Property("textures", texture, signature));
|
||||
//
|
||||
// return profile;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public PacketContainer getArmorStandMeta(final int armorStandId) {
|
||||
// final PacketContainer metaContainer = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
|
||||
//
|
||||
// WrappedDataWatcher metaData = new WrappedDataWatcher();
|
||||
//
|
||||
// final WrappedDataWatcher.Serializer byteSerializer = WrappedDataWatcher.Registry.get(Byte.class);
|
||||
//
|
||||
// metaData.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(0, byteSerializer), (byte) (0x20));
|
||||
// metaData.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(14, byteSerializer), (byte) (0x10));
|
||||
//
|
||||
// metaContainer.getIntegers().write(0, armorStandId);
|
||||
// metaContainer.getWatchableCollectionModifier().write(0, metaData.getWatchableObjects());
|
||||
// return metaContainer;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public PacketContainer getDestroyPacket(final int entityId) {
|
||||
// final PacketContainer destroyPacket = new PacketContainer(
|
||||
// PacketType.Play.Server.ENTITY_DESTROY);
|
||||
// destroyPacket.getIntegerArrays().write(0, new int[]{entityId});
|
||||
//
|
||||
// return destroyPacket;
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ repositories {
|
||||
maven("https://papermc.io/repo/repository/maven-public/")
|
||||
maven("https://oss.sonatype.org/content/repositories/snapshots")
|
||||
maven("https://jitpack.io")
|
||||
maven("https://repo.dmulloy2.net/repository/public/")
|
||||
// maven("https://repo.dmulloy2.net/repository/public/")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@@ -19,5 +19,5 @@ 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("com.comphenix.protocol:ProtocolLib:4.7.0")
|
||||
}
|
||||
|
||||
@@ -1,140 +1,120 @@
|
||||
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 {
|
||||
|
||||
@Override
|
||||
public PacketContainer getPlayerSpawnPacket(final Location location, UUID uuid, final int entityId) {
|
||||
final PacketContainer spawnPacket = new PacketContainer(PacketType.Play.Server.NAMED_ENTITY_SPAWN);
|
||||
spawnPacket.getUUIDs().write(0, uuid);
|
||||
spawnPacket.getIntegers().write(0, entityId);
|
||||
spawnPacket.getDoubles().
|
||||
write(0, location.getX()).
|
||||
write(1, location.getY()).
|
||||
write(2, location.getZ());
|
||||
spawnPacket.getBytes().write(0, (byte)(((location.getYaw() * 256.0F) / 360.0F)));
|
||||
|
||||
return spawnPacket;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PacketContainer getPlayerInfoPacket(final Player player, final UUID uuid) {
|
||||
final GameProfile profile = this.getCopyProfile(player, uuid);
|
||||
final PacketContainer playerInfoPacket = new PacketContainer(PacketType.Play.Server.PLAYER_INFO);
|
||||
final StructureModifier<EnumWrappers.PlayerInfoAction> action = playerInfoPacket.getPlayerInfoAction();
|
||||
final StructureModifier<List<PlayerInfoData>> infoData = playerInfoPacket.getPlayerInfoDataLists();
|
||||
|
||||
final List<PlayerInfoData> playerInfoData = new ArrayList<>();
|
||||
|
||||
playerInfoData.add(new PlayerInfoData(WrappedGameProfile
|
||||
.fromHandle(profile),
|
||||
0,
|
||||
EnumWrappers.NativeGameMode.fromBukkit(GameMode.CREATIVE),
|
||||
WrappedChatComponent.fromText(profile.getName())));
|
||||
|
||||
action.write(0, EnumWrappers.PlayerInfoAction.ADD_PLAYER);
|
||||
infoData.write(0, playerInfoData);
|
||||
|
||||
return playerInfoPacket;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PacketContainer getPlayerRemovePacket(final Player player, final UUID uuid, final int entityId) {
|
||||
final PacketContainer playerPacket = new PacketContainer(PacketType.Play.Server.PLAYER_INFO);
|
||||
final StructureModifier<EnumWrappers.PlayerInfoAction> action = playerPacket.getPlayerInfoAction();
|
||||
final StructureModifier<List<PlayerInfoData>> infoData = playerPacket.getPlayerInfoDataLists();
|
||||
|
||||
final List<PlayerInfoData> playerInfoData = new ArrayList<>();
|
||||
|
||||
final GameProfile profile = this.getCopyProfile(player, uuid);
|
||||
|
||||
playerInfoData.add(new PlayerInfoData(WrappedGameProfile
|
||||
.fromHandle(profile),
|
||||
0,
|
||||
EnumWrappers.NativeGameMode.fromBukkit(GameMode.CREATIVE),
|
||||
WrappedChatComponent.fromText("")));
|
||||
|
||||
action.write(0, EnumWrappers.PlayerInfoAction.REMOVE_PLAYER);
|
||||
infoData.write(0, playerInfoData);
|
||||
|
||||
return playerPacket;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PacketContainer getPlayerOverlayPacket(final int entityId) {
|
||||
final PacketContainer metaContainer = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
|
||||
|
||||
WrappedDataWatcher metaData = new WrappedDataWatcher();
|
||||
|
||||
final WrappedDataWatcher.Serializer byteSerializer = WrappedDataWatcher.Registry.get(Byte.class);
|
||||
|
||||
final byte mask = 0x01 | 0x02 | 0x04 | 0x08 | 0x010 | 0x020 | 0x40;
|
||||
|
||||
metaData.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(17, byteSerializer), mask);
|
||||
|
||||
metaContainer.getIntegers().write(0, entityId);
|
||||
metaContainer.getWatchableCollectionModifier().write(0, metaData.getWatchableObjects());
|
||||
return metaContainer;
|
||||
}
|
||||
|
||||
private GameProfile getCopyProfile(final Player player, final UUID uuid) {
|
||||
final GameProfile playerProfile = ((CraftPlayer) player).getProfile();
|
||||
final GameProfile profile = new GameProfile(
|
||||
uuid,
|
||||
player.getDisplayName()
|
||||
);
|
||||
|
||||
profile.getProperties().removeAll("textures");
|
||||
Property textureProperty = playerProfile.getProperties().get("textures").iterator().next();
|
||||
String texture = textureProperty.getValue();
|
||||
String signature = textureProperty.getSignature();
|
||||
profile.getProperties().put("textures", new Property("textures", texture, signature));
|
||||
|
||||
return profile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PacketContainer getArmorStandMeta(final int armorStandId) {
|
||||
final PacketContainer metaContainer = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
|
||||
|
||||
WrappedDataWatcher metaData = new WrappedDataWatcher();
|
||||
|
||||
final WrappedDataWatcher.Serializer byteSerializer = WrappedDataWatcher.Registry.get(Byte.class);
|
||||
|
||||
metaData.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(0, byteSerializer), (byte) (0x20));
|
||||
metaData.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(15, byteSerializer), (byte) (0x10));
|
||||
|
||||
metaContainer.getIntegers().write(0, armorStandId);
|
||||
metaContainer.getWatchableCollectionModifier().write(0, metaData.getWatchableObjects());
|
||||
return metaContainer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PacketContainer getDestroyPacket(final int entityId) {
|
||||
final PacketContainer destroyPacket = new PacketContainer(
|
||||
PacketType.Play.Server.ENTITY_DESTROY);
|
||||
destroyPacket.getModifier().write(0, new IntArrayList(new int[]{entityId}));
|
||||
|
||||
return destroyPacket;
|
||||
}
|
||||
// @Override
|
||||
// public PacketContainer getPlayerSpawnPacket(final Location location, UUID uuid, final int entityId) {
|
||||
// final PacketContainer spawnPacket = new PacketContainer(PacketType.Play.Server.NAMED_ENTITY_SPAWN);
|
||||
// spawnPacket.getUUIDs().write(0, uuid);
|
||||
// spawnPacket.getIntegers().write(0, entityId);
|
||||
// spawnPacket.getDoubles().
|
||||
// write(0, location.getX()).
|
||||
// write(1, location.getY()).
|
||||
// write(2, location.getZ());
|
||||
// spawnPacket.getBytes().write(0, (byte)(((location.getYaw() * 256.0F) / 360.0F)));
|
||||
//
|
||||
// return spawnPacket;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public PacketContainer getPlayerInfoPacket(final Player player, final UUID uuid) {
|
||||
// final GameProfile profile = this.getCopyProfile(player, uuid);
|
||||
// final PacketContainer playerInfoPacket = new PacketContainer(PacketType.Play.Server.PLAYER_INFO);
|
||||
// final StructureModifier<EnumWrappers.PlayerInfoAction> action = playerInfoPacket.getPlayerInfoAction();
|
||||
// final StructureModifier<List<PlayerInfoData>> infoData = playerInfoPacket.getPlayerInfoDataLists();
|
||||
//
|
||||
// final List<PlayerInfoData> playerInfoData = new ArrayList<>();
|
||||
//
|
||||
// playerInfoData.add(new PlayerInfoData(WrappedGameProfile
|
||||
// .fromHandle(profile),
|
||||
// 0,
|
||||
// EnumWrappers.NativeGameMode.fromBukkit(GameMode.CREATIVE),
|
||||
// WrappedChatComponent.fromText(profile.getName())));
|
||||
//
|
||||
// action.write(0, EnumWrappers.PlayerInfoAction.ADD_PLAYER);
|
||||
// infoData.write(0, playerInfoData);
|
||||
//
|
||||
// return playerInfoPacket;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public PacketContainer getPlayerRemovePacket(final Player player, final UUID uuid, final int entityId) {
|
||||
// final PacketContainer playerPacket = new PacketContainer(PacketType.Play.Server.PLAYER_INFO);
|
||||
// final StructureModifier<EnumWrappers.PlayerInfoAction> action = playerPacket.getPlayerInfoAction();
|
||||
// final StructureModifier<List<PlayerInfoData>> infoData = playerPacket.getPlayerInfoDataLists();
|
||||
//
|
||||
// final List<PlayerInfoData> playerInfoData = new ArrayList<>();
|
||||
//
|
||||
// final GameProfile profile = this.getCopyProfile(player, uuid);
|
||||
//
|
||||
// playerInfoData.add(new PlayerInfoData(WrappedGameProfile
|
||||
// .fromHandle(profile),
|
||||
// 0,
|
||||
// EnumWrappers.NativeGameMode.fromBukkit(GameMode.CREATIVE),
|
||||
// WrappedChatComponent.fromText("")));
|
||||
//
|
||||
// action.write(0, EnumWrappers.PlayerInfoAction.REMOVE_PLAYER);
|
||||
// infoData.write(0, playerInfoData);
|
||||
//
|
||||
// return playerPacket;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public PacketContainer getPlayerOverlayPacket(final int entityId) {
|
||||
// final PacketContainer metaContainer = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
|
||||
//
|
||||
// WrappedDataWatcher metaData = new WrappedDataWatcher();
|
||||
//
|
||||
// final WrappedDataWatcher.Serializer byteSerializer = WrappedDataWatcher.Registry.get(Byte.class);
|
||||
//
|
||||
// final byte mask = 0x01 | 0x02 | 0x04 | 0x08 | 0x010 | 0x020 | 0x40;
|
||||
//
|
||||
// metaData.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(17, byteSerializer), mask);
|
||||
//
|
||||
// metaContainer.getIntegers().write(0, entityId);
|
||||
// metaContainer.getWatchableCollectionModifier().write(0, metaData.getWatchableObjects());
|
||||
// return metaContainer;
|
||||
// }
|
||||
//
|
||||
// private GameProfile getCopyProfile(final Player player, final UUID uuid) {
|
||||
// final GameProfile playerProfile = ((CraftPlayer) player).getProfile();
|
||||
// final GameProfile profile = new GameProfile(
|
||||
// uuid,
|
||||
// player.getDisplayName()
|
||||
// );
|
||||
//
|
||||
// profile.getProperties().removeAll("textures");
|
||||
// Property textureProperty = playerProfile.getProperties().get("textures").iterator().next();
|
||||
// String texture = textureProperty.getValue();
|
||||
// String signature = textureProperty.getSignature();
|
||||
// profile.getProperties().put("textures", new Property("textures", texture, signature));
|
||||
//
|
||||
// return profile;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public PacketContainer getArmorStandMeta(final int armorStandId) {
|
||||
// final PacketContainer metaContainer = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
|
||||
//
|
||||
// WrappedDataWatcher metaData = new WrappedDataWatcher();
|
||||
//
|
||||
// final WrappedDataWatcher.Serializer byteSerializer = WrappedDataWatcher.Registry.get(Byte.class);
|
||||
//
|
||||
// metaData.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(0, byteSerializer), (byte) (0x20));
|
||||
// metaData.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(15, byteSerializer), (byte) (0x10));
|
||||
//
|
||||
// metaContainer.getIntegers().write(0, armorStandId);
|
||||
// metaContainer.getWatchableCollectionModifier().write(0, metaData.getWatchableObjects());
|
||||
// return metaContainer;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public PacketContainer getDestroyPacket(final int entityId) {
|
||||
// final PacketContainer destroyPacket = new PacketContainer(
|
||||
// PacketType.Play.Server.ENTITY_DESTROY);
|
||||
// destroyPacket.getModifier().write(0, new IntArrayList(new int[]{entityId}));
|
||||
//
|
||||
// return destroyPacket;
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ repositories {
|
||||
maven("https://papermc.io/repo/repository/maven-public/")
|
||||
maven("https://oss.sonatype.org/content/repositories/snapshots")
|
||||
maven("https://jitpack.io")
|
||||
maven("https://repo.dmulloy2.net/repository/public/")
|
||||
// maven("https://repo.dmulloy2.net/repository/public/")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@@ -19,5 +19,5 @@ dependencies {
|
||||
compileOnly("com.mojang:authlib:1.5.25")
|
||||
compileOnly("org.spigotmc:spigot:1.18-R0.1-SNAPSHOT")
|
||||
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;
|
||||
|
||||
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 {
|
||||
|
||||
@Override
|
||||
public PacketContainer getPlayerSpawnPacket(final Location location, UUID uuid, final int entityId) {
|
||||
final PacketContainer spawnPacket = new PacketContainer(PacketType.Play.Server.NAMED_ENTITY_SPAWN);
|
||||
spawnPacket.getUUIDs().write(0, uuid);
|
||||
spawnPacket.getIntegers().write(0, entityId);
|
||||
spawnPacket.getDoubles().
|
||||
write(0, location.getX()).
|
||||
write(1, location.getY()).
|
||||
write(2, location.getZ());
|
||||
spawnPacket.getBytes().write(0, (byte)(((location.getYaw() * 256.0F) / 360.0F)));
|
||||
|
||||
return spawnPacket;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PacketContainer getPlayerInfoPacket(final Player player, final UUID uuid) {
|
||||
final GameProfile profile = this.getCopyProfile(player, uuid);
|
||||
final PacketContainer playerInfoPacket = new PacketContainer(PacketType.Play.Server.PLAYER_INFO);
|
||||
final StructureModifier<EnumWrappers.PlayerInfoAction> action = playerInfoPacket.getPlayerInfoAction();
|
||||
final StructureModifier<List<PlayerInfoData>> infoData = playerInfoPacket.getPlayerInfoDataLists();
|
||||
|
||||
final List<PlayerInfoData> playerInfoData = new ArrayList<>();
|
||||
|
||||
playerInfoData.add(new PlayerInfoData(WrappedGameProfile
|
||||
.fromHandle(profile),
|
||||
0,
|
||||
EnumWrappers.NativeGameMode.fromBukkit(GameMode.SURVIVAL),
|
||||
WrappedChatComponent.fromText(profile.getName())));
|
||||
|
||||
action.write(0, EnumWrappers.PlayerInfoAction.ADD_PLAYER);
|
||||
infoData.write(0, playerInfoData);
|
||||
|
||||
return playerInfoPacket;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PacketContainer getPlayerRemovePacket(final Player player, final UUID uuid, final int entityId) {
|
||||
final PacketContainer playerPacket = new PacketContainer(PacketType.Play.Server.PLAYER_INFO);
|
||||
final StructureModifier<EnumWrappers.PlayerInfoAction> action = playerPacket.getPlayerInfoAction();
|
||||
final StructureModifier<List<PlayerInfoData>> infoData = playerPacket.getPlayerInfoDataLists();
|
||||
|
||||
final List<PlayerInfoData> playerInfoData = new ArrayList<>();
|
||||
|
||||
final GameProfile profile = this.getCopyProfile(player, uuid);
|
||||
|
||||
playerInfoData.add(new PlayerInfoData(WrappedGameProfile
|
||||
.fromHandle(profile),
|
||||
0,
|
||||
EnumWrappers.NativeGameMode.fromBukkit(GameMode.CREATIVE),
|
||||
WrappedChatComponent.fromText("")));
|
||||
|
||||
action.write(0, EnumWrappers.PlayerInfoAction.REMOVE_PLAYER);
|
||||
infoData.write(0, playerInfoData);
|
||||
|
||||
return playerPacket;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PacketContainer getPlayerOverlayPacket(final int entityId) {
|
||||
final PacketContainer metaContainer = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
|
||||
|
||||
WrappedDataWatcher metaData = new WrappedDataWatcher();
|
||||
|
||||
final WrappedDataWatcher.Serializer byteSerializer = WrappedDataWatcher.Registry.get(Byte.class);
|
||||
|
||||
final byte mask = 0x01 | 0x02 | 0x04 | 0x08 | 0x010 | 0x020 | 0x40;
|
||||
|
||||
metaData.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(17, byteSerializer), mask);
|
||||
|
||||
metaContainer.getIntegers().write(0, entityId);
|
||||
metaContainer.getWatchableCollectionModifier().write(0, metaData.getWatchableObjects());
|
||||
return metaContainer;
|
||||
}
|
||||
|
||||
private GameProfile getCopyProfile(final Player player, final UUID uuid) {
|
||||
final GameProfile playerProfile = ((CraftPlayer) player).getProfile();
|
||||
final GameProfile profile = new GameProfile(
|
||||
uuid,
|
||||
player.getDisplayName()
|
||||
);
|
||||
|
||||
profile.getProperties().removeAll("textures");
|
||||
Property textureProperty = playerProfile.getProperties().get("textures").iterator().next();
|
||||
String texture = textureProperty.getValue();
|
||||
String signature = textureProperty.getSignature();
|
||||
profile.getProperties().put("textures", new Property("textures", texture, signature));
|
||||
|
||||
return profile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PacketContainer getArmorStandMeta(final int armorStandId) {
|
||||
final PacketContainer metaContainer = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
|
||||
|
||||
WrappedDataWatcher metaData = new WrappedDataWatcher();
|
||||
|
||||
final WrappedDataWatcher.Serializer byteSerializer = WrappedDataWatcher.Registry.get(Byte.class);
|
||||
|
||||
metaData.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(0, byteSerializer), (byte) (0x20));
|
||||
metaData.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(15, byteSerializer), (byte) (0x10));
|
||||
|
||||
metaContainer.getIntegers().write(0, armorStandId);
|
||||
metaContainer.getWatchableCollectionModifier().write(0, metaData.getWatchableObjects());
|
||||
return metaContainer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PacketContainer getDestroyPacket(final int entityId) {
|
||||
final PacketContainer destroyPacket = new PacketContainer(
|
||||
PacketType.Play.Server.ENTITY_DESTROY);
|
||||
destroyPacket.getModifier().write(0, new IntArrayList(new int[]{entityId}));
|
||||
|
||||
return destroyPacket;
|
||||
}
|
||||
// @Override
|
||||
// public PacketContainer getPlayerSpawnPacket(final Location location, UUID uuid, final int entityId) {
|
||||
// final PacketContainer spawnPacket = new PacketContainer(PacketType.Play.Server.NAMED_ENTITY_SPAWN);
|
||||
// spawnPacket.getUUIDs().write(0, uuid);
|
||||
// spawnPacket.getIntegers().write(0, entityId);
|
||||
// spawnPacket.getDoubles().
|
||||
// write(0, location.getX()).
|
||||
// write(1, location.getY()).
|
||||
// write(2, location.getZ());
|
||||
// spawnPacket.getBytes().write(0, (byte)(((location.getYaw() * 256.0F) / 360.0F)));
|
||||
//
|
||||
// return spawnPacket;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public PacketContainer getPlayerInfoPacket(final Player player, final UUID uuid) {
|
||||
// final GameProfile profile = this.getCopyProfile(player, uuid);
|
||||
// final PacketContainer playerInfoPacket = new PacketContainer(PacketType.Play.Server.PLAYER_INFO);
|
||||
// final StructureModifier<EnumWrappers.PlayerInfoAction> action = playerInfoPacket.getPlayerInfoAction();
|
||||
// final StructureModifier<List<PlayerInfoData>> infoData = playerInfoPacket.getPlayerInfoDataLists();
|
||||
//
|
||||
// final List<PlayerInfoData> playerInfoData = new ArrayList<>();
|
||||
//
|
||||
// playerInfoData.add(new PlayerInfoData(WrappedGameProfile
|
||||
// .fromHandle(profile),
|
||||
// 0,
|
||||
// EnumWrappers.NativeGameMode.fromBukkit(GameMode.SURVIVAL),
|
||||
// WrappedChatComponent.fromText(profile.getName())));
|
||||
//
|
||||
// action.write(0, EnumWrappers.PlayerInfoAction.ADD_PLAYER);
|
||||
// infoData.write(0, playerInfoData);
|
||||
//
|
||||
// return playerInfoPacket;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public PacketContainer getPlayerRemovePacket(final Player player, final UUID uuid, final int entityId) {
|
||||
// final PacketContainer playerPacket = new PacketContainer(PacketType.Play.Server.PLAYER_INFO);
|
||||
// final StructureModifier<EnumWrappers.PlayerInfoAction> action = playerPacket.getPlayerInfoAction();
|
||||
// final StructureModifier<List<PlayerInfoData>> infoData = playerPacket.getPlayerInfoDataLists();
|
||||
//
|
||||
// final List<PlayerInfoData> playerInfoData = new ArrayList<>();
|
||||
//
|
||||
// final GameProfile profile = this.getCopyProfile(player, uuid);
|
||||
//
|
||||
// playerInfoData.add(new PlayerInfoData(WrappedGameProfile
|
||||
// .fromHandle(profile),
|
||||
// 0,
|
||||
// EnumWrappers.NativeGameMode.fromBukkit(GameMode.CREATIVE),
|
||||
// WrappedChatComponent.fromText("")));
|
||||
//
|
||||
// action.write(0, EnumWrappers.PlayerInfoAction.REMOVE_PLAYER);
|
||||
// infoData.write(0, playerInfoData);
|
||||
//
|
||||
// return playerPacket;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public PacketContainer getPlayerOverlayPacket(final int entityId) {
|
||||
// final PacketContainer metaContainer = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
|
||||
//
|
||||
// WrappedDataWatcher metaData = new WrappedDataWatcher();
|
||||
//
|
||||
// final WrappedDataWatcher.Serializer byteSerializer = WrappedDataWatcher.Registry.get(Byte.class);
|
||||
//
|
||||
// final byte mask = 0x01 | 0x02 | 0x04 | 0x08 | 0x010 | 0x020 | 0x40;
|
||||
//
|
||||
// metaData.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(17, byteSerializer), mask);
|
||||
//
|
||||
// metaContainer.getIntegers().write(0, entityId);
|
||||
// metaContainer.getWatchableCollectionModifier().write(0, metaData.getWatchableObjects());
|
||||
// return metaContainer;
|
||||
// }
|
||||
//
|
||||
// private GameProfile getCopyProfile(final Player player, final UUID uuid) {
|
||||
// final GameProfile playerProfile = ((CraftPlayer) player).getProfile();
|
||||
// final GameProfile profile = new GameProfile(
|
||||
// uuid,
|
||||
// player.getDisplayName()
|
||||
// );
|
||||
//
|
||||
// profile.getProperties().removeAll("textures");
|
||||
// Property textureProperty = playerProfile.getProperties().get("textures").iterator().next();
|
||||
// String texture = textureProperty.getValue();
|
||||
// String signature = textureProperty.getSignature();
|
||||
// profile.getProperties().put("textures", new Property("textures", texture, signature));
|
||||
//
|
||||
// return profile;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public PacketContainer getArmorStandMeta(final int armorStandId) {
|
||||
// final PacketContainer metaContainer = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
|
||||
//
|
||||
// WrappedDataWatcher metaData = new WrappedDataWatcher();
|
||||
//
|
||||
// final WrappedDataWatcher.Serializer byteSerializer = WrappedDataWatcher.Registry.get(Byte.class);
|
||||
//
|
||||
// metaData.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(0, byteSerializer), (byte) (0x20));
|
||||
// metaData.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(15, byteSerializer), (byte) (0x10));
|
||||
//
|
||||
// metaContainer.getIntegers().write(0, armorStandId);
|
||||
// metaContainer.getWatchableCollectionModifier().write(0, metaData.getWatchableObjects());
|
||||
// return metaContainer;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public PacketContainer getDestroyPacket(final int entityId) {
|
||||
// final PacketContainer destroyPacket = new PacketContainer(
|
||||
// PacketType.Play.Server.ENTITY_DESTROY);
|
||||
// destroyPacket.getModifier().write(0, new IntArrayList(new int[]{entityId}));
|
||||
//
|
||||
// return destroyPacket;
|
||||
// }
|
||||
}
|
||||
|
||||
109
build.gradle.kts
109
build.gradle.kts
@@ -1,112 +1,3 @@
|
||||
|
||||
//import net.minecrell.pluginyml.bukkit.BukkitPluginDescription
|
||||
//
|
||||
plugins {
|
||||
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.citizensnpcs.co")
|
||||
maven("https://mvn.lumine.io/repository/maven-public")
|
||||
maven("https://jitpack.io/")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(":1.16"))
|
||||
implementation(project(":1.17"))
|
||||
implementation(project(":1.18"))
|
||||
implementation(project(":nms"))
|
||||
// implementation(project(":1.16"))
|
||||
// implementation(project(":1.17"))
|
||||
// implementation(project(":1.18"))
|
||||
// implementation(project(":nms"))
|
||||
compileOnly("com.mojang:authlib:1.5.25")
|
||||
compileOnly("org.spigotmc:spigot:1.16.5-R0.1-SNAPSHOT")
|
||||
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("com.github.oraxen:oraxen:-SNAPSHOT")
|
||||
compileOnly("com.github.LoneDev6:API-ItemsAdder:2.5.4")
|
||||
compileOnly("net.citizensnpcs:citizens-main:2.0.29-SNAPSHOT")
|
||||
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-text-minimessage:4.10.0-SNAPSHOT")
|
||||
implementation("net.kyori:adventure-platform-bukkit:4.0.1")
|
||||
@@ -68,6 +70,7 @@ tasks {
|
||||
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")
|
||||
relocate("com.github.retrooper.packetevents", "io.github.fisher2911.hmccosmetics.packetevents")
|
||||
archiveFileName.set("HMCCosmetics.jar")
|
||||
|
||||
dependencies {
|
||||
@@ -100,8 +103,8 @@ bukkit {
|
||||
apiVersion = "1.16"
|
||||
name = "HMCCosmetics"
|
||||
authors = listOf("MasterOfTheFish")
|
||||
softDepend = listOf("Multiverse", "PlaceholderAPI", "Oraxen", "ItemsAdder", "Citizens", "ModelEngine")
|
||||
depend = listOf("ProtocolLib")
|
||||
softDepend = listOf("Multiverse", "PlaceholderAPI", "Oraxen", "ItemsAdder", "Citizens", "ModelEngine", "packetevents")
|
||||
// depend = listOf("ProtocolLib")
|
||||
permissions {
|
||||
register("hmccosmetics.cmd.default") {
|
||||
default = BukkitPluginDescription.Permission.Default.OP
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package io.github.fisher2911.hmccosmetics;
|
||||
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.comphenix.protocol.ProtocolManager;
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import io.github.fisher2911.hmccosmetics.command.CosmeticsCommand;
|
||||
import io.github.fisher2911.hmccosmetics.concurrent.Threads;
|
||||
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.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.hook.HookManager;
|
||||
import io.github.fisher2911.hmccosmetics.hook.item.ItemsAdderHook;
|
||||
import io.github.fisher2911.hmccosmetics.listener.ClickListener;
|
||||
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.task.TaskManager;
|
||||
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.Paths;
|
||||
@@ -38,18 +44,10 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
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 static final Path PLUGIN_FOLDER = Paths.get("plugins", "HMCCosmetics");
|
||||
|
||||
private ProtocolManager protocolManager;
|
||||
private TaskManager taskManager;
|
||||
private Settings settings;
|
||||
private UserManager userManager;
|
||||
@@ -62,12 +60,18 @@ public class HMCCosmetics extends JavaPlugin {
|
||||
|
||||
private BukkitTask saveTask;
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
PacketEvents.setAPI(SpigotPacketEventsBuilder.build(this));
|
||||
PacketEvents.getAPI().getSettings().debug(true);
|
||||
PacketEvents.getAPI().load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
PacketEvents.getAPI().init();
|
||||
final int pluginId = 13873;
|
||||
final Metrics metrics = new Metrics(this, pluginId);
|
||||
|
||||
this.protocolManager = ProtocolLibrary.getProtocolManager();
|
||||
this.taskManager = new TaskManager(this);
|
||||
this.taskManager.start();
|
||||
this.settings = new Settings(this);
|
||||
@@ -106,6 +110,7 @@ public class HMCCosmetics extends JavaPlugin {
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
PacketEvents.getAPI().terminate();
|
||||
this.saveTask.cancel();
|
||||
this.database.saveAll();
|
||||
this.messageHandler.close();
|
||||
@@ -237,10 +242,6 @@ public class HMCCosmetics extends JavaPlugin {
|
||||
return cosmeticsMenu;
|
||||
}
|
||||
|
||||
public ProtocolManager getProtocolManager() {
|
||||
return protocolManager;
|
||||
}
|
||||
|
||||
public Database getDatabase() {
|
||||
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 io.github.fisher2911.hmccosmetics.HMCCosmetics;
|
||||
import io.github.fisher2911.hmccosmetics.concurrent.Threads;
|
||||
import io.github.fisher2911.hmccosmetics.database.dao.ArmorItemDAO;
|
||||
import io.github.fisher2911.hmccosmetics.database.dao.CitizenDAO;
|
||||
import io.github.fisher2911.hmccosmetics.database.dao.UserDAO;
|
||||
import io.github.fisher2911.hmccosmetics.dao.ArmorItemDAO;
|
||||
import io.github.fisher2911.hmccosmetics.dao.CitizenDAO;
|
||||
import io.github.fisher2911.hmccosmetics.dao.UserDAO;
|
||||
import io.github.fisher2911.hmccosmetics.gui.ArmorItem;
|
||||
import io.github.fisher2911.hmccosmetics.inventory.PlayerArmor;
|
||||
import io.github.fisher2911.hmccosmetics.user.EntityIds;
|
||||
@@ -20,11 +20,8 @@ import org.bukkit.entity.Entity;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.SplittableRandom;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
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;
|
||||
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers;
|
||||
import dev.triumphteam.gui.components.GuiAction;
|
||||
import io.github.fisher2911.hmccosmetics.config.CosmeticGuiAction;
|
||||
import io.github.fisher2911.hmccosmetics.util.builder.ColorBuilder;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
@@ -16,6 +11,9 @@ import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ArmorItem extends WrappedGuiItem {
|
||||
|
||||
private final String name;
|
||||
@@ -338,13 +336,13 @@ public class ArmorItem extends WrappedGuiItem {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Type fromWrapper(EnumWrappers.ItemSlot slot) {
|
||||
public static Type fromWrapper(EquipmentSlot slot) {
|
||||
return switch (slot) {
|
||||
case HEAD -> Type.HAT;
|
||||
case CHEST -> Type.CHEST_PLATE;
|
||||
case LEGS -> Type.PANTS;
|
||||
case FEET -> Type.BOOTS;
|
||||
case OFFHAND -> Type.OFF_HAND;
|
||||
case OFF_HAND -> Type.OFF_HAND;
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,34 +1,14 @@
|
||||
package io.github.fisher2911.hmccosmetics.listener;
|
||||
|
||||
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 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.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.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.ItemStack;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class ClickListener implements Listener {
|
||||
|
||||
@@ -77,86 +57,86 @@ public class ClickListener implements Listener {
|
||||
this.userManager = this.plugin.getUserManager();
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onArmorSlotClick(final InventoryClickEvent event) {
|
||||
final int slot = event.getSlot();
|
||||
if (!(event.getWhoClicked() instanceof final Player player)) return;
|
||||
if (slot >= 36 && slot <= 40) {
|
||||
this.fixInventory(player);
|
||||
}
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onShiftClick(final InventoryClickEvent event) {
|
||||
if (event.getClick() != ClickType.SHIFT_LEFT &&
|
||||
event.getClick() != ClickType.SHIFT_RIGHT) return;
|
||||
if (!(event.getWhoClicked() instanceof final Player player)) return;
|
||||
final ItemStack clicked = event.getCurrentItem();
|
||||
if (clicked == null) return;
|
||||
this.checkFix(player, -1, clicked);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onCosmeticClick(final InventoryDragEvent event) {
|
||||
final HumanEntity player = event.getWhoClicked();
|
||||
if (!(player instanceof Player)) {
|
||||
return;
|
||||
}
|
||||
// this.fixInventory((Player) player);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onInventoryClose(final InventoryCloseEvent event) {
|
||||
final HumanEntity player = event.getPlayer();
|
||||
this.userManager.get(player.getUniqueId()).ifPresent(this::doRunnable);
|
||||
}
|
||||
|
||||
private void fixInventory(final Player player) {
|
||||
final Optional<User> optionalUser = this.userManager.get(player.getUniqueId());
|
||||
|
||||
if (optionalUser.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.doRunnable(optionalUser.get());
|
||||
}
|
||||
|
||||
private void doRunnable(final User user) {
|
||||
Bukkit.getScheduler().runTaskLaterAsynchronously(
|
||||
this.plugin, () -> this.userManager.updateCosmetics(user),
|
||||
1);
|
||||
}
|
||||
|
||||
private void checkFix(final Player player, final int clickedSlot, final ItemStack itemStack) {
|
||||
final EquipmentSlot slot = this.getArmorSlot(itemStack.getType());
|
||||
if (slot == null) return;
|
||||
final ItemStack wearing = player.getEquipment().getItem(slot);
|
||||
if (wearing == null) return;
|
||||
if (wearing.getType() == Material.AIR || (clickedSlot >= 39 && clickedSlot <= 40)) {
|
||||
this.fixInventory(player);
|
||||
}
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
// @EventHandler
|
||||
// public void onArmorSlotClick(final InventoryClickEvent event) {
|
||||
// final int slot = event.getSlot();
|
||||
// if (!(event.getWhoClicked() instanceof final Player player)) return;
|
||||
// if (slot >= 36 && slot <= 40) {
|
||||
// this.fixInventory(player);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @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);
|
||||
// }
|
||||
//
|
||||
// @EventHandler
|
||||
// public void onShiftClick(final InventoryClickEvent event) {
|
||||
// if (event.getClick() != ClickType.SHIFT_LEFT &&
|
||||
// event.getClick() != ClickType.SHIFT_RIGHT) return;
|
||||
// if (!(event.getWhoClicked() instanceof final Player player)) return;
|
||||
// final ItemStack clicked = event.getCurrentItem();
|
||||
// if (clicked == null) return;
|
||||
// this.checkFix(player, -1, clicked);
|
||||
// }
|
||||
//
|
||||
// @EventHandler
|
||||
// public void onCosmeticClick(final InventoryDragEvent event) {
|
||||
// final HumanEntity player = event.getWhoClicked();
|
||||
// if (!(player instanceof Player)) {
|
||||
// return;
|
||||
// }
|
||||
//// this.fixInventory((Player) player);
|
||||
// }
|
||||
//
|
||||
// @EventHandler
|
||||
// public void onInventoryClose(final InventoryCloseEvent event) {
|
||||
// final HumanEntity player = event.getPlayer();
|
||||
// this.userManager.get(player.getUniqueId()).ifPresent(this::doRunnable);
|
||||
// }
|
||||
//
|
||||
// private void fixInventory(final Player player) {
|
||||
// final Optional<User> optionalUser = this.userManager.get(player.getUniqueId());
|
||||
//
|
||||
// if (optionalUser.isEmpty()) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// this.doRunnable(optionalUser.get());
|
||||
// }
|
||||
//
|
||||
// private void doRunnable(final User user) {
|
||||
// Bukkit.getScheduler().runTaskLaterAsynchronously(
|
||||
// this.plugin, () -> this.userManager.updateCosmetics(user),
|
||||
// 1);
|
||||
// }
|
||||
//
|
||||
// private void checkFix(final Player player, final int clickedSlot, final ItemStack itemStack) {
|
||||
// final EquipmentSlot slot = this.getArmorSlot(itemStack.getType());
|
||||
// if (slot == null) return;
|
||||
// final ItemStack wearing = player.getEquipment().getItem(slot);
|
||||
// if (wearing == null) return;
|
||||
// if (wearing.getType() == Material.AIR || (clickedSlot >= 39 && clickedSlot <= 40)) {
|
||||
// this.fixInventory(player);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @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;
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
@@ -1,46 +1,346 @@
|
||||
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.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.util.Utils;
|
||||
import io.github.fisher2911.hmccosmetics.util.builder.ItemBuilder;
|
||||
import io.github.retrooper.packetevents.util.SpigotDataHelper;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
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.inventory.EntityEquipment;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
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 {
|
||||
|
||||
private final HMCCosmetics plugin;
|
||||
private final UserManager userManager;
|
||||
private final CosmeticSettings settings;
|
||||
private final TaskManager taskManager;
|
||||
|
||||
public CosmeticFixListener(final HMCCosmetics plugin) {
|
||||
this.plugin = plugin;
|
||||
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
|
||||
public void onEntityMount(final EntityMountEvent event) {
|
||||
if (!(event.getEntity() instanceof final Player player)) {
|
||||
return;
|
||||
public void onShiftClick(final InventoryClickEvent event) {
|
||||
if (event.getClick() != ClickType.SHIFT_LEFT && event.getClick() != ClickType.SHIFT_RIGHT) 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) {
|
||||
final ItemStack offHand = event.getOffHandItem();
|
||||
if (offHand != null && offHand.getType() != Material.AIR) {
|
||||
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) {
|
||||
if (event.getHand() != EquipmentSlot.OFF_HAND) {
|
||||
return;
|
||||
@@ -51,7 +351,60 @@ public class CosmeticFixListener implements Listener {
|
||||
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) {
|
||||
@@ -59,4 +412,67 @@ public class CosmeticFixListener implements Listener {
|
||||
() -> 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;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.comphenix.protocol.ProtocolManager;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers;
|
||||
import com.comphenix.protocol.wrappers.MinecraftKey;
|
||||
import com.comphenix.protocol.wrappers.Pair;
|
||||
import com.comphenix.protocol.wrappers.WrappedDataWatcher;
|
||||
import io.github.fisher2911.nms.PacketHelper;
|
||||
import io.github.fisher2911.nms.PacketHelper_1_16_R3;
|
||||
import io.github.fisher2911.nms.PacketHelper_1_17_R1;
|
||||
import io.github.fisher2911.nms.PacketHelper_1_18_R1;
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
|
||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes;
|
||||
import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
|
||||
import com.github.retrooper.packetevents.protocol.player.Equipment;
|
||||
import com.github.retrooper.packetevents.protocol.player.EquipmentSlot;
|
||||
import com.github.retrooper.packetevents.protocol.player.UserProfile;
|
||||
import com.github.retrooper.packetevents.util.Vector3d;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerAttachEntity;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerDestroyEntities;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityEquipment;
|
||||
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.Location;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
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.UUID;
|
||||
|
||||
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;
|
||||
|
||||
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 Collection<? extends Player> sendTo) {
|
||||
sendArmorStandMetaContainer(armorStandId, sendTo.toArray(new Player[0]));
|
||||
}
|
||||
|
||||
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) {
|
||||
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(
|
||||
public static void sendEntitySpawnPacket(
|
||||
final Location location,
|
||||
final int entityId,
|
||||
final EntityType entityType,
|
||||
final UUID uuid) {
|
||||
final PacketContainer packet = new PacketContainer(PacketType.Play.Server.SPAWN_ENTITY);
|
||||
|
||||
// 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;
|
||||
final Collection<? extends Player> sendTo) {
|
||||
sendEntitySpawnPacket(location, entityId, entityType, sendTo.toArray(new Player[0]));
|
||||
}
|
||||
|
||||
public static PacketContainer getInvisibilityPacket(final int entityId) {
|
||||
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,
|
||||
public static void sendEntitySpawnPacket(
|
||||
final Location location,
|
||||
final MinecraftKey name,
|
||||
final float volume,
|
||||
final float pitch,
|
||||
final EnumWrappers.SoundCategory soundCategory
|
||||
final int entityId,
|
||||
final EntityType entityType,
|
||||
final Player... sendTo) {
|
||||
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();
|
||||
final var packet = manager.createPacket(PacketType.Play.Server.CUSTOM_SOUND_EFFECT);
|
||||
sendTeleportPacket(entityId, location, onGround, sendTo.toArray(new Player[0]));
|
||||
}
|
||||
|
||||
packet.getMinecraftKeys()
|
||||
.write(
|
||||
0,
|
||||
name
|
||||
);
|
||||
public static void sendTeleportPacket(
|
||||
final int entityId,
|
||||
final Location location,
|
||||
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()
|
||||
.write(0, EnumWrappers.SoundCategory.valueOf(soundCategory.name()));
|
||||
public static void sendMovePacket(
|
||||
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()
|
||||
.write(0, location.getBlockX() * 8)
|
||||
.write(
|
||||
1, location.getBlockY() * 8
|
||||
public static void sendMovePacket(
|
||||
final int entityId,
|
||||
final Location from,
|
||||
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) {
|
||||
for (final Player player : Bukkit.getOnlinePlayers()) {
|
||||
sendPacket(player, packets);
|
||||
public static void sendFakePlayerInfoPacket(
|
||||
final Player player,
|
||||
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);
|
||||
}
|
||||
|
||||
public void submit(final Runnable runnable) {
|
||||
this.submit(new ImmediateTask(runnable));
|
||||
}
|
||||
|
||||
public void end() {
|
||||
this.timer.cancel();
|
||||
for (final Task task : this.tasks) {
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
package io.github.fisher2911.hmccosmetics.user;
|
||||
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers;
|
||||
import com.comphenix.protocol.wrappers.Pair;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
|
||||
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.Settings;
|
||||
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.inventory.PlayerArmor;
|
||||
import io.github.fisher2911.hmccosmetics.packet.PacketManager;
|
||||
import io.github.retrooper.packetevents.util.SpigotDataHelper;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
@@ -101,7 +100,7 @@ public abstract class BaseUser<T> {
|
||||
final HookManager hookManager = HookManager.getInstance();
|
||||
if (!hookManager.isEnabled(ModelEngineHook.class)) return;
|
||||
this.balloon.remove();
|
||||
PacketManager.sendPacketToOnline(PacketManager.getEntityDestroyPacket(this.getBalloonId()));
|
||||
PacketManager.sendEntityDestroyPacket(this.getBalloonId(), Bukkit.getOnlinePlayers());
|
||||
this.viewingBalloon.clear();
|
||||
this.balloon.setAlive(false);
|
||||
}
|
||||
@@ -110,7 +109,7 @@ public abstract class BaseUser<T> {
|
||||
final HookManager hookManager = HookManager.getInstance();
|
||||
if (!hookManager.isEnabled(ModelEngineHook.class)) return;
|
||||
this.balloon.removePlayerFromModel(other);
|
||||
PacketManager.sendPacket(other, PacketManager.getEntityDestroyPacket(this.getBalloonId()));
|
||||
PacketManager.sendEntityDestroyPacket(this.getBalloonId(), other);
|
||||
this.viewingBalloon.remove(other.getUniqueId());
|
||||
if (this.viewingBalloon.isEmpty()) {
|
||||
this.despawnBalloon();
|
||||
@@ -134,19 +133,10 @@ public abstract class BaseUser<T> {
|
||||
this.balloon.addPlayerToModel(other, id);
|
||||
}
|
||||
this.updateBalloon(other, location, settings);
|
||||
PacketManager.sendPacket(
|
||||
other,
|
||||
PacketManager.getEntitySpawnPacket(
|
||||
actual,
|
||||
this.getBalloonId(),
|
||||
this.balloon.getType()
|
||||
),
|
||||
PacketManager.getInvisibilityPacket(this.getBalloonId()),
|
||||
PacketManager.getLeashPacket(
|
||||
this.getBalloonId(),
|
||||
this.getEntityId()
|
||||
)
|
||||
);
|
||||
final int balloonId = this.getBalloonId();
|
||||
PacketManager.sendEntitySpawnPacket(actual, balloonId, EntityTypes.PUFFERFISH, other);
|
||||
PacketManager.sendInvisibilityPacket(balloonId, other);
|
||||
PacketManager.sendLeashPacket(balloonId, this.getEntityId(), other);
|
||||
}
|
||||
|
||||
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());
|
||||
// hookManager.getModelEngineHook().updateModel(this.balloon);
|
||||
this.balloon.updateModel();
|
||||
PacketManager.sendPacket(
|
||||
other,
|
||||
PacketManager.getTeleportPacket(this.getBalloonId(), actual),
|
||||
PacketManager.getLeashPacket(this.getBalloonId(), this.getEntityId())
|
||||
);
|
||||
final int balloonId = this.getBalloonId();
|
||||
PacketManager.sendTeleportPacket(balloonId, actual, false, other);
|
||||
PacketManager.sendLeashPacket(balloonId, this.getEntityId(), other);
|
||||
}
|
||||
|
||||
private void spawnArmorStand(final Player other, final Location location) {
|
||||
final PacketContainer packet = PacketManager.getEntitySpawnPacket(location, this.getArmorStandId(), EntityType.ARMOR_STAND);
|
||||
PacketManager.sendPacket(other, packet);
|
||||
PacketManager.sendEntitySpawnPacket(location, this.getArmorStandId(), EntityTypes.ARMOR_STAND, other);
|
||||
}
|
||||
|
||||
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) {
|
||||
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 UUID otherUUID = other.getUniqueId();
|
||||
final boolean hasBackpack = !this.playerArmor.getItem(ArmorItem.Type.BACKPACK).isEmpty();
|
||||
@@ -212,40 +199,37 @@ public abstract class BaseUser<T> {
|
||||
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);
|
||||
if (hidden) {
|
||||
equipmentList.add(new Pair<>(EnumWrappers.ItemSlot.HEAD,
|
||||
new ItemStack(Material.AIR)
|
||||
final int lookDownPitch = settings.getCosmeticSettings().getLookDownPitch();
|
||||
final boolean isLookingDown =
|
||||
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 {
|
||||
equipmentList.add(new Pair<>(EnumWrappers.ItemSlot.HEAD,
|
||||
this.playerArmor.getBackpack().getItemStack(ArmorItem.Status.APPLIED)
|
||||
final com.github.retrooper.packetevents.protocol.item.ItemStack itemStack =
|
||||
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 PacketContainer armorPacket = PacketManager.getEquipmentPacket(equipmentList, armorStandId);
|
||||
final PacketContainer rotationPacket = PacketManager.getRotationPacket(armorStandId, location);
|
||||
final PacketContainer ridingPacket = PacketManager.getRidingPacket(this.getEntityId(), armorStandId);
|
||||
final PacketContainer armorStandMetaContainer = PacketManager.getArmorStandMetaContainer(armorStandId);
|
||||
|
||||
PacketManager.sendPacket(other, armorPacket, armorStandMetaContainer, rotationPacket, ridingPacket);
|
||||
PacketManager.sendEquipmentPacket(equipment, armorStandId, other);
|
||||
PacketManager.sendRotationPacket(armorStandId, location, false, other);
|
||||
PacketManager.sendRidingPacket(this.getEntityId(), armorStandId, other);
|
||||
PacketManager.sendArmorStandMetaContainer(armorStandId, other);
|
||||
|
||||
if (hidden) return;
|
||||
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() {
|
||||
@@ -255,22 +239,17 @@ public abstract class BaseUser<T> {
|
||||
|
||||
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) {
|
||||
return location.getPitch() > pitchLimit;
|
||||
}
|
||||
|
||||
public void despawnAttached(final Player other) {
|
||||
PacketManager.sendPacket(other, PacketManager.getEntityDestroyPacket(this.getArmorStandId()));
|
||||
PacketManager.sendEntityDestroyPacket(this.getArmorStandId(), other);
|
||||
this.viewingArmorStand.remove(other.getUniqueId());
|
||||
}
|
||||
|
||||
public void despawnAttached() {
|
||||
PacketManager.sendPacketToOnline(PacketManager.getEntityDestroyPacket(this.getArmorStandId()));
|
||||
PacketManager.sendEntityDestroyPacket(this.getArmorStandId(), Bukkit.getOnlinePlayers());
|
||||
this.viewingArmorStand.clear();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
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.api.CosmeticItem;
|
||||
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.task.InfiniteTask;
|
||||
import io.github.fisher2911.hmccosmetics.util.builder.ItemBuilder;
|
||||
import io.github.retrooper.packetevents.util.SpigotDataHelper;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -49,7 +47,6 @@ public class UserManager {
|
||||
|
||||
public void add(final User user) {
|
||||
this.userMap.put(user.getId(), user);
|
||||
this.updateCosmetics(user);
|
||||
}
|
||||
|
||||
public Optional<User> get(final UUID uuid) {
|
||||
@@ -78,11 +75,11 @@ public class UserManager {
|
||||
|
||||
public void startTeleportTask() {
|
||||
// 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(
|
||||
() -> {
|
||||
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()) {
|
||||
final Player p = user.getPlayer();
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -101,16 +99,14 @@ public class UserManager {
|
||||
this.get(uuid).ifPresent(this::updateCosmetics);
|
||||
}
|
||||
|
||||
public void updateCosmetics(final BaseUser user) {
|
||||
public void updateCosmetics(final BaseUser<?> user) {
|
||||
for (final Player player : Bukkit.getOnlinePlayers()) {
|
||||
this.updateCosmetics(user, player);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateCosmetics(final BaseUser user, final Player other) {
|
||||
// final Player player = user.getPlayer();
|
||||
public void updateCosmetics(final BaseUser<?> user, final Player other) {
|
||||
final Equipment equipment = user.getEquipment();
|
||||
|
||||
for (final ArmorItem.Type type : ArmorItem.Type.values()) {
|
||||
if (type.getSlot() == null) continue;
|
||||
this.sendUpdatePacket(
|
||||
@@ -123,7 +119,7 @@ public class UserManager {
|
||||
}
|
||||
|
||||
private void sendUpdatePacket(
|
||||
final BaseUser user,
|
||||
final BaseUser<?> user,
|
||||
final Player other,
|
||||
final Equipment equipment,
|
||||
final ArmorItem.Type type) {
|
||||
@@ -131,14 +127,14 @@ public class UserManager {
|
||||
final EquipmentSlot slot = type.getSlot();
|
||||
final ItemStack itemStack = this.getCosmeticItem(user, equipment, playerArmor.getItem(type), ArmorItem.Status.APPLIED, slot);
|
||||
if (itemStack != null && itemStack.equals(equipment.getItem(slot))) return;
|
||||
final List<Pair<EnumWrappers.ItemSlot, ItemStack>> itemList = new ArrayList<>();
|
||||
itemList.add(new Pair<>(EnumWrappers.ItemSlot.valueOf(slot.toString().replace("_", "")), itemStack));
|
||||
PacketManager.sendPacket(
|
||||
other,
|
||||
PacketManager.getEquipmentPacket(
|
||||
final List<com.github.retrooper.packetevents.protocol.player.Equipment> itemList = new ArrayList<>();
|
||||
itemList.add(new com.github.retrooper.packetevents.protocol.player.Equipment(
|
||||
PacketManager.fromBukkitSlot(slot), SpigotDataHelper.fromBukkitItemStack(itemStack)
|
||||
));
|
||||
PacketManager.sendEquipmentPacket(
|
||||
itemList,
|
||||
user.getEntityId()
|
||||
)
|
||||
user.getEntityId(),
|
||||
other
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package io.github.fisher2911.hmccosmetics.user;
|
||||
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import io.github.fisher2911.hmccosmetics.HMCCosmetics;
|
||||
import io.github.fisher2911.hmccosmetics.config.WardrobeSettings;
|
||||
import io.github.fisher2911.hmccosmetics.gui.ArmorItem;
|
||||
@@ -16,7 +15,6 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
@@ -89,28 +87,18 @@ public class Wardrobe extends User {
|
||||
return;
|
||||
}
|
||||
|
||||
final PacketContainer playerSpawnPacket = PacketManager.getFakePlayerSpawnPacket(
|
||||
this.currentLocation,
|
||||
this.getId(),
|
||||
this.getEntityId()
|
||||
);
|
||||
final PacketContainer playerInfoPacket = PacketManager.getFakePlayerInfoPacket(
|
||||
viewer,
|
||||
this.getId()
|
||||
);
|
||||
|
||||
|
||||
Bukkit.getScheduler().runTaskLaterAsynchronously(
|
||||
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());
|
||||
PacketManager.sendPacket(
|
||||
viewer,
|
||||
PacketManager.getLookPacket(this.getEntityId(), this.currentLocation),
|
||||
PacketManager.getRotationPacket(this.getEntityId(), this.currentLocation),
|
||||
PacketManager.getPlayerOverlayPacket(this.getEntityId())
|
||||
);
|
||||
PacketManager.sendLookPacket(entityId, this.currentLocation, viewer);
|
||||
PacketManager.sendRotationPacket(entityId, this.currentLocation, true, viewer);
|
||||
PacketManager.sendPlayerOverlayPacket(entityId, viewer);
|
||||
},
|
||||
settings.getSpawnDelay()
|
||||
);
|
||||
@@ -125,13 +113,9 @@ public class Wardrobe extends User {
|
||||
Bukkit.getScheduler().runTaskLaterAsynchronously(
|
||||
this.plugin,
|
||||
() -> {
|
||||
PacketManager.sendPacket(
|
||||
viewer,
|
||||
PacketManager.getEntityDestroyPacket(this.getEntityId()),
|
||||
PacketManager.getRemovePlayerPacket(viewer, this.id, this.getEntityId())
|
||||
// for spectator packets
|
||||
// PacketManager.getEntityDestroyPacket(this.viewerId)
|
||||
);
|
||||
final int entityId = this.getEntityId();
|
||||
PacketManager.sendEntityDestroyPacket(entityId, viewer);
|
||||
PacketManager.sendRemovePlayerPacket(viewer, this.id, viewer);
|
||||
this.despawnAttached();
|
||||
this.despawnBalloon();
|
||||
this.showPlayer(this.plugin.getUserManager());
|
||||
@@ -170,19 +154,17 @@ public class Wardrobe extends User {
|
||||
private void startSpinTask(final Player player) {
|
||||
final AtomicInteger data = new AtomicInteger();
|
||||
final int rotationSpeed = this.plugin.getSettings().getWardrobeSettings().getRotationSpeed();
|
||||
final int entityId = this.getEntityId();
|
||||
final Task task = new SupplierTask(
|
||||
() -> {
|
||||
if (this.currentLocation == null) return;
|
||||
final Location location = this.currentLocation.clone();
|
||||
final int yaw = data.get();
|
||||
location.setYaw(yaw);
|
||||
PacketManager.sendPacket(player, PacketManager.getLookPacket(this.getEntityId(), location));
|
||||
PacketManager.sendLookPacket(entityId, location, player);
|
||||
this.updateOutsideCosmetics(player, location, this.plugin.getSettings());
|
||||
location.setYaw(this.getNextYaw(yaw - 30, rotationSpeed));
|
||||
PacketManager.sendPacket(
|
||||
player,
|
||||
PacketManager.getRotationPacket(this.getEntityId(), location)
|
||||
);
|
||||
PacketManager.sendRotationPacket(entityId, location, true, player);
|
||||
data.set(this.getNextYaw(yaw, rotationSpeed));
|
||||
},
|
||||
() -> !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://oss.sonatype.org/content/repositories/snapshots")
|
||||
maven("https://jitpack.io")
|
||||
maven("https://repo.dmulloy2.net/repository/public/")
|
||||
// maven("https://repo.dmulloy2.net/repository/public/")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
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("com.comphenix.protocol:ProtocolLib:4.7.0")
|
||||
// compileOnly("com.comphenix.protocol:ProtocolLib:4.7.0")
|
||||
}
|
||||
|
||||
@@ -1,19 +1,13 @@
|
||||
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 {
|
||||
|
||||
PacketContainer getPlayerSpawnPacket(final Location location, UUID uuid, final int entityId);
|
||||
PacketContainer getPlayerInfoPacket(final Player player, final UUID uuid);
|
||||
PacketContainer getPlayerRemovePacket(final Player player, final UUID uuid, final int entityId);
|
||||
PacketContainer getPlayerOverlayPacket(final int entityId);
|
||||
PacketContainer getDestroyPacket(final int entityId);
|
||||
PacketContainer getArmorStandMeta(final int armorStandId);
|
||||
// PacketContainer getPlayerSpawnPacket(final Location location, UUID uuid, final int entityId);
|
||||
// PacketContainer getPlayerInfoPacket(final Player player, final UUID uuid);
|
||||
// PacketContainer getPlayerRemovePacket(final Player player, final UUID uuid, final int entityId);
|
||||
// PacketContainer getPlayerOverlayPacket(final int entityId);
|
||||
// PacketContainer getDestroyPacket(final int entityId);
|
||||
// PacketContainer getArmorStandMeta(final int armorStandId);
|
||||
// PacketContainer getGuiOpenPacket(final Player player);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
rootProject.name = "HMCCosmetics"
|
||||
include(
|
||||
"common",
|
||||
"nms",
|
||||
"1.16",
|
||||
"1.17",
|
||||
"1.18"
|
||||
"common"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user