mirror of
https://github.com/IntellectualSites/PlotSquared.git
synced 2024-11-25 12:25:46 +01:00
Merge branch 'v6' of github.com:IntellectualSites/PlotSquared into v6
This commit is contained in:
commit
78a775530a
@ -27,6 +27,7 @@ package com.plotsquared.core.command;
|
|||||||
|
|
||||||
import com.plotsquared.core.PlotSquared;
|
import com.plotsquared.core.PlotSquared;
|
||||||
import com.plotsquared.core.configuration.Settings;
|
import com.plotsquared.core.configuration.Settings;
|
||||||
|
import com.plotsquared.core.configuration.caption.CaptionUtility;
|
||||||
import com.plotsquared.core.configuration.caption.StaticCaption;
|
import com.plotsquared.core.configuration.caption.StaticCaption;
|
||||||
import com.plotsquared.core.configuration.caption.Templates;
|
import com.plotsquared.core.configuration.caption.Templates;
|
||||||
import com.plotsquared.core.configuration.caption.TranslatableCaption;
|
import com.plotsquared.core.configuration.caption.TranslatableCaption;
|
||||||
@ -335,10 +336,11 @@ public final class FlagCommand extends Command {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
boolean force = event.getEventResult() == Result.FORCE;
|
boolean force = event.getEventResult() == Result.FORCE;
|
||||||
final String value = StringMan.join(Arrays.copyOfRange(args, 1, args.length), " ");
|
String value = StringMan.join(Arrays.copyOfRange(args, 1, args.length), " ");
|
||||||
if (!force && !checkPermValue(player, plotFlag, args[0], value)) {
|
if (!force && !checkPermValue(player, plotFlag, args[0], value)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
value = CaptionUtility.stripClickEvents(plotFlag, value);
|
||||||
final PlotFlag<?, ?> parsed;
|
final PlotFlag<?, ?> parsed;
|
||||||
try {
|
try {
|
||||||
parsed = plotFlag.parse(value);
|
parsed = plotFlag.parse(value);
|
||||||
|
@ -26,12 +26,14 @@
|
|||||||
package com.plotsquared.core.configuration;
|
package com.plotsquared.core.configuration;
|
||||||
|
|
||||||
import com.plotsquared.core.configuration.file.YamlConfiguration;
|
import com.plotsquared.core.configuration.file.YamlConfiguration;
|
||||||
|
import net.kyori.adventure.text.event.ClickEvent;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class Settings extends Config {
|
public class Settings extends Config {
|
||||||
|
|
||||||
@ -498,10 +500,12 @@ public class Settings extends Config {
|
|||||||
"notify-enter, notify-leave, greeting or farewell flag."})
|
"notify-enter, notify-leave, greeting or farewell flag."})
|
||||||
public static boolean NOTIFICATION_AS_ACTIONBAR = false;
|
public static boolean NOTIFICATION_AS_ACTIONBAR = false;
|
||||||
|
|
||||||
@Comment({"Whether to strip any possible <click_event> components from user-defined messages, e.g. plot greeting",
|
@Comment({"The click event actions that should be removed from user input in e.g. plot flags like 'greeting'.",
|
||||||
"This can allow players to use commands to give themselves ranks as commands ran in this fashion cannot be prevent by " +
|
"Actions like 'RUN_COMMAND' may be used maliciously as players could trick staff into clicking on messages",
|
||||||
"permissions etc."})
|
"triggering destructive commands."})
|
||||||
public static boolean REMOVE_USER_DEFINED_CLICK_EVENTS = true;
|
public static List<String> CLICK_EVENT_ACTIONS_TO_REMOVE = Arrays.stream(ClickEvent.Action.values())
|
||||||
|
.map(Enum::name)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,12 +25,42 @@
|
|||||||
*/
|
*/
|
||||||
package com.plotsquared.core.configuration.caption;
|
package com.plotsquared.core.configuration.caption;
|
||||||
|
|
||||||
|
import com.plotsquared.core.configuration.Settings;
|
||||||
import com.plotsquared.core.player.PlotPlayer;
|
import com.plotsquared.core.player.PlotPlayer;
|
||||||
|
import com.plotsquared.core.plot.flag.PlotFlag;
|
||||||
|
import com.plotsquared.core.plot.flag.implementations.DescriptionFlag;
|
||||||
|
import com.plotsquared.core.plot.flag.implementations.FarewellFlag;
|
||||||
|
import com.plotsquared.core.plot.flag.implementations.GreetingFlag;
|
||||||
|
import com.plotsquared.core.plot.flag.types.StringFlag;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.event.ClickEvent;
|
||||||
|
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static com.plotsquared.core.configuration.caption.ComponentTransform.nested;
|
||||||
|
import static com.plotsquared.core.configuration.caption.ComponentTransform.stripClicks;
|
||||||
|
|
||||||
public class CaptionUtility {
|
public class CaptionUtility {
|
||||||
|
|
||||||
|
// flags which values are parsed by minimessage
|
||||||
|
private static final Set<Class<? extends StringFlag<?>>> MINI_MESSAGE_FLAGS = Set.of(
|
||||||
|
GreetingFlag.class,
|
||||||
|
FarewellFlag.class,
|
||||||
|
DescriptionFlag.class
|
||||||
|
);
|
||||||
|
|
||||||
|
private static final ComponentTransform CLICK_STRIP_TRANSFORM = nested(
|
||||||
|
stripClicks(
|
||||||
|
Settings.Chat.CLICK_EVENT_ACTIONS_TO_REMOVE.stream()
|
||||||
|
.map(ClickEvent.Action::valueOf)
|
||||||
|
.toArray(ClickEvent.Action[]::new)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Format a chat message but keep the formatting keys
|
* Format a chat message but keep the formatting keys
|
||||||
*
|
*
|
||||||
@ -66,4 +96,42 @@ public class CaptionUtility {
|
|||||||
return chatContext.getMessage();
|
return chatContext.getMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Strips configured click events from a MiniMessage string.
|
||||||
|
*
|
||||||
|
* @param miniMessageString the message from which the specified click events should be removed from.
|
||||||
|
* @return the string without the click events that are configured to be removed.
|
||||||
|
*
|
||||||
|
* @see Settings.Chat#CLICK_EVENT_ACTIONS_TO_REMOVE
|
||||||
|
*/
|
||||||
|
public static String stripClickEvents(final @NonNull String miniMessageString) {
|
||||||
|
// parse, transform and serialize again
|
||||||
|
Component component = MiniMessage.get().parse(miniMessageString);
|
||||||
|
component = CLICK_STRIP_TRANSFORM.transform(component);
|
||||||
|
return MiniMessage.get().serialize(component);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Strips configured MiniMessage click events from a plot flag value.
|
||||||
|
* This is used before letting the string be parsed by the plot flag.
|
||||||
|
* This method works the same way as {@link #stripClickEvents(String)} but will only
|
||||||
|
* strip click events from messages that target flags that are meant to contain MiniMessage strings.
|
||||||
|
*
|
||||||
|
* @param flag the flag the message is targeted for.
|
||||||
|
* @param miniMessageString the message from which the specified click events should be removed from.
|
||||||
|
* @return the string without the click events that are configured to be removed.
|
||||||
|
*
|
||||||
|
* @see Settings.Chat#CLICK_EVENT_ACTIONS_TO_REMOVE
|
||||||
|
* @see #stripClickEvents(String)
|
||||||
|
*/
|
||||||
|
public static String stripClickEvents(
|
||||||
|
final @NonNull PlotFlag<?, ?> flag,
|
||||||
|
final @NonNull String miniMessageString
|
||||||
|
) {
|
||||||
|
if (MINI_MESSAGE_FLAGS.contains(flag.getClass())) {
|
||||||
|
return stripClickEvents(miniMessageString);
|
||||||
|
}
|
||||||
|
return miniMessageString;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* _____ _ _ _____ _
|
||||||
|
* | __ \| | | | / ____| | |
|
||||||
|
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
|
||||||
|
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
|
||||||
|
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
|
||||||
|
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
|
||||||
|
* | |
|
||||||
|
* |_|
|
||||||
|
* PlotSquared plot management system for Minecraft
|
||||||
|
* Copyright (C) 2021 IntellectualSites
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package com.plotsquared.core.configuration.caption;
|
||||||
|
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.event.ClickEvent;
|
||||||
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.EnumSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
final class ClickStripTransform implements ComponentTransform {
|
||||||
|
private final Set<ClickEvent.@NotNull Action> actionsToStrip;
|
||||||
|
|
||||||
|
public ClickStripTransform(final Set<ClickEvent.@NotNull Action> actionsToStrip) {
|
||||||
|
this.actionsToStrip = EnumSet.copyOf(actionsToStrip);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NonNull Component transform(@NonNull final Component original) {
|
||||||
|
var clickEvent = original.clickEvent();
|
||||||
|
if (clickEvent == null || !actionsToStrip.contains(clickEvent.action())) return original;
|
||||||
|
return original.clickEvent(null); // remove it
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* _____ _ _ _____ _
|
||||||
|
* | __ \| | | | / ____| | |
|
||||||
|
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
|
||||||
|
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
|
||||||
|
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
|
||||||
|
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
|
||||||
|
* | |
|
||||||
|
* |_|
|
||||||
|
* PlotSquared plot management system for Minecraft
|
||||||
|
* Copyright (C) 2021 IntellectualSites
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package com.plotsquared.core.configuration.caption;
|
||||||
|
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.event.ClickEvent;
|
||||||
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public interface ComponentTransform {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a transform that applies the given transform on all child components and the
|
||||||
|
* component itself. The children are transformed before the component itself is transformed.
|
||||||
|
*
|
||||||
|
* @param transform the transform to apply.
|
||||||
|
* @return a new transform which is applied on all child components and the component itself.
|
||||||
|
*/
|
||||||
|
static ComponentTransform nested(ComponentTransform transform) {
|
||||||
|
return new NestedComponentTransform(transform);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a transform that removes click events of the given actions from a component.
|
||||||
|
* Note: To remove click events from children too, the returned transform must be wrapped
|
||||||
|
* using {@link #nested(ComponentTransform)}.
|
||||||
|
*
|
||||||
|
* @param actionsToRemove the actions used to filter which click events should be removed.
|
||||||
|
* @return a new transform that removes click events from a component.
|
||||||
|
*/
|
||||||
|
static ComponentTransform stripClicks(ClickEvent.Action... actionsToRemove) {
|
||||||
|
return new ClickStripTransform(Set.of(actionsToRemove));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies this transform on the given component and returns the result.
|
||||||
|
*
|
||||||
|
* @param original the component to transform.
|
||||||
|
* @return the transformed component.
|
||||||
|
*/
|
||||||
|
@NonNull Component transform(@NonNull Component original);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* _____ _ _ _____ _
|
||||||
|
* | __ \| | | | / ____| | |
|
||||||
|
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
|
||||||
|
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
|
||||||
|
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
|
||||||
|
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
|
||||||
|
* | |
|
||||||
|
* |_|
|
||||||
|
* PlotSquared plot management system for Minecraft
|
||||||
|
* Copyright (C) 2021 IntellectualSites
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package com.plotsquared.core.configuration.caption;
|
||||||
|
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A transform that applies a nested transform on all child components and the component itself.
|
||||||
|
*/
|
||||||
|
final class NestedComponentTransform implements ComponentTransform {
|
||||||
|
private final ComponentTransform transform;
|
||||||
|
|
||||||
|
public NestedComponentTransform(final ComponentTransform transform) {
|
||||||
|
this.transform = transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NonNull Component transform(final @NonNull Component original) {
|
||||||
|
return this.transform.transform(original.children(transformChildren(original.children())));
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Component> transformChildren(List<Component> children) {
|
||||||
|
return children.stream().map(this::transform).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
}
|
@ -30,6 +30,7 @@ import com.plotsquared.core.PlotSquared;
|
|||||||
import com.plotsquared.core.configuration.ConfigurationSection;
|
import com.plotsquared.core.configuration.ConfigurationSection;
|
||||||
import com.plotsquared.core.configuration.Settings;
|
import com.plotsquared.core.configuration.Settings;
|
||||||
import com.plotsquared.core.configuration.Storage;
|
import com.plotsquared.core.configuration.Storage;
|
||||||
|
import com.plotsquared.core.configuration.caption.CaptionUtility;
|
||||||
import com.plotsquared.core.configuration.file.YamlConfiguration;
|
import com.plotsquared.core.configuration.file.YamlConfiguration;
|
||||||
import com.plotsquared.core.inject.annotations.WorldConfig;
|
import com.plotsquared.core.inject.annotations.WorldConfig;
|
||||||
import com.plotsquared.core.listener.PlotListener;
|
import com.plotsquared.core.listener.PlotListener;
|
||||||
@ -2033,7 +2034,7 @@ public class SQLManager implements AbstractDB {
|
|||||||
while (resultSet.next()) {
|
while (resultSet.next()) {
|
||||||
id = resultSet.getInt("plot_id");
|
id = resultSet.getInt("plot_id");
|
||||||
final String flag = resultSet.getString("flag");
|
final String flag = resultSet.getString("flag");
|
||||||
final String value = resultSet.getString("value");
|
String value = resultSet.getString("value");
|
||||||
final Plot plot = plots.get(id);
|
final Plot plot = plots.get(id);
|
||||||
if (plot != null) {
|
if (plot != null) {
|
||||||
final PlotFlag<?, ?> plotFlag =
|
final PlotFlag<?, ?> plotFlag =
|
||||||
@ -2041,6 +2042,7 @@ public class SQLManager implements AbstractDB {
|
|||||||
if (plotFlag == null) {
|
if (plotFlag == null) {
|
||||||
plot.getFlagContainer().addUnknownFlag(flag, value);
|
plot.getFlagContainer().addUnknownFlag(flag, value);
|
||||||
} else {
|
} else {
|
||||||
|
value = CaptionUtility.stripClickEvents(plotFlag, value);
|
||||||
try {
|
try {
|
||||||
plot.getFlagContainer().addFlag(plotFlag.parse(value));
|
plot.getFlagContainer().addFlag(plotFlag.parse(value));
|
||||||
} catch (final FlagParseException e) {
|
} catch (final FlagParseException e) {
|
||||||
|
@ -171,9 +171,6 @@ public class PlotListener {
|
|||||||
|
|
||||||
String greeting = plot.getFlag(GreetingFlag.class);
|
String greeting = plot.getFlag(GreetingFlag.class);
|
||||||
if (!greeting.isEmpty()) {
|
if (!greeting.isEmpty()) {
|
||||||
if (Settings.Chat.REMOVE_USER_DEFINED_CLICK_EVENTS) {
|
|
||||||
greeting = greeting.replaceAll(".([c-lC-L]{5}):([a-uA-U_]{11}):[^\\/]*[^>]*>>", "").replace("</click>", "");
|
|
||||||
}
|
|
||||||
if (!Settings.Chat.NOTIFICATION_AS_ACTIONBAR) {
|
if (!Settings.Chat.NOTIFICATION_AS_ACTIONBAR) {
|
||||||
plot.format(StaticCaption.of(greeting), player, false).thenAcceptAsync(player::sendMessage);
|
plot.format(StaticCaption.of(greeting), player, false).thenAcceptAsync(player::sendMessage);
|
||||||
} else {
|
} else {
|
||||||
@ -395,9 +392,6 @@ public class PlotListener {
|
|||||||
|
|
||||||
String farewell = plot.getFlag(FarewellFlag.class);
|
String farewell = plot.getFlag(FarewellFlag.class);
|
||||||
if (!farewell.isEmpty()) {
|
if (!farewell.isEmpty()) {
|
||||||
if (Settings.Chat.REMOVE_USER_DEFINED_CLICK_EVENTS) {
|
|
||||||
farewell = farewell.replaceAll(".([c-lC-L]{5}):([a-uA-U_]{11}):[^\\/]*[^>]*>", "").replace("</click>", "");
|
|
||||||
}
|
|
||||||
if (!Settings.Chat.NOTIFICATION_AS_ACTIONBAR) {
|
if (!Settings.Chat.NOTIFICATION_AS_ACTIONBAR) {
|
||||||
plot.format(StaticCaption.of(farewell), player, false).thenAcceptAsync(player::sendMessage);
|
plot.format(StaticCaption.of(farewell), player, false).thenAcceptAsync(player::sendMessage);
|
||||||
} else {
|
} else {
|
||||||
|
@ -2790,9 +2790,6 @@ public class Plot {
|
|||||||
String description = this.getFlag(DescriptionFlag.class);
|
String description = this.getFlag(DescriptionFlag.class);
|
||||||
if (description.isEmpty()) {
|
if (description.isEmpty()) {
|
||||||
description = TranslatableCaption.of("info.plot_no_description").getComponent(player);
|
description = TranslatableCaption.of("info.plot_no_description").getComponent(player);
|
||||||
} else if (Settings.Chat.REMOVE_USER_DEFINED_CLICK_EVENTS) {
|
|
||||||
description = description.replaceAll(".([c-lC-L]{5}):([a-uA-U_]{11}):[^\\/]*[^>]*>", "").replace("</click>",
|
|
||||||
"");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Component flags;
|
Component flags;
|
||||||
|
@ -27,6 +27,7 @@ package com.plotsquared.core.plot.flag;
|
|||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.plotsquared.core.configuration.caption.CaptionUtility;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
@ -316,8 +317,9 @@ public class FlagContainer {
|
|||||||
) {
|
) {
|
||||||
if (plotFlagUpdateType != PlotFlagUpdateType.FLAG_REMOVED && this.unknownFlags
|
if (plotFlagUpdateType != PlotFlagUpdateType.FLAG_REMOVED && this.unknownFlags
|
||||||
.containsKey(flag.getName())) {
|
.containsKey(flag.getName())) {
|
||||||
final String value = this.unknownFlags.remove(flag.getName());
|
String value = this.unknownFlags.remove(flag.getName());
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
|
value = CaptionUtility.stripClickEvents(flag, value);
|
||||||
try {
|
try {
|
||||||
this.addFlag(flag.parse(value));
|
this.addFlag(flag.parse(value));
|
||||||
} catch (final Exception ignored) {
|
} catch (final Exception ignored) {
|
||||||
|
@ -26,10 +26,10 @@
|
|||||||
package com.plotsquared.core.plot.flag.implementations;
|
package com.plotsquared.core.plot.flag.implementations;
|
||||||
|
|
||||||
import com.plotsquared.core.configuration.caption.TranslatableCaption;
|
import com.plotsquared.core.configuration.caption.TranslatableCaption;
|
||||||
import com.plotsquared.core.plot.flag.PlotFlag;
|
import com.plotsquared.core.plot.flag.types.StringFlag;
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
|
||||||
public class DescriptionFlag extends PlotFlag<String, DescriptionFlag> {
|
public class DescriptionFlag extends StringFlag<DescriptionFlag> {
|
||||||
|
|
||||||
public static final DescriptionFlag DESCRIPTION_FLAG_EMPTY = new DescriptionFlag("");
|
public static final DescriptionFlag DESCRIPTION_FLAG_EMPTY = new DescriptionFlag("");
|
||||||
|
|
||||||
|
@ -28,10 +28,10 @@ package com.plotsquared.core.plot.flag.implementations;
|
|||||||
import com.plotsquared.core.configuration.caption.TranslatableCaption;
|
import com.plotsquared.core.configuration.caption.TranslatableCaption;
|
||||||
import com.plotsquared.core.plot.Plot;
|
import com.plotsquared.core.plot.Plot;
|
||||||
import com.plotsquared.core.plot.flag.InternalFlag;
|
import com.plotsquared.core.plot.flag.InternalFlag;
|
||||||
import com.plotsquared.core.plot.flag.PlotFlag;
|
import com.plotsquared.core.plot.flag.types.StringFlag;
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
|
||||||
public class DoneFlag extends PlotFlag<String, DoneFlag> implements InternalFlag {
|
public class DoneFlag extends StringFlag<DoneFlag> implements InternalFlag {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a new flag instance.
|
* Construct a new flag instance.
|
||||||
|
@ -26,10 +26,10 @@
|
|||||||
package com.plotsquared.core.plot.flag.implementations;
|
package com.plotsquared.core.plot.flag.implementations;
|
||||||
|
|
||||||
import com.plotsquared.core.configuration.caption.TranslatableCaption;
|
import com.plotsquared.core.configuration.caption.TranslatableCaption;
|
||||||
import com.plotsquared.core.plot.flag.PlotFlag;
|
import com.plotsquared.core.plot.flag.types.StringFlag;
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
|
||||||
public class FarewellFlag extends PlotFlag<String, FarewellFlag> {
|
public class FarewellFlag extends StringFlag<FarewellFlag> {
|
||||||
|
|
||||||
public static final FarewellFlag FAREWELL_FLAG_EMPTY = new FarewellFlag("");
|
public static final FarewellFlag FAREWELL_FLAG_EMPTY = new FarewellFlag("");
|
||||||
|
|
||||||
|
@ -26,10 +26,10 @@
|
|||||||
package com.plotsquared.core.plot.flag.implementations;
|
package com.plotsquared.core.plot.flag.implementations;
|
||||||
|
|
||||||
import com.plotsquared.core.configuration.caption.TranslatableCaption;
|
import com.plotsquared.core.configuration.caption.TranslatableCaption;
|
||||||
import com.plotsquared.core.plot.flag.PlotFlag;
|
import com.plotsquared.core.plot.flag.types.StringFlag;
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
|
||||||
public class GreetingFlag extends PlotFlag<String, GreetingFlag> {
|
public class GreetingFlag extends StringFlag<GreetingFlag> {
|
||||||
|
|
||||||
public static final GreetingFlag GREETING_FLAG_EMPTY = new GreetingFlag("");
|
public static final GreetingFlag GREETING_FLAG_EMPTY = new GreetingFlag("");
|
||||||
|
|
||||||
|
@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* _____ _ _ _____ _
|
||||||
|
* | __ \| | | | / ____| | |
|
||||||
|
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
|
||||||
|
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
|
||||||
|
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
|
||||||
|
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
|
||||||
|
* | |
|
||||||
|
* |_|
|
||||||
|
* PlotSquared plot management system for Minecraft
|
||||||
|
* Copyright (C) 2021 IntellectualSites
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package com.plotsquared.core.plot.flag.types;
|
||||||
|
|
||||||
|
import com.plotsquared.core.configuration.caption.Caption;
|
||||||
|
import com.plotsquared.core.plot.flag.PlotFlag;
|
||||||
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
|
||||||
|
public abstract class StringFlag<F extends StringFlag<F>> extends PlotFlag<String, F> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a new flag instance.
|
||||||
|
*
|
||||||
|
* @param value Flag value
|
||||||
|
* @param flagCategory The flag category
|
||||||
|
* @param flagDescription A caption describing the flag functionality
|
||||||
|
*/
|
||||||
|
protected StringFlag(
|
||||||
|
final @NonNull String value,
|
||||||
|
final @NonNull Caption flagCategory,
|
||||||
|
final @NonNull Caption flagDescription
|
||||||
|
) {
|
||||||
|
super(value, flagCategory, flagDescription);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,96 @@
|
|||||||
|
/*
|
||||||
|
* _____ _ _ _____ _
|
||||||
|
* | __ \| | | | / ____| | |
|
||||||
|
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
|
||||||
|
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
|
||||||
|
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
|
||||||
|
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
|
||||||
|
* | |
|
||||||
|
* |_|
|
||||||
|
* PlotSquared plot management system for Minecraft
|
||||||
|
* Copyright (C) 2021 IntellectualSites
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package com.plotsquared.core.configuration.caption;
|
||||||
|
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.event.ClickEvent;
|
||||||
|
import net.kyori.adventure.text.event.HoverEvent;
|
||||||
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
import net.kyori.adventure.text.format.TextDecoration;
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.EnumSet;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
|
|
||||||
|
class ClickStripTransformTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("Remove click event of specific action correctly")
|
||||||
|
void removeClickEvent() {
|
||||||
|
var commonAction = ClickEvent.Action.OPEN_FILE;
|
||||||
|
var transform = new ClickStripTransform(EnumSet.of(commonAction));
|
||||||
|
var component = Component.text("Hello")
|
||||||
|
.clickEvent(ClickEvent.clickEvent(
|
||||||
|
commonAction,
|
||||||
|
"World"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
var transformedComponent = transform.transform(component);
|
||||||
|
assertNull(transformedComponent.clickEvent());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("Don't remove click events of other action types")
|
||||||
|
void ignoreClickEvent() {
|
||||||
|
var actionToRemove = ClickEvent.Action.SUGGEST_COMMAND;
|
||||||
|
var transform = new ClickStripTransform(EnumSet.of(actionToRemove));
|
||||||
|
var originalClickEvent = ClickEvent.clickEvent(
|
||||||
|
ClickEvent.Action.CHANGE_PAGE,
|
||||||
|
"World"
|
||||||
|
);
|
||||||
|
var component = Component.text("Hello")
|
||||||
|
.clickEvent(originalClickEvent);
|
||||||
|
var transformedComponent = transform.transform(component);
|
||||||
|
assertEquals(originalClickEvent, transformedComponent.clickEvent());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("Remove nested click events correctly")
|
||||||
|
void removeNestedClickEvent() {
|
||||||
|
// nested transform is required to apply on children
|
||||||
|
var transform = new NestedComponentTransform(new ClickStripTransform(EnumSet.allOf(ClickEvent.Action.class)));
|
||||||
|
var inner = Component
|
||||||
|
// some arbitrary values that should remain
|
||||||
|
.text("World")
|
||||||
|
.color(NamedTextColor.AQUA)
|
||||||
|
.hoverEvent(HoverEvent.showText(Component.text("ABC")))
|
||||||
|
.decorate(TextDecoration.OBFUSCATED)
|
||||||
|
.insertion("DEF");
|
||||||
|
var component = Component.text("Hello ")
|
||||||
|
.append(
|
||||||
|
inner.clickEvent(ClickEvent.clickEvent(ClickEvent.Action.OPEN_URL, "https://example.org"))
|
||||||
|
);
|
||||||
|
var transformedComponent = transform.transform(component);
|
||||||
|
assertFalse(transformedComponent.children().isEmpty()); // child still exists
|
||||||
|
assertEquals(inner, transformedComponent.children().get(0)); // only the click event has changed
|
||||||
|
assertNull(transformedComponent.children().get(0).clickEvent());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -81,6 +81,7 @@ allprojects {
|
|||||||
dependencies {
|
dependencies {
|
||||||
// Tests
|
// Tests
|
||||||
testImplementation("junit:junit:4.13.2")
|
testImplementation("junit:junit:4.13.2")
|
||||||
|
testImplementation("org.junit.jupiter:junit-jupiter:5.7.2")
|
||||||
}
|
}
|
||||||
|
|
||||||
plugins.withId("java") {
|
plugins.withId("java") {
|
||||||
@ -215,9 +216,13 @@ allprojects {
|
|||||||
named("build") {
|
named("build") {
|
||||||
dependsOn(named("shadowJar"))
|
dependsOn(named("shadowJar"))
|
||||||
}
|
}
|
||||||
|
test {
|
||||||
|
useJUnitPlatform()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
tasks {
|
tasks {
|
||||||
val aggregatedJavadocs = create<Javadoc>("aggregatedJavadocs") {
|
val aggregatedJavadocs = create<Javadoc>("aggregatedJavadocs") {
|
||||||
title = "${project.name} ${project.version} API"
|
title = "${project.name} ${project.version} API"
|
||||||
|
Loading…
Reference in New Issue
Block a user