From f25f847dc42eae0398688bdce56940224ad4158e Mon Sep 17 00:00:00 2001 From: MC_XiaoHei Date: Sat, 17 Feb 2024 20:46:28 +0800 Subject: [PATCH] refactor config, and add clear out date record file feature (iss#5) upgrade to 1.1.0 --- README.MD | 1 + build.gradle.kts | 3 +- gradle/wrapper/gradle-wrapper.properties | 4 +- settings.gradle.kts | 6 -- src/main/java/cn/xor7/iseeyou/ConfigData.kt | 55 ++++++----- .../java/cn/xor7/iseeyou/EventListener.kt | 20 ++-- src/main/java/cn/xor7/iseeyou/ISeeYou.kt | 96 +++++++++++-------- src/main/java/cn/xor7/iseeyou/TomlEx.java | 2 +- 8 files changed, 102 insertions(+), 85 deletions(-) create mode 100644 README.MD diff --git a/README.MD b/README.MD new file mode 100644 index 0000000..991aa1a --- /dev/null +++ b/README.MD @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 08bd162..48e1640 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,5 +1,4 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar -import org.apache.tools.ant.filters.ReplaceTokens plugins { id("java") @@ -8,7 +7,7 @@ plugins { } group = "cn.xor7" -version = "1.0.4" +version = "1.1.0" repositories { mavenLocal() diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 44e1b28..cf58316 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-8.1.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists +zipStorePath=wrapper/dists \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index 9ce5782..de1d375 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,9 +1,3 @@ -pluginManagement { - repositories { - mavenCentral() - gradlePluginPortal() - } -} plugins { id("org.gradle.toolchains.foojay-resolver-convention") version "0.5.0" } diff --git a/src/main/java/cn/xor7/iseeyou/ConfigData.kt b/src/main/java/cn/xor7/iseeyou/ConfigData.kt index e757aad..23b7768 100644 --- a/src/main/java/cn/xor7/iseeyou/ConfigData.kt +++ b/src/main/java/cn/xor7/iseeyou/ConfigData.kt @@ -3,47 +3,44 @@ package cn.xor7.iseeyou import org.bukkit.entity.Player data class ConfigData( - var pauseRecordingOnHighSpeed: HighSpeedPauseConfig = HighSpeedPauseConfig(), - var deleteTmpFileOnLoad: Boolean = true, - var pauseInsteadOfStopRecordingOnPlayerQuit: Boolean = false, - var recordMode: String = "blacklist", - var checkBy: String = "name", - var recordPath: String = "replay/player/\${name}@\${uuid}", - var blacklist: Set? = null, - var whitelist: Set? = null, - var outdatedRecordRetentionDays: Int = 7, - // var asyncSave: Boolean = false, + var pauseRecordingOnHighSpeed: HighSpeedPauseConfig = HighSpeedPauseConfig(), + var deleteTmpFileOnLoad: Boolean = true, + var pauseInsteadOfStopRecordingOnPlayerQuit: Boolean = false, + var filter: FilterConfig = FilterConfig(), + var recordPath: String = "replay/player/\${name}@\${uuid}", + var clearOutdatedRecordFile: OutdatedRecordRetentionConfig = OutdatedRecordRetentionConfig(), + // var asyncSave: Boolean = false, ) { fun isConfigValid(): String? { - if ("name" != checkBy && "uuid" != checkBy) { + if ("name" != filter.checkBy && "uuid" != filter.checkBy) { return "invalid checkBy value!" } - if ("blacklist" != recordMode && "whitelist" != recordMode) { + if ("blacklist" != filter.recordMode && "whitelist" != filter.recordMode) { return "invalid recordMode value!" } return null } fun setConfig() { - if ("blacklist" == recordMode) { - if (blacklist == null) { - blacklist = mutableSetOf() + if ("blacklist" == filter.recordMode) { + if (filter.blacklist == null) { + filter.blacklist = mutableSetOf() } - } else if (whitelist == null) { - whitelist = mutableSetOf() + } else if (filter.whitelist == null) { + filter.whitelist = mutableSetOf() } } fun shouldRecordPlayer(player: Player): Boolean { - return if ("blacklist" == recordMode) { - !containsPlayer(player, blacklist!!) + return if ("blacklist" == filter.recordMode) { + !containsPlayer(player, filter.blacklist!!) } else { - containsPlayer(player, whitelist!!) + containsPlayer(player, filter.whitelist!!) } } private fun containsPlayer(player: Player, list: Set): Boolean { - return if ("name" == checkBy) { + return if ("name" == filter.checkBy) { list.contains(player.name) } else { list.contains(player.uniqueId.toString()) @@ -52,6 +49,18 @@ data class ConfigData( } data class HighSpeedPauseConfig( - var enabled: Boolean = false, - var threshold: Double = 20.00, + var enabled: Boolean = false, + var threshold: Double = 20.00, +) + +data class OutdatedRecordRetentionConfig( + var enabled: Boolean = false, + var days: Int = 7, +) + +data class FilterConfig( + var checkBy: String = "name", + var recordMode: String = "blacklist", + var blacklist: Set? = null, + var whitelist: Set? = null, ) diff --git a/src/main/java/cn/xor7/iseeyou/EventListener.kt b/src/main/java/cn/xor7/iseeyou/EventListener.kt index 1b3130f..5802c2b 100644 --- a/src/main/java/cn/xor7/iseeyou/EventListener.kt +++ b/src/main/java/cn/xor7/iseeyou/EventListener.kt @@ -47,21 +47,21 @@ object EventListener : Listener { prefix = prefix.replace(".", "_") } val photographer = Bukkit - .getPhotographerManager() - .createPhotographer( - (prefix + "_" + UUID.randomUUID().toString().replace("-".toRegex(), "")).substring(0, 16), - player.location - ) + .getPhotographerManager() + .createPhotographer( + (prefix + "_" + UUID.randomUUID().toString().replace("-".toRegex(), "")).substring(0, 16), + player.location + ) if (photographer == null) { throw RuntimeException( - "Error on create photographer for player: {name: " + player.name + " , UUID:" + playerUniqueId + "}" + "Error on create photographer for player: {name: " + player.name + " , UUID:" + playerUniqueId + "}" ) } val currentTime = LocalDateTime.now() val recordPath: String = toml!!.data.recordPath - .replace("\${name}", player.name) - .replace("\${uuid}", playerUniqueId) + .replace("\${name}", player.name) + .replace("\${uuid}", playerUniqueId) File(recordPath).mkdirs() val recordFile = File(recordPath + "/" + currentTime.format(DATE_FORMATTER) + ".mcpr") if (recordFile.exists()) { @@ -82,8 +82,8 @@ object EventListener : Listener { val photographer: Photographer = photographers[event.player.uniqueId.toString()]!! val velocity = event.player.velocity if (toml!!.data.pauseRecordingOnHighSpeed.enabled && - velocity.x.pow(2.0) + velocity.z.pow(2.0) > pauseRecordingOnHighSpeedThresholdPerTickSquared && - !highSpeedPausedPhotographers.contains(photographer) + velocity.x.pow(2.0) + velocity.z.pow(2.0) > pauseRecordingOnHighSpeedThresholdPerTickSquared && + !highSpeedPausedPhotographers.contains(photographer) ) { photographer.pauseRecording() highSpeedPausedPhotographers.add(photographer) diff --git a/src/main/java/cn/xor7/iseeyou/ISeeYou.kt b/src/main/java/cn/xor7/iseeyou/ISeeYou.kt index ad00ac3..2b73bac 100644 --- a/src/main/java/cn/xor7/iseeyou/ISeeYou.kt +++ b/src/main/java/cn/xor7/iseeyou/ISeeYou.kt @@ -3,7 +3,9 @@ package cn.xor7.iseeyou import org.bukkit.Bukkit import org.bukkit.command.CommandExecutor +import org.bukkit.configuration.InvalidConfigurationException import org.bukkit.plugin.java.JavaPlugin +import org.bukkit.scheduler.BukkitRunnable import top.leavesmc.leaves.entity.Photographer import java.io.IOException import java.nio.file.* @@ -17,25 +19,36 @@ import kotlin.math.pow var toml: TomlEx? = null var photographers = mutableMapOf() var highSpeedPausedPhotographers = mutableSetOf() -var outdatedRecordRetentionDays: Int = 0 @Suppress("unused") class ISeeYou : JavaPlugin(), CommandExecutor { + private var outdatedRecordRetentionDays: Int = 0 + override fun onEnable() { setupConfig() if (toml != null) { if (toml!!.data.deleteTmpFileOnLoad) { try { - Files.walk(Paths.get(toml!!.data.recordPath), Int.MAX_VALUE, FileVisitOption.FOLLOW_LINKS).use { paths -> - paths.filter { it.isDirectory() && it.fileName.toString().endsWith(".tmp") } + Files.walk(Paths.get(toml!!.data.recordPath), Int.MAX_VALUE, FileVisitOption.FOLLOW_LINKS) + .use { paths -> + paths.filter { it.isDirectory() && it.fileName.toString().endsWith(".tmp") } .forEach { deleteTmpFolder(it) } - } - } catch (_: IOException) { + } + } catch (e: IOException) { + logger.severe("Error occurred while deleting tmp files: ${e.message}") + e.printStackTrace() } } EventListener.pauseRecordingOnHighSpeedThresholdPerTickSquared = - (toml!!.data.pauseRecordingOnHighSpeed.threshold / 20).pow(2.0) - cleanOutdatedRecordings() + (toml!!.data.pauseRecordingOnHighSpeed.threshold / 20).pow(2.0) + if(toml!!.data.clearOutdatedRecordFile.enabled) { + cleanOutdatedRecordings() + object : BukkitRunnable() { + override fun run() { + cleanOutdatedRecordings() + } + }.runTaskTimer(this, 0, 20 * 60 * 60 * 24) // Every day + } Bukkit.getPluginManager().registerEvents(EventListener, this) } else { logger.warning("Failed to initialize configuration. Plugin will not enable.") @@ -47,10 +60,10 @@ class ISeeYou : JavaPlugin(), CommandExecutor { toml = TomlEx("plugins/ISeeYou/config.toml", ConfigData::class.java) val errMsg = toml!!.data.isConfigValid() if (errMsg != null) { - throw Error(errMsg) + throw InvalidConfigurationException(errMsg) } toml!!.data.setConfig() - outdatedRecordRetentionDays = toml!!.data.outdatedRecordRetentionDays + outdatedRecordRetentionDays = toml!!.data.clearOutdatedRecordFile.days toml!!.save() } @@ -65,22 +78,22 @@ class ISeeYou : JavaPlugin(), CommandExecutor { private fun deleteTmpFolder(folderPath: Path) { try { Files.walkFileTree( - folderPath, - EnumSet.noneOf(FileVisitOption::class.java), - Int.MAX_VALUE, - object : SimpleFileVisitor() { - @Throws(IOException::class) - override fun visitFile(file: Path, attrs: BasicFileAttributes): FileVisitResult { - Files.delete(file) - return FileVisitResult.CONTINUE - } + folderPath, + EnumSet.noneOf(FileVisitOption::class.java), + Int.MAX_VALUE, + object : SimpleFileVisitor() { + @Throws(IOException::class) + override fun visitFile(file: Path, attrs: BasicFileAttributes): FileVisitResult { + Files.delete(file) + return FileVisitResult.CONTINUE + } - @Throws(IOException::class) - override fun postVisitDirectory(dir: Path, exc: IOException?): FileVisitResult { - Files.delete(dir) - return FileVisitResult.CONTINUE - } - }) + @Throws(IOException::class) + override fun postVisitDirectory(dir: Path, exc: IOException?): FileVisitResult { + Files.delete(dir) + return FileVisitResult.CONTINUE + } + }) } catch (e: IOException) { e.printStackTrace() } @@ -93,9 +106,9 @@ class ISeeYou : JavaPlugin(), CommandExecutor { var deletedCount = 0 Files.walk(recordingsDir).use { paths -> paths.filter { Files.isDirectory(it) && it.parent == recordingsDir } - .forEach { folder -> - deletedCount += deleteRecordingFiles(folder) - } + .forEach { folder -> + deletedCount += deleteRecordingFiles(folder) + } } logger.info("Finished deleting outdated recordings in $recordingsDir, deleted $deletedCount files") } catch (e: IOException) { @@ -110,22 +123,23 @@ class ISeeYou : JavaPlugin(), CommandExecutor { val currentDate = LocalDate.now() Files.walk(folderPath).use { paths -> paths.filter { Files.isRegularFile(it) && it.toString().endsWith(".mcpr") } - .forEach { file -> - val fileName = file.fileName.toString() - val creationDateStr = fileName.substringBefore('@') - val creationDate = LocalDate.parse(creationDateStr) - val daysSinceCreation = Duration.between(creationDate.atStartOfDay(), currentDate.atStartOfDay()).toDays() - if (daysSinceCreation > outdatedRecordRetentionDays) { - try { - Files.delete(file) - logger.info("Deleted recording file: $fileName") - deletedCount++ - } catch (e: IOException) { - logger.severe("Error occurred while deleting recording file: $fileName, Error: ${e.message}") - e.printStackTrace() - } + .forEach { file -> + val fileName = file.fileName.toString() + val creationDateStr = fileName.substringBefore('@') + val creationDate = LocalDate.parse(creationDateStr) + val daysSinceCreation = + Duration.between(creationDate.atStartOfDay(), currentDate.atStartOfDay()).toDays() + if (daysSinceCreation > outdatedRecordRetentionDays) { + try { + Files.delete(file) + logger.info("Deleted recording file: $fileName") + deletedCount++ + } catch (e: IOException) { + logger.severe("Error occurred while deleting recording file: $fileName, Error: ${e.message}") + e.printStackTrace() } } + } } } catch (e: IOException) { logger.severe("Error occurred while processing recording files in folder: $folderPath, Error: ${e.message}") diff --git a/src/main/java/cn/xor7/iseeyou/TomlEx.java b/src/main/java/cn/xor7/iseeyou/TomlEx.java index 24a8e7a..bfb0701 100644 --- a/src/main/java/cn/xor7/iseeyou/TomlEx.java +++ b/src/main/java/cn/xor7/iseeyou/TomlEx.java @@ -23,7 +23,7 @@ public TomlEx(String filePath, Class clazz) { try { file.getParentFile().mkdirs(); if (!file.createNewFile()) { - throw new Error("Can not create file: " + filePath); + throw new IOException("Can not create file: " + filePath); } } catch (IOException e) { throw new RuntimeException(e);