Merge branch 'develop' of https://git.pthub.vn/Unity/perfect-world-unity into feature/friend_ui
This commit is contained in:
@@ -230,7 +230,6 @@ namespace BrewMonster
|
||||
|
||||
base.Tick(dwDeltaTime);
|
||||
|
||||
|
||||
// Spawn fly GFX when entering Flying state / 进入飞行状态时生成飞行特效
|
||||
if (prevState == GfxSkillEventState.enumWait && m_enumState == GfxSkillEventState.enumFlying)
|
||||
{
|
||||
@@ -295,7 +294,7 @@ namespace BrewMonster
|
||||
protected override void HitTarget(Vector3 vTarget)
|
||||
{
|
||||
base.HitTarget(vTarget);
|
||||
|
||||
|
||||
// Only destroy fly GFX if NOT tracing target
|
||||
// If tracing target, fly GFX will be cleaned up when buff expires
|
||||
// 只有在不跟踪目标时才销毁飞行特效
|
||||
@@ -311,10 +310,9 @@ namespace BrewMonster
|
||||
if (m_flyGfxInstance != null)
|
||||
{
|
||||
SkillGfxMan.InstanceSub?.AddTraceTargetGfx(m_flyGfxInstance, 0); // Skill ID not available, use 0
|
||||
BMLogger.Log($"[TRACE_TARGET_GFX] HitTarget: Added fly GFX to trace target list (m_bTraceTarget=true)");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SpawnHitGfx(vTarget);
|
||||
|
||||
// TODO Phase 2: Special hit effects (rune, critical, nullity)
|
||||
@@ -356,7 +354,6 @@ namespace BrewMonster
|
||||
if (m_bTraceTarget)
|
||||
{
|
||||
SkillGfxMan.InstanceSub?.AddTraceTargetGfx(m_flyGfxInstance, 0); // Skill ID not available, use 0
|
||||
BMLogger.Log($"[TRACE_TARGET_GFX] SpawnFlyGfx: Added fly GFX to trace target list (m_bTraceTarget=true)");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -489,7 +486,7 @@ namespace BrewMonster
|
||||
DestroyFlyGfx();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (m_hitGfxInstance != null)
|
||||
{
|
||||
if (SkillGfxMan.InstanceSub != null && !SkillGfxMan.InstanceSub.IsTraceTargetGfx(m_hitGfxInstance))
|
||||
@@ -499,7 +496,7 @@ namespace BrewMonster
|
||||
m_hitGfxInstance = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
base.Resume();
|
||||
}
|
||||
|
||||
@@ -515,7 +512,7 @@ namespace BrewMonster
|
||||
// Program integration\\Hit\\Invalid attack hit.gfx
|
||||
szPath = "程序联入\\击中\\无效攻击击中.gfx";
|
||||
}
|
||||
|
||||
|
||||
// TODO: return AfxGetGFXExMan()->LoadGfx(pDev, szPath);
|
||||
return null;
|
||||
}*/
|
||||
@@ -526,7 +523,7 @@ namespace BrewMonster
|
||||
/// </summary>
|
||||
/*public void SetHitGfx(A3DGFXEx pHitGfx)
|
||||
{
|
||||
// if (m_dwModifier & CECAttackEvent::MOD_CRITICAL_STRIKE)
|
||||
// if (m_dwModifier & CECAttackEvent::MOD_CRITICAL_STRIKE)
|
||||
// pHitGfx->SetActualScale(pHitGfx->GetScale() * 2.0f);
|
||||
m_pHitGfx = pHitGfx;
|
||||
}*/
|
||||
@@ -1052,8 +1049,6 @@ namespace BrewMonster
|
||||
{
|
||||
m_TraceTargetGfxList.Add(gfxInstance);
|
||||
m_TraceTargetGfxSkillMap[gfxInstance] = skillId;
|
||||
|
||||
BMLogger.Log($"[TRACE_TARGET_GFX] Added GFX for skill {skillId}, total tracked: {m_TraceTargetGfxList.Count}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1063,8 +1058,6 @@ namespace BrewMonster
|
||||
/// </summary>
|
||||
public void RemoveAllTraceTargetGfx()
|
||||
{
|
||||
BMLogger.Log($"[TRACE_TARGET_GFX] Removing {m_TraceTargetGfxList.Count} trace target GFX");
|
||||
|
||||
foreach (GameObject gfx in m_TraceTargetGfxList)
|
||||
{
|
||||
if (gfx != null)
|
||||
@@ -1102,11 +1095,6 @@ namespace BrewMonster
|
||||
m_TraceTargetGfxList.Remove(gfx);
|
||||
m_TraceTargetGfxSkillMap.Remove(gfx);
|
||||
}
|
||||
|
||||
if (toRemove.Count > 0)
|
||||
{
|
||||
BMLogger.Log($"[TRACE_TARGET_GFX] Removed {toRemove.Count} GFX for skill {skillId}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* CREATED BY: Duyuxin, 2005/1/5
|
||||
* CONVERTED TO C#: 2025
|
||||
*
|
||||
* HISTORY:
|
||||
* HISTORY:
|
||||
*
|
||||
* Copyright (c) 2005 Archosaur Studio, All Rights Reserved.
|
||||
*/
|
||||
@@ -271,7 +271,7 @@ namespace BrewMonster
|
||||
{
|
||||
m_aShortcuts[iSlot] = null;
|
||||
}
|
||||
BMLogger.LogError("SetShortcut iSlot= " + iSlot);
|
||||
// BMLogger.LogError("SetShortcut iSlot= " + iSlot);
|
||||
m_aShortcuts[iSlot] = pShortcut;
|
||||
}
|
||||
|
||||
@@ -500,10 +500,10 @@ namespace BrewMonster
|
||||
// Record shortcut's position and type
|
||||
data.AddRange(BitConverter.GetBytes(i));
|
||||
data.AddRange(BitConverter.GetBytes((int)pSC.GetType()));
|
||||
|
||||
|
||||
BMLogger.Log($"[MH] Saving shortcut slot: {i} Type: {pSC.GetType()}");
|
||||
|
||||
// TODO: implement other shortcut types
|
||||
// TODO: implement other shortcut types
|
||||
switch ((CECShortcut.ShortcutType)pSC.GetType())
|
||||
{
|
||||
/* case CECShortcut.ShortcutType.SCT_COMMAND:
|
||||
@@ -595,7 +595,7 @@ namespace BrewMonster
|
||||
|
||||
int iSCType = GPDataTypeHelper.FromBytes<int>(pDataBuf, offset);
|
||||
offset += sizeof(int);
|
||||
|
||||
|
||||
//BMLogger.Log("[MH] Loading shortcut slot: " + iSlot + " Type: " + iSCType);
|
||||
|
||||
switch ((CECShortcut.ShortcutType)iSCType)
|
||||
@@ -744,7 +744,7 @@ namespace BrewMonster
|
||||
}
|
||||
|
||||
/* default:
|
||||
//TODO: uncomment
|
||||
//TODO: uncomment
|
||||
//BMLogger.LogError("CECShortcutSet::LoadConfigData - Unknown shortcut type");
|
||||
return false;*/
|
||||
}
|
||||
@@ -770,7 +770,7 @@ namespace BrewMonster
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
}
|
||||
|
||||
#region Placeholder Classes
|
||||
@@ -1124,11 +1124,11 @@ namespace BrewMonster
|
||||
|
||||
public override ShortcutType GetType() => ShortcutType.SCT_ITEM;
|
||||
public override CECShortcut Clone() => null;
|
||||
public bool Init(int iIvtr, int iSlot, CECIvtrItem pItem)
|
||||
{
|
||||
m_iInventory = iIvtr;
|
||||
m_iIvtrSlot = iSlot;
|
||||
return true;
|
||||
public bool Init(int iIvtr, int iSlot, CECIvtrItem pItem)
|
||||
{
|
||||
m_iInventory = iIvtr;
|
||||
m_iIvtrSlot = iSlot;
|
||||
return true;
|
||||
}
|
||||
public int GetInventory() => m_iInventory;
|
||||
public int GetIvtrSlot() => m_iIvtrSlot;
|
||||
@@ -1175,15 +1175,15 @@ namespace BrewMonster
|
||||
|
||||
// Placeholder classes for dependencies
|
||||
public class CECIvtrItem { }
|
||||
public class CECInventory
|
||||
{
|
||||
public CECIvtrItem GetItem(int slot) => null;
|
||||
public class CECInventory
|
||||
{
|
||||
public CECIvtrItem GetItem(int slot) => null;
|
||||
}
|
||||
public class CECHostGoblin
|
||||
{
|
||||
public CECSkill GetSkillByID(int id) => null;
|
||||
public class CECHostGoblin
|
||||
{
|
||||
public CECSkill GetSkillByID(int id) => null;
|
||||
}*/
|
||||
|
||||
|
||||
// class CECSCSysModule : public CECShortcut
|
||||
public class CECSCSysModule : CECShortcut
|
||||
{
|
||||
|
||||
@@ -7,6 +7,8 @@ namespace BrewMonster.PerfectWorld.Scripts.Utility.ChatFilter
|
||||
{
|
||||
public class ChatFilter
|
||||
{
|
||||
private const string BadWordReplacement = "**";
|
||||
|
||||
private HashSet<string> badWordSet = new HashSet<string>();
|
||||
|
||||
// =========================
|
||||
@@ -26,14 +28,16 @@ namespace BrewMonster.PerfectWorld.Scripts.Utility.ChatFilter
|
||||
// =========================
|
||||
// NORMALIZE
|
||||
// =========================
|
||||
private string NormalizeRuntime(string input, out List<int> map)
|
||||
private string NormalizeRuntime(string input, out List<int> charMap, out List<(int start, int end)> tokenRanges)
|
||||
{
|
||||
map = new List<int>();
|
||||
charMap = new List<int>();
|
||||
tokenRanges = new List<(int, int)>();
|
||||
|
||||
string formD = input.Normalize(NormalizationForm.FormD);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
bool lastWasSpace = false;
|
||||
bool inToken = false;
|
||||
int tokenStart = -1;
|
||||
|
||||
for (int i = 0; i < formD.Length; i++)
|
||||
{
|
||||
@@ -47,22 +51,32 @@ namespace BrewMonster.PerfectWorld.Scripts.Utility.ChatFilter
|
||||
|
||||
if (n == '\0')
|
||||
{
|
||||
if (!lastWasSpace)
|
||||
if (inToken)
|
||||
{
|
||||
sb.Append(' ');
|
||||
map.Add(i);
|
||||
lastWasSpace = true;
|
||||
tokenRanges.Add((tokenStart, charMap.Count - 1));
|
||||
inToken = false;
|
||||
}
|
||||
|
||||
sb.Append(' ');
|
||||
charMap.Add(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!inToken)
|
||||
{
|
||||
tokenStart = charMap.Count;
|
||||
inToken = true;
|
||||
}
|
||||
|
||||
sb.Append(n);
|
||||
map.Add(i);
|
||||
lastWasSpace = false;
|
||||
charMap.Add(i);
|
||||
}
|
||||
}
|
||||
|
||||
return sb.ToString().Trim();
|
||||
if (inToken)
|
||||
tokenRanges.Add((tokenStart, charMap.Count - 1));
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private char NormalizeChar(char c)
|
||||
@@ -138,21 +152,75 @@ namespace BrewMonster.PerfectWorld.Scripts.Utility.ChatFilter
|
||||
return false;
|
||||
}
|
||||
|
||||
private static List<(int start, int end)> MergeOverlappingSpans(List<(int start, int end)> spans)
|
||||
{
|
||||
if (spans == null || spans.Count == 0)
|
||||
return spans;
|
||||
|
||||
spans.Sort((a, b) => a.start.CompareTo(b.start));
|
||||
|
||||
var merged = new List<(int start, int end)>(spans.Count);
|
||||
foreach (var span in spans)
|
||||
{
|
||||
if (merged.Count == 0)
|
||||
{
|
||||
merged.Add(span);
|
||||
continue;
|
||||
}
|
||||
|
||||
var last = merged[merged.Count - 1];
|
||||
if (span.start <= last.end)
|
||||
merged[merged.Count - 1] = (last.start, Math.Max(last.end, span.end));
|
||||
else
|
||||
merged.Add(span);
|
||||
}
|
||||
|
||||
return merged;
|
||||
}
|
||||
|
||||
private static string BuildFilteredString(string input, List<(int start, int end)> mergedSpans, string replacement)
|
||||
{
|
||||
if (mergedSpans == null || mergedSpans.Count == 0)
|
||||
return input;
|
||||
|
||||
var sb = new StringBuilder(input.Length);
|
||||
int last = 0;
|
||||
|
||||
foreach (var (s, e) in mergedSpans)
|
||||
{
|
||||
if (s > last)
|
||||
sb.Append(input, last, s - last);
|
||||
|
||||
sb.Append(replacement);
|
||||
last = e + 1;
|
||||
}
|
||||
|
||||
if (last < input.Length)
|
||||
sb.Append(input, last, input.Length - last);
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
// =========================
|
||||
// FILTER
|
||||
// =========================
|
||||
public string Filter(string input, out bool isValidWord)
|
||||
{
|
||||
isValidWord = false;
|
||||
|
||||
if (string.IsNullOrEmpty(input))
|
||||
return input;
|
||||
|
||||
isValidWord = true;
|
||||
List<int> map;
|
||||
string normalized = NormalizeRuntime(input, out map);
|
||||
|
||||
List<int> charMap;
|
||||
List<(int start, int end)> tokenRanges;
|
||||
|
||||
string normalized = NormalizeRuntime(input, out charMap, out tokenRanges);
|
||||
|
||||
var tokens = normalized.Split(' ', StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
char[] result = input.ToCharArray();
|
||||
var matchSpans = new List<(int start, int end)>();
|
||||
|
||||
for (int i = 0; i < tokens.Length; i++)
|
||||
{
|
||||
@@ -161,23 +229,27 @@ namespace BrewMonster.PerfectWorld.Scripts.Utility.ChatFilter
|
||||
int startToken = i;
|
||||
int endToken = i + len - 1;
|
||||
|
||||
int startChar = FindCharIndex(normalized, startToken, map);
|
||||
int endChar = FindCharIndex(normalized, endToken, map);
|
||||
|
||||
if (startChar >= 0 && endChar >= 0)
|
||||
if (startToken < tokenRanges.Count && endToken < tokenRanges.Count)
|
||||
{
|
||||
for (int k = startChar; k <= endChar && k < result.Length; k++)
|
||||
{
|
||||
result[k] = '*';
|
||||
isValidWord = false;
|
||||
}
|
||||
int normStart = tokenRanges[startToken].start;
|
||||
int normEnd = tokenRanges[endToken].end;
|
||||
|
||||
int realStart = charMap[normStart];
|
||||
int realEnd = charMap[normEnd];
|
||||
|
||||
matchSpans.Add((realStart, realEnd));
|
||||
isValidWord = false;
|
||||
}
|
||||
|
||||
i += len - 1;
|
||||
}
|
||||
}
|
||||
|
||||
return new string(result);
|
||||
if (matchSpans.Count == 0)
|
||||
return input;
|
||||
|
||||
var merged = MergeOverlappingSpans(matchSpans);
|
||||
return BuildFilteredString(input, merged, BadWordReplacement);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,11 @@ namespace BrewMonster.PerfectWorld.Editor.ChatFilter
|
||||
RunTest();
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Run plan examples", GUILayout.Height(28)))
|
||||
{
|
||||
RunPlanExamplesFromCleanWords();
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Clear", GUILayout.Width(72), GUILayout.Height(28)))
|
||||
{
|
||||
_input = "";
|
||||
@@ -78,5 +83,38 @@ namespace BrewMonster.PerfectWorld.Editor.ChatFilter
|
||||
_hasRun = true;
|
||||
Repaint();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs sample inputs that use entries from clean_words.txt (plan: ** replacement, spaces preserved).
|
||||
/// </summary>
|
||||
private static void RunPlanExamplesFromCleanWords()
|
||||
{
|
||||
ChatFilterService.Init();
|
||||
|
||||
var cases = new[]
|
||||
{
|
||||
("con chó", "con **", false),
|
||||
("bitch cho", "** **", false),
|
||||
("hello world", "hello world", true),
|
||||
};
|
||||
|
||||
int failed = 0;
|
||||
foreach (var (input, expectedFiltered, expectedValid) in cases)
|
||||
{
|
||||
string got = ChatFilterService.Filter(input, out bool isValid);
|
||||
bool ok = got == expectedFiltered && isValid == expectedValid;
|
||||
if (!ok)
|
||||
{
|
||||
failed++;
|
||||
Debug.LogWarning(
|
||||
$"[ChatFilter plan check] FAIL\n in: {input}\n expected: {expectedFiltered} (valid={expectedValid})\n got: {got} (valid={isValid})");
|
||||
}
|
||||
else
|
||||
Debug.Log($"[ChatFilter plan check] OK: \"{input}\" -> \"{got}\"");
|
||||
}
|
||||
|
||||
if (failed == 0)
|
||||
Debug.Log("[ChatFilter plan check] All examples passed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using BrewMonster.Network;
|
||||
using BrewMonster.UI;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using BrewMonster.PerfectWorld.Scripts.Utility.ChatFilter;
|
||||
using BrewMonster.Scripts.Managers;
|
||||
using UnityEngine;
|
||||
using TMPro;
|
||||
@@ -299,7 +300,7 @@ public class CECUIManager : MonoSingleton<CECUIManager>
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public CDlgMessageBox ShowMessageBoxYes(string title, string message, AUIDialog dlg, Action onClickedYes)
|
||||
{
|
||||
var msgBox = GetInGameUIMan().GetDialog("DlgMessageBox") as CDlgMessageBox;
|
||||
@@ -336,7 +337,7 @@ public class CECUIManager : MonoSingleton<CECUIManager>
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
// public CDlgMessageBox ShowMessageBox(MessageBoxData messageBoxData)
|
||||
// {
|
||||
// var msgBox = GetInGameUIMan().GetDialog("DlgMessageBox") as CDlgMessageBox;
|
||||
@@ -467,7 +468,7 @@ public class CECUIManager : MonoSingleton<CECUIManager>
|
||||
// g_pGame->GetGameRun()->GetPendingLogOut().AppendForSaveConfig(new CECPendingLogoutCrossServer());
|
||||
// else
|
||||
// g_pGame->GetGameRun()->GetPendingLogOut().AppendForSaveConfig(new CECPendingLogoutHalf());
|
||||
|
||||
|
||||
EC_Game.GetGameRun().GetPendingLogOut().AppendForSaveConfig(new CECPendingLogoutHalf());
|
||||
}
|
||||
else
|
||||
@@ -714,7 +715,7 @@ public class CECUIManager : MonoSingleton<CECUIManager>
|
||||
// {
|
||||
// EC_Game.GetGameRun().StartGame(0, Vector3.zero);
|
||||
// }
|
||||
|
||||
|
||||
CECShortcut pSC = EC_Game.GetGameRun().GetPoseCmdShortcuts().GetShortcut(slot);
|
||||
if (pSC != null) // && pObjSrc->GetDataPtr("ptr_CECShortcut") == pSC
|
||||
{
|
||||
@@ -775,29 +776,6 @@ public class CECUIManager : MonoSingleton<CECUIManager>
|
||||
|
||||
public void FilterBadWords(ref string str)
|
||||
{
|
||||
if (string.IsNullOrEmpty(str))
|
||||
return;
|
||||
|
||||
string strLwr = str.ToLower();
|
||||
|
||||
char[] chars = str.ToCharArray();
|
||||
|
||||
foreach (string bad in gameUI.m_vecBadWords)
|
||||
{
|
||||
int pos = 0;
|
||||
string badLwr = bad.ToLower();
|
||||
|
||||
while ((pos = strLwr.IndexOf(badLwr, pos, StringComparison.Ordinal)) >= 0)
|
||||
{
|
||||
for (int j = 0; j < badLwr.Length; j++)
|
||||
{
|
||||
chars[pos + j] = '*';
|
||||
}
|
||||
|
||||
pos += badLwr.Length;
|
||||
}
|
||||
}
|
||||
|
||||
str = new string(chars);
|
||||
str = ChatFilterService.Filter(str, out var isValidWord);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ namespace BrewMonster.Scripts.ChatUI
|
||||
public List<ChannelButtonMapping> channelButtons = new();
|
||||
|
||||
private const int MAX_HISTORY = 10;
|
||||
private ChatChannel m_currentChannel = ChatChannel.GP_CHAT_LOCAL;
|
||||
|
||||
private struct ChatMsg
|
||||
{
|
||||
@@ -57,6 +58,13 @@ namespace BrewMonster.Scripts.ChatUI
|
||||
{
|
||||
OnCommand_speakmode(channelButtons[0].channel);
|
||||
}
|
||||
|
||||
// [Mobile Fix] Giữ cho chữ được hiển thị trực tiếp trên UI của game thay vì bị
|
||||
// đẩy vào một thanh ngang phụ (Native OS Input) bật lên cùng bàn phím.
|
||||
if (inputField != null)
|
||||
{
|
||||
inputField.shouldHideMobileInput = true;
|
||||
}
|
||||
}
|
||||
|
||||
// =====================================================
|
||||
@@ -79,13 +87,34 @@ namespace BrewMonster.Scripts.ChatUI
|
||||
}
|
||||
}
|
||||
|
||||
m_currentChannel = channel;
|
||||
var config = chatSystem.channelIcons.Find(c => c.channel == channel);
|
||||
if (config.prefix != null)
|
||||
{
|
||||
inputField.text = config.prefix;
|
||||
inputField.ActivateInputField();
|
||||
inputField.MoveTextEnd(false);
|
||||
string currentText = inputField.text;
|
||||
currentText = RemoveKnownPrefix(currentText);
|
||||
inputField.text = config.prefix + currentText;
|
||||
}
|
||||
|
||||
inputField.ActivateInputField();
|
||||
inputField.MoveTextEnd(false);
|
||||
}
|
||||
|
||||
private string RemoveKnownPrefix(string text)
|
||||
{
|
||||
if (string.IsNullOrEmpty(text)) return text;
|
||||
|
||||
if (text.StartsWith("!!") || text.StartsWith("!~") ||
|
||||
text.StartsWith("!@") || text.StartsWith("!#"))
|
||||
{
|
||||
return text.Substring(2);
|
||||
}
|
||||
else if (text.StartsWith("$"))
|
||||
{
|
||||
return text.Substring(1);
|
||||
}
|
||||
// Không tự ý remove prefix của Whisper (bắt đầu bằng '/') vì nó đi kèm tên người chơi
|
||||
return text;
|
||||
}
|
||||
|
||||
private void OnSubmit(string text)
|
||||
@@ -242,8 +271,8 @@ namespace BrewMonster.Scripts.ChatUI
|
||||
|
||||
private ChatChannel ParseAndSendMessage(string text, int nPack, int nSlot)
|
||||
{
|
||||
ChatChannel channel;
|
||||
string pszMsg;
|
||||
ChatChannel channel = m_currentChannel;
|
||||
string pszMsg = text;
|
||||
|
||||
if (text.StartsWith("!!"))
|
||||
{
|
||||
@@ -275,11 +304,7 @@ namespace BrewMonster.Scripts.ChatUI
|
||||
HandleWhisper(text, nPack, nSlot);
|
||||
return ChatChannel.GP_CHAT_WHISPER;
|
||||
}
|
||||
else
|
||||
{
|
||||
channel = ChatChannel.GP_CHAT_LOCAL;
|
||||
pszMsg = text;
|
||||
}
|
||||
// Không gõ prefix thủ công thì sẽ dùng m_currentChannel đã được gán ở đầu hàm
|
||||
|
||||
SendChat(channel, pszMsg, nPack, nSlot);
|
||||
return channel;
|
||||
@@ -363,8 +388,11 @@ namespace BrewMonster.Scripts.ChatUI
|
||||
{
|
||||
string strModified = msg;
|
||||
|
||||
// 1. Filter bad words
|
||||
CECUIManager.Instance.FilterBadWords(ref strModified);
|
||||
if (channel is not ChatChannel.GP_CHAT_MISC)
|
||||
{
|
||||
// 1. Filter bad words
|
||||
CECUIManager.Instance.FilterBadWords(ref strModified);
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(strModified))
|
||||
return;
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 598459b2399743b5ba1eb55fd1d9611e
|
||||
guid: 474cab0ba62d0eb45bdc28c5b381eb18
|
||||
timeCreated: 1762861835
|
||||
@@ -0,0 +1,96 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
using CSNetwork;
|
||||
using CSNetwork.GPDataType;
|
||||
using BrewMonster.Common;
|
||||
using UnityEngine;
|
||||
|
||||
// Account login info struct
|
||||
public struct AccountLoginInfo
|
||||
{
|
||||
public uint login_time;
|
||||
public uint login_ip;
|
||||
public uint current_ip;
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
login_time = 0;
|
||||
login_ip = 0;
|
||||
current_ip = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Game runtime partial class
|
||||
partial class CECGameRun
|
||||
{
|
||||
public AccountLoginInfo m_AccountLoginInfo = new AccountLoginInfo();
|
||||
public bool m_bAccountLoginInfoShown = false;
|
||||
public byte m_accountInfoFlag = 0;
|
||||
public bool m_bAccountInfoShown = false;
|
||||
|
||||
public void ResetAccountLoginInfo()
|
||||
{
|
||||
m_AccountLoginInfo.Reset();
|
||||
m_bAccountLoginInfoShown = true;
|
||||
}
|
||||
|
||||
public void ShowAccountLoginInfo()
|
||||
{
|
||||
Debug.Log("[Cuong] ShowAccountLoginInfo");
|
||||
if (!m_bAccountLoginInfoShown)
|
||||
{
|
||||
m_bAccountLoginInfoShown = true;
|
||||
|
||||
// Assuming CECUIConfig::Instance().GetGameUI().bEnableShowIP translates to true for now
|
||||
bool bEnableShowIP = true;
|
||||
if (bEnableShowIP)
|
||||
{
|
||||
// Last login time
|
||||
DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
||||
DateTime t = Epoch.AddSeconds(m_AccountLoginInfo.login_time).ToLocalTime();
|
||||
|
||||
string timeStr = string.Format("({0}-{1:00}-{2:00} {3:00}:{4:00})",
|
||||
t.Year, t.Month, t.Day, t.Hour, t.Minute);
|
||||
string textTime = string.Format("Lần đăng nhập trước: {0}", timeStr); // 9343
|
||||
|
||||
EventBus.Publish(new GameSession.ChatMessageEvent { context = textTime, channel = (byte)ChatChannel.GP_CHAT_SYSTEM });
|
||||
Debug.Log($"[Cuong] ShowAccountLoginInfo {textTime}");
|
||||
|
||||
// Last login IP
|
||||
string ipStr = new IPAddress((long)m_AccountLoginInfo.login_ip).ToString();
|
||||
string textIp = string.Format("IP đăng nhập trước: {0}", ipStr); // 9344
|
||||
|
||||
EventBus.Publish(new GameSession.ChatMessageEvent { context = textIp, channel = (byte)ChatChannel.GP_CHAT_SYSTEM });
|
||||
Debug.Log($"[Cuong] ShowAccountLoginInfo {textIp}");
|
||||
|
||||
// Current login IP
|
||||
string curIpStr = new IPAddress((long)m_AccountLoginInfo.current_ip).ToString();
|
||||
string textCurIp = string.Format("IP đăng nhập hiện tại: {0}", curIpStr); // 9345
|
||||
|
||||
EventBus.Publish(new GameSession.ChatMessageEvent { context = textCurIp, channel = (byte)ChatChannel.GP_CHAT_SYSTEM });
|
||||
Debug.Log($"[Cuong] ShowAccountLoginInfo {textCurIp}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetAccountInfoFlag(byte accountinfo_flag)
|
||||
{
|
||||
m_accountInfoFlag = accountinfo_flag;
|
||||
m_bAccountInfoShown = false;
|
||||
}
|
||||
|
||||
public void ShowAccountInfo()
|
||||
{
|
||||
if (!m_bAccountInfoShown)
|
||||
{
|
||||
m_bAccountInfoShown = true;
|
||||
bool bEnableCompleteAccount = true;
|
||||
if (bEnableCompleteAccount && ((m_accountInfoFlag & 0x03) != 0))
|
||||
{
|
||||
string text = "Hoàn tất thông tin tài khoản..."; // 9347
|
||||
EventBus.Publish(new GameSession.ChatMessageEvent { context = text, channel = (byte)ChatChannel.GP_CHAT_SYSTEM });
|
||||
Debug.Log($"[Cuong] ShowAccountInfo {text}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 598459b2399743b5ba1eb55fd1d9611e
|
||||
timeCreated: 1762861835
|
||||
+349
-29
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user