9
0
mirror of https://github.com/Auxilor/EcoBits.git synced 2025-12-19 15:09:19 +00:00

Merge pull request #2

Added support for _raw and _formatted in the leaderboard placeholders (old placeholders will still work and return formatted value by default)
This commit is contained in:
Will FP
2023-05-02 15:29:30 +01:00
committed by GitHub
13 changed files with 306 additions and 167 deletions

View File

@@ -1,122 +0,0 @@
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.10"
}
}
plugins {
id 'java-library'
id 'com.github.johnrengelman.shadow' version '7.0.0'
id 'maven-publish'
id 'java'
}
dependencies {
implementation project(":eco-core").getSubprojects()
}
allprojects {
apply plugin: 'java'
apply plugin: 'kotlin'
apply plugin: 'maven-publish'
apply plugin: 'com.github.johnrengelman.shadow'
repositories {
mavenCentral()
mavenLocal()
maven { url 'https://jitpack.io' }
maven { url 'https://hub.spigotmc.org/nexus/content/repositories/snapshots/' }
maven { url 'https://repo.codemc.org/repository/nms/' }
maven { url 'https://repo.codemc.io/repository/maven-public/' }
maven { url 'https://repo.dmulloy2.net/repository/public/' }
maven { url 'https://repo.extendedclip.com/content/repositories/placeholderapi/' }
}
jar {
onlyIf { !sourceSets.main.allSource.files.isEmpty() }
}
shadowJar {
}
dependencies {
compileOnly 'com.willfp:eco:6.50.1'
compileOnly 'org.jetbrains:annotations:23.0.0'
compileOnly 'org.jetbrains.kotlin:kotlin-stdlib:1.7.10'
compileOnly 'me.clip:placeholderapi:2.11.2'
implementation 'com.github.ben-manes.caffeine:caffeine:3.1.0'
}
tasks.withType(JavaCompile) {
options.deprecation = true
options.encoding = 'UTF-8'
}
processResources {
filesNotMatching(["**/*.png", "**/models/**", "**/textures/**", "**lang.yml"]) {
expand projectVersion: project.version
}
}
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile) {
kotlinOptions {
jvmTarget = "17"
freeCompilerArgs = ['-Xjvm-default=all']
}
}
java.sourceCompatibility = JavaVersion.VERSION_17
java.targetCompatibility = JavaVersion.VERSION_17
compileJava.options.encoding = 'UTF-8'
compileJava.dependsOn clean
build.dependsOn shadowJar
}
tasks.withType(Jar) {
destinationDirectory = file("$rootDir/bin/")
}
clean.doLast {
file("${rootDir}/bin").deleteDir()
}
shadowJar {
archiveFileName = findProperty("plugin-name") + " v" + findProperty("version") + ".jar"
}
jar {
archiveFileName = findProperty("plugin-name") + " v" + findProperty("version") + " " + "unshaded" + ".jar"
}
group = 'com.willfp'
archivesBaseName = project.name
version = findProperty("version")
compileJava.options.encoding = 'UTF-8'
build.dependsOn shadowJar
build.dependsOn publishToMavenLocal
task buyThePlugins {
dependsOn subprojects.build
doLast {
println 'If you like the plugin, please consider buying it on Spigot or Polymart!'
println 'Spigot: https://www.spigotmc.org/resources/authors/auxilor.507394/'
println 'Polymart: https://polymart.org/user/auxilor.1107/'
println 'Buying gives you access to support and the plugin auto-updater, and it allows me to keep developing plugins.'
}
}
build.finalizedBy buyThePlugins

123
build.gradle.kts Normal file
View File

@@ -0,0 +1,123 @@
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.10")
}
}
plugins {
id("java-library")
id("com.github.johnrengelman.shadow") version "7.0.0"
id("maven-publish")
id("java")
}
dependencies {
implementation(project(":eco-core"))
implementation(project(":eco-core:core-plugin"))
}
allprojects {
apply(plugin = "java")
apply(plugin = "kotlin")
apply(plugin = "maven-publish")
apply(plugin = "com.github.johnrengelman.shadow")
repositories {
mavenCentral()
mavenLocal()
maven { url = uri("https://jitpack.io") }
maven { url = uri("https://hub.spigotmc.org/nexus/content/repositories/snapshots/") }
maven { url = uri("https://repo.codemc.org/repository/nms/") }
maven { url = uri("https://repo.codemc.io/repository/maven-public/") }
maven { url = uri("https://repo.dmulloy2.net/repository/public/") }
maven { url = uri("https://repo.extendedclip.com/content/repositories/placeholderapi/") }
}
dependencies {
compileOnly("com.willfp:eco:6.53.0")
compileOnly("org.jetbrains:annotations:23.0.0")
compileOnly("org.jetbrains.kotlin:kotlin-stdlib:1.7.10")
compileOnly("me.clip:placeholderapi:2.11.2")
compileOnly("com.github.ben-manes.caffeine:caffeine:3.1.0")
}
tasks.withType<JavaCompile> {
options.encoding = "UTF-8"
}
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
kotlinOptions {
jvmTarget = "17"
}
}
tasks {
java {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
compileJava {
options.encoding = "UTF-8"
dependsOn(clean)
}
processResources {
filesMatching(listOf("**plugin.yml")) {
expand(mapOf("projectVersion" to project.version))
}
}
build {
dependsOn("shadowJar")
}
}
}
group = "com.willfp"
version = findProperty("version")!!
tasks.register("buyThePlugins") {
doLast {
println("If you like the plugin, please consider buying it on Spigot or Polymart!")
println("Spigot: https://www.spigotmc.org/resources/authors/auxilor.507394/")
println("Polymart: https://polymart.org/user/auxilor.1107/")
println("Buying gives you access to support and the plugin auto-updater, and it allows me to keep developing plugins.")
}
}
tasks {
build {
dependsOn("publishToMavenLocal")
finalizedBy("buyThePlugins")
}
withType<Jar> {
destinationDirectory.set(file("$rootDir/bin/"))
}
register("cleanBin") {
doLast {
file("$rootDir/bin").deleteRecursively()
}
}
clean {
finalizedBy("cleanBin")
}
named<ShadowJar>("shadowJar") {
archiveFileName.set("${findProperty("plugin-name")} v${findProperty("version")}.jar")
}
named<Jar>("jar") {
archiveFileName.set("${findProperty("plugin-name")} v${findProperty("version")} unshaded.jar")
}
}

View File

@@ -1,2 +0,0 @@
group 'com.willfp'
version rootProject.version

View File

@@ -0,0 +1,2 @@
group = "com.willfp"
version = rootProject.version

View File

@@ -1,19 +0,0 @@
group 'com.willfp'
version rootProject.version
dependencies {
compileOnly 'org.spigotmc:spigot-api:1.17.1-R0.1-SNAPSHOT'
compileOnly 'com.github.MilkBowl:VaultAPI:1.7'
compileOnly fileTree(dir: '../../lib', include: ['*.jar'])
}
build.dependsOn publishToMavenLocal
publishing {
publications {
maven(MavenPublication) {
from(components.java)
}
}
}

View File

@@ -0,0 +1,23 @@
group = "com.willfp"
version = rootProject.version
dependencies {
compileOnly("org.spigotmc:spigot-api:1.17.1-R0.1-SNAPSHOT")
compileOnly("com.github.MilkBowl:VaultAPI:1.7")
compileOnly(fileTree("../../lib") { include("*.jar") })
}
tasks {
build {
dependsOn("publishToMavenLocal")
}
}
publishing {
publications {
create<MavenPublication>("maven") {
from(components["java"])
}
}
}

View File

@@ -0,0 +1,103 @@
package com.willfp.ecobits.commands
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.command.impl.PluginCommand
import com.willfp.eco.core.command.impl.Subcommand
import com.willfp.eco.util.containsIgnoreCase
import com.willfp.ecobits.currencies.Currencies
import com.willfp.ecobits.currencies.Currency
import org.bukkit.Bukkit
import org.bukkit.command.CommandSender
import org.bukkit.entity.Player
import org.bukkit.util.StringUtil
class DynamicCurrencyCommand(
plugin: EcoPlugin,
label: String,
val currency: Currency
): PluginCommand(
plugin,
label,
"ecobits.command.${currency.id}",
false
) {
init {
DynamicCurrencySubcommand.allCommands.forEach {
this.addSubcommand(
DynamicCurrencySubcommand(plugin, it, currency)
)
}
}
override fun onExecute(sender: CommandSender, args: MutableList<String>) {
sender.sendMessage(this.plugin.langYml.getMessage("invalid-command"))
}
class DynamicCurrencySubcommand(
plugin: EcoPlugin,
val command: String,
val currency: Currency
): Subcommand(
plugin,
command,
"ecobits.command.${currency.id}.$command",
false
) {
override fun onExecute(sender: CommandSender, args: MutableList<String>) {
super.onExecute(sender, args)
}
override fun onExecute(sender: Player, args: MutableList<String>) {
val format = when {
currencyCommands.containsIgnoreCase(command) -> currencyFormat
playerCurrencyCommands.containsIgnoreCase(command) -> playerCurrencyFormat
playerCurrencyAmountCommands.containsIgnoreCase(command) -> playerCurrencyAmountFormat
else -> ""
}
Bukkit.dispatchCommand(sender,
format.replace(
"%command%", command
).replace(
"%player%", args.getOrElse(0) { "" }
).replace(
"%amount%", args.getOrElse(1) { "" }
).replace(
"%currency%", currency.id
)
)
}
override fun tabComplete(sender: CommandSender, args: MutableList<String>): MutableList<String> {
return when {
args.size == 1 -> {
if (currencyCommands.containsIgnoreCase(command)) {
StringUtil.copyPartialMatches(args.first(),
Currencies.values().map { it.id }, mutableListOf())
} else {
StringUtil.copyPartialMatches(args.first(),
Bukkit.getOnlinePlayers().map { it.name }, mutableListOf())
}
}
args.size == 2 && !currencyCommands.containsIgnoreCase(command) -> {
StringUtil.copyPartialMatches(args.first(),
Currencies.values().map { it.id }, mutableListOf())
}
else -> mutableListOf()
}
}
companion object {
val currencyCommands = listOf("balance")
val playerCurrencyCommands = listOf("get", "reset")
val playerCurrencyAmountCommands = listOf("give", "givesilent", "pay", "set", "take", "takesilent")
val allCommands = currencyCommands + playerCurrencyCommands + playerCurrencyAmountCommands
val currencyFormat = "ecobits %command% %currency%"
val playerCurrencyFormat = "ecobits %command% %player% %currency%"
val playerCurrencyAmountFormat = "ecobits %command% %player% %currency% %amount%"
}
}
}

View File

@@ -2,7 +2,6 @@
package com.willfp.ecobits.currencies
import com.github.benmanes.caffeine.cache.Cache
import com.github.benmanes.caffeine.cache.Caffeine
import com.willfp.eco.core.config.interfaces.Config
import com.willfp.eco.core.data.keys.PersistentDataKey
@@ -10,13 +9,13 @@ 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.DynamicPlaceholder
import com.willfp.eco.core.placeholder.PlayerDynamicPlaceholder
import com.willfp.eco.core.placeholder.PlayerPlaceholder
import com.willfp.eco.core.placeholder.PlayerlessPlaceholder
import com.willfp.eco.core.price.Prices
import com.willfp.eco.util.savedDisplayName
import com.willfp.eco.util.toNiceString
import com.willfp.ecobits.EcoBitsPlugin
import com.willfp.ecobits.commands.DynamicCurrencyCommand
import com.willfp.ecobits.integrations.IntegrationVault
import net.milkbowl.vault.economy.Economy
import org.bukkit.Bukkit
@@ -24,6 +23,7 @@ import org.bukkit.OfflinePlayer
import org.bukkit.plugin.ServicePriority
import java.text.DecimalFormat
import java.time.Duration
import java.util.Optional
import java.util.regex.Pattern
import kotlin.math.floor
import kotlin.math.log10
@@ -34,13 +34,14 @@ class Currency(
val plugin: EcoBitsPlugin,
val config: Config
) {
val leaderBoardCache: Cache<Int, LeaderboardCacheEntry?> = Caffeine.newBuilder()
val leaderboardCache = Caffeine.newBuilder()
.expireAfterWrite(Duration.ofSeconds(plugin.configYml.getInt("cache-expire-after").toLong()))
.build()
.build<Int, Optional<LeaderboardPlace>>()
val default = config.getDouble("default")
val name = config.getFormattedString("name")
val max = config.getDouble("max").let { if (it < 0) Double.MAX_VALUE else it }
val isPayable = config.getBool("payable")
@@ -51,42 +52,61 @@ class Currency(
val isLocal = config.getBool("local")
val commands = config.getStrings("commands").map { DynamicCurrencyCommand(plugin, it, this) }
val key = PersistentDataKey(
plugin.createNamespacedKey(if (isLocal) "${plugin.serverID}_${id}" else id),
PersistentDataKeyType.DOUBLE,
default
)
fun getTop(place: Int): LeaderboardCacheEntry? {
return leaderBoardCache.get(place) {
fun getLeaderboardPlace(place: Int): LeaderboardPlace? {
return leaderboardCache.get(place) {
val top = Bukkit.getOfflinePlayers()
.sortedByDescending { it.getBalance(this) }.getOrNull(place - 1)
if (top == null) {
null
} else LeaderboardCacheEntry(top, top.getBalance(this))
Optional.empty()
} else Optional.of(LeaderboardPlace(top, top.getBalance(this)))
}.orElse(null)
}
fun registerCommands() {
this.commands.forEach {
println("Registered ${it.name}")
it.register()
}
}
fun unregisterCommands() {
this.commands.forEach { it.unregister() }
}
init {
PlaceholderManager.registerPlaceholder(
DynamicPlaceholder(
plugin,
Pattern.compile("top_${id}_[0-9]+_[a-z]+"),
) {
value ->
Pattern.compile("top_${id}_[0-9]+_[a-z]+_?[a-z]*"),
) { value ->
val place = value.split("_").getOrNull(2)
?.toIntOrNull() ?: return@DynamicPlaceholder "Invalid place"
?.toIntOrNull() ?: return@DynamicPlaceholder ""
val type = value.split("_").getOrNull(3)
?: return@DynamicPlaceholder "Type required"
?: return@DynamicPlaceholder ""
val raw = value.split("_").getOrNull(4)
?.equals("raw", true) ?: true
val placeObj = getLeaderboardPlace(place)
return@DynamicPlaceholder when (type) {
"name" -> this.getTop(place)?.player?.savedDisplayName
"name" -> placeObj?.player?.savedDisplayName
?: plugin.langYml.getFormattedString("top.name-empty")
"amount" -> this.getTop(place)?.amount?.formatWithExtension()
"amount" -> (if (raw) placeObj?.amount.toNiceString() else placeObj?.amount?.formatWithExtension())
?: plugin.langYml.getFormattedString("top.amount-empty")
else -> "Invalid type"
else -> ""
}
}
)
@@ -137,10 +157,16 @@ class Currency(
ServicePriority.Highest
)
}
this.unregisterCommands()
this.registerCommands()
}
}
data class LeaderboardCacheEntry(val player: OfflinePlayer, val amount: Double)
data class LeaderboardPlace(
val player: OfflinePlayer,
val amount: Double
)
fun Double.formatWithExtension(): String {
val suffix = charArrayOf(' ', 'k', 'M', 'B', 'T', 'P', 'E')

View File

@@ -27,3 +27,6 @@ currencies:
decimal: true # If decimal amounts are allowed rather than just integer amounts
vault: false # If this currency should be registered with vault
local: false # If this currency should not sync between servers
commands: # A list of commands dedicated to this currency (for easier paying, checking balance, etc)
- crystals
- ecocrystals

View File

@@ -5,6 +5,8 @@ messages:
invalid-command: "&cUnknown subcommand!"
reloaded: "Reloaded!"
must-specify-player: "&cYou must specify a player!"
invalid-player: "&cInvalid player!"
must-specify-currency: "&cYou must specify a currency!"
invalid-currency: "&cInvalid currency!"
must-specify-amount: "&cYou must specify an amount!"

View File

@@ -1,2 +1,2 @@
version = 1.4.0
version = 1.5.0
plugin-name = EcoBits

View File

@@ -1,5 +0,0 @@
rootProject.name = 'EcoBits'
// Core
include ':eco-core'
include ':eco-core:core-plugin'

5
settings.gradle.kts Normal file
View File

@@ -0,0 +1,5 @@
rootProject.name = "EcoBits"
// Core
include(":eco-core")
include(":eco-core:core-plugin")