9
0
mirror of https://github.com/HibiscusMC/HMCCosmetics.git synced 2025-12-20 15:39:16 +00:00

Added wardrobe (Need to fix imports)

This commit is contained in:
HeroBrineGoat
2022-02-02 16:12:28 -05:00
parent 1ba07b87cf
commit a07eec4ddc
23 changed files with 533 additions and 32 deletions

36
.idea/codeStyles/Project.xml generated Normal file
View File

@@ -0,0 +1,36 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<option name="FORMATTER_TAGS_ENABLED" value="true" />
<JavaCodeStyleSettings>
<option name="GENERATE_FINAL_LOCALS" value="true" />
<option name="GENERATE_FINAL_PARAMETERS" value="true" />
<option name="REPLACE_NULL_CHECK" value="false" />
<option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999999999" />
<option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999999" />
</JavaCodeStyleSettings>
<JetCodeStyleSettings>
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</JetCodeStyleSettings>
<codeStyleSettings language="JAVA">
<arrangement>
<groups>
<group>
<type>GETTERS_AND_SETTERS</type>
<order>KEEP</order>
</group>
<group>
<type>OVERRIDDEN_METHODS</type>
<order>KEEP</order>
</group>
<group>
<type>DEPENDENT_METHODS</type>
<order>BREADTH_FIRST</order>
</group>
</groups>
</arrangement>
</codeStyleSettings>
<codeStyleSettings language="kotlin">
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</codeStyleSettings>
</code_scheme>
</component>

1
.idea/gradle.xml generated
View File

@@ -12,6 +12,7 @@
<option name="modules"> <option name="modules">
<set> <set>
<option value="$PROJECT_DIR$" /> <option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/common" />
</set> </set>
</option> </option>
</GradleProjectSettings> </GradleProjectSettings>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<module version="4">
<component name="TestModuleProperties" production-module="HMCCosmetics.common.main" />
</module>

View File

@@ -102,5 +102,9 @@ bukkit {
default = BukkitPluginDescription.Permission.Default.OP default = BukkitPluginDescription.Permission.Default.OP
description = "Permission to set other users' cosmetics." description = "Permission to set other users' cosmetics."
} }
register("hmccosmetics.cmd.wardrobe") {
default = BukkitPluginDescription.Permission.Default.OP
description = "Permission to view the wardrobe"
}
} }
} }

View File

@@ -1 +1,2 @@
rootProject.name = "HMCCosmetics" rootProject.name = "HMCCosmetics"
include("common")

View File

@@ -15,12 +15,14 @@ import io.github.fisher2911.hmccosmetics.hook.item.ItemsAdderHook;
import io.github.fisher2911.hmccosmetics.listener.ClickListener; import io.github.fisher2911.hmccosmetics.listener.ClickListener;
import io.github.fisher2911.hmccosmetics.listener.CosmeticFixListener; import io.github.fisher2911.hmccosmetics.listener.CosmeticFixListener;
import io.github.fisher2911.hmccosmetics.listener.JoinListener; import io.github.fisher2911.hmccosmetics.listener.JoinListener;
import io.github.fisher2911.hmccosmetics.listener.PlayerShiftListener;
import io.github.fisher2911.hmccosmetics.listener.RespawnListener; import io.github.fisher2911.hmccosmetics.listener.RespawnListener;
import io.github.fisher2911.hmccosmetics.listener.TeleportListener; import io.github.fisher2911.hmccosmetics.listener.TeleportListener;
import io.github.fisher2911.hmccosmetics.message.MessageHandler; import io.github.fisher2911.hmccosmetics.message.MessageHandler;
import io.github.fisher2911.hmccosmetics.message.Messages; import io.github.fisher2911.hmccosmetics.message.Messages;
import io.github.fisher2911.hmccosmetics.message.Translation; import io.github.fisher2911.hmccosmetics.message.Translation;
import io.github.fisher2911.hmccosmetics.user.UserManager; import io.github.fisher2911.hmccosmetics.user.UserManager;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.sql.SQLException; import java.sql.SQLException;
@@ -28,6 +30,7 @@ import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import me.mattstudios.mf.base.CommandManager; import me.mattstudios.mf.base.CommandManager;
import org.bstats.bukkit.Metrics; import org.bstats.bukkit.Metrics;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@@ -105,7 +108,8 @@ public class HMCCosmetics extends JavaPlugin {
new ClickListener(this), new ClickListener(this),
new TeleportListener(this), new TeleportListener(this),
new RespawnListener(this), new RespawnListener(this),
new CosmeticFixListener(this) new CosmeticFixListener(this),
new PlayerShiftListener(this)
). ).
forEach( forEach(
listener -> this.getServer().getPluginManager() listener -> this.getServer().getPluginManager()

View File

@@ -9,6 +9,7 @@ import io.github.fisher2911.hmccosmetics.message.Messages;
import io.github.fisher2911.hmccosmetics.message.Placeholder; import io.github.fisher2911.hmccosmetics.message.Placeholder;
import io.github.fisher2911.hmccosmetics.user.User; import io.github.fisher2911.hmccosmetics.user.User;
import io.github.fisher2911.hmccosmetics.user.UserManager; import io.github.fisher2911.hmccosmetics.user.UserManager;
import io.github.fisher2911.hmccosmetics.user.Wardrobe;
import io.github.fisher2911.hmccosmetics.util.StringUtils; import io.github.fisher2911.hmccosmetics.util.StringUtils;
import java.util.Map; import java.util.Map;
@@ -191,6 +192,31 @@ public class CosmeticsCommand extends CommandBase {
} }
} }
@SubCommand("wardrobe")
@Permission(io.github.fisher2911.hmccosmetics.message.Permission.VIEW_WARDROBE)
public void openWardrobe(final Player player) {
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;
}
wardrobe.setActive(true);
Bukkit.getScheduler().runTaskAsynchronously(
this.plugin,
() -> wardrobe.spawnFakePlayer(player)
);
this.cosmeticsMenu.openDefault(player);
}
private void setDyeColor(final String dyeColor, final ArmorItem armorItem, final CommandSender sender) { private void setDyeColor(final String dyeColor, final ArmorItem armorItem, final CommandSender sender) {
try { try {
final java.awt.Color awtColor = java.awt.Color.decode(dyeColor); final java.awt.Color awtColor = java.awt.Color.decode(dyeColor);

View File

@@ -11,11 +11,14 @@ import io.github.fisher2911.hmccosmetics.database.dao.UserDAO;
import io.github.fisher2911.hmccosmetics.gui.ArmorItem; import io.github.fisher2911.hmccosmetics.gui.ArmorItem;
import io.github.fisher2911.hmccosmetics.inventory.PlayerArmor; import io.github.fisher2911.hmccosmetics.inventory.PlayerArmor;
import io.github.fisher2911.hmccosmetics.user.User; import io.github.fisher2911.hmccosmetics.user.User;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer; import java.util.function.Consumer;
import io.github.fisher2911.hmccosmetics.user.Wardrobe;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
public class Database { public class Database {
@@ -25,7 +28,7 @@ public class Database {
final Dao<ArmorItemDAO, UUID> armorItemDao; final Dao<ArmorItemDAO, UUID> armorItemDao;
private final ConnectionSource dataSource; private final ConnectionSource dataSource;
private final DatabaseType databaseType; private final DatabaseType databaseType;
AtomicInteger ARMOR_STAND_ID = new AtomicInteger(Integer.MAX_VALUE); AtomicInteger FAKE_ENTITY_ID = new AtomicInteger(Integer.MAX_VALUE);
String TABLE_NAME = "user"; String TABLE_NAME = "user";
String PLAYER_UUID_COLUMN = "uuid"; String PLAYER_UUID_COLUMN = "uuid";
String BACKPACK_COLUMN = "backpack"; String BACKPACK_COLUMN = "backpack";
@@ -67,7 +70,8 @@ public class Database {
} }
public void loadUser(final UUID uuid, final Consumer<User> onComplete) { public void loadUser(final UUID uuid, final Consumer<User> onComplete) {
final int armorStandId = ARMOR_STAND_ID.getAndDecrement(); final int armorStandId = FAKE_ENTITY_ID.getAndDecrement();
final Wardrobe wardrobe = this.newWardrobe();
Threads.getInstance().execute( Threads.getInstance().execute(
() -> { () -> {
try { try {
@@ -80,8 +84,11 @@ public class Database {
final List<ArmorItemDAO> armorItems = this.armorItemDao.queryForEq("uuid", final List<ArmorItemDAO> armorItems = this.armorItemDao.queryForEq("uuid",
uuid.toString()); uuid.toString());
final User actualUser = user.toUser(this.plugin.getCosmeticManager(), final User actualUser = user.toUser(
armorItems, armorStandId); this.plugin.getCosmeticManager(),
armorItems,
wardrobe,
armorStandId);
Bukkit.getScheduler().runTask(this.plugin, Bukkit.getScheduler().runTask(this.plugin,
() -> { () -> {
this.plugin.getUserManager().add( this.plugin.getUserManager().add(
@@ -96,7 +103,7 @@ public class Database {
} }
}); });
final User user = new User(uuid, PlayerArmor.empty(), armorStandId); final User user = new User(uuid, PlayerArmor.empty(), wardrobe, armorStandId);
this.plugin.getUserManager().add(user); this.plugin.getUserManager().add(user);
onComplete.accept(user); onComplete.accept(user);
@@ -149,4 +156,13 @@ public class Database {
return armorItemDao; return armorItemDao;
} }
public Wardrobe newWardrobe() {
return new Wardrobe(
UUID.randomUUID(),
PlayerArmor.empty(),
FAKE_ENTITY_ID.getAndDecrement(),
FAKE_ENTITY_ID.getAndDecrement(),
false
);
}
} }

View File

@@ -4,6 +4,7 @@ import io.github.fisher2911.hmccosmetics.HMCCosmetics;
import io.github.fisher2911.hmccosmetics.gui.ArmorItem; import io.github.fisher2911.hmccosmetics.gui.ArmorItem;
import io.github.fisher2911.hmccosmetics.inventory.PlayerArmor; import io.github.fisher2911.hmccosmetics.inventory.PlayerArmor;
import io.github.fisher2911.hmccosmetics.user.User; import io.github.fisher2911.hmccosmetics.user.User;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Path; import java.nio.file.Path;
@@ -16,6 +17,7 @@ import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer; import java.util.function.Consumer;
import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.file.YamlConfiguration;
public class DatabaseConverter { public class DatabaseConverter {
@@ -85,11 +87,12 @@ public class DatabaseConverter {
while (results.next()) { while (results.next()) {
final PlayerArmor playerArmor = PlayerArmor.empty(); final PlayerArmor playerArmor = PlayerArmor.empty();
final User user = new User final User user = new User(
(UUID.fromString(results.getString(1)), UUID.fromString(results.getString(1)),
playerArmor, playerArmor,
this.database.ARMOR_STAND_ID.getAndDecrement() this.database.newWardrobe(),
); this.database.FAKE_ENTITY_ID.getAndDecrement()
);
final String backpackId = results.getString(2); final String backpackId = results.getString(2);
final String hatId = results.getString(3); final String hatId = results.getString(3);
final int hatDye = results.getInt(4); final int hatDye = results.getInt(4);

View File

@@ -6,6 +6,8 @@ import io.github.fisher2911.hmccosmetics.cosmetic.CosmeticManager;
import io.github.fisher2911.hmccosmetics.gui.ArmorItem; import io.github.fisher2911.hmccosmetics.gui.ArmorItem;
import io.github.fisher2911.hmccosmetics.inventory.PlayerArmor; import io.github.fisher2911.hmccosmetics.inventory.PlayerArmor;
import io.github.fisher2911.hmccosmetics.user.User; import io.github.fisher2911.hmccosmetics.user.User;
import io.github.fisher2911.hmccosmetics.user.Wardrobe;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.UUID; import java.util.UUID;
@@ -27,7 +29,10 @@ public class UserDAO {
this.uuid = uuid; this.uuid = uuid;
} }
public User toUser(final CosmeticManager cosmeticManager, final List<ArmorItemDAO> armorItems, public User toUser(
final CosmeticManager cosmeticManager,
final List<ArmorItemDAO> armorItems,
final Wardrobe wardrobe,
final int armorStandId) { final int armorStandId) {
final PlayerArmor playerArmor = PlayerArmor.empty(); final PlayerArmor playerArmor = PlayerArmor.empty();
@@ -39,7 +44,7 @@ public class UserDAO {
playerArmor.setItem(armorItem); playerArmor.setItem(armorItem);
} }
return new User(this.uuid, playerArmor, armorStandId); return new User(this.uuid, playerArmor, wardrobe, armorStandId);
} }
@Override @Override

View File

@@ -19,8 +19,6 @@ public class ClickListener implements Listener {
private final HMCCosmetics plugin; private final HMCCosmetics plugin;
private final UserManager userManager; private final UserManager userManager;
private final List<Integer> equipmentSlots = List.of(39, 40);
public ClickListener(final HMCCosmetics plugin) { public ClickListener(final HMCCosmetics plugin) {
this.plugin = plugin; this.plugin = plugin;
this.userManager = this.plugin.getUserManager(); this.userManager = this.plugin.getUserManager();

View File

@@ -2,7 +2,9 @@ package io.github.fisher2911.hmccosmetics.listener;
import io.github.fisher2911.hmccosmetics.HMCCosmetics; import io.github.fisher2911.hmccosmetics.HMCCosmetics;
import io.github.fisher2911.hmccosmetics.database.Database; import io.github.fisher2911.hmccosmetics.database.Database;
import io.github.fisher2911.hmccosmetics.user.User;
import io.github.fisher2911.hmccosmetics.user.UserManager; import io.github.fisher2911.hmccosmetics.user.UserManager;
import io.github.fisher2911.hmccosmetics.user.Wardrobe;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
@@ -10,6 +12,8 @@ import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerQuitEvent;
import java.util.Optional;
public class JoinListener implements Listener { public class JoinListener implements Listener {
private final HMCCosmetics plugin; private final HMCCosmetics plugin;
@@ -33,6 +37,17 @@ public class JoinListener implements Listener {
@EventHandler @EventHandler
public void onQuit(final PlayerQuitEvent event) { public void onQuit(final PlayerQuitEvent event) {
final Player player = event.getPlayer(); final Player player = event.getPlayer();
final Optional<User> optionalUser = this.userManager.get(player.getUniqueId());
optionalUser.ifPresent(user -> {
final Wardrobe wardrobe = user.getWardrobe();
if (wardrobe.isActive()) {
Bukkit.getScheduler().runTaskAsynchronously(
this.plugin,
() -> wardrobe.despawnFakePlayer(player)
);
}
});
this.userManager.remove(player.getUniqueId()); this.userManager.remove(player.getUniqueId());
} }

View File

@@ -0,0 +1,43 @@
package io.github.fisher2911.hmccosmetics.listener;
import io.github.fisher2911.hmccosmetics.HMCCosmetics;
import io.github.fisher2911.hmccosmetics.message.Messages;
import io.github.fisher2911.hmccosmetics.user.User;
import io.github.fisher2911.hmccosmetics.user.UserManager;
import io.github.fisher2911.hmccosmetics.user.Wardrobe;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerToggleSneakEvent;
import java.util.Optional;
public class PlayerShiftListener implements Listener {
private final HMCCosmetics plugin;
private final UserManager userManager;
public PlayerShiftListener(final HMCCosmetics plugin) {
this.plugin = plugin;
this.userManager = this.plugin.getUserManager();
}
@EventHandler
public void onPlayerShift(final PlayerToggleSneakEvent event) {
final Player player = event.getPlayer();
final Optional<User> userOptional = this.userManager.get(player.getUniqueId());
if (userOptional.isEmpty()) return;
final User user = userOptional.get();
final Wardrobe wardrobe = user.getWardrobe();
if (!wardrobe.isActive()) return;
wardrobe.setActive(false);
this.plugin.getMessageHandler().sendMessage(
player,
Messages.CLOSED_WARDROBE
);
}
}

View File

@@ -50,6 +50,13 @@ public class Messages {
<st> </st>"""); <st> </st>""");
public static final Message OPENED_WARDROBE =
new Message("opened-wardrobe", ChatColor.GREEN + "Viewing wardrobe!");
public static final Message CLOSED_WARDROBE =
new Message("closed-wardrobe", ChatColor.GREEN + "Closing wardrobe!");
public static final Message WARDROBE_ALREADY_OPEN =
new Message("wardrobe-already-open", ChatColor.RED + "The wardrobe is already open!");
public static final Message SET_OTHER_BACKPACK = new Message( public static final Message SET_OTHER_BACKPACK = new Message(
"set-other-backpack", ChatColor.GREEN + "You have set the backpack of " + "set-other-backpack", ChatColor.GREEN + "You have set the backpack of " +
Placeholder.PLAYER + " to " + Placeholder.TYPE + "." Placeholder.PLAYER + " to " + Placeholder.TYPE + "."

View File

@@ -7,5 +7,6 @@ public class Permission {
public static final String RELOAD_COMMAND = "hmccosmetics.cmd.reload"; public static final String RELOAD_COMMAND = "hmccosmetics.cmd.reload";
public static final String HELP_COMMAND = "hmccosmetics.cmd.help"; public static final String HELP_COMMAND = "hmccosmetics.cmd.help";
public static final String SET_COSMETIC_COMMAND = "hmccosmetics.cmd.set"; public static final String SET_COSMETIC_COMMAND = "hmccosmetics.cmd.set";
public static final String VIEW_WARDROBE = "hmccosmetics.cmd.wardrobe";
} }

View File

@@ -4,21 +4,45 @@ import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.ProtocolManager; import com.comphenix.protocol.ProtocolManager;
import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.reflect.StructureModifier;
import com.comphenix.protocol.wrappers.EnumWrappers; import com.comphenix.protocol.wrappers.EnumWrappers;
import com.comphenix.protocol.wrappers.MinecraftKey; import com.comphenix.protocol.wrappers.MinecraftKey;
import com.comphenix.protocol.wrappers.Pair; import com.comphenix.protocol.wrappers.Pair;
import java.lang.reflect.InvocationTargetException; import com.comphenix.protocol.wrappers.PlayerInfoData;
import java.util.List; import com.comphenix.protocol.wrappers.WrappedChatComponent;
import java.util.UUID; import com.comphenix.protocol.wrappers.WrappedGameProfile;
import com.mojang.authlib.GameProfile;
import io.github.fisher2911.hmccosmetics.playerpackets.PlayerPackets;
import io.github.fisher2911.hmccosmetics.playerpackets.PlayerPackets_1_17_R1;
import io.github.fisher2911.hmccosmetics.playerpackets.PlayerPackets_1_18_R1;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.craftbukkit.libs.it.unimi.dsi.fastutil.ints.IntArrayList; import org.bukkit.craftbukkit.libs.it.unimi.dsi.fastutil.ints.IntArrayList;
import org.bukkit.entity.EntityType; import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class PacketManager { public class PacketManager {
private static final PlayerPackets playerPackets;
static {
final String version = Bukkit.getVersion();
if (version.contains("1.17")) {
playerPackets = new PlayerPackets_1_17_R1();
} /*else if (version.contains("1.18")) {
playerPackets = new PlayerPackets_1_18_R1();
}*/ else {
playerPackets = null;
}
}
public static PacketContainer getEntitySpawnPacket(final Location location, final int entityId, public static PacketContainer getEntitySpawnPacket(final Location location, final int entityId,
final EntityType entityType) { final EntityType entityType) {
final PacketContainer packet = new PacketContainer(PacketType.Play.Server.SPAWN_ENTITY); final PacketContainer packet = new PacketContainer(PacketType.Play.Server.SPAWN_ENTITY);
@@ -91,8 +115,6 @@ public class PacketManager {
final float pitch, final float pitch,
final EnumWrappers.SoundCategory soundCategory final EnumWrappers.SoundCategory soundCategory
) { ) {
// final Location location = player.getLocation();
final var manager = ProtocolLibrary.getProtocolManager(); final var manager = ProtocolLibrary.getProtocolManager();
final var packet = manager.createPacket(PacketType.Play.Server.CUSTOM_SOUND_EFFECT); final var packet = manager.createPacket(PacketType.Play.Server.CUSTOM_SOUND_EFFECT);
@@ -119,6 +141,16 @@ public class PacketManager {
return packet; return packet;
} }
public static PacketContainer[] getFakePlayerPacket(final Location location, Player player, final UUID uuid, final int entityId) throws IllegalStateException {
if (playerPackets == null) throw new IllegalStateException("This cannot be used in version: " + Bukkit.getVersion());
return playerPackets.getSpawnPacket(location, player, uuid, entityId);
}
public static PacketContainer getRemovePlayerPacket(final Player player, final UUID uuid, final int entityId) {
if (playerPackets == null) throw new IllegalStateException("This cannot be used in version: " + Bukkit.getVersion());
return playerPackets.getRemovePacket(player, uuid, entityId);
}
public static void sendPacket(final Player to, final PacketContainer... packets) { public static void sendPacket(final Player to, final PacketContainer... packets) {
final ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager(); final ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager();
try { try {

View File

@@ -0,0 +1,14 @@
package io.github.fisher2911.hmccosmetics.playerpackets;
import com.comphenix.protocol.events.PacketContainer;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import java.util.UUID;
public interface PlayerPackets {
PacketContainer[] getSpawnPacket(final Location location, final Player player, final UUID uuid, final int entityId);
PacketContainer getRemovePacket(final Player player, final UUID uuid, final int entityId);
}

View File

@@ -0,0 +1,87 @@
package io.github.fisher2911.hmccosmetics.playerpackets;
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.WrappedGameProfile;
import com.mojang.authlib.GameProfile;
import org.bukkit.GameMode;
import org.bukkit.Location;
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.Set;
import java.util.UUID;
public class PlayerPackets_1_17_R1 implements PlayerPackets {
public PacketContainer[] getSpawnPacket(final Location location, final Player player, final UUID uuid, final int entityId) {
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<>();
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.ADD_PLAYER);
infoData.write(0, playerInfoData);
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());
return new PacketContainer[]{playerInfoPacket, spawnPacket};
}
public PacketContainer getRemovePacket(final Player player, final UUID uuid, final int entityId) {
final PacketContainer playerPacket = new PacketContainer(PacketType.Play.Server.PLAYER_INFO);
playerPacket.getIntegers().write(0, entityId);
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(profile.getName())));
action.write(0, EnumWrappers.PlayerInfoAction.REMOVE_PLAYER);
infoData.write(0, playerInfoData);
return playerPacket;
}
private GameProfile getCopyProfile(final Player player, final UUID uuid) {
final GameProfile playerProfile = ((CraftPlayer) player).getProfile();
final GameProfile profile = new GameProfile(
uuid,
player.getDisplayName());
for (final var entry : playerProfile.getProperties().entries()) {
profile.getProperties().put(entry.getKey(), entry.getValue());
}
return profile;
}
}

View File

@@ -0,0 +1,87 @@
package io.github.fisher2911.hmccosmetics.playerpackets;
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.WrappedGameProfile;
import com.mojang.authlib.GameProfile;
import org.bukkit.GameMode;
import org.bukkit.Location;
//import org.bukkit.craftbukkit.v1_18_R1.entity.CraftPlayer;
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 PlayerPackets_1_18_R1 implements PlayerPackets {
public PacketContainer[] getSpawnPacket(final Location location, final Player player, final UUID uuid, final int entityId) {
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<>();
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.ADD_PLAYER);
infoData.write(0, playerInfoData);
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());
return new PacketContainer[]{playerInfoPacket, spawnPacket};
}
public PacketContainer getRemovePacket(final Player player, final UUID uuid, final int entityId) {
final PacketContainer playerPacket = new PacketContainer(PacketType.Play.Server.PLAYER_INFO);
playerPacket.getIntegers().write(0, entityId);
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(profile.getName())));
action.write(0, EnumWrappers.PlayerInfoAction.REMOVE_PLAYER);
infoData.write(0, playerInfoData);
return playerPacket;
}
private GameProfile getCopyProfile(final Player player, final UUID uuid) {
final GameProfile playerProfile = ((CraftPlayer) player).getProfile();
final GameProfile profile = new GameProfile(
uuid,
player.getDisplayName());
for (final var entry : playerProfile.getProperties().entries()) {
profile.getProperties().put(entry.getKey(), entry.getValue());
}
return profile;
}
}

View File

@@ -0,0 +1,35 @@
package io.github.fisher2911.hmccosmetics.user;
import org.bukkit.inventory.EntityEquipment;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Nullable;
import java.util.EnumMap;
import java.util.Map;
public class Equipment {
private static final EquipmentSlot[] VALUES = EquipmentSlot.values();
private final Map<EquipmentSlot, ItemStack> equipment = new EnumMap<>(EquipmentSlot.class);
public Equipment() {
}
public static Equipment fromEntityEquipment(final EntityEquipment entityEquipment) {
final Equipment equipment = new Equipment();
for (final EquipmentSlot slot : VALUES) {
equipment.setItem(slot, entityEquipment.getItem(slot));
}
return equipment;
}
@Nullable
public ItemStack getItem(final EquipmentSlot slot) {
return this.equipment.get(slot);
}
public void setItem(final EquipmentSlot slot, @Nullable final ItemStack itemStack) {
this.equipment.put(slot, itemStack);
}
}

View File

@@ -27,12 +27,21 @@ public class User {
private final UUID uuid; private final UUID uuid;
private final PlayerArmor playerArmor; private final PlayerArmor playerArmor;
private Wardrobe wardrobe;
private ArmorItem lastSetItem = ArmorItem.empty(ArmorItem.Type.HAT); private ArmorItem lastSetItem = ArmorItem.empty(ArmorItem.Type.HAT);
private boolean hasArmorStand; private boolean hasArmorStand;
private final int armorStandId; private final int armorStandId;
public User(final UUID uuid, final PlayerArmor playerArmor, final int armorStandId) { public User(final UUID uuid, final PlayerArmor playerArmor, final Wardrobe wardrobe, final int armorStandId) {
this.uuid = uuid;
this.playerArmor = playerArmor;
this.wardrobe = wardrobe;
this.armorStandId = armorStandId;
}
protected User(final UUID uuid, final PlayerArmor playerArmor, final int armorStandId) {
this.uuid = uuid; this.uuid = uuid;
this.playerArmor = playerArmor; this.playerArmor = playerArmor;
this.armorStandId = armorStandId; this.armorStandId = armorStandId;
@@ -50,6 +59,10 @@ public class User {
return playerArmor; return playerArmor;
} }
public Wardrobe getWardrobe() {
return wardrobe;
}
protected void setPlayerArmor(final PlayerArmor playerArmor) { protected void setPlayerArmor(final PlayerArmor playerArmor) {
for (final ArmorItem armorItem : playerArmor.getArmorItems()) { for (final ArmorItem armorItem : playerArmor.getArmorItems()) {
this.playerArmor.setItem(armorItem); this.playerArmor.setItem(armorItem);
@@ -162,4 +175,16 @@ public class User {
public ArmorItem getLastSetItem() { public ArmorItem getLastSetItem() {
return lastSetItem; return lastSetItem;
} }
public int getEntityId() {
final Player player = this.getPlayer();
if (player == null) return -1;
return player.getEntityId();
}
public boolean hasPermissionToUse(final ArmorItem armorItem) {
final Player player = this.getPlayer();
if (player == null) return false;
return player.hasPermission(armorItem.getPermission());
}
} }

View File

@@ -125,8 +125,11 @@ public class UserManager {
public void updateCosmetics(final User user, final boolean ignoreRestrictions, final Player other) { public void updateCosmetics(final User user, final boolean ignoreRestrictions, final Player other) {
final Player player = user.getPlayer(); final Player player = user.getPlayer();
final Equipment equipment;
if (player == null) { if (player == null) {
return; equipment = new Equipment();
} else {
equipment = Equipment.fromEntityEquipment(player.getEquipment());
} }
final PlayerArmor playerArmor = user.getPlayerArmor(); final PlayerArmor playerArmor = user.getPlayerArmor();
@@ -134,28 +137,27 @@ public class UserManager {
final List<Pair<EnumWrappers.ItemSlot, ItemStack>> equipmentList = new ArrayList<>(); final List<Pair<EnumWrappers.ItemSlot, ItemStack>> equipmentList = new ArrayList<>();
equipmentList.add( equipmentList.add(
new Pair<>(EnumWrappers.ItemSlot.HEAD, this.getCosmeticItem(player, playerArmor.getHat(), EquipmentSlot.HEAD, ignoreRestrictions)) new Pair<>(EnumWrappers.ItemSlot.HEAD, this.getCosmeticItem(equipment, playerArmor.getHat(), EquipmentSlot.HEAD, ignoreRestrictions))
); );
equipmentList.add( equipmentList.add(
new Pair<>(EnumWrappers.ItemSlot.OFFHAND, this.getCosmeticItem(player, playerArmor.getOffHand(), EquipmentSlot.OFF_HAND, ignoreRestrictions)) new Pair<>(EnumWrappers.ItemSlot.OFFHAND, this.getCosmeticItem(equipment, playerArmor.getOffHand(), EquipmentSlot.OFF_HAND, ignoreRestrictions))
); );
PacketManager.sendPacket( PacketManager.sendPacket(
other, other,
PacketManager.getEquipmentPacket( PacketManager.getEquipmentPacket(
equipmentList, equipmentList,
player.getEntityId() user.getEntityId()
) )
); );
} }
private ItemStack getCosmeticItem( private ItemStack getCosmeticItem(
final Player player, final Equipment equipment,
final ArmorItem armorItem, final ArmorItem armorItem,
final EquipmentSlot slot, final EquipmentSlot slot,
final boolean ignoreRestrictions) { final boolean ignoreRestrictions) {
final CosmeticSettings cosmeticSettings = this.settings.getCosmeticSettings(); final CosmeticSettings cosmeticSettings = this.settings.getCosmeticSettings();
final EntityEquipment equipment = player.getEquipment();
final Map<String, String> placeholders = Map.of(Placeholder.ALLOWED, "true", final Map<String, String> placeholders = Map.of(Placeholder.ALLOWED, "true",
Placeholder.ENABLED, "true"); Placeholder.ENABLED, "true");
@@ -180,17 +182,24 @@ public class UserManager {
} }
public void setItem(final User user, final ArmorItem armorItem) { public void setItem(final User user, final ArmorItem armorItem) {
ArmorItem previous = user.getPlayerArmor().getItem(armorItem.getType()); final Wardrobe wardrobe = user.getWardrobe();
final User setUser;
if (wardrobe.isActive()) {
setUser = wardrobe;
} else {
setUser = user;
}
ArmorItem previous = setUser.getPlayerArmor().getItem(armorItem.getType());
final CosmeticChangeEvent event = final CosmeticChangeEvent event =
new CosmeticChangeEvent(new CosmeticItem(armorItem.copy()), new CosmeticItem(previous.copy()), user); new CosmeticChangeEvent(new CosmeticItem(armorItem.copy()), new CosmeticItem(previous.copy()), setUser);
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) return; if (event.isCancelled()) return;
user.setItem(event.getCosmeticItem().getArmorItem()); setUser.setItem(event.getCosmeticItem().getArmorItem());
Bukkit.getScheduler().runTaskAsynchronously(this.plugin, () -> { Bukkit.getScheduler().runTaskAsynchronously(this.plugin, () -> {
switch (armorItem.getType()) { switch (armorItem.getType()) {
case HAT, OFF_HAND -> this.updateCosmetics(user); case HAT, OFF_HAND -> this.updateCosmetics(setUser);
} }
}); });
} }

View File

@@ -0,0 +1,48 @@
package io.github.fisher2911.hmccosmetics.user;
import com.mojang.authlib.GameProfile;
import io.github.fisher2911.hmccosmetics.gui.ArmorItem;
import io.github.fisher2911.hmccosmetics.inventory.PlayerArmor;
import io.github.fisher2911.hmccosmetics.packet.PacketManager;
import org.bukkit.craftbukkit.v1_17_R1.entity.CraftPlayer;
import org.bukkit.entity.Player;
import java.util.UUID;
public class Wardrobe extends User {
private final int entityId;
private boolean active;
public Wardrobe(
final UUID uuid,
final PlayerArmor playerArmor,
final int armorStandId,
final int entityId,
final boolean active) {
super(uuid, playerArmor, armorStandId);
this.entityId = entityId;
this.active = active;
}
public void spawnFakePlayer(final Player viewer) {
PacketManager.sendPacket(viewer, PacketManager.getFakePlayerPacket(viewer.getLocation(), viewer, this.getUuid(), this.entityId));
}
public void despawnFakePlayer(final Player viewer) {
PacketManager.sendPacket(viewer, PacketManager.getRemovePlayerPacket(viewer, this.getUuid(), this.entityId));
}
@Override
public boolean hasPermissionToUse(final ArmorItem armorItem) {
return true;
}
public boolean isActive() {
return active;
}
public void setActive(final boolean active) {
this.active = active;
}
}