mirror of
https://github.com/alexcrea/CustomAnvil.git
synced 2026-08-28 08:25:56 +02:00
347 lines
11 KiB
Kotlin
347 lines
11 KiB
Kotlin
package io.delilaheve
|
|
|
|
import io.delilaheve.util.ConfigOptions
|
|
import org.bukkit.Bukkit
|
|
import org.bukkit.configuration.file.YamlConfiguration
|
|
import org.bukkit.plugin.java.JavaPlugin
|
|
import xyz.alexcrea.cuanvil.api.event.CAConfigReadyEvent
|
|
import xyz.alexcrea.cuanvil.api.event.CAEnchantRegistryReadyEvent
|
|
import xyz.alexcrea.cuanvil.command.CustomAnvilCommand
|
|
import xyz.alexcrea.cuanvil.config.ConfigHolder
|
|
import xyz.alexcrea.cuanvil.dependency.DependencyManager
|
|
import xyz.alexcrea.cuanvil.dependency.MinecraftVersionUtil
|
|
import xyz.alexcrea.cuanvil.dependency.economy.EconomyManager
|
|
import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil
|
|
import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry
|
|
import xyz.alexcrea.cuanvil.gui.config.MainConfigGui
|
|
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant
|
|
import xyz.alexcrea.cuanvil.lang.Lang
|
|
import xyz.alexcrea.cuanvil.lang.MsgError
|
|
import xyz.alexcrea.cuanvil.lang.MsgWarning
|
|
import xyz.alexcrea.cuanvil.listener.AnvilCloseListener
|
|
import xyz.alexcrea.cuanvil.listener.AnvilResultListener
|
|
import xyz.alexcrea.cuanvil.listener.ChatEventListener
|
|
import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener
|
|
import xyz.alexcrea.cuanvil.update.ModrinthUpdateChecker
|
|
import xyz.alexcrea.cuanvil.update.PluginSetDefault
|
|
import xyz.alexcrea.cuanvil.update.UpdateHandler
|
|
import xyz.alexcrea.cuanvil.update.UpdateUtils
|
|
import xyz.alexcrea.cuanvil.util.MetricsUtil
|
|
import java.io.File
|
|
import java.io.FileReader
|
|
import java.util.logging.Level
|
|
|
|
/**
|
|
* Bukkit/Spigot/Paper plugin to alter anvil feature
|
|
*/
|
|
open class CustomAnvil : JavaPlugin() {
|
|
|
|
companion object {
|
|
// pluginIDS
|
|
private const val modrinthPluginID = "S75Ueiq9"
|
|
|
|
// Permission string required to use the plugin's features
|
|
const val affectedByPluginPermission = "ca.affected"
|
|
|
|
// Permission string required to bypass enchantment conflicts test
|
|
const val bypassFusePermission = "ca.bypass.fuse"
|
|
|
|
// Permission string required to bypass enchantment conflicts test
|
|
const val bypassLevelPermission = "ca.bypass.level"
|
|
|
|
// Permission string required to reload the config
|
|
const val commandReloadPermission = "ca.command.reload"
|
|
|
|
// Permission string required to get diagnostic data
|
|
const val diagnosticPermission = "ca.command.diagnostic"
|
|
|
|
// Permission string required to edit the plugin's config
|
|
const val editConfigPermission = "ca.config.edit"
|
|
|
|
// Permission string required to edit the plugin's config
|
|
const val giveEnchantmentPermission = "ca.command.enchantment"
|
|
|
|
// Command Name to reload the config
|
|
const val commandReloadName = "anvilconfigreload"
|
|
|
|
// Config command name
|
|
const val commandConfigName = "customanvilconfig"
|
|
|
|
// Current plugin instance
|
|
lateinit var instance: CustomAnvil
|
|
|
|
// Chat message listener
|
|
lateinit var chatListener: ChatEventListener
|
|
|
|
var latestVer: String? = null
|
|
|
|
// Debug
|
|
val debugStorageQueue = ArrayDeque<String>()
|
|
|
|
private fun addToLogQueue(message: String) {
|
|
if(debugStorageQueue.size >= 200) {
|
|
// Let not store infinite debug logs
|
|
debugStorageQueue.removeFirst()
|
|
}
|
|
|
|
debugStorageQueue.addLast(message)
|
|
}
|
|
|
|
/**
|
|
* Logging handler
|
|
*/
|
|
@JvmStatic fun log(message: String) {
|
|
if (ConfigOptions.debugLog) {
|
|
if(ConfigOptions.showDebugLogInConsole)
|
|
instance.logger.info(message)
|
|
addToLogQueue(message)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Vebose Logging handler
|
|
*/
|
|
@JvmStatic fun verboseLog(message: String) {
|
|
if (ConfigOptions.verboseDebugLog) {
|
|
if(ConfigOptions.showDebugLogInConsole)
|
|
instance.logger.info(message)
|
|
addToLogQueue(message)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Error Logging handler
|
|
*/
|
|
@JvmStatic fun logError(message: String, throwable: Throwable? = null, track: Boolean = true, level: Level = Level.SEVERE) {
|
|
instance.logger.log(level, message, throwable)
|
|
addToLogQueue("Error: $message")
|
|
|
|
if(track) {
|
|
MetricsUtil.trackError(message, throwable)
|
|
}
|
|
}
|
|
}
|
|
|
|
// stop plugin if we do not force a dirty start (true by default)
|
|
// Return true if start was stopped
|
|
private fun tryDirtyStart(): Boolean {
|
|
if(ConfigHolder.DEFAULT_CONFIG == null) return false
|
|
if(!ConfigHolder.DEFAULT_CONFIG.config.getBoolean("dirty_start", false)) {
|
|
Bukkit.getPluginManager().disablePlugin(this)
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
// stop plugin if we force a safe start (false by default)
|
|
// Return true if start was stopped
|
|
private fun trySafeStart(): Boolean {
|
|
if(ConfigHolder.DEFAULT_CONFIG == null) return false
|
|
if(ConfigHolder.DEFAULT_CONFIG.config.getBoolean("safe_start", false)) {
|
|
Bukkit.getPluginManager().disablePlugin(this)
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
/**
|
|
* Setup plugin for use
|
|
*/
|
|
override fun onEnable() {
|
|
instance = this
|
|
// Load default configuration
|
|
try {
|
|
if(!ConfigHolder.loadDefaultConfig())
|
|
throw RuntimeException("Error loading configuration file")
|
|
} catch (e: Exception) {
|
|
logError("error occurred loading default configuration", e)
|
|
if(tryDirtyStart()) return
|
|
}
|
|
|
|
// Load language
|
|
try {
|
|
Lang.reload()
|
|
} catch (e: Exception) {
|
|
logError("error occurred loading language file", e)
|
|
if(tryDirtyStart()) return
|
|
}
|
|
|
|
try {
|
|
legacyCheck()
|
|
} catch (e: Exception) {
|
|
MsgError.LOAD_LEGACY_FAILED.log(e)
|
|
if(trySafeStart()) return
|
|
}
|
|
|
|
|
|
// Add commands
|
|
try {
|
|
CustomAnvilCommand(this)
|
|
} catch (e: Exception) {
|
|
MsgError.LOAD_COMMAND_REGISTER.log(e)
|
|
if(trySafeStart()) return
|
|
}
|
|
|
|
|
|
// Load dependency
|
|
try {
|
|
DependencyManager.loadDependency()
|
|
} catch (e: Exception) {
|
|
MsgError.LOAD_COMPATIBILITY.log(e)
|
|
if(tryDirtyStart()) return
|
|
}
|
|
|
|
// Register listeners
|
|
try {
|
|
registerListeners()
|
|
} catch (e: Exception) {
|
|
MsgError.LOAD_LISTENERS.log(e)
|
|
if(tryDirtyStart()) return
|
|
}
|
|
|
|
// Load metrics
|
|
MetricsUtil.loadMetrics(this)
|
|
|
|
// Load other thing later.
|
|
// It is so other dependent plugins can implement there event listener before we fire them.
|
|
DependencyManager.scheduler.scheduleGlobally(this) { loadEnchantmentSystemDirty() }
|
|
}
|
|
|
|
override fun onDisable() {
|
|
MetricsUtil.shutdownMetrics()
|
|
}
|
|
|
|
private fun legacyCheck() {
|
|
// Disable old plugin name if exist
|
|
val potentialPlugin = Bukkit.getPluginManager().getPlugin("UnsafeEnchantsPlus")
|
|
if (potentialPlugin != null) {
|
|
Bukkit.getPluginManager().disablePlugin(potentialPlugin)
|
|
MsgWarning.LOAD_LEGACY_OLD_NAME.log()
|
|
}
|
|
|
|
val isPaper = PlatformUtil.isPaper
|
|
if(!isPaper) {
|
|
MsgWarning.LOAD_LEGACY_SPIGOT.log()
|
|
if(MinecraftVersionUtil.isTooNewForSpigot)
|
|
MsgWarning.LOAD_LEGACY_SPIGOT_OLD.log()
|
|
|
|
}
|
|
|
|
val loader = if(isPaper) "paper" else "spigot"
|
|
|
|
val version = description.version
|
|
val featured = if(version.contains("dev")) null else true
|
|
|
|
ModrinthUpdateChecker(modrinthPluginID, loader,
|
|
UpdateUtils.currentMinecraftVersion().toString())
|
|
.setFeatured(featured)
|
|
.setOnError {
|
|
MsgError.LOAD_UPDATE_CHECK_FAIL.log(it, level = Level.WARNING, track = false)
|
|
}
|
|
.checkVersion { latestVer: String? ->
|
|
CustomAnvil.latestVer = latestVer
|
|
if(latestVer == null || version.contains(latestVer)) return@checkVersion
|
|
|
|
MsgWarning.LOAD_UPDATE_AVAILABLE.log(latestVer)
|
|
}
|
|
}
|
|
|
|
private fun registerListeners() {
|
|
// Register chat listener
|
|
chatListener = ChatEventListener()
|
|
server.pluginManager.registerEvents(chatListener, this)
|
|
|
|
// Register anvil events
|
|
server.pluginManager.registerEvents(PrepareAnvilListener(), this)
|
|
server.pluginManager.registerEvents(AnvilResultListener(), this)
|
|
server.pluginManager.registerEvents(AnvilCloseListener(DependencyManager.packetManager), this)
|
|
}
|
|
|
|
private fun loadEnchantmentSystemDirty() {
|
|
try {
|
|
loadEnchantmentSystem()
|
|
} catch (e: Exception) {
|
|
MsgError.LOAD_ENCHANT_SYSTEM.log(e)
|
|
tryDirtyStart()
|
|
}
|
|
}
|
|
|
|
private fun loadEnchantmentSystem(){
|
|
// Register enchantments
|
|
CAEnchantmentRegistry.getInstance().registerBukkit()
|
|
DependencyManager.registerEnchantments()
|
|
|
|
val enchantReadyEvent = CAEnchantRegistryReadyEvent()
|
|
server.pluginManager.callEvent(enchantReadyEvent)
|
|
|
|
// Load config
|
|
if (!ConfigHolder.loadNonDefaultConfig()) {
|
|
MsgError.LOAD_NON_DEFAULT_CONFIG.log()
|
|
server.pluginManager.disablePlugin(this)
|
|
return
|
|
}
|
|
|
|
// Handle minecraft and plugin updates
|
|
UpdateHandler.handleUpdates()
|
|
|
|
// Register enchantment of compatible plugin and load configuration change.
|
|
DependencyManager.handleCompatibilityConfig()
|
|
|
|
// Call config event
|
|
val configReadyEvent = CAConfigReadyEvent()
|
|
server.pluginManager.callEvent(configReadyEvent)
|
|
|
|
// Load gui constants //TODO maybe something better later
|
|
MainConfigGui.getInstance().init(DependencyManager.packetManager)
|
|
GuiSharedConstant.loadConstants()
|
|
|
|
// Prepare economy if possible
|
|
EconomyManager.setupEconomy(this)
|
|
|
|
// Finally, re add default we may be missing
|
|
PluginSetDefault.reAddMissingDefault()
|
|
}
|
|
|
|
fun reloadResource(
|
|
resourceName: String,
|
|
hardFailSafe: Boolean = true
|
|
): YamlConfiguration? {
|
|
// Save default resource
|
|
val file = File(dataFolder, resourceName)
|
|
if (!file.exists()) {
|
|
saveResource(resourceName, false)
|
|
}
|
|
|
|
return reloadResource(file, hardFailSafe)
|
|
}
|
|
|
|
// Unlike above function. this function will not clone default from jar.
|
|
fun reloadResource(
|
|
resourceFile: File,
|
|
hardFailSafe: Boolean = true
|
|
): YamlConfiguration? {
|
|
// Test if file exist
|
|
if (!resourceFile.exists()) {
|
|
return null
|
|
}
|
|
|
|
// Load resource
|
|
val yamlConfig = YamlConfiguration()
|
|
try {
|
|
val configReader = FileReader(resourceFile)
|
|
yamlConfig.load(configReader)
|
|
} catch (e: Exception) {
|
|
MsgError.RELOAD_FAIL.log(e, resourceFile.path)
|
|
if (hardFailSafe) {
|
|
// This is important and may impact gameplay if it does not load.
|
|
// Failsafe is to stop the plugin
|
|
MsgError.RELOAD_HARD_FAIL.log()
|
|
Bukkit.getPluginManager().disablePlugin(this)
|
|
}
|
|
|
|
return null
|
|
}
|
|
return yamlConfig
|
|
}
|
|
|
|
}
|