fix: avoid logger dispose errors in free-play flow
Some checks failed
Gitea Actions Demo / Explore-Gitea-Actions (push) Has been cancelled
Some checks failed
Gitea Actions Demo / Explore-Gitea-Actions (push) Has been cancelled
- Исправлен баг `GameManager.NewGame()`: в режиме бесплатной игры (`payment.freeGame = true`) больше не выполняется проверка/списание баланса. - Добавлен явный guard для free-play перед `Balance.CanStartGame()` и `Balance.SpendBalance(...)`, чтобы не было нежелательных списаний. - Устранена ошибка закрытия лог-файла `Cannot access a disposed object`: - `FileLogger` переведен на безопасный паттерн `Dispose(bool)` с идемпотентностью; - добавлена защита от повторного закрытия/записи в уже закрытый поток; - финализатор `FileLogger` больше не выполняет managed-cleanup. - Устранен риск повторной очистки в `CompositeLogger`: - добавлен флаг `_disposed`; - `Dispose(bool)` теперь выполняется только один раз; - финализатор вызывает `Dispose(false)` вместо полного `Dispose()`.
This commit is contained in:
parent
2963e342c2
commit
1cecbf2c11
@ -288,9 +288,10 @@ public void TogglePause() => SetPause(!IsPaused);
|
||||
public void NewGame()
|
||||
{
|
||||
Debug.Log("[GameManager] NewGame called");
|
||||
bool isFreeGame = Settings != null && Settings.GetBool("payment.freeGame");
|
||||
|
||||
// Проверка баланса перед началом игры
|
||||
if (Balance != null && !Balance.CanStartGame())
|
||||
if (!isFreeGame && Balance != null && !Balance.CanStartGame())
|
||||
{
|
||||
Logger?.Log(gameObject.name, "Cannot start game - insufficient balance");
|
||||
Debug.LogWarning("[GameManager] Cannot start - insufficient balance");
|
||||
@ -300,7 +301,7 @@ public void TogglePause() => SetPause(!IsPaused);
|
||||
int livesToGive = StartingLives;
|
||||
int balanceToSpend = 0;
|
||||
|
||||
if (Balance != null)
|
||||
if (!isFreeGame && Balance != null)
|
||||
{
|
||||
int currentBalance = Balance.CurrentBalance;
|
||||
int impulseCost = Settings?.GetInt("payment.paymentImpulseCost") ?? 10;
|
||||
@ -331,6 +332,10 @@ public void TogglePause() => SetPause(!IsPaused);
|
||||
|
||||
Debug.Log($"[GameManager] Spent entire balance: {balanceToSpend}, Lives given: {livesToGive}");
|
||||
}
|
||||
else if (isFreeGame)
|
||||
{
|
||||
Debug.Log("[GameManager] Free game mode enabled. Balance spend skipped.");
|
||||
}
|
||||
|
||||
Lives = livesToGive;
|
||||
LivesChanged?.Invoke(Lives);
|
||||
|
||||
@ -14,6 +14,7 @@ namespace RR.Common.Utility
|
||||
|
||||
private ILogger _oldLogger;
|
||||
private readonly List<ILogger> _additiveLoggers = new();
|
||||
private bool _disposed;
|
||||
|
||||
public void Initialize(ILogger additiveLogger = null)
|
||||
{
|
||||
@ -329,10 +330,13 @@ namespace RR.Common.Utility
|
||||
|
||||
private void Dispose(bool disposing)
|
||||
{
|
||||
if (!disposing) return;
|
||||
if (_disposed || !disposing) return;
|
||||
|
||||
lock (_additiveLoggers)
|
||||
{
|
||||
if (_disposed)
|
||||
return;
|
||||
|
||||
foreach (ILogger additiveLogger in _additiveLoggers.ToArray())
|
||||
{
|
||||
try
|
||||
@ -346,12 +350,13 @@ namespace RR.Common.Utility
|
||||
}
|
||||
}
|
||||
_additiveLoggers.Clear();
|
||||
_disposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
~CompositeLogger()
|
||||
{
|
||||
Dispose();
|
||||
Dispose(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -290,24 +290,45 @@ namespace RR.Common.Utility
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_disposed)
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
private void Dispose(bool disposing)
|
||||
{
|
||||
if (!disposing || _disposed)
|
||||
return;
|
||||
|
||||
lock (_lock)
|
||||
{
|
||||
if (_disposed)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
if (_writer == null) return;
|
||||
_writer.WriteLine();
|
||||
_writer.WriteLine(
|
||||
"================================================================================");
|
||||
_writer.WriteLine($"Сессия логирования завершена: {DateTime.Now:yyyy-MM-dd HH:mm:ss}");
|
||||
_writer.WriteLine(
|
||||
"================================================================================");
|
||||
_writer.Flush();
|
||||
_writer.Close();
|
||||
// _writer.Dispose();
|
||||
_writer = null;
|
||||
if (_writer != null)
|
||||
{
|
||||
// Закрывающий блок пишем только если поток ещё доступен.
|
||||
try
|
||||
{
|
||||
_writer.WriteLine();
|
||||
_writer.WriteLine("================================================================================");
|
||||
_writer.WriteLine($"Сессия логирования завершена: {DateTime.Now:yyyy-MM-dd HH:mm:ss}");
|
||||
_writer.WriteLine("================================================================================");
|
||||
_writer.Flush();
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
// Поток уже закрыт извне — это не ошибка завершения.
|
||||
}
|
||||
|
||||
_writer.Dispose();
|
||||
_writer = null;
|
||||
}
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
// Поток уже закрыт — игнорируем.
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -322,7 +343,7 @@ namespace RR.Common.Utility
|
||||
|
||||
~FileLogger()
|
||||
{
|
||||
Dispose();
|
||||
Dispose(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user