Skip to content

Commit

Permalink
Private messages (#11)
Browse files Browse the repository at this point in the history
  • Loading branch information
Boy0000 authored Jul 22, 2022
1 parent ddb2a6f commit 83dca6d
Show file tree
Hide file tree
Showing 8 changed files with 178 additions and 31 deletions.
116 changes: 98 additions & 18 deletions chatty-paper/src/main/kotlin/com/mineinabyss/chatty/ChattyCommands.kt
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
package com.mineinabyss.chatty

import com.github.shynixn.mccoroutine.bukkit.asyncDispatcher
import com.github.shynixn.mccoroutine.bukkit.launch
import com.mineinabyss.chatty.components.playerData
import com.mineinabyss.chatty.helpers.*
import com.mineinabyss.idofront.commands.arguments.stringArg
import com.mineinabyss.idofront.commands.execution.IdofrontCommandExecutor
import com.mineinabyss.idofront.commands.extensions.actions.ensureSenderIsPlayer
import com.mineinabyss.idofront.commands.extensions.actions.playerAction
import com.mineinabyss.idofront.messaging.miniMsg
import io.papermc.paper.chat.ChatRenderer
import io.papermc.paper.event.player.AsyncChatEvent
import org.bukkit.Bukkit
import org.bukkit.command.Command
import org.bukkit.command.CommandSender
Expand All @@ -15,6 +20,12 @@ import org.bukkit.entity.Player
class ChattyCommands : IdofrontCommandExecutor(), TabCompleter {
override val commands = commands(chattyPlugin) {
"chatty"(desc = "Chatty commands") {
("message" / "msg")(desc = "Private message another player") {
ensureSenderIsPlayer()
playerAction {
(sender as? Player)?.handlePrivateMessage(player, arguments)
}
}
"ping"(desc = "Commands related to the chat-ping feature.") {
"toggle"(desc = "Toggle the ping sound.") {
ensureSenderIsPlayer()
Expand All @@ -38,13 +49,13 @@ class ChattyCommands : IdofrontCommandExecutor(), TabCompleter {
}
}
}
"channels"(desc = "List all channels") {
("channels" / "ch")(desc = "List all channels") {
action {
(sender as? Player)?.sendFormattedMessage(chattyMessages.channels.availableChannels)
?: sender.sendMessage(chattyMessages.channels.availableChannels)
}
}
"nickname" {
("nickname" / "nick") {
action {
val nickMessage = chattyMessages.nicknames
val nickConfig = chattyConfig.nicknames
Expand Down Expand Up @@ -97,7 +108,7 @@ class ChattyCommands : IdofrontCommandExecutor(), TabCompleter {
}
}
}
"reload" {
("reload" / "rl") {
"config" {
action {
ChattyConfig.reload()
Expand Down Expand Up @@ -137,6 +148,30 @@ class ChattyCommands : IdofrontCommandExecutor(), TabCompleter {
}
}
}
("global" / "g") {
ensureSenderIsPlayer()
action {
(sender as? Player)?.shortcutCommand(getGlobalChat(), arguments)
}
}
("local" / "l") {
ensureSenderIsPlayer()
action {
(sender as? Player)?.shortcutCommand(getRadiusChannel(), arguments)
}
}
("admin" / "a") {
ensureSenderIsPlayer()
action {
(sender as? Player)?.shortcutCommand(getAdminChannel(), arguments)
}
}
("message" / "msg")(desc = "Private message another player") {
ensureSenderIsPlayer()
playerAction {
(sender as? Player)?.handlePrivateMessage(player, arguments)
}
}
}

override fun onTabComplete(
Expand All @@ -147,30 +182,75 @@ class ChattyCommands : IdofrontCommandExecutor(), TabCompleter {
): List<String> {
return if (command.name == "chatty") {
when (args.size) {
1 -> listOf("ping", "reload", "channels", "nickname")
1 -> listOf("message", "ping", "reload", "channels", "nickname")
2 -> when (args[0]) {
"ping" -> listOf("toggle", "sound")
"reload" -> listOf("config", "messages")
"reload", "rl" -> listOf("config", "messages")
"message", "msg" -> Bukkit.getOnlinePlayers().map { it.name }.filter { s -> s.startsWith(args[1]) }
else -> emptyList()
}
3 -> when {
args[1] == "sound" -> getAlternativePingSounds
args[1].startsWith(chattyConfig.nicknames.nickNameOtherPrefix) ->
Bukkit.getOnlinePlayers().map { it.name }.filter { s ->
s.replace(chattyConfig.nicknames.nickNameOtherPrefix.toString(), "").startsWith(args[1]) }
else -> emptyList()
}
3 ->
if (args[0] == "ping" && args[1] == "sound") getAlternativePingSounds
else emptyList()
else -> emptyList()
}
} else emptyList()
}
}

private fun Player.swapChannelCommand(channelId: String) {
val newChannel = getChannelFromId(channelId)
private fun Player.swapChannelCommand(channelId: String) {
val newChannel = getChannelFromId(channelId)

if (newChannel == null) {
sendFormattedMessage(chattyMessages.channels.noChannelWithName)
} else if (!hasPermission(newChannel.permission)) {
sendFormattedMessage(chattyMessages.channels.missingChannelPermission)
} else {
playerData.channelId = channelId
sendFormattedMessage(chattyMessages.channels.channelChanged)
}
}

private fun Player.shortcutCommand(
channel: Map.Entry<String, ChattyConfig.ChattyChannel>?,
arguments: List<String>
) {
val currentChannel = playerData.channelId
val msg = arguments.joinToString(" ").miniMsg()

if (newChannel == null) {
sendFormattedMessage(chattyMessages.channels.noChannelWithName)
} else if (!hasPermission(newChannel.permission)) {
sendFormattedMessage(chattyMessages.channels.missingChannelPermission)
} else {
playerData.channelId = channelId
sendFormattedMessage(chattyMessages.channels.channelChanged)
if (!hasPermission(channel?.value?.permission.toString()))
sendFormattedMessage(chattyMessages.channels.missingChannelPermission)
else if (channel?.key != null && arguments.isEmpty())
swapChannelCommand(channel.key)
else if (channel?.key != null && arguments.isNotEmpty()) {
playerData.channelId = channel.key
chattyPlugin.launch(chattyPlugin.asyncDispatcher) {
AsyncChatEvent(
true, this@shortcutCommand, mutableSetOf(), ChatRenderer.defaultRenderer(), msg, msg
).callEvent()
playerData.channelId = currentChannel
}
}
}

private fun Player.handlePrivateMessage(player: Player, arguments: List<String>) {
if (!chattyConfig.privateMessages.enabled) {
this.sendFormattedMessage(chattyMessages.privateMessages.disabled)
} else if (arguments.first().toPlayer() == null) {
this.sendFormattedMessage(chattyMessages.privateMessages.invalidPlayer)
} else {
val msg = arguments.removeFirstArgumentOfStringList()
val privateMessages = chattyConfig.privateMessages

this.sendFormattedPrivateMessage(privateMessages.messageSendFormat, msg, player)
player.sendFormattedPrivateMessage(privateMessages.messageReceiveFormat, msg, this)
if (privateMessages.messageSendSound.isNotEmpty())
this.playSound(player.location, privateMessages.messageSendSound, 1f, 1f)
if (privateMessages.messageReceivedSound.isNotEmpty())
player.playSound(player.location, privateMessages.messageReceivedSound, 1f, 1f)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,20 @@ object ChattyConfig : IdofrontConfig<ChattyConfig.Data>(chattyPlugin, Data.seria
val join: Join = Join(),
val leave: Leave = Leave(),
val proxy: Proxy = Proxy(),
val privateMessages: PrivateMessages = PrivateMessages(),
val channels: Map<String, ChattyChannel> = mutableMapOf("global" to ChattyChannel(ChannelType.GLOBAL)),
)

@Serializable
data class PrivateMessages(
val enabled: Boolean = true,
val proxy: Boolean = true,
val messageSendFormat: String = "<gold>You -> %player_displayname%: ",
val messageReceiveFormat: String = "<gold>%player_displayname% -> You: ",
val messageSendSound: String = "",
val messageReceivedSound: String = "",
)

@Serializable
data class Nickname(
val permission: String = "chatty.nickname",
Expand Down Expand Up @@ -57,6 +68,7 @@ object ChattyConfig : IdofrontConfig<ChattyConfig.Data>(chattyPlugin, Data.seria
val proxy: Boolean = false,
val discordsrv: Boolean = true,
val isDefaultChannel: Boolean = false,
val isStaffChannel: Boolean = false,
val format: Format = Format(),
val channelRadius: Int = 0,
val channelAliases: List<String> = listOf(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,19 @@ object ChattyMessages : IdofrontConfig<ChattyMessages.Messages>(chattyPlugin, Me

@Serializable
data class Messages(
val nicknames: Nicknames,
val ping: Pings,
val channels: Channels,
val proxies: Proxies,
val joinLeave: JoinLeave,
val other: Other
val nicknames: Nicknames = Nicknames(),
val privateMessages: PrivateMessages = PrivateMessages(),
val ping: Pings = Pings(),
val channels: Channels = Channels(),
val proxies: Proxies = Proxies(),
val joinLeave: JoinLeave = JoinLeave(),
val other: Other = Other()
)

@Serializable
data class PrivateMessages(
val disabled: String = "<red>Private messages are disabled",
val invalidPlayer: String = "<red>Invalid player",
)

@Serializable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,12 @@ fun Component.handlePlayerPings(player: Player, pingedPlayer: Player) {
fun getGlobalChat() =
chattyConfig.channels.entries.firstOrNull { it.value.channelType == ChannelType.GLOBAL }

fun getRadiusChannel() =
chattyConfig.channels.entries.firstOrNull { it.value.channelType == ChannelType.RADIUS }

fun getAdminChannel() =
chattyConfig.channels.entries.firstOrNull { it.value.isStaffChannel }

fun getDefaultChat() =
chattyConfig.channels.entries.firstOrNull { it.value.isDefaultChannel }
?: getGlobalChat()
Expand Down Expand Up @@ -200,10 +206,20 @@ fun String.getTags(): List<ChattyTags> {
return tags.toList()
}

fun String.toPlayer(): Player? {
return Bukkit.getPlayer(this)
}

fun Player.sendFormattedMessage(message: String) =
this.sendMessage(translatePlaceholders(this, message).serialize().miniMsg())

fun Player.sendFormattedMessage(message: String, optionalPlayer: Player? = null) =
this.sendMessage(translatePlaceholders((optionalPlayer ?: this), message))

fun Player.sendFormattedPrivateMessage(messageFormat: String, message: String, receiver: Player) =
receiver.sendMessage((translatePlaceholders(this, messageFormat).serialize() + message).miniMsg())

fun List<String>.removeFirstArgumentOfStringList(): String =
this.filter { it != this.first() }.joinToString(" ")

fun CommandSender.sendConsoleMessage(message: String) = this.sendMessage(message.miniMsg())
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ class ChatListener : Listener {
val channel = getChannelFromId(channelId) ?: return
val displayName = if (channel.format.useDisplayName) player.displayName() else player.name.miniMsg()
val audiences = viewers()
audiences.clear()
audiences.addAll(setAudienceForChannelType(player))

if (audiences.isNotEmpty()) audiences.clear()
audiences.addAll(setAudienceForChannelType(player))
message("<reset>".miniMsg()
.append(translatePlaceholders(player, channel.format.prefix))
.append(displayName)
Expand Down
17 changes: 13 additions & 4 deletions chatty-paper/src/main/resources/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@
playerHeadFont: "minecraft:chatty_heads"
useChattyCommandPrefix: true

privateMessages:
enabled: true
proxy: true # Not currently supported
messageSendFormat: "<gold>You -> %player_displayname%: "
messageReceiveFormat: "<gold>%player_displayname% -> You: "
messageSendSound: "" # Empty for no sound
messageReceiveSound: "" # Empty for no sound

nicknames:
permission: "chatty.nickname"
nickOtherPermission: "chatty.nickname.other"
Expand Down Expand Up @@ -38,16 +46,16 @@ proxy:
ping:
enabledChannels: # channelIds to enable pings for
- "global" # "all" or "*" for all channels
defaultPingSound: "block.amethyst_block.place"
alternativePingSounds: # "all" to let people choose any sound
- "block.stone.break"
- "block.grass.place"
pingVolume: 1.0
pingPitch: 1.0
pingPrefix: "@"
clickToReply: true
pingReceiveFormat: "<b>" # Default format the ping-message is marked with for pinged
pingSendFormat: "<i>" # Default format the ping-message is marked with for sender
defaultPingSound: "block.amethyst_block.place"
alternativePingSounds: # "all" to let people choose any sound
- "block.stone.break"
- "block.grass.place"


channels:
Expand Down Expand Up @@ -92,6 +100,7 @@ channels:
permission: "chatty.channel.staff"
requireEffectivePermission: false
isDefaultChannel: false
isStaffChannel: true
format:
usePlayerDisplayName: true
prefix: "<red>[Staff]"
Expand Down
4 changes: 4 additions & 0 deletions chatty-paper/src/main/resources/messages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ nicknames:
disallowedStyling: "<red>This nickname contains formatting that are not allowed!"
tooLong: "<red>The nickname was too long!"

privateMessages:
disabled: "<red>Private messages are disabled"
invalidPlayer: "<red>This player is not online or does not exist"

ping:
toggledPingSound: "Ping sound is now <i>%chatty_player_ping_toggle%</i>."
changedPingSound: "Ping sound set to <i>%chatty_player_ping_sound%</i>"
Expand Down
21 changes: 20 additions & 1 deletion chatty-paper/src/main/resources/plugin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,29 @@ name: chatty
version: ${plugin_version}
author: boy0000
main: com.mineinabyss.chatty.ChattyPlugin
api-version: 1.19
api-version: 1.18
depend: [ Geary ]
softdepend: [ BondrewdLikesHisEmotes, PlaceholderAPI, DiscordSRV ]
description: TODO

commands:
chatty:
aliases:
- chat
description: "Chatty is a plugin that allows you to chat in a more friendly way."
global:
permission: "chatty.global"
aliases:
- g
local:
permission: "chatty.local"
aliases:
- l
admin:
permission: "chatty.admin"
aliases:
- a
message:
permission: "chatty.message"
aliases:
- msg

0 comments on commit 83dca6d

Please sign in to comment.