mirror of
https://github.com/FabricMC/fabric.git
synced 2025-04-11 22:45:38 -04:00
Make DEFAULT_ENABLED
work with client resource pack
This commit is contained in:
parent
f60060dfe3
commit
e5c0910538
7 changed files with 101 additions and 22 deletions
fabric-resource-loader-v0/src
client/java/net/fabricmc/fabric/mixin/resource/loader/client
main/java/net/fabricmc/fabric
api/resource
impl/resource/loader
testmod
java/net/fabricmc/fabric/test/resource/loader
resources/resourcepacks/test
|
@ -16,9 +16,16 @@
|
|||
|
||||
package net.fabricmc.fabric.mixin.resource.loader.client;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
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;
|
||||
|
@ -26,32 +33,99 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
|||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import net.minecraft.client.option.GameOptions;
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
import net.minecraft.nbt.NbtElement;
|
||||
import net.minecraft.nbt.NbtIo;
|
||||
import net.minecraft.nbt.NbtList;
|
||||
import net.minecraft.nbt.NbtString;
|
||||
import net.minecraft.resource.ResourcePack;
|
||||
import net.minecraft.resource.ResourcePackProfile;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import net.fabricmc.fabric.impl.resource.loader.ModNioResourcePack;
|
||||
import net.fabricmc.fabric.impl.resource.loader.ModResourcePackCreator;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
|
||||
@Mixin(GameOptions.class)
|
||||
public class GameOptionsMixin {
|
||||
@Shadow
|
||||
public List<String> resourcePacks;
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
static Logger LOGGER;
|
||||
|
||||
@Inject(method = "load", at = @At("RETURN"))
|
||||
private void onLoad(CallbackInfo ci) {
|
||||
// Add built-in resource packs if they are enabled by default only if the options file is blank.
|
||||
if (this.resourcePacks.isEmpty()) {
|
||||
List<ResourcePackProfile> profiles = new ArrayList<>();
|
||||
ModResourcePackCreator.CLIENT_RESOURCE_PACK_PROVIDER.register(profiles::add);
|
||||
this.resourcePacks = new ArrayList<>();
|
||||
// Track built-in resource packs if they are enabled by default.
|
||||
// - If there is NO value with matching resource pack id, add it to the enabled packs and the tracker file.
|
||||
// - If there is a matching value and pack id, do not add it to the enabled packs and let
|
||||
// the options value decides if it is enabled or not.
|
||||
// - If there is a value without matching pack id (e.g. because the mod is removed),
|
||||
// remove it from the tracker file so that it would be enabled again if added back later.
|
||||
|
||||
for (ResourcePackProfile profile : profiles) {
|
||||
ResourcePack pack = profile.createResourcePack();
|
||||
if (profile.getSource() == ModResourcePackCreator.RESOURCE_PACK_SOURCE
|
||||
|| (pack instanceof ModNioResourcePack && ((ModNioResourcePack) pack).getActivationType().isEnabledByDefault())) {
|
||||
this.resourcePacks.add(profile.getName());
|
||||
File dataDir = FabricLoader.getInstance().getGameDir().resolve("data").toFile();
|
||||
|
||||
if (!dataDir.exists() && !dataDir.mkdirs()) {
|
||||
LOGGER.warn("[Fabric Resource Loader] Could not create data directory: " + dataDir.getAbsolutePath());
|
||||
}
|
||||
|
||||
File trackerFile = new File(dataDir, "fabricDefaultResourcePacks.dat");
|
||||
Set<Identifier> trackedPacks = new HashSet<>();
|
||||
|
||||
if (trackerFile.exists()) {
|
||||
try {
|
||||
NbtCompound data = NbtIo.readCompressed(trackerFile);
|
||||
NbtList values = data.getList("values", NbtElement.STRING_TYPE);
|
||||
|
||||
for (int i = 0; i < values.size(); i++) {
|
||||
trackedPacks.add(new Identifier(values.getString(i)));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
LOGGER.warn("[Fabric Resource Loader] Could not read " + trackerFile.getAbsolutePath(), e);
|
||||
}
|
||||
}
|
||||
|
||||
Set<Identifier> removedPacks = new HashSet<>(trackedPacks);
|
||||
Set<String> resourcePacks = new LinkedHashSet<>(this.resourcePacks);
|
||||
|
||||
List<ResourcePackProfile> profiles = new ArrayList<>();
|
||||
ModResourcePackCreator.CLIENT_RESOURCE_PACK_PROVIDER.register(profiles::add);
|
||||
|
||||
for (ResourcePackProfile profile : profiles) {
|
||||
// Always add "Fabric Mods" pack to enabled resource packs.
|
||||
if (profile.getSource() == ModResourcePackCreator.RESOURCE_PACK_SOURCE) {
|
||||
resourcePacks.add(profile.getName());
|
||||
continue;
|
||||
}
|
||||
|
||||
ResourcePack pack = profile.createResourcePack();
|
||||
|
||||
if (pack instanceof ModNioResourcePack builtinPack && builtinPack.getActivationType().isEnabledByDefault()) {
|
||||
if (trackedPacks.add(builtinPack.getId())) {
|
||||
resourcePacks.add(profile.getName());
|
||||
} else {
|
||||
removedPacks.remove(builtinPack.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
NbtList values = new NbtList();
|
||||
|
||||
for (Identifier id : trackedPacks) {
|
||||
if (!removedPacks.contains(id)) {
|
||||
values.add(NbtString.of(id.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
NbtCompound nbt = new NbtCompound();
|
||||
nbt.put("values", values);
|
||||
NbtIo.writeCompressed(nbt, trackerFile);
|
||||
} catch (IOException e) {
|
||||
LOGGER.warn("[Fabric Resource Loader] Could not write to " + trackerFile.getAbsolutePath(), e);
|
||||
}
|
||||
|
||||
this.resourcePacks = new ArrayList<>(resourcePacks);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,8 +26,6 @@ public enum ResourcePackActivationType {
|
|||
NORMAL,
|
||||
/**
|
||||
* Enabled by default. The user has still full control over the activation of the resource pack.
|
||||
*
|
||||
* <p>Note: this setting can only be satisfied on data packs, client resource packs cannot be by default enabled.
|
||||
*/
|
||||
DEFAULT_ENABLED,
|
||||
/**
|
||||
|
|
|
@ -56,6 +56,7 @@ public class ModNioResourcePack extends AbstractFileResourcePack implements ModR
|
|||
private static final Pattern RESOURCE_PACK_PATH = Pattern.compile("[a-z0-9-_.]+");
|
||||
private static final FileSystem DEFAULT_FS = FileSystems.getDefault();
|
||||
|
||||
private final Identifier id;
|
||||
private final String name;
|
||||
private final ModMetadata modInfo;
|
||||
private final List<Path> basePaths;
|
||||
|
@ -64,7 +65,7 @@ public class ModNioResourcePack extends AbstractFileResourcePack implements ModR
|
|||
private final ResourcePackActivationType activationType;
|
||||
private final Map<ResourceType, Set<String>> namespaces;
|
||||
|
||||
public static ModNioResourcePack create(String name, ModContainer mod, String subPath, ResourceType type, ResourcePackActivationType activationType) {
|
||||
public static ModNioResourcePack create(Identifier id, String name, ModContainer mod, String subPath, ResourceType type, ResourcePackActivationType activationType) {
|
||||
List<Path> rootPaths = mod.getRootPaths();
|
||||
List<Path> paths;
|
||||
|
||||
|
@ -87,14 +88,15 @@ public class ModNioResourcePack extends AbstractFileResourcePack implements ModR
|
|||
|
||||
if (paths.isEmpty()) return null;
|
||||
|
||||
ModNioResourcePack ret = new ModNioResourcePack(name, mod.getMetadata(), paths, type, null, activationType);
|
||||
ModNioResourcePack ret = new ModNioResourcePack(id, name, mod.getMetadata(), paths, type, null, activationType);
|
||||
|
||||
return ret.getNamespaces(type).isEmpty() ? null : ret;
|
||||
}
|
||||
|
||||
private ModNioResourcePack(String name, ModMetadata modInfo, List<Path> paths, ResourceType type, AutoCloseable closer, ResourcePackActivationType activationType) {
|
||||
private ModNioResourcePack(Identifier id, String name, ModMetadata modInfo, List<Path> paths, ResourceType type, AutoCloseable closer, ResourcePackActivationType activationType) {
|
||||
super(null);
|
||||
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.modInfo = modInfo;
|
||||
this.basePaths = paths;
|
||||
|
@ -158,8 +160,8 @@ public class ModNioResourcePack extends AbstractFileResourcePack implements ModR
|
|||
return null;
|
||||
}
|
||||
|
||||
private static final String resPrefix = ResourceType.CLIENT_RESOURCES.getDirectory()+"/";
|
||||
private static final String dataPrefix = ResourceType.SERVER_DATA.getDirectory()+"/";
|
||||
private static final String resPrefix = ResourceType.CLIENT_RESOURCES.getDirectory() + "/";
|
||||
private static final String dataPrefix = ResourceType.SERVER_DATA.getDirectory() + "/";
|
||||
|
||||
private boolean hasAbsentNs(String filename) {
|
||||
int prefixLen;
|
||||
|
@ -280,6 +282,10 @@ public class ModNioResourcePack extends AbstractFileResourcePack implements ModR
|
|||
return name;
|
||||
}
|
||||
|
||||
public Identifier getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
private static boolean exists(Path path) {
|
||||
// NIO Files.exists is notoriously slow when checking the file system
|
||||
return path.getFileSystem() == DEFAULT_FS ? path.toFile().exists() : Files.exists(path);
|
||||
|
|
|
@ -32,6 +32,7 @@ import net.minecraft.resource.DataPackSettings;
|
|||
import net.minecraft.resource.ResourcePack;
|
||||
import net.minecraft.resource.ResourcePackProfile;
|
||||
import net.minecraft.resource.ResourceType;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import net.fabricmc.fabric.api.resource.ModResourcePack;
|
||||
import net.fabricmc.fabric.api.resource.ResourcePackActivationType;
|
||||
|
@ -61,7 +62,7 @@ public final class ModResourcePackUtil {
|
|||
continue;
|
||||
}
|
||||
|
||||
ModResourcePack pack = ModNioResourcePack.create(getName(container.getMetadata()), container, null, type, ResourcePackActivationType.ALWAYS_ENABLED);
|
||||
ModResourcePack pack = ModNioResourcePack.create(new Identifier("fabric", container.getMetadata().getId()), getName(container.getMetadata()), container, null, type, ResourcePackActivationType.ALWAYS_ENABLED);
|
||||
|
||||
if (pack != null) {
|
||||
packs.add(pack);
|
||||
|
|
|
@ -71,8 +71,8 @@ public class ResourceManagerHelperImpl implements ResourceManagerHelper {
|
|||
String separator = container.getRootPath().getFileSystem().getSeparator();
|
||||
subPath = subPath.replace("/", separator);
|
||||
String name = displayName;
|
||||
ModNioResourcePack resourcePack = ModNioResourcePack.create(name, container, subPath, ResourceType.CLIENT_RESOURCES, activationType);
|
||||
ModNioResourcePack dataPack = ModNioResourcePack.create(name, container, subPath, ResourceType.SERVER_DATA, activationType);
|
||||
ModNioResourcePack resourcePack = ModNioResourcePack.create(id, name, container, subPath, ResourceType.CLIENT_RESOURCES, activationType);
|
||||
ModNioResourcePack dataPack = ModNioResourcePack.create(id, name, container, subPath, ResourceType.SERVER_DATA, activationType);
|
||||
if (resourcePack == null && dataPack == null) return false;
|
||||
|
||||
if (resourcePack != null) {
|
||||
|
|
|
@ -42,7 +42,7 @@ public class BuiltinResourcePackTestMod implements ModInitializer {
|
|||
// Should always be present as it's **this** mod.
|
||||
FabricLoader.getInstance().getModContainer(MODID)
|
||||
.map(container -> ResourceManagerHelper.registerBuiltinResourcePack(new Identifier(MODID, "test"),
|
||||
container, "Fabric Resource Loader Test Pack", ResourcePackActivationType.NORMAL))
|
||||
container, "Fabric Resource Loader Test Pack", ResourcePackActivationType.DEFAULT_ENABLED))
|
||||
.filter(success -> !success).ifPresent(success -> LOGGER.warn("Could not register built-in resource pack with custom name."));
|
||||
FabricLoader.getInstance().getModContainer(MODID)
|
||||
.map(container -> ResourceManagerHelper.registerBuiltinResourcePack(new Identifier(MODID, "test2"),
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"pack": {
|
||||
"pack_format": 8,
|
||||
"pack_format": 9,
|
||||
"description": "Fabric Resource Loader Test Builtin Pack."
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue