Skip to content

Commit

Permalink
Only load resources once for gametest servers (#1632)
Browse files Browse the repository at this point in the history
  • Loading branch information
Matyrobbrt authored Nov 10, 2024
1 parent 20ce6df commit c8114bf
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 40 deletions.
57 changes: 17 additions & 40 deletions patches/net/minecraft/server/Main.java.patch
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,22 @@
} catch (NbtException | ReportedNbtException | IOException ioexception) {
LOGGER.error("Failed to load world data from {}", levelstoragesource$leveldirectory.oldDataFile(), ioexception);
LOGGER.error(
@@ -173,6 +_,15 @@

PackRepository packrepository = ServerPacksSource.createPackRepository(levelstoragesource$levelstorageaccess);

+ if (gametestEnabled) {
+ net.neoforged.neoforge.gametest.GameTestHooks.registerGametests();
+ net.minecraft.core.BlockPos spawnPos = optionset.valueOf(spawnPosOpt);
+ MinecraftServer.spin(thread -> net.minecraft.gametest.framework.GameTestServer.create(thread, levelstoragesource$levelstorageaccess, packrepository, net.minecraft.gametest.framework.GameTestRegistry.getAllTestFunctions(), spawnPos));
+ // If we're running a gametest server we don't need to load the resources normally (GameTestServer#create does it using a flat world)
+ // or create a shutdown thread as the gametest server will always exit itself
+ return;
+ }
+
WorldStem worldstem;
try {
WorldLoader.InitConfig worldloader$initconfig = loadOrCreateConfig(dedicatedserversettings.getProperties(), dynamic1, flag, packrepository);
@@ -214,6 +_,9 @@
worlddimensions = dedicatedserverproperties.createDimensions(p_359487_.datapackWorldgen());
}
Expand All @@ -95,48 +111,9 @@
WorldDimensions.Complete worlddimensions$complete = worlddimensions.bake(registry);
Lifecycle lifecycle = worlddimensions$complete.lifecycle().add(p_359487_.datapackWorldgen().allRegistriesLifecycle());
return new WorldLoader.DataLoadOutput<>(
@@ -246,24 +_,22 @@

WorldData worlddata = worldstem.worldData();
levelstoragesource$levelstorageaccess.saveDataTag(registryaccess$frozen, worlddata);
- final DedicatedServer dedicatedserver = MinecraftServer.spin(
+ final MinecraftServer dedicatedserver = MinecraftServer.spin(
p_293760_ -> {
- DedicatedServer dedicatedserver1 = new DedicatedServer(
- p_293760_,
- levelstoragesource$levelstorageaccess,
- packrepository,
- worldstem,
- dedicatedserversettings,
- DataFixers.getDataFixer(),
- services,
- LoggerChunkProgressListener::createFromGameruleRadius
- );
+ MinecraftServer dedicatedserver1;
+ if (gametestEnabled) {
+ net.neoforged.neoforge.gametest.GameTestHooks.registerGametests();
+ net.minecraft.core.BlockPos spawnPos = optionset.valueOf(spawnPosOpt);
+ dedicatedserver1 = net.minecraft.gametest.framework.GameTestServer.create(p_293760_, levelstoragesource$levelstorageaccess, packrepository, net.minecraft.gametest.framework.GameTestRegistry.getAllTestFunctions(), spawnPos);
+ } else {
+ dedicatedserver1 = new DedicatedServer(p_293760_, levelstoragesource$levelstorageaccess, packrepository, worldstem, dedicatedserversettings, DataFixers.getDataFixer(), services, LoggerChunkProgressListener::createFromGameruleRadius);
+ }
dedicatedserver1.setPort(optionset.valueOf(optionspec11));
dedicatedserver1.setDemo(optionset.has(optionspec2));
dedicatedserver1.setId(optionset.valueOf(optionspec12));
boolean flag2 = !optionset.has(optionspec) && !optionset.valuesOf(optionspec15).contains("nogui");
- if (flag2 && !GraphicsEnvironment.isHeadless()) {
- dedicatedserver1.showGui();
+ if (dedicatedserver1 instanceof DedicatedServer dedicatedServer && flag2 && !GraphicsEnvironment.isHeadless()) {
+ dedicatedServer.showGui();
}

return dedicatedserver1;
@@ -272,7 +_,10 @@
Thread thread = new Thread("Server Shutdown Thread") {
@@ -273,6 +_,7 @@
@Override
public void run() {
+ // FORGE: Halting as GameTestServer will cause issues as it always calls System#exit on both crash and normal exit, so skip it
+ if (!(dedicatedserver instanceof net.minecraft.gametest.framework.GameTestServer))
dedicatedserver.halt(true);
+ org.apache.logging.log4j.LogManager.shutdown(); // we're manually managing the logging shutdown on the server. Make sure we do it here at the end.
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"values": {
"minecraft:blocks/copper_block": {
"duration": 100,
"id": "minecraft:nausea",
"show_icon": true
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
import net.minecraft.world.InteractionHand;
import net.minecraft.world.damagesource.DamageType;
import net.minecraft.world.damagesource.DamageTypes;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.HoneycombItem;
import net.minecraft.world.item.Item;
Expand All @@ -43,12 +45,14 @@
import net.minecraft.world.level.block.WeatheringCopper;
import net.minecraft.world.level.block.WeatheringCopperFullBlock;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.storage.loot.LootTable;
import net.neoforged.neoforge.common.DataMapHooks;
import net.neoforged.neoforge.common.NeoForge;
import net.neoforged.neoforge.common.data.DataMapProvider;
import net.neoforged.neoforge.debug.EventTests;
import net.neoforged.neoforge.event.entity.living.LivingDamageEvent;
import net.neoforged.neoforge.event.entity.player.UseItemOnBlockEvent;
import net.neoforged.neoforge.event.level.BlockEvent;
import net.neoforged.neoforge.registries.datamaps.AdvancedDataMapType;
import net.neoforged.neoforge.registries.datamaps.DataMapType;
import net.neoforged.neoforge.registries.datamaps.DataMapValueMerger;
Expand Down Expand Up @@ -302,6 +306,40 @@ protected void gather(HolderLookup.Provider provider) {
});
}

@GameTest
@EmptyTemplate
@TestHolder(description = "Tests if data maps can be successfully attached to reloadable registries")
static void reloadableRegDataMaps(final DynamicTest test, final RegistrationHelper reg) {
final DataMapType<LootTable, MobEffectInstance> effectGrant = reg.registerDataMap(DataMapType.builder(
ResourceLocation.fromNamespaceAndPath(reg.modId(), "effect_grant"),
Registries.LOOT_TABLE, MobEffectInstance.CODEC)
.build());

reg.addProvider(event -> new DataMapProvider(event.getGenerator().getPackOutput(), event.getLookupProvider()) {
@Override
protected void gather(HolderLookup.Provider provider) {
builder(effectGrant)
.add(Blocks.COPPER_BLOCK.getLootTable().orElseThrow(), new MobEffectInstance(MobEffects.CONFUSION, 100), false);
}
});

test.eventListeners().forge().addListener((final BlockEvent.EntityPlaceEvent event) -> {
var table = event.getPlacedBlock().getBlock().getLootTable();
if (table.isEmpty()) return;
final var grant = event.getLevel().getServer().reloadableRegistries().lookup().lookupOrThrow(Registries.LOOT_TABLE).getOrThrow(table.get()).getData(effectGrant);
if (grant != null && event.getEntity() instanceof Player player) {
player.addEffect(grant);
}
});

test.onGameTest(helper -> {
final Player player = helper.makeMockPlayer();
helper.useBlock(new BlockPos(0, 1, 0), player, Blocks.COPPER_BLOCK.asItem().getDefaultInstance());
helper.assertMobEffectPresent(player, MobEffects.CONFUSION, "has confusion");
helper.succeed();
});
}

@GameTest
@EmptyTemplate
@TestHolder(description = "Tests if custom compostables work")
Expand Down

0 comments on commit c8114bf

Please sign in to comment.