mirror of
https://github.com/EngineHub/WorldGuard.git
synced 2024-11-15 07:05:32 +01:00
Add /rg flags
command.
Provides an overview of all flags set on a region, including inherited values, and allows the user to set or unset flags with a single click.
This commit is contained in:
parent
fc4c67ff29
commit
7199b8e70f
@ -0,0 +1,502 @@
|
||||
/*
|
||||
* WorldGuard, a suite of tools for Minecraft
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* Copyright (C) WorldGuard team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser 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 Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.commands.region;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterators;
|
||||
import com.sk89q.worldedit.registry.Keyed;
|
||||
import com.sk89q.worldedit.registry.Registry;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldedit.util.formatting.component.PaginationBox;
|
||||
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
|
||||
import com.sk89q.worldedit.util.formatting.text.event.ClickEvent;
|
||||
import com.sk89q.worldedit.util.formatting.text.event.HoverEvent;
|
||||
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
|
||||
import com.sk89q.worldedit.util.formatting.text.format.TextDecoration;
|
||||
import com.sk89q.worldedit.util.formatting.text.serializer.legacy.LegacyComponentSerializer;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldguard.WorldGuard;
|
||||
import com.sk89q.worldguard.internal.permission.RegionPermissionModel;
|
||||
import com.sk89q.worldguard.protection.flags.BooleanFlag;
|
||||
import com.sk89q.worldguard.protection.flags.DoubleFlag;
|
||||
import com.sk89q.worldguard.protection.flags.Flag;
|
||||
import com.sk89q.worldguard.protection.flags.Flags;
|
||||
import com.sk89q.worldguard.protection.flags.IntegerFlag;
|
||||
import com.sk89q.worldguard.protection.flags.LocationFlag;
|
||||
import com.sk89q.worldguard.protection.flags.RegistryFlag;
|
||||
import com.sk89q.worldguard.protection.flags.SetFlag;
|
||||
import com.sk89q.worldguard.protection.flags.StateFlag;
|
||||
import com.sk89q.worldguard.protection.flags.StringFlag;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
class FlagHelperBox extends PaginationBox {
|
||||
|
||||
private static final List<Flag<?>> FLAGS = WorldGuard.getInstance().getFlagRegistry().getAll().stream()
|
||||
.sorted((f1, f2) -> {
|
||||
if (f1 == f2) return 0;
|
||||
int idx1 = Flags.INBUILT_FLAGS.indexOf(f1.getName());
|
||||
int idx2 = Flags.INBUILT_FLAGS.indexOf(f2.getName());
|
||||
if (idx1 < 0 && idx2 >= 0) return 1;
|
||||
if (idx2 < 0 && idx1 >= 0) return -1;
|
||||
if (idx1 < 0) return f1.getName().compareTo(f2.getName());
|
||||
return idx1 < idx2 ? -1 : 1;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
private static final int SIZE = FLAGS.size() == Flags.INBUILT_FLAGS.size() ? FLAGS.size() : FLAGS.size() + 1;
|
||||
private static final int PAD_PX_SIZE = 180;
|
||||
|
||||
private final World world;
|
||||
private final ProtectedRegion region;
|
||||
private final RegionPermissionModel perms;
|
||||
|
||||
FlagHelperBox(World world, ProtectedRegion region, RegionPermissionModel perms) {
|
||||
super("Flags for " + region.getId(), "/rg flags -w " + world.getName() + " " + region.getId() + " %page%");
|
||||
this.world = world;
|
||||
this.region = region;
|
||||
this.perms = perms;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getComponent(int number) {
|
||||
if (number == Flags.INBUILT_FLAGS.size()) {
|
||||
return centerAndBorder(TextComponent.of("Third-Party Flags", TextColor.AQUA));
|
||||
} else if (number > Flags.INBUILT_FLAGS.size()) {
|
||||
number -= 1;
|
||||
}
|
||||
Flag<?> flag = FLAGS.get(number);
|
||||
return createLine(flag, number >= Flags.INBUILT_FLAGS.size()); }
|
||||
|
||||
@Override
|
||||
public int getComponentsSize() {
|
||||
return SIZE;
|
||||
}
|
||||
|
||||
private Component createLine(Flag<?> flag, boolean thirdParty) {
|
||||
final TextComponent.Builder builder = TextComponent.builder("");
|
||||
|
||||
appendFlagName(builder, flag, thirdParty ? TextColor.LIGHT_PURPLE : TextColor.GOLD);
|
||||
appendFlagValue(builder, flag);
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private void appendFlagName(TextComponent.Builder builder, Flag<?> flag, TextColor color) {
|
||||
final String name = flag.getName();
|
||||
int length = FlagFontInfo.getPxLength(name);
|
||||
builder.append(TextComponent.of(name, color));
|
||||
if (flag.usesMembershipAsDefault()) {
|
||||
builder.append(Component.empty().append(TextComponent.of("*", TextColor.AQUA))
|
||||
.hoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT,
|
||||
TextComponent.of("This is a special flag which defaults to allow for members, and deny for non-members"))));
|
||||
length += FlagFontInfo.getPxLength('*');
|
||||
}
|
||||
if (flag == Flags.PASSTHROUGH) {
|
||||
builder.append(Component.empty().append(TextComponent.of("*", TextColor.AQUA))
|
||||
.hoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT,
|
||||
TextComponent.of("This is a special flag which overrides build checks. (Not movement related!)"))));
|
||||
length += FlagFontInfo.getPxLength('*');
|
||||
}
|
||||
int leftover = PAD_PX_SIZE - length;
|
||||
builder.append(Component.space());
|
||||
leftover -= 4;
|
||||
if (leftover > 0) {
|
||||
builder.append(TextComponent.of(Strings.repeat(".", leftover / 2), TextColor.DARK_GRAY));
|
||||
}
|
||||
}
|
||||
|
||||
private void appendFlagValue(TextComponent.Builder builder, Flag<?> flag) {
|
||||
if (flag instanceof StateFlag) {
|
||||
appendStateFlagValue(builder, (StateFlag) flag);
|
||||
} else if (flag instanceof BooleanFlag) {
|
||||
appendBoolFlagValue(builder, ((BooleanFlag) flag));
|
||||
} else if (flag instanceof SetFlag) {
|
||||
appendSetFlagValue(builder, ((SetFlag<?>) flag));
|
||||
} else if (flag instanceof RegistryFlag) {
|
||||
appendRegistryFlagValue(builder, ((RegistryFlag<?>) flag));
|
||||
} else if (flag instanceof StringFlag) {
|
||||
appendStringFlagValue(builder, ((StringFlag) flag));
|
||||
} else if (flag instanceof LocationFlag) {
|
||||
appendLocationFlagValue(builder, ((LocationFlag) flag));
|
||||
} else if (flag instanceof IntegerFlag) {
|
||||
appendNumericFlagValue(builder, (IntegerFlag) flag);
|
||||
} else if (flag instanceof DoubleFlag) {
|
||||
appendNumericFlagValue(builder, (DoubleFlag) flag);
|
||||
} else {
|
||||
String display = String.valueOf(region.getFlag(flag));
|
||||
if (display.length() > 23) {
|
||||
display = display.substring(0, 20) + "...";
|
||||
}
|
||||
appendValueText(builder, flag, display, null);
|
||||
}
|
||||
}
|
||||
|
||||
private <T> T getInheritedValue(ProtectedRegion region, Flag<T> flag) {
|
||||
ProtectedRegion parent = region.getParent();
|
||||
T val;
|
||||
while (parent != null) {
|
||||
val = parent.getFlag(flag);
|
||||
if (val != null) {
|
||||
return val;
|
||||
}
|
||||
parent = parent.getParent();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private <V> void appendValueChoices(TextComponent.Builder builder, Flag<V> flag, Iterator<V> choices, @Nullable String suggestChoice) {
|
||||
V defVal = flag.getDefault();
|
||||
V currVal = region.getFlag(flag);
|
||||
boolean inherited = false;
|
||||
if (currVal == null) {
|
||||
currVal = getInheritedValue(region, flag);
|
||||
if (currVal != null) {
|
||||
inherited = true;
|
||||
}
|
||||
}
|
||||
while (choices.hasNext()) {
|
||||
V choice = choices.next();
|
||||
boolean isExplicitSet = currVal == choice && !inherited;
|
||||
|
||||
boolean maySet = perms.maySetFlag(region, flag, isExplicitSet ? null : String.valueOf(choice));
|
||||
|
||||
TextColor col = isExplicitSet ? TextColor.WHITE : inherited && currVal == choice ? TextColor.GRAY : TextColor.DARK_GRAY;
|
||||
Set<TextDecoration> styles = choice == defVal ? ImmutableSet.of(TextDecoration.UNDERLINED) : Collections.emptySet();
|
||||
|
||||
Component choiceComponent = Component.empty().append(TextComponent.of(capitalize(String.valueOf(choice)), col, styles));
|
||||
|
||||
List<Component> hoverTexts = new ArrayList<>();
|
||||
if (maySet) {
|
||||
if (isExplicitSet) {
|
||||
hoverTexts.add(TextComponent.of("Click to unset", TextColor.GOLD));
|
||||
} else {
|
||||
hoverTexts.add(TextComponent.of("Click to set", TextColor.GOLD));
|
||||
}
|
||||
}
|
||||
Component valType = getToolTipHint(defVal, choice, inherited);
|
||||
if (valType != null) {
|
||||
hoverTexts.add(valType);
|
||||
}
|
||||
|
||||
if (!hoverTexts.isEmpty()) {
|
||||
TextComponent.Builder hoverBuilder = TextComponent.builder("");
|
||||
for (Iterator<Component> hovIt = hoverTexts.iterator(); hovIt.hasNext(); ) {
|
||||
hoverBuilder.append(hovIt.next());
|
||||
if (hovIt.hasNext()) {
|
||||
hoverBuilder.append(Component.newline());
|
||||
}
|
||||
}
|
||||
choiceComponent = choiceComponent.hoverEvent(
|
||||
new HoverEvent(HoverEvent.Action.SHOW_TEXT, hoverBuilder.build()));
|
||||
}
|
||||
|
||||
if (maySet) {
|
||||
builder.append(choiceComponent.clickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND,
|
||||
makeCommand(flag, isExplicitSet ? "" : choice))));
|
||||
} else {
|
||||
builder.append(choiceComponent);
|
||||
}
|
||||
builder.append(Component.space());
|
||||
}
|
||||
if (suggestChoice != null && perms.maySetFlag(region, flag)) {
|
||||
builder.append(TextComponent.of(suggestChoice, TextColor.DARK_GRAY)
|
||||
.hoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT,
|
||||
TextComponent.of("Click to set custom value", TextColor.GOLD)))
|
||||
.clickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, makeCommand(flag, ""))));
|
||||
}
|
||||
}
|
||||
|
||||
private <V> void appendValueText(TextComponent.Builder builder, Flag<V> flag, String display, @Nullable Component hover) {
|
||||
V defVal = flag.getDefault();
|
||||
V currVal = region.getFlag(flag);
|
||||
boolean inherited = false;
|
||||
if (currVal == null) {
|
||||
currVal = getInheritedValue(region, flag);
|
||||
if (currVal != null) {
|
||||
inherited = true;
|
||||
}
|
||||
}
|
||||
|
||||
boolean isExplicitSet = currVal != null && !inherited;
|
||||
|
||||
boolean maySet = perms.maySetFlag(region, flag);
|
||||
|
||||
TextColor col = isExplicitSet ? TextColor.WHITE : inherited ? TextColor.GRAY : TextColor.DARK_GRAY;
|
||||
Set<TextDecoration> styles = currVal == defVal ? ImmutableSet.of(TextDecoration.UNDERLINED) : Collections.emptySet();
|
||||
|
||||
Component displayComponent = Component.empty().append(TextComponent.of(display, col, styles));
|
||||
|
||||
List<Component> hoverTexts = new ArrayList<>();
|
||||
if (maySet) {
|
||||
if (isExplicitSet) {
|
||||
hoverTexts.add(TextComponent.of("Click to change", TextColor.GOLD));
|
||||
} else {
|
||||
hoverTexts.add(TextComponent.of("Click to set", TextColor.GOLD));
|
||||
}
|
||||
}
|
||||
Component valType = getToolTipHint(defVal, currVal, inherited);
|
||||
if (valType != null) {
|
||||
hoverTexts.add(valType);
|
||||
}
|
||||
|
||||
if (!hoverTexts.isEmpty()) {
|
||||
TextComponent.Builder hoverBuilder = TextComponent.builder("");
|
||||
for (Iterator<Component> hovIt = hoverTexts.iterator(); hovIt.hasNext(); ) {
|
||||
hoverBuilder.append(hovIt.next());
|
||||
if (hovIt.hasNext()) {
|
||||
hoverBuilder.append(Component.newline());
|
||||
}
|
||||
}
|
||||
if (hover != null) {
|
||||
hoverBuilder.append(Component.newline());
|
||||
hoverBuilder.append(hover);
|
||||
}
|
||||
displayComponent = displayComponent.hoverEvent(
|
||||
new HoverEvent(HoverEvent.Action.SHOW_TEXT, hoverBuilder.build()));
|
||||
}
|
||||
|
||||
if (maySet) {
|
||||
builder.append(displayComponent.clickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND,
|
||||
makeCommand(flag, ""))));
|
||||
} else {
|
||||
builder.append(displayComponent);
|
||||
}
|
||||
builder.append(Component.space());
|
||||
}
|
||||
|
||||
private String makeCommand(Flag<?> flag, Object choice) {
|
||||
return "/rg flag -w " + world.getName() + " -h " + getCurrentPage()
|
||||
+ " " + region.getId() + " " + flag.getName() + " " + choice;
|
||||
}
|
||||
|
||||
private String capitalize(String value) {
|
||||
if (value.isEmpty()) return value;
|
||||
value = value.toLowerCase();
|
||||
return value.length() > 1
|
||||
? Character.toUpperCase(value.charAt(0)) + value.substring(1)
|
||||
: String.valueOf(Character.toUpperCase(value.charAt(0)));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private <V> Component getToolTipHint(V defVal, V currVal, boolean inherited) {
|
||||
Component valType;
|
||||
if (inherited) {
|
||||
if (currVal == defVal) {
|
||||
valType = TextComponent.of("Inherited & ")
|
||||
.append(TextComponent.of("default")
|
||||
.decoration(TextDecoration.UNDERLINED, true))
|
||||
.append(TextComponent.of(" value"));
|
||||
} else {
|
||||
valType = TextComponent.of("Inherited value");
|
||||
}
|
||||
} else {
|
||||
if (currVal == defVal) {
|
||||
valType = Component.empty()
|
||||
.append(TextComponent.of("Default")
|
||||
.decoration(TextDecoration.UNDERLINED, true))
|
||||
.append(TextComponent.of(" value"));
|
||||
} else {
|
||||
valType = null;
|
||||
}
|
||||
}
|
||||
return valType;
|
||||
}
|
||||
|
||||
private void appendStateFlagValue(TextComponent.Builder builder, StateFlag flag) {
|
||||
final Iterator<StateFlag.State> choices = Iterators.forArray(StateFlag.State.values());
|
||||
appendValueChoices(builder, flag, choices, null);
|
||||
}
|
||||
|
||||
private void appendBoolFlagValue(TextComponent.Builder builder, BooleanFlag flag) {
|
||||
final Iterator<Boolean> choices = Iterators.forArray(Boolean.TRUE, Boolean.FALSE);
|
||||
appendValueChoices(builder, flag, choices, null);
|
||||
}
|
||||
|
||||
private <V> void appendSetFlagValue(TextComponent.Builder builder, SetFlag<V> flag) {
|
||||
Flag<V> subType = flag.getType();
|
||||
Class<?> clazz = subType.getClass();
|
||||
String subName;
|
||||
subName = clazz.isAssignableFrom(RegistryFlag.class)
|
||||
? ((RegistryFlag<?>) subType).getRegistry().getName()
|
||||
: subType.getClass().getSimpleName().replace("Flag", "");
|
||||
Set<V> currVal = region.getFlag(flag);
|
||||
if (currVal == null) {
|
||||
currVal = getInheritedValue(region, flag);
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
List<V> values = currVal == null ? Collections.emptyList() : (List<V>) flag.marshal(currVal);
|
||||
String display = (currVal == null ? "" : currVal.size() + "x ") + subName;
|
||||
final String stringValue = currVal == null ? ""
|
||||
: values.stream().map(String::valueOf).collect(Collectors.joining(","));
|
||||
TextComponent hoverComp = TextComponent.of("");
|
||||
if (currVal != null) {
|
||||
hoverComp = hoverComp.append(TextComponent.of("Current values:"))
|
||||
.append(Component.newline()).append(TextComponent.of(stringValue));
|
||||
}
|
||||
appendValueText(builder, flag, display, hoverComp);
|
||||
}
|
||||
|
||||
private void appendRegistryFlagValue(TextComponent.Builder builder, RegistryFlag<?> flag) {
|
||||
final Registry<?> registry = flag.getRegistry();
|
||||
String regName = registry.getName();
|
||||
Keyed currVal = region.getFlag(flag);
|
||||
if (currVal == null) {
|
||||
currVal = getInheritedValue(region, flag);
|
||||
}
|
||||
String display = currVal == null ? regName : currVal.getId();
|
||||
appendValueText(builder, flag, display, null);
|
||||
}
|
||||
|
||||
private void appendLocationFlagValue(TextComponent.Builder builder, LocationFlag flag) {
|
||||
Location currVal = region.getFlag(flag);
|
||||
if (currVal == null) {
|
||||
currVal = getInheritedValue(region, flag);
|
||||
}
|
||||
if (currVal == null) {
|
||||
final Location defVal = flag.getDefault();
|
||||
if (defVal == null) {
|
||||
appendValueText(builder, flag, "unset location", null);
|
||||
} else {
|
||||
appendValueText(builder, flag, defVal.toString(), TextComponent.of("Default value:")
|
||||
.append(Component.newline()).append(TextComponent.of(defVal.toString())));
|
||||
}
|
||||
} else {
|
||||
appendValueText(builder, flag, currVal.toString(), TextComponent.of("Current value:")
|
||||
.append(Component.newline()).append(TextComponent.of(currVal.toString())));
|
||||
}
|
||||
}
|
||||
|
||||
private <V extends Number> void appendNumericFlagValue(TextComponent.Builder builder, Flag<V> flag) {
|
||||
Number currVal = region.getFlag(flag);
|
||||
if (currVal == null) {
|
||||
currVal = getInheritedValue(region, flag);
|
||||
}
|
||||
Number defVal = flag.getDefault();
|
||||
Number[] suggested = getSuggestedNumbers(flag);
|
||||
SortedSet<Number> choices = new TreeSet<>(Comparator.comparing(Number::doubleValue));
|
||||
if (currVal != null) {
|
||||
choices.add(currVal);
|
||||
}
|
||||
if (defVal != null) {
|
||||
choices.add(defVal);
|
||||
}
|
||||
if (suggested.length > 0) {
|
||||
choices.addAll(Arrays.asList(suggested));
|
||||
}
|
||||
//noinspection unchecked
|
||||
appendValueChoices(builder, flag, (Iterator<V>) choices.iterator(), choices.isEmpty() ? "unset number" : "[custom]");
|
||||
}
|
||||
|
||||
private Number[] getSuggestedNumbers(Flag<? extends Number> flag) {
|
||||
if (flag == Flags.HEAL_AMOUNT || flag == Flags.FEED_AMOUNT) {
|
||||
return new Number[]{0, 5, 10, 20};
|
||||
} else if (flag == Flags.MIN_FOOD || flag == Flags.MIN_HEAL) {
|
||||
return new Number[]{0, 10};
|
||||
} else if (flag == Flags.MAX_FOOD || flag == Flags.MAX_HEAL) {
|
||||
return new Number[]{10, 20};
|
||||
} else if (flag == Flags.HEAL_DELAY || flag == Flags.FEED_DELAY) {
|
||||
return new Number[]{0, 1, 5};
|
||||
}
|
||||
return new Number[0];
|
||||
}
|
||||
|
||||
private void appendStringFlagValue(TextComponent.Builder builder, StringFlag flag) {
|
||||
String currVal = region.getFlag(flag);
|
||||
if (currVal == null) {
|
||||
currVal = getInheritedValue(region, flag);
|
||||
}
|
||||
if (currVal == null) {
|
||||
final String defVal = flag.getDefault();
|
||||
if (defVal == null) {
|
||||
appendValueText(builder, flag, "unset string", null);
|
||||
} else {
|
||||
final TextComponent defComp = LegacyComponentSerializer.INSTANCE.deserialize(defVal);
|
||||
String display = reduceToText(defComp);
|
||||
if (display.length() > 23) {
|
||||
display = display.substring(0, 20) + "...";
|
||||
}
|
||||
appendValueText(builder, flag, display, TextComponent.of("Default value:")
|
||||
.append(Component.newline()).append(defComp));
|
||||
}
|
||||
} else {
|
||||
TextComponent currComp = LegacyComponentSerializer.INSTANCE.deserialize(currVal);
|
||||
String display = reduceToText(currComp);
|
||||
if (display.length() > 23) {
|
||||
display = display.substring(0, 20) + "...";
|
||||
}
|
||||
appendValueText(builder, flag, display, TextComponent.of("Current value:")
|
||||
.append(Component.newline()).append(currComp));
|
||||
}
|
||||
}
|
||||
|
||||
private static String reduceToText(Component component) {
|
||||
StringBuilder text = new StringBuilder();
|
||||
appendTextTo(text, component);
|
||||
return text.toString();
|
||||
}
|
||||
|
||||
private static void appendTextTo(StringBuilder builder, Component component) {
|
||||
if (component instanceof TextComponent) {
|
||||
builder.append(((TextComponent) component).content());
|
||||
} else if (component instanceof TranslatableComponent) {
|
||||
builder.append(((TranslatableComponent) component).key());
|
||||
}
|
||||
for (Component child : component.children()) {
|
||||
appendTextTo(builder, child);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class FlagFontInfo {
|
||||
static int getPxLength(char c) {
|
||||
switch (c) {
|
||||
case 'i':
|
||||
case ':':
|
||||
return 1;
|
||||
case 'l':
|
||||
return 2;
|
||||
case '*':
|
||||
case 't':
|
||||
return 3;
|
||||
case 'f':
|
||||
case 'k':
|
||||
return 4;
|
||||
default:
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
|
||||
static int getPxLength(String string) {
|
||||
return string.chars().reduce(0, (p, i) -> p + getPxLength((char) i) + 1);
|
||||
}
|
||||
}
|
||||
}
|
@ -21,6 +21,7 @@
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.util.concurrent.Futures;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.sk89q.minecraft.util.commands.Command;
|
||||
@ -35,6 +36,7 @@
|
||||
import com.sk89q.worldedit.extension.platform.Capability;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldedit.util.formatting.component.ErrorFormat;
|
||||
import com.sk89q.worldedit.util.formatting.component.InvalidComponentException;
|
||||
import com.sk89q.worldedit.util.formatting.component.LabelFormat;
|
||||
import com.sk89q.worldedit.util.formatting.component.SubtleFormat;
|
||||
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||
@ -319,7 +321,7 @@ public void select(CommandContext args, Actor sender) throws CommandException {
|
||||
|
||||
// If no arguments were given, get the region that the player is inside
|
||||
if (args.argsLength() == 0) {
|
||||
existing = checkRegionStandingIn(manager, player);
|
||||
existing = checkRegionStandingIn(manager, player, "/rg select %id%");
|
||||
} else {
|
||||
existing = checkExistingRegion(manager, args.getString(0), false);
|
||||
}
|
||||
@ -360,7 +362,8 @@ public void info(CommandContext args, Actor sender) throws CommandException {
|
||||
throw new CommandException("Please specify the region with /region info -w world_name region_name.");
|
||||
}
|
||||
|
||||
existing = checkRegionStandingIn(manager, (LocalPlayer) sender, true);
|
||||
existing = checkRegionStandingIn(manager, (LocalPlayer) sender, true,
|
||||
"/rg info -w " + world.getName() + " %id%" + (args.hasFlag('u') ? " -u" : "") + (args.hasFlag('s') ? " -s" : ""));
|
||||
} else { // Get region from the ID
|
||||
existing = checkExistingRegion(manager, args.getString(0), true);
|
||||
}
|
||||
@ -463,7 +466,7 @@ public void list(CommandContext args, Actor sender) throws CommandException {
|
||||
*/
|
||||
@Command(aliases = {"flag", "f"},
|
||||
usage = "<id> <flag> [-w world] [-g group] [value]",
|
||||
flags = "g:w:e",
|
||||
flags = "g:w:eh:",
|
||||
desc = "Set flags",
|
||||
min = 2)
|
||||
public void flag(CommandContext args, Actor sender) throws CommandException {
|
||||
@ -537,9 +540,9 @@ public void flag(CommandContext args, Actor sender) throws CommandException {
|
||||
sender.print(builder.build());
|
||||
|
||||
return;
|
||||
} else {
|
||||
} else if (value != null) {
|
||||
if (foundFlag == Flags.BUILD || foundFlag == Flags.BLOCK_BREAK || foundFlag == Flags.BLOCK_PLACE) {
|
||||
sender.print(Component.empty().append(TextComponent.of("WARNING:", TextColor.RED).decoration(TextDecoration.BOLD, true))
|
||||
sender.print(Component.empty().append(TextComponent.of("WARNING:", TextColor.RED, Sets.newHashSet(TextDecoration.BOLD)))
|
||||
.append(ErrorFormat.wrap(" Setting the " + foundFlag.getName() + " flag is not required for protection."))
|
||||
.append(Component.newline())
|
||||
.append(TextComponent.of("Setting this flag will completely override default protection, and apply" +
|
||||
@ -554,7 +557,7 @@ public void flag(CommandContext args, Actor sender) throws CommandException {
|
||||
sender.printRaw("https://worldguard.readthedocs.io/en/latest/regions/flags/#protection-related");
|
||||
}
|
||||
} else if (foundFlag == Flags.PASSTHROUGH) {
|
||||
sender.print(Component.empty().append(TextComponent.of("WARNING:", TextColor.RED).decoration(TextDecoration.BOLD, true))
|
||||
sender.print(Component.empty().append(TextComponent.of("WARNING:", TextColor.RED, Sets.newHashSet(TextDecoration.BOLD)))
|
||||
.append(ErrorFormat.wrap(" This flag is unrelated to moving through regions."))
|
||||
.append(Component.newline())
|
||||
.append(TextComponent.of("It overrides build checks. If you're unsure what this means, see ")
|
||||
@ -604,7 +607,9 @@ public void flag(CommandContext args, Actor sender) throws CommandException {
|
||||
throw new CommandException(e.getMessage());
|
||||
}
|
||||
|
||||
sender.print("Region flag " + foundFlag.getName() + " set on '" + existing.getId() + "' to '" + value + "'.");
|
||||
if (!args.hasFlag('h')) {
|
||||
sender.print("Region flag " + foundFlag.getName() + " set on '" + existing.getId() + "' to '" + value + "'.");
|
||||
}
|
||||
|
||||
// No value? Clear the flag, if -g isn't specified
|
||||
} else if (!args.hasFlag('g')) {
|
||||
@ -617,7 +622,9 @@ public void flag(CommandContext args, Actor sender) throws CommandException {
|
||||
existing.setFlag(groupFlag, null);
|
||||
}
|
||||
|
||||
sender.print("Region flag " + foundFlag.getName() + " removed from '" + existing.getId() + "'. (Any -g(roups) were also removed.)");
|
||||
if (!args.hasFlag('h')) {
|
||||
sender.print("Region flag " + foundFlag.getName() + " removed from '" + existing.getId() + "'. (Any -g(roups) were also removed.)");
|
||||
}
|
||||
}
|
||||
|
||||
// Now set the group
|
||||
@ -635,11 +642,48 @@ public void flag(CommandContext args, Actor sender) throws CommandException {
|
||||
}
|
||||
|
||||
// Print region information
|
||||
RegionPrintoutBuilder printout = new RegionPrintoutBuilder(world.getName(), existing, null, sender);
|
||||
printout.append(SubtleFormat.wrap("(Current flags: "));
|
||||
printout.appendFlagsList(false);
|
||||
printout.append(SubtleFormat.wrap(")"));
|
||||
printout.send(sender);
|
||||
if (args.hasFlag('h')) {
|
||||
int page = args.getFlagInteger('h');
|
||||
try {
|
||||
final FlagHelperBox flagHelperBox = new FlagHelperBox(world, existing, permModel);
|
||||
flagHelperBox.setComponentsPerPage(18);
|
||||
sender.print(flagHelperBox.create(page));
|
||||
} catch (InvalidComponentException e) {
|
||||
throw new CommandException("Error creating component.", e);
|
||||
}
|
||||
} else {
|
||||
RegionPrintoutBuilder printout = new RegionPrintoutBuilder(world.getName(), existing, null, sender);
|
||||
printout.append(SubtleFormat.wrap("(Current flags: "));
|
||||
printout.appendFlagsList(false);
|
||||
printout.append(SubtleFormat.wrap(")"));
|
||||
printout.send(sender);
|
||||
}
|
||||
}
|
||||
|
||||
@Command(aliases = "flags",
|
||||
usage = "<id> [page]",
|
||||
flags = "w:",
|
||||
desc = "View region flags",
|
||||
min = 1, max = 2)
|
||||
public void flagHelper(CommandContext args, Actor sender) throws CommandException {
|
||||
World world = checkWorld(args, sender, 'w'); // Get the world
|
||||
|
||||
// Lookup the existing region
|
||||
RegionManager manager = checkRegionManager(world);
|
||||
ProtectedRegion region = checkExistingRegion(manager, args.getString(0), true);
|
||||
|
||||
final RegionPermissionModel perms = getPermissionModel(sender);
|
||||
if (!perms.mayLookup(region)) {
|
||||
throw new CommandPermissionsException();
|
||||
}
|
||||
int page = args.getInteger(1, 1);
|
||||
try {
|
||||
final FlagHelperBox flagHelperBox = new FlagHelperBox(world, region, perms);
|
||||
flagHelperBox.setComponentsPerPage(18);
|
||||
sender.print(flagHelperBox.create(page));
|
||||
} catch (InvalidComponentException e) {
|
||||
throw new CommandException("Error creating component.", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -34,6 +34,8 @@
|
||||
import com.sk89q.worldedit.regions.selector.Polygonal2DRegionSelector;
|
||||
import com.sk89q.worldedit.util.formatting.component.SubtleFormat;
|
||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||
import com.sk89q.worldedit.util.formatting.text.event.ClickEvent;
|
||||
import com.sk89q.worldedit.util.formatting.text.event.HoverEvent;
|
||||
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
@ -157,8 +159,8 @@ protected static ProtectedRegion checkExistingRegion(RegionManager regionManager
|
||||
* @return a region
|
||||
* @throws CommandException thrown if no region was found
|
||||
*/
|
||||
protected static ProtectedRegion checkRegionStandingIn(RegionManager regionManager, LocalPlayer player) throws CommandException {
|
||||
return checkRegionStandingIn(regionManager, player, false);
|
||||
protected static ProtectedRegion checkRegionStandingIn(RegionManager regionManager, LocalPlayer player, String rgCmd) throws CommandException {
|
||||
return checkRegionStandingIn(regionManager, player, false, rgCmd);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -176,7 +178,7 @@ protected static ProtectedRegion checkRegionStandingIn(RegionManager regionManag
|
||||
* @return a region
|
||||
* @throws CommandException thrown if no region was found
|
||||
*/
|
||||
protected static ProtectedRegion checkRegionStandingIn(RegionManager regionManager, LocalPlayer player, boolean allowGlobal) throws CommandException {
|
||||
protected static ProtectedRegion checkRegionStandingIn(RegionManager regionManager, LocalPlayer player, boolean allowGlobal, String rgCmd) throws CommandException {
|
||||
ApplicableRegionSet set = regionManager.getApplicableRegions(player.getLocation().toVector().toBlockPoint());
|
||||
|
||||
if (set.size() == 0) {
|
||||
@ -190,19 +192,24 @@ protected static ProtectedRegion checkRegionStandingIn(RegionManager regionManag
|
||||
"You're not standing in a region." +
|
||||
"Specify an ID if you want to select a specific region.");
|
||||
} else if (set.size() > 1) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
boolean first = true;
|
||||
|
||||
final TextComponent.Builder builder = TextComponent.builder("");
|
||||
builder.append(TextComponent.of("Current regions: ", TextColor.GOLD));
|
||||
for (ProtectedRegion region : set) {
|
||||
if (!first) {
|
||||
builder.append(", ");
|
||||
builder.append(TextComponent.of(", "));
|
||||
}
|
||||
first = false;
|
||||
builder.append(region.getId());
|
||||
TextComponent regionComp = TextComponent.of(region.getId(), TextColor.AQUA);
|
||||
if (rgCmd != null && rgCmd.contains("%id%")) {
|
||||
regionComp = regionComp.hoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, TextComponent.of("Click to pick this region")))
|
||||
.clickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, rgCmd.replace("%id%", region.getId())));
|
||||
}
|
||||
builder.append(regionComp);
|
||||
}
|
||||
|
||||
throw new CommandException(
|
||||
"You're standing in several regions (please pick one).\nYou're in: " + builder.toString());
|
||||
player.print(builder.build());
|
||||
throw new CommandException("You're standing in several regions (please pick one).");
|
||||
}
|
||||
|
||||
return set.iterator().next();
|
||||
|
@ -163,9 +163,9 @@ public void appendFlagsList(boolean useColors) {
|
||||
|
||||
if (perms != null && perms.maySetFlag(region)) {
|
||||
builder.append(Component.space())
|
||||
.append(TextComponent.of("[Add]", useColors ? TextColor.GREEN : TextColor.GRAY)
|
||||
.append(TextComponent.of("[Flags]", useColors ? TextColor.GREEN : TextColor.GRAY)
|
||||
.hoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, TextComponent.of("Click to set a flag")))
|
||||
.clickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/rg flag -w " + world + " " + region.getId() + " ")));
|
||||
.clickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/rg flags -w " + world + " " + region.getId())));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,15 @@
|
||||
import com.sk89q.worldguard.protection.util.NormativeOrders;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
@ -49,7 +57,6 @@
|
||||
*/
|
||||
public class FlagValueCalculator {
|
||||
|
||||
private final List<ProtectedRegion> regions;
|
||||
@Nullable
|
||||
private final ProtectedRegion globalRegion;
|
||||
private final Iterable<ProtectedRegion> applicable;
|
||||
@ -63,14 +70,10 @@ public class FlagValueCalculator {
|
||||
public FlagValueCalculator(List<ProtectedRegion> regions, @Nullable ProtectedRegion globalRegion) {
|
||||
checkNotNull(regions);
|
||||
|
||||
this.regions = regions;
|
||||
this.globalRegion = globalRegion;
|
||||
|
||||
if (globalRegion != null) {
|
||||
applicable = Iterables.concat(regions, Arrays.asList(globalRegion));
|
||||
} else {
|
||||
applicable = regions;
|
||||
}
|
||||
applicable = globalRegion == null ? regions
|
||||
: Iterables.concat(regions, Collections.singletonList(globalRegion));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -128,7 +131,7 @@ public Result getMembership(RegionAssociable subject) {
|
||||
|
||||
minimumPriority = getPriority(region);
|
||||
|
||||
boolean member = RegionGroup.MEMBERS.contains(subject.getAssociation(Arrays.asList(region)));
|
||||
boolean member = RegionGroup.MEMBERS.contains(subject.getAssociation(Collections.singletonList(region)));
|
||||
|
||||
if (member) {
|
||||
result = Result.SUCCESS;
|
||||
|
@ -32,12 +32,18 @@
|
||||
import com.sk89q.worldguard.protection.flags.registry.FlagRegistry;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The flags that are used in WorldGuard.
|
||||
*/
|
||||
public final class Flags {
|
||||
|
||||
private static final List<String> INBUILT_FLAGS_LIST = new ArrayList<>();
|
||||
public static final List<String> INBUILT_FLAGS = Collections.unmodifiableList(INBUILT_FLAGS_LIST);
|
||||
|
||||
// Overrides membership check
|
||||
public static final StateFlag PASSTHROUGH = register(new StateFlag("passthrough", false));
|
||||
|
||||
@ -91,7 +97,7 @@ public final class Flags {
|
||||
|
||||
// mob spawning related
|
||||
public static final StateFlag MOB_SPAWNING = register(new StateFlag("mob-spawning", true));
|
||||
public static final SetFlag<EntityType> DENY_SPAWN = register(new SetFlag<>("deny-spawn", new EntityTypeFlag(null)));
|
||||
public static final SetFlag<EntityType> DENY_SPAWN = register(new SetFlag<>("deny-spawn", new RegistryFlag<>(null, EntityType.REGISTRY)));
|
||||
|
||||
// block dynamics
|
||||
public static final StateFlag PISTONS = register(new StateFlag("pistons", true));
|
||||
@ -111,6 +117,9 @@ public final class Flags {
|
||||
public static final StateFlag WATER_FLOW = register(new StateFlag("water-flow", true));
|
||||
public static final StateFlag LAVA_FLOW = register(new StateFlag("lava-flow", true));
|
||||
|
||||
public static final RegistryFlag<WeatherType> WEATHER_LOCK = register(new RegistryFlag<>("weather-lock", WeatherType.REGISTRY));
|
||||
public static final StringFlag TIME_LOCK = register(new StringFlag("time-lock"));
|
||||
|
||||
// chat related flags
|
||||
public static final StateFlag SEND_CHAT = register(new StateFlag("send-chat", true));
|
||||
public static final StateFlag RECEIVE_CHAT = register(new StateFlag("receive-chat", true));
|
||||
@ -140,9 +149,7 @@ public final class Flags {
|
||||
public static final BooleanFlag NOTIFY_ENTER = register(new BooleanFlag("notify-enter"));
|
||||
public static final BooleanFlag NOTIFY_LEAVE = register(new BooleanFlag("notify-leave"));
|
||||
|
||||
public static final Flag<GameMode> GAME_MODE = register(new GameModeTypeFlag("game-mode"));
|
||||
public static final StringFlag TIME_LOCK = register(new StringFlag("time-lock"));
|
||||
public static final Flag<WeatherType> WEATHER_LOCK = register(new WeatherTypeFlag("weather-lock"));
|
||||
public static final RegistryFlag<GameMode> GAME_MODE = register(new RegistryFlag<>("game-mode", GameMode.REGISTRY));
|
||||
|
||||
public static final IntegerFlag HEAL_DELAY = register(new IntegerFlag("heal-delay"));
|
||||
public static final IntegerFlag HEAL_AMOUNT = register(new IntegerFlag("heal-amount"));
|
||||
@ -173,6 +180,7 @@ private Flags() {
|
||||
|
||||
private static <T extends Flag<?>> T register(final T flag) throws FlagConflictException {
|
||||
WorldGuard.getInstance().getFlagRegistry().register(flag);
|
||||
INBUILT_FLAGS_LIST.add(flag.getName());
|
||||
return flag;
|
||||
}
|
||||
|
||||
|
@ -67,23 +67,14 @@ public static boolean isMember(ProtectedRegion region, RegionGroup group, @Nulla
|
||||
if (group == null || group == RegionGroup.ALL) {
|
||||
return true;
|
||||
} else if (group == RegionGroup.OWNERS) {
|
||||
if (player != null && region.isOwner(player)) {
|
||||
return true;
|
||||
}
|
||||
return player != null && region.isOwner(player);
|
||||
} else if (group == RegionGroup.MEMBERS) {
|
||||
if (player != null && region.isMember(player)) {
|
||||
return true;
|
||||
}
|
||||
return player != null && region.isMember(player);
|
||||
} else if (group == RegionGroup.NON_OWNERS) {
|
||||
if (player == null || !region.isOwner(player)) {
|
||||
return true;
|
||||
}
|
||||
return player == null || !region.isOwner(player);
|
||||
} else if (group == RegionGroup.NON_MEMBERS) {
|
||||
if (player == null || !region.isMember(player)) {
|
||||
return true;
|
||||
}
|
||||
return player == null || !region.isMember(player);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -91,23 +82,14 @@ public static boolean isMember(ApplicableRegionSet set, @Nullable RegionGroup gr
|
||||
if (group == null || group == RegionGroup.ALL) {
|
||||
return true;
|
||||
} else if (group == RegionGroup.OWNERS) {
|
||||
if (set.isOwnerOfAll(player)) {
|
||||
return true;
|
||||
}
|
||||
return set.isOwnerOfAll(player);
|
||||
} else if (group == RegionGroup.MEMBERS) {
|
||||
if (set.isMemberOfAll(player)) {
|
||||
return true;
|
||||
}
|
||||
return set.isMemberOfAll(player);
|
||||
} else if (group == RegionGroup.NON_OWNERS) {
|
||||
if (!set.isOwnerOfAll(player)) {
|
||||
return true;
|
||||
}
|
||||
return !set.isOwnerOfAll(player);
|
||||
} else if (group == RegionGroup.NON_MEMBERS) {
|
||||
if (!set.isMemberOfAll(player)) {
|
||||
return true;
|
||||
}
|
||||
return !set.isMemberOfAll(player);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* WorldGuard, a suite of tools for Minecraft
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* Copyright (C) WorldGuard team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser 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 Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.protection.flags;
|
||||
|
||||
import com.sk89q.worldedit.registry.Keyed;
|
||||
import com.sk89q.worldedit.registry.Registry;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Locale;
|
||||
import java.util.Optional;
|
||||
|
||||
public class RegistryFlag<T extends Keyed> extends Flag<T> {
|
||||
private final Registry<T> registry;
|
||||
|
||||
public RegistryFlag(String name, Registry<T> registry) {
|
||||
super(name);
|
||||
this.registry = registry;
|
||||
}
|
||||
|
||||
public RegistryFlag(String name, @Nullable RegionGroup defaultGroup, Registry<T> registry) {
|
||||
super(name, defaultGroup);
|
||||
this.registry = registry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T parseInput(FlagContext context) throws InvalidFlagFormat {
|
||||
final String key = context.getUserInput().trim().toLowerCase(Locale.ENGLISH);
|
||||
return Optional.ofNullable(registry.get(key))
|
||||
.orElseThrow(() -> new InvalidFlagFormat("Unknown " + registry.getName() + ": " + key));
|
||||
}
|
||||
|
||||
public Registry<T> getRegistry() {
|
||||
return registry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T unmarshal(@Nullable Object o) {
|
||||
return registry.get(String.valueOf(o));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object marshal(T o) {
|
||||
return o.getId();
|
||||
}
|
||||
}
|
@ -19,7 +19,6 @@
|
||||
|
||||
package com.sk89q.worldguard.protection.flags.registry;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.Iterators;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
@ -80,7 +79,7 @@ public void registerAll(Collection<Flag<?>> flags) {
|
||||
|
||||
private Flag<?> forceRegister(Flag<?> flag) throws FlagConflictException {
|
||||
checkNotNull(flag, "flag");
|
||||
Preconditions.checkNotNull(flag.getName(), "flag.getName()");
|
||||
checkNotNull(flag.getName(), "flag.getName()");
|
||||
|
||||
synchronized (lock) {
|
||||
String name = flag.getName().toLowerCase();
|
||||
|
Loading…
Reference in New Issue
Block a user