mirror of
https://github.com/FabricMC/fabric.git
synced 2025-03-31 01:00:18 -04:00
Use knownPackInfo on mod data packs to avoid registry syncing (#3726)
* use knownPack to avoid syncing mod data packs.
* remove empty class
* checkstyle and licenses
* move debug logging from testmod into main module
* fix knownPackInfo not working for build-in data packs.
* make bundled data packs not required for client, and don't auto enable
* improve testmod with added builtin data pack + better error message
* Increase max known packs in C2S packet
* validate size before sending
* changeable with system property
* change mixin from ModifyConstant to ModifyArg to be more clear.
* Apply suggestions from code review
Co-authored-by: modmuss <modmuss50@gmail.com>
* store list of knownPacks as server start
avoids desync on pack change (since registries aren't reloaded)
* be extra safe: only request knownPacks that were enabled at server start and still are.
Doesn't rely on the fact that registries aren't synced anymore.
---------
Co-authored-by: modmuss <modmuss50@gmail.com>
(cherry picked from commit c0e5481f61
)
This commit is contained in:
parent
619abec242
commit
e8b7ff012a
21 changed files with 380 additions and 63 deletions
fabric-resource-loader-v0/src
client
java/net/fabricmc/fabric/mixin/resource/loader/client
resources
main
java/net/fabricmc/fabric
impl/resource/loader
FabricOriginalKnownPacksGetter.javaModNioResourcePack.javaModResourcePackCreator.javaModResourcePackUtil.javaResourceManagerHelperImpl.java
mixin/resource/loader
resources
testmod
java/net/fabricmc/fabric/test
mixin/resource/loader
resource/loader
resources
assets/fabric-resource-loader-v0-testmod/textures/entity/wolf
data/minecraft/wolf_variant
fabric-resource-loader-v0-testmod.mixins.jsonfabric.mod.jsonresourcepacks/test2/data/minecraft/wolf_variant
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* 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.resource.loader.client;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.llamalad7.mixinextras.injector.ModifyReturnValue;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
import net.minecraft.client.resource.ClientDataPackManager;
|
||||
import net.minecraft.registry.VersionedIdentifier;
|
||||
import net.minecraft.resource.ResourcePackManager;
|
||||
|
||||
import net.fabricmc.fabric.impl.resource.loader.ModResourcePackCreator;
|
||||
import net.fabricmc.fabric.impl.resource.loader.ModResourcePackUtil;
|
||||
|
||||
@Mixin(ClientDataPackManager.class)
|
||||
public class ClientDataPackManagerMixin {
|
||||
@Unique
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger("ClientDataPackManagerMixin");
|
||||
|
||||
@Redirect(method = "<init>", at = @At(value = "INVOKE", target = "Lnet/minecraft/resource/VanillaDataPackProvider;createClientManager()Lnet/minecraft/resource/ResourcePackManager;"))
|
||||
public ResourcePackManager createClientManager() {
|
||||
return ModResourcePackUtil.createClientManager();
|
||||
}
|
||||
|
||||
@ModifyReturnValue(method = "getCommonKnownPacks", at = @At("RETURN"))
|
||||
List<VersionedIdentifier> getCommonKnownPacksReturn(List<VersionedIdentifier> original) {
|
||||
if (original.size() > ModResourcePackCreator.MAX_KNOWN_PACKS) {
|
||||
LOGGER.warn("Too many knownPacks: Found {}; max {}", original.size(), ModResourcePackCreator.MAX_KNOWN_PACKS);
|
||||
return original.subList(0, ModResourcePackCreator.MAX_KNOWN_PACKS);
|
||||
}
|
||||
|
||||
return original;
|
||||
}
|
||||
}
|
|
@ -9,7 +9,8 @@
|
|||
"KeyedResourceReloadListenerClientMixin",
|
||||
"ResourcePackOrganizerMixin",
|
||||
"VanillaResourcePackProviderMixin",
|
||||
"GameOptionsWriteVisitorMixin"
|
||||
"GameOptionsWriteVisitorMixin",
|
||||
"ClientDataPackManagerMixin"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* 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.impl.resource.loader;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.registry.VersionedIdentifier;
|
||||
|
||||
public interface FabricOriginalKnownPacksGetter {
|
||||
/**
|
||||
* @return the data packs known at server start
|
||||
*/
|
||||
List<VersionedIdentifier> fabric_getOriginalKnownPacks();
|
||||
}
|
|
@ -42,6 +42,7 @@ import org.jetbrains.annotations.Nullable;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import net.minecraft.registry.VersionedIdentifier;
|
||||
import net.minecraft.resource.AbstractFileResourcePack;
|
||||
import net.minecraft.resource.InputSupplier;
|
||||
import net.minecraft.resource.ResourcePack;
|
||||
|
@ -106,7 +107,7 @@ public class ModNioResourcePack implements ResourcePack, ModResourcePack {
|
|||
packId,
|
||||
displayName,
|
||||
ModResourcePackCreator.RESOURCE_PACK_SOURCE,
|
||||
Optional.empty()
|
||||
Optional.of(new VersionedIdentifier(ModResourcePackCreator.FABRIC, packId, mod.getMetadata().getVersion().getFriendlyString()))
|
||||
);
|
||||
ModNioResourcePack ret = new ModNioResourcePack(packId, mod, paths, type, activationType, modBundled, metadata);
|
||||
|
||||
|
|
|
@ -68,12 +68,23 @@ public class ModResourcePackCreator implements ResourcePackProvider {
|
|||
}
|
||||
};
|
||||
public static final ModResourcePackCreator CLIENT_RESOURCE_PACK_PROVIDER = new ModResourcePackCreator(ResourceType.CLIENT_RESOURCES);
|
||||
private static final ResourcePackPosition ACTIVATION_INFO = new ResourcePackPosition(true, ResourcePackProfile.InsertionPosition.TOP, false);
|
||||
/**
|
||||
* The maximum ammount of known data packs requested from the client, including vanilla data packs.
|
||||
*/
|
||||
public static final int MAX_KNOWN_PACKS = Integer.getInteger("fabric-resource-loader-v0:maxKnownPacks", 1024);
|
||||
|
||||
private final ResourceType type;
|
||||
private final ResourcePackPosition activationInfo;
|
||||
private final boolean forClientDataPackManager;
|
||||
|
||||
public ModResourcePackCreator(ResourceType type) {
|
||||
this(type, false);
|
||||
}
|
||||
|
||||
protected ModResourcePackCreator(ResourceType type, boolean forClientDataPackManager) {
|
||||
this.type = type;
|
||||
this.activationInfo = new ResourcePackPosition(!forClientDataPackManager, ResourcePackProfile.InsertionPosition.TOP, false);
|
||||
this.forClientDataPackManager = forClientDataPackManager;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -106,7 +117,7 @@ public class ModResourcePackCreator implements ResourcePackProvider {
|
|||
metadata,
|
||||
new PlaceholderResourcePack.Factory(this.type, metadata),
|
||||
this.type,
|
||||
ACTIVATION_INFO
|
||||
this.activationInfo
|
||||
));
|
||||
|
||||
// Build a list of mod resource packs.
|
||||
|
@ -131,11 +142,14 @@ public class ModResourcePackCreator implements ResourcePackProvider {
|
|||
pack.getInfo(),
|
||||
new ModResourcePackFactory(pack),
|
||||
this.type,
|
||||
ACTIVATION_INFO
|
||||
this.activationInfo
|
||||
);
|
||||
|
||||
if (profile != null) {
|
||||
((FabricResourcePackProfile) profile).fabric_setParentsPredicate(parents);
|
||||
if (!forClientDataPackManager) {
|
||||
((FabricResourcePackProfile) profile).fabric_setParentsPredicate(parents);
|
||||
}
|
||||
|
||||
consumer.accept(profile);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,11 +43,14 @@ import net.minecraft.SharedConstants;
|
|||
import net.minecraft.resource.DataConfiguration;
|
||||
import net.minecraft.resource.DataPackSettings;
|
||||
import net.minecraft.resource.ResourcePack;
|
||||
import net.minecraft.resource.ResourcePackManager;
|
||||
import net.minecraft.resource.ResourcePackProfile;
|
||||
import net.minecraft.resource.ResourceType;
|
||||
import net.minecraft.resource.VanillaDataPackProvider;
|
||||
import net.minecraft.resource.featuretoggle.FeatureFlags;
|
||||
import net.minecraft.resource.metadata.PackResourceMetadata;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.path.SymlinkFinder;
|
||||
|
||||
import net.fabricmc.fabric.api.resource.ModResourcePack;
|
||||
import net.fabricmc.fabric.api.resource.ResourcePackActivationType;
|
||||
|
@ -233,4 +236,12 @@ public final class ModResourcePackUtil {
|
|||
|
||||
return new DataPackSettings(enabled, disabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the ResousePackManager used by the ClientDataPackManager and replaces
|
||||
* {@code VanillaDataPackProvider.createClientManager} used by vanilla.
|
||||
*/
|
||||
public static ResourcePackManager createClientManager() {
|
||||
return new ResourcePackManager(new VanillaDataPackProvider(new SymlinkFinder((path) -> true)), new ModResourcePackCreator(ResourceType.SERVER_DATA, true));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@ import java.util.Iterator;
|
|||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
|
@ -119,7 +118,7 @@ public class ResourceManagerHelperImpl implements ResourceManagerHelper {
|
|||
entry.getRight().getId(),
|
||||
entry.getLeft(),
|
||||
new BuiltinModResourcePackSource(pack.getFabricModMetadata().getName()),
|
||||
Optional.empty()
|
||||
entry.getRight().getKnownPackInfo()
|
||||
);
|
||||
ResourcePackPosition info2 = new ResourcePackPosition(
|
||||
pack.getActivationType() == ResourcePackActivationType.ALWAYS_ENABLED,
|
||||
|
|
|
@ -16,22 +16,41 @@
|
|||
|
||||
package net.fabricmc.fabric.mixin.resource.loader;
|
||||
|
||||
import java.net.Proxy;
|
||||
import java.util.List;
|
||||
|
||||
import com.mojang.datafixers.DataFixer;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
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.Redirect;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import net.minecraft.registry.VersionedIdentifier;
|
||||
import net.minecraft.resource.ResourcePack;
|
||||
import net.minecraft.resource.ResourcePackManager;
|
||||
import net.minecraft.resource.ResourcePackProfile;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.SaveLoader;
|
||||
import net.minecraft.server.WorldGenerationProgressListenerFactory;
|
||||
import net.minecraft.util.ApiServices;
|
||||
import net.minecraft.world.level.storage.LevelStorage;
|
||||
|
||||
import net.fabricmc.fabric.impl.resource.loader.BuiltinModResourcePackSource;
|
||||
import net.fabricmc.fabric.impl.resource.loader.FabricOriginalKnownPacksGetter;
|
||||
import net.fabricmc.fabric.impl.resource.loader.ModNioResourcePack;
|
||||
|
||||
@Mixin(MinecraftServer.class)
|
||||
public class MinecraftServerMixin {
|
||||
public class MinecraftServerMixin implements FabricOriginalKnownPacksGetter {
|
||||
@Unique
|
||||
private List<VersionedIdentifier> fabric_originalKnownPacks;
|
||||
|
||||
@Inject(method = "<init>", at = @At("TAIL"))
|
||||
private void init(Thread serverThread, LevelStorage.Session session, ResourcePackManager dataPackManager, SaveLoader saveLoader, Proxy proxy, DataFixer dataFixer, ApiServices apiServices, WorldGenerationProgressListenerFactory worldGenerationProgressListenerFactory, CallbackInfo ci) {
|
||||
this.fabric_originalKnownPacks = saveLoader.resourceManager().streamResourcePacks().flatMap(pack -> pack.getInfo().knownPackInfo().stream()).toList();
|
||||
}
|
||||
|
||||
@Redirect(method = "loadDataPacks(Lnet/minecraft/resource/ResourcePackManager;Lnet/minecraft/resource/DataConfiguration;ZZ)Lnet/minecraft/resource/DataConfiguration;", at = @At(value = "INVOKE", target = "Ljava/util/List;contains(Ljava/lang/Object;)Z"))
|
||||
private static boolean onCheckDisabled(List<String> list, Object o, ResourcePackManager resourcePackManager) {
|
||||
String profileId = (String) o;
|
||||
|
@ -52,4 +71,9 @@ public class MinecraftServerMixin {
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<VersionedIdentifier> fabric_getOriginalKnownPacks() {
|
||||
return this.fabric_originalKnownPacks;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,51 +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.resource.loader;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
|
||||
import com.llamalad7.mixinextras.sugar.Local;
|
||||
import com.mojang.serialization.Lifecycle;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
|
||||
import net.minecraft.registry.RegistryLoader;
|
||||
import net.minecraft.registry.entry.RegistryEntryInfo;
|
||||
import net.minecraft.resource.Resource;
|
||||
|
||||
import net.fabricmc.fabric.api.resource.ModResourcePack;
|
||||
|
||||
@Mixin(RegistryLoader.class)
|
||||
public class RegistryLoaderMixin {
|
||||
@Unique
|
||||
private static final RegistryEntryInfo MOD_PROVIDED_INFO = new RegistryEntryInfo(Optional.empty(), Lifecycle.stable());
|
||||
|
||||
// On the server side, loading mod-provided DRM entries should not show experiments screen.
|
||||
// While the lifecycle is set to experimental on the client side (a de-sync),
|
||||
// there is no good way to fix this without breaking protocol; the lifecycle seems to be unused on
|
||||
// the client side anyway.
|
||||
@ModifyExpressionValue(method = "loadFromResource(Lnet/minecraft/resource/ResourceManager;Lnet/minecraft/registry/RegistryOps$RegistryInfoGetter;Lnet/minecraft/registry/MutableRegistry;Lcom/mojang/serialization/Decoder;Ljava/util/Map;)V", at = @At(value = "INVOKE", target = "Ljava/util/function/Function;apply(Ljava/lang/Object;)Ljava/lang/Object;"))
|
||||
private static Object markModProvidedAsStable(Object original, @Local Resource resource) {
|
||||
if (original instanceof RegistryEntryInfo info && info.knownPackInfo().isEmpty() && resource.getPack() instanceof ModResourcePack) {
|
||||
return MOD_PROVIDED_INFO;
|
||||
}
|
||||
|
||||
return original;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* 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.resource.loader;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
||||
|
||||
import net.minecraft.network.packet.c2s.config.SelectKnownPacksC2SPacket;
|
||||
|
||||
import net.fabricmc.fabric.impl.resource.loader.ModResourcePackCreator;
|
||||
|
||||
@Mixin(SelectKnownPacksC2SPacket.class)
|
||||
public class SelectKnownPacksC2SPacketMixin {
|
||||
@ModifyArg(method = "<clinit>", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/codec/PacketCodecs;toList(I)Lnet/minecraft/network/codec/PacketCodec$ResultFunction;"))
|
||||
private static int setMaxKnownPacks(int constant) {
|
||||
return ModResourcePackCreator.MAX_KNOWN_PACKS;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* 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.resource.loader;
|
||||
|
||||
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.network.ClientConnection;
|
||||
import net.minecraft.registry.VersionedIdentifier;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.network.ConnectedClientData;
|
||||
import net.minecraft.server.network.ServerCommonNetworkHandler;
|
||||
import net.minecraft.server.network.ServerConfigurationNetworkHandler;
|
||||
|
||||
import net.fabricmc.fabric.impl.resource.loader.FabricOriginalKnownPacksGetter;
|
||||
|
||||
@Mixin(ServerConfigurationNetworkHandler.class)
|
||||
public abstract class ServerConfigurationNetworkHandlerMixin extends ServerCommonNetworkHandler {
|
||||
public ServerConfigurationNetworkHandlerMixin(MinecraftServer server, ClientConnection connection, ConnectedClientData clientData) {
|
||||
super(server, connection, clientData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Only use packs that were enabled at server start and are enabled now. This avoids a descync when packs have been
|
||||
* enabled or disabled before the client joins. Since the server registry contents aren't reloaded, we don't want
|
||||
* the client to use the new data pack data.
|
||||
*/
|
||||
@ModifyArg(method = "sendConfigurations", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/network/SynchronizeRegistriesTask;<init>(Ljava/util/List;Lnet/minecraft/registry/CombinedDynamicRegistries;)V", ordinal = 0))
|
||||
public List<VersionedIdentifier> filterKnownPacks(List<VersionedIdentifier> currentKnownPacks) {
|
||||
return ((FabricOriginalKnownPacksGetter) this.server).fabric_getOriginalKnownPacks().stream().filter(currentKnownPacks::contains).toList();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* 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.resource.loader;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
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;
|
||||
|
||||
import net.minecraft.network.packet.Packet;
|
||||
import net.minecraft.network.packet.s2c.config.SelectKnownPacksS2CPacket;
|
||||
import net.minecraft.registry.VersionedIdentifier;
|
||||
import net.minecraft.server.network.SynchronizeRegistriesTask;
|
||||
|
||||
import net.fabricmc.fabric.impl.resource.loader.ModResourcePackCreator;
|
||||
|
||||
@Mixin(SynchronizeRegistriesTask.class)
|
||||
public abstract class SynchronizeRegistriesTaskMixin {
|
||||
@Unique
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger("SynchronizeRegistriesTaskMixin");
|
||||
@Shadow
|
||||
@Final
|
||||
private List<VersionedIdentifier> knownPacks;
|
||||
|
||||
@Shadow
|
||||
protected abstract void syncRegistryAndTags(Consumer<Packet<?>> sender, Set<VersionedIdentifier> commonKnownPacks);
|
||||
|
||||
@Inject(method = "onSelectKnownPacks", at = @At("HEAD"), cancellable = true)
|
||||
public void onSelectKnownPacks(List<VersionedIdentifier> clientKnownPacks, Consumer<Packet<?>> sender, CallbackInfo ci) {
|
||||
if (new HashSet<>(this.knownPacks).containsAll(clientKnownPacks)) {
|
||||
this.syncRegistryAndTags(sender, Set.copyOf(clientKnownPacks));
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "syncRegistryAndTags", at = @At("HEAD"))
|
||||
public void syncRegistryAndTags(Consumer<Packet<?>> sender, Set<VersionedIdentifier> commonKnownPacks, CallbackInfo ci) {
|
||||
LOGGER.debug("Syncronizing registries with common known packs: {}", commonKnownPacks);
|
||||
}
|
||||
|
||||
@Inject(method = "sendPacket", at = @At("HEAD"), cancellable = true)
|
||||
private void sendPacket(Consumer<Packet<?>> sender, CallbackInfo ci) {
|
||||
if (this.knownPacks.size() > ModResourcePackCreator.MAX_KNOWN_PACKS) {
|
||||
LOGGER.warn("Too many knownPacks: Found {}; max {}", this.knownPacks.size(), ModResourcePackCreator.MAX_KNOWN_PACKS);
|
||||
sender.accept(new SelectKnownPacksS2CPacket(this.knownPacks.subList(0, ModResourcePackCreator.MAX_KNOWN_PACKS)));
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,12 +7,14 @@
|
|||
"KeyedResourceReloadListenerMixin",
|
||||
"LifecycledResourceManagerImplMixin",
|
||||
"MinecraftServerMixin",
|
||||
"RegistryLoaderMixin",
|
||||
"ResourceMixin",
|
||||
"ResourcePackManagerMixin",
|
||||
"ResourcePackProfileMixin",
|
||||
"SelectKnownPacksC2SPacketMixin",
|
||||
"ServerConfigurationNetworkHandlerMixin",
|
||||
"ServerPropertiesHandlerMixin",
|
||||
"SimpleResourceReloadMixin",
|
||||
"SynchronizeRegistriesTaskMixin",
|
||||
"TestServerMixin"
|
||||
],
|
||||
"server": [
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* 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.test.mixin.resource.loader;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
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 net.minecraft.network.packet.Packet;
|
||||
import net.minecraft.registry.VersionedIdentifier;
|
||||
import net.minecraft.server.network.SynchronizeRegistriesTask;
|
||||
|
||||
import net.fabricmc.fabric.test.resource.loader.BuiltinResourcePackTestMod;
|
||||
|
||||
@Mixin(SynchronizeRegistriesTask.class)
|
||||
public class SynchronizeRegistriesTaskMixin {
|
||||
@Shadow
|
||||
@Final
|
||||
private List<VersionedIdentifier> knownPacks;
|
||||
|
||||
@Inject(method = "syncRegistryAndTags", at = @At("HEAD"))
|
||||
public void syncRegistryAndTags(Consumer<Packet<?>> sender, Set<VersionedIdentifier> commonKnownPacks, CallbackInfo ci) {
|
||||
BuiltinResourcePackTestMod.LOGGER.info("Syncronizing registries with common known packs: {}", commonKnownPacks);
|
||||
|
||||
if (!commonKnownPacks.containsAll(this.knownPacks)) {
|
||||
BuiltinResourcePackTestMod.LOGGER.error("(Ignore when not local client) Not all server mod data packs known to client. Missing: {}", this.knownPacks.stream().filter(knownPack -> !commonKnownPacks.contains(knownPack)).toList());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -30,7 +30,7 @@ import net.fabricmc.loader.api.FabricLoader;
|
|||
public class BuiltinResourcePackTestMod implements ModInitializer {
|
||||
public static final String MODID = "fabric-resource-loader-v0-testmod";
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(BuiltinResourcePackTestMod.class);
|
||||
public static final Logger LOGGER = LoggerFactory.getLogger(BuiltinResourcePackTestMod.class);
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
|
|
Binary file not shown.
After ![]() (image error) Size: 6.1 KiB |
Binary file not shown.
After ![]() (image error) Size: 6.3 KiB |
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"wild_texture": "fabric-resource-loader-v0-testmod:entity/wolf/green",
|
||||
"angry_texture": "fabric-resource-loader-v0-testmod:entity/wolf/green",
|
||||
"tame_texture": "fabric-resource-loader-v0-testmod:entity/wolf/green",
|
||||
"biomes": "minecraft:forest"
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"required": true,
|
||||
"package": "net.fabricmc.fabric.test.mixin.resource.loader",
|
||||
"compatibilityLevel": "JAVA_17",
|
||||
"mixins": [
|
||||
"SynchronizeRegistriesTaskMixin"
|
||||
],
|
||||
"server": [
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
}
|
||||
}
|
|
@ -17,5 +17,8 @@
|
|||
"server": [
|
||||
"net.fabricmc.fabric.test.resource.loader.LanguageTestMod"
|
||||
]
|
||||
}
|
||||
},
|
||||
"mixins": [
|
||||
"fabric-resource-loader-v0-testmod.mixins.json"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"wild_texture": "fabric-resource-loader-v0-testmod:entity/wolf/pink",
|
||||
"angry_texture": "fabric-resource-loader-v0-testmod:entity/wolf/pink",
|
||||
"tame_texture": "fabric-resource-loader-v0-testmod:entity/wolf/pink",
|
||||
"biomes": "minecraft:forest"
|
||||
}
|
Loading…
Add table
Reference in a new issue