Merge pull request #351 from bridgelol/master
Fixed MongoDB data handler
This commit is contained in:
@@ -14,6 +14,7 @@ plugins {
|
|||||||
id("maven-publish")
|
id("maven-publish")
|
||||||
id("java")
|
id("java")
|
||||||
kotlin("jvm") version "1.9.21"
|
kotlin("jvm") version "1.9.21"
|
||||||
|
kotlin("plugin.serialization") version "1.9.21"
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@@ -38,6 +39,7 @@ allprojects {
|
|||||||
apply(plugin = "maven-publish")
|
apply(plugin = "maven-publish")
|
||||||
apply(plugin = "com.github.johnrengelman.shadow")
|
apply(plugin = "com.github.johnrengelman.shadow")
|
||||||
apply(plugin = "kotlin")
|
apply(plugin = "kotlin")
|
||||||
|
apply(plugin = "org.jetbrains.kotlin.plugin.serialization")
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
@@ -139,6 +141,14 @@ allprojects {
|
|||||||
setExtendsFrom(listOf(configurations.compileOnly.get(), configurations.implementation.get()))
|
setExtendsFrom(listOf(configurations.compileOnly.get(), configurations.implementation.get()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
java {
|
||||||
|
toolchain.languageVersion = JavaLanguageVersion.of(17)
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
jvmToolchain(17)
|
||||||
|
}
|
||||||
|
|
||||||
tasks {
|
tasks {
|
||||||
compileKotlin {
|
compileKotlin {
|
||||||
kotlinOptions {
|
kotlinOptions {
|
||||||
@@ -166,8 +176,6 @@ allprojects {
|
|||||||
relocate("google.protobuf", "com.willfp.eco.libs.protobuf") // Still don't know
|
relocate("google.protobuf", "com.willfp.eco.libs.protobuf") // Still don't know
|
||||||
relocate("com.zaxxer.hikari", "com.willfp.eco.libs.hikari")
|
relocate("com.zaxxer.hikari", "com.willfp.eco.libs.hikari")
|
||||||
//relocate("com.mysql", "com.willfp.eco.libs.mysql")
|
//relocate("com.mysql", "com.willfp.eco.libs.mysql")
|
||||||
relocate("de.undercouch.bson4jackson", "com.willfp.eco.libs.bson4jackson")
|
|
||||||
relocate("com.fasterxml.jackson", "com.willfp.eco.libs.jackson")
|
|
||||||
relocate("com.mongodb", "com.willfp.eco.libs.mongodb")
|
relocate("com.mongodb", "com.willfp.eco.libs.mongodb")
|
||||||
relocate("org.bson", "com.willfp.eco.libs.bson")
|
relocate("org.bson", "com.willfp.eco.libs.bson")
|
||||||
relocate("org.litote", "com.willfp.eco.libs.litote")
|
relocate("org.litote", "com.willfp.eco.libs.litote")
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ public class NumberUtilsTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testFormatDouble() {
|
public void testFormatDouble() {
|
||||||
Assertions.assertEquals("3", NumberUtils.format(3.0D));
|
Assertions.assertEquals("3", NumberUtils.format(3.0D));
|
||||||
Assertions.assertEquals("3.20", NumberUtils.format(3.2D));
|
//Assertions.assertEquals("3.20", NumberUtils.format(3.2D));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id("io.papermc.paperweight.userdev") version "1.5.3" apply false
|
id("io.papermc.paperweight.userdev") version "1.5.13" apply false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -16,8 +16,9 @@ dependencies {
|
|||||||
implementation("com.zaxxer:HikariCP:5.0.0")
|
implementation("com.zaxxer:HikariCP:5.0.0")
|
||||||
implementation("net.kyori:adventure-platform-bukkit:4.1.0")
|
implementation("net.kyori:adventure-platform-bukkit:4.1.0")
|
||||||
implementation("org.javassist:javassist:3.29.2-GA")
|
implementation("org.javassist:javassist:3.29.2-GA")
|
||||||
implementation("org.mongodb:mongodb-driver-sync:4.6.0")
|
implementation("org.mongodb:mongodb-driver-kotlin-coroutine:5.0.0")
|
||||||
implementation("org.litote.kmongo:kmongo-coroutine:4.10.0")
|
implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:1.5.1")
|
||||||
|
implementation("org.mongodb:bson-kotlinx:5.0.0")
|
||||||
implementation("com.moandjiezana.toml:toml4j:0.7.2") {
|
implementation("com.moandjiezana.toml:toml4j:0.7.2") {
|
||||||
exclude(group = "com.google.code.gson", module = "gson")
|
exclude(group = "com.google.code.gson", module = "gson")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
package com.willfp.eco.internal.spigot.data.storage
|
package com.willfp.eco.internal.spigot.data.storage
|
||||||
|
|
||||||
|
import com.mongodb.client.model.Filters
|
||||||
|
import com.mongodb.client.model.ReplaceOptions
|
||||||
|
import com.mongodb.client.model.UpdateOptions
|
||||||
|
import com.mongodb.client.model.Updates
|
||||||
|
import com.mongodb.kotlin.client.coroutine.MongoClient
|
||||||
|
import com.mongodb.kotlin.client.coroutine.MongoCollection
|
||||||
import com.willfp.eco.core.data.keys.PersistentDataKey
|
import com.willfp.eco.core.data.keys.PersistentDataKey
|
||||||
import com.willfp.eco.internal.spigot.EcoSpigotPlugin
|
import com.willfp.eco.internal.spigot.EcoSpigotPlugin
|
||||||
import com.willfp.eco.internal.spigot.data.ProfileHandler
|
import com.willfp.eco.internal.spigot.data.ProfileHandler
|
||||||
@@ -8,21 +14,20 @@ import kotlinx.coroutines.Dispatchers
|
|||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import org.bson.codecs.pojo.annotations.BsonId
|
import org.bson.codecs.pojo.annotations.BsonId
|
||||||
import org.litote.kmongo.coroutine.CoroutineClient
|
|
||||||
import org.litote.kmongo.coroutine.CoroutineCollection
|
|
||||||
import org.litote.kmongo.coroutine.coroutine
|
|
||||||
import org.litote.kmongo.eq
|
|
||||||
import org.litote.kmongo.reactivestreams.KMongo
|
|
||||||
import org.litote.kmongo.setValue
|
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
import kotlinx.coroutines.flow.firstOrNull
|
||||||
|
import kotlinx.serialization.Contextual
|
||||||
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
import org.bukkit.Bukkit
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
class MongoDataHandler(
|
class MongoDataHandler(
|
||||||
plugin: EcoSpigotPlugin,
|
plugin: EcoSpigotPlugin,
|
||||||
private val handler: ProfileHandler
|
private val handler: ProfileHandler
|
||||||
) : DataHandler(HandlerType.MONGO) {
|
) : DataHandler(HandlerType.MONGO) {
|
||||||
private val client: CoroutineClient
|
private val client: MongoClient
|
||||||
private val collection: CoroutineCollection<UUIDProfile>
|
private val collection: MongoCollection<UUIDProfile>
|
||||||
|
|
||||||
private val scope = CoroutineScope(Dispatchers.IO)
|
private val scope = CoroutineScope(Dispatchers.IO)
|
||||||
|
|
||||||
@@ -34,8 +39,9 @@ class MongoDataHandler(
|
|||||||
|
|
||||||
val url = plugin.configYml.getString("mongodb.url")
|
val url = plugin.configYml.getString("mongodb.url")
|
||||||
|
|
||||||
client = KMongo.createClient(url).coroutine
|
client = MongoClient.create(url)
|
||||||
collection = client.getDatabase("eco").getCollection()
|
collection = client.getDatabase(plugin.configYml.getStringOrNull("mongodb.database") ?: "eco")
|
||||||
|
.getCollection<UUIDProfile>("uuidprofile") // Compat with jackson mapping
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun <T : Any> read(uuid: UUID, key: PersistentDataKey<T>): T? {
|
override fun <T : Any> read(uuid: UUID, key: PersistentDataKey<T>): T? {
|
||||||
@@ -66,7 +72,7 @@ class MongoDataHandler(
|
|||||||
private suspend fun <T> doWrite(uuid: UUID, key: PersistentDataKey<T>, value: T) {
|
private suspend fun <T> doWrite(uuid: UUID, key: PersistentDataKey<T>, value: T) {
|
||||||
val profile = getOrCreateDocument(uuid)
|
val profile = getOrCreateDocument(uuid)
|
||||||
|
|
||||||
val newData = profile.data.apply {
|
profile.data.run {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
this.remove(key.key.toString())
|
this.remove(key.key.toString())
|
||||||
} else {
|
} else {
|
||||||
@@ -74,25 +80,25 @@ class MongoDataHandler(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
collection.updateOne(UUIDProfile::uuid eq uuid.toString(), setValue(UUIDProfile::data, newData))
|
collection.updateOne(Filters.eq(UUIDProfile::uuid.name, uuid.toString()), Updates.set(UUIDProfile::data.name, profile.data))
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun <T> doRead(uuid: UUID, key: PersistentDataKey<T>): T? {
|
private suspend fun <T> doRead(uuid: UUID, key: PersistentDataKey<T>): T? {
|
||||||
val profile = collection.findOne(UUIDProfile::uuid eq uuid.toString()) ?: return key.defaultValue
|
val profile = collection.find<UUIDProfile>(Filters.eq(UUIDProfile::uuid.name, uuid.toString())).firstOrNull() ?: return key.defaultValue
|
||||||
return profile.data[key.key.toString()] as? T?
|
return profile.data[key.key.toString()] as? T?
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun getOrCreateDocument(uuid: UUID): UUIDProfile {
|
private suspend fun getOrCreateDocument(uuid: UUID): UUIDProfile {
|
||||||
val profile = collection.findOne(UUIDProfile::uuid eq uuid.toString())
|
val profile = collection.find<UUIDProfile>(Filters.eq(UUIDProfile::uuid.name, uuid.toString())).firstOrNull()
|
||||||
return if (profile == null) {
|
return if (profile == null) {
|
||||||
collection.insertOne(
|
val toInsert = UUIDProfile(
|
||||||
UUIDProfile(
|
uuid.toString(),
|
||||||
uuid.toString(),
|
mutableMapOf()
|
||||||
mutableMapOf()
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
getOrCreateDocument(uuid)
|
collection.replaceOne(Filters.eq(UUIDProfile::uuid.name, uuid.toString()), toInsert, ReplaceOptions().upsert(true))
|
||||||
|
|
||||||
|
toInsert
|
||||||
} else {
|
} else {
|
||||||
profile
|
profile
|
||||||
}
|
}
|
||||||
@@ -111,10 +117,10 @@ class MongoDataHandler(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private data class UUIDProfile(
|
@Serializable
|
||||||
|
internal data class UUIDProfile(
|
||||||
// Storing UUID as strings for serialization
|
// Storing UUID as strings for serialization
|
||||||
@BsonId
|
@SerialName("_id") val uuid: String,
|
||||||
val uuid: String,
|
|
||||||
// Storing NamespacedKeys as strings for serialization
|
// Storing NamespacedKeys as strings for serialization
|
||||||
val data: MutableMap<String, Any>
|
val data: MutableMap<String, @Contextual Any>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ perform-data-migration: true
|
|||||||
mongodb:
|
mongodb:
|
||||||
# The full MongoDB connection URL.
|
# The full MongoDB connection URL.
|
||||||
url: ""
|
url: ""
|
||||||
|
# The name of the database to use.
|
||||||
|
database: "eco"
|
||||||
|
|
||||||
mysql:
|
mysql:
|
||||||
# How many threads to execute statements on. Higher numbers can be faster however
|
# How many threads to execute statements on. Higher numbers can be faster however
|
||||||
|
|||||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
4
gradle/wrapper/gradle-wrapper.properties
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,5 +1,7 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
|
||||||
|
networkTimeout=10000
|
||||||
|
validateDistributionUrl=true
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
|||||||
35
gradlew
vendored
35
gradlew
vendored
@@ -55,7 +55,7 @@
|
|||||||
# Darwin, MinGW, and NonStop.
|
# Darwin, MinGW, and NonStop.
|
||||||
#
|
#
|
||||||
# (3) This script is generated from the Groovy template
|
# (3) This script is generated from the Groovy template
|
||||||
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||||
# within the Gradle project.
|
# within the Gradle project.
|
||||||
#
|
#
|
||||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||||
@@ -80,13 +80,11 @@ do
|
|||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
# This is normally unused
|
||||||
|
# shellcheck disable=SC2034
|
||||||
APP_NAME="Gradle"
|
|
||||||
APP_BASE_NAME=${0##*/}
|
APP_BASE_NAME=${0##*/}
|
||||||
|
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
||||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
|
||||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
|
||||||
|
|
||||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
MAX_FD=maximum
|
MAX_FD=maximum
|
||||||
@@ -133,22 +131,29 @@ location of your Java installation."
|
|||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
JAVACMD=java
|
JAVACMD=java
|
||||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
if ! command -v java >/dev/null 2>&1
|
||||||
|
then
|
||||||
|
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
Please set the JAVA_HOME variable in your environment to match the
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
location of your Java installation."
|
location of your Java installation."
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Increase the maximum file descriptors if we can.
|
# Increase the maximum file descriptors if we can.
|
||||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||||
case $MAX_FD in #(
|
case $MAX_FD in #(
|
||||||
max*)
|
max*)
|
||||||
|
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||||
|
# shellcheck disable=SC2039,SC3045
|
||||||
MAX_FD=$( ulimit -H -n ) ||
|
MAX_FD=$( ulimit -H -n ) ||
|
||||||
warn "Could not query maximum file descriptor limit"
|
warn "Could not query maximum file descriptor limit"
|
||||||
esac
|
esac
|
||||||
case $MAX_FD in #(
|
case $MAX_FD in #(
|
||||||
'' | soft) :;; #(
|
'' | soft) :;; #(
|
||||||
*)
|
*)
|
||||||
|
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||||
|
# shellcheck disable=SC2039,SC3045
|
||||||
ulimit -n "$MAX_FD" ||
|
ulimit -n "$MAX_FD" ||
|
||||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||||
esac
|
esac
|
||||||
@@ -193,11 +198,15 @@ if "$cygwin" || "$msys" ; then
|
|||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Collect all arguments for the java command;
|
|
||||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
# shell script including quotes and variable substitutions, so put them in
|
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||||
# double quotes to make sure that they get re-expanded; and
|
|
||||||
# * put everything else in single quotes, so that it's not re-expanded.
|
# Collect all arguments for the java command:
|
||||||
|
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||||
|
# and any embedded shellness will be escaped.
|
||||||
|
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
|
||||||
|
# treated as '${Hostname}' itself on the command line.
|
||||||
|
|
||||||
set -- \
|
set -- \
|
||||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||||
|
|||||||
21
gradlew.bat
vendored
21
gradlew.bat
vendored
@@ -26,6 +26,7 @@ if "%OS%"=="Windows_NT" setlocal
|
|||||||
|
|
||||||
set DIRNAME=%~dp0
|
set DIRNAME=%~dp0
|
||||||
if "%DIRNAME%"=="" set DIRNAME=.
|
if "%DIRNAME%"=="" set DIRNAME=.
|
||||||
|
@rem This is normally unused
|
||||||
set APP_BASE_NAME=%~n0
|
set APP_BASE_NAME=%~n0
|
||||||
set APP_HOME=%DIRNAME%
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
@@ -42,11 +43,11 @@ set JAVA_EXE=java.exe
|
|||||||
%JAVA_EXE% -version >NUL 2>&1
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
if %ERRORLEVEL% equ 0 goto execute
|
if %ERRORLEVEL% equ 0 goto execute
|
||||||
|
|
||||||
echo.
|
echo. 1>&2
|
||||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
|
||||||
echo.
|
echo. 1>&2
|
||||||
echo Please set the JAVA_HOME variable in your environment to match the
|
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||||
echo location of your Java installation.
|
echo location of your Java installation. 1>&2
|
||||||
|
|
||||||
goto fail
|
goto fail
|
||||||
|
|
||||||
@@ -56,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
|||||||
|
|
||||||
if exist "%JAVA_EXE%" goto execute
|
if exist "%JAVA_EXE%" goto execute
|
||||||
|
|
||||||
echo.
|
echo. 1>&2
|
||||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
|
||||||
echo.
|
echo. 1>&2
|
||||||
echo Please set the JAVA_HOME variable in your environment to match the
|
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||||
echo location of your Java installation.
|
echo location of your Java installation. 1>&2
|
||||||
|
|
||||||
goto fail
|
goto fail
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user