Fix clean request logout1

This commit is contained in:
HungDK
2026-04-21 10:53:17 +07:00
parent ef0ee9a6dc
commit c9aef9d68d
2 changed files with 55 additions and 6 deletions
@@ -52,6 +52,9 @@ namespace CSNetwork
private Action<RoleInfo> _createRoleCallback;
private RoleInfo _selectedRole;
public bool IsConnected => _networkManager?.IsConnected ?? false;
// When true, suppress *gameplay traffic* (mostly gamedatasend C2S commands) during logout/scene transitions.
// We still allow account/role flow protocols like rolelist/selectrole so "Return to Select Role" can work.
private volatile bool _suppressGameplayTraffic = false;
public static SynchronizationContext Context;
private CECC2SCmdCache m_CmdCache; // C2S command cache
@@ -103,6 +106,17 @@ namespace CSNetwork
#endif
public CECC2SCmdCache CmdCache { get => m_CmdCache; }
public bool IsGameplayTrafficSuppressed => _suppressGameplayTraffic;
public void SetGameplayTrafficSuppressed(bool suppressed, bool clearCachedCmds = true)
{
_suppressGameplayTraffic = suppressed;
if (suppressed && clearCachedCmds)
{
try { m_CmdCache?.RemoveAllCmds(); } catch { /* best-effort */ }
}
}
public GameSession()
{
@@ -551,6 +565,15 @@ namespace CSNetwork
// --- Protocol Sending ---
public void SendProtocol(Protocol protocol, Action complete = null)
{
// During logout/role-select transitions, drop background gameplay commands (gamedatasend).
// Do NOT block rolelist/selectrole/login related protocols.
if (_suppressGameplayTraffic && protocol is gamedatasend)
{
_logger.Log(LogType.Warning,
$"Suppress outgoing: dropped {protocol?.GetType().Name ?? "null"} ({protocol?.GetPType().ToString() ?? "?"})");
return;
}
if (IsConnected)
{
_logger.Log(LogType.Debug,
@@ -1032,8 +1055,9 @@ namespace CSNetwork
int cashAmount = cashData.cash_amount;
PostToUnityContext(() => ShopUIManager.CacheCash(cashAmount));
}
catch (Exception ex)
catch (Exception)
{
// Ignore parse failures for optional cash payload.
}
}
@@ -38,6 +38,8 @@ namespace BrewMonster.Network
private string _username = "";
private string _password = "";
private bool _isIntentionalDisconnect = false;
// When true, prevent all outgoing protocols (background ticks, tasks, etc.) from sending.
private bool _suppressOutgoing = false;
CECStubbornFactionInfoSender m_stubbornFactionInfoSender;
public GameSession GameSession { get => _gameSession; }
@@ -149,8 +151,23 @@ namespace BrewMonster.Network
return;
}
// New login session: allow outgoing again.
Instance.SetSuppressOutgoing(false);
Instance._gameSession.LoginAsync(username, password, onLoginComplete);
}
private void SetSuppressOutgoing(bool suppressed)
{
_suppressOutgoing = suppressed;
try
{
_gameSession?.SetGameplayTrafficSuppressed(suppressed, clearCachedCmds: true);
}
catch (Exception ex)
{
BMLogger.LogError($"SetSuppressOutgoing failed: {ex.Message}");
}
}
public void c2s_SendCmdStopMove(in Vector3 vDest, float fSpeed, int iMoveMode,
byte byDir, ushort wStamp, int iTime)
{
@@ -191,6 +208,9 @@ namespace BrewMonster.Network
{
// Tell LoginScene what to show next.
LogoutFlowState.NextLoginEntry = entryTarget;
// Immediately suppress outgoing protocols so background systems can't send after LOGOUT begins.
SetSuppressOutgoing(true);
_gameSession.Disconnected -= OnUnexpectedDisconnect;
_gameSession.FriendRequestReceived -= OnFriendRequestReceived;
_gameSession.AddFriendResultReceived -= OnAddFriendResultReceived;
@@ -259,9 +279,9 @@ namespace BrewMonster.Network
var ui = all[i];
if (ui == null) continue;
if (!ui.gameObject.scene.IsValid() || ui.gameObject.scene.name != LoginSceneName) continue;
// Avoid hard dependency on method existence (merges may edit LoginScreenUI).
// ui.SendMessage("ApplyLoginEntry", entryTarget, SendMessageOptions.DontRequireReceiver);
ui.ApplyLoginEntry( entryTarget );
// Avoid hard dependency (and potential duplicate symbol ambiguity across merges):
// dispatch by name, do not statically bind here.
ui.SendMessage("ApplyLoginEntry", entryTarget, SendMessageOptions.DontRequireReceiver);
return;
}
}
@@ -415,6 +435,9 @@ namespace BrewMonster.Network
public static void EnterWorldAsync(RoleInfo roleInfo, Action callback = null)
{
BMLogger.Log("EnterWorldAsync !!!!! nay ");
// We are about to re-enter world gameplay: re-enable outgoing gameplay traffic + CmdCache tick.
// Without this, ReturnToSelectRole flow leaves suppression on and the player can't play after re-enter.
Instance.SetSuppressOutgoing(false);
Instance._gameSession.EnterWorldAsync(roleInfo, callback);
}
public static void SendChatData(byte cChannel, in string szMsg, int iPack, int iSlot)
@@ -733,7 +756,7 @@ namespace BrewMonster.Network
actDone?.Invoke(true);
}
void OnDestroy()
new void OnDestroy()
{
// Mark as intentional to prevent showing disconnect message
_isIntentionalDisconnect = true;
@@ -820,7 +843,9 @@ namespace BrewMonster.Network
public void Update()
{
_gameSession?.CmdCache?.Tick(Time.deltaTime);
// Don't tick/schedule outgoing C2S while we're in logout/role-select flow.
if (!_suppressOutgoing)
_gameSession?.CmdCache?.Tick(Time.deltaTime);
#if UNITY_EDITOR
// Debug: Press D to disconnect from server (Editor only)