refactor(net): own live session routing
This commit is contained in:
parent
707e606e35
commit
961bdd07b7
12 changed files with 1645 additions and 543 deletions
|
|
@ -12,13 +12,19 @@ public static class CombatStateWiring
|
|||
{
|
||||
public const uint CombatModePropertyId = 40u;
|
||||
|
||||
public static IDisposable Wire(WorldSession session, CombatState combat)
|
||||
public static IDisposable Wire(
|
||||
WorldSession session,
|
||||
CombatState combat,
|
||||
Func<bool>? accepting = null)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(session);
|
||||
ArgumentNullException.ThrowIfNull(combat);
|
||||
|
||||
Action<WorldSession.PlayerIntPropertyUpdate> handler = update =>
|
||||
{
|
||||
if (accepting?.Invoke() == false) return;
|
||||
ApplyPlayerIntProperty(combat, update.Property, update.Value);
|
||||
};
|
||||
session.PlayerIntPropertyUpdated += handler;
|
||||
return new EventSubscription(session, handler);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,7 +81,8 @@ public static class GameEventWiring
|
|||
Action<IReadOnlyList<(uint Id, uint Amount)>>? onDesiredComponents = null,
|
||||
Action<uint /*options1*/, uint /*options2*/>? onCharacterOptions = null,
|
||||
Func<double>? clientTime = null,
|
||||
ExternalContainerState? externalContainers = null)
|
||||
ExternalContainerState? externalContainers = null,
|
||||
Func<bool>? accepting = null)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(dispatcher);
|
||||
ArgumentNullException.ThrowIfNull(items);
|
||||
|
|
@ -89,7 +90,7 @@ public static class GameEventWiring
|
|||
ArgumentNullException.ThrowIfNull(spellbook);
|
||||
ArgumentNullException.ThrowIfNull(chat);
|
||||
clientTime ??= static () => 0d;
|
||||
var registrar = new OwnedGameEventRegistrar(dispatcher);
|
||||
var registrar = new OwnedGameEventRegistrar(dispatcher, accepting);
|
||||
using var construction = new RegistrationBuildScope(registrar);
|
||||
|
||||
// ── Chat ──────────────────────────────────────────────────
|
||||
|
|
@ -659,14 +660,23 @@ public static class GameEventWiring
|
|||
}
|
||||
|
||||
private sealed class OwnedGameEventRegistrar(
|
||||
GameEventDispatcher dispatcher) : IDisposable
|
||||
GameEventDispatcher dispatcher,
|
||||
Func<bool>? accepting) : IDisposable
|
||||
{
|
||||
private readonly SubscriptionSet _subscriptions = new();
|
||||
|
||||
public void Register(
|
||||
GameEventType type,
|
||||
GameEventDispatcher.EventHandler handler) =>
|
||||
_subscriptions.Add(dispatcher.RegisterOwned(type, handler));
|
||||
GameEventDispatcher.EventHandler handler)
|
||||
{
|
||||
GameEventDispatcher.EventHandler registered = accepting is null
|
||||
? handler
|
||||
: envelope =>
|
||||
{
|
||||
if (accepting()) handler(envelope);
|
||||
};
|
||||
_subscriptions.Add(dispatcher.RegisterOwned(type, registered));
|
||||
}
|
||||
|
||||
public void Dispose() => _subscriptions.Dispose();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,8 @@ public static class ObjectTableWiring
|
|||
WorldSession session,
|
||||
ClientObjectTable table,
|
||||
Func<uint>? playerGuid = null,
|
||||
LocalPlayerState? localPlayer = null)
|
||||
LocalPlayerState? localPlayer = null,
|
||||
Func<bool>? accepting = null)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(session);
|
||||
ArgumentNullException.ThrowIfNull(table);
|
||||
|
|
@ -37,7 +38,10 @@ public static class ObjectTableWiring
|
|||
// UiEffects — the server is the authority on object properties. UpdateIntProperty
|
||||
// stores it in the bundle and still mirrors UiEffects → the typed Effects field.
|
||||
Action<WorldSession.ObjectIntPropertyUpdate> objectIntUpdated = u =>
|
||||
{
|
||||
if (accepting?.Invoke() == false) return;
|
||||
table.UpdateIntProperty(u.Guid, u.Property, u.Value);
|
||||
};
|
||||
session.ObjectIntPropertyUpdated += objectIntUpdated;
|
||||
subscriptions.Add(() => session.ObjectIntPropertyUpdated -= objectIntUpdated);
|
||||
|
||||
|
|
@ -49,6 +53,7 @@ public static class ObjectTableWiring
|
|||
// than creating a phantom — the next PD / CreateObject seeds it.
|
||||
Action<WorldSession.PlayerIntPropertyUpdate> playerIntUpdated = u =>
|
||||
{
|
||||
if (accepting?.Invoke() == false) return;
|
||||
if (playerGuid is not null)
|
||||
table.UpdateIntProperty(playerGuid(), u.Property, u.Value);
|
||||
};
|
||||
|
|
@ -61,20 +66,30 @@ public static class ObjectTableWiring
|
|||
// Apply the authoritative 0x02CF update to both in this one wiring owner so they
|
||||
// cannot drift after the login PlayerDescription snapshot.
|
||||
Action<WorldSession.PlayerInt64PropertyUpdate> playerInt64Updated = u =>
|
||||
{
|
||||
if (accepting?.Invoke() == false) return;
|
||||
ApplyPlayerInt64PropertyUpdate(
|
||||
table, localPlayer, playerGuid?.Invoke() ?? 0u, u);
|
||||
table, localPlayer, playerGuid?.Invoke() ?? 0u, u);
|
||||
};
|
||||
session.PlayerInt64PropertyUpdated += playerInt64Updated;
|
||||
subscriptions.Add(() => session.PlayerInt64PropertyUpdated -= playerInt64Updated);
|
||||
|
||||
// B-Wire: SetStackSize (0x0197) — update the object's stack count + value.
|
||||
Action<WorldSession.StackSizeUpdate> stackSizeUpdated = u =>
|
||||
{
|
||||
if (accepting?.Invoke() == false) return;
|
||||
table.UpdateStackSize(u.Guid, u.StackSize, u.Value);
|
||||
};
|
||||
session.StackSizeUpdated += stackSizeUpdated;
|
||||
subscriptions.Add(() => session.StackSizeUpdated -= stackSizeUpdated);
|
||||
|
||||
// B-Wire: InventoryRemoveObject (0x0024) — the object left the player's inventory
|
||||
// view; drop it from the table (retail ClientUISystem removes it from maintenance).
|
||||
Action<uint> inventoryObjectRemoved = guid => table.Remove(guid);
|
||||
Action<uint> inventoryObjectRemoved = guid =>
|
||||
{
|
||||
if (accepting?.Invoke() == false) return;
|
||||
table.Remove(guid);
|
||||
};
|
||||
session.InventoryObjectRemoved += inventoryObjectRemoved;
|
||||
subscriptions.Add(() => session.InventoryObjectRemoved -= inventoryObjectRemoved);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue