• 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!

Spigot Onlinetime wird weiter gezählt, trotz das Spieler offline ist.

CapuzDE

Redstoneengineer
Osterei Experte
Mitglied seit
16 Juni 2018
Beiträge
39
Minecraft
CapuzDE
Hey,

Ich habe einen Onlinetime CMD-/Event programmiert.
Allerdings wird die Onlinetime auch hoch gesetzt wenn ich Offline bin.

Event:
Java:
    @EventHandler
    public void onJoin(PlayerJoinEvent e) {
        Player p = e.getPlayer();
        
        Bukkit.getScheduler().scheduleSyncRepeatingTask(Main.getPlugin(), new Runnable() {
            
            @Override
            public void run() {
                
                if(p != null) {
                    if(je.contains(p)) {
                
                int m = CFG.cfg.getInt(p.getUniqueId() + ".Onlinezeit" + ".minutes");
                int h = CFG.cfg.getInt(p.getUniqueId() + ".Onlinezeit" + ".hours");
                
                m++;
                CFG.cfg.set(p.getUniqueId() + ".Onlinezeit" + ".minutes", m);
                Main.getPlugin().saveConfig();
                
                if(m == 60) {
                    h++;
                    CFG.cfg.set(p.getUniqueId() + ".Onlinezeit" + ".minutes", 0);
                    CFG.cfg.set(p.getUniqueId() + ".Onlinezeit" + ".hours", h);
                    Main.getPlugin().saveConfig();
                }
                    } else {
                        je.add(p);
                    }
                }
            }
        }, 0, 20*60);
        
    }
CMD:
Java:
public class CMD_Onlinetime implements CommandExecutor {

    @SuppressWarnings("unused")
    @Override
    public boolean onCommand(CommandSender cs, Command arg1, String arg2, String[] args) {
        Player p = (Player) cs;
        
        if(args.length == 0) {
            int m = CFG.cfg.getInt(p.getUniqueId() + ".Onlinezeit" + ".minutes");
            int h = CFG.cfg.getInt(p.getUniqueId() + ".Onlinezeit" + ".hours");
            
            p.sendMessage(Main.prefix + "Du spielst seit §c" + h + "h " + m + "m §7auf diesem Server.");
            
        } else if(args.length == 1) {
            Player t = Bukkit.getPlayer(args[0]);
            int m = CFG.cfg.getInt(t.getUniqueId() + ".Onlinezeit" + ".minutes");
            int h = CFG.cfg.getInt(t.getUniqueId() + ".Onlinezeit" + ".hours");
            
            if(t != null) {
                p.sendMessage(Main.prefix + t.getName() + " spielt seit §c" + h + "h " + m + "m §7auf diesem Server.");
                
            } else {
                p.sendMessage(Main.prefix + "Dieser Spieler ist nicht Online.");
            }
            
        } else {
            p.sendMessage(Main.us + "/playtime <Spieler>");
        }
        
        return false;
    }

}
 

BloodSKreaper

Miner
Osterei Experte
Mitglied seit
12 Oktober 2014
Beiträge
174
Minecraft
BloodSKreaper
Guten Abend,

dein Hauptproblem dürfte sein, dass du mit einem repeating Task arbeitest, der niemals abgebrochen wird:
Bukkit.getScheduler().scheduleSyncRepeatingTask(Main.getPlugin(), new Runnable() { @Override public void run() { if(p != null) { if(je.contains(p)) { int m = CFG.cfg.getInt(p.getUniqueId() + ".Onlinezeit" + ".minutes"); int h = CFG.cfg.getInt(p.getUniqueId() + ".Onlinezeit" + ".hours"); m++; CFG.cfg.set(p.getUniqueId() + ".Onlinezeit" + ".minutes", m); Main.getPlugin().saveConfig(); if(m == 60) { h++; CFG.cfg.set(p.getUniqueId() + ".Onlinezeit" + ".minutes", 0); CFG.cfg.set(p.getUniqueId() + ".Onlinezeit" + ".hours", h); Main.getPlugin().saveConfig(); } } else { je.add(p); } } } }, 0, 20*60);
Das heißt das zählt immer weiter und weiter und weiter und ...
Außerdem heißt das, dass jedes mal wenn der Spieler joint ein neuer Task gestartet wird -> die Zeit kann somit mehrmals pro Sekunde hochgezählt werden.

Das führt leider dazu, dass du dir einen anderen Algorithmus zur Lösung des Problems ausdenken musst.

Freundliche Grüße
BloodSKreaper
 

ES-Henne

Redstoneengineer
Mitglied seit
3 Oktober 2017
Beiträge
41
Ich habe es so gelöst, dass beim joinen der Timestamp gespeichert wird und beim disconnecten dieser mit dem aktuellen Timestamp gegengerechnet wird. Um die aktuelle Spielzeit zu erhalten, wird ebenfalls der aktuelle Timestamp mit dem join Timestamp gegengerechnet.

Die Differenz beträgt die gespielte Zeit und wird mit der vorherigen Spielzeit addiert und gespeichert.
 

JOO200

Vorarbeiter
Osterei Experte
Mitglied seit
18 Dezember 2016
Beiträge
234
Sowas? Und wenn du dann noch regelmäßig was mit einem Task machen möchtest, kannst du in dem Task über die Map iterieren und jedesmal die Zeit checken.
Java:
public class TestClass implements Listener {
    private Map<UUID, Timestamp> activePlayer = new HashMap<>();
    
    @EventHandler(priority=EventPriority.MONITOR, ignoreCanceled=true)
    private void onLogin(PlayerLoginEvent event) {
        // Speichern. (Irgendwie so, Zeit heraus finden geht wahrscheinlich nicht genau so)
        activePlayer.put(event.getPlayer().getUniqueId(), System.currentTimeInMillis());
    }
    
    @EventHandler
    private void onLogout(PlayerLogoutEvent event) {
        Timestamp start = activePlayer.get(event.getPlayer().getUniqueId());
        long diff = System.currentTimeInMillis() - start.getTime();
        // TODO speichern.
        activePlayer.remove(event.getPlayer().getUniqueId());
    }
}
 

_dortom_

Minecrafter
Mitglied seit
1 November 2014
Beiträge
16
Minecraft
_dortom_
Ich habe das ganze mal überflogen..

Also du startest den Runnable wenn der Spieler joint. Was aber für mich auch heißt, wenn 1 Spieler joint --> 1 Runnable, 2 Spieler --> 2 Runnable usw... das ist Mist. Außerdem müsstest du dann wenn der Spieler offline geht im Leave Event den Runnable stoppen. Ansonsten zählt er weiter.
Ich hoffe das stimmt so :D.

Meine Lösung:
Wenn der Server startet einen Runnable erstellen der alle Onlinespieler abfragt und die Spielzeit hochzählt...

so hier sollte das gehen:

Java:
        Bukkit.getScheduler().scheduleAsyncRepeatingTask(Main.main, new Runnable() {

            @Override
            public void run() {

                for (Player p : Bukkit.getOnlinePlayers()) {

//Verweis auf das File in der die Spielzeiten stehen
                    int stunden = Main.main.player_season_cfg.getInt(p.getUniqueId().toString() + ".stunden");
                    int minuten = Main.main.player_season_cfg.getInt(p.getUniqueId().toString() + ".minuten");

                    minuten++;

//Abspeichern der neuen Minutenanzahl
                    Main.main.player_season_cfg.set(p.getUniqueId().toString() + ".minuten", minuten);

//dann natürlich das File wieder speichern
                    try {
                        Main.main.player_season_cfg.save(Main.main.player_season_file);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

//und hier dieses Umschalten von 60 Minuten auf +1 Stunde und Minuen 00
                    if (minuten == 60) {

                        Main.main.player_season_cfg.set(p.getUniqueId().toString() + ".minuten", 0);
                        stunden++;
                        Main.main.player_season_cfg.set(p.getUniqueId().toString() + ".stunden", stunden);
                        try {
                            Main.main.player_season_cfg.save(Main.main.player_season_file);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }, 20 * 1, 20 * 60);

Ich hoffe ich konnte helfen :D

LG _dortom_
 
Allgemein
Hilfe Benutzer
    HardSoul HardSoul: Guten Morgen Milchstraße
    Oben