Update to 1.19.4 and use Scope.fork instead of mutating a shared scope
All checks were successful
ci/woodpecker/push/docs Pipeline was successful
ci/woodpecker/push/jfmod Pipeline was successful

This commit is contained in:
Johannes Frohnmeyer 2023-03-14 20:03:36 +01:00
parent 9340f981fc
commit 42891f36c4
Signed by: Johannes
GPG Key ID: E76429612C2929F4
16 changed files with 112 additions and 180 deletions

View File

@ -27,7 +27,7 @@ dependencies {
modLocalRuntime("io.gitlab.jfronny.libjf:libjf-devutil:${prop("libjf_version")}") {
exclude("net.fabricmc") // required to work around duplicate fabric loaders
}
modLocalRuntime("com.terraformersmc:modmenu:5.0.2") {
modLocalRuntime("com.terraformersmc:modmenu:6.1.0-rc.1") {
exclude("net.fabricmc") // required to work around duplicate fabric loaders
}

View File

@ -1,7 +1,7 @@
# https://fabricmc.net/develop/
minecraft_version=1.19.3
yarn_mappings=build.5
loader_version=0.14.15
minecraft_version=1.19.4
yarn_mappings=build.1
loader_version=0.14.17
maven_group=io.gitlab.jfronny
archives_base_name=respackopts
@ -13,6 +13,6 @@ curseforge_id=430090
curseforge_required_dependencies=fabric-api, libjf
curseforge_optional_dependencies=modmenu
fabric_version=0.75.0+1.19.3
libjf_version=3.5.0
muscript_version=1.1-SNAPSHOT
fabric_version=0.75.3+1.19.4
libjf_version=3.6.0
muscript_version=1.2-SNAPSHOT

View File

@ -1,15 +1,15 @@
package io.gitlab.jfronny.respackopts.mixin;
import io.gitlab.jfronny.respackopts.RespackoptsClient;
import net.minecraft.client.gl.GLImportProcessor;
import net.minecraft.client.gl.GlImportProcessor;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyArg;
@Mixin(GLImportProcessor.class)
public class GLImportProcessorMixin {
@Mixin(GlImportProcessor.class)
public class GlImportProcessorMixin {
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)
@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" + RespackoptsClient.getShaderImportSource());
}

View File

@ -2,7 +2,8 @@ package io.gitlab.jfronny.respackopts.mixin;
import com.google.common.collect.ImmutableMap;
import io.gitlab.jfronny.respackopts.util.FallbackI18n;
import net.minecraft.client.resource.language.*;
import net.minecraft.client.resource.language.LanguageManager;
import net.minecraft.client.resource.language.TranslationStorage;
import net.minecraft.resource.ResourceManager;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
@ -14,8 +15,8 @@ import java.util.*;
@Mixin(LanguageManager.class)
public class LanguageManagerMixin {
@Inject(method = "reload(Lnet/minecraft/resource/ResourceManager;)V", at = @At("TAIL"), locals = LocalCapture.CAPTURE_FAILSOFT)
private void rpo$appendTranslations(ResourceManager manager, CallbackInfo ci, LanguageDefinition languageDefinition, List<LanguageDefinition> list, TranslationStorage translationStorage) {
@Inject(method = "reload(Lnet/minecraft/resource/ResourceManager;)V", at = @At("TAIL"), locals = LocalCapture.CAPTURE_FAILEXCEPTION)
private void rpo$appendTranslations(ResourceManager manager, CallbackInfo ci, List<String> list, boolean bl, TranslationStorage translationStorage) {
TranslationStorageAccessor storage = (TranslationStorageAccessor) translationStorage;
Map<String, String> map = new HashMap<>(storage.getTranslations());
FallbackI18n.insertInto(map);

View File

@ -4,7 +4,7 @@
"package": "io.gitlab.jfronny.respackopts.mixin",
"compatibilityLevel": "JAVA_8",
"client": [
"GLImportProcessorMixin",
"GlImportProcessorMixin",
"LanguageManagerMixin",
"OptionsScreenMixin",
"PackScreenMixin",

View File

@ -4,7 +4,10 @@ import io.gitlab.jfronny.commons.log.Logger;
import io.gitlab.jfronny.gson.Gson;
import io.gitlab.jfronny.gson.GsonBuilder;
import io.gitlab.jfronny.libjf.config.api.v1.ConfigHolder;
import io.gitlab.jfronny.muscript.StandardLib;
import io.gitlab.jfronny.muscript.ast.*;
import io.gitlab.jfronny.muscript.data.Scope;
import io.gitlab.jfronny.muscript.data.dynamic.additional.DFinal;
import io.gitlab.jfronny.respackopts.filters.DirFilterEvents;
import io.gitlab.jfronny.respackopts.filters.FileFilterEvents;
import io.gitlab.jfronny.respackopts.gson.*;
@ -16,6 +19,8 @@ import io.gitlab.jfronny.respackopts.server.ServerInstanceHolder;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.loader.api.FabricLoader;
import net.fabricmc.loader.api.VersionParsingException;
import net.fabricmc.loader.api.metadata.version.VersionPredicate;
import java.io.IOException;
import java.nio.file.Files;
@ -38,6 +43,23 @@ public class Respackopts implements ModInitializer, SaveHook {
.setPrettyPrinting()
.create();
public static final Scope ROOT_SCOPE = StandardLib.createScope();
static {
ROOT_SCOPE.set("version", args -> {
if (args.size() != 2) throw new IllegalArgumentException("Expected 2 arguments on version but got " + args.size());
VersionPredicate predicate;
try {
predicate = VersionPredicate.parse(args.get(1).asString().getValue());
} catch (VersionParsingException e) {
throw new IllegalArgumentException("Could not parse version predicate", e);
}
return DFinal.of(FabricLoader.getInstance().getModContainer(args.get(0).asString().getValue())
.map(c -> predicate.test(c.getMetadata().getVersion()))
.orElse(false));
});
}
public static final String ID = "respackopts";
public static final Logger LOGGER = Logger.forName(ID);

View File

@ -75,7 +75,7 @@ public enum DirFilterEvents implements UserResourceEvents.Open, UserResourceEven
if (rpo.condition == null)
return false;
try {
return !rpo.condition.get(MetaCache.getParameter(key));
return !rpo.condition.get(MetaCache.getScope(key));
} catch (Condition.ConditionException e) {
String res = "Could not evaluate condition " + file + " (pack: " + key.packName() + ")";
try {

View File

@ -14,7 +14,7 @@ public class FileExclusionProvider {
return false;
CacheKey key = MetaCache.getKeyByPack(pack);
try {
return !rpo.condition.get(MetaCache.getParameter(key));
return !rpo.condition.get(MetaCache.getScope(key));
} catch (Condition.ConditionException e) {
String res = "Could not evaluate condition " + file + " (pack: " + key.packName() + ")";
try {

View File

@ -21,7 +21,7 @@ public class FileExpansionProvider {
public static InputSupplier<InputStream> replace(InputSupplier<InputStream> inputStream, ResourcePack pack, String file) {
return FileRpoSearchProvider.modifyWithRpo(file, pack, rpo -> rpo.expansions == null || rpo.expansions.isEmpty() ? inputStream : () -> {
try (InputStream is = inputStream.get()) {
return replace(MetaCache.getParameter(MetaCache.getKeyByPack(pack)), is, rpo.expansions);
return replace(MetaCache.getScope(MetaCache.getKeyByPack(pack)), is, rpo.expansions);
}
}, inputStream);
}

View File

@ -1,6 +1,6 @@
package io.gitlab.jfronny.respackopts.model;
import io.gitlab.jfronny.commons.serialize.gson.api.Ignore;
import io.gitlab.jfronny.commons.serialize.gson.api.v1.Ignore;
import io.gitlab.jfronny.gson.annotations.SerializedName;
public class DirRpo {

View File

@ -1,6 +1,6 @@
package io.gitlab.jfronny.respackopts.model;
import io.gitlab.jfronny.commons.serialize.gson.api.Ignore;
import io.gitlab.jfronny.commons.serialize.gson.api.v1.Ignore;
import io.gitlab.jfronny.gson.annotations.SerializedName;
import io.gitlab.jfronny.muscript.ast.StringExpr;

View File

@ -1,6 +1,7 @@
package io.gitlab.jfronny.respackopts.model.cache;
import io.gitlab.jfronny.muscript.data.Scope;
import io.gitlab.jfronny.respackopts.Respackopts;
import io.gitlab.jfronny.respackopts.model.*;
import io.gitlab.jfronny.respackopts.model.tree.ConfigBranch;
@ -18,13 +19,15 @@ public record CachedPackState(
Scope executionScope
) {
public CachedPackState(CacheKey key, PackMeta meta, ConfigBranch branch) {
this(meta.id,
this(
meta.id,
key.displayName(),
key.packName(),
branch,
meta,
new HashMap<>(),
new HashMap<>(),
new Scope(branch.getDynamic()));
branch.addTo(Respackopts.ROOT_SCOPE.fork())
);
}
}

View File

@ -4,7 +4,9 @@ import com.google.common.collect.ImmutableMap;
import io.gitlab.jfronny.gson.reflect.TypeToken;
import io.gitlab.jfronny.libjf.config.api.v1.dsl.CategoryBuilder;
import io.gitlab.jfronny.libjf.config.api.v1.dsl.ConfigBuilder;
import io.gitlab.jfronny.muscript.data.Scope;
import io.gitlab.jfronny.muscript.data.dynamic.*;
import io.gitlab.jfronny.muscript.data.dynamic.additional.DFinal;
import io.gitlab.jfronny.respackopts.Respackopts;
import io.gitlab.jfronny.respackopts.RespackoptsConfig;
import io.gitlab.jfronny.respackopts.integration.SaveHook;
@ -26,8 +28,9 @@ public class ConfigBranch extends ConfigEntry<Map<String, ConfigEntry<?>>> {
public void sync(ConfigEntry<Map<String, ConfigEntry<?>>> source, ConfigSyncMode mode) {
for (Map.Entry<String, ConfigEntry<?>> e : source.getValue().entrySet()) {
if (!has(e.getKey())) {
if (mode == ConfigSyncMode.RESPACK_LOAD)
if (mode == ConfigSyncMode.RESPACK_LOAD) {
add(e.getKey(), e.getValue().clone());
}
} else {
ConfigEntry<?> current = get(e.getKey());
if (e.getValue().getEntryClass().equals(current.getEntryClass())) {
@ -42,11 +45,13 @@ public class ConfigBranch extends ConfigEntry<Map<String, ConfigEntry<?>>> {
}
}
}
if (mode == ConfigSyncMode.RESPACK_LOAD)
for (Map.Entry<String, ConfigEntry<?>> e : getValue().entrySet()) {
if (!source.getValue().containsKey(e.getKey()))
super.getValue().remove(e.getKey());
}
if (mode == ConfigSyncMode.RESPACK_LOAD) {
getValue().forEach((key, value) -> {
if (!source.getValue().containsKey(key)) {
super.getValue().remove(key);
}
});
}
}
private <T> void syncSub(ConfigEntry<T> current, ConfigEntry<T> next, ConfigSyncMode mode) {
@ -65,8 +70,9 @@ public class ConfigBranch extends ConfigEntry<Map<String, ConfigEntry<?>>> {
public String getEntryName(ConfigEntry<?> entry) {
for (Map.Entry<String, ConfigEntry<?>> e : getValue().entrySet()) {
if (e.getValue() == entry)
if (e.getValue() == entry) {
return e.getKey();
}
}
throw new IndexOutOfBoundsException();
}
@ -82,26 +88,33 @@ public class ConfigBranch extends ConfigEntry<Map<String, ConfigEntry<?>>> {
@Override
public void buildShader(StringBuilder sb, String valueName) {
for (Map.Entry<String, ConfigEntry<?>> e : super.getValue().entrySet()) {
e.getValue().buildShader(sb, valueName + "_" + Respackopts.sanitizeString(e.getKey()));
}
super.getValue().forEach((key, value) -> {
value.buildShader(sb, valueName + "_" + Respackopts.sanitizeString(key));
});
}
@Override
public DObject getDynamic() {
Map<String, Dynamic<?>> map = new HashMap<>();
for (Map.Entry<String, ConfigEntry<?>> e : super.getValue().entrySet()) {
map.put(Respackopts.sanitizeString(e.getKey()), e.getValue().getDynamic());
}
super.getValue().forEach((key, value) -> {
map.put(Respackopts.sanitizeString(key), value.getDynamic());
});
return DFinal.of(map);
}
public Scope addTo(Scope scope) {
super.getValue().forEach((key, value) -> {
scope.set(Respackopts.sanitizeString(key), value.getDynamic());
});
return scope;
}
@Override
public CategoryBuilder<?> buildEntry(GuiEntryBuilderParam builder) {
return builder.builder().category(builder.name(), cb -> {
for (Map.Entry<String, ConfigEntry<?>> e : getValue().entrySet()) {
e.getValue().buildEntry(new GuiEntryBuilderParam(cb, e.getKey(), builder.onSave()));
}
getValue().forEach((key, value) -> {
value.buildEntry(new GuiEntryBuilderParam(cb, key, builder.onSave()));
});
return cb;
});
}
@ -109,13 +122,15 @@ public class ConfigBranch extends ConfigEntry<Map<String, ConfigEntry<?>>> {
public <T extends ConfigBuilder<?>> T buildConfig(T builder, String packId, Path dataLocation) {
builder.setTranslationPrefix("rpo." + packId + ".");
PackReloadType.Aggregator agg = new PackReloadType.Aggregator();
for (Map.Entry<String, ConfigEntry<?>> e : getValue().entrySet()) {
e.getValue().buildEntry(
new GuiEntryBuilderParam(builder,
e.getKey(),
() -> agg.accept(e.getValue().getReloadType()))
getValue().forEach((key, value) -> {
value.buildEntry(
new GuiEntryBuilderParam(
builder,
key,
() -> agg.accept(value.getReloadType())
)
);
}
});
builder.executeAfterWrite(cfg -> {
if (RespackoptsConfig.debugLogs) Respackopts.LOGGER.info("GuiFactory SavingRunnable " + agg.get());
MetaCache.save(new SaveHook.Arguments(agg.get() == PackReloadType.Resource, false, true));
@ -127,20 +142,20 @@ public class ConfigBranch extends ConfigEntry<Map<String, ConfigEntry<?>>> {
@Override
public void appendString(IndentingStringBuilder sb) {
IndentingStringBuilder ind = sb.indent();
for (Map.Entry<String, ConfigEntry<?>> e : getValue().entrySet()) {
ind.line("- " + e.getValue().getName() + ":");
e.getValue().appendString(ind);
}
getValue().forEach((key, value) -> {
ind.line("- " + value.getName() + ":");
value.appendString(ind);
});
}
@Override
public ConfigBranch clone() {
ConfigBranch branch = new ConfigBranch();
for (Map.Entry<String, ConfigEntry<?>> e : getValue().entrySet()) {
ConfigEntry<?> entry = e.getValue().clone();
entry.setReloadType(e.getValue().getReloadType());
branch.add(e.getKey(), entry);
}
getValue().forEach((key, value) -> {
ConfigEntry<?> entry = value.clone();
entry.setReloadType(value.getReloadType());
branch.add(key, entry);
});
branch.setVersion(getVersion());
return branch;
}
@ -169,10 +184,10 @@ public class ConfigBranch extends ConfigEntry<Map<String, ConfigEntry<?>>> {
@Override
public int hashCode() {
List<Object> source = new ArrayList<>();
for (Map.Entry<String, ConfigEntry<?>> entry : getValue().entrySet()) {
source.add(entry.getKey());
source.add(entry.getValue());
}
getValue().forEach((key, value) -> {
source.add(key);
source.add(value);
});
source.add(super.hashCode());
return Objects.hash(source.toArray());
}

View File

@ -1,7 +1,7 @@
package io.gitlab.jfronny.respackopts.model.tree;
import io.gitlab.jfronny.libjf.config.api.v1.dsl.CategoryBuilder;
import io.gitlab.jfronny.muscript.data.dynamic.DEnum;
import io.gitlab.jfronny.muscript.data.dynamic.additional.DEnum;
import io.gitlab.jfronny.respackopts.Respackopts;
import io.gitlab.jfronny.respackopts.RespackoptsConfig;
import io.gitlab.jfronny.respackopts.model.enums.ConfigSyncMode;
@ -10,7 +10,7 @@ import io.gitlab.jfronny.respackopts.util.IndentingStringBuilder;
import java.util.*;
public class ConfigEnumEntry extends ConfigEntry<String> {
public List<String> values = new ArrayList<>();
public final List<String> values = new ArrayList<>();
private Integer nextValue;
public ConfigEnumEntry() {
@ -40,10 +40,8 @@ public class ConfigEnumEntry extends ConfigEntry<String> {
public String getDefault() {
String v = super.getDefault();
if (v == null) {
if (values.size() == 0)
throw new NullPointerException("Could not get default entry as the entry array is empty in " + getName());
else
v = values.get(0);
if (values.isEmpty()) throw new NullPointerException("Could not get default entry as the entry array is empty in " + getName());
v = values.get(0);
}
return v;
}
@ -52,9 +50,9 @@ public class ConfigEnumEntry extends ConfigEntry<String> {
public void sync(ConfigEntry<String> source, ConfigSyncMode mode) {
super.sync(source, mode);
ConfigEnumEntry n = (ConfigEnumEntry) source;
if (mode == ConfigSyncMode.RESPACK_LOAD) {
if (n.values != null && !n.values.isEmpty())
values = n.values;
if (mode == ConfigSyncMode.RESPACK_LOAD && !n.values.isEmpty()) {
values.clear();
values.addAll(n.values);
}
if (getValue() == null && nextValue != null) {
if (n.nextValue >= 0 && n.nextValue < values.size()) {
@ -79,7 +77,7 @@ public class ConfigEnumEntry extends ConfigEntry<String> {
public ConfigEntry<String> clone() {
ConfigEnumEntry e = new ConfigEnumEntry();
e.nextValue = nextValue;
e.values = List.copyOf(values);
e.values.addAll(values);
e.setValue(getValue());
e.setDefault(getDefault());
return e;

View File

@ -150,14 +150,15 @@ public class MetaCache {
return PACK_STATES.get(key);
}
public static Scope getParameter(@Nullable CacheKey key) {
Scope parameter = key == null ? new Scope() : MetaCache.getState(key).executionScope();
public static Scope getScope(@Nullable CacheKey key) {
Scope scope = (key == null ? Respackopts.ROOT_SCOPE : MetaCache.getState(key).executionScope()).fork();
MetaCache.forEach((id, state) -> {
String packId = Respackopts.sanitizeString(state.packId());
if (!parameter.has(packId))
parameter.set(packId, state.configBranch().getDynamic());
if (!scope.has(packId)) {
scope.set(packId, state.configBranch().getDynamic());
}
});
return MuUtils.addDefault(parameter);
return scope;
}
public static boolean hasCapability(ResourcePack pack, PackCapability capability) {

View File

@ -1,108 +0,0 @@
package io.gitlab.jfronny.respackopts.util;
import io.gitlab.jfronny.muscript.StandardLib;
import io.gitlab.jfronny.muscript.data.Scope;
import io.gitlab.jfronny.muscript.data.dynamic.*;
import net.fabricmc.loader.api.FabricLoader;
import net.fabricmc.loader.api.VersionParsingException;
import net.fabricmc.loader.api.metadata.version.VersionPredicate;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.Map;
import java.util.function.Supplier;
public class MuUtils {
public static Scope addDefault(Scope parameter) {
StandardLib.addTo(parameter);
parameter.set("version", args -> {
if (args.size() != 2) throw new IllegalArgumentException("Expected 2 arguments on version but got " + args.size());
VersionPredicate predicate;
try {
predicate = VersionPredicate.parse(args.get(1).asString().getValue());
} catch (VersionParsingException e) {
throw new RuntimeException("Could not parse version predicate", e);
}
return DFinal.of(FabricLoader.getInstance().getModContainer(args.get(0).asString().getValue())
.map(c -> predicate.test(c.getMetadata().getVersion()))
.orElse(false));
});
parameter.set("date", new DCallableObject(Map.of(
"today", new DDate(LocalDate::now)
), DFinal.of(args -> {
// Constructor
if (args.size() == 1) return new DDate(() -> LocalDate.ofEpochDay(args.get(0).asNumber().getValue().longValue()));
if (args.size() != 3) throw new IllegalArgumentException("Expected 3 arguments for full date constructor");
int a0 = args.get(0).asNumber().getValue().intValue();
int a1 = args.get(1).asNumber().getValue().intValue();
int a2 = args.get(2).asNumber().getValue().intValue();
return new DDate(() -> LocalDate.of(a0, a1, a2));
})));
parameter.set("time", new DCallableObject(Map.of(
"now", new DTime(LocalTime::now)
), DFinal.of(args -> {
// Constructor
if (args.size() == 1) return new DTime(() -> LocalTime.ofSecondOfDay(args.get(0).asNumber().getValue().intValue()));
if (args.size() != 3) throw new IllegalArgumentException("Expected 3 arguments for full time constructor");
int a0 = args.get(0).asNumber().getValue().intValue();
int a1 = args.get(1).asNumber().getValue().intValue();
int a2 = args.get(2).asNumber().getValue().intValue();
return new DTime(() -> LocalTime.of(a0, a1, a2));
})));
return parameter;
}
private record DCallableObject(Map<String, Dynamic<?>> value, DCallable callable) implements DObject {
@Override
public Map<String, Dynamic<?>> getValue() {
return value;
}
@Override
public DCallable asCallable() {
return callable;
}
}
private record DDate(Supplier<LocalDate> date) implements DObject {
@Override
public Map<String, Dynamic<?>> getValue() {
return Map.of(
"year", DFinal.of(date.get().getYear()),
"month", DFinal.of(date.get().getMonthValue()),
"day", DFinal.of(date.get().getDayOfMonth())
);
}
@Override
public DString asString() {
return DFinal.of(date.get().toString());
}
@Override
public DNumber asNumber() {
return DFinal.of(date.get().toEpochDay());
}
}
private record DTime(Supplier<LocalTime> time) implements DObject {
@Override
public Map<String, Dynamic<?>> getValue() {
return Map.of(
"hour", DFinal.of(time.get().getHour()),
"minute", DFinal.of(time.get().getMinute()),
"second", DFinal.of(time.get().getSecond())
);
}
@Override
public DString asString() {
return DFinal.of(time.get().toString());
}
@Override
public DNumber asNumber() {
return DFinal.of(time.get().toSecondOfDay());
}
}
}