--- a/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java @@ -225,7 +225,7 @@ public static S func_240784_a_(Function p_240784_0_) { AtomicReference atomicreference = new AtomicReference<>(); - Thread thread = new Thread(() -> { + Thread thread = new Thread(net.minecraftforge.fml.common.thread.SidedThreadGroups.SERVER, () -> { atomicreference.get().func_240802_v_(); }, "Server thread"); thread.setUncaughtExceptionHandler((p_240779_0_, p_240779_1_) -> { @@ -373,6 +373,7 @@ worldborder.func_177737_a(new IBorderListener.Impl(serverworld1.func_175723_af())); this.field_71305_c.put(registrykey1, serverworld1); } + net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.WorldEvent.Load(field_71305_c.get(registrykey))); } } @@ -384,6 +385,7 @@ } else if (p_240786_3_) { p_240786_1_.func_176143_a(BlockPos.field_177992_a.func_177984_a(), 0.0F); } else { + if (net.minecraftforge.event.ForgeEventFactory.onCreateWorldSpawn(p_240786_0_, p_240786_1_)) return; BiomeProvider biomeprovider = chunkgenerator.func_202090_b(); Random random = new Random(p_240786_0_.func_72905_C()); BlockPos blockpos = biomeprovider.func_225531_a_(0, p_240786_0_.func_181545_F(), 0, 256, (p_244265_0_) -> { @@ -449,6 +451,7 @@ } private void func_213186_a(IChunkStatusListener p_213186_1_) { + net.minecraftforge.common.world.StructureSpawnManager.gatherEntitySpawns(); ServerWorld serverworld = this.func_241755_D_(); field_147145_h.info("Preparing start region for dimension {}", (Object)serverworld.func_234923_W_().func_240901_a_()); BlockPos blockpos = serverworld.func_241135_u_(); @@ -563,6 +566,7 @@ for(ServerWorld serverworld1 : this.func_212370_w()) { if (serverworld1 != null) { try { + net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.WorldEvent.Unload(serverworld1)); serverworld1.close(); } catch (IOException ioexception1) { field_147145_h.error("Exception closing the level", (Throwable)ioexception1); @@ -611,6 +615,7 @@ protected void func_240802_v_() { try { if (this.func_71197_b()) { + net.minecraftforge.fml.server.ServerLifecycleHooks.handleServerStarted(this); this.field_211151_aa = Util.func_211177_b(); this.field_147147_p.func_151315_a(new StringTextComponent(this.field_71286_C)); this.field_147147_p.func_151321_a(new ServerStatusResponse.Version(SharedConstants.func_215069_a().getName(), SharedConstants.func_215069_a().getProtocolVersion())); @@ -640,7 +645,10 @@ this.func_240795_b_(longtickdetector); this.field_71296_Q = true; } + net.minecraftforge.fml.server.ServerLifecycleHooks.handleServerStopping(this); + net.minecraftforge.fml.server.ServerLifecycleHooks.expectServerStopped(); // has to come before finalTick to avoid race conditions } else { + net.minecraftforge.fml.server.ServerLifecycleHooks.expectServerStopped(); // has to come before finalTick to avoid race conditions this.func_71228_a((CrashReport)null); } } catch (Throwable throwable1) { @@ -659,6 +667,7 @@ field_147145_h.error("We were unable to save this crash report to disk."); } + net.minecraftforge.fml.server.ServerLifecycleHooks.expectServerStopped(); // has to come before finalTick to avoid race conditions this.func_71228_a(crashreport); } finally { try { @@ -667,6 +676,7 @@ } catch (Throwable throwable) { field_147145_h.error("Exception stopping the server", throwable); } finally { + net.minecraftforge.fml.server.ServerLifecycleHooks.handleServerStopped(this); this.func_71240_o(); } @@ -768,6 +778,7 @@ protected void func_71217_p(BooleanSupplier p_71217_1_) { long i = Util.func_211178_c(); + net.minecraftforge.fml.hooks.BasicEventHooks.onPreServerTick(); ++this.field_71315_w; this.func_71190_q(p_71217_1_); if (i - this.field_147142_T >= 5000000000L) { @@ -782,6 +793,7 @@ Collections.shuffle(Arrays.asList(agameprofile)); this.field_147147_p.func_151318_b().func_151330_a(agameprofile); + this.field_147147_p.invalidateJson(); } if (this.field_71315_w % 6000 == 0) { @@ -809,6 +821,7 @@ long i1 = Util.func_211178_c(); this.field_213215_ap.func_181747_a(i1 - i); this.field_71304_b.func_76319_b(); + net.minecraftforge.fml.hooks.BasicEventHooks.onPostServerTick(); } protected void func_71190_q(BooleanSupplier p_71190_1_) { @@ -816,7 +829,8 @@ this.func_193030_aL().func_73660_a(); this.field_71304_b.func_219895_b("levels"); - for(ServerWorld serverworld : this.func_212370_w()) { + for(ServerWorld serverworld : this.getWorldArray()) { + long tickStart = Util.func_211178_c(); this.field_71304_b.func_194340_a(() -> { return serverworld + " " + serverworld.func_234923_W_().func_240901_a_(); }); @@ -827,6 +841,7 @@ } this.field_71304_b.func_76320_a("tick"); + net.minecraftforge.fml.hooks.BasicEventHooks.onPreWorldTick(serverworld); try { serverworld.func_72835_b(p_71190_1_); @@ -835,9 +850,11 @@ serverworld.func_72914_a(crashreport); throw new ReportedException(crashreport); } + net.minecraftforge.fml.hooks.BasicEventHooks.onPostWorldTick(serverworld); this.field_71304_b.func_76319_b(); this.field_71304_b.func_76319_b(); + perWorldTickTimes.computeIfAbsent(serverworld.func_234923_W_(), k -> new long[100])[this.field_71315_w % 100] = Util.func_211178_c() - tickStart; } this.field_71304_b.func_219895_b("connection"); @@ -912,7 +929,7 @@ } public String getServerModName() { - return "vanilla"; + return net.minecraftforge.fml.BrandingControl.getServerBranding(); } public CrashReport func_71230_b(CrashReport p_71230_1_) { @@ -925,6 +942,7 @@ p_71230_1_.func_85056_g().func_189529_a("Data Packs", () -> { StringBuilder stringbuilder = new StringBuilder(); + LogManager.shutdown(); // we're manually managing the logging shutdown on the server. Make sure we do it here at the end. for(ResourcePackInfo resourcepackinfo : this.field_195577_ad.func_198980_d()) { if (stringbuilder.length() > 0) { stringbuilder.append(", "); @@ -1271,6 +1289,7 @@ this.func_184103_al().func_193244_w(); this.field_200258_al.func_240946_a_(this.field_195576_ac.func_240960_a_()); this.field_240765_ak_.func_195410_a(this.field_195576_ac.func_240970_h_()); + this.func_184103_al().func_181057_v().forEach(this.func_184103_al()::func_187243_f); //Forge: Fix newly added/modified commands not being sent to the client when commands reload. }, this); if (this.func_213162_bc()) { this.func_213161_c(completablefuture::isDone); @@ -1280,10 +1299,13 @@ } public static DatapackCodec func_240772_a_(ResourcePackList p_240772_0_, DatapackCodec p_240772_1_, boolean p_240772_2_) { + net.minecraftforge.fml.packs.ResourcePackLoader.loadResourcePacks(p_240772_0_, net.minecraftforge.fml.server.ServerLifecycleHooks::buildPackFinder); p_240772_0_.func_198983_a(); + DatapackCodec.field_234880_a_.addModPacks(net.minecraftforge.common.ForgeHooks.getModPacks()); + p_240772_1_.addModPacks(net.minecraftforge.common.ForgeHooks.getModPacks()); if (p_240772_2_) { - p_240772_0_.func_198985_a(Collections.singleton("vanilla")); - return new DatapackCodec(ImmutableList.of("vanilla"), ImmutableList.of()); + p_240772_0_.func_198985_a(net.minecraftforge.common.ForgeHooks.getModPacksWithVanilla()); + return new DatapackCodec(net.minecraftforge.common.ForgeHooks.getModPacksWithVanilla(), ImmutableList.of()); } else { Set set = Sets.newLinkedHashSet(); @@ -1433,6 +1455,31 @@ public abstract boolean func_213199_b(GameProfile p_213199_1_); + private Map, long[]> perWorldTickTimes = Maps.newIdentityHashMap(); + @Nullable + public long[] getTickTime(RegistryKey dim) { + return perWorldTickTimes.get(dim); + } + + @Deprecated //Forge Internal use Only, You can screw up a lot of things if you mess with this map. + public synchronized Map, ServerWorld> forgeGetWorldMap() { + return this.field_71305_c; + } + private int worldArrayMarker = 0; + private int worldArrayLast = -1; + private ServerWorld[] worldArray; + @Deprecated //Forge Internal use Only, use to protect against concurrent modifications in the world tick loop. + public synchronized void markWorldsDirty() { + worldArrayMarker++; + } + private ServerWorld[] getWorldArray() { + if (worldArrayMarker == worldArrayLast && worldArray != null) + return worldArray; + worldArray = this.field_71305_c.values().stream().toArray(x -> new ServerWorld[x]); + worldArrayLast = worldArrayMarker; + return worldArray; + } + public void func_223711_a(Path p_223711_1_) throws IOException { Path path = p_223711_1_.resolve("levels"); @@ -1561,6 +1608,10 @@ return this.field_240768_i_; } + public DataPackRegistries getDataPackRegistries() { + return field_195576_ac; + } + public DynamicRegistries func_244267_aX() { return this.field_240767_f_; }