• Es freut uns dass du in unser Minecraft Forum gefunden hast. Hier kannst du mit über 130.000 Minecraft Fans über Minecraft diskutieren, Fragen stellen und anderen helfen. In diesem Minecraft Forum kannst du auch nach Teammitgliedern, Administratoren, Moderatoren , Supporter oder Sponsoren suchen. Gerne kannst du im Offtopic Bereich unseres Minecraft Forums auch über nicht Minecraft spezifische Themen reden. Wir hoffen dir gefällt es in unserem Minecraft Forum!

Bukkit Scheduler Zeit verlängern

Y

yoshicrafter

Guest
Hallo,
hab hier nen Combat Log Plugin, welches Leute, die sich beim Kampf ausloggen, das die dann automatisch sterben.
Code:
package de.geheim.pvp;

import java.util.ArrayList;

import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
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.player.PlayerQuitEvent;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;

public class PvP extends JavaPlugin implements Listener {
    public static PluginManager pm = Bukkit.getPluginManager();
    public static ArrayList<Player> combat = new ArrayList<Player>();
    public static boolean pvpon = true;
   
    @Override
    public void onEnable() {
        pm.registerEvents(this, this);
        getLogger().info("§9[§aYoshi§9]§r Das Plugin YoshiPvP wurde erfolgreich aktiviert");
    }
   
    @Override
    public void onDisable() {
        getLogger().info("§9[§aYoshi§9]§r Das Plugin YoshiPvP wurde erfolgreich deaktiviert");
    }
   
    @Override
    public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
       
        if(cmd.getName().equalsIgnoreCase("pvp")) {
            if(sender.hasPermission("yoshicrafter.pvp.toggle")) {
                if(pvpon) {
                    pvpon = false;
                    sender.sendMessage("§9[§aYoshi§9] §1PvP §2§cAus");
                } else {
                    pvpon = true;
                    sender.sendMessage("§9[§aYoshi§9] §1PvP §2§aEin");
                }
            } else {
                sender.sendMessage("§9[§aYoshi§9] §4Du hast keine Berechtigung dafür");
            }
        }
       
        return false;
    }
   
    @EventHandler
    public void onAttack(EntityDamageByEntityEvent e) {
        if(e.getDamager() instanceof Player && e.getEntity() instanceof Player) {
            if(pvpon) {
                combat.add((Player) e.getDamager());
                combat.add((Player) e.getEntity());
                Bukkit.getScheduler().runTaskLater(this, new Runnable() {
                   
                    @Override
                    public void run() {
                        // TODO Auto-generated method stub
                        combat.remove((Player) e.getDamager());
                        combat.remove((Player) e.getEntity());
                        e.getEntity().sendMessage("§9[§aYoshi§9]§r §2Du befindest dich nun nicht mehr im Kampf");
                        e.getDamager().sendMessage("§9[§aYoshi§9]§r §2Du befindest dich nun nicht mehr im Kampf");
                    }
                   
                }, 10*20);
                e.getEntity().sendMessage("§9[§aYoshi§9]§r §cDu befindest dich nun im Kampf. Logge dich nicht aus");
                e.getDamager().sendMessage("§9[§aYoshi§9]§r §cDu befindest dich nun im Kampf. Logge dich nicht aus");
            } else {
                e.setCancelled(true);
            }
        }
    }
   
    @EventHandler
    public void onLeave(PlayerQuitEvent e) {
        if(isPvP(e.getPlayer())) {
            e.getPlayer().setHealth(0);
        }
    }
   
    public boolean isPvP(Player player) {
        if(combat.contains(player)) {
            return true;
        } else {
            return false;
        }
    }

}
Wenn 2 Leute miteinander kämpfen, dann kommen sie in eine Liste und nach 10 sek werden sie von Scheduler wieder entfernt.
aber ich will, das wenn sie sich zum 2. mal angreifen, das die zeit dann wieder auf 10 sekunden zurückgesetzt wird vom task
wie geht das?
 

UnityGaming

Workaholic
Registriert
25 Oktober 2015
Beiträge
527
Alter
26
Diamanten
312
Minecraft
FastFelix771
Schaue dir mal den CacheBuilder von Guava an.
Allerdings bitte [UUID -|- UUID] speichern und nicht die Player Objekte.
Den Cache stellst du auf die gewünschte Lebenszeit und checkst bloß noch beim Logout ob der Player im Cache ist und killst ihn dann, wenn das der Fall ist.

Um die Zeit zurückzusetzen packst du die Spieler einfach wieder in den Cache.

Das mit den Nachrichten wird komplizierter, da der Guava Cache nicht über einen Thread, sondern über get/put Aufrufe die Zeitstempel prüft und die Einträge dann ggf. entfernt.
Die Einträge werden also nicht sofort entfernt, sondern sind bloß nicht mehr verfügbar ab diesem Zeitpunkt.

cache2k hat dieses Feature - nennt sich Point-In-Time oder auch Sharp Expiry.
 

Chrisliebär❤️

nur echt mit ❤️
Moderator
Registriert
19 Mai 2014
Beiträge
1.675
Diamanten
830
Wie wärs einfach mit einem Task, der in jedem Tick ausgeführt wird und jeweils die Bedingungen prüft? Das ist ein einziger Vergleich, der da notwendig wird und im Attack Event setzt du die Zeit bis zum Ende neu. Deutlich effektiver, braucht keine externen Libraries und ist total simpel zu implementieren. Die Alternative dazu wäre, dass du den Task einfach cancelst, wenn die Spieler sich angreifen und einen neuen Task startest.

Und noch viel einfach wäre wenn du einfach für jeden Spieler den letzten Zeitpunkt speicherst, an dem er eine feindliche Handlung durchgeführt hat und beim Logout einfach prüfst, ob seit diesem Zeitpunkt mehr als 10 Sekunden vergangen sind. Das braucht nämlich gar keinen Timer und gar keine periodischen Tasks und ist zudem auch entkoppelt von "Person A vs. Person B". So ist es übrigens in so ziemlich jedem Anti-Logout System implementiert. Das sind insgesamt 3 Zeilen Code.

Versteh nicht wirklich was ihr da mit Guava wollt.
 
Y

yoshicrafter

Guest
Wie wärs einfach mit einem Task, der in jedem Tick ausgeführt wird und jeweils die Bedingungen prüft? Das ist ein einziger Vergleich, der da notwendig wird und im Attack Event setzt du die Zeit bis zum Ende neu. Deutlich effektiver, braucht keine externen Libraries und ist total simpel zu implementieren. Die Alternative dazu wäre, dass du den Task einfach cancelst, wenn die Spieler sich angreifen und einen neuen Task startest.

Und noch viel einfach wäre wenn du einfach für jeden Spieler den letzten Zeitpunkt speicherst, an dem er eine feindliche Handlung durchgeführt hat und beim Logout einfach prüfst, ob seit diesem Zeitpunkt mehr als 10 Sekunden vergangen sind. Das braucht nämlich gar keinen Timer und gar keine periodischen Tasks und ist zudem auch entkoppelt von "Person A vs. Person B". So ist es übrigens in so ziemlich jedem Anti-Logout System implementiert. Das sind insgesamt 3 Zeilen Code.

Versteh nicht wirklich was ihr da mit Guava wollt.
DAS ist genau die lösung für mich, vielen dank
 

UnityGaming

Workaholic
Registriert
25 Oktober 2015
Beiträge
527
Alter
26
Diamanten
312
Minecraft
FastFelix771
Versteh nicht wirklich was ihr da mit Guava wollt.
Not my idea. :D
Aber mit aufspringen kann man ja mal^^

@yoshicrafter Den Zeitstempel fürs PvP könnte man sogar prima als Player Metadata speichern.
Dann brauchst du das nicht extra irgendwo festhalten und hast über den Spieler direkt den Wert bei der Hand.

Finde ich persönlich praktischer, als jeden Tick irgendwas abzufragen oder andauernd neue Tasks zu registrieren.
Viel zu aufwändig.
 
Oben