Update for 1.19.1 with split sources
This commit is contained in:
parent
758c2eff68
commit
5fd4fdad94
|
@ -17,13 +17,14 @@ repositories {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
//TODO move modmenu/frex to client-only once they get remapped
|
||||
modImplementation("net.fabricmc.fabric-api:fabric-api:${project.fabric_version}")
|
||||
modImplementation("com.terraformersmc:modmenu:4.0.0-beta.4")
|
||||
modCompileOnly(modRuntimeOnly("com.terraformersmc:modmenu:4.0.5"))
|
||||
include modImplementation("io.gitlab.jfronny:muscript:${project.muscript_version}")
|
||||
modApi("me.shedaniel.cloth:cloth-config-fabric:7.0.65") {
|
||||
modApi("me.shedaniel.cloth:cloth-config-fabric:7.0.73") {
|
||||
exclude(group: "net.fabricmc.fabric-api")
|
||||
}
|
||||
modCompileOnly "io.vram:frex-fabric-mc119:+"
|
||||
modCompileOnly("io.vram:frex-fabric-mc119:+")
|
||||
modImplementation("io.gitlab.jfronny.libjf:libjf-data-manipulation-v0:${project.jfapi_version}")
|
||||
modRuntimeOnly("io.gitlab.jfronny.libjf:libjf-devutil-v0:${project.jfapi_version}")
|
||||
|
||||
|
@ -35,7 +36,7 @@ dependencies {
|
|||
// }
|
||||
|
||||
// DashLoader "compatibility"
|
||||
// modRuntimeOnly 'dev.quantumfusion.dashloader:dashloader-definitions:3.0-rc14-1.18'
|
||||
// clientRuntimeOnly("dev.quantumfusion.dashloader:dashloader-definitions:3.0-rc14-1.18")
|
||||
}
|
||||
|
||||
test {
|
||||
|
|
|
@ -8,12 +8,12 @@ Respackopts stores configurations next to their corresponding resource packs (`s
|
|||
This file contains all applied config options as saved by respackopts.
|
||||
|
||||
## Dump the internal representation
|
||||
Running `/rpo dump config` will dump all data available about the enabled packs, including their config options (but not individual configurations like .rpo files)
|
||||
Running `/rpoc dump config` will dump all data available about the enabled packs, including their config options (but not individual configurations like .rpo files)
|
||||
|
||||
You can use this if a conf.json isn't working as expected
|
||||
|
||||
## Dump GLSL code
|
||||
You can run the command `/rpo dump glsl` to dump the shader code generated by respackopts to a file.
|
||||
You can run the command `/rpoc dump glsl` to dump the shader code generated by respackopts to a file.
|
||||
|
||||
I recommend reading through it if your shader is misbehaving.
|
||||
The content imported to your shader by the integrations will equal the dumped code.
|
||||
|
|
|
@ -23,5 +23,5 @@ You will then need to include this file in the places you want to access its val
|
|||
|
||||
## Using the values
|
||||
All values respackotps exposes follow the form: `<id>_<entry>` or `<id>_<category>_<entry>`
|
||||
To view the code respackotps generates for your pack, you can run the `/rpo dump glsl` command in minecraft (You must enable the `debugCommands` config option for this).
|
||||
To view the code respackotps generates for your pack, you can run the `/rpoc dump glsl` command in minecraft (You must enable the `debugCommands` config option for this).
|
||||
This will create a frex.frag file in your .minecraft/respackotps directory containing the generated shader code (available since 2.7.0).
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
# https://fabricmc.net/develop/
|
||||
minecraft_version=1.19
|
||||
yarn_mappings=build.2
|
||||
loader_version=0.14.7
|
||||
minecraft_version=1.19.1
|
||||
yarn_mappings=build.1
|
||||
loader_version=0.14.8
|
||||
maven_group=io.gitlab.jfronny
|
||||
archives_base_name=respackopts
|
||||
fabric_version=0.55.3+1.19
|
||||
jfapi_version=2.9.1
|
||||
muscript_version=2022.6.13+11-33-14
|
||||
fabric_version=0.58.5+1.19.1
|
||||
jfapi_version=2.10.0
|
||||
muscript_version=2022.7.4+11-13-3
|
||||
|
||||
modrinth_id=respackopts
|
||||
modrinth_required_dependencies=fabric-api, cloth-config, libjf
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
package io.gitlab.jfronny.respackopts;
|
||||
|
||||
import io.gitlab.jfronny.respackopts.integration.*;
|
||||
import io.gitlab.jfronny.respackopts.util.GuiFactory;
|
||||
import io.gitlab.jfronny.respackopts.util.MetaCache;
|
||||
import net.fabricmc.api.*;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.server.integrated.IntegratedServer;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class RespackoptsClient implements ClientModInitializer, SaveHook {
|
||||
private static final boolean FREX_LOADED = FabricLoader.getInstance().isModLoaded("frex");
|
||||
public static final GuiFactory GUI_FACTORY = new GuiFactory();
|
||||
public static final Identifier RPO_SHADER_ID = new Identifier(Respackopts.ID, "config_supplier");
|
||||
public static boolean forcePackReload = false;
|
||||
private static String shaderImportSource;
|
||||
|
||||
public static String getShaderImportSource() {
|
||||
if (shaderImportSource == null) {
|
||||
Respackopts.LOGGER.error("Shader import source is null");
|
||||
return "";
|
||||
}
|
||||
return shaderImportSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInitializeClient() {
|
||||
if (Respackopts.CONFIG.debugCommands)
|
||||
RpoClientCommand.register();
|
||||
if (FREX_LOADED) {
|
||||
FrexCompat.init();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> onSave(Arguments args) {
|
||||
if (Respackopts.CONFIG.debugLogs)
|
||||
Respackopts.LOGGER.info("Generating shader code");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("#ifndef respackopts_loaded");
|
||||
sb.append("\n#define respackopts_loaded");
|
||||
MetaCache.forEach((key, state) -> state.configBranch().buildShader(sb, Respackopts.sanitizeString(state.packId())));
|
||||
sb.append("\n#endif");
|
||||
RespackoptsClient.shaderImportSource = sb.toString();
|
||||
if (FREX_LOADED) {
|
||||
FrexCompat.handleSave();
|
||||
}
|
||||
|
||||
if (args.flagResourcesForReload()) {
|
||||
forcePackReload = true;
|
||||
DashLoaderCompat.requestForceReload();
|
||||
}
|
||||
List<CompletableFuture<Void>> futures = new ArrayList<>();
|
||||
if (args.reloadResourcesImmediately()) {
|
||||
futures.add(forceReloadResources());
|
||||
}
|
||||
if (args.reloadData()) {
|
||||
futures.add(reloadIntegratedServerData());
|
||||
}
|
||||
return CompletableFuture.allOf(futures.toArray(CompletableFuture[]::new));
|
||||
}
|
||||
|
||||
public static CompletableFuture<Void> forceReloadResources() {
|
||||
forcePackReload = true;
|
||||
DashLoaderCompat.requestForceReload();
|
||||
if (Respackopts.CONFIG.debugLogs) Respackopts.LOGGER.info("Forcing resource reload");
|
||||
return CompletableFuture.allOf(MinecraftClient.getInstance().reloadResources());
|
||||
}
|
||||
|
||||
public static CompletableFuture<Void> reloadIntegratedServerData() {
|
||||
IntegratedServer is = MinecraftClient.getInstance().getServer();
|
||||
if (is != null) {
|
||||
is.getDataPackManager().scanPacks();
|
||||
return is.reloadResources(is.getDataPackManager().getEnabledNames());
|
||||
}
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
package io.gitlab.jfronny.respackopts;
|
||||
|
||||
import com.mojang.brigadier.Command;
|
||||
import io.gitlab.jfronny.respackopts.integration.SaveHook;
|
||||
import io.gitlab.jfronny.respackopts.util.MetaCache;
|
||||
import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback;
|
||||
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
|
||||
import net.fabricmc.loader.api.*;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.nio.file.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal;
|
||||
|
||||
public class RpoClientCommand {
|
||||
private static final Version VERSION = FabricLoader.getInstance().getModContainer(Respackopts.ID).get().getMetadata().getVersion();
|
||||
public static void register() {
|
||||
ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> {
|
||||
Command<FabricClientCommandSource> getVersion = ctx -> {
|
||||
ctx.getSource().sendFeedback(Text.translatable("respackopts.versionText", VERSION, Respackopts.META_VERSION));
|
||||
return 1;
|
||||
};
|
||||
Command<FabricClientCommandSource> dumpConfig = ctx -> {
|
||||
MetaCache.forEach((id, branch) -> ctx.getSource().sendFeedback(dump(branch.toString(), id + ".txt")));
|
||||
return 1;
|
||||
};
|
||||
Command<FabricClientCommandSource> dumpGlsl = ctx -> {
|
||||
ctx.getSource().sendFeedback(dump(RespackoptsClient.getShaderImportSource(), "frex.glsl"));
|
||||
return 1;
|
||||
};
|
||||
Command<FabricClientCommandSource> reload = ctx -> {
|
||||
MetaCache.clear();
|
||||
CompletableFuture.allOf(RespackoptsClient.forceReloadResources(), RespackoptsClient.reloadIntegratedServerData())
|
||||
.thenRun(() -> {
|
||||
ctx.getSource().sendFeedback(Text.translatable("respackopts.reloadSucceeded"));
|
||||
}).exceptionally(e -> {
|
||||
Respackopts.LOGGER.error("Could not reload resources", e);
|
||||
ctx.getSource().sendError(Text.translatable("respackopts.reloadFailed"));
|
||||
return null;
|
||||
});
|
||||
return 1;
|
||||
};
|
||||
dispatcher.register(literal("rpoc").executes(getVersion)
|
||||
.then(literal("dump").executes(dumpConfig)
|
||||
.then(literal("config").executes(dumpConfig))
|
||||
.then(literal("glsl").executes(dumpGlsl)))
|
||||
.then(literal("version").executes(getVersion))
|
||||
.then(literal("reload").executes(reload)));
|
||||
});
|
||||
}
|
||||
|
||||
private static final Path dumpPath = FabricLoader.getInstance().getGameDir().resolve("respackopts");
|
||||
private static Text dump(String text, String fileName) {
|
||||
try {
|
||||
if (!Files.exists(dumpPath)) Files.createDirectories(dumpPath);
|
||||
Path filePath = dumpPath.resolve(fileName);
|
||||
try (BufferedWriter bw = Files.newBufferedWriter(filePath, StandardOpenOption.CREATE)) {
|
||||
bw.write(text);
|
||||
}
|
||||
return Text.translatable("respackopts.dumpSucceeded", filePath.toAbsolutePath());
|
||||
}
|
||||
catch (Throwable e) {
|
||||
Respackopts.LOGGER.error("Could not dump resource", e);
|
||||
return Text.translatable("respackopts.dumpFailed");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package io.gitlab.jfronny.respackopts.integration;
|
||||
|
||||
import io.gitlab.jfronny.respackopts.*;
|
||||
import io.vram.frex.api.config.*;
|
||||
|
||||
public class FrexCompat {
|
||||
public static void init() {
|
||||
ShaderConfig.registerShaderConfigSupplier(RespackoptsClient.RPO_SHADER_ID, RespackoptsClient::getShaderImportSource);
|
||||
Respackopts.LOGGER.info("enabled frex/canvas support");
|
||||
}
|
||||
|
||||
public static void handleSave() {
|
||||
try {
|
||||
ShaderConfig.invalidateShaderConfig();
|
||||
} catch (RuntimeException e) {
|
||||
Respackopts.LOGGER.error("Could not reload shader config", e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@ package io.gitlab.jfronny.respackopts.integration;
|
|||
|
||||
import com.terraformersmc.modmenu.api.ConfigScreenFactory;
|
||||
import com.terraformersmc.modmenu.api.ModMenuApi;
|
||||
import io.gitlab.jfronny.respackopts.RespackoptsClient;
|
||||
import io.gitlab.jfronny.respackopts.util.MetaCache;
|
||||
import io.gitlab.jfronny.respackopts.Respackopts;
|
||||
import io.gitlab.jfronny.respackopts.model.ConfigFile;
|
||||
|
@ -25,12 +26,7 @@ public class ModMenuCompat implements ModMenuApi {
|
|||
PackReloadType.Aggregator agg = new PackReloadType.Aggregator();
|
||||
builder.setSavingRunnable(() -> {
|
||||
if (Respackopts.CONFIG.debugLogs) Respackopts.LOGGER.info("ModMenuCompat SavingRunnable " + agg.get());
|
||||
Respackopts.CONFIG.save();
|
||||
MetaCache.save();
|
||||
if (agg.get() == PackReloadType.Resource) {
|
||||
DashLoaderCompat.requestForceReload();
|
||||
Respackopts.forceReloadResources();
|
||||
}
|
||||
MetaCache.save(agg.get() == PackReloadType.Resource ? SaveHook.Arguments.RELOAD_ALL : SaveHook.Arguments.DO_NOTHING);
|
||||
});
|
||||
//Respackopts config screen
|
||||
ConfigFile defaultConfig = new ConfigFile();
|
||||
|
@ -57,7 +53,7 @@ public class ModMenuCompat implements ModMenuApi {
|
|||
//Pack config screens
|
||||
MetaCache.forEach((key, state) -> {
|
||||
ConfigCategory config = builder.getOrCreateCategory(Text.translatable((state.metadata().version >= 5 ? "rpo." : "respackopts.title.") + state.packId()));
|
||||
Respackopts.GUI_FACTORY.buildCategory(state.configBranch(), state.packId(), config::addEntry, agg, entryBuilder, "");
|
||||
RespackoptsClient.GUI_FACTORY.buildCategory(state.configBranch(), state.packId(), config::addEntry, agg, entryBuilder, "");
|
||||
});
|
||||
return builder.build();
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
package io.gitlab.jfronny.respackopts.mixin;
|
||||
|
||||
import io.gitlab.jfronny.respackopts.Respackopts;
|
||||
import io.gitlab.jfronny.respackopts.RespackoptsClient;
|
||||
import net.minecraft.client.gl.GLImportProcessor;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
|
@ -8,9 +8,9 @@ import org.spongepowered.asm.mixin.injection.ModifyArg;
|
|||
|
||||
@Mixin(GLImportProcessor.class)
|
||||
public class GLImportProcessorMixin {
|
||||
private static final String respackopts$prefix = "\n//include " + Respackopts.RPO_SHADER_ID;
|
||||
private static final String respackopts$prefix = "\n//include " + RespackoptsClient.RPO_SHADER_ID;
|
||||
@ModifyArg(method = "readSource(Ljava/lang/String;)Ljava/util/List;", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gl/GLImportProcessor;parseImports(Ljava/lang/String;Lnet/minecraft/client/gl/GLImportProcessor$Context;Ljava/lang/String;)Ljava/util/List;"), index = 0)
|
||||
private String modify(String value) {
|
||||
return value.replace(respackopts$prefix, "\n" + Respackopts.getShaderImportSource());
|
||||
return value.replace(respackopts$prefix, "\n" + RespackoptsClient.getShaderImportSource());
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package io.gitlab.jfronny.respackopts.mixin;
|
||||
|
||||
import io.gitlab.jfronny.respackopts.Respackopts;
|
||||
import io.gitlab.jfronny.respackopts.RespackoptsClient;
|
||||
import net.minecraft.client.gui.screen.option.OptionsScreen;
|
||||
import net.minecraft.client.option.GameOptions;
|
||||
import net.minecraft.resource.ResourcePackManager;
|
||||
|
@ -17,8 +18,8 @@ public class OptionsScreenMixin {
|
|||
|
||||
@Inject(at = @At("HEAD"), method = "refreshResourcePacks(Lnet/minecraft/resource/ResourcePackManager;)V")
|
||||
private void refreshResourcePacks(ResourcePackManager resourcePackManager, CallbackInfo info) {
|
||||
if (Respackopts.forcePackReload) {
|
||||
Respackopts.forcePackReload = false;
|
||||
if (RespackoptsClient.forcePackReload) {
|
||||
RespackoptsClient.forcePackReload = false;
|
||||
if (Respackopts.CONFIG.debugLogs)
|
||||
Respackopts.LOGGER.info("Clearing loaded resource packs to enable a proper resource reload");
|
||||
this.settings.resourcePacks.clear();
|
|
@ -1,9 +1,9 @@
|
|||
package io.gitlab.jfronny.respackopts.mixin;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import io.gitlab.jfronny.respackopts.RespackoptsClient;
|
||||
import io.gitlab.jfronny.respackopts.model.cache.CacheKey;
|
||||
import io.gitlab.jfronny.respackopts.util.MetaCache;
|
||||
import io.gitlab.jfronny.respackopts.Respackopts;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.DrawableHelper;
|
||||
import net.minecraft.client.gui.screen.pack.PackListWidget;
|
||||
|
@ -18,8 +18,6 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
|||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
@Mixin(PackListWidget.ResourcePackEntry.class)
|
||||
public abstract class ResourcePackEntryMixin {
|
||||
@Final @Shadow private PackListWidget widget;
|
||||
|
@ -48,7 +46,7 @@ public abstract class ResourcePackEntryMixin {
|
|||
if (dataLocation != null && rpo$selected) {
|
||||
info.setReturnValue(true);
|
||||
MinecraftClient c = MinecraftClient.getInstance();
|
||||
c.setScreen(Respackopts.GUI_FACTORY.buildGui(MetaCache.getBranch(dataLocation), MetaCache.getId(dataLocation), c.currentScreen));
|
||||
c.setScreen(RespackoptsClient.GUI_FACTORY.buildGui(MetaCache.getBranch(dataLocation), MetaCache.getId(dataLocation), c.currentScreen));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,25 +1,28 @@
|
|||
package io.gitlab.jfronny.respackopts;
|
||||
package io.gitlab.jfronny.respackopts.util;
|
||||
|
||||
import io.gitlab.jfronny.respackopts.integration.*;
|
||||
import io.gitlab.jfronny.respackopts.model.enums.*;
|
||||
import io.gitlab.jfronny.respackopts.Respackopts;
|
||||
import io.gitlab.jfronny.respackopts.integration.SaveHook;
|
||||
import io.gitlab.jfronny.respackopts.model.enums.PackReloadType;
|
||||
import io.gitlab.jfronny.respackopts.model.tree.*;
|
||||
import io.gitlab.jfronny.respackopts.util.*;
|
||||
import me.shedaniel.clothconfig2.api.*;
|
||||
import net.minecraft.client.gui.screen.*;
|
||||
import net.minecraft.text.*;
|
||||
import net.minecraft.util.*;
|
||||
import net.minecraft.client.gui.screen.FatalErrorScreen;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Language;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.*;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class GuiFactory {
|
||||
public class GuiFactory implements CategoryFactory {
|
||||
@Override
|
||||
public void buildCategory(ConfigBranch source, String screenId, Consumer<AbstractConfigListEntry<?>> config, Consumer<PackReloadType> reloadTypeAggregator, ConfigEntryBuilder entryBuilder, String namePrefix) {
|
||||
for (Map.Entry<String, ConfigEntry<?>> in : source.getValue().entrySet()) {
|
||||
ConfigEntry<?> entry = in.getValue();
|
||||
String entryName = ("".equals(namePrefix) ? "" : namePrefix + ".") + in.getKey();
|
||||
String translationPrefix = (source.getVersion() < 3 ? "respackopts." + entry.getEntryType() + "." : "rpo.") + screenId;
|
||||
config.accept(entry.buildEntry(
|
||||
new GuiEntryBuilderParam(entryBuilder, getText(entryName, translationPrefix), () -> {
|
||||
new GuiEntryBuilderParam(entryBuilder, entryName, () -> {
|
||||
String k = (source.getVersion() < 3 ? "respackopts.tooltip." : "rpo.tooltip.") + screenId + "." + entryName;
|
||||
if (Language.getInstance().hasTranslation(k)) {
|
||||
Text[] res = new Text[1];
|
||||
|
@ -27,35 +30,23 @@ public class GuiFactory {
|
|||
return Optional.of(res);
|
||||
} else
|
||||
return Optional.empty();
|
||||
}, screenId, entryName, translationPrefix, () -> reloadTypeAggregator.accept(entry.getReloadType()), reloadTypeAggregator)));
|
||||
}, screenId, entryName, translationPrefix, () -> reloadTypeAggregator.accept(entry.getReloadType()), reloadTypeAggregator, this)));
|
||||
}
|
||||
}
|
||||
|
||||
public static Text getText(String name, String translationPrefix) {
|
||||
String translatableNameKey = translationPrefix + "." + name;
|
||||
return Language.getInstance().hasTranslation(translatableNameKey)
|
||||
? Text.translatable(translatableNameKey)
|
||||
: Text.literal(name);
|
||||
}
|
||||
|
||||
public Screen buildGui(ConfigBranch source, String packId, Screen parent) {
|
||||
try {
|
||||
ConfigBuilder builder;
|
||||
builder = ConfigBuilder.create()
|
||||
.setParentScreen(parent)
|
||||
.setTitle(getText(packId, source.getVersion() < 4 ? "respackopts.title" : "rpo"));
|
||||
.setTitle(GuiEntryBuilderParam.getText(packId, source.getVersion() < 4 ? "respackopts.title" : "rpo"));
|
||||
ConfigEntryBuilder entryBuilder = builder.entryBuilder();
|
||||
PackReloadType.Aggregator agg = new PackReloadType.Aggregator();
|
||||
builder.setSavingRunnable(() -> {
|
||||
MetaCache.save();
|
||||
if (Respackopts.CONFIG.debugLogs) Respackopts.LOGGER.info("GuiFactory SavingRunnable " + agg.get());
|
||||
if (agg.get() == PackReloadType.Resource) {
|
||||
Respackopts.forcePackReload = true;
|
||||
DashLoaderCompat.requestForceReload();
|
||||
Respackopts.reloadData();
|
||||
}
|
||||
MetaCache.save(new SaveHook.Arguments(agg.get() == PackReloadType.Resource, false, true));
|
||||
});
|
||||
ConfigCategory config = builder.getOrCreateCategory(getText(packId, source.getVersion() < 4 ? "respackopts.title" : "rpo"));
|
||||
ConfigCategory config = builder.getOrCreateCategory(GuiEntryBuilderParam.getText(packId, source.getVersion() < 4 ? "respackopts.title" : "rpo"));
|
||||
buildCategory(source, packId, config::addEntry, agg, entryBuilder, "");
|
||||
return builder.build();
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"required": true,
|
||||
"minVersion": "0.8",
|
||||
"package": "io.gitlab.jfronny.respackopts.mixin",
|
||||
"compatibilityLevel": "JAVA_8",
|
||||
"client": [
|
||||
"GLImportProcessorMixin",
|
||||
"OptionsScreenMixin",
|
||||
"PackScreenMixin",
|
||||
"ResourcePackEntryMixin"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
}
|
||||
}
|
|
@ -1,28 +1,29 @@
|
|||
package io.gitlab.jfronny.respackopts;
|
||||
|
||||
import io.gitlab.jfronny.gson.*;
|
||||
import io.gitlab.jfronny.gson.Gson;
|
||||
import io.gitlab.jfronny.gson.GsonBuilder;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.*;
|
||||
import io.gitlab.jfronny.respackopts.filters.*;
|
||||
import io.gitlab.jfronny.respackopts.filters.DirFilterEventImpl;
|
||||
import io.gitlab.jfronny.respackopts.filters.FileFilterEventImpl;
|
||||
import io.gitlab.jfronny.respackopts.gson.*;
|
||||
import io.gitlab.jfronny.respackopts.gson.entry.*;
|
||||
import io.gitlab.jfronny.respackopts.integration.*;
|
||||
import io.gitlab.jfronny.respackopts.model.*;
|
||||
import io.gitlab.jfronny.respackopts.integration.SaveHook;
|
||||
import io.gitlab.jfronny.respackopts.model.Condition;
|
||||
import io.gitlab.jfronny.respackopts.model.ConfigFile;
|
||||
import io.gitlab.jfronny.respackopts.model.tree.*;
|
||||
import io.gitlab.jfronny.respackopts.util.*;
|
||||
import io.gitlab.jfronny.respackopts.server.ServerInstanceHolder;
|
||||
import net.fabricmc.api.*;
|
||||
import net.fabricmc.loader.api.*;
|
||||
import net.minecraft.client.*;
|
||||
import net.minecraft.server.integrated.*;
|
||||
import net.minecraft.util.*;
|
||||
import org.slf4j.*;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.minecraft.util.Identifier;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.file.*;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class Respackopts implements ClientModInitializer {
|
||||
public class Respackopts implements ModInitializer, SaveHook {
|
||||
public static final Integer META_VERSION = 8;
|
||||
public static final String FILE_EXTENSION = ".rpo";
|
||||
public static final Gson GSON;
|
||||
|
@ -30,14 +31,9 @@ public class Respackopts implements ClientModInitializer {
|
|||
public static final String ID = "respackopts";
|
||||
public static final Logger LOGGER = LoggerFactory.getLogger(ID);
|
||||
public static final Identifier CONF_ID = new Identifier(ID, "conf.json");
|
||||
public static final Set<Runnable> SAVE_ACTIONS = new HashSet<>();
|
||||
public static final GuiFactory GUI_FACTORY = new GuiFactory();
|
||||
|
||||
public static boolean forcePackReload = false;
|
||||
public static Path FALLBACK_CONF_DIR;
|
||||
public static ConfigFile CONFIG;
|
||||
public static final Identifier RPO_SHADER_ID = new Identifier(Respackopts.ID, "config_supplier");
|
||||
private static String shaderImportSource;
|
||||
|
||||
static {
|
||||
GSON = new GsonBuilder()
|
||||
|
@ -61,31 +57,26 @@ public class Respackopts implements ClientModInitializer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onInitializeClient() {
|
||||
public void onInitialize() {
|
||||
try {
|
||||
Files.createDirectories(FALLBACK_CONF_DIR);
|
||||
} catch (IOException e) {
|
||||
LOGGER.error("Could not initialize config directory", e);
|
||||
}
|
||||
if (CONFIG.debugLogs)
|
||||
SAVE_ACTIONS.add(() -> LOGGER.info("Save"));
|
||||
SAVE_ACTIONS.add(() -> {
|
||||
if (CONFIG.debugLogs)
|
||||
LOGGER.info("Generating shader code");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("#ifndef respackopts_loaded");
|
||||
sb.append("\n#define respackopts_loaded");
|
||||
MetaCache.forEach((key, state) -> state.configBranch().buildShader(sb, sanitizeString(state.packId())));
|
||||
sb.append("\n#endif");
|
||||
shaderImportSource = sb.toString();
|
||||
});
|
||||
DirFilterEventImpl.init();
|
||||
FileFilterEventImpl.init();
|
||||
if (CONFIG.debugCommands)
|
||||
RpoCommand.register();
|
||||
if (FabricLoader.getInstance().isModLoaded("frex")) {
|
||||
FrexCompat.onInitializeFrex();
|
||||
ServerInstanceHolder.init();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> onSave(Arguments args) {
|
||||
CONFIG.save();
|
||||
|
||||
if (args.reloadData() && FabricLoader.getInstance().getEnvironmentType() == EnvType.SERVER) {
|
||||
ServerInstanceHolder.reloadResources();
|
||||
}
|
||||
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
|
||||
public static String sanitizeString(String s) {
|
||||
|
@ -99,28 +90,4 @@ public class Respackopts implements ClientModInitializer {
|
|||
// [^a-zA-Z_] = not character or underscore
|
||||
return s.replaceAll("[^a-zA-Z_]|^[\\s_]*|[\\s_]*$", "");
|
||||
}
|
||||
|
||||
public static CompletableFuture<Void> forceReloadResources() {
|
||||
if (CONFIG.debugLogs)
|
||||
LOGGER.info("Forcing resource reload");
|
||||
return CompletableFuture.allOf(MinecraftClient.getInstance().reloadResources(),
|
||||
reloadData());
|
||||
}
|
||||
|
||||
public static CompletableFuture<Void> reloadData() {
|
||||
IntegratedServer is = MinecraftClient.getInstance().getServer();
|
||||
if (is != null) {
|
||||
is.getDataPackManager().scanPacks();
|
||||
return is.reloadResources(is.getDataPackManager().getEnabledNames());
|
||||
}
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
|
||||
public static String getShaderImportSource() {
|
||||
if (shaderImportSource == null) {
|
||||
Respackopts.LOGGER.error("Shader import source is null");
|
||||
return "";
|
||||
}
|
||||
return shaderImportSource;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,54 +0,0 @@
|
|||
package io.gitlab.jfronny.respackopts;
|
||||
|
||||
import io.gitlab.jfronny.respackopts.util.*;
|
||||
import net.fabricmc.fabric.api.client.command.v2.*;
|
||||
import net.fabricmc.loader.api.*;
|
||||
import net.minecraft.text.*;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.file.*;
|
||||
|
||||
import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.*;
|
||||
|
||||
public class RpoCommand {
|
||||
private static final ModContainer CONTAINER = FabricLoader.getInstance().getModContainer(Respackopts.ID).get();
|
||||
public static void register() {
|
||||
ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> {
|
||||
dispatcher.register(literal("rpo").then(literal("dump").then(literal("glsl").executes(ctx -> {
|
||||
ctx.getSource().sendFeedback(dump(Respackopts.getShaderImportSource(), "frex.glsl"));
|
||||
return 1;
|
||||
}))));
|
||||
dispatcher.register(literal("rpo").then(literal("dump").then(literal("config").executes(ctx -> {
|
||||
MetaCache.forEach((id, branch) -> ctx.getSource().sendFeedback(dump(branch.toString(), id + ".txt")));
|
||||
return 1;
|
||||
}))));
|
||||
dispatcher.register(literal("rpo").then(literal("dump").executes(ctx -> {
|
||||
MetaCache.forEach((id, branch) -> ctx.getSource().sendFeedback(dump(branch.toString(), id + ".txt")));
|
||||
return 1;
|
||||
})));
|
||||
dispatcher.register(literal("rpo").then(literal("version").executes(ctx -> {
|
||||
ctx.getSource().sendFeedback(Text.translatable("respackopts.versionText", CONTAINER.getMetadata().getVersion(), Respackopts.META_VERSION));
|
||||
return 1;
|
||||
})));
|
||||
dispatcher.register(literal("rpo").executes(ctx -> {
|
||||
ctx.getSource().sendFeedback(Text.translatable("respackopts.versionText", CONTAINER.getMetadata().getVersion(), Respackopts.META_VERSION));
|
||||
return 1;
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
private static final Path dumpPath = FabricLoader.getInstance().getGameDir().resolve("respackopts");
|
||||
private static Text dump(String text, String fileName) {
|
||||
try {
|
||||
if (!Files.exists(dumpPath)) Files.createDirectories(dumpPath);
|
||||
Path filePath = dumpPath.resolve(fileName);
|
||||
try (BufferedWriter bw = Files.newBufferedWriter(filePath, StandardOpenOption.CREATE)) {
|
||||
bw.write(text);
|
||||
}
|
||||
return Text.translatable("respackopts.dumpSucceeded", filePath.toAbsolutePath());
|
||||
}
|
||||
catch (Throwable e) {
|
||||
return Text.translatable("respackopts.dumpFailed");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,13 +1,13 @@
|
|||
package io.gitlab.jfronny.respackopts.filters.util;
|
||||
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.*;
|
||||
import io.gitlab.jfronny.muscript.dynamic.*;
|
||||
import io.gitlab.jfronny.respackopts.*;
|
||||
import io.gitlab.jfronny.respackopts.util.*;
|
||||
import net.minecraft.resource.*;
|
||||
import io.gitlab.jfronny.commons.data.dynamic.Dynamic;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.StringExpr;
|
||||
import io.gitlab.jfronny.respackopts.Respackopts;
|
||||
import io.gitlab.jfronny.respackopts.util.MetaCache;
|
||||
import net.minecraft.resource.ResourcePack;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.Map;
|
||||
|
||||
public class FileExpansionProvider {
|
||||
public static synchronized InputStream replace(Dynamic<?> parameter, InputStream is, Map<String, StringExpr> expansions) throws IOException {
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
package io.gitlab.jfronny.respackopts.integration;
|
||||
|
||||
import io.gitlab.jfronny.commons.throwable.*;
|
||||
import io.gitlab.jfronny.respackopts.*;
|
||||
import io.vram.frex.api.config.*;
|
||||
|
||||
public class FrexCompat {
|
||||
public static void onInitializeFrex() {
|
||||
ShaderConfig.registerShaderConfigSupplier(Respackopts.RPO_SHADER_ID, Respackopts::getShaderImportSource);
|
||||
Respackopts.LOGGER.info("enabled frex/canvas support");
|
||||
Respackopts.SAVE_ACTIONS.add(Try.handle(ShaderConfig::invalidateShaderConfig, e -> Respackopts.LOGGER.error("Could not reload shader config", e)));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package io.gitlab.jfronny.respackopts.integration;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public interface SaveHook {
|
||||
CompletableFuture<Void> onSave(Arguments args);
|
||||
|
||||
record Arguments(boolean flagResourcesForReload, boolean reloadResourcesImmediately, boolean reloadData) {
|
||||
public static final Arguments DO_NOTHING = new Arguments(false, false, false);
|
||||
public static final Arguments RELOAD_ALL = new Arguments(true, true, true);
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package io.gitlab.jfronny.respackopts.mixin;
|
||||
|
||||
import io.gitlab.jfronny.respackopts.integration.SaveHook;
|
||||
import io.gitlab.jfronny.respackopts.model.cache.CacheKey;
|
||||
import io.gitlab.jfronny.respackopts.util.MetaCache;
|
||||
import io.gitlab.jfronny.respackopts.Respackopts;
|
||||
|
@ -67,6 +68,6 @@ public class ResourcePackManagerMixin {
|
|||
CacheKey k = MetaCache.getKeyByDataLocation(s);
|
||||
if (k != null) MetaCache.remove(k);
|
||||
}
|
||||
MetaCache.save();
|
||||
MetaCache.save(SaveHook.Arguments.DO_NOTHING);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package io.gitlab.jfronny.respackopts.model;
|
||||
|
||||
import io.gitlab.jfronny.commons.data.dynamic.Dynamic;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.*;
|
||||
import io.gitlab.jfronny.muscript.dynamic.*;
|
||||
import io.gitlab.jfronny.muscript.error.*;
|
||||
|
||||
public record Condition(String source, BoolExpr expr) {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package io.gitlab.jfronny.respackopts.model.cache;
|
||||
|
||||
import io.gitlab.jfronny.muscript.*;
|
||||
import io.gitlab.jfronny.muscript.dynamic.*;
|
||||
import io.gitlab.jfronny.muscript.ExpressionParameter;
|
||||
import io.gitlab.jfronny.respackopts.model.DirRpo;
|
||||
import io.gitlab.jfronny.respackopts.model.FileRpo;
|
||||
import io.gitlab.jfronny.respackopts.model.PackMeta;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package io.gitlab.jfronny.respackopts.model.tree;
|
||||
|
||||
import io.gitlab.jfronny.muscript.dynamic.*;
|
||||
import io.gitlab.jfronny.commons.data.dynamic.DBool;
|
||||
import io.gitlab.jfronny.respackopts.Respackopts;
|
||||
import me.shedaniel.clothconfig2.api.AbstractConfigListEntry;
|
||||
|
||||
|
@ -34,17 +34,17 @@ public class ConfigBooleanEntry extends ConfigEntry<Boolean> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public AbstractConfigListEntry<?> buildEntry(GuiEntryBuilderParam guiEntryBuilderParam) {
|
||||
return guiEntryBuilderParam.entryBuilder().startBooleanToggle(guiEntryBuilderParam.name(), getValue())
|
||||
public AbstractConfigListEntry<?> buildEntry(GuiEntryBuilderParam args) {
|
||||
return args.entryBuilder().startBooleanToggle(args.getName(), getValue())
|
||||
.setDefaultValue(getDefault())
|
||||
.setSaveConsumer(value -> {
|
||||
if (getValue() != value) {
|
||||
if (Respackopts.CONFIG.debugLogs) Respackopts.LOGGER.info("ConfigBooleanEntry SaveCallback");
|
||||
guiEntryBuilderParam.saveCallback();
|
||||
args.saveCallback();
|
||||
}
|
||||
setValue(value);
|
||||
})
|
||||
.setTooltipSupplier(guiEntryBuilderParam.tooltipSupplier())
|
||||
.setTooltipSupplier(args.tooltipSupplier())
|
||||
.build();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package io.gitlab.jfronny.respackopts.model.tree;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import io.gitlab.jfronny.commons.data.dynamic.*;
|
||||
import io.gitlab.jfronny.gson.reflect.TypeToken;
|
||||
import io.gitlab.jfronny.muscript.dynamic.*;
|
||||
import io.gitlab.jfronny.respackopts.Respackopts;
|
||||
import io.gitlab.jfronny.respackopts.model.enums.ConfigSyncMode;
|
||||
import io.gitlab.jfronny.respackopts.util.IndentingStringBuilder;
|
||||
|
@ -121,10 +121,10 @@ public class ConfigBranch extends ConfigEntry<Map<String, ConfigEntry<?>>> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public AbstractConfigListEntry<?> buildEntry(GuiEntryBuilderParam guiEntryBuilderParam) {
|
||||
SubCategoryBuilder sc = guiEntryBuilderParam.entryBuilder().startSubCategory(guiEntryBuilderParam.name());
|
||||
Respackopts.GUI_FACTORY.buildCategory(this, guiEntryBuilderParam.screenId(), sc::add, guiEntryBuilderParam.agg(), guiEntryBuilderParam.entryBuilder(), guiEntryBuilderParam.entryName());
|
||||
sc.setTooltipSupplier(guiEntryBuilderParam.tooltipSupplier());
|
||||
public AbstractConfigListEntry<?> buildEntry(GuiEntryBuilderParam args) {
|
||||
SubCategoryBuilder sc = args.entryBuilder().startSubCategory(args.getName());
|
||||
args.buildCategory(this, args.screenId(), sc::add, args.agg(), args.entryBuilder(), args.entryName());
|
||||
sc.setTooltipSupplier(args.tooltipSupplier());
|
||||
return sc.build();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package io.gitlab.jfronny.respackopts.model.tree;
|
||||
|
||||
import io.gitlab.jfronny.muscript.dynamic.*;
|
||||
import io.gitlab.jfronny.commons.data.dynamic.Dynamic;
|
||||
import io.gitlab.jfronny.respackopts.Respackopts;
|
||||
import io.gitlab.jfronny.respackopts.model.enums.ConfigSyncMode;
|
||||
import io.gitlab.jfronny.respackopts.model.enums.PackReloadType;
|
||||
|
@ -104,7 +104,7 @@ public abstract class ConfigEntry<T> {
|
|||
|
||||
public abstract Dynamic<?> getDynamic();
|
||||
|
||||
public abstract AbstractConfigListEntry<?> buildEntry(GuiEntryBuilderParam guiEntryBuilderParam);
|
||||
public abstract AbstractConfigListEntry<?> buildEntry(GuiEntryBuilderParam args);
|
||||
|
||||
public String getEntryType() {
|
||||
return "field";
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
package io.gitlab.jfronny.respackopts.model.tree;
|
||||
|
||||
import io.gitlab.jfronny.muscript.dynamic.*;
|
||||
import io.gitlab.jfronny.respackopts.*;
|
||||
import io.gitlab.jfronny.respackopts.model.enums.*;
|
||||
import io.gitlab.jfronny.respackopts.util.*;
|
||||
import me.shedaniel.clothconfig2.api.*;
|
||||
import net.minecraft.text.*;
|
||||
import io.gitlab.jfronny.commons.data.dynamic.DEnum;
|
||||
import io.gitlab.jfronny.respackopts.Respackopts;
|
||||
import io.gitlab.jfronny.respackopts.model.enums.ConfigSyncMode;
|
||||
import io.gitlab.jfronny.respackopts.util.IndentingStringBuilder;
|
||||
import me.shedaniel.clothconfig2.api.AbstractConfigListEntry;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.*;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class ConfigEnumEntry extends ConfigEntry<String> {
|
||||
public List<String> values = new ArrayList<>();
|
||||
|
@ -118,15 +118,14 @@ public class ConfigEnumEntry extends ConfigEntry<String> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public AbstractConfigListEntry<?> buildEntry(GuiEntryBuilderParam guiEntryBuilderParam) {
|
||||
Function<String, Text> entryText = s -> GuiFactory.getText(s, ("".equals(guiEntryBuilderParam.translationPrefix()) ? "" : guiEntryBuilderParam.translationPrefix() + ".") + guiEntryBuilderParam.entryName());
|
||||
public AbstractConfigListEntry<?> buildEntry(GuiEntryBuilderParam args) {
|
||||
Map<String, String> translationReverseLookup = new HashMap<>();
|
||||
for (String value : values) {
|
||||
translationReverseLookup.put(entryText.apply(value).getString(), value);
|
||||
translationReverseLookup.put(args.prefixWithName(value).getString(), value);
|
||||
}
|
||||
return guiEntryBuilderParam.entryBuilder().startStringDropdownMenu(guiEntryBuilderParam.name(), entryText.apply(getValue()).getString(), entryText)
|
||||
return args.entryBuilder().startStringDropdownMenu(args.getName(), args.prefixWithName(getValue()).getString(), args::prefixWithName)
|
||||
.setSuggestionMode(false)
|
||||
.setDefaultValue(entryText.apply(getDefault()).getString())
|
||||
.setDefaultValue(args.prefixWithName(getDefault()).getString())
|
||||
.setSelections(translationReverseLookup.keySet())
|
||||
.setSaveConsumer(value -> {
|
||||
if (!translationReverseLookup.containsKey(value)) {
|
||||
|
@ -136,11 +135,11 @@ public class ConfigEnumEntry extends ConfigEntry<String> {
|
|||
value = translationReverseLookup.get(value);
|
||||
if (!Objects.equals(getValue(), value)) {
|
||||
if (Respackopts.CONFIG.debugLogs) Respackopts.LOGGER.info("ConfigEnumEntry SaveCallback");
|
||||
guiEntryBuilderParam.saveCallback();
|
||||
args.saveCallback();
|
||||
}
|
||||
setValue(value);
|
||||
})
|
||||
.setTooltipSupplier(guiEntryBuilderParam.tooltipSupplier())
|
||||
.setTooltipSupplier(args.tooltipSupplier())
|
||||
.build();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package io.gitlab.jfronny.respackopts.model.tree;
|
||||
|
||||
import io.gitlab.jfronny.muscript.dynamic.*;
|
||||
import io.gitlab.jfronny.commons.data.dynamic.DNumber;
|
||||
import io.gitlab.jfronny.respackopts.Respackopts;
|
||||
import io.gitlab.jfronny.respackopts.model.enums.ConfigSyncMode;
|
||||
import io.gitlab.jfronny.respackopts.model.enums.NumericEntryType;
|
||||
|
@ -72,32 +72,32 @@ public class ConfigNumericEntry extends ConfigEntry<Double> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public AbstractConfigListEntry<?> buildEntry(GuiEntryBuilderParam guiEntryBuilderParam) {
|
||||
public AbstractConfigListEntry<?> buildEntry(GuiEntryBuilderParam args) {
|
||||
if (type == NumericEntryType.Slider) {
|
||||
return guiEntryBuilderParam.entryBuilder().startIntSlider(guiEntryBuilderParam.name(),
|
||||
return args.entryBuilder().startIntSlider(args.getName(),
|
||||
getValue().intValue(), min.intValue(), max.intValue())
|
||||
.setDefaultValue(getDefault().intValue())
|
||||
.setSaveConsumer(value -> {
|
||||
if (!Objects.equals(getValue(), value.doubleValue())) {
|
||||
if (Respackopts.CONFIG.debugLogs) Respackopts.LOGGER.info("ConfigNumericEntrySlider SaveCallback");
|
||||
guiEntryBuilderParam.saveCallback();
|
||||
args.saveCallback();
|
||||
}
|
||||
setValue(value.doubleValue());
|
||||
})
|
||||
.setTooltipSupplier(guiEntryBuilderParam.tooltipSupplier())
|
||||
.setTooltipSupplier(args.tooltipSupplier())
|
||||
.build();
|
||||
}
|
||||
else {
|
||||
DoubleFieldBuilder builder = guiEntryBuilderParam.entryBuilder().startDoubleField(guiEntryBuilderParam.name(), getValue())
|
||||
DoubleFieldBuilder builder = args.entryBuilder().startDoubleField(args.getName(), getValue())
|
||||
.setDefaultValue(getDefault())
|
||||
.setSaveConsumer(value -> {
|
||||
if (!Objects.equals(getValue(), value)) {
|
||||
if (Respackopts.CONFIG.debugLogs) Respackopts.LOGGER.info("ConfigNumericEntryNormal SaveCallback");
|
||||
guiEntryBuilderParam.saveCallback();
|
||||
args.saveCallback();
|
||||
}
|
||||
setValue(value);
|
||||
})
|
||||
.setTooltipSupplier(guiEntryBuilderParam.tooltipSupplier());
|
||||
.setTooltipSupplier(args.tooltipSupplier());
|
||||
if (min != null) builder.setMin(min);
|
||||
if (max != null) builder.setMax(max);
|
||||
return builder.build();
|
||||
|
|
|
@ -1,17 +1,45 @@
|
|||
package io.gitlab.jfronny.respackopts.model.tree;
|
||||
|
||||
import io.gitlab.jfronny.respackopts.model.enums.PackReloadType;
|
||||
import io.gitlab.jfronny.respackopts.util.CategoryFactory;
|
||||
import me.shedaniel.clothconfig2.api.AbstractConfigListEntry;
|
||||
import me.shedaniel.clothconfig2.api.ConfigEntryBuilder;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Language;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public record GuiEntryBuilderParam(ConfigEntryBuilder entryBuilder, Text name,
|
||||
public record GuiEntryBuilderParam(ConfigEntryBuilder entryBuilder, String name,
|
||||
Supplier<Optional<Text[]>> tooltipSupplier, String screenId, String entryName,
|
||||
String translationPrefix, Runnable onSave, Consumer<PackReloadType> agg) {
|
||||
String translationPrefix, Runnable onSave, Consumer<PackReloadType> agg,
|
||||
CategoryFactory categoryFactory) implements CategoryFactory {
|
||||
public void saveCallback() {
|
||||
onSave.run();
|
||||
}
|
||||
|
||||
public Text getName() {
|
||||
return getText(name);
|
||||
}
|
||||
|
||||
public Text prefixWithName(String subName) {
|
||||
return getText(subName, translationPrefix.equals("") ? name : translationPrefix + "." + name);
|
||||
}
|
||||
|
||||
public Text getText(String name) {
|
||||
return getText(name, translationPrefix);
|
||||
}
|
||||
|
||||
public static Text getText(String name, String translationPrefix) {
|
||||
String translatableNameKey = translationPrefix + "." + name;
|
||||
return Language.getInstance().hasTranslation(translatableNameKey)
|
||||
? Text.translatable(translatableNameKey)
|
||||
: Text.literal(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void buildCategory(ConfigBranch source, String screenId, Consumer<AbstractConfigListEntry<?>> config, Consumer<PackReloadType> reloadTypeAggregator, ConfigEntryBuilder entryBuilder, String namePrefix) {
|
||||
categoryFactory.buildCategory(source, screenId, config, reloadTypeAggregator, entryBuilder, namePrefix);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
package io.gitlab.jfronny.respackopts.server;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import io.gitlab.jfronny.commons.ref.WeakSet;
|
||||
import io.gitlab.jfronny.respackopts.Respackopts;
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
|
||||
import net.minecraft.resource.ResourcePackManager;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.world.SaveProperties;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class ServerInstanceHolder {
|
||||
private static final Set<MinecraftServer> SERVERS = new WeakSet<>();
|
||||
|
||||
public static void init() {
|
||||
ServerLifecycleEvents.SERVER_STARTED.register(server -> {
|
||||
if (!SERVERS.isEmpty()) {
|
||||
Respackopts.LOGGER.warn("Multiple servers started at once. This is unexpected");
|
||||
}
|
||||
if (!SERVERS.add(server)) {
|
||||
Respackopts.LOGGER.warn("Called SERVER_STARTED on a server that is already started");
|
||||
}
|
||||
});
|
||||
ServerLifecycleEvents.SERVER_STOPPED.register(server -> {
|
||||
if (!SERVERS.remove(server)) {
|
||||
Respackopts.LOGGER.warn("Called SERVER_STOPPED on a server that was never started/already stopped");
|
||||
}
|
||||
if (!SERVERS.isEmpty()) {
|
||||
Respackopts.LOGGER.warn("Server stopped but another one is still running. This is unexpected");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void reloadResources() {
|
||||
if (SERVERS.isEmpty()) {
|
||||
Respackopts.LOGGER.warn("Attempted to reload resources while no server is running. Skipping");
|
||||
}
|
||||
for (MinecraftServer server : SERVERS) {
|
||||
ResourcePackManager manager = server.getDataPackManager();
|
||||
SaveProperties saveProperties = server.getSaveProperties();
|
||||
List<String> enabled = Lists.newArrayList(manager.getEnabledNames());
|
||||
manager.scanPacks();
|
||||
List<String> disabled = saveProperties.getDataPackSettings().getDisabled();
|
||||
for (String name : manager.getNames()) {
|
||||
if (!disabled.contains(name) && !enabled.contains(name)) {
|
||||
enabled.add(name);
|
||||
}
|
||||
}
|
||||
server.reloadResources(enabled).exceptionally(throwable -> {
|
||||
Respackopts.LOGGER.warn("Failed to reload data packs", throwable);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package io.gitlab.jfronny.respackopts.util;
|
||||
|
||||
import io.gitlab.jfronny.respackopts.model.enums.PackReloadType;
|
||||
import io.gitlab.jfronny.respackopts.model.tree.ConfigBranch;
|
||||
import me.shedaniel.clothconfig2.api.AbstractConfigListEntry;
|
||||
import me.shedaniel.clothconfig2.api.ConfigEntryBuilder;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public interface CategoryFactory {
|
||||
void buildCategory(ConfigBranch source, String screenId, Consumer<AbstractConfigListEntry<?>> config, Consumer<PackReloadType> reloadTypeAggregator, ConfigEntryBuilder entryBuilder, String namePrefix);
|
||||
}
|
|
@ -1,21 +1,25 @@
|
|||
package io.gitlab.jfronny.respackopts.util;
|
||||
|
||||
import io.gitlab.jfronny.commons.throwable.*;
|
||||
import io.gitlab.jfronny.muscript.*;
|
||||
import io.gitlab.jfronny.muscript.dynamic.*;
|
||||
import io.gitlab.jfronny.respackopts.*;
|
||||
import io.gitlab.jfronny.respackopts.model.*;
|
||||
import io.gitlab.jfronny.respackopts.model.cache.*;
|
||||
import io.gitlab.jfronny.respackopts.model.enums.*;
|
||||
import io.gitlab.jfronny.respackopts.model.tree.*;
|
||||
import net.fabricmc.loader.api.*;
|
||||
import net.fabricmc.loader.api.metadata.version.*;
|
||||
import net.minecraft.resource.*;
|
||||
import org.jetbrains.annotations.*;
|
||||
import io.gitlab.jfronny.commons.throwable.ThrowingBiConsumer;
|
||||
import io.gitlab.jfronny.muscript.ExpressionParameter;
|
||||
import io.gitlab.jfronny.respackopts.Respackopts;
|
||||
import io.gitlab.jfronny.respackopts.integration.SaveHook;
|
||||
import io.gitlab.jfronny.respackopts.model.PackMeta;
|
||||
import io.gitlab.jfronny.respackopts.model.cache.CacheKey;
|
||||
import io.gitlab.jfronny.respackopts.model.cache.CachedPackState;
|
||||
import io.gitlab.jfronny.respackopts.model.enums.ConfigSyncMode;
|
||||
import io.gitlab.jfronny.respackopts.model.enums.PackCapability;
|
||||
import io.gitlab.jfronny.respackopts.model.tree.ConfigBranch;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.minecraft.resource.ResourcePack;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.file.*;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class MetaCache {
|
||||
private static final Map<CacheKey, CachedPackState> PACK_STATES = new HashMap<>();
|
||||
|
@ -32,6 +36,13 @@ public class MetaCache {
|
|||
PACK_STATES.remove(key);
|
||||
}
|
||||
|
||||
public static void clear() {
|
||||
PACK_STATES.clear();
|
||||
KEYS_BY_DISPLAY_NAME.clear();
|
||||
KEYS_BY_PACK_NAME.clear();
|
||||
KEYS_BY_DATA_LOCATION.clear();
|
||||
}
|
||||
|
||||
public static void addFromScan(String displayName, String packName, PackMeta meta, Path dataLocation) {
|
||||
if (Respackopts.META_VERSION > meta.version) {
|
||||
Respackopts.LOGGER.warn(displayName + " uses an outdated RPO format (" + meta.version + "). Although this is supported, using the latest version (" + Respackopts.META_VERSION + ") is recommended");
|
||||
|
@ -69,15 +80,22 @@ public class MetaCache {
|
|||
save(dataLocation, meta.conf);
|
||||
}
|
||||
|
||||
public static void save() {
|
||||
public static CompletableFuture<Void> save(SaveHook.Arguments args) {
|
||||
if (Respackopts.CONFIG.debugLogs)
|
||||
Respackopts.LOGGER.info("Saving configs");
|
||||
for (Map.Entry<CacheKey, CachedPackState> e : PACK_STATES.entrySet()) {
|
||||
save(e.getKey().dataLocation(), e.getValue().configBranch());
|
||||
}
|
||||
for (Runnable action : Respackopts.SAVE_ACTIONS) {
|
||||
action.run();
|
||||
List<CompletableFuture<Void>> futures = new ArrayList<>();
|
||||
for (SaveHook hook : FabricLoader.getInstance().getEntrypoints(Respackopts.ID + ":save_hook", SaveHook.class)) {
|
||||
futures.add(hook.onSave(args));
|
||||
}
|
||||
if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT) {
|
||||
for (SaveHook hook : FabricLoader.getInstance().getEntrypoints(Respackopts.ID + ":client_save_hook", SaveHook.class)) {
|
||||
futures.add(hook.onSave(args));
|
||||
}
|
||||
}
|
||||
return CompletableFuture.allOf(futures.toArray(CompletableFuture[]::new));
|
||||
}
|
||||
|
||||
private static void save(Path dataLocation, ConfigBranch branch) {
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
package io.gitlab.jfronny.respackopts.util;
|
||||
|
||||
import io.gitlab.jfronny.muscript.*;
|
||||
import io.gitlab.jfronny.muscript.dynamic.*;
|
||||
import net.fabricmc.loader.api.*;
|
||||
import net.fabricmc.loader.api.metadata.version.*;
|
||||
import io.gitlab.jfronny.commons.data.dynamic.*;
|
||||
import io.gitlab.jfronny.muscript.ExpressionParameter;
|
||||
import io.gitlab.jfronny.muscript.StandardLib;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.fabricmc.loader.api.VersionParsingException;
|
||||
import net.fabricmc.loader.api.metadata.version.VersionPredicate;
|
||||
|
||||
import java.time.*;
|
||||
import java.util.*;
|
||||
import java.util.function.*;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalTime;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class MuUtils {
|
||||
public static ExpressionParameter addDefault(ExpressionParameter parameter) {
|
||||
|
|
|
@ -7,7 +7,9 @@
|
|||
"respackopts.mainconfig.debugLogs": "Debug Logs",
|
||||
"respackopts.mainconfig.dashloaderCompat": "Dashloader compatibility",
|
||||
"respackopts.invalid": "Invalid value",
|
||||
"respackopts.dumpFailed": "Could not dump the requested resource, look at your log for details",
|
||||
"respackopts.dumpSucceeded": "Successfully dumped the resource to %s",
|
||||
"respackopts.dumpFailed": "Could not dump the requested resource, look at your log for details",
|
||||
"respackopts.reloadSucceeded": "Successfully reloaded resources and data",
|
||||
"respackopts.reloadFailed": "Could not reload all resources, look at your log for details",
|
||||
"respackopts.versionText": "Version %s using the respackotps meta version %s"
|
||||
}
|
|
@ -12,24 +12,37 @@
|
|||
"icon": "assets/respackopts/icon.png",
|
||||
"environment": "client",
|
||||
"entrypoints": {
|
||||
"client": [
|
||||
"main": [
|
||||
"io.gitlab.jfronny.respackopts.Respackopts"
|
||||
],
|
||||
"client": [
|
||||
"io.gitlab.jfronny.respackopts.RespackoptsClient"
|
||||
],
|
||||
"modmenu": [
|
||||
"io.gitlab.jfronny.respackopts.integration.ModMenuCompat"
|
||||
],
|
||||
"frex": [
|
||||
"io.gitlab.jfronny.respackopts.integration.FrexCompat"
|
||||
],
|
||||
"respackopts:save_hook": [
|
||||
"io.gitlab.jfronny.respackopts.Respackopts"
|
||||
],
|
||||
"respackopts:client_save_hook": [
|
||||
"io.gitlab.jfronny.respackopts.RespackoptsClient"
|
||||
]
|
||||
},
|
||||
"mixins": [
|
||||
"respackopts.mixins.json"
|
||||
"respackopts.mixins.json",
|
||||
{
|
||||
"config": "respackopts.client.mixins.json",
|
||||
"environment": "client"
|
||||
}
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.12.0",
|
||||
"fabric": "*",
|
||||
"minecraft": "*",
|
||||
"cloth-config2": ">=5.0.0",
|
||||
"cloth-config2": ">=7.0.0",
|
||||
"libjf-data-manipulation-v0": ">=2.0",
|
||||
"libjf-base": ">=2.0"
|
||||
},
|
||||
|
|
|
@ -7,12 +7,6 @@
|
|||
"AbstractFileResourcePackAccessor",
|
||||
"ResourcePackManagerMixin"
|
||||
],
|
||||
"client": [
|
||||
"GLImportProcessorMixin",
|
||||
"OptionsScreenMixin",
|
||||
"PackScreenMixin",
|
||||
"ResourcePackEntryMixin"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue