Commits

md_5 authored 3a5dc78f472
Fix confusing migration message appearing on fresh server
No tags

nms-patches/MinecraftServer.patch

Modified
113 113 }
114 114
115 115 public void a(String s, String s1, long i, WorldType worldtype, JsonElement jsonelement) {
116 116 - this.convertWorld(s);
117 117 + // this.convertWorld(s); // CraftBukkit - moved down
118 118 this.b((IChatBaseComponent) (new ChatMessage("menu.loadingLevel", new Object[0])));
119 119 + /* CraftBukkit start - Remove ticktime arrays and worldsettings
120 120 IDataManager idatamanager = this.getConvertable().a(s, this);
121 121
122 122 this.a(this.getWorld(), idatamanager);
123 -@@ -244,54 +296,144 @@
123 +@@ -244,54 +296,145 @@
124 124 }
125 125
126 126 this.a(idatamanager.getDirectory(), worlddata);
127 127 - PersistentCollection persistentcollection = new PersistentCollection(idatamanager);
128 128 + */
129 129 + int worldCount = 3;
130 130
131 131 - this.a(idatamanager, persistentcollection, worlddata, worldsettings);
132 132 - this.a(this.getDifficulty());
133 133 - this.a(persistentcollection);
190 190 - worldserver.getWorldData().setGameType(this.getGamemode());
191 191 - }
192 192 + world.a(worldsettings);
193 193 + this.server.scoreboardManager = new org.bukkit.craftbukkit.scoreboard.CraftScoreboardManager(this, world.getScoreboard());
194 194 + } else {
195 195 + String dim = "DIM" + dimension;
196 196
197 197 - SecondaryWorldServer secondaryworldserver = (new SecondaryWorldServer(this, idatamanager, DimensionManager.NETHER, worldserver, this.methodProfiler)).i_();
198 198 + File newWorld = new File(new File(name), dim);
199 199 + File oldWorld = new File(new File(s), dim);
200 -
201 -- this.worldServer.put(DimensionManager.NETHER, secondaryworldserver);
202 -- secondaryworldserver.addIWorldAccess(new WorldManager(this, secondaryworldserver));
203 -- if (!this.H()) {
204 -- secondaryworldserver.getWorldData().setGameType(this.getGamemode());
205 -- }
206 -+ if ((!newWorld.isDirectory()) && (oldWorld.isDirectory())) {
200 ++ File oldLevelDat = new File(new File(s), "level.dat"); // The data folders exist on first run as they are created in the PersistentCollection constructor above, but the level.dat won't
201 ++
202 ++ if (!newWorld.isDirectory() && oldWorld.isDirectory() && oldLevelDat.isFile()) {
207 203 + MinecraftServer.LOGGER.info("---- Migration of old " + worldType + " folder required ----");
208 204 + MinecraftServer.LOGGER.info("Unfortunately due to the way that Minecraft implemented multiworld support in 1.6, Bukkit requires that you move your " + worldType + " folder to a new location in order to operate correctly.");
209 205 + MinecraftServer.LOGGER.info("We will move this folder for you, but it will mean that you need to move it back should you wish to stop using Bukkit in the future.");
210 206 + MinecraftServer.LOGGER.info("Attempting to move " + oldWorld + " to " + newWorld + "...");
211 207 +
212 208 + if (newWorld.exists()) {
213 209 + MinecraftServer.LOGGER.warn("A file or folder already exists at " + newWorld + "!");
214 210 + MinecraftServer.LOGGER.info("---- Migration of old " + worldType + " folder failed ----");
215 211 + } else if (newWorld.getParentFile().mkdirs()) {
216 212 + if (oldWorld.renameTo(newWorld)) {
217 213 + MinecraftServer.LOGGER.info("Success! To restore " + worldType + " in the future, simply move " + newWorld + " to " + oldWorld);
218 214 + // Migrate world data too.
219 215 + try {
220 -+ com.google.common.io.Files.copy(new File(new File(s), "level.dat"), new File(new File(name), "level.dat"));
216 ++ com.google.common.io.Files.copy(oldLevelDat, new File(new File(name), "level.dat"));
221 217 + org.apache.commons.io.FileUtils.copyDirectory(new File(new File(s), "data"), new File(new File(name), "data"));
222 218 + } catch (IOException exception) {
223 219 + MinecraftServer.LOGGER.warn("Unable to migrate world data.");
224 220 + }
225 221 + MinecraftServer.LOGGER.info("---- Migration of old " + worldType + " folder complete ----");
226 222 + } else {
227 223 + MinecraftServer.LOGGER.warn("Could not move folder " + oldWorld + " to " + newWorld + "!");
228 224 + MinecraftServer.LOGGER.info("---- Migration of old " + worldType + " folder failed ----");
229 225 + }
230 226 + } else {
231 227 + MinecraftServer.LOGGER.warn("Could not create path for " + newWorld + "!");
232 228 + MinecraftServer.LOGGER.info("---- Migration of old " + worldType + " folder failed ----");
233 229 + }
234 230 + }
235 231
236 -- SecondaryWorldServer secondaryworldserver1 = (new SecondaryWorldServer(this, idatamanager, DimensionManager.THE_END, worldserver, this.methodProfiler)).i_();
232 +- this.worldServer.put(DimensionManager.NETHER, secondaryworldserver);
233 +- secondaryworldserver.addIWorldAccess(new WorldManager(this, secondaryworldserver));
234 +- if (!this.H()) {
235 +- secondaryworldserver.getWorldData().setGameType(this.getGamemode());
236 +- }
237 237 + IDataManager idatamanager = new ServerNBTManager(server.getWorldContainer(), name, this, this.dataConverterManager);
238 238 + // world =, b0 to dimension, s1 to name, added Environment and gen
239 239 + worlddata = idatamanager.getWorldData();
240 240 + if (worlddata == null) {
241 241 + worlddata = new WorldData(worldsettings, name);
242 242 + }
243 243 + worlddata.checkName(name); // CraftBukkit - Migration did not rewrite the level.dat; This forces 1.8 to take the last loaded world as respawn (in this case the end)
244 244 + world = (WorldServer) new SecondaryWorldServer(this, idatamanager, DimensionManager.a(dimension), this.getWorldServer(DimensionManager.OVERWORLD), this.methodProfiler, worlddata, org.bukkit.World.Environment.getEnvironment(dimension), gen).i_();
245 245 + }
246 246
247 +- SecondaryWorldServer secondaryworldserver1 = (new SecondaryWorldServer(this, idatamanager, DimensionManager.THE_END, worldserver, this.methodProfiler)).i_();
248 ++ this.server.getPluginManager().callEvent(new org.bukkit.event.world.WorldInitEvent(world.getWorld()));
249 +
247 250 - this.worldServer.put(DimensionManager.THE_END, secondaryworldserver1);
248 251 - secondaryworldserver1.addIWorldAccess(new WorldManager(this, secondaryworldserver1));
249 252 - if (!this.H()) {
250 253 - secondaryworldserver1.getWorldData().setGameType(this.getGamemode());
251 254 - }
252 -+ this.server.getPluginManager().callEvent(new org.bukkit.event.world.WorldInitEvent(world.getWorld()));
253 -+
254 255 + world.addIWorldAccess(new WorldManager(this, world));
255 256 + if (!this.H()) {
256 257 + world.getWorldData().setGameType(this.getGamemode());
257 258 + }
259 ++
260 ++ this.worldServer.put(world.dimension, world);
261 ++ this.getPlayerList().setPlayerFileData(world);
258 262
259 263 - this.getPlayerList().setPlayerFileData(worldserver);
260 264 - if (worlddata.P() != null) {
261 265 - this.getBossBattleCustomData().a(worlddata.P());
262 -+ this.worldServer.put(world.dimension, world);
263 -+ this.getPlayerList().setPlayerFileData(world);
264 -+
265 266 + if (worlddata.P() != null) {
266 267 + this.getBossBattleCustomData().a(worlddata.P());
267 268 + }
268 269 }
269 270 + this.a(this.getDifficulty());
270 271 + this.a(this.getWorldServer(DimensionManager.OVERWORLD).worldMaps);
271 272 + // CraftBukkit end
272 273
273 274 }
274 275
290 291 + + " }\n"
291 292 + + "}", mcMeta, com.google.common.base.Charsets.UTF_8);
292 293 + } catch (IOException ex) {
293 294 + throw new RuntimeException("Could not initialize Bukkit datapack", ex);
294 295 + }
295 296 + }
296 297 + // CraftBukkit end
297 298 this.resourcePackRepository.a((ResourcePackSource) this.resourcePackFolder);
298 299 this.resourcePackRepository.a();
299 300 List<ResourcePackLoader> list = Lists.newArrayList();
300 -@@ -320,42 +462,52 @@
301 +@@ -320,42 +463,52 @@
301 302 boolean flag4 = true;
302 303
303 304 this.b((IChatBaseComponent) (new ChatMessage("menu.generatingTerrain", new Object[0])));
304 305 - WorldServer worldserver = this.getWorldServer(DimensionManager.OVERWORLD);
305 306
306 307 - MinecraftServer.LOGGER.info("Preparing start region for dimension " + DimensionManager.a(worldserver.worldProvider.getDimensionManager()));
307 308 - BlockPosition blockposition = worldserver.getSpawn();
308 309 - List<ChunkCoordIntPair> list = Lists.newArrayList();
309 310 - Set<ChunkCoordIntPair> set = Sets.newConcurrentHashSet();
310 311 + // CraftBukkit start - fire WorldLoadEvent and handle whether or not to keep the spawn in memory
336 337 - completablefuture.get(1L, TimeUnit.SECONDS);
337 338 - } catch (InterruptedException interruptedexception) {
338 339 - throw new RuntimeException(interruptedexception);
339 340 - } catch (ExecutionException executionexception) {
340 341 - if (executionexception.getCause() instanceof RuntimeException) {
341 342 - throw (RuntimeException) executionexception.getCause();
342 343 - }
343 344 + CompletableFuture completablefuture = worldserver.getChunkProvider().a((Iterable) list, (chunk) -> {
344 345 + set.add(chunk.getPos());
345 346 + });
346 -+
347 +
348 +- throw new RuntimeException(executionexception.getCause());
349 +- } catch (TimeoutException timeoutexception) {
350 +- this.a(new ChatMessage("menu.preparingSpawn", new Object[0]), set.size() * 100 / 625);
347 351 + while (!completablefuture.isDone()) {
348 352 + try {
349 353 + completablefuture.get(1L, TimeUnit.SECONDS);
350 354 + } catch (InterruptedException interruptedexception) {
351 355 + throw new RuntimeException(interruptedexception);
352 356 + } catch (ExecutionException executionexception) {
353 357 + if (executionexception.getCause() instanceof RuntimeException) {
354 358 + throw (RuntimeException) executionexception.getCause();
355 359 + }
356 -
357 -- throw new RuntimeException(executionexception.getCause());
358 -- } catch (TimeoutException timeoutexception) {
359 -- this.a(new ChatMessage("menu.preparingSpawn", new Object[0]), set.size() * 100 / 625);
360 ++
360 361 + throw new RuntimeException(executionexception.getCause());
361 362 + } catch (TimeoutException timeoutexception) {
362 363 + this.a(new ChatMessage("menu.preparingSpawn", new Object[0]), set.size() * 100 / 625);
363 364 + }
364 365 }
365 366 - }
366 367
367 368 - this.a(new ChatMessage("menu.preparingSpawn", new Object[0]), set.size() * 100 / 625);
368 369 + this.a(new ChatMessage("menu.preparingSpawn", new Object[0]), set.size() * 100 / 625);
369 370 + }
370 371 }
371 372
372 373 + for (WorldServer world : this.getWorlds()) {
373 374 + this.server.getPluginManager().callEvent(new org.bukkit.event.world.WorldLoadEvent(world.getWorld()));
374 375 + }
375 376 + // CraftBukkit end
376 377 MinecraftServer.LOGGER.info("Time elapsed: {} ms", stopwatch.elapsed(TimeUnit.MILLISECONDS));
377 378 Iterator iterator = DimensionManager.b().iterator();
378 379
379 -@@ -414,6 +566,10 @@
380 +@@ -414,6 +567,10 @@
380 381 protected void l() {
381 382 this.w = null;
382 383 this.x = 0;
383 384 + // CraftBukkit Start
384 385 + this.server.enablePlugins(org.bukkit.plugin.PluginLoadOrder.POSTWORLD);
385 386 + this.server.getPluginManager().callEvent(new ServerLoadEvent(ServerLoadEvent.LoadType.STARTUP));
386 387 + // CraftBukkit end
387 388 }
388 389
389 390 protected void saveChunks(boolean flag) {
390 -@@ -437,8 +593,24 @@
391 +@@ -437,8 +594,24 @@
391 392
392 393 }
393 394
394 395 - protected void stop() {
395 396 + // CraftBukkit start
396 397 + private boolean hasStopped = false;
397 398 + private final Object stopLock = new Object();
398 399 + // CraftBukkit end
399 400 +
400 401 + public void stop() throws ExceptionWorldConflict { // CraftBukkit - added throws
406 407 + // CraftBukkit end
407 408 MinecraftServer.LOGGER.info("Stopping server");
408 409 + // CraftBukkit start
409 410 + if (this.server != null) {
410 411 + this.server.disablePlugins();
411 412 + }
412 413 + // CraftBukkit end
413 414 if (this.getServerConnection() != null) {
414 415 this.getServerConnection().b();
415 416 }
416 -@@ -447,6 +619,7 @@
417 +@@ -447,6 +620,7 @@
417 418 MinecraftServer.LOGGER.info("Saving players");
418 419 this.playerList.savePlayers();
419 420 this.playerList.u();
420 421 + try { Thread.sleep(100); } catch (InterruptedException ex) {} // CraftBukkit - SPIGOT-625 - give server at least a chance to send packets
421 422 }
422 423
423 424 MinecraftServer.LOGGER.info("Saving worlds");
424 -@@ -511,11 +684,13 @@
425 +@@ -511,11 +685,13 @@
425 426 if (i > 2000L && this.nextTick - this.lastOverloadTime >= 15000L) {
426 427 long j = i / 50L;
427 428
428 429 + if (server.getWarnOnOverload()) // CraftBukkit
429 430 MinecraftServer.LOGGER.warn("Can't keep up! Is the server overloaded? Running {}ms or {} ticks behind", i, j);
430 431 this.nextTick += j * 50L;
431 432 this.lastOverloadTime = this.nextTick;
432 433 }
433 434
434 435 + MinecraftServer.currentTick = (int) (System.currentTimeMillis() / 50); // CraftBukkit
435 436 this.a(this::canSleepForTick);
436 437 this.nextTick += 50L;
437 438
438 -@@ -554,6 +729,12 @@
439 +@@ -554,6 +730,12 @@
439 440 } catch (Throwable throwable1) {
440 441 MinecraftServer.LOGGER.error("Exception stopping the server", throwable1);
441 442 } finally {
442 443 + // CraftBukkit start - Restore terminal to original settings
443 444 + try {
444 445 + reader.getTerminal().restore();
445 446 + } catch (Exception ignored) {
446 447 + }
447 448 + // CraftBukkit end
448 449 this.t();
449 450 }
450 451
451 -@@ -622,7 +803,7 @@
452 +@@ -622,7 +804,7 @@
452 453 this.m.b().a(agameprofile);
453 454 }
454 455
455 456 - if (this.ticks % 900 == 0) {
456 457 + if (autosavePeriod > 0 && this.ticks % autosavePeriod == 0) { // CraftBukkit
457 458 this.methodProfiler.enter("save");
458 459 this.playerList.savePlayers();
459 460 this.saveChunks(true);
460 -@@ -648,6 +829,7 @@
461 +@@ -648,6 +830,7 @@
461 462 }
462 463
463 464 public void b(BooleanSupplier booleansupplier) {
464 465 + this.server.getScheduler().mainThreadHeartbeat(this.ticks); // CraftBukkit
465 466 this.methodProfiler.enter("jobs");
466 467
467 468 FutureTask futuretask;
468 -@@ -660,23 +842,40 @@
469 +@@ -660,23 +843,40 @@
469 470 this.getFunctionData().tick();
470 471 this.methodProfiler.exitEnter("levels");
471 472
472 473 - WorldServer worldserver;
473 474 + // CraftBukkit start
474 475 + // Run tasks that are waiting on processing
475 476 + while (!processQueue.isEmpty()) {
476 477 + processQueue.remove().run();
477 478 + }
478 479 +
505 506 + /* Drop global time updates
506 507 if (this.ticks % 20 == 0) {
507 508 this.methodProfiler.enter("timeSync");
508 509 this.playerList.a((Packet) (new PacketPlayOutUpdateTime(worldserver.getTime(), worldserver.getDayTime(), worldserver.getGameRules().getBoolean("doDaylightCycle"))), worldserver.worldProvider.getDimensionManager());
509 510 this.methodProfiler.exit();
510 511 }
511 512 + // CraftBukkit end */
512 513
513 514 this.methodProfiler.enter("tick");
514 515
515 -@@ -727,10 +926,11 @@
516 +@@ -727,10 +927,11 @@
516 517 this.k.add(itickable);
517 518 }
518 519
519 520 - public static void main(String[] astring) {
520 521 + public static void main(final OptionSet options) { // CraftBukkit - replaces main(String[] astring)
521 522 DispenserRegistry.c();
522 523
523 524 try {
524 525 + /* CraftBukkit start - Replace everything
525 526 boolean flag = true;
526 527 String s = null;
527 528 String s1 = ".";
528 -@@ -778,13 +978,16 @@
529 +@@ -778,13 +979,16 @@
529 530 ++j;
530 531 }
531 532 }
532 533 + */ // CraftBukkit end
533 534
534 535 + String s1 = "."; // PAIL?
535 536 YggdrasilAuthenticationService yggdrasilauthenticationservice = new YggdrasilAuthenticationService(Proxy.NO_PROXY, UUID.randomUUID().toString());
536 537 MinecraftSessionService minecraftsessionservice = yggdrasilauthenticationservice.createMinecraftSessionService();
537 538 GameProfileRepository gameprofilerepository = yggdrasilauthenticationservice.createProfileRepository();
538 539 UserCache usercache = new UserCache(gameprofilerepository, new File(s1, MinecraftServer.a.getName()));
539 540 - final DedicatedServer dedicatedserver = new DedicatedServer(new File(s1), DataConverterRegistry.a(), yggdrasilauthenticationservice, minecraftsessionservice, gameprofilerepository, usercache);
540 541 + final DedicatedServer dedicatedserver = new DedicatedServer(options, DataConverterRegistry.a(), yggdrasilauthenticationservice, minecraftsessionservice, gameprofilerepository, usercache);
541 542
542 543 + /* CraftBukkit start
543 544 if (s != null) {
544 545 dedicatedserver.h(s);
545 546 }
546 -@@ -822,6 +1025,29 @@
547 +@@ -822,6 +1026,29 @@
547 548
548 549 thread.setUncaughtExceptionHandler(new DefaultUncaughtExceptionHandler(MinecraftServer.LOGGER));
549 550 Runtime.getRuntime().addShutdownHook(thread);
550 551 + */
551 552 +
552 553 + if (options.has("port")) {
553 554 + int port = (Integer) options.valueOf("port");
554 555 + if (port > 0) {
555 556 + dedicatedserver.setPort(port);
556 557 + }
566 567 +
567 568 + if (options.has("forceUpgrade")) {
568 569 + dedicatedserver.setForceUpgrade(true);
569 570 + }
570 571 +
571 572 + dedicatedserver.primaryThread.start();
572 573 + // CraftBukkit end
573 574 } catch (Exception exception) {
574 575 MinecraftServer.LOGGER.fatal("Failed to start the minecraft server", exception);
575 576 }
576 -@@ -833,11 +1059,13 @@
577 +@@ -833,11 +1060,13 @@
577 578 }
578 579
579 580 public void v() {
580 581 + /* CraftBukkit start - prevent abuse
581 582 this.serverThread = new Thread(this, "Server thread");
582 583 this.serverThread.setUncaughtExceptionHandler((thread, throwable) -> {
583 584 MinecraftServer.LOGGER.error(throwable);
584 585 });
585 586 this.serverThread.start();
586 587 + // CraftBukkit end */
587 588 }
588 589
589 590 public File c(String s) {
590 -@@ -877,7 +1105,7 @@
591 +@@ -877,7 +1106,7 @@
591 592 }
592 593
593 594 public boolean isDebugging() {
594 595 - return false;
595 596 + return this.getPropertyManager().getBoolean("debug", false); // CraftBukkit - don't hardcode
596 597 }
597 598
598 599 public void f(String s) {
599 -@@ -892,7 +1120,7 @@
600 +@@ -892,7 +1121,7 @@
600 601 }
601 602
602 603 public String getServerModName() {
603 604 - return "vanilla";
604 605 + return server.getName(); // CraftBukkit - cb > vanilla!
605 606 }
606 607
607 608 public CrashReport b(CrashReport crashreport) {
608 -@@ -928,7 +1156,7 @@
609 +@@ -928,7 +1157,7 @@
609 610 }
610 611
611 612 public boolean D() {
612 613 - return this.universe != null;
613 614 + return true; // CraftBukkit
614 615 }
615 616
616 617 public void sendMessage(IChatBaseComponent ichatbasecomponent) {
617 -@@ -1068,7 +1296,7 @@
618 +@@ -1068,7 +1297,7 @@
618 619 public abstract boolean Q();
619 620
620 621 public boolean getOnlineMode() {
621 622 - return this.onlineMode;
622 623 + return server.getOnlineMode(); // CraftBukkit
623 624 }
624 625
625 626 public void setOnlineMode(boolean flag) {
626 -@@ -1228,7 +1456,7 @@
627 +@@ -1228,7 +1457,7 @@
627 628
628 629 public <V> ListenableFuture<V> a(Callable<V> callable) {
629 630 Validate.notNull(callable);
630 631 - if (!this.isMainThread() && !this.isStopped()) {
631 632 + if (!this.isMainThread()) { // CraftBukkit && !this.isStopped()) {
632 633 ListenableFutureTask<V> listenablefuturetask = ListenableFutureTask.create(callable);
633 634
634 635 this.f.add(listenablefuturetask);
635 -@@ -1411,4 +1639,11 @@
636 +@@ -1411,4 +1640,11 @@
636 637 return 0;
637 638 }
638 639 }
639 640 +
640 641 + // CraftBukkit start
641 642 + @Deprecated
642 643 + public static MinecraftServer getServer() {
643 644 + return (Bukkit.getServer() instanceof CraftServer) ? ((CraftServer) Bukkit.getServer()).getServer() : null;
644 645 + }
645 646 + // CraftBukkit end
646 647 }

Everything looks good. We'll let you know here if there's anything you should know about.

Add shortcut