gpt4 book ai didi

java - 当 HashMap 值为 true 时任务不会被取消

转载 作者:行者123 更新时间:2023-12-02 04:25:11 25 4
gpt4 key购买 nike

我目前正在学习计划任务。

基本上,我正在制作一个 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;
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;
}

}

监听器类:

    package me.mortadelle2.pvptoggle;

import org.bukkit.Bukkit;
import org.bukkit.entity.Arrow;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityShootBowEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.util.Vector;

public class PlayerDamage implements Listener{

PVPToggle getter;

public PlayerDamage(PVPToggle plugin) {

plugin.getServer().getPluginManager().registerEvents(this, plugin);

this.getter = plugin;

}

@EventHandler
public void playerJoins(PlayerJoinEvent e){

Player p = e.getPlayer();
getter.hasMoved.put(p.getName(), false);

}

@EventHandler
public void playerDamages(EntityDamageByEntityEvent e){

Player victim = (Player) e.getEntity();
Player killer = (Player) e.getDamager();

victim.sendMessage("hey");

if (getter.noPVP.contains(victim.getName()) || getter.noPVP.contains(killer.getName())){
e.setCancelled(true);
}

}

@EventHandler
public void playerShootsPlayer(EntityShootBowEvent e){

Arrow a = (Arrow) e.getEntity();

Player shooter = (Player) a.getShooter();

if (getter.noPVP.contains(a.getName()) || getter.noPVP.contains(shooter.getName())){
e.setCancelled(true);
}



}

@EventHandler
public void playerMoves(PlayerMoveEvent e) {

final Player p = e.getPlayer();

final Vector pVel = p.getVelocity();

getter.getServer().getScheduler()
.scheduleSyncDelayedTask(getter, new Runnable() {

@Override
public void run() {


if (pVel.getX() != 0 || pVel.getBlockY() != 0
|| pVel.getBlockZ() != 0) {
getter.hasMoved.remove(p.getName());
getter.hasMoved.put(p.getName(), true);
} else {
getter.hasMoved.remove(p.getName());
getter.hasMoved.put(p.getName(), false);
}

}
}, 5L);

}

}

最佳答案

没有必要取消任务,因为它已经结束了。我还发现您的代码存在一些问题。第一个也可能是最严重的问题是您在 PlayerMoveEvent 中安排任务,不仅如此,而且也是不必要的。使用该事件时您应该始终非常小心。每当玩家移动任何东西(包括他们的头部)时都会调用它。因此,该事件每秒可以调用数百次或数千次。如果不是绝对必要,您应该始终进行检查,以确保玩家移动到新 block 以减少代码运行的次数。一个更简单的方法就是做这样的事情:

@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,它只会提高整体代码质量。您确实应该尽可能避免使用 HashMap,通常有更好的方法。

关于java - 当 HashMap 值为 true 时任务不会被取消,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32273491/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com