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.claim.ClaimContexts;
import com.griefdefender.api.permission.Context; import com.griefdefender.api.permission.Context;
import com.griefdefender.api.permission.ContextKeys; 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.Option;
import com.griefdefender.api.permission.option.Options; import com.griefdefender.api.permission.option.Options;
import com.griefdefender.api.permission.option.type.CreateModeType; import com.griefdefender.api.permission.option.type.CreateModeType;
@ -53,6 +54,7 @@
import com.griefdefender.configuration.MessageStorage; import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.event.GDCauseStackManager; import com.griefdefender.event.GDCauseStackManager;
import com.griefdefender.internal.pagination.PaginationList; import com.griefdefender.internal.pagination.PaginationList;
import com.griefdefender.listener.CommonEntityEventHandler;
import com.griefdefender.permission.GDPermissionHolder; import com.griefdefender.permission.GDPermissionHolder;
import com.griefdefender.permission.GDPermissionUser; import com.griefdefender.permission.GDPermissionUser;
import com.griefdefender.permission.GDPermissions; 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<>(); final Set<Context> contexts = new HashSet<>();
contexts.add(ClaimContexts.GLOBAL_DEFAULT_CONTEXT); contexts.add(ClaimContexts.GLOBAL_DEFAULT_CONTEXT);
for (Option option : OptionRegistryModule.getInstance().getAll()) { 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; boolean found = false;
for (Entry<String, OptionData> optionEntry : filteredContextMap.entrySet()) { for (Entry<String, OptionData> optionEntry : filteredContextMap.entrySet()) {
if (optionEntry.getValue().option == option) { if (optionEntry.getValue().option == option) {
@ -381,16 +390,11 @@ protected void showOptionPermissions(GDPermissionUser src, GDClaim claim, MenuTy
} }
} }
if (!found) { 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()) { for (Map.Entry<Set<Context>, Map<String, String>> mapEntry : PermissionUtil.getInstance().getPermanentOptions(this.subject).entrySet()) {
final Set<Context> contextSet = mapEntry.getKey(); final Set<Context> contextSet = mapEntry.getKey();
if (contextSet.contains(ClaimContexts.GLOBAL_DEFAULT_CONTEXT)) { 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) { if (option.getName().contains("tax") && !GriefDefenderPlugin.getGlobalConfig().getConfig().claim.bankTaxSystem) {
continue; continue;
} }
if (option.isGlobal() && displayType == MenuType.CLAIM) {
continue;
}
for (OptionContextHolder optionHolder : optionData.optionContextMap.values()) { for (OptionContextHolder optionHolder : optionData.optionContextMap.values()) {
if (displayType != MenuType.CLAIM && optionHolder.getType() != displayType) { if (displayType != MenuType.CLAIM && optionHolder.getType() != displayType) {
continue; continue;
@ -560,11 +568,7 @@ private Component getClickableOptionComponent(GDPermissionUser src, GDClaim clai
} }
} }
boolean customContexts = UIHelper.containsCustomContext(contexts); boolean customContexts = this.containsCustomContext(option, contexts);
// special case
if (option == Options.PLAYER_COMMAND_ENTER || option == Options.PLAYER_COMMAND_EXIT) {
customContexts = true;
}
Component optionContexts = UIHelper.getFriendlyContextString(claim, contexts); Component optionContexts = UIHelper.getFriendlyContextString(claim, contexts);
String currentValue = optionHolder.getValue(); String currentValue = optionHolder.getValue();
TextColor color = optionHolder.getColor(); 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) { private ClickEvent createClickEvent(Player src, Option option) {
return ClickEvent.suggestCommand("/gd option " + option.getName() + " "); return ClickEvent.suggestCommand("/gd option " + option.getName() + " ");
} }
@ -787,7 +782,7 @@ private Consumer<CommandSender> newOptionValueConsumer(GDPermissionUser src, GDC
} }
Set<Context> newContexts = new HashSet<>(); Set<Context> newContexts = new HashSet<>();
final boolean isCustom = UIHelper.containsCustomContext(contexts); final boolean isCustom = this.containsCustomContext(option, contexts);
if (!isCustom && displayType == MenuType.CLAIM) { if (!isCustom && displayType == MenuType.CLAIM) {
newContexts.add(claim.getContext()); newContexts.add(claim.getContext());
} else { } 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); 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) { private Component getOptionText(Option option, Set<Context> contexts) {
return consumer -> { boolean customContext = this.containsCustomContext(option, contexts);
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);
final Component optionText = TextComponent.builder().color(customContext ? TextColor.YELLOW : TextColor.GREEN).append(option.getName() + " ") final Component optionText = TextComponent.builder().color(customContext ? TextColor.YELLOW : TextColor.GREEN).append(option.getName() + " ")
.hoverEvent(HoverEvent.showText(TextComponent.builder() .hoverEvent(HoverEvent.showText(TextComponent.builder()
@ -998,4 +922,29 @@ private Consumer<CommandSender> createClaimOptionConsumer(GDPermissionUser src,
showOptionPermissions(src, claim, optionType); 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) { 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) { if (claimList.size() > 0) {
final Player player = src instanceof Player ? (Player) src : null;
for (Claim playerClaim : claimList) { for (Claim playerClaim : claimList) {
GDClaim claim = (GDClaim) playerClaim; 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()) { if (!listCommand && !overlap && !listChildren && claim.isSubdivision() && !claim.getData().getEconomyData().isForSale()) {
continue; continue;
} }
@ -658,7 +662,6 @@ public static List<Component> generateClaimTextList(List<Component> claimsTextLi
if (!listChildren) { if (!listChildren) {
childrenTextList = generateClaimTextList(new ArrayList<Component>(), claim.getChildren(true), worldName, user, src, returnCommand, true); 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(); Component buyClaim = TextComponent.empty();
if (player != null && claim.getEconomyData().isForSale() && claim.getEconomyData().getSalePrice() > -1) { if (player != null && claim.getEconomyData().isForSale() && claim.getEconomyData().getSalePrice() > -1) {
Component buyInfo = TextComponent.builder() Component buyInfo = TextComponent.builder()

View File

@ -217,11 +217,11 @@ public boolean onEntityMove(Event event, Location fromLocation, Location toLocat
playerData.inTown = false; playerData.inTown = false;
} }
if (player != null) { if (player != null) {
this.checkPlayerFlight(player, playerData, fromClaim, toClaim); this.checkPlayerFlight(user, fromClaim, toClaim);
this.checkPlayerGameMode(player, playerData, fromClaim, toClaim); this.checkPlayerGameMode(user, fromClaim, toClaim);
this.checkPlayerGodMode(player, playerData, fromClaim, toClaim); this.checkPlayerGodMode(user, fromClaim, toClaim);
this.checkPlayerWalkSpeed(player, playerData, fromClaim, toClaim); this.checkPlayerWalkSpeed(user, fromClaim, toClaim);
this.checkPlayerWeather(player, playerData, fromClaim, toClaim); this.checkPlayerWeather(user, fromClaim, toClaim, false);
this.runPlayerCommands(fromClaim, user, false); this.runPlayerCommands(fromClaim, user, false);
this.runPlayerCommands(toClaim, user, true); this.runPlayerCommands(toClaim, user, true);
} }
@ -319,11 +319,11 @@ public boolean onEntityMove(Event event, Location fromLocation, Location toLocat
} }
if (player != null) { if (player != null) {
this.checkPlayerFlight(player, playerData, fromClaim, toClaim); this.checkPlayerFlight(user, fromClaim, toClaim);
this.checkPlayerGameMode(player, playerData, fromClaim, toClaim); this.checkPlayerGameMode(user, fromClaim, toClaim);
this.checkPlayerGodMode(player, playerData, fromClaim, toClaim); this.checkPlayerGodMode(user, fromClaim, toClaim);
this.checkPlayerWalkSpeed(player, playerData, fromClaim, toClaim); this.checkPlayerWalkSpeed(user, fromClaim, toClaim);
this.checkPlayerWeather(player, playerData, fromClaim, toClaim); this.checkPlayerWeather(user, fromClaim, toClaim, false);
this.runPlayerCommands(fromClaim, user, false); this.runPlayerCommands(fromClaim, user, false);
this.runPlayerCommands(toClaim, user, true); this.runPlayerCommands(toClaim, user, true);
} }
@ -404,7 +404,9 @@ private String replacePlaceHolders(GDClaim claim, Player player, String command)
return 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(); final GameMode gameMode = player.getGameMode();
if (gameMode == GameMode.CREATIVE || gameMode == GameMode.SPECTATOR) { if (gameMode == GameMode.CREATIVE || gameMode == GameMode.SPECTATOR) {
return; 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(); final GameMode gameMode = player.getGameMode();
if (gameMode == GameMode.CREATIVE || gameMode == GameMode.SPECTATOR || !player.isInvulnerable()) { if (gameMode == GameMode.CREATIVE || gameMode == GameMode.SPECTATOR || !player.isInvulnerable()) {
return; 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) { if (fromClaim == toClaim) {
return; return;
} }
final Player player = user.getOnlinePlayer();
final GDPlayerData playerData = user.getInternalPlayerData();
final GameMode currentGameMode = player.getGameMode(); final GameMode currentGameMode = player.getGameMode();
final GameModeType gameModeType = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(GameModeType.class), playerData.getSubject(), Options.PLAYER_GAMEMODE, toClaim); 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()); 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) { if (fromClaim == toClaim) {
return; return;
} }
final Player player = user.getOnlinePlayer();
final GDPlayerData playerData = user.getInternalPlayerData();
final float currentWalkSpeed = player.getWalkSpeed(); final float currentWalkSpeed = player.getWalkSpeed();
final double walkSpeed = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Double.class), playerData.getSubject(), Options.PLAYER_WALK_SPEED, toClaim); 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()); 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) { public void checkPlayerWeather(GDPermissionUser user, GDClaim fromClaim, GDClaim toClaim, boolean force) {
if (fromClaim == toClaim) { if (!force && fromClaim == toClaim) {
return; 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 WeatherType weatherType = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(WeatherType.class), playerData.getSubject(), Options.PLAYER_WEATHER, toClaim);
if (weatherType != null && weatherType != WeatherTypes.UNDEFINED) { if (weatherType != null && weatherType != WeatherTypes.UNDEFINED) {
final org.bukkit.WeatherType currentWeather = player.getPlayerWeather(); 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_PVP_OVERRIDE = "griefdefender.user.claim.pvp-override";
public static final String CLAIM_RESIZE = "griefdefender.user.claim.resize"; 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 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 = "griefdefender.user.claim.visualize.base";
public static final String VISUALIZE_CLAIMS_NEARBY = "griefdefender.user.claim.visualize.nearby"; 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"; 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 LuckPerms luckPermsApi;
private final static DefaultDataQueryOrderFunction DEFAULT_DATA_QUERY_ORDER = new DefaultDataQueryOrderFunction(); 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() { public LuckPermsProvider() {
this.luckPermsApi = Bukkit.getServicesManager().getRegistration(LuckPerms.class).getProvider(); 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(); ImmutableContextSet set = this.getLPContexts(contexts).immutableCopy();
final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder); final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder);
if (permissionHolder == null) { if (permissionHolder == null) {
return RESULT_FAILURE; new GDPermissionResult(ResultTypes.FAILURE);
} }
final Option option = OptionRegistryModule.getInstance().getById(key).orElse(null); final Option option = OptionRegistryModule.getInstance().getById(key).orElse(null);
if (option == null) { if (option == null) {
return RESULT_FAILURE; new GDPermissionResult(ResultTypes.FAILURE);
} }
final Node node = MetaNode.builder().key(key).value(value).context(set).build(); 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 { } else {
this.clearMeta(permissionHolder, key, set); this.clearMeta(permissionHolder, key, set);
this.savePermissionHolder(permissionHolder); this.savePermissionHolder(permissionHolder);
return RESULT_SUCCESS; return new GDPermissionResult(ResultTypes.SUCCESS);
} }
if (result != null) { if (result != null) {
if (result.wasSuccessful()) { 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 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) { 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 Node node = this.luckPermsApi.getNodeBuilderRegistry().forPermission().permission(permission).value(value.asBoolean()).context(set).build();
final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder); final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder);
if (permissionHolder == null) { if (permissionHolder == null) {
return RESULT_FAILURE; return new GDPermissionResult(ResultTypes.FAILURE);
} }
if (value == Tristate.UNDEFINED) { 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-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-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é." 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-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="&cYou do not have access to use god mode in this claim." option-apply-player-deny-godmode="&cTu n'as pas accès au mode Dieu dans ce terrain."
option-apply-player-gamemode="&aYour gamemode has been changed to &6{gamemode}&a." option-apply-player-gamemode="&aTon mode de jeu a été changé à &6{gamemode}&a."
option-apply-player-walk-speed="&aYour walk speed has been changed to &6{speed}&a." option-apply-player-walk-speed="&aTa vitesse de marche a été changée à &6{speed}&a."
option-apply-player-weather="&aYour local weather has been changed to &6{weather}&a." option-apply-player-weather="&aLa météo local a été changée à &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-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-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-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." 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-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-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-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-enter="&aUtilisé pour exécuter une commande avec un contexte spécifique quand un joueur entre dans un terrain."
option-description-player-command-exit="&aUsed for executing a command with specific contexts when a player exits a claim." 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-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-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." 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-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-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-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-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-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="&aUtilisé pour déterminer si les joueurs peuvent se battrent."
option-description-pvp-combat-command="&aUsed to determine if a player can use commands during PvP combat." option-description-pvp-combat-command="&aUtilisé pour déterminer si un joueur peut utiliser des commandes en combat PvP."
option-description-pvp-combat-teleport="&aUsed to determine if a player can teleport during PvP combat." 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="&aUsed to determine how many seconds PvP combat is considered to continue after the most recent damage." 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-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-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="&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-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." 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-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-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-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-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-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." 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-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-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-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-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-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-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." 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-not-found="&cImpossible de localiser le plug-in avec l'id &b{id}&c."
plugin-reload="&aGriefDefender a été rechargé." plugin-reload="&aGriefDefender a été rechargé."
pvp-claim-not-allowed="&aTu n'as pas le droit de PvP dans cette protection." 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-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." 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." 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] softdepend: [dynmap, PlaceholderAPI, WorldEdit, WorldGuard, Vault]
depend: [LuckPerms] depend: [LuckPerms]
load: STARTUP load: STARTUP
version: '1.2.3' version: '1.2.4'
api-version: 1.13 api-version: 1.13

View File

@ -39,6 +39,7 @@
import com.griefdefender.api.claim.ClaimContexts; import com.griefdefender.api.claim.ClaimContexts;
import com.griefdefender.api.permission.Context; import com.griefdefender.api.permission.Context;
import com.griefdefender.api.permission.ContextKeys; 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.Option;
import com.griefdefender.api.permission.option.Options; import com.griefdefender.api.permission.option.Options;
import com.griefdefender.api.permission.option.type.CreateModeType; import com.griefdefender.api.permission.option.type.CreateModeType;
@ -53,6 +54,7 @@
import com.griefdefender.configuration.MessageStorage; import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.event.GDCauseStackManager; import com.griefdefender.event.GDCauseStackManager;
import com.griefdefender.internal.pagination.PaginationList; import com.griefdefender.internal.pagination.PaginationList;
import com.griefdefender.listener.CommonEntityEventHandler;
import com.griefdefender.permission.GDPermissionHolder; import com.griefdefender.permission.GDPermissionHolder;
import com.griefdefender.permission.GDPermissionUser; import com.griefdefender.permission.GDPermissionUser;
import com.griefdefender.permission.GDPermissions; 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<>(); final Set<Context> contexts = new HashSet<>();
contexts.add(ClaimContexts.GLOBAL_DEFAULT_CONTEXT); contexts.add(ClaimContexts.GLOBAL_DEFAULT_CONTEXT);
for (Option option : OptionRegistryModule.getInstance().getAll()) { 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; boolean found = false;
for (Entry<String, OptionData> optionEntry : filteredContextMap.entrySet()) { for (Entry<String, OptionData> optionEntry : filteredContextMap.entrySet()) {
if (optionEntry.getValue().option == option) { if (optionEntry.getValue().option == option) {
@ -381,16 +390,11 @@ protected void showOptionPermissions(GDPermissionUser src, GDClaim claim, MenuTy
} }
} }
if (!found) { 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()) { for (Map.Entry<Set<Context>, Map<String, String>> mapEntry : PermissionUtil.getInstance().getPermanentOptions(this.subject).entrySet()) {
final Set<Context> contextSet = mapEntry.getKey(); final Set<Context> contextSet = mapEntry.getKey();
if (contextSet.contains(ClaimContexts.GLOBAL_DEFAULT_CONTEXT)) { 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) { if (option.getName().contains("tax") && !GriefDefenderPlugin.getGlobalConfig().getConfig().claim.bankTaxSystem) {
continue; continue;
} }
if (option.isGlobal() && displayType == MenuType.CLAIM) {
continue;
}
for (OptionContextHolder optionHolder : optionData.optionContextMap.values()) { for (OptionContextHolder optionHolder : optionData.optionContextMap.values()) {
if (displayType != MenuType.CLAIM && optionHolder.getType() != displayType) { if (displayType != MenuType.CLAIM && optionHolder.getType() != displayType) {
continue; continue;
@ -560,11 +568,7 @@ private Component getClickableOptionComponent(GDPermissionUser src, GDClaim clai
} }
} }
boolean customContexts = UIHelper.containsCustomContext(contexts); boolean customContexts = this.containsCustomContext(option, contexts);
// special case
if (option == Options.PLAYER_COMMAND_ENTER || option == Options.PLAYER_COMMAND_EXIT) {
customContexts = true;
}
Component optionContexts = UIHelper.getFriendlyContextString(claim, contexts); Component optionContexts = UIHelper.getFriendlyContextString(claim, contexts);
String currentValue = optionHolder.getValue(); String currentValue = optionHolder.getValue();
TextColor color = optionHolder.getColor(); 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) { private ClickEvent createClickEvent(Player src, Option option) {
return ClickEvent.suggestCommand("/gd option " + option.getName() + " "); return ClickEvent.suggestCommand("/gd option " + option.getName() + " ");
} }
@ -787,7 +782,7 @@ private Consumer<CommandSource> newOptionValueConsumer(GDPermissionUser src, GDC
} }
Set<Context> newContexts = new HashSet<>(); Set<Context> newContexts = new HashSet<>();
final boolean isCustom = UIHelper.containsCustomContext(contexts); final boolean isCustom = this.containsCustomContext(option, contexts);
if (!isCustom && displayType == MenuType.CLAIM) { if (!isCustom && displayType == MenuType.CLAIM) {
newContexts.add(claim.getContext()); newContexts.add(claim.getContext());
} else { } 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); 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) { private Component getOptionText(Option option, Set<Context> contexts) {
return consumer -> { boolean customContext = this.containsCustomContext(option, contexts);
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);
final Component optionText = TextComponent.builder().color(customContext ? TextColor.YELLOW : TextColor.GREEN).append(option.getName() + " ") final Component optionText = TextComponent.builder().color(customContext ? TextColor.YELLOW : TextColor.GREEN).append(option.getName() + " ")
.hoverEvent(HoverEvent.showText(TextComponent.builder() .hoverEvent(HoverEvent.showText(TextComponent.builder()
@ -998,4 +922,29 @@ private Consumer<CommandSource> createClaimOptionConsumer(GDPermissionUser src,
showOptionPermissions(src, claim, optionType); 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) { 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 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), true, false, overlap);
List<Component> claimsTextList = generateClaimTextList(new ArrayList<Component>(), claims, worldName, null, src, createShowClaimsConsumer(src, claims, height, visualizeClaims), canListOthers, false, overlap);
if (visualizeClaims && src instanceof Player) { if (visualizeClaims && src instanceof Player) {
Player player = (Player) src; 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) { 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) { if (claimList.size() > 0) {
final Player player = src instanceof Player ? (Player) src : null;
for (Claim playerClaim : claimList) { for (Claim playerClaim : claimList) {
GDClaim claim = (GDClaim) playerClaim; 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()) { if (!listCommand && !overlap && !listChildren && claim.isSubdivision() && !claim.getData().getEconomyData().isForSale()) {
continue; continue;
} }
@ -668,7 +671,6 @@ public static List<Component> generateClaimTextList(List<Component> claimsTextLi
if (!listChildren) { if (!listChildren) {
childrenTextList = generateClaimTextList(new ArrayList<Component>(), claim.getChildren(true), worldName, user, src, returnCommand, true); 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(); Component buyClaim = TextComponent.empty();
if (player != null && claim.getEconomyData().isForSale() && claim.getEconomyData().getSalePrice() > -1) { if (player != null && claim.getEconomyData().isForSale() && claim.getEconomyData().getSalePrice() > -1) {
Component buyInfo = TextComponent.builder() Component buyInfo = TextComponent.builder()

View File

@ -277,7 +277,7 @@ public boolean onEntityMove(MoveEntityEvent event, Location<World> fromLocation,
this.checkPlayerGameMode(user, fromClaim, toClaim); this.checkPlayerGameMode(user, fromClaim, toClaim);
this.checkPlayerGodMode(user, fromClaim, toClaim); this.checkPlayerGodMode(user, fromClaim, toClaim);
this.checkPlayerWalkSpeed(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(fromClaim, user, false);
this.runPlayerCommands(toClaim, user, true); this.runPlayerCommands(toClaim, user, true);
} }
@ -363,19 +363,17 @@ public boolean onEntityMove(MoveEntityEvent event, Location<World> fromLocation,
user.getInternalPlayerData().inTown = false; user.getInternalPlayerData().inTown = false;
} }
if (player != null) {
if (player != null) { if (player != null) {
this.checkPlayerFlight(user, fromClaim, toClaim); this.checkPlayerFlight(user, fromClaim, toClaim);
this.checkPlayerGameMode(user, fromClaim, toClaim); this.checkPlayerGameMode(user, fromClaim, toClaim);
this.checkPlayerGodMode(user, fromClaim, toClaim); this.checkPlayerGodMode(user, fromClaim, toClaim);
this.checkPlayerWalkSpeed(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(fromClaim, user, false);
this.runPlayerCommands(toClaim, user, true); this.runPlayerCommands(toClaim, user, true);
} }
} }
} }
}
GDTimings.ENTITY_MOVE_EVENT.stopTimingIfSync(); GDTimings.ENTITY_MOVE_EVENT.stopTimingIfSync();
return true; return 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 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; 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) { if (player.getUniqueId().equals(toClaim.getOwnerUniqueId()) && ownerFly) {
return; return;
@ -540,29 +538,21 @@ private void checkPlayerWalkSpeed(GDPermissionUser user, GDClaim fromClaim, GDCl
} }
} }
private void checkPlayerWeather(GDPermissionUser user, GDClaim fromClaim, GDClaim toClaim) { public void checkPlayerWeather(GDPermissionUser user, GDClaim fromClaim, GDClaim toClaim, boolean force) {
if (fromClaim == toClaim) { if (!force && fromClaim == toClaim) {
return; return;
} }
final Player player = user.getOnlinePlayer(); final Player player = user.getOnlinePlayer();
final GDPlayerData playerData = user.getInternalPlayerData(); final GDPlayerData playerData = user.getInternalPlayerData();
final WeatherType weatherType = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(WeatherType.class), playerData.getSubject(), Options.PLAYER_WEATHER, toClaim); 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 (weatherType != null) {
if (false && bypassOption) {
return;
}
if (weatherType != null && weatherType != WeatherTypes.UNDEFINED) {
final Weather currentWeather = player.getWorld().getWeather(); final Weather currentWeather = player.getWorld().getWeather();
final Weather newWeather = PlayerUtil.WEATHERTYPE_MAP.get(weatherType);
if (currentWeather != newWeather) {
PlayerUtil.getInstance().setPlayerWeather(user, weatherType); PlayerUtil.getInstance().setPlayerWeather(user, weatherType);
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.OPTION_APPLY_PLAYER_WEATHER, final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.OPTION_APPLY_PLAYER_WEATHER,
ImmutableMap.of( ImmutableMap.of(
"weather", weatherType.getName().toUpperCase())); "weather", weatherType == WeatherTypes.UNDEFINED ? currentWeather.getName().toUpperCase() : weatherType.getName().toUpperCase()));
GriefDefenderPlugin.sendMessage(player, message); GriefDefenderPlugin.sendMessage(player, message);
}
} else { } else {
final WeatherType currentWeather = playerData.lastWeatherType; final WeatherType currentWeather = playerData.lastWeatherType;
PlayerUtil.getInstance().resetPlayerWeather(user); 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_PVP_OVERRIDE = "griefdefender.user.claim.pvp-override";
public static final String CLAIM_RESIZE = "griefdefender.user.claim.resize"; 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 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 = "griefdefender.user.claim.visualize.base";
public static final String VISUALIZE_CLAIMS_NEARBY = "griefdefender.user.claim.visualize.nearby"; 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"; 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 LuckPerms luckPermsApi;
private final static DefaultDataQueryOrderFunction DEFAULT_DATA_QUERY_ORDER = new DefaultDataQueryOrderFunction(); 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() { public LuckPermsProvider() {
final ProviderRegistration<LuckPerms> service = Sponge.getServiceManager().getRegistration(LuckPerms.class).orElse(null); 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(); ImmutableContextSet set = this.getLPContexts(contexts).immutableCopy();
final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder); final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder);
if (permissionHolder == null) { if (permissionHolder == null) {
return RESULT_FAILURE; new GDPermissionResult(ResultTypes.FAILURE);
} }
final Option option = OptionRegistryModule.getInstance().getById(key).orElse(null); final Option option = OptionRegistryModule.getInstance().getById(key).orElse(null);
if (option == null) { if (option == null) {
return RESULT_FAILURE; new GDPermissionResult(ResultTypes.FAILURE);
} }
final Node node = MetaNode.builder().key(key).value(value).context(set).build(); 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 { } else {
this.clearMeta(permissionHolder, key, set); this.clearMeta(permissionHolder, key, set);
this.savePermissionHolder(permissionHolder); this.savePermissionHolder(permissionHolder);
return RESULT_SUCCESS; return new GDPermissionResult(ResultTypes.SUCCESS);
} }
if (result != null) { if (result != null) {
if (result.wasSuccessful()) { 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 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) { 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 Node node = this.luckPermsApi.getNodeBuilderRegistry().forPermission().permission(permission).value(value.asBoolean()).context(set).build();
final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder); final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder);
if (permissionHolder == null) { if (permissionHolder == null) {
return RESULT_FAILURE; return new GDPermissionResult(ResultTypes.FAILURE);
} }
if (value == Tristate.UNDEFINED) { if (value == Tristate.UNDEFINED) {

View File

@ -57,6 +57,7 @@
import org.spongepowered.api.item.inventory.ItemStack; import org.spongepowered.api.item.inventory.ItemStack;
import org.spongepowered.api.service.user.UserStorageService; import org.spongepowered.api.service.user.UserStorageService;
import org.spongepowered.api.util.Direction; import org.spongepowered.api.util.Direction;
import org.spongepowered.api.world.weather.Weather;
import java.util.Optional; import java.util.Optional;
import java.util.UUID; import java.util.UUID;
@ -227,6 +228,10 @@ public int getVisualClaimHeight(GDPlayerData playerData, int height) {
public void setPlayerWeather(GDPermissionUser user, WeatherType type) { public void setPlayerWeather(GDPermissionUser user, WeatherType type) {
final Player player = user.getOnlinePlayer(); final Player player = user.getOnlinePlayer();
if (type == WeatherTypes.UNDEFINED) {
this.resetPlayerWeather(user);
return;
}
if (type == WeatherTypes.DOWNFALL) { if (type == WeatherTypes.DOWNFALL) {
((EntityPlayerMP) player).connection.sendPacket(new SPacketChangeGameState(2, 0)); ((EntityPlayerMP) player).connection.sendPacket(new SPacketChangeGameState(2, 0));
} else { } 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-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-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é." 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-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="&cYou do not have access to use god mode in this claim." option-apply-player-deny-godmode="&cTu n'as pas accès au mode Dieu dans ce terrain."
option-apply-player-gamemode="&aYour gamemode has been changed to &6{gamemode}&a." option-apply-player-gamemode="&aTon mode de jeu a été changé à &6{gamemode}&a."
option-apply-player-walk-speed="&aYour walk speed has been changed to &6{speed}&a." option-apply-player-walk-speed="&aTa vitesse de marche a été changée à &6{speed}&a."
option-apply-player-weather="&aYour local weather has been changed to &6{weather}&a." option-apply-player-weather="&aLa météo local a été changée à &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-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-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-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." 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-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-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-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-enter="&aUtilisé pour exécuter une commande avec un contexte spécifique quand un joueur entre dans un terrain."
option-description-player-command-exit="&aUsed for executing a command with specific contexts when a player exits a claim." 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-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-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." 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-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-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-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-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-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="&aUtilisé pour déterminer si les joueurs peuvent se battrent."
option-description-pvp-combat-command="&aUsed to determine if a player can use commands during PvP combat." option-description-pvp-combat-command="&aUtilisé pour déterminer si un joueur peut utiliser des commandes en combat PvP."
option-description-pvp-combat-teleport="&aUsed to determine if a player can teleport during PvP combat." 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="&aUsed to determine how many seconds PvP combat is considered to continue after the most recent damage." 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-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-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="&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-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." 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-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-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-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-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-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." 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-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-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-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-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-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-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." 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-not-found="&cImpossible de localiser le plug-in avec l'id &b{id}&c."
plugin-reload="&aGriefDefender a été rechargé." plugin-reload="&aGriefDefender a été rechargé."
pvp-claim-not-allowed="&aTu n'as pas le droit de PvP dans cette protection." 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-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." 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." registry-block-not-found="&cLe bloc {id} ne peut pas être trouvé dans le registre."