forked from chanbakjsd/TerraOceanPlugin
kotlin: refactor entire plugin to use mc-kutils, use an object-based configuration system, and convert to okhttp
parent
caf4dbeb4f
commit
45297d2c64
@ -0,0 +1,49 @@
|
|||||||
|
package com.terraocean.plugin
|
||||||
|
|
||||||
|
import hazae41.minecraft.kutils.bukkit.ConfigFile
|
||||||
|
import hazae41.minecraft.kutils.get
|
||||||
|
import java.io.File
|
||||||
|
import kotlin.reflect.KProperty
|
||||||
|
|
||||||
|
object Settings : TerraConfig(instance.dataFolder["config.yml"]) {
|
||||||
|
val socketURL by item("socket.url", "ws://localhost:8080/ws")
|
||||||
|
}
|
||||||
|
|
||||||
|
object Strings : TerraConfig(instance.dataFolder["strings.yml"]) {
|
||||||
|
val voteNew by message("vote.new")
|
||||||
|
val voteWarn by message("vote.warn")
|
||||||
|
val voteTimeout by message("vote.timeout")
|
||||||
|
|
||||||
|
val kickVoiceChannel by message("kick.voiceChannelLeave")
|
||||||
|
val voteKick by message("kick.voteKick")
|
||||||
|
val kickRemovedFromWhitelist by message("kick.removedFromWhitelist")
|
||||||
|
}
|
||||||
|
|
||||||
|
open class TerraConfig(file: File) : ConfigFile(file) {
|
||||||
|
inner class message(val path: String) {
|
||||||
|
init {
|
||||||
|
if (!config.contains(path)) {
|
||||||
|
set(path, "Message not found: $path")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
operator fun getValue(ref: Any?, prop: KProperty<*>): String =
|
||||||
|
config.getString(path, "Message not found: $path")!!
|
||||||
|
|
||||||
|
operator fun setValue(ref: Any?, prop: KProperty<*>, value: String) = set(path, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class item<T>(private val path: String, private val default: T) {
|
||||||
|
init {
|
||||||
|
if (!config.contains(path)) {
|
||||||
|
set(path, default)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
operator fun getValue(ref: Any?, prop: KProperty<*>): T =
|
||||||
|
config.get(path, default) as? T ?: run {
|
||||||
|
throw IllegalStateException("Path $path [value ${config["path"]}]] does not conform to type required")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,26 +1,21 @@
|
|||||||
package com.terraocean.plugin
|
package com.terraocean.plugin
|
||||||
|
|
||||||
|
import com.terraocean.plugin.afk.onPlayerMovement
|
||||||
import com.terraocean.plugin.bridge.establishConnection
|
import com.terraocean.plugin.bridge.establishConnection
|
||||||
import io.ktor.util.KtorExperimentalAPI
|
import hazae41.minecraft.kutils.bukkit.*
|
||||||
import kotlinx.coroutines.MainScope
|
|
||||||
import kotlinx.coroutines.coroutineScope
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import org.bukkit.plugin.java.JavaPlugin
|
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
internal lateinit var instance: TerraOceanPlugin
|
internal lateinit var instance: TerraOceanPlugin
|
||||||
|
|
||||||
class TerraOceanPlugin: JavaPlugin() {
|
class TerraOceanPlugin: BukkitPlugin() {
|
||||||
@KtorExperimentalAPI
|
|
||||||
override fun onEnable() {
|
override fun onEnable() {
|
||||||
instance = this
|
instance = this
|
||||||
config.load(File("plugin/terraocean.yml"))
|
Strings // Initialize the config classes
|
||||||
MainScope().launch {
|
Settings
|
||||||
|
|
||||||
|
listen(callback = ::onPlayerMovement)
|
||||||
|
|
||||||
|
schedule(async = true) {
|
||||||
establishConnection()
|
establishConnection()
|
||||||
}
|
}
|
||||||
logger.info("TerraOcean plugin has started.")
|
|
||||||
}
|
|
||||||
override fun onDisable() {
|
|
||||||
logger.info("TerraOcean plugin has stopped.")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
package com.terraocean.plugin.bridge
|
package com.terraocean.plugin.bridge
|
||||||
|
|
||||||
import io.ktor.http.cio.websocket.send
|
import com.terraocean.plugin.instance
|
||||||
import kotlinx.coroutines.MainScope
|
import hazae41.minecraft.kutils.bukkit.schedule
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
|
|
||||||
fun reportPlayerActivity(username: String, activity: Long) {
|
fun reportPlayerActivity(username: String, activity: Long) {
|
||||||
MainScope().launch {
|
instance.schedule(async = true) {
|
||||||
webSocketSession.send("active $username $activity")
|
socket.send("active $username $activity")
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,84 +1,75 @@
|
|||||||
package com.terraocean.plugin.bridge
|
package com.terraocean.plugin.bridge
|
||||||
|
|
||||||
|
import com.terraocean.plugin.Settings
|
||||||
|
import com.terraocean.plugin.Strings
|
||||||
import com.terraocean.plugin.instance
|
import com.terraocean.plugin.instance
|
||||||
import io.ktor.client.HttpClient
|
import hazae41.minecraft.kutils.bukkit.info
|
||||||
import io.ktor.client.features.websocket.DefaultClientWebSocketSession
|
import hazae41.minecraft.kutils.bukkit.warning
|
||||||
import io.ktor.client.features.websocket.WebSockets
|
import okhttp3.*
|
||||||
import io.ktor.client.features.websocket.ws
|
|
||||||
import io.ktor.http.cio.websocket.Frame
|
|
||||||
import io.ktor.http.cio.websocket.readText
|
|
||||||
import io.ktor.util.KtorExperimentalAPI
|
|
||||||
import org.bukkit.Bukkit
|
import org.bukkit.Bukkit
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
@KtorExperimentalAPI
|
val client = OkHttpClient.Builder()
|
||||||
val client = HttpClient {
|
.readTimeout(0, TimeUnit.MILLISECONDS)
|
||||||
install(WebSockets)
|
.build()
|
||||||
}
|
|
||||||
|
|
||||||
lateinit var webSocketSession: DefaultClientWebSocketSession
|
lateinit var socket: WebSocket
|
||||||
|
|
||||||
@KtorExperimentalAPI
|
fun establishConnection() {
|
||||||
suspend fun establishConnection() {
|
instance.info("establishing connection to ${Settings.socketURL}...")
|
||||||
client.ws(
|
val request = Request.Builder()
|
||||||
host = "localhost",
|
.url(Settings.socketURL)
|
||||||
port = 8080,
|
.build()
|
||||||
path = "/ws"
|
|
||||||
) {
|
socket = client.newWebSocket(request, WSListener())
|
||||||
webSocketSession = this
|
|
||||||
while (true) {
|
|
||||||
val message = incoming.receive()
|
|
||||||
if (message is Frame.Text) {
|
|
||||||
processMessage(message.readText().split(' '))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun processMessage(msg: List<String>) {
|
fun processMessage(msg: List<String>) {
|
||||||
when (msg[0]) {
|
when (msg[0]) {
|
||||||
"leave" -> {
|
"leave" -> {
|
||||||
Bukkit.getPlayer(msg[1])?.kickPlayer(
|
Bukkit.getPlayer(msg[1])?.kickPlayer(Strings.kickVoiceChannel)
|
||||||
instance.config.getString("voicechannel")
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
"vote" -> {
|
"vote" -> {
|
||||||
for (p in Bukkit.getOnlinePlayers()) {
|
Bukkit.getOnlinePlayers().forEach {
|
||||||
p.sendMessage(
|
it.sendMessage(Strings.voteNew)
|
||||||
instance.config.getString("vote.new") ?: "Message not found: vote.new"
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"votewarn" -> {
|
"votewarn" -> {
|
||||||
Bukkit.getPlayer(msg[1])?.sendMessage(
|
Bukkit.getPlayer(msg[1])?.sendMessage(Strings.voteWarn)
|
||||||
instance.config.getString("vote.warn") ?: "Message not found: vote.warn"
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
"votetimeout" -> {
|
"votetimeout" -> {
|
||||||
Bukkit.getPlayer(msg[1])?.kickPlayer(
|
Bukkit.getPlayer(msg[1])?.kickPlayer(Strings.voteTimeout)
|
||||||
instance.config.getString("vote.timeout") ?: "Message not found: vote.timeout"
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
"kick" -> {
|
"kick" -> {
|
||||||
Bukkit.getPlayer(msg[1])?.kickPlayer(
|
Bukkit.getPlayer(msg[1])?.kickPlayer(Strings.voteKick)
|
||||||
instance.config.getString("kick.votekick") ?: "Message not found: kick.votekick"
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
"whitelistadd" -> {
|
"whitelistadd" -> {
|
||||||
instance.server.run {
|
instance.server.run {
|
||||||
getOfflinePlayer(msg[1]).isWhitelisted = true
|
getOfflinePlayer(msg[1]).isWhitelisted = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"whitelistremove" -> {
|
"whitelistremove" -> {
|
||||||
instance.server.run {
|
instance.server.run {
|
||||||
getPlayer(msg[1])?.kickPlayer(
|
getPlayer(msg[1])?.kickPlayer(Strings.kickRemovedFromWhitelist)
|
||||||
instance.config.getString("kick.removedFromWhitelist") ?:
|
|
||||||
"Message not found: kick.removedFromWhitelist"
|
|
||||||
)
|
|
||||||
getOfflinePlayer(msg[1]).isWhitelisted = false
|
getOfflinePlayer(msg[1]).isWhitelisted = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> instance.logger.warning(
|
else -> instance.warning(
|
||||||
"Potentially out of date plugin. Unknown message: " + msg.joinToString(" ")
|
"Potentially out of date plugin. Unknown message: " + msg.joinToString(" ")
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class WSListener: WebSocketListener() {
|
||||||
|
override fun onMessage(webSocket: WebSocket, text: String) {
|
||||||
|
processMessage(text.split(' '))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onOpen(webSocket: WebSocket, response: Response) {
|
||||||
|
instance.info("Socket connection established to $response.")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
|
||||||
|
TODO("Automatic reconnection")
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue