fix: complete retail parity stability pass
All checks were successful
CI / linux-portable (push) Successful in 3m41s
CI / windows-gate (push) Successful in 6m49s
CI / release (push) Successful in 3m22s

This commit is contained in:
Erik 2026-08-28 20:01:39 +02:00
parent d3df4cb20a
commit f7aa8e0eb7
131 changed files with 7765 additions and 1190 deletions

View file

@ -652,7 +652,8 @@ public sealed class WorldSession : IDisposable
Volatile.Read(ref _lastInboundPacketTicks),
Stopwatch.GetTimestamp(),
Stopwatch.Frequency,
PingRoundTripSeconds);
PingRoundTripSeconds,
_transport?.PacketLossPercentage ?? 0d);
internal double? PingRoundTripSeconds
{
@ -1861,6 +1862,8 @@ public sealed class WorldSession : IDisposable
// last-heard clock only for valid server traffic. Record at checksum
// acceptance, before any heavy render-thread message handling.
Volatile.Write(ref _lastInboundPacketTicks, Stopwatch.GetTimestamp());
if (_transport is { } acceptedTransport)
acceptedTransport.Stats.PacketsReceived++;
// N6: the first checksum-valid post-negotiation packet confirms the
// server accepted our ConnectResponse and stops the handshake
@ -2814,13 +2817,234 @@ public sealed class WorldSession : IDisposable
SendGameAction(ClientCommandRequests.BuildRecallAllegianceHometown(seq));
}
/// <summary>Send retail "@allegiance info [name]" (0x027B).</summary>
/// <summary>Send retail "@allegiance info &lt;name&gt;" (0x027B).</summary>
public void SendAllegianceInfoRequest(string playerName)
{
uint seq = NextGameActionSequence();
SendGameAction(ClientCommandRequests.BuildAllegianceInfoRequest(seq, playerName));
}
public void SendBreakAllegianceBoot(string playerName, bool accountBoot)
{
uint seq = NextGameActionSequence();
SendGameAction(ClientCommandRequests.BuildBreakAllegianceBoot(
seq, playerName, accountBoot));
}
public void SendAllegianceChatBoot(string playerName, string reason)
{
uint seq = NextGameActionSequence();
SendGameAction(ClientCommandRequests.BuildAllegianceChatBoot(
seq, playerName, reason));
}
public void SendAllegianceChatGag(string playerName, bool enabled)
{
uint seq = NextGameActionSequence();
SendGameAction(ClientCommandRequests.BuildAllegianceChatGag(
seq, playerName, enabled));
}
public void SendAddAllegianceBan(string playerName)
{
uint seq = NextGameActionSequence();
SendGameAction(ClientCommandRequests.BuildAddAllegianceBan(seq, playerName));
}
public void SendRemoveAllegianceBan(string playerName)
{
uint seq = NextGameActionSequence();
SendGameAction(ClientCommandRequests.BuildRemoveAllegianceBan(seq, playerName));
}
public void SendListAllegianceBans()
{
uint seq = NextGameActionSequence();
SendGameAction(ClientCommandRequests.BuildListAllegianceBans(seq));
}
public void SendSetAllegianceOfficer(string playerName, uint level)
{
uint seq = NextGameActionSequence();
SendGameAction(ClientCommandRequests.BuildSetAllegianceOfficer(
seq, playerName, level));
}
public void SendRemoveAllegianceOfficer(string playerName)
{
uint seq = NextGameActionSequence();
SendGameAction(ClientCommandRequests.BuildRemoveAllegianceOfficer(
seq, playerName));
}
public void SendListAllegianceOfficers()
{
uint seq = NextGameActionSequence();
SendGameAction(ClientCommandRequests.BuildListAllegianceOfficers(seq));
}
public void SendClearAllegianceOfficers()
{
uint seq = NextGameActionSequence();
SendGameAction(ClientCommandRequests.BuildClearAllegianceOfficers(seq));
}
public void SendSetAllegianceOfficerTitle(uint level, string title)
{
uint seq = NextGameActionSequence();
SendGameAction(ClientCommandRequests.BuildSetAllegianceOfficerTitle(
seq, level, title));
}
public void SendListAllegianceOfficerTitles()
{
uint seq = NextGameActionSequence();
SendGameAction(ClientCommandRequests.BuildListAllegianceOfficerTitles(seq));
}
public void SendClearAllegianceOfficerTitles()
{
uint seq = NextGameActionSequence();
SendGameAction(ClientCommandRequests.BuildClearAllegianceOfficerTitles(seq));
}
public void SendQueryAllegianceName()
{
uint seq = NextGameActionSequence();
SendGameAction(ClientCommandRequests.BuildQueryAllegianceName(seq));
}
public void SendSetAllegianceName(string name)
{
uint seq = NextGameActionSequence();
SendGameAction(ClientCommandRequests.BuildSetAllegianceName(seq, name));
}
public void SendClearAllegianceName()
{
uint seq = NextGameActionSequence();
SendGameAction(ClientCommandRequests.BuildClearAllegianceName(seq));
}
public void SendAllegianceLockAction(uint action)
{
uint seq = NextGameActionSequence();
SendGameAction(ClientCommandRequests.BuildAllegianceLockAction(seq, action));
}
public void SendSetAllegianceApprovedVassal(string playerName)
{
uint seq = NextGameActionSequence();
SendGameAction(ClientCommandRequests.BuildSetAllegianceApprovedVassal(
seq, playerName));
}
public void SendAllegianceHouseAction(uint action)
{
uint seq = NextGameActionSequence();
SendGameAction(ClientCommandRequests.BuildAllegianceHouseAction(seq, action));
}
public void SendQueryMotd()
{
uint seq = NextGameActionSequence();
SendGameAction(ClientCommandRequests.BuildQueryMotd(seq));
}
public void SendSetMotd(string motd)
{
uint seq = NextGameActionSequence();
SendGameAction(ClientCommandRequests.BuildSetMotd(seq, motd));
}
public void SendClearMotd()
{
uint seq = NextGameActionSequence();
SendGameAction(ClientCommandRequests.BuildClearMotd(seq));
}
public void SendSetOpenHouseStatus(bool isOpen)
{
uint seq = NextGameActionSequence();
SendGameAction(ClientCommandRequests.BuildSetOpenHouseStatus(seq, isOpen));
}
public void SendAddPermanentGuest(string playerName)
{
uint seq = NextGameActionSequence();
SendGameAction(ClientCommandRequests.BuildAddPermanentGuest(seq, playerName));
}
public void SendRemovePermanentGuest(string playerName)
{
uint seq = NextGameActionSequence();
SendGameAction(ClientCommandRequests.BuildRemovePermanentGuest(seq, playerName));
}
public void SendRemoveAllPermanentGuests()
{
uint seq = NextGameActionSequence();
SendGameAction(ClientCommandRequests.BuildRemoveAllPermanentGuests(seq));
}
public void SendChangeStoragePermission(string playerName, bool enabled)
{
uint seq = NextGameActionSequence();
SendGameAction(ClientCommandRequests.BuildChangeStoragePermission(
seq, playerName, enabled));
}
public void SendAddAllStoragePermission()
{
uint seq = NextGameActionSequence();
SendGameAction(ClientCommandRequests.BuildAddAllStoragePermission(seq));
}
public void SendRemoveAllStoragePermission()
{
uint seq = NextGameActionSequence();
SendGameAction(ClientCommandRequests.BuildRemoveAllStoragePermission(seq));
}
public void SendRequestFullGuestList()
{
uint seq = NextGameActionSequence();
SendGameAction(ClientCommandRequests.BuildRequestFullGuestList(seq));
}
public void SendBootSpecificHouseGuest(string playerName)
{
uint seq = NextGameActionSequence();
SendGameAction(ClientCommandRequests.BuildBootSpecificHouseGuest(
seq, playerName));
}
public void SendBootEveryone()
{
uint seq = NextGameActionSequence();
SendGameAction(ClientCommandRequests.BuildBootEveryone(seq));
}
public void SendSetHooksVisibility(bool visible)
{
uint seq = NextGameActionSequence();
SendGameAction(ClientCommandRequests.BuildSetHooksVisibility(seq, visible));
}
public void SendModifyAllegianceGuestPermission(bool enabled)
{
uint seq = NextGameActionSequence();
SendGameAction(ClientCommandRequests.BuildModifyAllegianceGuestPermission(
seq, enabled));
}
public void SendModifyAllegianceStoragePermission(bool enabled)
{
uint seq = NextGameActionSequence();
SendGameAction(ClientCommandRequests.BuildModifyAllegianceStoragePermission(
seq, enabled));
}
// ── Campaign FA slice FA2 (2026-08-12): fellowship + allegiance
// outbound wrappers. SocialActions/AllegianceRequests ship the byte
// builders (repaired/added in FA1); this is the missing