From 469d3944b9d22653448eaadee5e28b23483786c8 Mon Sep 17 00:00:00 2001 From: tastybento Date: Sat, 9 Nov 2019 18:28:18 -0800 Subject: [PATCH 01/16] Updated gitignore with Eclipse ignores --- .gitignore | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index d5206b6..86eb68c 100644 --- a/.gitignore +++ b/.gitignore @@ -30,4 +30,7 @@ out/ ## File-based project format: *.ipr *.iws -*.iml \ No newline at end of file +*.iml +/.classpath +/.project +/.settings/ From 9f6b84cb24eb613ffd241ec2887ba29496153aab Mon Sep 17 00:00:00 2001 From: tastybento Date: Sat, 9 Nov 2019 18:31:14 -0800 Subject: [PATCH 02/16] Added Travis and SonarCloud --- .travis.yml | 23 ++++++++++++++ pom.xml | 86 +++++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 93 insertions(+), 16 deletions(-) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..6eede54 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,23 @@ +language: java +sudo: false +addons: + sonarcloud: + organization: "bentobox-world" + token: + secure: $SONAR_TOKEN +jdk: + - openjdk8 + - openjdk11 + +matrix: + allow_failures: + - jdk: openjdk11 + +script: + # the following command line builds the project, runs the tests with coverage and then execute the SonarCloud analysis + - mvn clean org.jacoco:jacoco-maven-plugin:prepare-agent install sonar:sonar -Dsonar.projectKey=BentoBoxWorld_Likes + +cache: + directories: + - '$HOME/.m2/repository' + - '$HOME/.sonar/cache' diff --git a/pom.xml b/pom.xml index 4dca20b..25eb497 100644 --- a/pom.xml +++ b/pom.xml @@ -1,7 +1,7 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 world.bentobox @@ -14,30 +14,31 @@ 2019 - - + + scm:git:https://github.com/BentoBoxWorld/Likes.git scm:git:git@github.com:BentoBoxWorld/Likes.git https://github.com/BentoBoxWorld/Likes - - + + jenkins http://ci.codemc.org/job/BentoBoxWorld/job/Likes - - + + GitHub https://github.com/BentoBoxWorld/Likes/issues - - + + codemc-snapshots @@ -49,9 +50,10 @@ - + - + UTF-8 UTF-8 1.8 @@ -98,13 +100,37 @@ ${build.version} - + + + sonar + + https://sonarcloud.io + bentobox-world + + + + + org.sonarsource.scanner.maven + sonar-maven-plugin + 3.6.0.1398 + + + verify + + sonar + + + + + + + - + spigot-repo @@ -124,7 +150,7 @@ - + org.spigotmc @@ -153,7 +179,8 @@ - + ${project.name}-${revision}${build.number} @@ -255,6 +282,33 @@ maven-install-plugin 2.5.2 + + org.jacoco + jacoco-maven-plugin + 0.8.3 + + true + + + **/*Names* + + + + + pre-unit-test + + prepare-agent + + + + post-unit-test + + report + + + + From f6d0688704228a4060c82da5e3419890781d8ca8 Mon Sep 17 00:00:00 2001 From: tastybento Date: Sat, 9 Nov 2019 18:32:41 -0800 Subject: [PATCH 03/16] Removed unused import --- .../commands/user/PlayerViewCommand.java | 280 +++++++++--------- 1 file changed, 139 insertions(+), 141 deletions(-) diff --git a/src/main/java/world/bentobox/likes/commands/user/PlayerViewCommand.java b/src/main/java/world/bentobox/likes/commands/user/PlayerViewCommand.java index 0988167..0a48ec9 100644 --- a/src/main/java/world/bentobox/likes/commands/user/PlayerViewCommand.java +++ b/src/main/java/world/bentobox/likes/commands/user/PlayerViewCommand.java @@ -12,9 +12,7 @@ import world.bentobox.bentobox.database.objects.Island; import world.bentobox.bentobox.util.Util; import world.bentobox.likes.LikesAddon; -import world.bentobox.likes.config.Settings; import world.bentobox.likes.panels.user.LikesViewPanel; -import world.bentobox.likes.panels.user.TopLikesPanel; import world.bentobox.likes.utils.Constants; @@ -23,143 +21,143 @@ */ public class PlayerViewCommand extends CompositeCommand { - /** - * This is simple constructor for initializing /{gamemode_player_command} example command. - * @param addon Our Example addon. - * @param parentCommand Parent Command where we hook our command into. - */ - public PlayerViewCommand(LikesAddon addon, CompositeCommand parentCommand) - { - super(addon, parentCommand, "view"); - } - - - /** - * Setups anything that is needed for this command.

It is recommended you - * do the following in this method: - *
    - *
  • Register any of the sub-commands of this command;
  • - *
  • Define the permission required to use this command using {@link - * CompositeCommand#setPermission(String)};
  • - *
  • Define whether this command can only be run by players or not using {@link - * CompositeCommand#setOnlyPlayer(boolean)};
  • - *
- */ - @Override - public void setup() - { - this.setPermission("likes.view"); - this.setOnlyPlayer(true); - this.setParametersHelp(Constants.COMMANDS + "view.parameters"); - this.setDescription(Constants.COMMANDS + "view.description"); - } - - - /** - * Returns whether the command can be executed by this user or not. It is recommended - * to send messages to let this user know why they could not execute the command. Note - * that this is run previous to {@link #execute(User, String, List)}. - * - * @param user the {@link User} who is executing this command. - * @param label the label which has been used to execute this command. It can be - * {@link CompositeCommand#getLabel()} or an alias. - * @param args the command arguments. - * @return {@code true} if this command can be executed, {@code false} otherwise. - * @since 1.3.0 - */ - @Override - public boolean canExecute(User user, String label, List args) - { - if (!args.isEmpty() && !user.hasPermission(this.getPermission() + "others")) - { - user.sendMessage("general.errors.no-permission", "[permission]", this.getPermission() + "others"); - return false; - } - - Island island; - - if (args.isEmpty()) - { - island = this.getAddon().getIslands().getIsland(this.getWorld(), user); - } - else - { - final UUID playerUUID = this.getAddon().getPlayers().getUUID(args.get(0)); - - if (playerUUID == null) - { - user.sendMessage("general.errors.unknown-player", TextVariables.NAME, args.get(0)); - return false; - } - - island = this.getAddon().getIslands().getIsland(this.getWorld(), playerUUID); - } - - if (island == null) - { - user.sendMessage(Constants.ERRORS + "not-on-island"); - return false; - } - - return true; - } - - - /** - * Defines what will be executed when this command is run. - * - * @param user the {@link User} who is executing this command. - * @param label the label which has been used to execute this command. It can be - * {@link CompositeCommand#getLabel()} or an alias. - * @param args the command arguments. - * @return {@code true} if the command executed successfully, {@code false} otherwise. - */ - @Override - public boolean execute(User user, String label, List args) - { - Island island; - - if (args.isEmpty()) - { - island = this.getAddon().getIslands().getIsland(this.getWorld(), user); - } - else - { - island = this.getAddon().getIslands().getIsland(this.getWorld(), - this.getAddon().getPlayers().getUUID(args.get(0))); - } - - LikesViewPanel.openPanel((LikesAddon) this.getAddon(), - user, - this.getWorld(), - this.getPermissionPrefix(), - island); - - return true; - } - - - /** - * Tab Completer for CompositeCommands. Note that any registered sub-commands will be - * automatically added to the list. Use this to add tab-complete for things like - * names. - * - * @param user the {@link User} who is executing this command. - * @param alias alias for command - * @param args command arguments - * @return List of strings that could be used to complete this command. - */ - @Override - public Optional> tabComplete(User user, String alias, List args) - { - String lastArg = !args.isEmpty() ? args.get(args.size() - 1) : ""; - - if (args.isEmpty()) - { - // Don't show every player on the server. Require at least the first letter - return Optional.empty(); - } - - return Optional.of(Util.tabLimit(new ArrayList<>(Util.getOnlinePlayerList(user)), lastArg)); - } + /** + * This is simple constructor for initializing /{gamemode_player_command} example command. + * @param addon Our Example addon. + * @param parentCommand Parent Command where we hook our command into. + */ + public PlayerViewCommand(LikesAddon addon, CompositeCommand parentCommand) + { + super(addon, parentCommand, "view"); + } + + + /** + * Setups anything that is needed for this command.

It is recommended you + * do the following in this method: + *
    + *
  • Register any of the sub-commands of this command;
  • + *
  • Define the permission required to use this command using {@link + * CompositeCommand#setPermission(String)};
  • + *
  • Define whether this command can only be run by players or not using {@link + * CompositeCommand#setOnlyPlayer(boolean)};
  • + *
+ */ + @Override + public void setup() + { + this.setPermission("likes.view"); + this.setOnlyPlayer(true); + this.setParametersHelp(Constants.COMMANDS + "view.parameters"); + this.setDescription(Constants.COMMANDS + "view.description"); + } + + + /** + * Returns whether the command can be executed by this user or not. It is recommended + * to send messages to let this user know why they could not execute the command. Note + * that this is run previous to {@link #execute(User, String, List)}. + * + * @param user the {@link User} who is executing this command. + * @param label the label which has been used to execute this command. It can be + * {@link CompositeCommand#getLabel()} or an alias. + * @param args the command arguments. + * @return {@code true} if this command can be executed, {@code false} otherwise. + * @since 1.3.0 + */ + @Override + public boolean canExecute(User user, String label, List args) + { + if (!args.isEmpty() && !user.hasPermission(this.getPermission() + "others")) + { + user.sendMessage("general.errors.no-permission", "[permission]", this.getPermission() + "others"); + return false; + } + + Island island; + + if (args.isEmpty()) + { + island = this.getAddon().getIslands().getIsland(this.getWorld(), user); + } + else + { + final UUID playerUUID = this.getAddon().getPlayers().getUUID(args.get(0)); + + if (playerUUID == null) + { + user.sendMessage("general.errors.unknown-player", TextVariables.NAME, args.get(0)); + return false; + } + + island = this.getAddon().getIslands().getIsland(this.getWorld(), playerUUID); + } + + if (island == null) + { + user.sendMessage(Constants.ERRORS + "not-on-island"); + return false; + } + + return true; + } + + + /** + * Defines what will be executed when this command is run. + * + * @param user the {@link User} who is executing this command. + * @param label the label which has been used to execute this command. It can be + * {@link CompositeCommand#getLabel()} or an alias. + * @param args the command arguments. + * @return {@code true} if the command executed successfully, {@code false} otherwise. + */ + @Override + public boolean execute(User user, String label, List args) + { + Island island; + + if (args.isEmpty()) + { + island = this.getAddon().getIslands().getIsland(this.getWorld(), user); + } + else + { + island = this.getAddon().getIslands().getIsland(this.getWorld(), + this.getAddon().getPlayers().getUUID(args.get(0))); + } + + LikesViewPanel.openPanel((LikesAddon) this.getAddon(), + user, + this.getWorld(), + this.getPermissionPrefix(), + island); + + return true; + } + + + /** + * Tab Completer for CompositeCommands. Note that any registered sub-commands will be + * automatically added to the list. Use this to add tab-complete for things like + * names. + * + * @param user the {@link User} who is executing this command. + * @param alias alias for command + * @param args command arguments + * @return List of strings that could be used to complete this command. + */ + @Override + public Optional> tabComplete(User user, String alias, List args) + { + String lastArg = !args.isEmpty() ? args.get(args.size() - 1) : ""; + + if (args.isEmpty()) + { + // Don't show every player on the server. Require at least the first letter + return Optional.empty(); + } + + return Optional.of(Util.tabLimit(new ArrayList<>(Util.getOnlinePlayerList(user)), lastArg)); + } } From 46780a98036c6d8358f7bbf396bd1e2e92a80492 Mon Sep 17 00:00:00 2001 From: tastybento Date: Sat, 9 Nov 2019 18:39:03 -0800 Subject: [PATCH 04/16] now with correct travis.yml file. --- .travis.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6eede54..cedf257 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,8 +3,7 @@ sudo: false addons: sonarcloud: organization: "bentobox-world" - token: - secure: $SONAR_TOKEN + jdk: - openjdk8 - openjdk11 From 65228ff23afaf0cb37fdfe08d8eab2c875cbaae5 Mon Sep 17 00:00:00 2001 From: tastybento Date: Mon, 11 Nov 2019 07:43:58 -0800 Subject: [PATCH 05/16] Chinese locale - credit @WTFTWTM --- src/main/resources/locales/zh-CN.yml | 125 +++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 src/main/resources/locales/zh-CN.yml diff --git a/src/main/resources/locales/zh-CN.yml b/src/main/resources/locales/zh-CN.yml new file mode 100644 index 0000000..038b70f --- /dev/null +++ b/src/main/resources/locales/zh-CN.yml @@ -0,0 +1,125 @@ +likes: + gui: + titles: + select-block: '&d选择一个方块' + top: '&d[type] 排行榜' + view: '&d空岛排名' + manage: '&d对当前岛屿进行评价' + settings: '&d更改设置' + admin: '&d管理员面板' + select-island: '&d选择一个岛屿' + select-player: '&d选择一个玩家' + edit-view: '&d修改岛屿评价' + buttons: + cancel: '&c取消' + accept: '&a确认' + previous: 上一页 + next: '下一页' + return: '&a返回' + view-mode: '&6排行榜类型' + name: '[name]' + like: '&6空岛好评计数' + like-rank: '&6空岛好评排名' + dislike: '&c空岛差评计数' + dislike-rank: '&c空岛差评排名' + overall: '&a空岛排名' + overall-rank: '&a空岛评价分' + add-like: '&6添加/移除 好评' + add-dislike: '&c添加/移除 差评' + like-cost: '好评费用' + like-remove-cost: '移除好评费用' + dislike-cost: '差评费用' + dislike-remove-cost: '移除差评费用' + default-icon: '默认图标' + inform-players: '通知岛屿成员' + log-history: '历史日志' + reset-likes: '重置岛屿时归零评价' + manage-likes: '管理岛屿评价' + likes-icon: '更改岛屿图标' + wipe-data: '清空数据' + edit-settings: '修改设置' + add-dislike-user: '添加差评' + add-like-user: '添加好评' + remove-dislike-user: '移除差评' + remove-like-user: '移除好评' + descriptions: + selected: '&d已选择' + view-mode: '&e当前排行榜类型' + mode: '按照 [type] 排名' + top-value: + likes: '&6[rank] 岛屿|&6拥有 [value] 个好评' + dislikes: '&6[rank] 岛屿|&6拥有 [value] 个差评' + rank: '&6[rank] 排名|&6拥有 [value] 排名分数' + values: '岛屿拥有:|[likes] 个好评|[dislikes] 个差评|[rank] 排名分数' + unknown: '&c未知玩家' + current-value: '当前值: [value]' + like: '被其他玩家好评的次数' + dislike: '被其他玩家差评的次数' + overall: '当前排名分|(好评 - 差评)' + like-rank: '全服优秀空岛排名|越高越好' + dislike-rank: '全服最差空岛排名|越低越好' + overall-rank: '全服综合空岛排名' + like-next: '展示下一个喜欢了|你的岛屿的玩家' + dislike-next: '展示下一个差评了|你的岛屿的玩家' + like-previous: '展示上一个喜欢了|你的岛屿的玩家' + dislike-previous: '展示上一个差评了|你的岛屿的玩家' + add-like: '添加或移除好评' + add-dislike: '添加或移除差评' + cost: '当前操作花费 $[value].' + like-cost: '更改添加好评的花费' + like-remove-cost: '更改移除好评的花费' + dislike-cost: '更改添加差评的花费' + dislike-remove-cost: '更改移除差评的花费' + default-icon: '更改排行榜默认图标' + inform-players: '更改岛屿成员|是否收到来自|好评或者差评|的提醒' + log-history: '更改是否|应该存储历史数据' + reset-likes: '更改是否|在岛屿重置时|重置评价计数' + manage-likes: '添加/删除|好评或差评了选中岛屿|的玩家' + likes-icon: '更改在排行榜中的岛屿的图标' + wipe-data: '完全删除|已经存储的|游戏信息' + edit-settings: '在GUI中编辑|插件信息' + types: + likes: '好评' + dislikes: '差评' + rank: '排名' + messages: + add-like: '&e狐游 &6┃┃ &a你好评了 [island] 的岛屿' + player-add-like: '&e狐游 &6┃┃ &a玩家 [user] 好评了你的岛屿' + remove-like: '&e狐游 &6┃┃ &c你从 [island] 的岛屿上移除了你的好评' + player-remove-like: '&e狐游 &6┃┃ &c玩家 [user] 从你的岛屿上移除了他的好评' + add-dislike: '&e狐游 &6┃┃ &c你差评了 [island] 的岛屿' + player-add-dislike: '&e狐游 &6┃┃ &c[user] 差评了你的岛屿' + remove-dislike: '&e狐游 &6┃┃ &a你从 [island] 的岛屿移除了你的差评' + player-remove-dislike: '&e狐游 &6┃┃ &a玩家 [user] 从你的岛屿上移除了他的差评' + no-data-about-island: '&e狐游 &6┃┃ &e这个岛屿暂时无人评价' + no-data-about-your-island: '&e狐游 &6┃┃ &e你的岛屿暂时无人评价' + errors: + not-on-island: '&e狐游 &6┃┃ &c你必须站在一个岛屿上才能使用这个命令' + your-island: '&e狐游 &6┃┃ &c你无法好评或差评你自己的岛屿' + numeric-only: '&e狐游 &6┃┃ &c输入只能接受数字!' + not-valid-value: '&e狐游 &6┃┃ &c数字需要大于 [min] 并且小于 [max],你提供的值 [value] 无法满足这个条件!' + top-is-empty: '&e狐游 &6┃┃ &c抱歉,排行榜上暂无任何人' + database-error: '&e狐游 &6┃┃ &c抱歉,数据库好像出了问题,无法找到你的岛屿信息' + questions: + prefix: '&e狐游 &6┃┃ ' + like-cost: '&5请输入好评所需要的费用' + like-remove-cost: '&5请输入移除好评所需要的费用' + dislike-cost: '&5请输入差评所需要的费用' + dislike-remove-cost: '&5请输入移除差评所需要的费用' + commands: + admin: + help: + parameters: '' + description: 打开管理员面板 + settings: + parameters: '' + description: 打开管理员设定面板 + help: + parameters: '' + description: 打开喜欢列表 + top: + parameters: + description: 打开排行榜 + view: + parameters: + description: 打开喜欢你的列表 From 81bc5649da7757329f45a8c8f0bef0085c64aa56 Mon Sep 17 00:00:00 2001 From: tastybento Date: Mon, 11 Nov 2019 22:20:26 -0800 Subject: [PATCH 06/16] Fixes most bugs reported by SonarCloud --- .../likes/commands/user/PlayerCommand.java | 191 +-- .../bentobox/likes/managers/LikesManager.java | 1155 ++++++++--------- .../likes/panels/admin/AdminViewPanel.java | 1040 +++++++-------- .../likes/panels/user/LikesViewPanel.java | 882 ++++++------- .../utils/collections/IndexedTreeMap.java | 294 ++++- 5 files changed, 1873 insertions(+), 1689 deletions(-) diff --git a/src/main/java/world/bentobox/likes/commands/user/PlayerCommand.java b/src/main/java/world/bentobox/likes/commands/user/PlayerCommand.java index eb9ade5..9dff99b 100644 --- a/src/main/java/world/bentobox/likes/commands/user/PlayerCommand.java +++ b/src/main/java/world/bentobox/likes/commands/user/PlayerCommand.java @@ -18,99 +18,100 @@ */ public class PlayerCommand extends CompositeCommand { - /** - * This is simple constructor for initializing /{gamemode_player_command} example command. - * @param addon Our Example addon. - * @param parentCommand Parent Command where we hook our command into. - */ - public PlayerCommand(LikesAddon addon, CompositeCommand parentCommand) - { - super(addon, parentCommand, "likes"); - } - - - /** - * Setups anything that is needed for this command.

It is recommended you - * do the following in this method: - *
    - *
  • Register any of the sub-commands of this command;
  • - *
  • Define the permission required to use this command using {@link - * CompositeCommand#setPermission(String)};
  • - *
  • Define whether this command can only be run by players or not using {@link - * CompositeCommand#setOnlyPlayer(boolean)};
  • - *
- */ - @Override - public void setup() - { - this.setPermission("likes"); - this.setOnlyPlayer(true); - this.setParametersHelp(Constants.COMMANDS + "help.parameters"); - this.setDescription(Constants.COMMANDS + "help.description"); - - new PlayerTopCommand((LikesAddon) this.getAddon(), this); - new PlayerViewCommand((LikesAddon) this.getAddon(), this); - } - - - /** - * Returns whether the command can be executed by this user or not. It is recommended - * to send messages to let this user know why they could not execute the command. Note - * that this is run previous to {@link #execute(User, String, List)}. - * - * @param user the {@link User} who is executing this command. - * @param label the label which has been used to execute this command. It can be - * {@link CompositeCommand#getLabel()} or an alias. - * @param args the command arguments. - * @return {@code true} if this command can be executed, {@code false} otherwise. - * @since 1.3.0 - */ - @Override - public boolean canExecute(User user, String label, List args) - { - Optional island = this.getAddon().getIslands().getIslandAt(user.getLocation()); - - if (!island.isPresent()) - { - user.sendMessage(Constants.ERRORS + "not-on-island"); - return false; - } - - return true; - } - - - /** - * Defines what will be executed when this command is run. - * - * @param user the {@link User} who is executing this command. - * @param label the label which has been used to execute this command. It can be - * {@link CompositeCommand#getLabel()} or an alias. - * @param args the command arguments. - * @return {@code true} if the command executed successfully, {@code false} otherwise. - */ - @Override - public boolean execute(User user, String label, List args) - { - Island island = this.getAddon().getIslands().getIslandAt(user.getLocation()).get(); - - if (island.getMemberSet().contains(user.getUniqueId())) - { - LikesViewPanel.openPanel((LikesAddon) this.getAddon(), - user, - this.getWorld(), - this.getPermissionPrefix(), - island); - } - else - { - LikesManagePanel.openPanel((LikesAddon) this.getAddon(), - user, - this.getWorld(), - this.getPermissionPrefix(), - island); - } - - return true; - } + /** + * This is simple constructor for initializing /{gamemode_player_command} example command. + * @param addon Our Example addon. + * @param parentCommand Parent Command where we hook our command into. + */ + public PlayerCommand(LikesAddon addon, CompositeCommand parentCommand) + { + super(addon, parentCommand, "likes"); + } + + + /** + * Setups anything that is needed for this command.

It is recommended you + * do the following in this method: + *
    + *
  • Register any of the sub-commands of this command;
  • + *
  • Define the permission required to use this command using {@link + * CompositeCommand#setPermission(String)};
  • + *
  • Define whether this command can only be run by players or not using {@link + * CompositeCommand#setOnlyPlayer(boolean)};
  • + *
+ */ + @Override + public void setup() + { + this.setPermission("likes"); + this.setOnlyPlayer(true); + this.setParametersHelp(Constants.COMMANDS + "help.parameters"); + this.setDescription(Constants.COMMANDS + "help.description"); + + new PlayerTopCommand((LikesAddon) this.getAddon(), this); + new PlayerViewCommand((LikesAddon) this.getAddon(), this); + } + + + /** + * Returns whether the command can be executed by this user or not. It is recommended + * to send messages to let this user know why they could not execute the command. Note + * that this is run previous to {@link #execute(User, String, List)}. + * + * @param user the {@link User} who is executing this command. + * @param label the label which has been used to execute this command. It can be + * {@link CompositeCommand#getLabel()} or an alias. + * @param args the command arguments. + * @return {@code true} if this command can be executed, {@code false} otherwise. + * @since 1.3.0 + */ + @Override + public boolean canExecute(User user, String label, List args) + { + + Optional island = this.getAddon().getIslands().getIslandAt(user.getLocation()); + + if (!island.isPresent()) + { + user.sendMessage(Constants.ERRORS + "not-on-island"); + return false; + } + + return true; + } + + + /** + * Defines what will be executed when this command is run. + * + * @param user the {@link User} who is executing this command. + * @param label the label which has been used to execute this command. It can be + * {@link CompositeCommand#getLabel()} or an alias. + * @param args the command arguments. + * @return {@code true} if the command executed successfully, {@code false} otherwise. + */ + @Override + public boolean execute(User user, String label, List args) + { + this.getAddon().getIslands().getIslandAt(user.getLocation()).ifPresent(island -> { + + if (island.getMemberSet().contains(user.getUniqueId())) + { + LikesViewPanel.openPanel((LikesAddon) this.getAddon(), + user, + this.getWorld(), + this.getPermissionPrefix(), + island); + } + else + { + LikesManagePanel.openPanel((LikesAddon) this.getAddon(), + user, + this.getWorld(), + this.getPermissionPrefix(), + island); + } + }); + return true; + } } diff --git a/src/main/java/world/bentobox/likes/managers/LikesManager.java b/src/main/java/world/bentobox/likes/managers/LikesManager.java index 1f34bf1..a46ec1c 100644 --- a/src/main/java/world/bentobox/likes/managers/LikesManager.java +++ b/src/main/java/world/bentobox/likes/managers/LikesManager.java @@ -37,582 +37,581 @@ */ public class LikesManager { -// --------------------------------------------------------------------- -// Section: Constructor -// --------------------------------------------------------------------- - - - /** - * Default constructor. - * @param addon Likes Addon instance - */ - public LikesManager(LikesAddon addon) - { - this.addon = addon; - - this.likesDatabase = new Database<>(addon, LikesObject.class); - this.likesCache = new HashMap<>(); - - this.sortedDislikeCache = new HashMap<>(); - this.sortedLikeCache = new HashMap<>(); - this.sortedRankCache = new HashMap<>(); - - this.load(); - } - - -// --------------------------------------------------------------------- -// Section: Load Methods -// --------------------------------------------------------------------- - - - /** - * This method loads all like objects. - */ - public void load() - { - this.likesCache.clear(); - - this.sortedLikeCache.clear(); - this.sortedDislikeCache.clear(); - this.sortedRankCache.clear(); - - this.addon.getLogger().info("Loading likes..."); - - this.likesDatabase.loadObjects().forEach(this::load); - } - - - /** - * This method loads given likeObject inside cache. - * @param likesObject Object that must be added to cache. - */ - private void load(LikesObject likesObject) - { - // Add object into Island to LikeObject cache. - this.likesCache.put(likesObject.getUniqueId(), likesObject); - - // Add object into GameMode to sorted by likes cache. - this.sortedLikeCache.computeIfAbsent(likesObject.getGameMode(), - gameMode -> new IndexedTreeSet<>(Comparator.comparing(LikesObject::getLikes).reversed(). - thenComparing(LikesObject::getDislikes). - thenComparing(LikesObject::getUniqueId))).add(likesObject); - - // Add object into GameMode to sorted by dislikes cache. - this.sortedDislikeCache.computeIfAbsent(likesObject.getGameMode(), - gameMode -> new IndexedTreeSet<>(Comparator.comparing(LikesObject::getDislikes).reversed(). - thenComparing(LikesObject::getLikes). - thenComparing(LikesObject::getUniqueId))).add(likesObject); - - // Add object into GameMode to sorted by rank cache. - this.sortedRankCache.computeIfAbsent(likesObject.getGameMode(), - gameMode -> new IndexedTreeSet<>(Comparator.comparing(LikesObject::getRank).reversed(). - thenComparing(LikesObject::getLikes).reversed(). - thenComparing(LikesObject::getDislikes).reversed(). - thenComparing(LikesObject::getUniqueId))).add(likesObject); - } - - - - /** - * This method checks if likes object with given UniqueId exist in database. - * If not, it creates new object for that. - * - * @param uniqueID - uniqueID to add - * @param gameMode - gameMode for like object. - */ - private LikesObject getIslandLikes(@NonNull String uniqueID, String gameMode) - { - if (this.likesCache.containsKey(uniqueID)) - { - return this.likesCache.get(uniqueID); - } - - // The player is not in the cache - // Check if the player exists in the database - - if (this.likesDatabase.objectExists(uniqueID)) - { - // Load player from database - LikesObject data = this.likesDatabase.loadObject(uniqueID); - // Store in cache - - if (data != null) - { - this.load(data); - } - else - { - this.addon.logError("Could not load NULL likes data object."); - } - - return data; - } - else - { - // Create the likes data - LikesObject likesObject = new LikesObject(); - likesObject.setUniqueId(uniqueID); - likesObject.setGameMode(gameMode); - - this.likesDatabase.saveObject(likesObject); - // Add to cache - this.load(likesObject); - - return likesObject; - } - } - - - /** - * This method returns Island Likes Object from cache or create new one. - * @param islandId IslandId which LikesObject must be returned. - * @param world Target world. - * @return Likes Object for given island. - */ - public LikesObject getIslandLikes(String islandId, World world) - { - return this.getIslandLikes(islandId, Utils.getGameMode(world)); - } - - - /** - * This method returns Island Likes Object from cache or create new one. - * @param islandId IslandId which LikesObject must be returned. - * @param gameModeAddon Target GameMode addon. - * @return Likes Object for given island. - */ - public LikesObject getIslandLikes(String islandId, GameModeAddon gameModeAddon) - { - return this.getIslandLikes(islandId, gameModeAddon.getDescription().getName()); - } - - - /** - * This method skips creating new island objects and return existing ones. - * @param uniqueId Island Unique ID. - * @return Likes Object for current island or null. - */ - public LikesObject getExistingIslandLikes(String uniqueId) - { - return this.likesCache.getOrDefault(uniqueId, null); - } - - -// --------------------------------------------------------------------- -// Section: Save methods -// --------------------------------------------------------------------- - - - /** - * This method saves all cached values into database. - */ - public void save() - { - this.likesCache.values().forEach(this.likesDatabase::saveObject); - } - - -// --------------------------------------------------------------------- -// Section: Wipe methods -// --------------------------------------------------------------------- - - - /** - * This method removes all data from database that referee to given world. - */ - public void wipeData(World world) - { - String gameMode = Utils.getGameMode(world); - - // Empty sorted cache - this.sortedLikeCache.remove(gameMode); - this.sortedDislikeCache.remove(gameMode); - this.sortedRankCache.remove(gameMode); - - // Remove from database - this.likesDatabase.loadObjects().stream(). - filter(likesObject -> gameMode.equalsIgnoreCase(likesObject.getGameMode())). - forEach(likesObject -> { - this.likesDatabase.deleteObject(likesObject); - this.likesCache.remove(likesObject.getUniqueId()); - }); - } - -// --------------------------------------------------------------------- -// Section: Like Methods -// --------------------------------------------------------------------- - - - /** - * This method adds like from given user to target island, in given world. - * @param user User who adds like. - * @param island Island which receive like. - * @param world World where island is located. - */ - public void addLike(User user, Island island, World world) - { - String gameMode = Utils.getGameMode(world); - LikesObject object = this.getIslandLikes(island.getUniqueId(), gameMode); - - if (!object.hasLiked(user.getUniqueId())) - { - object.addLike(user.getUniqueId()); - - // Log history - if (this.addon.getSettings().isLogHistory()) - { - object.addLogRecord(new LogEntry.Builder("ADD_LIKE"). - data("user-id", user.toString()). - build()); - } - - String name = island.getName() == null || island.getName().isEmpty() ? - this.addon.getPlayers().getName(island.getOwner()) : island.getName(); - - user.sendMessage(user.getTranslation(Constants.MESSAGE + "add-like", "[island]", name)); - - // Send message to users - if (this.addon.getSettings().isInformPlayers()) - { - island.getMemberSet().stream(). - map(User::getInstance). - filter(User::isOnline). - forEach(member -> member.sendMessage( - member.getTranslation(Constants.MESSAGE + "player-add-like", "[user]", user.getName()))); - } - - // Fire event - this.addon.callEvent(new LikeAddEvent(user.getUniqueId(), island.getUniqueId())); - } - } - - - /** - * This method removes like from given user to target island, in given world. - * @param user User who removes like. - * @param island Island which lost like. - * @param world World where island is located. - */ - public void removeLike(User user, Island island, World world) - { - String gameMode = Utils.getGameMode(world); - LikesObject object = this.getIslandLikes(island.getUniqueId(), gameMode); - - if (object.hasLiked(user.getUniqueId())) - { - object.removeLike(user.getUniqueId()); - - // Log history - if (this.addon.getSettings().isLogHistory()) - { - object.addLogRecord(new LogEntry.Builder("REMOVE_LIKE"). - data("user-id", user.toString()). - build()); - } - - String name = island.getName() == null || island.getName().isEmpty() ? - this.addon.getPlayers().getName(island.getOwner()) : island.getName(); - - user.sendMessage(user.getTranslation(Constants.MESSAGE + "remove-like", "[island]", name)); - - // Send message to users - if (this.addon.getSettings().isInformPlayers()) - { - island.getMemberSet().stream(). - map(User::getInstance). - filter(User::isOnline). - forEach(member -> member.sendMessage( - member.getTranslation(Constants.MESSAGE + "player-remove-like", "[user]", user.getName()))); - } - - // Fire event - this.addon.callEvent(new LikeRemoveEvent(user.getUniqueId(), island.getUniqueId())); - } - } - - - /** - * This method returns if given player has liked target island, in given world. - * @param user User which need to be checked. - * @param islandId Island which need to be checked. - * @param world World where island is located. - */ - public boolean hasLiked(UUID user, String islandId, World world) - { - return this.getIslandLikes(islandId, Utils.getGameMode(world)).hasLiked(user); - } - - - /** - * This method adds dislike from given user to target island, in given world. - * @param user User who adds dislike. - * @param island Island which receive dislike. - * @param world World where island is located. - */ - public void addDislike(User user, Island island, World world) - { - String gameMode = Utils.getGameMode(world); - LikesObject object = this.getIslandLikes(island.getUniqueId(), gameMode); - - if (!object.hasDisliked(user.getUniqueId())) - { - object.addDislike(user.getUniqueId()); - - // Log history - if (this.addon.getSettings().isLogHistory()) - { - object.addLogRecord(new LogEntry.Builder("ADD_DISLIKE"). - data("user-id", user.toString()). - build()); - } - - String name = island.getName() == null || island.getName().isEmpty() ? - this.addon.getPlayers().getName(island.getOwner()) : island.getName(); - - user.sendMessage(user.getTranslation(Constants.MESSAGE + "add-dislike", "[island]", name)); - - // Send message to users - if (this.addon.getSettings().isInformPlayers()) - { - island.getMemberSet().stream(). - map(User::getInstance). - filter(User::isOnline). - forEach(member -> member.sendMessage( - member.getTranslation(Constants.MESSAGE + "player-add-dislike", "[user]", user.getName()))); - } - - // Fire event - this.addon.callEvent(new DislikeAddEvent(user.getUniqueId(), island.getUniqueId())); - } - } - - - /** - * This method removes dislike from given user to target island, in given world. - * @param user User who adds dislike. - * @param island Island which lost dislike. - * @param world World where island is located. - */ - public void removeDislike(User user, Island island, World world) - { - String gameMode = Utils.getGameMode(world); - LikesObject object = this.getIslandLikes(island.getUniqueId(), gameMode); - - if (object.hasDisliked(user.getUniqueId())) - { - object.removeDislike(user.getUniqueId()); - - // Log history - if (this.addon.getSettings().isLogHistory()) - { - object.addLogRecord(new LogEntry.Builder("REMOVE_DISLIKE"). - data("user-id", user.toString()). - build()); - } - - String name = island.getName() == null || island.getName().isEmpty() ? - this.addon.getPlayers().getName(island.getOwner()) : island.getName(); - - user.sendMessage(user.getTranslation(Constants.MESSAGE + "remove-dislike", "[island]", name)); - - // Send message to users - if (this.addon.getSettings().isInformPlayers()) - { - island.getMemberSet().stream(). - map(User::getInstance). - filter(User::isOnline). - forEach(member -> member.sendMessage( - member.getTranslation(Constants.MESSAGE + "player-remove-dislike", "[user]", user.getName()))); - } - - // Fire event - this.addon.callEvent(new DislikeRemoveEvent(user.getUniqueId(), island.getUniqueId())); - } - } - - - /** - * This method returns if given player has disliked target island, in given world. - * @param user User which need to be checked. - * @param islandId Island which need to be checked. - * @param world World where island is located. - */ - public boolean hasDisliked(UUID user, String islandId, World world) - { - return this.getIslandLikes(islandId, Utils.getGameMode(world)).hasDisliked(user); - } - - - /** - * This method resets likes and dislikes for current island. - * @param user User who reset island. - * @param islandId Island Id. - * @param world World where island is located. - */ - public void resetLikes(UUID user, String islandId, World world) - { - String gameMode = Utils.getGameMode(world); - LikesObject object = this.getIslandLikes(islandId, gameMode); - - object.setLikes(0L); - object.setDislikes(0L); - - if (this.addon.getSettings().isLogHistory()) - { - object.addLogRecord( new LogEntry.Builder("RESET_ISLAND"). - data("user-id", user.toString()). - build()); - } - } - - -// --------------------------------------------------------------------- -// Section: Methods to get data -// --------------------------------------------------------------------- - - - /** - * This method returns top 10 islands by likes. - * @param world World where top list must be found. - * @return List that contains max 10 elements where ordered by likes. - */ - public List getTopByLikes(World world) - { - return this.getSortedLikes(world).stream().limit(10).filter(LikesObject::isNotEmpty).collect(Collectors.toList()); - } - - - /** - * This method returns top 10 islands by dislikes. - * @param world World where top list must be found. - * @return List that contains max 10 elements where ordered by dislikes. - */ - public List getTopByDislikes(World world) - { - return this.getSortedDislikes(world).stream().limit(10).filter(LikesObject::isNotEmpty).collect(Collectors.toList()); - } - - - /** - * This method returns top 10 islands by rank. - * @param world World where top list must be found. - * @return List that contains max 10 elements where ordered by rank. - */ - public List getTopByRank(World world) - { - return this.getSortedRank(world).stream().limit(10).filter(LikesObject::isNotEmpty).collect(Collectors.toList()); - } - - - /** - * This method returns Indexed Tree Set with Likes Object ordered by like count. - * @param world Target world - * @return Indexed Tree Set where likes objects are ordered by like count. - */ - public IndexedTreeSet getSortedLikes(World world) - { - return this.getSortedLikes(Utils.getGameMode(world)); - } - - - /** - * This method returns Indexed Tree Set with Likes Object ordered by like count. - * @param gameMode Target GameMode addon name. - * @return Indexed Tree Set where likes objects are ordered by like count. - */ - public IndexedTreeSet getSortedLikes(String gameMode) - { - return this.sortedLikeCache.containsKey(gameMode) ? - this.sortedLikeCache.get(gameMode) : - new IndexedTreeSet<>(); - } - - - /** - * This method returns Indexed Tree Set with Likes Object ordered by dislike count. - * @param world Target world - * @return Indexed Tree Set where likes objects are ordered by dislike count. - */ - public IndexedTreeSet getSortedDislikes(World world) - { - return this.getSortedDislikes(Utils.getGameMode(world)); - } - - - /** - * This method returns Indexed Tree Set with Likes Object ordered by dislike count. - * @param gameMode Target GameMode addon name. - * @return Indexed Tree Set where likes objects are ordered by dislike count. - */ - public IndexedTreeSet getSortedDislikes(String gameMode) - { - return this.sortedDislikeCache.containsKey(gameMode) ? - this.sortedDislikeCache.get(gameMode) : - new IndexedTreeSet<>(); - } - - - /** - * This method returns Indexed Tree Set with Likes Object ordered by rank. - * @param world Target world - * @return Indexed Tree Set where likes objects are ordered by rank. - */ - public IndexedTreeSet getSortedRank(World world) - { - return this.getSortedRank(Utils.getGameMode(world)); - } - - - /** - * This method returns Indexed Tree Set with Likes Object ordered by rank. - * @param gameMode Target GameMode addon name. - * @return Indexed Tree Set where likes objects are ordered by rank. - */ - public IndexedTreeSet getSortedRank(String gameMode) - { - return this.sortedRankCache.containsKey(gameMode) ? - this.sortedRankCache.get(gameMode) : - new IndexedTreeSet<>(); - } - - -// --------------------------------------------------------------------- -// Section: Instance Variables -// --------------------------------------------------------------------- - - - /** - * Likes Addon instance. - */ - private LikesAddon addon; - - /** - * This config object stores all likes objects. - */ - private Database likesDatabase; - - /** - * This map contains all likes object linked to their reference island. - * This will be faster way how to find out if island has or has not likes. - */ - private Map likesCache; - - /** - * This map links GameMode's to liked islands sorted by likes. - * It should be cached, because of PlaceHolders. - */ - private Map> sortedLikeCache; - - /** - * This map links GameMode's to liked islands sorted by dislikes. - * It should be cached, because of PlaceHolders. - */ - private Map> sortedDislikeCache; - - /** - * This map links GameMode's to liked islands sorted by rank. - * It should be cached, because of PlaceHolders. - */ - private Map> sortedRankCache; + // --------------------------------------------------------------------- + // Section: Constructor + // --------------------------------------------------------------------- + + + /** + * Default constructor. + * @param addon Likes Addon instance + */ + public LikesManager(LikesAddon addon) + { + this.addon = addon; + + this.likesDatabase = new Database<>(addon, LikesObject.class); + this.likesCache = new HashMap<>(); + + this.sortedDislikeCache = new HashMap<>(); + this.sortedLikeCache = new HashMap<>(); + this.sortedRankCache = new HashMap<>(); + + this.load(); + } + + + // --------------------------------------------------------------------- + // Section: Load Methods + // --------------------------------------------------------------------- + + + /** + * This method loads all like objects. + */ + public void load() + { + this.likesCache.clear(); + + this.sortedLikeCache.clear(); + this.sortedDislikeCache.clear(); + this.sortedRankCache.clear(); + + this.addon.getLogger().info("Loading likes..."); + + this.likesDatabase.loadObjects().forEach(this::load); + } + + + /** + * This method loads given likeObject inside cache. + * @param likesObject Object that must be added to cache. + */ + private void load(LikesObject likesObject) + { + // Add object into Island to LikeObject cache. + this.likesCache.put(likesObject.getUniqueId(), likesObject); + + // Add object into GameMode to sorted by likes cache. + this.sortedLikeCache.computeIfAbsent(likesObject.getGameMode(), + gameMode -> new IndexedTreeSet<>(Comparator.comparing(LikesObject::getLikes).reversed(). + thenComparing(LikesObject::getDislikes). + thenComparing(LikesObject::getUniqueId))).add(likesObject); + + // Add object into GameMode to sorted by dislikes cache. + this.sortedDislikeCache.computeIfAbsent(likesObject.getGameMode(), + gameMode -> new IndexedTreeSet<>(Comparator.comparing(LikesObject::getDislikes).reversed(). + thenComparing(LikesObject::getLikes). + thenComparing(LikesObject::getUniqueId))).add(likesObject); + + // Add object into GameMode to sorted by rank cache. + this.sortedRankCache.computeIfAbsent(likesObject.getGameMode(), + gameMode -> new IndexedTreeSet<>(Comparator.comparing(LikesObject::getRank).reversed(). + thenComparing(LikesObject::getLikes).reversed(). + thenComparing(LikesObject::getDislikes).reversed(). + thenComparing(LikesObject::getUniqueId))).add(likesObject); + } + + + + /** + * This method checks if likes object with given UniqueId exist in database. + * If not, it creates new object for that. + * + * @param uniqueID - uniqueID to add + * @param gameMode - gameMode for like object. + */ + @NonNull + private LikesObject getIslandLikes(@NonNull String uniqueID, String gameMode) + { + if (this.likesCache.containsKey(uniqueID)) + { + return this.likesCache.get(uniqueID); + } + + // The player is not in the cache + // Check if the player exists in the database + + if (this.likesDatabase.objectExists(uniqueID)) + { + // Load player from database + LikesObject data = this.likesDatabase.loadObject(uniqueID); + // Store in cache + if (data != null) + { + this.load(data); + return data; + } + this.addon.logError("Could not load NULL likes data object for " + uniqueID + " in " + gameMode); + + } + return newPlayer(gameMode, uniqueID); + } + + + private LikesObject newPlayer(String gameMode, @NonNull String uniqueID) { + // Create the likes data + LikesObject likesObject = new LikesObject(); + likesObject.setUniqueId(uniqueID); + likesObject.setGameMode(gameMode); + + this.likesDatabase.saveObject(likesObject); + // Add to cache + this.load(likesObject); + + return likesObject; + } + + + /** + * This method returns Island Likes Object from cache or create new one. + * @param islandId IslandId which LikesObject must be returned. + * @param world Target world. + * @return Likes Object for given island. + */ + public LikesObject getIslandLikes(String islandId, World world) + { + return this.getIslandLikes(islandId, Utils.getGameMode(world)); + } + + + /** + * This method returns Island Likes Object from cache or create new one. + * @param islandId IslandId which LikesObject must be returned. + * @param gameModeAddon Target GameMode addon. + * @return Likes Object for given island. + */ + public LikesObject getIslandLikes(String islandId, GameModeAddon gameModeAddon) + { + return this.getIslandLikes(islandId, gameModeAddon.getDescription().getName()); + } + + + /** + * This method skips creating new island objects and return existing ones. + * @param uniqueId Island Unique ID. + * @return Likes Object for current island or null. + */ + public LikesObject getExistingIslandLikes(String uniqueId) + { + return this.likesCache.getOrDefault(uniqueId, null); + } + + + // --------------------------------------------------------------------- + // Section: Save methods + // --------------------------------------------------------------------- + + + /** + * This method saves all cached values into database. + */ + public void save() + { + this.likesCache.values().forEach(this.likesDatabase::saveObject); + } + + + // --------------------------------------------------------------------- + // Section: Wipe methods + // --------------------------------------------------------------------- + + + /** + * This method removes all data from database that referee to given world. + */ + public void wipeData(World world) + { + String gameMode = Utils.getGameMode(world); + + // Empty sorted cache + this.sortedLikeCache.remove(gameMode); + this.sortedDislikeCache.remove(gameMode); + this.sortedRankCache.remove(gameMode); + + // Remove from database + this.likesDatabase.loadObjects().stream(). + filter(likesObject -> gameMode.equalsIgnoreCase(likesObject.getGameMode())). + forEach(likesObject -> { + this.likesDatabase.deleteObject(likesObject); + this.likesCache.remove(likesObject.getUniqueId()); + }); + } + + // --------------------------------------------------------------------- + // Section: Like Methods + // --------------------------------------------------------------------- + + + /** + * This method adds like from given user to target island, in given world. + * @param user User who adds like. + * @param island Island which receive like. + * @param world World where island is located. + */ + public void addLike(User user, Island island, World world) + { + String gameMode = Utils.getGameMode(world); + LikesObject object = this.getIslandLikes(island.getUniqueId(), gameMode); + + if (!object.hasLiked(user.getUniqueId())) + { + object.addLike(user.getUniqueId()); + + // Log history + if (this.addon.getSettings().isLogHistory()) + { + object.addLogRecord(new LogEntry.Builder("ADD_LIKE"). + data("user-id", user.toString()). + build()); + } + + String name = island.getName() == null || island.getName().isEmpty() ? + this.addon.getPlayers().getName(island.getOwner()) : island.getName(); + + user.sendMessage(user.getTranslation(Constants.MESSAGE + "add-like", "[island]", name)); + + // Send message to users + if (this.addon.getSettings().isInformPlayers()) + { + island.getMemberSet().stream(). + map(User::getInstance). + filter(User::isOnline). + forEach(member -> member.sendMessage( + member.getTranslation(Constants.MESSAGE + "player-add-like", "[user]", user.getName()))); + } + + // Fire event + this.addon.callEvent(new LikeAddEvent(user.getUniqueId(), island.getUniqueId())); + } + } + + + /** + * This method removes like from given user to target island, in given world. + * @param user User who removes like. + * @param island Island which lost like. + * @param world World where island is located. + */ + public void removeLike(User user, Island island, World world) + { + String gameMode = Utils.getGameMode(world); + LikesObject object = this.getIslandLikes(island.getUniqueId(), gameMode); + + if (object.hasLiked(user.getUniqueId())) + { + object.removeLike(user.getUniqueId()); + + // Log history + if (this.addon.getSettings().isLogHistory()) + { + object.addLogRecord(new LogEntry.Builder("REMOVE_LIKE"). + data("user-id", user.toString()). + build()); + } + + String name = island.getName() == null || island.getName().isEmpty() ? + this.addon.getPlayers().getName(island.getOwner()) : island.getName(); + + user.sendMessage(user.getTranslation(Constants.MESSAGE + "remove-like", "[island]", name)); + + // Send message to users + if (this.addon.getSettings().isInformPlayers()) + { + island.getMemberSet().stream(). + map(User::getInstance). + filter(User::isOnline). + forEach(member -> member.sendMessage( + member.getTranslation(Constants.MESSAGE + "player-remove-like", "[user]", user.getName()))); + } + + // Fire event + this.addon.callEvent(new LikeRemoveEvent(user.getUniqueId(), island.getUniqueId())); + } + } + + + /** + * This method returns if given player has liked target island, in given world. + * @param user User which need to be checked. + * @param islandId Island which need to be checked. + * @param world World where island is located. + */ + public boolean hasLiked(UUID user, String islandId, World world) + { + return this.getIslandLikes(islandId, Utils.getGameMode(world)).hasLiked(user); + } + + + /** + * This method adds dislike from given user to target island, in given world. + * @param user User who adds dislike. + * @param island Island which receive dislike. + * @param world World where island is located. + */ + public void addDislike(User user, Island island, World world) + { + String gameMode = Utils.getGameMode(world); + LikesObject object = this.getIslandLikes(island.getUniqueId(), gameMode); + + if (!object.hasDisliked(user.getUniqueId())) + { + object.addDislike(user.getUniqueId()); + + // Log history + if (this.addon.getSettings().isLogHistory()) + { + object.addLogRecord(new LogEntry.Builder("ADD_DISLIKE"). + data("user-id", user.toString()). + build()); + } + + String name = island.getName() == null || island.getName().isEmpty() ? + this.addon.getPlayers().getName(island.getOwner()) : island.getName(); + + user.sendMessage(user.getTranslation(Constants.MESSAGE + "add-dislike", "[island]", name)); + + // Send message to users + if (this.addon.getSettings().isInformPlayers()) + { + island.getMemberSet().stream(). + map(User::getInstance). + filter(User::isOnline). + forEach(member -> member.sendMessage( + member.getTranslation(Constants.MESSAGE + "player-add-dislike", "[user]", user.getName()))); + } + + // Fire event + this.addon.callEvent(new DislikeAddEvent(user.getUniqueId(), island.getUniqueId())); + } + } + + + /** + * This method removes dislike from given user to target island, in given world. + * @param user User who adds dislike. + * @param island Island which lost dislike. + * @param world World where island is located. + */ + public void removeDislike(User user, Island island, World world) + { + String gameMode = Utils.getGameMode(world); + LikesObject object = this.getIslandLikes(island.getUniqueId(), gameMode); + + if (object.hasDisliked(user.getUniqueId())) + { + object.removeDislike(user.getUniqueId()); + + // Log history + if (this.addon.getSettings().isLogHistory()) + { + object.addLogRecord(new LogEntry.Builder("REMOVE_DISLIKE"). + data("user-id", user.toString()). + build()); + } + + String name = island.getName() == null || island.getName().isEmpty() ? + this.addon.getPlayers().getName(island.getOwner()) : island.getName(); + + user.sendMessage(user.getTranslation(Constants.MESSAGE + "remove-dislike", "[island]", name)); + + // Send message to users + if (this.addon.getSettings().isInformPlayers()) + { + island.getMemberSet().stream(). + map(User::getInstance). + filter(User::isOnline). + forEach(member -> member.sendMessage( + member.getTranslation(Constants.MESSAGE + "player-remove-dislike", "[user]", user.getName()))); + } + + // Fire event + this.addon.callEvent(new DislikeRemoveEvent(user.getUniqueId(), island.getUniqueId())); + } + } + + + /** + * This method returns if given player has disliked target island, in given world. + * @param user User which need to be checked. + * @param islandId Island which need to be checked. + * @param world World where island is located. + */ + public boolean hasDisliked(UUID user, String islandId, World world) + { + return this.getIslandLikes(islandId, Utils.getGameMode(world)).hasDisliked(user); + } + + + /** + * This method resets likes and dislikes for current island. + * @param user User who reset island. + * @param islandId Island Id. + * @param world World where island is located. + */ + public void resetLikes(UUID user, String islandId, World world) + { + String gameMode = Utils.getGameMode(world); + LikesObject object = this.getIslandLikes(islandId, gameMode); + + object.setLikes(0L); + object.setDislikes(0L); + + if (this.addon.getSettings().isLogHistory()) + { + object.addLogRecord( new LogEntry.Builder("RESET_ISLAND"). + data("user-id", user.toString()). + build()); + } + } + + + // --------------------------------------------------------------------- + // Section: Methods to get data + // --------------------------------------------------------------------- + + + /** + * This method returns top 10 islands by likes. + * @param world World where top list must be found. + * @return List that contains max 10 elements where ordered by likes. + */ + public List getTopByLikes(World world) + { + return this.getSortedLikes(world).stream().limit(10).filter(LikesObject::isNotEmpty).collect(Collectors.toList()); + } + + + /** + * This method returns top 10 islands by dislikes. + * @param world World where top list must be found. + * @return List that contains max 10 elements where ordered by dislikes. + */ + public List getTopByDislikes(World world) + { + return this.getSortedDislikes(world).stream().limit(10).filter(LikesObject::isNotEmpty).collect(Collectors.toList()); + } + + + /** + * This method returns top 10 islands by rank. + * @param world World where top list must be found. + * @return List that contains max 10 elements where ordered by rank. + */ + public List getTopByRank(World world) + { + return this.getSortedRank(world).stream().limit(10).filter(LikesObject::isNotEmpty).collect(Collectors.toList()); + } + + + /** + * This method returns Indexed Tree Set with Likes Object ordered by like count. + * @param world Target world + * @return Indexed Tree Set where likes objects are ordered by like count. + */ + public IndexedTreeSet getSortedLikes(World world) + { + return this.getSortedLikes(Utils.getGameMode(world)); + } + + + /** + * This method returns Indexed Tree Set with Likes Object ordered by like count. + * @param gameMode Target GameMode addon name. + * @return Indexed Tree Set where likes objects are ordered by like count. + */ + public IndexedTreeSet getSortedLikes(String gameMode) + { + return this.sortedLikeCache.containsKey(gameMode) ? + this.sortedLikeCache.get(gameMode) : + new IndexedTreeSet<>(); + } + + + /** + * This method returns Indexed Tree Set with Likes Object ordered by dislike count. + * @param world Target world + * @return Indexed Tree Set where likes objects are ordered by dislike count. + */ + public IndexedTreeSet getSortedDislikes(World world) + { + return this.getSortedDislikes(Utils.getGameMode(world)); + } + + + /** + * This method returns Indexed Tree Set with Likes Object ordered by dislike count. + * @param gameMode Target GameMode addon name. + * @return Indexed Tree Set where likes objects are ordered by dislike count. + */ + public IndexedTreeSet getSortedDislikes(String gameMode) + { + return this.sortedDislikeCache.containsKey(gameMode) ? + this.sortedDislikeCache.get(gameMode) : + new IndexedTreeSet<>(); + } + + + /** + * This method returns Indexed Tree Set with Likes Object ordered by rank. + * @param world Target world + * @return Indexed Tree Set where likes objects are ordered by rank. + */ + public IndexedTreeSet getSortedRank(World world) + { + return this.getSortedRank(Utils.getGameMode(world)); + } + + + /** + * This method returns Indexed Tree Set with Likes Object ordered by rank. + * @param gameMode Target GameMode addon name. + * @return Indexed Tree Set where likes objects are ordered by rank. + */ + public IndexedTreeSet getSortedRank(String gameMode) + { + return this.sortedRankCache.containsKey(gameMode) ? + this.sortedRankCache.get(gameMode) : + new IndexedTreeSet<>(); + } + + + // --------------------------------------------------------------------- + // Section: Instance Variables + // --------------------------------------------------------------------- + + + /** + * Likes Addon instance. + */ + private LikesAddon addon; + + /** + * This config object stores all likes objects. + */ + private Database likesDatabase; + + /** + * This map contains all likes object linked to their reference island. + * This will be faster way how to find out if island has or has not likes. + */ + private Map likesCache; + + /** + * This map links GameMode's to liked islands sorted by likes. + * It should be cached, because of PlaceHolders. + */ + private Map> sortedLikeCache; + + /** + * This map links GameMode's to liked islands sorted by dislikes. + * It should be cached, because of PlaceHolders. + */ + private Map> sortedDislikeCache; + + /** + * This map links GameMode's to liked islands sorted by rank. + * It should be cached, because of PlaceHolders. + */ + private Map> sortedRankCache; } diff --git a/src/main/java/world/bentobox/likes/panels/admin/AdminViewPanel.java b/src/main/java/world/bentobox/likes/panels/admin/AdminViewPanel.java index de546f5..b8c771f 100644 --- a/src/main/java/world/bentobox/likes/panels/admin/AdminViewPanel.java +++ b/src/main/java/world/bentobox/likes/panels/admin/AdminViewPanel.java @@ -34,524 +34,524 @@ */ public class AdminViewPanel extends CommonPanel { - /** - * This is internal constructor. It is used internally in current class to avoid - * creating objects everywhere. - * @param parent Parent Panel - * @param island Island which View panel must be opened. - */ - private AdminViewPanel(@NonNull CommonPanel parent, - @NonNull Island island) - { - super(parent); - - // Create new object if it does not exist as admin is editing it. - this.likesObject = this.addon.getManager().getIslandLikes(island.getUniqueId(), this.world); - - this.likedByUsers = this.likesObject.getLikedBy().stream(). - map(uuid -> this.addon.getPlayers().getName(uuid)). - sorted(String::compareToIgnoreCase). - collect(Collectors.toList()); - - this.dislikedByUsers = this.likesObject.getDislikedBy().stream(). - map(uuid -> this.addon.getPlayers().getName(uuid)). - sorted(String::compareToIgnoreCase). - collect(Collectors.toList()); - - this.likeRank = this.addon.getManager().getSortedLikes(this.world).entryIndex(this.likesObject) + 1; - this.dislikeRank = this.addon.getManager().getSortedDislikes(this.world).entryIndex(this.likesObject) + 1; - this.overallRank = this.addon.getManager().getSortedRank(this.world).entryIndex(this.likesObject) + 1; - } - - - /** - * This method is used to open UserPanel outside this class. It will be much easier - * to open panel with single method call then initializing new object. - * @param parent Parent Panel - * @param island Island which View panel must be opened. - */ - public static void openPanel(@NonNull CommonPanel parent, - @NonNull Island island) - { - new AdminViewPanel(parent, island).build(); - } - - -// --------------------------------------------------------------------- -// Section: Methods -// --------------------------------------------------------------------- - - - @Override - protected void build() - { - PanelBuilder panelBuilder = new PanelBuilder(). - name(this.user.getTranslation(Constants.TITLE + "edit-view")). - user(this.user); - - GuiUtils.fillBorder(panelBuilder, 6, Material.MAGENTA_STAINED_GLASS_PANE); - - panelBuilder.item(2, this.createButton(Button.ADD_LIKE_USER)); - panelBuilder.item(3, this.createButton(Button.REMOVE_LIKE_USER)); - - panelBuilder.item(5, this.createButton(Button.ADD_DISLIKE_USER)); - panelBuilder.item(6, this.createButton(Button.REMOVE_DISLIKE_USER)); - - panelBuilder.item(10, this.createButton(Button.LIKE)); - panelBuilder.item(11, this.createButton(Button.LIKE_RANK)); - - panelBuilder.item(15, this.createButton(Button.OVERALL)); - panelBuilder.item(16, this.createButton(Button.OVERALL_RANK)); - - this.populateLikers(panelBuilder); - - panelBuilder.item(28, this.createButton(Button.DISLIKE)); - panelBuilder.item(29, this.createButton(Button.DISLIKE_RANK)); - - this.populateDislikers(panelBuilder); - - panelBuilder.item(53, this.returnButton); - - // At the end we just call build method that creates and opens panel. - panelBuilder.build(); - } - - - /** - * This method creates PanelItem button based on given button type. - * @param button Button that must be created. - * @return PanelItem object that represents given button. - */ - private PanelItem createButton(Button button) - { - ItemStack icon; - String name; - List description; - PanelItem.ClickHandler clickHandler; - - switch (button) - { - case LIKE: - { - icon = new ItemStack(Material.GOLD_INGOT); - name = this.user.getTranslation(Constants.BUTTON + "like"); - - description = new ArrayList<>(2); - description.add(this.user.getTranslation(Constants.DESCRIPTION + "like")); - description.add(this.user.getTranslation(Constants.DESCRIPTION + "current-value", - "[value]", - this.likesObject.getLikes() + "")); - - clickHandler = null; - - break; - } - case LIKE_RANK: - { - icon = new ItemStack(Material.GOLD_BLOCK); - name = this.user.getTranslation(Constants.BUTTON + "like-rank"); - - description = new ArrayList<>(2); - description.add(this.user.getTranslation(Constants.DESCRIPTION + "like-rank")); - description.add(this.user.getTranslation(Constants.DESCRIPTION + "current-value", - "[value]", - this.likeRank + "")); - - clickHandler = null; - - break; - } - case DISLIKE: - { - icon = new ItemStack(Material.IRON_INGOT); - name = this.user.getTranslation(Constants.BUTTON + "dislike"); - - description = new ArrayList<>(2); - description.add(this.user.getTranslation(Constants.DESCRIPTION + "dislike")); - description.add(this.user.getTranslation(Constants.DESCRIPTION + "current-value", - "[value]", - this.likesObject.getDislikes() + "")); - - clickHandler = null; - - break; - } - case DISLIKE_RANK: - { - icon = new ItemStack(Material.IRON_BLOCK); - name = this.user.getTranslation(Constants.BUTTON + "dislike-rank"); - - description = new ArrayList<>(2); - description.add(this.user.getTranslation(Constants.DESCRIPTION + "dislike-rank")); - description.add(this.user.getTranslation(Constants.DESCRIPTION + "current-value", - "[value]", - this.dislikeRank + "")); - - clickHandler = null; - - break; - } - case OVERALL: - { - icon = new ItemStack(Material.DIAMOND); - name = this.user.getTranslation(Constants.BUTTON + "overall"); - - description = new ArrayList<>(2); - description.add(this.user.getTranslation(Constants.DESCRIPTION + "overall")); - description.add(this.user.getTranslation(Constants.DESCRIPTION + "current-value", - "[value]", - this.likesObject.getRank() + "")); - - clickHandler = null; - - break; - } - case OVERALL_RANK: - { - icon = new ItemStack(Material.DIAMOND_BLOCK); - name = this.user.getTranslation(Constants.BUTTON + "overall-rank"); - - description = new ArrayList<>(2); - description.add(this.user.getTranslation(Constants.DESCRIPTION + "overall-rank")); - description.add(this.user.getTranslation(Constants.DESCRIPTION + "current-value", - "[value]", - this.overallRank + "")); - - clickHandler = null; - - break; - } - case NEXT_LIKE: - { - icon = new ItemStack(Material.OAK_SIGN); - name = this.user.getTranslation(Constants.BUTTON + "next"); - description = new ArrayList<>(1); - description.add(this.user.getTranslation(Constants.DESCRIPTION + "like-next")); - - clickHandler = (panel, user, clickType, slot) -> { - this.likeOffset++; - this.build(); - return true; - }; - - break; - } - case PREVIOUS_LIKE: - { - icon = new ItemStack(Material.OAK_SIGN); - name = this.user.getTranslation(Constants.BUTTON + "previous"); - description = new ArrayList<>(1); - description.add(this.user.getTranslation(Constants.DESCRIPTION + "like-previous")); - - clickHandler = (panel, user, clickType, slot) -> { - this.likeOffset--; - this.build(); - return true; - }; - - break; - } - case NEXT_DISLIKE: - { - icon = new ItemStack(Material.OAK_SIGN); - name = this.user.getTranslation(Constants.BUTTON + "next"); - description = new ArrayList<>(1); - description.add(this.user.getTranslation(Constants.DESCRIPTION + "dislike-next")); - - clickHandler = (panel, user, clickType, slot) -> { - this.dislikeOffset++; - this.build(); - return true; - }; - - break; - } - case PREVIOUS_DISLIKE: - { - icon = new ItemStack(Material.OAK_SIGN); - name = this.user.getTranslation(Constants.BUTTON + "previous"); - description = new ArrayList<>(1); - description.add(this.user.getTranslation(Constants.DESCRIPTION + "dislike-previous")); - - clickHandler = (panel, user, clickType, slot) -> { - this.dislikeOffset--; - this.build(); - return true; - }; - - break; - } - case ADD_LIKE_USER: - { - icon = new ItemStack(Material.GOLD_NUGGET); - name = this.user.getTranslation(Constants.BUTTON + "add-like-user"); - description = new ArrayList<>(1); - - clickHandler = (panel, user, clickType, slot) -> { - SelectUserGUI.open(user, - this.getOnlineUserList(), - this.convertToUserList(this.likesObject.getLikedBy()), - player -> { - if (player != null) - { - if (this.likesObject.hasDisliked(player.getUniqueId())) - { - this.dislikedByUsers.remove(player.getName()); - } - - this.likesObject.addLike(player.getUniqueId()); - this.likedByUsers.add(player.getName()); - } - - this.build(); - }); - return true; - }; - - break; - } - case REMOVE_LIKE_USER: - { - icon = new ItemStack(Material.LAVA_BUCKET); - name = this.user.getTranslation(Constants.BUTTON + "remove-like-user"); - description = new ArrayList<>(1); - - clickHandler = (panel, user, clickType, slot) -> { - SelectUserGUI.open(user, - this.convertToUserList(this.likesObject.getLikedBy()), - player -> { - if (player != null) - { - this.likesObject.removeLike(player.getUniqueId()); - this.likedByUsers.remove(player.getName()); - } - - this.build(); - }); - return true; - }; - - break; - } - case ADD_DISLIKE_USER: - { - icon = new ItemStack(Material.IRON_NUGGET); - name = this.user.getTranslation(Constants.BUTTON + "add-dislike-user"); - description = new ArrayList<>(1); - - clickHandler = (panel, user, clickType, slot) -> { - SelectUserGUI.open(user, - this.getOnlineUserList(), - this.convertToUserList(this.likesObject.getDislikedBy()), - player -> { - if (player != null) - { - if (this.likesObject.hasLiked(player.getUniqueId())) - { - this.likedByUsers.remove(player.getName()); - } - - this.likesObject.addDislike(player.getUniqueId()); - this.dislikedByUsers.add(player.getName()); - } - - this.build(); - }); - return true; - }; - - break; - } - case REMOVE_DISLIKE_USER: - { - icon = new ItemStack(Material.LAVA_BUCKET); - name = this.user.getTranslation(Constants.BUTTON + "remove-dislike-user"); - description = new ArrayList<>(1); - - clickHandler = (panel, user, clickType, slot) -> { - SelectUserGUI.open(user, - this.convertToUserList(this.likesObject.getDislikedBy()), - player -> { - if (player != null) - { - this.likesObject.removeDislike(player.getUniqueId()); - this.dislikedByUsers.remove(player.getName()); - } - - this.build(); - }); - return true; - }; - - break; - } - default: - return null; - } - - return new PanelItemBuilder(). - icon(icon). - name(name). - description(GuiUtils.stringSplit(description, 999)). - glow(false). - clickHandler(clickHandler). - build(); - } - - - /** - * This method populates all likers into given panel builder. - * @param panelBuilder PanelBuilder object. - */ - private void populateLikers(PanelBuilder panelBuilder) - { - if (this.likeOffset > 0) - { - panelBuilder.item(18, this.createButton(Button.PREVIOUS_LIKE)); - } - - if ((this.likeOffset + 1) * 7 < this.likesObject.getLikes()) - { - panelBuilder.item(26, this.createButton(Button.NEXT_LIKE)); - } - - final int startIndex = this.likeOffset * 7; - - for (int index = 0; index < 7 && startIndex + index < this.likesObject.getLikes(); index++) - { - String userName = this.likedByUsers.get(startIndex + index); - - panelBuilder.item(19 + index, new PanelItemBuilder(). - icon(userName). - glow(false). - build()); - } - } - - - /** - * This method populates all dislikers into given panel builder. - * @param panelBuilder PanelBuilder object. - */ - private void populateDislikers(PanelBuilder panelBuilder) - { - if (this.dislikeOffset > 0) - { - panelBuilder.item(36, this.createButton(Button.PREVIOUS_DISLIKE)); - } - - if ((this.dislikeOffset + 1) * 7 < this.likesObject.getDislikes()) - { - panelBuilder.item(44, this.createButton(Button.NEXT_DISLIKE)); - } - - final int startIndex = this.dislikeOffset * 7; - - for (int index = 0; index < 7 && startIndex + index < this.likesObject.getDislikes(); index++) - { - String userName = this.dislikedByUsers.get(startIndex + index); - - panelBuilder.item(37 + index, new PanelItemBuilder(). - icon(userName). - glow(false). - build()); - } - } - - - /** - * This method returns list that contains all online users. - * @return Online User List. - */ - private List getOnlineUserList() - { - return Bukkit.getOnlinePlayers().stream().map(User::getInstance).collect(Collectors.toList()); - } - - - /** - * This method converts and returns given set with UUIDs to User list. - * @param userSet Set that must be converted. - * @return Converted User List. - */ - private List convertToUserList(Set userSet) - { - return userSet.stream().map(User::getInstance).collect(Collectors.toList()); - } - - -// --------------------------------------------------------------------- -// Section: Enums -// --------------------------------------------------------------------- - - - /** - * This enum holds all action buttons that can be added in current gui. - */ - private enum Button - { - LIKE, - LIKE_RANK, - DISLIKE, - DISLIKE_RANK, - OVERALL, - OVERALL_RANK, - - NEXT_LIKE, - PREVIOUS_LIKE, - - NEXT_DISLIKE, - PREVIOUS_DISLIKE, - - ADD_LIKE_USER, - REMOVE_LIKE_USER, - ADD_DISLIKE_USER, - REMOVE_DISLIKE_USER - } - - -// --------------------------------------------------------------------- -// Section: Variables -// --------------------------------------------------------------------- - - - /** - * This variable holds likes object that is view by user in current gui. - */ - private final LikesObject likesObject; - - /** - * This variable stores index of current liker. - */ - private int likeOffset; - - /** - * This variable stores index of current disliker. - */ - private int dislikeOffset; - - /** - * This list contains player names that liked current island. - */ - private final List likedByUsers; - - /** - * This list contains player names that disliked current island. - */ - private final List dislikedByUsers; - - /** - * This variable holds island rank by likes. - */ - private final long likeRank; - - /** - * This variable holds island rank by dislikes. - */ - private final long dislikeRank; - - /** - * This variable holds island rank by rank. - */ - private final long overallRank; + /** + * This is internal constructor. It is used internally in current class to avoid + * creating objects everywhere. + * @param parent Parent Panel + * @param island Island which View panel must be opened. + */ + private AdminViewPanel(@NonNull CommonPanel parent, + @NonNull Island island) + { + super(parent); + + // Create new object if it does not exist as admin is editing it. + this.likesObject = this.addon.getManager().getIslandLikes(island.getUniqueId(), this.world); + + this.likedByUsers = this.likesObject.getLikedBy().stream(). + map(uuid -> this.addon.getPlayers().getName(uuid)). + sorted(String::compareToIgnoreCase). + collect(Collectors.toList()); + + this.dislikedByUsers = this.likesObject.getDislikedBy().stream(). + map(uuid -> this.addon.getPlayers().getName(uuid)). + sorted(String::compareToIgnoreCase). + collect(Collectors.toList()); + + this.likeRank = this.addon.getManager().getSortedLikes(this.world).entryIndex(this.likesObject) + 1L; + this.dislikeRank = this.addon.getManager().getSortedDislikes(this.world).entryIndex(this.likesObject) + 1L; + this.overallRank = this.addon.getManager().getSortedRank(this.world).entryIndex(this.likesObject) + 1L; + } + + + /** + * This method is used to open UserPanel outside this class. It will be much easier + * to open panel with single method call then initializing new object. + * @param parent Parent Panel + * @param island Island which View panel must be opened. + */ + public static void openPanel(@NonNull CommonPanel parent, + @NonNull Island island) + { + new AdminViewPanel(parent, island).build(); + } + + + // --------------------------------------------------------------------- + // Section: Methods + // --------------------------------------------------------------------- + + + @Override + protected void build() + { + PanelBuilder panelBuilder = new PanelBuilder(). + name(this.user.getTranslation(Constants.TITLE + "edit-view")). + user(this.user); + + GuiUtils.fillBorder(panelBuilder, 6, Material.MAGENTA_STAINED_GLASS_PANE); + + panelBuilder.item(2, this.createButton(Button.ADD_LIKE_USER)); + panelBuilder.item(3, this.createButton(Button.REMOVE_LIKE_USER)); + + panelBuilder.item(5, this.createButton(Button.ADD_DISLIKE_USER)); + panelBuilder.item(6, this.createButton(Button.REMOVE_DISLIKE_USER)); + + panelBuilder.item(10, this.createButton(Button.LIKE)); + panelBuilder.item(11, this.createButton(Button.LIKE_RANK)); + + panelBuilder.item(15, this.createButton(Button.OVERALL)); + panelBuilder.item(16, this.createButton(Button.OVERALL_RANK)); + + this.populateLikers(panelBuilder); + + panelBuilder.item(28, this.createButton(Button.DISLIKE)); + panelBuilder.item(29, this.createButton(Button.DISLIKE_RANK)); + + this.populateDislikers(panelBuilder); + + panelBuilder.item(53, this.returnButton); + + // At the end we just call build method that creates and opens panel. + panelBuilder.build(); + } + + + /** + * This method creates PanelItem button based on given button type. + * @param button Button that must be created. + * @return PanelItem object that represents given button. + */ + private PanelItem createButton(Button button) + { + ItemStack icon; + String name; + List description; + PanelItem.ClickHandler clickHandler; + + switch (button) + { + case LIKE: + { + icon = new ItemStack(Material.GOLD_INGOT); + name = this.user.getTranslation(Constants.BUTTON + "like"); + + description = new ArrayList<>(2); + description.add(this.user.getTranslation(Constants.DESCRIPTION + "like")); + description.add(this.user.getTranslation(Constants.DESCRIPTION + "current-value", + "[value]", + this.likesObject.getLikes() + "")); + + clickHandler = null; + + break; + } + case LIKE_RANK: + { + icon = new ItemStack(Material.GOLD_BLOCK); + name = this.user.getTranslation(Constants.BUTTON + "like-rank"); + + description = new ArrayList<>(2); + description.add(this.user.getTranslation(Constants.DESCRIPTION + "like-rank")); + description.add(this.user.getTranslation(Constants.DESCRIPTION + "current-value", + "[value]", + this.likeRank + "")); + + clickHandler = null; + + break; + } + case DISLIKE: + { + icon = new ItemStack(Material.IRON_INGOT); + name = this.user.getTranslation(Constants.BUTTON + "dislike"); + + description = new ArrayList<>(2); + description.add(this.user.getTranslation(Constants.DESCRIPTION + "dislike")); + description.add(this.user.getTranslation(Constants.DESCRIPTION + "current-value", + "[value]", + this.likesObject.getDislikes() + "")); + + clickHandler = null; + + break; + } + case DISLIKE_RANK: + { + icon = new ItemStack(Material.IRON_BLOCK); + name = this.user.getTranslation(Constants.BUTTON + "dislike-rank"); + + description = new ArrayList<>(2); + description.add(this.user.getTranslation(Constants.DESCRIPTION + "dislike-rank")); + description.add(this.user.getTranslation(Constants.DESCRIPTION + "current-value", + "[value]", + this.dislikeRank + "")); + + clickHandler = null; + + break; + } + case OVERALL: + { + icon = new ItemStack(Material.DIAMOND); + name = this.user.getTranslation(Constants.BUTTON + "overall"); + + description = new ArrayList<>(2); + description.add(this.user.getTranslation(Constants.DESCRIPTION + "overall")); + description.add(this.user.getTranslation(Constants.DESCRIPTION + "current-value", + "[value]", + this.likesObject.getRank() + "")); + + clickHandler = null; + + break; + } + case OVERALL_RANK: + { + icon = new ItemStack(Material.DIAMOND_BLOCK); + name = this.user.getTranslation(Constants.BUTTON + "overall-rank"); + + description = new ArrayList<>(2); + description.add(this.user.getTranslation(Constants.DESCRIPTION + "overall-rank")); + description.add(this.user.getTranslation(Constants.DESCRIPTION + "current-value", + "[value]", + this.overallRank + "")); + + clickHandler = null; + + break; + } + case NEXT_LIKE: + { + icon = new ItemStack(Material.OAK_SIGN); + name = this.user.getTranslation(Constants.BUTTON + "next"); + description = new ArrayList<>(1); + description.add(this.user.getTranslation(Constants.DESCRIPTION + "like-next")); + + clickHandler = (panel, user, clickType, slot) -> { + this.likeOffset++; + this.build(); + return true; + }; + + break; + } + case PREVIOUS_LIKE: + { + icon = new ItemStack(Material.OAK_SIGN); + name = this.user.getTranslation(Constants.BUTTON + "previous"); + description = new ArrayList<>(1); + description.add(this.user.getTranslation(Constants.DESCRIPTION + "like-previous")); + + clickHandler = (panel, user, clickType, slot) -> { + this.likeOffset--; + this.build(); + return true; + }; + + break; + } + case NEXT_DISLIKE: + { + icon = new ItemStack(Material.OAK_SIGN); + name = this.user.getTranslation(Constants.BUTTON + "next"); + description = new ArrayList<>(1); + description.add(this.user.getTranslation(Constants.DESCRIPTION + "dislike-next")); + + clickHandler = (panel, user, clickType, slot) -> { + this.dislikeOffset++; + this.build(); + return true; + }; + + break; + } + case PREVIOUS_DISLIKE: + { + icon = new ItemStack(Material.OAK_SIGN); + name = this.user.getTranslation(Constants.BUTTON + "previous"); + description = new ArrayList<>(1); + description.add(this.user.getTranslation(Constants.DESCRIPTION + "dislike-previous")); + + clickHandler = (panel, user, clickType, slot) -> { + this.dislikeOffset--; + this.build(); + return true; + }; + + break; + } + case ADD_LIKE_USER: + { + icon = new ItemStack(Material.GOLD_NUGGET); + name = this.user.getTranslation(Constants.BUTTON + "add-like-user"); + description = new ArrayList<>(1); + + clickHandler = (panel, user, clickType, slot) -> { + SelectUserGUI.open(user, + this.getOnlineUserList(), + this.convertToUserList(this.likesObject.getLikedBy()), + player -> { + if (player != null) + { + if (this.likesObject.hasDisliked(player.getUniqueId())) + { + this.dislikedByUsers.remove(player.getName()); + } + + this.likesObject.addLike(player.getUniqueId()); + this.likedByUsers.add(player.getName()); + } + + this.build(); + }); + return true; + }; + + break; + } + case REMOVE_LIKE_USER: + { + icon = new ItemStack(Material.LAVA_BUCKET); + name = this.user.getTranslation(Constants.BUTTON + "remove-like-user"); + description = new ArrayList<>(1); + + clickHandler = (panel, user, clickType, slot) -> { + SelectUserGUI.open(user, + this.convertToUserList(this.likesObject.getLikedBy()), + player -> { + if (player != null) + { + this.likesObject.removeLike(player.getUniqueId()); + this.likedByUsers.remove(player.getName()); + } + + this.build(); + }); + return true; + }; + + break; + } + case ADD_DISLIKE_USER: + { + icon = new ItemStack(Material.IRON_NUGGET); + name = this.user.getTranslation(Constants.BUTTON + "add-dislike-user"); + description = new ArrayList<>(1); + + clickHandler = (panel, user, clickType, slot) -> { + SelectUserGUI.open(user, + this.getOnlineUserList(), + this.convertToUserList(this.likesObject.getDislikedBy()), + player -> { + if (player != null) + { + if (this.likesObject.hasLiked(player.getUniqueId())) + { + this.likedByUsers.remove(player.getName()); + } + + this.likesObject.addDislike(player.getUniqueId()); + this.dislikedByUsers.add(player.getName()); + } + + this.build(); + }); + return true; + }; + + break; + } + case REMOVE_DISLIKE_USER: + { + icon = new ItemStack(Material.LAVA_BUCKET); + name = this.user.getTranslation(Constants.BUTTON + "remove-dislike-user"); + description = new ArrayList<>(1); + + clickHandler = (panel, user, clickType, slot) -> { + SelectUserGUI.open(user, + this.convertToUserList(this.likesObject.getDislikedBy()), + player -> { + if (player != null) + { + this.likesObject.removeDislike(player.getUniqueId()); + this.dislikedByUsers.remove(player.getName()); + } + + this.build(); + }); + return true; + }; + + break; + } + default: + return null; + } + + return new PanelItemBuilder(). + icon(icon). + name(name). + description(GuiUtils.stringSplit(description, 999)). + glow(false). + clickHandler(clickHandler). + build(); + } + + + /** + * This method populates all likers into given panel builder. + * @param panelBuilder PanelBuilder object. + */ + private void populateLikers(PanelBuilder panelBuilder) + { + if (this.likeOffset > 0) + { + panelBuilder.item(18, this.createButton(Button.PREVIOUS_LIKE)); + } + + if ((this.likeOffset + 1) * 7 < this.likesObject.getLikes()) + { + panelBuilder.item(26, this.createButton(Button.NEXT_LIKE)); + } + + final int startIndex = this.likeOffset * 7; + + for (int index = 0; index < 7 && startIndex + index < this.likesObject.getLikes(); index++) + { + String userName = this.likedByUsers.get(startIndex + index); + + panelBuilder.item(19 + index, new PanelItemBuilder(). + icon(userName). + glow(false). + build()); + } + } + + + /** + * This method populates all dislikers into given panel builder. + * @param panelBuilder PanelBuilder object. + */ + private void populateDislikers(PanelBuilder panelBuilder) + { + if (this.dislikeOffset > 0) + { + panelBuilder.item(36, this.createButton(Button.PREVIOUS_DISLIKE)); + } + + if ((this.dislikeOffset + 1) * 7 < this.likesObject.getDislikes()) + { + panelBuilder.item(44, this.createButton(Button.NEXT_DISLIKE)); + } + + final int startIndex = this.dislikeOffset * 7; + + for (int index = 0; index < 7 && startIndex + index < this.likesObject.getDislikes(); index++) + { + String userName = this.dislikedByUsers.get(startIndex + index); + + panelBuilder.item(37 + index, new PanelItemBuilder(). + icon(userName). + glow(false). + build()); + } + } + + + /** + * This method returns list that contains all online users. + * @return Online User List. + */ + private List getOnlineUserList() + { + return Bukkit.getOnlinePlayers().stream().map(User::getInstance).collect(Collectors.toList()); + } + + + /** + * This method converts and returns given set with UUIDs to User list. + * @param userSet Set that must be converted. + * @return Converted User List. + */ + private List convertToUserList(Set userSet) + { + return userSet.stream().map(User::getInstance).collect(Collectors.toList()); + } + + + // --------------------------------------------------------------------- + // Section: Enums + // --------------------------------------------------------------------- + + + /** + * This enum holds all action buttons that can be added in current gui. + */ + private enum Button + { + LIKE, + LIKE_RANK, + DISLIKE, + DISLIKE_RANK, + OVERALL, + OVERALL_RANK, + + NEXT_LIKE, + PREVIOUS_LIKE, + + NEXT_DISLIKE, + PREVIOUS_DISLIKE, + + ADD_LIKE_USER, + REMOVE_LIKE_USER, + ADD_DISLIKE_USER, + REMOVE_DISLIKE_USER + } + + + // --------------------------------------------------------------------- + // Section: Variables + // --------------------------------------------------------------------- + + + /** + * This variable holds likes object that is view by user in current gui. + */ + private final LikesObject likesObject; + + /** + * This variable stores index of current liker. + */ + private int likeOffset; + + /** + * This variable stores index of current disliker. + */ + private int dislikeOffset; + + /** + * This list contains player names that liked current island. + */ + private final List likedByUsers; + + /** + * This list contains player names that disliked current island. + */ + private final List dislikedByUsers; + + /** + * This variable holds island rank by likes. + */ + private final long likeRank; + + /** + * This variable holds island rank by dislikes. + */ + private final long dislikeRank; + + /** + * This variable holds island rank by rank. + */ + private final long overallRank; } diff --git a/src/main/java/world/bentobox/likes/panels/user/LikesViewPanel.java b/src/main/java/world/bentobox/likes/panels/user/LikesViewPanel.java index 5b79392..984bc5b 100644 --- a/src/main/java/world/bentobox/likes/panels/user/LikesViewPanel.java +++ b/src/main/java/world/bentobox/likes/panels/user/LikesViewPanel.java @@ -32,445 +32,445 @@ */ public class LikesViewPanel { - /** - * This is internal constructor. It is used internally in current class to avoid - * creating objects everywhere. - * @param addon Likes object. - * @param user User who opens Panel. - * @param world World where gui is opened - * @param permissionPrefix Permission Prefix - * @param likesObject LikeObject that will be viewed. - */ - private LikesViewPanel(@NonNull LikesAddon addon, - @NonNull User user, - @NonNull World world, - String permissionPrefix, - @NonNull LikesObject likesObject) - { - this.addon = addon; - this.user = user; - this.world = world; - - this.permissionPrefix = permissionPrefix; - - this.likesObject = likesObject; - - this.likedByUsers = this.likesObject.getLikedBy().stream(). - map(uuid -> this.addon.getPlayers().getName(uuid)). - sorted(String::compareToIgnoreCase). - collect(Collectors.toList()); - - this.dislikedByUsers = this.likesObject.getDislikedBy().stream(). - map(uuid -> this.addon.getPlayers().getName(uuid)). - sorted(String::compareToIgnoreCase). - collect(Collectors.toList()); - - if (this.addon.getManager().getSortedLikes(world).contains(likesObject)) - { - this.likeRank = this.addon.getManager().getSortedLikes(world).entryIndex(likesObject) + 1; - this.dislikeRank = this.addon.getManager().getSortedDislikes(world).entryIndex(likesObject) + 1; - this.overallRank = this.addon.getManager().getSortedRank(world).entryIndex(likesObject) + 1; - } - else - { - this.likeRank = -1; - this.dislikeRank = -1; - this.overallRank = -1; - } - } - - - /** - * This method is used to open UserPanel outside this class. It will be much easier - * to open panel with single method call then initializing new object. - * @param addon Likes Addon object - * @param user User who opens panel - * @param world World where gui is opened - * @param permissionPrefix Permission Prefix - * @param island Island which View panel must be opened. - */ - public static void openPanel(@NonNull LikesAddon addon, - @NonNull User user, - @NonNull World world, - String permissionPrefix, - @NonNull Island island) - { - LikesObject likesObject = addon.getManager().getExistingIslandLikes(island.getUniqueId()); - - if (likesObject == null) - { - if (island.getMemberSet().contains(user.getUniqueId())) - { - user.sendMessage(user.getTranslation(Constants.MESSAGE + "no-data-about-your-island")); - } - else - { - user.sendMessage(user.getTranslation(Constants.MESSAGE + "no-data-about-island")); - } - - // Do not open gui if there is no data. - return; - } - - new LikesViewPanel(addon, user, world, permissionPrefix, likesObject).build(); - } - - -// --------------------------------------------------------------------- -// Section: Methods -// --------------------------------------------------------------------- - - - private void build() - { - PanelBuilder panelBuilder = new PanelBuilder(). - name(this.user.getTranslation(Constants.TITLE + "view")). - user(this.user); - - GuiUtils.fillBorder(panelBuilder, 6, Material.MAGENTA_STAINED_GLASS_PANE); - - panelBuilder.item(10, this.createButton(Button.LIKE)); - panelBuilder.item(11, this.createButton(Button.LIKE_RANK)); - - panelBuilder.item(15, this.createButton(Button.OVERALL)); - panelBuilder.item(16, this.createButton(Button.OVERALL_RANK)); - - this.populateLikers(panelBuilder); - - panelBuilder.item(28, this.createButton(Button.DISLIKE)); - panelBuilder.item(29, this.createButton(Button.DISLIKE_RANK)); - - this.populateDislikers(panelBuilder); - - // At the end we just call build method that creates and opens panel. - panelBuilder.build(); - } - - - /** - * This method creates PanelItem button based on given button type. - * @param button Button that must be created. - * @return PanelItem object that represents given button. - */ - private PanelItem createButton(Button button) - { - ItemStack icon; - String name; - List description; - PanelItem.ClickHandler clickHandler; - - switch (button) - { - case LIKE: - { - icon = new ItemStack(Material.GOLD_INGOT); - name = this.user.getTranslation(Constants.BUTTON + "like"); - - description = new ArrayList<>(2); - description.add(this.user.getTranslation(Constants.DESCRIPTION + "like")); - description.add(this.user.getTranslation(Constants.DESCRIPTION + "current-value", - "[value]", - this.likesObject.getLikes() + "")); - - clickHandler = null; - - break; - } - case LIKE_RANK: - { - icon = new ItemStack(Material.GOLD_BLOCK); - name = this.user.getTranslation(Constants.BUTTON + "like-rank"); - - description = new ArrayList<>(2); - description.add(this.user.getTranslation(Constants.DESCRIPTION + "like-rank")); - description.add(this.user.getTranslation(Constants.DESCRIPTION + "current-value", - "[value]", - this.likeRank + "")); - - clickHandler = null; - - break; - } - case DISLIKE: - { - icon = new ItemStack(Material.IRON_INGOT); - name = this.user.getTranslation(Constants.BUTTON + "dislike"); - - description = new ArrayList<>(2); - description.add(this.user.getTranslation(Constants.DESCRIPTION + "dislike")); - description.add(this.user.getTranslation(Constants.DESCRIPTION + "current-value", - "[value]", - this.likesObject.getDislikes() + "")); - - clickHandler = null; - - break; - } - case DISLIKE_RANK: - { - icon = new ItemStack(Material.IRON_BLOCK); - name = this.user.getTranslation(Constants.BUTTON + "dislike-rank"); - - description = new ArrayList<>(2); - description.add(this.user.getTranslation(Constants.DESCRIPTION + "dislike-rank")); - description.add(this.user.getTranslation(Constants.DESCRIPTION + "current-value", - "[value]", - this.dislikeRank + "")); - - clickHandler = null; - - break; - } - case OVERALL: - { - icon = new ItemStack(Material.DIAMOND); - name = this.user.getTranslation(Constants.BUTTON + "overall"); - - description = new ArrayList<>(2); - description.add(this.user.getTranslation(Constants.DESCRIPTION + "overall")); - description.add(this.user.getTranslation(Constants.DESCRIPTION + "current-value", - "[value]", - this.likesObject.getRank() + "")); - - clickHandler = null; - - break; - } - case OVERALL_RANK: - { - icon = new ItemStack(Material.DIAMOND_BLOCK); - name = this.user.getTranslation(Constants.BUTTON + "overall-rank"); - - description = new ArrayList<>(2); - description.add(this.user.getTranslation(Constants.DESCRIPTION + "overall-rank")); - description.add(this.user.getTranslation(Constants.DESCRIPTION + "current-value", - "[value]", - this.overallRank + "")); - - clickHandler = null; - - break; - } - case NEXT_LIKE: - { - icon = new ItemStack(Material.OAK_SIGN); - name = this.user.getTranslation(Constants.BUTTON + "next"); - description = new ArrayList<>(1); - description.add(this.user.getTranslation(Constants.DESCRIPTION + "like-next")); - - clickHandler = (panel, user, clickType, slot) -> { - this.likeOffset++; - this.build(); - return true; - }; - - break; - } - case PREVIOUS_LIKE: - { - icon = new ItemStack(Material.OAK_SIGN); - name = this.user.getTranslation(Constants.BUTTON + "previous"); - description = new ArrayList<>(1); - description.add(this.user.getTranslation(Constants.DESCRIPTION + "like-previous")); - - clickHandler = (panel, user, clickType, slot) -> { - this.likeOffset--; - this.build(); - return true; - }; - - break; - } - case NEXT_DISLIKE: - { - icon = new ItemStack(Material.OAK_SIGN); - name = this.user.getTranslation(Constants.BUTTON + "next"); - description = new ArrayList<>(1); - description.add(this.user.getTranslation(Constants.DESCRIPTION + "dislike-next")); - - clickHandler = (panel, user, clickType, slot) -> { - this.dislikeOffset++; - this.build(); - return true; - }; - - break; - } - case PREVIOUS_DISLIKE: - { - icon = new ItemStack(Material.OAK_SIGN); - name = this.user.getTranslation(Constants.BUTTON + "previous"); - description = new ArrayList<>(1); - description.add(this.user.getTranslation(Constants.DESCRIPTION + "dislike-previous")); - - clickHandler = (panel, user, clickType, slot) -> { - this.dislikeOffset--; - this.build(); - return true; - }; - - break; - } - default: - return null; - } - - return new PanelItemBuilder(). - icon(icon). - name(name). - description(GuiUtils.stringSplit(description, 999)). - glow(false). - clickHandler(clickHandler). - build(); - } - - - /** - * This method populates all likers into given panel builder. - * @param panelBuilder PanelBuilder object. - */ - private void populateLikers(PanelBuilder panelBuilder) - { - if (this.likeOffset > 0) - { - panelBuilder.item(18, this.createButton(Button.PREVIOUS_LIKE)); - } - - if ((this.likeOffset + 1) * 7 < this.likesObject.getLikes()) - { - panelBuilder.item(26, this.createButton(Button.NEXT_LIKE)); - } - - final int startIndex = this.likeOffset * 7; - - for (int index = 0; index < 7 && startIndex + index < this.likesObject.getLikes(); index++) - { - String userName = this.likedByUsers.get(startIndex + index); - - panelBuilder.item(19 + index, new PanelItemBuilder(). - icon(userName). - glow(false). - build()); - } - } - - - /** - * This method populates all dislikers into given panel builder. - * @param panelBuilder PanelBuilder object. - */ - private void populateDislikers(PanelBuilder panelBuilder) - { - if (this.dislikeOffset > 0) - { - panelBuilder.item(36, this.createButton(Button.PREVIOUS_DISLIKE)); - } - - if ((this.dislikeOffset + 1) * 7 < this.likesObject.getDislikes()) - { - panelBuilder.item(44, this.createButton(Button.NEXT_DISLIKE)); - } - - final int startIndex = this.dislikeOffset * 7; - - for (int index = 0; index < 7 && startIndex + index < this.likesObject.getDislikes(); index++) - { - String userName = this.dislikedByUsers.get(startIndex + index); - - panelBuilder.item(37 + index, new PanelItemBuilder(). - icon(userName). - glow(false). - build()); - } - } - - -// --------------------------------------------------------------------- -// Section: Enums -// --------------------------------------------------------------------- - - - /** - * This enum holds all action buttons that can be added in current gui. - */ - private enum Button - { - LIKE, - LIKE_RANK, - DISLIKE, - DISLIKE_RANK, - OVERALL, - OVERALL_RANK, - - NEXT_LIKE, - PREVIOUS_LIKE, - - NEXT_DISLIKE, - PREVIOUS_DISLIKE - } - - -// --------------------------------------------------------------------- -// Section: Variables -// --------------------------------------------------------------------- - - /** - * This variable allows to access addon object. - */ - private final LikesAddon addon; - - /** - * This variable holds user who opens panel. Without it panel cannot be opened. - */ - private final User user; - - /** - * This variable holds a world to which gui referee. - */ - private final World world; - - /** - * Permission prefix - */ - private final String permissionPrefix; - - /** - * This variable holds likes object that is view by user in current gui. - */ - private final LikesObject likesObject; - - /** - * This variable stores index of current liker. - */ - private int likeOffset; - - /** - * This variable stores index of current disliker. - */ - private int dislikeOffset; - - /** - * This list contains player names that liked current island. - */ - private final List likedByUsers; - - /** - * This list contains player names that disliked current island. - */ - private final List dislikedByUsers; - - /** - * This variable holds island rank by likes. - */ - private final long likeRank; - - /** - * This variable holds island rank by dislikes. - */ - private final long dislikeRank; - - /** - * This variable holds island rank by rank. - */ - private final long overallRank; + /** + * This is internal constructor. It is used internally in current class to avoid + * creating objects everywhere. + * @param addon Likes object. + * @param user User who opens Panel. + * @param world World where gui is opened + * @param permissionPrefix Permission Prefix + * @param likesObject LikeObject that will be viewed. + */ + private LikesViewPanel(@NonNull LikesAddon addon, + @NonNull User user, + @NonNull World world, + String permissionPrefix, + @NonNull LikesObject likesObject) + { + this.addon = addon; + this.user = user; + this.world = world; + + this.permissionPrefix = permissionPrefix; + + this.likesObject = likesObject; + + this.likedByUsers = this.likesObject.getLikedBy().stream(). + map(uuid -> this.addon.getPlayers().getName(uuid)). + sorted(String::compareToIgnoreCase). + collect(Collectors.toList()); + + this.dislikedByUsers = this.likesObject.getDislikedBy().stream(). + map(uuid -> this.addon.getPlayers().getName(uuid)). + sorted(String::compareToIgnoreCase). + collect(Collectors.toList()); + + if (this.addon.getManager().getSortedLikes(world).contains(likesObject)) + { + this.likeRank = this.addon.getManager().getSortedLikes(world).entryIndex(likesObject) + 1L; + this.dislikeRank = this.addon.getManager().getSortedDislikes(world).entryIndex(likesObject) + 1L; + this.overallRank = this.addon.getManager().getSortedRank(world).entryIndex(likesObject) + 1L; + } + else + { + this.likeRank = -1; + this.dislikeRank = -1; + this.overallRank = -1; + } + } + + + /** + * This method is used to open UserPanel outside this class. It will be much easier + * to open panel with single method call then initializing new object. + * @param addon Likes Addon object + * @param user User who opens panel + * @param world World where gui is opened + * @param permissionPrefix Permission Prefix + * @param island Island which View panel must be opened. + */ + public static void openPanel(@NonNull LikesAddon addon, + @NonNull User user, + @NonNull World world, + String permissionPrefix, + @NonNull Island island) + { + LikesObject likesObject = addon.getManager().getExistingIslandLikes(island.getUniqueId()); + + if (likesObject == null) + { + if (island.getMemberSet().contains(user.getUniqueId())) + { + user.sendMessage(user.getTranslation(Constants.MESSAGE + "no-data-about-your-island")); + } + else + { + user.sendMessage(user.getTranslation(Constants.MESSAGE + "no-data-about-island")); + } + + // Do not open gui if there is no data. + return; + } + + new LikesViewPanel(addon, user, world, permissionPrefix, likesObject).build(); + } + + + // --------------------------------------------------------------------- + // Section: Methods + // --------------------------------------------------------------------- + + + private void build() + { + PanelBuilder panelBuilder = new PanelBuilder(). + name(this.user.getTranslation(Constants.TITLE + "view")). + user(this.user); + + GuiUtils.fillBorder(panelBuilder, 6, Material.MAGENTA_STAINED_GLASS_PANE); + + panelBuilder.item(10, this.createButton(Button.LIKE)); + panelBuilder.item(11, this.createButton(Button.LIKE_RANK)); + + panelBuilder.item(15, this.createButton(Button.OVERALL)); + panelBuilder.item(16, this.createButton(Button.OVERALL_RANK)); + + this.populateLikers(panelBuilder); + + panelBuilder.item(28, this.createButton(Button.DISLIKE)); + panelBuilder.item(29, this.createButton(Button.DISLIKE_RANK)); + + this.populateDislikers(panelBuilder); + + // At the end we just call build method that creates and opens panel. + panelBuilder.build(); + } + + + /** + * This method creates PanelItem button based on given button type. + * @param button Button that must be created. + * @return PanelItem object that represents given button. + */ + private PanelItem createButton(Button button) + { + ItemStack icon; + String name; + List description; + PanelItem.ClickHandler clickHandler; + + switch (button) + { + case LIKE: + { + icon = new ItemStack(Material.GOLD_INGOT); + name = this.user.getTranslation(Constants.BUTTON + "like"); + + description = new ArrayList<>(2); + description.add(this.user.getTranslation(Constants.DESCRIPTION + "like")); + description.add(this.user.getTranslation(Constants.DESCRIPTION + "current-value", + "[value]", + this.likesObject.getLikes() + "")); + + clickHandler = null; + + break; + } + case LIKE_RANK: + { + icon = new ItemStack(Material.GOLD_BLOCK); + name = this.user.getTranslation(Constants.BUTTON + "like-rank"); + + description = new ArrayList<>(2); + description.add(this.user.getTranslation(Constants.DESCRIPTION + "like-rank")); + description.add(this.user.getTranslation(Constants.DESCRIPTION + "current-value", + "[value]", + this.likeRank + "")); + + clickHandler = null; + + break; + } + case DISLIKE: + { + icon = new ItemStack(Material.IRON_INGOT); + name = this.user.getTranslation(Constants.BUTTON + "dislike"); + + description = new ArrayList<>(2); + description.add(this.user.getTranslation(Constants.DESCRIPTION + "dislike")); + description.add(this.user.getTranslation(Constants.DESCRIPTION + "current-value", + "[value]", + this.likesObject.getDislikes() + "")); + + clickHandler = null; + + break; + } + case DISLIKE_RANK: + { + icon = new ItemStack(Material.IRON_BLOCK); + name = this.user.getTranslation(Constants.BUTTON + "dislike-rank"); + + description = new ArrayList<>(2); + description.add(this.user.getTranslation(Constants.DESCRIPTION + "dislike-rank")); + description.add(this.user.getTranslation(Constants.DESCRIPTION + "current-value", + "[value]", + this.dislikeRank + "")); + + clickHandler = null; + + break; + } + case OVERALL: + { + icon = new ItemStack(Material.DIAMOND); + name = this.user.getTranslation(Constants.BUTTON + "overall"); + + description = new ArrayList<>(2); + description.add(this.user.getTranslation(Constants.DESCRIPTION + "overall")); + description.add(this.user.getTranslation(Constants.DESCRIPTION + "current-value", + "[value]", + this.likesObject.getRank() + "")); + + clickHandler = null; + + break; + } + case OVERALL_RANK: + { + icon = new ItemStack(Material.DIAMOND_BLOCK); + name = this.user.getTranslation(Constants.BUTTON + "overall-rank"); + + description = new ArrayList<>(2); + description.add(this.user.getTranslation(Constants.DESCRIPTION + "overall-rank")); + description.add(this.user.getTranslation(Constants.DESCRIPTION + "current-value", + "[value]", + this.overallRank + "")); + + clickHandler = null; + + break; + } + case NEXT_LIKE: + { + icon = new ItemStack(Material.OAK_SIGN); + name = this.user.getTranslation(Constants.BUTTON + "next"); + description = new ArrayList<>(1); + description.add(this.user.getTranslation(Constants.DESCRIPTION + "like-next")); + + clickHandler = (panel, user, clickType, slot) -> { + this.likeOffset++; + this.build(); + return true; + }; + + break; + } + case PREVIOUS_LIKE: + { + icon = new ItemStack(Material.OAK_SIGN); + name = this.user.getTranslation(Constants.BUTTON + "previous"); + description = new ArrayList<>(1); + description.add(this.user.getTranslation(Constants.DESCRIPTION + "like-previous")); + + clickHandler = (panel, user, clickType, slot) -> { + this.likeOffset--; + this.build(); + return true; + }; + + break; + } + case NEXT_DISLIKE: + { + icon = new ItemStack(Material.OAK_SIGN); + name = this.user.getTranslation(Constants.BUTTON + "next"); + description = new ArrayList<>(1); + description.add(this.user.getTranslation(Constants.DESCRIPTION + "dislike-next")); + + clickHandler = (panel, user, clickType, slot) -> { + this.dislikeOffset++; + this.build(); + return true; + }; + + break; + } + case PREVIOUS_DISLIKE: + { + icon = new ItemStack(Material.OAK_SIGN); + name = this.user.getTranslation(Constants.BUTTON + "previous"); + description = new ArrayList<>(1); + description.add(this.user.getTranslation(Constants.DESCRIPTION + "dislike-previous")); + + clickHandler = (panel, user, clickType, slot) -> { + this.dislikeOffset--; + this.build(); + return true; + }; + + break; + } + default: + return null; + } + + return new PanelItemBuilder(). + icon(icon). + name(name). + description(GuiUtils.stringSplit(description, 999)). + glow(false). + clickHandler(clickHandler). + build(); + } + + + /** + * This method populates all likers into given panel builder. + * @param panelBuilder PanelBuilder object. + */ + private void populateLikers(PanelBuilder panelBuilder) + { + if (this.likeOffset > 0) + { + panelBuilder.item(18, this.createButton(Button.PREVIOUS_LIKE)); + } + + if ((this.likeOffset + 1) * 7 < this.likesObject.getLikes()) + { + panelBuilder.item(26, this.createButton(Button.NEXT_LIKE)); + } + + final int startIndex = this.likeOffset * 7; + + for (int index = 0; index < 7 && startIndex + index < this.likesObject.getLikes(); index++) + { + String userName = this.likedByUsers.get(startIndex + index); + + panelBuilder.item(19 + index, new PanelItemBuilder(). + icon(userName). + glow(false). + build()); + } + } + + + /** + * This method populates all dislikers into given panel builder. + * @param panelBuilder PanelBuilder object. + */ + private void populateDislikers(PanelBuilder panelBuilder) + { + if (this.dislikeOffset > 0) + { + panelBuilder.item(36, this.createButton(Button.PREVIOUS_DISLIKE)); + } + + if ((this.dislikeOffset + 1) * 7 < this.likesObject.getDislikes()) + { + panelBuilder.item(44, this.createButton(Button.NEXT_DISLIKE)); + } + + final int startIndex = this.dislikeOffset * 7; + + for (int index = 0; index < 7 && startIndex + index < this.likesObject.getDislikes(); index++) + { + String userName = this.dislikedByUsers.get(startIndex + index); + + panelBuilder.item(37 + index, new PanelItemBuilder(). + icon(userName). + glow(false). + build()); + } + } + + + // --------------------------------------------------------------------- + // Section: Enums + // --------------------------------------------------------------------- + + + /** + * This enum holds all action buttons that can be added in current gui. + */ + private enum Button + { + LIKE, + LIKE_RANK, + DISLIKE, + DISLIKE_RANK, + OVERALL, + OVERALL_RANK, + + NEXT_LIKE, + PREVIOUS_LIKE, + + NEXT_DISLIKE, + PREVIOUS_DISLIKE + } + + + // --------------------------------------------------------------------- + // Section: Variables + // --------------------------------------------------------------------- + + /** + * This variable allows to access addon object. + */ + private final LikesAddon addon; + + /** + * This variable holds user who opens panel. Without it panel cannot be opened. + */ + private final User user; + + /** + * This variable holds a world to which gui referee. + */ + private final World world; + + /** + * Permission prefix + */ + private final String permissionPrefix; + + /** + * This variable holds likes object that is view by user in current gui. + */ + private final LikesObject likesObject; + + /** + * This variable stores index of current liker. + */ + private int likeOffset; + + /** + * This variable stores index of current disliker. + */ + private int dislikeOffset; + + /** + * This list contains player names that liked current island. + */ + private final List likedByUsers; + + /** + * This list contains player names that disliked current island. + */ + private final List dislikedByUsers; + + /** + * This variable holds island rank by likes. + */ + private final long likeRank; + + /** + * This variable holds island rank by dislikes. + */ + private final long dislikeRank; + + /** + * This variable holds island rank by rank. + */ + private final long overallRank; } diff --git a/src/main/java/world/bentobox/likes/utils/collections/IndexedTreeMap.java b/src/main/java/world/bentobox/likes/utils/collections/IndexedTreeMap.java index e9d035d..646a30d 100644 --- a/src/main/java/world/bentobox/likes/utils/collections/IndexedTreeMap.java +++ b/src/main/java/world/bentobox/likes/utils/collections/IndexedTreeMap.java @@ -94,8 +94,8 @@ */ public class IndexedTreeMap - extends AbstractMap - implements IndexedNavigableMap, Cloneable, java.io.Serializable { +extends AbstractMap +implements IndexedNavigableMap, Cloneable, java.io.Serializable { /** * The comparator used to maintain order in this tree map, or * null if it uses the natural ordering of its keys. @@ -195,6 +195,7 @@ public IndexedTreeMap(SortedMap m) { * * @return the number of key-value mappings in this map */ + @Override public int size() { return size; } @@ -212,6 +213,7 @@ public int size() { * and this map uses natural ordering, or its comparator * does not permit null keys */ + @Override public boolean containsKey(Object key) { return getEntry(key) != null; } @@ -229,6 +231,7 @@ public boolean containsKey(Object key) { * false otherwise * @since 1.2 */ + @Override public boolean containsValue(Object value) { for (Entry e = getFirstEntry(); e != null; e = successor(e)) if (valEquals(value, e.value)) @@ -258,11 +261,13 @@ public boolean containsValue(Object value) { * and this map uses natural ordering, or its comparator * does not permit null keys */ + @Override public V get(Object key) { Entry p = getEntry(key); return (p == null ? null : p.value); } + @Override public Comparator comparator() { return comparator; } @@ -271,6 +276,7 @@ public Comparator comparator() { * @throws java.util.NoSuchElementException * {@inheritDoc} */ + @Override public K firstKey() { return key(getFirstEntry()); } @@ -279,6 +285,7 @@ public K firstKey() { * @throws java.util.NoSuchElementException * {@inheritDoc} */ + @Override public K lastKey() { return key(getLastEntry()); } @@ -295,6 +302,7 @@ public K lastKey() { * the specified map contains a null key and this map does not * permit null keys */ + @Override public void putAll(Map map) { int mapSize = map.size(); if (size == 0 && mapSize != 0 && map instanceof SortedMap) { @@ -439,9 +447,9 @@ final Entry getFloorEntry(K key) { public void debug() throws Exception { Entry e = getFirstEntry(); while (e != null) { -// String l = e.left == null ? "null" : " " + e.left.key.toString(); -// String r = e.right == null ? "null" : " " + e.right.key.toString(); -// System.out.println(e.key + ":" + l + ":" + r + ":" + e.weight); + // String l = e.left == null ? "null" : " " + e.left.key.toString(); + // String r = e.right == null ? "null" : " " + e.right.key.toString(); + // System.out.println(e.key + ":" + l + ":" + r + ":" + e.weight); if (e.weight != e.sumup()) { throw new Exception("Weight is incorrect:" + e.weight + "!=" + e.sumup() + " for " + e.key); } @@ -539,6 +547,7 @@ final Entry getLowerEntry(K key) { * and this map uses natural ordering, or its comparator * does not permit null keys */ + @Override public V put(K key, V value) { Entry t = root; if (t == null) { @@ -611,6 +620,7 @@ else if (cmp > 0) * and this map uses natural ordering, or its comparator * does not permit null keys */ + @Override public V remove(Object key) { Entry p = getEntry(key); if (p == null) @@ -625,6 +635,7 @@ public V remove(Object key) { * Removes all of the mappings from this map. * The map will be empty after this call returns. */ + @Override public void clear() { modCount++; size = 0; @@ -637,6 +648,7 @@ public void clear() { * * @return a shallow copy of this map */ + @Override public Object clone() { IndexedTreeMap clone = null; try { @@ -668,6 +680,7 @@ public Object clone() { /** * @since 1.6 */ + @Override public Map.Entry firstEntry() { return exportEntry(getFirstEntry()); } @@ -675,6 +688,7 @@ public Map.Entry firstEntry() { /** * @since 1.6 */ + @Override public Map.Entry lastEntry() { return exportEntry(getLastEntry()); } @@ -682,6 +696,7 @@ public Map.Entry lastEntry() { /** * @since 1.6 */ + @Override public Map.Entry pollFirstEntry() { Entry p = getFirstEntry(); Map.Entry result = exportEntry(p); @@ -693,6 +708,7 @@ public Map.Entry pollFirstEntry() { /** * @since 1.6 */ + @Override public Map.Entry pollLastEntry() { Entry p = getLastEntry(); Map.Entry result = exportEntry(p); @@ -708,6 +724,7 @@ public Map.Entry pollLastEntry() { * does not permit null keys * @since 1.6 */ + @Override public Map.Entry lowerEntry(K key) { return exportEntry(getLowerEntry(key)); } @@ -719,6 +736,7 @@ public Map.Entry lowerEntry(K key) { * does not permit null keys * @since 1.6 */ + @Override public K lowerKey(K key) { return keyOrNull(getLowerEntry(key)); } @@ -730,6 +748,7 @@ public K lowerKey(K key) { * does not permit null keys * @since 1.6 */ + @Override public Map.Entry floorEntry(K key) { return exportEntry(getFloorEntry(key)); } @@ -741,6 +760,7 @@ public Map.Entry floorEntry(K key) { * does not permit null keys * @since 1.6 */ + @Override public K floorKey(K key) { return keyOrNull(getFloorEntry(key)); } @@ -752,6 +772,7 @@ public K floorKey(K key) { * does not permit null keys * @since 1.6 */ + @Override public Map.Entry ceilingEntry(K key) { return exportEntry(getCeilingEntry(key)); } @@ -763,6 +784,7 @@ public Map.Entry ceilingEntry(K key) { * does not permit null keys * @since 1.6 */ + @Override public K ceilingKey(K key) { return keyOrNull(getCeilingEntry(key)); } @@ -774,6 +796,7 @@ public K ceilingKey(K key) { * does not permit null keys * @since 1.6 */ + @Override public Map.Entry higherEntry(K key) { return exportEntry(getHigherEntry(key)); } @@ -785,10 +808,12 @@ public Map.Entry higherEntry(K key) { * does not permit null keys * @since 1.6 */ + @Override public K higherKey(K key) { return keyOrNull(getHigherEntry(key)); } + @Override public K exactKey(int index) { if (index < 0 || index > size() - 1) { throw new ArrayIndexOutOfBoundsException(); @@ -812,6 +837,7 @@ private K getExactKey(Entry e, int index) { return getExactKey(e.right, index - (e.left == null ? 0 : e.left.weight) - 1); } + @Override public int keyIndex(K key) { if (key == null) { throw new NullPointerException(); @@ -850,6 +876,7 @@ public int keyIndex(K key) { } + @Override public Entry exactEntry(int index) { return getExactEntry(root, index); } @@ -896,6 +923,7 @@ private Entry getExactEntry(Entry e, int index) { * operations. It does not support the add or addAll * operations. */ + @Override public Set keySet() { return navigableKeySet(); } @@ -903,6 +931,7 @@ public Set keySet() { /** * @since 1.6 */ + @Override public NavigableSet navigableKeySet() { KeySet nks = navigableKeySet; return (nks != null) ? nks : (navigableKeySet = new KeySet(this)); @@ -911,6 +940,7 @@ public NavigableSet navigableKeySet() { /** * @since 1.6 */ + @Override public NavigableSet descendingKeySet() { return descendingMap().navigableKeySet(); } @@ -930,6 +960,7 @@ public NavigableSet descendingKeySet() { * retainAll and clear operations. It does not * support the add or addAll operations. */ + @Override public Collection values() { Collection vs = values; return (vs != null) ? vs : (values = new Values()); @@ -950,6 +981,7 @@ public Collection values() { * clear operations. It does not support the * add or addAll operations. */ + @Override public Set> entrySet() { EntrySet es = entrySet; return (es != null) ? es : (entrySet = new EntrySet()); @@ -958,12 +990,13 @@ public Set> entrySet() { /** * @since 1.6 */ + @Override public NavigableMap descendingMap() { NavigableMap km = descendingMap; return (km != null) ? km : - (descendingMap = new DescendingSubMap(this, - true, null, true, - true, null, true)); + (descendingMap = new DescendingSubMap(this, + true, null, true, + true, null, true)); } /** @@ -974,8 +1007,9 @@ public NavigableMap descendingMap() { * @throws IllegalArgumentException {@inheritDoc} * @since 1.6 */ + @Override public NavigableMap subMap(K fromKey, boolean fromInclusive, - K toKey, boolean toInclusive) { + K toKey, boolean toInclusive) { return new AscendingSubMap(this, false, fromKey, fromInclusive, false, toKey, toInclusive); @@ -989,6 +1023,7 @@ public NavigableMap subMap(K fromKey, boolean fromInclusive, * @throws IllegalArgumentException {@inheritDoc} * @since 1.6 */ + @Override public NavigableMap headMap(K toKey, boolean inclusive) { return new AscendingSubMap(this, true, null, true, @@ -1003,6 +1038,7 @@ public NavigableMap headMap(K toKey, boolean inclusive) { * @throws IllegalArgumentException {@inheritDoc} * @since 1.6 */ + @Override public NavigableMap tailMap(K fromKey, boolean inclusive) { return new AscendingSubMap(this, false, fromKey, inclusive, @@ -1016,6 +1052,7 @@ public NavigableMap tailMap(K fromKey, boolean inclusive) { * does not permit null keys * @throws IllegalArgumentException {@inheritDoc} */ + @Override public SortedMap subMap(K fromKey, K toKey) { return subMap(fromKey, true, toKey, false); } @@ -1027,6 +1064,7 @@ public SortedMap subMap(K fromKey, K toKey) { * does not permit null keys * @throws IllegalArgumentException {@inheritDoc} */ + @Override public SortedMap headMap(K toKey) { return headMap(toKey, false); } @@ -1038,6 +1076,7 @@ public SortedMap headMap(K toKey) { * does not permit null keys * @throws IllegalArgumentException {@inheritDoc} */ + @Override public SortedMap tailMap(K fromKey) { return tailMap(fromKey, true); } @@ -1046,18 +1085,22 @@ public SortedMap tailMap(K fromKey) { // View class support class Values extends AbstractCollection { + @Override public Iterator iterator() { return new ValueIterator(getFirstEntry()); } + @Override public int size() { return IndexedTreeMap.this.size(); } + @Override public boolean contains(Object o) { return IndexedTreeMap.this.containsValue(o); } + @Override public boolean remove(Object o) { for (Entry e = getFirstEntry(); e != null; e = successor(e)) { if (valEquals(e.getValue(), o)) { @@ -1068,16 +1111,19 @@ public boolean remove(Object o) { return false; } + @Override public void clear() { IndexedTreeMap.this.clear(); } } class EntrySet extends AbstractSet> { + @Override public Iterator> iterator() { return new EntryIterator(getFirstEntry()); } + @Override public boolean contains(Object o) { if (!(o instanceof Map.Entry)) return false; @@ -1087,6 +1133,7 @@ public boolean contains(Object o) { return p != null && valEquals(p.getValue(), value); } + @Override public boolean remove(Object o) { if (!(o instanceof Map.Entry)) return false; @@ -1100,10 +1147,12 @@ public boolean remove(Object o) { return false; } + @Override public int size() { return IndexedTreeMap.this.size(); } + @Override public void clear() { IndexedTreeMap.this.clear(); } @@ -1132,106 +1181,129 @@ static final class KeySet extends AbstractSet implements NavigableSet { m = map; } + @Override public Iterator iterator() { if (m instanceof IndexedTreeMap) return ((IndexedTreeMap) m).keyIterator(); else - return (Iterator) (((IndexedTreeMap.NavigableSubMap) m).keyIterator()); + return (((IndexedTreeMap.NavigableSubMap) m).keyIterator()); } + @Override public Iterator descendingIterator() { if (m instanceof IndexedTreeMap) return ((IndexedTreeMap) m).descendingKeyIterator(); else - return (Iterator) (((IndexedTreeMap.NavigableSubMap) m).descendingKeyIterator()); + return (((IndexedTreeMap.NavigableSubMap) m).descendingKeyIterator()); } + @Override public int size() { return m.size(); } + @Override public boolean isEmpty() { return m.isEmpty(); } + @Override public boolean contains(Object o) { return m.containsKey(o); } + @Override public void clear() { m.clear(); } + @Override public E lower(E e) { return m.lowerKey(e); } + @Override public E floor(E e) { return m.floorKey(e); } + @Override public E ceiling(E e) { return m.ceilingKey(e); } + @Override public E higher(E e) { return m.higherKey(e); } + @Override public E first() { return m.firstKey(); } + @Override public E last() { return m.lastKey(); } + @Override public Comparator comparator() { return m.comparator(); } + @Override public E pollFirst() { Map.Entry e = m.pollFirstEntry(); return e == null ? null : e.getKey(); } + @Override public E pollLast() { Map.Entry e = m.pollLastEntry(); return e == null ? null : e.getKey(); } + @Override public boolean remove(Object o) { int oldSize = size(); m.remove(o); return size() != oldSize; } + @Override public NavigableSet subSet(E fromElement, boolean fromInclusive, - E toElement, boolean toInclusive) { + E toElement, boolean toInclusive) { return new IndexedTreeSet(m.subMap(fromElement, fromInclusive, toElement, toInclusive)); } + @Override public NavigableSet headSet(E toElement, boolean inclusive) { return new IndexedTreeSet(m.headMap(toElement, inclusive)); } + @Override public NavigableSet tailSet(E fromElement, boolean inclusive) { return new IndexedTreeSet(m.tailMap(fromElement, inclusive)); } + @Override public SortedSet subSet(E fromElement, E toElement) { return subSet(fromElement, true, toElement, false); } + @Override public SortedSet headSet(E toElement) { return headSet(toElement, false); } + @Override public SortedSet tailSet(E fromElement) { return tailSet(fromElement, true); } + @Override public NavigableSet descendingSet() { return new IndexedTreeSet(m.descendingMap()); } @@ -1251,6 +1323,7 @@ abstract class PrivateEntryIterator implements Iterator { next = first; } + @Override public final boolean hasNext() { return next != null; } @@ -1277,6 +1350,7 @@ final Entry prevEntry() { return e; } + @Override public void remove() { if (lastReturned == null) throw new IllegalStateException(); @@ -1296,7 +1370,11 @@ final class EntryIterator extends PrivateEntryIterator> { super(first); } + @Override public Map.Entry next() { + if(!hasNext()){ + throw new NoSuchElementException(); + } return nextEntry(); } } @@ -1306,7 +1384,11 @@ final class ValueIterator extends PrivateEntryIterator { super(first); } + @Override public V next() { + if(!hasNext()){ + throw new NoSuchElementException(); + } return nextEntry().value; } } @@ -1316,7 +1398,11 @@ final class KeyIterator extends PrivateEntryIterator { super(first); } + @Override public K next() { + if(!hasNext()){ + throw new NoSuchElementException(); + } return nextEntry().key; } } @@ -1326,7 +1412,11 @@ final class DescendingKeyIterator extends PrivateEntryIterator { super(first); } + @Override public K next() { + if(!hasNext()){ + throw new NoSuchElementException(); + } return prevEntry().key; } } @@ -1354,7 +1444,7 @@ final static boolean valEquals(Object o1, Object o2) { */ static Map.Entry exportEntry(IndexedTreeMap.Entry e) { return e == null ? null : - new java.util.AbstractMap.SimpleImmutableEntry(e); + new java.util.AbstractMap.SimpleImmutableEntry(e); } /** @@ -1382,7 +1472,7 @@ static K key(Entry e) { * @serial include */ static abstract class NavigableSubMap extends java.util.AbstractMap - implements NavigableMap, java.io.Serializable { + implements NavigableMap, java.io.Serializable { /** * The backing map. */ @@ -1401,8 +1491,8 @@ static abstract class NavigableSubMap extends java.util.AbstractMap final boolean loInclusive, hiInclusive; NavigableSubMap(IndexedTreeMap m, - boolean fromStart, K lo, boolean loInclusive, - boolean toEnd, K hi, boolean hiInclusive) { + boolean fromStart, K lo, boolean loInclusive, + boolean toEnd, K hi, boolean hiInclusive) { if (!fromStart && !toEnd) { if (m.compare(lo, hi) > 0) throw new IllegalArgumentException("fromKey > toKey"); @@ -1464,16 +1554,16 @@ final boolean inRange(Object key, boolean inclusive) { final IndexedTreeMap.Entry absLowest() { IndexedTreeMap.Entry e = (fromStart ? m.getFirstEntry() : - (loInclusive ? m.getCeilingEntry(lo) : - m.getHigherEntry(lo))); + (loInclusive ? m.getCeilingEntry(lo) : + m.getHigherEntry(lo))); return (e == null || tooHigh(e.key)) ? null : e; } final IndexedTreeMap.Entry absHighest() { IndexedTreeMap.Entry e = (toEnd ? m.getLastEntry() : - (hiInclusive ? m.getFloorEntry(hi) : - m.getLowerEntry(hi))); + (hiInclusive ? m.getFloorEntry(hi) : + m.getLowerEntry(hi))); return (e == null || tooLow(e.key)) ? null : e; } @@ -1511,7 +1601,7 @@ final IndexedTreeMap.Entry absLower(K key) { final IndexedTreeMap.Entry absHighFence() { return (toEnd ? null : (hiInclusive ? m.getHigherEntry(hi) : - m.getCeilingEntry(hi))); + m.getCeilingEntry(hi))); } /** @@ -1520,7 +1610,7 @@ final IndexedTreeMap.Entry absHighFence() { final IndexedTreeMap.Entry absLowFence() { return (fromStart ? null : (loInclusive ? m.getLowerEntry(lo) : - m.getFloorEntry(lo))); + m.getFloorEntry(lo))); } // Abstract methods defined in ascending vs descending classes @@ -1550,80 +1640,99 @@ final IndexedTreeMap.Entry absLowFence() { // public methods + @Override public boolean isEmpty() { return (fromStart && toEnd) ? m.isEmpty() : entrySet().isEmpty(); } + @Override public int size() { return (fromStart && toEnd) ? m.size() : entrySet().size(); } + @Override public final boolean containsKey(Object key) { return inRange(key) && m.containsKey(key); } + @Override public final V put(K key, V value) { if (!inRange(key)) throw new IllegalArgumentException("key out of range"); return m.put(key, value); } + @Override public final V get(Object key) { return !inRange(key) ? null : m.get(key); } + @Override public final V remove(Object key) { return !inRange(key) ? null : m.remove(key); } + @Override public final Map.Entry ceilingEntry(K key) { return exportEntry(subCeiling(key)); } + @Override public final K ceilingKey(K key) { return keyOrNull(subCeiling(key)); } + @Override public final Map.Entry higherEntry(K key) { return exportEntry(subHigher(key)); } + @Override public final K higherKey(K key) { return keyOrNull(subHigher(key)); } + @Override public final Map.Entry floorEntry(K key) { return exportEntry(subFloor(key)); } + @Override public final K floorKey(K key) { return keyOrNull(subFloor(key)); } + @Override public final Map.Entry lowerEntry(K key) { return exportEntry(subLower(key)); } + @Override public final K lowerKey(K key) { return keyOrNull(subLower(key)); } + @Override public final K firstKey() { return key(subLowest()); } + @Override public final K lastKey() { return key(subHighest()); } + @Override public final Map.Entry firstEntry() { return exportEntry(subLowest()); } + @Override public final Map.Entry lastEntry() { return exportEntry(subHighest()); } + @Override public final Map.Entry pollFirstEntry() { IndexedTreeMap.Entry e = subLowest(); Map.Entry result = exportEntry(e); @@ -1632,6 +1741,7 @@ public final Map.Entry pollFirstEntry() { return result; } + @Override public final Map.Entry pollLastEntry() { IndexedTreeMap.Entry e = subHighest(); Map.Entry result = exportEntry(e); @@ -1645,28 +1755,34 @@ public final Map.Entry pollLastEntry() { transient EntrySetView entrySetView = null; transient KeySet navigableKeySetView = null; + @Override public final NavigableSet navigableKeySet() { KeySet nksv = navigableKeySetView; return (nksv != null) ? nksv : - (navigableKeySetView = new IndexedTreeMap.KeySet(this)); + (navigableKeySetView = new IndexedTreeMap.KeySet(this)); } + @Override public final Set keySet() { return navigableKeySet(); } + @Override public NavigableSet descendingKeySet() { return descendingMap().navigableKeySet(); } + @Override public final SortedMap subMap(K fromKey, K toKey) { return subMap(fromKey, true, toKey, false); } + @Override public final SortedMap headMap(K toKey) { return headMap(toKey, false); } + @Override public final SortedMap tailMap(K fromKey) { return tailMap(fromKey, true); } @@ -1676,6 +1792,7 @@ public final SortedMap tailMap(K fromKey) { abstract class EntrySetView extends AbstractSet> { private transient int size = -1, sizeModCount; + @Override public int size() { if (fromStart && toEnd) return m.size(); @@ -1691,11 +1808,13 @@ public int size() { return size; } + @Override public boolean isEmpty() { IndexedTreeMap.Entry n = absLowest(); return n == null || tooHigh(n.key); } + @Override public boolean contains(Object o) { if (!(o instanceof Map.Entry)) return false; @@ -1708,6 +1827,7 @@ public boolean contains(Object o) { valEquals(node.getValue(), entry.getValue()); } + @Override public boolean remove(Object o) { if (!(o instanceof Map.Entry)) return false; @@ -1734,13 +1854,14 @@ abstract class SubMapIterator implements Iterator { int expectedModCount; SubMapIterator(IndexedTreeMap.Entry first, - IndexedTreeMap.Entry fence) { + IndexedTreeMap.Entry fence) { expectedModCount = m.modCount; lastReturned = null; next = first; fenceKey = fence == null ? null : fence.key; } + @Override public final boolean hasNext() { return next != null && next.key != fenceKey; } @@ -1794,14 +1915,19 @@ final void removeDescending() { final class SubMapEntryIterator extends SubMapIterator> { SubMapEntryIterator(IndexedTreeMap.Entry first, - IndexedTreeMap.Entry fence) { + IndexedTreeMap.Entry fence) { super(first, fence); } + @Override public Map.Entry next() { + if(!hasNext()){ + throw new NoSuchElementException(); + } return nextEntry(); } + @Override public void remove() { removeAscending(); } @@ -1809,14 +1935,19 @@ public void remove() { final class SubMapKeyIterator extends SubMapIterator { SubMapKeyIterator(IndexedTreeMap.Entry first, - IndexedTreeMap.Entry fence) { + IndexedTreeMap.Entry fence) { super(first, fence); } + @Override public K next() { + if(!hasNext()){ + throw new NoSuchElementException(); + } return nextEntry().key; } + @Override public void remove() { removeAscending(); } @@ -1824,14 +1955,19 @@ public void remove() { final class DescendingSubMapEntryIterator extends SubMapIterator> { DescendingSubMapEntryIterator(IndexedTreeMap.Entry last, - IndexedTreeMap.Entry fence) { + IndexedTreeMap.Entry fence) { super(last, fence); } + @Override public Map.Entry next() { + if(!hasNext()){ + throw new NoSuchElementException(); + } return prevEntry(); } + @Override public void remove() { removeDescending(); } @@ -1839,14 +1975,19 @@ public void remove() { final class DescendingSubMapKeyIterator extends SubMapIterator { DescendingSubMapKeyIterator(IndexedTreeMap.Entry last, - IndexedTreeMap.Entry fence) { + IndexedTreeMap.Entry fence) { super(last, fence); } + @Override public K next() { + if(!hasNext()){ + throw new NoSuchElementException(); + } return prevEntry().key; } + @Override public void remove() { removeDescending(); } @@ -1860,17 +2001,19 @@ static final class AscendingSubMap extends NavigableSubMap { private static final long serialVersionUID = 912986545866124060L; AscendingSubMap(IndexedTreeMap m, - boolean fromStart, K lo, boolean loInclusive, - boolean toEnd, K hi, boolean hiInclusive) { + boolean fromStart, K lo, boolean loInclusive, + boolean toEnd, K hi, boolean hiInclusive) { super(m, fromStart, lo, loInclusive, toEnd, hi, hiInclusive); } + @Override public Comparator comparator() { return m.comparator(); } + @Override public NavigableMap subMap(K fromKey, boolean fromInclusive, - K toKey, boolean toInclusive) { + K toKey, boolean toInclusive) { if (!inRange(fromKey, fromInclusive)) throw new IllegalArgumentException("fromKey out of range"); if (!inRange(toKey, toInclusive)) @@ -1880,6 +2023,7 @@ public NavigableMap subMap(K fromKey, boolean fromInclusive, false, toKey, toInclusive); } + @Override public NavigableMap headMap(K toKey, boolean inclusive) { if (!inRange(toKey, inclusive)) throw new IllegalArgumentException("toKey out of range"); @@ -1888,6 +2032,7 @@ public NavigableMap headMap(K toKey, boolean inclusive) { false, toKey, inclusive); } + @Override public NavigableMap tailMap(K fromKey, boolean inclusive) { if (!inRange(fromKey, inclusive)) throw new IllegalArgumentException("fromKey out of range"); @@ -1896,54 +2041,65 @@ public NavigableMap tailMap(K fromKey, boolean inclusive) { toEnd, hi, hiInclusive); } + @Override public NavigableMap descendingMap() { NavigableMap mv = descendingMapView; return (mv != null) ? mv : - (descendingMapView = - new DescendingSubMap(m, - fromStart, lo, loInclusive, - toEnd, hi, hiInclusive)); + (descendingMapView = + new DescendingSubMap(m, + fromStart, lo, loInclusive, + toEnd, hi, hiInclusive)); } + @Override Iterator keyIterator() { return new SubMapKeyIterator(absLowest(), absHighFence()); } + @Override Iterator descendingKeyIterator() { return new DescendingSubMapKeyIterator(absHighest(), absLowFence()); } final class AscendingEntrySetView extends EntrySetView { + @Override public Iterator> iterator() { return new SubMapEntryIterator(absLowest(), absHighFence()); } } + @Override public Set> entrySet() { EntrySetView es = entrySetView; return (es != null) ? es : new AscendingEntrySetView(); } + @Override IndexedTreeMap.Entry subLowest() { return absLowest(); } + @Override IndexedTreeMap.Entry subHighest() { return absHighest(); } + @Override IndexedTreeMap.Entry subCeiling(K key) { return absCeiling(key); } + @Override IndexedTreeMap.Entry subHigher(K key) { return absHigher(key); } + @Override IndexedTreeMap.Entry subFloor(K key) { return absFloor(key); } + @Override IndexedTreeMap.Entry subLower(K key) { return absLower(key); } @@ -1956,20 +2112,22 @@ static final class DescendingSubMap extends NavigableSubMap { private static final long serialVersionUID = 912986545866120460L; DescendingSubMap(IndexedTreeMap m, - boolean fromStart, K lo, boolean loInclusive, - boolean toEnd, K hi, boolean hiInclusive) { + boolean fromStart, K lo, boolean loInclusive, + boolean toEnd, K hi, boolean hiInclusive) { super(m, fromStart, lo, loInclusive, toEnd, hi, hiInclusive); } private final Comparator reverseComparator = Collections.reverseOrder(m.comparator); + @Override public Comparator comparator() { return reverseComparator; } + @Override public NavigableMap subMap(K fromKey, boolean fromInclusive, - K toKey, boolean toInclusive) { + K toKey, boolean toInclusive) { if (!inRange(fromKey, fromInclusive)) throw new IllegalArgumentException("fromKey out of range"); if (!inRange(toKey, toInclusive)) @@ -1979,6 +2137,7 @@ public NavigableMap subMap(K fromKey, boolean fromInclusive, false, fromKey, fromInclusive); } + @Override public NavigableMap headMap(K toKey, boolean inclusive) { if (!inRange(toKey, inclusive)) throw new IllegalArgumentException("toKey out of range"); @@ -1987,6 +2146,7 @@ public NavigableMap headMap(K toKey, boolean inclusive) { toEnd, hi, hiInclusive); } + @Override public NavigableMap tailMap(K fromKey, boolean inclusive) { if (!inRange(fromKey, inclusive)) throw new IllegalArgumentException("fromKey out of range"); @@ -1995,54 +2155,65 @@ public NavigableMap tailMap(K fromKey, boolean inclusive) { false, fromKey, inclusive); } + @Override public NavigableMap descendingMap() { NavigableMap mv = descendingMapView; return (mv != null) ? mv : - (descendingMapView = - new AscendingSubMap(m, - fromStart, lo, loInclusive, - toEnd, hi, hiInclusive)); + (descendingMapView = + new AscendingSubMap(m, + fromStart, lo, loInclusive, + toEnd, hi, hiInclusive)); } + @Override Iterator keyIterator() { return new DescendingSubMapKeyIterator(absHighest(), absLowFence()); } + @Override Iterator descendingKeyIterator() { return new SubMapKeyIterator(absLowest(), absHighFence()); } final class DescendingEntrySetView extends EntrySetView { + @Override public Iterator> iterator() { return new DescendingSubMapEntryIterator(absHighest(), absLowFence()); } } + @Override public Set> entrySet() { EntrySetView es = entrySetView; return (es != null) ? es : new DescendingEntrySetView(); } + @Override IndexedTreeMap.Entry subLowest() { return absHighest(); } + @Override IndexedTreeMap.Entry subHighest() { return absLowest(); } + @Override IndexedTreeMap.Entry subCeiling(K key) { return absFloor(key); } + @Override IndexedTreeMap.Entry subHigher(K key) { return absLower(key); } + @Override IndexedTreeMap.Entry subFloor(K key) { return absCeiling(key); } + @Override IndexedTreeMap.Entry subLower(K key) { return absHigher(key); } @@ -2058,7 +2229,7 @@ IndexedTreeMap.Entry subLower(K key) { * @serial include */ private class SubMap extends AbstractMap - implements SortedMap, java.io.Serializable { + implements SortedMap, java.io.Serializable { private static final long serialVersionUID = -6520786458950516097L; private boolean fromStart = false, toEnd = false; private K fromKey, toKey; @@ -2069,30 +2240,37 @@ private Object readResolve() { toEnd, toKey, false); } + @Override public Set> entrySet() { throw new InternalError(); } + @Override public K lastKey() { throw new InternalError(); } + @Override public K firstKey() { throw new InternalError(); } + @Override public SortedMap subMap(K fromKey, K toKey) { throw new InternalError(); } + @Override public SortedMap headMap(K toKey) { throw new InternalError(); } + @Override public SortedMap tailMap(K fromKey) { throw new InternalError(); } + @Override public Comparator comparator() { throw new InternalError(); } @@ -2148,6 +2326,7 @@ void updateWeight(int delta) { * * @return the key */ + @Override public K getKey() { return key; } @@ -2157,6 +2336,7 @@ public K getKey() { * * @return the value associated with the key */ + @Override public V getValue() { return value; } @@ -2168,12 +2348,14 @@ public V getValue() { * @return the value associated with the key before this method was * called */ + @Override public V setValue(V value) { V oldValue = this.value; this.value = value; return oldValue; } + @Override public boolean equals(Object o) { if (!(o instanceof Map.Entry)) return false; @@ -2182,12 +2364,14 @@ public boolean equals(Object o) { return valEquals(key, e.getKey()) && valEquals(value, e.getValue()); } + @Override public int hashCode() { int keyHash = (key == null ? 0 : key.hashCode()); int valueHash = (value == null ? 0 : value.hashCode()); return keyHash ^ valueHash; } + @Override public String toString() { return key + "=" + value; } @@ -2464,13 +2648,13 @@ private void deleteEntry(Entry p) { if (p.parent != null) { if (p == p.parent.left) { -// int delta = -getWeight(p.parent.left); + // int delta = -getWeight(p.parent.left); p.parent.left = null; -// p.parent.updateWeight(delta); + // p.parent.updateWeight(delta); } else if (p == p.parent.right) { -// int delta = -getWeight(p.parent.right); + // int delta = -getWeight(p.parent.right); p.parent.right = null; -// p.parent.updateWeight(delta); + // p.parent.updateWeight(delta); } p.parent.updateWeight(-1); @@ -2652,9 +2836,9 @@ void addAllForTreeSet(SortedSet set, V defaultVal) { * This cannot occur if str is null. */ private void buildFromSorted(int size, Iterator it, - java.io.ObjectInputStream str, - V defaultVal) - throws java.io.IOException, ClassNotFoundException { + java.io.ObjectInputStream str, + V defaultVal) + throws java.io.IOException, ClassNotFoundException { this.size = size; root = buildFromSorted(0, 0, size - 1, computeRedLevel(size), it, str, defaultVal); @@ -2675,11 +2859,11 @@ private void buildFromSorted(int size, Iterator it, * Must be equal to computeRedLevel for tree of this size. */ private final Entry buildFromSorted(int level, int lo, int hi, - int redLevel, - Iterator it, - java.io.ObjectInputStream str, - V defaultVal) - throws java.io.IOException, ClassNotFoundException { + int redLevel, + Iterator it, + java.io.ObjectInputStream str, + V defaultVal) + throws java.io.IOException, ClassNotFoundException { /* * Strategy: The root is the middlemost element. To get to it, we * have to first recursively construct the entire left subtree, From e5ccca2ba23499bb5c3fcec6e8efc63a8ceacb8c Mon Sep 17 00:00:00 2001 From: tastybento Date: Mon, 11 Nov 2019 23:04:03 -0800 Subject: [PATCH 07/16] Fixes some code smells. --- .../java/world/bentobox/likes/LikesAddon.java | 554 ++++++++-------- .../world/bentobox/likes/config/Settings.java | 600 +++++++++--------- .../world/bentobox/likes/panels/GuiUtils.java | 13 +- .../likes/panels/admin/AdminPanel.java | 7 +- .../likes/panels/admin/EditSettingsPanel.java | 6 +- .../likes/panels/user/LikesViewPanel.java | 13 - .../likes/panels/user/TopLikesPanel.java | 17 +- .../likes/panels/util/SelectBlocksGUI.java | 427 ++++++------- .../world/bentobox/likes/utils/Utils.java | 4 +- .../likes/utils/collections/AbstractMap.java | 16 +- .../likes/utils/collections/AbstractSet.java | 13 +- .../utils/collections/IndexedTreeMap.java | 60 +- .../utils/collections/IndexedTreeSet.java | 27 +- 13 files changed, 857 insertions(+), 900 deletions(-) diff --git a/src/main/java/world/bentobox/likes/LikesAddon.java b/src/main/java/world/bentobox/likes/LikesAddon.java index 37f8c64..16458f5 100644 --- a/src/main/java/world/bentobox/likes/LikesAddon.java +++ b/src/main/java/world/bentobox/likes/LikesAddon.java @@ -30,281 +30,281 @@ */ public class LikesAddon extends Addon { - // --------------------------------------------------------------------- - // Section: Methods - // --------------------------------------------------------------------- - - - /** - * Executes code when loading the addon. This is called before {@link #onEnable()}. - * This must be used to setup configuration, worlds and commands. - */ - @Override - public void onLoad() - { - super.onLoad(); - - // in most of addons, onLoad we want to store default configuration if it does not - // exist and load it. - - // Storing default configuration is simple. But be aware, you need - // @StoreAt(filename="config.yml", path="addons/Likes") in header of your Config file. - this.saveDefaultConfig(); - - this.settings = new Config<>(this, Settings.class).loadConfigObject(); - - if (this.settings == null) - { - // If we failed to load Settings then we should not enable addon. - // We can log error and set state to DISABLED. - - this.logError("Likes settings could not load! Addon disabled."); - this.setState(State.DISABLED); - } - } - - - /** - * Executes code when enabling the addon. This is called after {@link #onLoad()}. - *
Note that commands and worlds registration must be done in {@link - * #onLoad()}, if need be. Failure to do so will result in issues such as - * tab-completion not working for commands. - */ - @Override - public void onEnable() - { - // Check if it is enabled - it might be loaded, but not enabled. - - if (this.getPlugin() == null || !this.getPlugin().isEnabled()) - { - Bukkit.getLogger().severe("BentoBox is not available or disabled!"); - this.setState(State.DISABLED); - return; - } - - // Check if addon is not disabled before. - - if (this.getState().equals(State.DISABLED)) - { - Bukkit.getLogger().severe("Likes Addon is not available or disabled!"); - return; - } - - // Initialize data manager - this.manager = new LikesManager(this); - - // If your addon wants to hook into other GameModes, f.e. use flags, then you should - // hook these flags into each GameMode. - - // Fortunately BentoBox provides ability to a list of all loaded GameModes. - - this.getPlugin().getAddonsManager().getGameModeAddons().forEach(gameModeAddon -> { - // In Settings (and config) we define DisabledGameModes, list of GameModes where - // current Addon should not work. - // This is where we do not hook current addon into GameMode addon. - - if (!this.settings.getDisabledGameModes().contains(gameModeAddon.getDescription().getName())) - { - // Each GameMode could have Player Command and Admin Command and we could - // want to integrate our Example Command into these commands. - // It provides ability to call command with GameMode command f.e. "/island example" - - // Of course we should check if these commands exists, as it is possible to - // create GameMode without them. - - gameModeAddon.getPlayerCommand().ifPresent( - playerCommand -> new PlayerCommand(this, playerCommand)); - - gameModeAddon.getAdminCommand().ifPresent( - adminCommand -> new AdminCommand(this, adminCommand)); - - // Register all likes addon placeholders - this.registerAddonPlaceholders(gameModeAddon); - } - }); - - // BentoBox does not manage money, but it provides VaultHook that does it. - // I suggest to do the same trick as with Level addon. Create local variable and - // store if Vault is present there. - - Optional vaultHook = this.getPlugin().getVault(); - - // Even if Vault is installed, it does not mean that economy can be used. It is - // necessary to check it via VaultHook#hook() method. - - if (!vaultHook.isPresent() || !vaultHook.get().hook()) - { - this.vaultHook = null; - this.logWarning("Economy plugin not found by Likes Addon!"); - } - else - { - this.vaultHook = vaultHook.get(); - } - - // Check if warps exist, so players could warp when they click on player icon. - - Optional warps = this.getPlugin().getAddonsManager().getAddonByName("Warps"); - - if (warps.isPresent()) - { - this.warpHook = (Warp) warps.get(); - } - else - { - this.warpHook = null; - this.logWarning("Warps addon not found by Likes Addon!"); - } - - // Register Listener - this.registerListener(new ResetListener(this)); - - // Register Request Handlers - this.registerRequestHandler(new LikesRequestHandler(this)); - this.registerRequestHandler(new TopTenRequestHandler(this)); - } - - - /** - * Executes code when reloading the addon. - */ - @Override - public void onReload() - { - super.onReload(); - - // onReload most of addons just need to reload configuration. - // If flags, listeners and handlers were set up correctly via Addon.class then - // they will be reloaded automatically. - - this.settings = new Config<>(this, Settings.class).loadConfigObject(); - - if (this.settings == null) - { - // If we failed to load Settings then we should not enable addon. - // We can log error and set state to DISABLED. - - this.logError("Likes settings could not load! Addon disabled."); - this.setState(State.DISABLED); - } - } - - - /** - * Executes code when disabling the addon. - */ - @Override - public void onDisable() - { - // onDisable we would like to save exisitng settings. It is not necessary for - // addons that does not have interface for settings editing! - - if (this.settings != null) - { - new Config<>(this, Settings.class).saveConfigObject(this.settings); - } - - this.manager.save(); - } - - - /** - * This is simple method that adds given event to plugin manager. - * @param event BentoBoxEvent that is triggered. - */ - public void callEvent(BentoBoxEvent event) - { - Bukkit.getServer().getPluginManager().callEvent(event); - } - - - /** - * Registers LikesAddon placeholders for this gameMode Addon. - * @param gameModeAddon the gameMode Addon to register the LikesAddon placeholders. - */ - public void registerAddonPlaceholders(@NonNull GameModeAddon gameModeAddon) - { - final PlaceholdersManager manager = this.getPlugin().getPlaceholdersManager(); - - Arrays.stream(LikesAddonPlaceholderType.values()). - filter(placeholder -> !manager.isPlaceholder(gameModeAddon, placeholder.getPlaceholder())). - forEach(placeholder -> manager.registerPlaceholder(gameModeAddon, - placeholder.getPlaceholder(), - new LikesAddonPlaceholder(this, gameModeAddon, placeholder))); - } - - -// --------------------------------------------------------------------- -// Section: Getters -// --------------------------------------------------------------------- - - - /** - * This getter will allow to access to VaultHook. It is written so that it could - * return null, if Vault is not present. - * @return {@code VaultHook} if it is present, {@code null} otherwise. - */ - public VaultHook getVaultHook() - { - return this.vaultHook; - } - - - /** - * Method LikesAddon#getWarpHook returns the warpHook of this object. - * - * @return {@code Warp} of this object, {@code null} otherwise. - */ - public Warp getWarpHook() - { - return this.warpHook; - } - - - /** - * Method LikesAddon#getSettings returns the settings of this object. - * - * @return the settings (type Settings) of this object. - */ - public Settings getSettings() - { - return this.settings; - } - - - /** - * Method LikesAddon#getManager returns the manager of this object. - * - * @return the manager (type LikesManager) of this object. - */ - public LikesManager getManager() - { - return this.manager; - } - - -// --------------------------------------------------------------------- -// Section: Variables -// --------------------------------------------------------------------- - - - /** - * Settings object contains - */ - private Settings settings; - - /** - * Likes addon manager. - */ - private LikesManager manager; - - /** - * Local variable that stores if vaultHook is present. - */ - private VaultHook vaultHook; - - /** - * Local variable that stores if vaultHook is present. - */ - private Warp warpHook; + // --------------------------------------------------------------------- + // Section: Methods + // --------------------------------------------------------------------- + + + /** + * Executes code when loading the addon. This is called before {@link #onEnable()}. + * This must be used to setup configuration, worlds and commands. + */ + @Override + public void onLoad() + { + super.onLoad(); + + // in most of addons, onLoad we want to store default configuration if it does not + // exist and load it. + + // Storing default configuration is simple. But be aware, you need + // @StoreAt(filename="config.yml", path="addons/Likes") in header of your Config file. + this.saveDefaultConfig(); + + this.settings = new Config<>(this, Settings.class).loadConfigObject(); + + if (this.settings == null) + { + // If we failed to load Settings then we should not enable addon. + // We can log error and set state to DISABLED. + + this.logError("Likes settings could not load! Addon disabled."); + this.setState(State.DISABLED); + } + } + + + /** + * Executes code when enabling the addon. This is called after {@link #onLoad()}. + *
Note that commands and worlds registration must be done in {@link + * #onLoad()}, if need be. Failure to do so will result in issues such as + * tab-completion not working for commands. + */ + @Override + public void onEnable() + { + // Check if it is enabled - it might be loaded, but not enabled. + + if (this.getPlugin() == null || !this.getPlugin().isEnabled()) + { + Bukkit.getLogger().severe("BentoBox is not available or disabled!"); + this.setState(State.DISABLED); + return; + } + + // Check if addon is not disabled before. + + if (this.getState().equals(State.DISABLED)) + { + Bukkit.getLogger().severe("Likes Addon is not available or disabled!"); + return; + } + + // Initialize data manager + this.manager = new LikesManager(this); + + // If your addon wants to hook into other GameModes, f.e. use flags, then you should + // hook these flags into each GameMode. + + // Fortunately BentoBox provides ability to a list of all loaded GameModes. + + this.getPlugin().getAddonsManager().getGameModeAddons().forEach(gameModeAddon -> { + // In Settings (and config) we define DisabledGameModes, list of GameModes where + // current Addon should not work. + // This is where we do not hook current addon into GameMode addon. + + if (!this.settings.getDisabledGameModes().contains(gameModeAddon.getDescription().getName())) + { + // Each GameMode could have Player Command and Admin Command and we could + // want to integrate our Example Command into these commands. + // It provides ability to call command with GameMode command f.e. "/island example" + + // Of course we should check if these commands exists, as it is possible to + // create GameMode without them. + + gameModeAddon.getPlayerCommand().ifPresent( + playerCommand -> new PlayerCommand(this, playerCommand)); + + gameModeAddon.getAdminCommand().ifPresent( + adminCommand -> new AdminCommand(this, adminCommand)); + + // Register all likes addon placeholders + this.registerAddonPlaceholders(gameModeAddon); + } + }); + + // BentoBox does not manage money, but it provides VaultHook that does it. + // I suggest to do the same trick as with Level addon. Create local variable and + // store if Vault is present there. + + Optional vaultHook = this.getPlugin().getVault(); + + // Even if Vault is installed, it does not mean that economy can be used. It is + // necessary to check it via VaultHook#hook() method. + + if (!vaultHook.isPresent() || !vaultHook.get().hook()) + { + this.vaultHook = null; + this.logWarning("Economy plugin not found by Likes Addon!"); + } + else + { + this.vaultHook = vaultHook.get(); + } + + // Check if warps exist, so players could warp when they click on player icon. + + Optional warps = this.getPlugin().getAddonsManager().getAddonByName("Warps"); + + if (warps.isPresent()) + { + this.warpHook = (Warp) warps.get(); + } + else + { + this.warpHook = null; + this.logWarning("Warps addon not found by Likes Addon!"); + } + + // Register Listener + this.registerListener(new ResetListener(this)); + + // Register Request Handlers + this.registerRequestHandler(new LikesRequestHandler(this)); + this.registerRequestHandler(new TopTenRequestHandler(this)); + } + + + /** + * Executes code when reloading the addon. + */ + @Override + public void onReload() + { + super.onReload(); + + // onReload most of addons just need to reload configuration. + // If flags, listeners and handlers were set up correctly via Addon.class then + // they will be reloaded automatically. + + this.settings = new Config<>(this, Settings.class).loadConfigObject(); + + if (this.settings == null) + { + // If we failed to load Settings then we should not enable addon. + // We can log error and set state to DISABLED. + + this.logError("Likes settings could not load! Addon disabled."); + this.setState(State.DISABLED); + } + } + + + /** + * Executes code when disabling the addon. + */ + @Override + public void onDisable() + { + // onDisable we would like to save exisitng settings. It is not necessary for + // addons that does not have interface for settings editing! + + if (this.settings != null) + { + new Config<>(this, Settings.class).saveConfigObject(this.settings); + } + + this.manager.save(); + } + + + /** + * This is simple method that adds given event to plugin manager. + * @param event BentoBoxEvent that is triggered. + */ + public void callEvent(BentoBoxEvent event) + { + Bukkit.getServer().getPluginManager().callEvent(event); + } + + + /** + * Registers LikesAddon placeholders for this gameMode Addon. + * @param gameModeAddon the gameMode Addon to register the LikesAddon placeholders. + */ + public void registerAddonPlaceholders(@NonNull GameModeAddon gameModeAddon) + { + final PlaceholdersManager mgr = this.getPlugin().getPlaceholdersManager(); + + Arrays.stream(LikesAddonPlaceholderType.values()). + filter(placeholder -> !mgr.isPlaceholder(gameModeAddon, placeholder.getPlaceholder())). + forEach(placeholder -> mgr.registerPlaceholder(gameModeAddon, + placeholder.getPlaceholder(), + new LikesAddonPlaceholder(this, gameModeAddon, placeholder))); + } + + + // --------------------------------------------------------------------- + // Section: Getters + // --------------------------------------------------------------------- + + + /** + * This getter will allow to access to VaultHook. It is written so that it could + * return null, if Vault is not present. + * @return {@code VaultHook} if it is present, {@code null} otherwise. + */ + public VaultHook getVaultHook() + { + return this.vaultHook; + } + + + /** + * Method LikesAddon#getWarpHook returns the warpHook of this object. + * + * @return {@code Warp} of this object, {@code null} otherwise. + */ + public Warp getWarpHook() + { + return this.warpHook; + } + + + /** + * Method LikesAddon#getSettings returns the settings of this object. + * + * @return the settings (type Settings) of this object. + */ + public Settings getSettings() + { + return this.settings; + } + + + /** + * Method LikesAddon#getManager returns the manager of this object. + * + * @return the manager (type LikesManager) of this object. + */ + public LikesManager getManager() + { + return this.manager; + } + + + // --------------------------------------------------------------------- + // Section: Variables + // --------------------------------------------------------------------- + + + /** + * Settings object contains + */ + private Settings settings; + + /** + * Likes addon manager. + */ + private LikesManager manager; + + /** + * Local variable that stores if vaultHook is present. + */ + private VaultHook vaultHook; + + /** + * Local variable that stores if vaultHook is present. + */ + private Warp warpHook; } diff --git a/src/main/java/world/bentobox/likes/config/Settings.java b/src/main/java/world/bentobox/likes/config/Settings.java index 9a6abfe..84df298 100644 --- a/src/main/java/world/bentobox/likes/config/Settings.java +++ b/src/main/java/world/bentobox/likes/config/Settings.java @@ -28,304 +28,304 @@ @ConfigComment("") public class Settings implements ConfigObject { - // --------------------------------------------------------------------- - // Section: Getters and Setters - // --------------------------------------------------------------------- - - - /** - * This method returns the disabledGameModes value. - * - * @return the value of disabledGameModes. - */ - public Set getDisabledGameModes() - { - return disabledGameModes; - } - - - /** - * This method sets the disabledGameModes value. - * - * @param disabledGameModes the disabledGameModes new value. - */ - public void setDisabledGameModes(Set disabledGameModes) - { - this.disabledGameModes = disabledGameModes; - } - - - /** - * Method Settings#getDefaultIcon returns the defaultIcon of this object. - * - * @return the defaultIcon (type Material) of this object. - */ - public Material getDefaultIcon() - { - return defaultIcon; - } - - - /** - * Method Settings#setDefaultIcon sets new value for the defaultIcon of this object. - * - * @param defaultIcon new value for this object. - */ - public void setDefaultIcon(Material defaultIcon) - { - this.defaultIcon = defaultIcon; - } - - - /** - * Method Settings#isLogHistory returns the logHistory of this object. - * - * @return the logHistory (type boolean) of this object. - */ - public boolean isLogHistory() - { - return logHistory; - } - - - /** - * Method Settings#setLogHistory sets new value for the logHistory of this object. - * - * @param logHistory new value for this object. - */ - public void setLogHistory(boolean logHistory) - { - this.logHistory = logHistory; - } - - - /** - * Method Settings#isResetLikes returns the resetLikes of this object. - * - * @return the resetLikes (type boolean) of this object. - */ - public boolean isResetLikes() - { - return resetLikes; - } - - - /** - * Method Settings#setResetLikes sets new value for the resetLikes of this object. - * @param resetLikes new value for this object. - * - */ - public void setResetLikes(boolean resetLikes) - { - this.resetLikes = resetLikes; - } - - - /** - * Method Settings#getLikeAddCost returns the likeAddCost of this object. - * - * @return the likeAddCost (type double) of this object. - */ - public double getLikeAddCost() - { - return likeAddCost; - } - - - /** - * Method Settings#setLikeAddCost sets new value for the likeAddCost of this object. - * @param likeAddCost new value for this object. - * - */ - public void setLikeAddCost(double likeAddCost) - { - this.likeAddCost = likeAddCost; - } - - - /** - * Method Settings#getLikeRemoveCost returns the likeRemoveCost of this object. - * - * @return the likeRemoveCost (type double) of this object. - */ - public double getLikeRemoveCost() - { - return likeRemoveCost; - } - - - /** - * Method Settings#setLikeRemoveCost sets new value for the likeRemoveCost of this object. - * @param likeRemoveCost new value for this object. - * - */ - public void setLikeRemoveCost(double likeRemoveCost) - { - this.likeRemoveCost = likeRemoveCost; - } - - - /** - * Method Settings#getDislikeAddCost returns the dislikeAddCost of this object. - * - * @return the dislikeAddCost (type double) of this object. - */ - public double getDislikeAddCost() - { - return dislikeAddCost; - } - - - /** - * Method Settings#setDislikeAddCost sets new value for the dislikeAddCost of this object. - * @param dislikeAddCost new value for this object. - * - */ - public void setDislikeAddCost(double dislikeAddCost) - { - this.dislikeAddCost = dislikeAddCost; - } - - - /** - * Method Settings#getDislikeRemoveCost returns the dislikeRemoveCost of this object. - * - * @return the dislikeRemoveCost (type double) of this object. - */ - public double getDislikeRemoveCost() - { - return dislikeRemoveCost; - } - - - /** - * Method Settings#setDislikeRemoveCost sets new value for the dislikeRemoveCost of this object. - * @param dislikeRemoveCost new value for this object. - * - */ - public void setDislikeRemoveCost(double dislikeRemoveCost) - { - this.dislikeRemoveCost = dislikeRemoveCost; - } - - - /** - * Method Settings#isInformPlayers returns the informPlayers of this object. - * - * @return the informPlayers (type boolean) of this object. - */ - public boolean isInformPlayers() - { - return informPlayers; - } - - - /** - * Method Settings#setInformPlayers sets new value for the informPlayers of this object. - * @param informPlayers new value for this object. - * - */ - public void setInformPlayers(boolean informPlayers) - { - this.informPlayers = informPlayers; - } - - -// --------------------------------------------------------------------- -// Section: Variables -// --------------------------------------------------------------------- - - - @ConfigComment("") - @ConfigComment("Default icon for Top Island panel.") - @ConfigComment("Should be valid Material") - @ConfigEntry(path = "default-icon") - private Material defaultIcon = Material.PLAYER_HEAD; - - @ConfigComment("") - @ConfigComment("Allows to store history data about added and removed likes and dislikes.") - @ConfigEntry(path = "log-history") - private boolean logHistory; - - @ConfigComment("") - @ConfigComment("Allows to enable ability to send message to island members about someone") - @ConfigComment("liking or disliking their island.") - @ConfigEntry(path = "inform-members") - private boolean informPlayers; - - @ConfigComment("") - @ConfigComment("Allows reset likes and dislikes after resetting island.") - @ConfigEntry(path = "reset-on-reset") - private boolean resetLikes; - - @ConfigComment("") - @ConfigComment("Allows to define cost for player to add like.") - @ConfigEntry(path = "costs.add-like") - private double likeAddCost; - - @ConfigComment("") - @ConfigComment("Allows to define cost for player to remove like.") - @ConfigEntry(path = "costs.remove-like") - private double likeRemoveCost; - - @ConfigComment("") - @ConfigComment("Allows to define cost for player to add dislike.") - @ConfigEntry(path = "costs.add-dislike") - private double dislikeAddCost; - - @ConfigComment("") - @ConfigComment("Allows to define cost for player to remove dislike.") - @ConfigEntry(path = "costs.remove-dislike") - private double dislikeRemoveCost; - - @ConfigComment("") - @ConfigComment("This list stores GameModes in which Likes addon should not work.") - @ConfigComment("To disable addon it is necessary to write its name in new line that starts with -. Example:") - @ConfigComment("disabled-gamemodes:") - @ConfigComment(" - BSkyBlock") - @ConfigEntry(path = "disabled-gamemodes") - private Set disabledGameModes = new HashSet<>(); - - -// --------------------------------------------------------------------- -// Section: Enums -// --------------------------------------------------------------------- - - - /** - * Allows to select different Modes for viewing or choosing tops - */ - public enum VIEW_MODE - { - LIKES, - DISLIKES, - RANK; - - - /** - * This method returns stored parameter from string. - * @param parameter String of object that must be returned - * @return CommandParameters object or null. - */ - public static VIEW_MODE getMode(String parameter) - { - return BY_NAME.get(parameter); - } - - /** - * This map allows to access all enum values via their string. - */ - private final static Map BY_NAME = new HashMap<>(); - - /** - * This static method populated BY_NAME map. - */ - static - { - for (VIEW_MODE mode : VIEW_MODE.values()) - { - BY_NAME.put(mode.name(), mode); - } - } - } + // --------------------------------------------------------------------- + // Section: Getters and Setters + // --------------------------------------------------------------------- + + + /** + * This method returns the disabledGameModes value. + * + * @return the value of disabledGameModes. + */ + public Set getDisabledGameModes() + { + return disabledGameModes; + } + + + /** + * This method sets the disabledGameModes value. + * + * @param disabledGameModes the disabledGameModes new value. + */ + public void setDisabledGameModes(Set disabledGameModes) + { + this.disabledGameModes = disabledGameModes; + } + + + /** + * Method Settings#getDefaultIcon returns the defaultIcon of this object. + * + * @return the defaultIcon (type Material) of this object. + */ + public Material getDefaultIcon() + { + return defaultIcon; + } + + + /** + * Method Settings#setDefaultIcon sets new value for the defaultIcon of this object. + * + * @param defaultIcon new value for this object. + */ + public void setDefaultIcon(Material defaultIcon) + { + this.defaultIcon = defaultIcon; + } + + + /** + * Method Settings#isLogHistory returns the logHistory of this object. + * + * @return the logHistory (type boolean) of this object. + */ + public boolean isLogHistory() + { + return logHistory; + } + + + /** + * Method Settings#setLogHistory sets new value for the logHistory of this object. + * + * @param logHistory new value for this object. + */ + public void setLogHistory(boolean logHistory) + { + this.logHistory = logHistory; + } + + + /** + * Method Settings#isResetLikes returns the resetLikes of this object. + * + * @return the resetLikes (type boolean) of this object. + */ + public boolean isResetLikes() + { + return resetLikes; + } + + + /** + * Method Settings#setResetLikes sets new value for the resetLikes of this object. + * @param resetLikes new value for this object. + * + */ + public void setResetLikes(boolean resetLikes) + { + this.resetLikes = resetLikes; + } + + + /** + * Method Settings#getLikeAddCost returns the likeAddCost of this object. + * + * @return the likeAddCost (type double) of this object. + */ + public double getLikeAddCost() + { + return likeAddCost; + } + + + /** + * Method Settings#setLikeAddCost sets new value for the likeAddCost of this object. + * @param likeAddCost new value for this object. + * + */ + public void setLikeAddCost(double likeAddCost) + { + this.likeAddCost = likeAddCost; + } + + + /** + * Method Settings#getLikeRemoveCost returns the likeRemoveCost of this object. + * + * @return the likeRemoveCost (type double) of this object. + */ + public double getLikeRemoveCost() + { + return likeRemoveCost; + } + + + /** + * Method Settings#setLikeRemoveCost sets new value for the likeRemoveCost of this object. + * @param likeRemoveCost new value for this object. + * + */ + public void setLikeRemoveCost(double likeRemoveCost) + { + this.likeRemoveCost = likeRemoveCost; + } + + + /** + * Method Settings#getDislikeAddCost returns the dislikeAddCost of this object. + * + * @return the dislikeAddCost (type double) of this object. + */ + public double getDislikeAddCost() + { + return dislikeAddCost; + } + + + /** + * Method Settings#setDislikeAddCost sets new value for the dislikeAddCost of this object. + * @param dislikeAddCost new value for this object. + * + */ + public void setDislikeAddCost(double dislikeAddCost) + { + this.dislikeAddCost = dislikeAddCost; + } + + + /** + * Method Settings#getDislikeRemoveCost returns the dislikeRemoveCost of this object. + * + * @return the dislikeRemoveCost (type double) of this object. + */ + public double getDislikeRemoveCost() + { + return dislikeRemoveCost; + } + + + /** + * Method Settings#setDislikeRemoveCost sets new value for the dislikeRemoveCost of this object. + * @param dislikeRemoveCost new value for this object. + * + */ + public void setDislikeRemoveCost(double dislikeRemoveCost) + { + this.dislikeRemoveCost = dislikeRemoveCost; + } + + + /** + * Method Settings#isInformPlayers returns the informPlayers of this object. + * + * @return the informPlayers (type boolean) of this object. + */ + public boolean isInformPlayers() + { + return informPlayers; + } + + + /** + * Method Settings#setInformPlayers sets new value for the informPlayers of this object. + * @param informPlayers new value for this object. + * + */ + public void setInformPlayers(boolean informPlayers) + { + this.informPlayers = informPlayers; + } + + + // --------------------------------------------------------------------- + // Section: Variables + // --------------------------------------------------------------------- + + + @ConfigComment("") + @ConfigComment("Default icon for Top Island panel.") + @ConfigComment("Should be valid Material") + @ConfigEntry(path = "default-icon") + private Material defaultIcon = Material.PLAYER_HEAD; + + @ConfigComment("") + @ConfigComment("Allows to store history data about added and removed likes and dislikes.") + @ConfigEntry(path = "log-history") + private boolean logHistory; + + @ConfigComment("") + @ConfigComment("Allows to enable ability to send message to island members about someone") + @ConfigComment("liking or disliking their island.") + @ConfigEntry(path = "inform-members") + private boolean informPlayers; + + @ConfigComment("") + @ConfigComment("Allows reset likes and dislikes after resetting island.") + @ConfigEntry(path = "reset-on-reset") + private boolean resetLikes; + + @ConfigComment("") + @ConfigComment("Allows to define cost for player to add like.") + @ConfigEntry(path = "costs.add-like") + private double likeAddCost; + + @ConfigComment("") + @ConfigComment("Allows to define cost for player to remove like.") + @ConfigEntry(path = "costs.remove-like") + private double likeRemoveCost; + + @ConfigComment("") + @ConfigComment("Allows to define cost for player to add dislike.") + @ConfigEntry(path = "costs.add-dislike") + private double dislikeAddCost; + + @ConfigComment("") + @ConfigComment("Allows to define cost for player to remove dislike.") + @ConfigEntry(path = "costs.remove-dislike") + private double dislikeRemoveCost; + + @ConfigComment("") + @ConfigComment("This list stores GameModes in which Likes addon should not work.") + @ConfigComment("To disable addon it is necessary to write its name in new line that starts with -. Example:") + @ConfigComment("disabled-gamemodes:") + @ConfigComment(" - BSkyBlock") + @ConfigEntry(path = "disabled-gamemodes") + private Set disabledGameModes = new HashSet<>(); + + + // --------------------------------------------------------------------- + // Section: Enums + // --------------------------------------------------------------------- + + + /** + * Allows to select different Modes for viewing or choosing tops + */ + public enum VIEW_MODE + { + LIKES, + DISLIKES, + RANK; + + + /** + * This method returns stored parameter from string. + * @param parameter String of object that must be returned + * @return CommandParameters object or null. + */ + public static VIEW_MODE getMode(String parameter) + { + return BY_NAME.get(parameter); + } + + /** + * This map allows to access all enum values via their string. + */ + private static final Map BY_NAME = new HashMap<>(); + + /* + * This static method populated BY_NAME map. + */ + static + { + for (VIEW_MODE mode : VIEW_MODE.values()) + { + BY_NAME.put(mode.name(), mode); + } + } + } } diff --git a/src/main/java/world/bentobox/likes/panels/GuiUtils.java b/src/main/java/world/bentobox/likes/panels/GuiUtils.java index 7e20e0a..0e07314 100644 --- a/src/main/java/world/bentobox/likes/panels/GuiUtils.java +++ b/src/main/java/world/bentobox/likes/panels/GuiUtils.java @@ -5,15 +5,12 @@ import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.inventory.ItemStack; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - import world.bentobox.bentobox.api.panels.PanelItem; import world.bentobox.bentobox.api.panels.builders.PanelBuilder; import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder; +import java.util.*; + /** * This class contains static methods that is used through multiple GUIs. @@ -113,7 +110,7 @@ private BorderBlock(ItemStack icon) private static BorderBlock getPanelBorder(Material material) { ItemStack itemStack = new ItemStack(material); - itemStack.getItemMeta().setDisplayName(" "); + Objects.requireNonNull(itemStack.getItemMeta()).setDisplayName(" "); return new BorderBlock(itemStack); } @@ -205,12 +202,12 @@ public static ItemStack getMaterialItem(Material material, int amount) if (material.name().contains("WALL_")) { // Materials that is attached to wall cannot be showed in GUI. But they should be in list. - itemStack = new ItemStack(Material.getMaterial(material.name().replace("WALL_", ""))); + itemStack = new ItemStack(Objects.requireNonNull(Material.getMaterial(material.name().replace("WALL_", "")))); } else if (material.name().startsWith("POTTED_")) { // Materials Potted elements cannot be in inventory. - itemStack = new ItemStack(Material.getMaterial(material.name().replace("POTTED_", ""))); + itemStack = new ItemStack(Objects.requireNonNull(Material.getMaterial(material.name().replace("POTTED_", "")))); } else if (material.equals(Material.MELON_STEM) || material.equals(Material.ATTACHED_MELON_STEM)) { diff --git a/src/main/java/world/bentobox/likes/panels/admin/AdminPanel.java b/src/main/java/world/bentobox/likes/panels/admin/AdminPanel.java index 2d139f3..d5a008d 100644 --- a/src/main/java/world/bentobox/likes/panels/admin/AdminPanel.java +++ b/src/main/java/world/bentobox/likes/panels/admin/AdminPanel.java @@ -94,7 +94,6 @@ private PanelItem createButton(Button button) ItemStack icon; String name; String description; - boolean glow; PanelItem.ClickHandler clickHandler; switch (button) @@ -108,7 +107,6 @@ private PanelItem createButton(Button button) ListIslandsPanel.open(this, ListIslandsPanel.Type.MANAGE); return true; }; - glow = false; break; } @@ -121,7 +119,6 @@ private PanelItem createButton(Button button) ListIslandsPanel.open(this, ListIslandsPanel.Type.ICON); return true; }; - glow = false; break; } @@ -134,7 +131,6 @@ private PanelItem createButton(Button button) this.addon.getManager().wipeData(this.world); return true; }; - glow = false; break; } @@ -147,7 +143,6 @@ private PanelItem createButton(Button button) EditSettingsPanel.openPanel(this.addon, this.user, this.world, this.permissionPrefix); return true; }; - glow = false; break; } @@ -159,7 +154,7 @@ private PanelItem createButton(Button button) icon(icon). name(name). description(GuiUtils.stringSplit(description, 999)). - glow(glow). + glow(false). clickHandler(clickHandler). build(); } diff --git a/src/main/java/world/bentobox/likes/panels/admin/EditSettingsPanel.java b/src/main/java/world/bentobox/likes/panels/admin/EditSettingsPanel.java index 8f8ed9c..c1caf1b 100644 --- a/src/main/java/world/bentobox/likes/panels/admin/EditSettingsPanel.java +++ b/src/main/java/world/bentobox/likes/panels/admin/EditSettingsPanel.java @@ -165,7 +165,7 @@ private PanelItem createButton(Button button) name = this.user.getTranslation(Constants.BUTTON + "like-remove-cost"); description.add(this.user.getTranslation(Constants.DESCRIPTION + "like-remove-cost")); description.add(this.user.getTranslation(Constants.DESCRIPTION + "current-value", - "[value]", String.valueOf(this.settings.getLikeRemoveCost())));; + "[value]", String.valueOf(this.settings.getLikeRemoveCost()))); icon = new ItemStack(Material.GOLD_NUGGET); clickHandler = (panel, user, clickType, slot) -> { this.getNumberInput(number -> this.settings.setLikeRemoveCost(number.doubleValue()), @@ -181,7 +181,7 @@ private PanelItem createButton(Button button) name = this.user.getTranslation(Constants.BUTTON + "dislike-cost"); description.add(this.user.getTranslation(Constants.DESCRIPTION + "dislike-cost")); description.add(this.user.getTranslation(Constants.DESCRIPTION + "current-value", - "[value]", String.valueOf(this.settings.getDislikeAddCost())));; + "[value]", String.valueOf(this.settings.getDislikeAddCost()))); icon = new ItemStack(Material.IRON_INGOT); clickHandler = (panel, user, clickType, slot) -> { this.getNumberInput(number -> this.settings.setDislikeAddCost(number.doubleValue()), @@ -197,7 +197,7 @@ private PanelItem createButton(Button button) name = this.user.getTranslation(Constants.BUTTON + "dislike-remove-cost"); description.add(this.user.getTranslation(Constants.DESCRIPTION + "dislike-remove-cost")); description.add(this.user.getTranslation(Constants.DESCRIPTION + "current-value", - "[value]", String.valueOf(this.settings.getDislikeRemoveCost())));; + "[value]", String.valueOf(this.settings.getDislikeRemoveCost()))); icon = new ItemStack(Material.IRON_NUGGET); clickHandler = (panel, user, clickType, slot) -> { this.getNumberInput(number -> this.settings.setDislikeRemoveCost(number.doubleValue()), diff --git a/src/main/java/world/bentobox/likes/panels/user/LikesViewPanel.java b/src/main/java/world/bentobox/likes/panels/user/LikesViewPanel.java index 984bc5b..8bbd113 100644 --- a/src/main/java/world/bentobox/likes/panels/user/LikesViewPanel.java +++ b/src/main/java/world/bentobox/likes/panels/user/LikesViewPanel.java @@ -49,9 +49,6 @@ private LikesViewPanel(@NonNull LikesAddon addon, { this.addon = addon; this.user = user; - this.world = world; - - this.permissionPrefix = permissionPrefix; this.likesObject = likesObject; @@ -424,16 +421,6 @@ private enum Button */ private final User user; - /** - * This variable holds a world to which gui referee. - */ - private final World world; - - /** - * Permission prefix - */ - private final String permissionPrefix; - /** * This variable holds likes object that is view by user in current gui. */ diff --git a/src/main/java/world/bentobox/likes/panels/user/TopLikesPanel.java b/src/main/java/world/bentobox/likes/panels/user/TopLikesPanel.java index 434ee00..d1006d6 100644 --- a/src/main/java/world/bentobox/likes/panels/user/TopLikesPanel.java +++ b/src/main/java/world/bentobox/likes/panels/user/TopLikesPanel.java @@ -7,7 +7,6 @@ import org.bukkit.World; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Optional; import java.util.UUID; @@ -50,9 +49,12 @@ private TopLikesPanel(LikesAddon addon, User user, World world, String permissio this.user = user; this.world = world; - this.permissionPrefix = permissionPrefix; + /* + * Permission prefix + */ + String permissionPrefix1 = permissionPrefix; - this.iconPermission = this.permissionPrefix + "likes.icon"; + this.iconPermission = permissionPrefix1 + "likes.icon"; this.viewMode = mode; this.topPlayerList = new ArrayList<>(10); @@ -323,7 +325,7 @@ private PanelItem createPlayerButton(LikesObject likesObject, int rank) PanelItem panelItem; - if (icon.equals(Material.PLAYER_HEAD)) + if (icon == null || icon.equals(Material.PLAYER_HEAD)) { panelItem = new PanelItemBuilder(). name(this.user.getTranslation(Constants.BUTTON + "name", "[name]", name)). @@ -368,11 +370,6 @@ private PanelItem createPlayerButton(LikesObject likesObject, int rank) */ private final World world; - /** - * Permission prefix - */ - private final String permissionPrefix; - /** * Location to icon permission. */ @@ -397,7 +394,7 @@ private PanelItem createPlayerButton(LikesObject likesObject, int rank) */ private static final int[] PLACEMENTS = new int[10]; - /** + /* * Populate button indexes */ static diff --git a/src/main/java/world/bentobox/likes/panels/util/SelectBlocksGUI.java b/src/main/java/world/bentobox/likes/panels/util/SelectBlocksGUI.java index a9204b3..4c8f377 100644 --- a/src/main/java/world/bentobox/likes/panels/util/SelectBlocksGUI.java +++ b/src/main/java/world/bentobox/likes/panels/util/SelectBlocksGUI.java @@ -21,217 +21,218 @@ */ public class SelectBlocksGUI { - private SelectBlocksGUI(User user, boolean singleSelect, Set excludedMaterial, BiConsumer> consumer) - { - this.consumer = consumer; - this.user = user; - this.singleSelect = singleSelect; - - // Current GUI cannot display air blocks. It crashes with null-pointer - excludedMaterial.add(Material.AIR); - excludedMaterial.add(Material.CAVE_AIR); - excludedMaterial.add(Material.VOID_AIR); - - // Piston head and moving piston is not necessary. useless. - excludedMaterial.add(Material.PISTON_HEAD); - excludedMaterial.add(Material.MOVING_PISTON); - - // Barrier cannot be accessible to user. - excludedMaterial.add(Material.BARRIER); - - this.elements = new ArrayList<>(); - this.selectedMaterials = new HashSet<>(); - - for (Material material : Material.values()) - { - if (material.isBlock() && !material.isLegacy() && !excludedMaterial.contains(material)) - { - this.elements.add(material); - } - } - } - - - public static void open(User user, BiConsumer> consumer) - { - new SelectBlocksGUI(user, true, new HashSet<>(), consumer).build(0); - } - - -// --------------------------------------------------------------------- -// Section: Methods -// --------------------------------------------------------------------- - - - /** - * This method builds all necessary elements in GUI panel. - */ - private void build(int pageIndex) - { - PanelBuilder panelBuilder = new PanelBuilder().user(this.user). - name(this.user.getTranslation(Constants.TITLE + "select-block")); - - GuiUtils.fillBorder(panelBuilder, Material.BLUE_STAINED_GLASS_PANE); - - final int MAX_ELEMENTS = 21; - final int correctPage; - - if (pageIndex < 0) - { - correctPage = this.elements.size() / MAX_ELEMENTS; - } - else if (pageIndex > (this.elements.size() / MAX_ELEMENTS)) - { - correctPage = 0; - } - else - { - correctPage = pageIndex; - } - - int entitiesIndex = MAX_ELEMENTS * correctPage; - - // I want first row to be only for navigation and return button. - int index = 10; - - while (entitiesIndex < ((correctPage + 1) * MAX_ELEMENTS) && - entitiesIndex < this.elements.size()) - { - if (!panelBuilder.slotOccupied(index)) - { - panelBuilder.item(index, this.createMaterialButton(this.elements.get(entitiesIndex++))); - } - - index++; - } - - panelBuilder.item(3, - new PanelItemBuilder(). - icon(Material.RED_STAINED_GLASS_PANE). - name(this.user.getTranslation(Constants.BUTTON + "cancel")). - clickHandler( (panel, user1, clickType, slot) -> { - this.consumer.accept(false, null); - return true; - }).build()); - - - List description = new ArrayList<>(); - if (!this.selectedMaterials.isEmpty()) - { - description.add(this.user.getTranslation(Constants.DESCRIPTION + "selected") + ":"); - this.selectedMaterials.forEach(material -> description.add(" - " + material.name())); - } - - panelBuilder.item(5, - new PanelItemBuilder(). - icon(Material.GREEN_STAINED_GLASS_PANE). - name(this.user.getTranslation(Constants.BUTTON + "accept")). - description(description). - clickHandler( (panel, user1, clickType, slot) -> { - this.consumer.accept(true, this.selectedMaterials); - return true; - }).build()); - - if (this.elements.size() > MAX_ELEMENTS) - { - // Navigation buttons if necessary - - panelBuilder.item(18, - new PanelItemBuilder(). - icon(Material.OAK_SIGN). - name(this.user.getTranslation(Constants.BUTTON + "previous")). - clickHandler((panel, user1, clickType, slot) -> { - this.build(correctPage - 1); - return true; - }).build()); - - panelBuilder.item(26, - new PanelItemBuilder(). - icon(Material.OAK_SIGN). - name(this.user.getTranslation(Constants.BUTTON + "next")). - clickHandler((panel, user1, clickType, slot) -> { - this.build(correctPage + 1); - return true; - }).build()); - } - - panelBuilder.item(44, - new PanelItemBuilder(). - icon(Material.OAK_DOOR). - name(this.user.getTranslation(Constants.BUTTON + "return")). - clickHandler( (panel, user1, clickType, slot) -> { - this.consumer.accept(false, null); - return true; - }).build()); - - panelBuilder.build(); - } - - - /** - * This method creates PanelItem that represents given material. - * Some materials is not displayable in Inventory GUI, so they are replaced with "placeholder" items. - * @param material Material which icon must be created. - * @return PanelItem that represents given material. - */ - private PanelItem createMaterialButton(Material material) - { - ItemStack itemStack = GuiUtils.getMaterialItem(material); - - return new PanelItemBuilder(). - name(WordUtils.capitalize(material.name().toLowerCase().replace("_", " "))). - description(this.selectedMaterials.contains(material) ? - this.user.getTranslation(Constants.DESCRIPTION + "selected") : ""). - icon(itemStack). - clickHandler((panel, user1, clickType, slot) -> { - if (!this.singleSelect && clickType.isRightClick()) - { - if (!this.selectedMaterials.add(material)) - { - this.selectedMaterials.remove(material); - } - - panel.getInventory().setItem(slot, this.createMaterialButton(material).getItem()); - } - else - { - this.selectedMaterials.add(material); - this.consumer.accept(true, this.selectedMaterials); - } - - return true; - }). - glow(!itemStack.getType().equals(material)). - build(); - } - - -// --------------------------------------------------------------------- -// Section: Variables -// --------------------------------------------------------------------- - - /** - * List with elements that will be displayed in current GUI. - */ - private List elements; - - /** - * Set that contains selected materials. - */ - private Set selectedMaterials; - - /** - * This variable stores consumer. - */ - private BiConsumer> consumer; - - /** - * User who runs GUI. - */ - private User user; - - /** - * This indicate that return set must contain only single item. - */ - private boolean singleSelect; + @SuppressWarnings("deprecation") + private SelectBlocksGUI(User user, boolean singleSelect, Set excludedMaterial, BiConsumer> consumer) + { + this.consumer = consumer; + this.user = user; + this.singleSelect = singleSelect; + + // Current GUI cannot display air blocks. It crashes with null-pointer + excludedMaterial.add(Material.AIR); + excludedMaterial.add(Material.CAVE_AIR); + excludedMaterial.add(Material.VOID_AIR); + + // Piston head and moving piston is not necessary. useless. + excludedMaterial.add(Material.PISTON_HEAD); + excludedMaterial.add(Material.MOVING_PISTON); + + // Barrier cannot be accessible to user. + excludedMaterial.add(Material.BARRIER); + + this.elements = new ArrayList<>(); + this.selectedMaterials = new HashSet<>(); + + for (Material material : Material.values()) + { + if (material.isBlock() && !material.isLegacy() && !excludedMaterial.contains(material)) + { + this.elements.add(material); + } + } + } + + + public static void open(User user, BiConsumer> consumer) + { + new SelectBlocksGUI(user, true, new HashSet<>(), consumer).build(0); + } + + + // --------------------------------------------------------------------- + // Section: Methods + // --------------------------------------------------------------------- + + + /** + * This method builds all necessary elements in GUI panel. + */ + private void build(int pageIndex) + { + PanelBuilder panelBuilder = new PanelBuilder().user(this.user). + name(this.user.getTranslation(Constants.TITLE + "select-block")); + + GuiUtils.fillBorder(panelBuilder, Material.BLUE_STAINED_GLASS_PANE); + + final int MAX_ELEMENTS = 21; + final int correctPage; + + if (pageIndex < 0) + { + correctPage = this.elements.size() / MAX_ELEMENTS; + } + else if (pageIndex > (this.elements.size() / MAX_ELEMENTS)) + { + correctPage = 0; + } + else + { + correctPage = pageIndex; + } + + int entitiesIndex = MAX_ELEMENTS * correctPage; + + // I want first row to be only for navigation and return button. + int index = 10; + + while (entitiesIndex < ((correctPage + 1) * MAX_ELEMENTS) && + entitiesIndex < this.elements.size()) + { + if (!panelBuilder.slotOccupied(index)) + { + panelBuilder.item(index, this.createMaterialButton(this.elements.get(entitiesIndex++))); + } + + index++; + } + + panelBuilder.item(3, + new PanelItemBuilder(). + icon(Material.RED_STAINED_GLASS_PANE). + name(this.user.getTranslation(Constants.BUTTON + "cancel")). + clickHandler( (panel, user1, clickType, slot) -> { + this.consumer.accept(false, null); + return true; + }).build()); + + + List description = new ArrayList<>(); + if (!this.selectedMaterials.isEmpty()) + { + description.add(this.user.getTranslation(Constants.DESCRIPTION + "selected") + ":"); + this.selectedMaterials.forEach(material -> description.add(" - " + material.name())); + } + + panelBuilder.item(5, + new PanelItemBuilder(). + icon(Material.GREEN_STAINED_GLASS_PANE). + name(this.user.getTranslation(Constants.BUTTON + "accept")). + description(description). + clickHandler( (panel, user1, clickType, slot) -> { + this.consumer.accept(true, this.selectedMaterials); + return true; + }).build()); + + if (this.elements.size() > MAX_ELEMENTS) + { + // Navigation buttons if necessary + + panelBuilder.item(18, + new PanelItemBuilder(). + icon(Material.OAK_SIGN). + name(this.user.getTranslation(Constants.BUTTON + "previous")). + clickHandler((panel, user1, clickType, slot) -> { + this.build(correctPage - 1); + return true; + }).build()); + + panelBuilder.item(26, + new PanelItemBuilder(). + icon(Material.OAK_SIGN). + name(this.user.getTranslation(Constants.BUTTON + "next")). + clickHandler((panel, user1, clickType, slot) -> { + this.build(correctPage + 1); + return true; + }).build()); + } + + panelBuilder.item(44, + new PanelItemBuilder(). + icon(Material.OAK_DOOR). + name(this.user.getTranslation(Constants.BUTTON + "return")). + clickHandler( (panel, user1, clickType, slot) -> { + this.consumer.accept(false, null); + return true; + }).build()); + + panelBuilder.build(); + } + + + /** + * This method creates PanelItem that represents given material. + * Some materials is not displayable in Inventory GUI, so they are replaced with "placeholder" items. + * @param material Material which icon must be created. + * @return PanelItem that represents given material. + */ + private PanelItem createMaterialButton(Material material) + { + ItemStack itemStack = GuiUtils.getMaterialItem(material); + + return new PanelItemBuilder(). + name(WordUtils.capitalize(material.name().toLowerCase().replace("_", " "))). + description(this.selectedMaterials.contains(material) ? + this.user.getTranslation(Constants.DESCRIPTION + "selected") : ""). + icon(itemStack). + clickHandler((panel, user1, clickType, slot) -> { + if (!this.singleSelect && clickType.isRightClick()) + { + if (!this.selectedMaterials.add(material)) + { + this.selectedMaterials.remove(material); + } + + panel.getInventory().setItem(slot, this.createMaterialButton(material).getItem()); + } + else + { + this.selectedMaterials.add(material); + this.consumer.accept(true, this.selectedMaterials); + } + + return true; + }). + glow(!itemStack.getType().equals(material)). + build(); + } + + + // --------------------------------------------------------------------- + // Section: Variables + // --------------------------------------------------------------------- + + /** + * List with elements that will be displayed in current GUI. + */ + private List elements; + + /** + * Set that contains selected materials. + */ + private Set selectedMaterials; + + /** + * This variable stores consumer. + */ + private BiConsumer> consumer; + + /** + * User who runs GUI. + */ + private User user; + + /** + * This indicate that return set must contain only single item. + */ + private boolean singleSelect; } diff --git a/src/main/java/world/bentobox/likes/utils/Utils.java b/src/main/java/world/bentobox/likes/utils/Utils.java index b650806..40f2fa5 100644 --- a/src/main/java/world/bentobox/likes/utils/Utils.java +++ b/src/main/java/world/bentobox/likes/utils/Utils.java @@ -96,7 +96,7 @@ public static String getGameMode(GameModeAddon gameModeAddon) * @param Instance of given object. * @return Next value after currentValue in values array. */ - public static T getNextValue(T[] values, T currentValue) + public static T getNextValue(T[] values, T currentValue) { for (int i = 0; i < values.length; i++) { @@ -124,7 +124,7 @@ public static T getNextValue(T[] values, T currentValue) * @param Instance of given object. * @return Previous value before currentValue in values array. */ - public static T getPreviousValue(T[] values, T currentValue) + public static T getPreviousValue(T[] values, T currentValue) { for (int i = 0; i < values.length; i++) { diff --git a/src/main/java/world/bentobox/likes/utils/collections/AbstractMap.java b/src/main/java/world/bentobox/likes/utils/collections/AbstractMap.java index f9fa057..87b3ff6 100644 --- a/src/main/java/world/bentobox/likes/utils/collections/AbstractMap.java +++ b/src/main/java/world/bentobox/likes/utils/collections/AbstractMap.java @@ -1,6 +1,6 @@ package world.bentobox.likes.utils.collections; -/** +/* * User: Vitaly Sazanovich * Date: 07/02/13 * Time: 19:23 @@ -422,9 +422,7 @@ public boolean equals(Object o) { return false; try { - Iterator> i = entrySet().iterator(); - while (i.hasNext()) { - Entry e = i.next(); + for (Entry e : entrySet()) { K key = e.getKey(); V value = e.getValue(); if (value == null) { @@ -435,9 +433,7 @@ public boolean equals(Object o) { return false; } } - } catch (ClassCastException unused) { - return false; - } catch (NullPointerException unused) { + } catch (ClassCastException | NullPointerException unused) { return false; } @@ -463,9 +459,7 @@ public boolean equals(Object o) { */ public int hashCode() { int h = 0; - Iterator> i = entrySet().iterator(); - while (i.hasNext()) - h += i.next().hashCode(); + for (Entry kvEntry : entrySet()) h += kvEntry.hashCode(); return h; } @@ -519,7 +513,7 @@ protected Object clone() throws CloneNotSupportedException { * Test for equality, checking for nulls. */ private static boolean eq(Object o1, Object o2) { - return o1 == null ? o2 == null : o1.equals(o2); + return Objects.equals(o1, o2); } // Implementation Note: SimpleEntry and SimpleImmutableEntry diff --git a/src/main/java/world/bentobox/likes/utils/collections/AbstractSet.java b/src/main/java/world/bentobox/likes/utils/collections/AbstractSet.java index 9b05d64..7c856dd 100644 --- a/src/main/java/world/bentobox/likes/utils/collections/AbstractSet.java +++ b/src/main/java/world/bentobox/likes/utils/collections/AbstractSet.java @@ -1,6 +1,6 @@ package world.bentobox.likes.utils.collections; -/** +/* * User: Vitaly Sazanovich * Date: 07/02/13 * Time: 19:25 @@ -87,9 +87,7 @@ public boolean equals(Object o) { return false; try { return containsAll(c); - } catch (ClassCastException unused) { - return false; - } catch (NullPointerException unused) { + } catch (ClassCastException | NullPointerException unused) { return false; } } @@ -113,9 +111,7 @@ public boolean equals(Object o) { */ public int hashCode() { int h = 0; - Iterator i = iterator(); - while (i.hasNext()) { - E obj = i.next(); + for (E obj : this) { if (obj != null) h += obj.hashCode(); } @@ -161,8 +157,7 @@ public boolean removeAll(Collection c) { boolean modified = false; if (size() > c.size()) { - for (Iterator i = c.iterator(); i.hasNext(); ) - modified |= remove(i.next()); + for (Object o : c) modified |= remove(o); } else { for (Iterator i = iterator(); i.hasNext(); ) { if (c.contains(i.next())) { diff --git a/src/main/java/world/bentobox/likes/utils/collections/IndexedTreeMap.java b/src/main/java/world/bentobox/likes/utils/collections/IndexedTreeMap.java index 646a30d..06a7dd6 100644 --- a/src/main/java/world/bentobox/likes/utils/collections/IndexedTreeMap.java +++ b/src/main/java/world/bentobox/likes/utils/collections/IndexedTreeMap.java @@ -1,6 +1,6 @@ package world.bentobox.likes.utils.collections; -/** +/* * User: Vitaly Sazanovich * Date: 07/02/13 * Time: 19:16 @@ -13,6 +13,7 @@ * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ +import java.io.IOException; import java.util.*; @@ -182,8 +183,7 @@ public IndexedTreeMap(SortedMap m) { comparator = m.comparator(); try { buildFromSorted(m.size(), m.entrySet().iterator(), null, null); - } catch (java.io.IOException cannotHappen) { - } catch (ClassNotFoundException cannotHappen) { + } catch (IOException | ClassNotFoundException cannotHappen) { } } @@ -307,13 +307,12 @@ public void putAll(Map map) { int mapSize = map.size(); if (size == 0 && mapSize != 0 && map instanceof SortedMap) { Comparator c = ((SortedMap) map).comparator(); - if (c == comparator || (c != null && c.equals(comparator))) { + if (Objects.equals(c, comparator)) { ++modCount; try { buildFromSorted(mapSize, map.entrySet().iterator(), null, null); - } catch (java.io.IOException cannotHappen) { - } catch (ClassNotFoundException cannotHappen) { + } catch (IOException | ClassNotFoundException cannotHappen) { } return; } @@ -556,7 +555,7 @@ public V put(K key, V value) { // throw NullPointerException // // compare(key, key); // type check - root = new Entry(key, value, null); + root = new Entry<>(key, value, null); root.weight = 1; size = 1; modCount++; @@ -592,7 +591,7 @@ else if (cmp > 0) return t.setValue(value); } while (t != null); } - Entry e = new Entry(key, value, parent); + Entry e = new Entry<>(key, value, parent); if (cmp < 0) { parent.left = e; } else { @@ -650,7 +649,7 @@ public void clear() { */ @Override public Object clone() { - IndexedTreeMap clone = null; + IndexedTreeMap clone; try { clone = (IndexedTreeMap) super.clone(); } catch (CloneNotSupportedException e) { @@ -668,8 +667,7 @@ public Object clone() { // Initialize clone with our mappings try { clone.buildFromSorted(size, entrySet().iterator(), null, null); - } catch (java.io.IOException cannotHappen) { - } catch (ClassNotFoundException cannotHappen) { + } catch (IOException | ClassNotFoundException cannotHappen) { } return clone; @@ -1274,18 +1272,18 @@ public boolean remove(Object o) { @Override public NavigableSet subSet(E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) { - return new IndexedTreeSet(m.subMap(fromElement, fromInclusive, + return new IndexedTreeSet<>(m.subMap(fromElement, fromInclusive, toElement, toInclusive)); } @Override public NavigableSet headSet(E toElement, boolean inclusive) { - return new IndexedTreeSet(m.headMap(toElement, inclusive)); + return new IndexedTreeSet<>(m.headMap(toElement, inclusive)); } @Override public NavigableSet tailSet(E fromElement, boolean inclusive) { - return new IndexedTreeSet(m.tailMap(fromElement, inclusive)); + return new IndexedTreeSet<>(m.tailMap(fromElement, inclusive)); } @Override @@ -1435,8 +1433,8 @@ final int compare(Object k1, Object k2) { * Test two values for equality. Differs from o1.equals(o2) only in * that it copes with null o1 properly. */ - final static boolean valEquals(Object o1, Object o2) { - return (o1 == null ? o2 == null : o1.equals(o2)); + static boolean valEquals(Object o1, Object o2) { + return (Objects.equals(o1, o2)); } /** @@ -1444,7 +1442,7 @@ final static boolean valEquals(Object o1, Object o2) { */ static Map.Entry exportEntry(IndexedTreeMap.Entry e) { return e == null ? null : - new java.util.AbstractMap.SimpleImmutableEntry(e); + new java.util.AbstractMap.SimpleImmutableEntry<>(e); } /** @@ -1517,8 +1515,7 @@ static abstract class NavigableSubMap extends java.util.AbstractMap final boolean tooLow(Object key) { if (!fromStart) { int c = m.compare(key, lo); - if (c < 0 || (c == 0 && !loInclusive)) - return true; + return c < 0 || (c == 0 && !loInclusive); } return false; } @@ -1526,8 +1523,7 @@ final boolean tooLow(Object key) { final boolean tooHigh(Object key) { if (!toEnd) { int c = m.compare(key, hi); - if (c > 0 || (c == 0 && !hiInclusive)) - return true; + return c > 0 || (c == 0 && !hiInclusive); } return false; } @@ -1799,10 +1795,8 @@ public int size() { if (size == -1 || sizeModCount != m.modCount) { sizeModCount = m.modCount; size = 0; - Iterator i = iterator(); - while (i.hasNext()) { + for (Entry kvEntry : this) { size++; - i.next(); } } return size; @@ -2752,8 +2746,7 @@ private void writeObject(java.io.ObjectOutputStream s) s.writeInt(size); // Write out keys and values (alternating) - for (Iterator> i = entrySet().iterator(); i.hasNext(); ) { - Map.Entry e = i.next(); + for (Map.Entry e : entrySet()) { s.writeObject(e.getKey()); s.writeObject(e.getValue()); } @@ -2799,8 +2792,7 @@ private int updateWeight(Entrye){ void addAllForTreeSet(SortedSet set, V defaultVal) { try { buildFromSorted(set.size(), set.iterator(), null, defaultVal); - } catch (java.io.IOException cannotHappen) { - } catch (ClassNotFoundException cannotHappen) { + } catch (IOException | ClassNotFoundException cannotHappen) { } } @@ -2858,11 +2850,11 @@ private void buildFromSorted(int size, Iterator it, * @param redLevel the level at which nodes should be red. * Must be equal to computeRedLevel for tree of this size. */ - private final Entry buildFromSorted(int level, int lo, int hi, - int redLevel, - Iterator it, - java.io.ObjectInputStream str, - V defaultVal) + private Entry buildFromSorted(int level, int lo, int hi, + int redLevel, + Iterator it, + java.io.ObjectInputStream str, + V defaultVal) throws java.io.IOException, ClassNotFoundException { /* * Strategy: The root is the middlemost element. To get to it, we @@ -2902,7 +2894,7 @@ private final Entry buildFromSorted(int level, int lo, int hi, value = (defaultVal != null ? defaultVal : (V) str.readObject()); } - Entry middle = new Entry(key, value, null); + Entry middle = new Entry<>(key, value, null); // color nodes in non-full bottommost level red if (level == redLevel) diff --git a/src/main/java/world/bentobox/likes/utils/collections/IndexedTreeSet.java b/src/main/java/world/bentobox/likes/utils/collections/IndexedTreeSet.java index 3a7d8de..fa3a471 100644 --- a/src/main/java/world/bentobox/likes/utils/collections/IndexedTreeSet.java +++ b/src/main/java/world/bentobox/likes/utils/collections/IndexedTreeSet.java @@ -1,6 +1,6 @@ package world.bentobox.likes.utils.collections; -/** +/* * User: Vitaly Sazanovich * Date: 07/02/13 * Time: 19:26 @@ -114,7 +114,7 @@ public class IndexedTreeSet extends java.util.AbstractSet * {@code ClassCastException}. */ public IndexedTreeSet() { - this(new IndexedTreeMap()); + this(new IndexedTreeMap<>()); } /** @@ -131,7 +131,7 @@ public IndexedTreeSet() { * ordering} of the elements will be used. */ public IndexedTreeSet(Comparator comparator) { - this(new IndexedTreeMap(comparator)); + this(new IndexedTreeMap<>(comparator)); } /** @@ -297,7 +297,7 @@ public boolean addAll(Collection c) { IndexedTreeMap map = (IndexedTreeMap) m; Comparator cc = (Comparator) set.comparator(); Comparator mc = map.comparator(); - if (cc == mc || (cc != null && cc.equals(mc))) { + if (Objects.equals(cc, mc)) { map.addAllForTreeSet(set, PRESENT); return true; } @@ -315,7 +315,7 @@ public boolean addAll(Collection c) { */ public NavigableSet subSet(E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) { - return new IndexedTreeSet(m.subMap(fromElement, fromInclusive, + return new IndexedTreeSet<>(m.subMap(fromElement, fromInclusive, toElement, toInclusive)); } @@ -328,7 +328,7 @@ public NavigableSet subSet(E fromElement, boolean fromInclusive, * @since 1.6 */ public NavigableSet headSet(E toElement, boolean inclusive) { - return new IndexedTreeSet(m.headMap(toElement, inclusive)); + return new IndexedTreeSet<>(m.headMap(toElement, inclusive)); } /** @@ -340,7 +340,7 @@ public NavigableSet headSet(E toElement, boolean inclusive) { * @since 1.6 */ public NavigableSet tailSet(E fromElement, boolean inclusive) { - return new IndexedTreeSet(m.tailMap(fromElement, inclusive)); + return new IndexedTreeSet<>(m.tailMap(fromElement, inclusive)); } /** @@ -463,14 +463,14 @@ public E pollLast() { * @return a shallow copy of this set */ public Object clone() { - IndexedTreeSet clone = null; + IndexedTreeSet clone; try { clone = (IndexedTreeSet) super.clone(); } catch (CloneNotSupportedException e) { throw new InternalError(); } - clone.m = new IndexedTreeMap(m); + clone.m = new IndexedTreeMap<>(m); return clone; } @@ -498,8 +498,7 @@ private void writeObject(java.io.ObjectOutputStream s) s.writeInt(m.size()); // Write out all elements in the proper order. - for (Iterator i = m.keySet().iterator(); i.hasNext(); ) - s.writeObject(i.next()); + for (E e : m.keySet()) s.writeObject(e); } /** @@ -517,9 +516,9 @@ private void readObject(java.io.ObjectInputStream s) // Create backing IndexedTreeMap IndexedTreeMap tm; if (c == null) - tm = new IndexedTreeMap(); + tm = new IndexedTreeMap<>(); else - tm = new IndexedTreeMap(c); + tm = new IndexedTreeMap<>(c); m = tm; // Read in size @@ -548,7 +547,7 @@ public void debug() throws Exception { if (e.weight != e.sumup()) { throw new Exception("Weight is incorrect:" + e.weight + "!=" + e.sumup() + " for " + e.key); } - e = ((IndexedTreeMap) m).successor(e); + e = IndexedTreeMap.successor(e); } } } From d085db70fe99c3aff17929140c2c821605146492 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20Marczink=C3=B3?= Date: Sun, 24 Nov 2019 11:47:08 +0100 Subject: [PATCH 08/16] Translated into Hungarian --- src/main/resources/locales/hu.yml | 137 ++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 src/main/resources/locales/hu.yml diff --git a/src/main/resources/locales/hu.yml b/src/main/resources/locales/hu.yml new file mode 100644 index 0000000..15146fe --- /dev/null +++ b/src/main/resources/locales/hu.yml @@ -0,0 +1,137 @@ +likes: + gui: + titles: + select-block: "&dVálassz egy blokkot" + top: "&dTop szigetek: [type]" + view: "&dSziget like-ok megtekintése" + manage: "&dLike vagy Dislike hozzáadása" + settings: "&dBeállítások szerkesztése" + admin: "&dAdmin Panel" + select-island: "&dVálassz egy szigetet" + select-player: "&dVálassz egy játékost" + edit-view: "&dSziget like-ok szerkesztése" + buttons: + cancel: "&cMégse" + accept: "&aElfogad" + previous: "Előző" + next: "Következő" + return: "&aVissza" + + view-mode: "&6Top típus" + name: "[name]" + + like: "&6Like-ok számolása" + like-rank: "&6Like-ok alapján rangsorolva" + dislike: "&cDislike-ok számolása" + dislike-rank: "&cDislike-ok alapján rangsorolva" + overall: "&aRangsor" + overall-rank: "&aRendezés rang szerint" + + add-like: "&6Like hozzáadása/eltávolítása" + add-dislike: "&cDislike hozzáadása/eltávolítása" + + like-cost: "Like költség" + like-remove-cost: "Like eltávolításának költsége" + dislike-cost: "Dislike költsége" + dislike-remove-cost: "Dislike eltávolításának költsége" + default-icon: "Alapértelezett ikon" + inform-players: "Tájékoztatja a Sziget Tagokat" + log-history: "Log előzmények" + reset-likes: "Visszaállításnál like-ok visszaállítása" + + manage-likes: "Sziget Like/Dislike kezelése" + likes-icon: "Sziget ikon változtatása" + wipe-data: "Adat eltávolítása" + edit-settings: "Beállítások szerkesztése" + + add-dislike-user: "Dislike hozzáadása" + add-like-user: "Like hozzáadása" + remove-dislike-user: "Dislike eltávolítása" + remove-like-user: "Like eltávolítása" + descriptions: + selected: "&dKiválasztott" + + view-mode: "&fVálasztható|&fmelyik top legyen|&fbe megjelenítve." + mode: "Top tíz sziget|mutatása [type]." + top-value: + likes: "&6[rank]. Like-ok szerinti sziget|&6[value] like-al." + dislikes: "&6[rank]. Dislike-ok szerinti sziget|&6[value] dislike-al." + rank: "&6[rank]. Rang szerinti sziget|&6[value] rangponttal." + values: "A szigetnek van:|[likes] like|[dislikes] dislike|[rank] rangpont." + unknown: "&cismeretlen játékos" + + current-value: "Jelenlegi érték: [value]." + like: "Like-ok hozzáadva |más játékosok által." + dislike: "Dislike-ok hozzáadva |más játékosok által." + overall: "Kiszámított Rangérték|(like-ok - dislike-ok)." + like-rank: "Top helyezések|Like-ok által." + dislike-rank: "Top helyezések|Dislike-ok által." + overall-rank: "Top helyezések|Rangok által." + like-next: "Következő játékosok mutatása|akik like-olták a szigeted." + dislike-next: "SKövetkező játékosok mutatása|akik dislike-olták a szigeted." + like-previous: "Előző játékosok mutatása|akik like-olták a szigeted." + dislike-previous: "Előző játékosok mutatása|akik dislike-olták a szigeted." + + add-like: "Like-ok hozzáadásának/eltávolításának lehetősége ehhez|a szigethez." + add-dislike: "Dislike-ok hozzáadásának/eltávolításának lehetősége ehhez|a szigethez.." + cost: "Jelenlegi működési költség [value]$." + + like-cost: "Lehetővé teszi az új like hozzáadás költségének megváltoztatását." + like-remove-cost: "Lehetővé teszi a like eltávolítás költségének megváltoztatását." + dislike-cost: "Lehetővé teszi az új dislike hozzáadás költségének megváltoztatását." + dislike-remove-cost: "Lehetővé teszi a dislike eltávolítás költségének megváltoztatását." + default-icon: "Lehetővé teszi az alapértelmezett|ikon megváltoztatását a Topban." + inform-players: "Lehetővé teszi a váltást, hogy|a sziget tagok értesítést kapjanak|ha valaki|like-olta/dislike-olta a szigetüket." + log-history: "Lehetővé teszi a váltást,hogy|az előzményadatok tárolva legyenek-e." + reset-likes: "Lehetővé teszi a váltást,hogy|a sziget újrakezdésével|a like-ok száma visszaállítódjon-e." + + manage-likes: "Lehetővé teszi a hozzáadását/eltávolítását|olyan játékosoknak akik like-olták|vagy dislike-olták a kiválasztott szigetet." + likes-icon: "Lehetővé teszi a Top menüben lévő szigetikon megváltoztatását." + wipe-data: "Lehetővé teszi az összes tárolt adat|teljes eltávolítását|a jelenlegi játékmódból." + edit-settings: "Lehetővé teszi a kiegészítő|beállítások GUI-n keresztüli szerkesztését." + types: + likes: "Like-ok" + dislikes: "Dislike-ok" + rank: "Rang" + + messages: + add-like: "&aLike-oltad [island] szigetét." + player-add-like: "&a[user] like-olta a szigeted." + remove-like: "&cEdltávolítod a like-ot [island] szigetéről." + player-remove-like: "&c[user] eltávolította a like-ot a szigetedről." + add-dislike: "&cDislike-oltad [island] szigetét." + player-add-dislike: "&c[user] dislike-olta a szigeted." + remove-dislike: "&aEltávolítottad a dislike-ot [island] szigetéről." + player-remove-dislike: "&a[user] eltávolította a dislike-ot a szigetről." + no-data-about-island: "Nincs adat erről a szigetről." + no-data-about-your-island: "Nincs adat a szigetedről." + errors: + not-on-island: "&cA parancs futtatásához a szigeten kell lenned!" + your-island: "&cNem like-olhatod vagy dislike-olhatod a saját szigeted!" + numeric-only: "&cA bevitelnek számnak kell lennie!" + not-valid-value: "&cA számnak nagyobbnak kell lennie, mint[min] és kisebbnek, mint [max], de a bevitel [value]!" + top-is-empty: "&cSajnáljuk, senki nincs a top rangsorban!" + database-error: "&cSajnos hiba történt az adatbázisban. Nem találhatóak a sziget adatai." + questions: + prefix: "&c[SERVER]&r: " + like-cost: "&5Kérlek add meg a költséget like-onként." + like-remove-cost: "&5Kérlek add meg a költséget like eltávolításonként." + dislike-cost: "&5Kérlek add meg a költséget dislike-onként." + dislike-remove-cost: "&5Kérlek add meg a költséget dislike eltávolításonként." + commands: + admin: + help: + parameters: "" + description: "admin GUI megnyitása" + settings: + parameters: "" + description: "admin beállítások GUI megnyitása" + help: + parameters: "" + description: "like GUI megnyitása" + top: + parameters: "" + description: "top GUI megnyitása" + view: + parameters: "" + description: "megnyitja a GUI-t ahol láthatod a like-jaidat" From 46d21378466f7c9b0f871983cd1fdc97459b9a4c Mon Sep 17 00:00:00 2001 From: Florian CUNY Date: Sat, 11 Jan 2020 11:17:14 +0100 Subject: [PATCH 09/16] Use 'b' as character to identify builds instead of '#' --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 25eb497..dfb13f3 100644 --- a/pom.xml +++ b/pom.xml @@ -85,7 +85,7 @@ - -#${env.BUILD_NUMBER} + -b${env.BUILD_NUMBER} From 1196eb1f5d2ae184083baaff8671bea281693edf Mon Sep 17 00:00:00 2001 From: DuckSoft Date: Sun, 12 Jan 2020 06:25:58 +0800 Subject: [PATCH 10/16] =?UTF-8?q?remove=20embedded=20advertising=20for=20"?= =?UTF-8?q?=E7=8B=90=E6=B8=B8"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The localized file contains advertisement for a commercial Minecraft server provider ["狐游"](https://www.aliserver.net/), occurring here and there as prefix of the plugin message, which I think is bad. This patch is to remove them. --- src/main/resources/locales/zh-CN.yml | 34 ++++++++++++++-------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/main/resources/locales/zh-CN.yml b/src/main/resources/locales/zh-CN.yml index 038b70f..a096a91 100644 --- a/src/main/resources/locales/zh-CN.yml +++ b/src/main/resources/locales/zh-CN.yml @@ -83,25 +83,25 @@ likes: dislikes: '差评' rank: '排名' messages: - add-like: '&e狐游 &6┃┃ &a你好评了 [island] 的岛屿' - player-add-like: '&e狐游 &6┃┃ &a玩家 [user] 好评了你的岛屿' - remove-like: '&e狐游 &6┃┃ &c你从 [island] 的岛屿上移除了你的好评' - player-remove-like: '&e狐游 &6┃┃ &c玩家 [user] 从你的岛屿上移除了他的好评' - add-dislike: '&e狐游 &6┃┃ &c你差评了 [island] 的岛屿' - player-add-dislike: '&e狐游 &6┃┃ &c[user] 差评了你的岛屿' - remove-dislike: '&e狐游 &6┃┃ &a你从 [island] 的岛屿移除了你的差评' - player-remove-dislike: '&e狐游 &6┃┃ &a玩家 [user] 从你的岛屿上移除了他的差评' - no-data-about-island: '&e狐游 &6┃┃ &e这个岛屿暂时无人评价' - no-data-about-your-island: '&e狐游 &6┃┃ &e你的岛屿暂时无人评价' + add-like: '&a你好评了 [island] 的岛屿' + player-add-like: '&a玩家 [user] 好评了你的岛屿' + remove-like: '&c你从 [island] 的岛屿上移除了你的好评' + player-remove-like: '&c玩家 [user] 从你的岛屿上移除了他的好评' + add-dislike: '&c你差评了 [island] 的岛屿' + player-add-dislike: '&c[user] 差评了你的岛屿' + remove-dislike: '&a你从 [island] 的岛屿移除了你的差评' + player-remove-dislike: '&a玩家 [user] 从你的岛屿上移除了他的差评' + no-data-about-island: '&e这个岛屿暂时无人评价' + no-data-about-your-island: '&e你的岛屿暂时无人评价' errors: - not-on-island: '&e狐游 &6┃┃ &c你必须站在一个岛屿上才能使用这个命令' - your-island: '&e狐游 &6┃┃ &c你无法好评或差评你自己的岛屿' - numeric-only: '&e狐游 &6┃┃ &c输入只能接受数字!' - not-valid-value: '&e狐游 &6┃┃ &c数字需要大于 [min] 并且小于 [max],你提供的值 [value] 无法满足这个条件!' - top-is-empty: '&e狐游 &6┃┃ &c抱歉,排行榜上暂无任何人' - database-error: '&e狐游 &6┃┃ &c抱歉,数据库好像出了问题,无法找到你的岛屿信息' + not-on-island: '&c你必须站在一个岛屿上才能使用这个命令' + your-island: '&c你无法好评或差评你自己的岛屿' + numeric-only: '&c输入只能接受数字!' + not-valid-value: '&c数字需要大于 [min] 并且小于 [max],你提供的值 [value] 无法满足这个条件!' + top-is-empty: '&c抱歉,排行榜上暂无任何人' + database-error: '&c抱歉,数据库好像出了问题,无法找到你的岛屿信息' questions: - prefix: '&e狐游 &6┃┃ ' + prefix: '&c[SERVER]&r: ' like-cost: '&5请输入好评所需要的费用' like-remove-cost: '&5请输入移除好评所需要的费用' dislike-cost: '&5请输入差评所需要的费用' From 03fec5beb99ff96adc9c20684bc41626bfc3a079 Mon Sep 17 00:00:00 2001 From: tastybento Date: Thu, 30 Jan 2020 10:25:52 -0800 Subject: [PATCH 11/16] Czech translation. Credit @Polda18 --- src/main/resources/locales/cs.yml | 139 ++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 src/main/resources/locales/cs.yml diff --git a/src/main/resources/locales/cs.yml b/src/main/resources/locales/cs.yml new file mode 100644 index 0000000..b1b40d2 --- /dev/null +++ b/src/main/resources/locales/cs.yml @@ -0,0 +1,139 @@ +# Translation by: CZghost + +likes: + gui: + titles: + select-block: "&dVybrat blok" + top: "&dTop ostrovy podle [type]" + view: "&dUkázat hodnocení ostrovů" + manage: "&dPřidat hodnocení &eLíbí se &dnebo &eNelíbí se" + settings: "&dEditovat nastavení" + admin: "&dAdministrátorský panel" + select-island: "&dVybrat ostrov" + select-player: "&dVybrat hráče" + edit-view: "&dEditovat hodnocení ostrova" + buttons: + cancel: "&cZrušit" + accept: "&aPřijmout" + previous: "Předchozí" + next: "Další" + return: "&aZpět" + + view-mode: "&6Top typ" + name: "[name]" + + like: "&6Počet &2Líbí se" + like-rank: "&6Hodnost dle &2Líbí se" + dislike: "&cPočet &4Nelíbí se" + dislike-rank: "&cHodnost dle &4Nelíbí se" + overall: "&aČíslo hodnosti" + overall-rank: "&aŘadit dle hodnosti" + + add-like: "&6Přidat/Odebrat &2Líbí se" + add-dislike: "&cPřidat/Odebrat &4Nelíbí se" + + like-cost: "Cena &2Líbí se" + like-remove-cost: "Cena odebrání &2Líbí se" + dislike-cost: "Cena &4Nelíbí se" + dislike-remove-cost: "Cena odebrání &4Nelíbí se" + default-icon: "Výchozí ikona" + inform-players: "Informovat členy ostrova" + log-history: "Zapisovat historii" + reset-likes: "Resetovat hodnocení" + + manage-likes: "Spravovat hodnocení ostrova" + likes-icon: "Změnit ikonu ostrova" + wipe-data: "Smazat data" + edit-settings: "Editovat nastavení" + + add-dislike-user: "Přidat &4Nelíbí se" + add-like-user: "Přidat &2Líbí se" + remove-dislike-user: "Odebrat &4Nelíbí se" + remove-like-user: "Odebrat &2Líbí se" + descriptions: + selected: "&dZvoleno" + + view-mode: "&fUmoožňí zvolit,|&fkterý top|&fmá být zobrazen." + mode: "Ukáže TOP 10|ostrovů dle [type]." + top-value: + likes: "&6[rank]. ostrov dle &2Líbí se|&6s [value] &2Líbí se." + dislikes: "&6[rank]. ostrov dle &4Nelíbí se|&6s [value] &4Nelíbí se." + rank: "&6[rank]. ostrov dle bodů hodnocení|&6s [value] bodů hodnocení." + values: "Ostrov má:|[likes] &2Líbí se|[dislikes] &4Nelíbí se|[rank] bodů hodnocení." + unknown: "&cneznámý hráč" + + current-value: "Nynější hodnota: [value]." + like: "Líbí se|ostatním hráčům." + dislike: "Nelíbí se|ostatním hráčům." + overall: "Vypočítány body hodnocení|(líbí se - nelíbí se)." + like-rank: "Umístění v TOP podle|počtu &2Líbí se&r." + dislike-rank: "Umístění v TOP podle|počtu &4Nelíbí se&r." + overall-rank: "Umístění v TOP podle|bodů hodnocení." + like-next: "Ukázat další hráče,|kterým se líbí tvůj ostrov." + dislike-next: "Ukázat další hráče,|kterým se nelíbí tvůj ostrov." + like-previous: "Ukázat předchozí hráče,|kterým se líbí tvůj ostrov." + dislike-previous: "Ukázat předchozí hráče,|kterým se nelíbí tvůj ostrov." + + add-like: "Umožňuje přidat nebo|odebrat &2Líbí se|tomuto ostrovu." + add-dislike: "Umožňuje přidat nebo|odebrat &4Nelíbí se|tomuto ostrovu." + cost: "Nynější cena operace $[value]." + + like-cost: "Umožňuje změnit, kolik|stojí přidání nového &2Líbí se&r." + like-remove-cost: "Umožňuje změnit kolik|stojí odebrání &2Líbí se&r." + dislike-cost: "Umožňuje změnit kolik|stojí přidání nového &4Nelíbí se&r." + dislike-remove-cost: "Umožňuje změnit kolik|stojí odebrání &4Nelíbí se&r." + default-icon: "Umožňuje změnit výchozí|ikonu v TOPech." + inform-players: "Umožňuje přepnout, zda|by měli být členové ostrova|informováno, pokud se někomu|(ne)líbí jejich ostrov" + log-history: "Umožňuje přepnout, zda|by se měla historie|ukládat." + reset-likes: "Umožňuje přepnout, zda|by reetování ostrova mělo|resetovat hodnocení ostrova." + + manage-likes: "Umožňuje přidat/odebrat|hráče, kterým se (ne)líbí|vybrané ostrovy." + likes-icon: "Umožňuje změnit ikonu ostrova v menu TOP." + wipe-data: "Umožňuje kompletně|odstranit všechna uložená|data z nynějšího|herního módu." + edit-settings: "Umožňuje editovat|nastavení doplňku|prostřednictvím GUI." + types: + likes: "&2Líbí se" + dislikes: "&4Nelíbí se" + rank: "Body hodnocení" + + messages: + add-like: "&aLíbí se ti ostrov [island]." + player-add-like: "&a[user] se líbí tvůj ostrov." + remove-like: "&cOdstranil jsi své &2Líbí se &cz ostrova [island]." + player-remove-like: "&c[user] odstranil své &2Líbí se &cz tvého ostrova." + add-dislike: "&cNelíbí se ti ostrov [island]." + player-add-dislike: "&c[user] se nelíbí tvůj ostrov." + remove-dislike: "&aOdstranil jsi své &4Nelíbí se &cz ostrova [island]." + player-remove-dislike: "&a[user] odstranil své &4Nelíbí se &cz tvého ostrova." + no-data-about-island: "Nejsou zde data o tomto ostrově." + no-data-about-your-island: "Nejsou zde data o tvém ostrově." + errors: + not-on-island: "&cMusíš být na ostrově ke spuštění tohoto příkazu!" + your-island: "&cNemůžeš přidávat &2Líbí se &cnebo &4Nelíbí se &csvému ostrovu!" + numeric-only: "&cVstup by měl být pouze numerický!" + not-valid-value: "&cČíslo by mělo být větší než [min] a menší než [max], ale vstup je [value]!" + top-is-empty: "&cPardon, nikdo není v TOP!" + database-error: "&cPardon, vyskytla se chyba s databází. Nelze najít data tvého ostrova." + questions: + prefix: "&c[SERVER]&r: " + like-cost: "&5Prosím, vlož cenu za jednotku &2Líbí se&5." + like-remove-cost: "&5Prosím, vlož cenu za odebrání &2Líbí se&5." + dislike-cost: "&5Prosím, vlož cenu za jednotku &4Nelíbí se&5." + dislike-remove-cost: "&5Prosím, vlož cenu za odebrání &4Nelíbí se&5." + commands: + admin: + help: + parameters: "" + description: "otevře administrátorské GUI" + settings: + parameters: "" + description: "otevře administrátorské GUI nastavení" + help: + parameters: "" + description: "otevře GUI hodnocení" + top: + parameters: "" + description: "otevře GUI TOP" + view: + parameters: "" + description: "otevře GUI, kde můžeš vidět své hodnocení" From 69c6be095180220c0f0da0307415dedb9bea15f0 Mon Sep 17 00:00:00 2001 From: tastybento Date: Fri, 21 Feb 2020 15:58:59 -0800 Subject: [PATCH 12/16] Adds null check for owner id in TopLikesPanel Fixes https://github.com/BentoBoxWorld/Likes/issues/10 --- .../bentobox/likes/panels/user/TopLikesPanel.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main/java/world/bentobox/likes/panels/user/TopLikesPanel.java b/src/main/java/world/bentobox/likes/panels/user/TopLikesPanel.java index d1006d6..e1aed33 100644 --- a/src/main/java/world/bentobox/likes/panels/user/TopLikesPanel.java +++ b/src/main/java/world/bentobox/likes/panels/user/TopLikesPanel.java @@ -1,16 +1,17 @@ package world.bentobox.likes.panels.user; -import com.google.common.collect.ImmutableSet; -import org.bukkit.ChatColor; -import org.bukkit.Material; -import org.bukkit.World; - import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.UUID; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.World; + +import com.google.common.collect.ImmutableSet; + import world.bentobox.bentobox.api.panels.PanelItem; import world.bentobox.bentobox.api.panels.builders.PanelBuilder; import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder; @@ -279,7 +280,7 @@ private PanelItem createPlayerButton(LikesObject likesObject, int rank) PanelItem.ClickHandler clickHandler; - if (island.isPresent()) + if (island.isPresent() && island.get().getOwner() != null) { UUID ownerId = island.get().getOwner(); From 4f16e6b7dc06fe545be6a4df5e2c2cc7f2550d70 Mon Sep 17 00:00:00 2001 From: tastybento Date: Sun, 19 Apr 2020 09:49:12 -0700 Subject: [PATCH 13/16] Version 1.7.1 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index dfb13f3..373ba08 100644 --- a/pom.xml +++ b/pom.xml @@ -71,7 +71,7 @@ ${build.version}-SNAPSHOT - 1.7.0 + 1.7.1 -LOCAL
From f14a54038f2ef20bf378216366779bfe42b450d8 Mon Sep 17 00:00:00 2001 From: tastybento Date: Sun, 19 Apr 2020 09:49:32 -0700 Subject: [PATCH 14/16] Added default perms and softdepend for AOneBlock --- src/main/resources/addon.yml | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/main/resources/addon.yml b/src/main/resources/addon.yml index d4995c4..3a49d22 100644 --- a/src/main/resources/addon.yml +++ b/src/main/resources/addon.yml @@ -17,7 +17,7 @@ authors: - BONNe # Soft dependencies of current addon. -softdepend: AcidIsland, BSkyBlock, CaveBlock, SkyGrid, Warps +softdepend: AcidIsland, BSkyBlock, CaveBlock, SkyGrid, Warps, AOneBlock # List of addon permissions permissions: @@ -115,4 +115,28 @@ permissions: default: op skygrid.likes.admin.settings: description: Let the admin use the '/sga likes settings' command + default: op + + # aoneblock Permissions + aoneblock.likes: + description: Let the player use the '/ob likes' command + default: true + aoneblock.likes.top: + description: Let the player use the '/ob likes top' command + default: true + aoneblock.likes.view: + description: Let the player use the '/ob likes view' command + default: true + aoneblock.likes.view.others: + description: Let the player use the '/ob likes view ' command + default: op + aoneblock.likes.bypass-cost: + description: Let the player to avoid paying for any likes/dislikes changes. + default: op + + aoneblock.likes.admin: + description: Let the admin use the '/oba likes' command + default: op + aoneblock.likes.admin.settings: + description: Let the admin use the '/oba likes settings' command default: op \ No newline at end of file From e4ffa3e1ad88f6dfa274b2da02a46338acc4811a Mon Sep 17 00:00:00 2001 From: tastybento Date: Sun, 19 Apr 2020 09:50:21 -0700 Subject: [PATCH 15/16] Updated gitignore --- .gitignore | 95 +++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 73 insertions(+), 22 deletions(-) diff --git a/.gitignore b/.gitignore index 86eb68c..dad3d96 100644 --- a/.gitignore +++ b/.gitignore @@ -1,36 +1,87 @@ -# Compiled class file -*.class +# Git +*.orig +!.gitignore -# Log file -*.log +# Windows +Thumbs.db +ehthumbs.db +ehthumbs_vista.db +*.stackdump +[Dd]esktop.ini +$RECYCLE.BIN/ +*.lnk -# BlueJ files -*.ctxt +# Linux +*~ +.fuse_hidden* +.directory +.Trash-* +.nfs* -# Mobile Tools for Java (J2ME) -.mtj.tmp/ +# MacOS +.DS_Store +.AppleDouble +.LSOverride +._* -# Package Files # +# Java +*.class +*.log +*.ctxt +.mtj.tmp/ *.jar *.war *.nar *.ear -*.zip -*.tar.gz -*.rar - -# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* -### Intellij ### -.idea/ +# Maven target/ -out/ +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next +release.properties +dependency-reduced-pom.xml +buildNumber.properties -## File-based project format: +# Intellij +*.iml +*.java___jb_tmp___ +.idea/* *.ipr *.iws -*.iml -/.classpath -/.project -/.settings/ +/out/ +.idea_modules/ + +# Eclipse +*.pydevproject +.metadata +.gradle +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.settings/ +.loadpath +.project +.externalToolBuilders/ +*.launch +.cproject +.classpath +.buildpath +.target + +# NetBeans +nbproject/private/ +build/ +nbbuild/ +dist/ +nbdist/ +nbactions.xml +nb-configuration.xml +.nb-gradle/ +/.idea/ From 542b712ae8a5c212c131107f3c435a3dcdbed294 Mon Sep 17 00:00:00 2001 From: tastybento Date: Sun, 19 Apr 2020 09:52:11 -0700 Subject: [PATCH 16/16] Reorganized imports --- .../java/world/bentobox/likes/LikesAddon.java | 6 +++--- .../world/bentobox/likes/config/Settings.java | 3 ++- .../likes/database/objects/LikesObject.java | 4 ++-- .../bentobox/likes/managers/LikesManager.java | 5 +++-- .../world/bentobox/likes/panels/GuiUtils.java | 9 +++++++-- .../likes/panels/admin/AdminViewPanel.java | 9 +++++---- .../likes/panels/admin/EditSettingsPanel.java | 8 ++++---- .../likes/panels/admin/ListIslandsPanel.java | 8 +++++--- .../likes/panels/user/LikesManagePanel.java | 6 +++--- .../likes/panels/user/LikesViewPanel.java | 8 ++++---- .../likes/panels/util/SelectBlocksGUI.java | 8 ++++++-- .../bentobox/likes/panels/util/SelectUserGUI.java | 3 ++- .../java/world/bentobox/likes/utils/Utils.java | 5 +++-- .../likes/utils/collections/AbstractMap.java | 8 ++++++-- .../likes/utils/collections/IndexedTreeMap.java | 15 ++++++++++++++- .../likes/utils/collections/IndexedTreeSet.java | 11 +++++++++-- 16 files changed, 78 insertions(+), 38 deletions(-) diff --git a/src/main/java/world/bentobox/likes/LikesAddon.java b/src/main/java/world/bentobox/likes/LikesAddon.java index 16458f5..6dea0a2 100644 --- a/src/main/java/world/bentobox/likes/LikesAddon.java +++ b/src/main/java/world/bentobox/likes/LikesAddon.java @@ -1,12 +1,12 @@ package world.bentobox.likes; -import org.bukkit.Bukkit; -import org.eclipse.jdt.annotation.NonNull; - import java.util.Arrays; import java.util.Optional; +import org.bukkit.Bukkit; +import org.eclipse.jdt.annotation.NonNull; + import world.bentobox.bentobox.api.addons.Addon; import world.bentobox.bentobox.api.addons.GameModeAddon; import world.bentobox.bentobox.api.configuration.Config; diff --git a/src/main/java/world/bentobox/likes/config/Settings.java b/src/main/java/world/bentobox/likes/config/Settings.java index 84df298..1c3e0dc 100644 --- a/src/main/java/world/bentobox/likes/config/Settings.java +++ b/src/main/java/world/bentobox/likes/config/Settings.java @@ -1,12 +1,13 @@ package world.bentobox.likes.config; -import org.bukkit.Material; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; +import org.bukkit.Material; + import world.bentobox.bentobox.api.configuration.ConfigComment; import world.bentobox.bentobox.api.configuration.ConfigEntry; import world.bentobox.bentobox.api.configuration.ConfigObject; diff --git a/src/main/java/world/bentobox/likes/database/objects/LikesObject.java b/src/main/java/world/bentobox/likes/database/objects/LikesObject.java index 360289e..cdb5684 100644 --- a/src/main/java/world/bentobox/likes/database/objects/LikesObject.java +++ b/src/main/java/world/bentobox/likes/database/objects/LikesObject.java @@ -7,14 +7,14 @@ package world.bentobox.likes.database.objects; -import com.google.gson.annotations.Expose; - import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Set; import java.util.UUID; +import com.google.gson.annotations.Expose; + import world.bentobox.bentobox.api.logs.LogEntry; import world.bentobox.bentobox.database.objects.DataObject; import world.bentobox.bentobox.database.objects.adapters.Adapter; diff --git a/src/main/java/world/bentobox/likes/managers/LikesManager.java b/src/main/java/world/bentobox/likes/managers/LikesManager.java index a46ec1c..3397e84 100644 --- a/src/main/java/world/bentobox/likes/managers/LikesManager.java +++ b/src/main/java/world/bentobox/likes/managers/LikesManager.java @@ -7,8 +7,6 @@ package world.bentobox.likes.managers; -import org.bukkit.World; -import org.eclipse.jdt.annotation.NonNull; import java.util.Comparator; import java.util.HashMap; import java.util.List; @@ -16,6 +14,9 @@ import java.util.UUID; import java.util.stream.Collectors; +import org.bukkit.World; +import org.eclipse.jdt.annotation.NonNull; + import world.bentobox.bentobox.api.addons.GameModeAddon; import world.bentobox.bentobox.api.logs.LogEntry; import world.bentobox.bentobox.api.user.User; diff --git a/src/main/java/world/bentobox/likes/panels/GuiUtils.java b/src/main/java/world/bentobox/likes/panels/GuiUtils.java index 0e07314..1a34fc7 100644 --- a/src/main/java/world/bentobox/likes/panels/GuiUtils.java +++ b/src/main/java/world/bentobox/likes/panels/GuiUtils.java @@ -1,16 +1,21 @@ package world.bentobox.likes.panels; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Objects; + import org.apache.commons.lang.WordUtils; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.inventory.ItemStack; + import world.bentobox.bentobox.api.panels.PanelItem; import world.bentobox.bentobox.api.panels.builders.PanelBuilder; import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder; -import java.util.*; - /** * This class contains static methods that is used through multiple GUIs. diff --git a/src/main/java/world/bentobox/likes/panels/admin/AdminViewPanel.java b/src/main/java/world/bentobox/likes/panels/admin/AdminViewPanel.java index b8c771f..9caa713 100644 --- a/src/main/java/world/bentobox/likes/panels/admin/AdminViewPanel.java +++ b/src/main/java/world/bentobox/likes/panels/admin/AdminViewPanel.java @@ -7,16 +7,17 @@ package world.bentobox.likes.panels.admin; -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.inventory.ItemStack; -import org.eclipse.jdt.annotation.NonNull; import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.UUID; import java.util.stream.Collectors; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.eclipse.jdt.annotation.NonNull; + import world.bentobox.bentobox.api.panels.PanelItem; import world.bentobox.bentobox.api.panels.builders.PanelBuilder; import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder; diff --git a/src/main/java/world/bentobox/likes/panels/admin/EditSettingsPanel.java b/src/main/java/world/bentobox/likes/panels/admin/EditSettingsPanel.java index c1caf1b..27b605b 100644 --- a/src/main/java/world/bentobox/likes/panels/admin/EditSettingsPanel.java +++ b/src/main/java/world/bentobox/likes/panels/admin/EditSettingsPanel.java @@ -7,6 +7,10 @@ package world.bentobox.likes.panels.admin; +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; + import org.bukkit.Material; import org.bukkit.World; import org.bukkit.conversations.Conversation; @@ -17,10 +21,6 @@ import org.bukkit.inventory.ItemStack; import org.eclipse.jdt.annotation.NonNull; -import java.util.ArrayList; -import java.util.List; -import java.util.function.Consumer; - import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.api.panels.PanelItem; import world.bentobox.bentobox.api.panels.builders.PanelBuilder; diff --git a/src/main/java/world/bentobox/likes/panels/admin/ListIslandsPanel.java b/src/main/java/world/bentobox/likes/panels/admin/ListIslandsPanel.java index c4f60ac..060d465 100644 --- a/src/main/java/world/bentobox/likes/panels/admin/ListIslandsPanel.java +++ b/src/main/java/world/bentobox/likes/panels/admin/ListIslandsPanel.java @@ -1,13 +1,15 @@ package world.bentobox.likes.panels.admin; -import com.google.common.collect.ImmutableSet; -import org.bukkit.ChatColor; -import org.bukkit.Material; import java.util.ArrayList; import java.util.List; import java.util.UUID; +import org.bukkit.ChatColor; +import org.bukkit.Material; + +import com.google.common.collect.ImmutableSet; + import world.bentobox.bentobox.api.panels.PanelItem; import world.bentobox.bentobox.api.panels.builders.PanelBuilder; import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder; diff --git a/src/main/java/world/bentobox/likes/panels/user/LikesManagePanel.java b/src/main/java/world/bentobox/likes/panels/user/LikesManagePanel.java index f67188b..c5a9f41 100644 --- a/src/main/java/world/bentobox/likes/panels/user/LikesManagePanel.java +++ b/src/main/java/world/bentobox/likes/panels/user/LikesManagePanel.java @@ -7,12 +7,12 @@ package world.bentobox.likes.panels.user; -import org.bukkit.Material; -import org.bukkit.World; - import java.util.ArrayList; import java.util.List; +import org.bukkit.Material; +import org.bukkit.World; + import world.bentobox.bentobox.api.panels.Panel; import world.bentobox.bentobox.api.panels.PanelItem; import world.bentobox.bentobox.api.panels.builders.PanelBuilder; diff --git a/src/main/java/world/bentobox/likes/panels/user/LikesViewPanel.java b/src/main/java/world/bentobox/likes/panels/user/LikesViewPanel.java index 8bbd113..6a1e61b 100644 --- a/src/main/java/world/bentobox/likes/panels/user/LikesViewPanel.java +++ b/src/main/java/world/bentobox/likes/panels/user/LikesViewPanel.java @@ -7,15 +7,15 @@ package world.bentobox.likes.panels.user; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + import org.bukkit.Material; import org.bukkit.World; import org.bukkit.inventory.ItemStack; import org.eclipse.jdt.annotation.NonNull; -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Collectors; - import world.bentobox.bentobox.api.panels.PanelItem; import world.bentobox.bentobox.api.panels.builders.PanelBuilder; import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder; diff --git a/src/main/java/world/bentobox/likes/panels/util/SelectBlocksGUI.java b/src/main/java/world/bentobox/likes/panels/util/SelectBlocksGUI.java index 4c8f377..bddbd0e 100644 --- a/src/main/java/world/bentobox/likes/panels/util/SelectBlocksGUI.java +++ b/src/main/java/world/bentobox/likes/panels/util/SelectBlocksGUI.java @@ -1,11 +1,15 @@ package world.bentobox.likes.panels.util; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.function.BiConsumer; + import org.apache.commons.lang.WordUtils; import org.bukkit.Material; import org.bukkit.inventory.ItemStack; -import java.util.*; -import java.util.function.BiConsumer; import world.bentobox.bentobox.api.panels.PanelItem; import world.bentobox.bentobox.api.panels.builders.PanelBuilder; diff --git a/src/main/java/world/bentobox/likes/panels/util/SelectUserGUI.java b/src/main/java/world/bentobox/likes/panels/util/SelectUserGUI.java index 29583f1..fab7cd1 100644 --- a/src/main/java/world/bentobox/likes/panels/util/SelectUserGUI.java +++ b/src/main/java/world/bentobox/likes/panels/util/SelectUserGUI.java @@ -1,7 +1,6 @@ package world.bentobox.likes.panels.util; -import org.bukkit.Material; import java.util.Collections; import java.util.HashSet; import java.util.List; @@ -9,6 +8,8 @@ import java.util.function.Consumer; import java.util.stream.Collectors; +import org.bukkit.Material; + import world.bentobox.bentobox.api.panels.PanelItem; import world.bentobox.bentobox.api.panels.builders.PanelBuilder; import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder; diff --git a/src/main/java/world/bentobox/likes/utils/Utils.java b/src/main/java/world/bentobox/likes/utils/Utils.java index 40f2fa5..6263b30 100644 --- a/src/main/java/world/bentobox/likes/utils/Utils.java +++ b/src/main/java/world/bentobox/likes/utils/Utils.java @@ -7,11 +7,12 @@ package world.bentobox.likes.utils; -import org.bukkit.World; -import org.bukkit.permissions.PermissionAttachmentInfo; import java.util.List; import java.util.stream.Collectors; +import org.bukkit.World; +import org.bukkit.permissions.PermissionAttachmentInfo; + import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.api.addons.GameModeAddon; import world.bentobox.bentobox.api.user.User; diff --git a/src/main/java/world/bentobox/likes/utils/collections/AbstractMap.java b/src/main/java/world/bentobox/likes/utils/collections/AbstractMap.java index 87b3ff6..2f8e141 100644 --- a/src/main/java/world/bentobox/likes/utils/collections/AbstractMap.java +++ b/src/main/java/world/bentobox/likes/utils/collections/AbstractMap.java @@ -13,8 +13,12 @@ * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ - -import java.util.*; +import java.util.AbstractCollection; +import java.util.Collection; +import java.util.Iterator; +import java.util.Map; +import java.util.Objects; +import java.util.Set; /** * This class provides a skeletal implementation of the Map diff --git a/src/main/java/world/bentobox/likes/utils/collections/IndexedTreeMap.java b/src/main/java/world/bentobox/likes/utils/collections/IndexedTreeMap.java index 06a7dd6..d334ad6 100644 --- a/src/main/java/world/bentobox/likes/utils/collections/IndexedTreeMap.java +++ b/src/main/java/world/bentobox/likes/utils/collections/IndexedTreeMap.java @@ -14,7 +14,20 @@ */ import java.io.IOException; -import java.util.*; +import java.util.AbstractCollection; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.ConcurrentModificationException; +import java.util.Iterator; +import java.util.Map; +import java.util.NavigableMap; +import java.util.NavigableSet; +import java.util.NoSuchElementException; +import java.util.Objects; +import java.util.Set; +import java.util.SortedMap; +import java.util.SortedSet; /** diff --git a/src/main/java/world/bentobox/likes/utils/collections/IndexedTreeSet.java b/src/main/java/world/bentobox/likes/utils/collections/IndexedTreeSet.java index fa3a471..db007f3 100644 --- a/src/main/java/world/bentobox/likes/utils/collections/IndexedTreeSet.java +++ b/src/main/java/world/bentobox/likes/utils/collections/IndexedTreeSet.java @@ -12,8 +12,15 @@ * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ - -import java.util.*; +import java.util.Collection; +import java.util.Comparator; +import java.util.Iterator; +import java.util.Map; +import java.util.NavigableMap; +import java.util.NavigableSet; +import java.util.NoSuchElementException; +import java.util.Objects; +import java.util.SortedSet; /**