-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add persistent cooldowns + yaml wrapper
- Loading branch information
Showing
10 changed files
with
311 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package com.mattmx.ktgui.cooldown | ||
|
||
import java.time.Duration | ||
|
||
interface CoolDown<T : Any> { | ||
|
||
fun test(user: T) : Boolean | ||
|
||
fun removeAnyUsers(vararg user: Any) = user.forEach { removeUser(it) } | ||
|
||
fun removeUser(user: Any) | ||
|
||
fun millisRemaining(user: T) : Long | ||
|
||
fun durationRemaining(user: T) = Duration.ofMillis(millisRemaining(user)) | ||
|
||
} |
30 changes: 30 additions & 0 deletions
30
api/src/main/kotlin/com/mattmx/ktgui/cooldown/PersistentCoolDown.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package com.mattmx.ktgui.cooldown | ||
|
||
import java.time.Duration | ||
|
||
open class PersistentCoolDown<T : Any>( | ||
duration: Duration, | ||
val impl: Impl | ||
) : CoolDown<T> { | ||
var shouldRefreshIfAlreadyOnCoolDown = false | ||
private val expire = duration.toMillis() | ||
|
||
override fun test(user: T): Boolean { | ||
val currentMillis = System.currentTimeMillis() | ||
val returnValue = impl.get(user)?.let { currentMillis - it >= expire } ?: true | ||
|
||
if (returnValue || shouldRefreshIfAlreadyOnCoolDown) { | ||
impl.set(user, currentMillis) | ||
} | ||
|
||
return returnValue | ||
} | ||
|
||
override fun removeUser(user: Any) =impl.set(user, null) | ||
override fun millisRemaining(user: T) = impl.get(user) ?: 0L | ||
|
||
interface Impl { | ||
fun set(user: Any, lastExecuted: Long?) | ||
fun get(user: Any) : Long? | ||
} | ||
} |
32 changes: 32 additions & 0 deletions
32
api/src/main/kotlin/com/mattmx/ktgui/cooldown/YamlPersistentCoolDown.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package com.mattmx.ktgui.cooldown | ||
|
||
import com.mattmx.ktgui.scheduling.asyncRepeat | ||
import com.mattmx.ktgui.utils.minutes | ||
import org.bukkit.configuration.file.FileConfiguration | ||
import org.bukkit.configuration.file.YamlConfiguration | ||
import org.bukkit.configuration.file.YamlConstructor | ||
import java.io.File | ||
import java.time.Duration | ||
|
||
open class YamlPersistentCoolDown<T : Any>( | ||
path: String, | ||
file: File, | ||
duration: Duration, | ||
val yaml: YamlConfiguration = | ||
if (file.exists()) YamlConfiguration.loadConfiguration(file) | ||
else YamlConfiguration() | ||
) : PersistentCoolDown<T>(duration, object : Impl { | ||
override fun set(user: Any, lastExecuted: Long?) { | ||
yaml.set("$path.$user", lastExecuted) | ||
} | ||
|
||
override fun get(user: Any): Long? { | ||
return yaml.getString("$path.$user")?.toLongOrNull() | ||
} | ||
}) { | ||
init { | ||
asyncRepeat(5.minutes) { | ||
yaml.save(file) | ||
} | ||
} | ||
} |
4 changes: 4 additions & 0 deletions
4
api/src/main/kotlin/com/mattmx/ktgui/yaml/FileConfigurationMap.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
package com.mattmx.ktgui.yaml | ||
|
||
class FileConfigurationMap { | ||
} |
39 changes: 39 additions & 0 deletions
39
api/src/main/kotlin/com/mattmx/ktgui/yaml/FileConfigurationWrapper.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package com.mattmx.ktgui.yaml | ||
|
||
import org.bukkit.configuration.file.YamlConfiguration | ||
import java.io.File | ||
import java.time.Duration | ||
import java.util.* | ||
|
||
class FileConfigurationWrapper( | ||
val file: File, | ||
val autoSaveOptions: Options = Options() | ||
) : YamlConfiguration() { | ||
var lastAutoSaved = System.currentTimeMillis() | ||
var isDirty: Boolean = false | ||
private set | ||
|
||
init { | ||
load(file) | ||
} | ||
|
||
fun markDirty() { | ||
isDirty = true | ||
} | ||
|
||
fun tickAutoSave() : Boolean { | ||
if (!shouldSave()) return false | ||
save() | ||
return true | ||
} | ||
|
||
fun shouldSave() = isDirty | ||
&& autoSaveOptions.autoSaveTicks.isPresent | ||
&& System.currentTimeMillis() - lastAutoSaved >= autoSaveOptions.autoSaveTicks.get().toMillis() | ||
|
||
fun save() = save(file) | ||
|
||
class Options { | ||
var autoSaveTicks = Optional.of(Duration.ofSeconds(30L)) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package com.mattmx.ktgui.yaml | ||
|
||
import com.mattmx.ktgui.commands.declarative.runs | ||
import com.mattmx.ktgui.utils.not | ||
import org.bukkit.Location | ||
import org.bukkit.entity.Player | ||
|
||
class Warp( | ||
val id: String, | ||
var displayName: String, | ||
var location: Location, | ||
var directCommandWarp: Boolean = true | ||
) { | ||
|
||
fun registerDirectWarpCommand() { | ||
(id).runs<Player> { | ||
teleport(sender) | ||
} | ||
} | ||
|
||
fun teleport(player: Player) { | ||
player.sendMessage(!WarpsPlugin.get().msg_teleporting) | ||
player.teleportAsync(location) | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
package com.mattmx.ktgui.yaml | ||
|
||
import com.mattmx.ktgui.GuiManager | ||
import com.mattmx.ktgui.commands.declarative.arg.impl.booleanArgument | ||
import com.mattmx.ktgui.commands.declarative.arg.impl.multiChoiceArgument | ||
import com.mattmx.ktgui.commands.declarative.arg.impl.stringArgument | ||
import com.mattmx.ktgui.commands.declarative.div | ||
import com.mattmx.ktgui.commands.declarative.invoke | ||
import com.mattmx.ktgui.commands.declarative.runs | ||
import com.mattmx.ktgui.utils.not | ||
import com.mattmx.ktgui.utils.placeholders | ||
import org.bukkit.entity.Player | ||
import org.bukkit.plugin.java.JavaPlugin | ||
|
||
class WarpsPlugin : JavaPlugin() { | ||
val warps by yaml { | ||
getKeys(false) | ||
.mapNotNull { k -> getObject(k, Warp::class.java)?.let { k to it } } | ||
.toMap(HashMap()) | ||
} | ||
|
||
val lang by yaml() | ||
val msg_set_warp: String by lang("&aSet warp %warp_id% to location (%x%, %y%, %z%, %pitch%, %yaw%) in world '%world%'") | ||
val msg_del_warp: String by lang("&aDeleted warp %warp_id%") | ||
val msg_invalid_warp_id: String by lang("&cInvalid warp ID") | ||
val msg_teleporting: String by lang("&aTeleporting...") | ||
val msg_modify_warp_display: String by lang("&aSet display of %warp_id% to %warp_display%") | ||
val msg_modify_warp_location: String by lang("&aMoved display of %warp_id% to your position") | ||
val msg_modify_warp_directCommandWarp: String by lang("&aSet direct command of %warp_id% to %warp_directCommandWarp") | ||
|
||
override fun onEnable() { | ||
instance = this | ||
GuiManager.init(this) | ||
|
||
val newWarpId by stringArgument() | ||
newWarpId matches "[0-9a-z_]{3,16}".toRegex(RegexOption.IGNORE_CASE) | ||
newWarpId invalid { reply(!msg_invalid_warp_id) } | ||
|
||
("set-warp" / newWarpId).runs<Player> { | ||
val warp = Warp( | ||
newWarpId(), | ||
newWarpId(), | ||
sender.location.clone() | ||
) | ||
|
||
warps[warp.id] = warp | ||
|
||
reply(msg_set_warp placeholders sender) | ||
} register this | ||
|
||
val existingWarp by multiChoiceArgument(warps) | ||
existingWarp invalid { reply(!msg_invalid_warp_id) } | ||
|
||
("modify-warp" / existingWarp) { | ||
val display by stringArgument() | ||
("display" / display).runs<Player> { | ||
existingWarp().displayName = display() | ||
reply(!msg_modify_warp_display) | ||
} | ||
|
||
("move-here").runs<Player> { | ||
existingWarp().location = sender.location.clone() | ||
reply(!msg_modify_warp_location) | ||
} | ||
|
||
val enabled by booleanArgument() | ||
("direct-command" / enabled).runs<Player> { | ||
val newState = enabled() | ||
existingWarp().directCommandWarp = newState | ||
reply(!msg_modify_warp_directCommandWarp) | ||
} description "Should this warp have a direct command? e.g /warp spawn -> /spawn" | ||
} | ||
|
||
("warp" / existingWarp).runs<Player> { | ||
existingWarp().teleport(sender) | ||
} register this | ||
|
||
("del-warp" / existingWarp).runs<Player> { | ||
reply(msg_del_warp placeholders sender) | ||
} register this | ||
|
||
warps.values | ||
.filter(Warp::directCommandWarp) | ||
.forEach(Warp::registerDirectWarpCommand) | ||
} | ||
|
||
companion object { | ||
private lateinit var instance: WarpsPlugin | ||
fun get() = instance | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package com.mattmx.ktgui.yaml | ||
|
||
import org.bukkit.plugin.java.JavaPlugin | ||
import java.io.File | ||
import kotlin.properties.ReadOnlyProperty | ||
import kotlin.reflect.KProperty | ||
|
||
fun JavaPlugin.yaml() : ReadOnlyProperty<Any?, FileConfigurationWrapper> { | ||
var instance: FileConfigurationWrapper? = null | ||
return ReadOnlyProperty { ref: Any?, prop: KProperty<*> -> | ||
if (instance != null) return@ReadOnlyProperty instance!! | ||
|
||
instance = yaml(prop.name + ".yml") | ||
return@ReadOnlyProperty instance!! | ||
} | ||
} | ||
|
||
fun <T : Any> JavaPlugin.yaml(get: FileConfigurationWrapper.() -> T) : ReadOnlyProperty<Any?, T> { | ||
var yamlFile: FileConfigurationWrapper? = null | ||
var instance: T? = null | ||
|
||
// todo replace with ReadWriteProperty, list/map wrapper object | ||
return ReadOnlyProperty { ref: Any?, prop: KProperty<*> -> | ||
if (yamlFile != null) | ||
return@ReadOnlyProperty instance!! | ||
|
||
yamlFile = yaml(prop.name + ".yml") | ||
instance = get(yamlFile!!) | ||
return@ReadOnlyProperty instance!! | ||
} | ||
} | ||
|
||
fun JavaPlugin.yaml(path: String): FileConfigurationWrapper { | ||
val file = File("$dataFolder/path") | ||
|
||
if (!file.exists()) { | ||
kotlin.runCatching { | ||
saveResource(path, false) | ||
}.getOrNull() ?: file.createNewFile() | ||
} | ||
|
||
return FileConfigurationWrapper(file) | ||
} | ||
|
||
inline operator fun <reified T : Any> FileConfigurationWrapper.getValue(thisRef: Any?, property: KProperty<*>): T? { | ||
return getObject(pathFromPropertyName(property.name), T::class.java) | ||
} | ||
|
||
inline operator fun <reified T : Any> FileConfigurationWrapper.invoke(default: T) = | ||
ReadOnlyProperty { thisRef: Any?, prop -> | ||
val path = pathFromPropertyName(prop.name) | ||
val inConfig = getObject(path, T::class.java) | ||
return@ReadOnlyProperty if (inConfig == null) { | ||
set(path, default) | ||
default | ||
} else inConfig | ||
} | ||
|
||
fun pathFromPropertyName(name: String) = name.replace("_", ".") |