Unser eigenes Weltensystem - Das Filesystem.

  • Herzlich Willkommen zurück meine Lieben,


    Dies ist nun der zweite Teil meiner Forumreihe zum Thema Weltensysteme. Legen wir also direkt los.

    Java
    1. @Override public void onEnable() { registerCommands(); registerEvents(); FileManager.createStandardFiles(); Bukkit.getConsoleSender().sendMessage(prefix + "§aDas Plugin wurde aktiviert!"); } public void registerEvents() { new PlayerJoin(this); }

    In der Main-Klasse wurde nun die Methode createStandardFiles() und die Klasse für das PlayerJoinEvent regisrtiert.

    Java
    1. package Commands;import java.io.File;import org.bukkit.Bukkit;import org.bukkit.World.Environment;import org.bukkit.WorldCreator;import org.bukkit.WorldType;import org.bukkit.command.Command;import org.bukkit.command.CommandExecutor;import org.bukkit.command.CommandSender;import org.bukkit.command.ConsoleCommandSender;import org.bukkit.entity.Player;import Main.Worldsystem;public class CreateCommand implements CommandExecutor { @SuppressWarnings("unused") private Worldsystem plugin; public CreateCommand(Worldsystem plugin) { this.plugin = plugin; } @Override public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { if(!(sender instanceof ConsoleCommandSender)) { Player p = (Player) sender; if(p.hasPermission("Worldsystem.Create")) { if(args.length == 1) { String world = args[0]; File worldfile = new File("plugins/Worldsystem/Worlds/" + world + ".yml"); if(!worldfile.exists()) { p.sendMessage(Worldsystem.prefix + "§aDie Welt wird erstellt..."); WorldCreator wc = (WorldCreator) WorldCreator.name(world).environment(Environment.NORMAL).type(WorldType.NORMAL); Bukkit.createWorld(wc); p.sendMessage(Worldsystem.prefix + "§aDie Welt §e" + world + " §awurde erstellt."); p.teleport(Bukkit.getWorld(world).getSpawnLocation()); p.sendMessage(Worldsystem.prefix + "§cDer Weltenspawn wurde noch nicht gesetzt! Dieser muss mit dem Befehl /setspawn gesetzt werden!"); } else { p.sendMessage(Worldsystem.prefix + "§cDiese Welt existiert bereits!"); } } else { p.sendMessage(Worldsystem.prefix + "§cVerwende: /create <Weltname>"); } } else { p.sendMessage(Worldsystem.prefix + Worldsystem.noperms); } } else { if(args.length == 1) { String world = args[0]; File worldfile = new File("plugins/Worldsystem/Worlds/" + world + ".yml"); if(!worldfile.exists()) { sender.sendMessage(Worldsystem.prefix + "§aDie Welt wird erstellt..."); WorldCreator wc = (WorldCreator) WorldCreator.name(world).environment(Environment.NORMAL).type(WorldType.NORMAL); Bukkit.createWorld(wc); sender.sendMessage(Worldsystem.prefix + "§aDie Welt §e" + world + " §awurde erstellt."); sender.sendMessage(Worldsystem.prefix + "§cDer Weltenspawn wurde noch nicht gesetzt! Dieser muss von einem Admin gesetzt werden!"); } else { sender.sendMessage(Worldsystem.prefix + "§cDiese Welt existiert bereits!"); } } else { sender.sendMessage(Worldsystem.prefix + "§cVerwende: /create <Weltname>"); } } return true; }}

    In der /create Befehls Klasse wurde nun die Abfrage eingebaut, ob die Welt schon existiert, außerdem bekommt der Spieler beim erstellen eine Nachricht, dass der Weltenspawn noch gesetzt werden muss, um die Datei zu der Welt noch zu erstellen.

    Java
    1. package Utils;import java.io.File;import java.io.IOException;import org.bukkit.Location;import org.bukkit.configuration.file.YamlConfiguration;import org.bukkit.entity.Player;public class FileManager { public static void createStandardFiles() { File mainfolder = new File("plugins/Worldsystem"); File worldfolder = new File("plugins/Worldsystem/Worlds"); if(!mainfolder.exists()) { mainfolder.mkdir(); } if(!worldfolder.exists()) { worldfolder.mkdir(); } } public static void setWorldSpawn(String world, Player p) { File worldfile = new File("plugins/Worldsystem/Worlds/" + world + ".yml"); if(!worldfile.exists()) { try { worldfile.createNewFile(); } catch (IOException ex) { ex.printStackTrace(); } } YamlConfiguration cfg = YamlConfiguration.loadConfiguration(worldfile); Location loc = p.getLocation(); double x = loc.getX(); double y = loc.getY(); double z = loc.getZ(); float yaw = loc.getYaw(); float pitch = loc.getPitch(); String worldname = loc.getWorld().getName(); cfg.set("X", x); cfg.set("Y", y); cfg.set("Z", z); cfg.set("Yaw", yaw); cfg.set("Pitch", pitch); cfg.set("Worldname", worldname); try { cfg.save(worldfile); } catch (IOException ex) { ex.printStackTrace(); } }}

    In der FileManager-Klasse habe ich nun zum einem die Standard Ordner des Plugins mit der Methode createStandardFiles() erstellt und zum anderen habe ich die Methode setWorldSpawn() zum erstellen der Weltdateien geschrieben

    Zu guter Letzt habe ich in der PlayerJoin-Klasse festgelegt, dass die Weltdatei erstellt wird, sollte sie noch nicht existieren und dass man an dem gespeichertem Spawn aus der world-Datei gespawnt wird, sollte man noch nicht auf dem Server gespielt haben.


    Liebe Grüße,

    Mimnu • Martin


    PS: Der /setspawn Befehl kommt in der nächsten Folge des Tutorials.

  • If-Else sind eklig.

  • Ich gebe dir zumindest Recht das es auch anders ginge:
    Es kann nach diesem Code übersichtlicher werden :)

  • Hallo,


    ich habe ein paar störende Dinge welche mir aufgefallen sind:

    • Die Benennung von Paketen. Definitiv nicht Konventionen-Konform. Pakete werden klein und Klassen groß geschrieben. Dazu sind die so aufgebaut: com.domain.paket.Klasse
    • Statische Methoden - Darauf sollte man weitestgehend verzichten. Beispielsweise eine Klassen-Instanz in der Main.
    • Zum ganzen (WorldSystem plugin) im Konstruktor - Schau dir am besten mal das Singleton Pattern an.
    • Daten cachen. Du liest bei jedem Join-Event die Datei für das holen der Weltdaten aus. Cache diese Daten am besten beim Laden des Plugins und zusätzlich beim erstellen einer Welt.
    • Kleiner Tipp am Rande, du brauchst nicht X, Y, Z Koordinate und Yaw und Pitch einzeln speichern. Du hast die Möglichkeit Location-Objekte direkt per set zu speichern und mittels get zu laden (natürlich zur Location casten)


    MfG

  • Hallo,


    ich habe ein paar störende Dinge welche mir aufgefallen sind:

    • Kleiner Tipp am Rande, du brauchst nicht X, Y, Z Koordinate und Yaw und Pitch einzeln speichern. Du hast die Möglichkeit Location-Objekte direkt per set zu speichern und mittels get zu laden (natürlich zur Location casten)


    MfG

    Ich nutze dafür am liebsten meine Methode :) und danke für deine detaillierte Antwort:


    Java
    1. public static String serializeLocation(Location l, boolean exact) { if (l != null) { String key = l.getWorld().getName() + ","; if (exact) { key += l.getX() + "," + l.getY() + "," + l.getZ() + "," + l.getYaw() + "," + l.getPitch(); } else { key += l.getBlockX() + "," + l.getBlockY() + "," + l.getBlockZ(); } return key; } return null; }


    Wo ich aber so nen bisschen anderer Meinung bin ist hier:


    Hallo,


    ich habe ein paar störende Dinge welche mir aufgefallen sind:

    • Statische Methoden - Darauf sollte man weitestgehend verzichten. Beispielsweise eine Klassen-Instanz in der Main.


    MfG


    Was natürlich nicht nötig ist, ist das hier:

    Code
    1. public CreateCommand(Worldsystem plugin) {
    2. this.plugin = plugin;
    3. }


    Hier reicht eine Instanz in der Main Klasse selbst(die statisch ist) und z.B. mit einer get-Methode aufgerufen werden kann, z.B. Main.getInstance();
    Dies meintest du aber im Punkt 3.