Skip to content

Commit 684c2c4

Browse files
committed
Update to 26.1-snapshot-7, add client placeholders
1 parent 608d164 commit 684c2c4

16 files changed

Lines changed: 299 additions & 58 deletions

build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ dependencies {
5454

5555
// Fabric API. This is technically optional, but you probably want it anyway.
5656
//modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
57-
compileOnly("net.fabricmc.fabric-api:fabric-api:${project.fabric_version}")
58-
localRuntime("net.fabricmc.fabric-api:fabric-api:${project.fabric_version}")
57+
compileOnly("net.fabricmc.fabric-api:fabric-api:${project.fabric_api_version}")
58+
localRuntime("net.fabricmc.fabric-api:fabric-api:${project.fabric_api_version}")
5959

6060
// PSA: Some older mods, compiled on Loom 0.2.1, might have outdated Maven POMs.
6161
// You may need to force-disable transitiveness on them.

gradle.properties

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@ org.gradle.jvmargs=-Xmx1G
33

44
# Fabric Properties
55
# check these on https://fabricmc.net/use
6-
minecraft_version=26.1-snapshot-1
6+
minecraft_version=26.1-snapshot-7
77
loader_version=0.18.4
8-
loom_version=1.14-SNAPSHOT
8+
loom_version=1.15-SNAPSHOT
99

1010
# Fabric API
11-
fabric_version=0.140.2+26.1
11+
fabric_api_version=0.143.4+26.1
1212

1313
# Mod Properties
14-
mod_version = 3.0.0-alpha.1+26.1-snapshot-1
14+
mod_version = 3.0.0-beta.1+26.1
1515
maven_group = eu.pb4
1616
archives_base_name = placeholder-api

src/main/java/eu/pb4/placeholders/api/PlaceholderContext.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
import net.minecraft.world.entity.player.Player;
1616
import net.minecraft.world.level.Level;
1717
import net.minecraft.world.phys.Vec3;
18+
import org.intellij.lang.annotations.Flow;
19+
import org.jetbrains.annotations.Contract;
1820
import org.jspecify.annotations.Nullable;
1921

2022
import javax.tools.Diagnostic;
@@ -67,6 +69,7 @@ default void addToContext(ParserContext context) {
6769
}
6870

6971
HolderLookup.@Nullable Provider holderLookup();
72+
7073
@Nullable
7174
Level level();
7275

src/main/java/eu/pb4/placeholders/api/Placeholders.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
package eu.pb4.placeholders.api;
22

33
import com.google.common.collect.ImmutableMap;
4+
import eu.pb4.placeholders.api.client.ClientPlaceholderContext;
5+
import eu.pb4.placeholders.api.client.ClientPlaceholders;
46
import eu.pb4.placeholders.api.parsers.NodeParser;
57
import eu.pb4.placeholders.api.parsers.TagLikeParser;
8+
import eu.pb4.placeholders.impl.LoaderUtil;
69
import eu.pb4.placeholders.impl.PlaceholderContextImpl;
710
import eu.pb4.placeholders.impl.placeholder.builtin.PlayerPlaceholders;
811
import eu.pb4.placeholders.impl.placeholder.builtin.ServerPlaceholders;
@@ -107,6 +110,11 @@ public static void registerCommon(Placeholder<PlaceholderContext, ?> placeholder
107110
//noinspection unchecked
108111
registerServer((Placeholder<ServerPlaceholderContext, ?>) (Object) placeholder);
109112
}
113+
114+
if (LoaderUtil.IS_CLIENT) {
115+
//noinspection unchecked
116+
ClientPlaceholders.registerClient((Placeholder<ClientPlaceholderContext, ?>) (Object) placeholder);
117+
}
110118
}
111119

112120
public static ImmutableMap<Identifier, Placeholder<PlaceholderContext, ?>> getCommonPlaceholders() {

src/main/java/eu/pb4/placeholders/api/ServerPlaceholderContext.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ default boolean hasServerPlayer() {
6767
return this.serverPlayer() != null;
6868
}
6969

70-
ServerPlaceholderContext withView(PlaceholderContextImpl.ViewObject view);
70+
ServerPlaceholderContext withView(ViewObject view);
7171

7272
MinecraftServer server();
7373

@@ -81,12 +81,12 @@ default boolean hasServerPlayer() {
8181

8282
@Override
8383
default ParserContext asParserContext() {
84-
return ParserContext.of(SERVER_KEY, this).with(ParserContext.Key.HOLDER_LOOKUP, this.holderLookup());
84+
return ParserContext.of(SERVER_KEY, this).with(COMMON_KEY, this).with(ParserContext.Key.HOLDER_LOOKUP, this.holderLookup());
8585
}
8686

8787
@Override
8888
default void addToContext(ParserContext context) {
89-
context.with(SERVER_KEY, this);
89+
context.with(SERVER_KEY, this).with(COMMON_KEY, this);
9090
context.withIfNotSet(ParserContext.Key.HOLDER_LOOKUP, this.holderLookup());
9191
}
9292
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package eu.pb4.placeholders.api.client;
2+
3+
import eu.pb4.placeholders.api.ParserContext;
4+
import eu.pb4.placeholders.api.PlaceholderContext;
5+
import eu.pb4.placeholders.impl.client.ClientPlaceholderContextImpl;
6+
import net.fabricmc.api.EnvType;
7+
import net.fabricmc.api.Environment;
8+
import net.minecraft.client.Minecraft;
9+
import net.minecraft.client.multiplayer.ClientLevel;
10+
import net.minecraft.client.player.LocalPlayer;
11+
import org.jspecify.annotations.Nullable;
12+
13+
@Environment(EnvType.CLIENT)
14+
public interface ClientPlaceholderContext extends PlaceholderContext {
15+
ParserContext.Key<ClientPlaceholderContext> CLIENT_KEY = ParserContext.Key.of("client_placeholder_context", ClientPlaceholderContext.class);
16+
static ClientPlaceholderContext get() {
17+
return new ClientPlaceholderContextImpl(Minecraft.getInstance(), null);
18+
}
19+
20+
@Nullable
21+
ClientLevel level();
22+
23+
@Nullable
24+
LocalPlayer player();
25+
26+
@Override
27+
ClientPlaceholderContext withView(ViewObject view);
28+
29+
@Override
30+
default ParserContext asParserContext() {
31+
return ParserContext.of(CLIENT_KEY, this).with(COMMON_KEY, this).with(ParserContext.Key.HOLDER_LOOKUP, this.holderLookup());
32+
}
33+
34+
@Override
35+
default void addToContext(ParserContext context) {
36+
context.with(CLIENT_KEY, this).with(COMMON_KEY, this);
37+
context.withIfNotSet(ParserContext.Key.HOLDER_LOOKUP, this.holderLookup());
38+
}
39+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package eu.pb4.placeholders.api.client;
2+
3+
import com.google.common.collect.ImmutableMap;
4+
import eu.pb4.placeholders.api.*;
5+
import eu.pb4.placeholders.api.parsers.NodeParser;
6+
import eu.pb4.placeholders.api.parsers.TagLikeParser;
7+
import net.fabricmc.api.EnvType;
8+
import net.fabricmc.api.Environment;
9+
import net.minecraft.resources.Identifier;
10+
import org.jspecify.annotations.Nullable;
11+
12+
import java.util.ArrayList;
13+
import java.util.HashMap;
14+
import java.util.List;
15+
16+
@Environment(EnvType.CLIENT)
17+
public class ClientPlaceholders {
18+
private static final HashMap<Identifier, Placeholder<ClientPlaceholderContext, ?>> CLIENT_PLACEHOLDERS = new HashMap<>();
19+
public static final Placeholders.PlaceholderGetter<ClientPlaceholderContext> CLIENT_PLACEHOLDER_GETTER = placeholder -> getClientPlaceholder(Identifier.tryParse(placeholder));
20+
public static final NodeParser CLIENT_PLACEHOLDER_PARSER = TagLikeParser.placeholder(TagLikeParser.PLACEHOLDER, ClientPlaceholderContext.CLIENT_KEY, CLIENT_PLACEHOLDER_GETTER);
21+
private static final List<Placeholders.PlaceholderListChangedCallback> CLIENT_CHANGED_CALLBACKS = new ArrayList<>();
22+
23+
static {
24+
//noinspection ResultOfMethodCallIgnored
25+
Placeholders.COMMON_PLACEHOLDER_GETTER.getClass();
26+
}
27+
28+
/**
29+
* Parses PlaceholderContext, can be used for parsing by hand
30+
*
31+
* @return PlaceholderResult
32+
*/
33+
public static PlaceholderResult parseClientPlaceholder(Identifier identifier, String argument, ClientPlaceholderContext context) {
34+
var placeholder = getClientPlaceholder(identifier);
35+
if (placeholder != null) {
36+
return placeholder.onPlaceholderRequest(context, argument);
37+
} else {
38+
return PlaceholderResult.invalid("Placeholder doesn't exist!");
39+
}
40+
}
41+
42+
@Nullable
43+
public static Placeholder<ClientPlaceholderContext, ?> getClientPlaceholder(Identifier identifier) {
44+
return CLIENT_PLACEHOLDERS.get(identifier);
45+
}
46+
47+
/**
48+
* Registers new placeholder for identifier
49+
*/
50+
public static <T> void registerClient(Identifier identifier, Placeholder.Handler<ClientPlaceholderContext, String> handler) {
51+
registerClient(identifier, ArgumentParser.STRING, handler);
52+
}
53+
54+
public static <T> void registerClient(Identifier identifier, ArgumentParser<T> argumentParser, Placeholder.Handler<ClientPlaceholderContext, T> handler) {
55+
registerClient(new Placeholder<>(identifier, argumentParser, handler));
56+
}
57+
58+
public static void registerClient(Placeholder<ClientPlaceholderContext, ?> placeholder) {
59+
CLIENT_PLACEHOLDERS.put(placeholder.identifier(), placeholder);
60+
for (var e : CLIENT_CHANGED_CALLBACKS) {
61+
e.onPlaceholderListChange(placeholder.identifier(), false);
62+
}
63+
}
64+
65+
public static ImmutableMap<Identifier, Placeholder<ClientPlaceholderContext, ?>> getClientPlaceholders() {
66+
return ImmutableMap.copyOf(CLIENT_PLACEHOLDERS);
67+
}
68+
69+
public static void registerClientChangeEvent(Placeholders.PlaceholderListChangedCallback callback) {
70+
CLIENT_CHANGED_CALLBACKS.add(callback);
71+
}
72+
}

src/main/java/eu/pb4/placeholders/api/node/parent/HoverNode.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import eu.pb4.placeholders.impl.PlaceholderContextImpl;
66
import eu.pb4.placeholders.api.node.TextNode;
77
import eu.pb4.placeholders.api.parsers.NodeParser;
8+
import net.minecraft.world.item.ItemStackTemplate;
89
import org.jspecify.annotations.Nullable;
910

1011
import java.util.Arrays;
@@ -161,13 +162,12 @@ public String toString() {
161162
}
162163

163164
public record LazyItemStackNodeContent<T>(Identifier identifier, int count, DynamicOps<T> ops, T componentMap) {
164-
public ItemStack toVanilla(HolderLookup.Provider lookup) {
165-
var stack = new ItemStack(lookup.lookupOrThrow(Registries.ITEM).getOrThrow(ResourceKey.create(Registries.ITEM, identifier)));
166-
stack.setCount(count);
165+
public ItemStackTemplate toVanilla(HolderLookup.Provider lookup) {
166+
var patch = DataComponentPatch.EMPTY;
167167
if (componentMap != null) {
168-
stack.applyComponentsAndValidate(DataComponentPatch.CODEC.decode(lookup.createSerializationContext(ops), componentMap).getOrThrow().getFirst());
168+
patch = DataComponentPatch.CODEC.decode(lookup.createSerializationContext(ops), componentMap).getOrThrow().getFirst();
169169
}
170-
return stack;
170+
return new ItemStackTemplate(lookup.lookupOrThrow(Registries.ITEM).getOrThrow(ResourceKey.create(Registries.ITEM, identifier)), count, patch);
171171
}
172172

173173
@Override

src/main/java/eu/pb4/placeholders/api/parsers/ParserBuilder.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
package eu.pb4.placeholders.api.parsers;
22

33
import eu.pb4.placeholders.api.*;
4+
import eu.pb4.placeholders.api.client.ClientPlaceholderContext;
5+
import eu.pb4.placeholders.api.client.ClientPlaceholders;
46
import eu.pb4.placeholders.api.node.TextNode;
57
import eu.pb4.placeholders.api.parsers.tag.TagRegistry;
8+
import eu.pb4.placeholders.impl.LoaderUtil;
69
import eu.pb4.placeholders.impl.PlaceholderContextImpl;
710
import eu.pb4.placeholders.impl.textparser.MultiTagLikeParser;
811
import eu.pb4.placeholders.impl.textparser.SingleTagLikeParser;
@@ -11,6 +14,7 @@
1114
import java.util.function.Function;
1215
import net.minecraft.ChatFormatting;
1316
import net.minecraft.network.chat.Component;
17+
import org.jetbrains.annotations.ApiStatus;
1418

1519
/**
1620
* Allows you to create stacked parser in most "correct" and compatible way.
@@ -69,6 +73,21 @@ public ParserBuilder commonPlaceholders(TagLikeParser.Format format, ParserConte
6973
return customTags(format, TagLikeParser.Provider.placeholder(contextKey, Placeholders.COMMON_PLACEHOLDER_GETTER));
7074
}
7175

76+
@ApiStatus.Experimental
77+
public ParserBuilder clientPlaceholders() {
78+
if (LoaderUtil.IS_CLIENT) {
79+
return add(ClientPlaceholders.CLIENT_PLACEHOLDER_PARSER);
80+
}
81+
throw new RuntimeException("This method only work in client environment!");
82+
}
83+
84+
@ApiStatus.Experimental
85+
public ParserBuilder clientPlaceholders(TagLikeParser.Format format) {
86+
if (LoaderUtil.IS_CLIENT) {
87+
return customTags(format, TagLikeParser.Provider.placeholder(ClientPlaceholderContext.CLIENT_KEY, ClientPlaceholders.CLIENT_PLACEHOLDER_GETTER));
88+
}
89+
throw new RuntimeException("This method only work in client environment!");
90+
}
7291

7392
/**
7493
* Enables parsing of custom placeholder with a custom format and context source

src/main/java/eu/pb4/placeholders/impl/GeneralUtils.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import net.minecraft.network.chat.*;
99
import net.minecraft.network.chat.contents.*;
1010
import net.minecraft.world.item.ItemStack;
11+
import net.minecraft.world.item.ItemStackTemplate;
1112
import org.jetbrains.annotations.ApiStatus;
1213
import org.jspecify.annotations.Nullable;
1314
import org.slf4j.Logger;
@@ -226,7 +227,7 @@ public static Component getItemText(ItemStack stack, boolean rarity) {
226227
if (rarity) {
227228
mutableText.withStyle(stack.getRarity().color());
228229
}
229-
mutableText.withStyle((style) -> style.withHoverEvent(new HoverEvent.ShowItem(stack)));
230+
mutableText.withStyle((style) -> style.withHoverEvent(new HoverEvent.ShowItem(ItemStackTemplate.fromNonEmptyStack(stack))));
230231

231232
return mutableText;
232233
}

0 commit comments

Comments
 (0)