Вопрос Плагин на /tpa. Нужна помощь!

Версия Minecraft
1.16.X

EgoR_TATARKIN

Пользователь
Сообщения
70
Привет, пишу плагин на /tpa nick и у меня проблема. Я не знаю почему но если я отправил запрос к игроку а он пишет /tpaccept то игрока не начинает телепортировать а пишет что нет запросов.

Java:
package org.infernworld.awtpa.command;

import org.bukkit.*;
import org.bukkit.boss.BarColor;
import org.bukkit.boss.BarStyle;
import org.bukkit.boss.BossBar;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import org.infernworld.awtpa.AWtpa;
import org.infernworld.awtpa.util.Config;
import org.infernworld.awtpa.util.SoundUtil;
import org.jetbrains.annotations.NotNull;

import java.util.*;

public class Commands implements CommandExecutor {
    private final AWtpa plugin;
    private final Config cfg;
    private BossBar bossBar;
    private Map<Player, Player > called = new HashMap<>();

    public Commands(AWtpa plugin) {
        this.plugin = plugin;
        this.cfg = new Config(plugin);

    }
    @Override
    public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
        Player player = (Player) sender;
        if (command.getName().equalsIgnoreCase("tpa")) {
            if (args.length == 1) {
                Player target = Bukkit.getPlayer(args[0]);
                if (target != null) {
                    playerToCall(player, target);
                } else {
                    player.sendMessage("Игрок не найден.");
                }
            } else {
                player.sendMessage("Используйте: /tpa <игрок>");
            }
        } else if (command.getName().equalsIgnoreCase("tpaccept")) {
            playerCall(player);
        }
        return true;
    }

    private void playerToCall(Player player, Player player2) {
        player2.sendMessage(cfg.getMessageCall().replace("%player", player.getName()));
        called.put(player2, player);
        new BukkitRunnable() {
            @Override
            public void run() {
                called.remove(player2);
            }
        }.runTaskLater(plugin,10*20L);
    }
    public void playerCall(Player player) {
        Player sender = called.get(player);
        if (sender == null) {
            player.sendMessage("Запросов на тп нет!");
        }

        player.spawnParticle(Particle.PORTAL, player.getLocation(), 100, 0.5, 1, 0.5, 0.1);
        player.spawnParticle(Particle.SPELL_WITCH, player.getLocation(), 50, 0.5, 1, 0.5, 0.1);
        player.spawnParticle(Particle.CLOUD, player.getLocation(), 30, 0.5, 1, 0.5, 0.1);
        bossBar = Bukkit.createBossBar("Телепортация через " + cfg.getTime(), BarColor.GREEN, BarStyle.SEGMENTED_10);
        bossBar.addPlayer(player);
        cfg.getCall().forEach(player::sendMessage);
        new BukkitRunnable() {
            int time = cfg.getTime();
            @Override
            public void run() {
                if (time > 0) {
                    SoundUtil.playSound(player,cfg.getSoundcalled());
                    player.spawnParticle(Particle.PORTAL, player.getLocation(), 100, 0.5, 1, 0.5, 0.1);
                    bossBar.setTitle(cfg.getBossBar().replace("%time", String.valueOf(time)));
                    bossBar.setProgress((double) time / 5);
                    time--;
                } else {
                    bossBar.removePlayer(player);
                    bossBar.removeAll();
                    cancel();
                }
            }
        }.runTaskTimer(plugin,0L,20L);
        new BukkitRunnable() {
            @Override
            public void run() {
                sender.teleport(player);
                called.remove(sender);
                SoundUtil.playSound(player,cfg.getSoundTp());
            }
        }.runTaskLater(plugin,5*20L);
    }
}
 
Привет, пишу плагин на /tpa nick и у меня проблема. Я не знаю почему но если я отправил запрос к игроку а он пишет /tpaccept то игрока не начинает телепортировать а пишет что нет запросов.

Java:
package org.infernworld.awtpa.command;

import org.bukkit.*;
import org.bukkit.boss.BarColor;
import org.bukkit.boss.BarStyle;
import org.bukkit.boss.BossBar;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import org.infernworld.awtpa.AWtpa;
import org.infernworld.awtpa.util.Config;
import org.infernworld.awtpa.util.SoundUtil;
import org.jetbrains.annotations.NotNull;

import java.util.*;

public class Commands implements CommandExecutor {
    private final AWtpa plugin;
    private final Config cfg;
    private BossBar bossBar;
    private Map<Player, Player > called = new HashMap<>();

    public Commands(AWtpa plugin) {
        this.plugin = plugin;
        this.cfg = new Config(plugin);

    }
    @Override
    public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
        Player player = (Player) sender;
        if (command.getName().equalsIgnoreCase("tpa")) {
            if (args.length == 1) {
                Player target = Bukkit.getPlayer(args[0]);
                if (target != null) {
                    playerToCall(player, target);
                } else {
                    player.sendMessage("Игрок не найден.");
                }
            } else {
                player.sendMessage("Используйте: /tpa <игрок>");
            }
        } else if (command.getName().equalsIgnoreCase("tpaccept")) {
            playerCall(player);
        }
        return true;
    }

    private void playerToCall(Player player, Player player2) {
        player2.sendMessage(cfg.getMessageCall().replace("%player", player.getName()));
        called.put(player2, player);
        new BukkitRunnable() {
            @Override
            public void run() {
                called.remove(player2);
            }
        }.runTaskLater(plugin,10*20L);
    }
    public void playerCall(Player player) {
        Player sender = called.get(player);
        if (sender == null) {
            player.sendMessage("Запросов на тп нет!");
        }

        player.spawnParticle(Particle.PORTAL, player.getLocation(), 100, 0.5, 1, 0.5, 0.1);
        player.spawnParticle(Particle.SPELL_WITCH, player.getLocation(), 50, 0.5, 1, 0.5, 0.1);
        player.spawnParticle(Particle.CLOUD, player.getLocation(), 30, 0.5, 1, 0.5, 0.1);
        bossBar = Bukkit.createBossBar("Телепортация через " + cfg.getTime(), BarColor.GREEN, BarStyle.SEGMENTED_10);
        bossBar.addPlayer(player);
        cfg.getCall().forEach(player::sendMessage);
        new BukkitRunnable() {
            int time = cfg.getTime();
            @Override
            public void run() {
                if (time > 0) {
                    SoundUtil.playSound(player,cfg.getSoundcalled());
                    player.spawnParticle(Particle.PORTAL, player.getLocation(), 100, 0.5, 1, 0.5, 0.1);
                    bossBar.setTitle(cfg.getBossBar().replace("%time", String.valueOf(time)));
                    bossBar.setProgress((double) time / 5);
                    time--;
                } else {
                    bossBar.removePlayer(player);
                    bossBar.removeAll();
                    cancel();
                }
            }
        }.runTaskTimer(plugin,0L,20L);
        new BukkitRunnable() {
            @Override
            public void run() {
                sender.teleport(player);
                called.remove(sender);
                SoundUtil.playSound(player,cfg.getSoundTp());
            }
        }.runTaskLater(plugin,5*20L);
    }
}
Здравствуйте! Для начала, не храните в Map<Player, Player>, ведь это может вызвать мемори лики, что вам совсем не нужно и будет забивать память, если один из игроков в мэп выйдет. Далее я бы не стал всё писать в одном классе, разделите на пакеты (package) или же папки, в них джава классы, с соотвецтвующеми названиями, по типу в папку command засунуть ваш TpaCommand. далее, лучше писать код не
Java:
if (target != null) {
// Ваше действие
}


а лучше:

Java:
if (target == null) return;
// Ваши действия


так код не будет выглядеть как огромная макаронина, а будет в один столбик.

Далее совет для Map, не делайте его просто в одном классе и использование там же, сделайте package с названием tracker а там PlayerCallsTracker, там сделайте вот так:

Java:
  public class PlayerCallTracker {

  private static final PlayerCallTracker instance = new PlayerCallTracker();

  private final Map<UUID, UUID> calls = new HashMap<>();

  public void addCall(UUID senderUUID, UUID receiverUUID) {
    calls.put(senderUUID, receiverUUID);
  }

  public UUID getSender(UUID receiverUUID) {
    return calls.get(receiverUUID);
  }
 
  public void removePlayer(UUID playerUUID) {
    calls.remove(playerUUID);
  }
 
  public static PlayerCallTracker getInstance() {
    return instance;
  }
}

так вы сможете не обращаться напрямую к Map а делать это через безопасные методы. Чтобы сделать какое то действие, нужно писать так: PlayerCallTracker.getInstance().addCall(senderUUID, receiverUUID); - так вы добавите в мапу ваш call


Дальше совет к переменным, по типу вашей Map, она может быть private final Map, ведь вы создаёте один экземпляр вашей мэп, который будет от начала и до конца один, поэтому лучше сделать его final.

Что до вашей проблемы, из за такого написаного кода (не в обиду), сложно немного разобраться, но если честно, не очень понимаю почему просиходит данная проблема.

И что важно, советую к прочтению статьи на темы:
* паттернов в java: (В особенности: Builder, Singleton, Factory, AbstractFactory и Adapter. Остальные важны, но на ваше усмотрение)
* принципы SOLID: (Это чуть позже)
* в целом о чистом коде стоит почитать

Надеюсь я вам чем то помог. Хотя это больше для вашего будущего развития
 
Последнее редактирование:
Здравствуйте! Для начала, не храните в Map<Player, Player>, ведь это может вызвать мемори лики, что вам совсем не нужно и будет забивать память, если один из игроков в мэп выйдет. Далее я бы не стал всё писать в одном классе, разделите на пакеты (package) или же папки, в них джава классы, с соотвецтвующеми названиями, по типу в папку command засунуть ваш TpaCommand. далее, лучше писать код не
Java:
if (target != null) {
// Ваше действие
}


а лучше:

Java:
if (target == null) return;
// Ваши действия


так код не будет выглядеть как огромная макаронина, а будет в один столбик.

Далее совет для Map, не делайте его просто в одном классе и использование там же, сделайте package с названием tracker а там PlayerCallsTracker, там сделайте вот так:

Java:
  public class PlayerCallTracker {

  private static final PlayerCallTracker instance = new PlayerCallTracker();

  private final Map<UUID, UUID> calls = new HashMap<>();

  public void addCall(UUID senderUUID, UUID receiverUUID) {
    calls.put(senderUUID, receiverUUID);
  }

  public UUID getSender(UUID receiverUUID) {
    return calls.get(receiverUUID);
  }
 
  public void removePlayer(UUID playerUUID) {
    calls.remove(playerUUID);
  }
 
  public static PlayerCallTracker getInstance() {
    return instance;
  }
}

так вы сможете не обращаться напрямую к Map а делать это через безопасные методы. Чтобы сделать какое то действие, нужно писать так: PlayerCallTracker.getInstance().addCall(senderUUID, receiverUUID); - так вы добавите в мапу ваш call


Дальше совет к переменным, по типу вашей Map, она может быть private final Map, ведь вы создаёте один экземпляр вашей мэп, который будет от начала и до конца один, поэтому лучше сделать его final.

Что до вашей проблемы, из за такого написаного кода (не в обиду), сложно немного разобраться, но если честно, не очень понимаю почему просиходит данная проблема.

И что важно, советую к прочтению статьи на темы:
* паттернов в java: (В особенности: Builder, Singleton, Factory, AbstractFactory и Adapter. Остальные важны, но на ваше усмотрение)
* принципы SOLID: (Это чуть позже)
* в целом о чистом коде стоит почитать

Надеюсь я вам чем то помог. Хотя это больше для вашего будущего развития
Очень благодарен вам, спасибо большое ❤️
 
Назад
Сверху Снизу