diff --git a/CHANGELOG b/CHANGELOG index 4547883..eef53c4 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,10 @@ +2022-02-20 - v1.3.8 ++ Updates to used libraries. ++ Added build hashes and support for more 1.x vanilla builds. +* Fixed issue with bot not sending messages longer than 255 characters, since this is unsupported by WoW clients. + Instead, the bot will split up these messages and send them in multiple chat packets. +* Fixed issue with bot not sending Discord messages which are replies. + 2020-10-27 - v1.3.4/v1.3.5/v1.3.6 * Update to new Discord Library. This is a mandatory update. Using an old version will not connect to Discord. (Issue #45) * Added support for Discord Gateway Intents and appropriate requirement messages to users. (Issue #47) diff --git a/README.md b/README.md index f969210..dfffca4 100644 --- a/README.md +++ b/README.md @@ -119,6 +119,6 @@ Even though this bot does not do anything malicious, some servers may not like a OR to compile yourself: 1. WoW Chat is written in Scala and compiles to a Java executable using [maven](https://maven.apache.org). 2. It uses Java JDK 1.8 and Scala 2.12.12. -3. Run `mvn clean package` which will produce a file in the target folder called `wowchat-1.3.7.zip` -4. unzip `wowchat-1.3.7.zip`, edit the configuration file and run `java -jar wowchat.jar ` +3. Run `mvn clean package` which will produce a file in the target folder called `wowchat-1.3.8.zip` +4. unzip `wowchat-1.3.8.zip`, edit the configuration file and run `java -jar wowchat.jar ` * If no config file is supplied, the bot will try to use `wowchat.conf` diff --git a/pom.xml b/pom.xml index d542546..848bf08 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ wowchat wowchat - 1.3.7 + 1.3.8 1.8 @@ -25,32 +25,32 @@ ch.qos.logback logback-classic - 1.2.3 + 1.2.10 com.typesafe.scala-logging scala-logging_${scala.version.major} - 3.9.2 + 3.9.4 com.typesafe config - 1.3.4 + 1.4.2 io.netty netty-all - 4.1.63.Final + 4.1.74.Final net.dv8tion JDA - 4.2.1_265 + 4.4.0_352 club.minnced diff --git a/src/main/scala/wowchat/WoWChat.scala b/src/main/scala/wowchat/WoWChat.scala index cf6f5af..219d0f3 100644 --- a/src/main/scala/wowchat/WoWChat.scala +++ b/src/main/scala/wowchat/WoWChat.scala @@ -13,7 +13,7 @@ import scala.io.Source object WoWChat extends StrictLogging { - private val RELEASE = "v1.3.7" + private val RELEASE = "v1.3.8" def main(args: Array[String]): Unit = { logger.info(s"Running WoWChat - $RELEASE") diff --git a/src/main/scala/wowchat/common/Config.scala b/src/main/scala/wowchat/common/Config.scala index 3338ec5..e0b1db0 100644 --- a/src/main/scala/wowchat/common/Config.scala +++ b/src/main/scala/wowchat/common/Config.scala @@ -77,6 +77,13 @@ object WowChatConfig extends GamePackets { lazy val getBuild: Int = { Global.config.wow.build.getOrElse( version match { + case "1.6.1" => 4544 + case "1.6.2" => 4565 + case "1.6.3" => 4620 + case "1.7.1" => 4695 + case "1.8.4" => 4878 + case "1.9.4" => 5086 + case "1.10.2" => 5302 case "1.11.2" => 5464 case "1.12.1" => 5875 case "1.12.2" => 6005 diff --git a/src/main/scala/wowchat/discord/Discord.scala b/src/main/scala/wowchat/discord/Discord.scala index a22e8c9..39458d6 100644 --- a/src/main/scala/wowchat/discord/Discord.scala +++ b/src/main/scala/wowchat/discord/Discord.scala @@ -227,7 +227,8 @@ class Discord(discordConnectionCallback: CommonConnectionCallback) extends Liste } // ignore non-default messages - if (event.getMessage.getType != MessageType.DEFAULT) { + val messageType = event.getMessage.getType + if (messageType != MessageType.DEFAULT && messageType != MessageType.INLINE_REPLY) { return } @@ -247,31 +248,23 @@ class Discord(discordConnectionCallback: CommonConnectionCallback) extends Liste .get(channelName) .fold(Global.discordToWow.get(channelId))(Some(_)) .foreach(_.foreach(channelConfig => { - val finalMessage = if (shouldSendDirectly(message)) { - message + val finalMessages = if (shouldSendDirectly(message)) { + Seq(message) } else { - val formatted = channelConfig.format - .replace("%time", Global.getTime) - .replace("%user", effectiveName) - .replace("%message", message) - - // If the final formatted message is a dot command, it should be disabled. Add a space in front. - if (formatted.startsWith(".")) { - s" $formatted" - } else { - formatted - } + splitUpMessage(channelConfig.format, effectiveName, message) } - val filter = shouldFilter(channelConfig.filters, message) - logger.info(s"${if (filter) "FILTERED " else ""}Discord->WoW(${ - channelConfig.channel.getOrElse(ChatEvents.valueOf(channelConfig.tp)) - }) [$effectiveName]: $message") - if (!filter) { - Global.game.fold(logger.error("Cannot send message! Not connected to WoW!"))(handler => { - handler.sendMessageToWow(channelConfig.tp, finalMessage, channelConfig.channel) - }) - } + finalMessages.foreach(finalMessage => { + val filter = shouldFilter(channelConfig.filters, finalMessage) + logger.info(s"${if (filter) "FILTERED " else ""}Discord->WoW(${ + channelConfig.channel.getOrElse(ChatEvents.valueOf(channelConfig.tp)) + }) $finalMessage") + if (!filter) { + Global.game.fold(logger.error("Cannot send message! Not connected to WoW!"))(handler => { + handler.sendMessageToWow(channelConfig.tp, finalMessage, channelConfig.channel) + }) + } + }) })) } } @@ -305,4 +298,45 @@ class Discord(discordConnectionCallback: CommonConnectionCallback) extends Liste def sanitizeMessage(message: String): String = { EmojiParser.parseToAliases(message, EmojiParser.FitzpatrickAction.REMOVE) } + + def splitUpMessage(format: String, name: String, message: String): Seq[String] = { + val retArr = mutable.ArrayBuffer.empty[String] + val maxTmpLen = 255 - format + .replace("%time", Global.getTime) + .replace("%user", name) + .replace("%message", "") + .length + + var tmp = message + while (tmp.length > maxTmpLen) { + val subStr = tmp.substring(0, maxTmpLen) + val spaceIndex = subStr.lastIndexOf(' ') + tmp = if (spaceIndex == -1) { + retArr += subStr + tmp.substring(maxTmpLen) + } else { + retArr += subStr.substring(0, spaceIndex) + tmp.substring(spaceIndex + 1) + } + } + + if (tmp.nonEmpty) { + retArr += tmp + } + + retArr + .map(message => { + val formatted = format + .replace("%time", Global.getTime) + .replace("%user", name) + .replace("%message", message) + + // If the final formatted message is a dot command, it should be disabled. Add a space in front. + if (formatted.startsWith(".")) { + s" $formatted" + } else { + formatted + } + }) + } } diff --git a/src/main/scala/wowchat/realm/RealmPacketHandler.scala b/src/main/scala/wowchat/realm/RealmPacketHandler.scala index 5d793a8..173872b 100644 --- a/src/main/scala/wowchat/realm/RealmPacketHandler.scala +++ b/src/main/scala/wowchat/realm/RealmPacketHandler.scala @@ -21,17 +21,37 @@ class RealmPacketHandler(realmConnectionCallback: RealmConnectionCallback) private var logonState = 0 private val buildCrcHashes = Map( - (5875, Platform.Mac) + (4544, Platform.Windows) // 1.6.1 + -> Array(0xD7, 0xAC, 0x29, 0x0C, 0xC2, 0xE4, 0x2F, 0x9C, 0xC8, 0x3A, 0x90, 0x23, 0x80, 0x3A, 0x43, 0x24, 0x43, 0x59, 0xF0, 0x30).map(_.toByte), + (4565, Platform.Windows) // 1.6.2 + -> Array(0x1A, 0xC0, 0x2C, 0xE9, 0x3E, 0x7B, 0x82, 0xD1, 0x7E, 0x87, 0x18, 0x75, 0x8D, 0x67, 0xF5, 0x9F, 0xB0, 0xCA, 0x4B, 0x5D).map(_.toByte), + (4620, Platform.Windows) // 1.6.3 + -> Array(0x3C, 0x77, 0xED, 0x95, 0xD6, 0x00, 0xF9, 0xD4, 0x27, 0x0D, 0xA1, 0xA2, 0x91, 0xC7, 0xF6, 0x45, 0xCA, 0x4F, 0x2A, 0xAC).map(_.toByte), + (4695, Platform.Windows) // 1.7.1 + -> Array(0x37, 0xC0, 0x12, 0x91, 0x27, 0x1C, 0xBB, 0x89, 0x1D, 0x8F, 0xEE, 0xC1, 0x5B, 0x2F, 0x14, 0x7A, 0xA3, 0xE4, 0x0C, 0x80).map(_.toByte), + (4878, Platform.Windows) // 1.8.4 + -> Array(0x03, 0xDF, 0xB3, 0xC3, 0xF7, 0x24, 0x79, 0xF9, 0xBC, 0xC5, 0xED, 0xD8, 0xDC, 0xA1, 0x02, 0x5E, 0x8D, 0x11, 0xAF, 0x0F).map(_.toByte), + (5086, Platform.Windows) // 1.9.4 + -> Array(0xC5, 0x61, 0xB5, 0x2B, 0x3B, 0xDD, 0xDD, 0x17, 0x6A, 0x46, 0x43, 0x3C, 0x6D, 0x06, 0x7B, 0xA7, 0x45, 0xE6, 0xB0, 0x00).map(_.toByte), + (5302, Platform.Windows) // 1.10.2 + -> Array(0x70, 0xDD, 0x18, 0x3C, 0xE6, 0x71, 0xE7, 0x99, 0x09, 0xE0, 0x25, 0x54, 0xE9, 0x4C, 0xBE, 0x3F, 0x2C, 0x33, 0x8C, 0x55).map(_.toByte), + (5464, Platform.Windows) // 1.11.2 + -> Array(0x4D, 0xF8, 0xA5, 0x05, 0xE4, 0xFE, 0x8D, 0x83, 0x33, 0x50, 0x8C, 0x0E, 0x85, 0x84, 0x65, 0xE3, 0x57, 0x17, 0x86, 0x83).map(_.toByte), + (5875, Platform.Mac) // 1.12.1 -> Array(0x8D, 0x17, 0x3C, 0xC3, 0x81, 0x96, 0x1E, 0xEB, 0xAB, 0xF3, 0x36, 0xF5, 0xE6, 0x67, 0x5B, 0x10, 0x1B, 0xB5, 0x13, 0xE5).map(_.toByte), - (5875, Platform.Windows) + (5875, Platform.Windows) // 1.12.1 -> Array(0x95, 0xED, 0xB2, 0x7C, 0x78, 0x23, 0xB3, 0x63, 0xCB, 0xDD, 0xAB, 0x56, 0xA3, 0x92, 0xE7, 0xCB, 0x73, 0xFC, 0xCA, 0x20).map(_.toByte), - (8606, Platform.Mac) + (6005, Platform.Windows) // 1.12.2 + -> Array(0x06, 0x97, 0x32, 0x38, 0x76, 0x56, 0x96, 0x41, 0x48, 0x79, 0x28, 0xFD, 0xC7, 0xC9, 0xE3, 0x3B, 0x44, 0x70, 0xC8, 0x80).map(_.toByte), + (6141, Platform.Windows) // 1.12.3 + -> Array(0x2E, 0x52, 0x36, 0xE5, 0x66, 0xAE, 0xA9, 0xBF, 0xFA, 0x0C, 0xC0, 0x41, 0x67, 0x9C, 0x2D, 0xB5, 0x2E, 0x21, 0xC9, 0xDC).map(_.toByte), + (8606, Platform.Mac) // 2.4.3 -> Array(0xD8, 0xB0, 0xEC, 0xFE, 0x53, 0x4B, 0xC1, 0x13, 0x1E, 0x19, 0xBA, 0xD1, 0xD4, 0xC0, 0xE8, 0x13, 0xEE, 0xE4, 0x99, 0x4F).map(_.toByte), - (8606, Platform.Windows) + (8606, Platform.Windows) // 2.4.3 -> Array(0x31, 0x9A, 0xFA, 0xA3, 0xF2, 0x55, 0x96, 0x82, 0xF9, 0xFF, 0x65, 0x8B, 0xE0, 0x14, 0x56, 0x25, 0x5F, 0x45, 0x6F, 0xB1).map(_.toByte), - (12340, Platform.Mac) + (12340, Platform.Mac) // 3.3.5 -> Array(0xB7, 0x06, 0xD1, 0x3F, 0xF2, 0xF4, 0x01, 0x88, 0x39, 0x72, 0x94, 0x61, 0xE3, 0xF8, 0xA0, 0xE2, 0xB5, 0xFD, 0xC0, 0x34).map(_.toByte), - (12340, Platform.Windows) + (12340, Platform.Windows) // 3.3.5 -> Array(0xCD, 0xCB, 0xBD, 0x51, 0x88, 0x31, 0x5E, 0x6B, 0x4D, 0x19, 0x44, 0x9D, 0x49, 0x2D, 0xBC, 0xFA, 0xF1, 0x56, 0xA3, 0x47).map(_.toByte) )