Skip to content

Commit

Permalink
1.20 Scripting Backport (#618)
Browse files Browse the repository at this point in the history
* base functionality port

* update API calls and underlying logic

* post-testing tweaks
  • Loading branch information
Caltinor committed Dec 4, 2024
1 parent e56709a commit cb57bff
Show file tree
Hide file tree
Showing 13 changed files with 756 additions and 115 deletions.
206 changes: 117 additions & 89 deletions src/main/java/harmonised/pmmo/api/APIUtils.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@ public record LocationData(
List<ResourceLocation> veinBlacklist,
Map<String, Integer> travelReq,
Map<ResourceLocation, Map<String, Double>> mobModifiers) implements DataSource<LocationData>{


public LocationData(boolean override) {
this(override, new HashSet<>(), new HashMap<>(), new HashMap<>(), new HashMap<>(),
new ArrayList<>(), new HashMap<>(), new ArrayList<>(), new HashMap<>());
}
public LocationData() {this(
false, new HashSet<>(), new HashMap<>(), new HashMap<>(), new HashMap<>(),
new ArrayList<>(), new HashMap<>(), new HashMap<>());}
Expand Down
39 changes: 24 additions & 15 deletions src/main/java/harmonised/pmmo/config/readers/CoreLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

import harmonised.pmmo.config.scripting.Scripting;
import net.minecraft.core.RegistryAccess;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.registries.Registries;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import harmonised.pmmo.api.enums.ModifierDataType;
Expand Down Expand Up @@ -38,11 +44,12 @@ public class CoreLoader {
@SubscribeEvent
public static void onTagLoad(TagsUpdatedEvent event) {
Core core = Core.get(event.getUpdateCause() == UpdateCause.CLIENT_PACKET_RECEIVED ? LogicalSide.CLIENT : LogicalSide.SERVER);
core.getLoader().ITEM_LOADER.postProcess();
core.getLoader().BLOCK_LOADER.postProcess();
core.getLoader().ENTITY_LOADER.postProcess();
//core.getLoader().DIMENSION_LOADER.postProcess();
core.getLoader().BIOME_LOADER.postProcess();
core.getLoader().ITEM_LOADER.postProcess(event.getRegistryAccess());
core.getLoader().BLOCK_LOADER.postProcess(event.getRegistryAccess());
core.getLoader().ENTITY_LOADER.postProcess(event.getRegistryAccess());
//Until dimensions are stored as a client registry, this must remain commented.
//core.getLoader().DIMENSION_LOADER.postProcess(event.getRegistryAccess());
core.getLoader().BIOME_LOADER.postProcess(event.getRegistryAccess());
}

@SuppressWarnings("unchecked")
Expand Down Expand Up @@ -80,10 +87,12 @@ public <T extends DataSource<T>> void applyData(ObjectType type, Map<ResourceLoc
case BIOME -> BIOME_LOADER;
default -> null;};
}

public static final ExecutableListener RELOADER = new ExecutableListener(() -> {

public ExecutableListener RELOADER;
public static final Consumer<RegistryAccess> RELOADER_FUNCTION = access -> {
Core.get(LogicalSide.SERVER).getLoader().resetData();
});
Scripting.readFiles(access);
};

public void resetData() {
ITEM_LOADER.clearData();
Expand All @@ -97,21 +106,21 @@ public void resetData() {
}

public final MergeableCodecDataManager<ObjectData, Item> ITEM_LOADER = new MergeableCodecDataManager<>(
"pmmo/items", DATA_LOGGER, ObjectData.CODEC, this::mergeLoaderData, this::printData, ObjectData::new, ForgeRegistries.ITEMS);
"pmmo/items", DATA_LOGGER, ObjectData.CODEC, this::mergeLoaderData, this::printData, ObjectData::new, Registries.ITEM);
public final MergeableCodecDataManager<ObjectData, Block> BLOCK_LOADER = new MergeableCodecDataManager<>(
"pmmo/blocks", DATA_LOGGER, ObjectData.CODEC, this::mergeLoaderData, this::printData, ObjectData::new, ForgeRegistries.BLOCKS);
"pmmo/blocks", DATA_LOGGER, ObjectData.CODEC, this::mergeLoaderData, this::printData, ObjectData::new, Registries.BLOCK);
public final MergeableCodecDataManager<ObjectData, EntityType<?>> ENTITY_LOADER = new MergeableCodecDataManager<>(
"pmmo/entities", DATA_LOGGER, ObjectData.CODEC, this::mergeLoaderData, this::printData, ObjectData::new, ForgeRegistries.ENTITY_TYPES);
"pmmo/entities", DATA_LOGGER, ObjectData.CODEC, this::mergeLoaderData, this::printData, ObjectData::new, Registries.ENTITY_TYPE);
public final MergeableCodecDataManager<LocationData, Biome> BIOME_LOADER = new MergeableCodecDataManager<>(
"pmmo/biomes", DATA_LOGGER, LocationData.CODEC, this::mergeLoaderData, this::printData, LocationData::new, ForgeRegistries.BIOMES);
"pmmo/biomes", DATA_LOGGER, LocationData.CODEC, this::mergeLoaderData, this::printData, LocationData::new, Registries.BIOME);
public final MergeableCodecDataManager<LocationData, Level> DIMENSION_LOADER = new MergeableCodecDataManager<>(
"pmmo/dimensions", DATA_LOGGER, LocationData.CODEC, this::mergeLoaderData, this::printData, LocationData::new, null);
"pmmo/dimensions", DATA_LOGGER, LocationData.CODEC, this::mergeLoaderData, this::printData, LocationData::new, Registries.DIMENSION);
public final MergeableCodecDataManager<PlayerData, Player> PLAYER_LOADER = new MergeableCodecDataManager<>(
"pmmo/players", DATA_LOGGER, PlayerData.CODEC, this::mergeLoaderData, this::printData, PlayerData::new, null);
public final MergeableCodecDataManager<EnhancementsData, Enchantment> ENCHANTMENT_LOADER = new MergeableCodecDataManager<>(
"pmmo/enchantments", DATA_LOGGER, EnhancementsData.CODEC, this::mergeLoaderData, this::printData, EnhancementsData::new, ForgeRegistries.ENCHANTMENTS);
"pmmo/enchantments", DATA_LOGGER, EnhancementsData.CODEC, this::mergeLoaderData, this::printData, EnhancementsData::new, Registries.ENCHANTMENT);
public final MergeableCodecDataManager<EnhancementsData, MobEffect> EFFECT_LOADER = new MergeableCodecDataManager<>(
"pmmo/effects", DATA_LOGGER, EnhancementsData.CODEC, this::mergeLoaderData, this::printData, EnhancementsData::new, ForgeRegistries.MOB_EFFECTS);
"pmmo/effects", DATA_LOGGER, EnhancementsData.CODEC, this::mergeLoaderData, this::printData, EnhancementsData::new, Registries.MOB_EFFECT);


private <T extends DataSource<T>> T mergeLoaderData(final List<T> raws) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.util.function.Consumer;
import java.util.function.Supplier;

import net.minecraft.core.RegistryAccess;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.packs.resources.ResourceManager;
import net.minecraft.server.packs.resources.SimplePreparableReloadListener;
Expand All @@ -14,9 +15,11 @@
import net.minecraftforge.network.simple.SimpleChannel;

public class ExecutableListener extends SimplePreparableReloadListener<Boolean> {
private Runnable executor;

public ExecutableListener(Runnable executor) {
private final Consumer<RegistryAccess> executor;
private final RegistryAccess access;

public ExecutableListener(RegistryAccess access, Consumer<RegistryAccess> executor) {
this.access = access;
this.executor = executor;
}

Expand All @@ -25,7 +28,7 @@ public ExecutableListener(Runnable executor) {

@Override
protected void apply(Boolean pObject, ResourceManager pResourceManager, ProfilerFiller pProfiler) {
executor.run();
executor.accept(access);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,11 @@ public MergeableCodecDataManager(final String folderName, final Logger logger, C

public Map<ResourceLocation, T> getData() {return data;}

public void clearData() {this.data = new HashMap<>();}
public void clearData() {
this.data.clear();
this.overrideSettings.clear();
this.defaultSettings.clear();
}

public T getData(ResourceLocation id) {
return data.computeIfAbsent(id, res -> getGenericTypeInstance());
Expand All @@ -167,7 +171,7 @@ public T getData(ResourceLocation id) {
*/
@SuppressWarnings("unchecked")
public void registerDefault(ResourceLocation id, DataSource<?> data) {
defaultSettings.merge(id, (T) data, (currID, currData) -> currData.combine((T) data));
defaultSettings.merge(id, (T) data, DataSource::combine);
}

/**Adds override data to the loader. This data is applied on
Expand All @@ -185,7 +189,7 @@ public void registerDefault(ResourceLocation id, DataSource<?> data) {
*/
@SuppressWarnings("unchecked")
public void registerOverride(ResourceLocation id, DataSource<?> data) {
overrideSettings.merge(id, (T) data, (currID, currData) -> currData.combine((T) data));
overrideSettings.merge(id, (T) data, DataSource::combine);
}

/** Off-thread processing (can include reading files from hard drive) **/
Expand Down
100 changes: 100 additions & 0 deletions src/main/java/harmonised/pmmo/config/scripting/Expression.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package harmonised.pmmo.config.scripting;

import harmonised.pmmo.api.enums.ObjectType;
import harmonised.pmmo.util.MsLoggy;
import harmonised.pmmo.util.Reference;
import net.minecraft.core.Registry;
import net.minecraft.core.RegistryAccess;
import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.TagKey;

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

public record Expression(
ObjectType targetType,
ResourceLocation targetID,
Map<String, String> value,
List<Node> features) {
public record Node(String param, NodeConsumer consumer) {@Override public String toString() {return param;}}

public static List<Expression> create(RegistryAccess access, String str) {
MsLoggy.DEBUG.log(MsLoggy.LOG_CODE.DATA, "Raw Script Line: {}", str);
List<Expression> expressions = new ArrayList<>();
String[] nodes = str.replace(";", "").split("\\)\\.");
List<Node> features = new ArrayList<>();
Map<String, String> values = new HashMap<>();
List<ResourceLocation> targetIDs = new ArrayList<>();
ObjectType targetType = null;
for (String node : nodes) {
MsLoggy.DEBUG.log(MsLoggy.LOG_CODE.DATA, "NODE: {}", node);
String keyword = node.substring(0, node.indexOf('('));
String param = node.substring(node.indexOf('(')+1).replaceAll("[ )]", "");

if (ObjectType.byName(keyword.toUpperCase()) != null) {
targetType = ObjectType.byName(keyword.toUpperCase());
targetIDs = parseIDs(param, targetType, access);
}
else if (Functions.TARGETORS.containsKey(keyword)) {
TargetSelector.Selection selection = Functions.TARGETORS.get(keyword).read(param, access);
targetType = selection.type();
targetIDs = selection.IDs();
}
else if (Functions.KEYWORDS.containsKey(keyword))
features.add(new Node(param, Functions.KEYWORDS.get(keyword)));
else values.put(keyword, param);
}

for (ResourceLocation id : targetIDs) {expressions.add(new Expression(targetType, id, values, features));}
expressions.forEach(expr -> MsLoggy.DEBUG.log(MsLoggy.LOG_CODE.DATA, "Expressions: {}", expr));
return expressions;
}

public boolean isValid() {return targetType != null && targetID != null;}

public void commit() {
features.forEach(c -> c.consumer().consume(c.param(), targetID, targetType, value));
}

public static List<ResourceLocation> parseIDs(String raw, ObjectType type, RegistryAccess access) {
List<ResourceLocation> ids = new ArrayList<>();
String[] rawSplit = raw.split(",");
for (String str : rawSplit) {
if (str.startsWith("#")) {
ResourceLocation tagID = new ResourceLocation(str.substring(1));
ids.addAll(getMembers(true, tagID, access, type));
}
else if (str.endsWith(":*")) {
ResourceLocation namespace = new ResourceLocation(str.replace("*", "wildcard"));
ids.addAll(getMembers(false, namespace, access, type));
}
else ids.add(new ResourceLocation(str));
}
return ids;
}

private static List<ResourceLocation> getMembers(boolean isTag, ResourceLocation tagID, RegistryAccess access, ObjectType type) {
return switch (type) {
case ITEM -> readRegistry(isTag, access, Registries.ITEM, tagID);
case BLOCK -> readRegistry(isTag, access, Registries.BLOCK, tagID);
case ENTITY -> readRegistry(isTag, access, Registries.ENTITY_TYPE, tagID);
case BIOME -> readRegistry(isTag, access, Registries.BIOME, tagID);
case ENCHANTMENT -> readRegistry(isTag, access, Registries.ENCHANTMENT, tagID);
default -> List.of();
};
}

private static <T> List<ResourceLocation> readRegistry(boolean forTags, RegistryAccess access, ResourceKey<Registry<T>> registry, ResourceLocation tagID) {
var reg = access.registryOrThrow(registry);
return forTags
? reg.getTag(TagKey.create(registry, tagID))
.map(named -> named.stream().map(holder -> holder.unwrapKey().get().location()).toList())
.orElse(List.of())
: reg.keySet().stream().filter(id -> id.getNamespace().equals(tagID.getNamespace())).toList();
}

}
Loading

0 comments on commit cb57bff

Please sign in to comment.