Initial commit: port from svn

master
ALI Hamza 2021-01-06 07:03:40 +07:00
commit eef049f70f
Signed by: hamza
GPG Key ID: 22473A32291F8CB6
26 changed files with 1139 additions and 0 deletions

BIN
.DS_Store vendored

Binary file not shown.

@ -0,0 +1 @@
mvn package && start ../speak.vbs

@ -0,0 +1,6 @@
#!/usr/bin/env bash
mvn package
mv target/MDRanks-1.0.jar ~/server/plugins/
say up

BIN
libs/.DS_Store vendored

Binary file not shown.

Binary file not shown.

@ -0,0 +1,132 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>pw.hamzantal</groupId>
<artifactId>MDRanks</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<name>MDRanks</name>
<description>MDranks Plugin created by hhhapz</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<kotlin.version>1.3.71</kotlin.version>
<kotlin.compiler.jvmTarget>1.8</kotlin.compiler.jvmTarget>
<kotlin.code.style>official</kotlin.code.style>
</properties>
<url>https://hamzantal.pw</url>
<build>
<sourceDirectory>src/main/kotlin</sourceDirectory>
<defaultGoal>clean package</defaultGoal>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>${kotlin.version}</version>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
<repositories>
<repository>
<id>sonatype</id>
<url>https://oss.sonatype.org/content/groups/public/</url>
</repository>
<repository>
<id>placeholderapi</id>
<url>https://repo.extendedclip.com/content/repositories/placeholderapi/</url>
</repository>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<version>${kotlin.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.github.hazae41</groupId>
<artifactId>mc-kutils</artifactId>
<version>master-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.destroystokyo.paper</groupId>
<artifactId>paper-api</artifactId>
<version>1.8.8-R0.1-SNAPSHOT</version>
<scope>system</scope>
<systemPath>${project.basedir}/libs/Paperclip.jar</systemPath>
</dependency>
<dependency>
<groupId>me.clip</groupId>
<artifactId>placeholderapi</artifactId>
<version>2.10.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.github.MilkBowl</groupId>
<artifactId>VaultAPI</artifactId>
<version>1.7</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>net.luckperms</groupId>
<artifactId>api</artifactId>
<version>5.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

BIN
src/.DS_Store vendored

Binary file not shown.

BIN
src/main/.DS_Store vendored

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -0,0 +1,255 @@
package pw.hamzantal.mdranks
import hazae41.minecraft.kutils.bukkit.ConfigFile
import hazae41.minecraft.kutils.bukkit.keys
import hazae41.minecraft.kutils.get
import org.bukkit.ChatColor
import org.bukkit.configuration.ConfigurationSection
import org.bukkit.entity.Player
import pw.hamzantal.mdranks.api.Perms
import pw.hamzantal.mdranks.api.RankType
import pw.hamzantal.mdranks.api.Vault
import kotlin.math.floor
import kotlin.random.Random
import kotlin.random.nextInt
object Config : ConfigFile(MDRanks.pl.dataFolder["config.yml"]) {
val codes = listOf(
7 to "S",
6 to "Q",
5 to "q",
4 to "T",
3 to "B",
2 to "M",
1 to "K"
)
fun formatC(amount: Number): String {
var base: Number = amount.toLong()
var exponent = 0
while (base.toLong() > 1000) {
base = if (base.toLong() < 1_000_000) base.toDouble() / 1000
else base.toLong() / 1000
exponent++
}
val (_, suffix) = codes.firstOrNull { it.first <= exponent } ?: 0 to ""
return config.getString("currencyFormat").replace("%amt%", "${floor(base.toDouble() * 10.0) / 10}$suffix")
}
fun wBrcks(msg: String): String {
return config.getString("bracketformat", "&7[%display%&7]").replace("%display%", msg).c
}
val defaultPrestige by string("default_prestige")
val defaultRebirth by string("default_rebirth")
}
object Ranks : ConfigFile(MDRanks.pl.dataFolder["ranks.yml"]) {
init {
autoSave = true
minDelay = 1000
}
data class PlayerRank(val name: String, val regular: Int, val prestige: Int, val rebirth: Int)
private const val cacheTime = 1000 * 60 * 5 //calculate top every 5 mins
private var nextCalculate = 0L
private var topCache = listOf<PlayerRank>()
val top: List<PlayerRank> get() {
if (nextCalculate < System.currentTimeMillis()) {
topCache = config.keys.map {
PlayerRank(
config.getString("$it.name"),
config.getInt("$it.regular"),
config.getInt("$it.prestige"),
config.getInt("$it.rebirth")
)
}.sortedWith(compareBy(PlayerRank::rebirth, PlayerRank::prestige, PlayerRank::regular))
.reversed()
.take(10)
nextCalculate = System.currentTimeMillis() + cacheTime
}
return topCache
}
operator fun set(p: Player, path: String, value: Int) {
this["${p.uniqueId}.$path"] = value
this["${p.uniqueId}.name"] = p.name
}
}
val String.wBrackets: String get() = Config.wBrcks(this)
open class RankData(
val level: Int,
val isLast: Boolean,
val display: String,
val cost: Double,
val commandsOnUpgrade: List<String>,
val broadcast: List<String>,
val msg: List<String>,
val addPerms: List<String>,
val delPerms: List<String>,
val others: ConfigurationSection
) {
val randomCommandList: List<String>
get() {
val sec = others.getConfigurationSection("randomcmds") ?: return listOf()
val chancePair = sec.getKeys(false)
.map { sec.getInt("$it.chance") to sec.getStringList("$it.commands") }
val max = chancePair.sumBy { it.first }
val choice = Random.nextInt(1..max)
var total = 0
return chancePair.first {
total += it.first
total >= choice
}.second
}
fun cost(p: Player): Double {
var calcCost = cost.toDouble()
calcCost *= 1 + (RegularConfig(Perms.reg(p)).percentageIncrease / 100.0)
if (Perms.prestige(p) != 0)
calcCost *= 1 + (PrestigeConfig(Perms.prestige(p)).percentageIncrease / 100.0)
if (Perms.rebirth(p) != 0)
calcCost *= 1 + (RebirthConfig(Perms.rebirth(p)).percentageIncrease / 100.0)
return calcCost
}
val percentageIncrease: Double get() = others.getDouble("cost_percentage_increase", 0.0)
override fun toString() =
"RankData(level=$level, display='$display', cost=$cost, commandsOnUpgrade=$commandsOnUpgrade, broadcast=$broadcast, msg=$msg, addPerms=$addPerms, delPerms=$delPerms)"
}
abstract class PrisonConfig(fName: String) : ConfigFile(MDRanks.pl.dataFolder["$fName.yml"]) {
fun nextPcnt(p: Player, type: RankType): Double {
val current = this(p, type)
if (current?.isLast == true) return 0.0
val data = this(current?.level ?: 0 + 1)
return Vault.balance(p) / data.cost(p)
}
fun next(p: Player, type: RankType, block: RankData.() -> String): String {
val current = this(p, type)
if (current?.isLast == true) return when (type) {
RankType.REG -> "&euse /prestige!"
RankType.PRESTIGE -> "&euse /rebirth!"
RankType.REBIRTH -> "&eNo more rebirths!"
}
return this(current?.level ?: 0 + 1).block()
}
operator fun invoke(p: Player, type: RankType): RankData? {
val level = Perms.rankFor(p, type)
return if (level == 0) null
else this(level)
}
operator fun invoke(level: Int): RankData {
val sec = this.config.getConfigurationSection("$level") ?: run {
throw IllegalStateException("The specified level ($level) does not exist.")
}
val index = config.keys.indexOf("$level")
val last = index + 1 == config.keys.size
return RankData(
level,
last,
sec.getString("display", "").c,
sec.getDouble("cost", 0.0),
sec.getStringList("commands").c,
sec.getStringList("broadcast").c,
sec.getStringList("msg").c,
sec.getStringList("addpermission").c,
sec.getStringList("delpermission").c,
sec
)
}
fun max() = config.getKeys(false).last().toInt()
init {
val cFile = MDRanks.pl.dataFolder["$fName.yml"]
if (!cFile.exists()) {
cFile.createNewFile()
}
}
}
object RegularConfig : PrisonConfig("regular") {
init {
val cFile = MDRanks.pl.dataFolder["regular.yml"]
if (!cFile.exists()) {
cFile.createNewFile()
set("1.display", "&1A")
set("1.cost", 0)
set("1.addpermission", listOf("essentials.warp.1"))
set("2.display", "&2A")
set("2.cost", 25000)
set(
"2.commands",
listOf(
"[console] give %player% diamond 1",
"[op] say i am executing this command as an operator",
"[player] warp %rankup%"
)
)
set("2.broadcast", listOf("&7%player% &eranked up to &7%rankup%", "&7-----------------"))
set("2.msg", listOf("&9You got &b1 &bdiamond."))
set("2.randomcmds.1.chance", 70)
set("2.randomcmds.1.commands", listOf("[console] tell %player% this was executed 70% of the time"))
set("2.randomcmds.2.chance", 30)
set("2.randomcmds.2.commands", listOf("[console] tell %player% this was executed 30% of the time"))
set("2.addpermission", listOf("essentials.warp.2"))
set("2.delpermission", listOf("essentials.warp.1"))
}
}
}
object PrestigeConfig : PrisonConfig("prestige") {
init {
val cFile = MDRanks.pl.dataFolder["prestige.yml"]
if (!cFile.exists()) {
cFile.createNewFile()
set("1.display", "&1P1")
set("1.cost", 25000)
set("1.commands", listOf("[console] give %player% diamond 5"))
set("1.broadcast", listOf("&7%player% &eprestiged up to &7%rankup%", "&7-----------------"))
set("1.msg", listOf("&9You got &b5 &bdiamonds."))
set("1.cost_percentage_increase", 25)
set("2.display", "&2P2")
set("2.cost", 50000)
set("2.commands", listOf("[console] give %player% gold_ingot 10"))
set("2.broadcast", listOf("&7%player% &eprestiged up to &7%rankup%", "&7-----------------"))
set("2.msg", listOf("&9You got &b10 &6gold ingots."))
set("2.cost_percentage_increase", 30)
}
}
}
object RebirthConfig : PrisonConfig("rebirth") {
init {
val cFile = MDRanks.pl.dataFolder["rebirth.yml"]
if (!cFile.exists()) {
cFile.createNewFile()
set("1.display", "&1&lR1")
set("1.cost", 100000)
set("1.commands", listOf("[console] give %player% diamond 64"))
set("1.broadcast", listOf("&7&l%player% &e&lprestiged up to &7&l%rankup%", "&7-----------------"))
set("1.msg", listOf("&9You got &b5 &bdiamonds."))
set("1.cost_percentage_increase", 25)
set("1.cost_percentage_increase", 25)
}
}
}
val String.c: String get() = ChatColor.translateAlternateColorCodes('&', this)
val List<String>.c: List<String> get() = map { it.c }

@ -0,0 +1,105 @@
package pw.hamzantal.mdranks
import hazae41.minecraft.kutils.bukkit.BukkitPlugin
import hazae41.minecraft.kutils.bukkit.command
import hazae41.minecraft.kutils.bukkit.listen
import hazae41.minecraft.kutils.bukkit.msg
import hazae41.minecraft.kutils.get
import org.bukkit.Bukkit
import org.bukkit.entity.Player
import org.bukkit.event.player.PlayerJoinEvent
import pw.hamzantal.mdranks.api.Perms
import pw.hamzantal.mdranks.api.RankType
import pw.hamzantal.mdranks.api.Vault
import pw.hamzantal.mdranks.commands.checkBalance
import pw.hamzantal.mdranks.commands.onPrestige
import pw.hamzantal.mdranks.commands.onRankUp
import pw.hamzantal.mdranks.commands.onRebirth
class MDRanks : BukkitPlugin() {
companion object {
lateinit var pl: MDRanks
}
val ranksFile = dataFolder["ranks.yml"]
override fun onEnable() {
pl = this
saveDefaultConfig()
listen<PlayerJoinEvent> {
val p = it.player
val lvl = Perms.reg(p)
if (lvl == 0)
Vault.updateRank(p, RankType.REG, 1)
val regLevel = Perms.reg(p)
val prLevel = Perms.prestige(p)
val rbLevel = Perms.rebirth(p)
Ranks[p, "regular"] = regLevel
Ranks[p, "prestige"] = prLevel
Ranks[p, "rebirth"] = rbLevel
}
command("mdranks") { sender, args ->
if (!sender.hasPermission("mdranks.admin")) {
sender.err("no_access")
return@command
}
if (args.size == 2) {
val (player, toReset) = args
val p = Bukkit.getPlayer(player)?: run {
sender.err("player_not_found")
return@command
}
}
if (args.size < 3) {
sender.err("mdranks_usage")
return@command
}
val (player, type, num) = args
val p = Bukkit.getPlayer(player) ?: run {
sender.err("player_not_found")
return@command
}
val rank = RankType.byArg(type) ?: run {
sender.sendMessage("rank_not_found")
return@command
}
val level = num.toIntOrNull() ?: 0
Vault.updateRank(p, rank, level, true)
sender.success(
"update_player_rank_sender",
"player" to p.name,
"rank" to rank.rankName,
"level" to "$level"
)
p.general(
"update_player_rank_receiver",
"rank" to rank.rankName,
"level" to "$level"
)
}
command("rankup") { args ->
onRankUp(this, args)
}
command("prestige") { args ->
onPrestige(this, args)
}
command("rebirth") { _ ->
onRebirth(this)
}
command("bal") { args -> checkBalance(this, args) }
command("rebirthtop") { _ ->
msg("&a&m-------&f&m-------&a&m-------&f&m-------&a&m-------&f&m-------&a&m-------")
Ranks.top.forEachIndexed { i, rank ->
msg("&f&l#${i + 1}. &a${rank.name} &8» &7${rank.rebirth} Rebirth${if (rank.rebirth != 1) "s" else ""}")
}
msg("&a&m-------&f&m-------&a&m-------&f&m-------&a&m-------&f&m-------&a&m-------")
}
if (isPapi) PapiExpansion().register()
}
}

@ -0,0 +1,43 @@
package pw.hamzantal.mdranks
import hazae41.minecraft.kutils.bukkit.ConfigFile
import hazae41.minecraft.kutils.get
object Messages : ConfigFile(MDRanks.pl.dataFolder["messages.yml"]) {
override var minDelay: Long
get() = super.minDelay
set(value) {}
private val errorFormat by lazy { config.getString("error") }
fun error(msg: String, vararg params: Pair<String, String>): String {
var base = errorFormat.replace("%s", config.getString("error_msgs.$msg", msg))
params.forEach { (k, v) -> base = base.replace("%$k%", v) }
return base.c
}
private val generalFormat by lazy { config.getString("general") }
fun general(msg: String, vararg params: Pair<String, String>): String {
var base = generalFormat.replace("%s", config.getString("general_msgs.$msg", msg))
params.forEach { (k, v) -> base = base.replace("%$k%", v) }
return base.c
}
private val successFormat by lazy { config.getString("success") }
fun success(msg: String, vararg params: Pair<String, String>): String {
var base = successFormat.replace("%s", config.getString("success_msgs.$msg", msg))
params.forEach { (k, v) -> base = base.replace("%$k%", v) }
return base.c
}
init {
if (file == null) throw IllegalStateException("File can't be null")
val file = file!!
if (!file.exists()) {
val messages = MDRanks.pl.getResource("messages.yml").bufferedReader().readLines().joinToString("\n")
file.createNewFile()
file.writeText(messages)
}
}
}

@ -0,0 +1,136 @@
package pw.hamzantal.mdranks
import me.clip.placeholderapi.expansion.PlaceholderExpansion
import org.bukkit.entity.Player
import pw.hamzantal.mdranks.api.Perms
import pw.hamzantal.mdranks.api.RankType.*
import pw.hamzantal.mdranks.api.Vault
import kotlin.math.min
class PapiExpansion : PlaceholderExpansion() {
override fun getVersion() = MDRanks.pl.description.version ?: "0.9.0"
override fun getAuthor() = "hhhapz"
override fun getIdentifier() = "mdranks"
override fun persist() = true
override fun canRegister() = true
override fun onPlaceholderRequest(p: Player?, params: String?): String {
if (p == null) return "UNKNOWN_PLAYER"
if (params == null) return "UNKNOWN_PARAM"
val args = params.split("_", limit = 2)
if (args.size == 1) {
return when (args.component1()) {
"money" -> Config.formatC(Vault.balance(p))
"display" -> {
val dp = RegularConfig(p, REG)?.display ?: ""
val pr = PrestigeConfig(p, PRESTIGE)?.display?: Config.defaultPrestige
val rb = PrestigeConfig(p, REBIRTH)?.display?: Config.defaultRebirth
return "$rb $pr $dp"
}
else -> "UNKNOWN_PARAM"
}
}
if (params == "display_brackets") {
val dp = RegularConfig(p, REG)?.display?.wBrackets ?: ""
val pr = PrestigeConfig(p, PRESTIGE)?.display?.wBrackets
?: Config.defaultPrestige.wBrackets
val rb = PrestigeConfig(p, REBIRTH)?.display?.wBrackets
?: Config.defaultRebirth.wBrackets
return "$rb $pr $dp"
}
return when (args.component1()) {
"currentrank" -> return when (args.component2()) {
"name" -> "${Perms.reg(p)}"
"displayname" -> RegularConfig(p, REG)?.display ?: ""
"displayname_brackets" -> RegularConfig(p, REG)?.display?.wBrackets ?: ""
else -> "UNKNOWN_PARAM"
}
"rankup" -> return when (args.component2()) {
"name" -> RegularConfig.next(p, REG) { "$level" }
"displayname" -> RegularConfig.next(p, REG) { display }
"displayname_brackets" -> RegularConfig.next(p, REG) { display.wBrackets }
"cost" -> RegularConfig.next(p, REG) { "$cost(p)" }
"cost_formatted" -> RegularConfig.next(p, REG) { Config.formatC(cost(p)) }
"percentage" -> String.format("%.1f", min(100.0, RegularConfig.nextPcnt(p, REG) * 100.0))
"percentage_decimal" -> String.format("%.2f", min(100.0, RegularConfig.nextPcnt(p, REG)))
"percentage_nolimit" -> String.format("%.1f", RegularConfig.nextPcnt(p, REG) * 100.0)
"percentage_decimal_nolimit" -> String.format("%.2f", RegularConfig.nextPcnt(p, REG))
else -> "UNKNOWN_PARAM"
}
"prestige" -> return when (args.component2()) {
"name" -> "${Perms.prestige(p)}"
"displayname" -> PrestigeConfig(p, PRESTIGE)?.display ?: Config.defaultPrestige
"displayname_brackets" -> PrestigeConfig(p, PRESTIGE)?.display?.wBrackets ?: Config.defaultPrestige.wBrackets
else -> "UNKNOWN_PARAM"
}
"nextprestige" -> return when (args.component2()) {
"name" -> PrestigeConfig.next(p, PRESTIGE) { "$level" }
"displayname" -> PrestigeConfig.next(p, PRESTIGE) { display }
"displayname_brackets" -> PrestigeConfig.next(p, PRESTIGE) { display.wBrackets }
"cost" -> PrestigeConfig.next(p, PRESTIGE) { "$cost(p)" }
"cost_formatted" -> PrestigeConfig.next(p, PRESTIGE) { Config.formatC(cost(p)) }
"percentage" -> String.format("%.1f", min(100.0, RegularConfig.nextPcnt(p, PRESTIGE) * 100.0))
"percentage_decimal" -> String.format("%.2f", min(100.0, RegularConfig.nextPcnt(p, PRESTIGE)))
"percentage_nolimit" -> String.format("%.1f", RegularConfig.nextPcnt(p, PRESTIGE) * 100.0)
"percentage_decimal_nolimit" -> String.format("%.2f", RegularConfig.nextPcnt(p, PRESTIGE))
else -> "UNKNOWN_PARAM"
}
"rebirth" -> return when (args.component2()) {
"name" -> "${Perms.rebirth(p)}"
"displayname" -> RebirthConfig(p, REBIRTH)?.display ?: Config.defaultRebirth
"displayname_brackets" -> RebirthConfig(p, REBIRTH)?.display?.wBrackets ?: Config.defaultRebirth.wBrackets
else -> "UNKNOWN_PARAM"
}
"nextrebirth" -> return when (args.component2()) {
"name" -> RebirthConfig.next(p, REBIRTH) { "$level" }
"displayname" -> RebirthConfig.next(p, REBIRTH) { display }
"displayname_brackets" -> RebirthConfig.next(p, REBIRTH) { display.wBrackets }
"cost" -> RebirthConfig.next(p, REBIRTH) { "$cost(p)" }
"cost_formatted" -> RebirthConfig.next(p, REBIRTH) { Config.formatC(cost(p)) }
"percentage" -> String.format("%.1f", min(100.0, RegularConfig.nextPcnt(p, REBIRTH) * 100.0))
"percentage_decimal" -> String.format("%.2f", min(100.0, RegularConfig.nextPcnt(p, REBIRTH)))
"percentage_nolimit" -> String.format("%.1f", RegularConfig.nextPcnt(p, REBIRTH) * 100.0)
"percentage_decimal_nolimit" -> String.format("%.2f", RegularConfig.nextPcnt(p, REBIRTH))
else -> "UNKNOWN_PARAM"
}
"money" -> return when {
args.component2() == "nonformatted" -> "${Vault.balance(p)}"
else -> "UNKNOWN_PARAM"
}
"next" -> return when (args.component2()) {
"percentage" -> String.format("%.1f", min(100.0, nextPercentage(p) * 100.0))
"percentage_decimal" -> String.format("%.2f", min(1.0, nextPercentage(p)))
else -> "UNKNOWN_PARAM"
}
else -> "UNKNOWN_PARAM"
}
}
fun nextPercentage(p: Player): Double {
val bal = Vault.balance(p)
val reg = RegularConfig(p, REG) ?: throw IllegalStateException("The regular rank data was not found for ${p.name}")
if (!reg.isLast) return bal / RegularConfig(reg.level + 1).cost(p)
val currentPrestige = PrestigeConfig(p, PRESTIGE)?.level ?: 0
if (currentPrestige != PrestigeConfig.max()) return bal / PrestigeConfig(currentPrestige + 1).cost(p)
val currentRebirth = RebirthConfig(p, REBIRTH)?.level ?: 0
if (currentRebirth != RebirthConfig.max()) return bal / RebirthConfig(currentRebirth + 1).cost(p)
return 100.0
}
}

@ -0,0 +1,10 @@
package pw.hamzantal.mdranks
fun main() {
val names = listOf("person a", "p b", "per c", "p e", "asdasdasd")
val size = names.map { it.length }.max()?: 0
names.forEach {
val name = String.format("%-${size}s >", it)
println(name)
}
}

@ -0,0 +1,40 @@
package pw.hamzantal.mdranks
import hazae41.minecraft.kutils.bukkit.msg
import me.clip.placeholderapi.PlaceholderAPI
import org.bukkit.Bukkit
import org.bukkit.command.CommandSender
import org.bukkit.entity.Player
import pw.hamzantal.mdranks.api.RankType
import pw.hamzantal.mdranks.api.Vault
fun CommandSender.send(message: String) {
msg(message)
}
val isPapi by lazy { Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null }
fun String.placeholders(p: Player, data: RankData, cmdPrefix: Boolean = false): String {
val baseReplacement = replace("%player%", p.name)
.replace("%rankup%", "${data.level}")
.replace("%display%", data.display)
.run {
if (cmdPrefix) replaceFirst("[console] ", "")
.replaceFirst("[op] ", "")
.replaceFirst("[player] ", "")
else this
}
return if (isPapi) PlaceholderAPI.setPlaceholders(p, baseReplacement) else baseReplacement
}
fun CommandSender.err(msg: String, vararg placeholder: Pair<String, String>) {
msg(Messages.error(msg, *placeholder))
}
fun CommandSender.general(msg: String, vararg placeholder: Pair<String, String>) {
msg(Messages.general(msg, *placeholder))
}
fun CommandSender.success(msg: String, vararg placeholder: Pair<String, String>) {
msg(Messages.success(msg, *placeholder))
}

@ -0,0 +1,30 @@
package pw.hamzantal.mdranks.api
import net.luckperms.api.LuckPerms
import net.luckperms.api.model.user.User
import org.bukkit.entity.Player
import pw.hamzantal.mdranks.*
enum class RankType(val rankName: String, val alias: List<String> = listOf(), val config: PrisonConfig) {
REG("regular", listOf("reg", "regular", "rg"), RegularConfig),
PRESTIGE("prestige", listOf("pr", "prestige"), PrestigeConfig),
REBIRTH("rebirth", listOf("rb", "rebirth", "birth"), RebirthConfig);
companion object {
fun byArg(arg: String) = values().firstOrNull { arg in it.alias }
}
}
object Perms {
fun rankFor(p: Player, type: RankType): Int {
return p.effectivePermissions
.filter { it.permission.startsWith("mdranks.${type.rankName}.") }
.map { (it.permission.removePrefix("mdranks.${type.rankName}.").toIntOrNull()) ?: 0 }
.max() ?: 0
}
fun reg(p: Player) = rankFor(p, RankType.REG)
fun prestige(p: Player) = rankFor(p, RankType.PRESTIGE)
fun rebirth(p: Player) = rankFor(p, RankType.REBIRTH)
}

@ -0,0 +1,65 @@
package pw.hamzantal.mdranks.api
import net.milkbowl.vault.economy.Economy
import net.milkbowl.vault.economy.EconomyResponse
import net.milkbowl.vault.permission.Permission
import org.bukkit.entity.Player
import pw.hamzantal.mdranks.MDRanks
import pw.hamzantal.mdranks.Ranks
object Vault {
private val pl = MDRanks.pl
val econ by lazy {
if (pl.server.pluginManager.getPlugin("Vault") == null) {
throw IllegalStateException("The vault dependency was not found")
}
pl.server.servicesManager.getRegistration(Economy::class.java).provider!!
}
val perms by lazy {
if (pl.server.pluginManager.getPlugin("Vault") == null) {
throw IllegalStateException("The vault dependency was not found")
}
pl.server.servicesManager.getRegistration(Permission::class.java).provider!!
}
fun withdraw(p: Player, amount: Number, onError: EconomyResponse.() -> Unit): Double {
if (!econ.hasAccount(p)) econ.createPlayerAccount(p)
val success = econ.withdrawPlayer(p, amount.toDouble())
if (!success.transactionSuccess()) {
success.onError()
throw IllegalStateException("Fail on Withdraw: ${success.errorMessage}")
}
return econ.getBalance(p)
}
fun balance(p: Player) = econ.getBalance(p)
fun updateRank(p: Player, type: RankType, level: Int, manual: Boolean = false) {
if (level == 0 && type == RankType.REG) {
updateRank(p, type, 1, manual)
return
}
if (manual) {
val current = Perms.rankFor(p, type)
type.config(current).addPerms.forEach { perms.playerRemove(null, p, it) }
}
Ranks[p, type.rankName] = level
p.effectivePermissions
.filter { it.value && it.permission.startsWith("mdranks.${type.rankName}") }
.forEach { perms.playerRemove(null, p, it.permission) }
if (level == 0) return
val config = type.config(level)
config.addPerms.forEach { perms.playerAdd(null, p, it) }
config.delPerms.forEach { perms.playerRemove(null, p, it) }
perms.playerAdd(null, p, "mdranks.${type.rankName}.$level")
}
}

@ -0,0 +1,30 @@
package pw.hamzantal.mdranks.commands
import org.bukkit.Bukkit
import org.bukkit.command.CommandSender
import org.bukkit.entity.Player
import pw.hamzantal.mdranks.Config
import pw.hamzantal.mdranks.api.Vault
import pw.hamzantal.mdranks.err
import pw.hamzantal.mdranks.general
fun checkBalance(sender: CommandSender, args: Array<String>) {
if (sender is Player) {
if (args.isEmpty()) {
sender.general("balance_format", "balance" to Config.formatC(Vault.balance(sender)))
return
}
} else {
if (args.isEmpty()) sender.err("You must be a player to use this. /bal [player].")
return
}
val target = Bukkit.getPlayer(args.component1()) ?: sender.run {
this.err("player_not_found")
return
}
sender.general(
"other_balance",
"player" to target.name.toUpperCase(),
"balance" to Config.formatC(Vault.balance(target))
)
}

@ -0,0 +1,61 @@
package pw.hamzantal.mdranks.commands
import org.bukkit.Bukkit
import org.bukkit.entity.Player
import pw.hamzantal.mdranks.Config
import pw.hamzantal.mdranks.RankData
import pw.hamzantal.mdranks.api.RankType
import pw.hamzantal.mdranks.api.Vault
import pw.hamzantal.mdranks.err
import pw.hamzantal.mdranks.placeholders
fun rankUpgradePrerequisites(p: Player, next: RankData, type: RankType = RankType.REG): Boolean {
val balance = Vault.balance(p)
val cost = next.cost(p)
if (balance < cost) {
return false
}
Vault.withdraw(p, cost) {
p.err("unknown_error_withdraw", "cost" to Config.formatC(cost))
}
performUpgradeRank(p, next, type)
return true
}
fun performUpgradeRank(p: Player, data: RankData, type: RankType) {
Vault.updateRank(p, type, data.level)
if (type == RankType.REBIRTH) {
Vault.updateRank(p, RankType.REG, 1, true)
Vault.updateRank(p, RankType.PRESTIGE, 0, true)
}
data.commandsOnUpgrade.forEach {
it.executeCommandWithPrefix(p, data)
}
data.broadcast.forEach {
val msg = it.placeholders(p, data)
Bukkit.broadcastMessage(msg)
}
data.msg.forEach {
val msg = it.placeholders(p, data)
p.sendMessage(msg)
}
data.randomCommandList.forEach {
it.executeCommandWithPrefix(p, data)
}
}
fun String.executeCommandWithPrefix(p: Player, data: RankData) {
val cmd = placeholders(p, data, true)
when {
startsWith("[console]") -> Bukkit.dispatchCommand(Bukkit.getConsoleSender(), cmd)
startsWith("[player]") -> p.performCommand(cmd)
startsWith("[op]") -> {
val prev = p.isOp
p.isOp = true
p.performCommand(cmd)
p.isOp = prev
}
else -> throw IllegalStateException("The [commandsOnUpgrade ($this), level (${data.level})] command does not start with a prefix")
}
}

@ -0,0 +1,66 @@
package pw.hamzantal.mdranks.commands
import org.bukkit.command.CommandSender
import org.bukkit.entity.Player
import pw.hamzantal.mdranks.Config
import pw.hamzantal.mdranks.PrestigeConfig
import pw.hamzantal.mdranks.RegularConfig
import pw.hamzantal.mdranks.api.Perms
import pw.hamzantal.mdranks.api.RankType
import pw.hamzantal.mdranks.err
fun onPrestige(p: CommandSender, args: Array<String>) {
if (p !is Player) {
p.err("prestige_not_player")
return
}
val regMax = RegularConfig.max()
if (regMax != Perms.reg(p)) {
p.err(
"prestige_not_max_rankup",
"rankup_display" to RegularConfig(regMax).display,
"rankup" to "$regMax"
)
return
}
if (args.isNotEmpty() && args.first() == "max") return onPrestigeMax(p)
val currentLevel = Perms.prestige(p)
if (currentLevel != 0) {
val current = PrestigeConfig(currentLevel)
if (current.isLast) {
p.err("prestige_max")
return
}
}
val next = PrestigeConfig(currentLevel + 1)
if (!rankUpgradePrerequisites(p, next, RankType.PRESTIGE)) {
p.err("prestige_not_enough_money", "cost" to Config.formatC(next.cost(p)))
}
}
fun onPrestigeMax(p: Player) {
val currentLevel = Perms.prestige(p)
if (currentLevel != 0) {
val current = PrestigeConfig(currentLevel)
if (current.isLast) {
p.err("prestige_max")
return
}
}
var nextLevel = currentLevel + 1
while (nextLevel <= PrestigeConfig.max()) {
val next = PrestigeConfig(nextLevel)
if (!rankUpgradePrerequisites(p, next, RankType.PRESTIGE)) {
if (nextLevel == currentLevel + 1)
p.err("prestige_not_enough_money", "cost" to Config.formatC(next.cost(p)))
return
}
nextLevel++
}
}

@ -0,0 +1,50 @@
package pw.hamzantal.mdranks.commands
import org.bukkit.command.CommandSender
import org.bukkit.entity.Player
import pw.hamzantal.mdranks.Config
import pw.hamzantal.mdranks.RegularConfig
import pw.hamzantal.mdranks.api.Perms
import pw.hamzantal.mdranks.err
fun onRankUp(p: CommandSender, args: Array<String>) {
if (p !is Player) {
p.err("rankup_not_player")
return
}
if (args.isNotEmpty() && args.first() == "max") return onRankupMax(p)
val current = RegularConfig(Perms.reg(p))
if (current.isLast) {
p.err("rankup_max")
return
}
val next = RegularConfig(current.level + 1)
if (!rankUpgradePrerequisites(p, next)) {
p.err("rankup_not_enough_money", "cost" to Config.formatC(next.cost(p)))
}
}
fun onRankupMax(p: Player) {
val currentLevel = Perms.reg(p)
val current = RegularConfig(currentLevel)
if (current.isLast) {
p.err("rankup_max")
return
}
var nextLevel = currentLevel + 1
while (nextLevel <= RegularConfig.max()) {
val next = RegularConfig(nextLevel)
if (!rankUpgradePrerequisites(p, next)) {
if (nextLevel == currentLevel + 1)
p.err("rankup_not_enough_money", "cost" to Config.formatC(next.cost(p)))
return
}
nextLevel++
}
}

@ -0,0 +1,48 @@
package pw.hamzantal.mdranks.commands
import org.bukkit.command.CommandSender
import org.bukkit.entity.Player
import pw.hamzantal.mdranks.*
import pw.hamzantal.mdranks.api.Perms
import pw.hamzantal.mdranks.api.RankType
fun onRebirth(p: CommandSender) {
if (p !is Player) {
p.err("You can only rebirth up as a player")
return
}
val regMax = RegularConfig.max()
if (regMax != Perms.reg(p)) {
p.err(
"rebirth_not_max_rankup",
"rankup_display" to RegularConfig(regMax).display,
"rankup" to "$regMax"
)
return
}
val prMax = PrestigeConfig.max()
if (prMax != Perms.prestige(p)) {
p.err(
"rebirth_not_max_prestige",
"prestige_display" to PrestigeConfig(prMax).display,
"prestige" to "$prMax"
)
return
}
val currentLevel = Perms.rebirth(p)
if (currentLevel != 0) {
val current = RebirthConfig(currentLevel)
if (current.isLast) {
p.err("rebirth_max")
return
}
}
val next = RebirthConfig(currentLevel + 1)
if (!rankUpgradePrerequisites(p, next, RankType.REBIRTH)) {
p.err("rebirth_not_enough_money", "cost" to Config.formatC(next.cost(p)))
}
}

@ -0,0 +1,6 @@
currencyFormat: "$%amt%"
bracketformat: "&7[%display%&7]"
default_prestige: "&fR0"
default_rebirth: "&fP0"

@ -0,0 +1,35 @@
error: "&c[!] &7%s"
general: "&7%s"
success: "&a%s"
error_msgs:
no_access: "You do not have access to this command."
mdranks_usage: "/mdranks [player] [reg|prestige|rebirth] [level]"
player_not_found: "The specified player was not found."
rank_not_found: "The specified rank was not found."
##############
rankup_not_player: "You can only rank up as a player"
rankup_max: "You are at the max level! Use /prestige instead."
rankup_not_enough_money: "You do not have enough money to rankup. The next rankup costs %cost%."
##############
prestige_not_player: "You can only prestige as a player"
prestige_not_max_rankup: "You must be rank %rankup_display% first!" # use rankup_display for max display, or rankup for rankup level (numerical value)
prestige_max: "You are at the max level! Use /rebirth instead."
prestige_not_enough_money: "You do not have enough money to prestige. The next prestige costs %cost%."
##############
rebirth_not_player: "You can only rebirth up as a player"
rebirth_not_max_rankup: "You must be rank %rankup_display% first!" # same placeholder options as prestige_not_max_rankup
rebirth_not_max_prestige: "You must be prestige %prestige_display% first!" # same placeholder options as above, (prestige instead of rankup)
rebirth_max: "You are at the max level!"
rebirth_not_enough_money: "You do not have enough money to rebirth. The next rebirth costs %cost%."
##############
unknown_error_withdraw: "An error occurred while withdrawing %cost%. Ask an administrator if you believe this is an error."
general_msgs:
balance_format: "&a&lBALANCE &8» &7%balance%"
other_balance: "&a&lBALANCE OF %player% &8» &7%balance%"
success_msgs:
update_player_rank_sender: "%player% has been set to %rank% %level%"
update_player_rank_receiver: "You are now %rank% %level%"

@ -0,0 +1,20 @@
name: MDRanks
version: ${project.version}
main: pw.hamzantal.mdranks.MDRanks
api-version: 1.13
authors: [hhhapz]
depend: [Vault, LuckPerms]
description: MDranks Plugin created by hhhapz
website: https://hamzantal.pw
commands:
mdranks:
rankup:
prestige:
rebirth:
rebirthtop:
aliases: [ranktop, prestigetop]
bal:
aliases: [balance, money]
permissions:
mkdranks.admin:
default: op