1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2024-12-14 04:00:30 +00:00

Move some Forge hooks into a separate class

This commit is contained in:
Jonathan Coates 2021-08-19 19:23:32 +01:00
parent 3e8c741170
commit 4dea3dff36
No known key found for this signature in database
GPG Key ID: B9E431FF07C98D06
4 changed files with 186 additions and 98 deletions

View File

@ -90,7 +90,6 @@ public final class NetworkHandler
}
/**
* /**
* Register packet, and a thread-unsafe handler for it.
*
* @param <T> The type of the packet to send.

View File

@ -7,12 +7,18 @@ package dan200.computercraft.ingame.mod;
import com.mojang.brigadier.CommandDispatcher;
import net.minecraft.command.CommandSource;
import net.minecraft.data.NBTToSNBTConverter;
import net.minecraft.server.MinecraftServer;
import net.minecraft.test.TestFunctionInfo;
import net.minecraft.test.TestRegistry;
import net.minecraft.test.*;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.util.text.TextFormatting;
import javax.annotation.Nonnull;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import static dan200.computercraft.shared.command.builder.HelpingArgumentBuilder.choice;
import static net.minecraft.command.Commands.literal;
@ -32,14 +38,24 @@ class CCTestCommand
.then( literal( "export" ).executes( context -> {
exportFiles( context.getSource().getServer() );
Path path = Paths.get( StructureHelper.testStructuresDir );
int total = 0;
for( TestFunctionInfo function : TestRegistry.getAllTestFunctions() )
{
total += dispatcher.execute( "test import " + function.getTestName(), context.getSource() );
total += dispatcher.execute( "test export " + function.getTestName(), context.getSource() );
ResourceLocation resourcelocation = new ResourceLocation( "minecraft", function.getStructureName() );
Path input = context.getSource().getLevel().getStructureManager().createPathToStructure( resourcelocation, ".nbt" );
Path output = NBTToSNBTConverter.convertStructure( input, function.getStructureName(), path );
if( output != null ) total++;
}
return total;
} ) )
.then( literal( "runall" ).executes( context -> {
TestRegistry.forgetFailedTests();
TestResultList result = TestHooks.runTests();
result.addListener( new Callback( context.getSource(), result ) );
result.addFailureListener( x -> TestRegistry.rememberFailedTest( x.getTestFunction() ) );
return 0;
} ) )
);
}
@ -66,4 +82,29 @@ class CCTestCommand
throw new UncheckedIOException( e );
}
}
private static class Callback implements ITestCallback
{
private final CommandSource source;
private final TestResultList result;
public Callback( CommandSource source, TestResultList result )
{
this.source = source;
this.result = result;
}
@Override
public void testStructureLoaded( @Nonnull TestTracker tracker )
{
}
@Override
public void testFailed( @Nonnull TestTracker tracker )
{
if( !tracker.isDone() ) return;
source.sendFailure( new StringTextComponent( result.getFailedRequiredCount() + " required tests failed" ).withStyle( TextFormatting.RED ) );
}
}
}

View File

@ -0,0 +1,139 @@
package dan200.computercraft.ingame.mod;
import net.minecraft.client.Minecraft;
import net.minecraft.command.CommandSource;
import net.minecraft.server.MinecraftServer;
import net.minecraft.test.*;
import net.minecraft.util.Rotation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.GameRules;
import net.minecraft.world.World;
import net.minecraft.world.gen.Heightmap;
import net.minecraft.world.server.ServerWorld;
import net.minecraftforge.event.RegisterCommandsEvent;
import net.minecraftforge.event.TickEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.server.FMLServerStartedEvent;
import net.minecraftforge.fml.loading.FMLLoader;
import net.minecraftforge.fml.server.ServerLifecycleHooks;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.Collection;
import java.util.stream.Collectors;
@Mod.EventBusSubscriber( modid = TestMod.MOD_ID )
public class TestHooks
{
private static final Logger log = LogManager.getLogger( TestHooks.class );
private static TestResultList runningTests = null;
private static int countdown = 20;
@SubscribeEvent
public static void onRegisterCommands( RegisterCommandsEvent event )
{
log.info( "Starting server, registering command helpers." );
TestCommand.register( event.getDispatcher() );
CCTestCommand.register( event.getDispatcher() );
}
@SubscribeEvent
public static void onServerStarted( FMLServerStartedEvent event )
{
MinecraftServer server = event.getServer();
GameRules rules = server.getGameRules();
rules.getRule( GameRules.RULE_DAYLIGHT ).set( false, server );
rules.getRule( GameRules.RULE_WEATHER_CYCLE ).set( false, server );
rules.getRule( GameRules.RULE_DOMOBSPAWNING ).set( false, server );
ServerWorld world = event.getServer().getLevel( World.OVERWORLD );
if( world != null ) world.setDayTime( 6000 );
log.info( "Cleaning up after last run" );
CommandSource source = server.createCommandSourceStack();
TestUtils.clearAllTests( source.getLevel(), getStart( source ), TestCollection.singleton, 200 );
log.info( "Importing files" );
CCTestCommand.importFiles( server );
}
@SubscribeEvent
public static void onServerTick( TickEvent.ServerTickEvent event )
{
if( event.phase != TickEvent.Phase.START ) return;
// Let the world settle a bit before starting tests.
countdown--;
if( countdown == 0 && System.getProperty( "cctest.run", "false" ).equals( "true" ) ) startTests();
TestCollection.singleton.tick();
MainThread.INSTANCE.tick();
if( runningTests != null && runningTests.isDone() ) finishTests();
}
public static TestResultList runTests()
{
MinecraftServer server = ServerLifecycleHooks.getCurrentServer();
CommandSource source = server.createCommandSourceStack();
Collection<TestFunctionInfo> tests = TestRegistry.getAllTestFunctions()
.stream()
.filter( x -> FMLLoader.getDist().isClient() | !x.batchName.startsWith( "client" ) )
.collect( Collectors.toList() );
log.info( "Running {} tests...", tests.size() );
Collection<TestBatch> batches = TestUtils.groupTestsIntoBatches( tests );
return new TestResultList( TestUtils.runTestBatches(
batches, getStart( source ), Rotation.NONE, source.getLevel(), TestCollection.singleton, 8
) );
}
private static void startTests()
{
runningTests = runTests();
}
private static void finishTests()
{
log.info( "Finished tests - {} were run", runningTests.getTotalCount() );
if( runningTests.hasFailedRequired() )
{
log.error( "{} required tests failed", runningTests.getFailedRequiredCount() );
}
if( runningTests.hasFailedOptional() )
{
log.warn( "{} optional tests failed", runningTests.getFailedOptionalCount() );
}
if( ServerLifecycleHooks.getCurrentServer().isDedicatedServer() )
{
log.info( "Stopping server." );
// We can't exit in the main thread, as Minecraft registers a shutdown hook which results
// in a deadlock. So we do this weird janky thing!
Thread thread = new Thread( () -> System.exit( runningTests.hasFailedRequired() ? 1 : 0 ) );
thread.setDaemon( true );
thread.start();
}
else
{
shutdownClient();
}
}
private static BlockPos getStart( CommandSource source )
{
BlockPos pos = new BlockPos( source.getPosition() );
return new BlockPos( pos.getX(), source.getLevel().getHeightmapPos( Heightmap.Type.WORLD_SURFACE, pos ).getY(), pos.getZ() + 3 );
}
private static void shutdownClient()
{
Minecraft.getInstance().clearLevel();
Minecraft.getInstance().stop();
if( runningTests.hasFailedOptional() ) System.exit( 1 );
}
}

View File

@ -6,38 +6,23 @@
package dan200.computercraft.ingame.mod;
import dan200.computercraft.api.ComputerCraftAPI;
import net.minecraft.command.CommandSource;
import net.minecraft.server.MinecraftServer;
import net.minecraft.test.*;
import net.minecraft.util.Rotation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.GameRules;
import net.minecraft.world.gen.Heightmap;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.RegisterCommandsEvent;
import net.minecraftforge.event.TickEvent;
import net.minecraft.test.StructureHelper;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.server.FMLServerStartedEvent;
import net.minecraftforge.fml.server.ServerLifecycleHooks;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collection;
@Mod( TestMod.MOD_ID )
public class TestMod
{
public static final Path sourceDir = Paths.get( "../../src/testMod/server-files/" ).toAbsolutePath();
public static final Path sourceDir = Paths.get( "../../src/testMod/server-files" ).normalize().toAbsolutePath();
public static final String MOD_ID = "cctest";
public static final Logger log = LogManager.getLogger( MOD_ID );
private TestResultList runningTests = null;
private int countdown = 20;
public TestMod()
{
log.info( "CC: Test initialised" );
@ -45,81 +30,5 @@ public class TestMod
TestLoader.setup();
StructureHelper.testStructuresDir = sourceDir.resolve( "structures" ).toString();
MinecraftForge.EVENT_BUS.addListener( ( RegisterCommandsEvent event ) -> {
log.info( "Starting server, registering command helpers." );
TestCommand.register( event.getDispatcher() );
CCTestCommand.register( event.getDispatcher() );
} );
MinecraftForge.EVENT_BUS.addListener( ( FMLServerStartedEvent event ) -> {
MinecraftServer server = event.getServer();
GameRules rules = server.getGameRules();
rules.getRule( GameRules.RULE_DAYLIGHT ).set( false, server );
rules.getRule( GameRules.RULE_WEATHER_CYCLE ).set( false, server );
rules.getRule( GameRules.RULE_DOMOBSPAWNING ).set( false, server );
log.info( "Cleaning up after last run" );
CommandSource source = server.createCommandSourceStack();
TestUtils.clearAllTests( source.getLevel(), getStart( source ), TestCollection.singleton, 200 );
log.info( "Importing files" );
CCTestCommand.importFiles( server );
} );
MinecraftForge.EVENT_BUS.addListener( ( TickEvent.ServerTickEvent event ) -> {
if( event.phase != TickEvent.Phase.START ) return;
// Let the world settle a bit before starting tests.
countdown--;
if( countdown == 0 && System.getProperty( "cctest.run", "false" ).equals( "true" ) ) startTests();
TestCollection.singleton.tick();
MainThread.INSTANCE.tick();
if( runningTests != null && runningTests.isDone() ) finishTests();
} );
}
private void startTests()
{
MinecraftServer server = ServerLifecycleHooks.getCurrentServer();
CommandSource source = server.createCommandSourceStack();
Collection<TestFunctionInfo> tests = TestRegistry.getAllTestFunctions();
log.info( "Running {} tests...", tests.size() );
runningTests = new TestResultList( TestUtils.runTests(
tests, getStart( source ), Rotation.NONE, source.getLevel(), TestCollection.singleton, 8
) );
}
private void finishTests()
{
log.info( "Finished tests - {} were run", runningTests.getTotalCount() );
if( runningTests.hasFailedRequired() )
{
log.error( "{} required tests failed", runningTests.getFailedRequiredCount() );
}
if( runningTests.hasFailedOptional() )
{
log.warn( "{} optional tests failed", runningTests.getFailedOptionalCount() );
}
if( ServerLifecycleHooks.getCurrentServer().isDedicatedServer() )
{
log.info( "Stopping server." );
// We can't exit in the main thread, as Minecraft registers a shutdown hook which results
// in a deadlock. So we do this weird janky thing!
Thread thread = new Thread( () -> System.exit( runningTests.hasFailedRequired() ? 1 : 0 ) );
thread.setDaemon( true );
thread.start();
}
}
private BlockPos getStart( CommandSource source )
{
BlockPos pos = new BlockPos( source.getPosition() );
return new BlockPos( pos.getX(), source.getLevel().getHeightmapPos( Heightmap.Type.WORLD_SURFACE, pos ).getY(), pos.getZ() + 3 );
}
}