diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index 1feca0a..abe2587 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -8,7 +8,6 @@
diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml
index d4b7acc..c224ad5 100644
--- a/.idea/kotlinc.xml
+++ b/.idea/kotlinc.xml
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/model/build.gradle.kts b/model/build.gradle.kts
index b768bd0..6db0383 100644
--- a/model/build.gradle.kts
+++ b/model/build.gradle.kts
@@ -3,7 +3,8 @@ import net.thebugmc.gradle.sonatypepublisher.PublishingType
plugins {
id("java-library")
id("net.thebugmc.gradle.sonatype-central-portal-publisher").version("1.2.3")
- kotlin("jvm") version "2.0.20"
+ kotlin("jvm") version "2.0.21"
+ id("com.google.devtools.ksp").version("2.0.21-1.0.26")
}
group = "net.dungeon-hub.api"
@@ -13,9 +14,30 @@ description = "The model classes that are used in the Dungeon Hub API."
repositories {
mavenCentral()
+
+ maven {
+ url = uri("https://repo.kordex.dev/releases")
+ name = "KordEx (Releases)"
+ }
+ maven {
+ url = uri("https://repo.kordex.dev/snapshots")
+ name = "KordEx (Snapshots)"
+ }
+ maven {
+ url = uri("https://oss.sonatype.org/content/repositories/snapshots")
+ name = "Sonatype Snapshots (Legacy)"
+ }
}
dependencies {
+ //Moshi, the JSON library
+ api("com.squareup.moshi:moshi-kotlin:1.15.1")
+ ksp("com.squareup.moshi:moshi-kotlin-codegen:1.15.1")
+
+ //Used frameworks for compatible classes
+ implementation("dev.kordex:kord-extensions:2.2.1-SNAPSHOT")
+ implementation("org.springframework:spring-web:6.1.12")
+
testImplementation(platform("org.junit:junit-bom:5.10.0"))
testImplementation("org.junit.jupiter:junit-jupiter")
testImplementation(kotlin("test"))
@@ -67,6 +89,9 @@ tasks.test {
kotlin {
jvmToolchain(17)
+ compilerOptions {
+ freeCompilerArgs.add("-Xjvm-default=all")
+ }
}
java {
diff --git a/model/src/main/kotlin/net/dungeonhub/enums/QueueStep.kt b/model/src/main/kotlin/net/dungeonhub/enums/QueueStep.kt
new file mode 100644
index 0000000..e87582c
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/enums/QueueStep.kt
@@ -0,0 +1,7 @@
+package net.dungeonhub.enums
+
+enum class QueueStep {
+ Confirmation,
+ Transcript,
+ Approving
+}
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/enums/ScoreResetType.kt b/model/src/main/kotlin/net/dungeonhub/enums/ScoreResetType.kt
new file mode 100644
index 0000000..6f70b07
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/enums/ScoreResetType.kt
@@ -0,0 +1,11 @@
+package net.dungeonhub.enums
+
+import dev.kordex.core.commands.application.slash.converters.ChoiceEnum
+
+enum class ScoreResetType : ChoiceEnum {
+ Default,
+ Event,
+ Both;
+
+ override val readableName = name
+}
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/enums/ScoreType.kt b/model/src/main/kotlin/net/dungeonhub/enums/ScoreType.kt
new file mode 100644
index 0000000..a9f60de
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/enums/ScoreType.kt
@@ -0,0 +1,32 @@
+package net.dungeonhub.enums
+
+import dev.kordex.core.commands.application.slash.converters.ChoiceEnum
+import net.dungeonhub.model.carry_type.CarryTypeModel
+
+enum class ScoreType(
+ override val readableName: String,
+ val displayName: String,
+ val leaderboardSuffix: String?
+) : ChoiceEnum {
+ Default("current", "Current"),
+ Alltime("alltime", "Alltime", "(all-time)"),
+ Event("event", "Event", "(event)");
+
+ constructor(name: String, displayName: String) : this(name, displayName, null)
+
+ fun getLeaderboardTitle(carryType: CarryTypeModel?): String {
+ val suffix = if (leaderboardSuffix.isNullOrBlank()) "" else " $leaderboardSuffix"
+
+ if (carryType == null) {
+ return "Leaderboard | Total score$suffix"
+ }
+
+ return "Leaderboard | ${carryType.displayName}-Carries$suffix"
+ }
+
+ companion object {
+ fun fromName(name: String): ScoreType? = entries.firstOrNull { currentType: ScoreType ->
+ currentType.readableName.equals(name, ignoreCase = true)
+ }
+ }
+}
diff --git a/model/src/main/kotlin/net/dungeonhub/enums/WarningAction.kt b/model/src/main/kotlin/net/dungeonhub/enums/WarningAction.kt
new file mode 100644
index 0000000..ea0cf18
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/enums/WarningAction.kt
@@ -0,0 +1,9 @@
+package net.dungeonhub.enums
+
+enum class WarningAction {
+ Timeout,
+ Ban,
+ RemoveRole,
+ RemoveRoleGroup,
+ AddRole;
+}
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/enums/WarningComparison.kt b/model/src/main/kotlin/net/dungeonhub/enums/WarningComparison.kt
new file mode 100644
index 0000000..befe3d8
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/enums/WarningComparison.kt
@@ -0,0 +1,6 @@
+package net.dungeonhub.enums
+
+enum class WarningComparison {
+ Equal,
+ GreaterOrEqual;
+}
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/enums/WarningType.kt b/model/src/main/kotlin/net/dungeonhub/enums/WarningType.kt
new file mode 100644
index 0000000..db2cafd
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/enums/WarningType.kt
@@ -0,0 +1,8 @@
+package net.dungeonhub.enums
+
+enum class WarningType {
+ Strike,
+ Minor,
+ Major,
+ Serious;
+}
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/expections/EntityUnknownException.kt b/model/src/main/kotlin/net/dungeonhub/expections/EntityUnknownException.kt
new file mode 100644
index 0000000..24d27df
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/expections/EntityUnknownException.kt
@@ -0,0 +1,5 @@
+package net.dungeonhub.expections
+
+class EntityUnknownException(
+ val id: Long
+) : IllegalStateException()
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/model/auth/JwtTokenModel.kt b/model/src/main/kotlin/net/dungeonhub/model/auth/JwtTokenModel.kt
new file mode 100644
index 0000000..a593e50
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/model/auth/JwtTokenModel.kt
@@ -0,0 +1,6 @@
+package net.dungeonhub.model.auth
+
+import java.time.Instant
+
+@JvmRecord
+data class JwtTokenModel(val token: String, val validUntil: Instant)
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/model/carry/CarryModel.kt b/model/src/main/kotlin/net/dungeonhub/model/carry/CarryModel.kt
new file mode 100644
index 0000000..f21f74a
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/model/carry/CarryModel.kt
@@ -0,0 +1,44 @@
+package net.dungeonhub.model.carry
+
+import net.dungeonhub.structure.model.Model
+import net.dungeonhub.model.carry_difficulty.CarryDifficultyModel
+import net.dungeonhub.model.discord_user.DiscordUserModel
+import net.dungeonhub.service.MoshiService
+import java.time.Instant
+
+data class CarryModel(
+ val id: Long,
+ val amount: Long,
+ val carryDifficulty: CarryDifficultyModel,
+ val player: DiscordUserModel,
+ val carrier: DiscordUserModel,
+ val approver: Long?,
+ val attachmentLink: String?,
+ val time: Instant?
+): Model {
+ val carryTier = carryDifficulty.carryTier
+ val carryType = carryDifficulty.carryType
+
+ val scoreMultiplier = carryDifficulty.score
+
+ fun calculatePrice(): Long {
+ val bulkPrice = carryDifficulty.bulkPrice
+ val bulkAmount = carryDifficulty.bulkAmount
+
+ if (bulkPrice != null && bulkAmount != null && bulkAmount <= amount) {
+ return bulkPrice.toLong()
+ }
+
+ return carryDifficulty.price.toLong()
+ }
+
+ fun calculateScore(): Long {
+ return scoreMultiplier * amount
+ }
+
+ companion object {
+ fun fromString(json: String): CarryModel {
+ return MoshiService.moshi.adapter(CarryModel::class.java).fromJson(json)!!
+ }
+ }
+}
diff --git a/model/src/main/kotlin/net/dungeonhub/model/carry_difficulty/CarryDifficultyCreationModel.kt b/model/src/main/kotlin/net/dungeonhub/model/carry_difficulty/CarryDifficultyCreationModel.kt
new file mode 100644
index 0000000..f77156a
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/model/carry_difficulty/CarryDifficultyCreationModel.kt
@@ -0,0 +1,14 @@
+package net.dungeonhub.model.carry_difficulty
+
+import net.dungeonhub.structure.model.CreationModel
+
+class CarryDifficultyCreationModel(
+ var identifier: String,
+ var displayName: String,
+ var thumbnailUrl: String? = null,
+ var bulkPrice: Int? = null,
+ var bulkAmount: Int? = null,
+ var priceName: String? = null,
+ var price: Int,
+ var score: Int
+) : CreationModel
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/model/carry_difficulty/CarryDifficultyModel.kt b/model/src/main/kotlin/net/dungeonhub/model/carry_difficulty/CarryDifficultyModel.kt
new file mode 100644
index 0000000..c302b18
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/model/carry_difficulty/CarryDifficultyModel.kt
@@ -0,0 +1,65 @@
+package net.dungeonhub.model.carry_difficulty
+
+import net.dungeonhub.model.carry_tier.CarryTierModel
+import net.dungeonhub.model.carry_type.CarryTypeModel
+import net.dungeonhub.service.MoshiService
+import net.dungeonhub.structure.model.UpdateableModel
+import kotlin.math.max
+
+class CarryDifficultyModel(
+ val id: Long,
+ val identifier: String,
+ val displayName: String,
+ val carryTier: CarryTierModel,
+ val price: Int,
+ bulkPrice: Int?,
+ bulkAmount: Int?,
+ score: Int,
+ thumbnailUrl: String?,
+ priceName: String?
+) : UpdateableModel {
+ val bulkPrice = bulkPrice
+ get() = if (field != null && field > 0) field else null
+
+ val bulkAmount = bulkAmount
+ get() = if (field != null && field > 0) field else null
+
+ val score = score
+ get() = max(field, 0)
+
+ val thumbnailUrl: String? = thumbnailUrl
+ get() = field ?: carryTier.thumbnailUrl
+
+ val priceName = priceName
+ get() = (if (!field.isNullOrBlank()) field else null) ?: displayName
+
+ val carryType: CarryTypeModel
+ get() = carryTier.carryType
+
+ fun toJson(): String {
+ return MoshiService.moshi.adapter(CarryDifficultyModel::class.java).toJson(this)
+ }
+
+ override fun getUpdateModel(): CarryDifficultyUpdateModel {
+ return CarryDifficultyUpdateModel(null, null, null, null, null, null, null)
+ }
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (javaClass != other?.javaClass) return false
+
+ other as CarryDifficultyModel
+
+ return id == other.id
+ }
+
+ override fun hashCode(): Int {
+ return id.hashCode()
+ }
+
+ companion object {
+ fun fromJson(json: String): CarryDifficultyModel {
+ return MoshiService.moshi.adapter(CarryDifficultyModel::class.java).fromJson(json)!!
+ }
+ }
+}
diff --git a/model/src/main/kotlin/net/dungeonhub/model/carry_difficulty/CarryDifficultyUpdateModel.kt b/model/src/main/kotlin/net/dungeonhub/model/carry_difficulty/CarryDifficultyUpdateModel.kt
new file mode 100644
index 0000000..9444a30
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/model/carry_difficulty/CarryDifficultyUpdateModel.kt
@@ -0,0 +1,89 @@
+package net.dungeonhub.model.carry_difficulty
+
+import net.dungeonhub.service.MoshiService
+import net.dungeonhub.structure.model.UpdateModel
+
+class CarryDifficultyUpdateModel(
+ var displayName: String?,
+ thumbnailUrl: String?,
+ bulkPrice: Int?,
+ bulkAmount: Int?,
+ priceName: String?,
+ var price: Int?,
+ var score: Int?
+) : UpdateModel {
+ var thumbnailUrl = thumbnailUrl
+ set(value) {
+ field = value
+ resetThumbnailUrl = value == null
+ }
+
+ var bulkPrice = bulkPrice
+ set(value) {
+ field = value
+ resetBulkPrice = value == null
+ }
+
+ var bulkAmount = bulkAmount
+ set(value) {
+ field = value
+ resetBulkAmount = value == null
+ }
+
+ var priceName = priceName
+ set(value) {
+ field = value
+ resetPriceName = value == null
+ }
+
+ var resetThumbnailUrl = false
+ private set
+ var resetBulkPrice = false
+ private set
+ var resetBulkAmount = false
+ private set
+ var resetPriceName = false
+ private set
+
+ /*override fun apply(model: CarryDifficultyModel): CarryDifficultyModel {
+ if (displayName != null) {
+ model.setDisplayName(displayName)
+ }
+
+ if (thumbnailUrl != null) {
+ model.setThumbnailUrl(thumbnailUrl)
+ }
+
+ if (bulkPrice != null) {
+ model.setBulkPrice(bulkPrice)
+ }
+
+ if (bulkAmount != null) {
+ model.setBulkAmount(bulkAmount)
+ }
+
+ if (priceName != null) {
+ model.setPriceName(priceName)
+ }
+
+ if (price != null) {
+ model.setPrice(price)
+ }
+
+ if (score != null) {
+ model.setScore(score)
+ }
+
+ return model
+ }*/
+
+ fun toJson(): String {
+ return MoshiService.moshi.adapter(CarryDifficultyUpdateModel::class.java).toJson(this)
+ }
+
+ companion object {
+ fun fromJson(json: String): CarryDifficultyUpdateModel {
+ return MoshiService.moshi.adapter(CarryDifficultyUpdateModel::class.java).fromJson(json)!!
+ }
+ }
+}
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/model/carry_queue/CarryQueueCreationModel.kt b/model/src/main/kotlin/net/dungeonhub/model/carry_queue/CarryQueueCreationModel.kt
new file mode 100644
index 0000000..50da893
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/model/carry_queue/CarryQueueCreationModel.kt
@@ -0,0 +1,20 @@
+package net.dungeonhub.model.carry_queue
+
+import net.dungeonhub.enums.QueueStep
+import net.dungeonhub.service.MoshiService
+import net.dungeonhub.structure.model.CreationModel
+import java.time.Instant
+
+class CarryQueueCreationModel(
+ var queueStep: QueueStep,
+ var carrier: Long,
+ var player: Long,
+ var amount: Long,
+ var relationId: Long? = null,
+ var attachmentLink: String? = null,
+ var time: Instant? = null,
+) : CreationModel {
+ fun toJson(): String {
+ return MoshiService.moshi.adapter(CarryQueueCreationModel::class.java).toJson(this)
+ }
+}
diff --git a/model/src/main/kotlin/net/dungeonhub/model/carry_queue/CarryQueueModel.kt b/model/src/main/kotlin/net/dungeonhub/model/carry_queue/CarryQueueModel.kt
new file mode 100644
index 0000000..6286219
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/model/carry_queue/CarryQueueModel.kt
@@ -0,0 +1,40 @@
+package net.dungeonhub.model.carry_queue
+
+import net.dungeonhub.enums.QueueStep
+import net.dungeonhub.model.carry_difficulty.CarryDifficultyModel
+import net.dungeonhub.model.discord_user.DiscordUserModel
+import net.dungeonhub.service.MoshiService
+import net.dungeonhub.structure.model.UpdateableModel
+import java.time.Instant
+
+class CarryQueueModel(
+ val id: Long,
+ val queueStep: QueueStep,
+ val carrier: DiscordUserModel,
+ val player: DiscordUserModel,
+ val amount: Long,
+ val carryDifficulty: CarryDifficultyModel,
+ val relationId: Long?,
+ val attachmentLink: String?,
+ val time: Instant?
+) : UpdateableModel {
+ val carryTier = carryDifficulty.carryTier
+
+ val carryType = carryTier.carryType
+
+ fun calculateScore(): Long {
+ return scoreMultiplier * amount
+ }
+
+ private val scoreMultiplier = carryDifficulty.score
+
+ companion object {
+ fun fromJson(json: String): CarryQueueModel {
+ return MoshiService.moshi.adapter(CarryQueueModel::class.java).fromJson(json)!!
+ }
+ }
+
+ override fun getUpdateModel(): CarryQueueUpdateModel {
+ return CarryQueueUpdateModel(null, null, null, null, null, null, null, null, null)
+ }
+}
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/model/carry_queue/CarryQueueUpdateModel.kt b/model/src/main/kotlin/net/dungeonhub/model/carry_queue/CarryQueueUpdateModel.kt
new file mode 100644
index 0000000..a50f971
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/model/carry_queue/CarryQueueUpdateModel.kt
@@ -0,0 +1,85 @@
+package net.dungeonhub.model.carry_queue
+
+import net.dungeonhub.enums.QueueStep
+import net.dungeonhub.model.carry_difficulty.CarryDifficultyModel
+import net.dungeonhub.model.discord_user.DiscordUserModel
+import net.dungeonhub.service.MoshiService
+import net.dungeonhub.structure.model.UpdateModel
+import java.time.Instant
+
+class CarryQueueUpdateModel(
+ var queueStep: QueueStep?,
+ var carrier: DiscordUserModel?,
+ var player: DiscordUserModel?,
+ var amount: Long?,
+ var carryDifficulty: CarryDifficultyModel?,
+ relationId: Long?,
+ attachmentLink: String?,
+ time: Instant?,
+ var approver: Long?
+) : UpdateModel {
+ var relationId = relationId
+ set(value) {
+ field = value
+ resetRelationId = value == null
+ }
+
+ var attachmentLink = attachmentLink
+ set(value) {
+ field = value
+ resetAttachmentLink = value == null
+ }
+
+ var time = time
+ set(value) {
+ field = value
+ resetTime = value == null
+ }
+
+ var resetRelationId = false
+ private set
+ var resetAttachmentLink = false
+ private set
+ var resetTime = false
+ private set
+
+ /*override fun apply(carryQueueModel: CarryQueueModel): CarryQueueModel {
+ if (queueStep != null) {
+ carryQueueModel.setQueueStep(queueStep)
+ }
+
+ if (carrier != null) {
+ carryQueueModel.setCarrier(carrier)
+ }
+
+ if (player != null) {
+ carryQueueModel.setPlayer(player)
+ }
+
+ if (amount != null) {
+ carryQueueModel.setAmount(amount)
+ }
+
+ if (carryDifficulty != null) {
+ carryQueueModel.setCarryDifficulty(carryDifficulty)
+ }
+
+ if (relationId != null) {
+ carryQueueModel.setRelationId(relationId)
+ }
+
+ if (attachmentLink != null) {
+ carryQueueModel.setAttachmentLink(attachmentLink)
+ }
+
+ if (time != null) {
+ carryQueueModel.setTime(time)
+ }
+
+ return carryQueueModel
+ }*/
+
+ fun toJson(): String {
+ return MoshiService.moshi.adapter(CarryQueueUpdateModel::class.java).toJson(this)
+ }
+}
diff --git a/model/src/main/kotlin/net/dungeonhub/model/carry_tier/CarryTierCreationModel.kt b/model/src/main/kotlin/net/dungeonhub/model/carry_tier/CarryTierCreationModel.kt
new file mode 100644
index 0000000..f86831e
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/model/carry_tier/CarryTierCreationModel.kt
@@ -0,0 +1,19 @@
+package net.dungeonhub.model.carry_tier
+
+import net.dungeonhub.service.MoshiService
+import net.dungeonhub.structure.model.CreationModel
+
+class CarryTierCreationModel(
+ var identifier: String,
+ var displayName: String,
+ var category: Long? = null,
+ var priceChannel: Long? = null,
+ var descriptiveName: String? = null,
+ var thumbnailUrl: String? = null,
+ var priceTitle: String? = null,
+ var priceDescription: String? = null,
+) : CreationModel {
+ fun toJson(): String {
+ return MoshiService.moshi.adapter(CarryTierCreationModel::class.java).toJson(this)
+ }
+}
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/model/carry_tier/CarryTierModel.kt b/model/src/main/kotlin/net/dungeonhub/model/carry_tier/CarryTierModel.kt
new file mode 100644
index 0000000..a6f4984
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/model/carry_tier/CarryTierModel.kt
@@ -0,0 +1,66 @@
+package net.dungeonhub.model.carry_tier
+
+import net.dungeonhub.model.carry_type.CarryTypeModel
+import net.dungeonhub.service.MoshiService
+import net.dungeonhub.structure.model.UpdateableModel
+import org.jetbrains.annotations.NotNull
+
+class CarryTierModel(
+ val id: Long,
+ val identifier: String,
+ val displayName: String,
+ val carryType: CarryTypeModel,
+ category: Long?,
+ priceChannel: Long?,
+ descriptiveName: String?,
+ thumbnailUrl: String?,
+ priceTitle: String?,
+ priceDescription: String?
+) : UpdateableModel {
+ val descriptiveName = descriptiveName
+ @NotNull
+ get() = (if (!field.isNullOrBlank()) field else null) ?: displayName
+
+ val category = category
+ get() = (if (field != null && field > 0L) field else null)
+
+ val thumbnailUrl = thumbnailUrl
+ get() = if (!field.isNullOrBlank()) field else null
+
+ val priceTitle = priceTitle
+ @NotNull
+ get() = (if (!field.isNullOrBlank()) field else null) ?: descriptiveName
+
+ val priceDescription = priceDescription
+ get() = if (!field.isNullOrBlank()) field else null
+
+ val priceChannel = priceChannel
+ get() = if (field != null && field > 0L) field else null
+
+ override fun getUpdateModel(): CarryTierUpdateModel {
+ return CarryTierUpdateModel(null, null, null, null, null, null, null)
+ }
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (javaClass != other?.javaClass) return false
+
+ other as CarryTierModel
+
+ return id == other.id
+ }
+
+ override fun hashCode(): Int {
+ return id.hashCode()
+ }
+
+ fun toJson(): String {
+ return MoshiService.moshi.adapter(CarryTierModel::class.java).toJson(this)
+ }
+
+ companion object {
+ fun fromJson(json: String): CarryTierModel {
+ return MoshiService.moshi.adapter(CarryTierModel::class.java).fromJson(json)!!
+ }
+ }
+}
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/model/carry_tier/CarryTierUpdateModel.kt b/model/src/main/kotlin/net/dungeonhub/model/carry_tier/CarryTierUpdateModel.kt
new file mode 100644
index 0000000..ca99f17
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/model/carry_tier/CarryTierUpdateModel.kt
@@ -0,0 +1,105 @@
+package net.dungeonhub.model.carry_tier
+
+import net.dungeonhub.service.MoshiService
+import net.dungeonhub.structure.model.UpdateModel
+
+class CarryTierUpdateModel(
+ var displayName: String?,
+ category: Long?,
+ priceChannel: Long?,
+ descriptiveName: String?,
+ thumbnailUrl: String?,
+ priceTitle: String?,
+ priceDescription: String?
+) : UpdateModel {
+ var category = category
+ set(value) {
+ field = value
+ resetCategory = value == null
+ }
+
+ var priceChannel = priceChannel
+ set(value) {
+ field = value
+ resetPriceChannel = value == null
+ }
+
+ var descriptiveName = descriptiveName
+ set(value) {
+ field = value
+ resetDescriptiveName = value == null
+ }
+
+ var thumbnailUrl = thumbnailUrl
+ set(value) {
+ field = value
+ resetThumbnailUrl = value == null
+ }
+
+ var priceTitle = priceTitle
+ set(value) {
+ field = value
+ resetPriceTitle = value == null
+ }
+
+ var priceDescription = priceDescription
+ set(value) {
+ field = value
+ resetPriceDescription = value == null
+ }
+
+ var resetCategory = false
+ private set
+ var resetPriceChannel = false
+ private set
+ var resetDescriptiveName = false
+ private set
+ var resetThumbnailUrl = false
+ private set
+ var resetPriceTitle = false
+ private set
+ var resetPriceDescription = false
+ private set
+
+ /*override fun apply(model: CarryTierModel): CarryTierModel {
+ if (category != null) {
+ model.setCategory(category)
+ }
+
+ if (priceChannel != null) {
+ model.setPriceChannel(priceChannel)
+ }
+
+ if (descriptiveName != null) {
+ model.setDescriptiveName(descriptiveName)
+ }
+
+ if (thumbnailUrl != null) {
+ model.setThumbnailUrl(thumbnailUrl)
+ }
+
+ if (priceTitle != null) {
+ model.setPriceTitle(priceTitle)
+ }
+
+ if (priceDescription != null) {
+ model.setPriceDescription(priceDescription)
+ }
+
+ if (displayName != null) {
+ model.setDisplayName(displayName)
+ }
+
+ return model
+ }*/
+
+ fun toJson(): String {
+ return MoshiService.moshi.adapter(CarryTierUpdateModel::class.java).toJson(this)
+ }
+
+ companion object {
+ fun fromJson(json: String): CarryTierUpdateModel {
+ return MoshiService.moshi.adapter(CarryTierUpdateModel::class.java).fromJson(json)!!
+ }
+ }
+}
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/model/carry_type/CarryTypeCreationModel.kt b/model/src/main/kotlin/net/dungeonhub/model/carry_type/CarryTypeCreationModel.kt
new file mode 100644
index 0000000..cad3195
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/model/carry_type/CarryTypeCreationModel.kt
@@ -0,0 +1,16 @@
+package net.dungeonhub.model.carry_type
+
+import net.dungeonhub.service.MoshiService
+import net.dungeonhub.structure.model.CreationModel
+
+class CarryTypeCreationModel(
+ var identifier: String,
+ var displayName: String,
+ var logChannel: Long? = null,
+ var leaderboardChannel: Long? = null,
+ var eventActive: Boolean? = null
+) : CreationModel {
+ fun toJson(): String {
+ return MoshiService.moshi.adapter(CarryTypeCreationModel::class.java).toJson(this)
+ }
+}
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/model/carry_type/CarryTypeModel.kt b/model/src/main/kotlin/net/dungeonhub/model/carry_type/CarryTypeModel.kt
new file mode 100644
index 0000000..47b0344
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/model/carry_type/CarryTypeModel.kt
@@ -0,0 +1,51 @@
+package net.dungeonhub.model.carry_type
+
+import net.dungeonhub.model.discord_server.DiscordServerModel
+import net.dungeonhub.service.MoshiService
+import net.dungeonhub.structure.model.UpdateableModel
+
+class CarryTypeModel(
+ val id: Long,
+ val identifier: String,
+ val displayName: String,
+ val server: DiscordServerModel,
+ logChannel: Long?,
+ leaderboardChannel: Long?,
+ isEventActive: Boolean?
+) : UpdateableModel {
+ val isEventActive = isEventActive
+ get() = java.lang.Boolean.TRUE == field
+
+ val logChannel = logChannel
+ get() = (if (field != null && field > 0L) field else null)
+
+ val leaderboardChannel = leaderboardChannel
+ get() = (if (field != null && field > 0L) field else null)
+
+ override fun getUpdateModel(): CarryTypeUpdateModel {
+ return CarryTypeUpdateModel(null, null, null, null)
+ }
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (javaClass != other?.javaClass) return false
+
+ other as CarryTypeModel
+
+ return id == other.id
+ }
+
+ override fun hashCode(): Int {
+ return id.hashCode()
+ }
+
+ fun toJson(): String {
+ return MoshiService.moshi.adapter(CarryTypeModel::class.java).toJson(this)
+ }
+
+ companion object {
+ fun fromJson(json: String): CarryTypeModel {
+ return MoshiService.moshi.adapter(CarryTypeModel::class.java).fromJson(json)!!
+ }
+ }
+}
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/model/carry_type/CarryTypeUpdateModel.kt b/model/src/main/kotlin/net/dungeonhub/model/carry_type/CarryTypeUpdateModel.kt
new file mode 100644
index 0000000..aa16ea2
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/model/carry_type/CarryTypeUpdateModel.kt
@@ -0,0 +1,60 @@
+package net.dungeonhub.model.carry_type
+
+import net.dungeonhub.service.MoshiService
+import net.dungeonhub.structure.model.UpdateModel
+
+class CarryTypeUpdateModel(
+ var displayName: String?,
+ logChannel: Long?,
+ leaderboardChannel: Long?,
+ eventActive: Boolean?
+) : UpdateModel {
+ var logChannel = logChannel
+ set(value) {
+ field = value
+ resetLogChannel = value == null
+ }
+
+ var leaderboardChannel = leaderboardChannel
+ set(value) {
+ field = value
+ resetLeaderboardChannel = value == null
+ }
+
+ var eventActive = eventActive
+ set(value) {
+ field = value
+ resetEventActive = value == null
+ }
+
+ var resetLogChannel = false
+ private set
+ var resetLeaderboardChannel = false
+ private set
+ var resetEventActive = false
+ private set
+
+ /*override fun apply(carryTypeModel: CarryTypeModel): CarryTypeModel {
+ if (displayName != null) {
+ carryTypeModel.setDisplayName(displayName)
+ }
+
+ if (logChannel != null) {
+ carryTypeModel.setLogChannel(logChannel)
+ }
+
+ if (leaderboardChannel != null) {
+ carryTypeModel.setLeaderboardChannel(leaderboardChannel)
+ }
+
+ if (eventActive != null) {
+ carryTypeModel.setEventActive(eventActive)
+ }
+
+ return carryTypeModel
+ }*/
+
+ fun toJson(): String {
+ return MoshiService.moshi.adapter(CarryTypeUpdateModel::class.java).toJson(this)
+ }
+}
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/model/cnt_request/CntRequestCreationModel.kt b/model/src/main/kotlin/net/dungeonhub/model/cnt_request/CntRequestCreationModel.kt
new file mode 100644
index 0000000..e77f3f6
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/model/cnt_request/CntRequestCreationModel.kt
@@ -0,0 +1,19 @@
+package net.dungeonhub.model.cnt_request
+
+import net.dungeonhub.service.MoshiService
+import net.dungeonhub.structure.model.CreationModel
+import java.time.Instant
+
+class CntRequestCreationModel(
+ var messageId: Long,
+ var user: Long,
+ var claimer: Long? = null,
+ var time: Instant,
+ var coinValue: String,
+ var description: String,
+ var requirement: String
+) : CreationModel {
+ fun toJson(): String {
+ return MoshiService.moshi.adapter(CntRequestCreationModel::class.java).toJson(this)
+ }
+}
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/model/cnt_request/CntRequestModel.kt b/model/src/main/kotlin/net/dungeonhub/model/cnt_request/CntRequestModel.kt
new file mode 100644
index 0000000..deaa488
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/model/cnt_request/CntRequestModel.kt
@@ -0,0 +1,29 @@
+package net.dungeonhub.model.cnt_request
+
+import net.dungeonhub.model.discord_server.DiscordServerModel
+import net.dungeonhub.model.discord_user.DiscordUserModel
+import net.dungeonhub.service.MoshiService
+import net.dungeonhub.structure.model.UpdateableModel
+import java.time.Instant
+
+class CntRequestModel(
+ val id: Long,
+ val messageId: Long,
+ val discordServer: DiscordServerModel,
+ val user: DiscordUserModel,
+ val claimer: DiscordUserModel?,
+ val time: Instant,
+ val coinValue: String,
+ val description: String,
+ val requirement: String
+) : UpdateableModel {
+ companion object {
+ fun fromJson(json: String): CntRequestModel {
+ return MoshiService.moshi.adapter(CntRequestModel::class.java).fromJson(json)!!
+ }
+ }
+
+ override fun getUpdateModel(): CntRequestUpdateModel {
+ return CntRequestUpdateModel(null, null, null, null)
+ }
+}
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/model/cnt_request/CntRequestUpdateModel.kt b/model/src/main/kotlin/net/dungeonhub/model/cnt_request/CntRequestUpdateModel.kt
new file mode 100644
index 0000000..e965ef7
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/model/cnt_request/CntRequestUpdateModel.kt
@@ -0,0 +1,48 @@
+package net.dungeonhub.model.cnt_request
+
+import net.dungeonhub.model.discord_user.DiscordUserModel
+import net.dungeonhub.service.MoshiService
+import net.dungeonhub.structure.model.UpdateModel
+
+class CntRequestUpdateModel(
+ claimer: DiscordUserModel?,
+ var coinValue: String?,
+ var description: String?,
+ var requirement: String?
+) : UpdateModel {
+ var claimer = claimer
+ set(value) {
+ resetClaimer = value == null
+ field = value
+ }
+
+ var resetClaimer = false
+ private set
+ /*override fun apply(model: CntRequestModel): CntRequestModel {
+ if (removeClaimer) {
+ model.setClaimer(null)
+ }
+
+ if (claimer != null) {
+ model.setClaimer(claimer)
+ }
+
+ if (coinValue != null) {
+ model.setCoinValue(coinValue)
+ }
+
+ if (description != null) {
+ model.setDescription(description)
+ }
+
+ if (requirement != null) {
+ model.setRequirement(requirement)
+ }
+
+ return model
+ }*/
+
+ fun toJson(): String {
+ return MoshiService.moshi.adapter(CntRequestUpdateModel::class.java).toJson(this)
+ }
+}
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/model/discord_role/DiscordRoleCreationModel.kt b/model/src/main/kotlin/net/dungeonhub/model/discord_role/DiscordRoleCreationModel.kt
new file mode 100644
index 0000000..b07d782
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/model/discord_role/DiscordRoleCreationModel.kt
@@ -0,0 +1,14 @@
+package net.dungeonhub.model.discord_role
+
+import net.dungeonhub.service.MoshiService
+import net.dungeonhub.structure.model.CreationModel
+
+class DiscordRoleCreationModel(
+ var id: Long,
+ var nameSchema: String? = null,
+ var verifiedRole: Boolean = false
+) : CreationModel {
+ fun toJson(): String {
+ return MoshiService.moshi.adapter(DiscordRoleCreationModel::class.java).toJson(this)
+ }
+}
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/model/discord_role/DiscordRoleModel.kt b/model/src/main/kotlin/net/dungeonhub/model/discord_role/DiscordRoleModel.kt
new file mode 100644
index 0000000..e4038b9
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/model/discord_role/DiscordRoleModel.kt
@@ -0,0 +1,18 @@
+package net.dungeonhub.model.discord_role
+
+import net.dungeonhub.structure.model.Model
+import net.dungeonhub.model.discord_server.DiscordServerModel
+import net.dungeonhub.service.MoshiService
+
+class DiscordRoleModel(
+ val id: Long,
+ val nameSchema: String?,
+ val verifiedRole: Boolean,
+ val discordServerModel: DiscordServerModel
+) : Model {
+ companion object {
+ fun fromJson(json: String): DiscordRoleModel {
+ return MoshiService.moshi.adapter(DiscordRoleModel::class.java).fromJson(json)!!
+ }
+ }
+}
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/model/discord_role/DiscordRoleUpdateModel.kt b/model/src/main/kotlin/net/dungeonhub/model/discord_role/DiscordRoleUpdateModel.kt
new file mode 100644
index 0000000..e48c6e3
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/model/discord_role/DiscordRoleUpdateModel.kt
@@ -0,0 +1,34 @@
+package net.dungeonhub.model.discord_role
+
+import net.dungeonhub.service.MoshiService
+import net.dungeonhub.structure.model.UpdateModel
+
+class DiscordRoleUpdateModel(
+ nameSchema: String?,
+ var verifiedRole: Boolean?
+) : UpdateModel {
+ var nameSchema = nameSchema
+ set(value) {
+ resetNameSchema = value == null
+ field = value
+ }
+
+ var resetNameSchema = false
+ private set
+
+ /*override fun apply(model: DiscordRoleModel): DiscordRoleModel {
+ if (nameSchema != null) {
+ model.setNameSchema(nameSchema)
+ }
+
+ if (verifiedRole != null) {
+ model.setVerifiedRole(verifiedRole)
+ }
+
+ return model
+ }*/
+
+ fun toJson(): String {
+ return MoshiService.moshi.adapter(DiscordRoleUpdateModel::class.java).toJson(this)
+ }
+}
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/model/discord_role_group/DiscordRoleGroupCreationModel.kt b/model/src/main/kotlin/net/dungeonhub/model/discord_role_group/DiscordRoleGroupCreationModel.kt
new file mode 100644
index 0000000..2673c92
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/model/discord_role_group/DiscordRoleGroupCreationModel.kt
@@ -0,0 +1,9 @@
+package net.dungeonhub.model.discord_role_group
+
+import net.dungeonhub.model.discord_role.DiscordRoleModel
+import net.dungeonhub.structure.model.CreationModel
+
+class DiscordRoleGroupCreationModel(
+ var discordRole: DiscordRoleModel,
+ var roleGroup: DiscordRoleModel
+) : CreationModel
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/model/discord_role_group/DiscordRoleGroupModel.kt b/model/src/main/kotlin/net/dungeonhub/model/discord_role_group/DiscordRoleGroupModel.kt
new file mode 100644
index 0000000..32dd533
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/model/discord_role_group/DiscordRoleGroupModel.kt
@@ -0,0 +1,10 @@
+package net.dungeonhub.model.discord_role_group
+
+import net.dungeonhub.structure.model.Model
+import net.dungeonhub.model.discord_role.DiscordRoleModel
+
+class DiscordRoleGroupModel(
+ val id: Long,
+ val discordRole: DiscordRoleModel,
+ val roleGroup: DiscordRoleModel
+) : Model
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/model/discord_role_group/DiscordRoleGroupUpdateModel.kt b/model/src/main/kotlin/net/dungeonhub/model/discord_role_group/DiscordRoleGroupUpdateModel.kt
new file mode 100644
index 0000000..b517e88
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/model/discord_role_group/DiscordRoleGroupUpdateModel.kt
@@ -0,0 +1,6 @@
+package net.dungeonhub.model.discord_role_group
+
+import net.dungeonhub.structure.model.UpdateModel
+
+//this won't be updated, still needs to exist due to internal references
+class DiscordRoleGroupUpdateModel : UpdateModel
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/model/discord_server/DiscordServerModel.kt b/model/src/main/kotlin/net/dungeonhub/model/discord_server/DiscordServerModel.kt
new file mode 100644
index 0000000..138f805
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/model/discord_server/DiscordServerModel.kt
@@ -0,0 +1,16 @@
+package net.dungeonhub.model.discord_server
+
+import net.dungeonhub.structure.model.CreationModel
+import net.dungeonhub.structure.model.Model
+import net.dungeonhub.structure.model.UpdateModel
+import net.dungeonhub.service.MoshiService
+
+class DiscordServerModel(
+ val id: Long
+) : Model, CreationModel, UpdateModel {
+ companion object {
+ fun fromJson(json: String): DiscordServerModel {
+ return MoshiService.moshi.adapter(DiscordServerModel::class.java).fromJson(json)!!
+ }
+ }
+}
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/model/discord_user/DiscordUserCreationModel.kt b/model/src/main/kotlin/net/dungeonhub/model/discord_user/DiscordUserCreationModel.kt
new file mode 100644
index 0000000..50a1088
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/model/discord_user/DiscordUserCreationModel.kt
@@ -0,0 +1,14 @@
+package net.dungeonhub.model.discord_user
+
+import net.dungeonhub.service.MoshiService
+import net.dungeonhub.structure.model.CreationModel
+import java.util.*
+
+class DiscordUserCreationModel(
+ var id: Long,
+ var minecraftId: UUID? = null
+) : CreationModel {
+ fun toJson(): String {
+ return MoshiService.moshi.adapter(DiscordUserCreationModel::class.java).toJson(this)
+ }
+}
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/model/discord_user/DiscordUserModel.kt b/model/src/main/kotlin/net/dungeonhub/model/discord_user/DiscordUserModel.kt
new file mode 100644
index 0000000..66d89ad
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/model/discord_user/DiscordUserModel.kt
@@ -0,0 +1,20 @@
+package net.dungeonhub.model.discord_user
+
+import net.dungeonhub.service.MoshiService
+import net.dungeonhub.structure.model.UpdateableModel
+import java.util.*
+
+class DiscordUserModel(
+ val id: Long,
+ val minecraftId: UUID?
+) : UpdateableModel {
+ companion object {
+ fun fromJson(json: String): DiscordUserModel {
+ return MoshiService.moshi.adapter(DiscordUserModel::class.java).fromJson(json)!!
+ }
+ }
+
+ override fun getUpdateModel(): DiscordUserUpdateModel {
+ return DiscordUserUpdateModel(null)
+ }
+}
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/model/discord_user/DiscordUserUpdateModel.kt b/model/src/main/kotlin/net/dungeonhub/model/discord_user/DiscordUserUpdateModel.kt
new file mode 100644
index 0000000..30664ee
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/model/discord_user/DiscordUserUpdateModel.kt
@@ -0,0 +1,34 @@
+package net.dungeonhub.model.discord_user
+
+import net.dungeonhub.service.MoshiService
+import net.dungeonhub.structure.model.UpdateModel
+import java.util.*
+
+class DiscordUserUpdateModel(
+ minecraftId: UUID?
+) : UpdateModel {
+ var minecraftId = minecraftId
+ set(value) {
+ field = value
+ removeMinecraftId = value == null
+ }
+
+ var removeMinecraftId = false
+ private set
+
+ /*override fun apply(model: DiscordUserModel): DiscordUserModel {
+ if (removeMinecraftId) {
+ model.setMinecraftId(null)
+ }
+
+ if (minecraftId != null) {
+ model.setMinecraftId(minecraftId)
+ }
+
+ return model
+ }*/
+
+ fun toJson(): String {
+ return MoshiService.moshi.adapter(DiscordUserUpdateModel::class.java).toJson(this)
+ }
+}
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/model/purge_type/PurgeTypeCreationModel.kt b/model/src/main/kotlin/net/dungeonhub/model/purge_type/PurgeTypeCreationModel.kt
new file mode 100644
index 0000000..52e9167
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/model/purge_type/PurgeTypeCreationModel.kt
@@ -0,0 +1,13 @@
+package net.dungeonhub.model.purge_type
+
+import net.dungeonhub.service.MoshiService
+import net.dungeonhub.structure.model.CreationModel
+
+class PurgeTypeCreationModel(
+ var identifier: String,
+ var displayName: String
+) : CreationModel {
+ fun toJson(): String {
+ return MoshiService.moshi.adapter(PurgeTypeCreationModel::class.java).toJson(this)
+ }
+}
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/model/purge_type/PurgeTypeModel.kt b/model/src/main/kotlin/net/dungeonhub/model/purge_type/PurgeTypeModel.kt
new file mode 100644
index 0000000..e0a262a
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/model/purge_type/PurgeTypeModel.kt
@@ -0,0 +1,12 @@
+package net.dungeonhub.model.purge_type
+
+import net.dungeonhub.structure.model.Model
+import net.dungeonhub.model.carry_type.CarryTypeModel
+
+class PurgeTypeModel(
+ val id: Long,
+ val identifier: String,
+ val displayName: String,
+ val carryType: CarryTypeModel,
+ val purgeTypeRoleModels: List
+) : Model
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/model/purge_type/PurgeTypeRoleModel.kt b/model/src/main/kotlin/net/dungeonhub/model/purge_type/PurgeTypeRoleModel.kt
new file mode 100644
index 0000000..e9e54c6
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/model/purge_type/PurgeTypeRoleModel.kt
@@ -0,0 +1,9 @@
+package net.dungeonhub.model.purge_type
+
+import net.dungeonhub.structure.model.Model
+import net.dungeonhub.model.discord_role.DiscordRoleModel
+
+class PurgeTypeRoleModel(
+ val purgeTypeModel: PurgeTypeModel,
+ val discordRoleModel: DiscordRoleModel
+) : Model
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/model/purge_type/PurgeTypeUpdateModel.kt b/model/src/main/kotlin/net/dungeonhub/model/purge_type/PurgeTypeUpdateModel.kt
new file mode 100644
index 0000000..898abf7
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/model/purge_type/PurgeTypeUpdateModel.kt
@@ -0,0 +1,20 @@
+package net.dungeonhub.model.purge_type
+
+import net.dungeonhub.service.MoshiService
+import net.dungeonhub.structure.model.UpdateModel
+
+class PurgeTypeUpdateModel(
+ var displayName: String?
+) : UpdateModel {
+ /*override fun apply(purgeTypeModel: PurgeTypeModel): PurgeTypeModel {
+ if (displayName != null) {
+ purgeTypeModel.setDisplayName(displayName)
+ }
+
+ return purgeTypeModel
+ }*/
+
+ fun toJson(): String {
+ return MoshiService.moshi.adapter(PurgeTypeUpdateModel::class.java).toJson(this)
+ }
+}
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/model/score/LeaderboardModel.kt b/model/src/main/kotlin/net/dungeonhub/model/score/LeaderboardModel.kt
new file mode 100644
index 0000000..7a582cb
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/model/score/LeaderboardModel.kt
@@ -0,0 +1,26 @@
+package net.dungeonhub.model.score
+
+import net.dungeonhub.service.MoshiService
+import net.dungeonhub.structure.model.Model
+
+class LeaderboardModel(
+ val page: Int,
+ val totalPages: Int,
+ val scores: List,
+ val playerPosition: Int? = null,
+ val playerScore: ScoreModel? = null
+) : Model {
+ fun hasNextPage(): Boolean {
+ return page < totalPages - 1
+ }
+
+ fun hasPrevPage(): Boolean {
+ return page > 0
+ }
+
+ companion object {
+ fun fromJson(json: String): LeaderboardModel {
+ return MoshiService.moshi.adapter(LeaderboardModel::class.java).fromJson(json)!!
+ }
+ }
+}
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/model/score/LoggedCarryModel.kt b/model/src/main/kotlin/net/dungeonhub/model/score/LoggedCarryModel.kt
new file mode 100644
index 0000000..ee14f62
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/model/score/LoggedCarryModel.kt
@@ -0,0 +1,13 @@
+package net.dungeonhub.model.score
+
+import net.dungeonhub.model.carry.CarryModel
+import net.dungeonhub.service.MoshiService
+import net.dungeonhub.structure.model.Model
+
+class LoggedCarryModel(val carryModel: CarryModel, val scoreModels: List) : Model {
+ companion object {
+ fun fromJson(json: String): LoggedCarryModel {
+ return MoshiService.moshi.adapter(LoggedCarryModel::class.java).fromJson(json)!!
+ }
+ }
+}
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/model/score/ScoreModel.kt b/model/src/main/kotlin/net/dungeonhub/model/score/ScoreModel.kt
new file mode 100644
index 0000000..d945689
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/model/score/ScoreModel.kt
@@ -0,0 +1,20 @@
+package net.dungeonhub.model.score
+
+import net.dungeonhub.enums.ScoreType
+import net.dungeonhub.model.carry_type.CarryTypeModel
+import net.dungeonhub.model.discord_user.DiscordUserModel
+import net.dungeonhub.service.MoshiService
+import net.dungeonhub.structure.model.Model
+
+class ScoreModel(
+ val carrier: DiscordUserModel,
+ val carryType: CarryTypeModel?,
+ val scoreType: ScoreType,
+ val scoreAmount: Long?
+) : Model {
+ companion object {
+ fun fromJson(json: String): ScoreModel {
+ return MoshiService.moshi.adapter(ScoreModel::class.java).fromJson(json)!!
+ }
+ }
+}
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/model/score/ScoreResetModel.kt b/model/src/main/kotlin/net/dungeonhub/model/score/ScoreResetModel.kt
new file mode 100644
index 0000000..816e0f8
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/model/score/ScoreResetModel.kt
@@ -0,0 +1,15 @@
+package net.dungeonhub.model.score
+
+import net.dungeonhub.service.MoshiService
+import net.dungeonhub.structure.model.Model
+
+class ScoreResetModel(
+ val defaultCount: Long,
+ val eventCount: Long
+) : Model {
+ companion object {
+ fun fromJson(json: String): ScoreResetModel {
+ return MoshiService.moshi.adapter(ScoreResetModel::class.java).fromJson(json)!!
+ }
+ }
+}
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/model/score/ScoreUpdateModel.kt b/model/src/main/kotlin/net/dungeonhub/model/score/ScoreUpdateModel.kt
new file mode 100644
index 0000000..c4c646a
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/model/score/ScoreUpdateModel.kt
@@ -0,0 +1,13 @@
+package net.dungeonhub.model.score
+
+import net.dungeonhub.service.MoshiService
+import net.dungeonhub.structure.model.UpdateModel
+
+class ScoreUpdateModel(
+ val id: Long,
+ var amount: Long
+) : UpdateModel {
+ fun toJson(): String {
+ return MoshiService.moshi.adapter(ScoreUpdateModel::class.java).toJson(this)
+ }
+}
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/model/warning/AddedWarningModel.kt b/model/src/main/kotlin/net/dungeonhub/model/warning/AddedWarningModel.kt
new file mode 100644
index 0000000..4519569
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/model/warning/AddedWarningModel.kt
@@ -0,0 +1,15 @@
+package net.dungeonhub.model.warning
+
+import net.dungeonhub.service.MoshiService
+import net.dungeonhub.structure.model.Model
+
+class AddedWarningModel(
+ val warningModel: WarningModel,
+ val warningActionModel: List
+) : Model {
+ companion object {
+ fun fromJson(json: String): AddedWarningModel {
+ return MoshiService.moshi.adapter(AddedWarningModel::class.java).fromJson(json)!!
+ }
+ }
+}
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/model/warning/DetailedWarningModel.kt b/model/src/main/kotlin/net/dungeonhub/model/warning/DetailedWarningModel.kt
new file mode 100644
index 0000000..7ca055f
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/model/warning/DetailedWarningModel.kt
@@ -0,0 +1,26 @@
+package net.dungeonhub.model.warning
+
+import net.dungeonhub.enums.WarningType
+import net.dungeonhub.model.discord_server.DiscordServerModel
+import net.dungeonhub.model.discord_user.DiscordUserModel
+import net.dungeonhub.service.MoshiService
+import net.dungeonhub.structure.model.Model
+import java.time.Instant
+
+class DetailedWarningModel(
+ val id: Long,
+ val server: DiscordServerModel,
+ val user: DiscordUserModel,
+ val striker: DiscordUserModel,
+ val warningType: WarningType,
+ val reason: String?,
+ val active: Boolean,
+ val time: Instant,
+ val evidences: List
+) : Model {
+ companion object {
+ fun fromJson(json: String): DetailedWarningModel {
+ return MoshiService.moshi.adapter(DetailedWarningModel::class.java).fromJson(json)!!
+ }
+ }
+}
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/model/warning/WarningActionModel.kt b/model/src/main/kotlin/net/dungeonhub/model/warning/WarningActionModel.kt
new file mode 100644
index 0000000..275f4ac
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/model/warning/WarningActionModel.kt
@@ -0,0 +1,8 @@
+package net.dungeonhub.model.warning
+
+import net.dungeonhub.enums.WarningAction
+
+class WarningActionModel(
+ val warningAction: WarningAction,
+ val data: String?
+)
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/model/warning/WarningCreationModel.kt b/model/src/main/kotlin/net/dungeonhub/model/warning/WarningCreationModel.kt
new file mode 100644
index 0000000..2be2605
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/model/warning/WarningCreationModel.kt
@@ -0,0 +1,17 @@
+package net.dungeonhub.model.warning
+
+import net.dungeonhub.enums.WarningType
+import net.dungeonhub.service.MoshiService
+import net.dungeonhub.structure.model.CreationModel
+
+class WarningCreationModel(
+ var user: Long,
+ var striker: Long,
+ var warningType: WarningType,
+ var reason: String? = null,
+ var active: Boolean = true
+) : CreationModel {
+ fun toJson(): String {
+ return MoshiService.moshi.adapter(WarningCreationModel::class.java).toJson(this)
+ }
+}
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/model/warning/WarningEvidenceCreationModel.kt b/model/src/main/kotlin/net/dungeonhub/model/warning/WarningEvidenceCreationModel.kt
new file mode 100644
index 0000000..84eaab4
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/model/warning/WarningEvidenceCreationModel.kt
@@ -0,0 +1,13 @@
+package net.dungeonhub.model.warning
+
+import net.dungeonhub.service.MoshiService
+import net.dungeonhub.structure.model.CreationModel
+
+class WarningEvidenceCreationModel(
+ var evidence: String,
+ var submitter: Long
+) : CreationModel {
+ fun toJson(): String {
+ return MoshiService.moshi.adapter(WarningEvidenceCreationModel::class.java).toJson(this)
+ }
+}
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/model/warning/WarningEvidenceModel.kt b/model/src/main/kotlin/net/dungeonhub/model/warning/WarningEvidenceModel.kt
new file mode 100644
index 0000000..167e134
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/model/warning/WarningEvidenceModel.kt
@@ -0,0 +1,11 @@
+package net.dungeonhub.model.warning
+
+import net.dungeonhub.model.discord_user.DiscordUserModel
+import net.dungeonhub.structure.model.Model
+
+class WarningEvidenceModel(
+ val id: Long,
+ val warningModel: WarningModel,
+ val evidence: String,
+ val submitter: DiscordUserModel
+) : Model
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/model/warning/WarningModel.kt b/model/src/main/kotlin/net/dungeonhub/model/warning/WarningModel.kt
new file mode 100644
index 0000000..787e859
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/model/warning/WarningModel.kt
@@ -0,0 +1,25 @@
+package net.dungeonhub.model.warning
+
+import net.dungeonhub.structure.model.Model
+import net.dungeonhub.enums.WarningType
+import net.dungeonhub.model.discord_server.DiscordServerModel
+import net.dungeonhub.model.discord_user.DiscordUserModel
+import net.dungeonhub.service.MoshiService
+import java.time.Instant
+
+class WarningModel(
+ val id: Long,
+ val server: DiscordServerModel,
+ val user: DiscordUserModel,
+ val striker: DiscordUserModel,
+ val warningType: WarningType,
+ val reason: String?,
+ val active: Boolean,
+ val time: Instant
+) : Model {
+ companion object {
+ fun fromJson(json: String): WarningModel {
+ return MoshiService.moshi.adapter(WarningModel::class.java).fromJson(json)!!
+ }
+ }
+}
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/model/warning/WarningUpdateModel.kt b/model/src/main/kotlin/net/dungeonhub/model/warning/WarningUpdateModel.kt
new file mode 100644
index 0000000..303a50b
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/model/warning/WarningUpdateModel.kt
@@ -0,0 +1,35 @@
+package net.dungeonhub.model.warning
+
+import net.dungeonhub.enums.WarningType
+import net.dungeonhub.structure.model.UpdateModel
+
+class WarningUpdateModel(
+ var warningType: WarningType?,
+ reason: String?,
+ var active: Boolean?
+) : UpdateModel {
+ var reason = reason
+ set(value) {
+ field = value
+ resetReason = value == null
+ }
+
+ var resetReason = false
+ private set
+
+ /*override fun apply(model: WarningModel): WarningModel {
+ if (warningType != null) {
+ model.setWarningType(warningType)
+ }
+
+ if (reason != null) {
+ model.setReason(reason)
+ }
+
+ if (active != null) {
+ model.setActive(active)
+ }
+
+ return model
+ }*/
+}
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/service/MoshiService.kt b/model/src/main/kotlin/net/dungeonhub/service/MoshiService.kt
new file mode 100644
index 0000000..b0d1825
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/service/MoshiService.kt
@@ -0,0 +1,113 @@
+package net.dungeonhub.service
+
+import com.squareup.moshi.*
+import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
+import net.dungeonhub.model.carry_difficulty.CarryDifficultyModel
+import net.dungeonhub.model.carry_queue.CarryQueueModel
+import net.dungeonhub.model.carry_tier.CarryTierModel
+import net.dungeonhub.model.carry_type.CarryTypeModel
+import net.dungeonhub.model.discord_role.DiscordRoleModel
+import net.dungeonhub.model.discord_role_group.DiscordRoleGroupModel
+import net.dungeonhub.model.discord_server.DiscordServerModel
+import net.dungeonhub.model.discord_user.DiscordUserModel
+import net.dungeonhub.model.purge_type.PurgeTypeModel
+import net.dungeonhub.model.score.ScoreModel
+import net.dungeonhub.model.warning.DetailedWarningModel
+import java.awt.Color
+import java.time.Instant
+import java.util.*
+
+@OptIn(ExperimentalStdlibApi::class)
+object MoshiService {
+ //TODO add type adapter for kord embeds ?
+ val moshi: Moshi = Moshi.Builder()
+ .add(Instant::class.java, InstantAdapter())
+ .add(Color::class.java, ColorAdapter())
+ .add(UUID::class.java, UUIDAdapter())
+ .addLast(KotlinJsonAdapterFactory())
+ .build()
+
+ val carryTypeListMoshi = moshi.adapter>()
+ val carryTierListMoshi = moshi.adapter>()
+ val carryDifficultyListMoshi = moshi.adapter>()
+ val carryQueueSetMoshi = moshi.adapter>()
+ val detailedWarningListMoshi = moshi.adapter>()
+ val discordRoleListMoshi = moshi.adapter>()
+ val discordRoleGroupListMoshi = moshi.adapter>()
+ val discordServerListMoshi = moshi.adapter>()
+ val discordUserListMoshi = moshi.adapter>()
+ val purgeTypeListMoshi = moshi.adapter>()
+ val scoreListMoshi = moshi.adapter>()
+
+ class InstantAdapter : JsonAdapter() {
+ override fun toJson(writer: JsonWriter, instant: Instant?) {
+ if(instant == null) {
+ writer.nullValue()
+ return
+ }
+
+ writer.value(instant.toEpochMilli())
+ }
+
+ override fun fromJson(reader: JsonReader): Instant? {
+ if(reader.peek() == JsonReader.Token.NULL) {
+ reader.nextNull()
+ return null
+ }
+
+ return Instant.ofEpochMilli(reader.nextLong())
+ }
+ }
+
+ class ColorAdapter : JsonAdapter() {
+ override fun toJson(writer: JsonWriter, color: Color?) {
+ if(color == null) {
+ writer.nullValue()
+ return
+ }
+
+ writer.value("#${Integer.toHexString(
+ color.red * 256 * 256 + color.green * 256 + color.blue
+ ).uppercase()}")
+ }
+
+ override fun fromJson(reader: JsonReader): Color? {
+ if(reader.peek() == JsonReader.Token.NULL) {
+ reader.nextNull()
+ return null
+ }
+
+ val hexString = reader.nextString()
+
+ //If the String doesn't start with a # this wasn't encoded with this adapter
+ // --> This might have come from the old library and is just not hex encoded
+ if(!hexString.startsWith("#")) {
+ return Color.decode(hexString)
+ }
+
+ val colorValue = Integer.parseUnsignedInt(hexString.substring(1), 16)
+
+ return Color.decode(colorValue.toString())
+ }
+ }
+
+ class UUIDAdapter : JsonAdapter() {
+ override fun toJson(writer: JsonWriter, uuid: UUID?) {
+ if(uuid == null) {
+ writer.nullValue()
+ return
+ }
+
+ writer.value(uuid.toString())
+ }
+
+ override fun fromJson(reader: JsonReader): UUID? {
+ if(reader.peek() == JsonReader.Token.NULL) {
+ reader.nextNull()
+ return null
+ }
+
+ return UUID.fromString(reader.nextString())
+ }
+ }
+}
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/structure/entity/Entity.kt b/model/src/main/kotlin/net/dungeonhub/structure/entity/Entity.kt
new file mode 100644
index 0000000..87b8c0d
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/structure/entity/Entity.kt
@@ -0,0 +1,7 @@
+package net.dungeonhub.structure.entity
+
+import net.dungeonhub.structure.model.Model
+
+interface Entity {
+ fun toModel(): M
+}
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/structure/entity/EntityService.kt b/model/src/main/kotlin/net/dungeonhub/structure/entity/EntityService.kt
new file mode 100644
index 0000000..27b7519
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/structure/entity/EntityService.kt
@@ -0,0 +1,69 @@
+package net.dungeonhub.structure.entity
+
+import net.dungeonhub.expections.EntityUnknownException
+import net.dungeonhub.structure.model.CreationModel
+import net.dungeonhub.structure.model.InitializeModel
+import net.dungeonhub.structure.model.Model
+import net.dungeonhub.structure.model.UpdateModel
+import org.springframework.http.HttpStatus
+import org.springframework.web.server.ResponseStatusException
+import java.util.*
+import java.util.function.Function
+import java.util.stream.Collectors
+
+interface EntityService, M : Model, C : CreationModel, I : InitializeModel, U : UpdateModel> {
+ fun loadEntityById(id: Long): Optional
+
+ fun findAllEntities(): List
+
+ fun createEntity(initalizationModel: I): E
+
+ fun delete(id: Long): Boolean
+
+ fun saveEntity(entity: E): E
+
+ fun toEntity(): Function?
+
+ fun toModel(): Function
+
+ fun loadById(id: Long): Optional {
+ return loadEntityById(id).map(toModel())
+ }
+
+ fun findAll(): Set {
+ return findAllEntities().stream().map(toModel()).collect(Collectors.toSet())
+ }
+
+ fun create(model: I): M {
+ return toModel().apply(createEntity(model))
+ }
+
+ fun save(entity: E): M {
+ return toModel().apply(saveEntity(entity))
+ }
+
+ fun update(entity: E, updateModel: U): E {
+ try {
+ return saveEntity(updateEntity(entity, updateModel))
+ } catch (exception: NumberFormatException) {
+ throw ResponseStatusException(HttpStatus.BAD_REQUEST)
+ } catch (exception: UnsupportedOperationException) {
+ throw ResponseStatusException(HttpStatus.BAD_REQUEST)
+ }
+ }
+
+ fun update(id: Long, updateModel: U): E {
+ return loadEntityById(id)
+ .map { entity -> update(entity, updateModel) }
+ .orElseThrow { EntityUnknownException(id) }
+ }
+
+ /**
+ * This function should be implemented by the respective service to update the entity with the values given in the update model.
+ * If you want to update the entity, please use [update] instead, as that function filters some common exceptions already.
+ *
+ * @param entity The entity to be updated
+ * @param updateModel The model containing the values to be updated
+ */
+ fun updateEntity(entity: E, updateModel: U): E
+}
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/structure/entity/InitializingFactory.kt b/model/src/main/kotlin/net/dungeonhub/structure/entity/InitializingFactory.kt
new file mode 100644
index 0000000..c6733dc
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/structure/entity/InitializingFactory.kt
@@ -0,0 +1,7 @@
+package net.dungeonhub.structure.entity
+
+import net.dungeonhub.structure.model.Model
+
+interface InitializingFactory, M : Model> {
+ fun transform(entity: E): E
+}
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/structure/model/CreationModel.kt b/model/src/main/kotlin/net/dungeonhub/structure/model/CreationModel.kt
new file mode 100644
index 0000000..53b93b8
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/structure/model/CreationModel.kt
@@ -0,0 +1,3 @@
+package net.dungeonhub.structure.model
+
+interface CreationModel : Model
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/structure/model/InitializeModel.kt b/model/src/main/kotlin/net/dungeonhub/structure/model/InitializeModel.kt
new file mode 100644
index 0000000..86ca2ef
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/structure/model/InitializeModel.kt
@@ -0,0 +1,14 @@
+package net.dungeonhub.structure.model
+
+import net.dungeonhub.structure.entity.Entity
+import net.dungeonhub.structure.entity.InitializingFactory
+
+interface InitializeModel, M : Model, C : CreationModel?> : Model {
+ fun toEntity(): E
+
+ fun fromCreationModel(creationModel: C): InitializeModel
+
+ fun toEntity(factory: InitializingFactory): E {
+ return factory.transform(toEntity())
+ }
+}
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/structure/model/Model.kt b/model/src/main/kotlin/net/dungeonhub/structure/model/Model.kt
new file mode 100644
index 0000000..2f2b915
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/structure/model/Model.kt
@@ -0,0 +1,3 @@
+package net.dungeonhub.structure.model
+
+interface Model
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/structure/model/UpdateModel.kt b/model/src/main/kotlin/net/dungeonhub/structure/model/UpdateModel.kt
new file mode 100644
index 0000000..ea141ff
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/structure/model/UpdateModel.kt
@@ -0,0 +1,3 @@
+package net.dungeonhub.structure.model
+
+interface UpdateModel
\ No newline at end of file
diff --git a/model/src/main/kotlin/net/dungeonhub/structure/model/UpdateableModel.kt b/model/src/main/kotlin/net/dungeonhub/structure/model/UpdateableModel.kt
new file mode 100644
index 0000000..9d768e9
--- /dev/null
+++ b/model/src/main/kotlin/net/dungeonhub/structure/model/UpdateableModel.kt
@@ -0,0 +1,5 @@
+package net.dungeonhub.structure.model
+
+interface UpdateableModel, M : Model> : Model {
+ fun getUpdateModel(): U
+}
\ No newline at end of file
diff --git a/model/src/test/kotlin/net/dungeonhub/enums/ScoreTypeTest.kt b/model/src/test/kotlin/net/dungeonhub/enums/ScoreTypeTest.kt
new file mode 100644
index 0000000..fdf923d
--- /dev/null
+++ b/model/src/test/kotlin/net/dungeonhub/enums/ScoreTypeTest.kt
@@ -0,0 +1,27 @@
+package net.dungeonhub.enums
+
+import net.dungeonhub.model.carry_type.CarryTypeModel
+import net.dungeonhub.model.discord_server.DiscordServerModel
+import org.junit.jupiter.api.Test
+import kotlin.test.assertEquals
+
+class ScoreTypeTest {
+ @Test
+ fun testLeaderboardTitle() {
+ for(scoreType in ScoreType.entries) {
+ val suffix = if (scoreType.leaderboardSuffix.isNullOrBlank()) "" else " ${scoreType.leaderboardSuffix}"
+
+ val carryType = CarryTypeModel(0, "identifier", "DisplayName", DiscordServerModel(0), null, null, false)
+
+ assertEquals(
+ "Leaderboard | Total score$suffix",
+ scoreType.getLeaderboardTitle(null)
+ )
+
+ assertEquals(
+ "Leaderboard | DisplayName-Carries$suffix",
+ scoreType.getLeaderboardTitle(carryType)
+ )
+ }
+ }
+}
\ No newline at end of file
diff --git a/model/src/test/kotlin/net/dungeonhub/model/CarryDifficultyUpdateModelTest.kt b/model/src/test/kotlin/net/dungeonhub/model/CarryDifficultyUpdateModelTest.kt
new file mode 100644
index 0000000..de8973b
--- /dev/null
+++ b/model/src/test/kotlin/net/dungeonhub/model/CarryDifficultyUpdateModelTest.kt
@@ -0,0 +1,87 @@
+package net.dungeonhub.model
+
+import net.dungeonhub.model.carry_difficulty.CarryDifficultyModel
+import net.dungeonhub.model.carry_difficulty.CarryDifficultyUpdateModel
+import net.dungeonhub.model.carry_tier.CarryTierModel
+import net.dungeonhub.model.carry_type.CarryTypeModel
+import net.dungeonhub.model.discord_server.DiscordServerModel
+import org.junit.jupiter.api.Test
+import kotlin.test.assertEquals
+
+class CarryDifficultyUpdateModelTest {
+ @Test
+ fun testCorrectSettingOfNullValues() {
+ val carryDifficultyUpdateModel = CarryDifficultyUpdateModel(
+ "displayName",
+ "thumbnailUrl",
+ 1,
+ 1,
+ "priceName",
+ 1,
+ 1
+ )
+
+ val resetThumbnailUrl = carryDifficultyUpdateModel.javaClass.getDeclaredField("resetThumbnailUrl")
+ resetThumbnailUrl.trySetAccessible()
+
+ assertEquals("thumbnailUrl", carryDifficultyUpdateModel.thumbnailUrl)
+ assertEquals(false, resetThumbnailUrl.getBoolean(carryDifficultyUpdateModel))
+
+ carryDifficultyUpdateModel.thumbnailUrl = null
+
+ assertEquals(null, carryDifficultyUpdateModel.thumbnailUrl)
+ assertEquals(true, resetThumbnailUrl.getBoolean(carryDifficultyUpdateModel))
+
+ val json = carryDifficultyUpdateModel.toJson()
+
+ val newObject = CarryDifficultyUpdateModel.fromJson(json)
+
+ assertEquals(null, newObject.thumbnailUrl)
+ assertEquals(true, resetThumbnailUrl.getBoolean(newObject))
+ }
+
+ @Test
+ fun testCorrectCreationOfUpdateModel() {
+ val carryDifficultyModel = CarryDifficultyModel(
+ 0,
+ "identifier",
+ "displayName",
+ CarryTierModel(
+ 0,
+ "identifier",
+ "displayName",
+ CarryTypeModel(
+ 0,
+ "identifier",
+ "displayName",
+ DiscordServerModel(0),
+ 0,
+ 0,
+ false
+ ),
+ 0,
+ 0,
+ "descriptiveName",
+ "thumbnailUrl",
+ "priceTitle",
+ "priceDescription"
+ ),
+ 0,
+ 0,
+ 0,
+ 0,
+ "thumbnailUrl",
+ "priceName"
+ )
+
+ val updateModel = carryDifficultyModel.getUpdateModel()
+
+ assertEquals(carryDifficultyModel.displayName, updateModel.displayName)
+ assertEquals(carryDifficultyModel.thumbnailUrl, updateModel.thumbnailUrl)
+ assertEquals(carryDifficultyModel.bulkPrice, updateModel.bulkPrice)
+ assertEquals(carryDifficultyModel.bulkAmount, updateModel.bulkAmount)
+ assertEquals(carryDifficultyModel.priceName, updateModel.priceName)
+ assertEquals(carryDifficultyModel.price, updateModel.price)
+ assertEquals(carryDifficultyModel.score, updateModel.score)
+ }
+}
\ No newline at end of file
diff --git a/model/src/test/kotlin/net/dungeonhub/model/DiscordUserCreationModelTest.kt b/model/src/test/kotlin/net/dungeonhub/model/DiscordUserCreationModelTest.kt
new file mode 100644
index 0000000..4592b68
--- /dev/null
+++ b/model/src/test/kotlin/net/dungeonhub/model/DiscordUserCreationModelTest.kt
@@ -0,0 +1,20 @@
+package net.dungeonhub.model
+
+import net.dungeonhub.model.discord_user.DiscordUserCreationModel
+import org.junit.jupiter.api.Test
+import java.util.UUID
+import kotlin.test.assertEquals
+
+class DiscordUserCreationModelTest {
+ @Test
+ fun testCorrectSerializationOfUuid() {
+ val discordUserCreationModel = DiscordUserCreationModel(
+ 0,
+ UUID.fromString("39642ffc-a7fb-4d24-a1d4-916f4cad1d98")
+ )
+
+ val json = discordUserCreationModel.toJson()
+
+ assertEquals("{\"id\":0,\"minecraftId\":\"39642ffc-a7fb-4d24-a1d4-916f4cad1d98\"}", json.replace("\\s".toRegex(), ""))
+ }
+}
\ No newline at end of file
diff --git a/model/src/test/kotlin/net/dungeonhub/service/MoshiServiceTest.kt b/model/src/test/kotlin/net/dungeonhub/service/MoshiServiceTest.kt
new file mode 100644
index 0000000..3b5b1ea
--- /dev/null
+++ b/model/src/test/kotlin/net/dungeonhub/service/MoshiServiceTest.kt
@@ -0,0 +1,90 @@
+package net.dungeonhub.service
+
+import com.squareup.moshi.JsonClass
+import com.squareup.moshi.JsonDataException
+import com.squareup.moshi.JsonEncodingException
+import org.junit.jupiter.api.Test
+import org.junit.jupiter.api.assertThrows
+import java.awt.Color
+import java.time.Instant
+import kotlin.test.assertEquals
+import kotlin.test.assertNotEquals
+
+class MoshiServiceTest {
+ @Test
+ fun testColorAdapter() {
+ val whiteColor = Color(255, 255, 255)
+ val dungeonHubColor = Color(165, 23, 112)
+
+ val whiteHex = "#FFFFFF"
+ val dungeonHubHex = "#A51770"
+
+ val whiteInt = Integer.parseUnsignedInt(whiteHex.substring(1), 16)
+ val dungeonHubInt = Integer.parseUnsignedInt(dungeonHubHex.substring(1), 16)
+
+ assertEquals(whiteHex, MoshiService.moshi.adapter(Color::class.java).toJsonValue(whiteColor))
+ assertEquals(dungeonHubHex, MoshiService.moshi.adapter(Color::class.java).toJsonValue(dungeonHubColor))
+
+ assertEquals(whiteColor, MoshiService.moshi.adapter(Color::class.java).fromJsonValue(whiteHex))
+ assertEquals(dungeonHubColor, MoshiService.moshi.adapter(Color::class.java).fromJsonValue(dungeonHubHex))
+
+ assertEquals(whiteColor, MoshiService.moshi.adapter(Color::class.java).fromJsonValue(whiteInt.toString()))
+ assertEquals(
+ dungeonHubColor,
+ MoshiService.moshi.adapter(Color::class.java).fromJsonValue(dungeonHubInt.toString())
+ )
+ }
+
+ @Test
+ fun testInstantAdapter() {
+ val currentMillis = System.currentTimeMillis()
+ val currentInstant = Instant.ofEpochMilli(currentMillis)
+
+ val epoch = 0L
+ val epochInstant = Instant.ofEpochMilli(epoch)
+
+ assertEquals(currentMillis, MoshiService.moshi.adapter(Instant::class.java).toJsonValue(currentInstant))
+ assertEquals(currentInstant, MoshiService.moshi.adapter(Instant::class.java).fromJsonValue(currentMillis))
+
+ assertEquals(epoch, MoshiService.moshi.adapter(Instant::class.java).toJsonValue(epochInstant))
+ assertEquals(epochInstant, MoshiService.moshi.adapter(Instant::class.java).fromJsonValue(epoch))
+ }
+
+ @Test
+ fun testBasicTypes() {
+ val numberString = "-42"
+ val booleanString = "true"
+ val string = "Hello, World!"
+
+ assertEquals(-42, MoshiService.moshi.adapter(Int::class.java).fromJson(numberString))
+ assertEquals(true, MoshiService.moshi.adapter(Boolean::class.java).fromJson(booleanString))
+ assertEquals(string, MoshiService.moshi.adapter(String::class.java).fromJsonValue(string))
+
+ assertThrows {
+ MoshiService.moshi.adapter(Int::class.java).fromJsonValue(string)
+ }
+ }
+
+ @Test
+ fun testObjects() {
+ val firstJson = "{\"name\":\"Taubsie\"}"
+ val incorrectJson = "{name:\"SomeoneElse\"}"
+
+ assertEquals(TestObject("Taubsie"), MoshiService.moshi.adapter(TestObject::class.java).fromJson(firstJson))
+ assertNotEquals(
+ TestObject("SomeoneElse"),
+ MoshiService.moshi.adapter(TestObject::class.java).fromJson(firstJson)
+ )
+
+ assertThrows {
+ MoshiService.moshi.adapter(TestObject::class.java).fromJson(incorrectJson)
+ }
+
+ assertEquals(AnotherTestObject("Taubsie"), MoshiService.moshi.adapter(AnotherTestObject::class.java).fromJson(firstJson))
+ }
+
+ @JsonClass(generateAdapter = true)
+ data class TestObject(val name: String)
+
+ data class AnotherTestObject(val name: String)
+}
\ No newline at end of file
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 5d6b38c..3bb4062 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -4,4 +4,5 @@ plugins {
rootProject.name = "dungeon-hub-api"
include(":model")
-include(":client")
+//TODO uncomment
+//include(":client")