diff --git a/gradle.properties b/gradle.properties index a39dc79..17476b9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,15 +3,15 @@ org.gradle.jvmargs=-Xmx1G # Fabric Properties # check these on https://fabricmc.net/use - minecraft_version=1.19-rc2 - yarn_mappings=1.19-rc2+build.1 + minecraft_version=1.19 + yarn_mappings=1.19+build.1 loader_version=0.14.6 #Fabric api - fabric_version=0.55.0+1.19 + fabric_version=0.55.1+1.19 # Mod Properties - mod_version = 2.0.0-beta.4+1.19 + mod_version = 2.0.0-beta.5+1.19 maven_group = eu.pb4 archives_base_name = placeholder-api diff --git a/src/main/java/eu/pb4/placeholders/api/PlaceholderContext.java b/src/main/java/eu/pb4/placeholders/api/PlaceholderContext.java index 130fe13..1c4065c 100644 --- a/src/main/java/eu/pb4/placeholders/api/PlaceholderContext.java +++ b/src/main/java/eu/pb4/placeholders/api/PlaceholderContext.java @@ -1,19 +1,29 @@ package eu.pb4.placeholders.api; import com.mojang.authlib.GameProfile; +import com.mojang.brigadier.context.CommandContext; import net.minecraft.entity.Entity; import net.minecraft.server.MinecraftServer; +import net.minecraft.server.command.CommandOutput; +import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.world.ServerWorld; +import net.minecraft.text.Text; +import net.minecraft.util.math.Vec2f; +import net.minecraft.util.math.Vec3d; import javax.annotation.Nullable; public record PlaceholderContext(MinecraftServer server, + ServerCommandSource source, @Nullable ServerWorld world, @Nullable ServerPlayerEntity player, @Nullable Entity entity, @Nullable GameProfile gameProfile ) { + + + public static ParserContext.Key KEY = new ParserContext.Key<>("placeholder_context", PlaceholderContext.class); public boolean hasWorld() { @@ -37,22 +47,27 @@ public ParserContext asParserContext() { } public static PlaceholderContext of(MinecraftServer server) { - return new PlaceholderContext(server,null, null, null, null); + return new PlaceholderContext(server, server.getCommandSource(), null, null, null, null); } public static PlaceholderContext of(GameProfile profile, MinecraftServer server) { - return new PlaceholderContext(server, null, null, null, profile); + var name = profile.getName() != null ? profile.getName() : profile.getId().toString(); + return new PlaceholderContext(server, new ServerCommandSource(CommandOutput.DUMMY, Vec3d.ZERO, Vec2f.ZERO, server.getOverworld(), server.getPermissionLevel(profile), name, Text.literal(name), server, null), null, null, null, profile); } public static PlaceholderContext of(ServerPlayerEntity player) { - return new PlaceholderContext(player.getServer(), player.getWorld(), player, player, player.getGameProfile()); + return new PlaceholderContext(player.getServer(), player.getCommandSource(), player.getWorld(), player, player, player.getGameProfile()); + } + + public static PlaceholderContext of(ServerCommandSource source) { + return new PlaceholderContext(source.getServer(), source, source.getWorld(), source.getPlayer(), source.getEntity(), source.getPlayer() != null ? source.getPlayer().getGameProfile() : null); } public static PlaceholderContext of(Entity entity) { if (entity instanceof ServerPlayerEntity player) { - return new PlaceholderContext(entity.getServer(), player.getWorld(), player, entity, player.getGameProfile()); + return of(player); } else { - return new PlaceholderContext(entity.getServer(), (ServerWorld) entity.getWorld(), null, entity, null); + return new PlaceholderContext(entity.getServer(), entity.getCommandSource(), (ServerWorld) entity.getWorld(), null, entity, null); } } } diff --git a/src/main/java/eu/pb4/placeholders/api/PlaceholderHandler.java b/src/main/java/eu/pb4/placeholders/api/PlaceholderHandler.java index c00e63f..53e1d4e 100644 --- a/src/main/java/eu/pb4/placeholders/api/PlaceholderHandler.java +++ b/src/main/java/eu/pb4/placeholders/api/PlaceholderHandler.java @@ -5,5 +5,6 @@ @FunctionalInterface public interface PlaceholderHandler { + PlaceholderHandler EMPTY = (ctx, arg) -> PlaceholderResult.invalid(); PlaceholderResult onPlaceholderRequest(PlaceholderContext context, @Nullable String argument); } diff --git a/src/main/java/eu/pb4/placeholders/api/Placeholders.java b/src/main/java/eu/pb4/placeholders/api/Placeholders.java index c3a6c4d..9428ed1 100644 --- a/src/main/java/eu/pb4/placeholders/api/Placeholders.java +++ b/src/main/java/eu/pb4/placeholders/api/Placeholders.java @@ -10,9 +10,11 @@ import net.minecraft.server.MinecraftServer; import net.minecraft.text.Text; import net.minecraft.util.Identifier; +import org.jetbrains.annotations.Nullable; import java.util.HashMap; import java.util.Map; +import java.util.Set; import java.util.regex.Pattern; public final class Placeholders { @@ -37,7 +39,6 @@ public boolean isContextOptional() { return false; } }; - private static final PlaceholderContext EMPTY_CONTEXT = PlaceholderContext.of((MinecraftServer) null); /** * Parses PlaceholderContext, can be used for parsing by hand @@ -84,6 +85,26 @@ public boolean isContextOptional() { })); } + public static ParentNode parseNodes(TextNode node, Pattern pattern, Set placeholders, ParserContext.Key key) { + return new ParentNode(NodePlaceholderParserImpl.recursivePlaceholderParsing(node, pattern, new PlaceholderGetter() { + @Override + public PlaceholderHandler getPlaceholder(String placeholder, ParserContext context) { + var get = context.get(key); + return get != null ? get.getPlaceholder(placeholder, context) : null; + } + + @Override + public PlaceholderHandler getPlaceholder(String placeholder) { + return placeholders.contains(placeholder) ? PlaceholderHandler.EMPTY : null; + } + + @Override + public boolean isContextOptional() { + return true; + } + })); + } + /** * Parses placeholders in text @@ -104,7 +125,11 @@ public static Text parseText(Text text, PlaceholderContext context, Pattern patt } public static Text parseText(Text text, Pattern pattern, Map placeholders) { - return parseNodes(TextNode.convert(text), pattern, placeholders).toText(ParserContext.of(PlaceholderContext.KEY, Placeholders.EMPTY_CONTEXT), true); + return parseNodes(TextNode.convert(text), pattern, placeholders).toText(ParserContext.of(), true); + } + + public static Text parseText(Text text, Pattern pattern, Set placeholders, ParserContext.Key key) { + return parseNodes(TextNode.convert(text), pattern, placeholders, key).toText(ParserContext.of(), true); } public static Text parseText(TextNode textNode, PlaceholderContext context) { @@ -124,7 +149,11 @@ public static Text parseText(TextNode textNode, PlaceholderContext context, Patt } public static Text parseText(TextNode textNode, Pattern pattern, Map placeholders) { - return parseNodes(textNode, pattern, placeholders).toText(ParserContext.of(PlaceholderContext.KEY, Placeholders.EMPTY_CONTEXT), true); + return parseNodes(textNode, pattern, placeholders).toText(ParserContext.of(), true); + } + + public static Text parseText(TextNode textNode, Pattern pattern, Set placeholders, ParserContext.Key key) { + return parseNodes(textNode, pattern, placeholders, key).toText(ParserContext.of(), true); } /** @@ -147,11 +176,21 @@ public static ImmutableMap getPlaceholders() { public interface PlaceholderGetter { + @Nullable PlaceholderHandler getPlaceholder(String placeholder); + @Nullable + default PlaceholderHandler getPlaceholder(String placeholder, ParserContext context) { + return getPlaceholder(placeholder); + } + default boolean isContextOptional() { return false; } + + default boolean exists(String placeholder) { + return this.getPlaceholder(placeholder) != null; + } } static { diff --git a/src/main/java/eu/pb4/placeholders/api/node/parent/ParentNode.java b/src/main/java/eu/pb4/placeholders/api/node/parent/ParentNode.java index 7353186..51254b6 100644 --- a/src/main/java/eu/pb4/placeholders/api/node/parent/ParentNode.java +++ b/src/main/java/eu/pb4/placeholders/api/node/parent/ParentNode.java @@ -28,17 +28,19 @@ public ParentTextNode copyWith(TextNode[] children) { public final Text toText(ParserContext context, boolean removeSingleSlash) { if (this.children.length == 0) { return Text.empty(); - } else if (this.children.length == 1) { + } else if (this.children.length == 1 && this.children[0] != null) { var out = this.children[0].toText(context, true); return ((MutableText) this.applyFormatting(out.copy(), context)).fillStyle(out.getStyle()); } else { var base = Text.empty(); for (int i = 0; i < this.children.length; i++) { - var child = this.children[i].toText(context, true); + if (this.children[i] != null) { + var child = this.children[i].toText(context, true); - if (child.getContent() != TextContent.EMPTY || child.getSiblings().size() > 0) { - base.append(child); + if (child.getContent() != TextContent.EMPTY || child.getSiblings().size() > 0) { + base.append(child); + } } } diff --git a/src/main/java/eu/pb4/placeholders/impl/placeholder/NodePlaceholderParserImpl.java b/src/main/java/eu/pb4/placeholders/impl/placeholder/NodePlaceholderParserImpl.java index 2f06f14..81cd226 100644 --- a/src/main/java/eu/pb4/placeholders/impl/placeholder/NodePlaceholderParserImpl.java +++ b/src/main/java/eu/pb4/placeholders/impl/placeholder/NodePlaceholderParserImpl.java @@ -1,6 +1,5 @@ package eu.pb4.placeholders.impl.placeholder; -import eu.pb4.placeholders.api.PlaceholderHandler; import eu.pb4.placeholders.api.Placeholders; import eu.pb4.placeholders.api.node.LiteralNode; import eu.pb4.placeholders.api.node.TextNode; @@ -48,8 +47,8 @@ public static TextNode[] recursivePlaceholderParsing(TextNode text, Pattern patt out.add(new LiteralNode(string.substring(previousEnd, start))); } - if (placeholders.getPlaceholder(placeholder[0]) != null) { - out.add(new PlaceholderNode(createRemoteHandler(placeholders, placeholder[0]), placeholders.isContextOptional(), placeholder.length == 2 ? placeholder[1] : null)); + if (placeholders.exists(placeholder[0])) { + out.add(new PlaceholderNode(placeholder[0], placeholders, placeholders.isContextOptional(), placeholder.length == 2 ? placeholder[1] : null)); } else { out.add(new LiteralNode(matcher.group(0))); } @@ -106,10 +105,6 @@ public static TextNode[] recursivePlaceholderParsing(TextNode text, Pattern patt return new TextNode[] { text }; } - private static PlaceholderHandler createRemoteHandler(Placeholders.PlaceholderGetter placeholders, String id) { - return (context, argument) -> placeholders.getPlaceholder(id).onPlaceholderRequest(context, argument); - } - /*private static TemplateStyle parsePlaceholdersInStyle(TemplateStyle style, Object object, Pattern pattern, Map placeholders) { if (style == null) { return null; diff --git a/src/main/java/eu/pb4/placeholders/impl/placeholder/PlaceholderNode.java b/src/main/java/eu/pb4/placeholders/impl/placeholder/PlaceholderNode.java index 474ec36..f0e866e 100644 --- a/src/main/java/eu/pb4/placeholders/impl/placeholder/PlaceholderNode.java +++ b/src/main/java/eu/pb4/placeholders/impl/placeholder/PlaceholderNode.java @@ -1,7 +1,7 @@ package eu.pb4.placeholders.impl.placeholder; import eu.pb4.placeholders.api.PlaceholderContext; -import eu.pb4.placeholders.api.PlaceholderHandler; +import eu.pb4.placeholders.api.Placeholders; import eu.pb4.placeholders.api.node.TextNode; import eu.pb4.placeholders.api.ParserContext; import net.minecraft.text.Text; @@ -10,10 +10,11 @@ import javax.annotation.Nullable; @ApiStatus.Internal -public record PlaceholderNode(PlaceholderHandler handler, boolean optionalContext, @Nullable String argument) implements TextNode { +public record PlaceholderNode(String placeholder, Placeholders.PlaceholderGetter getter, boolean optionalContext, @Nullable String argument) implements TextNode { @Override public Text toText(ParserContext context, boolean removeSingleSlash) { var ctx = context.get(PlaceholderContext.KEY); - return ctx != null || this.optionalContext ? handler.onPlaceholderRequest(ctx, argument).text() : Text.empty(); + var handler = getter.getPlaceholder(placeholder, context); + return (ctx != null || this.optionalContext) && handler != null ? handler.onPlaceholderRequest(ctx, argument).text() : Text.empty(); } } diff --git a/src/main/java/eu/pb4/placeholders/impl/placeholder/builtin/WorldPlaceholders.java b/src/main/java/eu/pb4/placeholders/impl/placeholder/builtin/WorldPlaceholders.java index 40a5c34..b9c9226 100644 --- a/src/main/java/eu/pb4/placeholders/impl/placeholder/builtin/WorldPlaceholders.java +++ b/src/main/java/eu/pb4/placeholders/impl/placeholder/builtin/WorldPlaceholders.java @@ -53,7 +53,7 @@ public static void register() { world = ctx.server().getOverworld(); } - return PlaceholderResult.value("" + world.getTime() / 24000); + return PlaceholderResult.value("" + world.getTimeOfDay() / 24000); }); Placeholders.register(new Identifier("world", "id"), (ctx, arg) -> {