Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix world ratio oversight #37

Merged
merged 15 commits into from
Sep 4, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,10 @@ Please note that this recipe is only used if **enable-key-items** is set to `tru

### Commands
- **/waystones**: Provides info about the plugin
- **/waystones getkey [ count | player [count] ]***: Gives warpkeys to players
- **/waystones getkey [ count | player [count] ]**: Gives warpkeys to players
- **/waystones ratio [ set <value> [name] [-environment] | remove [name] [-environment] | list ]**: Manages the plugin's ratios

### Permissions
- **waystones.getkey.self** - Allows using the `getkey` command to give yourself a Warp Key
- **waystones.getkey.all** - Allows using the `getkey` command to give any player a Warp Key
- **waystones.ratios** - Allows use of the `ratio` command to manage teleport ratios
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ repositories {
}

dependencies {
compileOnly 'org.spigotmc:spigot-api:1.16.3-R0.1-SNAPSHOT'
compileOnly 'org.spigotmc:spigot-api:1.16.5-R0.1-SNAPSHOT'
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.21'
}

Expand Down
3 changes: 2 additions & 1 deletion src/main/kotlin/xyz/atrius/waystones/Waystones.kt
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ class Waystones : KotlinPlugin() {
InfoCommand,
GetKeyCommand,
ReloadCommand,
ConfigCommand
ConfigCommand,
RatioCommand
)
)
logger.info("Waystones loaded!")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import org.bukkit.command.CommandExecutor
import org.bukkit.command.CommandSender
import xyz.atrius.waystones.data.MultiReferencable
import xyz.atrius.waystones.utility.message
import xyz.atrius.waystones.utility.split

class CommandNamespace(
override vararg val aliases: String
Expand All @@ -31,7 +32,12 @@ class CommandNamespace(
// Execute the given command
for (c in commands) {
if (args[0] in c.aliases) {
c.execute(sender, args.drop(1).toTypedArray())
val (arguments, flags) = args.drop(1).split { !it.startsWith("-") }
c.execute(
sender,
arguments.map(String::toLowerCase).toTypedArray(),
Flags(flags.toSet())
)
return true
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import xyz.atrius.waystones.utility.message

object ConfigCommand : SimpleCommand("config", "conf", "co", "c") {

override fun execute(sender: CommandSender, args: Array<String>) {
override fun execute(sender: CommandSender, args: Array<String>, flags: Flags) {
// Permissions Check
if (!sender.hasPermission("waystones.config"))
return sender.message(localization["command-no-permission"])
Expand Down
11 changes: 11 additions & 0 deletions src/main/kotlin/xyz/atrius/waystones/commands/Flags.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package xyz.atrius.waystones.commands

class Flags(
values: Set<String>
) : Set<String> by (values.map {
it.toLowerCase().removePrefix("-")
}.toSet()) {

operator fun contains(values: Collection<String>): Boolean =
values.map(String::toLowerCase).any(::contains)
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ object GetKeyCommand : SimpleCommand("getkey", "gk", "key", "k") {
return player to amount
}

override fun execute(sender: CommandSender, args: Array<String>) {
override fun execute(sender: CommandSender, args: Array<String>, flags: Flags) {
// Set Amount and Player to give WarpKeys to
val (player, amount) = getPlayerAndAmount(
sender as? Player,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,6 @@ object InfoCommand : SimpleCommand("info", "i") {
|&7---------------&b-&d-&f-&d-&b-&7---------------
""".trimMargin().translateColors()

override fun execute(sender: CommandSender, args: Array<String>) =
override fun execute(sender: CommandSender, args: Array<String>, flags: Flags) =
sender.sendMessage(infoMsg)
}
84 changes: 84 additions & 0 deletions src/main/kotlin/xyz/atrius/waystones/commands/RatioCommand.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package xyz.atrius.waystones.commands

import org.bukkit.World
import org.bukkit.command.CommandSender
import org.bukkit.command.ConsoleCommandSender
import org.bukkit.entity.Player
import xyz.atrius.waystones.localization
import xyz.atrius.waystones.service.WorldRatioService
import xyz.atrius.waystones.utility.message
import xyz.atrius.waystones.utility.toInt

object RatioCommand : SimpleCommand("ratio", "ra", "r") {

override fun execute(sender: CommandSender, args: Array<String>, flags: Flags) {
if (!sender.hasPermission("waystones.ratios"))
return sender.message(localization["command-no-permission"])
if (args.isEmpty())
return sender.message(localization["command-no-arguments"])
val environment = setOf("environment", "env", "e") in flags
val world = (sender as? Player)?.world
when (args[0]) {
in setOf("s", "set") -> set(sender, args, world, environment)
in setOf("r", "rem", "remove") -> remove(sender, args, world, environment)
in setOf("l", "list") -> list(sender)
else -> sender.message(localization["command-ratio-invalid-command", args[0]])
}
}

private fun set(sender: CommandSender, args: Array<String>, world: World?, environment: Boolean) {
if (args.size < 2)
return sender.message(localization["command-no-arguments"])
val selection = (args.getOrNull(2)
?: if (environment) world?.environment?.name else world?.name)?.capitalize()
val message = if (args.size > 2)
localization["command-ratio-world-not-found", environment.toInt(), args[2]]
else
localization["command-ratio-bad-sender"]
val added = WorldRatioService.add(
selection?.toLowerCase()
?: return sender.message(message),
environment,
args[1].toDoubleOrNull()
?: return sender.message(localization["command-ratio-bad-ratio", args[1]])
)
sender.message(
if (added)
localization["command-ratio-added-successfully", environment.toInt(), selection, args[1]]
else
localization["command-ratio-addition-failed", selection]
)
}

private fun remove(sender: CommandSender, args: Array<String>, world: World?, environment: Boolean) {
if (args.size < 2 && sender is ConsoleCommandSender)
return sender.message(localization["command-no-arguments"])
val selection = (args.getOrNull(1)
?: if (environment) world?.environment?.name else world?.name)?.capitalize()
val message = if (args.size > 1)
localization["command-ratio-world-not-found", environment.toInt(), args[1]]
else
localization["command-ratio-bad-sender"]
val added = WorldRatioService.remove(
selection?.toLowerCase()
?: return sender.message(message),
environment
)
sender.message(
if (added)
localization["command-ratio-removed-successfully", environment.toInt(), selection]
else
localization["command-ratio-removal-failed", selection]
)
}

private fun list(sender: CommandSender) {
if (WorldRatioService.isEmpty())
return sender.message(localization["command-ratio-no-ratios"])
sender.message("&7--------- &dWaystones Ratios &7----------&r")
// Display each config property
for ((item, ratio) in WorldRatioService)
sender.message("&f$item&f: &b$ratio")
sender.message("&7-----------------------------------")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import xyz.atrius.waystones.localization
import xyz.atrius.waystones.utility.message

object ReloadCommand : SimpleCommand("reload", "rl") {

override fun execute(sender: CommandSender, args: Array<String>) {
if (!sender.hasPermission("waystones.reload"))
return sender.message(localization["command-no-permission"])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ abstract class SimpleCommand(
}
}

abstract fun execute(sender: CommandSender, args: Array<String>)
abstract fun execute(sender: CommandSender, args: Array<String>, flags: Flags)
}
6 changes: 3 additions & 3 deletions src/main/kotlin/xyz/atrius/waystones/data/JsonFile.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ import xyz.atrius.waystones.plugin
import java.io.File
import java.io.FileReader
import java.nio.file.Files
import java.nio.file.StandardOpenOption.CREATE
import java.nio.file.StandardOpenOption.WRITE

open class JsonFile<T>(name: String) {
private val file = File(plugin.dataFolder, "$name.json")
Expand All @@ -23,7 +21,9 @@ open class JsonFile<T>(name: String) {
data = json.fromJson(FileReader(file), HashMap<String, T>()::class.java)
}

fun save() {
fun save(forceLowercase: Boolean = false) {
if (forceLowercase)
data.mapKeysTo(data) { (key) -> key.toLowerCase() }
val json = json.toJson(data)
Files.write(file.toPath(), json.toByteArray())
}
Expand Down
39 changes: 37 additions & 2 deletions src/main/kotlin/xyz/atrius/waystones/service/WorldRatioService.kt
Original file line number Diff line number Diff line change
@@ -1,10 +1,45 @@
package xyz.atrius.waystones.service

import org.bukkit.Bukkit
import org.bukkit.World
import xyz.atrius.waystones.data.JsonFile

object WorldRatioService : JsonFile<Double>("ratios") {
object WorldRatioService : JsonFile<Double>("ratios"), Iterable<Map.Entry<String, Double>> {

operator fun get(world: World): Double =
data.getOrDefault(world.name, 1.0)
data["name${world.name.toLowerCase()}"]
?: data[world.environment.name.toLowerCase()]
?: 1.0

fun add(item: String, asEnvironment: Boolean, ratio: Double): Boolean {
if (!asEnvironment) {
val world = Bukkit.getWorld(item)
if (world != null)
data["name:${world.name.toLowerCase()}"] = ratio
return world != null
}
val env = World.Environment.values().any { it.name == item.toUpperCase() }
if (env)
data[item.toLowerCase()] = ratio
return env
}

fun remove(item: String, asEnvironment: Boolean): Boolean {
if (!asEnvironment) {
val world = Bukkit.getWorld(item)
if (world != null)
data.remove("name:${world.name.toLowerCase()}")
return world != null
}
val env = World.Environment.values().any { it.name == item.toUpperCase() }
if (env)
data.remove(item.toLowerCase())
return env
}

fun isEmpty(): Boolean =
data.isEmpty()

override fun iterator(): Iterator<Map.Entry<String, Double>> =
data.iterator()
}
4 changes: 2 additions & 2 deletions src/main/kotlin/xyz/atrius/waystones/utility/Location.kt
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ fun Location.rotateY(angle: Double, amp: Double = 1.0) =
add(Vector(cos(angle) * amp, 2.0, sin(angle) * amp))

fun Location.sameDimension(other: Location) =
world == other.world ?: false
world == other.world

/*
* Synchronizes the world coordinates between 2 trans-dimensional locations. This is
Expand All @@ -76,7 +76,7 @@ fun Location.synchronize(other: Location): TeleportType =
if (sameDimension(other.world)) Normal else Interdimensional(world, other.world)

fun Location.sameDimension(world: World?) =
world == this.world ?: false
world == this.world

fun Location.playSound(sound: Sound, volume: Float = 1f, pitch: Float = 1f) = Bukkit.getOnlinePlayers()
.forEach { if (it.world == world) it.playSound(this, sound, volume, pitch) }
Expand Down
15 changes: 14 additions & 1 deletion src/main/kotlin/xyz/atrius/waystones/utility/String.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,17 @@ fun String.splitMultiline() =
split("\n").toTypedArray()

// Glues a list together into a single string
fun <T> List<T>.glue(): String = joinToString("")
fun <T> List<T>.glue(): String = joinToString("")

inline fun <reified T> Collection<T>.split(splitter: (T) -> Boolean): Pair<Array<T>, Array<T>> {
val match = mutableListOf<T>()
val rest = mutableListOf<T>()
for (item in this)
if (splitter(item)) match += item else rest += item
return match.toTypedArray() to rest.toTypedArray()
}

operator fun <T> List<T>.contains(values: Set<T>): Boolean =
values.any(::contains)

fun Boolean.toInt(): Int = if (this) 1 else 0
11 changes: 11 additions & 0 deletions src/main/resources/locale-en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,17 @@ command-config-view: "&7[&dWaystones&7] &f{0}&7: &b{1}"
command-config-set: "&7[&dWaystones&7] &bSuccessfully updated &e{0} &bto &a{1}!"
command-config-set-fail: "&7[&dWaystones&7] &cFailed to update setting {0}."
command-give-key: "&7[&dWaystones&7]&f Gave &bx{0}&r {0,choice,1#WarpKey|1<WarpKeys} to &a{1}&r"
command-reload: "&7[&dWaystones&7] &aReloaded config!"
command-ratio-invalid-command: "&7[&dWaystones&7] &cInvalid subcommand: {0}"
command-no-arguments: "&7[&dWaystones&7] &cNo arguments were provided for the subcommand."
command-ratio-bad-sender: "&7[&dWaystones&7] &cConsole users must supply a world or environment to use this command."
command-ratio-world-not-found: "&7[&dWaystones&7] &cThe {0,choice,0#world|1#environment} {1} could not be found."
command-ratio-added-successfully: "&7[&dWaystones&7] &aThe {0,choice,0#world|1#environment} {1} was successfully set!"
command-ratio-addition-failed: "&7[&dWaystones&7] &cFailed to add {0} to the config."
command-ratio-removed-successfully: '&7[&dWaystones&7] &aThe {0,choice,0#world|1#environment} {1} was successfully removed!'
command-ratio-removal-failed: "&7[&dWaystones&7] &cFailed to remove {0} from the config."
command-ratio-no-ratios: "&7[&dWaystones&7] &bNo ratios currently set!"
command-ratio-bad-ratio: "&7[&dWaystones&7] &cImproper ratio provided: {0}"
command-reload-config: "&7[&dWaystones&7] &aReloaded config!"
command-reload-advancements: "&7[&dWaystones&7] &aReloaded advancements!"
command-reload-failed: "&7[&dWaystones&7] &cFailed to reload. Invalid argument: {0}"
Expand Down
7 changes: 4 additions & 3 deletions src/main/resources/ratios.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"world": 1,
"world_nether": 8,
"world_end": 1
"normal": 1,
"nether": 8,
"the_end": 1,
"custom:limbo": -1
}