refactor(net): converge live session state reset
This commit is contained in:
parent
78a9223b65
commit
4f31a5085f
35 changed files with 1460 additions and 83 deletions
|
|
@ -53,4 +53,27 @@ public sealed class ChatLogLocalGuidTests
|
|||
Assert.Equal("You", log.Snapshot()[0].Sender);
|
||||
Assert.Equal(ChatKind.RangedSpeech, log.Snapshot()[0].Kind);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ResetSessionIdentity_RetainsTranscriptButClearsGuidAndDedupeWindow()
|
||||
{
|
||||
var log = new ChatLog();
|
||||
const uint oldGuid = 0x50000001u;
|
||||
const uint newGuid = 0x50000002u;
|
||||
log.SetLocalPlayerGuid(oldGuid);
|
||||
log.OnSystemMessage("session boundary", 1u);
|
||||
log.OnLocalSpeech("Old", "before", oldGuid, isRanged: false);
|
||||
|
||||
log.ResetSessionIdentity();
|
||||
log.OnSystemMessage("session boundary", 1u);
|
||||
log.OnLocalSpeech("Old", "after", oldGuid, isRanged: false);
|
||||
log.SetLocalPlayerGuid(newGuid);
|
||||
log.OnLocalSpeech("New", "new", newGuid, isRanged: false);
|
||||
|
||||
ChatEntry[] entries = log.Snapshot();
|
||||
Assert.Equal(5, entries.Length);
|
||||
Assert.Equal("You", entries[1].Sender);
|
||||
Assert.Equal("Old", entries[3].Sender);
|
||||
Assert.Equal("You", entries[4].Sender);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,32 @@ namespace AcDream.Core.Tests.Chat;
|
|||
/// </summary>
|
||||
public sealed class TurbineChatStateTests
|
||||
{
|
||||
[Fact]
|
||||
public void Reset_ClearsRoomsAndRestartsSessionCookieAtOne()
|
||||
{
|
||||
var state = new TurbineChatState();
|
||||
state.OnChannelsReceived(1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u, 10u);
|
||||
Assert.Equal(1u, state.NextContextId());
|
||||
Assert.Equal(2u, state.NextContextId());
|
||||
|
||||
state.Reset();
|
||||
|
||||
Assert.False(state.Enabled);
|
||||
Assert.Equal(0u, state.AllegianceRoom);
|
||||
Assert.Equal(0u, state.GeneralRoom);
|
||||
Assert.Equal(0u, state.TradeRoom);
|
||||
Assert.Equal(0u, state.LfgRoom);
|
||||
Assert.Equal(0u, state.RoleplayRoom);
|
||||
Assert.Equal(0u, state.OlthoiRoom);
|
||||
Assert.Equal(0u, state.SocietyRoom);
|
||||
Assert.Equal(0u, state.SocietyCelestialHandRoom);
|
||||
Assert.Equal(0u, state.SocietyEldrytchWebRoom);
|
||||
Assert.Equal(0u, state.SocietyRadiantBloodRoom);
|
||||
Assert.Equal(1u, state.NextContextId());
|
||||
state.Reset();
|
||||
Assert.Equal(1u, state.NextContextId());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InitialState_DisabledAndZeroRooms_NextContextIdStartsAt1()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -141,4 +141,31 @@ public sealed class CombatStateTests
|
|||
Assert.Equal(0, state.TrackedTargetCount);
|
||||
Assert.Equal(CombatMode.NonCombat, state.CurrentMode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Clear_RetryRepublishesAndOneObserverCannotStarveAnother()
|
||||
{
|
||||
var state = new CombatState();
|
||||
state.SetCombatMode(CombatMode.Melee);
|
||||
bool fail = true;
|
||||
int delivered = 0;
|
||||
state.CombatModeChanged += _ =>
|
||||
{
|
||||
if (fail)
|
||||
{
|
||||
fail = false;
|
||||
throw new InvalidOperationException("transient");
|
||||
}
|
||||
};
|
||||
state.CombatModeChanged += mode =>
|
||||
{
|
||||
Assert.Equal(CombatMode.NonCombat, mode);
|
||||
delivered++;
|
||||
};
|
||||
|
||||
Assert.Throws<AggregateException>(state.Clear);
|
||||
Assert.Equal(1, delivered);
|
||||
state.Clear();
|
||||
Assert.Equal(2, delivered);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,6 +68,32 @@ public sealed class ExternalContainerStateTests
|
|||
Assert.False(state.ApplyViewContents(2u));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Reset_RetryRepublishesAndOneObserverCannotStarveAnother()
|
||||
{
|
||||
var state = Open(1u);
|
||||
bool fail = true;
|
||||
int delivered = 0;
|
||||
state.Changed += _ =>
|
||||
{
|
||||
if (fail)
|
||||
{
|
||||
fail = false;
|
||||
throw new InvalidOperationException("transient");
|
||||
}
|
||||
};
|
||||
state.Changed += transition =>
|
||||
{
|
||||
Assert.Equal(ExternalContainerTransitionKind.Reset, transition.Kind);
|
||||
delivered++;
|
||||
};
|
||||
|
||||
Assert.Throws<AggregateException>(() => state.Reset());
|
||||
Assert.Equal(1, delivered);
|
||||
Assert.False(state.Reset());
|
||||
Assert.Equal(2, delivered);
|
||||
}
|
||||
|
||||
private static ExternalContainerState Open(uint id)
|
||||
{
|
||||
var state = new ExternalContainerState();
|
||||
|
|
|
|||
|
|
@ -436,4 +436,45 @@ public sealed class LocalPlayerStateTests
|
|||
s.OnProperties(props);
|
||||
Assert.False(s.DebitInt64Property(2u, 100L)); // already 0 — no negative banking
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Clear_ReturnsEveryCharacterSnapshotToPreLoginState()
|
||||
{
|
||||
var s = new LocalPlayerState();
|
||||
var properties = new PropertyBundle();
|
||||
properties.Ints[1u] = 42;
|
||||
s.OnVitalUpdate(7u, 1u, 2u, 3u, 4u);
|
||||
s.OnAttributeUpdate(1u, 5u, 6u, 7u);
|
||||
s.OnSkillUpdate(8u, 9u, 2u, 10u, 11u, 12u, 13d, 14u);
|
||||
s.OnPositions(new Dictionary<uint, AcDream.Core.Physics.Position>
|
||||
{
|
||||
[1u] = new AcDream.Core.Physics.Position(
|
||||
0xA9B40001u,
|
||||
new System.Numerics.Vector3(1f, 2f, 3f),
|
||||
System.Numerics.Quaternion.Identity),
|
||||
});
|
||||
s.OnProperties(properties);
|
||||
int characterChanges = 0;
|
||||
var vitalChanges = new List<LocalPlayerState.VitalKind>();
|
||||
var attributeChanges = new List<LocalPlayerState.AttributeKind>();
|
||||
s.CharacterChanged += () => characterChanges++;
|
||||
s.Changed += vitalChanges.Add;
|
||||
s.AttributeChanged += attributeChanges.Add;
|
||||
|
||||
s.Clear();
|
||||
|
||||
Assert.Null(s.Get(LocalPlayerState.VitalKind.Health));
|
||||
Assert.Null(s.GetAttribute(LocalPlayerState.AttributeKind.Strength));
|
||||
Assert.Empty(s.Skills);
|
||||
Assert.Empty(s.Positions);
|
||||
Assert.Empty(s.Properties.Ints);
|
||||
Assert.Equal(Enum.GetValues<LocalPlayerState.VitalKind>(), vitalChanges);
|
||||
Assert.Equal(Enum.GetValues<LocalPlayerState.AttributeKind>(), attributeChanges);
|
||||
Assert.Equal(1, characterChanges);
|
||||
|
||||
s.Clear();
|
||||
Assert.Null(s.Get(LocalPlayerState.VitalKind.Health));
|
||||
Assert.Empty(s.Skills);
|
||||
Assert.Empty(s.Properties.Ints);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,33 @@ public sealed class SelectionStateTests
|
|||
Assert.False(state.SelectPrevious());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Reset_RetryRepublishesAndOneObserverCannotStarveAnother()
|
||||
{
|
||||
var state = new SelectionState();
|
||||
state.Select(0x50000001u, SelectionChangeSource.World);
|
||||
bool fail = true;
|
||||
int delivered = 0;
|
||||
state.Changed += _ =>
|
||||
{
|
||||
if (fail)
|
||||
{
|
||||
fail = false;
|
||||
throw new InvalidOperationException("transient");
|
||||
}
|
||||
};
|
||||
state.Changed += transition =>
|
||||
{
|
||||
Assert.Equal(SelectionChangeReason.SessionReset, transition.Reason);
|
||||
delivered++;
|
||||
};
|
||||
|
||||
Assert.Throws<AggregateException>(() => state.Reset());
|
||||
Assert.Equal(1, delivered);
|
||||
Assert.False(state.Reset());
|
||||
Assert.Equal(2, delivered);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Select_CommitsOneTransitionAndTracksPreviousLikeRetail()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,6 +4,30 @@ namespace AcDream.Core.Tests.Social;
|
|||
|
||||
public sealed class SocialStateTests
|
||||
{
|
||||
[Fact]
|
||||
public void SquelchState_Clear_ReturnsEmptyDatabase()
|
||||
{
|
||||
var state = new SquelchState();
|
||||
state.Replace(new SquelchDatabase(
|
||||
new Dictionary<string, uint> { ["Account"] = 1u },
|
||||
new Dictionary<uint, SquelchInfo>
|
||||
{
|
||||
[2u] = new("Character", false, new HashSet<uint> { 3u }),
|
||||
},
|
||||
new SquelchInfo("Global", true, new HashSet<uint> { 4u })));
|
||||
|
||||
state.Clear();
|
||||
|
||||
SquelchDatabase snapshot = state.Snapshot();
|
||||
Assert.Empty(snapshot.Accounts);
|
||||
Assert.Empty(snapshot.Characters);
|
||||
Assert.Empty(snapshot.Global.MessageTypes);
|
||||
Assert.Equal(string.Empty, snapshot.Global.Name);
|
||||
Assert.False(snapshot.Global.AccountWide);
|
||||
state.Clear();
|
||||
Assert.Empty(state.Snapshot().Accounts);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FriendsState_AppliesRetailIncrementalUpdateKindsByObjectId()
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue