diff --git a/.github/workflows/main.yml b/.github/workflows/build.yml similarity index 93% rename from .github/workflows/main.yml rename to .github/workflows/build.yml index dc465a1..2c745d6 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/build.yml @@ -1,4 +1,4 @@ -name: Java CI +name: Java CI with Gradle on: pull_request: diff --git a/.github/workflows/publish-packages.yml b/.github/workflows/publish.yml similarity index 84% rename from .github/workflows/publish-packages.yml rename to .github/workflows/publish.yml index b009cd3..3dcda21 100644 --- a/.github/workflows/publish-packages.yml +++ b/.github/workflows/publish.yml @@ -1,4 +1,4 @@ -name: Publish GitHub Packages +name: Publish on: push: @@ -11,13 +11,14 @@ on: jobs: build: runs-on: ubuntu-latest - steps: - uses: actions/checkout@v3 - uses: MineInAbyss/publish-action@master with: maven-metadata-url: https://repo.mineinabyss.com/releases/com/mineinabyss/deeperworld/maven-metadata.xml + pages-path: build/dokka/htmlMultiModule/ + dokka: dokkaHtmlMultiModule maven-username: ${{ secrets.MAVEN_PUBLISH_USERNAME }} maven-password: ${{ secrets.MAVEN_PUBLISH_PASSWORD }} release-files: | diff --git a/build.gradle.kts b/build.gradle.kts index 66a9617..224cb26 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,12 +1,12 @@ @Suppress("DSL_SCOPE_VIOLATION") plugins { alias(libs.plugins.kotlinx.serialization) - id("com.mineinabyss.conventions.kotlin.jvm") - id("com.mineinabyss.conventions.papermc") - id("com.mineinabyss.conventions.copyjar") - id("com.mineinabyss.conventions.publication") - id("com.mineinabyss.conventions.testing") - id("com.mineinabyss.conventions.autoversion") + alias(libs.plugins.mia.kotlin.jvm) + alias(libs.plugins.mia.papermc) + alias(libs.plugins.mia.copyjar) + alias(libs.plugins.mia.testing) + alias(libs.plugins.mia.publication) + alias(libs.plugins.mia.autoversion) } repositories { diff --git a/gradle.properties b/gradle.properties index 26c49ff..f4706db 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ group=com.mineinabyss -version=0.8 -idofrontVersion=0.18.26 +version=0.9 +idofrontVersion=0.19.14 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index fae0804..e411586 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/src/main/kotlin/com/mineinabyss/deeperworld/DeeperCommandExecutor.kt b/src/main/kotlin/com/mineinabyss/deeperworld/DeeperCommandExecutor.kt index e82c35f..1cb8662 100644 --- a/src/main/kotlin/com/mineinabyss/deeperworld/DeeperCommandExecutor.kt +++ b/src/main/kotlin/com/mineinabyss/deeperworld/DeeperCommandExecutor.kt @@ -14,10 +14,10 @@ import com.mineinabyss.idofront.commands.arguments.intArg import com.mineinabyss.idofront.commands.execution.IdofrontCommandExecutor import com.mineinabyss.idofront.commands.execution.stopCommand import com.mineinabyss.idofront.commands.extensions.actions.playerAction -import com.mineinabyss.idofront.config.config import com.mineinabyss.idofront.messaging.error import com.mineinabyss.idofront.messaging.info import com.mineinabyss.idofront.messaging.success +import com.mineinabyss.idofront.plugin.Plugins import com.sk89q.worldedit.EditSession import com.sk89q.worldedit.WorldEdit import com.sk89q.worldedit.bukkit.WorldEditPlugin @@ -34,11 +34,12 @@ import org.bukkit.command.CommandSender import org.bukkit.command.TabCompleter class DeeperCommandExecutor : IdofrontCommandExecutor(), TabCompleter { - override val commands = commands(deeperWorld) { + override val commands = commands(deeperWorld.plugin) { ("deeperworld" / "dw") { "reload" { action { - deeperWorld.config = config("config") { deeperWorld.fromPluginPath(loadDefault = true)} + deeperWorld.plugin.createDeeperWorldContext() + sender.success("Reloaded DeeperWorld") } } "tp"(desc = "Enables or disables automatic teleports between sections for a player") { @@ -66,11 +67,11 @@ class DeeperCommandExecutor : IdofrontCommandExecutor(), TabCompleter { val time by intArg() "set"(desc = "Set the time of the main synchronization world and the other worlds with their respective offsets") { playerAction { - deeperConfig.time.mainWorld?.let { world -> + deeperWorld.config.time.mainWorld?.let { world -> world.time = time.toLong() } ?: command.stopCommand("No main world specified for time synchronization. Check the config!") - deeperConfig.time.syncedWorlds.forEach { (world, offset) -> + deeperWorld.config.time.syncedWorlds.forEach { (world, offset) -> world.time = (time.toLong() + offset) % FULL_DAY_TIME } @@ -79,10 +80,10 @@ class DeeperCommandExecutor : IdofrontCommandExecutor(), TabCompleter { } "add"(desc = "Add to the main synchronization world time and the other worlds with their respective offsets") { playerAction { - deeperConfig.time.mainWorld?.let { mainWorld -> + deeperWorld.config.time.mainWorld?.let { mainWorld -> mainWorld.time += time.toLong() - deeperConfig.time.syncedWorlds.forEach { (world, offset) -> + deeperWorld.config.time.syncedWorlds.forEach { (world, offset) -> world.time = (mainWorld.time + offset) % FULL_DAY_TIME } @@ -101,7 +102,7 @@ class DeeperCommandExecutor : IdofrontCommandExecutor(), TabCompleter { } when { - DeeperContext.isFAWELoaded -> { + Plugins.isEnabled("FastAsyncWorldEdit") -> { try { val pos1 = BlockVector3.at( (player.location.x + range), diff --git a/src/main/kotlin/com/mineinabyss/deeperworld/DeeperConfig.kt b/src/main/kotlin/com/mineinabyss/deeperworld/DeeperConfig.kt index d703bb1..8599050 100644 --- a/src/main/kotlin/com/mineinabyss/deeperworld/DeeperConfig.kt +++ b/src/main/kotlin/com/mineinabyss/deeperworld/DeeperConfig.kt @@ -2,22 +2,32 @@ package com.mineinabyss.deeperworld +import com.charleskorn.kaml.YamlComment +import com.mineinabyss.deeperworld.world.Region import com.mineinabyss.deeperworld.world.section.Section +import com.mineinabyss.idofront.di.DI import com.mineinabyss.idofront.serialization.DurationSerializer import com.mineinabyss.idofront.serialization.WorldSerializer import com.mineinabyss.idofront.time.ticks import kotlinx.serialization.Serializable import kotlinx.serialization.UseSerializers +import org.bukkit.Bukkit import org.bukkit.World import kotlin.time.Duration import kotlin.time.Duration.Companion.seconds -val deeperConfig get() = deeperWorld.config.data +val deeperWorld by DI.observe() @Serializable data class DeeperWorldConfig( - val sections: List
= emptyList(), - val damageOutsideSections: Double = 0.0, + val sections: List
= listOf( + Section("section1", Region(0,0,0,1000,256,1000), Bukkit.getWorld("world")!!, "0, 0, 0", "0, 16, 0"), + Section("section2", Region(1000, 0, 0, 2000 ,256, 1000), Bukkit.getWorld("world")!!, "1000, 240, 0", "2000, 16, 0"), + ), + @YamlComment("The damage players will take when outside a managed section.") + val damageOutsideSections: Double = 1.0, + @YamlComment("Worlds which shouldn't damage players when outside of a section.") val damageExcludedWorlds: Set<@Serializable(with = WorldSerializer::class) World> = emptySet(), + @YamlComment("Sends an additional remount packet after this delay to prevent client-side mount bugs when moving between sections.\n") val remountPacketDelay: Duration = 40.ticks, val fall: FallDamageConfig = FallDamageConfig(), val time: TimeConfig = TimeConfig(), @@ -26,17 +36,25 @@ data class DeeperWorldConfig( @Serializable data class FallDamageConfig( + @YamlComment("The maximum safe falling distance, after which players will start taking damage. Set to -1 to disable falling damage") val maxSafeDist: Float = -1f, + @YamlComment("The multiplier for damage taken while falling. Set to 0 to deal consistent damage.") val fallDistanceDamageScaler: Double = 0.01, + @YamlComment("The minimum damage to deal.") val startingDamage: Double = 1.0, + @YamlComment("How often to damage players in ticks") val hitDelay: @Serializable(DurationSerializer::class) Duration = 10.ticks, + @YamlComment("Whether to spawn cloud particles when the player is being damaged.") val spawnParticles: Boolean = true ) @Serializable data class TimeConfig( + @YamlComment("How often to synchronize time between worlds") val updateInterval: @Serializable(DurationSerializer::class) Duration = 1800.seconds, - val mainWorld: @Serializable(WorldSerializer::class) World? = null, - val syncedWorlds: Map<@Serializable(WorldSerializer::class) World, Long> = emptyMap(), + @YamlComment("The main synchronization world. Other worlds will get synchronized based on the time in this world.") + val mainWorld: @Serializable(WorldSerializer::class) World? = Bukkit.getWorld("world"), + @YamlComment("The worlds where time should be synchronized with the mainWorld. Optionally specify a time offset (leave 0 if no offset is desired)") + val syncedWorlds: Map<@Serializable(WorldSerializer::class) World, Long> = mutableMapOf(Bukkit.getWorld("world")!! to 0L) ) } diff --git a/src/main/kotlin/com/mineinabyss/deeperworld/DeeperContext.kt b/src/main/kotlin/com/mineinabyss/deeperworld/DeeperContext.kt index 7207e0d..75f8491 100644 --- a/src/main/kotlin/com/mineinabyss/deeperworld/DeeperContext.kt +++ b/src/main/kotlin/com/mineinabyss/deeperworld/DeeperContext.kt @@ -3,7 +3,7 @@ package com.mineinabyss.deeperworld /** * Easy access to information related to the [DeeperWorldPlugin] plugin. */ -object DeeperContext { - val isBlockLockerLoaded: Boolean = deeperWorld.server.pluginManager.isPluginEnabled("BlockLocker") - val isFAWELoaded: Boolean = deeperWorld.server.pluginManager.isPluginEnabled("FastAsyncWorldEdit") +interface DeeperContext { + val plugin: DeeperWorldPlugin + val config: DeeperWorldConfig } diff --git a/src/main/kotlin/com/mineinabyss/deeperworld/DeeperWorldPlugin.kt b/src/main/kotlin/com/mineinabyss/deeperworld/DeeperWorldPlugin.kt index 5f1fc5c..3391a73 100644 --- a/src/main/kotlin/com/mineinabyss/deeperworld/DeeperWorldPlugin.kt +++ b/src/main/kotlin/com/mineinabyss/deeperworld/DeeperWorldPlugin.kt @@ -14,8 +14,8 @@ import com.mineinabyss.deeperworld.synchronization.ContainerSyncListener import com.mineinabyss.deeperworld.synchronization.ExploitPreventionListener import com.mineinabyss.deeperworld.synchronization.SectionSyncListener import com.mineinabyss.deeperworld.world.WorldManagerImpl -import com.mineinabyss.idofront.config.IdofrontConfig import com.mineinabyss.idofront.config.config +import com.mineinabyss.idofront.di.DI import com.mineinabyss.idofront.platforms.Platforms import com.mineinabyss.idofront.plugin.listeners import com.mineinabyss.idofront.plugin.service @@ -27,25 +27,23 @@ import org.bukkit.plugin.java.JavaPlugin val protocolManager: ProtocolManager = ProtocolLibrary.getProtocolManager() class DeeperWorldPlugin : JavaPlugin() { - lateinit var config: IdofrontConfig override fun onLoad() { Platforms.load(this, "mineinabyss") } override fun onEnable() { - config = config("config") { fromPluginPath(loadDefault = true)} - + createDeeperWorldContext() service(WorldManagerImpl()) service(PlayerManagerImpl()) // Register aboveKey / belowKey as new config breaks this - for (section in deeperConfig.sections) { + for (section in deeperWorld.config.sections) { when (section) { - deeperConfig.sections.first() -> section.belowKey = deeperConfig.sections[1].key - deeperConfig.sections.last() -> section.aboveKey = deeperConfig.sections[deeperConfig.sections.size - 2].key + deeperWorld.config.sections.first() -> section.belowKey = deeperWorld.config.sections[1].key + deeperWorld.config.sections.last() -> section.aboveKey = deeperWorld.config.sections[deeperWorld.config.sections.size - 2].key else -> { - section.aboveKey = deeperConfig.sections[deeperConfig.sections.indexOf(section) - 1].key - section.belowKey = deeperConfig.sections[deeperConfig.sections.indexOf(section) + 1].key + section.aboveKey = deeperWorld.config.sections[deeperWorld.config.sections.indexOf(section) - 1].key + section.belowKey = deeperWorld.config.sections[deeperWorld.config.sections.indexOf(section) + 1].key } } } @@ -62,9 +60,9 @@ class DeeperWorldPlugin : JavaPlugin() { DeeperCommandExecutor() // Initialize falling damage task - if (deeperConfig.fall.maxSafeDist >= 0f && deeperConfig.fall.fallDistanceDamageScaler >= 0.0) { - val hitDellay = deeperConfig.fall.hitDelay.coerceAtLeast(1.ticks) - deeperWorld.launch { + if (deeperWorld.config.fall.maxSafeDist >= 0f && deeperWorld.config.fall.fallDistanceDamageScaler >= 0.0) { + val hitDellay = deeperWorld.config.fall.hitDelay.coerceAtLeast(1.ticks) + deeperWorld.plugin.launch { while (true) { server.onlinePlayers.forEach { FallingDamageManager.updateFallingDamage(it) @@ -75,13 +73,13 @@ class DeeperWorldPlugin : JavaPlugin() { } // Initialize time synchronization task - if (deeperConfig.time.syncedWorlds.isNotEmpty()) { - deeperConfig.time.mainWorld?.let { mainWorld -> - val updateInterval = deeperConfig.time.updateInterval.coerceAtLeast(1.ticks) - deeperWorld.launch { + if (deeperWorld.config.time.syncedWorlds.isNotEmpty()) { + deeperWorld.config.time.mainWorld?.let { mainWorld -> + val updateInterval = deeperWorld.config.time.updateInterval.coerceAtLeast(1.ticks) + deeperWorld.plugin.launch { while (true) { val mainWorldTime = mainWorld.time - deeperConfig.time.syncedWorlds.forEach { (world, offset) -> + deeperWorld.config.time.syncedWorlds.forEach { (world, offset) -> world.time = (mainWorldTime + offset) % FULL_DAY_TIME } delay(updateInterval) @@ -91,6 +89,14 @@ class DeeperWorldPlugin : JavaPlugin() { } } + fun createDeeperWorldContext() { + DI.remove() + DI.add(object : DeeperContext { + override val plugin = this@DeeperWorldPlugin + override val config: DeeperWorldConfig by config("config", dataFolder.toPath(), DeeperWorldConfig()) + }) + } + override fun onDisable() { MovementListener.temporaryBedrock.forEach { it.type = Material.AIR diff --git a/src/main/kotlin/com/mineinabyss/deeperworld/Helpers.kt b/src/main/kotlin/com/mineinabyss/deeperworld/Helpers.kt deleted file mode 100644 index 23b0536..0000000 --- a/src/main/kotlin/com/mineinabyss/deeperworld/Helpers.kt +++ /dev/null @@ -1,8 +0,0 @@ -package com.mineinabyss.deeperworld - -import org.bukkit.plugin.java.JavaPlugin - -/** - * Gets [DeeperWorldPlugin] via Bukkit once, then sends that reference back afterwards - */ -val deeperWorld: DeeperWorldPlugin by lazy { JavaPlugin.getPlugin(DeeperWorldPlugin::class.java) } diff --git a/src/main/kotlin/com/mineinabyss/deeperworld/movement/BedrockBlockingInvalidTeleportHandler.kt b/src/main/kotlin/com/mineinabyss/deeperworld/movement/BedrockBlockingInvalidTeleportHandler.kt index 4438f79..d41227b 100644 --- a/src/main/kotlin/com/mineinabyss/deeperworld/movement/BedrockBlockingInvalidTeleportHandler.kt +++ b/src/main/kotlin/com/mineinabyss/deeperworld/movement/BedrockBlockingInvalidTeleportHandler.kt @@ -20,7 +20,7 @@ class BedrockBlockingInvalidTeleportHandler(player: Player, from: Location, to: // Keep bedrock spawned if there are players within a 1.5 radius (regular jump height). // If no players are in this radius, destroy the bedrock. - deeperWorld.launch { + deeperWorld.plugin.launch { while (spawnedBedrock.location.up(1).getNearbyPlayers(1.5).isNotEmpty()) { delay(5.ticks) } diff --git a/src/main/kotlin/com/mineinabyss/deeperworld/movement/MovementHandler.kt b/src/main/kotlin/com/mineinabyss/deeperworld/movement/MovementHandler.kt index f935f62..5282897 100644 --- a/src/main/kotlin/com/mineinabyss/deeperworld/movement/MovementHandler.kt +++ b/src/main/kotlin/com/mineinabyss/deeperworld/movement/MovementHandler.kt @@ -1,6 +1,6 @@ package com.mineinabyss.deeperworld.movement -import com.mineinabyss.deeperworld.deeperConfig +import com.mineinabyss.deeperworld.deeperWorld import com.mineinabyss.deeperworld.movement.transition.ConfigSectionChecker import com.mineinabyss.deeperworld.movement.transition.SectionTransition import com.mineinabyss.deeperworld.movement.transition.TransitionKind @@ -39,13 +39,13 @@ object MovementHandler { //TODO abstract this away. Should instead do out of bounds action if out of bounds. private fun Player.applyOutOfBoundsDamage() { - if (deeperConfig.damageOutsideSections > 0.0 - && location.world !in deeperConfig.damageExcludedWorlds + if (deeperWorld.config.damageOutsideSections > 0.0 + && location.world !in deeperWorld.config.damageExcludedWorlds && (gameMode == GameMode.SURVIVAL || gameMode == GameMode.ADVENTURE) - && location.world in deeperConfig.worlds + && location.world in deeperWorld.config.worlds ) { damage(0.01) //give a damage effect - health = (health - deeperConfig.damageOutsideSections / 10) + health = (health - deeperWorld.config.damageOutsideSections / 10) .coerceIn(0.0, getAttribute(Attribute.GENERIC_MAX_HEALTH)?.value) //ignores armor showTitle( Title.title( diff --git a/src/main/kotlin/com/mineinabyss/deeperworld/movement/SectionTeleportPacketAdapter.kt b/src/main/kotlin/com/mineinabyss/deeperworld/movement/SectionTeleportPacketAdapter.kt index badbdbf..2aa9388 100644 --- a/src/main/kotlin/com/mineinabyss/deeperworld/movement/SectionTeleportPacketAdapter.kt +++ b/src/main/kotlin/com/mineinabyss/deeperworld/movement/SectionTeleportPacketAdapter.kt @@ -6,7 +6,6 @@ import com.comphenix.protocol.events.PacketContainer import com.comphenix.protocol.events.PacketEvent import com.github.shynixn.mccoroutine.bukkit.launch import com.mineinabyss.deeperworld.datastructures.VehicleTree -import com.mineinabyss.deeperworld.deeperConfig import com.mineinabyss.deeperworld.deeperWorld import com.mineinabyss.deeperworld.protocolManager import com.mineinabyss.idofront.time.ticks @@ -29,7 +28,7 @@ class SectionTeleportPacketAdapter( private val oldVelocity: Vector, private val vehicleTree: VehicleTree? = null ) : PacketAdapter( - deeperWorld, + deeperWorld.plugin, PacketType.Play.Client.POSITION, PacketType.Play.Client.POSITION_LOOK ) { @@ -38,7 +37,7 @@ class SectionTeleportPacketAdapter( protocolManager.removePacketListener(this) - deeperWorld.launch { + deeperWorld.plugin.launch { delay(1.ticks) oldLeashedEntities.toSet().forEach { @@ -64,7 +63,7 @@ class SectionTeleportPacketAdapter( vehicleTree.root.value.fallDistance = oldFallDistance vehicleTree.root.value.velocity = oldVelocity - delay(deeperConfig.remountPacketDelay) + delay(deeperWorld.config.remountPacketDelay) player.vehicle?.let { vehicle -> val playerVehicleID = vehicle.entityId diff --git a/src/main/kotlin/com/mineinabyss/deeperworld/movement/TransitionTeleportHandler.kt b/src/main/kotlin/com/mineinabyss/deeperworld/movement/TransitionTeleportHandler.kt index 8d2c8f9..8420365 100644 --- a/src/main/kotlin/com/mineinabyss/deeperworld/movement/TransitionTeleportHandler.kt +++ b/src/main/kotlin/com/mineinabyss/deeperworld/movement/TransitionTeleportHandler.kt @@ -51,7 +51,7 @@ class TransitionTeleportHandler(val player: Player, val from: Location, val to: // Delay the teleportation by 1 tick after passenger removal to avoid occasional // "Removing ticking entity!" exceptions. - deeperWorld.launch { + deeperWorld.plugin.launch { delay(1.ticks) player.teleportWithSpectatorsAsync(to) { diff --git a/src/main/kotlin/com/mineinabyss/deeperworld/player/FallingDamageManager.kt b/src/main/kotlin/com/mineinabyss/deeperworld/player/FallingDamageManager.kt index b2013d3..3355861 100644 --- a/src/main/kotlin/com/mineinabyss/deeperworld/player/FallingDamageManager.kt +++ b/src/main/kotlin/com/mineinabyss/deeperworld/player/FallingDamageManager.kt @@ -1,6 +1,6 @@ package com.mineinabyss.deeperworld.player -import com.mineinabyss.deeperworld.deeperConfig +import com.mineinabyss.deeperworld.deeperWorld import com.mineinabyss.deeperworld.extensions.getRootVehicle import org.bukkit.GameMode.ADVENTURE import org.bukkit.GameMode.SURVIVAL @@ -11,20 +11,20 @@ internal object FallingDamageManager { fun updateFallingDamage(player: Player) { val actualFallDistance = player.getRootVehicle()?.fallDistance ?: player.fallDistance - if (actualFallDistance > deeperConfig.fall.maxSafeDist + if (actualFallDistance > deeperWorld.config.fall.maxSafeDist && !player.isGliding && !player.allowFlight && !player.isDead && (player.gameMode == SURVIVAL || player.gameMode == ADVENTURE) ) { // Always deal a minimum of 1 damage, else the first damage tick could deal (almost) no damage - val damageToDeal = ((actualFallDistance - deeperConfig.fall.maxSafeDist) * deeperConfig.fall.fallDistanceDamageScaler) - .coerceAtLeast(deeperConfig.fall.startingDamage) + val damageToDeal = ((actualFallDistance - deeperWorld.config.fall.maxSafeDist) * deeperWorld.config.fall.fallDistanceDamageScaler) + .coerceAtLeast(deeperWorld.config.fall.startingDamage) player.damage(0.01) // Damage animation player.health = (player.health - damageToDeal).coerceAtLeast(0.0) - if (deeperConfig.fall.spawnParticles) + if (deeperWorld.config.fall.spawnParticles) player.world.spawnParticle( Particle.CLOUD, player.location.apply { y += player.velocity.y * 2 }, diff --git a/src/main/kotlin/com/mineinabyss/deeperworld/synchronization/ContainerSyncListener.kt b/src/main/kotlin/com/mineinabyss/deeperworld/synchronization/ContainerSyncListener.kt index d04faee..6f11073 100644 --- a/src/main/kotlin/com/mineinabyss/deeperworld/synchronization/ContainerSyncListener.kt +++ b/src/main/kotlin/com/mineinabyss/deeperworld/synchronization/ContainerSyncListener.kt @@ -1,10 +1,10 @@ package com.mineinabyss.deeperworld.synchronization -import com.mineinabyss.deeperworld.DeeperContext import com.mineinabyss.deeperworld.deeperWorld import com.mineinabyss.deeperworld.world.section.* import com.mineinabyss.idofront.destructure.component1 import com.mineinabyss.idofront.messaging.info +import com.mineinabyss.idofront.plugin.Plugins import nl.rutgerkok.blocklocker.BlockLockerAPIv2 import nl.rutgerkok.blocklocker.SearchMode import org.bukkit.Chunk @@ -45,7 +45,7 @@ object ContainerSyncListener : Listener { val linkedSection = loc.correspondingSection ?: return val linkedBlock = loc.getCorrespondingLocation(section, linkedSection)?.block ?: return - if (DeeperContext.isBlockLockerLoaded) { + if (Plugins.isEnabled("BlockLocker")) { updateProtection(linkedBlock) updateProtection(clicked) @@ -58,7 +58,7 @@ object ContainerSyncListener : Listener { } if (container is Lidded) { - (linkedBlock.state as Lidded).open(); + (linkedBlock.state as Lidded).open() if (!section.isOnTopOf(linkedSection)) (container as Lidded).open() } @@ -82,10 +82,10 @@ object ContainerSyncListener : Listener { } //keep chunk loaded - linkedBlock.chunk.addPluginChunkTicket(deeperWorld) + linkedBlock.chunk.addPluginChunkTicket(deeperWorld.plugin) //keep track of players opening inventory in this chunk - keepLoadedInventories.getOrPut(linkedBlock.chunk, { mutableListOf() }) += player + keepLoadedInventories.getOrPut(linkedBlock.chunk) { mutableListOf() } += player } } } @@ -104,7 +104,7 @@ object ContainerSyncListener : Listener { if (keepLoadedInventories[chunk]?.remove(player) != null) { if (keepLoadedInventories[chunk]?.isEmpty() == true) { keepLoadedInventories -= chunk - chunk.removePluginChunkTicket(deeperWorld) + chunk.removePluginChunkTicket(deeperWorld.plugin) } } } diff --git a/src/main/kotlin/com/mineinabyss/deeperworld/synchronization/SectionSyncListener.kt b/src/main/kotlin/com/mineinabyss/deeperworld/synchronization/SectionSyncListener.kt index c568c99..a10ec05 100644 --- a/src/main/kotlin/com/mineinabyss/deeperworld/synchronization/SectionSyncListener.kt +++ b/src/main/kotlin/com/mineinabyss/deeperworld/synchronization/SectionSyncListener.kt @@ -1,13 +1,13 @@ package com.mineinabyss.deeperworld.synchronization import com.github.shynixn.mccoroutine.bukkit.launch -import com.mineinabyss.deeperworld.DeeperContext import com.mineinabyss.deeperworld.deeperWorld import com.mineinabyss.deeperworld.event.BlockSyncEvent import com.mineinabyss.deeperworld.event.SyncType import com.mineinabyss.deeperworld.world.section.correspondingLocation import com.mineinabyss.deeperworld.world.section.inSectionOverlap import com.mineinabyss.idofront.events.call +import com.mineinabyss.idofront.plugin.Plugins import com.mineinabyss.idofront.time.ticks import kotlinx.coroutines.delay import net.kyori.adventure.text.Component @@ -70,7 +70,7 @@ object SectionSyncListener : Listener { } //sync any changes to BlockLocker's signs` - if (DeeperContext.isBlockLockerLoaded && state is Sign && + if (Plugins.isEnabled("BlockLocker") && state is Sign && (state.getSide(Side.FRONT).lines().first() == Component.text("[Private]") || state.getSide(Side.BACK).lines().first() == Component.text("[Private]"))) { syncBlockLocker(corr) @@ -113,7 +113,7 @@ object SectionSyncListener : Listener { fun BlockGrowEvent.syncBlockGrow() { if (!block.location.inSectionOverlap) return if (!block.location.inSectionOverlap) return - deeperWorld.launch { + deeperWorld.plugin.launch { delay(1.ticks) block.sync(updateBlockData(block.blockData)) } @@ -131,7 +131,7 @@ object SectionSyncListener : Listener { if (block.blockData !is Ageable || block is Sapling) return if (!block.location.inSectionOverlap || corrBlock.type != block.type) return - deeperWorld.launch { + deeperWorld.plugin.launch { delay(1.ticks) block.sync(updateBlockData(block.blockData)) } diff --git a/src/main/kotlin/com/mineinabyss/deeperworld/world/Point.kt b/src/main/kotlin/com/mineinabyss/deeperworld/world/Point.kt index e75d2aa..d81c248 100644 --- a/src/main/kotlin/com/mineinabyss/deeperworld/world/Point.kt +++ b/src/main/kotlin/com/mineinabyss/deeperworld/world/Point.kt @@ -1,8 +1,13 @@ package com.mineinabyss.deeperworld.world +import kotlinx.serialization.Serializable +import org.bukkit.Location +import org.bukkit.World + /** * Represents a single X/Y/Z cube in a minecraft world. */ +@Serializable data class CubePoint(val x: Int, val y: Int, val z: Int) { operator fun plus(other: CubePoint) = CubePoint(x + other.x, y + other.y, z + other.z) @@ -11,4 +16,8 @@ data class CubePoint(val x: Int, val y: Int, val z: Int) { operator fun div(o: Float) = CubePoint((x / o).toInt(), (y / o).toInt(), (z / o).toInt()) operator fun div(o: Int) = CubePoint(x / o, y / o, z / o) + + override fun toString() = "$x,$y,$z" + + fun toLocation(world: World) = Location(world, x.toDouble(), y.toDouble(), z.toDouble()) } diff --git a/src/main/kotlin/com/mineinabyss/deeperworld/world/Region.kt b/src/main/kotlin/com/mineinabyss/deeperworld/world/Region.kt index 28bb8d1..f83a925 100644 --- a/src/main/kotlin/com/mineinabyss/deeperworld/world/Region.kt +++ b/src/main/kotlin/com/mineinabyss/deeperworld/world/Region.kt @@ -12,7 +12,7 @@ import kotlin.math.min * Represents a region of the world. */ @Serializable(with = RegionSerializer::class) -class Region(val start: CubePoint, val end: CubePoint) { +data class Region(val start: CubePoint, val end: CubePoint) { val min = CubePoint(min(start.x, end.x), min(start.y, end.y), min(start.z, end.z)) val max = CubePoint(max(start.x, end.x), max(start.y, end.y), max(start.z, end.z)) diff --git a/src/main/kotlin/com/mineinabyss/deeperworld/world/WorldManagerImpl.kt b/src/main/kotlin/com/mineinabyss/deeperworld/world/WorldManagerImpl.kt index 9d29927..b61ccc4 100644 --- a/src/main/kotlin/com/mineinabyss/deeperworld/world/WorldManagerImpl.kt +++ b/src/main/kotlin/com/mineinabyss/deeperworld/world/WorldManagerImpl.kt @@ -1,6 +1,6 @@ package com.mineinabyss.deeperworld.world -import com.mineinabyss.deeperworld.deeperConfig +import com.mineinabyss.deeperworld.deeperWorld import com.mineinabyss.deeperworld.services.WorldManager import com.mineinabyss.deeperworld.world.section.AbstractSectionKey.CustomSectionKey import com.mineinabyss.deeperworld.world.section.Section @@ -11,7 +11,7 @@ import org.bukkit.World class WorldManagerImpl : WorldManager { override val sections get() = sectionMap.values.toSet() - private val sectionMap = deeperConfig.sections.associateBy { it.key }.toMutableMap() + private val sectionMap = deeperWorld.config.sections.associateBy { it.key }.toMutableMap() override fun registerSection(name: String, section: Section): SectionKey = diff --git a/src/main/kotlin/com/mineinabyss/deeperworld/world/section/Section.kt b/src/main/kotlin/com/mineinabyss/deeperworld/world/section/Section.kt index 8d65442..09f1f66 100644 --- a/src/main/kotlin/com/mineinabyss/deeperworld/world/section/Section.kt +++ b/src/main/kotlin/com/mineinabyss/deeperworld/world/section/Section.kt @@ -2,15 +2,14 @@ package com.mineinabyss.deeperworld.world.section +import com.charleskorn.kaml.YamlComment import com.mineinabyss.deeperworld.world.Region import com.mineinabyss.deeperworld.world.getCoordinates import com.mineinabyss.idofront.serialization.LocationSerializer import com.mineinabyss.idofront.serialization.VectorSerializer import com.mineinabyss.idofront.serialization.WorldSerializer -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable -import kotlinx.serialization.Transient -import kotlinx.serialization.UseSerializers +import kotlinx.serialization.* +import org.bukkit.Bukkit import org.bukkit.Location import org.bukkit.World @@ -28,15 +27,18 @@ import org.bukkit.World @Serializable data class Section( val name: String? = null, - val region: Region, - val world: @Serializable(WorldSerializer::class) World, + val region: Region = Region(0,0,0,1,1,1), + val world: @Serializable(WorldSerializer::class) World = Bukkit.getWorld("world")!!, @SerialName("refTop") private val _refTop: String, + @YamlComment("refBottom should connect to the refTop of the next section.") @SerialName("refBottom") private val _refBottom: String ) { @Serializable(LocationSerializer::class) + @EncodeDefault(EncodeDefault.Mode.NEVER) val referenceTop = _refTop.toLocation(world) @Serializable(LocationSerializer::class) + @EncodeDefault(EncodeDefault.Mode.NEVER) val referenceBottom = _refBottom.toLocation(world) fun String.toLocation(world: World): Location { @@ -44,6 +46,7 @@ data class Section( return Location(world, x, y, z) } + @Transient val key: SectionKey = name?.let { AbstractSectionKey.CustomSectionKey(name) } ?: AbstractSectionKey.InternalSectionKey() diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml deleted file mode 100644 index a6776c3..0000000 --- a/src/main/resources/config.yml +++ /dev/null @@ -1,47 +0,0 @@ -### Example config: -sections: - - name: section1 - refTop: 0, 0, 0 - # refBottom should connect to the refTop of the next section. - refBottom: 0, 16, 0 - region: - start: 0, 0, 0 - end: 1000, 256, 1000 - world: world - - name: section2 - refTop: 1000, 240, 0 - refBottom: 2000, 16, 0 - region: - start: 1000, 0, 0 - end: 2000, 256, 1000 - world: world -# The damage players will take when outside a managed section. -damageOutsideSections: 1.0 - -fall: - # The maximum safe falling distance, after which players will start taking damage. Set to -1 to disable falling damage - maxSafeDist: -1 - # The multiplier for damage taken while falling. Set to 0 to deal consistent damage. - fallDistanceDamageScaler: 0.01 - # The minimum damage to deal. - startingDamage: 1.0 - # How often to damage players in ticks - hitDelay: 10t - # Whether to spawn cloud particles when the player is being damaged. - spawnParticles: true - -time: - # How often to synchronize time between worlds - updateInterval: 1800s - # The main synchronization world. Other worlds will get synchronized based on the time in this world. - mainWorld: world - # The worlds where time should be synchronized with the mainWorld. Optionally specify a time offset (leave 0 if no offset is desired) - syncedWorlds: - world: 0 - -# Sends an additional remount packet after this delay to prevent client-side mount bugs when moving between sections. -remountPacketDelay: 40t - -# Worlds which shouldn't damage players when outside of a section. -#damageExcludedWorlds: -# - world