More improvements for Option GUI.

* Fix missing options from claim tab.
* Fix '/claimlist' showing claims to non-trusted users.
* Fix setOptionValue return result.
* Fix wrong version in 'plugin.yml'.
* Force local weather change to player on toggle.
* Add missing fr_FR translations.
This commit is contained in:
bloodshot 2019-12-31 04:00:25 -05:00
parent dde267d997
commit 091106308b
14 changed files with 204 additions and 302 deletions

View File

@ -39,6 +39,7 @@
import com.griefdefender.api.claim.ClaimContexts;
import com.griefdefender.api.permission.Context;
import com.griefdefender.api.permission.ContextKeys;
import com.griefdefender.api.permission.PermissionResult;
import com.griefdefender.api.permission.option.Option;
import com.griefdefender.api.permission.option.Options;
import com.griefdefender.api.permission.option.type.CreateModeType;
@ -53,6 +54,7 @@
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.event.GDCauseStackManager;
import com.griefdefender.internal.pagination.PaginationList;
import com.griefdefender.listener.CommonEntityEventHandler;
import com.griefdefender.permission.GDPermissionHolder;
import com.griefdefender.permission.GDPermissionUser;
import com.griefdefender.permission.GDPermissions;
@ -369,10 +371,17 @@ protected void showOptionPermissions(GDPermissionUser src, GDClaim claim, MenuTy
}
}
if (displayType == MenuType.DEFAULT) {
if (displayType == MenuType.DEFAULT || displayType == MenuType.CLAIM) {
final Set<Context> contexts = new HashSet<>();
contexts.add(ClaimContexts.GLOBAL_DEFAULT_CONTEXT);
for (Option option : OptionRegistryModule.getInstance().getAll()) {
if (option.isGlobal() && displayType == MenuType.CLAIM) {
continue;
}
// commands are special-cased as they use a List and cannot show up with no data
if (option == Options.PLAYER_COMMAND_ENTER || option == Options.PLAYER_COMMAND_EXIT) {
continue;
}
boolean found = false;
for (Entry<String, OptionData> optionEntry : filteredContextMap.entrySet()) {
if (optionEntry.getValue().option == option) {
@ -381,16 +390,11 @@ protected void showOptionPermissions(GDPermissionUser src, GDClaim claim, MenuTy
}
}
if (!found) {
filteredContextMap.put(option.getPermission(), new OptionData(option, "undefined", displayType, contexts));
filteredContextMap.put(option.getPermission(), new OptionData(option, option.getDefaultValue().toString(), MenuType.DEFAULT, contexts));
}
}
}
if (displayType == MenuType.CLAIM) {
final Set<Context> contexts = new HashSet<>();
contexts.add(ClaimContexts.GLOBAL_DEFAULT_CONTEXT);
filteredContextMap.put(Options.PVP.getPermission(), new OptionData(Options.PVP, "undefined", MenuType.DEFAULT, contexts));
}
for (Map.Entry<Set<Context>, Map<String, String>> mapEntry : PermissionUtil.getInstance().getPermanentOptions(this.subject).entrySet()) {
final Set<Context> contextSet = mapEntry.getKey();
if (contextSet.contains(ClaimContexts.GLOBAL_DEFAULT_CONTEXT)) {
@ -437,6 +441,10 @@ protected void showOptionPermissions(GDPermissionUser src, GDClaim claim, MenuTy
if (option.getName().contains("tax") && !GriefDefenderPlugin.getGlobalConfig().getConfig().claim.bankTaxSystem) {
continue;
}
if (option.isGlobal() && displayType == MenuType.CLAIM) {
continue;
}
for (OptionContextHolder optionHolder : optionData.optionContextMap.values()) {
if (displayType != MenuType.CLAIM && optionHolder.getType() != displayType) {
continue;
@ -560,11 +568,7 @@ private Component getClickableOptionComponent(GDPermissionUser src, GDClaim clai
}
}
boolean customContexts = UIHelper.containsCustomContext(contexts);
// special case
if (option == Options.PLAYER_COMMAND_ENTER || option == Options.PLAYER_COMMAND_EXIT) {
customContexts = true;
}
boolean customContexts = this.containsCustomContext(option, contexts);
Component optionContexts = UIHelper.getFriendlyContextString(claim, contexts);
String currentValue = optionHolder.getValue();
TextColor color = optionHolder.getColor();
@ -657,15 +661,6 @@ private void appendContexts(TextComponent.Builder builder, Set<Context> contexts
}
}
private boolean containsDefaultContext(Set<Context> contexts) {
for (Context context : contexts) {
if (context.getKey().contains("gd_claim_default")) {
return true;
}
}
return false;
}
private ClickEvent createClickEvent(Player src, Option option) {
return ClickEvent.suggestCommand("/gd option " + option.getName() + " ");
}
@ -787,7 +782,7 @@ private Consumer<CommandSender> newOptionValueConsumer(GDPermissionUser src, GDC
}
Set<Context> newContexts = new HashSet<>();
final boolean isCustom = UIHelper.containsCustomContext(contexts);
final boolean isCustom = this.containsCustomContext(option, contexts);
if (!isCustom && displayType == MenuType.CLAIM) {
newContexts.add(claim.getContext());
} else {
@ -803,7 +798,12 @@ private Consumer<CommandSender> newOptionValueConsumer(GDPermissionUser src, GDC
}
}
PermissionUtil.getInstance().setOptionValue(this.subject, option.getPermission(), newValue, newContexts);
final PermissionResult result = PermissionUtil.getInstance().setOptionValue(this.subject, option.getPermission(), newValue, newContexts);
if (result.successful()) {
if (option == Options.PLAYER_WEATHER) {
CommonEntityEventHandler.getInstance().checkPlayerWeather(src, claim, claim, true);
}
}
showOptionPermissions(src, claim, displayType);
};
}
@ -815,84 +815,8 @@ private Consumer<CommandSender> removeOptionValueConsumer(GDPermissionUser src,
};
}
private Consumer<CommandSender> adjustNumberConsumer(GDPermissionUser src, GDClaim claim, Option option, String currentValue, MenuType menuType, Set<Context> contexts) {
return consumer -> {
String newValue = "";
final Set<Context> filteredContexts = applySelectedTypeContext(claim, menuType, contexts);
if (option.getAllowedType().isAssignableFrom(Boolean.class)) {
Boolean value = getMenuTypeValue(TypeToken.of(Boolean.class), currentValue);
if (value == null) {
newValue = "true";
} else if (value) {
newValue = "false";
} else {
newValue = "undefined";
}
PermissionUtil.getInstance().setOptionValue(this.subject, option.getPermission(), newValue, filteredContexts);
}
if (option.getAllowedType().isAssignableFrom(Integer.class)) {
newValue = getMenuTypeValue(TypeToken.of(String.class), currentValue);
if (newValue == null) {
newValue = "undefined";
}
PermissionUtil.getInstance().setOptionValue(this.subject, option.getPermission(), newValue, filteredContexts);
}
showOptionPermissions(src, claim, menuType);
};
}
private Set<Context> applySelectedTypeContext(Claim claim, MenuType menuType, Set<Context> contexts) {
Set<Context> filteredContexts = new HashSet<>(contexts);
for (Context context : contexts) {
if (context.getKey().contains("gd_claim")) {
filteredContexts.remove(context);
}
}
if (menuType == MenuType.DEFAULT) {
filteredContexts.add(ClaimContexts.GLOBAL_DEFAULT_CONTEXT);
}
if (menuType == MenuType.CLAIM) {
filteredContexts.add(claim.getContext());
}
if (menuType == MenuType.OVERRIDE) {
filteredContexts.add(ClaimContexts.GLOBAL_OVERRIDE_CONTEXT);
}
return filteredContexts;
}
private boolean contextsMatch(Set<Context> contexts, Set<Context> newContexts) {
// first filter out gd claim contexts
final Set<Context> filteredContexts = new HashSet<>();
final Set<Context> filteredNewContexts = new HashSet<>();
for (Context context : contexts) {
if (context.getKey().contains("gd_claim")) {
continue;
}
filteredContexts.add(context);
}
for (Context context : newContexts) {
if (context.getKey().contains("gd_claim")) {
continue;
}
filteredNewContexts.add(context);
}
return Objects.hash(filteredContexts) == Objects.hash(filteredNewContexts);
}
private static Set<Context> createClaimContextSet(GDClaim claim, Set<Context> contexts) {
Set<Context> claimContexts = new HashSet<>();
claimContexts.add(claim.getContext());
for (Context context : contexts) {
if (context.getKey().contains("world") || context.getKey().contains("gd_claim")) {
continue;
}
claimContexts.add(context);
}
return claimContexts;
}
private static Component getOptionText(Option option, Set<Context> contexts) {
boolean customContext = UIHelper.containsCustomContext(contexts);
private Component getOptionText(Option option, Set<Context> contexts) {
boolean customContext = this.containsCustomContext(option, contexts);
final Component optionText = TextComponent.builder().color(customContext ? TextColor.YELLOW : TextColor.GREEN).append(option.getName() + " ")
.hoverEvent(HoverEvent.showText(TextComponent.builder()
@ -998,4 +922,29 @@ private Consumer<CommandSender> createClaimOptionConsumer(GDPermissionUser src,
showOptionPermissions(src, claim, optionType);
};
}
private boolean containsCustomContext(Option option, Set<Context> contexts) {
boolean hasClaimContext = false;
for (Context context : contexts) {
if (context.getKey().equals("gd_claim")) {
hasClaimContext = true;
continue;
}
// Options with a claim context is considered custom
if (context.getKey().equals("gd_claim_default") || context.getKey().equals("server")) {
continue;
}
return true;
}
// Always treat double and integer options as custom if not default
if (hasClaimContext) {
if (option.getAllowedType().isAssignableFrom(Double.class) || option.getAllowedType().isAssignableFrom(Integer.class)) {
return true;
}
}
return false;
}
}

View File

@ -581,8 +581,12 @@ public static List<Component> generateClaimTextList(List<Component> claimsTextLi
public static List<Component> generateClaimTextList(List<Component> claimsTextList, Set<Claim> claimList, String worldName, GDPermissionUser user, CommandSender src, Consumer<CommandSender> returnCommand, boolean listChildren, boolean overlap, boolean listCommand) {
if (claimList.size() > 0) {
final Player player = src instanceof Player ? (Player) src : null;
for (Claim playerClaim : claimList) {
GDClaim claim = (GDClaim) playerClaim;
if (player != null && !claim.getData().getEconomyData().isForSale() && !claim.isUserTrusted(player, TrustTypes.ACCESSOR)) {
continue;
}
if (!listCommand && !overlap && !listChildren && claim.isSubdivision() && !claim.getData().getEconomyData().isForSale()) {
continue;
}
@ -658,7 +662,6 @@ public static List<Component> generateClaimTextList(List<Component> claimsTextLi
if (!listChildren) {
childrenTextList = generateClaimTextList(new ArrayList<Component>(), claim.getChildren(true), worldName, user, src, returnCommand, true);
}
final Player player = src instanceof Player ? (Player) src : null;
Component buyClaim = TextComponent.empty();
if (player != null && claim.getEconomyData().isForSale() && claim.getEconomyData().getSalePrice() > -1) {
Component buyInfo = TextComponent.builder()

View File

@ -217,11 +217,11 @@ public boolean onEntityMove(Event event, Location fromLocation, Location toLocat
playerData.inTown = false;
}
if (player != null) {
this.checkPlayerFlight(player, playerData, fromClaim, toClaim);
this.checkPlayerGameMode(player, playerData, fromClaim, toClaim);
this.checkPlayerGodMode(player, playerData, fromClaim, toClaim);
this.checkPlayerWalkSpeed(player, playerData, fromClaim, toClaim);
this.checkPlayerWeather(player, playerData, fromClaim, toClaim);
this.checkPlayerFlight(user, fromClaim, toClaim);
this.checkPlayerGameMode(user, fromClaim, toClaim);
this.checkPlayerGodMode(user, fromClaim, toClaim);
this.checkPlayerWalkSpeed(user, fromClaim, toClaim);
this.checkPlayerWeather(user, fromClaim, toClaim, false);
this.runPlayerCommands(fromClaim, user, false);
this.runPlayerCommands(toClaim, user, true);
}
@ -319,11 +319,11 @@ public boolean onEntityMove(Event event, Location fromLocation, Location toLocat
}
if (player != null) {
this.checkPlayerFlight(player, playerData, fromClaim, toClaim);
this.checkPlayerGameMode(player, playerData, fromClaim, toClaim);
this.checkPlayerGodMode(player, playerData, fromClaim, toClaim);
this.checkPlayerWalkSpeed(player, playerData, fromClaim, toClaim);
this.checkPlayerWeather(player, playerData, fromClaim, toClaim);
this.checkPlayerFlight(user, fromClaim, toClaim);
this.checkPlayerGameMode(user, fromClaim, toClaim);
this.checkPlayerGodMode(user, fromClaim, toClaim);
this.checkPlayerWalkSpeed(user, fromClaim, toClaim);
this.checkPlayerWeather(user, fromClaim, toClaim, false);
this.runPlayerCommands(fromClaim, user, false);
this.runPlayerCommands(toClaim, user, true);
}
@ -404,7 +404,9 @@ private String replacePlaceHolders(GDClaim claim, Player player, String command)
return command;
}
private void checkPlayerFlight(Player player, GDPlayerData playerData, GDClaim fromClaim, GDClaim toClaim) {
private void checkPlayerFlight(GDPermissionUser user, GDClaim fromClaim, GDClaim toClaim) {
final Player player = user.getOnlinePlayer();
final GDPlayerData playerData = user.getInternalPlayerData();
final GameMode gameMode = player.getGameMode();
if (gameMode == GameMode.CREATIVE || gameMode == GameMode.SPECTATOR) {
return;
@ -428,7 +430,9 @@ private void checkPlayerFlight(Player player, GDPlayerData playerData, GDClaim f
}
}
private void checkPlayerGodMode(Player player, GDPlayerData playerData, GDClaim fromClaim, GDClaim toClaim) {
private void checkPlayerGodMode(GDPermissionUser user, GDClaim fromClaim, GDClaim toClaim) {
final Player player = user.getOnlinePlayer();
final GDPlayerData playerData = user.getInternalPlayerData();
final GameMode gameMode = player.getGameMode();
if (gameMode == GameMode.CREATIVE || gameMode == GameMode.SPECTATOR || !player.isInvulnerable()) {
return;
@ -446,11 +450,13 @@ private void checkPlayerGodMode(Player player, GDPlayerData playerData, GDClaim
}
}
private void checkPlayerGameMode(Player player, GDPlayerData playerData, GDClaim fromClaim, GDClaim toClaim) {
private void checkPlayerGameMode(GDPermissionUser user, GDClaim fromClaim, GDClaim toClaim) {
if (fromClaim == toClaim) {
return;
}
final Player player = user.getOnlinePlayer();
final GDPlayerData playerData = user.getInternalPlayerData();
final GameMode currentGameMode = player.getGameMode();
final GameModeType gameModeType = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(GameModeType.class), playerData.getSubject(), Options.PLAYER_GAMEMODE, toClaim);
final boolean bypassOption = player.hasPermission(GDPermissions.BYPASS_OPTION + "." + Options.PLAYER_GAMEMODE.getName().toLowerCase());
@ -466,11 +472,13 @@ private void checkPlayerGameMode(Player player, GDPlayerData playerData, GDClaim
}
}
private void checkPlayerWalkSpeed(Player player, GDPlayerData playerData, GDClaim fromClaim, GDClaim toClaim) {
private void checkPlayerWalkSpeed(GDPermissionUser user, GDClaim fromClaim, GDClaim toClaim) {
if (fromClaim == toClaim) {
return;
}
final Player player = user.getOnlinePlayer();
final GDPlayerData playerData = user.getInternalPlayerData();
final float currentWalkSpeed = player.getWalkSpeed();
final double walkSpeed = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Double.class), playerData.getSubject(), Options.PLAYER_WALK_SPEED, toClaim);
final boolean bypassOption = player.hasPermission(GDPermissions.BYPASS_OPTION + "." + Options.PLAYER_WALK_SPEED.getName().toLowerCase());
@ -485,11 +493,13 @@ private void checkPlayerWalkSpeed(Player player, GDPlayerData playerData, GDClai
}
}
private void checkPlayerWeather(Player player, GDPlayerData playerData, GDClaim fromClaim, GDClaim toClaim) {
if (fromClaim == toClaim) {
public void checkPlayerWeather(GDPermissionUser user, GDClaim fromClaim, GDClaim toClaim, boolean force) {
if (!force && fromClaim == toClaim) {
return;
}
final Player player = user.getOnlinePlayer();
final GDPlayerData playerData = user.getInternalPlayerData();
final WeatherType weatherType = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(WeatherType.class), playerData.getSubject(), Options.PLAYER_WEATHER, toClaim);
if (weatherType != null && weatherType != WeatherTypes.UNDEFINED) {
final org.bukkit.WeatherType currentWeather = player.getPlayerWeather();

View File

@ -87,7 +87,6 @@ public class GDPermissions {
public static final String CLAIM_PVP_OVERRIDE = "griefdefender.user.claim.pvp-override";
public static final String CLAIM_RESIZE = "griefdefender.user.claim.resize";
public static final String CLAIM_SHOW_TUTORIAL = "griefdefender.user.claim.show-tutorial";
public static final String LIST_OTHER_CLAIMS = "griefdefender.user.claim.list.other";
public static final String VISUALIZE_CLAIMS = "griefdefender.user.claim.visualize.base";
public static final String VISUALIZE_CLAIMS_NEARBY = "griefdefender.user.claim.visualize.nearby";
public static final String COMMAND_PLAYER_INFO_BASE = "griefdefender.user.command.info.base";

View File

@ -107,8 +107,6 @@ public int compare(Set<Context> s1, Set<Context> s2) {
private final LuckPerms luckPermsApi;
private final static DefaultDataQueryOrderFunction DEFAULT_DATA_QUERY_ORDER = new DefaultDataQueryOrderFunction();
private final static PermissionResult RESULT_FAILURE = new GDPermissionResult(ResultTypes.FAILURE);
private final static PermissionResult RESULT_SUCCESS = new GDPermissionResult(ResultTypes.SUCCESS);
public LuckPermsProvider() {
this.luckPermsApi = Bukkit.getServicesManager().getRegistration(LuckPerms.class).getProvider();
@ -748,12 +746,12 @@ public PermissionResult setOptionValue(GDPermissionHolder holder, String key, St
ImmutableContextSet set = this.getLPContexts(contexts).immutableCopy();
final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder);
if (permissionHolder == null) {
return RESULT_FAILURE;
new GDPermissionResult(ResultTypes.FAILURE);
}
final Option option = OptionRegistryModule.getInstance().getById(key).orElse(null);
if (option == null) {
return RESULT_FAILURE;
new GDPermissionResult(ResultTypes.FAILURE);
}
final Node node = MetaNode.builder().key(key).value(value).context(set).build();
@ -765,7 +763,7 @@ public PermissionResult setOptionValue(GDPermissionHolder holder, String key, St
} else {
this.clearMeta(permissionHolder, key, set);
this.savePermissionHolder(permissionHolder);
return RESULT_SUCCESS;
return new GDPermissionResult(ResultTypes.SUCCESS);
}
if (result != null) {
if (result.wasSuccessful()) {
@ -775,7 +773,7 @@ public PermissionResult setOptionValue(GDPermissionHolder holder, String key, St
return new GDPermissionResult(ResultTypes.FAILURE, TextComponent.builder().append(result.name()).build());
}
return RESULT_FAILURE;
return new GDPermissionResult(ResultTypes.FAILURE);
}
public PermissionResult setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set<Context> contexts, boolean save) {
@ -784,7 +782,7 @@ public PermissionResult setPermissionValue(GDPermissionHolder holder, String per
final Node node = this.luckPermsApi.getNodeBuilderRegistry().forPermission().permission(permission).value(value.asBoolean()).context(set).build();
final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder);
if (permissionHolder == null) {
return RESULT_FAILURE;
return new GDPermissionResult(ResultTypes.FAILURE);
}
if (value == Tristate.UNDEFINED) {

View File

@ -424,12 +424,12 @@ GriefDefender {
mode-nature="&aPrêt pour restaurer la protection ! Clique-droit sur un bloc pour restaurer, et utilises &f/modebasic&c pour arrêter."
mode-subdivision="&aMode Sous-divions. Utilises la pelle pour créer une sous-division dans ta protection existante. Utilises &f/modebasic&a pour sortir."
mode-town="&aMode création de Village activé."
option-apply-player-deny-flight="&cYou do not have access to fly in this claim and have been teleported to a safe spot on ground."
option-apply-player-deny-godmode="&cYou do not have access to use god mode in this claim."
option-apply-player-gamemode="&aYour gamemode has been changed to &6{gamemode}&a."
option-apply-player-walk-speed="&aYour walk speed has been changed to &6{speed}&a."
option-apply-player-weather="&aYour local weather has been changed to &6{weather}&a."
option-apply-spawn-limit="&cThis claim has reached the &a{type}&c spawn limit of &6{limit}&c and can no longer spawn any more."
option-apply-player-deny-flight="&cTu n'as pas accès au vol dans ce terrain et tu as été téléporté sur une zone sécurisé au sol."
option-apply-player-deny-godmode="&cTu n'as pas accès au mode Dieu dans ce terrain."
option-apply-player-gamemode="&aTon mode de jeu a été changé à &6{gamemode}&a."
option-apply-player-walk-speed="&aTa vitesse de marche a été changée à &6{speed}&a."
option-apply-player-weather="&aLa météo local a été changée à &6{weather}&a."
option-apply-spawn-limit="&cCe terrain a atteint la limite &6{limit}&c d'apparition de &a{type}&c et ne peu plus en faire apparaitre plus."
option-description-abandon-delay="&aLe nombre de jours avant qu'une nouvelle protection créée puisse être abandonnée."
option-description-abandon-return-ratio="&aLa portion de bloc de protection basique rendu au joueur quand une protection est abandonnée."
option-description-blocks-accrued-per-hour="&aBlocs gagnés par heure.\n&dNote&f: Regarde /playerinfo pour plus d'informations."
@ -449,8 +449,8 @@ GriefDefender {
option-description-min-size-x="&aLa taille minimum de blocs l'axe x peut être."
option-description-min-size-y="&aLa taille minimum de blocs l'axe y peut être."
option-description-min-size-z="&aLa taille minimum de blocs l'axe z peut être."
option-description-player-command-enter="&aUsed for executing a command with specific contexts when a player enters a claim."
option-description-player-command-exit="&aUsed for executing a command with specific contexts when a player exits a claim."
option-description-player-command-enter="&aUtilisé pour exécuter une commande avec un contexte spécifique quand un joueur entre dans un terrain."
option-description-player-command-exit="&aUtilisé pour exécuter une commande avec un contexte spécifique quand un joueur sort d'un terrain."
option-description-player-deny-flight="&aUtilisé pour déterminer si un joueur est incapable de fly dans une protection.\n&dNote&f: Cela ne donne pas l'abilité de fly au joueur, ça supprime juste l'abilité si elle a été donnée. Cela donne la meilleurs compatibilité avec les plugins."
option-description-player-deny-godmode="&aUtilisé pour déterminer si un joueur est incapable de godmode dans une protection.\n&dNote&f: Cela ne donne pas l'abilité de godmode au joueur, ça supprime juste l'abilité si elle a été donnée. Cela donne la meilleurs compatibilité avec les plugins."
option-description-player-deny-hunger="&aUtilisé pour refuser la famine dans une protection.\n&dNote&f: Cela ne donne pas l'abilité de gagner de la famine au joueur, ça supprime l'abilité de cause de la famine si défini. Cela donne la meilleurs compatibilité avec les plugins."
@ -458,16 +458,16 @@ GriefDefender {
option-description-player-health-regen="&aUtilisé pour définir le nombre de vies régénérée pour un joueur dans la protection.\n&dNote&f: Si le joueur a la vie au maximum, cela n'aura pas d'effet. \n&dNote&f: Une valeur de&6-1&f désactive cette option."
option-description-player-keep-inventory="&aUtilisé pour déterminer si un joueur à le droit de garder son inventaire après la mort dans une protection."
option-description-player-keep-level="&aUtilisé pour déterminer si un joueur à le droit de garder son niveau après la mort dans une protection."
option-description-player-teleport-delay="&aUsed to determine the delay before teleporting a player to a new location."
option-description-player-teleport-delay="&aUtilisé pour déterminer le délai avant de téléporter un joueur à une nouvelle location."
option-description-player-walk-speed="&aUtilisé pour définir la vitesse de marche dans une protection.\n&dNote&f: Une valeur de &6-1&f désactive cette option."
option-description-player-weather="&aUtilisé pour définir la météo d'un joueur dans une protection."
option-description-pvp="&aUsed to determine if players can combat each other."
option-description-pvp-combat-command="&aUsed to determine if a player can use commands during PvP combat."
option-description-pvp-combat-teleport="&aUsed to determine if a player can teleport during PvP combat."
option-description-pvp-combat-timeout="&aUsed to determine how many seconds PvP combat is considered to continue after the most recent damage."
option-description-pvp="&aUtilisé pour déterminer si les joueurs peuvent se battrent."
option-description-pvp-combat-command="&aUtilisé pour déterminer si un joueur peut utiliser des commandes en combat PvP."
option-description-pvp-combat-teleport="&aUtilisé pour déterminer si un joueur peut se téléporter en combat PvP."
option-description-pvp-combat-timeout="&aUtilisé pour déterminer combien de secondes dure un combat après le dommage le plus récent."
option-description-radius-inspect="&aLe rayon de recherche pour les protections à proximité lors de l'inspection."
option-description-radius-list="&aLe rayon en blocs utilisés pour lister les protections à proximité."
option-description-spawn-limit="&aUsed to determine the spawn limit for a specific set of contexts in a claim."
option-description-spawn-limit="&aUtilisé pour déterminé la limite d'apparition pour une liste spécifique de contexte."
option-description-tax-expiration="&aNombre de jour après ne pas avoir payé les taxes avant que la protection soi mise en demeure.\n&dNote&f: Une mise en demeure signifie que tu n'auras plus accès à la construction ou l'intération avec la protection jusqu'au paiement des taxes."
option-description-tax-expiration-days-keep="&aNombre de jour pour garder une protection basique mise en demeure et avant expiration.\n&dNote&f: Lors de l'expiration, une protection peut soit être restaurée à son état d'origine ou supprimée. Cela dépend de la configuration du serveur. Contacte un administrateur pour plus d'informations."
option-description-tax-rate="&aLe taux de taxe de la protection.\n&dNote&f: Le taux de taxe est calculé par le nombre de blocs de protection dans les protections basiques."
@ -478,7 +478,7 @@ GriefDefender {
option-not-set="{option}&f est actuellement non définit.\n&dNote&f: La valeur par défaut {value}&f de l'option sera active jusqu'à définition."
option-override-not-supported="&cProtection de type {type}&c ne supporte pas les options outrepassantes."
option-player-deny-flight="&cTu n'as pas accès au fly dans cette protection et a été téléporté dans une zone sécurisée au sol."
option-requires-contexts="&cThis option requres contexts '&a{contexts}&c' to be set."
option-requires-contexts="&cCette option a besoin que le contexte '&a{contexts}&c' soi défini."
option-reset-success="&aOption de la protection remises par défaut avec succès."
option-set-target="&aDéfinis {type}&a de l'option &b{option}&a à {value}&a avec le contexte &7{contexts}&a sur la cible &6{target}&a."
option-ui-click-toggle="Clique ici pour changer la valeur de {option}&f."
@ -511,9 +511,9 @@ GriefDefender {
permission-cuboid="&cTu n'as pas la permission pour créer/redimensionner les protections basiques en mode 3D."
permission-edit-claim="&cTu n'as pas la permission pour éditer cette protection."
permission-fire-spread="&cTu n'as pas la permission pour propager le feu dans cette protection."
permission-flag-arg="&cYou don't have permission to use the flag command with arguments."
permission-flag-arg="&cTu n'as pas la permission pour utiliser cette commande drapeau avec argument."
permission-flag-defaults="&cTu n'as pas la permission pour gérer les flags par défaut."
permission-flag-gui="&cYou don't have permission to use the flag GUI."
permission-flag-gui="&cTu n'as pas la permission pour utiliser ce drapeau dans le GUI."
permission-flag-overrides="&cTu n'as pas la permission pour gérer les flags outrepassant."
permission-flag-use="&cTu n'as pas la permission pour utiliser ce flag."
permission-flow-liquid="&cTu n'as pas la permission pour faire couler le liquide dans cette protection."
@ -570,7 +570,7 @@ GriefDefender {
plugin-not-found="&cImpossible de localiser le plug-in avec l'id &b{id}&c."
plugin-reload="&aGriefDefender a été rechargé."
pvp-claim-not-allowed="&aTu n'as pas le droit de PvP dans cette protection."
pvp-in-combat-not-allowed="&aYou cannot perform this action while in PvP combat. You must stay out of combat for &6{time-remaining}&a more seconds."
pvp-in-combat-not-allowed="&aTu ne peux pas effectuer cette action en combat. Tu dois rester en dehors d'un combat pour encore &6{time-remaining}&a secondes."
pvp-source-not-allowed="&aTu n'as pas le droit de PvP."
pvp-target-not-allowed="&aTu ne peut pas attaquer les joueurs qui ne participent pas au PvP."
registry-block-not-found="&cLe bloc {id} ne peut pas être trouvé dans le registre."

View File

@ -3,5 +3,5 @@ main: com.griefdefender.GDBootstrap
softdepend: [dynmap, PlaceholderAPI, WorldEdit, WorldGuard, Vault]
depend: [LuckPerms]
load: STARTUP
version: '1.2.3'
version: '1.2.4'
api-version: 1.13

View File

@ -39,6 +39,7 @@
import com.griefdefender.api.claim.ClaimContexts;
import com.griefdefender.api.permission.Context;
import com.griefdefender.api.permission.ContextKeys;
import com.griefdefender.api.permission.PermissionResult;
import com.griefdefender.api.permission.option.Option;
import com.griefdefender.api.permission.option.Options;
import com.griefdefender.api.permission.option.type.CreateModeType;
@ -53,6 +54,7 @@
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.event.GDCauseStackManager;
import com.griefdefender.internal.pagination.PaginationList;
import com.griefdefender.listener.CommonEntityEventHandler;
import com.griefdefender.permission.GDPermissionHolder;
import com.griefdefender.permission.GDPermissionUser;
import com.griefdefender.permission.GDPermissions;
@ -369,10 +371,17 @@ protected void showOptionPermissions(GDPermissionUser src, GDClaim claim, MenuTy
}
}
if (displayType == MenuType.DEFAULT) {
if (displayType == MenuType.DEFAULT || displayType == MenuType.CLAIM) {
final Set<Context> contexts = new HashSet<>();
contexts.add(ClaimContexts.GLOBAL_DEFAULT_CONTEXT);
for (Option option : OptionRegistryModule.getInstance().getAll()) {
if (option.isGlobal() && displayType == MenuType.CLAIM) {
continue;
}
// commands are special-cased as they use a List and cannot show up with no data
if (option == Options.PLAYER_COMMAND_ENTER || option == Options.PLAYER_COMMAND_EXIT) {
continue;
}
boolean found = false;
for (Entry<String, OptionData> optionEntry : filteredContextMap.entrySet()) {
if (optionEntry.getValue().option == option) {
@ -381,16 +390,11 @@ protected void showOptionPermissions(GDPermissionUser src, GDClaim claim, MenuTy
}
}
if (!found) {
filteredContextMap.put(option.getPermission(), new OptionData(option, "undefined", displayType, contexts));
filteredContextMap.put(option.getPermission(), new OptionData(option, option.getDefaultValue().toString(), MenuType.DEFAULT, contexts));
}
}
}
if (displayType == MenuType.CLAIM) {
final Set<Context> contexts = new HashSet<>();
contexts.add(ClaimContexts.GLOBAL_DEFAULT_CONTEXT);
filteredContextMap.put(Options.PVP.getPermission(), new OptionData(Options.PVP, "undefined", MenuType.DEFAULT, contexts));
}
for (Map.Entry<Set<Context>, Map<String, String>> mapEntry : PermissionUtil.getInstance().getPermanentOptions(this.subject).entrySet()) {
final Set<Context> contextSet = mapEntry.getKey();
if (contextSet.contains(ClaimContexts.GLOBAL_DEFAULT_CONTEXT)) {
@ -437,6 +441,10 @@ protected void showOptionPermissions(GDPermissionUser src, GDClaim claim, MenuTy
if (option.getName().contains("tax") && !GriefDefenderPlugin.getGlobalConfig().getConfig().claim.bankTaxSystem) {
continue;
}
if (option.isGlobal() && displayType == MenuType.CLAIM) {
continue;
}
for (OptionContextHolder optionHolder : optionData.optionContextMap.values()) {
if (displayType != MenuType.CLAIM && optionHolder.getType() != displayType) {
continue;
@ -560,11 +568,7 @@ private Component getClickableOptionComponent(GDPermissionUser src, GDClaim clai
}
}
boolean customContexts = UIHelper.containsCustomContext(contexts);
// special case
if (option == Options.PLAYER_COMMAND_ENTER || option == Options.PLAYER_COMMAND_EXIT) {
customContexts = true;
}
boolean customContexts = this.containsCustomContext(option, contexts);
Component optionContexts = UIHelper.getFriendlyContextString(claim, contexts);
String currentValue = optionHolder.getValue();
TextColor color = optionHolder.getColor();
@ -657,15 +661,6 @@ private void appendContexts(TextComponent.Builder builder, Set<Context> contexts
}
}
private boolean containsDefaultContext(Set<Context> contexts) {
for (Context context : contexts) {
if (context.getKey().contains("gd_claim_default")) {
return true;
}
}
return false;
}
private ClickEvent createClickEvent(Player src, Option option) {
return ClickEvent.suggestCommand("/gd option " + option.getName() + " ");
}
@ -787,7 +782,7 @@ private Consumer<CommandSource> newOptionValueConsumer(GDPermissionUser src, GDC
}
Set<Context> newContexts = new HashSet<>();
final boolean isCustom = UIHelper.containsCustomContext(contexts);
final boolean isCustom = this.containsCustomContext(option, contexts);
if (!isCustom && displayType == MenuType.CLAIM) {
newContexts.add(claim.getContext());
} else {
@ -803,7 +798,12 @@ private Consumer<CommandSource> newOptionValueConsumer(GDPermissionUser src, GDC
}
}
PermissionUtil.getInstance().setOptionValue(this.subject, option.getPermission(), newValue, newContexts);
final PermissionResult result = PermissionUtil.getInstance().setOptionValue(this.subject, option.getPermission(), newValue, newContexts);
if (result.successful()) {
if (option == Options.PLAYER_WEATHER) {
CommonEntityEventHandler.getInstance().checkPlayerWeather(src, claim, claim, true);
}
}
showOptionPermissions(src, claim, displayType);
};
}
@ -815,84 +815,8 @@ private Consumer<CommandSource> removeOptionValueConsumer(GDPermissionUser src,
};
}
private Consumer<CommandSource> adjustNumberConsumer(GDPermissionUser src, GDClaim claim, Option option, String currentValue, MenuType menuType, Set<Context> contexts) {
return consumer -> {
String newValue = "";
final Set<Context> filteredContexts = applySelectedTypeContext(claim, menuType, contexts);
if (option.getAllowedType().isAssignableFrom(Boolean.class)) {
Boolean value = getMenuTypeValue(TypeToken.of(Boolean.class), currentValue);
if (value == null) {
newValue = "true";
} else if (value) {
newValue = "false";
} else {
newValue = "undefined";
}
PermissionUtil.getInstance().setOptionValue(this.subject, option.getPermission(), newValue, filteredContexts);
}
if (option.getAllowedType().isAssignableFrom(Integer.class)) {
newValue = getMenuTypeValue(TypeToken.of(String.class), currentValue);
if (newValue == null) {
newValue = "undefined";
}
PermissionUtil.getInstance().setOptionValue(this.subject, option.getPermission(), newValue, filteredContexts);
}
showOptionPermissions(src, claim, menuType);
};
}
private Set<Context> applySelectedTypeContext(Claim claim, MenuType menuType, Set<Context> contexts) {
Set<Context> filteredContexts = new HashSet<>(contexts);
for (Context context : contexts) {
if (context.getKey().contains("gd_claim")) {
filteredContexts.remove(context);
}
}
if (menuType == MenuType.DEFAULT) {
filteredContexts.add(ClaimContexts.GLOBAL_DEFAULT_CONTEXT);
}
if (menuType == MenuType.CLAIM) {
filteredContexts.add(claim.getContext());
}
if (menuType == MenuType.OVERRIDE) {
filteredContexts.add(ClaimContexts.GLOBAL_OVERRIDE_CONTEXT);
}
return filteredContexts;
}
private boolean contextsMatch(Set<Context> contexts, Set<Context> newContexts) {
// first filter out gd claim contexts
final Set<Context> filteredContexts = new HashSet<>();
final Set<Context> filteredNewContexts = new HashSet<>();
for (Context context : contexts) {
if (context.getKey().contains("gd_claim")) {
continue;
}
filteredContexts.add(context);
}
for (Context context : newContexts) {
if (context.getKey().contains("gd_claim")) {
continue;
}
filteredNewContexts.add(context);
}
return Objects.hash(filteredContexts) == Objects.hash(filteredNewContexts);
}
private static Set<Context> createClaimContextSet(GDClaim claim, Set<Context> contexts) {
Set<Context> claimContexts = new HashSet<>();
claimContexts.add(claim.getContext());
for (Context context : contexts) {
if (context.getKey().contains("world") || context.getKey().contains("gd_claim")) {
continue;
}
claimContexts.add(context);
}
return claimContexts;
}
private static Component getOptionText(Option option, Set<Context> contexts) {
boolean customContext = UIHelper.containsCustomContext(contexts);
private Component getOptionText(Option option, Set<Context> contexts) {
boolean customContext = this.containsCustomContext(option, contexts);
final Component optionText = TextComponent.builder().color(customContext ? TextColor.YELLOW : TextColor.GREEN).append(option.getName() + " ")
.hoverEvent(HoverEvent.showText(TextComponent.builder()
@ -998,4 +922,29 @@ private Consumer<CommandSource> createClaimOptionConsumer(GDPermissionUser src,
showOptionPermissions(src, claim, optionType);
};
}
private boolean containsCustomContext(Option option, Set<Context> contexts) {
boolean hasClaimContext = false;
for (Context context : contexts) {
if (context.getKey().equals("gd_claim")) {
hasClaimContext = true;
continue;
}
// Options with a claim context is considered custom
if (context.getKey().equals("gd_claim_default") || context.getKey().equals("server")) {
continue;
}
return true;
}
// Always treat double and integer options as custom if not default
if (hasClaimContext) {
if (option.getAllowedType().isAssignableFrom(Double.class) || option.getAllowedType().isAssignableFrom(Integer.class)) {
return true;
}
}
return false;
}
}

View File

@ -550,8 +550,7 @@ public static void showClaims(CommandSource src, Set<Claim> claims, int height,
public static void showClaims(CommandSource src, Set<Claim> claims, int height, boolean visualizeClaims, boolean overlap) {
final String worldName = src instanceof Player ? ((Player) src).getWorld().getName() : Sponge.getServer().getDefaultWorldName();
final boolean canListOthers = src.hasPermission(GDPermissions.LIST_OTHER_CLAIMS);
List<Component> claimsTextList = generateClaimTextList(new ArrayList<Component>(), claims, worldName, null, src, createShowClaimsConsumer(src, claims, height, visualizeClaims), canListOthers, false, overlap);
List<Component> claimsTextList = generateClaimTextList(new ArrayList<Component>(), claims, worldName, null, src, createShowClaimsConsumer(src, claims, height, visualizeClaims), true, false, overlap);
if (visualizeClaims && src instanceof Player) {
Player player = (Player) src;
@ -591,8 +590,12 @@ public static List<Component> generateClaimTextList(List<Component> claimsTextLi
public static List<Component> generateClaimTextList(List<Component> claimsTextList, Set<Claim> claimList, String worldName, GDPermissionUser user, CommandSource src, Consumer<CommandSource> returnCommand, boolean listChildren, boolean overlap, boolean listCommand) {
if (claimList.size() > 0) {
final Player player = src instanceof Player ? (Player) src : null;
for (Claim playerClaim : claimList) {
GDClaim claim = (GDClaim) playerClaim;
if (player != null && !claim.getData().getEconomyData().isForSale() && !claim.isUserTrusted(player, TrustTypes.ACCESSOR)) {
continue;
}
if (!listCommand && !overlap && !listChildren && claim.isSubdivision() && !claim.getData().getEconomyData().isForSale()) {
continue;
}
@ -668,7 +671,6 @@ public static List<Component> generateClaimTextList(List<Component> claimsTextLi
if (!listChildren) {
childrenTextList = generateClaimTextList(new ArrayList<Component>(), claim.getChildren(true), worldName, user, src, returnCommand, true);
}
final Player player = src instanceof Player ? (Player) src : null;
Component buyClaim = TextComponent.empty();
if (player != null && claim.getEconomyData().isForSale() && claim.getEconomyData().getSalePrice() > -1) {
Component buyInfo = TextComponent.builder()

View File

@ -277,7 +277,7 @@ public boolean onEntityMove(MoveEntityEvent event, Location<World> fromLocation,
this.checkPlayerGameMode(user, fromClaim, toClaim);
this.checkPlayerGodMode(user, fromClaim, toClaim);
this.checkPlayerWalkSpeed(user, fromClaim, toClaim);
this.checkPlayerWeather(user, fromClaim, toClaim);
this.checkPlayerWeather(user, fromClaim, toClaim, false);
this.runPlayerCommands(fromClaim, user, false);
this.runPlayerCommands(toClaim, user, true);
}
@ -364,15 +364,13 @@ public boolean onEntityMove(MoveEntityEvent event, Location<World> fromLocation,
}
if (player != null) {
if (player != null) {
this.checkPlayerFlight(user, fromClaim, toClaim);
this.checkPlayerGameMode(user, fromClaim, toClaim);
this.checkPlayerGodMode(user, fromClaim, toClaim);
this.checkPlayerWalkSpeed(user, fromClaim, toClaim);
this.checkPlayerWeather(user, fromClaim, toClaim);
this.runPlayerCommands(fromClaim, user, false);
this.runPlayerCommands(toClaim, user, true);
}
this.checkPlayerFlight(user, fromClaim, toClaim);
this.checkPlayerGameMode(user, fromClaim, toClaim);
this.checkPlayerGodMode(user, fromClaim, toClaim);
this.checkPlayerWalkSpeed(user, fromClaim, toClaim);
this.checkPlayerWeather(user, fromClaim, toClaim, false);
this.runPlayerCommands(fromClaim, user, false);
this.runPlayerCommands(toClaim, user, true);
}
}
}
@ -465,7 +463,7 @@ private void checkPlayerFlight(GDPermissionUser user, GDClaim fromClaim, GDClaim
}
final Boolean noFly = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Boolean.class), playerData.getSubject(), Options.PLAYER_DENY_FLIGHT, toClaim);
final boolean adminFly = player.hasPermission(GDPermissions.BYPASS_OPTION);
final boolean adminFly = player.hasPermission(GDPermissions.BYPASS_OPTION + "." + Options.PLAYER_DENY_FLIGHT.getName().toLowerCase());
final boolean ownerFly = toClaim.isBasicClaim() ? player.hasPermission(GDPermissions.USER_OPTION_PERK_OWNER_FLY_BASIC) : toClaim.isTown() ? player.hasPermission(GDPermissions.USER_OPTION_PERK_OWNER_FLY_TOWN) : false;
if (player.getUniqueId().equals(toClaim.getOwnerUniqueId()) && ownerFly) {
return;
@ -540,29 +538,21 @@ private void checkPlayerWalkSpeed(GDPermissionUser user, GDClaim fromClaim, GDCl
}
}
private void checkPlayerWeather(GDPermissionUser user, GDClaim fromClaim, GDClaim toClaim) {
if (fromClaim == toClaim) {
public void checkPlayerWeather(GDPermissionUser user, GDClaim fromClaim, GDClaim toClaim, boolean force) {
if (!force && fromClaim == toClaim) {
return;
}
final Player player = user.getOnlinePlayer();
final GDPlayerData playerData = user.getInternalPlayerData();
final WeatherType weatherType = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(WeatherType.class), playerData.getSubject(), Options.PLAYER_WEATHER, toClaim);
final boolean bypassOption = player.hasPermission(GDPermissions.BYPASS_OPTION + "." + Options.PLAYER_WEATHER.getName().toLowerCase());
if (false && bypassOption) {
return;
}
if (weatherType != null && weatherType != WeatherTypes.UNDEFINED) {
if (weatherType != null) {
final Weather currentWeather = player.getWorld().getWeather();
final Weather newWeather = PlayerUtil.WEATHERTYPE_MAP.get(weatherType);
if (currentWeather != newWeather) {
PlayerUtil.getInstance().setPlayerWeather(user, weatherType);
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.OPTION_APPLY_PLAYER_WEATHER,
ImmutableMap.of(
"weather", weatherType.getName().toUpperCase()));
GriefDefenderPlugin.sendMessage(player, message);
}
PlayerUtil.getInstance().setPlayerWeather(user, weatherType);
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.OPTION_APPLY_PLAYER_WEATHER,
ImmutableMap.of(
"weather", weatherType == WeatherTypes.UNDEFINED ? currentWeather.getName().toUpperCase() : weatherType.getName().toUpperCase()));
GriefDefenderPlugin.sendMessage(player, message);
} else {
final WeatherType currentWeather = playerData.lastWeatherType;
PlayerUtil.getInstance().resetPlayerWeather(user);

View File

@ -87,7 +87,6 @@ public class GDPermissions {
public static final String CLAIM_PVP_OVERRIDE = "griefdefender.user.claim.pvp-override";
public static final String CLAIM_RESIZE = "griefdefender.user.claim.resize";
public static final String CLAIM_SHOW_TUTORIAL = "griefdefender.user.claim.show-tutorial";
public static final String LIST_OTHER_CLAIMS = "griefdefender.user.claim.list.other";
public static final String VISUALIZE_CLAIMS = "griefdefender.user.claim.visualize.base";
public static final String VISUALIZE_CLAIMS_NEARBY = "griefdefender.user.claim.visualize.nearby";
public static final String COMMAND_PLAYER_INFO_BASE = "griefdefender.user.command.info.base";

View File

@ -107,8 +107,6 @@ public int compare(Set<Context> s1, Set<Context> s2) {
private final LuckPerms luckPermsApi;
private final static DefaultDataQueryOrderFunction DEFAULT_DATA_QUERY_ORDER = new DefaultDataQueryOrderFunction();
private final static PermissionResult RESULT_FAILURE = new GDPermissionResult(ResultTypes.FAILURE);
private final static PermissionResult RESULT_SUCCESS = new GDPermissionResult(ResultTypes.SUCCESS);
public LuckPermsProvider() {
final ProviderRegistration<LuckPerms> service = Sponge.getServiceManager().getRegistration(LuckPerms.class).orElse(null);
@ -744,12 +742,12 @@ public PermissionResult setOptionValue(GDPermissionHolder holder, String key, St
ImmutableContextSet set = this.getLPContexts(contexts).immutableCopy();
final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder);
if (permissionHolder == null) {
return RESULT_FAILURE;
new GDPermissionResult(ResultTypes.FAILURE);
}
final Option option = OptionRegistryModule.getInstance().getById(key).orElse(null);
if (option == null) {
return RESULT_FAILURE;
new GDPermissionResult(ResultTypes.FAILURE);
}
final Node node = MetaNode.builder().key(key).value(value).context(set).build();
@ -761,7 +759,7 @@ public PermissionResult setOptionValue(GDPermissionHolder holder, String key, St
} else {
this.clearMeta(permissionHolder, key, set);
this.savePermissionHolder(permissionHolder);
return RESULT_SUCCESS;
return new GDPermissionResult(ResultTypes.SUCCESS);
}
if (result != null) {
if (result.wasSuccessful()) {
@ -771,7 +769,7 @@ public PermissionResult setOptionValue(GDPermissionHolder holder, String key, St
return new GDPermissionResult(ResultTypes.FAILURE, TextComponent.builder().append(result.name()).build());
}
return RESULT_FAILURE;
return new GDPermissionResult(ResultTypes.FAILURE);
}
public PermissionResult setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set<Context> contexts, boolean save) {
@ -780,7 +778,7 @@ public PermissionResult setPermissionValue(GDPermissionHolder holder, String per
final Node node = this.luckPermsApi.getNodeBuilderRegistry().forPermission().permission(permission).value(value.asBoolean()).context(set).build();
final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder);
if (permissionHolder == null) {
return RESULT_FAILURE;
return new GDPermissionResult(ResultTypes.FAILURE);
}
if (value == Tristate.UNDEFINED) {

View File

@ -57,6 +57,7 @@
import org.spongepowered.api.item.inventory.ItemStack;
import org.spongepowered.api.service.user.UserStorageService;
import org.spongepowered.api.util.Direction;
import org.spongepowered.api.world.weather.Weather;
import java.util.Optional;
import java.util.UUID;
@ -227,6 +228,10 @@ public int getVisualClaimHeight(GDPlayerData playerData, int height) {
public void setPlayerWeather(GDPermissionUser user, WeatherType type) {
final Player player = user.getOnlinePlayer();
if (type == WeatherTypes.UNDEFINED) {
this.resetPlayerWeather(user);
return;
}
if (type == WeatherTypes.DOWNFALL) {
((EntityPlayerMP) player).connection.sendPacket(new SPacketChangeGameState(2, 0));
} else {

View File

@ -424,12 +424,12 @@ GriefDefender {
mode-nature="&aPrêt pour restaurer la protection ! Clique-droit sur un bloc pour restaurer, et utilises &f/modebasic&c pour arrêter."
mode-subdivision="&aMode Sous-divions. Utilises la pelle pour créer une sous-division dans ta protection existante. Utilises &f/modebasic&a pour sortir."
mode-town="&aMode création de Village activé."
option-apply-player-deny-flight="&cYou do not have access to fly in this claim and have been teleported to a safe spot on ground."
option-apply-player-deny-godmode="&cYou do not have access to use god mode in this claim."
option-apply-player-gamemode="&aYour gamemode has been changed to &6{gamemode}&a."
option-apply-player-walk-speed="&aYour walk speed has been changed to &6{speed}&a."
option-apply-player-weather="&aYour local weather has been changed to &6{weather}&a."
option-apply-spawn-limit="&cThis claim has reached the &a{type}&c spawn limit of &6{limit}&c and can no longer spawn any more."
option-apply-player-deny-flight="&cTu n'as pas accès au vol dans ce terrain et tu as été téléporté sur une zone sécurisé au sol."
option-apply-player-deny-godmode="&cTu n'as pas accès au mode Dieu dans ce terrain."
option-apply-player-gamemode="&aTon mode de jeu a été changé à &6{gamemode}&a."
option-apply-player-walk-speed="&aTa vitesse de marche a été changée à &6{speed}&a."
option-apply-player-weather="&aLa météo local a été changée à &6{weather}&a."
option-apply-spawn-limit="&cCe terrain a atteint la limite &6{limit}&c d'apparition de &a{type}&c et ne peu plus en faire apparaitre plus."
option-description-abandon-delay="&aLe nombre de jours avant qu'une nouvelle protection créée puisse être abandonnée."
option-description-abandon-return-ratio="&aLa portion de bloc de protection basique rendu au joueur quand une protection est abandonnée."
option-description-blocks-accrued-per-hour="&aBlocs gagnés par heure.\n&dNote&f: Regarde /playerinfo pour plus d'informations."
@ -449,8 +449,8 @@ GriefDefender {
option-description-min-size-x="&aLa taille minimum de blocs l'axe x peut être."
option-description-min-size-y="&aLa taille minimum de blocs l'axe y peut être."
option-description-min-size-z="&aLa taille minimum de blocs l'axe z peut être."
option-description-player-command-enter="&aUsed for executing a command with specific contexts when a player enters a claim."
option-description-player-command-exit="&aUsed for executing a command with specific contexts when a player exits a claim."
option-description-player-command-enter="&aUtilisé pour exécuter une commande avec un contexte spécifique quand un joueur entre dans un terrain."
option-description-player-command-exit="&aUtilisé pour exécuter une commande avec un contexte spécifique quand un joueur sort d'un terrain."
option-description-player-deny-flight="&aUtilisé pour déterminer si un joueur est incapable de fly dans une protection.\n&dNote&f: Cela ne donne pas l'abilité de fly au joueur, ça supprime juste l'abilité si elle a été donnée. Cela donne la meilleurs compatibilité avec les plugins."
option-description-player-deny-godmode="&aUtilisé pour déterminer si un joueur est incapable de godmode dans une protection.\n&dNote&f: Cela ne donne pas l'abilité de godmode au joueur, ça supprime juste l'abilité si elle a été donnée. Cela donne la meilleurs compatibilité avec les plugins."
option-description-player-deny-hunger="&aUtilisé pour refuser la famine dans une protection.\n&dNote&f: Cela ne donne pas l'abilité de gagner de la famine au joueur, ça supprime l'abilité de cause de la famine si défini. Cela donne la meilleurs compatibilité avec les plugins."
@ -458,16 +458,16 @@ GriefDefender {
option-description-player-health-regen="&aUtilisé pour définir le nombre de vies régénérée pour un joueur dans la protection.\n&dNote&f: Si le joueur a la vie au maximum, cela n'aura pas d'effet. \n&dNote&f: Une valeur de&6-1&f désactive cette option."
option-description-player-keep-inventory="&aUtilisé pour déterminer si un joueur à le droit de garder son inventaire après la mort dans une protection."
option-description-player-keep-level="&aUtilisé pour déterminer si un joueur à le droit de garder son niveau après la mort dans une protection."
option-description-player-teleport-delay="&aUsed to determine the delay before teleporting a player to a new location."
option-description-player-teleport-delay="&aUtilisé pour déterminer le délai avant de téléporter un joueur à une nouvelle location."
option-description-player-walk-speed="&aUtilisé pour définir la vitesse de marche dans une protection.\n&dNote&f: Une valeur de &6-1&f désactive cette option."
option-description-player-weather="&aUtilisé pour définir la météo d'un joueur dans une protection."
option-description-pvp="&aUsed to determine if players can combat each other."
option-description-pvp-combat-command="&aUsed to determine if a player can use commands during PvP combat."
option-description-pvp-combat-teleport="&aUsed to determine if a player can teleport during PvP combat."
option-description-pvp-combat-timeout="&aUsed to determine how many seconds PvP combat is considered to continue after the most recent damage."
option-description-pvp="&aUtilisé pour déterminer si les joueurs peuvent se battrent."
option-description-pvp-combat-command="&aUtilisé pour déterminer si un joueur peut utiliser des commandes en combat PvP."
option-description-pvp-combat-teleport="&aUtilisé pour déterminer si un joueur peut se téléporter en combat PvP."
option-description-pvp-combat-timeout="&aUtilisé pour déterminer combien de secondes dure un combat après le dommage le plus récent."
option-description-radius-inspect="&aLe rayon de recherche pour les protections à proximité lors de l'inspection."
option-description-radius-list="&aLe rayon en blocs utilisés pour lister les protections à proximité."
option-description-spawn-limit="&aUsed to determine the spawn limit for a specific set of contexts in a claim."
option-description-spawn-limit="&aUtilisé pour déterminé la limite d'apparition pour une liste spécifique de contexte."
option-description-tax-expiration="&aNombre de jour après ne pas avoir payé les taxes avant que la protection soi mise en demeure.\n&dNote&f: Une mise en demeure signifie que tu n'auras plus accès à la construction ou l'intération avec la protection jusqu'au paiement des taxes."
option-description-tax-expiration-days-keep="&aNombre de jour pour garder une protection basique mise en demeure et avant expiration.\n&dNote&f: Lors de l'expiration, une protection peut soit être restaurée à son état d'origine ou supprimée. Cela dépend de la configuration du serveur. Contacte un administrateur pour plus d'informations."
option-description-tax-rate="&aLe taux de taxe de la protection.\n&dNote&f: Le taux de taxe est calculé par le nombre de blocs de protection dans les protections basiques."
@ -478,7 +478,7 @@ GriefDefender {
option-not-set="{option}&f est actuellement non définit.\n&dNote&f: La valeur par défaut {value}&f de l'option sera active jusqu'à définition."
option-override-not-supported="&cProtection de type {type}&c ne supporte pas les options outrepassantes."
option-player-deny-flight="&cTu n'as pas accès au fly dans cette protection et a été téléporté dans une zone sécurisée au sol."
option-requires-contexts="&cThis option requres contexts '&a{contexts}&c' to be set."
option-requires-contexts="&cCette option a besoin que le contexte '&a{contexts}&c' soi défini."
option-reset-success="&aOption de la protection remises par défaut avec succès."
option-set-target="&aDéfinis {type}&a de l'option &b{option}&a à {value}&a avec le contexte &7{contexts}&a sur la cible &6{target}&a."
option-ui-click-toggle="Clique ici pour changer la valeur de {option}&f."
@ -511,9 +511,9 @@ GriefDefender {
permission-cuboid="&cTu n'as pas la permission pour créer/redimensionner les protections basiques en mode 3D."
permission-edit-claim="&cTu n'as pas la permission pour éditer cette protection."
permission-fire-spread="&cTu n'as pas la permission pour propager le feu dans cette protection."
permission-flag-arg="&cYou don't have permission to use the flag command with arguments."
permission-flag-arg="&cTu n'as pas la permission pour utiliser cette commande drapeau avec argument."
permission-flag-defaults="&cTu n'as pas la permission pour gérer les flags par défaut."
permission-flag-gui="&cYou don't have permission to use the flag GUI."
permission-flag-gui="&cTu n'as pas la permission pour utiliser ce drapeau dans le GUI."
permission-flag-overrides="&cTu n'as pas la permission pour gérer les flags outrepassant."
permission-flag-use="&cTu n'as pas la permission pour utiliser ce flag."
permission-flow-liquid="&cTu n'as pas la permission pour faire couler le liquide dans cette protection."
@ -570,7 +570,7 @@ GriefDefender {
plugin-not-found="&cImpossible de localiser le plug-in avec l'id &b{id}&c."
plugin-reload="&aGriefDefender a été rechargé."
pvp-claim-not-allowed="&aTu n'as pas le droit de PvP dans cette protection."
pvp-in-combat-not-allowed="&aYou cannot perform this action while in PvP combat. You must stay out of combat for &6{time-remaining}&a more seconds."
pvp-in-combat-not-allowed="&aTu ne peux pas effectuer cette action en combat. Tu dois rester en dehors d'un combat pour encore &6{time-remaining}&a secondes."
pvp-source-not-allowed="&aTu n'as pas le droit de PvP."
pvp-target-not-allowed="&aTu ne peut pas attaquer les joueurs qui ne participent pas au PvP."
registry-block-not-found="&cLe bloc {id} ne peut pas être trouvé dans le registre."