Spieler Teleportieren, der Quasi Offline ist

Dieses Thema im Forum "Programmierung" wurde erstellt von Crafter6432, 23. September 2013.

  1. Crafter6432
    Offline

    Crafter6432

    Registriert seit:
    22. Dezember 2011
    Beiträge:
    686
    Hallo,

    In meinem Plugin starte ich im PlayerQuitEvent einen Thread, der die Position und das Inventar des Spielers von der Festplatte läd, wenn dies fertig führt der Thread über den Bukkit Scheduler das wiederherstellen des Inventars und der Position im Mainthread durch. Das Problem dabei ist, dass der Spieler meistens schon Offline ist, wenn die Position wiedergestellt wird, komischerweise klappt es mit dem Inventar problemlos.

    Code (Text):
    1.  
    2. //Wird vom Quit event aufgerufen
    3. public void restorePlayer(final Session session) {
    4.         final Player p = session.getPlayer();
    5.         new Thread(new Runnable() {
    6.  
    7.  
    8.             @Override
    9.             public void run() {
    10.                 File loc = getPlayerCache(p);
    11.                 if (!loc.exists())
    12.                     return;
    13.                 final YamlConfiguration invStorage = YamlConfiguration
    14.                         .loadConfiguration(loc);
    15.                 loc.delete();
    16.                 Commands.getInstance().runSync(new Runnable() {
    17.                     @Override
    18.                     public void run() {
    19.                         ConfigurationSection potion = invStorage
    20.                                 .getConfigurationSection("potion");
    21.                         if (potion != null) {
    22.                             for (String pe : potion.getKeys(false)) {
    23.                                 p.addPotionEffect((PotionEffect) potion.get(pe));
    24.                             }
    25.                         }
    26.  
    27.  
    28.                         Location loc = new Location(getServer().getWorld(
    29.                                 invStorage.getString("location.world",
    30.                                         getServer().getWorlds().get(0)
    31.                                                 .getName())), invStorage
    32.                                 .getDouble("location.x", 0), invStorage
    33.                                 .getDouble("location.y", 128), invStorage
    34.                                 .getDouble("location.z", 0));
    35.                         if (loc != null) {
    36.                             session.setLastPos(loc);
    37.                         }
    38.                         for (int i = 0; i < p.getInventory().getSize(); i++) {
    39.                             if (invStorage.isSet(String.valueOf(i))) {
    40.                                 p.getInventory().setItem(
    41.                                         i,
    42.                                         (ItemStack) invStorage.get(String
    43.                                                 .valueOf(i)));
    44.                             }
    45.                         }
    46.                         safeTeleport(p, session.getLastPos());
    47.                         System.out.println(p.getLocation()); //Position ändert sich nicht
    48.                         p.saveData();
    49.  
    50.  
    51.                     }
    52.                 });
    53.  
    54.  
    55.             }
    56.         }).start();
    57.     }
    58.     public Location safeTeleportLocation(Player p,Location loc){
    59.         Material block = loc.getBlock().getType();
    60.         Material blockU = loc.getBlock().getRelative(BlockFace.UP).getLocation().getBlock().getType();
    61.         while (block.isSolid() || block == Material.LAVA|| blockU.isSolid()) {
    62.             loc.setY(loc.getY()+1);
    63.             block = loc.getBlock().getType();
    64.             blockU = loc.getBlock().getRelative(BlockFace.UP).getLocation().getBlock().getType();
    65.         }
    66.         if(loc.getY() % 1 < 0.1){
    67.             loc.setY(loc.getY()+0.1);
    68.         }
    69.         return loc;
    70.     }
    71.    
    72.     public void safeTeleport(Player p,Location loc){
    73.         p.teleport(safeTeleportLocation(p, loc));
    74.     }
    75.  
    76.  
    Hat jemand eine Idee, wie ich den Spieler Teleportieren kann, obwohl dieser Offline ist? Das ganze möchte ich aber nicht im Mainthread laufen lassen oder den Spieler erst beim nächsten Join teleportieren!
     
    #1
  2. Crafter6432
    Offline

    Crafter6432

    Registriert seit:
    22. Dezember 2011
    Beiträge:
    686

    Genau das will ich nicht, wie ich auch schon geschrieben hatte.
     
    #2
  3. ChunkNorris
    Online

    ChunkNorris

    Wenn der Spieler offline ist, einfach die <player>.dat öffnen, die Location umschreiben, speichern, fertig. :D
     
    #3
  4. Crafter6432
    Offline

    Crafter6432

    Registriert seit:
    22. Dezember 2011
    Beiträge:
    686

    NBT ist aber nicht von Bukkit, also muss ich es für jede neue Version Plugin kompilieren, gibt es denn keine "schöne" Lösung über die Bukkit API ?
     
    #4
  5. ChunkNorris
    Online

    ChunkNorris

    Könntest ja ne andere NBT-Implementation als die von MC selbst nehmen. :D
     
    #5
  6. Chrisliebaer
    Online

    Chrisliebaer

    Du müsst nur eine Library verwenden, die dir direkt den Zugriff auf die NBT Struktur erlaubt. Das hat ja mit Bukkit nichts zu tun und läuft komplett extra. Du wird lediglich das Problem haben, dass du nicht weiß, wann Bukkit die Datei nicht mehr offen hat.

    Ich habe auch mal nach einer solchen Möglichkeit gesucht und nichts gefunden. Entweder player.dat oder beim joinen.
     
    #6