/************************************************************************* * ModernUO * * Copyright 2019-2026 - ModernUO Development Team * * Email: hi@modernuo.com * * File: IncomingMessagePackets.cs * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * *************************************************************************/ using System; using System.Buffers; namespace Server.Network; public static class IncomingMessagePackets { private static readonly KeywordList m_KeywordList = new(); public static unsafe void Configure() { IncomingPackets.Register(0x03, 0, true, &AsciiSpeech); IncomingPackets.Register(0xAD, 0, true, &UnicodeSpeech); } public static void AsciiSpeech(NetState state, SpanReader reader) { var from = state.Mobile; if (from == null) { return; } var type = (MessageType)reader.ReadByte(); int hue = reader.ReadInt16(); reader.ReadInt16(); // font var text = reader.ReadLatin1Safe().Trim(); if (text.Length is <= 0 or > 128) { return; } if (!Enum.IsDefined(typeof(MessageType), type)) { type = MessageType.Regular; } from.DoSpeech(text, Array.Empty(), type, Utility.ClipDyedHue(hue)); } public static void UnicodeSpeech(NetState state, SpanReader reader) { var from = state.Mobile; if (from == null) { return; } var type = (MessageType)reader.ReadByte(); int hue = reader.ReadInt16(); reader.ReadInt16(); // font var lang = reader.ReadAscii(4); string text; var isEncoded = (type & MessageType.Encoded) != 0; int[] keywords; if (isEncoded) { int value = reader.ReadInt16(); var count = (value & 0xFFF0) >> 4; var hold = value & 0xF; if (count is < 0 or > 50) { return; } var keyList = m_KeywordList; for (var i = 0; i < count; ++i) { int speechID; if ((i & 1) == 0) { hold <<= 8; hold |= reader.ReadByte(); speechID = hold; hold = 0; } else { value = reader.ReadInt16(); speechID = (value & 0xFFF0) >> 4; hold = value & 0xF; } if (!keyList.Contains(speechID)) { keyList.Add(speechID); } } text = reader.ReadUTF8Safe(); keywords = keyList.ToArray(); } else { text = reader.ReadBigUniSafe(); keywords = Array.Empty(); } text = text.Trim(); if (text.Length is <= 0 or > 128) { return; } type &= ~MessageType.Encoded; if (!Enum.IsDefined(typeof(MessageType), type)) { type = MessageType.Regular; } from.Language = lang; from.DoSpeech(text, keywords, type, Utility.ClipDyedHue(hue)); } }