Skip to content

Commit 427ba64

Browse files
committed
fix(1598): Prevent players from being logged into until they finish saving
1 parent a354250 commit 427ba64

File tree

4 files changed

+66
-14
lines changed

4 files changed

+66
-14
lines changed

Intersect.Server.Core/Entities/Player.Database.cs

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,26 @@ public partial class Player
3333
[NotMapped, JsonIgnore]
3434
public long SaveTimer { get; set; } = Timing.Global.Milliseconds + Options.Instance.Processing.PlayerSaveInterval;
3535

36+
[NotMapped, JsonIgnore]
37+
public bool IsSaving
38+
{
39+
get
40+
{
41+
lock (_pendingLogoutLock)
42+
{
43+
if (_pendingLogouts.Contains(Id))
44+
{
45+
return true;
46+
}
47+
}
48+
49+
lock (_savingLock)
50+
{
51+
return _saving;
52+
}
53+
}
54+
}
55+
3656
#endregion
3757

3858
#region Entity Framework
@@ -165,15 +185,6 @@ public static bool PlayerExists(string name)
165185

166186
public bool LoadRelationships(PlayerContext playerContext, bool loadBags = false)
167187
{
168-
lock (_savingLock)
169-
{
170-
if (_saving)
171-
{
172-
Log.Warn($"Skipping loading relationships for player {Id} because it is being saved.");
173-
return false;
174-
}
175-
}
176-
177188
var entityEntry = playerContext.Players.Attach(this);
178189
entityEntry.Collection(p => p.Bank).Load();
179190
entityEntry.Collection(p => p.Hotbar).Load();

Intersect.Server.Core/Entities/Player.cs

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,11 @@ private void Logout(bool softLogout = false)
493493
{
494494
lock (_savingLock)
495495
{
496+
lock (_pendingLogoutLock)
497+
{
498+
_pendingLogouts.Add(Id);
499+
}
500+
496501
_saving = true;
497502
}
498503

@@ -591,14 +596,17 @@ private void Logout(bool softLogout = false)
591596
var stackTrace = default(string);
592597
#endif
593598
var logoutOperationId = Guid.NewGuid();
594-
DbInterface.Pool.QueueWorkItem(CompleteLogout, logoutOperationId, stackTrace);
599+
DbInterface.Pool.QueueWorkItem(CompleteLogout, logoutOperationId, softLogout, stackTrace);
595600
}
596601

597602
#if DIAGNOSTIC
598603
private int _logoutCounter = 0;
599604
#endif
600605

601-
public void CompleteLogout(Guid logoutOperationId, string? stackTrace = default)
606+
private static readonly HashSet<Guid> _pendingLogouts = [];
607+
private static readonly object _pendingLogoutLock = new();
608+
609+
public void CompleteLogout(Guid logoutOperationId, bool softLogout, string? stackTrace = default)
602610
{
603611
if (logoutOperationId != default)
604612
{
@@ -648,10 +656,20 @@ public void CompleteLogout(Guid logoutOperationId, string? stackTrace = default)
648656

649657
lock (_savingLock)
650658
{
659+
var logoutType = softLogout ? "soft" : "hard";
660+
Log.Info($"[Player.CompleteLogout] Done saving {Name} ({logoutType} logout, {Id})");
651661
_saving = false;
652-
}
653662

654-
Dispose();
663+
if (!softLogout)
664+
{
665+
Dispose();
666+
}
667+
668+
lock (_pendingLogoutLock)
669+
{
670+
_pendingLogouts.Remove(Id);
671+
}
672+
}
655673

656674
#if DIAGNOSTIC
657675
Log.Debug($"Finished {nameof(CompleteLogout)}() #{currentExecutionId} on {Name} ({User?.Name})");

Intersect.Server.Core/Localization/Strings.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ public sealed partial class AccountNamespace : LocaleNamespace
6767
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
6868
public readonly LocalizedString LoadFail = @"Failed to load account. Please try logging in again.";
6969

70+
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
71+
public readonly LocalizedString PlayerSavingTryAgainLater = @"'{00}' is currently being saved, please try again later.";
72+
7073
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
7174
public readonly LocalizedString MaxCharacters = @"You have already created the maximum number of characters. Delete one before creating a new one.";
7275

Intersect.Server.Core/Networking/PacketHandler.cs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2508,13 +2508,33 @@ public void HandlePacket(Client client, SelectCharacterPacket packet)
25082508
return;
25092509
}
25102510

2511+
if (character.IsSaving)
2512+
{
2513+
PacketSender.SendError(
2514+
client,
2515+
Strings.Account.PlayerSavingTryAgainLater.ToString(character.Name),
2516+
Strings.General.NoticeError
2517+
);
2518+
return;
2519+
}
2520+
2521+
ObjectDisposedException.ThrowIf(character.IsDisposed, character);
2522+
25112523
client.LoadCharacter(character);
25122524

2513-
UserActivityHistory.LogActivity(client.User?.Id ?? Guid.Empty, client?.Entity?.Id ?? Guid.Empty, client?.Ip, UserActivityHistory.PeerType.Client, UserActivityHistory.UserAction.SelectPlayer, $"{client?.Name},{client?.Entity?.Name}");
2525+
UserActivityHistory.LogActivity(
2526+
client.User?.Id ?? Guid.Empty,
2527+
client?.Entity?.Id ?? Guid.Empty,
2528+
client?.Ip,
2529+
UserActivityHistory.PeerType.Client,
2530+
UserActivityHistory.UserAction.SelectPlayer,
2531+
$"{client?.Name},{client?.Entity?.Name}"
2532+
);
25142533

25152534
try
25162535
{
25172536
client.Entity?.SetOnline();
2537+
25182538
PacketSender.SendJoinGame(client);
25192539
}
25202540
catch (Exception exception)

0 commit comments

Comments
 (0)