--- a/net/minecraft/server/Main.java
+++ b/net/minecraft/server/Main.java
@@ -61,16 +61,28 @@
 import net.minecraft.world.level.storage.WorldInfo;
 import org.slf4j.Logger;
 
+// CraftBukkit start
+import com.google.common.base.Charsets;
+import java.io.InputStreamReader;
+import java.util.concurrent.atomic.AtomicReference;
+import net.minecraft.SharedConstants;
+import net.minecraft.server.packs.EnumResourcePackType;
+import net.minecraft.world.level.dimension.WorldDimension;
+import net.minecraft.world.level.storage.SavedFile;
+import org.bukkit.configuration.file.YamlConfiguration;
+// CraftBukkit end
+
 public class Main {
 
     private static final Logger LOGGER = LogUtils.getLogger();
 
     public Main() {}
 
-    @SuppressForbidden(a = "System.out needed before bootstrap")
+    @SuppressForbidden(reason = "System.out needed before bootstrap") // CraftBukkit - decompile error
     @DontObfuscate
-    public static void main(String[] astring) {
+    public static void main(final OptionSet optionset) { // CraftBukkit - replaces main(String[] astring)
         SharedConstants.tryDetectVersion();
+        /* CraftBukkit start - Replace everything
         OptionParser optionparser = new OptionParser();
         OptionSpec<Void> optionspec = optionparser.accepts("nogui");
         OptionSpec<Void> optionspec1 = optionparser.accepts("initSettings", "Initializes 'server.properties' and 'eula.txt', then quits");
@@ -96,15 +108,18 @@
                 optionparser.printHelpOn(System.err);
                 return;
             }
+            */ // CraftBukkit end
 
-            Path path = (Path) optionset.valueOf(optionspec14);
+        try {
+
+            Path path = (Path) optionset.valueOf("pidFile"); // CraftBukkit
 
             if (path != null) {
                 writePidFile(path);
             }
 
             CrashReport.preload();
-            if (optionset.has(optionspec13)) {
+            if (optionset.has("jfrProfile")) { // CraftBukkit
                 JvmProfiler.INSTANCE.start(Environment.SERVER);
             }
 
@@ -112,14 +127,27 @@
             DispenserRegistry.validate();
             SystemUtils.startTimerHackThread();
             Path path1 = Paths.get("server.properties");
-            DedicatedServerSettings dedicatedserversettings = new DedicatedServerSettings(path1);
+            DedicatedServerSettings dedicatedserversettings = new DedicatedServerSettings(optionset); // CraftBukkit - CLI argument support
 
             dedicatedserversettings.forceSave();
             RegionFileCompression.configure(dedicatedserversettings.getProperties().regionFileComression);
             Path path2 = Paths.get("eula.txt");
             EULA eula = new EULA(path2);
 
-            if (optionset.has(optionspec1)) {
+            if (optionset.has("initSettings")) { // CraftBukkit
+                // CraftBukkit start - SPIGOT-5761: Create bukkit.yml and commands.yml if not present
+                File configFile = (File) optionset.valueOf("bukkit-settings");
+                YamlConfiguration configuration = YamlConfiguration.loadConfiguration(configFile);
+                configuration.options().copyDefaults(true);
+                configuration.setDefaults(YamlConfiguration.loadConfiguration(new InputStreamReader(Main.class.getClassLoader().getResourceAsStream("configurations/bukkit.yml"), Charsets.UTF_8)));
+                configuration.save(configFile);
+
+                File commandFile = (File) optionset.valueOf("commands-settings");
+                YamlConfiguration commandsConfiguration = YamlConfiguration.loadConfiguration(commandFile);
+                commandsConfiguration.options().copyDefaults(true);
+                commandsConfiguration.setDefaults(YamlConfiguration.loadConfiguration(new InputStreamReader(Main.class.getClassLoader().getResourceAsStream("configurations/commands.yml"), Charsets.UTF_8)));
+                commandsConfiguration.save(commandFile);
+                // CraftBukkit end
                 Main.LOGGER.info("Initialized '{}' and '{}'", path1.toAbsolutePath(), path2.toAbsolutePath());
                 return;
             }
@@ -129,11 +157,13 @@
                 return;
             }
 
-            File file = new File((String) optionset.valueOf(optionspec9));
+            File file = (File) optionset.valueOf("universe"); // CraftBukkit
             Services services = Services.create(new YggdrasilAuthenticationService(Proxy.NO_PROXY), file);
-            String s = (String) Optional.ofNullable((String) optionset.valueOf(optionspec10)).orElse(dedicatedserversettings.getProperties().levelName);
+            // CraftBukkit start
+            String s = (String) Optional.ofNullable((String) optionset.valueOf("world")).orElse(dedicatedserversettings.getProperties().levelName);
             Convertable convertable = Convertable.createDefault(file.toPath());
-            Convertable.ConversionSession convertable_conversionsession = convertable.validateAndCreateAccess(s);
+            Convertable.ConversionSession convertable_conversionsession = convertable.validateAndCreateAccess(s, WorldDimension.OVERWORLD);
+            // CraftBukkit end
             Dynamic dynamic;
 
             if (convertable_conversionsession.hasWorldData()) {
@@ -174,13 +204,31 @@
             }
 
             Dynamic<?> dynamic1 = dynamic;
-            boolean flag = optionset.has(optionspec7);
+            boolean flag = optionset.has("safeMode"); // CraftBukkit
 
             if (flag) {
                 Main.LOGGER.warn("Safe mode active, only vanilla datapack will be loaded");
             }
 
             ResourcePackRepository resourcepackrepository = ResourcePackSourceVanilla.createPackRepository(convertable_conversionsession);
+            // CraftBukkit start
+            File bukkitDataPackFolder = new File(convertable_conversionsession.getLevelPath(SavedFile.DATAPACK_DIR).toFile(), "bukkit");
+            if (!bukkitDataPackFolder.exists()) {
+                bukkitDataPackFolder.mkdirs();
+            }
+            File mcMeta = new File(bukkitDataPackFolder, "pack.mcmeta");
+            try {
+                com.google.common.io.Files.write("{\n"
+                        + "    \"pack\": {\n"
+                        + "        \"description\": \"Data pack for resources provided by Bukkit plugins\",\n"
+                        + "        \"pack_format\": " + SharedConstants.getCurrentVersion().getPackVersion(EnumResourcePackType.SERVER_DATA) + "\n"
+                        + "    }\n"
+                        + "}\n", mcMeta, com.google.common.base.Charsets.UTF_8);
+            } catch (java.io.IOException ex) {
+                throw new RuntimeException("Could not initialize Bukkit datapack", ex);
+            }
+            AtomicReference<WorldLoader.a> worldLoader = new AtomicReference<>();
+            // CraftBukkit end
 
             WorldStem worldstem;
 
@@ -189,6 +237,7 @@
 
                 worldstem = (WorldStem) SystemUtils.blockUntilDone((executor) -> {
                     return WorldLoader.load(worldloader_c, (worldloader_a) -> {
+                        worldLoader.set(worldloader_a); // CraftBukkit
                         IRegistry<WorldDimension> iregistry = worldloader_a.datapackDimensions().lookupOrThrow(Registries.LEVEL_STEM);
 
                         if (dynamic1 != null) {
@@ -201,7 +250,7 @@
                             WorldOptions worldoptions;
                             WorldDimensions worlddimensions;
 
-                            if (optionset.has(optionspec2)) {
+                            if (optionset.has("demo")) { // CraftBukkit
                                 worldsettings = MinecraftServer.DEMO_SETTINGS;
                                 worldoptions = WorldOptions.DEMO_OPTIONS;
                                 worlddimensions = WorldPresets.createNormalWorldDimensions(worldloader_a.datapackWorldgen());
@@ -209,7 +258,7 @@
                                 DedicatedServerProperties dedicatedserverproperties = dedicatedserversettings.getProperties();
 
                                 worldsettings = new WorldSettings(dedicatedserverproperties.levelName, dedicatedserverproperties.gamemode, dedicatedserverproperties.hardcore, dedicatedserverproperties.difficulty, false, new GameRules(worldloader_a.dataConfiguration().enabledFeatures()), worldloader_a.dataConfiguration());
-                                worldoptions = optionset.has(optionspec3) ? dedicatedserverproperties.worldOptions.withBonusChest(true) : dedicatedserverproperties.worldOptions;
+                                worldoptions = optionset.has("bonusChest") ? dedicatedserverproperties.worldOptions.withBonusChest(true) : dedicatedserverproperties.worldOptions; // CraftBukkit
                                 worlddimensions = dedicatedserverproperties.createDimensions(worldloader_a.datapackWorldgen());
                             }
 
@@ -225,6 +274,7 @@
                 return;
             }
 
+            /*
             IRegistryCustom.Dimension iregistrycustom_dimension = worldstem.registries().compositeAccess();
             boolean flag1 = optionset.has(optionspec6);
 
@@ -237,20 +287,31 @@
             SaveData savedata = worldstem.worldData();
 
             convertable_conversionsession.saveDataTag(iregistrycustom_dimension, savedata);
+            */
             final DedicatedServer dedicatedserver = (DedicatedServer) MinecraftServer.spin((thread) -> {
-                DedicatedServer dedicatedserver1 = new DedicatedServer(thread, convertable_conversionsession, resourcepackrepository, worldstem, dedicatedserversettings, DataConverterRegistry.getDataFixer(), services, WorldLoadListenerLogger::createFromGameruleRadius);
+                DedicatedServer dedicatedserver1 = new DedicatedServer(optionset, worldLoader.get(), thread, convertable_conversionsession, resourcepackrepository, worldstem, dedicatedserversettings, DataConverterRegistry.getDataFixer(), services, WorldLoadListenerLogger::createFromGameruleRadius);
 
+                /*
                 dedicatedserver1.setPort((Integer) optionset.valueOf(optionspec11));
                 dedicatedserver1.setDemo(optionset.has(optionspec2));
                 dedicatedserver1.setId((String) optionset.valueOf(optionspec12));
-                boolean flag2 = !optionset.has(optionspec) && !optionset.valuesOf(optionspec15).contains("nogui");
+                */
+                boolean flag2 = !optionset.has("nogui") && !optionset.nonOptionArguments().contains("nogui");
 
                 if (flag2 && !GraphicsEnvironment.isHeadless()) {
                     dedicatedserver1.showGui();
                 }
 
+                if (optionset.has("port")) {
+                    int port = (Integer) optionset.valueOf("port");
+                    if (port > 0) {
+                        dedicatedserver1.setPort(port);
+                    }
+                }
+
                 return dedicatedserver1;
             });
+            /* CraftBukkit start
             Thread thread = new Thread("Server Shutdown Thread") {
                 public void run() {
                     dedicatedserver.halt(true);
@@ -259,6 +320,7 @@
 
             thread.setUncaughtExceptionHandler(new DefaultUncaughtExceptionHandler(Main.LOGGER));
             Runtime.getRuntime().addShutdownHook(thread);
+            */ // CraftBukkit end
         } catch (Exception exception1) {
             Main.LOGGER.error(LogUtils.FATAL_MARKER, "Failed to start the minecraft server", exception1);
         }
@@ -295,7 +357,7 @@
     }
 
     public static void forceUpgrade(Convertable.ConversionSession convertable_conversionsession, DataFixer datafixer, boolean flag, BooleanSupplier booleansupplier, IRegistryCustom iregistrycustom, boolean flag1) {
-        Main.LOGGER.info("Forcing world upgrade!");
+        Main.LOGGER.info("Forcing world upgrade! {}", convertable_conversionsession.getLevelId()); // CraftBukkit
         WorldUpgrader worldupgrader = new WorldUpgrader(convertable_conversionsession, datafixer, iregistrycustom, flag, flag1);
 
         try {
