mirror of
https://gitlab.com/2009scape/2009scape.git
synced 2025-12-09 16:45:44 -07:00
Implemented Global Chat
Added global chat feature, so players can still maintain global communication while being in their own clan chat An individual player can opt out of global chat by using the ::muteglobal command Implemented automatic message splitting for clan and global chat Implemented colour selection for global chat (prefix your message with hex colour code, e.g. //%690420 before the message)
This commit is contained in:
parent
124eeab893
commit
3445b792c8
5 changed files with 100 additions and 16 deletions
|
|
@ -264,5 +264,8 @@ class ServerConstants {
|
|||
|
||||
@JvmField
|
||||
var DRAGON_AXE_USE_OSRS_SPEC = false
|
||||
|
||||
@JvmField
|
||||
var ENABLE_GLOBALCHAT = false
|
||||
}
|
||||
}
|
||||
|
|
|
|||
40
Server/src/main/core/game/system/communication/GlobalChat.kt
Normal file
40
Server/src/main/core/game/system/communication/GlobalChat.kt
Normal file
|
|
@ -0,0 +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
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -133,6 +133,7 @@ object ServerConfigParser {
|
|||
ServerConstants.DISCORD_MOD_WEBHOOK = data.getString("server.moderation_webhook", "")
|
||||
ServerConstants.NOAUTH_DEFAULT_ADMIN = data.getBoolean("server.noauth_default_admin", false)
|
||||
ServerConstants.DRAGON_AXE_USE_OSRS_SPEC = data.getBoolean("world.dragon_axe_use_osrs_spec", false)
|
||||
ServerConstants.ENABLE_GLOBALCHAT = data.getBoolean("world.enable_globalchat", true)
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ import core.game.node.entity.player.info.LogType
|
|||
import core.game.node.entity.player.info.PlayerMonitor
|
||||
import core.tools.SystemLogger
|
||||
import core.game.system.command.CommandSystem
|
||||
import core.game.system.communication.GlobalChat
|
||||
import core.game.world.GameWorld
|
||||
import core.game.world.repository.Repository
|
||||
import core.net.packet.`in`.Packet
|
||||
|
|
@ -54,6 +55,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 {
|
||||
|
|
@ -198,13 +200,28 @@ object PacketProcessor {
|
|||
if (pkt.player.details.isMuted)
|
||||
pkt.player.sendMessage("You have been muted due to breaking a rule.")
|
||||
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())
|
||||
if (ServerConstants.ENABLE_GLOBALCHAT && pkt.message.startsWith("//")) {
|
||||
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) {
|
||||
if (message.isNotBlank())
|
||||
GlobalChat.process(pkt.player.username, message)
|
||||
}
|
||||
return
|
||||
}
|
||||
else if (pkt.message.startsWith("/") && pkt.player.communication.clan != null) {
|
||||
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) {
|
||||
if (message.isBlank()) continue
|
||||
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)
|
||||
|
|
@ -759,5 +776,24 @@ object PacketProcessor {
|
|||
container.insert(slot, secondSlot, false)
|
||||
}
|
||||
container.refresh()
|
||||
}
|
||||
}
|
||||
|
||||
fun splitChatMessage(message: String, clanLength: Int, rankPresent: Boolean) : ArrayList<String> {
|
||||
val messages = ArrayList<String>()
|
||||
|
||||
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
|
||||
}
|
||||
|
|
@ -7,14 +7,18 @@ const val GREEN = "<col=66ff33>"
|
|||
const val BLUE = "<col=3366ff>"
|
||||
const val PURPLE = "<col=cc00ff>"
|
||||
|
||||
fun colorize(line: String): String{
|
||||
val new = line.replace("%R", RED)
|
||||
.replace("%O", ORANGE)
|
||||
.replace("%Y", YELLOW)
|
||||
.replace("%G", GREEN)
|
||||
.replace("%B", BLUE)
|
||||
.replace("%P", PURPLE).append("</col>") + " "
|
||||
return new
|
||||
private val pattern = Regex("%[0-9a-fA-F]{6}")
|
||||
private val testData = arrayOf("This is a string with no colors.", "This %R is a string with one color.", "This %R %G %B is a string with multiple colors.", "This %ffffff is an arbitrary hex string.")
|
||||
|
||||
fun colorize(line: String): String {
|
||||
return line.replace("%R", RED)
|
||||
.replace("%O", ORANGE)
|
||||
.replace("%Y", YELLOW)
|
||||
.replace("%G", GREEN)
|
||||
.replace("%B", BLUE)
|
||||
.replace("%P", PURPLE)
|
||||
.replace(pattern) { matchResult -> "<col=${matchResult.value.substring(1)}>" }
|
||||
.append("</col>") + " "
|
||||
}
|
||||
|
||||
fun colorize(line: String, hexColor: String): String{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue