diff --git a/CleanerX-Paper/build.gradle.kts b/CleanerX-Paper/build.gradle.kts index abd17ac..300888b 100644 --- a/CleanerX-Paper/build.gradle.kts +++ b/CleanerX-Paper/build.gradle.kts @@ -18,10 +18,14 @@ repositories { maven("https://oss.sonatype.org/content/groups/public/") { name = "sonatype" } + maven { + name = "faststatsReleases" + url = uri("https://repo.faststats.dev/releases") } +} dependencies { - compileOnly("io.papermc.paper:paper-api:26.1.1.build.+") + compileOnly("io.papermc.paper:paper-api:1.21.11-R0.1-SNAPSHOT") compileOnly("org.eclipse.aether:aether-api:1.1.0") compileOnly("org.yaml:snakeyaml:2.6") compileOnly("com.google.code.gson:gson:2.13.2") @@ -33,18 +37,24 @@ dependencies { compileOnly("pl.syntaxdevteam:core:1.3.0-R0.2-SNAPSHOT") compileOnly("pl.syntaxdevteam:messageHandler-paper:1.1.2-R0.1-SNAPSHOT") compileOnly("pl.syntaxdevteam.punisher:PunisherX:1.6.1") + compileOnly("dev.faststats.metrics:bukkit:0.22.0") testImplementation(kotlin("test")) testImplementation("org.junit.jupiter:junit-jupiter:6.0.3") testImplementation("io.mockk:mockk:1.14.9") - testImplementation("io.papermc.paper:paper-api:26.1.1.build.+") + testImplementation("io.papermc.paper:paper-api:1.21.11-R0.1-SNAPSHOT") testImplementation("pl.syntaxdevteam:core:1.3.0-R0.1.2-SNAPSHOT") testImplementation("pl.syntaxdevteam:messageHandler-paper:1.1.2-R0.1-SNAPSHOT") + testImplementation("dev.faststats.metrics:bukkit:0.22.0") testRuntimeOnly("org.slf4j:slf4j-simple:2.0.17") } -val targetJavaVersion = 25 +val targetJavaVersion = 21 +java { + toolchain.languageVersion.set(org.gradle.jvm.toolchain.JavaLanguageVersion.of(targetJavaVersion)) +} + kotlin { jvmToolchain(targetJavaVersion) } @@ -63,6 +73,7 @@ tasks{ useJUnitPlatform() jvmArgs("-XX:+EnableDynamicAgentLoading", "-Xshare:off") } + } diff --git a/CleanerX-Paper/src/main/kotlin/pl/syntaxdevteam/cleanerx/CleanerX.kt b/CleanerX-Paper/src/main/kotlin/pl/syntaxdevteam/cleanerx/CleanerX.kt index b879aa2..e563a48 100644 --- a/CleanerX-Paper/src/main/kotlin/pl/syntaxdevteam/cleanerx/CleanerX.kt +++ b/CleanerX-Paper/src/main/kotlin/pl/syntaxdevteam/cleanerx/CleanerX.kt @@ -24,6 +24,9 @@ import java.io.File import java.util.Locale class CleanerX : JavaPlugin(), Listener { + private val fastStatsBridge: FastStatsBridge by lazy { + FastStatsBridge(this, "f32783ff0554d455034d573bfef0e6c2") + } private lateinit var pluginInitializer: PluginInitializer @@ -45,27 +48,39 @@ class CleanerX : JavaPlugin(), Listener { var lpcMode: Boolean = false override fun onEnable() { - SyntaxCore.registerUpdateSources( - GitHubSource("SyntaxDevTeam/CleanerX"), - ModrinthSource("zJ4dsnYc") - ) - SyntaxCore.init(this, versionType = "paper") - pluginInitializer = PluginInitializer(this) - pluginInitializer.onEnable() - placeholderFix() - versionChecker.checkAndLog() + try { + SyntaxCore.registerUpdateSources( + GitHubSource("SyntaxDevTeam/CleanerX"), + ModrinthSource("zJ4dsnYc") + ) + SyntaxCore.init(this, versionType = "paper") + pluginInitializer = PluginInitializer(this) + pluginInitializer.onEnable() + fastStatsBridge.ready() + placeholderFix() + versionChecker.checkAndLog() + } catch (exception: Exception) { + reportError(exception) + throw exception + } } override fun onDisable() { AsyncChatEvent.getHandlerList().unregister(this as Plugin) + fastStatsBridge.shutdown() pluginInitializer.onDisable() } + fun reportError(throwable: Throwable) { + fastStatsBridge.trackError(throwable) + } + fun restartMyTask() { try { messageHandler.reloadMessages() } catch (e: Exception) { logger.err("${messageHandler.stringMessageToComponent("error", "reload")} ${e.message}") + reportError(e) } saveDefaultConfig() @@ -78,6 +93,7 @@ class CleanerX : JavaPlugin(), Listener { pluginInitializer.registerEvents() } catch (ee: Exception) { logger.err("An error occurred while reloading the configuration: " + ee.message) + reportError(ee) } } @@ -103,6 +119,7 @@ class CleanerX : JavaPlugin(), Listener { logger.success("$prefix Converted placeholders in ${langFile.name}.") } catch (e: Exception) { logger.err("$prefix Failed to convert placeholders: ${e.message}") + reportError(e) } } } diff --git a/CleanerX-Paper/src/main/kotlin/pl/syntaxdevteam/cleanerx/FastStatsBridge.kt b/CleanerX-Paper/src/main/kotlin/pl/syntaxdevteam/cleanerx/FastStatsBridge.kt new file mode 100644 index 0000000..751cf15 --- /dev/null +++ b/CleanerX-Paper/src/main/kotlin/pl/syntaxdevteam/cleanerx/FastStatsBridge.kt @@ -0,0 +1,92 @@ +package pl.syntaxdevteam.cleanerx + +import org.bukkit.plugin.java.JavaPlugin +import java.lang.reflect.Method + +class FastStatsBridge( + private val plugin: JavaPlugin, + private val token: String +) { + private var errorTracker: Any? = null + private var metrics: Any? = null + private var available = false + + fun ready() { + ensureInitialized() + invokeNoArg(metrics, "ready") + } + + fun shutdown() { + invokeNoArg(metrics, "shutdown") + } + + fun trackError(throwable: Throwable) { + ensureInitialized() + invokeOneArg(errorTracker, "trackError", Throwable::class.java, throwable) + } + + private fun ensureInitialized() { + if (available || metrics != null) { + return + } + + try { + val errorTrackerClass = Class.forName("dev.faststats.core.ErrorTracker") + val contextAware = errorTrackerClass.getMethod("contextAware") + errorTracker = contextAware.invoke(null) + + val bukkitMetricsClass = Class.forName("dev.faststats.bukkit.BukkitMetrics") + val factory = bukkitMetricsClass.getMethod("factory").invoke(null) + val builderClass = factory.javaClass + invokeCompatible(builderClass, factory, "token", token) + invokeCompatible(builderClass, factory, "errorTracker", errorTracker!!) + metrics = invokeCompatible(builderClass, factory, "create", plugin) + available = true + } catch (exception: Exception) { + plugin.logger.warning("[CleanerX] FastStats is unavailable, metrics disabled: ${exception::class.java.simpleName}: ${exception.message}") + } + } + + private fun invokeNoArg(target: Any?, methodName: String) { + if (!available || target == null) { + return + } + try { + target.javaClass.getMethod(methodName).invoke(target) + } catch (_: Exception) { + // no-op + } + } + + private fun invokeOneArg(target: Any?, methodName: String, paramType: Class<*>, argument: Any) { + if (!available || target == null) { + return + } + try { + target.javaClass.getMethod(methodName, paramType).invoke(target, argument) + } catch (_: Exception) { + // no-op + } + } + + private fun invokeCompatible(targetClass: Class<*>, target: Any, methodName: String, argument: Any): Any? { + val candidate: Method = targetClass.methods.firstOrNull { method -> + method.name == methodName && + method.parameterCount == 1 && + method.parameters[0].type.isAssignableFrom(argument.javaClass) + } ?: throw NoSuchMethodException("No compatible '$methodName' method found in ${targetClass.name}") + + candidate.isAccessible = true + return candidate.invoke(target, argument) + } + + companion object { + fun trackBootstrapError(throwable: Throwable) { + runCatching { + val errorTrackerClass = Class.forName("dev.faststats.core.ErrorTracker") + val tracker = errorTrackerClass.getMethod("contextAware").invoke(null) + tracker.javaClass.getMethod("trackError", Throwable::class.java).invoke(tracker, throwable) + } + } + } +} diff --git a/CleanerX-Paper/src/main/kotlin/pl/syntaxdevteam/cleanerx/common/BannedWordsSynchronizer.kt b/CleanerX-Paper/src/main/kotlin/pl/syntaxdevteam/cleanerx/common/BannedWordsSynchronizer.kt index da1b643..d5c6b09 100644 --- a/CleanerX-Paper/src/main/kotlin/pl/syntaxdevteam/cleanerx/common/BannedWordsSynchronizer.kt +++ b/CleanerX-Paper/src/main/kotlin/pl/syntaxdevteam/cleanerx/common/BannedWordsSynchronizer.kt @@ -69,6 +69,7 @@ class BannedWordsSynchronizer(private val plugin: CleanerX) { complete(onComplete, mergedWords.toList()) } catch (exception: Exception) { plugin.logger.err("Failed to synchronize banned words: ${exception.message}") + plugin.reportError(exception) } } } @@ -120,6 +121,7 @@ class BannedWordsSynchronizer(private val plugin: CleanerX) { } }.onFailure { exception -> plugin.logger.warning("Banned words sync failed for $source: ${exception.message}") + plugin.reportError(exception) } } diff --git a/CleanerX-Paper/src/main/kotlin/pl/syntaxdevteam/cleanerx/eventhandler/CleanerXChat.kt b/CleanerX-Paper/src/main/kotlin/pl/syntaxdevteam/cleanerx/eventhandler/CleanerXChat.kt index 75beb37..fb25a8d 100644 --- a/CleanerX-Paper/src/main/kotlin/pl/syntaxdevteam/cleanerx/eventhandler/CleanerXChat.kt +++ b/CleanerX-Paper/src/main/kotlin/pl/syntaxdevteam/cleanerx/eventhandler/CleanerXChat.kt @@ -69,7 +69,7 @@ class CleanerXChat( plugin.logger.severe( "Critical error in onLegacyChat: ${e.message}" ) - e.printStackTrace() + plugin.reportError(e) } } @@ -109,6 +109,7 @@ class CleanerXChat( "Critical error in onChat: ${e.message}" ) plugin.logger.severe("[CLX-CHAT-001] Stacktrace: ${e.stackTraceToString()}") + plugin.reportError(e) } } @@ -127,6 +128,7 @@ class CleanerXChat( isMuted || isJailed } catch (exception: Exception) { plugin.logger.severe("Could not check penalty status for ${player.name}: ${exception.message}") + plugin.reportError(exception) false } } diff --git a/CleanerX-Paper/src/main/kotlin/pl/syntaxdevteam/cleanerx/loader/PluginInitializer.kt b/CleanerX-Paper/src/main/kotlin/pl/syntaxdevteam/cleanerx/loader/PluginInitializer.kt index bd55448..120dd45 100644 --- a/CleanerX-Paper/src/main/kotlin/pl/syntaxdevteam/cleanerx/loader/PluginInitializer.kt +++ b/CleanerX-Paper/src/main/kotlin/pl/syntaxdevteam/cleanerx/loader/PluginInitializer.kt @@ -97,9 +97,11 @@ class PluginInitializer(private val plugin: CleanerX) { Class.forName("pl.syntaxdevteam.punisher.api.PunisherXApi", false, punisherPlugin.javaClass.classLoader) } catch (exception: ClassNotFoundException) { plugin.logger.warning("PunisherX wykryty, ale brakuje API (PunisherXApi). Pomijam integrację.") + plugin.reportError(exception) return } catch (exception: Throwable) { plugin.logger.warning("PunisherX wykryty, ale API jest niedostępne (${exception.javaClass.simpleName}). Pomijam integrację.") + plugin.reportError(exception) return } @@ -107,6 +109,7 @@ class PluginInitializer(private val plugin: CleanerX) { plugin.server.servicesManager.load(apiClass) } catch (exception: Throwable) { plugin.logger.warning("PunisherX wykryty, ale nie udało się pobrać API (${exception.javaClass.simpleName}). Pomijam integrację.") + plugin.reportError(exception) return } ?: run { plugin.logger.warning("PunisherX wykryty, ale nie udostępnia API. Pomijam integrację.") diff --git a/CleanerX-Paper/src/main/kotlin/pl/syntaxdevteam/cleanerx/loader/SyntaxLoader.kt b/CleanerX-Paper/src/main/kotlin/pl/syntaxdevteam/cleanerx/loader/SyntaxLoader.kt index 03d256b..6af4f1d 100644 --- a/CleanerX-Paper/src/main/kotlin/pl/syntaxdevteam/cleanerx/loader/SyntaxLoader.kt +++ b/CleanerX-Paper/src/main/kotlin/pl/syntaxdevteam/cleanerx/loader/SyntaxLoader.kt @@ -7,6 +7,7 @@ import org.eclipse.aether.artifact.DefaultArtifact import org.eclipse.aether.graph.Dependency import org.eclipse.aether.repository.RemoteRepository import org.yaml.snakeyaml.Yaml +import pl.syntaxdevteam.cleanerx.FastStatsBridge import java.io.IOException import java.io.InputStream import java.util.logging.Level @@ -31,6 +32,8 @@ class SyntaxLoader : PluginLoader { resolver.addRepository(RemoteRepository.Builder("central-mirror", "default", "https://repo.papermc.io/repository/maven-central/").build()) resolver.addRepository(RemoteRepository.Builder("jitpack", "default", "https://jitpack.io/").build()) resolver.addRepository(RemoteRepository.Builder("codemc-snapshots", "default", "https://repo.codemc.io/repository/maven-snapshots/").build()) + resolver.addRepository(RemoteRepository.Builder("faststatsReleases", "default", "https://repo.faststats.dev/releases").build()) + pluginClasspath.addLibrary(resolver) } @@ -39,6 +42,7 @@ class SyntaxLoader : PluginLoader { readLibraryListFromYaml() } catch (e: IOException) { LOGGER.log(Level.SEVERE, "Failed to resolve libraries from paper-libraries.yml", e) + FastStatsBridge.trackBootstrapError(e) emptyList() } } diff --git a/CleanerX-Paper/src/main/resources/paper-libraries.yml b/CleanerX-Paper/src/main/resources/paper-libraries.yml index 1b5a8c9..f2e9aa3 100644 --- a/CleanerX-Paper/src/main/resources/paper-libraries.yml +++ b/CleanerX-Paper/src/main/resources/paper-libraries.yml @@ -12,4 +12,6 @@ libraries: # SyntaxCore dependencies - com.github.ben-manes.caffeine:caffeine:3.2.3 - pl.syntaxdevteam:core:1.3.0-R0.2-SNAPSHOT - - pl.syntaxdevteam:messageHandler-paper:1.1.2-R0.1-SNAPSHOT \ No newline at end of file + - pl.syntaxdevteam:messageHandler-paper:1.1.2-R0.1-SNAPSHOT + # FastStats dependencies + - dev.faststats.metrics:bukkit:0.22.0 \ No newline at end of file diff --git a/CleanerX-Spigot/build.gradle.kts b/CleanerX-Spigot/build.gradle.kts index 4a53e2c..d35a3f1 100644 --- a/CleanerX-Spigot/build.gradle.kts +++ b/CleanerX-Spigot/build.gradle.kts @@ -17,10 +17,14 @@ repositories { maven("https://repo.alessiodp.com/releases/") { name = "alessiodp" } + maven { + name = "faststatsReleases" + url = uri("https://repo.faststats.dev/releases") + } } dependencies { - compileOnly("org.spigotmc:spigot-api:26.1.1-R0.1-SNAPSHOT") + compileOnly("org.spigotmc:spigot-api:1.21.11-R0.1-SNAPSHOT") compileOnly("org.eclipse.aether:aether-api:1.1.0") compileOnly("org.yaml:snakeyaml:2.6") compileOnly("com.google.code.gson:gson:2.13.2") @@ -42,14 +46,21 @@ dependencies { compileOnly("pl.syntaxdevteam:messageHandler-spigot:1.1.2-R0.1-SNAPSHOT") compileOnly("pl.syntaxdevteam.punisher:PunisherX:1.6.1") implementation("net.byteflux:libby-bukkit:1.3.1") + compileOnly("dev.faststats.metrics:bukkit:0.21.0") testImplementation(kotlin("test")) testImplementation("org.mockito:mockito-core:5.23.0") testImplementation("org.mockito:mockito-inline:5.2.0") testImplementation("org.mockito.kotlin:mockito-kotlin:6.3.0") + + testImplementation("dev.faststats.metrics:bukkit:0.21.0") +} + +val targetJavaVersion = 21 +java { + toolchain.languageVersion.set(org.gradle.jvm.toolchain.JavaLanguageVersion.of(targetJavaVersion)) } -val targetJavaVersion = 25 kotlin { jvmToolchain(targetJavaVersion) } diff --git a/CleanerX-Spigot/src/main/kotlin/pl/syntaxdevteam/cleanerx/CleanerX.kt b/CleanerX-Spigot/src/main/kotlin/pl/syntaxdevteam/cleanerx/CleanerX.kt index 90ef2d9..5e1d4b1 100644 --- a/CleanerX-Spigot/src/main/kotlin/pl/syntaxdevteam/cleanerx/CleanerX.kt +++ b/CleanerX-Spigot/src/main/kotlin/pl/syntaxdevteam/cleanerx/CleanerX.kt @@ -24,6 +24,9 @@ import java.io.File import java.util.Locale class CleanerX : JavaPlugin(), Listener { + private val fastStatsBridge: FastStatsBridge by lazy { + FastStatsBridge(this, "f32783ff0554d455034d573bfef0e6c2") + } private lateinit var pluginInitializer: PluginInitializer private lateinit var libraryLoader: LibraryLoader @@ -47,28 +50,45 @@ class CleanerX : JavaPlugin(), Listener { override fun onLoad() { libraryLoader = LibraryLoader(this) - libraryLoader.loadRuntimeLibraries() + try { + libraryLoader.loadRuntimeLibraries() + } catch (exception: Exception) { + reportError(exception) + throw exception + } } override fun onEnable() { - SyntaxCore.registerUpdateSources( - GitHubSource("SyntaxDevTeam/CleanerX"), - ModrinthSource("zJ4dsnYc") - ) - SyntaxCore.init(this, versionType = "spigot") - pluginInitializer = PluginInitializer(this) - pluginInitializer.onEnable() + try { + SyntaxCore.registerUpdateSources( + GitHubSource("SyntaxDevTeam/CleanerX"), + ModrinthSource("zJ4dsnYc") + ) + SyntaxCore.init(this, versionType = "spigot") + pluginInitializer = PluginInitializer(this) + pluginInitializer.onEnable() + fastStatsBridge.ready() + } catch (exception: Exception) { + reportError(exception) + throw exception + } } override fun onDisable() { + fastStatsBridge.shutdown() pluginInitializer.onDisable() } + fun reportError(throwable: Throwable) { + fastStatsBridge.trackError(throwable) + } + fun restartMyTask() { try { messageHandler.reloadMessages() } catch (e: Exception) { logger.err("${messageHandler.stringMessageToComponent("error", "reload")} ${e.message}") + reportError(e) } saveDefaultConfig() @@ -81,6 +101,7 @@ class CleanerX : JavaPlugin(), Listener { pluginInitializer.registerEvents() } catch (ee: Exception) { logger.err("An error occurred while reloading the configuration: " + ee.message) + reportError(ee) } } @@ -105,6 +126,7 @@ class CleanerX : JavaPlugin(), Listener { logger.success("Converted placeholders in ${langFile.name}.") } catch (e: Exception) { logger.err("Failed to convert placeholders: ${e.message}") + reportError(e) } } } diff --git a/CleanerX-Spigot/src/main/kotlin/pl/syntaxdevteam/cleanerx/FastStatsBridge.kt b/CleanerX-Spigot/src/main/kotlin/pl/syntaxdevteam/cleanerx/FastStatsBridge.kt new file mode 100644 index 0000000..a3287a0 --- /dev/null +++ b/CleanerX-Spigot/src/main/kotlin/pl/syntaxdevteam/cleanerx/FastStatsBridge.kt @@ -0,0 +1,82 @@ +package pl.syntaxdevteam.cleanerx + +import org.bukkit.plugin.java.JavaPlugin +import java.lang.reflect.Method + +class FastStatsBridge( + private val plugin: JavaPlugin, + private val token: String +) { + private var errorTracker: Any? = null + private var metrics: Any? = null + private var available = false + + fun ready() { + ensureInitialized() + invokeNoArg(metrics, "ready") + } + + fun shutdown() { + invokeNoArg(metrics, "shutdown") + } + + fun trackError(throwable: Throwable) { + ensureInitialized() + invokeOneArg(errorTracker, "trackError", Throwable::class.java, throwable) + } + + private fun ensureInitialized() { + if (available || metrics != null) { + return + } + + try { + val errorTrackerClass = Class.forName("dev.faststats.core.ErrorTracker") + val contextAware = errorTrackerClass.getMethod("contextAware") + errorTracker = contextAware.invoke(null) + + val bukkitMetricsClass = Class.forName("dev.faststats.bukkit.BukkitMetrics") + val factory = bukkitMetricsClass.getMethod("factory").invoke(null) + val builderClass = factory.javaClass + invokeCompatible(builderClass, factory, "token", token) + invokeCompatible(builderClass, factory, "errorTracker", errorTracker!!) + metrics = invokeCompatible(builderClass, factory, "create", plugin) + available = true + } catch (exception: Exception) { + plugin.logger.warning("[CleanerX] FastStats is unavailable, metrics disabled: ${exception::class.java.simpleName}: ${exception.message}") + } + } + + private fun invokeNoArg(target: Any?, methodName: String) { + if (!available || target == null) { + return + } + try { + target.javaClass.getMethod(methodName).invoke(target) + } catch (_: Exception) { + // no-op + } + } + + private fun invokeOneArg(target: Any?, methodName: String, paramType: Class<*>, argument: Any) { + if (!available || target == null) { + return + } + try { + target.javaClass.getMethod(methodName, paramType).invoke(target, argument) + } catch (_: Exception) { + // no-op + } + } + + private fun invokeCompatible(targetClass: Class<*>, target: Any, methodName: String, argument: Any): Any? { + val candidate: Method = targetClass.methods.firstOrNull { method -> + method.name == methodName && + method.parameterCount == 1 && + method.parameters[0].type.isAssignableFrom(argument.javaClass) + } ?: throw NoSuchMethodException("No compatible '$methodName' method found in ${targetClass.name}") + + candidate.isAccessible = true + return candidate.invoke(target, argument) + } +} diff --git a/CleanerX-Spigot/src/main/kotlin/pl/syntaxdevteam/cleanerx/common/BannedWordsSynchronizer.kt b/CleanerX-Spigot/src/main/kotlin/pl/syntaxdevteam/cleanerx/common/BannedWordsSynchronizer.kt index 8c3ed03..8481b3c 100644 --- a/CleanerX-Spigot/src/main/kotlin/pl/syntaxdevteam/cleanerx/common/BannedWordsSynchronizer.kt +++ b/CleanerX-Spigot/src/main/kotlin/pl/syntaxdevteam/cleanerx/common/BannedWordsSynchronizer.kt @@ -69,6 +69,7 @@ class BannedWordsSynchronizer(private val plugin: CleanerX) { complete(onComplete, mergedWords.toList()) } catch (exception: Exception) { plugin.logger.err("Failed to synchronize banned words: ${exception.message}") + plugin.reportError(exception) } }) } @@ -120,6 +121,7 @@ class BannedWordsSynchronizer(private val plugin: CleanerX) { } }.onFailure { exception -> plugin.logger.warning("Banned words sync failed for $source: ${exception.message}") + plugin.reportError(exception) } } diff --git a/CleanerX-Spigot/src/main/kotlin/pl/syntaxdevteam/cleanerx/eventhandler/CleanerXChat.kt b/CleanerX-Spigot/src/main/kotlin/pl/syntaxdevteam/cleanerx/eventhandler/CleanerXChat.kt index 04d907e..8820c6a 100644 --- a/CleanerX-Spigot/src/main/kotlin/pl/syntaxdevteam/cleanerx/eventhandler/CleanerXChat.kt +++ b/CleanerX-Spigot/src/main/kotlin/pl/syntaxdevteam/cleanerx/eventhandler/CleanerXChat.kt @@ -66,6 +66,7 @@ class CleanerXChat( } catch (e: Exception) { plugin.logger.severe("Critical error! Send a message to the plugin author with the subject \"Error in onChat\" and the content: ${e.message}") plugin.logger.severe("[CLX-CHAT-001] Stacktrace: ${e.stackTraceToString()}") + plugin.reportError(e) } } @@ -84,6 +85,7 @@ class CleanerXChat( isMuted || isJailed } catch (exception: Exception) { plugin.logger.severe("Could not check penalty status for ${player.name}: ${exception.message}") + plugin.reportError(exception) false } } diff --git a/CleanerX-Spigot/src/main/kotlin/pl/syntaxdevteam/cleanerx/loader/LibraryLoader.kt b/CleanerX-Spigot/src/main/kotlin/pl/syntaxdevteam/cleanerx/loader/LibraryLoader.kt index ddd16c9..d389107 100644 --- a/CleanerX-Spigot/src/main/kotlin/pl/syntaxdevteam/cleanerx/loader/LibraryLoader.kt +++ b/CleanerX-Spigot/src/main/kotlin/pl/syntaxdevteam/cleanerx/loader/LibraryLoader.kt @@ -4,6 +4,7 @@ import net.byteflux.libby.BukkitLibraryManager import net.byteflux.libby.Library import org.bukkit.configuration.file.YamlConfiguration import org.bukkit.plugin.java.JavaPlugin +import pl.syntaxdevteam.cleanerx.CleanerX import java.io.InputStreamReader import java.nio.charset.StandardCharsets @@ -25,6 +26,7 @@ class LibraryLoader(private val plugin: JavaPlugin) { libraryManager.addMavenCentral() libraryManager.addRepository("https://nexus.syntaxdevteam.pl/repository/maven-releases/") libraryManager.addRepository("https://nexus.syntaxdevteam.pl/repository/maven-snapshots/") + libraryManager.addRepository("https://repo.faststats.dev/releases") val runtimeLibraries = loadLibrariesFromConfig() @@ -39,6 +41,7 @@ class LibraryLoader(private val plugin: JavaPlugin) { plugin.logger.info("[CleanerX] Loaded runtime library: $coordinates") } catch (exception: Exception) { plugin.logger.severe("[CleanerX] Failed to load runtime library $coordinates: ${exception.message}") + (plugin as? CleanerX)?.reportError(exception) throw IllegalStateException("Unable to load runtime library $coordinates", exception) } } @@ -85,4 +88,4 @@ class LibraryLoader(private val plugin: JavaPlugin) { companion object { private const val LIBRARIES_RESOURCE = "spigot-libraries.yml" } -} \ No newline at end of file +} diff --git a/CleanerX-Spigot/src/main/kotlin/pl/syntaxdevteam/cleanerx/loader/PluginInitializer.kt b/CleanerX-Spigot/src/main/kotlin/pl/syntaxdevteam/cleanerx/loader/PluginInitializer.kt index 97aa61b..c1dccce 100644 --- a/CleanerX-Spigot/src/main/kotlin/pl/syntaxdevteam/cleanerx/loader/PluginInitializer.kt +++ b/CleanerX-Spigot/src/main/kotlin/pl/syntaxdevteam/cleanerx/loader/PluginInitializer.kt @@ -95,9 +95,11 @@ class PluginInitializer(private val plugin: CleanerX) { Class.forName("pl.syntaxdevteam.punisher.api.PunisherXApi", false, punisherPlugin.javaClass.classLoader) } catch (exception: ClassNotFoundException) { plugin.logger.warning("PunisherX wykryty, ale brakuje API (PunisherXApi). Pomijam integrację.") + plugin.reportError(exception) return } catch (exception: Throwable) { plugin.logger.warning("PunisherX wykryty, ale API jest niedostępne (${exception.javaClass.simpleName}). Pomijam integrację.") + plugin.reportError(exception) return } @@ -105,6 +107,7 @@ class PluginInitializer(private val plugin: CleanerX) { plugin.server.servicesManager.load(apiClass) } catch (exception: Throwable) { plugin.logger.warning("PunisherX wykryty, ale nie udało się pobrać API (${exception.javaClass.simpleName}). Pomijam integrację.") + plugin.reportError(exception) return } ?: run { plugin.logger.warning("PunisherX wykryty, ale nie udostępnia API. Pomijam integrację.") diff --git a/CleanerX-Spigot/src/main/resources/spigot-libraries.yml b/CleanerX-Spigot/src/main/resources/spigot-libraries.yml index 8edb088..e21042a 100644 --- a/CleanerX-Spigot/src/main/resources/spigot-libraries.yml +++ b/CleanerX-Spigot/src/main/resources/spigot-libraries.yml @@ -23,3 +23,5 @@ libraries: - com.google.code.gson:gson:2.13.2 - org.yaml:snakeyaml:2.6 - org.eclipse.aether:aether-api:1.1.0 + # FastStats dependencies + - dev.faststats.metrics:bukkit:0.22.0 \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 15218e9..20f84b1 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -5,7 +5,7 @@ plugins { } group = "pl.syntaxdevteam" -version = "1.5.6" +version = "1.5.7-SNAPSHOT" description = "A sophisticated plugin designed to filter and replace inappropriate language with censored alternatives or remove it entirely, ensuring a clean and respectful gaming environment." allprojects {