fix: complete retail parity stability pass
This commit is contained in:
parent
d3df4cb20a
commit
f7aa8e0eb7
131 changed files with 7765 additions and 1190 deletions
|
|
@ -60,6 +60,41 @@ public static class ClientCommandRequests
|
|||
public const uint AddPlayerPermissionOpcode = 0x0219u;
|
||||
public const uint RemovePlayerPermissionOpcode = 0x021Au;
|
||||
public const uint AbandonHouseOpcode = 0x021Fu;
|
||||
public const uint QueryAllegianceNameOpcode = 0x0030u;
|
||||
public const uint ClearAllegianceNameOpcode = 0x0031u;
|
||||
public const uint SetAllegianceNameOpcode = 0x0033u;
|
||||
public const uint SetAllegianceOfficerOpcode = 0x003Bu;
|
||||
public const uint SetAllegianceOfficerTitleOpcode = 0x003Cu;
|
||||
public const uint ListAllegianceOfficerTitlesOpcode = 0x003Du;
|
||||
public const uint ClearAllegianceOfficerTitlesOpcode = 0x003Eu;
|
||||
public const uint DoAllegianceLockActionOpcode = 0x003Fu;
|
||||
public const uint SetAllegianceApprovedVassalOpcode = 0x0040u;
|
||||
public const uint AllegianceChatGagOpcode = 0x0041u;
|
||||
public const uint DoAllegianceHouseActionOpcode = 0x0042u;
|
||||
public const uint AddPermanentGuestOpcode = 0x0245u;
|
||||
public const uint RemovePermanentGuestOpcode = 0x0246u;
|
||||
public const uint SetOpenHouseStatusOpcode = 0x0247u;
|
||||
public const uint ChangeStoragePermissionOpcode = 0x0249u;
|
||||
public const uint BootSpecificHouseGuestOpcode = 0x024Au;
|
||||
public const uint RemoveAllStoragePermissionOpcode = 0x024Cu;
|
||||
public const uint RequestFullGuestListOpcode = 0x024Du;
|
||||
public const uint SetMotdOpcode = 0x0254u;
|
||||
public const uint QueryMotdOpcode = 0x0255u;
|
||||
public const uint ClearMotdOpcode = 0x0256u;
|
||||
public const uint AddAllStoragePermissionOpcode = 0x025Cu;
|
||||
public const uint RemoveAllPermanentGuestsOpcode = 0x025Eu;
|
||||
public const uint BootEveryoneOpcode = 0x025Fu;
|
||||
public const uint SetHooksVisibilityOpcode = 0x0266u;
|
||||
public const uint ModifyAllegianceGuestPermissionOpcode = 0x0267u;
|
||||
public const uint ModifyAllegianceStoragePermissionOpcode = 0x0268u;
|
||||
public const uint BreakAllegianceBootOpcode = 0x0277u;
|
||||
public const uint AllegianceChatBootOpcode = 0x02A0u;
|
||||
public const uint AddAllegianceBanOpcode = 0x02A1u;
|
||||
public const uint RemoveAllegianceBanOpcode = 0x02A2u;
|
||||
public const uint ListAllegianceBansOpcode = 0x02A3u;
|
||||
public const uint RemoveAllegianceOfficerOpcode = 0x02A5u;
|
||||
public const uint ListAllegianceOfficersOpcode = 0x02A6u;
|
||||
public const uint ClearAllegianceOfficersOpcode = 0x02A7u;
|
||||
// Batch C (Map/House toolbar panel, 2026-08-17): the query the House
|
||||
// tab needs to populate. ACE GameActionHouseQuery.cs: [GameAction(
|
||||
// GameActionType.HouseQuery)] (0x021E), Handle reads no payload and
|
||||
|
|
@ -283,8 +318,9 @@ public static class ClientCommandRequests
|
|||
public static byte[] BuildRecallAllegianceHometown(uint sequence) =>
|
||||
BuildParameterless(sequence, RecallAllegianceHometownOpcode);
|
||||
|
||||
// "@allegiance info [name]" — GameActionAllegianceInfoRequest.Handle:
|
||||
// ReadString16L() player name (empty string = self).
|
||||
// "@allegiance info <name>" — GameActionAllegianceInfoRequest.Handle:
|
||||
// ReadString16L() player name. Retail refuses an empty argument before
|
||||
// constructing this request.
|
||||
public static byte[] BuildAllegianceInfoRequest(uint sequence, string playerName) =>
|
||||
BuildString(sequence, AllegianceInfoRequestOpcode, playerName);
|
||||
|
||||
|
|
@ -308,6 +344,133 @@ public static class ClientCommandRequests
|
|||
public static byte[] BuildAbandonHouse(uint sequence) =>
|
||||
BuildParameterless(sequence, AbandonHouseOpcode);
|
||||
|
||||
// Complete named-retail @allegiance/@house administration family.
|
||||
// Opcodes and field order are cross-checked against ACE's individual
|
||||
// GameAction readers; the client-side grammar is ported separately by
|
||||
// ClientCommandController from DoAllegiance/DoHouse and their helpers.
|
||||
public static byte[] BuildBreakAllegianceBoot(
|
||||
uint sequence, string playerName, bool accountBoot) =>
|
||||
BuildStringUInt32(
|
||||
sequence, BreakAllegianceBootOpcode, playerName, accountBoot ? 1u : 0u);
|
||||
|
||||
public static byte[] BuildAllegianceChatBoot(
|
||||
uint sequence, string playerName, string reason) =>
|
||||
BuildTwoStrings(sequence, AllegianceChatBootOpcode, playerName, reason);
|
||||
|
||||
public static byte[] BuildAllegianceChatGag(
|
||||
uint sequence, string playerName, bool enabled) =>
|
||||
BuildStringUInt32(
|
||||
sequence, AllegianceChatGagOpcode, playerName, enabled ? 1u : 0u);
|
||||
|
||||
public static byte[] BuildAddAllegianceBan(uint sequence, string playerName) =>
|
||||
BuildString(sequence, AddAllegianceBanOpcode, playerName);
|
||||
|
||||
public static byte[] BuildRemoveAllegianceBan(uint sequence, string playerName) =>
|
||||
BuildString(sequence, RemoveAllegianceBanOpcode, playerName);
|
||||
|
||||
public static byte[] BuildListAllegianceBans(uint sequence) =>
|
||||
BuildParameterless(sequence, ListAllegianceBansOpcode);
|
||||
|
||||
public static byte[] BuildSetAllegianceOfficer(
|
||||
uint sequence, string playerName, uint officerLevel) =>
|
||||
BuildStringUInt32(
|
||||
sequence, SetAllegianceOfficerOpcode, playerName, officerLevel);
|
||||
|
||||
public static byte[] BuildRemoveAllegianceOfficer(
|
||||
uint sequence, string playerName) =>
|
||||
BuildString(sequence, RemoveAllegianceOfficerOpcode, playerName);
|
||||
|
||||
public static byte[] BuildListAllegianceOfficers(uint sequence) =>
|
||||
BuildParameterless(sequence, ListAllegianceOfficersOpcode);
|
||||
|
||||
public static byte[] BuildClearAllegianceOfficers(uint sequence) =>
|
||||
BuildParameterless(sequence, ClearAllegianceOfficersOpcode);
|
||||
|
||||
public static byte[] BuildSetAllegianceOfficerTitle(
|
||||
uint sequence, uint officerLevel, string title) =>
|
||||
BuildUInt32String(
|
||||
sequence, SetAllegianceOfficerTitleOpcode, officerLevel, title);
|
||||
|
||||
public static byte[] BuildListAllegianceOfficerTitles(uint sequence) =>
|
||||
BuildParameterless(sequence, ListAllegianceOfficerTitlesOpcode);
|
||||
|
||||
public static byte[] BuildClearAllegianceOfficerTitles(uint sequence) =>
|
||||
BuildParameterless(sequence, ClearAllegianceOfficerTitlesOpcode);
|
||||
|
||||
public static byte[] BuildQueryAllegianceName(uint sequence) =>
|
||||
BuildParameterless(sequence, QueryAllegianceNameOpcode);
|
||||
|
||||
public static byte[] BuildSetAllegianceName(uint sequence, string name) =>
|
||||
BuildString(sequence, SetAllegianceNameOpcode, name);
|
||||
|
||||
public static byte[] BuildClearAllegianceName(uint sequence) =>
|
||||
BuildParameterless(sequence, ClearAllegianceNameOpcode);
|
||||
|
||||
public static byte[] BuildAllegianceLockAction(uint sequence, uint action) =>
|
||||
BuildUInt32(sequence, DoAllegianceLockActionOpcode, action);
|
||||
|
||||
public static byte[] BuildSetAllegianceApprovedVassal(
|
||||
uint sequence, string playerName) =>
|
||||
BuildString(sequence, SetAllegianceApprovedVassalOpcode, playerName);
|
||||
|
||||
public static byte[] BuildAllegianceHouseAction(uint sequence, uint action) =>
|
||||
BuildUInt32(sequence, DoAllegianceHouseActionOpcode, action);
|
||||
|
||||
public static byte[] BuildQueryMotd(uint sequence) =>
|
||||
BuildParameterless(sequence, QueryMotdOpcode);
|
||||
|
||||
public static byte[] BuildSetMotd(uint sequence, string motd) =>
|
||||
BuildString(sequence, SetMotdOpcode, motd);
|
||||
|
||||
public static byte[] BuildClearMotd(uint sequence) =>
|
||||
BuildParameterless(sequence, ClearMotdOpcode);
|
||||
|
||||
public static byte[] BuildSetOpenHouseStatus(uint sequence, bool isOpen) =>
|
||||
BuildUInt32(sequence, SetOpenHouseStatusOpcode, isOpen ? 1u : 0u);
|
||||
|
||||
public static byte[] BuildAddPermanentGuest(uint sequence, string playerName) =>
|
||||
BuildString(sequence, AddPermanentGuestOpcode, playerName);
|
||||
|
||||
public static byte[] BuildRemovePermanentGuest(uint sequence, string playerName) =>
|
||||
BuildString(sequence, RemovePermanentGuestOpcode, playerName);
|
||||
|
||||
public static byte[] BuildRemoveAllPermanentGuests(uint sequence) =>
|
||||
BuildParameterless(sequence, RemoveAllPermanentGuestsOpcode);
|
||||
|
||||
public static byte[] BuildChangeStoragePermission(
|
||||
uint sequence, string playerName, bool enabled) =>
|
||||
BuildStringUInt32(
|
||||
sequence, ChangeStoragePermissionOpcode, playerName, enabled ? 1u : 0u);
|
||||
|
||||
public static byte[] BuildAddAllStoragePermission(uint sequence) =>
|
||||
BuildParameterless(sequence, AddAllStoragePermissionOpcode);
|
||||
|
||||
public static byte[] BuildRemoveAllStoragePermission(uint sequence) =>
|
||||
BuildParameterless(sequence, RemoveAllStoragePermissionOpcode);
|
||||
|
||||
public static byte[] BuildRequestFullGuestList(uint sequence) =>
|
||||
BuildParameterless(sequence, RequestFullGuestListOpcode);
|
||||
|
||||
public static byte[] BuildBootSpecificHouseGuest(
|
||||
uint sequence, string playerName) =>
|
||||
BuildString(sequence, BootSpecificHouseGuestOpcode, playerName);
|
||||
|
||||
public static byte[] BuildBootEveryone(uint sequence) =>
|
||||
BuildParameterless(sequence, BootEveryoneOpcode);
|
||||
|
||||
public static byte[] BuildSetHooksVisibility(uint sequence, bool visible) =>
|
||||
BuildUInt32(sequence, SetHooksVisibilityOpcode, visible ? 1u : 0u);
|
||||
|
||||
public static byte[] BuildModifyAllegianceGuestPermission(
|
||||
uint sequence, bool enabled) =>
|
||||
BuildUInt32(
|
||||
sequence, ModifyAllegianceGuestPermissionOpcode, enabled ? 1u : 0u);
|
||||
|
||||
public static byte[] BuildModifyAllegianceStoragePermission(
|
||||
uint sequence, bool enabled) =>
|
||||
BuildUInt32(
|
||||
sequence, ModifyAllegianceStoragePermissionOpcode, enabled ? 1u : 0u);
|
||||
|
||||
// Queries the local player's house info (owned house data, or a
|
||||
// no-house status) — GameActionHouseQuery.Handle: no payload read.
|
||||
public static byte[] BuildHouseQuery(uint sequence) =>
|
||||
|
|
@ -337,6 +500,39 @@ public static class ClientCommandRequests
|
|||
return body;
|
||||
}
|
||||
|
||||
private static byte[] BuildStringUInt32(
|
||||
uint sequence, uint opcode, string value, uint number)
|
||||
{
|
||||
byte[] packed = PackString16L(value);
|
||||
byte[] body = CreateBody(sequence, opcode, packed.Length + 4);
|
||||
packed.CopyTo(body, 12);
|
||||
BinaryPrimitives.WriteUInt32LittleEndian(
|
||||
body.AsSpan(12 + packed.Length), number);
|
||||
return body;
|
||||
}
|
||||
|
||||
private static byte[] BuildUInt32String(
|
||||
uint sequence, uint opcode, uint number, string value)
|
||||
{
|
||||
byte[] packed = PackString16L(value);
|
||||
byte[] body = CreateBody(sequence, opcode, 4 + packed.Length);
|
||||
BinaryPrimitives.WriteUInt32LittleEndian(body.AsSpan(12), number);
|
||||
packed.CopyTo(body, 16);
|
||||
return body;
|
||||
}
|
||||
|
||||
private static byte[] BuildTwoStrings(
|
||||
uint sequence, uint opcode, string first, string second)
|
||||
{
|
||||
byte[] packedFirst = PackString16L(first);
|
||||
byte[] packedSecond = PackString16L(second);
|
||||
byte[] body = CreateBody(
|
||||
sequence, opcode, packedFirst.Length + packedSecond.Length);
|
||||
packedFirst.CopyTo(body, 12);
|
||||
packedSecond.CopyTo(body, 12 + packedFirst.Length);
|
||||
return body;
|
||||
}
|
||||
|
||||
private static byte[] CreateBody(uint sequence, uint opcode, int payloadLength)
|
||||
{
|
||||
byte[] body = new byte[12 + payloadLength];
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue