26.1-snapshot-6

This commit is contained in:
modmuss50 2026-02-03 16:33:42 +00:00
parent efb289876b
commit 00a1fba694
16 changed files with 106 additions and 51 deletions

View file

@ -16,6 +16,8 @@
package net.fabricmc.fabric.mixin.client.gametest.threading;
import java.util.Optional;
import com.google.common.base.Preconditions;
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod;
@ -34,6 +36,7 @@ import net.minecraft.client.gui.screens.Screen;
import net.minecraft.server.WorldStem;
import net.minecraft.server.packs.repository.PackRepository;
import net.minecraft.util.thread.BlockableEventLoop;
import net.minecraft.world.level.gamerules.GameRules;
import net.minecraft.world.level.storage.LevelStorageSource;
import net.fabricmc.fabric.impl.client.gametest.TestSystemProperties;
@ -108,10 +111,10 @@ public class MinecraftMixin {
}
@Inject(method = "doWorldLoad", at = @At("HEAD"), cancellable = true)
private void deferStartIntegratedServer(LevelStorageSource.LevelStorageAccess storageAccess, PackRepository dataPackManager, WorldStem worldStem, boolean newWorld, CallbackInfo ci) {
private void deferStartIntegratedServer(LevelStorageSource.LevelStorageAccess storageAccess, PackRepository dataPackManager, WorldStem worldStem, Optional<GameRules> gameRules, boolean newWorld, CallbackInfo ci) {
if (ThreadingImpl.taskToRun != null) {
// don't start the integrated server (which busywaits) inside a task
deferredTask = () -> Minecraft.getInstance().doWorldLoad(storageAccess, dataPackManager, worldStem, newWorld);
deferredTask = () -> Minecraft.getInstance().doWorldLoad(storageAccess, dataPackManager, worldStem, gameRules, newWorld);
ci.cancel();
}
}

View file

@ -40,7 +40,7 @@ public class CreateWorldScreenMixin {
@Inject(method = "onCreate", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/worldselection/WorldOpenFlows;confirmWorldCreation(Lnet/minecraft/client/Minecraft;Lnet/minecraft/client/gui/screens/worldselection/CreateWorldScreen;Lcom/mojang/serialization/Lifecycle;Ljava/lang/Runnable;Z)V"), cancellable = true)
private void createLevelDataForServers(CallbackInfo ci, @Local(name = "finalLayers") LayeredRegistryAccess<RegistryLayer> finalLayers, @Local(name = "worldData") PrimaryLevelData worldData) {
if (DedicatedServerImplUtil.saveLevelDataTo != null) {
CompoundTag levelDatInner = worldData.createTag(finalLayers.compositeAccess(), null);
CompoundTag levelDatInner = worldData.createTag(null);
CompoundTag levelDat = new CompoundTag();
levelDat.put("Data", levelDatInner);

View file

@ -27,6 +27,7 @@ import org.slf4j.LoggerFactory;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtOps;
import net.minecraft.resources.Identifier;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.ProblemReporter;
import net.minecraft.world.level.saveddata.SavedData;
@ -40,7 +41,7 @@ import net.minecraft.world.level.storage.ValueInput;
*/
public class AttachmentSavedData extends SavedData {
private static final Logger LOGGER = LoggerFactory.getLogger(AttachmentSavedData.class);
public static final String ID = "fabric_attachments";
public static final Identifier ID = Identifier.fromNamespaceAndPath("fabric", "attachments");
private final AttachmentTargetImpl levelTarget;
private final boolean wasSerialized;

View file

@ -0,0 +1,47 @@
/*
* 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.attachment;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyArg;
import net.minecraft.util.filefix.fixes.DimensionStorageFileFix;
import net.minecraft.util.filefix.operations.FileFixOperation;
import net.minecraft.util.filefix.operations.FileFixOperations;
@Mixin(DimensionStorageFileFix.class)
abstract class DimensionStorageFileFixMixin {
@ModifyArg(
method = "makeFixer",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/util/filefix/operations/FileFixOperations;applyInFolders(Lnet/minecraft/util/filefix/access/FileRelation;Ljava/util/List;)Lnet/minecraft/util/filefix/operations/ApplyInFolders;",
ordinal = 1
),
index = 1
)
private List<FileFixOperation> addFabricAttachmentsMigration(List<FileFixOperation> original) {
List<FileFixOperation> operations = new ArrayList<>(original);
operations.add(FileFixOperations.move("fabric_attachments.dat", "fabric/attachments.dat"));
return Collections.unmodifiableList(operations);
}
}

View file

@ -10,6 +10,7 @@
"ClientboundCustomPayloadPacketAccessor",
"ChunkHolderMixin",
"ConnectionMixin",
"DimensionStorageFileFixMixin",
"EntityMixin",
"ImposterProtoChunkMixin",
"LevelChunkMixin",

View file

@ -15,5 +15,6 @@
"min_y": 0,
"effects": "fabric_dimension:void",
"monster_spawn_block_light_limit": 15,
"monster_spawn_light_level": 15
"monster_spawn_light_level": 15,
"has_ender_dragon_fight": false
}

View file

@ -139,7 +139,7 @@ public class MinecraftGameRuleServiceImplTest {
DedicatedServer server = mock(DedicatedServer.class);
WorldData worldData = mock(WorldData.class);
when(server.getWorldData()).thenReturn(worldData);
when(worldData.getGameRules()).thenReturn(this.gameRules);
when(server.getGameRules()).thenReturn(this.gameRules);
return server;
}

View file

@ -26,8 +26,6 @@ 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.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@ -39,47 +37,49 @@ import net.minecraft.resources.FileToIdConverter;
import net.minecraft.resources.Identifier;
import net.minecraft.server.packs.resources.Resource;
import net.minecraft.server.packs.resources.ResourceManager;
import net.minecraft.util.datafix.DataFixTypes;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager;
import net.minecraft.world.level.levelgen.structure.templatesystem.loader.TemplateSource;
import net.minecraft.world.level.storage.LevelStorageSource;
import net.fabricmc.fabric.impl.gametest.FabricGameTestRunner;
@Mixin(StructureTemplateManager.class)
public abstract class StructureTemplateManagerMixin {
@Shadow
private ResourceManager resourceManager;
@Shadow
public abstract StructureTemplate readStructure(CompoundTag compoundTag);
@Unique
private Optional<StructureTemplate> fabric_loadSnbtFromResource(Identifier id) {
Identifier path = FabricGameTestRunner.GAMETEST_STRUCTURE_FINDER.idToFile(id);
Optional<Resource> resource = this.resourceManager.getResource(path);
if (resource.isPresent()) {
try {
String snbt = IOUtils.toString(resource.get().openAsReader());
CompoundTag tag = NbtUtils.snbtToStructure(snbt);
return Optional.of(this.readStructure(tag));
} catch (IOException | CommandSyntaxException e) {
throw new RuntimeException("Failed to load GameTest structure " + id, e);
}
}
return Optional.empty();
}
@Unique
private Stream<Identifier> streamTemplatesFromResource() {
FileToIdConverter finder = FabricGameTestRunner.GAMETEST_STRUCTURE_FINDER;
return finder.listMatchingResources(this.resourceManager).keySet().stream().map(finder::fileToId);
}
@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))
private void addFabricTemplateProvider(ResourceManager resourceManager, LevelStorageSource.LevelStorageAccess storageAccess, DataFixer dataFixer, HolderGetter<Block> blockLookup, CallbackInfo ci, @Local(name = "builder") ImmutableList.Builder<StructureTemplateManager.Source> builder) {
builder.add(new StructureTemplateManager.Source(this::fabric_loadSnbtFromResource, this::streamTemplatesFromResource));
private void addFabricTemplateProvider(ResourceManager resourceManager, LevelStorageSource.LevelStorageAccess storageAccess, DataFixer dataFixer, HolderGetter<Block> blockLookup, CallbackInfo ci, @Local(name = "sources") ImmutableList.Builder<TemplateSource> builder) {
builder.add(new TemplateSource(dataFixer, blockLookup) {
@Override
public Optional<StructureTemplate> load(Identifier id) {
Identifier path = FabricGameTestRunner.GAMETEST_STRUCTURE_FINDER.idToFile(id);
Optional<Resource> resource = resourceManager.getResource(path);
if (resource.isPresent()) {
try {
String snbt = IOUtils.toString(resource.get().openAsReader());
CompoundTag tag = NbtUtils.snbtToStructure(snbt);
// Replicate readStructure logic from TemplateSource
StructureTemplate structureTemplate = new StructureTemplate();
int version = NbtUtils.getDataVersion(tag, 500);
structureTemplate.load(blockLookup, DataFixTypes.STRUCTURE.updateToCurrentVersion(dataFixer, tag, version));
return Optional.of(structureTemplate);
} catch (IOException | CommandSyntaxException e) {
throw new RuntimeException("Failed to load GameTest structure " + id, e);
}
}
return Optional.empty();
}
@Override
public Stream<Identifier> list() {
FileToIdConverter finder = FabricGameTestRunner.GAMETEST_STRUCTURE_FINDER;
return finder.listMatchingResources(resourceManager).keySet().stream().map(finder::fileToId);
}
});
}
}

View file

@ -1,6 +1,6 @@
classTweaker v1 official
accessible class net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplateManager$Source
accessible method net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplateManager$Source <init> (Ljava/util/function/Function;Ljava/util/function/Supplier;)V
accessible class net/minecraft/world/level/levelgen/structure/templatesystem/loader/TemplateSource
accessible method net/minecraft/world/level/levelgen/structure/templatesystem/loader/TemplateSource <init> (Lcom/mojang/datafixers/DataFixer;Lnet/minecraft/core/HolderGetter;)V
accessible field net/minecraft/resources/RegistryLoadTask registry Lnet/minecraft/core/WritableRegistry;

View file

@ -40,7 +40,7 @@ import net.fabricmc.fabric.impl.loot.LootUtil;
public class SimpleJsonResourceReloadListenerMixin {
@Inject(method = "scanDirectory(Lnet/minecraft/server/packs/resources/ResourceManager;Lnet/minecraft/resources/FileToIdConverter;Lcom/mojang/serialization/DynamicOps;Lcom/mojang/serialization/Codec;Ljava/util/Map;)V", at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/resources/FileToIdConverter;fileToId(Lnet/minecraft/resources/Identifier;)Lnet/minecraft/resources/Identifier;"))
private static <T> void fillSourceMap(ResourceManager manager, FileToIdConverter fileToIdConverter, DynamicOps<JsonElement> ops, Codec<T> codec, Map<Identifier, T> result, CallbackInfo ci, @Local(name = "entry") Map.Entry<Identifier, Resource> entry, @Local(name = "id") Identifier id) {
final String dirName = ((FileToIdConverterAccessor) fileToIdConverter).getPrefix();
final String dirName = fileToIdConverter.prefix();
if (!LootDataType.TABLE.registryKey().identifier().getPath().equals(dirName)) return;
LootUtil.SOURCES.get().put(id, LootUtil.determineSource(entry.getValue()));

View file

@ -24,10 +24,10 @@ import org.spongepowered.asm.mixin.injection.At;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.util.datafix.DataFixTypes;
import net.minecraft.world.level.storage.DimensionDataStorage;
import net.minecraft.world.level.storage.SavedDataStorage;
@Mixin(DimensionDataStorage.class)
class DimensionDataStorageMixin {
@Mixin(SavedDataStorage.class)
class SavedDataStorageMixin {
/**
* Handle mods passing a null DataFixTypes to a PersistentState.Type.
*/

View file

@ -9,7 +9,7 @@
"DetectorRailBlockMixin",
"EntityTypeBuilderMixin",
"EntityTypeMixin",
"DimensionDataStorageMixin",
"SavedDataStorageMixin",
"EntityDataSerializersAccessor",
"EntityDataSerializersMixin"
],

View file

@ -52,7 +52,7 @@ public class DimensionDataStorageTest implements ModInitializer {
private static final Codec<TestState> CODEC = RecordCodecBuilder.create(instance -> instance.group(
Codec.STRING.fieldOf("value").forGetter(TestState::getValue)
).apply(instance, TestState::new));
private static final SavedDataType<TestState> TYPE = new SavedDataType<>(ObjectBuilderTestConstants.id("test_state").toString().replace(":", "_"), TestState::new, CODEC, null);
private static final SavedDataType<TestState> TYPE = new SavedDataType<>(ObjectBuilderTestConstants.id("test_state"), TestState::new, CODEC, null);
public static TestState getOrCreate(ServerLevel level) {
return level.getDataStorage().computeIfAbsent(TestState.TYPE);

View file

@ -60,7 +60,7 @@ public class SimpleJsonResourceReloadListenerMixin {
if (resourceData.isJsonObject()) {
JsonObject obj = resourceData.getAsJsonObject();
final String dataType = ((FileToIdConverterAccessor) resourceFinder).getDirectoryName();
final String dataType = resourceFinder.prefix();
if (!ResourceConditionsImpl.applyResourceConditions(obj, dataType, entry.getKey(), registryInfo)) {
return DataResult.success(SKIP_DATA_MARKER);

View file

@ -18,6 +18,7 @@ package net.fabricmc.fabric.mixin.resource;
import java.net.Proxy;
import java.util.List;
import java.util.Optional;
import com.mojang.datafixers.DataFixer;
import org.spongepowered.asm.mixin.Mixin;
@ -36,6 +37,7 @@ import net.minecraft.server.packs.PackResources;
import net.minecraft.server.packs.repository.KnownPack;
import net.minecraft.server.packs.repository.Pack;
import net.minecraft.server.packs.repository.PackRepository;
import net.minecraft.world.level.gamerules.GameRules;
import net.minecraft.world.level.storage.LevelStorageSource;
import net.fabricmc.fabric.api.resource.v1.DataResourceStore;
@ -61,7 +63,7 @@ public class MinecraftServerMixin implements DataResourceStore, FabricOriginalKn
}
@Inject(method = "<init>", at = @At("TAIL"))
private void init(Thread serverThread, LevelStorageSource.LevelStorageAccess storageAccess, PackRepository dataPackManager, WorldStem worldStem, Proxy proxy, DataFixer dataFixer, Services apiServices, LevelLoadListener chunkLoadProgress, CallbackInfo ci) {
private void init(Thread serverThread, LevelStorageSource.LevelStorageAccess storageAccess, PackRepository dataPackManager, WorldStem worldStem, Optional<GameRules> gameRules, Proxy proxy, DataFixer dataFixer, Services apiServices, LevelLoadListener chunkLoadProgress, CallbackInfo ci) {
this.originalKnownPacks = worldStem.resourceManager().listPacks().flatMap(pack -> pack.location().knownPackInfo().stream()).toList();
}

View file

@ -3,7 +3,7 @@ org.gradle.parallel=true
org.gradle.configuration-cache=false
version=0.143.1
minecraft_version=26.1-snapshot-5
minecraft_version=26.1-snapshot-6
loader_version=0.18.4
installer_version=1.0.1