diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecocrates/commands/CommandEcoCrates.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecocrates/commands/CommandEcoCrates.kt index 317473f..8df5ad7 100644 --- a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecocrates/commands/CommandEcoCrates.kt +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecocrates/commands/CommandEcoCrates.kt @@ -22,6 +22,7 @@ class CommandEcoCrates(plugin: EcoPlugin) : PluginCommand( .addSubcommand(CommandConvert(plugin)) .addSubcommand(CommandGiveall(plugin)) .addSubcommand(CommandTake(plugin)) + .addSubcommand(CommandGiveoffline(plugin)) } override fun onExecute(sender: CommandSender, args: List) { diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecocrates/commands/CommandGiveoffline.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecocrates/commands/CommandGiveoffline.kt new file mode 100644 index 0000000..efbc90d --- /dev/null +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecocrates/commands/CommandGiveoffline.kt @@ -0,0 +1,116 @@ +package com.willfp.ecocrates.commands + +import com.willfp.eco.core.EcoPlugin +import com.willfp.eco.core.command.impl.Subcommand +import com.willfp.eco.core.drops.DropQueue +import com.willfp.ecocrates.crate.Crate +import com.willfp.ecocrates.crate.Crates +import org.bukkit.Bukkit +import org.bukkit.command.CommandSender +import org.bukkit.entity.Player +import org.bukkit.inventory.ItemStack +import org.bukkit.persistence.PersistentDataType +import org.bukkit.util.StringUtil + +class CommandGiveoffline(plugin: EcoPlugin) : Subcommand( + plugin, + "giveoffline", + "ecocrates.command.giveoffline", + false +) { + override fun onExecute(sender: CommandSender, args: List) { + if (args.size < 1) { + sender.sendMessage("must-specify-crate") + return + } + + val crate = Crates.getByID(args[0]) + + if (crate == null) { + sender.sendMessage(plugin.langYml.getMessage("invalid-crate")) + return + } + + val physical = args.getOrNull(1)?.equals("physical", ignoreCase = true) == true + + val amount = args.getOrNull(2)?.toIntOrNull() ?: 1 + + for (player in Bukkit.getOfflinePlayers()) { + if (physical) { + val online = player.player + if (online != null) { + val items = mutableListOf().apply { repeat(amount) { add(crate.key.item) } } + + if (plugin.configYml.getBool("track-player-keys")) { + items.map { + val meta = it.itemMeta!! + meta.persistentDataContainer.set( + plugin.namespacedKeyFactory.create("player"), + PersistentDataType.STRING, + player.uniqueId.toString() + ) + it.itemMeta = meta + } + } + + DropQueue(online) + .addItems(items) + .forceTelekinesis() + .push() + } else { + crate.adjustKeysToGet(player, amount) + } + } else { + crate.adjustVirtualKeys(player, amount) + } + } + + sender.sendMessage( + plugin.langYml.getMessage("gave-keys-all-offline") + .replace("%amount%", amount.toString()) + .replace("%crate%", crate.name) + ) + } + + override fun tabComplete(sender: CommandSender, args: List): List { + val completions = mutableListOf() + + if (args.isEmpty()) { + return Crates.values().map { it.id } + } + + if (args.size == 1) { + StringUtil.copyPartialMatches( + args[0], + Crates.values().map { it.id }, + completions + ) + + return completions + } + + if (args.size == 2) { + StringUtil.copyPartialMatches( + args[1], + listOf("physical", "virtual"), + completions + ) + + return completions + } + + if (args.size == 3) { + StringUtil.copyPartialMatches( + args[2], + listOf("1", "2", "3", "4", "5", "10"), + completions + ) + + return completions + } + + return emptyList() + } +} + + diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecocrates/crate/Crate.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecocrates/crate/Crate.kt index 181da62..2539171 100644 --- a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecocrates/crate/Crate.kt +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecocrates/crate/Crate.kt @@ -133,6 +133,12 @@ class Crate( 0 ) + private val toGetKey: PersistentDataKey = PersistentDataKey( + plugin.namespacedKeyFactory.create("${id}_to_get"), + PersistentDataKeyType.INT, + 0 + ) + private val rollFactory = Rolls.getByID(config.getString("roll"))!! private val previewGUI = menu(config.getInt("preview.rows")) { @@ -531,6 +537,18 @@ class Crate( return key.matches(player.inventory.itemInMainHand) } + fun getKeysToGet(player: OfflinePlayer): Int { + return player.profile.read(this.toGetKey) + } + + fun setKeysToGet(player: OfflinePlayer, amount: Int) { + player.profile.write(this.toGetKey, amount) + } + + fun adjustKeysToGet(player: OfflinePlayer, amount: Int) { + this.setKeysToGet(player, this.getKeysToGet(player) + amount) + } + fun hasVirtualKey(player: Player): Boolean { return getVirtualKeys(player) > 0 } diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecocrates/crate/CrateKey.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecocrates/crate/CrateKey.kt index 6c5f30f..41fb5c8 100644 --- a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecocrates/crate/CrateKey.kt +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecocrates/crate/CrateKey.kt @@ -1,9 +1,11 @@ package com.willfp.ecocrates.crate +import com.willfp.eco.core.drops.DropQueue import com.willfp.ecocrates.EcoCratesPlugin import org.bukkit.event.EventHandler import org.bukkit.event.Listener import org.bukkit.event.block.BlockPlaceEvent +import org.bukkit.event.player.PlayerJoinEvent import org.bukkit.inventory.ItemStack import org.bukkit.persistence.PersistentDataType @@ -41,4 +43,39 @@ class CrateKeyListener : Listener { event.isCancelled = true } } + + @EventHandler + fun handleToGet(event: PlayerJoinEvent) { + for (crate in Crates.values()) { + val toGet = crate.getKeysToGet(event.player) + if (toGet > 0) { + val items = mutableListOf().apply { repeat(toGet) { add(crate.key.item) } } + + if (plugin.configYml.getBool("track-player-keys")) { + items.map { + val meta = it.itemMeta!! + meta.persistentDataContainer.set( + plugin.namespacedKeyFactory.create("player"), + PersistentDataType.STRING, + event.player.uniqueId.toString() + ) + it.itemMeta = meta + } + } + + crate.setKeysToGet(event.player, 0) + + DropQueue(event.player) + .addItems(items) + .forceTelekinesis() + .push() + + event.player.sendMessage( + plugin.langYml.getMessage(" offline-keys-received") + .replace("%amount%", toGet.toString()) + .replace("%crate%", crate.name) + ) + } + } + } } diff --git a/eco-core/core-plugin/src/main/resources/lang.yml b/eco-core/core-plugin/src/main/resources/lang.yml index e3877f7..7260725 100644 --- a/eco-core/core-plugin/src/main/resources/lang.yml +++ b/eco-core/core-plugin/src/main/resources/lang.yml @@ -12,6 +12,7 @@ messages: invalid-player: "&cUnknown player!" gave-keys: "Gave %amount%&f %crate%&f key(s) to %user%&f!" gave-keys-all: "Gave %amount%&f %crate%&f key(s) to all online players!" + gave-keys-offline: "Gave %amount%&f %crate%&f key(s) to all online and offline players!" took-keys: "Took %amount%&f %crate%&f key(s) from %user%&f!" not-enough-took-keys: "&c%user%&f has not enough %crate% key(s) to take!" must-target-block: "&cYou must be looking at a block!" @@ -25,3 +26,4 @@ messages: invalid-converter: "&cUnknown converter!" converted: "&aConverted successfully!" converting: "Attempting to convert..." + offline-keys-received: "You have received %amount%&f %crate%&f key(s) while being offline!" diff --git a/eco-core/core-plugin/src/main/resources/plugin.yml b/eco-core/core-plugin/src/main/resources/plugin.yml index d20bc31..1122df7 100644 --- a/eco-core/core-plugin/src/main/resources/plugin.yml +++ b/eco-core/core-plugin/src/main/resources/plugin.yml @@ -41,6 +41,7 @@ permissions: ecocrates.command.resetwins: true ecocrates.command.convert: true ecocrates.command.giveall: true + ecocrates.command.giveoffline: true ecocrates.rewards.*: true ecocrates.break: true ecocrates.open.*: true @@ -56,7 +57,10 @@ permissions: description: Allows giving players keys default: op ecocrates.command.giveall: - description: Allows giving all players keys + description: Allows giving all online players keys + default: op + ecocrates.command.giveoffline: + description: Allows giving all online and offline players keys default: op ecocrates.command.take: description: Allows taking players keys