Skip to content

Commit

Permalink
Backported tag rewrite from 1.20
Browse files Browse the repository at this point in the history
  • Loading branch information
LatvianModder committed Sep 7, 2023
1 parent f160da9 commit d1fa267
Show file tree
Hide file tree
Showing 16 changed files with 705 additions and 527 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import dev.latvian.mods.kubejs.server.CommandEventJS;
import dev.latvian.mods.kubejs.server.CustomCommandEventJS;
import dev.latvian.mods.kubejs.server.ServerEventJS;
import dev.latvian.mods.kubejs.server.TagEventJS;
import dev.latvian.mods.kubejs.server.tag.TagEventJS;

public interface ServerEvents {
EventGroup GROUP = EventGroup.of("ServerEvents");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,38 +1,98 @@
package dev.latvian.mods.kubejs.core;

import com.google.gson.JsonArray;
import dev.latvian.mods.kubejs.bindings.event.ServerEvents;
import dev.latvian.mods.kubejs.item.ingredient.TagContext;
import dev.latvian.mods.kubejs.registry.RegistryInfo;
import dev.latvian.mods.kubejs.server.DataExport;
import dev.latvian.mods.kubejs.server.ServerScriptManager;
import dev.latvian.mods.kubejs.server.TagEventJS;
import dev.latvian.mods.kubejs.server.tag.TagEventFilter;
import dev.latvian.mods.kubejs.server.tag.TagEventJS;
import dev.latvian.mods.kubejs.server.tag.TagWrapper;
import dev.latvian.mods.kubejs.util.ConsoleJS;
import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.TagLoader;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public interface TagLoaderKJS<T> {
default void kjs$customTags(Map<ResourceLocation, List<TagLoader.EntryWithSource>> map) {
default void kjs$customTags(ServerScriptManager ssm, Map<ResourceLocation, List<TagLoader.EntryWithSource>> map) {
TagContext.INSTANCE.setValue(TagContext.EMPTY);
var reg = kjs$getRegistry();

if (reg == null) {
return;
}
var regInfo = RegistryInfo.MAP.get(reg.key());

if ((regInfo != null && regInfo.hasDefaultTags) || ServerEvents.TAGS.hasListeners(reg.key())) {
var dir = kjs$getDirectory();
new TagEventJS<>(dir, map, reg).post(ServerScriptManager.instance == null ? null : ServerScriptManager.instance.tagEventHolders.get(reg.key()));
var regInfo = RegistryInfo.of(reg.key());

if (regInfo.hasDefaultTags || ServerEvents.TAGS.hasListeners(reg.key())) {
var preEvent = ssm.preTagEvents.get(reg.key());

var event = new TagEventJS(regInfo, reg);

for (var entry : map.entrySet()) {
var w = new TagWrapper(event, entry.getKey(), entry.getValue());
event.tags.put(w.id, w);

if (ConsoleJS.SERVER.shouldPrintDebug()) {
ConsoleJS.SERVER.debug("Tags %s/#%s; %d".formatted(regInfo, w.id, w.entries.size()));
}
}

for (var builder : regInfo.objects.values()) {
for (var s : builder.defaultTags) {
event.add(s, new TagEventFilter.ID(builder.id));
}
}

if (preEvent == null) {
ServerEvents.TAGS.post(event, regInfo.key, TagEventJS.TAG_EVENT_HANDLER);
} else {
for (var a : preEvent.actions) {
a.accept(event);
}
}

map.clear();

for (var entry : event.tags.entrySet()) {
map.put(entry.getKey(), entry.getValue().entries);
}

if (DataExport.export != null) {
var loc = "tags/" + regInfo + "/";

for (var entry : map.entrySet()) {
var list = new ArrayList<String>();

for (var e : entry.getValue()) {
list.add(e.entry().toString());
}

list.sort(String.CASE_INSENSITIVE_ORDER);
var arr = new JsonArray();

for (var e : list) {
arr.add(e);
}

DataExport.export.addJson(loc + entry.getKey() + ".json", arr);
}
}

if (event.totalAdded > 0 || event.totalRemoved > 0 || ConsoleJS.SERVER.shouldPrintDebug()) {
ConsoleJS.SERVER.info("[%s] Found %d tags, added %d objects, removed %d objects".formatted(regInfo, event.tags.size(), event.totalAdded, event.totalRemoved));
}
}
}

void kjs$setRegistry(Registry<T> registry);

@Nullable
Registry<T> kjs$getRegistry();

String kjs$getDirectory();
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.gen.Accessor;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
Expand All @@ -28,8 +27,10 @@ public abstract class TagLoaderMixin<T> implements TagLoaderKJS<T> {
private void customTags(ResourceManager resourceManager, CallbackInfoReturnable<Map<ResourceLocation, List<TagLoader.EntryWithSource>>> cir) {
// band-aid fix for #237, as some mods use tags on the client side;
// technically not an intended use case, but easy enough to fix
if (ServerScriptManager.instance != null) {
kjs$customTags(cir.getReturnValue());
var ssm = ServerScriptManager.instance;

if (ssm != null) {
kjs$customTags(ssm, cir.getReturnValue());
}
}

Expand All @@ -42,8 +43,4 @@ private void customTags(ResourceManager resourceManager, CallbackInfoReturnable<
public @Nullable Registry<T> kjs$getRegistry() {
return kjs$storedRegistry;
}

@Override
@Accessor("directory")
public abstract String kjs$getDirectory();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package dev.latvian.mods.kubejs.event;

import dev.latvian.mods.rhino.WrappedException;

@FunctionalInterface
public interface EventExceptionHandler {
/**
* Handles an exception thrown by an event handler.
*
* @param event The event being posted
* @param container The event handler container that threw the exception
* @param ex The exception that was thrown
* @return <code>null</code> if the exception could be recovered from, otherwise the exception that should be rethrown
* @implNote The thrown exception will never be an instance of {@link EventExit} or {@link WrappedException},
* as those are already handled by the container itself.
*/
Throwable handle(EventJS event, EventHandlerContainer container, Throwable ex);
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import dev.latvian.mods.rhino.BaseFunction;
import dev.latvian.mods.rhino.Context;
import dev.latvian.mods.rhino.Scriptable;
import dev.latvian.mods.rhino.WrappedException;
import dev.latvian.mods.rhino.Wrapper;
import dev.latvian.mods.rhino.util.HideFromJS;
import org.jetbrains.annotations.Nullable;
Expand Down Expand Up @@ -366,19 +365,4 @@ public Set<Object> findUniqueExtraIds(ScriptType type) {

return set;
}

@FunctionalInterface
public interface EventExceptionHandler {
/**
* Handles an exception thrown by an event handler.
*
* @param event The event being posted
* @param container The event handler container that threw the exception
* @param ex The exception that was thrown
* @return <code>null</code> if the exception could be recovered from, otherwise the exception that should be rethrown
* @implNote The thrown exception will never be an instance of {@link EventExit} or {@link WrappedException},
* as those are already handled by the container itself.
*/
Throwable handle(EventJS event, EventHandlerContainer container, Throwable ex);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public EventHandlerContainer(Object extraId, IEventHandler handler, String sourc
this.line = line;
}

public EventResult handle(EventJS event, EventHandler.EventExceptionHandler exh) throws EventExit {
public EventResult handle(EventJS event, EventExceptionHandler exh) throws EventExit {
var itr = this;

do {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import dev.latvian.mods.kubejs.DevProperties;
import dev.latvian.mods.kubejs.bindings.event.ServerEvents;
import dev.latvian.mods.kubejs.core.RecipeKJS;
import dev.latvian.mods.kubejs.event.EventHandler;
import dev.latvian.mods.kubejs.event.EventExceptionHandler;
import dev.latvian.mods.kubejs.event.EventJS;
import dev.latvian.mods.kubejs.item.ingredient.IngredientWithCustomPredicate;
import dev.latvian.mods.kubejs.item.ingredient.TagContext;
Expand Down Expand Up @@ -73,7 +73,7 @@
public class RecipesEventJS extends EventJS {
public static final Pattern SKIP_ERROR = Pattern.compile("at.*dev\\.latvian\\.mods\\.kubejs\\.recipe\\.RecipesEventJS\\.post");
private static final Predicate<RecipeJS> RECIPE_NOT_REMOVED = r -> r != null && !r.removed;
private static final EventHandler.EventExceptionHandler RECIPE_EXCEPTION_HANDLER = (event, handler, ex) -> {
private static final EventExceptionHandler RECIPE_EXCEPTION_HANDLER = (event, handler, ex) -> {
// skip the current handler on a recipe or JSON exception, but let other handlers run
if (ex instanceof RecipeExceptionJS || ex instanceof JsonParseException) {
ConsoleJS.SERVER.error("Error while processing recipe event handler: " + handler, ex);
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
package dev.latvian.mods.kubejs.server;

import dev.latvian.mods.kubejs.DevProperties;
import dev.latvian.mods.kubejs.KubeJS;
import dev.latvian.mods.kubejs.KubeJSPaths;
import dev.latvian.mods.kubejs.KubeJSPlugin;
import dev.latvian.mods.kubejs.bindings.event.ServerEvents;
import dev.latvian.mods.kubejs.platform.RecipePlatformHelper;
import dev.latvian.mods.kubejs.recipe.RecipesEventJS;
import dev.latvian.mods.kubejs.recipe.ingredientaction.CustomIngredientAction;
import dev.latvian.mods.kubejs.recipe.special.SpecialRecipeSerializerManager;
import dev.latvian.mods.kubejs.registry.RegistryInfo;
import dev.latvian.mods.kubejs.script.ScriptManager;
import dev.latvian.mods.kubejs.script.ScriptType;
import dev.latvian.mods.kubejs.script.data.DataPackEventJS;
import dev.latvian.mods.kubejs.script.data.KubeJSFolderPackResources;
import dev.latvian.mods.kubejs.script.data.VirtualKubeJSDataPack;
import dev.latvian.mods.kubejs.server.tag.PreTagEventJS;
import dev.latvian.mods.kubejs.util.ConsoleJS;
import dev.latvian.mods.kubejs.util.KubeJSPlugins;
import net.minecraft.resources.ResourceKey;
Expand All @@ -40,7 +38,7 @@ public static ScriptManager getScriptManager() {
}

private final ScriptManager scriptManager = new ScriptManager(ScriptType.SERVER, KubeJSPaths.SERVER_SCRIPTS);
public final Map<ResourceKey<?>, FakeTagEventJS> tagEventHolders = new ConcurrentHashMap<>();
public final Map<ResourceKey<?>, PreTagEventJS> preTagEvents = new ConcurrentHashMap<>();

public ServerScriptManager() {
try {
Expand Down Expand Up @@ -98,27 +96,7 @@ public MultiPackResourceManager wrapResourceManager(CloseableResourceManager ori
ServerEvents.SPECIAL_RECIPES.post(ScriptType.SERVER, SpecialRecipeSerializerManager.INSTANCE);
KubeJSPlugins.forEachPlugin(KubeJSPlugin::onServerReload);

tagEventHolders.clear();

if (ServerEvents.TAGS.hasListeners()) {
for (var id : ServerEvents.TAGS.findUniqueExtraIds(ScriptType.SERVER)) {
var e = new FakeTagEventJS(RegistryInfo.of((ResourceKey) id));
try {
ServerEvents.TAGS.post(ScriptType.SERVER, id, e);
} catch (Exception ex) {
e.invalid = true;

if (DevProperties.get().debugInfo) {
KubeJS.LOGGER.warn("Fake Tag event for " + e.registry + " failed:");
ex.printStackTrace();
}
}

if (!e.invalid) {
tagEventHolders.put(e.registry.key, e);
}
}
}
PreTagEventJS.handle(preTagEvents);

if (ServerEvents.RECIPES.hasListeners()) {
RecipesEventJS.instance = new RecipesEventJS();
Expand Down
Loading

0 comments on commit d1fa267

Please sign in to comment.