summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDico <dico.karssiens@gmail.com>2018-09-27 07:03:02 +0100
committerDico <dico.karssiens@gmail.com>2018-09-27 07:03:02 +0100
commit842e52bd92f0c67aa1906b899ce600ecb3b26bda (patch)
treef0e03e66ba0dfeb8d3aee58a09acd6889f5ee20e
parent307b7aee4af34e47139259db7049a85c682b7be2 (diff)
Fixes n tweaks
-rw-r--r--src/main/kotlin/io/dico/parcels2/Interactable.kt2
-rw-r--r--src/main/kotlin/io/dico/parcels2/Parcel.kt2
-rw-r--r--src/main/kotlin/io/dico/parcels2/ParcelGenerator.kt20
-rw-r--r--src/main/kotlin/io/dico/parcels2/ParcelId.kt2
-rw-r--r--src/main/kotlin/io/dico/parcels2/ParcelWorld.kt4
-rw-r--r--src/main/kotlin/io/dico/parcels2/ParcelsPlugin.kt12
-rw-r--r--src/main/kotlin/io/dico/parcels2/Privilege.kt7
-rw-r--r--src/main/kotlin/io/dico/parcels2/blockvisitor/Attachables.kt2
-rw-r--r--src/main/kotlin/io/dico/parcels2/blockvisitor/JobDispatcher.kt (renamed from src/main/kotlin/io/dico/parcels2/blockvisitor/WorkDispatcher.kt)140
-rw-r--r--src/main/kotlin/io/dico/parcels2/blockvisitor/RegionTraverser.kt49
-rw-r--r--src/main/kotlin/io/dico/parcels2/blockvisitor/Schematic.kt14
-rw-r--r--src/main/kotlin/io/dico/parcels2/command/AbstractParcelCommands.kt4
-rw-r--r--src/main/kotlin/io/dico/parcels2/command/CommandsDebug.kt4
-rw-r--r--src/main/kotlin/io/dico/parcels2/command/ParcelTarget.kt4
-rw-r--r--src/main/kotlin/io/dico/parcels2/defaultimpl/DefaultParcelGenerator.kt35
-rw-r--r--src/main/kotlin/io/dico/parcels2/defaultimpl/ParcelImpl.kt2
-rw-r--r--src/main/kotlin/io/dico/parcels2/defaultimpl/ParcelProviderImpl.kt23
-rw-r--r--src/main/kotlin/io/dico/parcels2/defaultimpl/ParcelWorldImpl.kt6
-rw-r--r--src/main/kotlin/io/dico/parcels2/listener/ParcelListeners.kt51
-rw-r--r--src/main/kotlin/io/dico/parcels2/options/Options.kt4
-rw-r--r--src/main/kotlin/io/dico/parcels2/storage/Backing.kt4
-rw-r--r--src/main/kotlin/io/dico/parcels2/storage/Storage.kt10
-rw-r--r--src/main/kotlin/io/dico/parcels2/storage/exposed/ExposedBacking.kt19
-rw-r--r--src/main/kotlin/io/dico/parcels2/storage/exposed/ListTables.kt18
-rw-r--r--src/main/kotlin/io/dico/parcels2/util/Region.kt18
-rw-r--r--src/main/kotlin/io/dico/parcels2/util/Vec2i.kt11
-rw-r--r--src/main/kotlin/io/dico/parcels2/util/ext/Misc.kt5
-rw-r--r--src/main/kotlin/io/dico/parcels2/util/math/Dimension.kt19
-rw-r--r--src/main/kotlin/io/dico/parcels2/util/math/Region.kt37
-rw-r--r--src/main/kotlin/io/dico/parcels2/util/math/Vec2i.kt6
-rw-r--r--src/main/kotlin/io/dico/parcels2/util/math/Vec3d.kt54
-rw-r--r--src/main/kotlin/io/dico/parcels2/util/math/Vec3i.kt (renamed from src/main/kotlin/io/dico/parcels2/util/Vec3i.kt)44
-rw-r--r--src/main/kotlin/io/dico/parcels2/util/math/ext/Math.kt (renamed from src/main/kotlin/io/dico/parcels2/util/ext/Math.kt)3
33 files changed, 393 insertions, 242 deletions
diff --git a/src/main/kotlin/io/dico/parcels2/Interactable.kt b/src/main/kotlin/io/dico/parcels2/Interactable.kt
index 100e433..825be94 100644
--- a/src/main/kotlin/io/dico/parcels2/Interactable.kt
+++ b/src/main/kotlin/io/dico/parcels2/Interactable.kt
@@ -1,6 +1,6 @@
package io.dico.parcels2
-import io.dico.parcels2.util.ext.ceilDiv
+import io.dico.parcels2.util.math.ext.ceilDiv
import io.dico.parcels2.util.ext.getMaterialsWithWoodTypePrefix
import org.bukkit.Material
import java.util.EnumMap
diff --git a/src/main/kotlin/io/dico/parcels2/Parcel.kt b/src/main/kotlin/io/dico/parcels2/Parcel.kt
index 22ec0df..517b88f 100644
--- a/src/main/kotlin/io/dico/parcels2/Parcel.kt
+++ b/src/main/kotlin/io/dico/parcels2/Parcel.kt
@@ -1,6 +1,6 @@
package io.dico.parcels2
-import io.dico.parcels2.util.Vec2i
+import io.dico.parcels2.util.math.Vec2i
import org.bukkit.Location
import org.joda.time.DateTime
import java.util.UUID
diff --git a/src/main/kotlin/io/dico/parcels2/ParcelGenerator.kt b/src/main/kotlin/io/dico/parcels2/ParcelGenerator.kt
index 4e0aeb4..d45ff83 100644
--- a/src/main/kotlin/io/dico/parcels2/ParcelGenerator.kt
+++ b/src/main/kotlin/io/dico/parcels2/ParcelGenerator.kt
@@ -1,9 +1,9 @@
package io.dico.parcels2
import io.dico.parcels2.blockvisitor.*
-import io.dico.parcels2.util.Region
-import io.dico.parcels2.util.Vec2i
-import io.dico.parcels2.util.get
+import io.dico.parcels2.util.math.Region
+import io.dico.parcels2.util.math.Vec2i
+import io.dico.parcels2.util.math.get
import kotlinx.coroutines.CoroutineScope
import org.bukkit.Chunk
import org.bukkit.Location
@@ -37,12 +37,12 @@ abstract class ParcelGenerator : ChunkGenerator() {
abstract fun makeParcelLocatorAndBlockManager(worldId: ParcelWorldId,
container: ParcelContainer,
coroutineScope: CoroutineScope,
- workDispatcher: WorkDispatcher): Pair<ParcelLocator, ParcelBlockManager>
+ jobDispatcher: JobDispatcher): Pair<ParcelLocator, ParcelBlockManager>
}
interface ParcelBlockManager {
val world: World
- val workDispatcher: WorkDispatcher
+ val jobDispatcher: JobDispatcher
val parcelTraverser: RegionTraverser
// fun getBottomBlock(parcel: ParcelId): Vec2i
@@ -55,13 +55,13 @@ interface ParcelBlockManager {
fun setOwnerBlock(parcel: ParcelId, owner: PlayerProfile?)
- fun setBiome(parcel: ParcelId, biome: Biome): Worker
+ fun setBiome(parcel: ParcelId, biome: Biome): Job
- fun clearParcel(parcel: ParcelId): Worker
+ fun clearParcel(parcel: ParcelId): Job
- fun swapParcels(parcel1: ParcelId, parcel2: ParcelId): Worker
+ fun swapParcels(parcel1: ParcelId, parcel2: ParcelId): Job
- fun submitBlockVisitor(vararg parcelIds: ParcelId, task: WorkerTask): Worker
+ fun submitBlockVisitor(vararg parcelIds: ParcelId, task: JobFunction): Job
/**
* Used to update owner blocks in the corner of the parcel
@@ -71,7 +71,7 @@ interface ParcelBlockManager {
inline fun ParcelBlockManager.doBlockOperation(parcel: ParcelId,
traverser: RegionTraverser,
- crossinline operation: suspend WorkerScope.(Block) -> Unit) = submitBlockVisitor(parcel) {
+ crossinline operation: suspend JobScope.(Block) -> Unit) = submitBlockVisitor(parcel) {
val region = getRegion(parcel)
val blockCount = region.blockCount.toDouble()
val blocks = traverser.traverseRegion(region)
diff --git a/src/main/kotlin/io/dico/parcels2/ParcelId.kt b/src/main/kotlin/io/dico/parcels2/ParcelId.kt
index 72eceb9..926fc23 100644
--- a/src/main/kotlin/io/dico/parcels2/ParcelId.kt
+++ b/src/main/kotlin/io/dico/parcels2/ParcelId.kt
@@ -1,6 +1,6 @@
package io.dico.parcels2
-import io.dico.parcels2.util.Vec2i
+import io.dico.parcels2.util.math.Vec2i
import org.bukkit.Bukkit
import org.bukkit.World
import java.util.UUID
diff --git a/src/main/kotlin/io/dico/parcels2/ParcelWorld.kt b/src/main/kotlin/io/dico/parcels2/ParcelWorld.kt
index 1e9dc44..87e4c68 100644
--- a/src/main/kotlin/io/dico/parcels2/ParcelWorld.kt
+++ b/src/main/kotlin/io/dico/parcels2/ParcelWorld.kt
@@ -2,8 +2,8 @@ package io.dico.parcels2
import io.dico.parcels2.options.RuntimeWorldOptions
import io.dico.parcels2.storage.Storage
-import io.dico.parcels2.util.Vec2i
-import io.dico.parcels2.util.ext.floor
+import io.dico.parcels2.util.math.Vec2i
+import io.dico.parcels2.util.math.ext.floor
import org.bukkit.Location
import org.bukkit.World
import org.bukkit.block.Block
diff --git a/src/main/kotlin/io/dico/parcels2/ParcelsPlugin.kt b/src/main/kotlin/io/dico/parcels2/ParcelsPlugin.kt
index 7af7468..b1bf554 100644
--- a/src/main/kotlin/io/dico/parcels2/ParcelsPlugin.kt
+++ b/src/main/kotlin/io/dico/parcels2/ParcelsPlugin.kt
@@ -3,8 +3,8 @@ package io.dico.parcels2
import io.dico.dicore.Registrator
import io.dico.dicore.command.EOverridePolicy
import io.dico.dicore.command.ICommandDispatcher
-import io.dico.parcels2.blockvisitor.BukkitWorkDispatcher
-import io.dico.parcels2.blockvisitor.WorkDispatcher
+import io.dico.parcels2.blockvisitor.BukkitJobDispatcher
+import io.dico.parcels2.blockvisitor.JobDispatcher
import io.dico.parcels2.command.getParcelCommands
import io.dico.parcels2.defaultimpl.GlobalPrivilegesManagerImpl
import io.dico.parcels2.defaultimpl.ParcelProviderImpl
@@ -44,7 +44,7 @@ class ParcelsPlugin : JavaPlugin(), CoroutineScope, PluginScheduler {
override val coroutineContext: CoroutineContext = MainThreadDispatcher(this)
override val plugin: Plugin get() = this
- val workDispatcher: WorkDispatcher by lazy { BukkitWorkDispatcher(this, options.tickWorktime) }
+ val jobDispatcher: JobDispatcher by lazy { BukkitJobDispatcher(this, options.tickJobtime) }
override fun onEnable() {
plogger.info("Debug enabled: ${plogger.isDebugEnabled}")
@@ -55,11 +55,11 @@ class ParcelsPlugin : JavaPlugin(), CoroutineScope, PluginScheduler {
}
override fun onDisable() {
- val hasWorkers = workDispatcher.workers.isNotEmpty()
+ val hasWorkers = jobDispatcher.jobs.isNotEmpty()
if (hasWorkers) {
- plogger.warn("Parcels is attempting to complete all ${workDispatcher.workers.size} remaining jobs before shutdown...")
+ plogger.warn("Parcels is attempting to complete all ${jobDispatcher.jobs.size} remaining jobs before shutdown...")
}
- workDispatcher.completeAllTasks()
+ jobDispatcher.completeAllTasks()
if (hasWorkers) {
plogger.info("Parcels has completed the remaining jobs.")
}
diff --git a/src/main/kotlin/io/dico/parcels2/Privilege.kt b/src/main/kotlin/io/dico/parcels2/Privilege.kt
index bc16f77..7949dbc 100644
--- a/src/main/kotlin/io/dico/parcels2/Privilege.kt
+++ b/src/main/kotlin/io/dico/parcels2/Privilege.kt
@@ -66,7 +66,7 @@ interface RawPrivileges {
open class PrivilegesHolder(override var privilegeMap: MutablePrivilegeMap = EmptyPrivilegeMap) : RawPrivileges {
private var _privilegeOfStar: Privilege = DEFAULT
- override var privilegeOfStar: Privilege
+ override /*open*/ var privilegeOfStar: Privilege
get() = _privilegeOfStar
set(value) = run { _privilegeOfStar = value }
@@ -94,5 +94,10 @@ open class PrivilegesHolder(override var privilegeMap: MutablePrivilegeMap = Emp
return if (privilege == DEFAULT) privilegeMap.remove(key) != null
else privilegeMap.put(key, privilege) != privilege
}
+
+ fun copyPrivilegesFrom(other: PrivilegesHolder) {
+ privilegeMap = other.privilegeMap
+ privilegeOfStar = other.privilegeOfStar
+ }
}
diff --git a/src/main/kotlin/io/dico/parcels2/blockvisitor/Attachables.kt b/src/main/kotlin/io/dico/parcels2/blockvisitor/Attachables.kt
index f5b7ad8..8f2c565 100644
--- a/src/main/kotlin/io/dico/parcels2/blockvisitor/Attachables.kt
+++ b/src/main/kotlin/io/dico/parcels2/blockvisitor/Attachables.kt
@@ -1,6 +1,6 @@
package io.dico.parcels2.blockvisitor
-import io.dico.parcels2.util.Vec3i
+import io.dico.parcels2.util.math.Vec3i
import io.dico.parcels2.util.ext.getMaterialsWithWoodTypePrefix
import io.dico.parcels2.util.ext.getMaterialsWithWoolColorPrefix
import org.bukkit.Material
diff --git a/src/main/kotlin/io/dico/parcels2/blockvisitor/WorkDispatcher.kt b/src/main/kotlin/io/dico/parcels2/blockvisitor/JobDispatcher.kt
index 7162561..702a680 100644
--- a/src/main/kotlin/io/dico/parcels2/blockvisitor/WorkDispatcher.kt
+++ b/src/main/kotlin/io/dico/parcels2/blockvisitor/JobDispatcher.kt
@@ -2,11 +2,11 @@ package io.dico.parcels2.blockvisitor
import io.dico.parcels2.ParcelsPlugin
import io.dico.parcels2.logger
-import io.dico.parcels2.util.ext.clampMin
+import io.dico.parcels2.util.math.ext.clampMin
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineStart.LAZY
-import kotlinx.coroutines.Job
+import kotlinx.coroutines.Job as CoroutineJob
import kotlinx.coroutines.launch
import org.bukkit.scheduler.BukkitTask
import java.lang.System.currentTimeMillis
@@ -16,21 +16,21 @@ import kotlin.coroutines.intrinsics.COROUTINE_SUSPENDED
import kotlin.coroutines.intrinsics.suspendCoroutineUninterceptedOrReturn
import kotlin.coroutines.resume
-typealias WorkerTask = suspend WorkerScope.() -> Unit
-typealias WorkerUpdateLister = Worker.(Double, Long) -> Unit
+typealias JobFunction = suspend JobScope.() -> Unit
+typealias JobUpdateLister = Job.(Double, Long) -> Unit
-data class TickWorktimeOptions(var workTime: Int, var tickInterval: Int)
+data class TickJobtimeOptions(var jobTime: Int, var tickInterval: Int)
-interface WorkDispatcher {
+interface JobDispatcher {
/**
* Submit a [task] that should be run synchronously, but limited such that it does not stall the server
*/
- fun dispatch(task: WorkerTask): Worker
+ fun dispatch(task: JobFunction): Job
/**
- * Get a list of all workers
+ * Get a list of all jobs
*/
- val workers: List<Worker>
+ val jobs: List<Job>
/**
* Attempts to complete any remaining tasks immediately, without suspension.
@@ -38,27 +38,27 @@ interface WorkDispatcher {
fun completeAllTasks()
}
-interface WorkerAndScopeMembersUnion {
+interface JobAndScopeMembersUnion {
/**
- * The time that elapsed since this worker was dispatched, in milliseconds
+ * The time that elapsed since this job was dispatched, in milliseconds
*/
val elapsedTime: Long
/**
- * A value indicating the progress of this worker, in the range 0.0 <= progress <= 1.0
+ * A value indicating the progress of this job, in the range 0.0 <= progress <= 1.0
* with no guarantees to its accuracy.
*/
val progress: Double
}
-interface Worker : WorkerAndScopeMembersUnion {
+interface Job : JobAndScopeMembersUnion {
/**
- * The coroutine associated with this worker
+ * The coroutine associated with this job
*/
- val job: Job
+ val job: CoroutineJob
/**
- * true if this worker has completed
+ * true if this job has completed
*/
val isComplete: Boolean
@@ -69,28 +69,28 @@ interface Worker : WorkerAndScopeMembersUnion {
val completionException: Throwable?
/**
- * Calls the given [block] whenever the progress of this worker is updated,
+ * Calls the given [block] whenever the progress of this job is updated,
* if [minInterval] milliseconds expired since the last call.
* The first call occurs after at least [minDelay] milliseconds in a likewise manner.
* Repeated invocations of this method result in an [IllegalStateException]
*
* if [asCompletionListener] is true, [onCompleted] is called with the same [block]
*/
- fun onProgressUpdate(minDelay: Int, minInterval: Int, asCompletionListener: Boolean = true, block: WorkerUpdateLister): Worker
+ fun onProgressUpdate(minDelay: Int, minInterval: Int, asCompletionListener: Boolean = true, block: JobUpdateLister): Job
/**
- * Calls the given [block] when this worker completes, with the progress value 1.0.
+ * Calls the given [block] when this job completes, with the progress value 1.0.
* Multiple listeners may be registered to this function.
*/
- fun onCompleted(block: WorkerUpdateLister): Worker
+ fun onCompleted(block: JobUpdateLister): Job
/**
- * Await completion of this worker
+ * Await completion of this job
*/
suspend fun awaitCompletion()
}
-interface WorkerScope : WorkerAndScopeMembersUnion {
+interface JobScope : JobAndScopeMembersUnion {
/**
* A task should call this frequently during its execution, such that the timer can suspend it when necessary.
*/
@@ -107,29 +107,29 @@ interface WorkerScope : WorkerAndScopeMembersUnion {
fun markComplete() = setProgress(1.0)
/**
- * Get a [WorkerScope] that is responsible for [portion] part of the progress
+ * Get a [JobScope] that is responsible for [portion] part of the progress
* If [portion] is negative, the remaining progress is used
*/
- fun delegateWork(portion: Double = -1.0): WorkerScope
+ fun delegateProgress(portion: Double = -1.0): JobScope
}
-inline fun <T> WorkerScope.delegateWork(portion: Double = -1.0, block: WorkerScope.() -> T): T {
- delegateWork(portion).apply {
+inline fun <T> JobScope.delegateWork(portion: Double = -1.0, block: JobScope.() -> T): T {
+ delegateProgress(portion).apply {
val result = block()
markComplete()
return result
}
}
-interface WorkerInternal : Worker, WorkerScope {
+interface JobInternal : Job, JobScope {
/**
- * Start or resumes the execution of this worker
- * and returns true if the worker completed
+ * Start or resumes the execution of this job
+ * and returns true if the job completed
*
* [worktime] is the maximum amount of time, in milliseconds,
* that this job may run for until suspension.
*
- * If [worktime] is not positive, the worker will complete
+ * If [worktime] is not positive, the job will complete
* without suspension and this method will always return true.
*/
fun resume(worktime: Long): Boolean
@@ -137,68 +137,68 @@ interface WorkerInternal : Worker, WorkerScope {
/**
* An object that controls one or more jobs, ensuring that they don't stall the server too much.
- * There is a configurable maxiumum amount of milliseconds that can be allocated to all workers together in each server tick
+ * There is a configurable maxiumum amount of milliseconds that can be allocated to all jobs together in each server tick
* This object attempts to split that maximum amount of milliseconds equally between all jobs
*/
-class BukkitWorkDispatcher(private val plugin: ParcelsPlugin, var options: TickWorktimeOptions) : WorkDispatcher {
+class BukkitJobDispatcher(private val plugin: ParcelsPlugin, var options: TickJobtimeOptions) : JobDispatcher {
// The currently registered bukkit scheduler task
private var bukkitTask: BukkitTask? = null
- // The workers.
- private val _workers = LinkedList<WorkerInternal>()
- override val workers: List<Worker> = _workers
+ // The jobs.
+ private val _jobs = LinkedList<JobInternal>()
+ override val jobs: List<Job> = _jobs
- override fun dispatch(task: WorkerTask): Worker {
- val worker: WorkerInternal = WorkerImpl(plugin, task)
+ override fun dispatch(task: JobFunction): Job {
+ val job: JobInternal = JobImpl(plugin, task)
if (bukkitTask == null) {
- val completed = worker.resume(options.workTime.toLong())
- if (completed) return worker
- bukkitTask = plugin.scheduleRepeating(0, options.tickInterval) { tickJobs() }
+ val completed = job.resume(options.jobTime.toLong())
+ if (completed) return job
+ bukkitTask = plugin.scheduleRepeating(0, options.tickInterval) { tickCoroutineJobs() }
}
- _workers.addFirst(worker)
- return worker
+ _jobs.addFirst(job)
+ return job
}
- private fun tickJobs() {
- val workers = _workers
- if (workers.isEmpty()) return
+ private fun tickCoroutineJobs() {
+ val jobs = _jobs
+ if (jobs.isEmpty()) return
val tickStartTime = System.currentTimeMillis()
- val iterator = workers.listIterator(index = 0)
+ val iterator = jobs.listIterator(index = 0)
while (iterator.hasNext()) {
val time = System.currentTimeMillis()
val timeElapsed = time - tickStartTime
- val timeLeft = options.workTime - timeElapsed
+ val timeLeft = options.jobTime - timeElapsed
if (timeLeft <= 0) return
- val count = workers.size - iterator.nextIndex()
+ val count = jobs.size - iterator.nextIndex()
val timePerJob = (timeLeft + count - 1) / count
- val worker = iterator.next()
- val completed = worker.resume(timePerJob)
+ val job = iterator.next()
+ val completed = job.resume(timePerJob)
if (completed) {
iterator.remove()
}
}
- if (workers.isEmpty()) {
+ if (jobs.isEmpty()) {
bukkitTask?.cancel()
bukkitTask = null
}
}
override fun completeAllTasks() {
- _workers.forEach {
+ _jobs.forEach {
it.resume(-1)
}
- _workers.clear()
+ _jobs.clear()
bukkitTask?.cancel()
bukkitTask = null
}
}
-private class WorkerImpl(scope: CoroutineScope, task: WorkerTask) : WorkerInternal {
- override val job: Job = scope.launch(start = LAZY) { task() }
+private class JobImpl(scope: CoroutineScope, task: JobFunction) : JobInternal {
+ override val job: CoroutineJob = scope.launch(start = LAZY) { task() }
private var continuation: Continuation<Unit>? = null
private var nextSuspensionTime: Long = 0L
@@ -217,17 +217,17 @@ private class WorkerImpl(scope: CoroutineScope, task: WorkerTask) : WorkerIntern
override var completionException: Throwable? = null; private set
private var startTimeOrElapsedTime: Long = 0L // startTime before completed, elapsed time otherwise
- private var onProgressUpdate: WorkerUpdateLister? = null
+ private var onProgressUpdate: JobUpdateLister? = null
private var progressUpdateInterval: Int = 0
private var lastUpdateTime: Long = 0L
- private var onCompleted: WorkerUpdateLister? = null
+ private var onCompleted: JobUpdateLister? = null
init {
job.invokeOnCompletion { exception ->
// report any error that occurred
completionException = exception?.also {
if (it !is CancellationException)
- logger.error("WorkerTask generated an exception", it)
+ logger.error("JobFunction generated an exception", it)
}
// convert to elapsed time here
@@ -239,7 +239,7 @@ private class WorkerImpl(scope: CoroutineScope, task: WorkerTask) : WorkerIntern
}
}
- override fun onProgressUpdate(minDelay: Int, minInterval: Int, asCompletionListener: Boolean, block: WorkerUpdateLister): Worker {
+ override fun onProgressUpdate(minDelay: Int, minInterval: Int, asCompletionListener: Boolean, block: JobUpdateLister): Job {
onProgressUpdate?.let { throw IllegalStateException() }
if (asCompletionListener) onCompleted(block)
if (isComplete) return this
@@ -250,7 +250,7 @@ private class WorkerImpl(scope: CoroutineScope, task: WorkerTask) : WorkerIntern
return this
}
- override fun onCompleted(block: WorkerUpdateLister): Worker {
+ override fun onCompleted(block: JobUpdateLister): Job {
if (isComplete) {
block(1.0, startTimeOrElapsedTime)
return this
@@ -260,7 +260,7 @@ private class WorkerImpl(scope: CoroutineScope, task: WorkerTask) : WorkerIntern
onCompleted = if (cur == null) {
block
} else {
- fun Worker.(prog: Double, el: Long) {
+ fun Job.(prog: Double, el: Long) {
cur(prog, el)
block(prog, el)
}
@@ -315,25 +315,25 @@ private class WorkerImpl(scope: CoroutineScope, task: WorkerTask) : WorkerIntern
job.join()
}
- private fun delegateWork(curPortion: Double, portion: Double): WorkerScope =
+ private fun delegateProgress(curPortion: Double, portion: Double): JobScope =
DelegateScope(progress, curPortion * (if (portion < 0) 1.0 - progress else portion).clampMin(0.0))
- override fun delegateWork(portion: Double): WorkerScope = delegateWork(1.0, portion)
+ override fun delegateProgress(portion: Double): JobScope = delegateProgress(1.0, portion)
- private inner class DelegateScope(val progressStart: Double, val portion: Double) : WorkerScope {
+ private inner class DelegateScope(val progressStart: Double, val portion: Double) : JobScope {
override val elapsedTime: Long
- get() = this@WorkerImpl.elapsedTime
+ get() = this@JobImpl.elapsedTime
override suspend fun markSuspensionPoint() =
- this@WorkerImpl.markSuspensionPoint()
+ this@JobImpl.markSuspensionPoint()
override val progress: Double
- get() = (this@WorkerImpl.progress - progressStart) / portion
+ get() = (this@JobImpl.progress - progressStart) / portion
override fun setProgress(progress: Double) =
- this@WorkerImpl.setProgress(progressStart + progress * portion)
+ this@JobImpl.setProgress(progressStart + progress * portion)
- override fun delegateWork(portion: Double): WorkerScope =
- this@WorkerImpl.delegateWork(this.portion, portion)
+ override fun delegateProgress(portion: Double): JobScope =
+ this@JobImpl.delegateProgress(this.portion, portion)
}
}
diff --git a/src/main/kotlin/io/dico/parcels2/blockvisitor/RegionTraverser.kt b/src/main/kotlin/io/dico/parcels2/blockvisitor/RegionTraverser.kt
index feab318..bd00407 100644
--- a/src/main/kotlin/io/dico/parcels2/blockvisitor/RegionTraverser.kt
+++ b/src/main/kotlin/io/dico/parcels2/blockvisitor/RegionTraverser.kt
@@ -1,8 +1,9 @@
package io.dico.parcels2.blockvisitor
-import io.dico.parcels2.util.Region
-import io.dico.parcels2.util.Vec3i
-import io.dico.parcels2.util.ext.clampMax
+import io.dico.parcels2.util.math.Dimension
+import io.dico.parcels2.util.math.Region
+import io.dico.parcels2.util.math.Vec3i
+import io.dico.parcels2.util.math.ext.clampMax
private typealias Scope = SequenceScope<Vec3i>
@@ -54,9 +55,9 @@ sealed class RegionTraverser {
val (primary, secondary, tertiary) = order.toArray()
val (origin, size) = region
- val maxOfPrimary = primary.extract(size) - 1
- val maxOfSecondary = secondary.extract(size) - 1
- val maxOfTertiary = tertiary.extract(size) - 1
+ val maxOfPrimary = size[primary] - 1
+ val maxOfSecondary = size[secondary] - 1
+ val maxOfTertiary = size[tertiary] - 1
val isPrimaryIncreasing = direction.isIncreasing(primary)
val isSecondaryIncreasing = direction.isIncreasing(secondary)
@@ -137,24 +138,6 @@ sealed class RegionTraverser {
}
-enum class Dimension {
- X,
- Y,
- Z;
-
- fun extract(block: Vec3i) =
- when (this) {
- X -> block.x
- Y -> block.y
- Z -> block.z
- }
-
- companion object {
- private val values = values()
- operator fun get(ordinal: Int) = values[ordinal]
- }
-}
-
object TraverseOrderFactory {
private fun isSwap(primary: Dimension, secondary: Dimension) = secondary.ordinal != (primary.ordinal + 1) % 3
@@ -194,15 +177,15 @@ inline class TraverseOrder(val orderNum: Int) {
*/
fun toArray() = arrayOf(primary, secondary, tertiary)
- fun add(vec: Vec3i, dp: Int, ds: Int, dt: Int): Vec3i =
+ fun add(vec: Vec3i, p: Int, s: Int, t: Int): Vec3i =
// optimize this, will be called lots
when (orderNum) {
- 0 -> vec.add(dp, ds, dt) // xyz
- 1 -> vec.add(dt, dp, ds) // yzx
- 2 -> vec.add(ds, dt, dp) // zxy
- 3 -> vec.add(dp, dt, ds) // xzy
- 4 -> vec.add(ds, dp, dt) // yxz
- 5 -> vec.add(dt, ds, dp) // zyx
+ 0 -> vec.add(p, s, t) // xyz
+ 1 -> vec.add(t, p, s) // yzx
+ 2 -> vec.add(s, t, p) // zxy
+ 3 -> vec.add(p, t, s) // xzy
+ 4 -> vec.add(s, p, t) // yxz
+ 5 -> vec.add(t, s, p) // zyx
else -> error("Invalid orderNum $orderNum")
}
}
@@ -212,9 +195,9 @@ inline class TraverseDirection(val bits: Int) {
fun comesFirst(current: Vec3i, block: Vec3i, dimension: Dimension): Boolean =
if (isIncreasing(dimension))
- dimension.extract(block) <= dimension.extract(current)
+ block[dimension] <= current[dimension]
else
- dimension.extract(block) >= dimension.extract(current)
+ block[dimension] >= current[dimension]
fun comesFirst(current: Vec3i, block: Vec3i) =
comesFirst(current, block, Dimension.X)
diff --git a/src/main/kotlin/io/dico/parcels2/blockvisitor/Schematic.kt b/src/main/kotlin/io/dico/parcels2/blockvisitor/Schematic.kt
index 9f88fd9..84931b2 100644
--- a/src/main/kotlin/io/dico/parcels2/blockvisitor/Schematic.kt
+++ b/src/main/kotlin/io/dico/parcels2/blockvisitor/Schematic.kt
@@ -1,8 +1,8 @@
package io.dico.parcels2.blockvisitor
-import io.dico.parcels2.util.Region
-import io.dico.parcels2.util.Vec3i
-import io.dico.parcels2.util.get
+import io.dico.parcels2.util.math.Region
+import io.dico.parcels2.util.math.Vec3i
+import io.dico.parcels2.util.math.get
import org.bukkit.Bukkit
import org.bukkit.Material
import org.bukkit.World
@@ -24,7 +24,7 @@ class Schematic {
private var isLoaded = false; private set
private val traverser: RegionTraverser = RegionTraverser.upward
- suspend fun WorkerScope.load(world: World, region: Region) {
+ suspend fun JobScope.load(world: World, region: Region) {
_size = region.size
val data = arrayOfNulls<BlockData>(region.blockCount).also { blockDatas = it }
@@ -52,7 +52,7 @@ class Schematic {
isLoaded = true
}
- suspend fun WorkerScope.paste(world: World, position: Vec3i) {
+ suspend fun JobScope.paste(world: World, position: Vec3i) {
if (!isLoaded) throw IllegalStateException()
val region = Region(position, _size!!)
@@ -108,11 +108,11 @@ class Schematic {
}
}
- fun getLoadTask(world: World, region: Region): WorkerTask = {
+ fun getLoadTask(world: World, region: Region): JobFunction = {
load(world, region)
}
- fun getPasteTask(world: World, position: Vec3i): WorkerTask = {
+ fun getPasteTask(world: World, position: Vec3i): JobFunction = {
paste(world, position)
}
diff --git a/src/main/kotlin/io/dico/parcels2/command/AbstractParcelCommands.kt b/src/main/kotlin/io/dico/parcels2/command/AbstractParcelCommands.kt
index 79faf36..41f5d36 100644
--- a/src/main/kotlin/io/dico/parcels2/command/AbstractParcelCommands.kt
+++ b/src/main/kotlin/io/dico/parcels2/command/AbstractParcelCommands.kt
@@ -6,7 +6,7 @@ import io.dico.parcels2.ParcelsPlugin
import io.dico.parcels2.PlayerProfile
import io.dico.parcels2.PlayerProfile.*
import io.dico.parcels2.PrivilegeKey
-import io.dico.parcels2.blockvisitor.Worker
+import io.dico.parcels2.blockvisitor.Job
import io.dico.parcels2.util.ext.hasPermAdminManage
import io.dico.parcels2.util.ext.parcelLimit
import org.bukkit.entity.Player
@@ -50,7 +50,7 @@ abstract class AbstractParcelCommands(val plugin: ParcelsPlugin) : ICommandRecei
world.blockManager.clearParcel(parcel.id)
}
- protected fun Worker.reportProgressUpdates(context: ExecutionContext, action: String) {
+ protected fun Job.reportProgressUpdates(context: ExecutionContext, action: String) {
onProgressUpdate(1000, 1000) { progress, elapsedTime ->
val alt = context.getFormat(EMessageType.NUMBER)
val main = context.getFormat(EMessageType.INFORMATIVE)
diff --git a/src/main/kotlin/io/dico/parcels2/command/CommandsDebug.kt b/src/main/kotlin/io/dico/parcels2/command/CommandsDebug.kt
index 6331b4c..c6a4d6a 100644
--- a/src/main/kotlin/io/dico/parcels2/command/CommandsDebug.kt
+++ b/src/main/kotlin/io/dico/parcels2/command/CommandsDebug.kt
@@ -81,14 +81,14 @@ class CommandsDebug(plugin: ParcelsPlugin) : AbstractParcelCommands(plugin) {
@Cmd("jobs")
fun cmdJobs(): Any? {
- val workers = plugin.workDispatcher.workers
+ val workers = plugin.jobDispatcher.jobs
println(workers.map { it.job }.joinToString(separator = "\n"))
return "Task count: ${workers.size}"
}
@Cmd("complete_jobs")
fun cmdCompleteJobs(): Any? = cmdJobs().also {
- plugin.launch { plugin.workDispatcher.completeAllTasks() }
+ plugin.launch { plugin.jobDispatcher.completeAllTasks() }
}
@Cmd("message")
diff --git a/src/main/kotlin/io/dico/parcels2/command/ParcelTarget.kt b/src/main/kotlin/io/dico/parcels2/command/ParcelTarget.kt
index 2852ff0..05a10bd 100644
--- a/src/main/kotlin/io/dico/parcels2/command/ParcelTarget.kt
+++ b/src/main/kotlin/io/dico/parcels2/command/ParcelTarget.kt
@@ -16,8 +16,8 @@ import io.dico.parcels2.command.ParcelTarget.TargetKind.Companion.OWNER_REAL
import io.dico.parcels2.command.ParcelTarget.TargetKind.Companion.PREFER_OWNED_FOR_DEFAULT
import io.dico.parcels2.command.ParcelTarget.TargetKind.Companion.REAL
import io.dico.parcels2.storage.Storage
-import io.dico.parcels2.util.Vec2i
-import io.dico.parcels2.util.ext.floor
+import io.dico.parcels2.util.math.Vec2i
+import io.dico.parcels2.util.math.ext.floor
import org.bukkit.command.CommandSender
import org.bukkit.entity.Player
diff --git a/src/main/kotlin/io/dico/parcels2/defaultimpl/DefaultParcelGenerator.kt b/src/main/kotlin/io/dico/parcels2/defaultimpl/DefaultParcelGenerator.kt
index 7ccb458..25d76e3 100644
--- a/src/main/kotlin/io/dico/parcels2/defaultimpl/DefaultParcelGenerator.kt
+++ b/src/main/kotlin/io/dico/parcels2/defaultimpl/DefaultParcelGenerator.kt
@@ -3,12 +3,12 @@ package io.dico.parcels2.defaultimpl
import io.dico.parcels2.*
import io.dico.parcels2.blockvisitor.*
import io.dico.parcels2.options.DefaultGeneratorOptions
-import io.dico.parcels2.util.Region
-import io.dico.parcels2.util.Vec2i
-import io.dico.parcels2.util.Vec3i
-import io.dico.parcels2.util.ext.even
-import io.dico.parcels2.util.ext.umod
-import io.dico.parcels2.util.get
+import io.dico.parcels2.util.math.Region
+import io.dico.parcels2.util.math.Vec2i
+import io.dico.parcels2.util.math.Vec3i
+import io.dico.parcels2.util.math.ext.even
+import io.dico.parcels2.util.math.ext.umod
+import io.dico.parcels2.util.math.get
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineStart.UNDISPATCHED
import kotlinx.coroutines.launch
@@ -121,9 +121,9 @@ class DefaultParcelGenerator(
worldId: ParcelWorldId,
container: ParcelContainer,
coroutineScope: CoroutineScope,
- workDispatcher: WorkDispatcher
+ jobDispatcher: JobDispatcher
): Pair<ParcelLocator, ParcelBlockManager> {
- return ParcelLocatorImpl(worldId, container) to ParcelBlockManagerImpl(worldId, coroutineScope, workDispatcher)
+ return ParcelLocatorImpl(worldId, container) to ParcelBlockManagerImpl(worldId, coroutineScope, jobDispatcher)
}
private inline fun <T> convertBlockLocationToId(x: Int, z: Int, mapper: (Int, Int) -> T): T? {
@@ -158,7 +158,7 @@ class DefaultParcelGenerator(
private inner class ParcelBlockManagerImpl(
val worldId: ParcelWorldId,
coroutineScope: CoroutineScope,
- override val workDispatcher: WorkDispatcher
+ override val jobDispatcher: JobDispatcher
) : ParcelBlockManagerBase(), CoroutineScope by coroutineScope {
override val world: World = this@DefaultParcelGenerator.world
override val parcelTraverser: RegionTraverser = RegionTraverser.convergingTo(o.floorHeight)
@@ -177,7 +177,10 @@ class DefaultParcelGenerator(
override fun getRegion(parcel: ParcelId): Region {
val bottom = getBottomBlock(parcel)
- return Region(Vec3i(bottom.x, 0, bottom.z), Vec3i(o.parcelSize, maxHeight, o.parcelSize))
+ return Region(
+ Vec3i(bottom.x, 0, bottom.z),
+ Vec3i(o.parcelSize, maxHeight, o.parcelSize)
+ )
}
private fun getRegionConsideringWorld(parcel: ParcelId): Region {
@@ -234,12 +237,12 @@ class DefaultParcelGenerator(
return world.getParcelById(parcelId)
}
- override fun submitBlockVisitor(vararg parcelIds: ParcelId, task: WorkerTask): Worker {
+ override fun submitBlockVisitor(vararg parcelIds: ParcelId, task: JobFunction): Job {
val parcels = parcelIds.mapNotNull { getParcel(it) }
- if (parcels.isEmpty()) return workDispatcher.dispatch(task)
+ if (parcels.isEmpty()) return jobDispatcher.dispatch(task)
if (parcels.any { it.hasBlockVisitors }) throw IllegalArgumentException("This parcel already has a block visitor")
- val worker = workDispatcher.dispatch(task)
+ val worker = jobDispatcher.dispatch(task)
for (parcel in parcels) {
launch(start = UNDISPATCHED) {
@@ -252,7 +255,7 @@ class DefaultParcelGenerator(
return worker
}
- override fun setBiome(parcel: ParcelId, biome: Biome): Worker = submitBlockVisitor(parcel) {
+ override fun setBiome(parcel: ParcelId, biome: Biome): Job = submitBlockVisitor(parcel) {
val world = world
val b = getBottomBlock(parcel)
val parcelSize = o.parcelSize
@@ -264,7 +267,7 @@ class DefaultParcelGenerator(
}
}
- override fun clearParcel(parcel: ParcelId): Worker = submitBlockVisitor(parcel) {
+ override fun clearParcel(parcel: ParcelId): Job = submitBlockVisitor(parcel) {
val region = getRegion(parcel)
val blocks = parcelTraverser.traverseRegion(region)
val blockCount = region.blockCount.toDouble()
@@ -288,7 +291,7 @@ class DefaultParcelGenerator(
}
}
- override fun swapParcels(parcel1: ParcelId, parcel2: ParcelId): Worker = submitBlockVisitor(parcel1, parcel2) {
+ override fun swapParcels(parcel1: ParcelId, parcel2: ParcelId): Job = submitBlockVisitor(parcel1, parcel2) {
var region1 = getRegionConsideringWorld(parcel1)
var region2 = getRegionConsideringWorld(parcel2)
diff --git a/src/main/kotlin/io/dico/parcels2/defaultimpl/ParcelImpl.kt b/src/main/kotlin/io/dico/parcels2/defaultimpl/ParcelImpl.kt
index 243ec19..65378bf 100644
--- a/src/main/kotlin/io/dico/parcels2/defaultimpl/ParcelImpl.kt
+++ b/src/main/kotlin/io/dico/parcels2/defaultimpl/ParcelImpl.kt
@@ -3,7 +3,7 @@ package io.dico.parcels2.defaultimpl
import io.dico.dicore.Formatting
import io.dico.parcels2.*
import io.dico.parcels2.Privilege.*
-import io.dico.parcels2.util.Vec2i
+import io.dico.parcels2.util.math.Vec2i
import io.dico.parcels2.util.ext.alsoIfTrue
import org.bukkit.Material
import org.joda.time.DateTime
diff --git a/src/main/kotlin/io/dico/parcels2/defaultimpl/ParcelProviderImpl.kt b/src/main/kotlin/io/dico/parcels2/defaultimpl/ParcelProviderImpl.kt
index ff2fcd4..1edf849 100644
--- a/src/main/kotlin/io/dico/parcels2/defaultimpl/ParcelProviderImpl.kt
+++ b/src/main/kotlin/io/dico/parcels2/defaultimpl/ParcelProviderImpl.kt
@@ -58,8 +58,10 @@ class ParcelProviderImpl(val plugin: ParcelsPlugin) : ParcelProvider {
if (worldExists) Bukkit.getWorld(worldName)!!
else WorldCreator(worldName).generator(generator).createWorld().also { logger.info("Creating world $worldName") }
- parcelWorld = ParcelWorldImpl(bukkitWorld, generator, worldOptions.runtime, plugin.storage,
- plugin.globalPrivileges, ::DefaultParcelContainer, plugin, plugin.workDispatcher)
+ parcelWorld = ParcelWorldImpl(
+ bukkitWorld, generator, worldOptions.runtime, plugin.storage,
+ plugin.globalPrivileges, ::DefaultParcelContainer, plugin, plugin.jobDispatcher
+ )
if (!worldExists) {
val time = DateTime.now()
@@ -95,11 +97,18 @@ class ParcelProviderImpl(val plugin: ParcelsPlugin) : ParcelProvider {
logger.info("Loading all parcel data...")
val channel = plugin.storage.transmitAllParcelData()
- do {
- val pair = channel.receiveOrNull() ?: break
- val parcel = getParcelById(pair.first) ?: continue
- pair.second?.let { parcel.copyDataIgnoringDatabase(it) }
- } while (true)
+ while (true) {
+ val (id, data) = channel.receiveOrNull() ?: break
+ val parcel = getParcelById(id) ?: continue
+ data?.let { parcel.copyDataIgnoringDatabase(it) }
+ }
+
+ val channel2 = plugin.storage.transmitAllGlobalPrivileges()
+ while (true) {
+ val (profile, data) = channel2.receiveOrNull() ?: break
+ val key = profile as? PrivilegeKey ?: continue
+ (plugin.globalPrivileges[key] as PrivilegesHolder).copyPrivilegesFrom(data)
+ }
logger.info("Loading data completed")
_dataIsLoaded = true
diff --git a/src/main/kotlin/io/dico/parcels2/defaultimpl/ParcelWorldImpl.kt b/src/main/kotlin/io/dico/parcels2/defaultimpl/ParcelWorldImpl.kt
index 24bad79..78257c3 100644
--- a/src/main/kotlin/io/dico/parcels2/defaultimpl/ParcelWorldImpl.kt
+++ b/src/main/kotlin/io/dico/parcels2/defaultimpl/ParcelWorldImpl.kt
@@ -3,7 +3,7 @@
package io.dico.parcels2.defaultimpl
import io.dico.parcels2.*
-import io.dico.parcels2.blockvisitor.WorkDispatcher
+import io.dico.parcels2.blockvisitor.JobDispatcher
import io.dico.parcels2.options.RuntimeWorldOptions
import io.dico.parcels2.storage.Storage
import kotlinx.coroutines.CoroutineScope
@@ -18,7 +18,7 @@ class ParcelWorldImpl(override val world: World,
override val globalPrivileges: GlobalPrivilegesManager,
containerFactory: ParcelContainerFactory,
coroutineScope: CoroutineScope,
- workDispatcher: WorkDispatcher)
+ jobDispatcher: JobDispatcher)
: ParcelWorld,
ParcelWorldId,
ParcelContainer, /* missing delegation */
@@ -39,7 +39,7 @@ class ParcelWorldImpl(override val world: World,
override val blockManager: ParcelBlockManager
init {
- val pair = generator.makeParcelLocatorAndBlockManager(id, container, coroutineScope, workDispatcher)
+ val pair = generator.makeParcelLocatorAndBlockManager(id, container, coroutineScope, jobDispatcher)
locator = pair.first
blockManager = pair.second
diff --git a/src/main/kotlin/io/dico/parcels2/listener/ParcelListeners.kt b/src/main/kotlin/io/dico/parcels2/listener/ParcelListeners.kt
index a62f569..ff96536 100644
--- a/src/main/kotlin/io/dico/parcels2/listener/ParcelListeners.kt
+++ b/src/main/kotlin/io/dico/parcels2/listener/ParcelListeners.kt
@@ -7,6 +7,12 @@ import io.dico.dicore.RegistratorListener
import io.dico.parcels2.*
import io.dico.parcels2.storage.Storage
import io.dico.parcels2.util.ext.*
+import io.dico.parcels2.util.math.Dimension
+import io.dico.parcels2.util.math.Vec3d
+import io.dico.parcels2.util.math.Vec3i
+import io.dico.parcels2.util.math.ext.clampMax
+import io.dico.parcels2.util.math.ext.clampMin
+import org.bukkit.Location
import org.bukkit.Material.*
import org.bukkit.World
import org.bukkit.block.Biome
@@ -52,6 +58,7 @@ class ParcelListeners(
return world to world.getParcelAt(block)
}
+
/*
* Prevents players from entering plots they are banned from
*/
@@ -59,12 +66,36 @@ class ParcelListeners(
val onPlayerMoveEvent = RegistratorListener<PlayerMoveEvent> l@{ event ->
val user = event.player
if (user.hasPermBanBypass) return@l
- val parcel = parcelProvider.getParcelAt(event.to) ?: return@l
+ val toLoc = event.to
+ val parcel = parcelProvider.getParcelAt(toLoc) ?: return@l
+
if (!parcel.canEnterFast(user)) {
- parcelProvider.getParcelAt(event.from)?.also {
- user.teleport(it.homeLocation)
+ val region = parcel.world.blockManager.getRegion(parcel.id)
+ val dimension = region.getFirstUncontainedDimensionOf(Vec3i(event.from))
+
+ if (dimension == null) {
+ user.teleport(parcel.homeLocation)
user.sendParcelMessage(nopermit = true, message = "You are banned from this parcel")
- } ?: run { event.to = event.from }
+
+ } else {
+ val speed = getPlayerSpeed(user)
+ val from = Vec3d(event.from)
+ val to = Vec3d(toLoc).with(dimension, from[dimension])
+
+ var newTo = to
+ dimension.otherDimensions.forEach {
+ val delta = to[it] - from[it]
+ newTo = newTo.add(it, delta * 100 * if (it == Dimension.Y) 0.5 else speed)
+ }
+
+
+
+ event.to = Location(
+ toLoc.world,
+ newTo.x, newTo.y.clampMin(0.0).clampMax(255.0), newTo.z,
+ toLoc.yaw, toLoc.pitch
+ )
+ }
}
}
@@ -607,4 +638,16 @@ class ParcelListeners(
}
}
+
+ private fun getPlayerSpeed(player: Player): Double =
+ if (player.isFlying) {
+ player.flySpeed * if (player.isSprinting) 21.6 else 10.92
+ } else {
+ player.walkSpeed * when {
+ player.isSprinting -> 5.612
+ player.isSneaking -> 1.31
+ else -> 4.317
+ } / 1.5 //?
+ } / 20.0
+
} \ No newline at end of file
diff --git a/src/main/kotlin/io/dico/parcels2/options/Options.kt b/src/main/kotlin/io/dico/parcels2/options/Options.kt
index 79dbb46..dc80db9 100644
--- a/src/main/kotlin/io/dico/parcels2/options/Options.kt
+++ b/src/main/kotlin/io/dico/parcels2/options/Options.kt
@@ -1,6 +1,6 @@
package io.dico.parcels2.options
-import io.dico.parcels2.blockvisitor.TickWorktimeOptions
+import io.dico.parcels2.blockvisitor.TickJobtimeOptions
import org.bukkit.GameMode
import org.bukkit.Material
import java.io.Reader
@@ -11,7 +11,7 @@ class Options {
var worlds: Map<String, WorldOptions> = hashMapOf()
private set
var storage: StorageOptions = StorageOptions()
- var tickWorktime: TickWorktimeOptions = TickWorktimeOptions(20, 1)
+ var tickJobtime: TickJobtimeOptions = TickJobtimeOptions(20, 1)
var migration = MigrationOptionsHolder()
fun addWorld(name: String,
diff --git a/src/main/kotlin/io/dico/parcels2/storage/Backing.kt b/src/main/kotlin/io/dico/parcels2/storage/Backing.kt
index 6f71471..2e0a8ee 100644
--- a/src/main/kotlin/io/dico/parcels2/storage/Backing.kt
+++ b/src/main/kotlin/io/dico/parcels2/storage/Backing.kt
@@ -61,9 +61,9 @@ interface Backing {
fun setParcelOptionsInteractConfig(parcel: ParcelId, config: InteractableConfiguration)
- fun transmitAllGlobalAddedData(channel: SendChannel<AddedDataPair<PlayerProfile>>)
+ fun transmitAllGlobalPrivileges(channel: SendChannel<PrivilegePair<PlayerProfile>>)
- fun readGlobalPrivileges(owner: PlayerProfile): MutablePrivilegeMap
+ fun readGlobalPrivileges(owner: PlayerProfile): PrivilegesHolder?
fun setGlobalPrivilege(owner: PlayerProfile, player: PlayerProfile, privilege: Privilege)
}
diff --git a/src/main/kotlin/io/dico/parcels2/storage/Storage.kt b/src/main/kotlin/io/dico/parcels2/storage/Storage.kt
index 334d010..abd9f41 100644
--- a/src/main/kotlin/io/dico/parcels2/storage/Storage.kt
+++ b/src/main/kotlin/io/dico/parcels2/storage/Storage.kt
@@ -14,7 +14,7 @@ import java.util.UUID
import kotlin.coroutines.CoroutineContext
typealias DataPair = Pair<ParcelId, ParcelData?>
-typealias AddedDataPair<TAttach> = Pair<TAttach, MutablePrivilegeMap>
+typealias PrivilegePair<TAttach> = Pair<TAttach, PrivilegesHolder>
interface Storage {
val name: String
@@ -55,9 +55,9 @@ interface Storage {
fun setParcelOptionsInteractConfig(parcel: ParcelId, config: InteractableConfiguration): Job
- fun transmitAllGlobalAddedData(): ReceiveChannel<AddedDataPair<PlayerProfile>>
+ fun transmitAllGlobalPrivileges(): ReceiveChannel<PrivilegePair<PlayerProfile>>
- fun readGlobalPrivileges(owner: PlayerProfile): Deferred<MutablePrivilegeMap?>
+ fun readGlobalPrivileges(owner: PlayerProfile): Deferred<PrivilegesHolder?>
fun setGlobalPrivilege(owner: PlayerProfile, player: PlayerProfile, privilege: Privilege): Job
@@ -104,9 +104,9 @@ class BackedStorage internal constructor(val b: Backing) : Storage, CoroutineSco
override fun setParcelOptionsInteractConfig(parcel: ParcelId, config: InteractableConfiguration) = b.launchJob { b.setParcelOptionsInteractConfig(parcel, config) }
- override fun transmitAllGlobalAddedData(): ReceiveChannel<AddedDataPair<PlayerProfile>> = b.openChannel { b.transmitAllGlobalAddedData(it) }
+ override fun transmitAllGlobalPrivileges(): ReceiveChannel<PrivilegePair<PlayerProfile>> = b.openChannel { b.transmitAllGlobalPrivileges(it) }
- override fun readGlobalPrivileges(owner: PlayerProfile): Deferred<MutablePrivilegeMap?> = b.launchFuture { b.readGlobalPrivileges(owner) }
+ override fun readGlobalPrivileges(owner: PlayerProfile): Deferred<PrivilegesHolder?> = b.launchFuture { b.readGlobalPrivileges(owner) }
override fun setGlobalPrivilege(owner: PlayerProfile, player: PlayerProfile, privilege: Privilege) = b.launchJob { b.setGlobalPrivilege(owner, player, privilege) }
diff --git a/src/main/kotlin/io/dico/parcels2/storage/exposed/ExposedBacking.kt b/src/main/kotlin/io/dico/parcels2/storage/exposed/ExposedBacking.kt
index d0b1296..e3ed21b 100644
--- a/src/main/kotlin/io/dico/parcels2/storage/exposed/ExposedBacking.kt
+++ b/src/main/kotlin/io/dico/parcels2/storage/exposed/ExposedBacking.kt
@@ -6,7 +6,7 @@ import com.zaxxer.hikari.HikariDataSource
import io.dico.parcels2.*
import io.dico.parcels2.PlayerProfile.Star.name
import io.dico.parcels2.storage.*
-import io.dico.parcels2.util.ext.clampMax
+import io.dico.parcels2.util.math.ext.clampMax
import io.dico.parcels2.util.ext.synchronized
import kotlinx.coroutines.*
import kotlinx.coroutines.channels.ArrayChannel
@@ -193,6 +193,10 @@ class ExposedBacking(private val dataSourceFactory: () -> DataSource, val poolSi
PrivilegesLocalT.setPrivilege(parcel, profile, privilege)
}
+ data.privilegeOfStar.takeIf { it != Privilege.DEFAULT }?.let { privilege ->
+ PrivilegesLocalT.setPrivilege(parcel, PlayerProfile.Star, privilege)
+ }
+
setParcelOptionsInteractConfig(parcel, data.interactableConfig)
}
@@ -242,13 +246,13 @@ class ExposedBacking(private val dataSourceFactory: () -> DataSource, val poolSi
}
}
- override fun transmitAllGlobalAddedData(channel: SendChannel<AddedDataPair<PlayerProfile>>) {
- PrivilegesGlobalT.sendAllAddedData(channel)
+ override fun transmitAllGlobalPrivileges(channel: SendChannel<PrivilegePair<PlayerProfile>>) {
+ PrivilegesGlobalT.sendAllPrivilegesH(channel)
channel.close()
}
- override fun readGlobalPrivileges(owner: PlayerProfile): MutablePrivilegeMap {
- return PrivilegesGlobalT.readPrivileges(ProfilesT.getId(owner.toOwnerProfile()) ?: return hashMapOf())
+ override fun readGlobalPrivileges(owner: PlayerProfile): PrivilegesHolder? {
+ return PrivilegesGlobalT.readPrivileges(ProfilesT.getId(owner.toOwnerProfile()) ?: return null)
}
override fun setGlobalPrivilege(owner: PlayerProfile, player: PlayerProfile, privilege: Privilege) {
@@ -267,7 +271,10 @@ class ExposedBacking(private val dataSourceFactory: () -> DataSource, val poolSi
System.arraycopy(source, 0, target, 0, source.size.clampMax(target.size))
}
- privilegeMap = PrivilegesLocalT.readPrivileges(id)
+ val privileges = PrivilegesLocalT.readPrivileges(id)
+ if (privileges != null) {
+ copyPrivilegesFrom(privileges)
+ }
}
}
diff --git a/src/main/kotlin/io/dico/parcels2/storage/exposed/ListTables.kt b/src/main/kotlin/io/dico/parcels2/storage/exposed/ListTables.kt
index d22316a..6a0a41b 100644
--- a/src/main/kotlin/io/dico/parcels2/storage/exposed/ListTables.kt
+++ b/src/main/kotlin/io/dico/parcels2/storage/exposed/ListTables.kt
@@ -15,7 +15,7 @@ object ParcelOptionsT : Table("parcel_options") {
val interact_bitmask = binary("interact_bitmask", 4)
}
-typealias PrivilegesSendChannel<AttachT> = SendChannel<Pair<AttachT, MutablePrivilegeMap>>
+typealias PrivilegesSendChannel<AttachT> = SendChannel<Pair<AttachT, PrivilegesHolder>>
sealed class PrivilegesTable<AttachT>(name: String, val idTable: IdTransactionsTable<*, AttachT>) : Table(name) {
val attach_id = integer("attach_id").references(idTable.id, ReferenceOption.CASCADE)
@@ -43,32 +43,32 @@ sealed class PrivilegesTable<AttachT>(name: String, val idTable: IdTransactionsT
}
}
- fun readPrivileges(id: Int): MutablePrivilegeMap {
+ fun readPrivileges(id: Int): PrivilegesHolder? {
val list = slice(profile_id, privilege).select { attach_id eq id }
- val result = MutablePrivilegeMap()
+ val result = PrivilegesHolder()
for (row in list) {
val profile = ProfilesT.getRealItem(row[profile_id]) ?: continue
- result[profile] = Privilege.getByNumber(row[privilege]) ?: continue
+ result.setRawStoredPrivilege(profile, Privilege.getByNumber(row[privilege]) ?: continue)
}
return result
}
- fun sendAllAddedData(channel: PrivilegesSendChannel<AttachT>) {
+ fun sendAllPrivilegesH(channel: PrivilegesSendChannel<AttachT>) {
val iterator = selectAll().orderBy(attach_id).iterator()
if (iterator.hasNext()) {
val firstRow = iterator.next()
var id: Int = firstRow[attach_id]
var attach: AttachT? = null
- var map: MutablePrivilegeMap? = null
+ var map: PrivilegesHolder? = null
fun initAttachAndMap() {
attach = idTable.getItem(id)
- map = attach?.let { mutableMapOf() }
+ map = attach?.let { PrivilegesHolder() }
}
fun sendIfPresent() {
- if (attach != null && map != null && map!!.isNotEmpty()) {
+ if (attach != null && map != null) {
channel.offer(attach!! to map!!)
}
attach = null
@@ -91,7 +91,7 @@ sealed class PrivilegesTable<AttachT>(name: String, val idTable: IdTransactionsT
val profile = ProfilesT.getRealItem(row[profile_id]) ?: continue
val privilege = Privilege.getByNumber(row[privilege]) ?: continue
- map!![profile] = privilege
+ map!!.setRawStoredPrivilege(profile, privilege)
}
sendIfPresent()
diff --git a/src/main/kotlin/io/dico/parcels2/util/Region.kt b/src/main/kotlin/io/dico/parcels2/util/Region.kt
deleted file mode 100644
index 1801b4e..0000000
--- a/src/main/kotlin/io/dico/parcels2/util/Region.kt
+++ /dev/null
@@ -1,18 +0,0 @@
-package io.dico.parcels2.util
-
-data class Region(val origin: Vec3i, val size: Vec3i) {
- val blockCount: Int get() = size.x * size.y * size.z
-
- val center: Vec3d
- get() {
- val x = (origin.x + size.x) / 2.0
- val y = (origin.y + size.y) / 2.0
- val z = (origin.z + size.z) / 2.0
- return Vec3d(x, y, z)
- }
-
- fun withSize(size: Vec3i): Region {
- if (size == this.size) return this
- return Region(origin, size)
- }
-} \ No newline at end of file
diff --git a/src/main/kotlin/io/dico/parcels2/util/Vec2i.kt b/src/main/kotlin/io/dico/parcels2/util/Vec2i.kt
deleted file mode 100644
index 62ac97f..0000000
--- a/src/main/kotlin/io/dico/parcels2/util/Vec2i.kt
+++ /dev/null
@@ -1,11 +0,0 @@
-package io.dico.parcels2.util
-
-data class Vec2i(
- val x: Int,
- val z: Int
-)
-
-data class Region2i(
- val bottom: Vec2i,
- val top: Vec2i
-) \ No newline at end of file
diff --git a/src/main/kotlin/io/dico/parcels2/util/ext/Misc.kt b/src/main/kotlin/io/dico/parcels2/util/ext/Misc.kt
index 4df4d52..a826687 100644
--- a/src/main/kotlin/io/dico/parcels2/util/ext/Misc.kt
+++ b/src/main/kotlin/io/dico/parcels2/util/ext/Misc.kt
@@ -77,3 +77,8 @@ class EditLoopScope<T, U>(val _map: MutableMap<T, U>) {
operator fun Formatting.plus(other: Formatting) = toString() + other
operator fun Formatting.plus(other: String) = toString() + other
+
+inline fun <T> Pair<T, T>.forEach(block: (T) -> Unit) {
+ block(first)
+ block(second)
+}
diff --git a/src/main/kotlin/io/dico/parcels2/util/math/Dimension.kt b/src/main/kotlin/io/dico/parcels2/util/math/Dimension.kt
new file mode 100644
index 0000000..cf67148
--- /dev/null
+++ b/src/main/kotlin/io/dico/parcels2/util/math/Dimension.kt
@@ -0,0 +1,19 @@
+package io.dico.parcels2.util.math
+
+enum class Dimension {
+ X,
+ Y,
+ Z;
+
+ val otherDimensions
+ get() = when (this) {
+ X -> Y to Z
+ Y -> X to Z
+ Z -> X to Y
+ }
+
+ companion object {
+ private val values = values()
+ operator fun get(ordinal: Int) = values[ordinal]
+ }
+} \ No newline at end of file
diff --git a/src/main/kotlin/io/dico/parcels2/util/math/Region.kt b/src/main/kotlin/io/dico/parcels2/util/math/Region.kt
new file mode 100644
index 0000000..cdbd497
--- /dev/null
+++ b/src/main/kotlin/io/dico/parcels2/util/math/Region.kt
@@ -0,0 +1,37 @@
+package io.dico.parcels2.util.math
+
+data class Region(val origin: Vec3i, val size: Vec3i) {
+ val blockCount: Int get() = size.x * size.y * size.z
+
+ val center: Vec3d
+ get() {
+ val x = (origin.x + size.x) / 2.0
+ val y = (origin.y + size.y) / 2.0
+ val z = (origin.z + size.z) / 2.0
+ return Vec3d(x, y, z)
+ }
+
+ val end: Vec3i
+ get() = origin + size
+
+ val max: Vec3i
+ get() = Vec3i(origin.x + size.x - 1, origin.y + size.y - 1, origin.z + size.z - 1)
+
+ fun withSize(size: Vec3i): Region {
+ if (size == this.size) return this
+ return Region(origin, size)
+ }
+
+ operator fun contains(loc: Vec3i): Boolean = getFirstUncontainedDimensionOf(loc) == null
+
+ fun getFirstUncontainedDimensionOf(loc: Vec3i): Dimension? {
+ val max = max
+ return when {
+ loc.x !in origin.x..max.x -> Dimension.X
+ loc.z !in origin.z..max.z -> Dimension.Z
+ loc.y !in origin.y..max.y -> Dimension.Y
+ else -> null
+ }
+ }
+
+} \ No newline at end of file
diff --git a/src/main/kotlin/io/dico/parcels2/util/math/Vec2i.kt b/src/main/kotlin/io/dico/parcels2/util/math/Vec2i.kt
new file mode 100644
index 0000000..9385535
--- /dev/null
+++ b/src/main/kotlin/io/dico/parcels2/util/math/Vec2i.kt
@@ -0,0 +1,6 @@
+package io.dico.parcels2.util.math
+
+data class Vec2i(
+ val x: Int,
+ val z: Int
+)
diff --git a/src/main/kotlin/io/dico/parcels2/util/math/Vec3d.kt b/src/main/kotlin/io/dico/parcels2/util/math/Vec3d.kt
new file mode 100644
index 0000000..45e6216
--- /dev/null
+++ b/src/main/kotlin/io/dico/parcels2/util/math/Vec3d.kt
@@ -0,0 +1,54 @@
+package io.dico.parcels2.util.math
+
+import io.dico.parcels2.util.math.ext.floor
+import org.bukkit.Location
+import kotlin.math.sqrt
+
+data class Vec3d(
+ val x: Double,
+ val y: Double,
+ val z: Double
+) {
+ constructor(loc: Location) : this(loc.x, loc.y, loc.z)
+
+ operator fun plus(o: Vec3d) = Vec3d(x + o.x, y + o.y, z + o.z)
+ operator fun minus(o: Vec3i) = Vec3d(x - o.x, y - o.y, z - o.z)
+ infix fun addX(o: Double) = Vec3d(x + o, y, z)
+ infix fun addY(o: Double) = Vec3d(x, y + o, z)
+ infix fun addZ(o: Double) = Vec3d(x, y, z + o)
+ infix fun withX(o: Double) = Vec3d(o, y, z)
+ infix fun withY(o: Double) = Vec3d(x, o, z)
+ infix fun withZ(o: Double) = Vec3d(x, y, o)
+ fun add(ox: Double, oy: Double, oz: Double) = Vec3d(x + ox, y + oy, z + oz)
+ fun toVec3i() = Vec3i(x.floor(), y.floor(), z.floor())
+
+ fun distanceSquared(o: Vec3d): Double {
+ val dx = o.x - x
+ val dy = o.y - y
+ val dz = o.z - z
+ return dx * dx + dy * dy + dz * dz
+ }
+
+ fun distance(o: Vec3d) = sqrt(distanceSquared(o))
+
+ operator fun get(dimension: Dimension) =
+ when (dimension) {
+ Dimension.X -> x
+ Dimension.Y -> y
+ Dimension.Z -> z
+ }
+
+ fun with(dimension: Dimension, value: Double) =
+ when (dimension) {
+ Dimension.X -> withX(value)
+ Dimension.Y -> withY(value)
+ Dimension.Z -> withZ(value)
+ }
+
+ fun add(dimension: Dimension, value: Double) =
+ when (dimension) {
+ Dimension.X -> addX(value)
+ Dimension.Y -> addY(value)
+ Dimension.Z -> addZ(value)
+ }
+} \ No newline at end of file
diff --git a/src/main/kotlin/io/dico/parcels2/util/Vec3i.kt b/src/main/kotlin/io/dico/parcels2/util/math/Vec3i.kt
index 8608e13..418fd0f 100644
--- a/src/main/kotlin/io/dico/parcels2/util/Vec3i.kt
+++ b/src/main/kotlin/io/dico/parcels2/util/math/Vec3i.kt
@@ -1,31 +1,18 @@
-package io.dico.parcels2.util
+package io.dico.parcels2.util.math
-import io.dico.parcels2.util.ext.clampMax
+import io.dico.parcels2.util.math.ext.clampMax
+import org.bukkit.Location
import org.bukkit.World
import org.bukkit.block.Block
import org.bukkit.block.BlockFace
-data class Vec3d(
- val x: Double,
- val y: Double,
- val z: Double
-) {
- operator fun plus(o: Vec3d) = Vec3d(x + o.x, y + o.y, z + o.z)
- operator fun minus(o: Vec3i) = Vec3d(x - o.x, y - o.y, z - o.z)
- infix fun addX(o: Double) = Vec3d(x + o, y, z)
- infix fun addY(o: Double) = Vec3d(x, y + o, z)
- infix fun addZ(o: Double) = Vec3d(x, y, z + o)
- infix fun withX(o: Double) = Vec3d(o, y, z)
- infix fun withY(o: Double) = Vec3d(x, o, z)
- infix fun withZ(o: Double) = Vec3d(x, y, o)
- fun add(ox: Double, oy: Double, oz: Double) = Vec3d(x + ox, y + oy, z + oz)
-}
-
data class Vec3i(
val x: Int,
val y: Int,
val z: Int
) {
+ constructor(loc: Location) : this(loc.blockX, loc.blockY, loc.blockZ)
+
operator fun plus(o: Vec3i) = Vec3i(x + o.x, y + o.y, z + o.z)
operator fun minus(o: Vec3i) = Vec3i(x - o.x, y - o.y, z - o.z)
infix fun addX(o: Int) = Vec3i(x + o, y, z)
@@ -38,6 +25,27 @@ data class Vec3i(
fun neg() = Vec3i(-x, -y, -z)
fun clampMax(o: Vec3i) = Vec3i(x.clampMax(o.x), y.clampMax(o.y), z.clampMax(o.z))
+ operator fun get(dimension: Dimension) =
+ when (dimension) {
+ Dimension.X -> x
+ Dimension.Y -> y
+ Dimension.Z -> z
+ }
+
+ fun with(dimension: Dimension, value: Int) =
+ when (dimension) {
+ Dimension.X -> withX(value)
+ Dimension.Y -> withY(value)
+ Dimension.Z -> withZ(value)
+ }
+
+ fun add(dimension: Dimension, value: Int) =
+ when (dimension) {
+ Dimension.X -> addX(value)
+ Dimension.Y -> addY(value)
+ Dimension.Z -> addZ(value)
+ }
+
companion object {
private operator fun invoke(face: BlockFace) = Vec3i(face.modX, face.modY, face.modZ)
val down = Vec3i(BlockFace.DOWN)
diff --git a/src/main/kotlin/io/dico/parcels2/util/ext/Math.kt b/src/main/kotlin/io/dico/parcels2/util/math/ext/Math.kt
index a123bcf..1211894 100644
--- a/src/main/kotlin/io/dico/parcels2/util/ext/Math.kt
+++ b/src/main/kotlin/io/dico/parcels2/util/math/ext/Math.kt
@@ -1,4 +1,4 @@
-package io.dico.parcels2.util.ext
+package io.dico.parcels2.util.math.ext
fun Double.floor(): Int {
val down = toInt()
@@ -34,6 +34,7 @@ fun IntRange.clamp(min: Int, max: Int): IntRange {
// the name coerceAtMost is bad
fun Int.clampMax(max: Int) = coerceAtMost(max)
fun Double.clampMin(min: Double) = coerceAtLeast(min)
+fun Double.clampMax(max: Double) = coerceAtMost(max)
// Why does this not exist?
infix fun Int.ceilDiv(divisor: Int): Int {