add limit char for chat
This commit is contained in:
@@ -47,3 +47,4 @@ MonoBehaviour:
|
||||
iconName:
|
||||
icon: {fileID: 0}
|
||||
prefix: '!#'
|
||||
maxRawCharactersPerMessage: 80
|
||||
|
||||
@@ -11,6 +11,7 @@ namespace BrewMonster.Scripts.Chat
|
||||
public static class ChatWireTmpCodec
|
||||
{
|
||||
private static readonly Regex SpriteTagRegex = new Regex(@"<sprite\s[^>]*>", RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||
private static readonly Regex OrphanSpriteFragmentRegex = new Regex(@"^\s*sprite\s[^>]*>", RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||
|
||||
/// <summary>
|
||||
/// Tạo một đoạn wire marshal cho một emotion (set:index) — gửi server đúng protocol.
|
||||
@@ -45,19 +46,40 @@ namespace BrewMonster.Scripts.Chat
|
||||
int last = 0;
|
||||
foreach (Match m in SpriteTagRegex.Matches(tmpBody))
|
||||
{
|
||||
sb.Append(tmpBody, last, m.Index - last);
|
||||
AppendSanitizedPlainText(sb, 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;
|
||||
|
||||
// Defensive: TMP_InputField can transiently expose an orphan fragment like
|
||||
// `sprite anim="..."` right after a valid <sprite ...> tag when input updates race.
|
||||
// Skip it so we do not leak malformed rich-text into wire text.
|
||||
var orphan = OrphanSpriteFragmentRegex.Match(tmpBody, last);
|
||||
if (orphan.Success)
|
||||
last += orphan.Length;
|
||||
}
|
||||
|
||||
sb.Append(tmpBody, last, tmpBody.Length - last);
|
||||
AppendSanitizedPlainText(sb, tmpBody, last, tmpBody.Length - last);
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static void AppendSanitizedPlainText(StringBuilder sb, string source, int start, int length)
|
||||
{
|
||||
if (length <= 0)
|
||||
return;
|
||||
|
||||
int end = start + length;
|
||||
for (int i = start; i < end; i++)
|
||||
{
|
||||
char ch = source[i];
|
||||
if (!AUICommon.IsEditboxItemCode(ch))
|
||||
sb.Append(ch);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Khớp tag với EmotionTMPTagBuilder — duyệt (set,index) đủ nhỏ.
|
||||
/// Match tag to EmotionTMPTagBuilder output — brute-force over (set,index) within reasonable bounds.
|
||||
|
||||
@@ -23,5 +23,34 @@ namespace BrewMonster.Scripts.ChatUI
|
||||
|
||||
[Header("Channel Icons")]
|
||||
public List<ChannelIconMapping> channelIcons = new List<ChannelIconMapping>();
|
||||
|
||||
[Header("Message Limits")]
|
||||
[Tooltip("Giới hạn số ký tự thô cho một tin nhắn. <= 0 nghĩa là không giới hạn. " +
|
||||
"TMP tag như <sprite ...> cũng được tính theo đúng số ký tự của tag.")]
|
||||
public int maxRawCharactersPerMessage = 60;
|
||||
|
||||
/// <summary>
|
||||
/// Đếm số ký tự thô (raw) của nội dung đang nhập.
|
||||
/// Count raw characters from current input text.
|
||||
/// </summary>
|
||||
public int CountRawCharacters(string rawText)
|
||||
{
|
||||
if (string.IsNullOrEmpty(rawText))
|
||||
return 0;
|
||||
return rawText.Length;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Kiểm tra có thể dùng thêm reserveChars mà vẫn không vượt giới hạn ký tự thô.
|
||||
/// Check whether reserveChars can be added without exceeding raw character limit.
|
||||
/// </summary>
|
||||
public bool CanUseRawCharacters(string rawText, int reserveChars, out int usedChars, out int limitChars)
|
||||
{
|
||||
limitChars = maxRawCharactersPerMessage;
|
||||
usedChars = CountRawCharacters(rawText) + Mathf.Max(0, reserveChars);
|
||||
if (limitChars <= 0)
|
||||
return true;
|
||||
return usedChars <= limitChars;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,8 +164,9 @@ namespace BrewMonster.Scripts.ChatUI
|
||||
TryAutoWireIfNeeded();
|
||||
if (_chatInput != null)
|
||||
{
|
||||
EmotionTMPTagBuilder.InsertEmotionTag(_chatInput.inputField, _emotionSpriteMap, emotionSet,
|
||||
emotionIndex);
|
||||
// Keep wire body as source of truth to avoid TMP tag race/corruption
|
||||
// when player taps emoji repeatedly.
|
||||
_chatInput.InsertEmoji(emotionSet, emotionIndex);
|
||||
Debug.Log("[Cuong] HandleEmojiClicked.");
|
||||
}
|
||||
else
|
||||
|
||||
@@ -277,7 +277,7 @@ MonoBehaviour:
|
||||
_gridContent: {fileID: 7741139062211830239}
|
||||
_cellPrefab: {fileID: 4685469653980001717, guid: 616f563fe32927844be2a17dbb408331, type: 3}
|
||||
_cellSize: {x: 64, y: 64}
|
||||
_cellSpacing: {x: 4, y: 4}
|
||||
_cellSpacing: {x: 0, y: 4}
|
||||
_columnCount: 8
|
||||
_chatInput: {fileID: 5889020827802476297}
|
||||
_chatSystemUI: {fileID: 2621697629504226575}
|
||||
@@ -746,7 +746,7 @@ MonoBehaviour:
|
||||
m_PressedTrigger: Pressed
|
||||
m_SelectedTrigger: Selected
|
||||
m_DisabledTrigger: Disabled
|
||||
m_Interactable: 0
|
||||
m_Interactable: 1
|
||||
m_TargetGraphic: {fileID: 2689844286198437230}
|
||||
m_OnClick:
|
||||
m_PersistentCalls:
|
||||
@@ -1061,7 +1061,7 @@ MonoBehaviour:
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 0.392}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 0}
|
||||
m_RaycastTarget: 1
|
||||
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_Maskable: 1
|
||||
|
||||
@@ -259,6 +259,9 @@ namespace BrewMonster.Scripts.ChatUI
|
||||
FilterBadWords(ref strText);
|
||||
_chatWireBody = strText;
|
||||
|
||||
if (!CanUseRawCharacters(0))
|
||||
return;
|
||||
|
||||
if (HandleDebugCommand(routingLine))
|
||||
return;
|
||||
|
||||
@@ -752,6 +755,14 @@ namespace BrewMonster.Scripts.ChatUI
|
||||
string segment = ChatWireTmpCodec.BuildMarshaledEmotionWire(emotionSet, emotionIndex);
|
||||
if (string.IsNullOrEmpty(segment))
|
||||
return;
|
||||
|
||||
int reserveChars = 0;
|
||||
if (_spriteMap != null && EmotionTMPTagBuilder.TryBuildEmotionTag(_spriteMap, emotionSet, emotionIndex, out string tag))
|
||||
reserveChars = tag.Length;
|
||||
|
||||
if (!CanUseRawCharacters(reserveChars))
|
||||
return;
|
||||
|
||||
_chatWireBody += segment;
|
||||
RefreshInputDisplayFromWire();
|
||||
}
|
||||
@@ -766,5 +777,18 @@ namespace BrewMonster.Scripts.ChatUI
|
||||
{
|
||||
AppendEmotionWire(emotionSet, emotionIndex);
|
||||
}
|
||||
|
||||
private bool CanUseRawCharacters(int reserveChars)
|
||||
{
|
||||
if (chatSystem == null)
|
||||
return true;
|
||||
|
||||
string rawBody = ExtractMessageBodyFromVisual(inputField != null ? inputField.text ?? "" : "");
|
||||
if (chatSystem.CanUseRawCharacters(rawBody, reserveChars, out int usedChars, out int limitChars))
|
||||
return true;
|
||||
|
||||
//AddChatMessage($"Tin nhan vuot gioi han: {usedChars}/{limitChars} ky tu.", ChatChannel.GP_CHAT_MISC);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user