Added Tab Completer, with perms cache

This commit is contained in:
Sn0wStorm 2020-11-24 12:48:43 +01:00
parent e2d27641af
commit 211833a188
8 changed files with 304 additions and 62 deletions

View File

@ -13,14 +13,15 @@ Also see [Wiki](https://github.com/DieReicheErethons/Brewery/wiki) | [Releases]
```XML
<repository>
<id>brewery-repo</id>
<url>https://zebradrive.de/maven/</url>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
<dependency>
<groupId>com.de</groupId>
<groupId>com.github.DieReicheErethons</groupId>
<artifactId>Brewery</artifactId>
<version>2.1.2</version>
<version>2.1.3</version>
<scope>provided</scope>
</dependency>
```
_For older maven releases see [here](https://github.com/DieReicheErethons/Brewery/blob/v2.1.2/README.md)_

20
pom.xml
View File

@ -89,13 +89,14 @@
<url>http://maven.sk89q.com/repo/</url>
</repository>
<repository>
<!-- GriefPrevention, SlimeFun, Towny -->
<!-- GriefPrevention, SlimeFun, Towny, Brewery -->
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
<repository>
<id>brewery-repo</id>
<url>https://zebradrive.de/maven/</url>
<!-- LWC Extended -->
<id>ender-repo</id>
<url>https://ci.ender.zone/plugin/repository/everything/</url>
</repository>
<repository>
<id>chestshop-repo</id>
@ -190,9 +191,9 @@
</exclusions>
</dependency>
<dependency>
<groupId>com.griefcraft</groupId>
<artifactId>entitylwc</artifactId>
<version>2.1</version>
<groupId>com.griefcraft.lwc</groupId>
<artifactId>LWCX</artifactId>
<version>2.2.6</version>
<scope>provided</scope>
</dependency>
<dependency>
@ -263,11 +264,4 @@
<scope>compile</scope>
</dependency>
</dependencies>
<distributionManagement>
<repository>
<id>file-repo</id>
<url>file:///var/tmp/MavenRepo</url>
</repository>
</distributionManagement>
</project>

View File

@ -215,6 +215,9 @@ public class P extends JavaPlugin {
// Reload Cauldron Particle Recipes
BCauldron.reload();
// Clear Recipe completions
TabListener.reload();
// Reload Recipes
boolean successful = true;
for (Brew brew : Brew.legacyPotions.values()) {

View File

@ -7,6 +7,7 @@ import com.dre.brewery.recipe.BRecipe;
import com.dre.brewery.recipe.Ingredient;
import com.dre.brewery.recipe.RecipeItem;
import com.dre.brewery.utility.BUtil;
import com.dre.brewery.utility.PermissionUtil;
import com.dre.brewery.utility.Tuple;
import org.bukkit.Material;
import org.bukkit.command.Command;
@ -22,6 +23,8 @@ import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Locale;
import static com.dre.brewery.utility.PermissionUtil.BPermission.*;
public class CommandListener implements CommandExecutor {
public P p = P.p;
@ -194,46 +197,51 @@ public class CommandListener implements CommandExecutor {
ArrayList<String> cmds = new ArrayList<>();
cmds.add(p.languageReader.get("Help_Help"));
PermissionUtil.evaluateExtendedPermissions(sender);
if (sender.hasPermission("brewery.cmd.player")) {
if (PLAYER.checkCached(sender)) {
cmds.add (p.languageReader.get("Help_Player"));
}
if (sender.hasPermission("brewery.cmd.info")) {
if (INFO.checkCached(sender)) {
cmds.add (p.languageReader.get("Help_Info"));
}
if (P.use1_13 && sender.hasPermission("brewery.cmd.seal")) {
if (P.use1_13 && SEAL.checkCached(sender)) {
cmds.add (p.languageReader.get("Help_Seal"));
}
if (sender.hasPermission("brewery.cmd.unlabel")) {
if (UNLABEL.checkCached(sender)) {
cmds.add (p.languageReader.get("Help_UnLabel"));
}
if (sender.hasPermission("brewery.cmd.infoOther")) {
if (PermissionUtil.noExtendedPermissions(sender)) {
return cmds;
}
if (INFO_OTHER.checkCached(sender)) {
cmds.add (p.languageReader.get("Help_InfoOther"));
}
if (sender.hasPermission("brewery.cmd.create")) {
if (CREATE.checkCached(sender)) {
cmds.add(p.languageReader.get("Help_Create"));
cmds.add(p.languageReader.get("Help_Give"));
}
if (sender.hasPermission("brewery.cmd.drink") || sender.hasPermission("brewery.cmd.drinkOther")) {
if (DRINK.checkCached(sender) || DRINK_OTHER.checkCached(sender)) {
cmds.add(p.languageReader.get("Help_Drink"));
}
if (sender.hasPermission("brewery.cmd.reload")) {
if (RELOAD.checkCached(sender)) {
cmds.add(p.languageReader.get("Help_Configname"));
cmds.add(p.languageReader.get("Help_Reload"));
}
if (sender.hasPermission("brewery.cmd.puke") || sender.hasPermission("brewery.cmd.pukeOther")) {
if (PUKE.checkCached(sender) || PUKE_OTHER.checkCached(sender)) {
cmds.add(p.languageReader.get("Help_Puke"));
}
if (sender.hasPermission("brewery.cmd.wakeup")) {
if (WAKEUP.checkCached(sender)) {
cmds.add(p.languageReader.get("Help_Wakeup"));
cmds.add(p.languageReader.get("Help_WakeupList"));
cmds.add(p.languageReader.get("Help_WakeupCheck"));
@ -242,15 +250,15 @@ public class CommandListener implements CommandExecutor {
cmds.add(p.languageReader.get("Help_WakeupRemove"));
}
if (sender.hasPermission("brewery.cmd.static")) {
if (STATIC.checkCached(sender)) {
cmds.add(p.languageReader.get("Help_Static"));
}
if (sender.hasPermission("brewery.cmd.copy")) {
if (COPY.checkCached(sender)) {
cmds.add (p.languageReader.get("Help_Copy"));
}
if (sender.hasPermission("brewery.cmd.delete")) {
if (DELETE.checkCached(sender)) {
cmds.add (p.languageReader.get("Help_Delete"));
}

View File

@ -4,6 +4,7 @@ import com.dre.brewery.*;
import com.dre.brewery.filedata.BConfig;
import com.dre.brewery.filedata.UpdateChecker;
import com.dre.brewery.utility.LegacyUtil;
import com.dre.brewery.utility.PermissionUtil;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.block.Block;
@ -256,6 +257,7 @@ public class PlayerListener implements Listener {
if (bplayer != null) {
bplayer.disconnecting();
}
PermissionUtil.logout(event.getPlayer());
}
@EventHandler
@ -264,5 +266,6 @@ public class PlayerListener implements Listener {
if (bplayer != null) {
bplayer.disconnecting();
}
PermissionUtil.logout(event.getPlayer());
}
}

View File

@ -1,47 +1,153 @@
package com.dre.brewery.listeners;
import com.dre.brewery.recipe.BRecipe;
import com.dre.brewery.utility.PermissionUtil;
import com.dre.brewery.utility.Tuple;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static com.dre.brewery.utility.PermissionUtil.BPermission.DRINK;
import static com.dre.brewery.utility.PermissionUtil.BPermission.WAKEUP;
public class TabListener implements TabCompleter {
private static final Map<String, List<String>> completions = new HashMap<>();
private static final List<String> topCompletions = new ArrayList<>(2);
private static final String[] COMPLETIONS = {"unLabel", "help"};
private static final String[] EXT_COMPLETIONS = {"info", "create", "reload", "drink", "itemName", "seal", "static", "puke", "wakeup"};
static {
completions.put("", Arrays.asList("info", "unlabel", "help"));
topCompletions.add("brew");
//topCompletions.add("brewery");
}
private static final String[] QUALITY = {"1", "10"};
private static Set<Tuple<String, String>> mainSet;
private static Set<Tuple<String, String>> altSet;
@Override
public List<String> onTabComplete(CommandSender commandSender, Command cmd, String command, String[] args) {
if (args.length == 0) {
return topCompletions;
} else if (args.length == 1) {
for (Map.Entry<String, List<String>> entry : completions.entrySet()) {
List<String> list = new ArrayList<>();
for (String comp : entry.getValue()) {
if (comp.startsWith(args[0])) {
list.add(comp);
}
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command cmd, @NotNull String command, String[] args) {
if (args.length < 1) {
return null;
}
if (args.length == 1) {
List<String> commands;
if (PermissionUtil.noExtendedPermissions(sender)) {
commands = filterWithInput(COMPLETIONS, args[0]);
} else {
Stream<String> filteredCompletionsStream = Arrays.stream(COMPLETIONS)
.filter(s -> s.startsWith(args[0]));
Stream<String> filteredExtendedCompletionsStream = Arrays.stream(EXT_COMPLETIONS)
.filter(s -> s.startsWith(args[0]));
commands = Stream.concat(filteredCompletionsStream, filteredExtendedCompletionsStream)
.collect(Collectors.toList());
}
if (commands.isEmpty()) {
return null; // Player List
} else {
return commands;
}
} else if (args.length == 2) {
if (args[0].equalsIgnoreCase("wakeup")) {
if (WAKEUP.checkCached(sender)) {
return tabWakeup(args[1]);
}
if (list.isEmpty()) {
return null;
}
return list;
}
}
if (args[0].equalsIgnoreCase("create") || args[0].equalsIgnoreCase("drink")) {
if (DRINK.checkCached(sender)) {
return tabCreateAndDrink(args);
}
}
return null;
}
private static final String[] WAK = {"list", "add", "check", "remove", "cancel"};
public List<String> tabWakeup(String input) {
return filterWithInput(WAK, input);
}
public List<String> tabCreateAndDrink(String[] args) {
if (args.length == 2) {
if (mainSet == null) {
mainSet = new HashSet<>();
altSet = new HashSet<>();
for (BRecipe recipe : BRecipe.getAllRecipes()) {
mainSet.addAll(createLookupFromName(recipe.getName(5)));
Set<String> altNames = new HashSet<>(3);
altNames.add(recipe.getName(1));
altNames.add(recipe.getName(10));
if (recipe.getOptionalID().isPresent()) {
altNames.add(recipe.getOptionalID().get());
}
for (String altName : altNames) {
altSet.addAll(createLookupFromName(altName));
}
}
}
final String input = args[1].toLowerCase();
List<String> options = mainSet.stream()
.filter(s -> s.a().startsWith(input))
.map(Tuple::second)
.collect(Collectors.toList());
if (options.isEmpty()) {
options = altSet.stream()
.filter(s -> s.a().startsWith(input))
.map(Tuple::second)
.collect(Collectors.toList());
}
return options;
} else {
if (args[args.length - 2].matches("\\d")) {
// Player list
return null;
} else {
return filterWithInput(QUALITY, args[args.length - 1]);
}
}
}
private static List<Tuple<String, String>> createLookupFromName(final String name) {
return Arrays.stream(name.split(" "))
.map(word -> new Tuple<>(word.toLowerCase(), name))
.collect(Collectors.toList());
}
public static List<String> filterWithInput(String[] options, String input) {
return Arrays.stream(options)
.filter(s -> s.startsWith(input))
.collect(Collectors.toList());
}
public static List<String> filterWithInput(Collection<String> options, String input) {
return options.stream()
.filter(s -> s.startsWith(input))
.collect(Collectors.toList());
}
public static void reload() {
mainSet = null;
altSet = null;
}
}

View File

@ -19,6 +19,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
/**
@ -416,13 +417,15 @@ public class BRecipe {
}
public void applyDrinkFeatures(Player player, int quality) {
if (playercmds != null && !playercmds.isEmpty()) {
for (String cmd : getPlayercmdsForQuality(quality)) {
List<String> playerCmdsForQuality = getPlayercmdsForQuality(quality);
if (playerCmdsForQuality != null) {
for (String cmd : playerCmdsForQuality) {
player.performCommand(BUtil.applyPlaceholders(cmd, player.getName(), quality));
}
}
if (servercmds != null && !servercmds.isEmpty()) {
for (String cmd : getServercmdsForQuality(quality)) {
List<String> serverCmdsForQuality = getServercmdsForQuality(quality);
if (serverCmdsForQuality != null) {
for (String cmd : serverCmdsForQuality) {
P.p.getServer().dispatchCommand(P.p.getServer().getConsoleSender(), BUtil.applyPlaceholders(cmd, player.getName(), quality));
}
}
@ -544,9 +547,8 @@ public class BRecipe {
return false;
}
@Nullable
public String getOptionalID() {
return optionalID;
public Optional<String> getOptionalID() {
return Optional.ofNullable(optionalID);
}
public List<RecipeItem> getIngredients() {
@ -773,7 +775,7 @@ public class BRecipe {
}
}
for (BRecipe recipe : recipes) {
if (recipe.getOptionalID().equalsIgnoreCase(name)) {
if (recipe.getOptionalID().isPresent() && recipe.getOptionalID().get().equalsIgnoreCase(name)) {
return recipe;
}
}

View File

@ -0,0 +1,125 @@
package com.dre.brewery.utility;
import com.dre.brewery.P;
import org.bukkit.command.CommandSender;
import java.util.HashMap;
import java.util.Map;
public class PermissionUtil {
public static Map<CommandSender, Boolean> extendedPermsCache = new HashMap<>();
public static void logout(CommandSender sender) {
extendedPermsCache.remove(sender);
}
/**
* Update the Permission Cache, sets it to false if the sender
* currently doesn't have any more than the default permission
*
* @param sender The sender of which to update the permission cache
*/
public static void evaluateExtendedPermissions(CommandSender sender) {
for (BPermission perm : BPermission.values()) {
if (perm != BPermission.UNLABEL) { // This is the default permission
if (sender.hasPermission(perm.permission)) {
extendedPermsCache.put(sender, true);
return;
}
}
}
extendedPermsCache.put(sender, false);
}
/**
* Check if the Sender might have more than just the default permissions
*
* @return false if there _might be_ more permissions for this sender
*/
public static boolean noExtendedPermissions(CommandSender sender) {
Boolean extendedPerms = extendedPermsCache.get(sender);
if (extendedPerms == null) {
evaluateExtendedPermissions(sender);
extendedPerms = extendedPermsCache.get(sender);
}
P.p.log("extended Perms for " + sender.getName() + ": " + extendedPerms);
return extendedPerms == null || !extendedPerms;
}
/**
* Returns true if the Sender has the permission, returns false if the cache says he is unlikely to have it
*
* @return true only if the sender definitely has the permission. false if he hasn't or it's unlikely
*/
public static boolean hasCachedPermission(CommandSender sender, String permission) {
BPermission perm = BPermission.get(permission);
if (perm != null) {
return hasCachedPermission(sender, perm);
} else {
return sender.hasPermission(permission);
}
}
/**
* Returns true if the Sender has the permission, returns false if the cache says he is unlikely to have it
*
* @return true only if the sender definitely has the permission. false if he hasn't or it's unlikely
*/
public static boolean hasCachedPermission(CommandSender sender, BPermission bPerm) {
if (bPerm != BPermission.UNLABEL) {
if (noExtendedPermissions(sender)) {
return false;
}
}
return sender.hasPermission(bPerm.permission);
}
/**
* Brewery Permissions of _only_ the Commands
*/
public enum BPermission {
PLAYER("brewery.cmd.player"),
SEAL("brewery.cmd.seal"),
UNLABEL("brewery.cmd.unlabel"),
INFO("brewery.cmd.info"),
INFO_OTHER("brewery.cmd.infoOther"),
CREATE("brewery.cmd.create"),
DRINK("brewery.cmd.drink"),
DRINK_OTHER("brewery.cmd.drinkOther"),
RELOAD("brewery.cmd.reload"),
PUKE("brewery.cmd.puke"),
PUKE_OTHER("brewery.cmd.pukeOther"),
WAKEUP("brewery.cmd.wakeup"),
STATIC("brewery.cmd.static"),
COPY("brewery.cmd.copy"),
DELETE("brewery.cmd.delete");
public String permission;
BPermission(String permission) {
this.permission = permission;
}
public boolean checkCached(CommandSender sender) {
return hasCachedPermission(sender, this);
}
public static BPermission get(String permission) {
for (BPermission bPerm : BPermission.values()) {
if (bPerm.permission.equals(permission)) {
return bPerm;
}
}
return null;
}
}
}