Skip to content

Commit d3d33c5

Browse files
committed
GH-4: Introduce sound support
1 parent bdf0d86 commit d3d33c5

File tree

7 files changed

+82
-44
lines changed

7 files changed

+82
-44
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
## [Unreleased]
44
### Added
5+
- GH-4: Sound support (@tajobe)
56
- GH-3: Title type announcement sender (@tajobe)
67
- MIT license
78

@@ -13,6 +14,7 @@
1314
- Config Auto-reload is now a repeating task as intended
1415
- Config actually created on first run
1516
- Copy updated default header when config is updated
17+
- Chat sender advancing the current message per player
1618

1719
### Removed
1820
- Offline variant is now the default jar, no longer producing an "online" version

src/main/kotlin/org/simplemc/simpleannounce/config/SimpleAnnounceConfig.kt

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ import com.fasterxml.jackson.annotation.JsonAlias
44
import com.fasterxml.jackson.annotation.JsonIgnore
55
import com.fasterxml.jackson.annotation.JsonTypeInfo
66
import com.fasterxml.jackson.annotation.JsonUnwrapped
7+
import org.bukkit.Sound
78
import org.bukkit.boss.BarColor
89
import org.bukkit.boss.BarStyle
10+
import org.simplemc.simpleannounce.config.SimpleAnnounceConfig.AnnouncementConfig.Chat.ChatMessage
911
import org.simplemc.simpleannounce.inTicks
1012
import kotlin.time.Duration
1113
import kotlin.time.Duration.Companion.milliseconds
@@ -16,8 +18,8 @@ data class SimpleAnnounceConfig(
1618
val announcements: List<AnnouncementConfig<*>>,
1719
) {
1820
companion object {
19-
private fun Duration?.checkNullZeroOrPositive(name: String) {
20-
check(this == null || this == Duration.Companion.ZERO || this.isPositive()) {
21+
private fun Duration?.requireNullZeroOrPositive(name: String) {
22+
require(this == null || this == Duration.Companion.ZERO || this.isPositive()) {
2123
"When set, $name must be >= 0s"
2224
}
2325
}
@@ -27,53 +29,63 @@ data class SimpleAnnounceConfig(
2729
val autoReloadTicks = autoReload?.inTicks
2830

2931
init {
30-
check(autoReload == null || autoReload == Duration.Companion.ZERO || autoReload.inWholeMinutes >= 1) {
32+
require(autoReload == null || autoReload == Duration.Companion.ZERO || autoReload.inWholeMinutes >= 1) {
3133
"When set, Auto Reload Duration must be > 1 minute"
3234
}
3335
}
3436

3537
@JsonTypeInfo(use = JsonTypeInfo.Id.SIMPLE_NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
36-
sealed class AnnouncementConfig<T> {
38+
sealed class AnnouncementConfig<T : AnnouncementConfig.Message> {
3739
abstract val random: Boolean
3840
abstract val delay: Duration
3941
abstract val repeat: Duration?
42+
abstract val sound: SoundConfig?
4043
abstract val includesPermissions: List<String>
4144
abstract val excludesPermissions: List<String>
4245
abstract val messages: List<T>
4346

47+
interface Message {
48+
val sound: SoundConfig?
49+
}
50+
4451
@JsonIgnore
4552
val delayTicks = delay.inTicks.toInt()
4653

4754
@JsonIgnore
4855
val repeatTicks = repeat?.inTicks?.toInt()
4956

5057
init {
51-
delay.checkNullZeroOrPositive("delay")
52-
repeat.checkNullZeroOrPositive("repeat")
58+
delay.requireNullZeroOrPositive("delay")
59+
repeat.requireNullZeroOrPositive("repeat")
5360
}
5461

5562
data class Chat(
5663
override val random: Boolean = false,
5764
override val delay: Duration = Duration.Companion.ZERO,
5865
override val repeat: Duration? = null,
66+
override val sound: SoundConfig? = null,
5967
override val includesPermissions: List<String> = emptyList(),
6068
override val excludesPermissions: List<String> = emptyList(),
61-
@field:JsonAlias("message") override val messages: List<String>,
62-
) : AnnouncementConfig<String>()
69+
@field:JsonAlias("message") override val messages: List<ChatMessage>,
70+
) : AnnouncementConfig<ChatMessage>() {
71+
data class ChatMessage(val message: String, override val sound: SoundConfig? = null) : Message
72+
}
6373

6474
data class Boss(
6575
override val random: Boolean = false,
6676
override val delay: Duration = Duration.Companion.ZERO,
6777
override val repeat: Duration? = null,
78+
override val sound: SoundConfig? = null,
6879
override val includesPermissions: List<String> = emptyList(),
6980
override val excludesPermissions: List<String> = emptyList(),
7081
@field:JsonAlias("message") override val messages: List<BossBarMessage>,
7182
@field:JsonUnwrapped val barConfig: BarConfig = BarConfig(),
7283
) : AnnouncementConfig<Boss.BossBarMessage>() {
7384
data class BossBarMessage(
7485
val message: String,
86+
override val sound: SoundConfig? = null,
7587
@field:JsonUnwrapped val barConfig: BarConfig? = null,
76-
) {
88+
) : Message {
7789
init {
7890
require(message.length <= 64) { "Boss Bar text must be <= 64 characters" }
7991
}
@@ -90,7 +102,7 @@ data class SimpleAnnounceConfig(
90102
val holdTicks = hold.inTicks
91103

92104
init {
93-
hold.checkNullZeroOrPositive("hold")
105+
hold.requireNullZeroOrPositive("hold")
94106
}
95107
}
96108
}
@@ -99,6 +111,7 @@ data class SimpleAnnounceConfig(
99111
override val random: Boolean = false,
100112
override val delay: Duration = Duration.Companion.ZERO,
101113
override val repeat: Duration? = null,
114+
override val sound: SoundConfig? = null,
102115
override val includesPermissions: List<String> = emptyList(),
103116
override val excludesPermissions: List<String> = emptyList(),
104117
@field:JsonAlias("message") override val messages: List<TitleMessage>,
@@ -107,8 +120,9 @@ data class SimpleAnnounceConfig(
107120
data class TitleMessage(
108121
val title: String,
109122
val subtitle: String? = null,
123+
override val sound: SoundConfig? = null,
110124
@field:JsonUnwrapped val titleConfig: TitleConfig? = null,
111-
)
125+
) : Message
112126

113127
data class TitleConfig(
114128
val fadeIn: Duration = 500.milliseconds,
@@ -125,11 +139,18 @@ data class SimpleAnnounceConfig(
125139
val fadeOutTicks = fadeOut.inTicks.toInt()
126140

127141
init {
128-
fadeIn.checkNullZeroOrPositive("fadeIn")
129-
stay.checkNullZeroOrPositive("stay")
130-
fadeOut.checkNullZeroOrPositive("fadeOut")
142+
fadeIn.requireNullZeroOrPositive("fadeIn")
143+
stay.requireNullZeroOrPositive("stay")
144+
fadeOut.requireNullZeroOrPositive("fadeOut")
131145
}
132146
}
133147
}
148+
149+
data class SoundConfig(val sound: Sound, val volume: Float = 1F, val pitch: Float = 1F) {
150+
init {
151+
require(volume >= 0 && volume <= 1) { "Sound volume must be between 0 and 1" }
152+
require(pitch >= 0.5 && pitch <= 2) { "Sound pitch must be between 0.5 and 2" }
153+
}
154+
}
134155
}
135156
}

src/main/kotlin/org/simplemc/simpleannounce/sender/AnnouncementSender.kt

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ import io.github.oshai.kotlinlogging.KotlinLogging
44
import org.bukkit.Bukkit
55
import org.bukkit.entity.Player
66
import org.bukkit.plugin.Plugin
7-
import org.simplemc.simpleannounce.config.SimpleAnnounceConfig
7+
import org.simplemc.simpleannounce.config.SimpleAnnounceConfig.AnnouncementConfig
88
import org.simplemc.simpleannounce.inTicks
99
import java.util.concurrent.atomic.AtomicInteger
1010
import kotlin.random.Random
1111

1212
private val logger = KotlinLogging.logger("SimpleAnnounce AnnouncementSender")
1313

14-
abstract class AnnouncementSender<MessageType, ConfigType : SimpleAnnounceConfig.AnnouncementConfig<MessageType>>(
14+
abstract class AnnouncementSender<MessageType : AnnouncementConfig.Message, ConfigType : AnnouncementConfig<MessageType>>(
1515
internal val plugin: Plugin,
1616
internal val announcement: ConfigType,
1717
) : Runnable {
@@ -36,7 +36,15 @@ abstract class AnnouncementSender<MessageType, ConfigType : SimpleAnnounceConfig
3636
return hasAllRequiredPermissions && hasNoExcludedPermissions
3737
}
3838

39-
internal fun getNextAnnouncement(): MessageType = when {
39+
internal fun send(message: MessageType, messageAction: (Player) -> Unit) {
40+
val sound = message.sound ?: announcement.sound
41+
Bukkit.getOnlinePlayers().filterNotNull().filter(this::shouldSendTo).forEach {
42+
messageAction(it)
43+
sound?.let { sound -> it.playSound(it.location, sound.sound, sound.volume, sound.pitch) }
44+
}
45+
}
46+
47+
internal fun getNextMessage(): MessageType = when {
4048
announcement.messages.size == 1 -> announcement.messages[0]
4149
announcement.random -> announcement.messages[Random.nextInt(announcement.messages.size)]
4250
else -> {

src/main/kotlin/org/simplemc/simpleannounce/sender/BossBarSender.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,15 @@ class BossBarSender(
1111
announcement: Boss,
1212
) : AnnouncementSender<Boss.BossBarMessage, Boss>(plugin, announcement) {
1313
override fun run() {
14-
val message = getNextAnnouncement()
14+
val message = getNextMessage()
1515
val barConfig = message.barConfig ?: announcement.barConfig
1616

1717
// create the bar
1818
val bar = Bukkit.createBossBar(message.message, barConfig.color, barConfig.style)
1919
bar.progress = if (barConfig.reverseAnimation) 1.0 else 0.0
2020

2121
// show bar to players
22-
Bukkit.getOnlinePlayers().filterNotNull().filter(this::shouldSendTo).forEach(bar::addPlayer)
22+
send(message, bar::addPlayer)
2323
bar.isVisible = true
2424

2525
// set up animation
Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
11
package org.simplemc.simpleannounce.sender
22

3-
import org.bukkit.Bukkit
43
import org.bukkit.plugin.Plugin
54
import org.simplemc.simpleannounce.config.SimpleAnnounceConfig.AnnouncementConfig.Chat
65

76
class ChatSender(
87
plugin: Plugin,
98
announcement: Chat,
10-
) : AnnouncementSender<String, Chat>(plugin, announcement) {
9+
) : AnnouncementSender<Chat.ChatMessage, Chat>(plugin, announcement) {
1110
override fun run() {
12-
Bukkit.getOnlinePlayers()
13-
.filterNotNull()
14-
.filter(this::shouldSendTo)
15-
.forEach { it.sendMessage(getNextAnnouncement()) }
11+
val message = getNextMessage()
12+
send(message) { it.sendMessage(message.message) }
1613
}
1714
}
Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package org.simplemc.simpleannounce.sender
22

3-
import org.bukkit.Bukkit
43
import org.bukkit.plugin.Plugin
54
import org.simplemc.simpleannounce.config.SimpleAnnounceConfig.AnnouncementConfig.Title
65

@@ -9,20 +8,17 @@ class TitleSender(
98
announcement: Title,
109
) : AnnouncementSender<Title.TitleMessage, Title>(plugin, announcement) {
1110
override fun run() {
12-
val message = getNextAnnouncement()
11+
val message = getNextMessage()
1312
val titleConfig = message.titleConfig ?: announcement.titleConfig
1413

15-
Bukkit.getOnlinePlayers()
16-
.filterNotNull()
17-
.filter(this::shouldSendTo)
18-
.forEach {
19-
it.sendTitle(
20-
message.title,
21-
message.subtitle,
22-
titleConfig.fadeInTicks,
23-
titleConfig.stayTicks,
24-
titleConfig.fadeOutTicks,
25-
)
26-
}
14+
send(message) {
15+
it.sendTitle(
16+
message.title,
17+
message.subtitle,
18+
titleConfig.fadeInTicks,
19+
titleConfig.stayTicks,
20+
titleConfig.fadeOutTicks,
21+
)
22+
}
2723
}
2824
}

src/main/resources/config.yml

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414
# random(boolean, optional): <if list of messages should be sent in random order>
1515
# delay(duration, optional - default 0): <Delay to send message>
1616
# repeat(duration, optional): <time between sending/repeating each message>
17+
# sound(SoundConfig):
18+
# sound(Sound): <Sound to send with announcement, see https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/Sound.html)
19+
# volume(float, optional): <Volume of sound to send between 0 and 1, default 1>
20+
# pitch(float, optional): <Pitch of sound to send between 0.5 and 2, default 1>
1721
# includesPermissions(String list, optional):
1822
# - <only send to those with this perm>
1923
# - <and this one>
@@ -26,7 +30,9 @@
2630
#
2731
# Chat type:
2832

29-
# messages(String list): [<list of messages>]
33+
# messages(ChatMessage list):
34+
# - message(string): <message string>
35+
# <sound config overrides, eg sound, volume, pitch>
3036
#
3137
# Boss type:
3238
#
@@ -37,6 +43,7 @@
3743
# reverseAnimation(boolean): <if animation should be reversed>
3844
# messages(BossBarMessage list):
3945
# - message(string): <message string>
46+
# <sound config overrides, eg sound, volume, pitch>
4047
# <boss bar config overrides eg hold, color, style, animate, etc...see above>
4148
#
4249
# Title type:
@@ -47,6 +54,7 @@
4754
# messages(TitleMessage list):
4855
# - title(string): <title string>
4956
# subtitle(string): <subtitle string, appears below title slightly smaller>
57+
# <sound config overrides, eg sound, volume, pitch>
5058
# <title config overrides eg fadeIn, stay, fadeOut...see above>
5159
#
5260
# -------------------------
@@ -64,13 +72,19 @@ announcements:
6472
excludesPermissions:
6573
- permissions.admin
6674
messages:
67-
- hello
68-
- world
75+
- message: hello
76+
- message: world
6977
- type: Chat
7078
repeat: 1m 40s
79+
sound:
80+
sound: AMBIENT_CAVE
81+
volume: .5
82+
pitch: 2
7183
messages:
72-
- abc
73-
- xyz
84+
- message: abc
85+
sound:
86+
sound: BLOCK_ENCHANTMENT_TABLE_USE
87+
- message: xyz
7488
- type: Title
7589
repeat: 30s
7690
messages:

0 commit comments

Comments
 (0)