Java HashMap值为true时未取消任务
我目前正在学习计划任务 基本上,我正在制作一个Bukkit插件,您可以在其中启用或禁用PVP。 当玩家键入/pvp on或/pvp off时,他们在5秒内不得移动,但是,任务取消似乎没有执行 主要类别:Java HashMap值为true时未取消任务,java,bukkit,Java,Bukkit,我目前正在学习计划任务 基本上,我正在制作一个Bukkit插件,您可以在其中启用或禁用PVP。 当玩家键入/pvp on或/pvp off时,他们在5秒内不得移动,但是,任务取消似乎没有执行 主要类别: package me.mortadelle2.pvptoggle; import java.util.ArrayList; import java.util.HashMap; import org.bukkit.Bukkit; import org.bukkit.ChatColor; imp
package me.mortadelle2.pvptoggle;
import java.util.ArrayList;
import java.util.HashMap;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.util.Vector;
public class PVPToggle extends JavaPlugin {
ArrayList<String> noPVP = new ArrayList<String>();
HashMap<String, Boolean> hasMoved = new HashMap<String, Boolean>();
Player p;
public void onEnable() {
new PlayerDamage(this);
getLogger().info("PVPToggle toggled!");
}
public void onDisable() {
getLogger().info("PVPToggle disabled!");
}
public boolean onCommand(CommandSender sender, Command cmd, String label,
String[] args) {
p = (Player) sender;
if (cmd.getName().equalsIgnoreCase("pvp")) {
if (args.length == 0) {
p.sendMessage(ChatColor.RED + "Invalid usage! /pvp [on or off]");
return true;
}
if (args.length == 1) {
if (args[0].equalsIgnoreCase("on")) {
p.sendMessage(ChatColor.YELLOW
+ "PVP will be turned on in 5 seconds! Don't move!");
hasMoved.remove(p.getName());
hasMoved.put(p.getName(), false);
int turnOn = this.getServer().getScheduler()
.scheduleSyncDelayedTask(this, new Runnable() {
@Override
public void run() {
if (hasMoved.get(p.getName()) == false) {
noPVP.remove(p.getName());
p.sendMessage(ChatColor.YELLOW
+ "You have turned PVP on!");
}
}
}, 100L);
if (hasMoved.get(p.getName()) == true) {
p.sendMessage(ChatColor.RED
+ "You moved so the action was cancelled.");
this.getServer().getScheduler().cancelTask(turnOn);
}
return true;
}
if (args[0].equalsIgnoreCase("off")) {
p.sendMessage(ChatColor.YELLOW
+ "PVP will be turned off in 5 seconds. Don't move!");
hasMoved.remove(p.getName());
hasMoved.put(p.getName(), false);
int turnOff = this.getServer().getScheduler()
.scheduleSyncDelayedTask(this, new Runnable() {
@Override
public void run() {
if (hasMoved.get(p.getName()) == false) {
noPVP.add(p.getName());
p.sendMessage(ChatColor.YELLOW
+ "You have turned PVP off!");
}
}
}, 100L);
if (hasMoved.get(p.getName()) == true) {
p.sendMessage(ChatColor.RED
+ "You moved so the action was cancelled.");
this.getServer().getScheduler().cancelTask(turnOff);
}
return true;
}
}
}
return false;
}
}
没有必要取消任务,因为它已经结束了。我发现您的代码也存在一些问题。首先,也可能是最严重的一点是,您在PlayerMoveEvent中安排了一项任务,不仅如此,这也是不必要的。在使用该事件时,应始终非常小心。每当玩家移动任何东西,包括他们的头部时,它都会被调用。因此,这个事件每秒可以被称为数百次或数千次。如果不是绝对必要,您应该始终进行检查,确保播放器移动到一个新块,以减少代码的运行次数。一个简单得多的方法就是这样做:
@EventHandler
public void playerMoves(PlayerMoveEvent e) {
Player p = e.getPlayer();
//Check if the player moved to a new block
if (e.getTo().getBlockX() != e.getFrom().getBlockX() || e.getTo().getBlockY() != e.getFrom().getBlockY() || e.getTo().getBlockZ() != e.getFrom().getBlockZ()) {
//If they have, set their value in the hashmap to true
getter.hasMoved.put(p.getName(), true);
}
}
还要知道,只有当滴答声过去时,调度程序才会被调用一次,而程序的其余部分将继续。您可以检查播放机是否已在调度程序中移动
Bukkit.getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
@Override
public void run() {
if (hasMoved.get(p.getName()) == false) {
noPVP.remove(p.getName());
p.sendMessage(ChatColor.YELLOW + "You have turned PVP on!");
} else {
p.sendMessage(ChatColor.RED + "You moved so the action was cancelled.");
}
}
}, 100L);
还有一个提示:您不需要每次更改播放机的值时都将其从HashMap中删除。HashMap.put()将覆盖现有值
编辑(另一项建议):
这可能是最好的方法,如果您希望在播放器移动时立即将取消消息发送给播放器,您可以从playerMoves
方法中取消调度程序,而不是将播放器添加到HashMap中。这样,HashMap就不再需要了,它只会提高总体代码质量。你真的应该尽量避免使用HashMaps,通常有更好的方法
Bukkit.getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
@Override
public void run() {
if (hasMoved.get(p.getName()) == false) {
noPVP.remove(p.getName());
p.sendMessage(ChatColor.YELLOW + "You have turned PVP on!");
} else {
p.sendMessage(ChatColor.RED + "You moved so the action was cancelled.");
}
}
}, 100L);