GoldenSunsetMine
Пользователь
- Сообщения
- 121
- Решения
- 2
Помогите, я уже задолбался это решать. Мне нужно сделать такую систему:
Когда игрок смотрит на сундук, то ему отображается голограмма через armorstand, а когда он отворачивается от сундука, голограмма перестает отображаться.
Сейчас такая проблема, что если на сундук смотрят 2 игрока, то если 1 из них отвернется и посмотрит заново, то у другого игрока поставится ещё 1 armorstand и то есть голограмма будет заполняться так каждый раз.
И да, потом я разделю все методы на классы, не обращайте внимания что всё в Main.
Когда игрок смотрит на сундук, то ему отображается голограмма через armorstand, а когда он отворачивается от сундука, голограмма перестает отображаться.
Сейчас такая проблема, что если на сундук смотрят 2 игрока, то если 1 из них отвернется и посмотрит заново, то у другого игрока поставится ещё 1 armorstand и то есть голограмма будет заполняться так каждый раз.
И да, потом я разделю все методы на классы, не обращайте внимания что всё в Main.
Java:
package com.bodya.skypvp;
import com.bodya.skypvp.Commands.xCommand;
import com.bodya.skypvp.Listener.*;
import com.bodya.skypvp.Managers.ItemManager;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.ProtocolManager;
import com.comphenix.protocol.events.PacketContainer;
import net.milkbowl.vault.economy.Economy;
import org.bukkit.*;
import org.bukkit.block.*;
import org.bukkit.command.*;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.*;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.inventory.*;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.util.io.BukkitObjectInputStream;
import org.bukkit.util.io.BukkitObjectOutputStream;
import java.io.*;
import java.util.*;
public class Main extends JavaPlugin implements Listener, CommandExecutor {
private HashMap<Player, Block> playerLookBlock = new HashMap<>();
private HashMap<Block, List<ArmorStand>> activeArmorStands = new HashMap<>();
private static Economy economy = null;
private File shopFile;
private FileConfiguration shopConfig;
private static Main instance;
public static Main plugin;
@Override
public void onEnable() {
plugin = this;
instance = this;
this.saveDefaultConfig();
ItemManager.init();
getServer().getPluginManager().registerEvents(new PlayerDeath(), this);
getServer().getPluginManager().registerEvents(new SignSetup(this), this);
getServer().getPluginManager().registerEvents(new LaunchTNT(this), this);
getServer().getPluginManager().registerEvents(new JumpModule(this), this);
getServer().getPluginManager().registerEvents(new GoldenCarrot(this), this);
this.getCommand("skypvpx").setExecutor(new xCommand(this));
SignSetup.setupAllSigns(this);
getServer().getPluginManager().registerEvents(this, this);
createShopFile();
if (!setupEconomy()) {
getLogger().warning("Плагин Vault не обнаружен! Пожалуйста, установите Vault для корректной работы магазинов.");
} else {
getLogger().info("Плагин Vault успешно инициализирован!");
}
}
@Override
public void onDisable() {
playerLookBlock.clear();
}
@EventHandler
public void onPlayerMove(PlayerMoveEvent event) {
Player player = event.getPlayer();
Block currentBlock = player.getTargetBlock(null, 5);
Block previousBlock = playerLookBlock.get(player);
if (previousBlock == null || !currentBlock.equals(previousBlock)) {
if (previousBlock != null) {
removeArmorStand(player, previousBlock);
playerLookBlock.remove(player);
}
if (currentBlock.getType() == Material.CHEST) {
Location loc = currentBlock.getLocation();
String locString = loc.getWorld().getName() + ","
+ loc.getBlockX() + "," + loc.getBlockY() + "," + loc.getBlockZ();
if (shopConfig.contains(locString)) {
createArmorStand(player, currentBlock, locString);
playerLookBlock.put(player, currentBlock);
}
}
}
}
private void createArmorStand(Player player, Block block, String locString) {
String action = shopConfig.getString(locString + ".action");
int price = shopConfig.getInt(locString + ".price");
ItemStack item = deserializeItemStack(shopConfig.getString(locString + ".item"));
String itemName = (item.getItemMeta() != null && item.getItemMeta().hasDisplayName()) ? item.getItemMeta().getDisplayName() : ChatColor.YELLOW + item.getI18NDisplayName();
Location spawnLocation = block.getLocation().clone().add(0.5, -0.50, 0.5);
ArmorStand armorStand = (ArmorStand) block.getWorld().spawnEntity(spawnLocation, EntityType.ARMOR_STAND);
armorStand.setCustomNameVisible(true);
armorStand.setGravity(false);
armorStand.setVisible(false);
armorStand.setCustomName(ChatColor.translateAlternateColorCodes('&', itemName + " &fx" + item.getAmount()));
armorStand.setMetadata("shopArmorStand", new FixedMetadataValue(this, true));
broadcastArmorStand(block, armorStand);
ArmorStand armorStand2 = (ArmorStand) block.getWorld().spawnEntity(spawnLocation.clone().add(0, -0.25, 0), EntityType.ARMOR_STAND);
armorStand2.setCustomNameVisible(true);
armorStand2.setGravity(false);
armorStand2.setVisible(false);
armorStand2.setCustomName(ChatColor.translateAlternateColorCodes('&', (action.equalsIgnoreCase("sell") ? "&aПродать: $" + price : "&6Цена: $" + price)));
armorStand2.setMetadata("shopArmorStand", new FixedMetadataValue(this, true));
broadcastArmorStand(block, armorStand2);
}
private void broadcastArmorStand(Block targetBlock, ArmorStand armorStand) {
ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager();
PacketContainer spawnPacket = protocolManager.createPacket(PacketType.Play.Server.SPAWN_ENTITY);
spawnPacket.getIntegers()
.write(0, armorStand.getEntityId())
.write(1, (int) EntityType.ARMOR_STAND.getTypeId());
spawnPacket.getDoubles()
.write(0, armorStand.getLocation().getX())
.write(1, armorStand.getLocation().getY())
.write(2, armorStand.getLocation().getZ());
spawnPacket.getUUIDs()
.write(0, armorStand.getUniqueId());
PacketContainer destroyPacket = protocolManager.createPacket(PacketType.Play.Server.ENTITY_DESTROY);
destroyPacket.getIntegerArrays().write(0, new int[] { armorStand.getEntityId() });
for (Player p : Bukkit.getOnlinePlayers()) {
if (p.getWorld().equals(armorStand.getWorld()) && p.getLocation().distance(armorStand.getLocation()) < 50) {
Block playerTargetBlock = p.getTargetBlock(null, 5);
if (playerTargetBlock.equals(targetBlock)) {
try {
protocolManager.sendServerPacket(p, spawnPacket);
} catch (Exception e) {
e.printStackTrace();
}
} else {
try {
protocolManager.sendServerPacket(p, destroyPacket);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
private void removeArmorStand(Player player, Block block) {
List<Entity> entities = new ArrayList<>(block.getWorld().getNearbyEntities(block.getLocation().add(0.5, 0.5, 0.5), 0.5, 1.0, 0.5));
ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager();
for (Entity entity : entities) {
if (entity instanceof ArmorStand && entity.hasMetadata("shopArmorStand")) {
ArmorStand armorStand = (ArmorStand) entity;
Block playerTargetBlock = player.getTargetBlock(null, 5);
if (!playerTargetBlock.equals(block)) {
PacketContainer destroyPacket = protocolManager.createPacket(PacketType.Play.Server.ENTITY_DESTROY);
destroyPacket.getIntegerArrays().write(0, new int[] { armorStand.getEntityId() });
try {
protocolManager.sendServerPacket(player, destroyPacket);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
private void createShopFile() {
shopFile = new File(getDataFolder() + "/data", "shops.yml");
if (!shopFile.exists()) {
shopFile.getParentFile().mkdirs();
try {
shopFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
shopConfig = YamlConfiguration.loadConfiguration(shopFile);
}
private String serializeItemStack(ItemStack itemStack) {
if (itemStack == null || itemStack.getType() == Material.AIR) {
return "";
}
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
DataOutputStream dataOutput = new DataOutputStream(outputStream);
try {
BukkitObjectOutputStream bukkitOutput = new BukkitObjectOutputStream(dataOutput);
bukkitOutput.writeObject(itemStack);
bukkitOutput.close();
} catch (IOException e) {
e.printStackTrace();
}
return Base64.getEncoder().encodeToString(outputStream.toByteArray());
}
private ItemStack deserializeItemStack(String data) {
if (data == null || data.isEmpty()) {
return new ItemStack(Material.AIR);
}
ByteArrayInputStream inputStream = new ByteArrayInputStream(Base64.getDecoder().decode(data));
DataInputStream dataInput = new DataInputStream(inputStream);
try {
BukkitObjectInputStream bukkitInput = new BukkitObjectInputStream(dataInput);
ItemStack itemStack = (ItemStack) bukkitInput.readObject();
bukkitInput.close();
return itemStack;
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
return new ItemStack(Material.AIR);
}
@EventHandler
public void onBlockBreak(BlockBreakEvent event) {
Block block = event.getBlock();
if (block.getType() == Material.CHEST) {
Chest chest = (Chest) block.getState();
Location loc = chest.getLocation();
String locString = Objects.requireNonNull(loc.getWorld()).getName() + ","
+ loc.getBlockX() + "," + loc.getBlockY() + "," + loc.getBlockZ();
if (shopConfig.contains(locString)) {
shopConfig.set(locString, null);
try {
shopConfig.save(shopFile);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) {
Player player = event.getPlayer();
if (event.getAction() == Action.RIGHT_CLICK_BLOCK) {
Block clickedBlock = event.getClickedBlock();
if (clickedBlock != null && clickedBlock.getType() == Material.CHEST) {
Chest chest = (Chest) clickedBlock.getState();
Location loc = chest.getLocation();
String locString = loc.getWorld().getName() + ","
+ loc.getBlockX() + "," + loc.getBlockY() + "," + loc.getBlockZ();
if (shopConfig.contains(locString)) {
event.setCancelled(true);
String action = shopConfig.getString(locString + ".action");
int price = shopConfig.getInt(locString + ".price");
ItemStack itemShop = deserializeItemStack(shopConfig.getString(locString + ".item"));
if (action.equalsIgnoreCase("buy")) {
if (player.getInventory().firstEmpty() != -1) {
if (economy.getBalance(player) >= price) {
economy.withdrawPlayer(player, price);
player.getInventory().addItem(itemShop);
String displayName = (itemShop.hasItemMeta() && itemShop.getItemMeta().hasDisplayName()) ? itemShop.getItemMeta().getDisplayName() : itemShop.getType().toString();
player.sendMessage(ChatColor.translateAlternateColorCodes('&', "&6Вы купили &r" + displayName + " x" + itemShop.getAmount() + " &6за " + price + "$"));
} else {
player.sendMessage(ChatColor.RED + "У Вас недостаточно денег.");
}
} else {
player.sendMessage(ChatColor.RED + "Ваш инвентарь полон.");
}
} else if (action.equalsIgnoreCase("sell")) {
ItemStack itemStack = null;
for (ItemStack stack : player.getInventory().getContents()) {
if (stack != null && stack.isSimilar(itemShop)) {
itemStack = stack;
break;
}
}
if (itemStack != null && itemStack.getAmount() >= itemShop.getAmount()) {
ItemMeta itemMeta = itemShop.getItemMeta();
String displayName = (itemMeta == null || itemMeta.getDisplayName() == null) ? itemShop.getI18NDisplayName() : itemMeta.getDisplayName();
economy.depositPlayer(player, price);
itemStack.setAmount(itemStack.getAmount() - itemShop.getAmount());
player.sendMessage(ChatColor.translateAlternateColorCodes('&', "&6Вы продали &r" + displayName + " x" + itemShop.getAmount() + " &6за " + price + "$"));
} else {
player.sendMessage(ChatColor.RED + "Вашего товара недостаточно.");
}
}
}
}
}
}
private boolean setupEconomy()
{
RegisteredServiceProvider<Economy> economyProvider = getServer().getServicesManager().getRegistration(net.milkbowl.vault.economy.Economy.class);
if (economyProvider != null) {
economy = economyProvider.getProvider();
}
return (economy != null);
}
public static Main getInstance() {
return instance;
}
public static Economy getEconomy() {
return economy;
}
}