diff --git a/src/main/java/ch/njol/skript/Skript.java b/src/main/java/ch/njol/skript/Skript.java index 2b8d8c142d1..e96ff06907e 100644 --- a/src/main/java/ch/njol/skript/Skript.java +++ b/src/main/java/ch/njol/skript/Skript.java @@ -77,6 +77,7 @@ import org.skriptlang.skript.bukkit.registration.BukkitSyntaxInfos; import org.skriptlang.skript.bukkit.tags.TagModule; import org.skriptlang.skript.common.CommonModule; +import org.skriptlang.skript.bukkit.whitelist.WhitelistModule; import org.skriptlang.skript.lang.comparator.Comparator; import org.skriptlang.skript.lang.comparator.Comparators; import org.skriptlang.skript.lang.converter.Converter; @@ -571,7 +572,8 @@ public void onEnable() { new DamageSourceModule(), new ItemComponentModule(), new BrewingModule(), - new CommonModule() + new CommonModule(), + new WhitelistModule() ); } catch (final Exception e) { exception(e, "Could not load required .class files: " + e.getLocalizedMessage()); diff --git a/src/main/java/org/skriptlang/skript/bukkit/whitelist/WhitelistModule.java b/src/main/java/org/skriptlang/skript/bukkit/whitelist/WhitelistModule.java new file mode 100644 index 00000000000..0a43c72ba15 --- /dev/null +++ b/src/main/java/org/skriptlang/skript/bukkit/whitelist/WhitelistModule.java @@ -0,0 +1,20 @@ +package org.skriptlang.skript.bukkit.whitelist; + +import java.io.IOException; + +import ch.njol.skript.Skript; +import org.skriptlang.skript.addon.AddonModule; +import org.skriptlang.skript.addon.SkriptAddon; + +public class WhitelistModule implements AddonModule { + + @Override + public void load(SkriptAddon addon) { + try { + Skript.getAddonInstance().loadClasses("org.skriptlang.skript.bukkit.whitelist", "elements"); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + +} diff --git a/src/main/java/ch/njol/skript/conditions/CondIsWhitelisted.java b/src/main/java/org/skriptlang/skript/bukkit/whitelist/elements/CondIsWhitelisted.java similarity index 70% rename from src/main/java/ch/njol/skript/conditions/CondIsWhitelisted.java rename to src/main/java/org/skriptlang/skript/bukkit/whitelist/elements/CondIsWhitelisted.java index f7f3d1cc4eb..b79ad8b7ded 100644 --- a/src/main/java/ch/njol/skript/conditions/CondIsWhitelisted.java +++ b/src/main/java/org/skriptlang/skript/bukkit/whitelist/elements/CondIsWhitelisted.java @@ -1,29 +1,24 @@ -package ch.njol.skript.conditions; +package org.skriptlang.skript.bukkit.whitelist.elements; + +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.event.Event; +import org.jetbrains.annotations.Nullable; import ch.njol.skript.Skript; -import ch.njol.skript.doc.Description; -import ch.njol.skript.doc.Examples; -import ch.njol.skript.doc.Name; -import ch.njol.skript.doc.RequiredPlugins; -import ch.njol.skript.doc.Since; +import ch.njol.skript.doc.*; import ch.njol.skript.lang.Condition; import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.SkriptParser.ParseResult; +import ch.njol.skript.lang.SyntaxStringBuilder; import ch.njol.util.Kleenean; -import org.bukkit.Bukkit; -import org.bukkit.OfflinePlayer; -import org.bukkit.event.Event; -import org.jetbrains.annotations.Nullable; @Name("Is Whitelisted") @Description("Whether or not the server or a player is whitelisted, or the server is whitelist enforced.") -@Examples({ - "if the player is whitelisted:", - "if the server is whitelisted:", - "if the server whitelist is enforced:" -}) +@Example("if the player is whitelisted:") +@Example("if the server is whitelisted:") +@Example("if the server whitelist is enforced:") @Since("2.5.2, 2.9.0 (enforce, offline players)") -@RequiredPlugins("MC 1.17+ (enforce)") public class CondIsWhitelisted extends Condition { static { @@ -33,9 +28,7 @@ public class CondIsWhitelisted extends Condition { "[the] server white[ ]list (is|not:(isn't|is not)) enforced"); } - @Nullable private Expression players; - private boolean isServer; private boolean isEnforce; @@ -59,14 +52,23 @@ public boolean check(Event event) { @Override public String toString(@Nullable Event event, boolean debug) { - String negation = isNegated() ? "not" : ""; + SyntaxStringBuilder builder = new SyntaxStringBuilder(event, debug); if (isServer) { if (isEnforce) { - return "the server whitelist is " + negation + " enforced"; + builder.append("the server whitelist") + .append(isNegated() ? "is not" : "is") + .append("enforced"); + } else { + builder.append("the server") + .append(isNegated() ? "is not" : "is") + .append("whitelisted"); } - return "the server is " + negation + " whitelisted"; + } else { + builder.append(players) + .append(isNegated() ? "is not" : "is") + .append("whitelisted"); } - return players.toString(event, debug) + " is " + negation + " whitelisted"; + return builder.toString(); } } diff --git a/src/main/java/org/skriptlang/skript/bukkit/whitelist/elements/CondWillBeWhitelisted.java b/src/main/java/org/skriptlang/skript/bukkit/whitelist/elements/CondWillBeWhitelisted.java new file mode 100644 index 00000000000..0472ec343c6 --- /dev/null +++ b/src/main/java/org/skriptlang/skript/bukkit/whitelist/elements/CondWillBeWhitelisted.java @@ -0,0 +1,74 @@ +package org.skriptlang.skript.bukkit.whitelist.elements; + +import com.destroystokyo.paper.event.server.WhitelistToggleEvent; +import io.papermc.paper.event.server.WhitelistStateUpdateEvent; +import org.bukkit.event.Event; +import org.jetbrains.annotations.Nullable; + +import ch.njol.skript.Skript; +import ch.njol.skript.doc.*; +import ch.njol.skript.lang.Condition; +import ch.njol.skript.lang.Expression; +import ch.njol.skript.lang.SkriptParser.ParseResult; +import ch.njol.skript.lang.SyntaxStringBuilder; +import ch.njol.util.Kleenean; + +@Name("Will Be Whitelisted") +@Description("Checks whether the server or a player will be whitelisted in a whitelist event.") +@Keywords("server, player") +@Example(""" + on server whitelist: + send "Server whitelist has been set to %whether server will be whitelisted%" to all ops + """) +@Example(""" + on player whitelist: + send "Whitelist of player %event-player% has been set to %whether server will be whitelisted%" to all ops + """) +@Since("INSERT VERSION") +public class CondWillBeWhitelisted extends Condition { + + static { + Skript.registerCondition(CondWillBeWhitelisted.class, + "[the] (:player|server) will be whitelisted", + "[the] (:player|server) (will not|won't) be whitelisted" + ); + } + + private boolean isServer; + + @Override + public boolean init(Expression[] expressions, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { + isServer = !parseResult.hasTag("player"); + if (isServer) { + if (!getParser().isCurrentEvent(WhitelistToggleEvent.class)) { + Skript.error("The 'server will be whitelisted' condition can only be used in an 'server whitelist' event"); + return false; + } + } else { + if (!getParser().isCurrentEvent(WhitelistStateUpdateEvent.class)) { + Skript.error("The 'player will be whitelisted' condition can only be used in an 'player whitelist' event"); + return false; + } + } + setNegated(matchedPattern == 1); + return true; + } + + @Override + public boolean check(Event event) { + if (isServer) + return ((WhitelistToggleEvent) event).isEnabled() ^ isNegated(); + return (((WhitelistStateUpdateEvent) event).getStatus() == WhitelistStateUpdateEvent.WhitelistStatus.ADDED) ^ isNegated(); + } + + @Override + public String toString(@Nullable Event event, boolean debug) { + return new SyntaxStringBuilder(event, debug) + .append("the") + .append(isServer ? "server" : "player") + .append(isNegated() ? "will not" : "will") + .append("be whitelisted") + .toString(); + } + +} diff --git a/src/main/java/ch/njol/skript/effects/EffEnforceWhitelist.java b/src/main/java/org/skriptlang/skript/bukkit/whitelist/elements/EffEnforceWhitelist.java similarity index 86% rename from src/main/java/ch/njol/skript/effects/EffEnforceWhitelist.java rename to src/main/java/org/skriptlang/skript/bukkit/whitelist/elements/EffEnforceWhitelist.java index f1bbe878a74..c31912f657c 100644 --- a/src/main/java/ch/njol/skript/effects/EffEnforceWhitelist.java +++ b/src/main/java/org/skriptlang/skript/bukkit/whitelist/elements/EffEnforceWhitelist.java @@ -1,4 +1,4 @@ -package ch.njol.skript.effects; +package org.skriptlang.skript.bukkit.whitelist.elements; import org.bukkit.Bukkit; import org.bukkit.configuration.file.YamlConfiguration; @@ -9,11 +9,7 @@ import java.io.File; import ch.njol.skript.Skript; -import ch.njol.skript.doc.Name; -import ch.njol.skript.doc.Description; -import ch.njol.skript.doc.Examples; -import ch.njol.skript.doc.Since; -import ch.njol.skript.doc.RequiredPlugins; +import ch.njol.skript.doc.*; import ch.njol.skript.lang.Effect; import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.SkriptParser.ParseResult; @@ -25,12 +21,9 @@ "Enforces or un-enforce a server's whitelist.", "All non-whitelisted players will be kicked upon enforcing the whitelist." }) -@Examples({ - "enforce the whitelist", - "unenforce the whitelist" -}) +@Example("enforce the whitelist") +@Example("unenforce the whitelist") @Since("2.9.0") -@RequiredPlugins("MC 1.17+") public class EffEnforceWhitelist extends Effect { private static String NOT_WHITELISTED_MESSAGE = "You are not whitelisted on this server!"; diff --git a/src/main/java/org/skriptlang/skript/bukkit/whitelist/elements/EvtPlayerWhitelist.java b/src/main/java/org/skriptlang/skript/bukkit/whitelist/elements/EvtPlayerWhitelist.java new file mode 100644 index 00000000000..bb8f95acba7 --- /dev/null +++ b/src/main/java/org/skriptlang/skript/bukkit/whitelist/elements/EvtPlayerWhitelist.java @@ -0,0 +1,88 @@ +package org.skriptlang.skript.bukkit.whitelist.elements; + +import io.papermc.paper.event.server.WhitelistStateUpdateEvent; +import io.papermc.paper.event.server.WhitelistStateUpdateEvent.WhitelistStatus; +import org.bukkit.OfflinePlayer; +import org.bukkit.event.Event; +import org.jetbrains.annotations.Nullable; + +import ch.njol.skript.Skript; +import ch.njol.skript.lang.Literal; +import ch.njol.skript.lang.SkriptEvent; +import ch.njol.skript.lang.SkriptParser.ParseResult; +import ch.njol.skript.lang.SyntaxStringBuilder; +import ch.njol.skript.registrations.EventValues; + +public class EvtPlayerWhitelist extends SkriptEvent { + + private enum EventState { + + WHITELISTED("whitelisted"), + UNWHITELISTED("unwhitelisted"); + + final String toString; + + EventState(String toString) { + this.toString = toString; + } + + @Override + public String toString() { + return toString; + } + + } + + static { + Skript.registerEvent("Player Whitelist", EvtPlayerWhitelist.class, WhitelistStateUpdateEvent.class, + "player whitelist [state] (change[d]|update[d])", + "player (added to whitelist|whitelist[ed])", + "player (removed from whitelist|unwhitelist[ed])") + .description( + "Called whenever a player has been added to or removed from the server's whitelist.", + "Use will be whitelisted condition to check with its state.") + .examples( + "on player whitelisted:", + "on player unwhitelisted:", + "", + "on player whitelist state changed:", + "\tsend \"Whitelist of player %event-offlineplayer% has been set to %whether server will be whitelisted%\" to all ops") + .since("INSERT VERSION"); + + EventValues.registerEventValue(WhitelistStateUpdateEvent.class, OfflinePlayer.class, WhitelistStateUpdateEvent::getPlayer); + } + + private @Nullable EventState state = null; + + @Override + public boolean init(Literal[] args, int matchedPattern, ParseResult parseResult) { + if (matchedPattern == 1) + state = EventState.WHITELISTED; + else if (matchedPattern == 2) + state = EventState.UNWHITELISTED; + return true; + } + + @Override + public boolean check(Event event) { + if (state != null) + return (state == EventState.WHITELISTED) == (((WhitelistStateUpdateEvent) event).getStatus() == WhitelistStatus.ADDED); + return true; + } + + @Override + public String toString(@Nullable Event event, boolean debug) { + SyntaxStringBuilder builder = new SyntaxStringBuilder(event, debug) + .append("player"); + if (state != null) { + if (state == EventState.WHITELISTED) + builder.append("added to whitelist"); + else + builder.append("removed from whitelist"); + } else { + builder.append("whitelist state changed"); + } + return builder.toString(); + } + +} diff --git a/src/main/java/org/skriptlang/skript/bukkit/whitelist/elements/EvtServerWhitelist.java b/src/main/java/org/skriptlang/skript/bukkit/whitelist/elements/EvtServerWhitelist.java new file mode 100644 index 00000000000..4762ecb4522 --- /dev/null +++ b/src/main/java/org/skriptlang/skript/bukkit/whitelist/elements/EvtServerWhitelist.java @@ -0,0 +1,74 @@ +package org.skriptlang.skript.bukkit.whitelist.elements; + +import com.destroystokyo.paper.event.server.WhitelistToggleEvent; +import org.bukkit.event.Event; +import org.jetbrains.annotations.Nullable; + +import ch.njol.skript.Skript; +import ch.njol.skript.lang.Literal; +import ch.njol.skript.lang.SkriptEvent; +import ch.njol.skript.lang.SkriptParser.ParseResult; +import ch.njol.skript.lang.SyntaxStringBuilder; + +public class EvtServerWhitelist extends SkriptEvent { + + private enum EventState { + + ON("on"), + OFF("off"); + + final String toString; + + EventState(String toString) { + this.toString = toString; + } + + @Override + public String toString() { + return toString; + } + + } + + static { + Skript.registerEvent("Whitelist Toggled", EvtServerWhitelist.class, WhitelistToggleEvent.class, "whitelist toggle[d] [:on|:off]") + .description( + "Called whenever the server's whitelist has been toggled on or off.", + "Use will be whitelisted condition to check with its state.") + .examples( + "on whitelist toggled on:", + "on whitelist toggled off:", + "", + "on whitelist toggled:", + "\tsend \"Server whitelist has been set to %whether server will be whitelisted%\" to all ops") + .since("INSERT VERSION"); + } + + private @Nullable EventState state = null; + + @Override + public boolean init(Literal[] args, int matchedPattern, ParseResult parseResult) { + if (parseResult.hasTag("on")) + state = EventState.ON; + else if (parseResult.hasTag("off")) + state = EventState.OFF; + return true; + } + + @Override + public boolean check(Event event) { + if (state != null) + return (state == EventState.ON) == ((WhitelistToggleEvent) event).isEnabled(); + return true; + } + + @Override + public String toString(@Nullable Event event, boolean debug) { + SyntaxStringBuilder builder = new SyntaxStringBuilder(event, debug) + .append("server whitelist toggled"); + if (state != null) + builder.append(state); + return builder.toString(); + } + +} diff --git a/src/main/java/ch/njol/skript/expressions/ExprWhitelist.java b/src/main/java/org/skriptlang/skript/bukkit/whitelist/elements/ExprWhitelist.java similarity index 76% rename from src/main/java/ch/njol/skript/expressions/ExprWhitelist.java rename to src/main/java/org/skriptlang/skript/bukkit/whitelist/elements/ExprWhitelist.java index 355070c268f..3874465b68f 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprWhitelist.java +++ b/src/main/java/org/skriptlang/skript/bukkit/whitelist/elements/ExprWhitelist.java @@ -1,6 +1,5 @@ -package ch.njol.skript.expressions; +package org.skriptlang.skript.bukkit.whitelist.elements; -import ch.njol.skript.effects.EffEnforceWhitelist; import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.event.Event; @@ -9,7 +8,7 @@ import ch.njol.skript.Skript; import ch.njol.skript.classes.Changer.ChangeMode; import ch.njol.skript.doc.Description; -import ch.njol.skript.doc.Examples; +import ch.njol.skript.doc.Example; import ch.njol.skript.doc.Name; import ch.njol.skript.doc.Since; import ch.njol.skript.lang.Expression; @@ -25,11 +24,9 @@ "Players may be added and removed from the whitelist.", "The whitelist can be enabled or disabled by setting the whitelist to true or false respectively." }) -@Examples({ - "set the whitelist to false", - "add all players to whitelist", - "reset the whitelist" -}) +@Example("set the whitelist to false") +@Example("add all players to whitelist") +@Example("reset the whitelist") @Since("2.5.2, 2.9.0 (delete)") public class ExprWhitelist extends SimpleExpression { @@ -49,43 +46,35 @@ protected OfflinePlayer[] get(Event event) { @Override public Class[] acceptChange(ChangeMode mode) { - switch (mode) { - case ADD: - case REMOVE: - return CollectionUtils.array(OfflinePlayer.class); - case DELETE: - case RESET: - case SET: - return CollectionUtils.array(Boolean.class); - } - return null; + return switch (mode) { + case ADD, REMOVE -> CollectionUtils.array(OfflinePlayer.class); + case DELETE, RESET, SET -> CollectionUtils.array(Boolean.class); + default -> null; + }; } @Override public void change(Event event, Object @Nullable [] delta, ChangeMode mode) { switch (mode) { - case SET: - boolean toggle = (Boolean) delta[0]; + case SET -> { + boolean toggle = (boolean) delta[0]; Bukkit.setWhitelist(toggle); if (toggle) EffEnforceWhitelist.reloadWhitelist(); - break; - case ADD: + } + case ADD -> { for (Object player : delta) ((OfflinePlayer) player).setWhitelisted(true); - break; - case REMOVE: + } + case REMOVE -> { for (Object player : delta) ((OfflinePlayer) player).setWhitelisted(false); EffEnforceWhitelist.reloadWhitelist(); - break; - case DELETE: - case RESET: + } + case DELETE, RESET -> { for (OfflinePlayer player : Bukkit.getWhitelistedPlayers()) player.setWhitelisted(false); - break; - default: - assert false; + } } } @@ -101,7 +90,7 @@ public Class getReturnType() { @Override public String toString(@Nullable Event event, boolean debug) { - return "whitelist"; + return "the whitelist"; } } diff --git a/src/test/java/org/skriptlang/skript/test/tests/syntaxes/events/EvtWhitelistTest.java b/src/test/java/org/skriptlang/skript/test/tests/syntaxes/events/EvtWhitelistTest.java new file mode 100644 index 00000000000..7efe319f6c6 --- /dev/null +++ b/src/test/java/org/skriptlang/skript/test/tests/syntaxes/events/EvtWhitelistTest.java @@ -0,0 +1,33 @@ +package org.skriptlang.skript.test.tests.syntaxes.events; + +import com.destroystokyo.paper.event.server.WhitelistToggleEvent; +import io.papermc.paper.event.server.WhitelistStateUpdateEvent; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.junit.Before; +import org.junit.Test; + +import ch.njol.skript.test.runner.SkriptJUnitTest; + +public class EvtWhitelistTest extends SkriptJUnitTest { + + static { + setShutdownDelay(1); + } + + private OfflinePlayer player; + + @Before + public void setup() { + player = Bukkit.getOfflinePlayer("Njol"); + } + + @Test + public void test() { + Bukkit.getPluginManager().callEvent(new WhitelistToggleEvent(true)); + Bukkit.getPluginManager().callEvent(new WhitelistToggleEvent(false)); + Bukkit.getPluginManager().callEvent(new WhitelistStateUpdateEvent(player.getPlayerProfile(), WhitelistStateUpdateEvent.WhitelistStatus.ADDED)); + Bukkit.getPluginManager().callEvent(new WhitelistStateUpdateEvent(player.getPlayerProfile(), WhitelistStateUpdateEvent.WhitelistStatus.REMOVED)); + } + +} diff --git a/src/test/skript/junit/EvtWhitelistTest.sk b/src/test/skript/junit/EvtWhitelistTest.sk new file mode 100644 index 00000000000..b3249445543 --- /dev/null +++ b/src/test/skript/junit/EvtWhitelistTest.sk @@ -0,0 +1,48 @@ +options: + test: "org.skriptlang.skript.test.tests.syntaxes.events.EvtWhitelistTest" + +test "EvtWhitelistTest" when running JUnit: + add "server whitelist event - general" to {_events::*} + add "server whitelist event - on" to {_events::*} + add "server whitelist event - off" to {_events::*} + add "player whitelist event - general" to {_events::*} + add "player whitelist event - added" to {_events::*} + add "player whitelist event - removed" to {_events::*} + + add "will be whitelisted - server" to {_events::*} + add "will not be whitelisted - server" to {_events::*} + add "will be whitelisted - player" to {_events::*} + add "will not be whitelisted - player" to {_events::*} + ensure junit test {@test} completes {_events::*} + +on whitelist toggled: + junit test is {@test} + complete objective "server whitelist event - general" for {@test} + +on whitelist toggled on: + junit test is {@test} + complete objective "server whitelist event - on" for {@test} + the server will be whitelisted + complete objective "will be whitelisted - server" for {@test} + +on whitelist toggled off: + junit test is {@test} + complete objective "server whitelist event - off" for {@test} + the server will not be whitelisted + complete objective "will not be whitelisted - server" for {@test} + +on player whitelist state changed: + junit test is {@test} + complete objective "player whitelist event - general" for {@test} + +on player whitelisted: + junit test is {@test} + complete objective "player whitelist event - added" for {@test} + the player will be whitelisted + complete objective "will be whitelisted - player" for {@test} + +on player unwhitelisted: + junit test is {@test} + complete objective "player whitelist event - removed" for {@test} + the player will not be whitelisted + complete objective "will not be whitelisted - player" for {@test}