Merge branch 'Auxilor:master' into master
This commit is contained in:
@@ -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'
|
||||
|
||||
|
||||
@@ -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<Booster>
|
||||
get() {
|
||||
val found = mutableListOf<Booster>()
|
||||
|
||||
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<Booster>
|
||||
}
|
||||
|
||||
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(
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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<ActivatedBooster>()
|
||||
|
||||
fun Server.addActiveBooster(activatedBooster: ActivatedBooster) {
|
||||
boosters += activatedBooster
|
||||
}
|
||||
|
||||
val Server.activeBoosters: Set<ActivatedBooster>
|
||||
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)
|
||||
}
|
||||
}
|
||||
@@ -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<Int> = PersistentDataKey(
|
||||
val ownedDataKey: PersistentDataKey<Int> = PersistentDataKey(
|
||||
plugin.namespacedKeyFactory.create(id),
|
||||
PersistentDataKeyType.INT,
|
||||
0
|
||||
).player()
|
||||
|
||||
val activeDataKey: PersistentDataKey<String> = 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<String> = config.getFormattedStrings("messages.expiry")
|
||||
|
||||
val activationCommands: List<String> = config.getFormattedStrings("commands.activation")
|
||||
|
||||
val expiryCommands: List<String> = 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)
|
||||
}
|
||||
|
||||
@@ -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<String>) {
|
||||
(plugin as BoostersPlugin).activeBooster = null
|
||||
for (booster in Bukkit.getServer().activeBoosters) {
|
||||
Bukkit.getServer().expireBooster(booster.booster)
|
||||
}
|
||||
sender.sendMessage(plugin.langYml.getMessage("cancelled"))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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:
|
||||
- ""
|
||||
|
||||
@@ -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!"
|
||||
|
||||
@@ -14,8 +14,7 @@ softdepend:
|
||||
- Jobs
|
||||
- mcMMO
|
||||
- Vault
|
||||
- DeluxeSellwands
|
||||
- ShopGUIPlus
|
||||
- EcoArmor
|
||||
|
||||
commands:
|
||||
boosters:
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
version = 3.19.0
|
||||
version = 4.2.0
|
||||
plugin-name = Boosters
|
||||
Reference in New Issue
Block a user