GoldenSunsetMine
Пользователь
- Сообщения
- 121
- Решения
- 2
Не обращайте внимания на то, что сейчас всё находится в классе Main.
Проблема следующая: если игрок Player1 смотрит на сундук, и ему тем самым отображаются голограммы, то при входе на сервер или респауне(из далекого от сундука места) игрока Player2 ему будут видны те же armorstand'ы, что и Player1. Нужно это исправить, чтобы каждый игрок видел только свои armorstand'ы, независимо от других игроков.
Если вам не трудно, допишите код который нужно дописать за меня, я уже несколько дней пытаюсь это исправить и устал.
Проблема следующая: если игрок Player1 смотрит на сундук, и ему тем самым отображаются голограммы, то при входе на сервер или респауне(из далекого от сундука места) игрока Player2 ему будут видны те же armorstand'ы, что и Player1. Нужно это исправить, чтобы каждый игрок видел только свои armorstand'ы, независимо от других игроков.
Если вам не трудно, допишите код который нужно дописать за меня, я уже несколько дней пытаюсь это исправить и устал.
Java:
package com.bodya.skypvp;
import com.bodya.skypvp.Commands.xCommand;
import com.bodya.skypvp.Jumps.JumpCommand;
import com.bodya.skypvp.Jumps.JumpManager;
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.entity.ItemDespawnEvent;
import org.bukkit.event.player.*;
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 Map<Player, List<ArmorStand>> playerArmorStands = 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);
getServer().getPluginManager().registerEvents(new JumpManager(this), this);
this.getCommand("skypvpx").setExecutor(new xCommand(this));
this.getCommand("skyshop").setExecutor(this);
this.getCommand("skyjump").setExecutor(new JumpCommand(this));
SignSetup.setupAllSigns(this);
getServer().getPluginManager().registerEvents(this, this);
createShopFile();
if (!setupEconomy()) {
getLogger().warning("Плагин Vault не обнаружен! Пожалуйста, установите Vault для корректной работы магазинов.");
} else {
getLogger().info("Плагин Vault успешно инициализирован!");
}
}
@Override
public void onDisable() {
for (Player player : Bukkit.getOnlinePlayers()) {
removeAllArmorStands(player);
}
playerArmorStands.clear();
playerLookBlock.clear();
Bukkit.getScheduler().cancelTasks(this);
}
@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)) {
removeArmorStandsForPlayer(player);
playerLookBlock.put(player, currentBlock);
if (currentBlock.getType() == Material.CHEST || currentBlock.getType() == Material.TRAPPED_CHEST) {
Location loc = currentBlock.getLocation();
String locString = loc.getWorld().getName() + ","
+ loc.getBlockX() + "," + loc.getBlockY() + "," + loc.getBlockZ();
if (shopConfig.contains(locString)) {
createArmorStand(player, currentBlock, locString);
}
}
}
}
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (sender instanceof Player) {
Player player = (Player) sender;
Block block = player.getTargetBlock(null, 5);
if (block == null || (block.getType() != Material.CHEST && block.getType() != Material.TRAPPED_CHEST)) {
player.sendMessage(ChatColor.RED + "Ошибка! Вы должны смотреть на сундук.");
return true;
}
if (args.length != 2) {
player.sendMessage(ChatColor.RED + "Держите предмет с нужным количеством в руке и пропишите команду: " + ChatColor.WHITE + "/skypvpx <sell/buy> <цена>");
return true;
}
String action = args[0];
int price;
try {
price = Integer.parseInt(args[1]);
} catch (NumberFormatException e) {
player.sendMessage(ChatColor.RED + "Ошибка! Ваша цена не является допустимой.");
return true;
}
ItemStack item = player.getInventory().getItemInMainHand();
Location loc = block.getLocation();
String locString = loc.getWorld().getName() + ","
+ loc.getBlockX() + "," + loc.getBlockY() + "," + loc.getBlockZ();
shopConfig.set(locString + ".item", serializeItemStack(item));
shopConfig.set(locString + ".action", action);
shopConfig.set(locString + ".price", price);
try {
shopConfig.save(shopFile);
} catch (IOException e) {
e.printStackTrace();
}
String displayName = (item.hasItemMeta() && item.getItemMeta().hasDisplayName()) ? item.getItemMeta().getDisplayName() : item.getType().toString();
player.sendMessage(ChatColor.translateAlternateColorCodes('&', "&6SkyPvP: &eМагазин успешно создан. Предмет: &r" + displayName + " x" + item.getAmount() + "&e, Действие: &f" + action + "&e, Цена: &f" + price + "$"));
}
return true;
}
private boolean isShopLocation(Location itemLocation) {
for (String key : shopConfig.getKeys(false)) {
String[] locData = key.split(",");
if (locData.length == 4) {
String worldName = locData[0];
int x = Integer.parseInt(locData[1]);
int y = Integer.parseInt(locData[2]);
int z = Integer.parseInt(locData[3]);
Location shopLocation = new Location(Bukkit.getWorld(worldName), x, y, z);
Block shopBlock = shopLocation.getBlock();
if ((shopBlock.getType() == Material.CHEST || shopBlock.getType() == Material.TRAPPED_CHEST) &&
shopBlock.getLocation().equals(itemLocation.getBlock().getLocation())) {
return true;
}
}
}
return false;
}
@EventHandler
public void onPickupItem(PlayerPickupItemEvent event) {
Item item = event.getItem();
Location itemLocation = item.getLocation();
if (isShopLocation(itemLocation)) {
event.setCancelled(true);
}
}
@EventHandler
public void onItemDespawn(ItemDespawnEvent event) {
Item item = event.getEntity();
Location itemLocation = item.getLocation();
if (isShopLocation(itemLocation)) {
event.setCancelled(true);
}
}
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));
playerArmorStands.computeIfAbsent(player, k -> new ArrayList<>()).add(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));
playerArmorStands.computeIfAbsent(player, k -> new ArrayList<>()).add(armorStand2);
broadcastArmorStand(player, block, armorStand);
broadcastArmorStand(player, block, armorStand2);
}
private void removeArmorStandsForPlayer(Player player) {
List<ArmorStand> armorStands = playerArmorStands.get(player);
if (armorStands != null) {
for (ArmorStand armorStand : armorStands) {
armorStand.remove();
}
playerArmorStands.remove(player);
}
}
private void removeAllArmorStands(Player player) {
List<ArmorStand> armorStands = playerArmorStands.get(player);
if (armorStands != null) {
for (ArmorStand armorStand : armorStands) {
armorStand.remove();
}
playerArmorStands.remove(player);
}
}
private void broadcastArmorStand(Player player, 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());
try {
protocolManager.sendServerPacket(player, spawnPacket);
} catch (Exception e) {
e.printStackTrace();
}
PacketContainer destroyPacket = protocolManager.createPacket(PacketType.Play.Server.ENTITY_DESTROY);
destroyPacket.getIntegerArrays().write(0, new int[]{armorStand.getEntityId()});
for (Player p : Bukkit.getOnlinePlayers()) {
if (p.equals(player)) {
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 || block.getType() == Material.TRAPPED_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 || clickedBlock.getType() == Material.TRAPPED_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;
}
}