Skip to content

Commit af5bb54

Browse files
committed
Add ScoreHolder, Operation, Objective, and Team argument types
1 parent 6fb36e3 commit af5bb54

File tree

25 files changed

+669
-51
lines changed

25 files changed

+669
-51
lines changed

LICENSE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,4 +65,5 @@ aerulion <aerulion@gmail.com>
6565
Lukas Planz <lukas.planz@web.de>
6666
granny <contact@granny.dev>
6767
mja00 <me@mja00.dev>
68+
Strokkur24 <strokkur.24@gmail.com>
6869
```

build-data/paper.at

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ public net.minecraft.Util onThreadException(Ljava/lang/Thread;Ljava/lang/Throwab
1313
public net.minecraft.advancements.Advancement decorateName(Lnet/minecraft/advancements/DisplayInfo;)Lnet/minecraft/network/chat/Component;
1414
public net.minecraft.commands.CommandSourceStack source
1515
public net.minecraft.commands.arguments.DimensionArgument ERROR_INVALID_VALUE
16+
public net.minecraft.commands.arguments.OperationArgument ERROR_INVALID_OPERATION
17+
public net.minecraft.commands.arguments.OperationArgument$SimpleOperation
1618
public net.minecraft.commands.arguments.blocks.BlockInput tag
1719
public net.minecraft.core.MappedRegistry validateWrite(Lnet/minecraft/resources/ResourceKey;)V
1820
public net.minecraft.nbt.ListTag <init>(Ljava/util/List;)V

paper-api/src/main/java/io/papermc/paper/InternalAPIBridge.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,17 @@
33
import io.papermc.paper.command.brigadier.CommandSourceStack;
44
import io.papermc.paper.world.damagesource.CombatEntry;
55
import io.papermc.paper.world.damagesource.FallLocationType;
6+
import java.util.function.Predicate;
67
import net.kyori.adventure.util.Services;
78
import org.bukkit.block.Biome;
89
import org.bukkit.damage.DamageEffect;
910
import org.bukkit.damage.DamageSource;
1011
import org.bukkit.entity.LivingEntity;
12+
import org.bukkit.scoreboard.ScoreHolder;
1113
import org.jetbrains.annotations.ApiStatus;
1214
import org.jspecify.annotations.NullMarked;
1315
import org.jspecify.annotations.Nullable;
1416

15-
import java.util.function.Predicate;
16-
1717
/**
1818
* Static bridge to the server internals.
1919
* <p>
@@ -77,6 +77,14 @@ class Holder {
7777
*/
7878
CombatEntry createCombatEntry(DamageSource damageSource, float damage, @Nullable FallLocationType fallLocationType, float fallDistance);
7979

80+
/**
81+
* Creates a wrapping score holder
82+
*
83+
* @param entry The entry to wrap
84+
* @return a wrapping ScoreHolder
85+
*/
86+
ScoreHolder scoreHolderOf(String entry);
87+
8088
/**
8189
* Causes this predicate to be considered restricted.
8290
* Applying this to a command node prevents this command from being executed from an

paper-api/src/main/java/io/papermc/paper/command/brigadier/argument/ArgumentTypes.java

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
package io.papermc.paper.command.brigadier.argument;
22

33
import com.mojang.brigadier.arguments.ArgumentType;
4+
import io.papermc.paper.command.brigadier.argument.operation.Operation;
45
import io.papermc.paper.command.brigadier.argument.predicate.ItemStackPredicate;
56
import io.papermc.paper.command.brigadier.argument.range.DoubleRangeProvider;
67
import io.papermc.paper.command.brigadier.argument.range.IntegerRangeProvider;
78
import io.papermc.paper.command.brigadier.argument.resolvers.BlockPositionResolver;
89
import io.papermc.paper.command.brigadier.argument.resolvers.FinePositionResolver;
10+
import io.papermc.paper.command.brigadier.argument.resolvers.ObjectiveResolver;
911
import io.papermc.paper.command.brigadier.argument.resolvers.PlayerProfileListResolver;
1012
import io.papermc.paper.command.brigadier.argument.resolvers.RotationResolver;
13+
import io.papermc.paper.command.brigadier.argument.resolvers.ScoreHolderResolver;
14+
import io.papermc.paper.command.brigadier.argument.resolvers.TeamResolver;
1115
import io.papermc.paper.command.brigadier.argument.resolvers.selector.EntitySelectorArgumentResolver;
1216
import io.papermc.paper.command.brigadier.argument.resolvers.selector.PlayerSelectorArgumentResolver;
1317
import io.papermc.paper.entity.LookAnchor;
@@ -297,6 +301,53 @@ public static ArgumentType<Criteria> objectiveCriteria() {
297301
return provider().objectiveCriteria();
298302
}
299303

304+
/**
305+
* Represents a selector that can capture any single
306+
* score holder.
307+
*
308+
* @return argument
309+
*/
310+
public static ArgumentType<ScoreHolderResolver> scoreHolder() {
311+
return provider().scoreHolder();
312+
}
313+
314+
/**
315+
* Represents a selector that can capture multiple
316+
* score holders.
317+
*
318+
* @return argument
319+
*/
320+
public static ArgumentType<ScoreHolderResolver> scoreHolders() {
321+
return provider().scoreHolders();
322+
}
323+
324+
/**
325+
* An operation argument.
326+
*
327+
* @return argument
328+
*/
329+
public static ArgumentType<Operation> operation() {
330+
return provider().operation();
331+
}
332+
333+
/**
334+
* An objective argument.
335+
*
336+
* @return argument
337+
*/
338+
public static ArgumentType<ObjectiveResolver> objective() {
339+
return provider().objective();
340+
}
341+
342+
/**
343+
* A team argument.
344+
*
345+
* @return argument
346+
*/
347+
public static ArgumentType<TeamResolver> team() {
348+
return provider().team();
349+
}
350+
300351
/**
301352
* An entity anchor argument.
302353
*

paper-api/src/main/java/io/papermc/paper/command/brigadier/argument/VanillaArgumentProvider.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
package io.papermc.paper.command.brigadier.argument;
22

33
import com.mojang.brigadier.arguments.ArgumentType;
4+
import io.papermc.paper.command.brigadier.argument.operation.Operation;
45
import io.papermc.paper.command.brigadier.argument.predicate.ItemStackPredicate;
56
import io.papermc.paper.command.brigadier.argument.range.DoubleRangeProvider;
67
import io.papermc.paper.command.brigadier.argument.range.IntegerRangeProvider;
78
import io.papermc.paper.command.brigadier.argument.resolvers.BlockPositionResolver;
89
import io.papermc.paper.command.brigadier.argument.resolvers.FinePositionResolver;
10+
import io.papermc.paper.command.brigadier.argument.resolvers.ObjectiveResolver;
911
import io.papermc.paper.command.brigadier.argument.resolvers.PlayerProfileListResolver;
1012
import io.papermc.paper.command.brigadier.argument.resolvers.RotationResolver;
13+
import io.papermc.paper.command.brigadier.argument.resolvers.ScoreHolderResolver;
14+
import io.papermc.paper.command.brigadier.argument.resolvers.TeamResolver;
1115
import io.papermc.paper.command.brigadier.argument.resolvers.selector.EntitySelectorArgumentResolver;
1216
import io.papermc.paper.command.brigadier.argument.resolvers.selector.PlayerSelectorArgumentResolver;
1317
import io.papermc.paper.entity.LookAnchor;
@@ -31,6 +35,8 @@
3135
import org.bukkit.inventory.ItemStack;
3236
import org.bukkit.scoreboard.Criteria;
3337
import org.bukkit.scoreboard.DisplaySlot;
38+
import org.bukkit.scoreboard.Scoreboard;
39+
import org.bukkit.scoreboard.Team;
3440
import org.jetbrains.annotations.ApiStatus;
3541

3642
@ApiStatus.Internal
@@ -75,6 +81,16 @@ static VanillaArgumentProvider provider() {
7581
ArgumentType<SignedMessageResolver> signedMessage();
7682

7783
ArgumentType<DisplaySlot> scoreboardDisplaySlot();
84+
85+
ArgumentType<ScoreHolderResolver> scoreHolder();
86+
87+
ArgumentType<ScoreHolderResolver> scoreHolders();
88+
89+
ArgumentType<Operation> operation();
90+
91+
ArgumentType<ObjectiveResolver> objective();
92+
93+
ArgumentType<TeamResolver> team();
7894

7995
ArgumentType<NamespacedKey> namespacedKey();
8096

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package io.papermc.paper.command.brigadier.argument.operation;
2+
3+
import com.mojang.brigadier.exceptions.CommandSyntaxException;
4+
import it.unimi.dsi.fastutil.ints.IntIntPair;
5+
import org.jetbrains.annotations.ApiStatus;
6+
import org.jspecify.annotations.NullMarked;
7+
8+
/**
9+
* Represents a simple arithmetic operation between two integers.
10+
* An {@link Operation} backs an operator.
11+
* Most arithmetic operators (like {@code +=, -=, /=, etc.}) are
12+
* supported, alongside certain conditional operators ({@code >=, <=, ==, etc.}).
13+
* <p>
14+
* Note that conditional operators, instead of yielding a boolean value, return the value
15+
* that matches the operation.
16+
* For example, the {@code <=} operator always returns the <strong>smaller</strong> value
17+
* of two given values.
18+
*/
19+
@ApiStatus.Experimental
20+
@NullMarked
21+
public interface Operation {
22+
23+
/**
24+
* Applies this operation to a pair of integers.
25+
* <p>
26+
* Arithmetic between two integers always follows this pattern:
27+
* <pre>
28+
* return left &lt;operator&gt; right
29+
* </pre>
30+
* On certain operators, such as division, the order matters.
31+
* {@code 20 %= 10} yields a different result than{@code 10 %= 20}.
32+
*
33+
* @param left left side of the expression
34+
* @param right right side of the expression
35+
* @return result of this operation
36+
*/
37+
IntIntPair apply(int left, int right) throws CommandSyntaxException;
38+
39+
/**
40+
* Applies this operation to a pair of integers.
41+
* <p>
42+
* Arithmetic between two integers always follows this pattern:
43+
* <pre>
44+
* return left &lt;operator&gt; right
45+
* </pre>
46+
* On certain operators, such as division, the order matters.
47+
* {@code 20 %= 10} yields a different result than{@code 10 %= 20}.
48+
*
49+
* @param left left side of the expression
50+
* @param right right side of the expression
51+
* @return the left side of the result of this operation
52+
* @see #apply(int, int)
53+
*/
54+
default int applyLeftSide(int left, int right) throws CommandSyntaxException {
55+
return apply(left, right).leftInt();
56+
}
57+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package io.papermc.paper.command.brigadier.argument.resolvers;
2+
3+
import com.mojang.brigadier.exceptions.CommandSyntaxException;
4+
import io.papermc.paper.command.brigadier.CommandSourceStack;
5+
import io.papermc.paper.command.brigadier.argument.ArgumentTypes;
6+
import org.bukkit.Bukkit;
7+
import org.bukkit.scoreboard.Objective;
8+
import org.bukkit.scoreboard.Scoreboard;
9+
import org.jetbrains.annotations.ApiStatus;
10+
import org.jspecify.annotations.NullMarked;
11+
12+
/**
13+
* A resolver that's capable of resolving
14+
* an {@link Objective} value using a {@link Scoreboard} and {@link CommandSourceStack}.
15+
*
16+
* @see ArgumentTypes#objective()
17+
*/
18+
@ApiStatus.Experimental
19+
@ApiStatus.NonExtendable
20+
@NullMarked
21+
public interface ObjectiveResolver {
22+
23+
/**
24+
* Resolves the argument with the given command source stack.
25+
* <p>
26+
* This method is the same as calling {@link #resolve(Scoreboard, CommandSourceStack)} with
27+
* the scoreboard retrieved from {@code Bukkit.getScoreboardManager().getMainScoreboard()}.
28+
*
29+
* @param sourceStack source stack
30+
* @return resolved objective
31+
*/
32+
default Objective resolve(CommandSourceStack sourceStack) throws CommandSyntaxException {
33+
return resolve(Bukkit.getScoreboardManager().getMainScoreboard(), sourceStack);
34+
}
35+
36+
/**
37+
* Resolves the argument with the given command source stack.
38+
* <p>
39+
* This method is the same as calling {@link #resolve(Scoreboard, CommandSourceStack)} with
40+
* the scoreboard retrieved from {@code Bukkit.getScoreboardManager().getMainScoreboard()}.
41+
*
42+
* @param sourceStack source stack
43+
* @return resolved objective, whose criteria is writable
44+
*/
45+
default Objective resolveWritable(CommandSourceStack sourceStack) throws CommandSyntaxException {
46+
return resolveWritable(Bukkit.getScoreboardManager().getMainScoreboard(), sourceStack);
47+
}
48+
49+
/**
50+
* Resolves the argument with the given command source stack.
51+
*
52+
* @param scoreboard scoreboard to get the objective from
53+
* @param sourceStack source stack
54+
* @return resolved objective
55+
*/
56+
Objective resolve(Scoreboard scoreboard, CommandSourceStack sourceStack) throws CommandSyntaxException;
57+
58+
/**
59+
* Resolves the argument with the given command source stack.
60+
*
61+
* @param scoreboard scoreboard to get the objective from
62+
* @param sourceStack source stack
63+
* @return resolved objective, whose criteria is writable
64+
*/
65+
Objective resolveWritable(Scoreboard scoreboard, CommandSourceStack sourceStack) throws CommandSyntaxException;
66+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package io.papermc.paper.command.brigadier.argument.resolvers;
2+
3+
import io.papermc.paper.command.brigadier.CommandSourceStack;
4+
import io.papermc.paper.command.brigadier.argument.ArgumentTypes;
5+
import org.bukkit.scoreboard.ScoreHolder;
6+
import org.jetbrains.annotations.ApiStatus;
7+
import java.util.Collection;
8+
import java.util.List;
9+
10+
/**
11+
* An {@link ArgumentResolver} that's capable of resolving
12+
* an argument value using a {@link CommandSourceStack} into a
13+
* list of {@link ScoreHolder}s.
14+
*
15+
* @see ArgumentTypes#scoreHolders()
16+
*/
17+
@ApiStatus.Experimental
18+
@ApiStatus.NonExtendable
19+
public interface ScoreHolderResolver extends ArgumentResolver<List<ScoreHolder>> {
20+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package io.papermc.paper.command.brigadier.argument.resolvers;
2+
3+
import com.mojang.brigadier.exceptions.CommandSyntaxException;
4+
import io.papermc.paper.command.brigadier.CommandSourceStack;
5+
import io.papermc.paper.command.brigadier.argument.ArgumentTypes;
6+
import org.bukkit.Bukkit;
7+
import org.bukkit.scoreboard.Scoreboard;
8+
import org.bukkit.scoreboard.ScoreboardManager;
9+
import org.bukkit.scoreboard.Team;
10+
import org.jetbrains.annotations.ApiStatus;
11+
import org.jspecify.annotations.NullMarked;
12+
13+
/**
14+
* A resolver that's capable of resolving
15+
* a {@link Team} value using a {@link Scoreboard} and {@link CommandSourceStack}.
16+
*
17+
* @see ArgumentTypes#objective()
18+
*/
19+
@ApiStatus.Experimental
20+
@ApiStatus.NonExtendable
21+
@NullMarked
22+
public interface TeamResolver {
23+
24+
/**
25+
* Resolves the argument with the given command source stack.
26+
* <p>
27+
* This method is the same as calling {@link #resolve(Scoreboard, CommandSourceStack)} with
28+
* the scoreboard retrieved from {@code Bukkit.getScoreboardManager().getMainScoreboard()}.
29+
*
30+
* @param sourceStack source stack
31+
* @return resolved team
32+
* @see #resolve(Scoreboard, CommandSourceStack)
33+
* @see ScoreboardManager#getMainScoreboard()
34+
*/
35+
default Team resolve(CommandSourceStack sourceStack) throws CommandSyntaxException {
36+
return resolve(Bukkit.getScoreboardManager().getMainScoreboard(), sourceStack);
37+
}
38+
39+
/**
40+
* Resolves the argument with the given scoreboard and command source stack.
41+
*
42+
* @param scoreboard scoreboard to get the team from
43+
* @param sourceStack source stack
44+
* @return resolved team
45+
*/
46+
Team resolve(Scoreboard scoreboard, CommandSourceStack sourceStack) throws CommandSyntaxException;
47+
}

paper-api/src/main/java/org/bukkit/OfflinePlayer.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import org.bukkit.entity.Player;
1212
import org.bukkit.permissions.ServerOperator;
1313
import org.bukkit.profile.PlayerProfile;
14+
import org.bukkit.scoreboard.ScoreHolder;
1415
import org.jspecify.annotations.NullMarked;
1516
import org.jspecify.annotations.Nullable;
1617

@@ -20,7 +21,7 @@
2021
* player needing to be online.
2122
*/
2223
@NullMarked
23-
public interface OfflinePlayer extends ServerOperator, AnimalTamer, ConfigurationSerializable, io.papermc.paper.persistence.PersistentDataViewHolder { // Paper - Add Offline PDC API
24+
public interface OfflinePlayer extends ServerOperator, AnimalTamer, ConfigurationSerializable, io.papermc.paper.persistence.PersistentDataViewHolder, ScoreHolder { // Paper - Add Offline PDC API
2425

2526
/**
2627
* Checks if this player is currently online

0 commit comments

Comments
 (0)