Bukkit Kit alle 3 Stunden?

04/12/2014 18:41 .cryptex#1
Hey Community,

ich hätte eine frage bezüglich kits, wie muss
ich das machen? wenn ein ItemStack alle 3 Stunden
nutzbar sein kann? Falls er noch 2 Stunden warten muss, dass es dann
auch im chat steht?
Muss ich das in einer ArrayList machen? wenn ja wie.

Ich danke euch jetzt schon für die Leute, die sich die
Zeit genommen haben.

mfg
04/12/2014 18:59 Floppy012#2
Wenn das Item genutzt wird, dann Trage seinen Namen in eine List ein und starte einen Delayed Scheduler der erst nach 3 Stunden auslösen soll. Dieser nimmt dann den Namen wieder aus der Liste. Dann kannst du noch einen für 2 Stunden starten. Der dann die Nachricht schickt.

Mit freundlichen Grüßen

Floppy012
04/12/2014 20:01 .cryptex#3
phuuu. Also ich schaffe es irgendwie nicht. Kann mir jemand eine kleine Hilfe geben?
04/12/2014 20:04 Floppy012#4
Wo hängt es denn?

Mit freundlichen Grüßen

Floppy012
04/12/2014 20:38 Attila494#5
Benutzt du Essentials Kits?
Wenn ja schreib in der config:

kits:
[kitname]:
delay: 10800 (in Sekunden, sind 3 Stunden)
items:
- [itemid] [anzahl]

Falls man das kit vor den 3 Stunden nutzt, steht dort wieviele Sekunden man noch warten muss.
Hoffe du meintest das damit, habe die Frage jetzt nicht so richtig verstanden.
04/12/2014 20:40 lordsill#6
Wie genau soll es denn sein?
1. Automatisch alle 3 Stunden das ItemStack
2. Erst nach 3h wieder erlauben, dass der Befehl ausgeführt wird, ansonsten eine Nachricht mit der Wartezeit an den Spieler

Die Beispielcodes dienen dafür, wenn du nicht genau weißt, wie du das machen solltest, um dir so nochmal etwas Hilfestellung zu geben

Zu 1.
Einfach ein Scheduler alle 3h laufen lassen, der dann die ItemStacks an die Spieler vergibt
Hier mal ein Beispielcode:

Zu 2.
In einer HashMap Spielername + Timestamp speichern. Dabei kannst du entscheiden, ob du den Timestamp in 3h oder den aktuellen nimmst (siehe System.currentTimeMillis()).
Wenn der Befehl ausgeführt wird, prüfe es, ob die 3h über dem Wert liegen. Wenn ja => Spieler erhält ItemStack. Wenn nicht, Spieler erhält die Nachricht. Aus der Differenz der beiden Werte (Ablauf-Timestamp und aktuellen Timestamp) kannst du dann die Restzeit berechnen, bis der Spieler den Befehl wieder einsetzen kann und ihm diese Zeit senden.
Der Timestamp von System.currentTimeMillis() sind die ms (nicht die Sekunden wie beim unix-Timestamp) seit 01.01.1970
Hier ebenfalls ein Beispielcode:

@Attila494: Ich denke er möchte das gerne selbst programmieren
04/12/2014 22:09 .cryptex#7
The operator + is undefined for the argument type(s) HashMap<Player,Long>, long steht bei mir.
04/12/2014 22:13 lordsill#8
argh sorry, mein fehler:

if((waittime.get(p)+dreiStunden) < System.currentTimeMillis())
04/13/2014 12:12 .cryptex#9
PHP Code:
public boolean onCommand(CommandSender senderCommand cmdString label,
            
String args) {
        
Player p = (Player)sender;
        
        if(
cmd.getName().equalsIgnoreCase("das")) {
        
        if(
waittime.containsKey(p)) {
            
long dreistunden 3L*3600L*1000L;
            if((
waittime.get(p)+dreistunden) < System.currentTimeMillis()) {
                
                
p.sendMessage("Du kannst das Kit erst wieder in §b" waittime "§f Sekunden nutzen.");
                
                return 
true;
                }
    
            }
        

        
ItemStack helm = new ItemStack(Material.IRON_HELMET);
        
helm.addUnsafeEnchantment(Enchantment.PROTECTION_ENVIRONMENTAL1);
        
helm.addUnsafeEnchantment(Enchantment.DURABILITY1);
        
ItemMeta helmm helm.getItemMeta();
        
helmm.setDisplayName("§7Eisen Kit §8| §fHelm");
        
helm.setItemMeta(helmm);
        
        
p.getInventory().setItem(4helm);
        
        
waittime.put(pSystem.currentTimeMillis());
        
        }
        return 
true;
    } 
Hmm klappt bei mir nicht.
04/13/2014 12:17 lordsill#10
1.
Code:
public boolean onCommand(CommandSender sender, Command cmd, String label,
            String args) {
zu:
Code:
public boolean onCommand(CommandSender sender, Command cmd, String label,
            String[] args) {
da args ein Array ist

2.
Code:
p.sendMessage("Du kannst das Kit erst wieder in §b" + waittime + "§f Sekunden nutzen.");
zu
Code:
p.sendMessage("Du kannst das Kit erst wieder in §b" + waittime.get(p) + "§f Sekunden nutzen.");
3. Ist der Befehl registriert? also in der plugin.yml Datei? Bzw. was geht denn sonst genau nicht?
04/13/2014 12:21 .cryptex#11
ohhh fuck xD genau da fehlt []
srry war zu dumm^^


€: Man kanns immer wieder holen.
04/13/2014 12:28 lordsill#12
oh stimmt, die if anweisung ist falsch:
Code:
if((waittime.get(p)+dreiStunden) < System.currentTimeMillis()) {
müsste
Code:
if((waittime.get(p)+dreiStunden) > System.currentTimeMillis()) {
sein

Denn erst wenn der aktuelle Timestamp größer (und nicht kleiner) als der Timestamp+3h ist, soll ja der andere Code ausgeführt werden
04/13/2014 14:42 .cryptex#13
Uff das klappt einfach nicht -.-
04/13/2014 14:45 Floppy012#14
Poste mal den ganzen Code in [code]...[/code] tags.
Kommt ein Fehler in der Konsole?

Und du versuchst direkt am anfang der onCommand Methode den CommandSender zu Player zu casten. Wenn du jetzt z.B. einen Befehl über die Konsole machst, bekommst du einen Fehler.

Code:
Player p = null;
if(sender instanceof Player){
     p = (Player)sender;
}
Das wäre eine Möglichkeit da müsstest du dann aber bei jedem Command abfragen ob Player nicht null ist. Ist ganz nützlich wenn du Befehle hast, die auch von der Konsole ausführbar sein sollen. Wenn du nur befehle hast in denen ein Player benötigt wird kannst du das ganze mit else schreiben und dann eifach return true.
Code:
Player p = null;
if(sender instanceof Player){
     p = (Player)sender;
}else{
sender.sendMessage("Befehle koennen nicht aus der Konsole ausgefuehrt werden"); //Optional
return true;
}
Mit freundlichen Grüßen

Floppy012
04/13/2014 16:50 ComputerBaer#15
Quote:
Originally Posted by Floppy012 View Post
Code:
Player p = null;
if(sender instanceof Player){
Player p = (Player)sender;
}
Dann aber bitte auch so, sonst gibt es nur einen weiteren Fehler.
Code:
Player p = null;
if(sender instanceof Player){
    p = (Player)sender;
}
Edit:
Ich würde die HashMap wher mit <String, Long> aufbauen, weil ich nicht mit Sicherheit sagen kann, dass das Spielobjekt bis zum Ende der drei Stunden existiert bzw. immernoch das selbe ist. (Der String ist der Spielername, alternativ geht da auch die UUID)

Edit 2:
Code:
p.sendMessage("Du kannst das Kit erst wieder in §b" + waittime.get(p) + "§f Sekunden nutzen.");
Stehen da wirklich die Sekunden drin? Ich denke mal das sind eher Millisekunden, oder?
Code:
p.sendMessage("Du kannst das Kit erst wieder in §b" + (waittime.get(p) / 1000) + "§f Sekunden nutzen.");
Edit 3:
Die Zeit in der Nachricht ist ohnehin blödsinn, mit den Sekunden seit 1970 wird wohl keiner etwas anfangen können. Richtig wäre also eher:
Code:
p.sendMessage("Du kannst das Kit erst wieder in §b" + ((waittime.get(p) + dreistunden - System.currentTimeMillis())/ 1000) + "§f Sekunden nutzen.");