diff --git a/Server/src/main/core/game/system/communication/GlobalChat.kt b/Server/src/main/core/game/system/communication/GlobalChat.kt index bff657636..98e60229a 100644 --- a/Server/src/main/core/game/system/communication/GlobalChat.kt +++ b/Server/src/main/core/game/system/communication/GlobalChat.kt @@ -1,19 +1,40 @@ package core.game.system.communication +import core.api.Commands import core.api.getAttribute import core.api.sendMessage +import core.api.setAttribute +import core.game.system.command.Privilege import core.game.world.repository.Repository import core.tools.colorize -object GlobalChat { - private val ATTR_GLOBAL_MUTE = "/save:globalmute" - fun process(sender: String, message: String) { - val msg = prepare(sender, message) - for (player in Repository.players.filter { !getAttribute(it, ATTR_GLOBAL_MUTE, false) }) - sendMessage(player, msg) +class GlobalChat : Commands { + override fun defineCommands() { + define("muteglobal", Privilege.STANDARD, "", "Toggles global chat on or off.") {player, _ -> + val original = getAttribute(player, ATTR_GLOBAL_MUTE, false) + setAttribute(player, ATTR_GLOBAL_MUTE, !original) + sendMessage(player, "Global chat is now ${if (original) "ON" else "OFF"}.") + return@define + } } - private fun prepare(sender: String, message: String) : String { - return colorize("%44e3e0[%GG%44e3e0] %ffffff$sender: $message") + companion object { + val ATTR_GLOBAL_MUTE = "/save:globalmute" + fun process(sender: String, message: String) { + val msgSD = prepare(sender, message, false) + val msgHD = prepare(sender, message, true) + for (player in Repository.players.filter { !getAttribute(it, ATTR_GLOBAL_MUTE, false) }) { + if (player.interfaceManager.isResizable) + sendMessage(player, msgHD) + else + sendMessage(player, msgSD) + } + } + + private fun prepare(sender: String, message: String, isResizable: Boolean): String { + val baseColor = if (isResizable) "%G" else "%7512ff" + val bracketColor = if (isResizable) "%ffffff" else "%000000" + return colorize("$bracketColor[${baseColor}G$bracketColor] $sender: ${baseColor}$message") + } } } \ No newline at end of file diff --git a/Server/src/main/core/net/packet/PacketProcessor.kt b/Server/src/main/core/net/packet/PacketProcessor.kt index 9b59eafe2..9b5456282 100644 --- a/Server/src/main/core/net/packet/PacketProcessor.kt +++ b/Server/src/main/core/net/packet/PacketProcessor.kt @@ -63,6 +63,7 @@ import core.net.packet.`in`.RunScript import core.worker.ManagementEvents import java.io.PrintWriter import java.io.StringWriter +import java.lang.Math.min import java.util.* object PacketProcessor { @@ -204,16 +205,24 @@ object PacketProcessor { pkt.player.sendMessage("You have been muted due to breaking a rule.") else { if (ServerConstants.ENABLE_GLOBALCHAT && pkt.message.startsWith("//")) { - GlobalChat.process(pkt.player.username, pkt.message.substring(2)) + if (getAttribute(pkt.player, GlobalChat.ATTR_GLOBAL_MUTE, false)) + return + + val messages = splitChatMessage(pkt.message.substring(2), pkt.player.name.length + 3, false) + for (message in messages) + GlobalChat.process(pkt.player.username, message) return } else if (pkt.message.startsWith("/") && pkt.player.communication.clan != null) { - val builder = ClanMessage.newBuilder() - builder.sender = pkt.player.name - builder.clanName = pkt.player.communication.clan.owner.lowercase().replace(" ", "_") - builder.message = pkt.message.substring(1) - builder.rank = pkt.player.rights.ordinal - ManagementEvents.publish(builder.build()) + val messages = splitChatMessage(pkt.message.substring(1), pkt.player.communication.clan.name.length + pkt.player.name.length, pkt.player.details.rights.ordinal != 0) + for (message in messages) { + val builder = ClanMessage.newBuilder() + builder.sender = pkt.player.name + builder.clanName = pkt.player.communication.clan.owner.lowercase().replace(" ", "_") + builder.message = message + builder.rank = pkt.player.rights.ordinal + ManagementEvents.publish(builder.build()) + } return } PlayerMonitor.logChat(pkt.player, "public", pkt.message) @@ -761,5 +770,24 @@ object PacketProcessor { container.insert(slot, secondSlot, false) } container.refresh() - } + } + + fun splitChatMessage(message: String, clanLength: Int, rankPresent: Boolean) : ArrayList { + val messages = ArrayList() + + val effectiveCutoff = BASE_CHAT_CUTOFF - (clanLength + if (rankPresent) 9 else 0) + var counter = 0 + for (token in message.split(" ")) { + if (counter + token.length > effectiveCutoff) + break + counter += token.length + 1 + } + messages.add(message.substring(0, min(counter, message.length))) + if (counter < message.length) + messages.add(message.substring(counter, message.length)) + + return messages + } + + const val BASE_CHAT_CUTOFF = 81 } \ No newline at end of file