package net.minecraft.gametest.framework; import com.mojang.brigadier.context.CommandContext; import java.util.Collection; import java.util.LinkedList; import java.util.List; import java.util.function.Supplier; import java.util.function.UnaryOperator; import java.util.stream.Stream; import net.minecraft.commands.CommandSourceStack; import net.minecraft.core.BlockPos; import net.minecraft.core.Holder; public class TestFinder implements TestInstanceFinder, TestPosFinder { private static final TestInstanceFinder NO_FUNCTIONS = Stream::empty; private static final TestPosFinder NO_STRUCTURES = Stream::empty; private final TestInstanceFinder testInstanceFinder; private final TestPosFinder testPosFinder; private final CommandSourceStack source; @Override public Stream findTestPos() { return this.testPosFinder.findTestPos(); } public static TestFinder.Builder builder() { return new TestFinder.Builder(); } private TestFinder(final CommandSourceStack source, final TestInstanceFinder testInstanceFinder, final TestPosFinder testPosFinder) { this.source = source; this.testInstanceFinder = testInstanceFinder; this.testPosFinder = testPosFinder; } public CommandSourceStack source() { return this.source; } @Override public Stream> findTests() { return this.testInstanceFinder.findTests(); } public static class Builder { private final UnaryOperator>>> testFinderWrapper; private final UnaryOperator>> structureBlockPosFinderWrapper; public Builder() { this.testFinderWrapper = f -> f; this.structureBlockPosFinderWrapper = f -> f; } private Builder( final UnaryOperator>>> testFinderWrapper, final UnaryOperator>> structureBlockPosFinderWrapper ) { this.testFinderWrapper = testFinderWrapper; this.structureBlockPosFinderWrapper = structureBlockPosFinderWrapper; } public TestFinder.Builder createMultipleCopies(final int amount) { return new TestFinder.Builder(createCopies(amount), createCopies(amount)); } private static UnaryOperator>> createCopies(final int amount) { return source -> { List copyList = new LinkedList(); List sourceList = ((Stream)source.get()).toList(); for (int i = 0; i < amount; i++) { copyList.addAll(sourceList); } return copyList::stream; }; } private TestFinder build(final CommandSourceStack source, final TestInstanceFinder testInstanceFinder, final TestPosFinder testPosFinder) { return new TestFinder( source, ((Supplier)this.testFinderWrapper.apply(testInstanceFinder::findTests))::get, ((Supplier)this.structureBlockPosFinderWrapper.apply(testPosFinder::findTestPos))::get ); } public TestFinder radius(final CommandContext sourceStack, final int radius) { CommandSourceStack source = sourceStack.getSource(); BlockPos pos = BlockPos.containing(source.getPosition()); return this.build(source, TestFinder.NO_FUNCTIONS, () -> StructureUtils.findTestBlocks(pos, radius, source.getLevel())); } public TestFinder nearest(final CommandContext sourceStack) { CommandSourceStack source = sourceStack.getSource(); BlockPos pos = BlockPos.containing(source.getPosition()); return this.build(source, TestFinder.NO_FUNCTIONS, () -> StructureUtils.findNearestTest(pos, 15, source.getLevel()).stream()); } public TestFinder allNearby(final CommandContext sourceStack) { CommandSourceStack source = sourceStack.getSource(); BlockPos pos = BlockPos.containing(source.getPosition()); return this.build(source, TestFinder.NO_FUNCTIONS, () -> StructureUtils.findTestBlocks(pos, 250, source.getLevel())); } public TestFinder lookedAt(final CommandContext sourceStack) { CommandSourceStack source = sourceStack.getSource(); return this.build( source, TestFinder.NO_FUNCTIONS, () -> StructureUtils.lookedAtTestPos(BlockPos.containing(source.getPosition()), source.getPlayer().getCamera(), source.getLevel()) ); } public TestFinder failedTests(final CommandContext sourceStack, final boolean onlyRequiredTests) { return this.build( sourceStack.getSource(), () -> FailedTestTracker.getLastFailedTests().filter(test -> !onlyRequiredTests || ((GameTestInstance)test.value()).required()), TestFinder.NO_STRUCTURES ); } public TestFinder byResourceSelection(final CommandContext sourceStack, final Collection> holders) { return this.build(sourceStack.getSource(), holders::stream, TestFinder.NO_STRUCTURES); } public TestFinder failedTests(final CommandContext sourceStack) { return this.failedTests(sourceStack, false); } } }