From ff6e28b27ed466eed8b370fb7c3d9fbd95ff6061 Mon Sep 17 00:00:00 2001 From: BONNe1704 Date: Thu, 9 May 2019 16:22:02 +0300 Subject: [PATCH 01/18] Init next release (for BentoBox 1.5.0) --- README.md | 12 ++++++------ pom.xml | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 0d38f40..57f0b91 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Add-on for BentoBox to provide challenges for any BentoBox GameMode. ## Where to find Currently Challenges Addon is in **Beta stage**, so it may or may not contain bugs... a lot of bugs. Also it means, that some features are not working or implemented. -Latest official **Beta Release is 0.7.0**, and you can download it from [Release tab](https://github.com/BentoBoxWorld/Challenges/releases) +Latest official **Beta Release is 0.7.5**, and you can download it from [Release tab](https://github.com/BentoBoxWorld/Challenges/releases) Or you can try **nightly builds** where you can check and test new features that will be implemented in next release from [Jenkins Server](https://ci.codemc.org/job/BentoBoxWorld/job/Challenges/lastStableBuild/). @@ -29,11 +29,11 @@ There exist also some default challenges, which importing also are available via ## Compatibility -- [x] BentoBox - 1.4.0 version -- [x] BSkyBlock - 1.4.0 version -- [x] AcidIsland - 1.4.0 version -- [x] SkyGrid - 1.4.0 version -- [x] CaveBlock - 1.4.0 version +- [x] BentoBox - 1.5.0 version +- [x] BSkyBlock - 1.5.0 version +- [x] AcidIsland - 1.5.0 version +- [x] SkyGrid - 1.5.0 version +- [x] CaveBlock - 1.5.0 version ## Config.yml diff --git a/pom.xml b/pom.xml index 8a76d65..83e0e4c 100644 --- a/pom.xml +++ b/pom.xml @@ -36,13 +36,13 @@ 1.7.4 1.13.2-R0.1-SNAPSHOT - 1.4.0 + 1.5.0-SNAPSHOT 1.4.0 68f14ec ${build.version}-SNAPSHOT - 0.7.0 + 0.7.5 -LOCAL @@ -95,7 +95,7 @@ codemc-repo - https://repo.codemc.org/repository/maven-releases/ + https://repo.codemc.org/repository/maven-public/ From a25796613f1e0130dfef6f6c8264f1710030e4f9 Mon Sep 17 00:00:00 2001 From: tastybento Date: Thu, 9 May 2019 06:24:01 -0700 Subject: [PATCH 02/18] Changes to fit new API for database transition. (#114) Config files must implement the ConfigObject interface now instead of DataObject. They no longer need to specify uniqueId. --- .../world/bentobox/challenges/Settings.java | 1159 ++++++++--------- .../challenges/database/object/Challenge.java | 2 +- 2 files changed, 571 insertions(+), 590 deletions(-) diff --git a/src/main/java/world/bentobox/challenges/Settings.java b/src/main/java/world/bentobox/challenges/Settings.java index 3666ca7..e5818a3 100644 --- a/src/main/java/world/bentobox/challenges/Settings.java +++ b/src/main/java/world/bentobox/challenges/Settings.java @@ -1,15 +1,16 @@ package world.bentobox.challenges; -import org.bukkit.Material; -import org.bukkit.inventory.ItemStack; import java.util.HashSet; import java.util.Set; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; + import world.bentobox.bentobox.api.configuration.ConfigComment; import world.bentobox.bentobox.api.configuration.ConfigEntry; +import world.bentobox.bentobox.api.configuration.ConfigObject; import world.bentobox.bentobox.api.configuration.StoreAt; -import world.bentobox.bentobox.database.objects.DataObject; @StoreAt(filename="config.yml", path="addons/Challenges") @@ -18,591 +19,571 @@ import world.bentobox.bentobox.database.objects.DataObject; @ConfigComment("You cannot edit it while the server is running because changes will") @ConfigComment("be lost! Use in-game settings GUI or edit when server is offline.") @ConfigComment("") -public class Settings implements DataObject +public class Settings implements ConfigObject { - @ConfigComment("") - @ConfigComment("Allows to define common challenges command that will open User GUI") - @ConfigComment("with all GameMode selection or Challenges from user world.") - @ConfigComment("This will not affect /{gamemode_user} challenges command.") - @ConfigEntry(path = "commands.user", needsReset = true) - private String userCommand = "challenges c"; - - @ConfigComment("") - @ConfigComment("Allows to define common challenges command that will open Admin GUI") - @ConfigComment("with all GameMode selection.") - @ConfigComment("This will not affect /{gamemode_admin} challenges command.") - @ConfigEntry(path = "commands.admin", needsReset = true) - private String adminCommand = "challengesadmin chadmin"; - - @ConfigComment("") - @ConfigComment("This enables/disables common command that will be independent from") - @ConfigComment("all GameModes. For admins it will open selection with all GameModes") - @ConfigComment("(unless there is one), but for users it will open GUI that corresponds") - @ConfigComment("to their world (unless it is specified other way in Admin GUI).") - @ConfigEntry(path = "commands.single-gui", needsReset = true) - private boolean useCommonGUI = false; - - @ConfigComment("") - @ConfigComment("This allows for admins to define which GUI will be opened for admins") - @ConfigComment("when users calls single-gui command.") - @ConfigComment("Acceptable values:") - @ConfigComment(" - CURRENT_WORLD - will open GUI that corresponds to user location.") - @ConfigComment(" - GAMEMODE_LIST - will open GUI with all installed game modes.") - @ConfigEntry(path = "commands.single-gamemode") - private GuiMode userGuiMode = GuiMode.CURRENT_WORLD; - - @ConfigComment("") - @ConfigComment("This indicate if player challenges data history will be stored or not.") - @ConfigEntry(path = "history.store-history-data") - private boolean storeHistory = false; - - @ConfigComment("") - @ConfigComment("This allows to specify an amount of time in days when history data will") - @ConfigComment("be removed. 0 means that data will not be removed.") - @ConfigEntry(path = "history.lifespan") - private int lifeSpan = 14; - - @ConfigComment("") - @ConfigComment("Remove non-repeatable challenges from the challenge GUI when complete.") - @ConfigEntry(path = "gui-settings.remove-complete-one-time-challenges") - private boolean removeCompleteOneTimeChallenges = false; - - @ConfigComment("") - @ConfigComment("Add enchanted glow to completed challenges") - @ConfigEntry(path = "gui-settings.add-completed-glow") - private boolean addCompletedGlow = true; - - @ConfigComment("") - @ConfigComment("This allows to change default locked level icon. This option may be") - @ConfigComment("overwritten by each challenge level. If challenge level has specified") - @ConfigComment("their locked level icon, then it will be used, instead of this one.") - @ConfigEntry(path = "gui-settings.locked-level-icon") - private ItemStack lockedLevelIcon = new ItemStack(Material.BOOK); - - @ConfigComment("") - @ConfigComment("This indicate if free challenges must be at the start (true) or at the end (false) of list.") - @ConfigEntry(path = "gui-settings.free-challenges-first") - private boolean freeChallengesFirst = true; - - @ConfigComment("") - @ConfigComment("This allows to change lore description line length. By default it is 25, but some server") - @ConfigComment("owners may like it to be larger.") - @ConfigEntry(path = "gui-settings.lore-length") - private int loreLineLength = 25; - - @ConfigComment("") - @ConfigComment("This string allows to change element order in Challenge description. Each letter represents") - @ConfigComment("one object from challenge description. If letter is not used, then its represented part") - @ConfigComment("will not be in description. If use any letter that is not recognized, then it will be") - @ConfigComment("ignored. Some strings can be customized via lang file under 'challenges.gui.challenge-description'.") - @ConfigComment("List of letters and their meaning: ") - @ConfigComment(" - L - Level String: '*.level'") - @ConfigComment(" - S - Status String: '*.completed'") - @ConfigComment(" - T - Times String: '*.completed-times', '*.completed-times-of' or '*.maxed-reached'") - @ConfigComment(" - D - Description String: defined in challenge object - challenge.description") - @ConfigComment(" - W - Warning String: '*.warning-items-take', '*.objects-close-by', '*.warning-entities-kill', '*.warning-blocks-remove'") - @ConfigComment(" - E - Environment String: defined in challenge object - challenge.environment") - @ConfigComment(" - Q - Requirement String: '*.required-level', '*.required-money', '*.required-experience'") - @ConfigComment(" - R - Reward String: '*.experience-reward', '*.money-reward', '*.not-repeatable'") - @ConfigComment("By adding 'i' after Q or R (requirements and rewards) will display list of items, blocks") - @ConfigComment("and entities that are defined in challenge and can be customized under 'challenges.gui.description.*'") - @ConfigEntry(path = "gui-settings.challenge-lore-message") - private String challengeLoreMessage = "LSTDEQiWRi"; - - @ConfigComment("") - @ConfigComment("This string allows to change element order in Level description. Each letter represents") - @ConfigComment("one object from level description. If letter is not used, then its represented part") - @ConfigComment("will not be in description. If use any letter that is not recognized, then it will be") - @ConfigComment("ignored. Some strings can be customized via lang file under 'challenges.gui.level-description'.") - @ConfigComment("List of letters and their meaning: ") - @ConfigComment(" - S - Status String: '*.completed'") - @ConfigComment(" - T - Count of completed challenges String: '*.completed-challenges-of'") - @ConfigComment(" - D - Description String: defined in level object - challengeLevel.unlockMessage") - @ConfigComment(" - A - WaiverAmount String: '*.waver-amount'") - @ConfigComment(" - R - Reward String: '*.experience-reward', '*.money-reward', '*.not-repeatable'") - @ConfigComment("By adding 'i' after R (rewards) will display list of items that are defined in challenge") - @ConfigComment("and can be customized under 'challenges.gui.description.*'") - @ConfigEntry(path = "gui-settings.level-lore-message") - private String levelLoreMessage = "STDARi"; - - @ConfigComment("") - @ConfigComment("This indicate if challenges data will be stored per island (true) or per player (false).") - @ConfigEntry(path = "store-island-data") - private boolean storeAsIslandData = false; - - @ConfigComment("") - @ConfigComment("Reset Challenges - if this is true, player's challenges will reset when users") - @ConfigComment("reset an island or if users are kicked or leave a team. Prevents exploiting the") - @ConfigComment("challenges by doing them repeatedly.") - @ConfigEntry(path = "reset-challenges") - private boolean resetChallenges = true; - - @ConfigComment("") - @ConfigComment("Broadcast 1st time challenge completion messages to all players.") - @ConfigComment("Change to false if the spam becomes too much.") - @ConfigEntry(path = "broadcast-messages") - private boolean broadcastMessages = true; - - @ConfigComment("") - @ConfigComment("Shows a title screen for player after completion a challenge or level.") - @ConfigComment("Message can be edited via language settings.") - @ConfigEntry(path = "title.show-title") - private boolean showCompletionTitle = true; - - @ConfigComment("") - @ConfigComment("Integer that represents how long title will be visible for player.") - @ConfigEntry(path = "title.title-showtime") - private int titleShowtime = 70; - - @ConfigComment("") - @ConfigComment("This list stores GameModes in which Challenges 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<>(); - - /** - * Default variable. - */ - @ConfigComment("") - private String uniqueId = "config"; - - /** - * Configuration version - */ - @ConfigComment("") - private String configVersion = "v3"; - - -// --------------------------------------------------------------------- -// Section: Methods -// --------------------------------------------------------------------- - - - /** - * This method returns the challengeLoreMessage object. - * @return the challengeLoreMessage object. - */ - public String getChallengeLoreMessage() - { - return challengeLoreMessage; - } - - - /** - * This method returns the configVersion object. - * @return the configVersion object. - */ - public String getConfigVersion() - { - return configVersion; - } - - - @Override - public String getUniqueId() - { - return this.uniqueId; - } - - - /** - * @return resetChallenges value. - */ - public boolean isResetChallenges() - { - return this.resetChallenges; - } - - - /** - * @return broadcastMessages value. - */ - public boolean isBroadcastMessages() - { - return this.broadcastMessages; - } - - - /** - * @return removeCompleteOneTimeChallenges value. - */ - public boolean isRemoveCompleteOneTimeChallenges() - { - return this.removeCompleteOneTimeChallenges; - } - - - /** - * @return addCompletedGlow value. - */ - public boolean isAddCompletedGlow() - { - return this.addCompletedGlow; - } - - - /** - * @return disabledGameModes value. - */ - public Set getDisabledGameModes() - { - return this.disabledGameModes; - } - - - /** - * @return freeChallengesFirst value. - */ - public boolean isFreeChallengesFirst() - { - return this.freeChallengesFirst; - } - - - /** - * This method returns the loreLineLength object. - * @return the loreLineLength object. - */ - public int getLoreLineLength() - { - return loreLineLength; - } - - - /** - * This method returns the levelLoreMessage object. - * @return the levelLoreMessage object. - */ - public String getLevelLoreMessage() - { - return levelLoreMessage; - } - - - /** - * This method returns the storeAsIslandData object. - * @return the storeAsIslandData object. - */ - public boolean isStoreAsIslandData() - { - return storeAsIslandData; - } - - - /** - * This method returns the storeHistory object. - * @return the storeHistory object. - */ - public boolean isStoreHistory() - { - return storeHistory; - } - - - /** - * This method returns the userCommand value. - * @return the value of userCommand. - */ - public String getUserCommand() - { - return userCommand; - } - - - /** - * This method returns the adminCommand value. - * @return the value of adminCommand. - */ - public String getAdminCommand() - { - return adminCommand; - } - - - /** - * This method returns the useCommonGUI value. - * @return the value of useCommonGUI. - */ - public boolean isUseCommonGUI() - { - return useCommonGUI; - } - - - /** - * This method returns the userGuiMode value. - * @return the value of userGuiMode. - */ - public GuiMode getUserGuiMode() - { - return userGuiMode; - } - - - /** - * This method returns the lifeSpan value. - * @return the value of lifeSpan. - */ - public int getLifeSpan() - { - return lifeSpan; - } - - - /** - * This method returns the lockedLevelIcon value. - * @return the value of lockedLevelIcon. - */ - public ItemStack getLockedLevelIcon() - { - return lockedLevelIcon.clone(); - } - - - /** - * This method returns the showCompletionTitle object. - * @return the showCompletionTitle object. - */ - public boolean isShowCompletionTitle() - { - return this.showCompletionTitle; - } - - - /** - * This method returns the titleShowtime object. - * @return the titleShowtime object. - */ - public int getTitleShowtime() - { - return this.titleShowtime; - } - - - /** - * This method sets the titleShowtime object value. - * @param titleShowtime the titleShowtime object new value. - * - */ - public void setTitleShowtime(int titleShowtime) - { - this.titleShowtime = titleShowtime; - } - - - /** - * This method sets the showCompletionTitle object value. - * @param showCompletionTitle the showCompletionTitle object new value. - * - */ - public void setShowCompletionTitle(boolean showCompletionTitle) - { - this.showCompletionTitle = showCompletionTitle; - } - - - /** - * This method sets the lockedLevelIcon value. - * @param lockedLevelIcon the lockedLevelIcon new value. - * - */ - public void setLockedLevelIcon(ItemStack lockedLevelIcon) - { - this.lockedLevelIcon = lockedLevelIcon; - } - - - /** - * This method sets the userGuiMode value. - * @param userGuiMode the userGuiMode new value. - */ - public void setUserGuiMode(GuiMode userGuiMode) - { - this.userGuiMode = userGuiMode; - } - - - /** - * This method sets the configVersion object value. - * @param configVersion the configVersion object new value. - */ - public void setConfigVersion(String configVersion) - { - this.configVersion = configVersion; - } - - - @Override - public void setUniqueId(String uniqueId) - { - this.uniqueId = uniqueId; - } - - - /** - * This method sets the challengeLoreMessage object value. - * @param challengeLoreMessage the challengeLoreMessage object new value. - */ - public void setChallengeLoreMessage(String challengeLoreMessage) - { - this.challengeLoreMessage = challengeLoreMessage; - } - - - /** - * This method sets the levelLoreMessage object value. - * @param levelLoreMessage the levelLoreMessage object new value. - */ - public void setLevelLoreMessage(String levelLoreMessage) - { - this.levelLoreMessage = levelLoreMessage; - } - - - /** - * @param resetChallenges new resetChallenges value. - */ - public void setResetChallenges(boolean resetChallenges) - { - this.resetChallenges = resetChallenges; - } - - - /** - * @param broadcastMessages new broadcastMessages value. - */ - public void setBroadcastMessages(boolean broadcastMessages) - { - this.broadcastMessages = broadcastMessages; - } - - - /** - * @param removeCompleteOneTimeChallenges new removeCompleteOneTimeChallenges value. - */ - public void setRemoveCompleteOneTimeChallenges(boolean removeCompleteOneTimeChallenges) - { - this.removeCompleteOneTimeChallenges = removeCompleteOneTimeChallenges; - } - - - /** - * @param addCompletedGlow new addCompletedGlow value. - */ - public void setAddCompletedGlow(boolean addCompletedGlow) - { - this.addCompletedGlow = addCompletedGlow; - } - - - /** - * @param disabledGameModes new disabledGameModes value. - */ - public void setDisabledGameModes(Set disabledGameModes) - { - this.disabledGameModes = disabledGameModes; - } - - - /** - * @param freeChallengesFirst new freeChallengesFirst value. - */ - public void setFreeChallengesFirst(boolean freeChallengesFirst) - { - this.freeChallengesFirst = freeChallengesFirst; - } - - - /** - * This method sets the loreLineLength object value. - * @param loreLineLength the loreLineLength object new value. - */ - public void setLoreLineLength(int loreLineLength) - { - this.loreLineLength = loreLineLength; - } - - - /** - * This method sets the storeAsIslandData object value. - * @param storeAsIslandData the storeAsIslandData object new value. - */ - public void setStoreAsIslandData(boolean storeAsIslandData) - { - this.storeAsIslandData = storeAsIslandData; - } - - - /** - * This method sets the storeHistory object value. - * @param storeHistory the storeHistory object new value. - */ - public void setStoreHistory(boolean storeHistory) - { - this.storeHistory = storeHistory; - } - - - /** - * This method sets the userCommand value. - * @param userCommand the userCommand new value. - */ - public void setUserCommand(String userCommand) - { - this.userCommand = userCommand; - } - - - /** - * This method sets the adminCommand value. - * @param adminCommand the adminCommand new value. - */ - public void setAdminCommand(String adminCommand) - { - this.adminCommand = adminCommand; - } - - - /** - * This method sets the useCommonGUI value. - * @param useCommonGUI the useCommonGUI new value. - */ - public void setUseCommonGUI(boolean useCommonGUI) - { - this.useCommonGUI = useCommonGUI; - } - - - /** - * This method sets the lifeSpan value. - * @param lifeSpan the lifeSpan new value. - * - */ - public void setLifeSpan(int lifeSpan) - { - this.lifeSpan = lifeSpan; - } - - -// --------------------------------------------------------------------- -// Section: Enums -// --------------------------------------------------------------------- - - - /** - * This enum holds all possible values for Gui Opening for users. - */ - public enum GuiMode - { - /** - * Opens user GUI with list of all GameModes. - */ - GAMEMODE_LIST, - /** - * Opens user GUI with challenges in given world. - */ - CURRENT_WORLD - } + @ConfigComment("") + @ConfigComment("Allows to define common challenges command that will open User GUI") + @ConfigComment("with all GameMode selection or Challenges from user world.") + @ConfigComment("This will not affect /{gamemode_user} challenges command.") + @ConfigEntry(path = "commands.user", needsReset = true) + private String userCommand = "challenges c"; + + @ConfigComment("") + @ConfigComment("Allows to define common challenges command that will open Admin GUI") + @ConfigComment("with all GameMode selection.") + @ConfigComment("This will not affect /{gamemode_admin} challenges command.") + @ConfigEntry(path = "commands.admin", needsReset = true) + private String adminCommand = "challengesadmin chadmin"; + + @ConfigComment("") + @ConfigComment("This enables/disables common command that will be independent from") + @ConfigComment("all GameModes. For admins it will open selection with all GameModes") + @ConfigComment("(unless there is one), but for users it will open GUI that corresponds") + @ConfigComment("to their world (unless it is specified other way in Admin GUI).") + @ConfigEntry(path = "commands.single-gui", needsReset = true) + private boolean useCommonGUI = false; + + @ConfigComment("") + @ConfigComment("This allows for admins to define which GUI will be opened for admins") + @ConfigComment("when users calls single-gui command.") + @ConfigComment("Acceptable values:") + @ConfigComment(" - CURRENT_WORLD - will open GUI that corresponds to user location.") + @ConfigComment(" - GAMEMODE_LIST - will open GUI with all installed game modes.") + @ConfigEntry(path = "commands.single-gamemode") + private GuiMode userGuiMode = GuiMode.CURRENT_WORLD; + + @ConfigComment("") + @ConfigComment("This indicate if player challenges data history will be stored or not.") + @ConfigEntry(path = "history.store-history-data") + private boolean storeHistory = false; + + @ConfigComment("") + @ConfigComment("This allows to specify an amount of time in days when history data will") + @ConfigComment("be removed. 0 means that data will not be removed.") + @ConfigEntry(path = "history.lifespan") + private int lifeSpan = 14; + + @ConfigComment("") + @ConfigComment("Remove non-repeatable challenges from the challenge GUI when complete.") + @ConfigEntry(path = "gui-settings.remove-complete-one-time-challenges") + private boolean removeCompleteOneTimeChallenges = false; + + @ConfigComment("") + @ConfigComment("Add enchanted glow to completed challenges") + @ConfigEntry(path = "gui-settings.add-completed-glow") + private boolean addCompletedGlow = true; + + @ConfigComment("") + @ConfigComment("This allows to change default locked level icon. This option may be") + @ConfigComment("overwritten by each challenge level. If challenge level has specified") + @ConfigComment("their locked level icon, then it will be used, instead of this one.") + @ConfigEntry(path = "gui-settings.locked-level-icon") + private ItemStack lockedLevelIcon = new ItemStack(Material.BOOK); + + @ConfigComment("") + @ConfigComment("This indicate if free challenges must be at the start (true) or at the end (false) of list.") + @ConfigEntry(path = "gui-settings.free-challenges-first") + private boolean freeChallengesFirst = true; + + @ConfigComment("") + @ConfigComment("This allows to change lore description line length. By default it is 25, but some server") + @ConfigComment("owners may like it to be larger.") + @ConfigEntry(path = "gui-settings.lore-length") + private int loreLineLength = 25; + + @ConfigComment("") + @ConfigComment("This string allows to change element order in Challenge description. Each letter represents") + @ConfigComment("one object from challenge description. If letter is not used, then its represented part") + @ConfigComment("will not be in description. If use any letter that is not recognized, then it will be") + @ConfigComment("ignored. Some strings can be customized via lang file under 'challenges.gui.challenge-description'.") + @ConfigComment("List of letters and their meaning: ") + @ConfigComment(" - L - Level String: '*.level'") + @ConfigComment(" - S - Status String: '*.completed'") + @ConfigComment(" - T - Times String: '*.completed-times', '*.completed-times-of' or '*.maxed-reached'") + @ConfigComment(" - D - Description String: defined in challenge object - challenge.description") + @ConfigComment(" - W - Warning String: '*.warning-items-take', '*.objects-close-by', '*.warning-entities-kill', '*.warning-blocks-remove'") + @ConfigComment(" - E - Environment String: defined in challenge object - challenge.environment") + @ConfigComment(" - Q - Requirement String: '*.required-level', '*.required-money', '*.required-experience'") + @ConfigComment(" - R - Reward String: '*.experience-reward', '*.money-reward', '*.not-repeatable'") + @ConfigComment("By adding 'i' after Q or R (requirements and rewards) will display list of items, blocks") + @ConfigComment("and entities that are defined in challenge and can be customized under 'challenges.gui.description.*'") + @ConfigEntry(path = "gui-settings.challenge-lore-message") + private String challengeLoreMessage = "LSTDEQiWRi"; + + @ConfigComment("") + @ConfigComment("This string allows to change element order in Level description. Each letter represents") + @ConfigComment("one object from level description. If letter is not used, then its represented part") + @ConfigComment("will not be in description. If use any letter that is not recognized, then it will be") + @ConfigComment("ignored. Some strings can be customized via lang file under 'challenges.gui.level-description'.") + @ConfigComment("List of letters and their meaning: ") + @ConfigComment(" - S - Status String: '*.completed'") + @ConfigComment(" - T - Count of completed challenges String: '*.completed-challenges-of'") + @ConfigComment(" - D - Description String: defined in level object - challengeLevel.unlockMessage") + @ConfigComment(" - A - WaiverAmount String: '*.waver-amount'") + @ConfigComment(" - R - Reward String: '*.experience-reward', '*.money-reward', '*.not-repeatable'") + @ConfigComment("By adding 'i' after R (rewards) will display list of items that are defined in challenge") + @ConfigComment("and can be customized under 'challenges.gui.description.*'") + @ConfigEntry(path = "gui-settings.level-lore-message") + private String levelLoreMessage = "STDARi"; + + @ConfigComment("") + @ConfigComment("This indicate if challenges data will be stored per island (true) or per player (false).") + @ConfigEntry(path = "store-island-data") + private boolean storeAsIslandData = false; + + @ConfigComment("") + @ConfigComment("Reset Challenges - if this is true, player's challenges will reset when users") + @ConfigComment("reset an island or if users are kicked or leave a team. Prevents exploiting the") + @ConfigComment("challenges by doing them repeatedly.") + @ConfigEntry(path = "reset-challenges") + private boolean resetChallenges = true; + + @ConfigComment("") + @ConfigComment("Broadcast 1st time challenge completion messages to all players.") + @ConfigComment("Change to false if the spam becomes too much.") + @ConfigEntry(path = "broadcast-messages") + private boolean broadcastMessages = true; + + @ConfigComment("") + @ConfigComment("Shows a title screen for player after completion a challenge or level.") + @ConfigComment("Message can be edited via language settings.") + @ConfigEntry(path = "title.show-title") + private boolean showCompletionTitle = true; + + @ConfigComment("") + @ConfigComment("Integer that represents how long title will be visible for player.") + @ConfigEntry(path = "title.title-showtime") + private int titleShowtime = 70; + + @ConfigComment("") + @ConfigComment("This list stores GameModes in which Challenges 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<>(); + + /** + * Configuration version + */ + @ConfigComment("") + private String configVersion = "v3"; + + + // --------------------------------------------------------------------- + // Section: Methods + // --------------------------------------------------------------------- + + + /** + * This method returns the challengeLoreMessage object. + * @return the challengeLoreMessage object. + */ + public String getChallengeLoreMessage() + { + return challengeLoreMessage; + } + + + /** + * This method returns the configVersion object. + * @return the configVersion object. + */ + public String getConfigVersion() + { + return configVersion; + } + + + /** + * @return resetChallenges value. + */ + public boolean isResetChallenges() + { + return this.resetChallenges; + } + + + /** + * @return broadcastMessages value. + */ + public boolean isBroadcastMessages() + { + return this.broadcastMessages; + } + + + /** + * @return removeCompleteOneTimeChallenges value. + */ + public boolean isRemoveCompleteOneTimeChallenges() + { + return this.removeCompleteOneTimeChallenges; + } + + + /** + * @return addCompletedGlow value. + */ + public boolean isAddCompletedGlow() + { + return this.addCompletedGlow; + } + + + /** + * @return disabledGameModes value. + */ + public Set getDisabledGameModes() + { + return this.disabledGameModes; + } + + + /** + * @return freeChallengesFirst value. + */ + public boolean isFreeChallengesFirst() + { + return this.freeChallengesFirst; + } + + + /** + * This method returns the loreLineLength object. + * @return the loreLineLength object. + */ + public int getLoreLineLength() + { + return loreLineLength; + } + + + /** + * This method returns the levelLoreMessage object. + * @return the levelLoreMessage object. + */ + public String getLevelLoreMessage() + { + return levelLoreMessage; + } + + + /** + * This method returns the storeAsIslandData object. + * @return the storeAsIslandData object. + */ + public boolean isStoreAsIslandData() + { + return storeAsIslandData; + } + + + /** + * This method returns the storeHistory object. + * @return the storeHistory object. + */ + public boolean isStoreHistory() + { + return storeHistory; + } + + + /** + * This method returns the userCommand value. + * @return the value of userCommand. + */ + public String getUserCommand() + { + return userCommand; + } + + + /** + * This method returns the adminCommand value. + * @return the value of adminCommand. + */ + public String getAdminCommand() + { + return adminCommand; + } + + + /** + * This method returns the useCommonGUI value. + * @return the value of useCommonGUI. + */ + public boolean isUseCommonGUI() + { + return useCommonGUI; + } + + + /** + * This method returns the userGuiMode value. + * @return the value of userGuiMode. + */ + public GuiMode getUserGuiMode() + { + return userGuiMode; + } + + + /** + * This method returns the lifeSpan value. + * @return the value of lifeSpan. + */ + public int getLifeSpan() + { + return lifeSpan; + } + + + /** + * This method returns the lockedLevelIcon value. + * @return the value of lockedLevelIcon. + */ + public ItemStack getLockedLevelIcon() + { + return lockedLevelIcon.clone(); + } + + + /** + * This method returns the showCompletionTitle object. + * @return the showCompletionTitle object. + */ + public boolean isShowCompletionTitle() + { + return this.showCompletionTitle; + } + + + /** + * This method returns the titleShowtime object. + * @return the titleShowtime object. + */ + public int getTitleShowtime() + { + return this.titleShowtime; + } + + + /** + * This method sets the titleShowtime object value. + * @param titleShowtime the titleShowtime object new value. + * + */ + public void setTitleShowtime(int titleShowtime) + { + this.titleShowtime = titleShowtime; + } + + + /** + * This method sets the showCompletionTitle object value. + * @param showCompletionTitle the showCompletionTitle object new value. + * + */ + public void setShowCompletionTitle(boolean showCompletionTitle) + { + this.showCompletionTitle = showCompletionTitle; + } + + + /** + * This method sets the lockedLevelIcon value. + * @param lockedLevelIcon the lockedLevelIcon new value. + * + */ + public void setLockedLevelIcon(ItemStack lockedLevelIcon) + { + this.lockedLevelIcon = lockedLevelIcon; + } + + + /** + * This method sets the userGuiMode value. + * @param userGuiMode the userGuiMode new value. + */ + public void setUserGuiMode(GuiMode userGuiMode) + { + this.userGuiMode = userGuiMode; + } + + + /** + * This method sets the configVersion object value. + * @param configVersion the configVersion object new value. + */ + public void setConfigVersion(String configVersion) + { + this.configVersion = configVersion; + } + + + /** + * This method sets the challengeLoreMessage object value. + * @param challengeLoreMessage the challengeLoreMessage object new value. + */ + public void setChallengeLoreMessage(String challengeLoreMessage) + { + this.challengeLoreMessage = challengeLoreMessage; + } + + + /** + * This method sets the levelLoreMessage object value. + * @param levelLoreMessage the levelLoreMessage object new value. + */ + public void setLevelLoreMessage(String levelLoreMessage) + { + this.levelLoreMessage = levelLoreMessage; + } + + + /** + * @param resetChallenges new resetChallenges value. + */ + public void setResetChallenges(boolean resetChallenges) + { + this.resetChallenges = resetChallenges; + } + + + /** + * @param broadcastMessages new broadcastMessages value. + */ + public void setBroadcastMessages(boolean broadcastMessages) + { + this.broadcastMessages = broadcastMessages; + } + + + /** + * @param removeCompleteOneTimeChallenges new removeCompleteOneTimeChallenges value. + */ + public void setRemoveCompleteOneTimeChallenges(boolean removeCompleteOneTimeChallenges) + { + this.removeCompleteOneTimeChallenges = removeCompleteOneTimeChallenges; + } + + + /** + * @param addCompletedGlow new addCompletedGlow value. + */ + public void setAddCompletedGlow(boolean addCompletedGlow) + { + this.addCompletedGlow = addCompletedGlow; + } + + + /** + * @param disabledGameModes new disabledGameModes value. + */ + public void setDisabledGameModes(Set disabledGameModes) + { + this.disabledGameModes = disabledGameModes; + } + + + /** + * @param freeChallengesFirst new freeChallengesFirst value. + */ + public void setFreeChallengesFirst(boolean freeChallengesFirst) + { + this.freeChallengesFirst = freeChallengesFirst; + } + + + /** + * This method sets the loreLineLength object value. + * @param loreLineLength the loreLineLength object new value. + */ + public void setLoreLineLength(int loreLineLength) + { + this.loreLineLength = loreLineLength; + } + + + /** + * This method sets the storeAsIslandData object value. + * @param storeAsIslandData the storeAsIslandData object new value. + */ + public void setStoreAsIslandData(boolean storeAsIslandData) + { + this.storeAsIslandData = storeAsIslandData; + } + + + /** + * This method sets the storeHistory object value. + * @param storeHistory the storeHistory object new value. + */ + public void setStoreHistory(boolean storeHistory) + { + this.storeHistory = storeHistory; + } + + + /** + * This method sets the userCommand value. + * @param userCommand the userCommand new value. + */ + public void setUserCommand(String userCommand) + { + this.userCommand = userCommand; + } + + + /** + * This method sets the adminCommand value. + * @param adminCommand the adminCommand new value. + */ + public void setAdminCommand(String adminCommand) + { + this.adminCommand = adminCommand; + } + + + /** + * This method sets the useCommonGUI value. + * @param useCommonGUI the useCommonGUI new value. + */ + public void setUseCommonGUI(boolean useCommonGUI) + { + this.useCommonGUI = useCommonGUI; + } + + + /** + * This method sets the lifeSpan value. + * @param lifeSpan the lifeSpan new value. + * + */ + public void setLifeSpan(int lifeSpan) + { + this.lifeSpan = lifeSpan; + } + + + // --------------------------------------------------------------------- + // Section: Enums + // --------------------------------------------------------------------- + + + /** + * This enum holds all possible values for Gui Opening for users. + */ + public enum GuiMode + { + /** + * Opens user GUI with list of all GameModes. + */ + GAMEMODE_LIST, + /** + * Opens user GUI with challenges in given world. + */ + CURRENT_WORLD + } } diff --git a/src/main/java/world/bentobox/challenges/database/object/Challenge.java b/src/main/java/world/bentobox/challenges/database/object/Challenge.java index bcf666b..20ae133 100644 --- a/src/main/java/world/bentobox/challenges/database/object/Challenge.java +++ b/src/main/java/world/bentobox/challenges/database/object/Challenge.java @@ -311,7 +311,7 @@ public class Challenge implements DataObject */ public ItemStack getIcon() { - return icon.clone(); + return icon !=null ? icon.clone() : new ItemStack(Material.PAPER); } From 34ed09e7684d694fd003af6db0b9063ac1ddcb43 Mon Sep 17 00:00:00 2001 From: BONNe1704 Date: Thu, 9 May 2019 16:45:53 +0300 Subject: [PATCH 03/18] Change json adapter factory to BentoBoxTypeAdapterFactory class. --- .../bentobox/challenges/ChallengesImportManager.java | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/main/java/world/bentobox/challenges/ChallengesImportManager.java b/src/main/java/world/bentobox/challenges/ChallengesImportManager.java index dc426f4..2d9c496 100644 --- a/src/main/java/world/bentobox/challenges/ChallengesImportManager.java +++ b/src/main/java/world/bentobox/challenges/ChallengesImportManager.java @@ -8,7 +8,6 @@ import java.nio.file.Files; import java.util.*; import java.util.stream.Collectors; -import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.World; import org.bukkit.configuration.ConfigurationSection; @@ -16,10 +15,8 @@ import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.EntityType; import org.bukkit.inventory.ItemStack; -import org.bukkit.potion.PotionEffectType; -import world.bentobox.bentobox.api.flags.Flag; -import world.bentobox.bentobox.database.json.adapters.*; +import world.bentobox.bentobox.database.json.BentoboxTypeAdapterFactory; import world.bentobox.bentobox.database.objects.DataObject; import world.bentobox.bentobox.util.ItemParser; import world.bentobox.challenges.database.object.ChallengeLevel; @@ -431,11 +428,7 @@ public class ChallengesImportManager { GsonBuilder builder = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().enableComplexMapKeySerialization(); // Register adapters - builder.registerTypeAdapter(Location.class, new LocationAdapter()) ; - builder.registerTypeAdapter(World.class, new WorldAdapter()); - builder.registerTypeAdapter(Flag.class, new FlagAdapter(addon.getPlugin())); - builder.registerTypeAdapter(PotionEffectType.class, new PotionEffectTypeAdapter()); - builder.registerTypeAdapter(ItemStack.class, new ItemStackTypeAdapter()); + builder.registerTypeAdapterFactory(new BentoboxTypeAdapterFactory(addon.getPlugin())); // Keep null in the database builder.serializeNulls(); // Allow characters like < or > without escaping them From 9f8bf037087ab56f6e4d2380691d5d1bdca5b9ca Mon Sep 17 00:00:00 2001 From: BONNe Date: Tue, 14 May 2019 09:20:17 +0300 Subject: [PATCH 04/18] Fix wrongly display message for required money in edit challenge gui (#119) It showed required level instead of required money in element description. --- .../bentobox/challenges/panel/admin/EditChallengeGUI.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/world/bentobox/challenges/panel/admin/EditChallengeGUI.java b/src/main/java/world/bentobox/challenges/panel/admin/EditChallengeGUI.java index 1a158ea..febaa7b 100644 --- a/src/main/java/world/bentobox/challenges/panel/admin/EditChallengeGUI.java +++ b/src/main/java/world/bentobox/challenges/panel/admin/EditChallengeGUI.java @@ -604,7 +604,7 @@ public class EditChallengeGUI extends CommonGUI { name = this.user.getTranslation("challenges.gui.buttons.admin.required-blocks"); - description = new ArrayList<>(this.challenge.getRequiredEntities().size() + 1); + description = new ArrayList<>(this.challenge.getRequiredBlocks().size() + 1); description.add(this.user.getTranslation("challenges.gui.descriptions.admin.required-blocks")); for (Map.Entry entry : this.challenge.getRequiredBlocks().entrySet()) @@ -713,7 +713,7 @@ public class EditChallengeGUI extends CommonGUI { name = this.user.getTranslation("challenges.gui.buttons.admin.required-items"); - description = new ArrayList<>(this.challenge.getRequiredEntities().size() + 1); + description = new ArrayList<>(this.challenge.getRequiredItems().size() + 1); description.add(this.user.getTranslation("challenges.gui.descriptions.admin.required-items")); for (ItemStack itemStack : this.challenge.getRequiredItems()) @@ -847,7 +847,7 @@ public class EditChallengeGUI extends CommonGUI description = new ArrayList<>(2); description.add(this.user.getTranslation("challenges.gui.descriptions.admin.required-money")); description.add(this.user.getTranslation("challenges.gui.descriptions.current-value", - "[value]", Long.toString(this.challenge.getRequiredIslandLevel()))); + "[value]", Long.toString(this.challenge.getRequiredMoney()))); icon = new ItemStack(this.addon.isEconomyProvided() ? Material.GOLD_INGOT : Material.BARRIER); clickHandler = (panel, user, clickType, slot) -> { From 3521495739eb0cd61311a31fd462cf94812b6778 Mon Sep 17 00:00:00 2001 From: BONNe Date: Tue, 14 May 2019 09:55:34 +0300 Subject: [PATCH 05/18] Fix issue when entities has not been removed on challenge completion (#118). I forgot to populate entity queue :( --- .../java/world/bentobox/challenges/tasks/TryToComplete.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/world/bentobox/challenges/tasks/TryToComplete.java b/src/main/java/world/bentobox/challenges/tasks/TryToComplete.java index ca915a8..2242922 100644 --- a/src/main/java/world/bentobox/challenges/tasks/TryToComplete.java +++ b/src/main/java/world/bentobox/challenges/tasks/TryToComplete.java @@ -1064,6 +1064,8 @@ public class TryToComplete // Check if entity is inside challenge bounding box if (requiredMap.containsKey(entity.getType())) { + entityQueue.add(entity); + entitiesFound.putIfAbsent(entity.getType(), 1); entitiesFound.computeIfPresent(entity.getType(), (reqEntity, amount) -> amount + 1); From 9704ed32aa37189bc8f9790ce6e7f0715bfe655d Mon Sep 17 00:00:00 2001 From: BONNe1704 Date: Thu, 16 May 2019 10:30:01 +0300 Subject: [PATCH 06/18] Fix issue when IslandTypeChallenges required blocks were cleared if completion was uncessesfull. The issue was that it cleared wrong map. It must clear priority queue, but cleared required elements. --- .../java/world/bentobox/challenges/tasks/TryToComplete.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/world/bentobox/challenges/tasks/TryToComplete.java b/src/main/java/world/bentobox/challenges/tasks/TryToComplete.java index ca915a8..aff57be 100644 --- a/src/main/java/world/bentobox/challenges/tasks/TryToComplete.java +++ b/src/main/java/world/bentobox/challenges/tasks/TryToComplete.java @@ -162,7 +162,9 @@ public class TryToComplete this.permissionPrefix = permissionPrefix; this.user = user; this.manager = addon.getChallengesManager(); - this.challenge = challenge; + // To avoid any modifications that may accure to challenges in current completion + // just clone it. + this.challenge = challenge.clone(); this.topLabel = topLabel; } @@ -1021,7 +1023,7 @@ public class TryToComplete // kick garbage collector blocks.clear(); blocksFound.clear(); - requiredMap.clear(); + blockFromWorld.clear(); return EMPTY_RESULT; } From c3f93fd797a01f5ef28815570d93294ed30c84c6 Mon Sep 17 00:00:00 2001 From: BONNe Date: Sat, 18 May 2019 00:01:03 +0300 Subject: [PATCH 07/18] Implement ability to select multiple Entities and Blocks in SelectBlockGUI and SelectEntityGUI. (#121) Fix issue with unsplitted text in ManageBlocksGUI and ManageEntitiesGUI. (#121) --- .../panel/admin/ManageBlocksGUI.java | 11 ++-- .../panel/admin/ManageEntitiesGUI.java | 12 ++--- .../panel/util/SelectBlocksGUI.java | 52 +++++++++++++++---- .../panel/util/SelectEntityGUI.java | 50 +++++++++++++++--- 4 files changed, 100 insertions(+), 25 deletions(-) diff --git a/src/main/java/world/bentobox/challenges/panel/admin/ManageBlocksGUI.java b/src/main/java/world/bentobox/challenges/panel/admin/ManageBlocksGUI.java index 2d5fa06..9fad135 100644 --- a/src/main/java/world/bentobox/challenges/panel/admin/ManageBlocksGUI.java +++ b/src/main/java/world/bentobox/challenges/panel/admin/ManageBlocksGUI.java @@ -111,6 +111,7 @@ public class ManageBlocksGUI extends CommonGUI */ private PanelItem createButton(Button button) { + int lineLength = this.addon.getChallengesSettings().getLoreLineLength(); PanelItemBuilder builder = new PanelItemBuilder(); switch (button) @@ -120,11 +121,13 @@ public class ManageBlocksGUI extends CommonGUI builder.icon(Material.BUCKET); builder.clickHandler((panel, user1, clickType, slot) -> { - new SelectBlocksGUI(this.user, new HashSet<>(this.materialList), (status, material) -> { + new SelectBlocksGUI(this.user, new HashSet<>(this.materialList), (status, materials) -> { if (status) { - this.materialMap.put(material, 1); - this.materialList.add(material); + materials.forEach(material -> { + this.materialMap.put(material, 1); + this.materialList.add(material); + }); } this.build(); @@ -134,7 +137,7 @@ public class ManageBlocksGUI extends CommonGUI break; case REMOVE: builder.name(this.user.getTranslation("challenges.gui.buttons.admin.remove-selected")); - builder.description(this.user.getTranslation("challenges.gui.descriptions.admin.remove-selected")); + builder.description(GuiUtils.stringSplit(this.user.getTranslation("challenges.gui.descriptions.admin.remove-selected"), lineLength)); builder.icon(Material.LAVA_BUCKET); builder.clickHandler((panel, user1, clickType, slot) -> { this.materialMap.keySet().removeAll(this.selectedMaterials); diff --git a/src/main/java/world/bentobox/challenges/panel/admin/ManageEntitiesGUI.java b/src/main/java/world/bentobox/challenges/panel/admin/ManageEntitiesGUI.java index df8e401..135621d 100644 --- a/src/main/java/world/bentobox/challenges/panel/admin/ManageEntitiesGUI.java +++ b/src/main/java/world/bentobox/challenges/panel/admin/ManageEntitiesGUI.java @@ -111,6 +111,7 @@ public class ManageEntitiesGUI extends CommonGUI */ private PanelItem createButton(Button button) { + int lineLength = this.addon.getChallengesSettings().getLoreLineLength(); PanelItemBuilder builder = new PanelItemBuilder(); switch (button) @@ -119,14 +120,13 @@ public class ManageEntitiesGUI extends CommonGUI builder.name(this.user.getTranslation("challenges.gui.buttons.admin.add")); builder.icon(Material.BUCKET); builder.clickHandler((panel, user1, clickType, slot) -> { - new SelectEntityGUI(this.user, Collections.emptySet(), this.asEggs, (status, entity) -> { + new SelectEntityGUI(this.user, this.requiredEntities.keySet(), this.asEggs, (status, entities) -> { if (status) { - if (!this.requiredEntities.containsKey(entity)) - { + entities.forEach(entity -> { this.requiredEntities.put(entity, 1); this.entityList.add(entity); - } + }); } this.build(); @@ -136,7 +136,7 @@ public class ManageEntitiesGUI extends CommonGUI break; case REMOVE: builder.name(this.user.getTranslation("challenges.gui.buttons.admin.remove-selected")); - builder.description(this.user.getTranslation("challenges.gui.descriptions.admin.remove-selected")); + builder.description(GuiUtils.stringSplit(this.user.getTranslation("challenges.gui.descriptions.admin.remove-selected"), lineLength)); builder.icon(Material.LAVA_BUCKET); builder.clickHandler((panel, user1, clickType, slot) -> { this.requiredEntities.keySet().removeAll(this.selectedEntities); @@ -147,7 +147,7 @@ public class ManageEntitiesGUI extends CommonGUI break; case SWITCH: builder.name(this.user.getTranslation("challenges.gui.buttons.admin.show-eggs")); - builder.description(this.user.getTranslation("challenges.gui.descriptions.admin.show-eggs")); + builder.description(GuiUtils.stringSplit(this.user.getTranslation("challenges.gui.descriptions.admin.show-eggs"), lineLength)); builder.icon(this.asEggs ? Material.EGG : Material.PLAYER_HEAD); builder.clickHandler((panel, user1, clickType, slot) -> { this.asEggs = !this.asEggs; diff --git a/src/main/java/world/bentobox/challenges/panel/util/SelectBlocksGUI.java b/src/main/java/world/bentobox/challenges/panel/util/SelectBlocksGUI.java index 1ac4f5f..52a79f2 100644 --- a/src/main/java/world/bentobox/challenges/panel/util/SelectBlocksGUI.java +++ b/src/main/java/world/bentobox/challenges/panel/util/SelectBlocksGUI.java @@ -4,10 +4,7 @@ package world.bentobox.challenges.panel.util; import org.apache.commons.lang.WordUtils; import org.bukkit.Material; import org.bukkit.inventory.ItemStack; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Set; +import java.util.*; import java.util.function.BiConsumer; import world.bentobox.bentobox.api.panels.PanelItem; @@ -23,13 +20,13 @@ import world.bentobox.challenges.utils.GuiUtils; */ public class SelectBlocksGUI { - public SelectBlocksGUI(User user, BiConsumer consumer) + public SelectBlocksGUI(User user, BiConsumer> consumer) { this(user, Collections.emptySet(), consumer); } - public SelectBlocksGUI(User user, Set excludedMaterial, BiConsumer consumer) + public SelectBlocksGUI(User user, Set excludedMaterial, BiConsumer> consumer) { this.consumer = consumer; this.user = user; @@ -47,6 +44,7 @@ public class SelectBlocksGUI excludedMaterial.add(Material.BARRIER); this.elements = new ArrayList<>(); + this.selectedMaterials = new HashSet<>(); for (Material material : Material.values()) { @@ -107,7 +105,7 @@ public class SelectBlocksGUI index++; } - panelBuilder.item(4, + panelBuilder.item(3, new PanelItemBuilder(). icon(Material.RED_STAINED_GLASS_PANE). name(this.user.getTranslation("challenges.gui.buttons.admin.cancel")). @@ -116,6 +114,24 @@ public class SelectBlocksGUI return true; }).build()); + + List description = new ArrayList<>(); + if (!this.selectedMaterials.isEmpty()) + { + description.add(this.user.getTranslation("challenges.gui.descriptions.admin.selected") + ":"); + this.selectedMaterials.forEach(material -> description.add(" - " + material.name())); + } + + panelBuilder.item(5, + new PanelItemBuilder(). + icon(Material.GREEN_STAINED_GLASS_PANE). + name(this.user.getTranslation("challenges.gui.buttons.admin.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 @@ -164,9 +180,22 @@ public class SelectBlocksGUI return new PanelItemBuilder(). name(WordUtils.capitalize(material.name().toLowerCase().replace("_", " "))). + description(this.selectedMaterials.contains(material) ? + this.user.getTranslation("challenges.gui.descriptions.admin.selected") : ""). icon(itemStack). clickHandler((panel, user1, clickType, slot) -> { - this.consumer.accept(true, material); + if (clickType.isRightClick()) + { + if (!this.selectedMaterials.add(material)) + { + this.selectedMaterials.remove(material); + } + } + else + { + this.consumer.accept(true, this.selectedMaterials); + } + return true; }). glow(!itemStack.getType().equals(material)). @@ -183,10 +212,15 @@ public class SelectBlocksGUI */ private List elements; + /** + * Set that contains selected materials. + */ + private Set selectedMaterials; + /** * This variable stores consumer. */ - private BiConsumer consumer; + private BiConsumer> consumer; /** * User who runs GUI. diff --git a/src/main/java/world/bentobox/challenges/panel/util/SelectEntityGUI.java b/src/main/java/world/bentobox/challenges/panel/util/SelectEntityGUI.java index 295ef21..4cf2a72 100644 --- a/src/main/java/world/bentobox/challenges/panel/util/SelectEntityGUI.java +++ b/src/main/java/world/bentobox/challenges/panel/util/SelectEntityGUI.java @@ -20,19 +20,20 @@ import world.bentobox.challenges.utils.GuiUtils; */ public class SelectEntityGUI { - public SelectEntityGUI(User user, BiConsumer consumer) + public SelectEntityGUI(User user, BiConsumer> consumer) { this(user, Collections.emptySet(), true, consumer); } - public SelectEntityGUI(User user, Set excludedEntities, boolean asEggs, BiConsumer consumer) + public SelectEntityGUI(User user, Set excludedEntities, boolean asEggs, BiConsumer> consumer) { this.consumer = consumer; this.user = user; this.asEggs = asEggs; this.entities = new ArrayList<>(EntityType.values().length); + this.selectedEntities = new HashSet<>(EntityType.values().length); for (EntityType entityType : EntityType.values()) { @@ -81,7 +82,7 @@ public class SelectEntityGUI correctPage = pageIndex; } - panelBuilder.item(4, + panelBuilder.item(3, new PanelItemBuilder(). icon(Material.RED_STAINED_GLASS_PANE). name(this.user.getTranslation("challenges.gui.buttons.admin.cancel")). @@ -90,6 +91,23 @@ public class SelectEntityGUI return true; }).build()); + List description = new ArrayList<>(); + if (!this.selectedEntities.isEmpty()) + { + description.add(this.user.getTranslation("challenges.gui.descriptions.admin.selected") + ":"); + this.selectedEntities.forEach(entity -> description.add(" - " + entity.name())); + } + + panelBuilder.item(5, + new PanelItemBuilder(). + icon(Material.GREEN_STAINED_GLASS_PANE). + name(this.user.getTranslation("challenges.gui.buttons.admin.accept")). + description(description). + clickHandler( (panel, user1, clickType, slot) -> { + this.consumer.accept(true, this.selectedEntities); + return true; + }).build()); + if (this.entities.size() > MAX_ELEMENTS) { // Navigation buttons if necessary @@ -156,10 +174,25 @@ public class SelectEntityGUI return new PanelItemBuilder(). name(WordUtils.capitalize(entity.name().toLowerCase().replace("_", " "))). icon(itemStack). + description(this.selectedEntities.contains(entity) ? + this.user.getTranslation("challenges.gui.descriptions.admin.selected") : ""). clickHandler((panel, user1, clickType, slot) -> { - this.consumer.accept(true, entity); + if (clickType.isRightClick()) + { + if (!this.selectedEntities.add(entity)) + { + this.selectedEntities.remove(entity); + } + } + else + { + this.consumer.accept(true, this.selectedEntities); + } + return true; - }).build(); + }). + glow(this.selectedEntities.contains(entity)). + build(); } @@ -171,7 +204,12 @@ public class SelectEntityGUI /** * This variable stores consumer. */ - private BiConsumer consumer; + private BiConsumer> consumer; + + /** + * Set that contains selected entities. + */ + private Set selectedEntities; /** * User who runs GUI. From 7e04f592add57bbee5e7713b4b4fc17a65997897 Mon Sep 17 00:00:00 2001 From: BONNe Date: Sun, 19 May 2019 13:29:02 +0300 Subject: [PATCH 08/18] Add custom admin message that informs about non-existing challenges in current world. --- .../commands/ChallengesCommand.java | 69 +++++++++++++++---- src/main/resources/locales/en-US.yml | 1 + src/main/resources/locales/lv-LV.yml | 1 + 3 files changed, 57 insertions(+), 14 deletions(-) diff --git a/src/main/java/world/bentobox/challenges/commands/ChallengesCommand.java b/src/main/java/world/bentobox/challenges/commands/ChallengesCommand.java index f14a4c3..d094bdc 100644 --- a/src/main/java/world/bentobox/challenges/commands/ChallengesCommand.java +++ b/src/main/java/world/bentobox/challenges/commands/ChallengesCommand.java @@ -1,7 +1,9 @@ package world.bentobox.challenges.commands; import java.util.List; +import java.util.Optional; +import world.bentobox.bentobox.api.addons.GameModeAddon; import world.bentobox.challenges.ChallengesAddon; import world.bentobox.bentobox.api.commands.CompositeCommand; import world.bentobox.bentobox.api.user.User; @@ -19,26 +21,64 @@ public class ChallengesCommand extends CompositeCommand } + /** + * {@inheritDoc} + */ + @Override + public boolean canExecute(User user, String label, List args) + { + Optional optionalAddon = this.getAddon().getPlugin().getIWM().getAddon(this.getWorld()); + + if (!optionalAddon.isPresent()) + { + // Not a GameMode world. + user.sendMessage("general.errors.wrong-world"); + return false; + } + + if (!((ChallengesAddon) this.getAddon()).getChallengesManager().hasAnyChallengeData(this.getWorld())) + { + // Do not open gui if there is no challenges. + + this.getAddon().getLogger().severe("There are no challenges set up in " + this.getWorld() + "!"); + + // Show admin better explanation. + if (user.isOp() || user.hasPermission(this.getPermissionPrefix() + ".admin.challenges")) + { + String topLabel = optionalAddon.get().getAdminCommand().orElseGet(this::getParent).getTopLabel(); + user.sendMessage("challenges.errors.no-challenges-admin", "[label]", topLabel); + } + else + { + user.sendMessage("challenges.errors.no-challenges"); + } + + return false; + } + + if (this.getPlugin().getIslands().getIsland(this.getWorld(), user.getUniqueId()) == null) + { + // Do not open gui if there is no island for this player. + user.sendMessage("general.errors.no-island"); + return false; + } + + return true; + } + + @Override public boolean execute(User user, String label, List args) { // Open up the challenges GUI if (user.isPlayer()) { - if (this.getPlugin().getIslands().getIsland(this.getWorld(), user.getUniqueId()) != null) - { - new ChallengesGUI((ChallengesAddon) this.getAddon(), - this.getWorld(), - user, - this.getTopLabel(), - this.getPermissionPrefix()).build(); - return true; - } - else - { - user.sendMessage("general.errors.no-island"); - return false; - } + new ChallengesGUI((ChallengesAddon) this.getAddon(), + this.getWorld(), + user, + this.getTopLabel(), + this.getPermissionPrefix()).build(); + return true; } // Show help showHelp(this, user); @@ -54,5 +94,6 @@ public class ChallengesCommand extends CompositeCommand this.setDescription("challenges.commands.user.main.description"); new CompleteChallengeCommand(this.getAddon(), this); + this.setOnlyPlayer(true); } } diff --git a/src/main/resources/locales/en-US.yml b/src/main/resources/locales/en-US.yml index bd49e2f..ca2748c 100755 --- a/src/main/resources/locales/en-US.yml +++ b/src/main/resources/locales/en-US.yml @@ -353,6 +353,7 @@ challenges: defaults-file-exist: '&cdefaults.json already exists. Use overwrite mode to replace it!' defaults-file-error: '&cThere was an error while creating defaults.json file! Check console!' no-challenges: '&cChallenges are not implemented in current world!' + no-challenges-admin: '&cChallenges are not implemented in current world! You should use &5/[label] challenges &cto adding them!' missing-level: '&cChallenge Level [level] is not defined in database. It may case some errors!' protection: flags: diff --git a/src/main/resources/locales/lv-LV.yml b/src/main/resources/locales/lv-LV.yml index aa85683..8c0faaf 100755 --- a/src/main/resources/locales/lv-LV.yml +++ b/src/main/resources/locales/lv-LV.yml @@ -351,6 +351,7 @@ challenges: defaults-file-exist: '&cdefaults.json jau eksistē. Lieto overwrite, lai to pārrakstītu!' defaults-file-error: '&cRadās kļūda veidojot defaults.json failu! Pārbaudi konsoli!' no-challenges: '&cŠajā pasaulē nav izveidoti uzdevumi!' + no-challenges-admin: '&cŠajā pasaulē nav izveidoti uzdevumi! Izmanot komandu &5/[label] challenges&c, lai tos pievienotu!' missing-level: '&cLīmenis [level] nav definēts datubāzē. Tas var radīt problēmas!' protection: flags: From 330034ea8e05023b80174579957b880dda6a7486 Mon Sep 17 00:00:00 2001 From: BONNe Date: Mon, 20 May 2019 08:28:35 +0300 Subject: [PATCH 09/18] Add SIGN_MATERIAL constant in ChallengesAddon which value depends on Minecraft version. This will allow to drop down 1.14 branch. --- .../world/bentobox/challenges/ChallengesAddon.java | 8 ++++++++ .../world/bentobox/challenges/panel/CommonGUI.java | 4 ++-- .../challenges/panel/admin/EditSettingsGUI.java | 2 +- .../challenges/panel/user/ChallengesGUI.java | 12 ++++++------ .../challenges/panel/util/SelectBlocksGUI.java | 5 +++-- .../challenges/panel/util/SelectChallengeGUI.java | 5 +++-- .../challenges/panel/util/SelectEntityGUI.java | 5 +++-- 7 files changed, 26 insertions(+), 15 deletions(-) diff --git a/src/main/java/world/bentobox/challenges/ChallengesAddon.java b/src/main/java/world/bentobox/challenges/ChallengesAddon.java index e3b7a71..0735838 100644 --- a/src/main/java/world/bentobox/challenges/ChallengesAddon.java +++ b/src/main/java/world/bentobox/challenges/ChallengesAddon.java @@ -88,6 +88,14 @@ public class ChallengesAddon extends Addon { new Flag.Builder("CHALLENGES_ISLAND_PROTECTION", Material.COMMAND_BLOCK).defaultRank(RanksManager.VISITOR_RANK).build(); + /** + * This ir ugly way how to fix comparability issues between 1.13 and 1.14 versions. + * @deprecated Should be removed as soon as 1.13 support are dropped down. + */ + @Deprecated + public static final Material SIGN_MATERIAL = Bukkit.getBukkitVersion().startsWith("1.13") ? Material.getMaterial("SIGN") : Material.getMaterial("OAK_SIGN"); + + // --------------------------------------------------------------------- // Section: Methods // --------------------------------------------------------------------- diff --git a/src/main/java/world/bentobox/challenges/panel/CommonGUI.java b/src/main/java/world/bentobox/challenges/panel/CommonGUI.java index 219a2be..31ccae9 100644 --- a/src/main/java/world/bentobox/challenges/panel/CommonGUI.java +++ b/src/main/java/world/bentobox/challenges/panel/CommonGUI.java @@ -216,7 +216,7 @@ public abstract class CommonGUI { name = this.user.getTranslation("challenges.gui.buttons.next"); description = Collections.emptyList(); - icon = new ItemStack(Material.SIGN); + icon = new ItemStack(ChallengesAddon.SIGN_MATERIAL); clickHandler = (panel, user, clickType, slot) -> { this.pageIndex++; this.build(); @@ -229,7 +229,7 @@ public abstract class CommonGUI { name = this.user.getTranslation("challenges.gui.buttons.previous"); description = Collections.emptyList(); - icon = new ItemStack(Material.SIGN); + icon = new ItemStack(ChallengesAddon.SIGN_MATERIAL); clickHandler = (panel, user, clickType, slot) -> { this.pageIndex--; this.build(); diff --git a/src/main/java/world/bentobox/challenges/panel/admin/EditSettingsGUI.java b/src/main/java/world/bentobox/challenges/panel/admin/EditSettingsGUI.java index 42864e5..e4c46a7 100644 --- a/src/main/java/world/bentobox/challenges/panel/admin/EditSettingsGUI.java +++ b/src/main/java/world/bentobox/challenges/panel/admin/EditSettingsGUI.java @@ -466,7 +466,7 @@ public class EditSettingsGUI extends CommonGUI this.user.getTranslation("challenges.gui.descriptions.enabled") : this.user.getTranslation("challenges.gui.descriptions.disabled"))); name = this.user.getTranslation("challenges.gui.buttons.admin.title-enable"); - icon = new ItemStack(Material.SIGN); + icon = new ItemStack(ChallengesAddon.SIGN_MATERIAL); clickHandler = (panel, user1, clickType, i) -> { this.settings.setShowCompletionTitle(!this.settings.isShowCompletionTitle()); diff --git a/src/main/java/world/bentobox/challenges/panel/user/ChallengesGUI.java b/src/main/java/world/bentobox/challenges/panel/user/ChallengesGUI.java index 29d52ff..c9cbff9 100644 --- a/src/main/java/world/bentobox/challenges/panel/user/ChallengesGUI.java +++ b/src/main/java/world/bentobox/challenges/panel/user/ChallengesGUI.java @@ -162,7 +162,7 @@ public class ChallengesGUI extends CommonGUI if (this.freeChallengeIndex > 0) { panelBuilder.item(index++, new PanelItemBuilder(). - icon(Material.SIGN). + icon(ChallengesAddon.SIGN_MATERIAL). name(this.user.getTranslation("challenges.gui.buttons.previous")). clickHandler((panel, user1, clickType, slot) -> { this.freeChallengeIndex--; @@ -186,7 +186,7 @@ public class ChallengesGUI extends CommonGUI else if (currentIndex < freeChallengesCount) { panelBuilder.item(index, new PanelItemBuilder(). - icon(Material.SIGN). + icon(ChallengesAddon.SIGN_MATERIAL). name(this.user.getTranslation("challenges.gui.buttons.next")). clickHandler((panel, user1, clickType, slot) -> { this.freeChallengeIndex++; @@ -232,7 +232,7 @@ public class ChallengesGUI extends CommonGUI if (this.pageIndex > 0) { panelBuilder.item(index++, new PanelItemBuilder(). - icon(Material.SIGN). + icon(ChallengesAddon.SIGN_MATERIAL). name(this.user.getTranslation("challenges.gui.buttons.previous")). clickHandler((panel, user1, clickType, slot) -> { this.pageIndex--; @@ -256,7 +256,7 @@ public class ChallengesGUI extends CommonGUI else if (currentIndex < challengesCount) { panelBuilder.item(index, new PanelItemBuilder(). - icon(Material.SIGN). + icon(ChallengesAddon.SIGN_MATERIAL). name(this.user.getTranslation("challenges.gui.buttons.next")). clickHandler((panel, user1, clickType, slot) -> { this.pageIndex++; @@ -293,7 +293,7 @@ public class ChallengesGUI extends CommonGUI if (this.levelIndex > 0) { panelBuilder.item(index++, new PanelItemBuilder(). - icon(Material.SIGN). + icon(ChallengesAddon.SIGN_MATERIAL). name(this.user.getTranslation("challenges.gui.buttons.previous")). clickHandler((panel, user1, clickType, slot) -> { this.levelIndex--; @@ -317,7 +317,7 @@ public class ChallengesGUI extends CommonGUI else if (currentIndex < levelCounts) { panelBuilder.item(index, new PanelItemBuilder(). - icon(Material.SIGN). + icon(ChallengesAddon.SIGN_MATERIAL). name(this.user.getTranslation("challenges.gui.buttons.next")). clickHandler((panel, user1, clickType, slot) -> { this.levelIndex++; diff --git a/src/main/java/world/bentobox/challenges/panel/util/SelectBlocksGUI.java b/src/main/java/world/bentobox/challenges/panel/util/SelectBlocksGUI.java index 52a79f2..7bcc51c 100644 --- a/src/main/java/world/bentobox/challenges/panel/util/SelectBlocksGUI.java +++ b/src/main/java/world/bentobox/challenges/panel/util/SelectBlocksGUI.java @@ -11,6 +11,7 @@ import world.bentobox.bentobox.api.panels.PanelItem; import world.bentobox.bentobox.api.panels.builders.PanelBuilder; import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder; import world.bentobox.bentobox.api.user.User; +import world.bentobox.challenges.ChallengesAddon; import world.bentobox.challenges.utils.GuiUtils; @@ -138,7 +139,7 @@ public class SelectBlocksGUI panelBuilder.item(18, new PanelItemBuilder(). - icon(Material.SIGN). + icon(ChallengesAddon.SIGN_MATERIAL). name(this.user.getTranslation("challenges.gui.buttons.previous")). clickHandler((panel, user1, clickType, slot) -> { this.build(correctPage - 1); @@ -147,7 +148,7 @@ public class SelectBlocksGUI panelBuilder.item(26, new PanelItemBuilder(). - icon(Material.SIGN). + icon(ChallengesAddon.SIGN_MATERIAL). name(this.user.getTranslation("challenges.gui.buttons.next")). clickHandler((panel, user1, clickType, slot) -> { this.build(correctPage + 1); diff --git a/src/main/java/world/bentobox/challenges/panel/util/SelectChallengeGUI.java b/src/main/java/world/bentobox/challenges/panel/util/SelectChallengeGUI.java index b348663..3988544 100644 --- a/src/main/java/world/bentobox/challenges/panel/util/SelectChallengeGUI.java +++ b/src/main/java/world/bentobox/challenges/panel/util/SelectChallengeGUI.java @@ -11,6 +11,7 @@ import world.bentobox.bentobox.api.panels.PanelItem; import world.bentobox.bentobox.api.panels.builders.PanelBuilder; import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder; import world.bentobox.bentobox.api.user.User; +import world.bentobox.challenges.ChallengesAddon; import world.bentobox.challenges.database.object.Challenge; import world.bentobox.challenges.utils.GuiUtils; @@ -75,7 +76,7 @@ public class SelectChallengeGUI panelBuilder.item(18, new PanelItemBuilder(). - icon(Material.SIGN). + icon(ChallengesAddon.SIGN_MATERIAL). name(this.user.getTranslation("challenges.gui.buttons.previous")). clickHandler((panel, user1, clickType, slot) -> { this.build(correctPage - 1); @@ -84,7 +85,7 @@ public class SelectChallengeGUI panelBuilder.item(26, new PanelItemBuilder(). - icon(Material.SIGN). + icon(ChallengesAddon.SIGN_MATERIAL). name(this.user.getTranslation("challenges.gui.buttons.next")). clickHandler((panel, user1, clickType, slot) -> { this.build(correctPage + 1); diff --git a/src/main/java/world/bentobox/challenges/panel/util/SelectEntityGUI.java b/src/main/java/world/bentobox/challenges/panel/util/SelectEntityGUI.java index 4cf2a72..27ef404 100644 --- a/src/main/java/world/bentobox/challenges/panel/util/SelectEntityGUI.java +++ b/src/main/java/world/bentobox/challenges/panel/util/SelectEntityGUI.java @@ -12,6 +12,7 @@ import world.bentobox.bentobox.api.panels.PanelItem; import world.bentobox.bentobox.api.panels.builders.PanelBuilder; import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder; import world.bentobox.bentobox.api.user.User; +import world.bentobox.challenges.ChallengesAddon; import world.bentobox.challenges.utils.GuiUtils; @@ -114,7 +115,7 @@ public class SelectEntityGUI panelBuilder.item(18, new PanelItemBuilder(). - icon(Material.SIGN). + icon(ChallengesAddon.SIGN_MATERIAL). name(this.user.getTranslation("challenges.gui.buttons.previous")). clickHandler((panel, user1, clickType, slot) -> { this.build(correctPage - 1); @@ -123,7 +124,7 @@ public class SelectEntityGUI panelBuilder.item(26, new PanelItemBuilder(). - icon(Material.SIGN). + icon(ChallengesAddon.SIGN_MATERIAL). name(this.user.getTranslation("challenges.gui.buttons.next")). clickHandler((panel, user1, clickType, slot) -> { this.build(correctPage + 1); From deab2d3530485aeac92a0882486f559da7fb4a2c Mon Sep 17 00:00:00 2001 From: BONNe Date: Fri, 24 May 2019 09:39:40 +0300 Subject: [PATCH 10/18] Fix failing Tests. These tests failed because in I added Server version check in ChallengesAddon class. --- .../bentobox/challenges/tasks/TryToCompleteTest.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/test/java/world/bentobox/challenges/tasks/TryToCompleteTest.java b/src/test/java/world/bentobox/challenges/tasks/TryToCompleteTest.java index b60aff7..083b699 100644 --- a/src/test/java/world/bentobox/challenges/tasks/TryToCompleteTest.java +++ b/src/test/java/world/bentobox/challenges/tasks/TryToCompleteTest.java @@ -56,6 +56,11 @@ public class TryToCompleteTest { */ @Before public void setUp() throws Exception { + Server server = mock(Server.class); + PowerMockito.mockStatic(Bukkit.class); + when(Bukkit.getServer()).thenReturn(server); + when(Bukkit.getBukkitVersion()).thenReturn("1.13.2"); + user = mock(User.class); inv = mock(PlayerInventory.class); when(inv.getContents()).thenReturn(stacks); @@ -63,7 +68,6 @@ public class TryToCompleteTest { addon = mock(ChallengesAddon.class); required = new ArrayList<>(); - Server server = mock(Server.class); ItemFactory itemFactory = mock(ItemFactory.class); when(server.getItemFactory()).thenReturn(itemFactory); @@ -71,9 +75,6 @@ public class TryToCompleteTest { when(itemFactory.getItemMeta(any())).thenReturn(null); when(itemFactory.equals(null, null)).thenReturn(true); - PowerMockito.mockStatic(Bukkit.class); - when(Bukkit.getServer()).thenReturn(server); - when(Bukkit.getItemFactory()).thenReturn(itemFactory); when(Bukkit.getLogger()).thenReturn(Logger.getAnonymousLogger()); } From 66351b577694075e9aaad722738508fd2d3d3496 Mon Sep 17 00:00:00 2001 From: BONNe1704 Date: Tue, 28 May 2019 16:04:07 +0300 Subject: [PATCH 11/18] Replace org.spigotmc.spigot to org.bukkit.craftbukkit dependency for Mojang Account shadowing. Spigot close their server-side code. --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 83e0e4c..e20c3d4 100644 --- a/pom.xml +++ b/pom.xml @@ -120,8 +120,8 @@ provided - org.spigotmc - spigot + org.bukkit + craftbukkit ${spigot.version} provided From 6a7b26afc005904938dbe0549f67f68e7738a265 Mon Sep 17 00:00:00 2001 From: BONNe1704 Date: Tue, 28 May 2019 16:37:16 +0300 Subject: [PATCH 12/18] Add missing Spigot Group Repository. --- pom.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pom.xml b/pom.xml index e20c3d4..15e7009 100644 --- a/pom.xml +++ b/pom.xml @@ -93,6 +93,10 @@ spigot-repo https://hub.spigotmc.org/nexus/content/repositories/snapshots + + spigotmc-public + https://hub.spigotmc.org/nexus/content/groups/public/ + codemc-repo https://repo.codemc.org/repository/maven-public/ From 7914f315f4a5a0a4b1e8d252bfdebc2e98279a94 Mon Sep 17 00:00:00 2001 From: BONNe Date: Tue, 28 May 2019 20:18:29 +0300 Subject: [PATCH 13/18] Use codemc-nms repo. --- pom.xml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 15e7009..67c366b 100644 --- a/pom.xml +++ b/pom.xml @@ -101,6 +101,10 @@ codemc-repo https://repo.codemc.org/repository/maven-public/ + + codemc-nms + https://repo.codemc.org/repository/nms/ + @@ -124,8 +128,8 @@ provided - org.bukkit - craftbukkit + org.spigotmc + spigot ${spigot.version} provided From a9abe32dbe6f9c69d32badc92af51582caea83aa Mon Sep 17 00:00:00 2001 From: BONNe Date: Mon, 3 Jun 2019 23:14:12 +0300 Subject: [PATCH 14/18] Add a lot null-pointer checks and console errors about loading null-value element from database. --- .../challenges/ChallengesManager.java | 83 +++++++++++++++---- 1 file changed, 68 insertions(+), 15 deletions(-) diff --git a/src/main/java/world/bentobox/challenges/ChallengesManager.java b/src/main/java/world/bentobox/challenges/ChallengesManager.java index c15427f..75b98ae 100644 --- a/src/main/java/world/bentobox/challenges/ChallengesManager.java +++ b/src/main/java/world/bentobox/challenges/ChallengesManager.java @@ -175,7 +175,7 @@ public class ChallengesManager * @param challenge Challenge that must be loaded. * @return true if successful */ - private void loadChallenge(Challenge challenge) + private void loadChallenge(@NonNull Challenge challenge) { this.loadChallenge(challenge, true, null, true); } @@ -190,11 +190,17 @@ public class ChallengesManager * @param silent - if true, no messages are sent to user * @return - true if imported */ - public boolean loadChallenge(Challenge challenge, + public boolean loadChallenge(@NonNull Challenge challenge, boolean overwrite, User user, boolean silent) { + if (challenge == null) + { + this.addon.logError("Tried to load NULL element from Database. One challenge is broken and will not work."); + return false; + } + if (this.challengeCacheData.containsKey(challenge.getUniqueId())) { if (!overwrite) @@ -235,7 +241,7 @@ public class ChallengesManager * * @param level the challenge level */ - private void loadLevel(ChallengeLevel level) + private void loadLevel(@NonNull ChallengeLevel level) { this.loadLevel(level, true, null, true); } @@ -250,8 +256,14 @@ public class ChallengesManager * @param silent of type boolean that indicate if message to user must be sent. * @return boolean that indicate about load status. */ - public boolean loadLevel(ChallengeLevel level, boolean overwrite, User user, boolean silent) + public boolean loadLevel(@NonNull ChallengeLevel level, boolean overwrite, User user, boolean silent) { + if (level == null) + { + this.addon.logError("Tried to load NULL element from Database. One level is broken and will not work."); + return false; + } + if (!this.isValidLevel(level)) { if (user != null) @@ -306,7 +318,7 @@ public class ChallengesManager * This method stores PlayerData into local cache. * @param playerData ChallengesPlayerData that must be loaded. */ - private void loadPlayerData(ChallengesPlayerData playerData) + private void loadPlayerData(@NonNull ChallengesPlayerData playerData) { try { @@ -352,7 +364,7 @@ public class ChallengesManager * @param level that must be validated * @return true ir level is valid, otherwise false. */ - private boolean isValidLevel(ChallengeLevel level) + private boolean isValidLevel(@NonNull ChallengeLevel level) { if (!this.addon.getPlugin().getIWM().inWorld(Bukkit.getWorld(level.getWorld()))) { @@ -369,6 +381,7 @@ public class ChallengesManager } else { + this.addon.logError("Cannot find " + uniqueID + " challenge for " + level.getUniqueId()); return false; } } @@ -398,7 +411,15 @@ public class ChallengesManager // Load player from database ChallengesPlayerData data = this.playersDatabase.loadObject(uniqueID); // Store in cache - this.playerCacheData.put(uniqueID, data); + + if (data != null) + { + this.playerCacheData.put(uniqueID, data); + } + else + { + this.addon.logError("Could not load NULL player data object."); + } } else { @@ -1194,8 +1215,16 @@ public class ChallengesManager if (this.challengeDatabase.objectExists(name)) { Challenge challenge = this.challengeDatabase.loadObject(name); - this.challengeCacheData.put(name, challenge); - return challenge; + + if (challenge != null) + { + this.challengeCacheData.put(name, challenge); + return challenge; + } + else + { + this.addon.logError("Tried to load NULL challenge object!"); + } } } @@ -1221,8 +1250,16 @@ public class ChallengesManager if (this.challengeDatabase.objectExists(name)) { Challenge challenge = this.challengeDatabase.loadObject(name); - this.challengeCacheData.put(name, challenge); - return true; + + if (challenge != null) + { + this.challengeCacheData.put(name, challenge); + return true; + } + else + { + this.addon.logError("Tried to load NULL challenge object!"); + } } } @@ -1342,8 +1379,16 @@ public class ChallengesManager if (this.levelDatabase.objectExists(name)) { ChallengeLevel level = this.levelDatabase.loadObject(name); - this.levelCacheData.put(name, level); - return level; + + if (level != null) + { + this.levelCacheData.put(name, level); + return level; + } + else + { + this.addon.logError("Tried to load NULL level."); + } } } @@ -1369,8 +1414,16 @@ public class ChallengesManager if (this.levelDatabase.objectExists(name)) { ChallengeLevel level = this.levelDatabase.loadObject(name); - this.levelCacheData.put(name, level); - return true; + + if (level != null) + { + this.levelCacheData.put(name, level); + return true; + } + else + { + this.addon.logError("Tried to load NULL level."); + } } } From 94c3fd9fa43a8154a3f9e91bba5c11b6aba2ba29 Mon Sep 17 00:00:00 2001 From: BONNe1704 Date: Wed, 5 Jun 2019 12:30:48 +0300 Subject: [PATCH 15/18] Add Complete Wipe button in AdminGUI that allows to remove all Challenges Addon data from database. This request comes from Discord. It also mention to format DiskDrive to avoid ability to restore database, but it is not implemented yet. Will be implemented in future releases. --- .../challenges/ChallengesManager.java | 54 +++++++++++++++++++ .../bentobox/challenges/panel/CommonGUI.java | 2 + .../challenges/panel/admin/AdminGUI.java | 30 ++++++++++- src/main/resources/locales/en-US.yml | 3 ++ src/main/resources/locales/lv-LV.yml | 3 ++ 5 files changed, 91 insertions(+), 1 deletion(-) diff --git a/src/main/java/world/bentobox/challenges/ChallengesManager.java b/src/main/java/world/bentobox/challenges/ChallengesManager.java index 75b98ae..9a7c54f 100644 --- a/src/main/java/world/bentobox/challenges/ChallengesManager.java +++ b/src/main/java/world/bentobox/challenges/ChallengesManager.java @@ -431,6 +431,60 @@ public class ChallengesManager } } + // --------------------------------------------------------------------- + // Section: Wipe data + // --------------------------------------------------------------------- + + + /** + * This method removes all challenges addon data from Database. + */ + public void wipeDatabase() + { + this.wipeLevels(); + this.wipeChallenges(); + this.wipePlayers(); + } + + + /** + * This method collects all data from levels database and removes them. + * Also clears levels cache data. + */ + private void wipeLevels() + { + List levelList = this.levelDatabase.loadObjects(); + + levelList.forEach(level -> this.levelDatabase.deleteID(level.getUniqueId())); + this.levelCacheData.clear(); + } + + + /** + * This method collects all data from challenges database and removes them. + * Also clears challenges cache data. + */ + private void wipeChallenges() + { + List challengeList = this.challengeDatabase.loadObjects(); + + challengeList.forEach(challenge -> this.challengeDatabase.deleteID(challenge.getUniqueId())); + this.challengeCacheData.clear(); + } + + + /** + * This method collects all data from players database and removes them. + * Also clears players cache data. + */ + private void wipePlayers() + { + List playerDataList = this.playersDatabase.loadObjects(); + + playerDataList.forEach(playerData -> this.playersDatabase.deleteID(playerData.getUniqueId())); + this.playerCacheData.clear(); + } + // --------------------------------------------------------------------- // Section: Saving methods diff --git a/src/main/java/world/bentobox/challenges/panel/CommonGUI.java b/src/main/java/world/bentobox/challenges/panel/CommonGUI.java index 31ccae9..484640a 100644 --- a/src/main/java/world/bentobox/challenges/panel/CommonGUI.java +++ b/src/main/java/world/bentobox/challenges/panel/CommonGUI.java @@ -110,6 +110,8 @@ public abstract class CommonGUI protected static final String DELETE = "delete"; + protected static final String WIPE = "wipe"; + protected static final String EDIT = "edit"; protected static final String ADD = "add"; diff --git a/src/main/java/world/bentobox/challenges/panel/admin/AdminGUI.java b/src/main/java/world/bentobox/challenges/panel/admin/AdminGUI.java index dc9e410..d8b504e 100644 --- a/src/main/java/world/bentobox/challenges/panel/admin/AdminGUI.java +++ b/src/main/java/world/bentobox/challenges/panel/admin/AdminGUI.java @@ -58,7 +58,8 @@ public class AdminGUI extends CommonGUI IMPORT_CHALLENGES, EDIT_SETTINGS, DEFAULT_IMPORT_CHALLENGES, - DEFAULT_EXPORT_CHALLENGES + DEFAULT_EXPORT_CHALLENGES, + COMPLETE_WIPE } @@ -120,6 +121,9 @@ public class AdminGUI extends CommonGUI // Edit Addon Settings panelBuilder.item(16, this.createButton(Button.EDIT_SETTINGS)); + // Button that deletes everything from challenges addon + panelBuilder.item(34, this.createButton(Button.COMPLETE_WIPE)); + panelBuilder.item(44, this.returnButton); panelBuilder.build(); @@ -439,6 +443,30 @@ public class AdminGUI extends CommonGUI break; } + case COMPLETE_WIPE: + { + permissionSuffix = WIPE; + + name = this.user.getTranslation("challenges.gui.buttons.admin.complete-wipe"); + description = this.user.getTranslation("challenges.gui.descriptions.admin.complete-wipe"); + icon = new ItemStack(Material.TNT); + clickHandler = (panel, user, clickType, slot) -> { + new ConfirmationGUI(this.user, value -> { + if (value) + { + this.addon.getChallengesManager().wipeDatabase(); + this.user.sendMessage("challenges.messages.admin.complete-wipe"); + } + + this.build(); + }); + + return true; + }; + glow = false; + + break; + } default: // This should never happen. return null; diff --git a/src/main/resources/locales/en-US.yml b/src/main/resources/locales/en-US.yml index ca2748c..f03991c 100755 --- a/src/main/resources/locales/en-US.yml +++ b/src/main/resources/locales/en-US.yml @@ -148,6 +148,7 @@ challenges: title-showtime: 'Title Show Time' default-import: 'Import Default Challenges' default-export: 'Export Existing Challenges' + complete-wipe: 'Wipe Addon Databases' next: 'Next' previous: 'Previous' return: 'Return' @@ -243,6 +244,7 @@ challenges: title-showtime: 'Allows to modify how long title message will be visible for player.' default-import: 'Allows to import default challenges.' default-export: 'Allows to export existing challenges into defaults.json file.' + complete-wipe: 'Allows to completely clear all challenges addon databases. Includes player data!' current-value: '|&6Current value: [value].' enabled: 'Active' disabled: 'Disabled' @@ -309,6 +311,7 @@ challenges: hit-things: 'Hit things to add them to the list of things required. Right click when done.' you-added: 'You added one [thing] to the challenge' challenge-created: '[challenge]&r created!' + complete-wipe: '&cHope you have backups, as you just empty all Challenges Addon databases!' you-completed-challenge: '&2You completed the [value] &r&2challenge!' you-repeated-challenge: '&2You repeated the [value] &r&2challenge!' you-repeated-challenge-multiple: '&2You repeated the [value] &r&2challenge [count] times!' diff --git a/src/main/resources/locales/lv-LV.yml b/src/main/resources/locales/lv-LV.yml index 8c0faaf..3415b39 100755 --- a/src/main/resources/locales/lv-LV.yml +++ b/src/main/resources/locales/lv-LV.yml @@ -148,6 +148,7 @@ challenges: title-showtime: 'Virsrakta rādīšanas ilgums' default-import: 'Importēt standarta Uzdevumus' default-export: 'Exportēt esošos Uzdevumus' + complete-wipe: 'Iztīrīt datubāzes' next: 'Nākošā' previous: 'Iepriekšējā' return: 'Atgriezties' @@ -243,6 +244,7 @@ challenges: title-showtime: 'Ļauj mainīt cik ilgi virsraksts spēlētājam būs redzams.' default-import: 'Ļauj ielādēt sākotnējos uzdevumus.' default-export: 'Ļauj eksportēt uzdevumus uz defaults.json failu.' + complete-wipe: 'Ļauj pilnībā iztīrīt papildinājuma datubāzes. Ieskaitot spēlētāju datus!' current-value: '|&6Šī brīža vērtība: [value].' enabled: 'Aktīvs' disabled: 'Neaktīvs' @@ -307,6 +309,7 @@ challenges: messages: admin: challenge-created: '[challenge]&r izveidots!' + complete-wipe: '&cCerams, ka tev ir saglabātas rezerves kopijas, jo tu tikko iztīrīji visas šī papildinājuma datubāzes!' you-completed-challenge: '&2Tu izpildīji [value] &r&2uzdevumu!' you-repeated-challenge: '&2Tu atkārtoji [value] &r&2uzdevumu!' you-repeated-challenge-multiple: '&2Tu atkārtoji [value] &r&2uzdevumu [count] reizes!' From daeaafd0b28529757fa719b3ef11ebffd6144b3f Mon Sep 17 00:00:00 2001 From: nivcoo <36514752+nivcoo@users.noreply.github.com> Date: Mon, 10 Jun 2019 13:37:22 +0200 Subject: [PATCH 16/18] Added fr-FR translation (#131) * Update ReadMe. * Remove # symbol from development build name * feat. add FR language * feat. add FR language * feat. add FR language * Added nivcoo to the authors of this locale --- src/main/resources/locales/fr-FR.yml | 371 +++++++++++++++++++++++++++ 1 file changed, 371 insertions(+) create mode 100644 src/main/resources/locales/fr-FR.yml diff --git a/src/main/resources/locales/fr-FR.yml b/src/main/resources/locales/fr-FR.yml new file mode 100644 index 0000000..d1063c1 --- /dev/null +++ b/src/main/resources/locales/fr-FR.yml @@ -0,0 +1,371 @@ +########################################################################################### +# This is a YML file. Be careful when editing. Check your edits in a YAML checker like # +# the one at http://yaml-online-parser.appspot.com # +########################################################################################### + +meta: + authors: + - nivcoo + +challenges: + commands: + admin: + main: + parameters: '' + description: 'Commande principale Admin. Ouverture du menu.' + import: + description: 'Importer les challenges du challenges.yml|Ce paramètre écrasera vos anciens challenges et levels !' + parameters: '[overwrite]' + reload: + description: 'Recharger les challenges depuis la base de données|Le paramètre hard réinitialisera la connexion à la base de données.' + parameters: '[hard]' + show: + description: 'Cette méthode écrira dans le chat tous les challenges du monde.' + parameters: '' + defaults: + description: 'Cette méthode permet d''afficher les sous commandes pour importer/exporter les challenges par défauts.' + parameters: '[command]' + defaults-import: + description: 'Cette méthode permet d''importer les challenges par défauts.' + parameters: '' + defaults-generate: + description: 'Cette méthode permet d''exporter les challenges dans un fichier default.json.' + parameters: '[overwrite] - permet d''écraser le fichier existant.' + user: + main: + description: 'Cette méthode ouvre le menu des Challenges.' + parameters: '' + complete: + description: 'Cette méthode permet de compléter un challenger sans menu.' + parameters: ' [count]' + gui: + title: + admin: + gui-title: '&aMenu admin des Challenges' + edit-challenge-title: '&aModification Challenge' + edit-level-title: '&aModification Niveau' + settings-title: '&aModification Paramètre' + choose-challenge-title: '&aChoix du Challenge' + choose-level-title: '&aChoix du Niveau' + choose-user-title: '&aChoix du Joueur' + manage-blocks: '&aGestion des Blocs' + manage-entities: '&aGestion des Entités' + confirm-title: '&aConfirmation' + manage-items: '&aGestion des Items' + manage-numbers: '&aGestion des chiffres' + select-block: '&aSelection du Bloc' + select-challenge: '&aSelection du Challenge' + select-entity: '&aSelection de l''Entité' + toggle-environment: '&aChanger l''Environnement' + edit-text-fields: '&aModification du Texte' + challenges: '&aListe des challenges' + game-modes: '&aChoisissez votre mode de jeux' + buttons: + admin: + complete: 'Compléter le challenge d''un joueur' + reset: 'Réinitialiser le challenge d''un joueur' + create-challenge: 'Ajouter un nouveau challenge' + create-level: 'Ajouter un nouveau Niveau' + edit-challenge: 'Modifier un Challenge' + edit-level: 'Modifier un Niveau' + delete-challenge: 'Supprimer un Challenge' + delete-level: 'Supprimer un Niveau' + import: 'Importer les Challenges d''ASkyblock' + settings: 'Modifier les paramètres' + properties: 'Propriétés' + requirements: 'Prérequis' + rewards: 'Récompenses' + challenges: 'Challenges' + type: 'Type de Challenge' + deployment: 'Déploiement' + icon: 'Icône' + locked-icon: 'Icône verrouillée' + description: 'Description' + order: 'Ordre' + environment: 'Environnement' + remove-on-complete: 'Supprimer après l''achèvement' + name: 'Nom visible' + required-entities: 'Entités requises' + remove-entities: 'Tuer des entités' + required-blocks: 'Blocs requis' + remove-blocks: 'Supprimer des blocs' + search-radius: 'Rayon de recherche' + required-permissions: 'Permissions requises' + required-items: 'Items requis' + remove-items: 'Supprimer les Items' + required-experience: 'Experience requise' + remove-experience: 'Supprimer de l''expérience' + required-level: 'Niveau d''island requis' + required-money: 'Monnaies requises' + remove-money: 'Supprimer de la monnaies' + reward-text: 'Message de récompense' + reward-items: 'Items gagnés' + reward-experience: 'Expériences gagnées' + reward-money: 'Monnaies gagnées' + reward-commands: 'Commandes gagnées' + repeatable: 'Répétable' + repeat-count: 'Maximum de répétitions' + repeat-reward-text: 'Message de récompense(s) lors d''une répétition' + repeat-reward-items: 'Récompense(s) lors d''une répétition' + repeat-reward-experience: 'Récompense(s) lors d''une répétition' + repeat-reward-money: 'Récompense(s) lors d''une répétition' + repeat-reward-commands: 'Récompense(s) lors d''une répétition' + waiver-amount: 'Montant de la renonciation' + add-challenge: 'Ajouter un Challenge' + remove-challenge: 'Supprimer un Challenge' + reset-on-new: 'Réinitialiser sur nouvelle île' + broadcast: 'Message de l''achèvement' + remove-completed: 'Supprimer après l''achèvement' + glow: 'Brillant lorsque complété' + free-at-top: 'Les premiers challenges gratuits' + line-length: 'Taille des Lores' + toggle-user-list: 'Liste des joueurs' + remove-selected: 'Supprimer la sélection' + add: 'Ajouter' + show-eggs: 'Changer de mode d''affichage' + accept: 'Accepter' + decline: 'Décliner' + save: 'Sauvegarder' + cancel: 'Annuler' + input: 'Champ d''écriture' + value: 'Valeur' + set: '=' + increase: '+' + reduce: '-' + multiply: '*' + clear: 'Vider' + remove-empty: 'Supprimer le vide' + number: '[number]' + level-lore: 'Description du Niveau' + challenge-lore: 'Description du Challenge' + gui-view-mode: 'Afficher tous les Mode de jeux' + gui-mode: 'Menus des Challenges uniquement' + history-store: 'Historique des Challenges' + history-lifespan: 'Durée d''ancienneté de l''historique' + island-store: 'Stockage par île' + default-locked-icon: 'Icône de niveau verrouillé' + input-mode: 'Changer de mode d''entrée' + title-enable: 'Titre d''achèvement' + title-showtime: 'Titre affichant l''heure' + default-import: 'Importer les Challenges par défaut' + default-export: 'Exporter les Challenges existants' + complete-wipe: 'Vider entièrement toute les données' + next: 'Suivant' + previous: 'Précédent' + return: 'Retour' + descriptions: + admin: + save: 'Sauvegarder et retourner au Menus précédent.' + cancel: 'Retourner au Menus précédent. Les changements ne sont pas sauvegardés.' + input: 'Ouvrir l''éditeur de texte.' + set: 'En cliquant sur les chiffres, la valeur devient le chiffre sélectionné.' + increase: 'Augmenter la valeur. En cliquant sur les nombres, vous augmentez la valeur du chiffre sélectionné.' + reduce: 'Réduire la valeur. En cliquant sur les chiffres, vous diminuez la valeur du chiffre sélectionné.' + multiply: 'Multiplier la valeur. En cliquant sur les chiffres, vous multiplier la valeur du chiffre sélectionné.' + import: 'Permet d''importer des challenges ASkyblock.|Un clic droit sur la souris active/désactive l''écrasement des données|Placez le fichier Challenges.yml dans le dossier ./BentoBox/addons/Challenges.' + complete: 'Permet de compléter les Challenges d''un joueur.|Ce joueur ne gagne pas les récompenses.' + reset: 'Permet de réinitialiser les Challenges terminés d''un joueur.|Clic droit activer / désactiver, Réinitialiser toutes les fonctionnalités.' + create-challenge: 'Permet d''ajouter un nouveau Challenge.|Par défaut il est dans la liste des Challenges gratuits.' + create-level: 'Permet d''ajouter un nouveau Niveau.' + edit-challenge: 'Permet de modifier les paramètres du Challenge.' + edit-level: 'Permet de modifier les paramètres du niveau.' + delete-challenge: 'Permet de supprimer un Challenge.' + delete-level: 'Permet de supprimer n''importe quel niveau.' + settings: 'Permet de changer les paramètres d''un Addon.' + properties: 'Permet de modifier les propriétés générales' + requirements: 'Permet de gérer les prérequis' + rewards: 'Permet de modifier les récompenses' + challenges: 'Permet de contrôler le niveau des Challenges (Ajouter / Supprimer).' + deployment: 'Permet aux joueurs de compléter (voir) le Challenge.' + icon-challenge: 'Icône qui sera affichée dans le menu pour ce Challenge.' + icon-level: 'Icône qui sera affichée dans le menu pour ce Niveau.' + locked-icon: 'Icône qui sera affichée dans le menu si le niveau est verrouillé.' + description: 'Permet de modifier la description.' + order: 'Permet de changer le numéro de classification.' + environment: 'Permet de changer l''environnement où le Challenge est effectué.' + type: 'Permet de changer le type de challenge. Chaque type a ses propres prérequis.' + remove-on-complete: 'Permet de supprimer le Challenge dans le menu du joueur une fois celui-ci terminé.' + name-challenge: 'Permet de changer le nom d''affichage du Challenge.' + name-level: 'Permet de changer le nom d''affichage du Niveau.' + required-entities: 'Permet d''ajouter, modifier ou supprimer des entités requises.|Entités:|' + remove-entities: 'Permet de supprimer (tuer) des entités à la fin du Challenge.' + required-blocks: 'Permet d''ajouter, modifier ou supprimer les blocs requis.|Blocs:|' + remove-blocks: 'Permet de supprimer (remplacer par du vide) les blocs à la fin du challenge.' + search-radius: 'Rayon autour de l''emplacement du joueur où les entités et les blocs requis seront recherchés.' + required-permissions: 'Permissions requises pour que le joueur puisse compléter le Challenge.|Permission:' + required-items: 'Objets requis dans l''inventaire du joueur.|Items:' + remove-items: 'Permet de supprimer les objets de l''inventaire du joueur après avoir terminé le Challenge.' + required-experience: 'Permet de définir l''expérience requise pour que le joueur puisse compléter le Challenge.' + remove-experience: 'Permet de supprimer l''expérience requise.' + required-level: 'Permet de définir le niveau d''île requis pour ce challenge.|&cNécessite Level addon.' + required-money: 'Permet de définir l''argent requis sur le compte du joueur.|&cNécessite Vault ou un plugin d''économie.' + remove-money: 'Permet de retirer l''argent requis du compte du joueur.|&cNécessite Vault ou un plugin d''économie.' + reward-text: 'Permet de changer le message qui sera envoyé au joueur après la fin du Challenge.' + reward-items: 'Permet de changer la récompense du premier achèvement.|Items:' + reward-experience: 'Permet de changer la récompense (experience) du premier achèvement.' + reward-money: 'Permet de changer la récompense (monnaie) du premier achèvement.|&cNécessite Vault ou un plugin d''économie.' + reward-commands: 'Permet de changer la récompense (commandes) du premier achèvement.|***Ajouter "[SELF]" signifie que la commande sera exécutée par le joueur. Exemple "/kill"|***Le mot "[player]" sera remplacé par le pseudo du joueur, exemple "/kill [player]" sera remplacé par "/kill BONNe1704"|Commands:' + repeatable: 'Permet de définir si le Challenge est répétable.' + repeat-count: 'Permet de définir le nombre maximal de répétitions. Si la valeur est définie sur 0 ou moins, il n''y a pas de limitation.' + repeat-reward-text: 'Permet de changer le message qui sera envoyé au joueur suite à la répétition du challenge.' + repeat-reward-items: 'Permet de changer les récompenses lors d''une répétition|Items:' + repeat-reward-experience: Permet de changer les récompenses (Expériences) lors d''une répétition' + repeat-reward-money: 'Permet de changer les récompenses (Monnaies) lors d''une répétition|&cNécessite Vault ou un plugin d''économie.' + repeat-reward-commands: 'Permet de changer les récompenses (Commandes) lors d''une répétition|***Ajouter "[SELF]" signifie que la commande sera exécutée par le joueur. Exemple "/kill"|***Le mot "[player]" sera remplacé par le pseudo du joueur, exemple "/kill [player]" sera remplacé par "/kill BONNe1704"|Commands:' + waiver-amount: 'Permet de définir le nombre de Challenges non-obligatoire pour changer de Niveau.' + reward-text-level: 'Permet de changer le message qui sera envoyé au joueur après avoir complété tous les Challenges du Niveau.' + add-challenge: 'Permet d''ajouter un Challenge existant au Niveau actuel.' + remove-challenge: 'Permet de supprimer un Challenge du Niveau actuel.' + reset-on-new: 'Activer/Désactiver, la réinitialisation de tous les challenges du joueur lorsqu''il recommence son île ou qu''il a quitté/été kické de son île.' + broadcast: 'Activer/Désactiver le message global lorsqu''un joueur complète pour la première fois un Challenge.' + remove-completed: 'Activer/Désactiver que les challenges complété et non répétable soit cachés.' + glow: 'Activer/Désactiver l''effet de brillance sur un Challenge complété.' + free-at-top: 'Permet de changer l''emplacement des Challenges gratuits. “True” signifie que les Challenges seront les premiers, sinon ils seront les derniers.' + line-length: 'Permet de modifier la longueur maximale (ligne) de la description de l''objet. N''affectera pas les objets stockés.' + toggle-user-list: 'Basculer vers une liste de joueurs différente.' + mode-online: 'Joueurs actuellement en ligne.' + mode-in-world: 'Les joueurs qui sont dans le monde GameMode.' + mode-with-island: 'Les joueurs qui ont une île dans GameMode.' + selected: 'Sélectionné' + remove-selected: 'Supprimer les éléments sélectionnés.|Vous pouvez sélectionner des éléments avec le bouton droit de la souris.' + show-eggs: 'Basculer la vue d''entité entre le mode Egg ou le mode Head.' + level-lore: 'Permet de modifier quels éléments de la description du Niveau qui doivent être visibles.' + challenge-lore: 'Permet de modifier quels éléments de la description du Challenge qui doivent être visibles.' + gui-view-mode: 'Permet de définir si le menu du /challenges doit montrer les modes de jeu ou les challenges dans le monde des joueurs.' + history-store: 'Permet d''activer / désactiver le stockage de l''historique des Challenges.' + history-lifespan: 'Permet de modifier le nombre de jours d''enregistrement de l''historique.|0 signifie pour toujours.' + island-store: 'Permet d''activer / désactiver les données stockés des Challenges par île. Cela signifie que les challenges seront les mêmes pour toute l''équipe, si cela est activé.|Cela ne convertira PAS les données au clic. LES PROGRÈS SERONT PERDUS.' + default-locked-icon: 'Permet de changer l''icône de niveau verrouillé par défaut.|Cette option peut être enlevé par chaque niveau.' + gui-mode: 'Permet d''activer / désactiver le menu de Challenge seul|&2Nécessite un redémarrage du serveur.' + click-to-edit: '&4Cliquez ici pour modifier l''entrée.' + edit-text-line: '&6Modifier le message du texte !' + add-text-line: '&6 Ajouter un nouveau message !' + input-mode: 'Basculer entre les modes, chat et enclume (menu).' + title-enable: 'Permet d''activer / désactiver le message de titre qui sera affiché lorsque le joueur aura terminé son challenge.' + title-showtime: 'Permet de modifier la longueur du message que le joueur pourra voir.' + default-import: 'Permet d''importer des challenges par défaut.' + default-export: 'Permet d''exporter les Challenges dans le fichier defaults.json.' + complete-wipe: 'Permet d''effacer complètement toutes les données des Challenges. Inclut les données du joueur!' + current-value: '|&6Valeur actuelle: [value].' + enabled: 'Activé' + disabled: 'Désactivé' + type: + island: '- Type, île:| (permet d''obliger le joueur à avoir certains blocs/mobs autour de lui)' + inventory: '- Type, inventaire:| (permet d''obliger le joueur d''avoir certain items dans son inventaire)' + other: '- Autre type:| (permet d''obliger autre chose depuis d''autres plugins/addons)' + the-end: '- The End' + nether: '- Nether' + normal: '- Overworld' + entity: '- [entity] : [count]' + block: '- [block] : [count]' + permission: '- [permission]' + item: '- [count] x [item]' + item-meta: ' ([meta])' + item-enchant: ' - [enchant] [level]' + command: '- [command]' + level-unlocked: '&fCliquez pour regarder les challenges : [level]' + level-locked: '&fComplétez [count] challenges [level] pour débloquer ce niveau !' + challenge-description: + level: '&fNiveau: [level]' + completed: '&bCompletés' + completed-times-of: 'Complété [donetimes]/[maxtimes] fois' + maxed-reached: 'Complété [donetimes]/[maxtimes] fois' + completed-times: 'Complété [donetimes] fois' + warning-items-take: '&cLes objets requis seront enlevés de votre inventaire !' + objects-close-by: '&cTous les blocs et entités requis doivent être proches de vous sur votre île !' + warning-entities-kill: '&cToutes les entités requises seront tuées lorsque vous aurez terminé ce Challenge !' + warning-blocks-remove: '&cTous les blocs requis seront supprimés lorsque vous aurez terminé ce Challenge. !' + not-repeatable: '&cCe challenge n''est pas répétable !' + experience-reward: '&6Récompense en XP: [value]' + money-reward: '&6Récompense: [value]$' + required-experience: '&6XP requis: [value]' + required-money: '&6Monnaie requise: [value]$' + required-island-level: '&6Niveau d''île requis: [value]' + environment: 'Environement requis:' + reward-items: '&6Récompenses:' + reward-commands: '&6Récompenses (commandes):' + required-items: 'Items requis:' + required-entities: 'Entitiés requises:' + required-blocks: 'Blocs requis:' + level-description: + completed: '&BComplété' + completed-challenges-of: '&3Vous avez complété [number] sur [max] Challenges dans ce niveau.' + waver-amount: '&6Vous pouvez sauter [value] de ce Challenge pour débloquer le niveau suivant.' + experience-reward: '&6Récompense en XP: [value]' + money-reward: '&6Récompense: [value]$' + reward-items: '&6Récompenses:' + reward-commands: '&6Récompenses (commandes):' + titles: +# Title and subtitle my contain variable in [] that will be replaced with proper message from challenge object. +# [friendlyName] will be replaced with challenge friendly name. +# [level] will be replaced with level friendly name. +# [rewardText] will be replaced with challenge reward text. + challenge-title: 'Complété avec succès' + challenge-subtitle: '[friendlyName]' +# Title and subtitle my contain variable in [] that will be replaced with proper message from level object. +# [friendlyName] will be replaced with level friendly name. +# [rewardText] will be replaced with level reward text. + level-title: 'Complété avec succès' + level-subtitle: '[friendlyName]' + messages: + admin: + hit-things: 'Taper des choses pour les ajouter à la liste des choses requises. Faites un clic droit lorsque vous avez terminé.' + you-added: 'Vous avez ajouter [thing] dans le challenge' + challenge-created: '[challenge]&r crée !' + complete-wipe: '&cJ''espère que vous aurez des sauvegardes, car vous venez de vider toutes les données !' + you-completed-challenge: '&2Vous avez complété le challenge: [value] !' + you-repeated-challenge: '&2Vous avez répété le challenge: [value] !' + you-repeated-challenge-multiple: '&2Vous avez répété le challenge: [value] &r&2 [count] fois !' + you-completed-level: '&2Vous avez complété le niveau: [value] !' + name-has-completed-challenge: '&5[name] a complété le challenge: [value] !' + name-has-completed-level: '&5[name] a complété le niveau: [value] !' + import-levels: 'Importer les Niveau' + import-challenges: 'Importer les Challenges' + no-levels: 'Attention: Aucun niveau est défini dans le fichier challenges.yml' + import-number: '[number] Challenges ont été importés' + load-skipping: '"[value]" existe déjà - ignoré' + load-overwriting: 'Écrasement "[value]"' + load-add: 'Ajout d''un nouveau objet: [value]' + defaults-file-overwrite: 'defaults.json existe. Il sera écrasé.' + defaults-file-completed: 'defaults.json file est rempli de challenges dans [world] !' + errors: + no-name: '&cNom du Challenge manquant' + unknown-challenge: '&cChallenge inconnu' + unique-id: '&cL''UniqueID "[id]" n''est pas valide.' + wrong-icon: '&cLe matériau "[value]" n''est pas valide et ne peut pas être utilisé comme un icône.' + not-valid-integer: '&cLa valeur "[value]" n''est pas valide !|Elle doit être comprise entre [min] et [max].' + not-a-integer: '&cLa valeur "[value]" n''est pas un entier!' + not-deployed: '&cLe Challenge ne peut pas être réalisé !' + not-on-island: '&cVous devez être sur votre île pour faire le Challenge !' + challenge-level-not-available: '&cVous n''avez pas débloqué le niveau pour compléter ce Challenge.' + not-repeatable: '&cCe Challenge n''est pas répétable !' + wrong-environment: '&cVous êtes dans le mauvais environnement !' + not-enough-items: '&cVous n''avez pas assez [items] pour relever ce Challenge !' + not-close-enough: '&cVous devez vous tenir dans un rayon de [number] blocs autour de tous les éléments requis.' + you-still-need: '&cTu as encore besoin [amount] [item]' + missing-addon: '&cImpossible de terminer le Challenge. L''addon ou le plugin requis est manquant.' + incorrect: '&cImpossible de compléter le challenge. Les nécessités sont incorrects' + not-enough-money: '&cIl est nécéssaire d''avoir [value] sur votre compte pour compléter le challenge.' + not-enough-experience: '&cIl est nécessaire d''avoir [value] XP pour compléter le challenge.' + island-level: '&cVotre île doit être niveau [number] pour compléter le challenge.' + import-no-file: '&cLe fichier challenges.yml n''a pas été trouvé !' + no-load: '&cErreur: Impossible de charger le fichier challenges.yml. [message]' + load-error: '&cErreur: Impossible de charger [value].' + no-rank: "&cVous n''avez pas le rang pour le faire." + cannot-remove-items: '&cCertains items ne peuvent pas être supprimer de votre inventaire !' + exist-challenges-or-levels: '&cDans votre monde il existe déjà des challenges. Impossible de continuer !' + defaults-file-exist: '&cdefaults.json existe déja. Utilisez le mode écrasement pour le remplacer !' + defaults-file-error: '&cIl y a une erreur lors de la création du fichier defaults.json ! Regardez la console !' + no-challenges: '&cLes challenges ne sont pas actifs dans le monde actuel !' + no-challenges-admin: '&cLes Challenges ne sont pas actifs dans le monde actuel ! Vous devez utiliser &5/[label] Challenges &cpour ajouter cela !' + missing-level: '&cLe Niveau du Challenge [niveau] n''est pas défini dans la base de données. Il peut y avoir des erreurs !' +protection: + flags: + CHALLENGES_ISLAND_PROTECTION: + description: "&5&oChange qui peut\n&5&ocompléter les Challenges" + name: "Protection de Challenge" + CHALLENGES_WORLD_PROTECTION: + description: "&5&oCela permet d''activer / désactiver\n&5&oles prérequis pour les joueurs de\n&5&oqui doivent être sur leur île pour\n&5&ocompléter le Challenge." + name: "Limite de Challenge sur l''île " + hint: "Aucun Challenge en dehors de l''île" +version: 11 From fc4f3ca0b68fdb4c661ae832e4846291d648982a Mon Sep 17 00:00:00 2001 From: BONNe Date: Wed, 12 Jun 2019 22:56:52 +0300 Subject: [PATCH 17/18] Add AutoSaver task for Challenges Addon. Remove WorldSave event listener. --- .../bentobox/challenges/ChallengesAddon.java | 10 +++++++ .../world/bentobox/challenges/Settings.java | 27 +++++++++++++++++++ .../challenges/listeners/SaveListener.java | 15 ----------- src/main/resources/config.yml | 4 +++ 4 files changed, 41 insertions(+), 15 deletions(-) diff --git a/src/main/java/world/bentobox/challenges/ChallengesAddon.java b/src/main/java/world/bentobox/challenges/ChallengesAddon.java index 0735838..59d3a38 100644 --- a/src/main/java/world/bentobox/challenges/ChallengesAddon.java +++ b/src/main/java/world/bentobox/challenges/ChallengesAddon.java @@ -220,6 +220,16 @@ public class ChallengesAddon extends Addon { this.registerRequestHandler(new LevelDataRequestHandler(this)); this.registerRequestHandler(new CompletedChallengesRequestHandler(this)); + + if (this.settings.getAutoSaveTimer() > 0) + { + this.getPlugin().getServer().getScheduler().runTaskTimerAsynchronously( + this.getPlugin(), + bukkitTask -> ChallengesAddon.this.challengesManager.save(), + this.settings.getAutoSaveTimer() * 60 * 20, + this.settings.getAutoSaveTimer() * 60 * 20 + ); + } } else { this.logError("Challenges could not hook into AcidIsland or BSkyBlock so will not do anything!"); this.setState(State.DISABLED); diff --git a/src/main/java/world/bentobox/challenges/Settings.java b/src/main/java/world/bentobox/challenges/Settings.java index e5818a3..a1a5ccd 100644 --- a/src/main/java/world/bentobox/challenges/Settings.java +++ b/src/main/java/world/bentobox/challenges/Settings.java @@ -155,6 +155,12 @@ public class Settings implements ConfigObject @ConfigEntry(path = "title.title-showtime") private int titleShowtime = 70; + @ConfigComment("") + @ConfigComment("Long that represents how frequently (in minutes) challenges addon will save data to database.") + @ConfigComment("If this is set to 0, saving will not happen.") + @ConfigEntry(path = "auto-saver") + private long autoSaveTimer = 30; + @ConfigComment("") @ConfigComment("This list stores GameModes in which Challenges addon should not work.") @ConfigComment("To disable addon it is necessary to write its name in new line that starts with -. Example:") @@ -369,6 +375,27 @@ public class Settings implements ConfigObject } + /** + * This method returns the autoSaveTimer object. + * @return the autoSaveTimer object. + */ + public long getAutoSaveTimer() + { + return autoSaveTimer; + } + + + /** + * This method sets the autoSaveTimer object value. + * @param autoSaveTimer the autoSaveTimer object new value. + * + */ + public void setAutoSaveTimer(long autoSaveTimer) + { + this.autoSaveTimer = autoSaveTimer; + } + + /** * This method sets the titleShowtime object value. * @param titleShowtime the titleShowtime object new value. diff --git a/src/main/java/world/bentobox/challenges/listeners/SaveListener.java b/src/main/java/world/bentobox/challenges/listeners/SaveListener.java index cebf22b..ccb043a 100644 --- a/src/main/java/world/bentobox/challenges/listeners/SaveListener.java +++ b/src/main/java/world/bentobox/challenges/listeners/SaveListener.java @@ -22,21 +22,6 @@ public class SaveListener implements Listener } - /** - * This event listener handles world save event. - * @param e World Save event. - */ - @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) - public void onWorldSave(WorldSaveEvent e) - { - // Save only for worlds where exist any challenge addon data. - if (this.addon.getChallengesManager().hasAnyChallengeData(e.getWorld())) - { - this.addon.getChallengesManager().save(); - } - } - - /** * This event listener handles player kick event. * If player is kicked, then remove it from player cache data. diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 6056a2b..fb4b81c 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -109,6 +109,10 @@ title: # Integer that represents how long title will be visible for player. title-showtime: 70 # +# Long that represents how frequently (in minutes) challenges addon will save data to database. +# If this is set to 0, saving will not happen. +auto-saver: 30 +# # This list stores GameModes in which Challenges addon should not work. # To disable addon it is necessary to write its name in new line that starts with -. Example: # disabled-gamemodes: From 64f04829bdc411036d816b6c6c85195de6dc050f Mon Sep 17 00:00:00 2001 From: BONNe Date: Wed, 12 Jun 2019 22:59:38 +0300 Subject: [PATCH 18/18] Update to BentoBox 1.5.0 release version. --- pom.xml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 67c366b..d2f0242 100644 --- a/pom.xml +++ b/pom.xml @@ -36,7 +36,7 @@ 1.7.4 1.13.2-R0.1-SNAPSHOT - 1.5.0-SNAPSHOT + 1.5.0 1.4.0 68f14ec @@ -177,6 +177,14 @@ + + + + + + + ${project.name}-${revision}${build.number} + clean package