diff --git a/README.md b/README.md index 16c7998..8e8a5e2 100644 --- a/README.md +++ b/README.md @@ -2,4 +2,4 @@ Static MiniMessage based tablist plugin for servers like Auth and Limbo in Galaxy Network! -Placeholders not supported, this is designed to be the most lightweight it can possibily be. +Placeholders are now supported, you can choose to enable or disable that though diff --git a/build.gradle.kts b/build.gradle.kts index a283686..9e94b0c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -5,7 +5,7 @@ plugins { } group = "xyz.lncvrt" -version = "1.0.2" +version = "1.1.0" repositories { mavenCentral() @@ -15,10 +15,14 @@ repositories { maven("https://oss.sonatype.org/content/groups/public/") { name = "sonatype" } + maven("https://repo.extendedclip.com/releases/") { + name = "placeholderapi" + } } dependencies { compileOnly("io.papermc.paper:paper-api:1.20.1-R0.1-SNAPSHOT") + compileOnly("me.clip:placeholderapi:2.11.6") implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") implementation("org.incendo:cloud-paper:2.0.0-beta.10") implementation("org.incendo:cloud-kotlin-extensions:2.0.0") @@ -34,10 +38,10 @@ tasks.build { } tasks.processResources { - val props = mapOf("version" to version) + val props = mapOf("version" to project.version) inputs.properties(props) filteringCharset = "UTF-8" - filesMatching("plugin.yml") { + filesMatching(listOf("paper-plugin.yml", "config.yml")) { expand(props) } } diff --git a/src/main/kotlin/xyz/lncvrt/galaxytab/GalaxyTab.kt b/src/main/kotlin/xyz/lncvrt/galaxytab/GalaxyTab.kt index c9867f2..d943a20 100644 --- a/src/main/kotlin/xyz/lncvrt/galaxytab/GalaxyTab.kt +++ b/src/main/kotlin/xyz/lncvrt/galaxytab/GalaxyTab.kt @@ -1,39 +1,147 @@ package xyz.lncvrt.galaxytab +import me.clip.placeholderapi.PlaceholderAPI import net.kyori.adventure.text.Component import net.kyori.adventure.text.minimessage.MiniMessage import org.bukkit.configuration.file.FileConfiguration +import org.bukkit.configuration.file.YamlConfiguration import org.bukkit.entity.Player -import org.bukkit.event.EventHandler import org.bukkit.event.Listener -import org.bukkit.event.player.PlayerJoinEvent import org.bukkit.plugin.java.JavaPlugin import xyz.lncvrt.galaxytab.commands.GalaxyTabCommand +import xyz.lncvrt.galaxytab.events.PlayerJoinEventListener +import java.io.File +import java.io.InputStreamReader import java.lang.String +import kotlin.Exception +import kotlin.Int +import kotlin.Suppress +import kotlin.let + class GalaxyTab : JavaPlugin(), Listener { private val miniMessage = MiniMessage.miniMessage() - var configFile: FileConfiguration? = null + var mainConfig: FileConfiguration? = null + var usePlaceholderAPI = false + var placeholderTask: Int? = null override fun onEnable() { instance = this - saveDefaultConfig() - configFile = config - server.pluginManager.registerEvents(this, this) + logger.info("Loading plugin") + + //misc + loadConfig() + + //events + server.pluginManager.registerEvents(PlayerJoinEventListener(), this) + + //commands GalaxyTabCommand() + + if (usePlaceholderAPI) { + startPlaceholderTask() + } } - @EventHandler - fun onPlayerJoinEvent(event: PlayerJoinEvent) { - setTab(event.player) + fun loadConfig() { + if (!dataFolder.exists()) { + dataFolder.mkdirs() + } + + val configFile = File(dataFolder, "config.yml") + if (!configFile.exists()) { + saveResource(configFile.name, false) + logger.info("${configFile.name} doesn't exist, creating it...") + } + mainConfig = YamlConfiguration() + mainConfig?.load(configFile) + updateYamlFile(configFile) + + logger.info("Loaded config!") + hookPlaceholderAPI() + } + + fun hookPlaceholderAPI() { + if (mainConfig?.getBoolean("placeholderapi-hook") == true) { + if (server.pluginManager.isPluginEnabled("PlaceholderAPI")) { + usePlaceholderAPI = true + logger.info("Hooked into PlaceholderAPI!") + } else { + logger.warning("Failed to hook into PlaceholderAPI") + } + } else { + usePlaceholderAPI = false + } } fun setTab(player: Player) { - val header: Component = miniMessage.deserialize(String.join("\n", configFile?.getStringList("header"))) - val footer: Component = miniMessage.deserialize(String.join("\n", configFile?.getStringList("footer"))) + val headerRaw = String.join("\n", mainConfig?.getStringList("header") ?: listOf()) + val footerRaw = String.join("\n", mainConfig?.getStringList("footer") ?: listOf()) + val header: Component = miniMessage.deserialize(if (usePlaceholderAPI) PlaceholderAPI.setPlaceholders(player, headerRaw) else headerRaw) + val footer: Component = miniMessage.deserialize(if (usePlaceholderAPI) PlaceholderAPI.setPlaceholders(player, footerRaw) else footerRaw) player.sendPlayerListHeaderAndFooter(header, footer) } + fun updateYamlFile(file: File) { + @Suppress("DEPRECATION") val pluginVersion = description.version + val oldConfig = YamlConfiguration() + + if (file.exists()) { + try { + oldConfig.load(file) + } catch (e: Exception) { + e.printStackTrace() + return + } + } + + var configVersion = oldConfig.getString("config-version") + if (configVersion == pluginVersion) return + val defaultConfigStream = getResource(file.name) ?: return + val defaultConfig = YamlConfiguration() + + try { + defaultConfig.load(InputStreamReader(defaultConfigStream)) + } catch (e: Exception) { + e.printStackTrace() + return + } + + for (key in defaultConfig.getKeys(true)) { + if (oldConfig.contains(key)) { + defaultConfig.set(key, oldConfig.get(key)) + } + } + + defaultConfig.set("config-version", pluginVersion) + defaultConfig.save(file) + + if (file.name == "config.yml") mainConfig = defaultConfig + if (configVersion == null) configVersion = "n/a (Legacy)" + + logger.info("Updated ${file.name} from $configVersion to $pluginVersion") + } + + fun startPlaceholderTask() { + stopTask() + val delay = mainConfig?.getLong("placeholder-update-delay", 500) ?: 500 + val validDelay = if (delay == 0L) 500L else maxOf(delay / 50, 1) + + placeholderTask = server.scheduler.runTaskTimer(this, Runnable { + for (player in server.onlinePlayers) { + setTab(player) + } + }, 0L, validDelay).taskId + } + + fun restartTask() { + startPlaceholderTask() + } + + fun stopTask() { + placeholderTask?.let { server.scheduler.cancelTask(it) } + } + companion object { private lateinit var instance: GalaxyTab diff --git a/src/main/kotlin/xyz/lncvrt/galaxytab/commands/GalaxyTabCommand.kt b/src/main/kotlin/xyz/lncvrt/galaxytab/commands/GalaxyTabCommand.kt index 7896e0c..16edf4c 100644 --- a/src/main/kotlin/xyz/lncvrt/galaxytab/commands/GalaxyTabCommand.kt +++ b/src/main/kotlin/xyz/lncvrt/galaxytab/commands/GalaxyTabCommand.kt @@ -25,10 +25,13 @@ class GalaxyTabCommand : BukkitCommand(GalaxyTab.getInstance(), "galaxytab", arr val miniMessage = MiniMessage.miniMessage() val instance = GalaxyTab.getInstance() - instance.saveDefaultConfig() - instance.reloadConfig() - instance.configFile = instance.config - for (player in instance.server.onlinePlayers) instance.setTab(player) + instance.loadConfig() + if (instance.usePlaceholderAPI) { + instance.restartTask() + } else { + instance.stopTask() + for (player in instance.server.onlinePlayers) instance.setTab(player) + } sender.sendMessage(miniMessage.deserialize("GalaxyTab has been reloaded!")) } diff --git a/src/main/kotlin/xyz/lncvrt/galaxytab/events/PlayerJoinEventListener.kt b/src/main/kotlin/xyz/lncvrt/galaxytab/events/PlayerJoinEventListener.kt new file mode 100644 index 0000000..9de1302 --- /dev/null +++ b/src/main/kotlin/xyz/lncvrt/galaxytab/events/PlayerJoinEventListener.kt @@ -0,0 +1,13 @@ +package xyz.lncvrt.galaxytab.events + +import org.bukkit.event.EventHandler +import org.bukkit.event.Listener +import org.bukkit.event.player.PlayerJoinEvent +import xyz.lncvrt.galaxytab.GalaxyTab + +class PlayerJoinEventListener : Listener { + @EventHandler + fun onPlayerJoinEvent(event: PlayerJoinEvent) { + GalaxyTab.getInstance().setTab(event.player) + } +} \ No newline at end of file diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index edfa399..1c29af0 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,4 +1,19 @@ +config-version: '${version}' # Don't touch :) + +########################################################################## +# Header and Footer +########################################################################## + header: - - "Header" + - "Header content" footer: - - "Footer" \ No newline at end of file + - "Footer content" + +########################################################################## +# Placeholders +########################################################################## + +# Weather we should enable PlaceholderAPI hook, if found on the server +placeholderapi-hook: false +# The delay between updating Placeholders in tab, if enabled +placeholder-update-delay: 500 # 500 = 0.5s diff --git a/src/main/resources/paper-plugin.yml b/src/main/resources/paper-plugin.yml index 4de1fbe..01afe16 100644 --- a/src/main/resources/paper-plugin.yml +++ b/src/main/resources/paper-plugin.yml @@ -2,3 +2,8 @@ name: GalaxyTab version: '${version}' main: xyz.lncvrt.galaxytab.GalaxyTab api-version: '1.20' +dependencies: + server: + PlaceholderAPI: + load: BEFORE + required: false \ No newline at end of file