Improve ban system.

* Fix empty text serialization.
* Update adapters for NPE bug fix.
This commit is contained in:
bloodshot 2019-08-24 01:53:13 -04:00
parent c7bed01866
commit 0520c502c9
14 changed files with 112 additions and 55 deletions

View File

@ -704,6 +704,7 @@ public void registerBaseCommands() {
tabList.add("block"); tabList.add("block");
tabList.add("entity"); tabList.add("entity");
tabList.add("item"); tabList.add("item");
tabList.add("hand");
return ImmutableList.copyOf(tabList); return ImmutableList.copyOf(tabList);
}); });
manager.getCommandCompletions().registerCompletion("gdclaimtypes", c -> { manager.getCommandCompletions().registerCompletion("gdclaimtypes", c -> {

View File

@ -46,6 +46,7 @@
import com.griefdefender.internal.registry.ItemTypeRegistryModule; import com.griefdefender.internal.registry.ItemTypeRegistryModule;
import com.griefdefender.permission.GDPermissions; import com.griefdefender.permission.GDPermissions;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
@CommandAlias("%griefdefender") @CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_CLAIM_BAN) @CommandPermission(GDPermissions.COMMAND_CLAIM_BAN)
@ -54,9 +55,9 @@ public class CommandClaimBan extends BaseCommand {
@CommandCompletion("@gdbantypes @gdmcids @gddummy") @CommandCompletion("@gdbantypes @gdmcids @gddummy")
@CommandAlias("claimban") @CommandAlias("claimban")
@Description("Bans target id from all usage.") @Description("Bans target id from all usage.")
@Syntax("<type> <target> [<message>]") @Syntax("hand | <type> <target> [<message>]")
@Subcommand("ban") @Subcommand("ban")
public void execute(Player player, String type, String id, @Optional String message) { public void execute(Player player, String type, @Optional String id, @Optional String message) {
Component component = null; Component component = null;
if (type.equalsIgnoreCase("block")) { if (type.equalsIgnoreCase("block")) {
if (!BlockTypeRegistryModule.getInstance().getById(id).isPresent()) { if (!BlockTypeRegistryModule.getInstance().getById(id).isPresent()) {
@ -103,6 +104,18 @@ public void execute(Player player, String type, String id, @Optional String mess
GriefDefenderPlugin.getGlobalConfig().save(); GriefDefenderPlugin.getGlobalConfig().save();
TextAdapter.sendComponent(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.COMMAND_CLAIMBAN_SUCCESS_ITEM, TextAdapter.sendComponent(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.COMMAND_CLAIMBAN_SUCCESS_ITEM,
ImmutableMap.of("id", TextComponent.of(id, TextColor.LIGHT_PURPLE)))); ImmutableMap.of("id", TextComponent.of(id, TextColor.LIGHT_PURPLE))));
} else if (type.equalsIgnoreCase("hand")) {
final ItemStack itemInHand = player.getItemInHand();
final String handItemId = ItemTypeRegistryModule.getInstance().getNMSKey(itemInHand);
if (message == null) {
component = TextComponent.empty();
} else {
component = LegacyComponentSerializer.legacy().deserialize(message, '&');
}
GriefDefenderPlugin.getGlobalConfig().getConfig().bans.addItemBan(handItemId, component);
GriefDefenderPlugin.getGlobalConfig().save();
TextAdapter.sendComponent(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.COMMAND_CLAIMBAN_SUCCESS_ITEM,
ImmutableMap.of("id", TextComponent.of(handItemId, TextColor.LIGHT_PURPLE))));
} }
if (component == null) { if (component == null) {
TextAdapter.sendComponent(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.COMMAND_INVALID_TYPE, TextAdapter.sendComponent(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.COMMAND_INVALID_TYPE,

View File

@ -32,11 +32,9 @@
import co.aikar.commands.annotation.Optional; import co.aikar.commands.annotation.Optional;
import co.aikar.commands.annotation.Subcommand; import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax; import co.aikar.commands.annotation.Syntax;
import net.kyori.text.Component;
import net.kyori.text.TextComponent; import net.kyori.text.TextComponent;
import net.kyori.text.adapter.bukkit.TextAdapter; import net.kyori.text.adapter.bukkit.TextAdapter;
import net.kyori.text.format.TextColor; import net.kyori.text.format.TextColor;
import net.kyori.text.serializer.legacy.LegacyComponentSerializer;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.griefdefender.GriefDefenderPlugin; import com.griefdefender.GriefDefenderPlugin;
@ -44,8 +42,10 @@
import com.griefdefender.internal.registry.BlockTypeRegistryModule; import com.griefdefender.internal.registry.BlockTypeRegistryModule;
import com.griefdefender.internal.registry.EntityTypeRegistryModule; import com.griefdefender.internal.registry.EntityTypeRegistryModule;
import com.griefdefender.internal.registry.ItemTypeRegistryModule; import com.griefdefender.internal.registry.ItemTypeRegistryModule;
import com.griefdefender.internal.util.NMSUtil;
import com.griefdefender.permission.GDPermissions; import com.griefdefender.permission.GDPermissions;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
@CommandAlias("%griefdefender") @CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_CLAIM_BAN) @CommandPermission(GDPermissions.COMMAND_CLAIM_BAN)
@ -54,9 +54,9 @@ public class CommandClaimUnban extends BaseCommand {
@CommandCompletion("@gdbantypes @gdmcids @gddummy") @CommandCompletion("@gdbantypes @gdmcids @gddummy")
@CommandAlias("claimunban") @CommandAlias("claimunban")
@Description("Unbans target id allowing it to be used again.") @Description("Unbans target id allowing it to be used again.")
@Syntax("<type> <target>") @Syntax("hand | <type> <target>")
@Subcommand("unban") @Subcommand("unban")
public void execute(Player player, String type, String id) { public void execute(Player player, String type, @Optional String id) {
if (type.equalsIgnoreCase("block")) { if (type.equalsIgnoreCase("block")) {
if (!BlockTypeRegistryModule.getInstance().getById(id).isPresent()) { if (!BlockTypeRegistryModule.getInstance().getById(id).isPresent()) {
TextAdapter.sendComponent(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.REGISTRY_BLOCK_NOT_FOUND, TextAdapter.sendComponent(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.REGISTRY_BLOCK_NOT_FOUND,
@ -89,6 +89,13 @@ public void execute(Player player, String type, String id) {
GriefDefenderPlugin.getGlobalConfig().save(); GriefDefenderPlugin.getGlobalConfig().save();
TextAdapter.sendComponent(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.COMMAND_CLAIMUNBAN_SUCCESS_ITEM, TextAdapter.sendComponent(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.COMMAND_CLAIMUNBAN_SUCCESS_ITEM,
ImmutableMap.of("id", TextComponent.of(id, TextColor.LIGHT_PURPLE)))); ImmutableMap.of("id", TextComponent.of(id, TextColor.LIGHT_PURPLE))));
} else if (type.equalsIgnoreCase("hand")) {
final ItemStack itemInHand = player.getItemInHand();
final String handItemId = ItemTypeRegistryModule.getInstance().getNMSKey(itemInHand);
GriefDefenderPlugin.getGlobalConfig().getConfig().bans.removeItemBan(handItemId);
GriefDefenderPlugin.getGlobalConfig().save();
TextAdapter.sendComponent(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.COMMAND_CLAIMUNBAN_SUCCESS_ITEM,
ImmutableMap.of("id", TextComponent.of(handItemId, TextColor.LIGHT_PURPLE))));
} else { } else {
TextAdapter.sendComponent(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.COMMAND_INVALID_TYPE, TextAdapter.sendComponent(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.COMMAND_INVALID_TYPE,
ImmutableMap.of("type", type))); ImmutableMap.of("type", type)));

View File

@ -44,6 +44,18 @@ public class BanCategory extends ConfigCategory {
private Map<String, Component> items = new HashMap<>(); private Map<String, Component> items = new HashMap<>();
public Map<String, Component> getBlockMap() {
return this.blocks;
}
public Map<String, Component> getEntityMap() {
return this.entities;
}
public Map<String, Component> getItemMap() {
return this.items;
}
public boolean isBlockBanned(String id) { public boolean isBlockBanned(String id) {
if (id == null) { if (id == null) {
return false; return false;

View File

@ -77,10 +77,10 @@ public Component deserialize(TypeToken<?> type, ConfigurationNode node) throws O
@Override @Override
public void serialize(TypeToken<?> type, Component obj, ConfigurationNode node) throws ObjectMappingException { public void serialize(TypeToken<?> type, Component obj, ConfigurationNode node) throws ObjectMappingException {
if (obj == TextComponent.empty()) { if (obj == TextComponent.empty()) {
return; node.setValue("");
} else {
node.setValue(LegacyComponentSerializer.legacy().serialize(obj, '&'));
} }
node.setValue(LegacyComponentSerializer.legacy().serialize(obj, '&'));
} }
} }

View File

@ -52,6 +52,7 @@
import com.griefdefender.claim.GDClaim; import com.griefdefender.claim.GDClaim;
import com.griefdefender.command.CommandHelper; import com.griefdefender.command.CommandHelper;
import com.griefdefender.configuration.MessageStorage; import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.configuration.category.BanCategory;
import com.griefdefender.event.GDCauseStackManager; import com.griefdefender.event.GDCauseStackManager;
import com.griefdefender.event.GDFlagPermissionEvent; import com.griefdefender.event.GDFlagPermissionEvent;
import com.griefdefender.internal.registry.BlockTypeRegistryModule; import com.griefdefender.internal.registry.BlockTypeRegistryModule;
@ -67,6 +68,7 @@
import net.kyori.text.adapter.bukkit.TextAdapter; import net.kyori.text.adapter.bukkit.TextAdapter;
import net.kyori.text.format.TextColor; import net.kyori.text.format.TextColor;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
@ -94,6 +96,7 @@
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
@ -587,31 +590,52 @@ public boolean isObjectIdBanned(GDClaim claim, String id, BanType type) {
if (id.equalsIgnoreCase("player")) { if (id.equalsIgnoreCase("player")) {
return false; return false;
} }
final World world = claim.getWorld();
final String permission = StringUtils.replace(id, ":", "."); GDPermissionUser user = null;
Component banReason = null; if (this.eventSubject != null && this.eventSubject instanceof GDPermissionUser) {
if (type == BanType.BLOCK) { user = (GDPermissionUser) this.eventSubject;
banReason = GriefDefenderPlugin.getGlobalConfig().getConfig().bans.getBlockBanReason(id); if (user.getInternalPlayerData() != null && user.getInternalPlayerData().canIgnoreClaim(claim)) {
if (banReason != null && banReason.equals(TextComponent.empty())) { return false;
banReason = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.PERMISSION_BAN_BLOCK,
ImmutableMap.of("id", TextComponent.of(id, TextColor.GOLD)));
}
} else if (type == BanType.ITEM) {
banReason = GriefDefenderPlugin.getGlobalConfig().getConfig().bans.getItemBanReason(id);
if (banReason != null && banReason.equals(TextComponent.empty())) {
banReason = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.PERMISSION_BAN_ITEM,
ImmutableMap.of("id", TextComponent.of(id, TextColor.GOLD)));
}
} else {
banReason = GriefDefenderPlugin.getGlobalConfig().getConfig().bans.getEntityBanReason(id);
if (banReason != null && banReason.equals(TextComponent.empty())) {
banReason = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.PERMISSION_BAN_ENTITY,
ImmutableMap.of("id", TextComponent.of(id, TextColor.GOLD)));
} }
} }
if (banReason != null && this.eventSubject != null && this.eventSubject instanceof GDPermissionUser) { final String permission = StringUtils.replace(id, ":", ".");
final GDPermissionUser user = (GDPermissionUser) this.eventSubject; Component banReason = null;
final BanCategory banCategory = GriefDefenderPlugin.getGlobalConfig().getConfig().bans;
if (type == BanType.BLOCK) {
for (Entry<String, Component> banId : banCategory.getBlockMap().entrySet()) {
if (FilenameUtils.wildcardMatch(id, banId.getKey())) {
banReason = GriefDefenderPlugin.getGlobalConfig().getConfig().bans.getBlockBanReason(banId.getKey());
if (banReason != null && banReason.equals(TextComponent.empty())) {
banReason = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.PERMISSION_BAN_BLOCK,
ImmutableMap.of("id", TextComponent.of(id, TextColor.GOLD)));
}
break;
}
}
} else if (type == BanType.ITEM) {
for (Entry<String, Component> banId : banCategory.getItemMap().entrySet()) {
if (FilenameUtils.wildcardMatch(id, banId.getKey())) {
banReason = GriefDefenderPlugin.getGlobalConfig().getConfig().bans.getItemBanReason(banId.getKey());
if (banReason != null && banReason.equals(TextComponent.empty())) {
banReason = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.PERMISSION_BAN_ITEM,
ImmutableMap.of("id", TextComponent.of(id, TextColor.GOLD)));
}
}
}
} else if (type == BanType.ENTITY) {
for (Entry<String, Component> banId : banCategory.getEntityMap().entrySet()) {
if (FilenameUtils.wildcardMatch(id, banId.getKey())) {
banReason = GriefDefenderPlugin.getGlobalConfig().getConfig().bans.getEntityBanReason(banId.getKey());
if (banReason != null && banReason.equals(TextComponent.empty())) {
banReason = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.PERMISSION_BAN_ENTITY,
ImmutableMap.of("id", TextComponent.of(id, TextColor.GOLD)));
}
}
}
}
if (banReason != null && user != null) {
final Player player = user.getOnlinePlayer(); final Player player = user.getOnlinePlayer();
if (player != null) { if (player != null) {
if (banReason.equals(TextComponent.empty())) { if (banReason.equals(TextComponent.empty())) {

View File

@ -3,9 +3,9 @@
"libraries": [ "libraries": [
{ {
"name": "com.griefdefender:adapter:1.12.2", "name": "com.griefdefender:adapter:1.12.2",
"sha1": "540a07679ae4323989569d5eaf503194769a477b", "sha1": "49a2722e73f2dae2ae30905a1c34f8ecbe6ac84c",
"path": "com/griefdefender/adapter/1.12.2-SNAPSHOT/adapter-1.12.2-20190823.170931-16.jar", "path": "com/griefdefender/adapter/1.12.2-SNAPSHOT/adapter-1.12.2-20190824.054201-17.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.12.2-SNAPSHOT/adapter-1.12.2-20190823.170931-16.jar" "url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.12.2-SNAPSHOT/adapter-1.12.2-20190824.054201-17.jar"
}, },
{ {
"name": "com.griefdefender:api:1.0.0", "name": "com.griefdefender:api:1.0.0",

View File

@ -3,9 +3,9 @@
"libraries": [ "libraries": [
{ {
"name": "com.griefdefender:adapter:1.13.2", "name": "com.griefdefender:adapter:1.13.2",
"sha1": "84ee6f7193f0c9e79c1fa6fe70576f723b8261b6", "sha1": "392cab759abcf0adfc73d4bad702583d5471645c",
"path": "com/griefdefender/adapter/1.13.2-SNAPSHOT/adapter-1.13.2-20190823.170029-15.jar", "path": "com/griefdefender/adapter/1.13.2-SNAPSHOT/adapter-1.13.2-20190824.054317-16.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.13.2-SNAPSHOT/adapter-1.13.2-20190823.170029-15.jar" "url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.13.2-SNAPSHOT/adapter-1.13.2-20190824.054317-16.jar"
}, },
{ {
"name": "com.griefdefender:api:1.0.0", "name": "com.griefdefender:api:1.0.0",

View File

@ -3,9 +3,9 @@
"libraries": [ "libraries": [
{ {
"name": "com.griefdefender:adapter:1.14.2", "name": "com.griefdefender:adapter:1.14.2",
"sha1": "4b5c423490fd6ac2bceb9a051e7748362f8e9de8", "sha1": "233717ff2c34f5a26c68d6d7e36c2d288454b677",
"path": "com/griefdefender/adapter/1.14.2-SNAPSHOT/adapter-1.14.2-20190823.165847-15.jar", "path": "com/griefdefender/adapter/1.14.2-SNAPSHOT/adapter-1.14.2-20190824.054513-16.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.14.2-SNAPSHOT/adapter-1.14.2-20190823.165847-15.jar" "url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.14.2-SNAPSHOT/adapter-1.14.2-20190824.054513-16.jar"
}, },
{ {
"name": "com.griefdefender:api:1.0.0", "name": "com.griefdefender:api:1.0.0",

View File

@ -3,9 +3,9 @@
"libraries": [ "libraries": [
{ {
"name": "com.griefdefender:adapter:1.14.3", "name": "com.griefdefender:adapter:1.14.3",
"sha1": "f2715e8def25b3b2e71bcaee2687c4158a60d5ed", "sha1": "f850a336ea29e1f926e7b6e7220bd03174418e49",
"path": "com/griefdefender/adapter/1.14.3-SNAPSHOT/adapter-1.14.3-20190823.164433-16.jar", "path": "com/griefdefender/adapter/1.14.3-SNAPSHOT/adapter-1.14.3-20190824.054551-17.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.14.3-SNAPSHOT/adapter-1.14.3-20190823.164433-16.jar" "url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.14.3-SNAPSHOT/adapter-1.14.3-20190824.054551-17.jar"
}, },
{ {
"name": "com.griefdefender:api:1.0.0", "name": "com.griefdefender:api:1.0.0",

View File

@ -3,9 +3,9 @@
"libraries": [ "libraries": [
{ {
"name": "com.griefdefender:adapter:1.14.4", "name": "com.griefdefender:adapter:1.14.4",
"sha1": "4e5c6b12375678703df8ca7ffde4e1d0d2ee7c79", "sha1": "bd0432df546af6c352a09836b4116887e5b596e3",
"path": "com/griefdefender/adapter/1.14.4-SNAPSHOT/adapter-1.14.4-20190823.163709-13.jar", "path": "com/griefdefender/adapter/1.14.4-SNAPSHOT/adapter-1.14.4-20190824.054634-14.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.14.4-SNAPSHOT/adapter-1.14.4-20190823.163709-13.jar" "url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.14.4-SNAPSHOT/adapter-1.14.4-20190824.054634-14.jar"
}, },
{ {
"name": "com.griefdefender:api:1.0.0", "name": "com.griefdefender:api:1.0.0",

View File

@ -3,9 +3,9 @@
"libraries": [ "libraries": [
{ {
"name": "com.griefdefender:adapter:1.8.8", "name": "com.griefdefender:adapter:1.8.8",
"sha1": "5228e3ff78a4a15068b057d3335da11fcda5bc57", "sha1": "b6abc129566822a55c70760f39c8b053ebe2ce22",
"path": "com/griefdefender/adapter/1.8.8-SNAPSHOT/adapter-1.8.8-20190823.171045-16.jar", "path": "com/griefdefender/adapter/1.8.8-SNAPSHOT/adapter-1.8.8-20190824.054037-17.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.8.8-SNAPSHOT/adapter-1.8.8-20190823.171045-16.jar" "url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.8.8-SNAPSHOT/adapter-1.8.8-20190824.054037-17.jar"
}, },
{ {
"name": "com.griefdefender:api:1.0.0", "name": "com.griefdefender:api:1.0.0",

View File

@ -545,9 +545,9 @@ GriefDefender {
plugin-event-cancel="&cA plugin has cancelled this action." plugin-event-cancel="&cA plugin has cancelled this action."
plugin-not-found="&cCould not locate plugin with id &b{id}&c." plugin-not-found="&cCould not locate plugin with id &b{id}&c."
plugin-reload="&aGriefDefender has been reloaded." plugin-reload="&aGriefDefender has been reloaded."
registry-block-not-found="&cThe block {id} could not be found in registry." registry-block-not-found="&cThe block {id}&c could not be found in registry."
registry-entity-not-found="&cThe entity {id} could not be found in registry." registry-entity-not-found="&cThe entity {id}&c could not be found in registry."
registry-item-not-found="&cThe item {id} could not be found in registry." registry-item-not-found="&cThe item {id}&c could not be found in registry."
resize-overlap="&cCan't resize here because it would overlap another nearby claim." resize-overlap="&cCan't resize here because it would overlap another nearby claim."
resize-overlap-subdivision="&cYou can't create a subdivision here because it would overlap another subdivision. Consider &f/abandon&c to delete it, or use your shovel at a corner to resize it." resize-overlap-subdivision="&cYou can't create a subdivision here because it would overlap another subdivision. Consider &f/abandon&c to delete it, or use your shovel at a corner to resize it."
resize-same-location="&cYou must select a different block location to resize claim." resize-same-location="&cYou must select a different block location to resize claim."

View File

@ -545,9 +545,9 @@ GriefDefender {
plugin-event-cancel="&cПлагин отменил это действие." plugin-event-cancel="&cПлагин отменил это действие."
plugin-not-found="&cНе удалось найти плагин с идентификатором &b{id}&c." plugin-not-found="&cНе удалось найти плагин с идентификатором &b{id}&c."
plugin-reload="&aGriefDefender перезагружен." plugin-reload="&aGriefDefender перезагружен."
registry-block-not-found="&cБлок {id} не найден в реестре." registry-block-not-found="&cБлок {id}&c не найден в реестре."
registry-entity-not-found="&cСущность {id} не найдена в реестре." registry-entity-not-found="&cСущность {id}&c не найдена в реестре."
registry-item-not-found="&cПредмет {id} не найден в реестре." registry-item-not-found="&cПредмет {id}&c не найден в реестре."
resize-overlap="&cНельзя изменить размер региона - в этом случае он будет пересекаться с другим регионом." resize-overlap="&cНельзя изменить размер региона - в этом случае он будет пересекаться с другим регионом."
resize-overlap-subdivision="&cНельзя изменить размер суб-региона - в этом случае он будет пересекаться с другим суб-регионом. Воспользуйтесь &f/abandon&c, чтобы удалить его, или используйте лопату на его угол, чтобы изменить его размер." resize-overlap-subdivision="&cНельзя изменить размер суб-региона - в этом случае он будет пересекаться с другим суб-регионом. Воспользуйтесь &f/abandon&c, чтобы удалить его, или используйте лопату на его угол, чтобы изменить его размер."
resize-same-location="&cУгол региона уже находится здесь. Нужно выбрать другое место для угла региона, чтобы изменить его размер." resize-same-location="&cУгол региона уже находится здесь. Нужно выбрать другое место для угла региона, чтобы изменить его размер."