feat(mosstank): add VTank-style automation PoC

This commit is contained in:
Erik 2026-08-27 18:57:21 +02:00
parent f6fe0f2a4f
commit 4e6e9bc9d9
212 changed files with 49462 additions and 416 deletions

View file

@ -27,6 +27,7 @@ public static class InventoryActions
public const uint DropItemOpcode = 0x001Bu;
public const uint NoLongerViewingContentsOpcode = 0x0195u;
public const uint SetInscriptionOpcode = 0x00BFu;
public const uint CreateTinkeringToolOpcode = 0x027Du;
/// <summary>
/// Merge stack A into stack B of the same item type. Server validates
@ -205,4 +206,48 @@ public static class InventoryActions
text.CopyTo(body, 18);
return body;
}
/// <summary>
/// Salvage one or more carried items with an owned salvage tool. Retail
/// <c>CM_Inventory::Event_CreateTinkeringTool @ 0x006AB830</c> writes the
/// tool id followed by <c>PackableList&lt;unsigned long&gt;</c>: u32 count,
/// then the object ids in list order. The server replies with GameEvent
/// <c>0x02B4 SalvageOperationsResult</c> and removes accepted source items.
/// </summary>
public static byte[] BuildCreateTinkeringTool(
uint seq,
uint toolGuid,
IReadOnlyList<uint> itemGuids)
{
ArgumentNullException.ThrowIfNull(itemGuids);
if (toolGuid == 0u)
throw new ArgumentOutOfRangeException(nameof(toolGuid));
if (itemGuids.Count == 0)
throw new ArgumentException(
"At least one item is required for salvage.",
nameof(itemGuids));
byte[] body = new byte[20 + (itemGuids.Count * sizeof(uint))];
BinaryPrimitives.WriteUInt32LittleEndian(body, GameActionEnvelope);
BinaryPrimitives.WriteUInt32LittleEndian(body.AsSpan(4), seq);
BinaryPrimitives.WriteUInt32LittleEndian(
body.AsSpan(8),
CreateTinkeringToolOpcode);
BinaryPrimitives.WriteUInt32LittleEndian(body.AsSpan(12), toolGuid);
BinaryPrimitives.WriteUInt32LittleEndian(
body.AsSpan(16),
checked((uint)itemGuids.Count));
for (int index = 0; index < itemGuids.Count; index++)
{
uint itemGuid = itemGuids[index];
if (itemGuid == 0u)
throw new ArgumentException(
"Salvage item ids must be non-zero.",
nameof(itemGuids));
BinaryPrimitives.WriteUInt32LittleEndian(
body.AsSpan(20 + (index * sizeof(uint))),
itemGuid);
}
return body;
}
}