diff --git a/README.MD b/README.MD index a1a0e56..5811ff7 100644 --- a/README.MD +++ b/README.MD @@ -51,10 +51,10 @@ pauseInsteadOfStopRecordingOnPlayerQuit = false # Description: Template for the recording storage path, supports ${name} and ${uuid} variables. recordPath = "replay/player/${name}@${uuid}" -# enabled: Whether to enable the high-speed recording pause function, this function pauses recording when the player moves at high speed, default is false. -# threshold: Speed threshold for triggering high-speed recording pause, default is 20.00. [pauseRecordingOnHighSpeed] +# enabled: Whether to enable the high-speed recording pause function, this function pauses recording when the player moves at high speed, default is false. enabled = false +# threshold: Speed threshold for triggering high-speed recording pause, default is 20.00. threshold = 20.0 [filter] diff --git a/README_CN.md b/README_CN.md index 8aba8de..ae8bc84 100644 --- a/README_CN.md +++ b/README_CN.md @@ -51,10 +51,10 @@ pauseInsteadOfStopRecordingOnPlayerQuit = false # 描述: 录像存储路径模板,支持 ${name} 和 ${uuid} 变量。 recordPath = "replay/player/${name}@${uuid}" -# enabled: 是否启用高速录制暂停功能,此功能在玩家高速运动时暂停录制,默认为 false。 -# threshold: 触发高速录制暂停的速度阈值,默认为 20.00。 [pauseRecordingOnHighSpeed] +# enabled: 是否启用高速录制暂停功能,此功能在玩家高速运动时暂停录制,默认为 false。 enabled = false +# threshold: 触发高速录制暂停的速度阈值,默认为 20.00。 threshold = 20.0 [filter] diff --git a/src/main/java/cn/xor7/iseeyou/ConfigData.kt b/src/main/java/cn/xor7/iseeyou/ConfigData.kt index f5a5d5e..99d409c 100644 --- a/src/main/java/cn/xor7/iseeyou/ConfigData.kt +++ b/src/main/java/cn/xor7/iseeyou/ConfigData.kt @@ -10,7 +10,6 @@ data class ConfigData( var recordPath: String = "replay/player/\${name}@\${uuid}", var clearOutdatedRecordFile: OutdatedRecordRetentionConfig = OutdatedRecordRetentionConfig(), var recordSuspiciousPlayer: RecordSuspiciousPlayerConfig = RecordSuspiciousPlayerConfig(), - var recordMatrixSuspiciousPlayer: RecordMatrixSuspiciousPlayerConfig = RecordMatrixSuspiciousPlayerConfig() // var asyncSave: Boolean = false, ) { fun isConfigValid(): String? { @@ -61,17 +60,12 @@ data class OutdatedRecordRetentionConfig( ) data class RecordSuspiciousPlayerConfig( - var enabledThemis: Boolean = true, + var enableThemisIntegration: Boolean = false, + var enableMatrixIntegration: Boolean = false, var recordMinutes: Long = 5, var recordPath: String = "replay/suspicious/Themis/\${name}@\${uuid}", ) -data class RecordMatrixSuspiciousPlayerConfig( - var enabledMatrix: Boolean = true, - var recordMinutes: Long = 5, - var recordPath: String = "replay/suspicious/Matrix/\${name}@\${uuid}", -) - data class FilterConfig( var checkBy: String = "name", var recordMode: String = "blacklist", diff --git a/src/main/java/cn/xor7/iseeyou/ISeeYou.kt b/src/main/java/cn/xor7/iseeyou/ISeeYou.kt index f59d62b..72fecc7 100644 --- a/src/main/java/cn/xor7/iseeyou/ISeeYou.kt +++ b/src/main/java/cn/xor7/iseeyou/ISeeYou.kt @@ -1,10 +1,9 @@ package cn.xor7.iseeyou - -import cn.xor7.iseeyou.matrix.MatrixListener -import cn.xor7.iseeyou.matrix.matrixSuspiciousPhotographers -import cn.xor7.iseeyou.themis.ThemisListener -import cn.xor7.iseeyou.themis.suspiciousPhotographers +import cn.xor7.iseeyou.anticheat.AntiCheatListener +import cn.xor7.iseeyou.anticheat.listeners.MatrixListener +import cn.xor7.iseeyou.anticheat.listeners.ThemisListener +import cn.xor7.iseeyou.anticheat.suspiciousPhotographers import org.bukkit.Bukkit import org.bukkit.command.CommandExecutor import org.bukkit.configuration.InvalidConfigurationException @@ -58,12 +57,16 @@ class ISeeYou : JavaPlugin(), CommandExecutor { logger.warning("Failed to initialize configuration. Plugin will not enable.") Bukkit.getPluginManager().disablePlugin(this) } - if (Bukkit.getPluginManager().isPluginEnabled("Themis") || toml!!.data.recordSuspiciousPlayer.enabledThemis) { - Bukkit.getPluginManager().registerEvents(ThemisListener, this) - } - if (Bukkit.getPluginManager().isPluginEnabled("Matrix") || toml!!.data.recordMatrixSuspiciousPlayer.enabledMatrix) { - Bukkit.getServer().pluginManager.registerEvents(MatrixListener, this) - } + + Bukkit.getPluginManager().registerEvents(AntiCheatListener, this) + + if (Bukkit.getPluginManager().isPluginEnabled("Themis") || + toml!!.data.recordSuspiciousPlayer.enableThemisIntegration + ) Bukkit.getPluginManager().registerEvents(ThemisListener(), this) + + if (Bukkit.getPluginManager().isPluginEnabled("Matrix") || + toml!!.data.recordSuspiciousPlayer.enableMatrixIntegration + ) Bukkit.getPluginManager().registerEvents(MatrixListener(), this) } private fun setupConfig() { @@ -84,7 +87,6 @@ class ISeeYou : JavaPlugin(), CommandExecutor { photographers.clear() highSpeedPausedPhotographers.clear() suspiciousPhotographers.clear() - matrixSuspiciousPhotographers.clear() instance = null } diff --git a/src/main/java/cn/xor7/iseeyou/themis/ThemisListener.kt b/src/main/java/cn/xor7/iseeyou/anticheat/AntiCheatListener.kt similarity index 65% rename from src/main/java/cn/xor7/iseeyou/themis/ThemisListener.kt rename to src/main/java/cn/xor7/iseeyou/anticheat/AntiCheatListener.kt index fe8de21..928f081 100644 --- a/src/main/java/cn/xor7/iseeyou/themis/ThemisListener.kt +++ b/src/main/java/cn/xor7/iseeyou/anticheat/AntiCheatListener.kt @@ -1,11 +1,12 @@ -package cn.xor7.iseeyou.themis +package cn.xor7.iseeyou.anticheat import cn.xor7.iseeyou.EventListener import cn.xor7.iseeyou.instance import cn.xor7.iseeyou.toml import com.gmail.olexorus.themis.api.ActionEvent -import com.gmail.olexorus.themis.api.ViolationEvent +import me.rerere.matrix.api.events.PlayerViolationEvent import org.bukkit.Bukkit +import org.bukkit.entity.Player import org.bukkit.event.EventHandler import org.bukkit.event.Listener import org.bukkit.event.player.PlayerQuitEvent @@ -17,47 +18,46 @@ import java.util.* val suspiciousPhotographers: MutableMap = mutableMapOf() -object ThemisListener : Listener { +object AntiCheatListener : Listener { init { object : BukkitRunnable() { override fun run() { val currentTime = System.currentTimeMillis() - suspiciousPhotographers.forEach { (_, susPhotographer) -> - if (currentTime - susPhotographer.lastTagged > + suspiciousPhotographers.entries.removeIf { + if (currentTime - it.value.lastTagged > Duration.ofMinutes(toml!!.data.recordSuspiciousPlayer.recordMinutes).toMillis() ) { - susPhotographer.photographer.stopRecording() - suspiciousPhotographers.remove(susPhotographer.name) - } + it.value.photographer.stopRecording() + return@removeIf true + } else false } } }.runTaskTimer(instance!!, 0, 20 * 60 * 5) } - @EventHandler - fun onAction(e: ActionEvent) { - val suspiciousPhotographer = suspiciousPhotographers[e.player.name] + fun onAntiCheatAction(player: Player) { + val suspiciousPhotographer = suspiciousPhotographers[player.name] if (suspiciousPhotographer != null) { - suspiciousPhotographers[e.player.name] = + suspiciousPhotographers[player.name] = suspiciousPhotographer.copy(lastTagged = System.currentTimeMillis()) } else { val photographer = Bukkit .getPhotographerManager() .createPhotographer( - (e.player.name + "_sus_" + UUID.randomUUID().toString().replace("-".toRegex(), "")) + (player.name + "_sus_" + UUID.randomUUID().toString().replace("-".toRegex(), "")) .substring(0, 16), - e.player.location + player.location ) if (photographer == null) { throw RuntimeException( - "Error on create photographer for player: {name: " + e.player.name + " , UUID:" + e.player.uniqueId + "}" + "Error on create suspicious photographer for player: {name: " + player.name + " , UUID:" + player.uniqueId + "}" ) } - photographer.setFollowPlayer(e.player) + photographer.setFollowPlayer(player) val currentTime = LocalDateTime.now() val recordPath: String = toml!!.data.recordSuspiciousPlayer.recordPath - .replace("\${name}", e.player.name) - .replace("\${uuid}", e.player.uniqueId.toString()) + .replace("\${name}", player.name) + .replace("\${uuid}", player.uniqueId.toString()) File(recordPath).mkdirs() val recordFile = File(recordPath + "/" + currentTime.format(EventListener.DATE_FORMATTER) + ".mcpr") @@ -66,9 +66,9 @@ object ThemisListener : Listener { } recordFile.createNewFile() photographer.setRecordFile(recordFile) - suspiciousPhotographers[e.player.name] = SuspiciousPhotographer( + suspiciousPhotographers[player.name] = SuspiciousPhotographer( photographer = photographer, - name = e.player.name, + name = player.name, lastTagged = System.currentTimeMillis() ) } diff --git a/src/main/java/cn/xor7/iseeyou/themis/SuspiciousPhotographer.kt b/src/main/java/cn/xor7/iseeyou/anticheat/SuspiciousPhotographer.kt similarity index 83% rename from src/main/java/cn/xor7/iseeyou/themis/SuspiciousPhotographer.kt rename to src/main/java/cn/xor7/iseeyou/anticheat/SuspiciousPhotographer.kt index 464b206..335377b 100644 --- a/src/main/java/cn/xor7/iseeyou/themis/SuspiciousPhotographer.kt +++ b/src/main/java/cn/xor7/iseeyou/anticheat/SuspiciousPhotographer.kt @@ -1,4 +1,4 @@ -package cn.xor7.iseeyou.themis +package cn.xor7.iseeyou.anticheat import top.leavesmc.leaves.entity.Photographer diff --git a/src/main/java/cn/xor7/iseeyou/anticheat/listeners/MatrixListener.kt b/src/main/java/cn/xor7/iseeyou/anticheat/listeners/MatrixListener.kt new file mode 100644 index 0000000..a99fcae --- /dev/null +++ b/src/main/java/cn/xor7/iseeyou/anticheat/listeners/MatrixListener.kt @@ -0,0 +1,12 @@ +package cn.xor7.iseeyou.anticheat.listeners + +import cn.xor7.iseeyou.anticheat.AntiCheatListener +import com.gmail.olexorus.themis.api.ActionEvent +import me.rerere.matrix.api.events.PlayerViolationEvent +import org.bukkit.event.EventHandler +import org.bukkit.event.Listener + +class MatrixListener : Listener { + @EventHandler + fun onPlayerViolation(e: PlayerViolationEvent) = AntiCheatListener.onAntiCheatAction(e.player) +} \ No newline at end of file diff --git a/src/main/java/cn/xor7/iseeyou/anticheat/listeners/ThemisListener.kt b/src/main/java/cn/xor7/iseeyou/anticheat/listeners/ThemisListener.kt new file mode 100644 index 0000000..c028e47 --- /dev/null +++ b/src/main/java/cn/xor7/iseeyou/anticheat/listeners/ThemisListener.kt @@ -0,0 +1,11 @@ +package cn.xor7.iseeyou.anticheat.listeners + +import cn.xor7.iseeyou.anticheat.AntiCheatListener +import com.gmail.olexorus.themis.api.ActionEvent +import org.bukkit.event.EventHandler +import org.bukkit.event.Listener + +class ThemisListener : Listener { + @EventHandler + fun onAction(e: ActionEvent) = AntiCheatListener.onAntiCheatAction(e.player) +} \ No newline at end of file diff --git a/src/main/java/cn/xor7/iseeyou/matrix/MatrixListener.kt b/src/main/java/cn/xor7/iseeyou/matrix/MatrixListener.kt deleted file mode 100644 index c5e4111..0000000 --- a/src/main/java/cn/xor7/iseeyou/matrix/MatrixListener.kt +++ /dev/null @@ -1,101 +0,0 @@ -package cn.xor7.iseeyou.matrix - -import cn.xor7.iseeyou.EventListener -import cn.xor7.iseeyou.instance -import cn.xor7.iseeyou.toml -import me.rerere.matrix.api.MatrixAPI -import me.rerere.matrix.api.MatrixAPIProvider -import me.rerere.matrix.api.events.PlayerViolationEvent - -import org.bukkit.Bukkit -import org.bukkit.event.EventHandler -import org.bukkit.event.Listener -import org.bukkit.event.player.PlayerQuitEvent -import org.bukkit.scheduler.BukkitRunnable -import java.io.File -import java.time.Duration -import java.time.LocalDateTime -import java.util.* - -val matrixSuspiciousPhotographers: MutableMap = mutableMapOf() - -object MatrixListener : Listener { - val api: MatrixAPI = MatrixAPIProvider.getAPI() - - init { - object : BukkitRunnable() { - override fun run() { - val currentTime = System.currentTimeMillis() - matrixSuspiciousPhotographers.forEach { (_, susPhotographer) -> - if (currentTime - susPhotographer.lastTagged > - Duration.ofMinutes(toml!!.data.recordMatrixSuspiciousPlayer.recordMinutes).toMillis() - ) { - susPhotographer.photographer.stopRecording() - matrixSuspiciousPhotographers.remove(susPhotographer.name) - } - } - } - }.runTaskTimer(instance!!, 0, 20 * 60 * 5) - } - - @EventHandler - fun onPlayerViolation(e: PlayerViolationEvent) { - val playerName = e.player.name - val suspiciousPhotographer = matrixSuspiciousPhotographers[playerName] - if (suspiciousPhotographer != null) { - matrixSuspiciousPhotographers[e.player.name] = - suspiciousPhotographer.copy(lastTagged = System.currentTimeMillis()) - } else { - val runnable = object : BukkitRunnable() { - override fun run() { - var prefix = e.player.name - if (prefix.length > 10) { - prefix = prefix.substring(0, 10) - } - if (prefix.startsWith(".")) { - prefix = prefix.replace(".", "_") - } - val photographer = Bukkit - .getPhotographerManager() - .createPhotographer( - (prefix + "_" + UUID.randomUUID().toString().replace("-".toRegex(), "")).substring(0, 16), - e.player.location - ) - if (photographer == null) { - throw RuntimeException( - "Error on create photographer for player: {name: " + e.player.name + " , UUID:" + e.player.uniqueId + "}" - ) - } - photographer.setFollowPlayer(e.player) - val currentTime = LocalDateTime.now() - val recordPath: String = toml?.data?.recordMatrixSuspiciousPlayer?.recordPath - ?.replace("\${name}", e.player.name) - ?.replace("\${uuid}", e.player.uniqueId.toString()) ?: "" - File(recordPath).mkdirs() - val recordFile = - File(recordPath + "/" + currentTime.format(EventListener.DATE_FORMATTER) + ".mcpr") - if (recordFile.exists()) { - recordFile.delete() - } - recordFile.createNewFile() - photographer.setRecordFile(recordFile) - matrixSuspiciousPhotographers[e.player.name] = MatrixSuspiciousPhotographer( - photographer = photographer, - name = e.player.name, - lastTagged = System.currentTimeMillis() - ) - } - } - runnable.runTask(instance!!) - } - } - - @EventHandler - fun onPlayerQuit(e: PlayerQuitEvent) { - val suspiciousPhotographer = matrixSuspiciousPhotographers[e.player.name] - if (suspiciousPhotographer != null) { - suspiciousPhotographer.photographer.stopRecording() - matrixSuspiciousPhotographers.remove(e.player.name) - } - } -} diff --git a/src/main/java/cn/xor7/iseeyou/matrix/MatrixSuspiciousPhotographer.kt b/src/main/java/cn/xor7/iseeyou/matrix/MatrixSuspiciousPhotographer.kt deleted file mode 100644 index eb1462e..0000000 --- a/src/main/java/cn/xor7/iseeyou/matrix/MatrixSuspiciousPhotographer.kt +++ /dev/null @@ -1,9 +0,0 @@ -package cn.xor7.iseeyou.matrix - -import top.leavesmc.leaves.entity.Photographer - -data class MatrixSuspiciousPhotographer( - val photographer: Photographer, - val name: String, - val lastTagged: Long, -)