Skip to content

Commit

Permalink
Merge pull request #467 from FxRayHughes/dev/other
Browse files Browse the repository at this point in the history
增加了一种新的 database-player 的控制器 支持了redis
  • Loading branch information
Bkm016 authored Sep 21, 2024
2 parents da69d53 + c55ef33 commit e539657
Show file tree
Hide file tree
Showing 6 changed files with 194 additions and 4 deletions.
10 changes: 10 additions & 0 deletions module/database/database-player-redis/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
dependencies {
compileOnly(project(":common"))
compileOnly(project(":common-util"))
compileOnly(project(":common-platform-api"))
compileOnly(project(":module:database"))
compileOnly(project(":module:database:database-player"))
compileOnly(project(":module:database:database-alkaid-redis"))
compileOnly(project(":module:basic:basic-configuration"))
compileOnly("ink.ptms.core:v11701:11701-minimize:universal")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package taboolib.expansion

import taboolib.common.platform.function.submitAsync
import java.util.*
import java.util.concurrent.TimeUnit

/**
* Redis 数据容器
* get 时优先判断Redis缓存 若无则设置数据到缓存
* set 时删除Redis缓存
*
* @property user 用户标识
* @property database 数据库实例
* @property redis 数据管理器
*/
class RedisDataContainer(val user: String, val database: Database, val redis: RedisDatabaseHandler) {

/**
* 设置指定键的值并立即保存
*
* @param key 键
* @param value 值
*/
operator fun set(key: String, value: Any) {
redis.connection?.delete(key)
database[user, key] = value.toString()
}

/**
* 设置指定键的值,并在指定延迟后删除 (不进入数据库)
*
* @param key 键
* @param value 值
* @param delay 延迟时间
* @param timeUnit 时间单位
*/
fun setDelayed(key: String, value: Any, delay: Long = 3L, timeUnit: TimeUnit = TimeUnit.SECONDS) {
redis.connection?.setEx(key, value.toString(), delay, timeUnit)
}

/**
* 获取指定键的值 优先从缓存中取出
*
* @param key 键
* @return 对应的值,如果不存在则返回 null
*/
operator fun get(key: String): String? {
val redisCache = redis.connection?.get(key)
if (redisCache != null) {
return redisCache
}
val data = database[user, key]
if (data != null) {
redis.connection?.setEx(key, data, REDIS_SECONDS, REDIS_TIMEOUT)
return data
}
return null
}

/**
* 返回对象的字符串表示
*
* @return 对象的字符串表示
*/
override fun toString(): String {
return "RedisDataContainer(user='$user')"
}

companion object {

/**
* 缓存设置多长时间后删除
*
* 默认为 30分钟
*/
var REDIS_SECONDS = 1800L

/**
* 缓存设置多长时间后删除 - 单位
*/
var REDIS_TIMEOUT = TimeUnit.SECONDS
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package taboolib.expansion

import taboolib.common.io.newFile
import taboolib.common.platform.function.getDataFolder
import taboolib.common.platform.function.pluginId
import taboolib.library.configuration.ConfigurationSection
import java.util.concurrent.ConcurrentHashMap

/**
* 创建 Redis 数据管理器
* 配置文件要求如下:
* Database:
* enable: false
* host: localhost
* port: 3306
* user: root
* password: root
* database: minecraft
* table: elytra
* Redis:
* host: localhost
* port: 6379
* user: user
* password: password
* connect: 32
* timeout: 1000
*/
class RedisDatabaseHandler(
val conf: ConfigurationSection,
var table: String = "",
flags: List<String> = emptyList(),
clearFlags: Boolean = false,
ssl: String? = null,
dataFile: String = "data.db",
) {

val database: Database
private var connector: SingleRedisConnector? = null
var connection: SingleRedisConnection? = null

/**
* 玩家Redis数据容器。
*
* 该变量用于存储玩家的数据容器。它是一个线程安全的并发哈希映射,
* 以玩家的 UUID 为键,对应的 [DataContainer] 为值。
* 这允许快速、安全地访问和修改玩家的数据。
*/
val redisDataContainer = ConcurrentHashMap<String, RedisDataContainer>()

init {
table = conf.getConfigurationSection("Database")!!.getString("table", pluginId)!!
database = if (conf.getBoolean("enable")) {
buildPlayerDatabase(conf, table, flags, clearFlags, ssl)
} else {
buildPlayerDatabase(newFile(getDataFolder(), dataFile), table)
}
val redis = conf.getConfigurationSection("Redis")!!
if (redis.getBoolean("enable")) {
connector = AlkaidRedis.create().fromConfig(redis)
connection?.close()
connection = connector!!.connect().connection()
}
}

/**
* 初始化数据容器
* 这个user作为索引,不一定非得是玩家的UUID
*/
fun setupRedisDataContainer(user: String): RedisDataContainer {
return redisDataContainer.computeIfAbsent(user) { RedisDataContainer(user, database, this) }
}

/**
* 获取数据容器
*/
fun getRedisDataContainer(user: String): RedisDataContainer {
return redisDataContainer[user] ?: error("unavailable database container ${user}")
}

/**
* 移除数据容器
*/
fun removeRedisDataContainer(user: String) {
redisDataContainer.remove(user)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package taboolib.expansion
import taboolib.common.Inject
import taboolib.common.platform.Schedule
import taboolib.common.platform.function.submitAsync
import java.util.UUID
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.TimeUnit

Expand Down Expand Up @@ -39,9 +40,16 @@ class DataContainer(val user: String, val database: Database) {
* @param targetUser 目标用户
* @param key 键
* @param value 值
* @param sync 是否同步给内存,要求targetUser为UUID
*/
operator fun set(targetUser: String, key: String, value: Any) {
fun forcedSet(targetUser: String, key: String, value: Any, sync: Boolean = false) {
database[targetUser, key] = value.toString()
// 因为 targetUser 不一定是UUID
if (sync) {
UUID.fromString(targetUser)?.let {
playerDataContainer[it]?.source?.set(key, value.toString())
}
}
}

/**
Expand Down Expand Up @@ -136,4 +144,4 @@ class DataContainer(val user: String, val database: Database) {
playerDataContainer.entries.forEach { it.value.checkUpdate() }
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package taboolib.expansion

import org.bukkit.event.player.PlayerJoinEvent
import org.bukkit.event.player.PlayerQuitEvent
import taboolib.common.Inject
import taboolib.common.platform.event.SubscribeEvent

Expand All @@ -17,9 +18,9 @@ object MultipleHandlerListener {
}

@SubscribeEvent
fun onPlayerQuit(event: PlayerJoinEvent) {
fun onPlayerQuit(event: PlayerQuitEvent) {
hooks.forEach {
it.removeDataContainer(event.player.uniqueId.toString())
}
}
}
}
1 change: 1 addition & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ include(
"module:database:database-player",
"module:database:database-ptc",
"module:database:database-ptc-object",
"module:database:database-player-redis",

// 脚本环境
"module:script:script-javascript",
Expand Down

0 comments on commit e539657

Please sign in to comment.