Skip to content

Commit 72cc86f

Browse files
authored
1.21.11 update (#2798)
2 parents df922b2 + 8f9438b commit 72cc86f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+363
-218
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ The Denizen Scripting Language - Spigot Impl
33

44
An implementation of the Denizen Scripting Language for Spigot servers, with strong Citizens interlinks to emphasize the power of using Denizen with NPCs!
55

6-
**Version 1.3.1**: Compatible with Spigot 1.17.1, 1.18.2, 1.19.4, 1.20.6, and 1.21.10!
6+
**Version 1.3.1**: Compatible with Spigot 1.17.1, 1.18.2, 1.19.4, 1.20.6, and 1.21.11!
77

88
**Learn about Denizen from the Beginner's guide:** https://guide.denizenscript.com/guides/background/index.html
99

paper/pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,13 @@
2525
<dependency>
2626
<groupId>io.papermc.paper</groupId>
2727
<artifactId>paper-api</artifactId>
28-
<version>1.21.10-R0.1-SNAPSHOT</version>
28+
<version>1.21.11-R0.1-SNAPSHOT</version>
2929
<scope>provided</scope>
3030
</dependency>
3131
<dependency>
3232
<groupId>net.citizensnpcs</groupId>
3333
<artifactId>citizens-main</artifactId>
34-
<version>2.0.38-SNAPSHOT</version>
34+
<version>2.0.41-SNAPSHOT</version>
3535
<type>jar</type>
3636
<scope>provided</scope>
3737
<exclusions>

paper/src/main/java/com/denizenscript/denizen/paper/events/WorldGameRuleChangeScriptEvent.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import com.denizenscript.denizen.objects.PlayerTag;
88
import com.denizenscript.denizen.objects.WorldTag;
99
import com.denizenscript.denizen.utilities.implementation.BukkitScriptEntryData;
10+
import com.denizenscript.denizen.utilities.world.GameRuleReflect;
1011
import com.denizenscript.denizencore.objects.ObjectTag;
1112
import com.denizenscript.denizencore.objects.core.ElementTag;
1213
import com.denizenscript.denizencore.scripts.ScriptEntryData;
@@ -69,7 +70,7 @@ public boolean matches(ScriptPath path) {
6970
if (path.eventArgLowerAt(2).equals("in") && !path.tryArgObject(3, world)) {
7071
return false;
7172
}
72-
if (!runGenericSwitchCheck(path, "gamerule", event.getGameRule().getName())) {
73+
if (!runGenericSwitchCheck(path, "gamerule", GameRuleReflect.getName(event.getGameRule()))) {
7374
return false;
7475
}
7576
return super.matches(path);
@@ -78,7 +79,7 @@ public boolean matches(ScriptPath path) {
7879
@Override
7980
public ObjectTag getContext(String name) {
8081
return switch (name) {
81-
case "gamerule" -> new ElementTag(event.getGameRule().getName(), true);
82+
case "gamerule" -> new ElementTag(GameRuleReflect.getName(event.getGameRule()), true);
8283
case "value" -> new ElementTag(event.getValue(), true);
8384
case "source_type" -> getSourceType();
8485
case "command_block_location" -> getCommandBlock();

plugin/pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
<dependency>
3131
<groupId>org.spigotmc</groupId>
3232
<artifactId>spigot-api</artifactId>
33-
<version>1.21.10-R0.1-SNAPSHOT</version>
33+
<version>1.21.11-R0.1-SNAPSHOT</version>
3434
<type>jar</type>
3535
<scope>provided</scope>
3636
</dependency>
@@ -44,7 +44,7 @@
4444
<dependency>
4545
<groupId>net.citizensnpcs</groupId>
4646
<artifactId>citizens-main</artifactId>
47-
<version>2.0.38-SNAPSHOT</version>
47+
<version>2.0.41-SNAPSHOT</version>
4848
<type>jar</type>
4949
<scope>provided</scope>
5050
<exclusions>

plugin/src/main/java/com/denizenscript/denizen/objects/WorldTag.java

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import com.denizenscript.denizen.nms.abstracts.BiomeNMS;
77
import com.denizenscript.denizen.utilities.BukkitImplDeprecations;
88
import com.denizenscript.denizen.utilities.flags.WorldFlagHandler;
9+
import com.denizenscript.denizen.utilities.world.GameRuleReflect;
910
import com.denizenscript.denizencore.flags.AbstractFlagTracker;
1011
import com.denizenscript.denizencore.flags.FlaggableObject;
1112
import com.denizenscript.denizencore.objects.Adjustable;
@@ -177,7 +178,7 @@ public <T> T getGameRuleOrDefault(GameRule<T> gameRule) {
177178
if (value == null) {
178179
value = world.getGameRuleDefault(gameRule);
179180
if (value == null) {
180-
throw new IllegalStateException("World " + world_name + " contains no GameRule " + gameRule.getName());
181+
throw new IllegalStateException("World " + world_name + " contains no GameRule " + GameRuleReflect.getName(gameRule));
181182
}
182183
}
183184
return value;
@@ -852,16 +853,19 @@ else if (time >= 12500) {
852853
// @returns ElementTag
853854
// @description
854855
// Returns the current value of the specified gamerule in the world.
855-
// Note that the name is case-sensitive... so "doFireTick" is correct, but "dofiretick" is not.
856856
// -->
857857
registerTag(ElementTag.class, "gamerule", (attribute, object) -> {
858858
if (!attribute.hasParam()) {
859859
attribute.echoError("The tag 'worldtag.gamerule[...]' must have an input value.");
860860
return null;
861861
}
862-
GameRule rule = GameRule.getByName(attribute.getParam());
863-
Object result = object.getWorld().getGameRuleValue(rule);
864-
return new ElementTag(result == null ? "null" : result.toString());
862+
GameRule<?> rule = GameRuleReflect.getByName(attribute.getParam());
863+
if (rule == null) {
864+
attribute.echoError("Invalid game rule specified: " + attribute.getParam() + '.');
865+
return null;
866+
}
867+
Object result = GameRuleReflect.getValue(object.getWorld(), rule);
868+
return new ElementTag(String.valueOf(result), true);
865869
});
866870

867871
// <--[tag]
@@ -872,10 +876,10 @@ else if (time >= 12500) {
872876
// -->
873877
registerTag(MapTag.class, "gamerule_map", (attribute, object) -> {
874878
MapTag map = new MapTag();
875-
for (GameRule rule : GameRule.values()) {
876-
Object result = object.getWorld().getGameRuleValue(rule);
879+
for (GameRule<?> rule : GameRuleReflect.values()) {
880+
Object result = GameRuleReflect.getValue(object.getWorld(), rule);
877881
if (result != null) {
878-
map.putObject(rule.getName(), new ElementTag(result.toString()));
882+
map.putObject(GameRuleReflect.getName(rule), new ElementTag(result.toString(), true));
879883
}
880884
}
881885
return map;
@@ -987,7 +991,7 @@ else if (time >= 12500) {
987991
// @description
988992
// Returns whether enough players are sleeping to prepare for the night to advance.
989993
// Typically used before checking <@link tag WorldTag.enough_deep_sleeping>
990-
// By default, automatically checks the playersSleepingPercentage gamerule,
994+
// By default, automatically checks the players_sleeping_percentage gamerule,
991995
// but this can optionally be overridden by specifying a percentage integer.
992996
// Any integer above 100 will always yield 'false'. Requires at least one player to be sleeping to return 'true'.
993997
// -->
@@ -1008,7 +1012,7 @@ else if (time >= 12500) {
10081012
// @description
10091013
// Returns whether enough players have been in bed long enough for the night to advance (generally 100 ticks).
10101014
// Loops through all online players, so is typically used after checking <@link tag WorldTag.enough_sleeping>
1011-
// By default, automatically checks the playersSleepingPercentage gamerule,
1015+
// By default, automatically checks the players_sleeping_percentage gamerule,
10121016
// but this can optionally be overridden by specifying a percentage integer.
10131017
// Any integer above 100 will always yield 'false'. Requires at least one player to be sleeping to return 'true'.
10141018
// -->
@@ -1509,7 +1513,7 @@ else if (time >= 12500) {
15091513
// @input None
15101514
// @description
15111515
// Skips to the next day as if enough players slept through the night.
1512-
// NOTE: This ignores the doDaylightCycle gamerule!
1516+
// NOTE: This ignores the advance_time gamerule!
15131517
// -->
15141518
tagProcessor.registerMechanism("skip_night", false, (object, mechanism) -> {
15151519
// general logic from NMS world tick
@@ -1525,7 +1529,7 @@ else if (time >= 12500) {
15251529
NMSHandler.worldHelper.wakeUpAllPlayers(world);
15261530
}
15271531
// minor change: prior to 1.18, hasStorm/isRaining was not checked
1528-
if (object.getGameRuleOrDefault(GameRule.DO_WEATHER_CYCLE) && world.hasStorm()) {
1532+
if (object.getGameRuleOrDefault(GameRuleReflect.WEATHER_CYCLE_GAMERULE) && world.hasStorm()) {
15291533
NMSHandler.worldHelper.clearWeather(world);
15301534
}
15311535
});

plugin/src/main/java/com/denizenscript/denizen/scripts/commands/world/GameRuleCommand.java

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
package com.denizenscript.denizen.scripts.commands.world;
22

3-
import com.denizenscript.denizencore.utilities.debugging.Debug;
43
import com.denizenscript.denizen.objects.WorldTag;
4+
import com.denizenscript.denizen.utilities.world.GameRuleReflect;
55
import com.denizenscript.denizencore.exceptions.InvalidArgumentsException;
66
import com.denizenscript.denizencore.objects.Argument;
77
import com.denizenscript.denizencore.objects.core.ElementTag;
88
import com.denizenscript.denizencore.scripts.ScriptEntry;
99
import com.denizenscript.denizencore.scripts.commands.AbstractCommand;
10+
import com.denizenscript.denizencore.utilities.debugging.Debug;
11+
import com.denizenscript.denizencore.utilities.debugging.DebugInternals;
1012
import org.bukkit.Bukkit;
13+
import org.bukkit.GameRule;
1114
import org.bukkit.generator.WorldInfo;
1215

13-
import java.util.stream.Collectors;
14-
1516
public class GameRuleCommand extends AbstractCommand {
1617

1718
public GameRuleCommand() {
@@ -31,24 +32,25 @@ public GameRuleCommand() {
3132
//
3233
// @Description
3334
// Sets a gamerule on the world. A list of valid gamerules can be found here: <@link url https://minecraft.wiki/w/Game_rule>
34-
// Note: Be careful, gamerules are CASE SENSITIVE.
3535
//
3636
// @Tags
3737
// <WorldTag.gamerule[<gamerule>]>
3838
//
3939
// @Usage
4040
// Use to disable fire spreading in world "Adventure".
41-
// - gamerule Adventure doFireTick false
41+
// - gamerule Adventure fire_spread_radius_around_player 0
4242
//
4343
// @Usage
4444
// Use to avoid mobs from destroying blocks (creepers, endermen...) and picking items up (zombies, skeletons...) in world "Adventure".
45-
// - gamerule Adventure mobGriefing false
45+
// - gamerule Adventure mob_griefing false
4646
// -->
4747

4848
@Override
4949
public void addCustomTabCompletions(TabCompletionsBuilder tab) {
50-
tab.add(Bukkit.getWorlds().get(0).getGameRules());
51-
tab.add(Bukkit.getWorlds().stream().map(WorldInfo::getName).collect(Collectors.toSet()));
50+
for (GameRule<?> gameRule : GameRuleReflect.values()) {
51+
tab.add(GameRuleReflect.getName(gameRule));
52+
}
53+
tab.add(Bukkit.getWorlds().stream().map(WorldInfo::getName).toList());
5254
}
5355

5456
@Override
@@ -82,12 +84,37 @@ else if (!scriptEntry.hasObject("value")) {
8284
@Override
8385
public void execute(ScriptEntry scriptEntry) {
8486
WorldTag world = scriptEntry.getObjectTag("world");
85-
ElementTag gamerule = scriptEntry.getElement("gamerule");
86-
ElementTag value = scriptEntry.getElement("value");
87+
ElementTag gameRuleInput = scriptEntry.getElement("gamerule");
88+
ElementTag valueInput = scriptEntry.getElement("value");
8789
if (scriptEntry.dbCallShouldDebug()) {
88-
Debug.report(scriptEntry, getName(), world, gamerule, value);
90+
Debug.report(scriptEntry, getName(), world, gameRuleInput, valueInput);
91+
}
92+
GameRule gameRule = GameRuleReflect.getByName(gameRuleInput.asString());
93+
if (gameRule == null) {
94+
Debug.echoError("Invalid game rule specified: " + gameRuleInput.asString() + '.');
95+
return;
96+
}
97+
Class<?> gameRuleType = GameRuleReflect.getType(gameRule);
98+
Object convertedValue;
99+
if (gameRuleType == Integer.class) {
100+
if (!valueInput.isInt()) {
101+
Debug.echoError("Invalid value specified: must be a number.");
102+
return;
103+
}
104+
convertedValue = valueInput.asInt();
105+
}
106+
else if (gameRuleType == Boolean.class) {
107+
if (!valueInput.isBoolean()) {
108+
Debug.echoError("Invalid value specified: must be a boolean.");
109+
return;
110+
}
111+
convertedValue = valueInput.asBoolean();
112+
}
113+
else {
114+
Debug.echoError("Unrecognized game rule type '" + DebugInternals.getFullClassNameOpti(gameRuleType) + "'! Please report this to the developers.");
115+
return;
89116
}
90-
if (!world.getWorld().setGameRuleValue(gamerule.asString(), value.asString())) {
117+
if (!world.getWorld().setGameRule(gameRule, convertedValue)) {
91118
Debug.echoError(scriptEntry, "Invalid gamerule!");
92119
}
93120
}

plugin/src/main/java/com/denizenscript/denizen/tags/core/ServerTagBase.java

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import com.denizenscript.denizen.utilities.*;
1515
import com.denizenscript.denizen.utilities.depends.Depends;
1616
import com.denizenscript.denizen.utilities.inventory.SlotHelper;
17+
import com.denizenscript.denizen.utilities.world.GameRuleReflect;
1718
import com.denizenscript.denizencore.DenizenCore;
1819
import com.denizenscript.denizencore.events.ScriptEvent;
1920
import com.denizenscript.denizencore.objects.Mechanism;
@@ -639,11 +640,7 @@ else if (param.shouldBeType(EntityTag.class)) {
639640
// Returns a list of all available gamerules on the server.
640641
// -->
641642
tagProcessor.registerStaticTag(ListTag.class, "gamerules", (attribute, object) -> {
642-
ListTag gamerules = new ListTag();
643-
for (GameRule<?> rule : GameRule.values()) {
644-
gamerules.add(rule.getName());
645-
}
646-
return gamerules;
643+
return new ListTag(Arrays.asList(GameRuleReflect.values()), gameRule -> new ElementTag(GameRuleReflect.getName(gameRule), true));
647644
});
648645

649646
// <--[tag]
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package com.denizenscript.denizen.utilities.world;
2+
3+
import com.denizenscript.denizen.nms.NMSHandler;
4+
import com.denizenscript.denizen.nms.NMSVersion;
5+
import com.denizenscript.denizencore.utilities.ReflectionHelper;
6+
import org.bukkit.GameRule;
7+
import org.bukkit.World;
8+
9+
import java.lang.invoke.MethodHandle;
10+
11+
public class GameRuleReflect {
12+
13+
private static final MethodHandle GAMERULE_VALUES = ReflectionHelper.getMethodHandle(GameRule.class, "values");
14+
private static final MethodHandle GAMERULE_GET_BY_NAME = ReflectionHelper.getMethodHandle(GameRule.class, "getByName", String.class);
15+
private static final MethodHandle GAMERULE_GET_NAME = ReflectionHelper.getMethodHandle(GameRule.class, "getName");
16+
private static final MethodHandle GAMERULE_GET_TYPE = ReflectionHelper.getMethodHandle(GameRule.class, "getType");
17+
18+
public static final GameRule<Boolean> WEATHER_CYCLE_GAMERULE = NMSHandler.getVersion().isAtLeast(NMSVersion.v1_21) ? GameRule.ADVANCE_WEATHER : (GameRule<Boolean>) getByName("doWeatherCycle");
19+
20+
public static GameRule<?>[] values() {
21+
try {
22+
return (GameRule<?>[]) GAMERULE_VALUES.invokeExact();
23+
}
24+
catch (Throwable e) {
25+
throw new RuntimeException(e);
26+
}
27+
}
28+
29+
public static GameRule<?> getByName(String name) {
30+
try {
31+
return (GameRule<?>) GAMERULE_GET_BY_NAME.invokeExact(name);
32+
}
33+
catch (Throwable e) {
34+
throw new RuntimeException(e);
35+
}
36+
}
37+
38+
public static String getName(GameRule<?> gameRule) {
39+
try {
40+
return (String) GAMERULE_GET_NAME.invokeExact(gameRule);
41+
}
42+
catch (Throwable e) {
43+
throw new RuntimeException(e);
44+
}
45+
}
46+
47+
public static Class<?> getType(GameRule<?> gameRule) {
48+
try {
49+
return (Class<?>) GAMERULE_GET_TYPE.invokeExact(gameRule);
50+
}
51+
catch (Throwable e) {
52+
throw new RuntimeException(e);
53+
}
54+
}
55+
56+
// TODO 1.21.11: certain gamemodes (e.g. max_minecart_speed) behave badly on Spigot, need to test with Paper
57+
public static <T> T getValue(World world, GameRule<T> gameRule) {
58+
try {
59+
return world.getGameRuleValue(gameRule);
60+
}
61+
catch (IllegalArgumentException e) {
62+
if (e.getMessage().equals("Tried to access invalid game rule")) {
63+
return null;
64+
}
65+
throw e;
66+
}
67+
}
68+
}

plugin/src/main/java/com/denizenscript/denizen/utilities/world/PathFinder.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.denizenscript.denizen.objects.LocationTag;
44
import com.denizenscript.denizencore.utilities.debugging.Debug;
5+
import net.citizensnpcs.api.ai.NavigatorParameters;
56
import net.citizensnpcs.api.astar.AStarMachine;
67
import net.citizensnpcs.api.astar.pathfinder.*;
78
import org.bukkit.Location;
@@ -19,7 +20,7 @@ public class PathFinder {
1920

2021
public static List<LocationTag> getPath(Location start, Location dest) {
2122
VectorGoal goal = new VectorGoal(dest, 1);
22-
Path plan = (Path) ASTAR.runFully(goal, new VectorNode(goal, start, new ChunkBlockSource(start, 100), new MinecraftBlockExaminer()), 50000);
23+
Path plan = (Path) ASTAR.runFully(goal, new VectorNode(goal, start, new ChunkBlockSource(start, 100), new NavigatorParameters().examiner(new MinecraftBlockExaminer())), 50000);
2324
if (plan == null) {
2425
Debug.verboseLog("PathFinder: No path found from " + start + " to " + dest + " (return null)");
2526
return new ArrayList<>();

0 commit comments

Comments
 (0)