在Bukkit/Java上取消预定的中继器

ujv3wf0j  于 2022-12-02  发布在  Java
关注(0)|答案(1)|浏览(118)

我正在编写一个插件,记录整个游戏中玩家在Minecraft中的坐标,用Java和Bukkit API编写。
我在下面的bukkit/java代码中使用了**“重复任务”结构。
然而,我需要
“取消”这个重复的任务时,特定的球员注销,否则,如果球员'A'登录和注销50次,在一行,我将有50个运行的任务。
这个想法是当且仅当
玩家'A'注销(而不是B)时,停止玩家'A'的runnable。
我说下面的代码只会在特定玩家注销时取消该特定玩家的重复任务,对吗?
我会非常感激你的帮助!

@EventHandler
    public void onLogin(final PlayerJoinEvent event) {
        final Player thePlayer = event.getPlayer();
        this.stopRepeater = true;
        final Location playerSpawnLocation = thePlayer.getLocation();
        getLogger().info(String.valueOf(thePlayer.getName()) + " is logging in!");
        getLogger().info("Welcome " + thePlayer.getName() + ". Your current position is: " + playerSpawnLocation);
        int taskID = Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask(this, () -> {
            if(this.stopRepeater) {
                this.logToFile(thePlayer, thePlayer.getLocation());
            }
        }, 0L, 20L);}
    
    @EventHandler
    public void onQuit(final PlayerQuitEvent event) {
        Player thePlayer = event.getPlayer(); 
        if(!thePlayer.isOnline()) {
            this.stopRepeater = false;  
            Bukkit.getScheduler().cancelTask(taskID); 
            getLogger().info(String.valueOf(event.getPlayer().getName()) + " has left the game");
        }
    }
igetnqfo

igetnqfo1#

你的代码实际上只对一个玩家有效。你应该为每个玩家保存一个Map任务对象。
我建议你使用runTaskTimer来拥有一个BukkitTask,然后这样使用:

HashMap<UUID, BukkitTask> tasks = new HashMap<>()

玩家登录时:

BukkitTask task = getServer().getScheduler().runTaskTimer(this, () -> doThing(), 0, 20);
tasks.put(player.getUniqueId(), task); // add in map

最后,当玩家离开时:

BukkitTask task = tasks.remove(player.getUniqueId()); // remove from map if exist
if(task != null) { // task found
   task.cancel();
}

相关问题