Skip to content

Commit a2360f5

Browse files
Replace region literal parsing in favor of runtime computation
Safer in case world/region gets unloaded/deleted
1 parent ce78dd3 commit a2360f5

File tree

3 files changed

+81
-53
lines changed

3 files changed

+81
-53
lines changed

src/main/java/org/skriptlang/skriptworldguard/SkriptWorldGuard.java

Lines changed: 7 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,9 @@
1616
import ch.njol.yggdrasil.Fields;
1717
import com.sk89q.worldguard.WorldGuard;
1818
import com.sk89q.worldguard.session.MoveType;
19-
import org.bukkit.Bukkit;
2019
import org.bukkit.World;
2120
import org.bukkit.plugin.Plugin;
2221
import org.bukkit.plugin.java.JavaPlugin;
23-
import org.jetbrains.annotations.NotNull;
24-
import org.jetbrains.annotations.Nullable;
2522
import org.skriptlang.skript.addon.AddonModule;
2623
import org.skriptlang.skript.addon.SkriptAddon;
2724
import org.skriptlang.skript.registration.SyntaxRegistry;
@@ -32,8 +29,6 @@
3229

3330
import java.io.StreamCorruptedException;
3431
import java.lang.reflect.InvocationTargetException;
35-
import java.util.regex.Matcher;
36-
import java.util.regex.Pattern;
3732

3833
public class SkriptWorldGuard extends JavaPlugin implements AddonModule {
3934

@@ -96,55 +91,37 @@ public void init(SkriptAddon addon) {
9691
.requiredPlugins("WorldGuard 7")
9792
.since("1.0")
9893
.parser(new Parser<>() {
99-
// TODO maybe we should do something else here... perhaps make use of SkriptParser methods?
100-
final Pattern regionPattern = Pattern.compile(
101-
"(?:the )?(?:worldguard )?region (?:with (?:the )?(?:name|id) |named )?\"(.+)\" (?:in|of) (?:(?:the )?world )?\"(.+)\""
102-
);
103-
104-
@Override
105-
public @Nullable WorldGuardRegion parse(@NotNull String input, @NotNull ParseContext context) {
106-
if (context == ParseContext.EVENT || context == ParseContext.COMMAND) {
107-
Matcher matcher = regionPattern.matcher(input);
108-
if (matcher.matches()) {
109-
String id = matcher.group(1);
110-
World world = Bukkit.getWorld(matcher.group(2));
111-
return world == null ? null : RegionUtils.getRegion(world, id);
112-
}
113-
}
114-
return null;
115-
}
116-
11794
@Override
118-
public boolean canParse(@NotNull ParseContext context) {
119-
return context == ParseContext.EVENT || context == ParseContext.COMMAND;
95+
public boolean canParse(ParseContext context) {
96+
return false;
12097
}
12198

12299
@Override
123-
public @NotNull String toString(WorldGuardRegion region, int flags) {
100+
public String toString(WorldGuardRegion region, int flags) {
124101
return region.toString();
125102
}
126103

127104
@Override
128-
public @NotNull String toVariableNameString(WorldGuardRegion region) {
105+
public String toVariableNameString(WorldGuardRegion region) {
129106
return "worldguardregion:" + region;
130107
}
131108
})
132109
.serializer(new Serializer<>() {
133110
@Override
134-
public @NotNull Fields serialize(WorldGuardRegion region) {
111+
public Fields serialize(WorldGuardRegion region) {
135112
Fields fields = new Fields();
136113
fields.putObject("world", region.world());
137114
fields.putObject("id", region.region().getId());
138115
return fields;
139116
}
140117

141118
@Override
142-
public void deserialize(WorldGuardRegion region, @NotNull Fields fields) {
119+
public void deserialize(WorldGuardRegion region, Fields fields) {
143120
assert false;
144121
}
145122

146123
@Override
147-
protected WorldGuardRegion deserialize(@NotNull Fields fields) throws StreamCorruptedException {
124+
protected WorldGuardRegion deserialize(Fields fields) throws StreamCorruptedException {
148125
World world = fields.getObject("world", World.class);
149126
String id = fields.getObject("id", String.class);
150127
if (world == null || id == null) {
Lines changed: 72 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,37 @@
11
package org.skriptlang.skriptworldguard.elements.events;
22

3+
import ch.njol.skript.config.Node;
34
import ch.njol.skript.lang.Literal;
45
import ch.njol.skript.lang.SkriptEvent;
56
import ch.njol.skript.lang.SkriptParser.ParseResult;
67
import ch.njol.skript.lang.SyntaxStringBuilder;
8+
import ch.njol.skript.lang.util.SimpleExpression;
79
import ch.njol.skript.registrations.EventValues;
810
import com.sk89q.worldguard.session.MoveType;
11+
import org.bukkit.Bukkit;
12+
import org.bukkit.World;
913
import org.bukkit.entity.Player;
1014
import org.bukkit.event.Event;
1115
import org.jetbrains.annotations.Nullable;
1216
import org.skriptlang.skript.bukkit.registration.BukkitRegistryKeys;
1317
import org.skriptlang.skript.bukkit.registration.BukkitSyntaxInfos;
18+
import org.skriptlang.skript.log.runtime.SyntaxRuntimeErrorProducer;
1419
import org.skriptlang.skript.registration.SyntaxRegistry;
1520
import org.skriptlang.skriptworldguard.worldguard.RegionEnterLeaveEvent;
21+
import org.skriptlang.skriptworldguard.worldguard.RegionUtils;
1622
import org.skriptlang.skriptworldguard.worldguard.WorldGuardRegion;
1723

18-
public class EvtRegionEnterLeave extends SkriptEvent {
24+
public class EvtRegionEnterLeave extends SkriptEvent implements SyntaxRuntimeErrorProducer {
1925

2026
public static void register(SyntaxRegistry registry) {
27+
String regionPattern = "[the] [worldguard] region[s] [with [the] (name[s]|id[s])|named] %*strings% (in|of) [[the] world] %*string%";
2128
registry.register(BukkitRegistryKeys.EVENT, BukkitSyntaxInfos.Event.builder(EvtRegionEnterLeave.class, "Region Enter/Leave")
2229
.supplier(EvtRegionEnterLeave::new)
2330
.addEvent(RegionEnterLeaveEvent.class)
24-
.addPatterns("enter[ing] of ([a] region|%-worldguardregions%)",
25-
"(region|%-worldguardregions%) enter[ing]",
26-
"(leav(e|ing)|exit[ing]) of ([a] region|%-worldguardregions%)",
27-
"(region|%-worldguardregions%) (leav(e|ing)|exit[ing])")
31+
.addPatterns("region enter[ing]",
32+
"enter[ing] of " + regionPattern,
33+
"region (exit[ing]|leav(e|ing))",
34+
"exit[ing] of " + regionPattern)
2835
.addDescription("Called when a player enters or leaves a region (or the specified region(s))")
2936
.addExample("""
3037
on region enter:
@@ -38,39 +45,83 @@ public static void register(SyntaxRegistry registry) {
3845
EventValues.registerEventValue(RegionEnterLeaveEvent.class, MoveType.class, RegionEnterLeaveEvent::getMoveType);
3946
}
4047

41-
private @Nullable Literal<WorldGuardRegion> regions;
42-
private boolean enter;
48+
private Node node;
49+
50+
private @Nullable Literal<String> regionIds;
51+
private @Nullable Literal<String> world;
52+
private boolean isEntering;
4353

4454
@Override
4555
public boolean init(Literal<?>[] args, int matchedPattern, ParseResult parseResult) {
46-
//noinspection unchecked
47-
regions = (Literal<WorldGuardRegion>) args[0];
48-
enter = matchedPattern <= 1;
56+
node = getParser().getNode();
57+
if (args.length != 0) {
58+
//noinspection unchecked
59+
regionIds = (Literal<String>) args[0];
60+
//noinspection unchecked
61+
world = (Literal<String>) args[1];
62+
}
63+
isEntering = matchedPattern <= 1;
4964
return true;
5065
}
5166

5267
@Override
5368
public boolean check(Event event) {
54-
return event instanceof RegionEnterLeaveEvent enterLeaveEvent
55-
&& enterLeaveEvent.isEntering() == enter
56-
&& (regions == null || regions.check(enterLeaveEvent, region -> region.equals(enterLeaveEvent.getRegion())));
69+
if (!(event instanceof RegionEnterLeaveEvent enterLeaveEvent) || enterLeaveEvent.isEntering() != isEntering) {
70+
return false;
71+
}
72+
if (regionIds == null) {
73+
return true;
74+
}
75+
assert world != null;
76+
77+
// validate world
78+
World world = Bukkit.getWorld(this.world.getSingle());
79+
if (world == null) {
80+
error("The world '" + this.world.getSingle() + "' does not exist");
81+
return false;
82+
}
83+
84+
// map regions
85+
String[] regionIds = this.regionIds.getAll();
86+
WorldGuardRegion[] regions = new WorldGuardRegion[regionIds.length];
87+
for (int i = 0; i < regionIds.length; i++) {
88+
regions[i] = RegionUtils.getRegion(world, regionIds[i]);
89+
if (regions[i] == null) {
90+
error("The region '" + regionIds[i] + "' does not exist in the world '" + world.getName() + "'");
91+
return false;
92+
}
93+
}
94+
95+
return SimpleExpression.check(regions, region -> region.equals(enterLeaveEvent.getRegion()), false, false);
5796
}
5897

5998
@Override
6099
public String toString(@Nullable Event event, boolean debug) {
61100
SyntaxStringBuilder builder = new SyntaxStringBuilder(event, debug);
62-
if (enter) {
63-
builder.append("entering");
64-
} else {
65-
builder.append("leaving");
101+
if (regionIds == null) {
102+
builder.append("region");
66103
}
67-
builder.append("of");
68-
if (regions == null) {
69-
builder.append("a region");
104+
if (isEntering) {
105+
builder.append("enter");
70106
} else {
71-
builder.append(regions);
107+
builder.append("exit");
108+
}
109+
if (regionIds != null) {
110+
assert world != null;
111+
builder.append("of");
112+
if (regionIds.isSingle()) {
113+
builder.append("region");
114+
} else {
115+
builder.append("regions");
116+
}
117+
builder.append("named", regionIds, "in the world", world);
72118
}
73119
return builder.toString();
74120
}
75121

122+
@Override
123+
public Node getNode() {
124+
return node;
125+
}
126+
76127
}

src/main/java/org/skriptlang/skriptworldguard/elements/expressions/ExprRegionNamed.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ public class ExprRegionNamed extends SimpleExpression<WorldGuardRegion> {
3434
public static void register(SyntaxRegistry registry) {
3535
registry.register(SyntaxRegistry.EXPRESSION, SyntaxInfo.Expression.builder(ExprRegionNamed.class, WorldGuardRegion.class)
3636
.supplier(ExprRegionNamed::new)
37-
.addPatterns("[the] [worldguard] region[s] [named] %strings% [in %world%]",
38-
"[the] [worldguard] region[s] with [the] (name[s]|id[s]) %strings% [in %world%]")
37+
.addPatterns("[the] [worldguard] region[s] [named] %strings% [(in|of) %world%]",
38+
"[the] [worldguard] region[s] with [the] (name[s]|id[s]) %strings% [(in|of) %world%]")
3939
.build());
4040
}
4141

0 commit comments

Comments
 (0)