Implement stacking prefixes - closes #60

This commit is contained in:
Luck 2017-01-22 18:23:08 +00:00
parent 38d1c9974b
commit 292d4cd450
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B
22 changed files with 879 additions and 17 deletions

View File

@ -22,6 +22,7 @@
package me.lucko.luckperms.bukkit;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import me.lucko.luckperms.common.config.AbstractConfiguration;
@ -38,7 +39,10 @@ import java.util.stream.Collectors;
@RequiredArgsConstructor
public class BukkitConfig extends AbstractConfiguration {
@Getter
private final LPBukkitPlugin plugin;
private YamlConfiguration configuration;
@Override

View File

@ -75,6 +75,38 @@ group-weight:
# +------------------------------------------------------------------------+ #
# | Meta Formatting & Stacking | #
# +------------------------------------------------------------------------+ #
# Allows you to setup prefix/suffix stacking options.
#
# Available formats:
# - highest
# - lowest
# - highest_own
# - lowest_own
# - highest_on_track_<track>
# - lowest_on_track_<track>
#
# Each element is added in the order listed.
meta-formatting:
prefix:
format:
- "highest"
start-spacer: ""
middle-spacer: " "
end-spacer: ""
suffix:
format:
- "highest"
start-spacer: ""
middle-spacer: " "
end-spacer: ""
# +------------------------------------------------------------------------+ #
# | OP (Server Operator) Settings | #
# +------------------------------------------------------------------------+ #

View File

@ -22,6 +22,7 @@
package me.lucko.luckperms.bungee;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import me.lucko.luckperms.common.config.AbstractConfiguration;
@ -42,7 +43,10 @@ import java.util.stream.Collectors;
@RequiredArgsConstructor
public class BungeeConfig extends AbstractConfiguration {
@Getter
private final LPBungeePlugin plugin;
private Configuration configuration;
@SuppressWarnings("ResultOfMethodCallIgnored")

View File

@ -85,6 +85,38 @@ group-weight:
# +------------------------------------------------------------------------+ #
# | Meta Formatting & Stacking | #
# +------------------------------------------------------------------------+ #
# Allows you to setup prefix/suffix stacking options.
#
# Available formats:
# - highest
# - lowest
# - highest_own
# - lowest_own
# - highest_on_track_<track>
# - lowest_on_track_<track>
#
# Each element is added in the order listed.
meta-formatting:
prefix:
format:
- "highest"
start-spacer: ""
middle-spacer: " "
end-spacer: ""
suffix:
format:
- "highest"
start-spacer: ""
middle-spacer: " "
end-spacer: ""
# +------------------------------------------------------------------------+ #
# | Storage | #
# +------------------------------------------------------------------------+ #

View File

@ -29,6 +29,8 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSortedMap;
import me.lucko.luckperms.api.caching.MetaData;
import me.lucko.luckperms.common.caching.stacking.MetaStack;
import me.lucko.luckperms.common.caching.stacking.NoopMetaStack;
import java.util.Map;
import java.util.SortedMap;
@ -51,12 +53,20 @@ public class MetaCache implements MetaData {
@Getter
private SortedMap<Integer, String> suffixes = ImmutableSortedMap.of();
@Getter
private MetaStack prefixStack = NoopMetaStack.INSTANCE;
@Getter
private MetaStack suffixStack = NoopMetaStack.INSTANCE;
public void loadMeta(MetaHolder meta) {
lock.writeLock().lock();
try {
this.meta = ImmutableMap.copyOf(meta.getMeta());
this.prefixes = ImmutableSortedMap.copyOfSorted(meta.getPrefixes());
this.suffixes = ImmutableSortedMap.copyOfSorted(meta.getSuffixes());
this.prefixStack = meta.getPrefixStack();
this.suffixStack = meta.getSuffixStack();
} finally {
lock.writeLock().unlock();
}
@ -66,11 +76,7 @@ public class MetaCache implements MetaData {
public String getPrefix() {
lock.readLock().lock();
try {
if (prefixes.isEmpty()) {
return null;
}
return prefixes.get(prefixes.firstKey());
return prefixStack.toFormattedString();
} finally {
lock.readLock().unlock();
}
@ -80,11 +86,7 @@ public class MetaCache implements MetaData {
public String getSuffix() {
lock.readLock().lock();
try {
if (suffixes.isEmpty()) {
return null;
}
return suffixes.get(suffixes.firstKey());
return suffixStack.toFormattedString();
} finally {
lock.readLock().unlock();
}

View File

@ -25,7 +25,9 @@ package me.lucko.luckperms.common.caching;
import lombok.Getter;
import lombok.ToString;
import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.api.LocalizedNode;
import me.lucko.luckperms.common.caching.stacking.MetaStack;
import me.lucko.luckperms.common.caching.stacking.NoopMetaStack;
import java.util.Comparator;
import java.util.HashMap;
@ -40,11 +42,26 @@ import java.util.TreeMap;
@ToString
public class MetaHolder {
private final Map<String, String> meta = new HashMap<>();
private final SortedMap<Integer, String> prefixes = new TreeMap<>(Comparator.reverseOrder());
private final SortedMap<Integer, String> suffixes = new TreeMap<>(Comparator.reverseOrder());
private final Map<String, String> meta;
private final SortedMap<Integer, String> prefixes;
private final SortedMap<Integer, String> suffixes;
public void accumulateNode(Node n) {
private final MetaStack prefixStack;
private final MetaStack suffixStack;
public MetaHolder(MetaStack prefixStack, MetaStack suffixStack) {
this.meta = new HashMap<>();
this.prefixes = new TreeMap<>(Comparator.reverseOrder());
this.suffixes = new TreeMap<>(Comparator.reverseOrder());
this.prefixStack = prefixStack;
this.suffixStack = suffixStack;
}
public MetaHolder() {
this(NoopMetaStack.INSTANCE, NoopMetaStack.INSTANCE);
}
public void accumulateNode(LocalizedNode n) {
if (n.isMeta()) {
Map.Entry<String, String> entry = n.getMeta();
if (!meta.containsKey(entry.getKey())) {
@ -57,6 +74,8 @@ public class MetaHolder {
if (!prefixes.containsKey(value.getKey())) {
prefixes.put(value.getKey(), value.getValue());
}
prefixStack.accumulateToAll(n);
}
if (n.isSuffix()) {
@ -64,6 +83,8 @@ public class MetaHolder {
if (!suffixes.containsKey(value.getKey())) {
suffixes.put(value.getKey(), value.getValue());
}
suffixStack.accumulateToAll(n);
}
}

View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.common.caching.stacking;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import java.util.ArrayList;
import java.util.List;
@Getter
@RequiredArgsConstructor
public class GenericMetaStack implements MetaStack {
private final List<MetaStackElement> elements;
private final String startSpacer;
private final String middleSpacer;
private final String endSpacer;
@Override
public String toFormattedString() {
List<MetaStackElement> ret = new ArrayList<>(elements);
ret.removeIf(m -> !m.getEntry().isPresent());
if (ret.isEmpty()) {
return null;
}
StringBuilder sb = new StringBuilder();
sb.append(startSpacer);
for (int i = 0; i < ret.size(); i++) {
if (i != 0) {
sb.append(middleSpacer);
}
MetaStackElement e = ret.get(i);
sb.append(e.getEntry().get().getValue());
}
sb.append(endSpacer);
return sb.toString();
}
}

View File

@ -0,0 +1,38 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.common.caching.stacking;
import me.lucko.luckperms.api.LocalizedNode;
import java.util.List;
public interface MetaStack {
List<MetaStackElement> getElements();
String toFormattedString();
default void accumulateToAll(LocalizedNode node) {
getElements().forEach(m -> m.accumulateNode(node));
}
}

View File

@ -0,0 +1,91 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.common.caching.stacking;
import me.lucko.luckperms.api.LocalizedNode;
import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.core.model.Track;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
public interface MetaStackElement {
Optional<Map.Entry<Integer, String>> getEntry();
boolean accumulateNode(LocalizedNode node);
/**
* Returns true if the types do not match
* @param expectingPrefix if the method is expecting a prefix
* @param node the node to check
* @return true if the accumulation should return
*/
static boolean checkMetaType(boolean expectingPrefix, LocalizedNode node) {
if (expectingPrefix) {
if (!node.isPrefix()) {
return true;
}
} else {
if (!node.isSuffix()) {
return true;
}
}
return false;
}
/**
* Returns true if the node is not held by a user
* @param node the node to check
* @return true if the accumulation should return
*/
static boolean checkOwnElement(LocalizedNode node) {
if (node.getLocation() == null || node.getLocation().equals("")) {
return true;
}
try {
UUID.fromString(node.getLocation());
return false;
} catch (IllegalArgumentException e) {
return true;
}
}
/**
* Returns true if the node is not held by a group on the track
* @param node the node to check
* @param track the track
* @return true if the accumulation should return
*/
static boolean checkTrackElement(LuckPermsPlugin plugin, LocalizedNode node, String track) {
if (node.getLocation() == null || node.getLocation().equals("")) {
return true;
}
Track t = plugin.getTrackManager().getIfLoaded(track);
return t == null || !t.containsGroup(node.getLocation());
}
}

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.common.caching.stacking;
import java.util.Collections;
import java.util.List;
public class NoopMetaStack implements MetaStack {
public static final NoopMetaStack INSTANCE = new NoopMetaStack();
@Override
public List<MetaStackElement> getElements() {
return Collections.emptyList();
}
@Override
public String toFormattedString() {
return null;
}
}

View File

@ -0,0 +1,79 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.common.caching.stacking;
import lombok.experimental.UtilityClass;
import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.caching.stacking.elements.HighestPriorityElement;
import me.lucko.luckperms.common.caching.stacking.elements.HighestPriorityOwnElement;
import me.lucko.luckperms.common.caching.stacking.elements.HighestPriorityTrackElement;
import me.lucko.luckperms.common.caching.stacking.elements.LowestPriorityElement;
import me.lucko.luckperms.common.caching.stacking.elements.LowestPriorityOwnElement;
import me.lucko.luckperms.common.caching.stacking.elements.LowestPriorityTrackElement;
import me.lucko.luckperms.common.utils.ImmutableCollectors;
import java.util.List;
import java.util.Optional;
@UtilityClass
public class StackElementFactory {
public static Optional<MetaStackElement> fromString(LuckPermsPlugin plugin, String s, boolean prefix) {
s = s.toLowerCase();
if (s.equals("highest")) {
return Optional.of(new HighestPriorityElement(prefix));
}
if (s.equals("lowest")) {
return Optional.of(new LowestPriorityElement(prefix));
}
if (s.equals("highest_own")) {
return Optional.of(new HighestPriorityOwnElement(prefix));
}
if (s.equals("lowest_own")) {
return Optional.of(new LowestPriorityOwnElement(prefix));
}
if (s.startsWith("highest_on_track_") && s.length() > "highest_on_track_".length()) {
String track = s.substring("highest_on_track_".length());
return Optional.of(new HighestPriorityTrackElement(prefix, plugin, track));
}
if (s.startsWith("lowest_on_track_") && s.length() > "lowest_on_track_".length()) {
String track = s.substring("lowest_on_track_".length());
return Optional.of(new LowestPriorityTrackElement(prefix, plugin, track));
}
new IllegalArgumentException("Cannot parse MetaStackElement: " + s).printStackTrace();
return Optional.empty();
}
public static List<MetaStackElement> fromList(LuckPermsPlugin plugin, List<String> strings, boolean prefix) {
return strings.stream().map(s -> fromString(plugin, s, prefix)).filter(Optional::isPresent).map(Optional::get).collect(ImmutableCollectors.toImmutableList());
}
}

View File

@ -0,0 +1,68 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.common.caching.stacking.elements;
import lombok.RequiredArgsConstructor;
import me.lucko.luckperms.api.LocalizedNode;
import me.lucko.luckperms.common.caching.stacking.MetaStackElement;
import java.util.Map;
import java.util.Optional;
@RequiredArgsConstructor
public class HighestPriorityElement implements MetaStackElement {
/**
* Returns true if the current node has the greater priority
* @param current the current entry
* @param newEntry the new entry
* @return true if the accumulation should return
*/
public static boolean compareEntries(Map.Entry<Integer, String> current, Map.Entry<Integer, String> newEntry) {
return current != null && current.getKey() >= newEntry.getKey();
}
private final boolean prefix;
private Map.Entry<Integer, String> entry = null;
@Override
public Optional<Map.Entry<Integer, String>> getEntry() {
return Optional.ofNullable(entry);
}
@Override
public boolean accumulateNode(LocalizedNode node) {
if (MetaStackElement.checkMetaType(prefix, node)) {
return false;
}
Map.Entry<Integer, String> entry = prefix ? node.getPrefix() : node.getSuffix();
if (compareEntries(this.entry, entry)) {
return false;
}
this.entry = entry;
return true;
}
}

View File

@ -0,0 +1,62 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.common.caching.stacking.elements;
import lombok.RequiredArgsConstructor;
import me.lucko.luckperms.api.LocalizedNode;
import me.lucko.luckperms.common.caching.stacking.MetaStackElement;
import java.util.Map;
import java.util.Optional;
@RequiredArgsConstructor
public class HighestPriorityOwnElement implements MetaStackElement {
private final boolean prefix;
private Map.Entry<Integer, String> entry = null;
@Override
public Optional<Map.Entry<Integer, String>> getEntry() {
return Optional.ofNullable(entry);
}
@Override
public boolean accumulateNode(LocalizedNode node) {
if (MetaStackElement.checkMetaType(prefix, node)) {
return false;
}
if (MetaStackElement.checkOwnElement(node)) {
return false;
}
Map.Entry<Integer, String> entry = prefix ? node.getPrefix() : node.getSuffix();
if (HighestPriorityElement.compareEntries(this.entry, entry)) {
return false;
}
this.entry = entry;
return true;
}
}

View File

@ -0,0 +1,65 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.common.caching.stacking.elements;
import lombok.RequiredArgsConstructor;
import me.lucko.luckperms.api.LocalizedNode;
import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.caching.stacking.MetaStackElement;
import java.util.Map;
import java.util.Optional;
@RequiredArgsConstructor
public class HighestPriorityTrackElement implements MetaStackElement {
private final boolean prefix;
private final LuckPermsPlugin plugin;
private final String trackName;
private Map.Entry<Integer, String> entry = null;
@Override
public Optional<Map.Entry<Integer, String>> getEntry() {
return Optional.ofNullable(entry);
}
@Override
public boolean accumulateNode(LocalizedNode node) {
if (MetaStackElement.checkMetaType(prefix, node)) {
return false;
}
Map.Entry<Integer, String> entry = prefix ? node.getPrefix() : node.getSuffix();
if (HighestPriorityElement.compareEntries(this.entry, entry)) {
return false;
}
if (MetaStackElement.checkTrackElement(plugin, node, trackName)) {
return false;
}
this.entry = entry;
return true;
}
}

View File

@ -0,0 +1,68 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.common.caching.stacking.elements;
import lombok.RequiredArgsConstructor;
import me.lucko.luckperms.api.LocalizedNode;
import me.lucko.luckperms.common.caching.stacking.MetaStackElement;
import java.util.Map;
import java.util.Optional;
@RequiredArgsConstructor
public class LowestPriorityElement implements MetaStackElement {
/**
* Returns true if the current node has the lesser priority
* @param current the current entry
* @param newEntry the new entry
* @return true if the accumulation should return
*/
public static boolean compareEntries(Map.Entry<Integer, String> current, Map.Entry<Integer, String> newEntry) {
return current != null && current.getKey() <= newEntry.getKey();
}
private final boolean prefix;
private Map.Entry<Integer, String> entry = null;
@Override
public Optional<Map.Entry<Integer, String>> getEntry() {
return Optional.ofNullable(entry);
}
@Override
public boolean accumulateNode(LocalizedNode node) {
if (MetaStackElement.checkMetaType(prefix, node)) {
return false;
}
Map.Entry<Integer, String> entry = prefix ? node.getPrefix() : node.getSuffix();
if (compareEntries(this.entry, entry)) {
return false;
}
this.entry = entry;
return true;
}
}

View File

@ -0,0 +1,61 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.common.caching.stacking.elements;
import lombok.RequiredArgsConstructor;
import me.lucko.luckperms.api.LocalizedNode;
import me.lucko.luckperms.common.caching.stacking.MetaStackElement;
import java.util.Map;
import java.util.Optional;
@RequiredArgsConstructor
public class LowestPriorityOwnElement implements MetaStackElement {
private final boolean prefix;
private Map.Entry<Integer, String> entry = null;
@Override
public Optional<Map.Entry<Integer, String>> getEntry() {
return Optional.ofNullable(entry);
}
@Override
public boolean accumulateNode(LocalizedNode node) {
if (MetaStackElement.checkMetaType(prefix, node)) {
return false;
}
if (MetaStackElement.checkOwnElement(node)) {
return false;
}
Map.Entry<Integer, String> entry = prefix ? node.getPrefix() : node.getSuffix();
if (LowestPriorityElement.compareEntries(this.entry, entry)) {
return false;
}
this.entry = entry;
return true;
}
}

View File

@ -0,0 +1,65 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.common.caching.stacking.elements;
import lombok.RequiredArgsConstructor;
import me.lucko.luckperms.api.LocalizedNode;
import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.caching.stacking.MetaStackElement;
import java.util.Map;
import java.util.Optional;
@RequiredArgsConstructor
public class LowestPriorityTrackElement implements MetaStackElement {
private final boolean prefix;
private final LuckPermsPlugin plugin;
private final String trackName;
private Map.Entry<Integer, String> entry = null;
@Override
public Optional<Map.Entry<Integer, String>> getEntry() {
return Optional.ofNullable(entry);
}
@Override
public boolean accumulateNode(LocalizedNode node) {
if (MetaStackElement.checkMetaType(prefix, node)) {
return false;
}
Map.Entry<Integer, String> entry = prefix ? node.getPrefix() : node.getSuffix();
if (LowestPriorityElement.compareEntries(this.entry, entry)) {
return false;
}
if (MetaStackElement.checkTrackElement(plugin, node, trackName)) {
return false;
}
this.entry = entry;
return true;
}
}

View File

@ -27,6 +27,8 @@ import lombok.experimental.UtilityClass;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import me.lucko.luckperms.common.caching.stacking.GenericMetaStack;
import me.lucko.luckperms.common.caching.stacking.StackElementFactory;
import me.lucko.luckperms.common.config.keys.AbstractKey;
import me.lucko.luckperms.common.config.keys.BooleanKey;
import me.lucko.luckperms.common.config.keys.EnduringKey;
@ -38,6 +40,7 @@ import me.lucko.luckperms.common.defaults.Rule;
import me.lucko.luckperms.common.storage.DatastoreConfiguration;
import me.lucko.luckperms.common.utils.ImmutableCollectors;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@ -68,6 +71,22 @@ public class ConfigKeys {
})
);
});
public static final ConfigKey<GenericMetaStack> PREFIX_FORMATTING_OPTIONS = AbstractKey.of(l -> {
List<String> format = l.getList("meta-formatting.prefix.format", Collections.singletonList("highest"));
String startSpacer = l.getString("meta-formatting.prefix.start-spacer", "");
String middleSpacer = l.getString("meta-formatting.prefix.middle-spacer", " ");
String endSpacer = l.getString("meta-formatting.prefix.end-spacer", "");
return new GenericMetaStack(StackElementFactory.fromList(l.getPlugin(), format, true), startSpacer, middleSpacer, endSpacer);
});
public static final ConfigKey<GenericMetaStack> SUFFIX_FORMATTING_OPTIONS = AbstractKey.of(l -> {
List<String> format = l.getList("meta-formatting.suffix.format", Collections.singletonList("highest"));
String startSpacer = l.getString("meta-formatting.suffix.start-spacer", "");
String middleSpacer = l.getString("meta-formatting.suffix.middle-spacer", " ");
String endSpacer = l.getString("meta-formatting.suffix.end-spacer", "");
return new GenericMetaStack(StackElementFactory.fromList(l.getPlugin(), format, false), startSpacer, middleSpacer, endSpacer);
});
public static final ConfigKey<Boolean> LOG_NOTIFY = BooleanKey.of("log-notify", true);
public static final ConfigKey<Boolean> AUTO_OP = EnduringKey.wrap(BooleanKey.of("auto-op", false));
public static final ConfigKey<Boolean> OPS_ENABLED = EnduringKey.wrap(AbstractKey.of(c -> !AUTO_OP.get(c) && c.getBoolean("enable-ops", true)));

View File

@ -22,11 +22,15 @@
package me.lucko.luckperms.common.config;
import me.lucko.luckperms.common.LuckPermsPlugin;
import java.util.List;
import java.util.Map;
public interface LPConfiguration {
LuckPermsPlugin getPlugin();
void init();
void reload();

View File

@ -467,7 +467,10 @@ public abstract class PermissionHolder {
public MetaHolder accumulateMeta(MetaHolder holder, List<String> excludedGroups, ExtractedContexts contexts) {
if (holder == null) {
holder = new MetaHolder();
holder = new MetaHolder(
plugin.getConfiguration().get(ConfigKeys.PREFIX_FORMATTING_OPTIONS),
plugin.getConfiguration().get(ConfigKeys.SUFFIX_FORMATTING_OPTIONS)
);
}
if (excludedGroups == null) {
@ -490,7 +493,7 @@ public abstract class PermissionHolder {
if (!n.shouldApplyOnWorld(world, context.isIncludeGlobalWorld(), false)) continue;
if (!n.shouldApplyWithContext(contexts.getContextSet(), false)) continue;
holder.accumulateNode(n);
holder.accumulateNode(ln);
}
Set<Node> parents = all.stream()

View File

@ -22,6 +22,7 @@
package me.lucko.luckperms.sponge;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import com.google.common.base.Splitter;
@ -45,7 +46,10 @@ import java.util.stream.Collectors;
@RequiredArgsConstructor
public class SpongeConfig extends AbstractConfiguration {
@Getter
private final LPSpongePlugin plugin;
private ConfigurationNode root;
@SuppressWarnings("ResultOfMethodCallIgnored")

View File

@ -84,6 +84,43 @@ group-weight {
# +------------------------------------------------------------------------+ #
# | Meta Formatting & Stacking | #
# +------------------------------------------------------------------------+ #
# Allows you to setup prefix/suffix stacking options.
#
# Available formats:
# - highest
# - lowest
# - highest_own
# - lowest_own
# - highest_on_track_<track>
# - lowest_on_track_<track>
#
# Each element is added in the order listed.
meta-formatting {
prefix {
format = [
"highest"
]
start-spacer=""
middle-spacer=" "
end-spacer=""
}
suffix {
format = [
"highest"
]
start-spacer=""
middle-spacer=" "
end-spacer=""
}
}
# +------------------------------------------------------------------------+ #
# | Storage | #
# +------------------------------------------------------------------------+ #