GameTest: Improve structure loading ()

* GameTest: improve structure loading

* Address issues

* Re-run actions

* Test missing template

* Revert "Test missing template"

This reverts commit 0e7189bf73.

* Update fabric-gametest-api-v1/src/main/java/net/fabricmc/fabric/mixin/gametest/StructureTemplateManagerMixin.java

Co-authored-by: Juuz <6596629+Juuxel@users.noreply.github.com>

---------

Co-authored-by: Juuz <6596629+Juuxel@users.noreply.github.com>
(cherry picked from commit 2ff127f537)
This commit is contained in:
apple502j 2023-02-13 18:30:09 +09:00 committed by modmuss50
parent 57338cbe24
commit 28c7be2139
7 changed files with 97 additions and 69 deletions

View file

@ -1,6 +1,10 @@
archivesBaseName = "fabric-gametest-api-v1"
version = getSubprojectVersion(project)
loom {
accessWidenerPath = file("src/main/resources/fabric-gametest-api-v1.accesswidener")
}
moduleDependencies(project, [
'fabric-api-base',
'fabric-resource-loader-v0'

View file

@ -28,6 +28,7 @@ import javax.xml.parsers.ParserConfigurationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import net.minecraft.resource.ResourceFinder;
import net.minecraft.resource.ResourcePackManager;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.command.TestCommand;
@ -59,6 +60,10 @@ public final class FabricGameTestHelper {
private static final Logger LOGGER = LoggerFactory.getLogger(FabricGameTestHelper.class);
private static final String GAMETEST_STRUCTURE_PATH = "gametest/structures";
public static final ResourceFinder GAMETEST_STRUCTURE_FINDER = new ResourceFinder(GAMETEST_STRUCTURE_PATH, ".snbt");
private FabricGameTestHelper() {
}

View file

@ -0,0 +1,82 @@
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.fabricmc.fabric.mixin.gametest;
import java.io.IOException;
import java.util.Optional;
import java.util.stream.Stream;
import com.google.common.collect.ImmutableList;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.datafixers.DataFixer;
import org.apache.commons.io.IOUtils;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import net.minecraft.block.Block;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtHelper;
import net.minecraft.registry.RegistryEntryLookup;
import net.minecraft.resource.Resource;
import net.minecraft.resource.ResourceFinder;
import net.minecraft.resource.ResourceManager;
import net.minecraft.structure.StructureTemplate;
import net.minecraft.structure.StructureTemplateManager;
import net.minecraft.util.Identifier;
import net.minecraft.world.level.storage.LevelStorage;
import net.fabricmc.fabric.impl.gametest.FabricGameTestHelper;
@Mixin(StructureTemplateManager.class)
public abstract class StructureTemplateManagerMixin {
@Shadow
private ResourceManager resourceManager;
@Shadow
public abstract StructureTemplate createTemplate(NbtCompound nbt);
private Optional<StructureTemplate> fabric_loadSnbtFromResource(Identifier id) {
Identifier path = FabricGameTestHelper.GAMETEST_STRUCTURE_FINDER.toResourcePath(id);
Optional<Resource> resource = this.resourceManager.getResource(path);
if (resource.isPresent()) {
try {
String snbt = IOUtils.toString(resource.get().getReader());
NbtCompound nbt = NbtHelper.fromNbtProviderString(snbt);
return Optional.of(this.createTemplate(nbt));
} catch (IOException | CommandSyntaxException e) {
throw new RuntimeException("Failed to load GameTest structure " + id, e);
}
}
return Optional.empty();
}
private Stream<Identifier> fabric_streamTemplatesFromResource() {
ResourceFinder finder = FabricGameTestHelper.GAMETEST_STRUCTURE_FINDER;
return finder.findResources(this.resourceManager).keySet().stream().map(finder::toResourceId);
}
@Inject(method = "<init>", at = @At(value = "INVOKE", target = "Lcom/google/common/collect/ImmutableList$Builder;add(Ljava/lang/Object;)Lcom/google/common/collect/ImmutableList$Builder;", ordinal = 2, shift = At.Shift.AFTER), locals = LocalCapture.CAPTURE_FAILHARD)
private void addFabricTemplateProvider(ResourceManager resourceManager, LevelStorage.Session session, DataFixer dataFixer, RegistryEntryLookup<Block> blockLookup, CallbackInfo ci, ImmutableList.Builder<StructureTemplateManager.Provider> builder) {
builder.add(new StructureTemplateManager.Provider(this::fabric_loadSnbtFromResource, this::fabric_streamTemplatesFromResource));
}
}

View file

@ -1,68 +0,0 @@
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.fabricmc.fabric.mixin.gametest;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtHelper;
import net.minecraft.resource.Resource;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.structure.StructureTemplate;
import net.minecraft.test.StructureTestUtil;
import net.minecraft.util.Identifier;
@Mixin(StructureTestUtil.class)
public abstract class StructureTestUtilMixin {
private static final String GAMETEST_STRUCTURE_PATH = "gametest/structures/";
// Replace the default test structure loading with something that works a bit better for mods.
@Inject(at = @At("HEAD"), method = "createStructureTemplate(Ljava/lang/String;Lnet/minecraft/server/world/ServerWorld;)Lnet/minecraft/structure/StructureTemplate;", cancellable = true)
private static void createStructure(String id, ServerWorld world, CallbackInfoReturnable<StructureTemplate> cir) {
Identifier baseId = new Identifier(id);
Identifier structureId = new Identifier(baseId.getNamespace(), GAMETEST_STRUCTURE_PATH + baseId.getPath() + ".snbt");
try {
Resource resource = world.getServer().getResourceManager().getResource(structureId).orElse(null);
if (resource == null) {
throw new RuntimeException("Unable to get resource: " + structureId);
}
String snbt;
try (InputStream inputStream = resource.getInputStream()) {
snbt = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
}
NbtCompound nbtCompound = NbtHelper.fromNbtProviderString(snbt);
StructureTemplate structure = world.getStructureTemplateManager().createTemplate(nbtCompound);
cir.setReturnValue(structure);
} catch (IOException | CommandSyntaxException e) {
throw new RuntimeException("Error while trying to load structure: " + structureId, e);
}
}
}

View file

@ -0,0 +1,4 @@
accessWidener v2 named
accessible class net/minecraft/structure/StructureTemplateManager$Provider
accessible method net/minecraft/structure/StructureTemplateManager$Provider <init> (Ljava/util/function/Function;Ljava/util/function/Supplier;)V

View file

@ -6,7 +6,7 @@
"ArgumentTypesMixin",
"CommandManagerMixin",
"MinecraftServerMixin",
"StructureTestUtilMixin",
"StructureTemplateManagerMixin",
"TestFunctionsMixin",
"TestServerMixin"
],

View file

@ -27,6 +27,7 @@
"mixins": [
"fabric-gametest-api-v1.mixins.json"
],
"accessWidener": "fabric-gametest-api-v1.accesswidener",
"custom": {
"fabric-api:module-lifecycle": "stable"
}