Skip to content
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
kotlin.code.style=official
kotlin.stdlib.default.dependency=false
org.gradle.parallel=true
version=3.3.7
version=3.3.8
Original file line number Diff line number Diff line change
Expand Up @@ -78,5 +78,7 @@ object PaperCommandManager {
worldCommand()
pingCommand()
echestCommand()
testSoundCommand()
serializeItemCommand()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@ object PaperListenerManager {
SpecialItemListener.register()
HungerListener.register()
RestartListener.register()
SpectatorFlyListener.register()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package dev.slne.surf.essentials.command
import dev.jorel.commandapi.kotlindsl.commandTree
import dev.jorel.commandapi.kotlindsl.playerExecutor
import dev.slne.surf.api.core.messages.adventure.sendText
import dev.slne.surf.api.core.util.random
import dev.slne.surf.essentials.util.permission.EssentialsPermissionRegistry
import org.bukkit.Bukkit

Expand All @@ -13,7 +14,7 @@ fun teleportRandomCommand() = commandTree("teleportrandom") {
playerExecutor { player, _ ->
val selected = Bukkit.getOnlinePlayers()
.filter { !it.hasPermission(EssentialsPermissionRegistry.TELEPORT_RANDOM_BYPASS) }
.randomOrNull() ?: run {
.secureRandomOrNull() ?: run {
player.sendText {
appendErrorPrefix()
error("Es wurde kein Spieler gefunden, zu dem du teleportiert werden kannst.")
Expand All @@ -29,4 +30,8 @@ fun teleportRandomCommand() = commandTree("teleportrandom") {
success(" teleportiert.")
}
}
}
}


private fun <T> List<T>.secureRandomOrNull(): T? =
if (isEmpty()) null else this[random.nextInt(size)]
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package dev.slne.surf.essentials.command

import dev.jorel.commandapi.kotlindsl.commandTree
import dev.jorel.commandapi.kotlindsl.playerExecutor
import dev.slne.surf.api.core.messages.adventure.sendText
import dev.slne.surf.essentials.util.permission.EssentialsPermissionRegistry
import net.kyori.adventure.text.format.TextDecoration
import kotlin.io.encoding.Base64

fun serializeItemCommand() = commandTree("serializeitem") {
withPermission(EssentialsPermissionRegistry.SERIALIZE_ITEM_COMMAND)
playerExecutor { player, _ ->
val item = player.inventory.itemInMainHand
val bytes = item.serializeAsBytes()
val base64 = Base64.encode(bytes)

player.sendText {
appendSuccessPrefix()
success("Das Item ")
translatable(item.type.translationKey())
success(" wurde in ")
variableValue(bytes.size)
success(" Bytes serialisiert und in Base64 kodiert. ")
append {
decorate(TextDecoration.ITALIC)
spacer("kopieren...")
clickCopiesToClipboard(base64)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package dev.slne.surf.essentials.command

import dev.jorel.commandapi.kotlindsl.*
import dev.slne.surf.api.core.messages.adventure.playSound
import dev.slne.surf.api.core.messages.adventure.sendText
import dev.slne.surf.api.paper.util.BukkitSound
import dev.slne.surf.essentials.util.permission.EssentialsPermissionRegistry
import org.bukkit.Registry

fun testSoundCommand() = commandTree("testsound") {
withPermission(EssentialsPermissionRegistry.TEST_SOUND_COMMAND)

soundArgument("sound") {
playerExecutor { player, arguments ->
val sound: BukkitSound by arguments

player.playSound(true) {
type(sound)
}

player.sendText {
appendSuccessPrefix()
success("Der Sound ")
variableValue(Registry.SOUNDS.getKey(sound)?.key.toString())
success(" wurde erfolgreich abgespielt.")
}
}
floatArgument("pitch") {
playerExecutor { player, arguments ->
val sound: BukkitSound by arguments
val pitch: Float by arguments

player.playSound(true) {
type(sound)
pitch(pitch)
}

player.sendText {
appendSuccessPrefix()
success("Der Sound ")
variableValue(Registry.SOUNDS.getKey(sound)?.key.toString())
success(" wurde erfolgreich abgespielt.")
}
}

floatArgument("volume") {
playerExecutor { player, arguments ->
val sound: BukkitSound by arguments
val pitch: Float by arguments
val volume: Float? by arguments

player.playSound(true) {
type(sound)
pitch(pitch)
volume?.let {
volume(it)
}
}

player.sendText {
appendSuccessPrefix()
success("Der Sound ")
variableValue(Registry.SOUNDS.getKey(sound)?.key.toString())
success(" wurde erfolgreich abgespielt.")
}
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package dev.slne.surf.essentials.listener

import dev.slne.surf.essentials.plugin
import org.bukkit.GameMode
import org.bukkit.event.EventHandler
import org.bukkit.event.Listener
import org.bukkit.event.player.PlayerGameModeChangeEvent
import org.bukkit.event.player.PlayerQuitEvent
import java.util.*
import java.util.concurrent.ConcurrentHashMap

object SpectatorFlyListener : Listener {
private val allowFlightPlayers = ConcurrentHashMap.newKeySet<UUID>()
private val flyingPlayers = ConcurrentHashMap.newKeySet<UUID>()

@EventHandler(ignoreCancelled = true)
fun onGameModeChange(event: PlayerGameModeChangeEvent) {
val player = event.player
val previousGameMode = player.gameMode
val newGameMode = event.newGameMode

val isOldFlightMode =
previousGameMode == GameMode.SPECTATOR || previousGameMode == GameMode.CREATIVE
val isNewFlightMode = newGameMode == GameMode.SPECTATOR || newGameMode == GameMode.CREATIVE

if (!isOldFlightMode && isNewFlightMode) {
if (player.allowFlight) {
allowFlightPlayers.add(player.uniqueId)
if (player.isFlying) {
flyingPlayers.add(player.uniqueId)
}
}
return
}

if (isOldFlightMode && !isNewFlightMode) {
val hadAllowFlight = allowFlightPlayers.remove(player.uniqueId)
val wasFlying = flyingPlayers.remove(player.uniqueId)

player.scheduler.runDelayed(plugin, {
if (player.isOnline) {
player.allowFlight = hadAllowFlight
player.isFlying = wasFlying && hadAllowFlight
}
}, null, 1L)
}
}

@EventHandler
fun onQuit(event: PlayerQuitEvent) {
allowFlightPlayers.remove(event.player.uniqueId)
flyingPlayers.remove(event.player.uniqueId)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -123,4 +123,8 @@ object EssentialsPermissionRegistry : PermissionRegistry() {
val RENAME_COMMAND = create("$PREFIX.rename.command")
val RENAME_COMMAND_BYPASS = create("$PREFIX.rename.command.bypass")
val RENAME_COMMAND_MINIMESSAGE = create("$PREFIX.rename.command.minimessage")

val SERIALIZE_ITEM_COMMAND = create("$PREFIX.serializeitem.command")

val TEST_SOUND_COMMAND = create("$PREFIX.testsound.command")
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine

@Suppress("SuspendCoroutineLacksCancellationGuarantees")
suspend fun World.unloadCanvasWorld(save: Boolean = true): WorldUnloadResult = suspendCoroutine { cont ->
Bukkit.unloadWorldAsync(this, save) {
cont.resume(it)
}
}
suspend fun World.unloadCanvasWorld(save: Boolean = true): WorldUnloadResult =
suspendCoroutine { cont ->
Bukkit.getServer().unloadWorldAsync(this, save) {
cont.resume(it)
}
}