diff --git a/build.gradle b/build.gradle index 1b7b638..499458a 100644 --- a/build.gradle +++ b/build.gradle @@ -27,7 +27,6 @@ allprojects { repositories { mavenCentral() - mavenLocal() maven { url 'https://jitpack.io' } maven { url 'https://hub.spigotmc.org/nexus/content/repositories/snapshots/' } } @@ -41,8 +40,8 @@ allprojects { } dependencies { - compileOnly 'com.willfp:eco:6.34.0' - implementation 'com.willfp:libreforge:3.36.0' + compileOnly 'com.willfp:eco:6.35.1' + implementation 'com.willfp:libreforge:3.38.0' compileOnly 'org.jetbrains:annotations:23.0.0' diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/boosters/BoosterUtils.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/boosters/BoosterUtils.kt index 3247335..203572d 100644 --- a/eco-core/core-plugin/src/main/kotlin/com/willfp/boosters/BoosterUtils.kt +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/boosters/BoosterUtils.kt @@ -5,6 +5,7 @@ package com.willfp.boosters import com.willfp.boosters.boosters.ActivatedBooster import com.willfp.boosters.boosters.Booster import com.willfp.boosters.boosters.Boosters +import com.willfp.boosters.boosters.addActiveBooster import com.willfp.eco.core.data.ServerProfile import com.willfp.eco.core.data.profile import org.bukkit.Bukkit @@ -12,14 +13,12 @@ import org.bukkit.OfflinePlayer import org.bukkit.Sound import org.bukkit.entity.Player -private val plugin = BoostersPlugin.instance - val OfflinePlayer.boosters: List get() { val found = mutableListOf() for (booster in Boosters.values()) { - val amount = this.profile.read(booster.dataKey) + val amount = this.profile.read(booster.ownedDataKey) for (i in 0 until amount) { found.add(booster) } @@ -29,11 +28,11 @@ val OfflinePlayer.boosters: List } fun OfflinePlayer.getAmountOfBooster(booster: Booster): Int { - return this.profile.read(booster.dataKey) + return this.profile.read(booster.ownedDataKey) } fun OfflinePlayer.setAmountOfBooster(booster: Booster, amount: Int) { - this.profile.write(booster.dataKey, amount) + this.profile.write(booster.ownedDataKey, amount) } fun OfflinePlayer.incrementBoosters(booster: Booster, amount: Int) { @@ -53,12 +52,26 @@ fun Player.activateBooster(booster: Booster): Boolean { Bukkit.broadcastMessage(activationMessage) } + for (expiryCommand in booster.activationCommands) { + Bukkit.dispatchCommand( + Bukkit.getConsoleSender(), + expiryCommand.replace("%player%", booster.active?.player?.name ?: "") + ) + } + ServerProfile.load().write( - plugin.expiryTimeKey, + booster.expiryTimeKey, (booster.duration.toDouble() * 50) + System.currentTimeMillis() ) - plugin.activeBooster = ActivatedBooster(booster, this.uniqueId) + ServerProfile.load().write( + booster.activeDataKey, + this.uniqueId.toString() + ) + + Bukkit.getServer().addActiveBooster( + ActivatedBooster(booster, this.uniqueId) + ) for (player in Bukkit.getOnlinePlayers()) { player.playSound( diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/boosters/BoostersPlugin.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/boosters/BoostersPlugin.kt index c5ea6f6..3d593b9 100644 --- a/eco-core/core-plugin/src/main/kotlin/com/willfp/boosters/BoostersPlugin.kt +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/boosters/BoostersPlugin.kt @@ -1,13 +1,12 @@ package com.willfp.boosters -import com.willfp.boosters.boosters.ActivatedBooster import com.willfp.boosters.boosters.Boosters +import com.willfp.boosters.boosters.activeBoosters +import com.willfp.boosters.boosters.expireBooster import com.willfp.boosters.commands.CommandBoosters import com.willfp.boosters.config.BoostersYml import com.willfp.eco.core.command.impl.PluginCommand import com.willfp.eco.core.data.ServerProfile -import com.willfp.eco.core.data.keys.PersistentDataKey -import com.willfp.eco.core.data.keys.PersistentDataKeyType import com.willfp.eco.core.data.profile import com.willfp.eco.core.integrations.placeholder.PlaceholderManager import com.willfp.eco.core.placeholder.PlayerlessPlaceholder @@ -16,153 +15,36 @@ import com.willfp.eco.util.savedDisplayName import com.willfp.libreforge.LibReforgePlugin import org.bukkit.Bukkit import org.bukkit.event.Listener -import java.util.UUID import kotlin.math.floor class BoostersPlugin : LibReforgePlugin(2036, 14269, "&e") { val boostersYml = BoostersYml(this) - private val boosterKey = PersistentDataKey( - this.namespacedKeyFactory.create("active_booster"), - PersistentDataKeyType.STRING, - "" - ).server() - - val expiryTimeKey = PersistentDataKey( - this.namespacedKeyFactory.create("expiry_time"), - PersistentDataKeyType.DOUBLE, - 0.0 - ).server() - - var activeBooster: ActivatedBooster? - get() { - val key = Bukkit.getServer().profile.read(boosterKey) - - return if (key.isEmpty()) { - null - } else { - val booster = key.split("::") - val id = booster[0] - val uuid = UUID.fromString(booster[1]) - ActivatedBooster( - Boosters.getByID(id) ?: return null, - uuid - ) - } - } - set(value) { - if (value == null) { - Bukkit.getServer().profile.write(boosterKey, "") - } else { - Bukkit.getServer().profile.write(boosterKey, "${value.booster.id}::${value.player.uniqueId}") - } - } - - private val secondsLeft: Int - get() { - val endTime = ServerProfile.load().read(expiryTimeKey) - val currentTime = System.currentTimeMillis() - return if (endTime < currentTime || activeBooster == null) { - 0 - } else { - ((endTime - currentTime) / 1000).toInt() - } - } - override fun handleEnableAdditional() { - PlaceholderManager.registerPlaceholder( - PlayerlessPlaceholder( - this, - "booster_info" - ) { - val booster = activeBooster - - if (booster == null) { - return@PlayerlessPlaceholder this.langYml.getString("no-currently-active") - .formatEco(formatPlaceholders = false) - } else { - return@PlayerlessPlaceholder this.langYml.getString("active-placeholder") - .replace("%player%", booster.player.savedDisplayName) - .replace("%booster%", booster.booster.name) - .formatEco(formatPlaceholders = false) - } - } - ) - - PlaceholderManager.registerPlaceholder( - PlayerlessPlaceholder( - this, - "active", - ) { - activeBooster?.booster?.id ?: "" - } - ) - - PlaceholderManager.registerPlaceholder( - PlayerlessPlaceholder( - this, - "active_name" - ) { - activeBooster?.booster?.name ?: "" - } - ) - - PlaceholderManager.registerPlaceholder( - PlayerlessPlaceholder( - this, - "active_player", - ) { - activeBooster?.player?.savedDisplayName ?: "" - } - ) - - PlaceholderManager.registerPlaceholder( - PlayerlessPlaceholder( - this, - "seconds_remaining" - ) { - secondsLeft.toString() - } - ) - - PlaceholderManager.registerPlaceholder( - PlayerlessPlaceholder( - this, - "time_remaining" - ) { - if (secondsLeft <= 0) { - return@PlayerlessPlaceholder "00:00:00" - } - - // if you've seen this code on the internet, no you haven't. shush - val seconds = secondsLeft % 3600 % 60 - val minutes = floor(secondsLeft % 3600 / 60.0).toInt() - val hours = floor(secondsLeft / 3600.0).toInt() - - val hh = (if (hours < 10) "0" else "") + hours - val mm = (if (minutes < 10) "0" else "") + minutes - val ss = (if (seconds < 10) "0" else "") + seconds - - "${hh}:${mm}:${ss}" - } - ) - - this.registerHolderProvider { - activeBooster.let { - if (it == null) emptyList() else listOf(it.booster) - } - } + this.registerHolderProvider { Bukkit.getServer().activeBoosters.map { it.booster } } } override fun handleReloadAdditional() { this.scheduler.runTimer(1, 1) { - val booster = activeBooster ?: return@runTimer - val endTime = ServerProfile.load().read(expiryTimeKey) - if (endTime <= System.currentTimeMillis()) { - for (expiryMessage in booster.booster.expiryMessages) { - Bukkit.broadcastMessage(expiryMessage) + for (booster in Boosters.values()) { + if (booster.active == null) { + continue + } + + if (booster.secondsLeft <= 0) { + for (expiryMessage in booster.expiryMessages) { + Bukkit.broadcastMessage(expiryMessage) + } + + for (expiryCommand in booster.expiryCommands) { + Bukkit.dispatchCommand( + Bukkit.getConsoleSender(), + expiryCommand.replace("%player%", booster.active?.player?.name ?: "") + ) + } + + Bukkit.getServer().expireBooster(booster) } - activeBooster = null } } } @@ -180,7 +62,7 @@ class BoostersPlugin : LibReforgePlugin(2036, 14269, "&e") { } override fun getMinimumEcoVersion(): String { - return "6.24.0" + return "6.35.1" } init { diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/boosters/boosters/ActivatedBooster.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/boosters/boosters/ActivatedBooster.kt new file mode 100644 index 0000000..6d7d5cc --- /dev/null +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/boosters/boosters/ActivatedBooster.kt @@ -0,0 +1,47 @@ +@file:Suppress("unused") + +package com.willfp.boosters.boosters + +import com.willfp.eco.core.data.ServerProfile +import org.bukkit.Bukkit +import org.bukkit.OfflinePlayer +import org.bukkit.Server +import java.util.* + +private val boosters = mutableSetOf() + +fun Server.addActiveBooster(activatedBooster: ActivatedBooster) { + boosters += activatedBooster +} + +val Server.activeBoosters: Set + get() = boosters.toSet() + +fun Server.expireBooster(booster: Booster) { + boosters.removeIf { it.booster == booster } + + ServerProfile.load().write( + booster.activeDataKey, + "" + ) +} + +data class ActivatedBooster( + val booster: Booster, + private val uuid: UUID +) { + val player: OfflinePlayer + get() = Bukkit.getOfflinePlayer(uuid) + + override fun equals(other: Any?): Boolean { + if (other !is ActivatedBooster) { + return false + } + + return other.booster == this.booster + } + + override fun hashCode(): Int { + return Objects.hash(this.booster) + } +} diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/boosters/boosters/Booster.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/boosters/boosters/Booster.kt index a02c37f..249076e 100644 --- a/eco-core/core-plugin/src/main/kotlin/com/willfp/boosters/boosters/Booster.kt +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/boosters/boosters/Booster.kt @@ -5,18 +5,22 @@ import com.willfp.boosters.getAmountOfBooster import com.willfp.eco.core.config.interfaces.Config import com.willfp.eco.core.data.keys.PersistentDataKey import com.willfp.eco.core.data.keys.PersistentDataKeyType +import com.willfp.eco.core.data.profile +import com.willfp.eco.core.integrations.placeholder.PlaceholderManager import com.willfp.eco.core.items.Items import com.willfp.eco.core.items.builder.ItemStackBuilder +import com.willfp.eco.core.placeholder.PlayerlessPlaceholder import com.willfp.eco.util.StringUtils import com.willfp.eco.util.formatEco +import com.willfp.eco.util.savedDisplayName import com.willfp.libreforge.Holder import com.willfp.libreforge.conditions.Conditions import com.willfp.libreforge.effects.Effects import org.bukkit.Bukkit -import org.bukkit.OfflinePlayer import org.bukkit.entity.Player import org.bukkit.inventory.ItemStack import java.util.* +import kotlin.math.floor class Booster( private val plugin: BoostersPlugin, @@ -24,12 +28,48 @@ class Booster( ) : Holder { val id = config.getString("id") - val dataKey: PersistentDataKey = PersistentDataKey( + val ownedDataKey: PersistentDataKey = PersistentDataKey( plugin.namespacedKeyFactory.create(id), PersistentDataKeyType.INT, 0 ).player() + val activeDataKey: PersistentDataKey = PersistentDataKey( + plugin.namespacedKeyFactory.create("${id}_active"), + PersistentDataKeyType.STRING, + "" + ).server() + + val expiryTimeKey = PersistentDataKey( + plugin.namespacedKeyFactory.create("${id}_expiry_time"), + PersistentDataKeyType.DOUBLE, + 0.0 + ).server() + + val active: ActivatedBooster? + get() { + val activeKey = Bukkit.getServer().profile.read(activeDataKey) + + if (activeKey.isEmpty()) { + return null + } + + val uuid = UUID.fromString(activeKey) + + return ActivatedBooster(this, uuid) + } + + val secondsLeft: Int + get() { + val endTime = Bukkit.getServer().profile.read(expiryTimeKey) + val currentTime = System.currentTimeMillis() + return if (endTime < currentTime || active == null) { + 0 + } else { + ((endTime - currentTime) / 1000).toInt() + } + } + val name = config.getFormattedString("name") val duration = config.getInt("duration") @@ -49,6 +89,10 @@ class Booster( val expiryMessages: List = config.getFormattedStrings("messages.expiry") + val activationCommands: List = config.getFormattedStrings("commands.activation") + + val expiryCommands: List = config.getFormattedStrings("commands.expiry") + fun getGuiItem(player: Player): ItemStack { return ItemStackBuilder(Items.lookup(config.getString("gui.item"))) .setDisplayName(config.getFormattedString("gui.name")) @@ -74,6 +118,64 @@ class Booster( init { Boosters.addNewBooster(this) + PlaceholderManager.registerPlaceholder( + PlayerlessPlaceholder( + plugin, + "${id}_info" + ) { + val active = this.active + + if (active != null) { + plugin.langYml.getString("active-placeholder") + .replace("%player%", active.player.savedDisplayName) + .replace("%booster%", active.booster.name) + .formatEco(formatPlaceholders = false) + } else { + plugin.langYml.getString("no-currently-active") + .formatEco(formatPlaceholders = false) + } + } + ) + + PlaceholderManager.registerPlaceholder( + PlayerlessPlaceholder( + plugin, + "${id}_player", + ) { + active?.player?.savedDisplayName ?: "" + } + ) + + PlaceholderManager.registerPlaceholder( + PlayerlessPlaceholder( + plugin, + "${id}_seconds_remaining" + ) { + secondsLeft.toString() + } + ) + + PlaceholderManager.registerPlaceholder( + PlayerlessPlaceholder( + plugin, + "${id}_time_remaining" + ) { + if (secondsLeft <= 0) { + return@PlayerlessPlaceholder "00:00:00" + } + + // if you've seen this code on the internet, no you haven't. shush + val seconds = secondsLeft % 3600 % 60 + val minutes = floor(secondsLeft % 3600 / 60.0).toInt() + val hours = floor(secondsLeft / 3600.0).toInt() + + val hh = (if (hours < 10) "0" else "") + hours + val mm = (if (minutes < 10) "0" else "") + minutes + val ss = (if (seconds < 10) "0" else "") + seconds + + "${hh}:${mm}:${ss}" + } + ) } override fun equals(other: Any?): Boolean { @@ -88,11 +190,3 @@ class Booster( return this.id.hashCode() } } - -data class ActivatedBooster( - val booster: Booster, - private val uuid: UUID -) { - val player: OfflinePlayer - get() = Bukkit.getOfflinePlayer(uuid) -} diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/boosters/commands/CommandCancel.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/boosters/commands/CommandCancel.kt index ad14462..1f0bec2 100644 --- a/eco-core/core-plugin/src/main/kotlin/com/willfp/boosters/commands/CommandCancel.kt +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/boosters/commands/CommandCancel.kt @@ -1,8 +1,11 @@ package com.willfp.boosters.commands import com.willfp.boosters.BoostersPlugin +import com.willfp.boosters.boosters.activeBoosters +import com.willfp.boosters.boosters.expireBooster import com.willfp.eco.core.EcoPlugin import com.willfp.eco.core.command.impl.Subcommand +import org.bukkit.Bukkit import org.bukkit.command.CommandSender class CommandCancel(plugin: EcoPlugin) : @@ -14,7 +17,9 @@ class CommandCancel(plugin: EcoPlugin) : ) { override fun onExecute(sender: CommandSender, args: List) { - (plugin as BoostersPlugin).activeBooster = null + for (booster in Bukkit.getServer().activeBoosters) { + Bukkit.getServer().expireBooster(booster.booster) + } sender.sendMessage(plugin.langYml.getMessage("cancelled")) } } diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/boosters/gui/BoosterGUI.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/boosters/gui/BoosterGUI.kt index c424fb3..c0fe807 100644 --- a/eco-core/core-plugin/src/main/kotlin/com/willfp/boosters/gui/BoosterGUI.kt +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/boosters/gui/BoosterGUI.kt @@ -11,7 +11,7 @@ import com.willfp.eco.core.gui.slot import com.willfp.eco.core.gui.slot.FillerMask import com.willfp.eco.core.gui.slot.MaskItems import com.willfp.eco.core.gui.slot.functional.SlotHandler -import com.willfp.libreforge.tryAsPlayer +import com.willfp.eco.util.tryAsPlayer import org.bukkit.Sound import org.bukkit.entity.Player @@ -22,7 +22,7 @@ object BoosterGUI { return SlotHandler { event, _, _ -> val player = event.whoClicked.tryAsPlayer() ?: return@SlotHandler - if (plugin.activeBooster != null) { + if (booster.active != null) { player.sendMessage(plugin.langYml.getMessage("already-active")) player.playSound( player.location, diff --git a/eco-core/core-plugin/src/main/resources/boosters.yml b/eco-core/core-plugin/src/main/resources/boosters.yml index 3e1d39f..66c075d 100644 --- a/eco-core/core-plugin/src/main/resources/boosters.yml +++ b/eco-core/core-plugin/src/main/resources/boosters.yml @@ -7,6 +7,9 @@ boosters: args: multiplier: 1.5 conditions: [] + commands: + activation: [] + expiry: [] messages: activation: - "" @@ -45,6 +48,9 @@ boosters: args: multiplier: 2 conditions: [] + commands: + activation: [] + expiry: [] messages: activation: - "" @@ -83,6 +89,9 @@ boosters: args: multiplier: 2 conditions: [] + commands: + activation: [] + expiry: [] messages: activation: - "" diff --git a/eco-core/core-plugin/src/main/resources/lang.yml b/eco-core/core-plugin/src/main/resources/lang.yml index 06d47c3..6af7acf 100644 --- a/eco-core/core-plugin/src/main/resources/lang.yml +++ b/eco-core/core-plugin/src/main/resources/lang.yml @@ -9,13 +9,13 @@ messages: requires-booster: "&cYou must specify a booster!" invalid-booster: "&cInvalid booster!" gave-booster: "Gave %player% %booster% &fx%amount%!" - already-active: "&cA booster is already active!" + already-active: "&cThis booster is already active!" dont-have: "&cYou don't have any of these boosters! Get some at &astore.ecomc.net" on-cooldown: "&cThis effect is on cooldown! &fTime left: &a%seconds% seconds" cannot-afford: "&cYou can't afford to do this! &fCost: &a$$%cost%" cannot-afford-type: "&cYou can't afford to do this! &fCost: &a%cost% %type%" - cancelled: "Cancelled the active booster" + cancelled: "Cancelled the active boosters" cannot-transmit: "&cYou can't transmit here!" -no-currently-active: "&cThere is no booster currently active!" -active-placeholder: "%player% &fhas activated a %booster%&f!" +no-currently-active: "&cNot Active!" +active-placeholder: "&fThanks %player% &ffor activating %booster%&f!" diff --git a/eco-core/core-plugin/src/main/resources/plugin.yml b/eco-core/core-plugin/src/main/resources/plugin.yml index 16af910..251eaad 100644 --- a/eco-core/core-plugin/src/main/resources/plugin.yml +++ b/eco-core/core-plugin/src/main/resources/plugin.yml @@ -14,8 +14,7 @@ softdepend: - Jobs - mcMMO - Vault - - DeluxeSellwands - - ShopGUIPlus + - EcoArmor commands: boosters: diff --git a/gradle.properties b/gradle.properties index c040962..b68c272 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,2 +1,2 @@ -version = 3.19.0 +version = 4.2.0 plugin-name = Boosters \ No newline at end of file