using System.Text;
using System.Text.RegularExpressions;
using CSNetwork;
namespace BrewMonster.Scripts.Chat
{
///
/// Chat 输入/协议:wire(MarshalEditBoxText)↔ TMP <sprite> 显示。
/// Chat input/protocol: wire (MarshalEditBoxText) ↔ TMP <sprite> display.
///
public static class ChatWireTmpCodec
{
private static readonly Regex SpriteTagRegex = new Regex(@"]*>", RegexOptions.IgnoreCase | RegexOptions.Compiled);
///
/// Tạo một đoạn wire marshal cho một emotion (set:index) — gửi server đúng protocol.
/// Build one marshaled wire segment for a single emotion (set:index) — correct server protocol.
///
public static string BuildMarshaledEmotionWire(int emotionSet, int emotionIndex)
{
var item = new EditBoxItemBase(AUICommon.EditboxItemType.enumEIEmotion);
item.SetName("W");
item.SetInfo(AUICommon.MarshalEmotionInfo(emotionSet, emotionIndex));
var items = new EditBoxItemsSet();
char c = items.AppendItem(item);
if (c == '\0')
return "";
string display = c.ToString();
return AUICommon.MarshalEditBoxText(display, items);
}
///
/// TMP 正文(无频道前缀)→ wire marshal(用于发送)。
/// TMP body text (no channel prefix) → marshaled wire (for sending).
///
public static string TmpBodyToWire(string tmpBody, IEmotionSpriteMap map)
{
if (string.IsNullOrEmpty(tmpBody))
return "";
if (map == null)
return tmpBody;
var sb = new StringBuilder(tmpBody.Length);
int last = 0;
foreach (Match m in SpriteTagRegex.Matches(tmpBody))
{
sb.Append(tmpBody, last, m.Index - last);
string tag = m.Value;
if (TryMatchSpriteTagToEmotion(map, tag, out int es, out int ei))
sb.Append(BuildMarshaledEmotionWire(es, ei));
else
sb.Append(tag);
last = m.Index + m.Length;
}
sb.Append(tmpBody, last, tmpBody.Length - last);
return sb.ToString();
}
///
/// Khớp tag với EmotionTMPTagBuilder — duyệt (set,index) đủ nhỏ.
/// Match tag to EmotionTMPTagBuilder output — brute-force over (set,index) within reasonable bounds.
///
public static bool TryMatchSpriteTagToEmotion(IEmotionSpriteMap map, string spriteTag, out int emotionSet, out int emotionIndex)
{
emotionSet = 0;
emotionIndex = 0;
if (map == null || string.IsNullOrEmpty(spriteTag))
return false;
string normalized = spriteTag.Trim();
for (int s = 0; s < AUICommon.AUIMANAGER_MAX_EMOTIONGROUPS; s++)
{
for (int e = 0; e < 512; e++)
{
if (!EmotionTMPTagBuilder.TryBuildEmotionTag(map, s, e, out string built))
continue;
if (built == normalized)
{
emotionSet = s;
emotionIndex = e;
return true;
}
}
}
return false;
}
///
/// Wire → TMP 富文本(FilterEmotionSet + Unmarshal + ConvertInlineItemsToTmp)。
/// Wire → TMP rich text (FilterEmotionSet + Unmarshal + ConvertInlineItemsToTmp).
///
public static string WireBodyToTmpForDisplay(string wireBody, IEmotionSpriteMap map, int cEmotion)
{
return ChatEmotionDisplayPipeline.ConvertWireBodyToTmpDisplay(wireBody, map, cEmotion);
}
}
}