World whitelists for beheading and broadcasting
This commit is contained in:
1 parent
bf4b54744b
commit
3f71a49c7c
7 files changed
+164
-1
No files matched your search
@@ -50,11 +50,13 @@ repositories {
|
||||
mavenCentral() // Import the Maven Central Maven Repository.
|
||||
gradlePluginPortal() // Import the Gradle Plugin Portal Maven Repository.
|
||||
maven { url = uri("https://repo.purpurmc.org/snapshots") } // Import the PurpurMC Maven Repository.
|
||||
maven { url = uri("https://repo.lucko.me/") } // Import the LuckPerms Maven Repository.
|
||||
}
|
||||
|
||||
/* ---------------------- Java project deps ---------------------------- */
|
||||
dependencies {
|
||||
compileOnly("org.purpurmc.purpur:purpur-api:1.19.4-R0.1-SNAPSHOT") // Declare Purpur API version to be packaged.
|
||||
compileOnly("net.luckperms:api:5.5") // Declare LuckPerms API for prefix/name color lookups.
|
||||
implementation("org.jetbrains.kotlin:kotlin-stdlib") // Import Kotlin standard library.
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2") // Import Kotlin async library.
|
||||
}
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
rootProject.name = "MobHeads-OG"
|
||||
rootProject.name = "MobHeads-OG"
|
||||
@@ -0,0 +1,102 @@
|
||||
package net.trueog.mobheadsog
|
||||
|
||||
import net.kyori.adventure.text.Component
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage
|
||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder
|
||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer
|
||||
import net.luckperms.api.LuckPermsProvider
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.entity.Creeper
|
||||
import org.bukkit.entity.Entity
|
||||
import org.bukkit.entity.EntityType
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
object Broadcast {
|
||||
private val mm = MiniMessage.miniMessage()
|
||||
private val legacy = LegacyComponentSerializer.builder().character('&').hexColors().build()
|
||||
|
||||
/** Announce that [killer] beheaded [entity] to every online player in a whitelisted world. */
|
||||
fun beheaded(killer: Player, entity: Entity) {
|
||||
val config = MobHeadsOG.config
|
||||
if (!config.broadcastEnabled) {
|
||||
return
|
||||
}
|
||||
if (config.broadcastWorlds.isEmpty()) {
|
||||
return
|
||||
}
|
||||
|
||||
val rawPrefix = (getPrefix(killer) ?: "").replace('§', '&')
|
||||
val prefix = legacy.deserialize(rawPrefix)
|
||||
val name = legacy.deserialize(trailingColor(rawPrefix) + killer.name)
|
||||
val mob = Component.text(mobName(entity))
|
||||
|
||||
val message =
|
||||
mm.deserialize(
|
||||
config.broadcastMessage,
|
||||
Placeholder.component("prefix", prefix),
|
||||
Placeholder.component("name", name),
|
||||
Placeholder.component("mob", mob),
|
||||
)
|
||||
|
||||
for (player in Bukkit.getOnlinePlayers()) {
|
||||
if (player.world.name in config.broadcastWorlds) {
|
||||
player.sendMessage(message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @return The player's LuckPerms prefix, or null if LuckPerms is absent or the player has none. */
|
||||
private fun getPrefix(player: Player): String? {
|
||||
if (Bukkit.getPluginManager().getPlugin("LuckPerms") == null) {
|
||||
return null
|
||||
}
|
||||
return try {
|
||||
val luckPerms = LuckPermsProvider.get()
|
||||
val user = luckPerms.getPlayerAdapter(Player::class.java).getUser(player)
|
||||
user.cachedData.metaData.prefix
|
||||
} catch (_: Exception) {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
/** @return The last color/hex code (with its '&') in [raw], or an empty string if there is none. */
|
||||
private fun trailingColor(raw: String): String {
|
||||
var result = ""
|
||||
var i = 0
|
||||
while (i < raw.length) {
|
||||
if (raw[i] != '&' || i + 1 >= raw.length) {
|
||||
i++
|
||||
continue
|
||||
}
|
||||
val code = raw[i + 1].lowercaseChar()
|
||||
when {
|
||||
code == '#' && i + 7 < raw.length -> {
|
||||
result = raw.substring(i, i + 8) // &#rrggbb
|
||||
i += 8
|
||||
}
|
||||
code in "0123456789abcdef" -> {
|
||||
result = raw.substring(i, i + 2)
|
||||
i += 2
|
||||
}
|
||||
code == 'r' -> {
|
||||
result = "" // Reset clears the active color.
|
||||
i += 2
|
||||
}
|
||||
code in "klmno" -> i += 2 // Formatting codes leave the color untouched.
|
||||
else -> i++
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
/** @return A human readable name for [entity] to display in the broadcast. */
|
||||
private fun mobName(entity: Entity): String {
|
||||
if (entity.type == EntityType.CREEPER) {
|
||||
return if ((entity as Creeper).isPowered) "Charged Creeper" else "Creeper"
|
||||
}
|
||||
return Heads.getNameForEntity(entity)
|
||||
?: entity.type.name.split("_").joinToString(" ") { word ->
|
||||
word.lowercase().replaceFirstChar(Char::uppercase)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,14 @@ class Config {
|
||||
|
||||
var chargedCreeperChance: Double = 0.0
|
||||
|
||||
val beheadWorlds: MutableList<String> = mutableListOf()
|
||||
|
||||
var broadcastEnabled: Boolean = false
|
||||
|
||||
val broadcastWorlds: MutableList<String> = mutableListOf()
|
||||
|
||||
var broadcastMessage: String = ""
|
||||
|
||||
/** @return True if successful */
|
||||
fun load(): Boolean {
|
||||
val file = File(MobHeadsOG.plugin.dataFolder, "config.yml")
|
||||
@@ -17,6 +25,28 @@ class Config {
|
||||
}
|
||||
val config = YamlConfiguration.loadConfiguration(file)
|
||||
|
||||
val beheadSection = config.getConfigurationSection("behead")
|
||||
if (beheadSection == null) {
|
||||
MobHeadsOG.plugin.logger.severe("Couldn't find a valid behead section in the config")
|
||||
return false
|
||||
}
|
||||
beheadWorlds.clear()
|
||||
beheadWorlds.addAll(beheadSection.getStringList("worlds"))
|
||||
|
||||
val broadcastSection = config.getConfigurationSection("broadcast")
|
||||
if (broadcastSection == null) {
|
||||
MobHeadsOG.plugin.logger.severe("Couldn't find a valid broadcast section in the config")
|
||||
return false
|
||||
}
|
||||
broadcastEnabled = broadcastSection.getBoolean("enabled")
|
||||
broadcastWorlds.clear()
|
||||
broadcastWorlds.addAll(broadcastSection.getStringList("worlds"))
|
||||
broadcastMessage = broadcastSection.getString("message") ?: ""
|
||||
if (broadcastEnabled && broadcastMessage.isEmpty()) {
|
||||
MobHeadsOG.plugin.logger.severe("Couldn't find a valid broadcast message in the config")
|
||||
return false
|
||||
}
|
||||
|
||||
val dropChancesSection = config.getConfigurationSection("dropChances")
|
||||
if (dropChancesSection == null) {
|
||||
MobHeadsOG.plugin.logger.severe("Couldn't find a valid dropChances section in the config")
|
||||
|
||||
@@ -39,6 +39,10 @@ class Events : Listener {
|
||||
return
|
||||
}
|
||||
|
||||
if (event.entity.world.name !in MobHeadsOG.config.beheadWorlds) {
|
||||
return
|
||||
}
|
||||
|
||||
val dropChance =
|
||||
if (event.entityType == EntityType.CREEPER && (event.entity as Creeper).isPowered) {
|
||||
MobHeadsOG.config.chargedCreeperChance
|
||||
@@ -54,16 +58,20 @@ class Events : Listener {
|
||||
return
|
||||
}
|
||||
|
||||
val killer = event.entity.killer as Player
|
||||
|
||||
when (event.entityType) {
|
||||
EntityType.SKELETON -> {
|
||||
val skull = ItemStack(Material.SKELETON_SKULL, 1)
|
||||
event.drops.add(skull)
|
||||
Broadcast.beheaded(killer, event.entity)
|
||||
return
|
||||
}
|
||||
|
||||
EntityType.ZOMBIE -> {
|
||||
val head = ItemStack(Material.ZOMBIE_HEAD, 1)
|
||||
event.drops.add(head)
|
||||
Broadcast.beheaded(killer, event.entity)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -71,6 +79,7 @@ class Events : Listener {
|
||||
if (!(event.entity as Creeper).isPowered) {
|
||||
val head = ItemStack(Material.CREEPER_HEAD, 1)
|
||||
event.drops.add(head)
|
||||
Broadcast.beheaded(killer, event.entity)
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -98,6 +107,7 @@ class Events : Listener {
|
||||
headMeta.playerProfile = profile
|
||||
head.itemMeta = headMeta
|
||||
event.drops.add(head)
|
||||
Broadcast.beheaded(killer, event.entity)
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
|
||||
@@ -1,3 +1,20 @@
|
||||
behead:
|
||||
# Heads only drop in these worlds.
|
||||
worlds:
|
||||
- world
|
||||
- world_nether
|
||||
- world_the_end
|
||||
|
||||
broadcast:
|
||||
enabled: true
|
||||
# Only players in these worlds see the broadcast.
|
||||
worlds:
|
||||
- world
|
||||
- world_nether
|
||||
- world_the_end
|
||||
# Placeholders: <prefix>, <name>, <mob>.
|
||||
message: "<dark_red>☠</dark_red> <prefix><name> <gray>decapitated a</gray> <mob><gray>!</gray>"
|
||||
|
||||
dropChances:
|
||||
allay: 0.025
|
||||
axolotl: 0.025
|
||||
|
||||
@@ -2,3 +2,5 @@ name: MobHeads-OG
|
||||
version: '${version}'
|
||||
main: net.trueog.mobheadsog.MobHeadsOG
|
||||
api-version: '${apiVersion}'
|
||||
softdepend:
|
||||
- LuckPerms
|
||||
Reference in new issue
Block a user