feat(chat): port retail client command families
Expand the typed client-command boundary across travel, character queries, local UI and layout controls, AFK and consent, emotes, friends, squelch and filters, and fill-components. Preserve retail packet layouts and queue ownership, import the confirmation dialog, and keep authoritative social state in Core. Co-Authored-By: Codex <codex@openai.com>
This commit is contained in:
parent
5a45a7ac7f
commit
9ea579bdd0
47 changed files with 6659 additions and 99 deletions
|
|
@ -1272,6 +1272,153 @@ public sealed class WorldSession : IDisposable
|
|||
SendGameAction(InteractRequests.BuildTeleToLifestone(seq));
|
||||
}
|
||||
|
||||
/// <summary>Send retail marketplace recall (0x028D).</summary>
|
||||
public void SendTeleportToMarketplace()
|
||||
{
|
||||
uint seq = NextGameActionSequence();
|
||||
SendGameAction(ClientCommandRequests.BuildMarketplace(seq));
|
||||
}
|
||||
|
||||
/// <summary>Send retail full-PK arena recall (0x0027).</summary>
|
||||
public void SendTeleportToPkArena()
|
||||
{
|
||||
uint seq = NextGameActionSequence();
|
||||
SendGameAction(ClientCommandRequests.BuildPkArena(seq));
|
||||
}
|
||||
|
||||
/// <summary>Send retail PKLite arena recall (0x0026).</summary>
|
||||
public void SendTeleportToPkLiteArena()
|
||||
{
|
||||
uint seq = NextGameActionSequence();
|
||||
SendGameAction(ClientCommandRequests.BuildPkLiteArena(seq));
|
||||
}
|
||||
|
||||
/// <summary>Send retail personal-house recall (0x0262).</summary>
|
||||
public void SendTeleportToHouse()
|
||||
{
|
||||
uint seq = NextGameActionSequence();
|
||||
SendGameAction(ClientCommandRequests.BuildHouseRecall(seq));
|
||||
}
|
||||
|
||||
/// <summary>Send retail allegiance-mansion recall (0x0278).</summary>
|
||||
public void SendTeleportToMansion()
|
||||
{
|
||||
uint seq = NextGameActionSequence();
|
||||
SendGameAction(ClientCommandRequests.BuildMansionRecall(seq));
|
||||
}
|
||||
|
||||
/// <summary>Query the local character's played time (0x01C2).</summary>
|
||||
public void SendQueryAge()
|
||||
{
|
||||
uint seq = NextGameActionSequence();
|
||||
SendGameAction(ClientCommandRequests.BuildQueryAge(seq));
|
||||
}
|
||||
|
||||
/// <summary>Query the local character's creation date (0x01C4).</summary>
|
||||
public void SendQueryBirth()
|
||||
{
|
||||
uint seq = NextGameActionSequence();
|
||||
SendGameAction(ClientCommandRequests.BuildQueryBirth(seq));
|
||||
}
|
||||
|
||||
/// <summary>Reply to a server confirmation request (0x0275).</summary>
|
||||
public void SendConfirmationResponse(uint confirmationType, uint contextId, bool accepted)
|
||||
{
|
||||
uint seq = NextGameActionSequence();
|
||||
SendGameAction(ClientCommandRequests.BuildConfirmationResponse(
|
||||
seq, confirmationType, contextId, accepted));
|
||||
}
|
||||
|
||||
/// <summary>Send the confirmed retail suicide action (0x0279).</summary>
|
||||
public void SendSuicide()
|
||||
{
|
||||
uint seq = NextGameActionSequence();
|
||||
SendGameAction(ClientCommandRequests.BuildSuicide(seq));
|
||||
}
|
||||
|
||||
public void SendSetAfkMode(bool away)
|
||||
{
|
||||
uint seq = NextGameActionSequence();
|
||||
SendGameAction(ClientCommandRequests.BuildSetAfkMode(seq, away));
|
||||
}
|
||||
|
||||
public void SendSetAfkMessage(string message)
|
||||
{
|
||||
uint seq = NextGameActionSequence();
|
||||
SendGameAction(ClientCommandRequests.BuildSetAfkMessage(seq, message));
|
||||
}
|
||||
|
||||
public void SendEmote(string message)
|
||||
{
|
||||
uint seq = NextGameActionSequence();
|
||||
SendGameAction(ClientCommandRequests.BuildEmote(seq, message));
|
||||
}
|
||||
|
||||
public void SendAddFriend(string name)
|
||||
{
|
||||
uint seq = NextGameActionSequence();
|
||||
SendGameAction(ClientCommandRequests.BuildAddFriend(seq, name));
|
||||
}
|
||||
|
||||
public void SendRemoveFriend(uint friendId)
|
||||
{
|
||||
uint seq = NextGameActionSequence();
|
||||
SendGameAction(ClientCommandRequests.BuildRemoveFriend(seq, friendId));
|
||||
}
|
||||
|
||||
public void SendClearFriends()
|
||||
{
|
||||
uint seq = NextGameActionSequence();
|
||||
SendGameAction(ClientCommandRequests.BuildClearFriends(seq));
|
||||
}
|
||||
|
||||
public void SendLegacyFriendsListRequest() =>
|
||||
SendControlMessage(ClientCommandRequests.BuildLegacyFriendsCommand(0u, string.Empty));
|
||||
|
||||
public void SendModifyCharacterSquelch(bool add, uint characterId, string name, uint messageType)
|
||||
{
|
||||
uint seq = NextGameActionSequence();
|
||||
SendGameAction(ClientCommandRequests.BuildModifyCharacterSquelch(
|
||||
seq, add, characterId, name, messageType));
|
||||
}
|
||||
|
||||
public void SendModifyAccountSquelch(bool add, string name)
|
||||
{
|
||||
uint seq = NextGameActionSequence();
|
||||
SendGameAction(ClientCommandRequests.BuildModifyAccountSquelch(seq, add, name));
|
||||
}
|
||||
|
||||
public void SendModifyGlobalSquelch(bool add, uint messageType)
|
||||
{
|
||||
uint seq = NextGameActionSequence();
|
||||
SendGameAction(ClientCommandRequests.BuildModifyGlobalSquelch(seq, add, messageType));
|
||||
}
|
||||
|
||||
public void SendClearConsent()
|
||||
{
|
||||
uint seq = NextGameActionSequence();
|
||||
SendGameAction(ClientCommandRequests.BuildClearConsent(seq));
|
||||
}
|
||||
|
||||
public void SendDisplayConsent()
|
||||
{
|
||||
uint seq = NextGameActionSequence();
|
||||
SendGameAction(ClientCommandRequests.BuildDisplayConsent(seq));
|
||||
}
|
||||
|
||||
public void SendRemoveConsent(string name)
|
||||
{
|
||||
uint seq = NextGameActionSequence();
|
||||
SendGameAction(ClientCommandRequests.BuildRemoveConsent(seq, name));
|
||||
}
|
||||
|
||||
public void SendClearDesiredComponents()
|
||||
{
|
||||
uint seq = NextGameActionSequence();
|
||||
SendGameAction(ClientCommandRequests.BuildSetDesiredComponentLevel(
|
||||
seq, componentId: 0u, amount: uint.MaxValue));
|
||||
}
|
||||
|
||||
/// <summary>Send retail ChangeCombatMode (0x0053).</summary>
|
||||
public void SendChangeCombatMode(CombatMode mode)
|
||||
{
|
||||
|
|
@ -1517,10 +1664,20 @@ public sealed class WorldSession : IDisposable
|
|||
SendGameAction(body);
|
||||
}
|
||||
|
||||
private void SendGameMessage(byte[] gameMessageBody)
|
||||
private void SendGameMessage(byte[] gameMessageBody) =>
|
||||
SendGameMessage(gameMessageBody, GameMessageGroup.UIQueue);
|
||||
|
||||
/// <summary>
|
||||
/// Retail <c>Proto_UI::SendToControl</c> path used by standalone control
|
||||
/// messages such as the legacy <c>0xF7CD</c> friends request.
|
||||
/// </summary>
|
||||
private void SendControlMessage(byte[] gameMessageBody) =>
|
||||
SendGameMessage(gameMessageBody, GameMessageGroup.ControlQueue);
|
||||
|
||||
private void SendGameMessage(byte[] gameMessageBody, GameMessageGroup queue)
|
||||
{
|
||||
var fragment = GameMessageFragment.BuildSingleFragment(
|
||||
_fragmentSequence++, GameMessageGroup.UIQueue, gameMessageBody);
|
||||
_fragmentSequence++, queue, gameMessageBody);
|
||||
byte[] packetBody = GameMessageFragment.Serialize(fragment);
|
||||
var header = new PacketHeader
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue