Plugin für mehrere Spieler tauglich machen.

Dieses Thema im Forum "Programmierung" wurde erstellt von HappyMajor, 26. Mai 2013.

  1. HappyMajor
    Offline

    HappyMajor

    Registriert seit:
    6. Oktober 2012
    Beiträge:
    21
    Hey Leute,
    ich bin gerade dabei ein Naruto Plugin zu erstellen und habe dabei schon die ersten Jutsus realisiert (kawarimi,Katon,Erdversteck für die, die es interessiert).Und bei dem Kawarimi und Erdversteck treten ein paar Probleme auf, wenn mehrere Spieler es gleichzeitig nutzen.

    Folgendes Problem (Kawarimi) :
    Kawarimi ist ein sehr simples Plugin.Sobald ein Spieler das Jutsu aktiviert, merkt sich das Plugin die Stelle wo der Spieler stand, als er das Jutsu aktiviert hat.Nach 5 Sekunden wird der Spieler an seine ursprüngliche Position teleportiert und dort wo er vorher stand, steht nun ein Baumstamm, also 2 Holzblöcke übereinander.Nach weiteren 5 Sekunden werden die Holzblöcke wieder aus der Welt entfernt.Soweit so gut funktioniert alles.

    Das Problem jetzt wenn es 2 oder mehr Spieler gleichzeitig nutzen : Auch dort funktioniert alles, alles bis auf eine Sache, nämlich das Entfernen der Blöcke zum Schluss.Denn das komische ist, das nur die Blöcke von dem Spieler entfernt werden, der es als letztes nutzte.
    Ich glaub auch das Problem zu kennen.Denn um die Blöcke zu erstellen, lokalisiere ich erstmal den gewünschten Ort und erstelle dann mithilfe von den Location´s 2 Block Variablen, womit ich dann die beiden in die Welt setze.Nachdem die Blöcke dann gesetzt wurden, sollen sie ja nach weiteren 5 Sekunden verschwinden und genau um sie verschwinden zu lassen, benutze ich einfach die gleichen Block Variablen um sie zu setzen und remove sie einfach anstatt sie zu setzen.

    Das genaue Problem ist, das beide Spieler diese Block Variablen nutzen.Das heißt wenn jemand das Jutsu aktiviert -> werden seine Location´s für den späteren Baumstamm in die 2 Block Variablen gespeichert.Wenn jetzt jedoch noch ein 2ter das Jutsu nutzt - > werden die Block Variablen mit seinen Location´s überschrieben, dadurch werden auch nur seine Blöcke gelöscht, da man ja auch die 2 Block Variablen zum Löschen benutzt.

    Habt ihr da eine Lösung?
    Schon mal danke im voraus.

    EDIT: Und habt ihr vll Tipps um solche Fehler zu vermeiden? Also die Plugins Massen tauglicher zu machen?
     
    #1
  2. Mojo Blaster
    Offline

    Mojo Blaster

    Ich bin mir nicht ganz sicher, ob ich dein Problem verstanden habe, aber wenn du schon weisst, dass es an den Variablen liegt, mach doch einfach noch 2 neue Variablen. Moment, das ist Quark. Du bräuchtest doch für jeden Nutzer, der die Funktion im Moment benutz eine neue Variable, dann hättest du das Problem gelöst. Sprich bei jedem Aufruf wird eine neue Variable erstellt.

    Ich denke nicht, dass das in irgendeiner Form hilfreich für dich ist, aber ich habe mein bestes gegeben :D

    Mfg
    Mojo_Blaster
     
    #2
  3. Chrisliebaer
    Offline

    Chrisliebaer

    Das Zauberwork lautet vermutlich WeakHashMap. Funktioniert im Endeffekt wie eine normale HashMap, mit dem unterschied, dass der Eintrag automatisch gelöscht wird, wenn der Key (in deinem Fall das Spieler Objekt) gelöscht wird. Somit hast du keine Probleme mit Speicherlöchern.

    Ggf. solltest du villeicht noch Google verwenden, denn die WeakHashMap kann man auch gut falsch verwenden und da du noch nicht so erfahren scheinst, möchtest du dich lieber vorher nochmal informieren.
     
    #3
  4. HappyMajor
    Offline

    HappyMajor

    Registriert seit:
    6. Oktober 2012
    Beiträge:
    21
    Mh.. ich weiß irgendwie nicht wie eine HashMap mein Problem lösen soll.
    Ich weiß echt nicht wie ich das anstellen soll.

    Hier erklär ich mal mein Problem anhand von Code :
    Code (Text):
    1.                 Bukkit.getScheduler().scheduleSyncDelayedTask(this.plugin,new Runnable()           
    2.                 {
    3.                     @Override
    4.                     public void run()
    5.                     {
    6.  
    7.                         final Location loc115 = p.getLocation();
    8.                        
    9.                         blocky = loc115.getBlock().getRelative(BlockFace.UP);
    10.                         blocky2 = loc115.getBlock();
    11.                        
    12.                         blocky2.setTypeId(17);
    13.                         blocky.setTypeId(17);
    14.                         p.teleport(loc);
    15.                     }
    16.                    
    17.                 }, 100L);
    18.                 p.sendMessage(ChatColor.GRAY + "Das Jutsu wirkt in 5 Sekunden");
    19.                 this.cooldowns.put(p.getName(), time);
    20.                 Bukkit.getScheduler().scheduleSyncDelayedTask(this.plugin,new Runnable()
    21.                 {
    22.                     public void run()
    23.                     {
    24.                         blocky.setTypeId(0);
    25.                         blocky2.setTypeId(0);
    26.                         p.sendMessage(ChatColor.RED + "Blöcke wurden entfernt");
    27.                     }
    28.                 }, 200L);
    29.                 }
    30.  
    Ich muss irgendwie "blocky" und "blocky2" für den benutzenden Spieler spezialisieren.Denn das Problem ist, das ich die Blöcke in Variablen blocky und blocky2 speicher, doch wenn dann ein anderer Spieler das gleiche tut, werden seine Daten in blocky und blocky2 gespeichert. Somit werden seine Blöcke auch nur gelöscht (blocky.setTypeId(0);,blocky2.setTypeId(0);).
     
    #4
  5. Muchacho LP
    Offline

    Muchacho LP

    Registriert seit:
    12. März 2013
    Beiträge:
    378
    Ort:
    ALT + F4
    Minecraft:
    ikrumi
    Aber für jeden Player einzeln?!
     
    #5
  6. Benni1000
    Offline

    Benni1000 Ehem. Teammitglied

    Registriert seit:
    4. Mai 2012
    Beiträge:
    1.408
    Du kannst den Namen des Spielers und beide Blöcke in einer weakHashmap, einer hashmap oder einer ArrayList speichern.
    D.h in Platz 1 speicherst du den namen des Spielers und in platz 2 ein array das beide blöcke enthält.
    Dann kannst du einfach die map nach dem Spielernamen durchsuchen und dann die entsprechenden blöcke entfernen.
    Oder du erstellst ein Objekt das 2 Blöcke und den Spielernamen halten kann und machst daraus eine ArrayList, wobei
    das bei 2 Blöcken relativ unnötig wäre.

    Ich möchte hier jetzt absichtlich keinen Code posten, da die Lösung wirklich nicht schwer ist, und du
    dann wirklich verstehst was du da machst, wenn du es selber Programmierst.
    Wenn du nicht weist wie man hashmaps benutzt kannst du dir auch die Dokumentation durchlesen:
    http://docs.oracle.com/javase/1.5.0/docs/api/java/util/HashMap.html
    Oder hier auf Deutsch: http://openbook.galileodesign.de/javainsel5/javainsel11_005.htm

    Für mich hört es sich aber so an als ob du grundlegende Probleme mit Java hast, so einen "fehler" zu beheben sollte
    für jeden einigermaßen guten Programmierer eine Sache von 5 minuten sein. Meine Empfehlung ist das du dir erstmal ein
    Java Buch zulegst bevor du anfängst Bukkit-plugins zu programmieren.
     
    #6
  7. Chrisliebaer
    Offline

    Chrisliebaer

    Ich kann Benni da nur beipflichten. Das Problem ist definitiv, dass du nicht richtig Programmieren kann (das hat mit Java nicht einmal etwas zu tun).

    Ein Buch direkt empfehlen kann ich nicht, da ich noch nie eines gelesen habe. Aber "Java ist auch eine Insel" soll gut sein. Es gibt auch eine abgespekte Onlineversion auf der Verlagsseite:
    http://openbook.galileocomputing.de/javainsel/

    Zumindest durchlesen solltest du alles einmal. Auch wenn du vielleicht vieles nicht verstehst, aber es du wirst am Ende trozdem vieles verstehen. Manchmal hilft auch mehrfach lesen. Überspringen könntest du Teile von XML, grafische Oberflächen (sofern es dich nicht interessiert), JDBC und Datenbanken und alles was danach kommt, wobei m.M.n. erst ab dann der Spaß beginnt.

    Und wie Benni auch sagt. Fertiger Code wird dir nicht helfen. Er löst vielleicht dieses Problem, aber weder lernst du dabei etwas neues, noch löst du damit zukünftige Probleme.
     
    #7
  8. HappyMajor
    Offline

    HappyMajor

    Registriert seit:
    6. Oktober 2012
    Beiträge:
    21
    Hey danke für eure Hilfe!
    Ich hab gerade eine WeakHashMap erstellt und ihm den Spielernamen als Key und ein Array mit den 2 Block Objekten als Value zugewiesen.
    (Weiß nicht ob es richtig war)
    Jedoch gab es ein Problem als ich den Array aus der HashMap in der Scheduler Methode holen wollte.
    Da stand, das ich irgendwie eine neue Runnable erstellen muss.

    Ich werde mir dein Link über die HashMap später anschauen, danke!
    Habe jetzt jedoch keine Zeit mehr und konnte deswegen auch nicht sofort herausfinden, warum es in der Scheduler Methode nicht funktioniert.

    Aber ich denke das werde ich dann schon schaffen!
     
    #8
  9. Muchacho LP
    Offline

    Muchacho LP

    Registriert seit:
    12. März 2013
    Beiträge:
    378
    Ort:
    ALT + F4
    Minecraft:
    ikrumi
    Bei scheduler IMMER "run()" verwenden!
     
    #9