internal.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424
  1. #pragma once
  2. #include <array>
  3. #include <bitset>
  4. #include <cstddef>
  5. #include <cstdint>
  6. #include <span>
  7. #include <vector>
  8. #include "../../../../core/filesystem/path.h"
  9. #include "../../../../middleware/content/packages/reader/reader.h"
  10. #include "../../../../middleware/content/packages/tables/definition_index_table.h"
  11. #include "../../../../middleware/content/packages/tables/items.h"
  12. #include "../../../../state/build_data/abilities/definition.h"
  13. #include "../../../../state/build_data/collectibles/collectible_catalog.h"
  14. #include "../../../../state/build_data/constants/definition.h"
  15. #include "../../../../state/build_data/inventory/buckets/definition.h"
  16. #include "../../../../state/build_data/items/details/definition.h"
  17. #include "../../../../state/build_data/items/item_catalog.h"
  18. #include "../../../../state/build_data/material_requirements/material_requirement_catalog.h"
  19. #include "../../../../state/build_data/progressions/definition.h"
  20. #include "../../../../state/build_data/runtime.h"
  21. namespace sunrise::client::content::items::packages {
  22. namespace reader = middleware::content::packages::reader;
  23. namespace tables = middleware::content::packages::tables;
  24. /** Equippable rows, their initial plugs, and authored override plugs. */
  25. inline constexpr std::size_t kDetailCapacity =
  26. state::build_data::items::details::kDefinitionCapacity;
  27. /** Native item indices selected for the deduplicated detail closure. */
  28. using DetailRequests = std::bitset<state::build_data::items::kDefinitionCapacity>;
  29. /** Authored definition hashes one pass looks for while walking the item index table. */
  30. struct AuthoredHashes {
  31. std::array<std::uint32_t, kDetailCapacity> values{};
  32. std::size_t count{};
  33. };
  34. /** Everything the detail pass needs to read one requested definition from the packages. */
  35. struct DetailSource {
  36. const reader::Source* source{};
  37. reader::Scratch* scratch{};
  38. /** Item index table blob owning the located array. */
  39. std::span<const std::byte> table{};
  40. tables::Array array{};
  41. std::vector<std::byte>* definition{};
  42. };
  43. /** The container name is not always unique, so every match is a candidate. */
  44. inline constexpr std::size_t kContainerCandidates = 16;
  45. /** Lock-owned storage kept off the caller stack, shared by every stage of the pass. */
  46. struct Storage {
  47. reader::Scratch scratch{};
  48. std::vector<std::byte> container{};
  49. std::vector<std::byte> child{};
  50. std::vector<std::byte> root{};
  51. std::vector<std::byte> definition{};
  52. /** Shared reusable/randomized plug-set table read from investment-root slot 51. */
  53. std::vector<std::byte> plugSetTable{};
  54. /** Compact 0..3 special plug-category code of every dense installed item row. */
  55. std::array<std::uint8_t, state::build_data::items::kDefinitionCapacity> specialPlugCategories{};
  56. /** Inventory routing rows held until the paired bucket-definition table is resolved. */
  57. std::array<state::build_data::inventory::buckets::Descriptor,
  58. state::build_data::inventory::buckets::kDescriptorCapacity>
  59. bucketRows{};
  60. std::size_t bucketCount{};
  61. std::array<std::int8_t, state::build_data::inventory::buckets::kDescriptorCapacity>
  62. equipmentSlotByBucket{};
  63. DetailRequests detailRequests{};
  64. std::array<std::uint16_t, kDetailCapacity> requestedDetailIndices{};
  65. std::vector<state::build_data::items::details::Definition> details{};
  66. AuthoredHashes authoredHashes{};
  67. std::vector<std::byte> abilityTable{};
  68. std::vector<std::byte> abilityPool{};
  69. std::array<state::build_data::abilities::Definition,
  70. state::build_data::abilities::kDefinitionCapacity>
  71. abilityRows{};
  72. std::array<state::build_data::socket_entry_buckets::Definition,
  73. state::build_data::socket_entry_buckets::kDefinitionCapacity>
  74. entryBucketRows{};
  75. std::array<state::build_data::progressions::Definition,
  76. state::build_data::progressions::kDefinitionCapacity>
  77. progressionRows{};
  78. /** Record rows held until the completion flag mapping is resolved. */
  79. std::array<state::build_data::records::Definition,
  80. state::build_data::records::kDefinitionCapacity>
  81. recordRows{};
  82. /** Node rows held until the value slot and owned records are resolved. */
  83. std::array<state::build_data::nodes::Definition,
  84. state::build_data::nodes::kDefinitionCapacity>
  85. nodeRows{};
  86. std::array<state::build_data::collectibles::Definition,
  87. state::build_data::collectibles::kDefinitionCapacity>
  88. collectibleRows{};
  89. std::array<state::build_data::material_requirements::Definition,
  90. state::build_data::material_requirements::kDefinitionCapacity>
  91. materialRequirementRows{};
  92. std::array<state::build_data::items::Definition, state::build_data::items::kDefinitionCapacity>
  93. rows{};
  94. };
  95. /**
  96. * Collects the authored equipment and plug hashes every configured character names.
  97. * Hashes are sorted so the index-table walk can test each row by binary search instead of
  98. * rescanning the whole authored set per row.
  99. * @param output Receives the sorted unique authored hashes.
  100. * @return True when the account is good and every hash fits.
  101. */
  102. [[nodiscard]] bool collect_authored_hashes(AuthoredHashes& output) noexcept;
  103. /** @param hashes Sorted authored hashes. @param hash Row hash. @return True when authored. */
  104. [[nodiscard]] bool authored(const AuthoredHashes& hashes, std::uint32_t hash) noexcept;
  105. /**
  106. * @param row Installed item row.
  107. * @return True when its bucket maps to an equipment slot
  108. * supported by the generated loadout.
  109. */
  110. [[nodiscard]] bool equippable(const tables::items::Row& row) noexcept;
  111. /** Publishes parsed inventory buckets after applying the extracted item-slot relation. */
  112. [[nodiscard]] bool publish_buckets(Storage& storage) noexcept;
  113. /**
  114. * Adds one definition index to the deduplicated requested set.
  115. * @param definitionIndex Native
  116. * item index.
  117. * @param requested Requested-set storage.
  118. */
  119. void request(std::uint16_t definitionIndex, DetailRequests& requested) noexcept;
  120. /**
  121. * Adds every socket lane's initial plug to the requested set.
  122. * A lane using native defaults falls back to this plug, so its detail must exist.
  123. * @param row Item row already read from its definition blob.
  124. * @param itemDefinitionCount Installed item-table bound.
  125. * @param requested Requested-set storage.
  126. */
  127. void append_initial_plugs(const tables::items::Row& row,
  128. std::uint64_t itemDefinitionCount,
  129. DetailRequests& requested) noexcept;
  130. /**
  131. * Materializes requested native indices in ascending order.
  132. * @param requested Deduplicated native-index set.
  133. * @param output Fixed detail-index storage.
  134. * @param count Receives the number of selected rows, or zero when output is too small.
  135. * @return True when every selected row fits.
  136. */
  137. [[nodiscard]] bool materialize_requests(const DetailRequests& requested,
  138. std::span<std::uint16_t> output,
  139. std::size_t& count) noexcept;
  140. /**
  141. * Reads one requested definition and turns it into its cached detail form.
  142. * @param source Located item index table and package reader state.
  143. * @param definitionIndex Native item index.
  144. * @param detail Receives the cached detail.
  145. * @param item Receives the raw definition row the detail was built from.
  146. * @return True when the row is found and its definition blob reads.
  147. */
  148. [[nodiscard]] bool build_detail(const DetailSource& source,
  149. std::uint16_t definitionIndex,
  150. state::build_data::items::details::Definition& detail,
  151. tables::items::Row& item) noexcept;
  152. /**
  153. * Reads the stat rows the installed investment constants blob names.
  154. * @param source Package source.
  155. * @param scratch Reader scratch.
  156. * @param root Investment root bytes.
  157. * @param blob Scratch storage for the constants blob.
  158. * @param output Receives the extracted stat rows.
  159. * @return True when the blob reads and carries every named row.
  160. */
  161. [[nodiscard]] bool
  162. read_investment_constants(const reader::Source& source,
  163. reader::Scratch& scratch,
  164. std::span<const std::byte> root,
  165. std::vector<std::byte>& blob,
  166. state::build_data::constants::InvestmentConstants& output) noexcept;
  167. /**
  168. * Builds the ability buckets one subclass publishes under one ability selection.
  169. * @param source Package source.
  170. * @param scratch Reader scratch.
  171. * @param listDefinition Socket-entry-list definition bytes of the subclass.
  172. * @param blob Scratch storage reused for every pool blob.
  173. * @param selection The character's 5 selected socket entries.
  174. * @param output Receives the 12 buckets and the overflow bank.
  175. * @return True when every selected entry reaches a bucket of its own.
  176. */
  177. [[nodiscard]] bool build_ability_buckets(const reader::Source& source,
  178. reader::Scratch& scratch,
  179. std::span<const std::byte> listDefinition,
  180. std::vector<std::byte>& blob,
  181. const state::build_data::abilities::Selection& selection,
  182. state::build_data::abilities::Definition& output) noexcept;
  183. /**
  184. * Builds one ability bucket row per distinct subclass and ability selection in use.
  185. * Two characters on the same subclass with the same ability selection publish identical
  186. * buckets, so the row is keyed by both and built once.
  187. * @param source Package source.
  188. * @param scratch Reader scratch.
  189. * @param root Investment root bytes.
  190. * @param table Scratch storage for the socket entry list table.
  191. * @param definition Scratch storage for one socket entry list definition.
  192. * @param blob Scratch storage reused for every pool blob.
  193. * @param output Row storage.
  194. * @param count Receives the number of rows built.
  195. * @return True when the table reads; a subclass that fails is skipped, not fatal.
  196. */
  197. [[nodiscard]] bool build_character_abilities(
  198. const reader::Source& source,
  199. reader::Scratch& scratch,
  200. std::span<const std::byte> root,
  201. std::vector<std::byte>& table,
  202. std::vector<std::byte>& definition,
  203. std::vector<std::byte>& blob,
  204. std::span<state::build_data::abilities::Definition> output,
  205. std::size_t& count,
  206. std::span<state::build_data::socket_entry_buckets::Definition> entryBucketOutput,
  207. std::size_t& entryBucketCount) noexcept;
  208. /**
  209. * Resolves which of the 12 semantic ability buckets every entry in one socket-entry list reaches.
  210. * @param source Package source.
  211. * @param scratch Reader scratch.
  212. * @param listDefinition One socket-entry list's definition bytes.
  213. * @param blob Scratch storage reused for every pool blob.
  214. * @param output Receives one resolved bucket per entry, or the no-destination sentinel.
  215. * @return True when the list's entries read.
  216. */
  217. [[nodiscard]] bool resolve_entry_buckets(
  218. const reader::Source& source,
  219. reader::Scratch& scratch,
  220. std::span<const std::byte> listDefinition,
  221. std::vector<std::byte>& blob,
  222. std::array<std::uint8_t, state::build_data::socket_entry_lists::kEntryCapacity>&
  223. output) noexcept;
  224. /**
  225. * Reads the progression definition table and the object array each definition routes to.
  226. * The table is inline rows, not index rows. The scope byte in a row picks the replicated object
  227. * holding that progression, and the row's place among rows of that scope is its slot there.
  228. * @param source Package source.
  229. * @param scratch Reader scratch.
  230. * @param root Investment root bytes.
  231. * @param blob Scratch storage for the table.
  232. * @param output Row storage in native definition order.
  233. * @param count Receives the number of rows read.
  234. * @return True when the table reads and every row fits.
  235. */
  236. /**
  237. * Reads the records table and resolves each record's completion flag to a bank index.
  238. * @param source Package source.
  239. * @param scratch Reader scratch.
  240. * @param root Investment root bytes.
  241. * @param blob Scratch storage for the tables.
  242. * @param output Row storage in native record order.
  243. * @param count Receives the number of rows read.
  244. * @return True when both tables read and every row fits.
  245. */
  246. /**
  247. * Reads the presentation node table and resolves each node's value slot and owned records.
  248. * @param source Package source.
  249. * @param scratch Reader scratch.
  250. * @param root Investment root bytes.
  251. * @param blob Scratch storage for the tables.
  252. * @param output Row storage in native node order.
  253. * @param count Receives the number of rows read.
  254. * @return True when both tables read and every row fits.
  255. */
  256. [[nodiscard]] bool build_nodes(const reader::Source& source,
  257. reader::Scratch& scratch,
  258. std::span<const std::byte> root,
  259. std::vector<std::byte>& blob,
  260. std::span<state::build_data::nodes::Definition> output,
  261. std::size_t& count) noexcept;
  262. [[nodiscard]] bool build_records(const reader::Source& source,
  263. reader::Scratch& scratch,
  264. std::span<const std::byte> root,
  265. std::vector<std::byte>& blob,
  266. std::span<state::build_data::records::Definition> output,
  267. std::size_t& count) noexcept;
  268. [[nodiscard]] bool build_progressions(const reader::Source& source,
  269. reader::Scratch& scratch,
  270. std::span<const std::byte> root,
  271. std::vector<std::byte>& blob,
  272. std::span<state::build_data::progressions::Definition> output,
  273. std::size_t& count) noexcept;
  274. /**
  275. * Copies the block key material this pass borrows.
  276. * @param keys Receives the primary, alternate and nonce material.
  277. * @return True when the installed key table and the bootstrap token are both there.
  278. */
  279. [[nodiscard]] bool collect_keys(reader::BlockKeys& keys) noexcept;
  280. /**
  281. * Collects every catalogue tag carrying the container name.
  282. * @param candidates Receives the candidate tags.
  283. * @param count Receives the number of candidates.
  284. * @return True when the catalogue names at least one.
  285. */
  286. [[nodiscard]] bool
  287. investment_globals_tags(std::array<std::uint32_t, kContainerCandidates>& candidates,
  288. std::size_t& count) noexcept;
  289. /** @param directory Receives the installed packages directory. @return True when it exists. */
  290. [[nodiscard]] bool package_directory(core::path::Buffer& directory) noexcept;
  291. /** @param slot Requested-set position. @param definitionIndex Native item index that failed. */
  292. void report_detail_failure(std::size_t slot, std::uint16_t definitionIndex) noexcept;
  293. /** @param count Ability bucket rows the pass built, one per subclass and ability selection. */
  294. void report_ability_count(std::size_t count) noexcept;
  295. /** Reports a bounded number of exact subclass/ability extraction failures per process. */
  296. void report_ability_failure(const char* stage,
  297. std::size_t character,
  298. std::size_t first,
  299. std::size_t second) noexcept;
  300. /** Reports requested, retained, and skipped detail closure rows. */
  301. void report_detail_count(std::size_t requested, std::size_t built) noexcept;
  302. /**
  303. * Reports the item index-table walk, including rows the pass could not read.
  304. * @param walked Table entries the pass visited.
  305. * @param rows Readable rows it retained.
  306. * @param skipped Entries omitted because their index row or definition was malformed.
  307. * @param truncated True when the walk stopped early because the row storage filled.
  308. */
  309. void report_row_count(std::size_t walked,
  310. std::size_t rows,
  311. std::size_t skipped,
  312. bool truncated) noexcept;
  313. /** Reports the exact socket-rule, deduplicated-pool, member, and skipped-lane counts. */
  314. void report_socket_plug_count(std::size_t rules,
  315. std::size_t pools,
  316. std::size_t members,
  317. std::size_t skipped) noexcept;
  318. /** Reports the validated installed bucket/equipment-slot coverage. */
  319. void report_bucket_equipment_mapping(std::size_t mappedSlots) noexcept;
  320. /** Reports the first rejected bucket-definition invariant in one process. */
  321. void report_bucket_equipment_failure(const char* stage,
  322. std::size_t first,
  323. std::size_t second) noexcept;
  324. /**
  325. * Reports the pass outcome once.
  326. * @param published Rows published, or zero on failure.
  327. * @param reason Stage the pass reached, named in the line.
  328. */
  329. void report(std::size_t published, const char* reason) noexcept;
  330. /**
  331. * Publishes the inventory bucket descriptors from the root's bucket table.
  332. * @param source Package source.
  333. * @param storage Pass storage.
  334. * @param root Investment root bytes.
  335. * @return True when the table reads and publishes.
  336. */
  337. [[nodiscard]] bool build_buckets(const reader::Source& source,
  338. Storage& storage,
  339. std::span<const std::byte> root) noexcept;
  340. /**
  341. * Publishes the socket entry list table from the root.
  342. * @param source Package source.
  343. * @param storage Pass storage.
  344. * @param root Investment root bytes.
  345. * @return True when the table reads and publishes.
  346. */
  347. [[nodiscard]] bool build_socket_entry_lists(const reader::Source& source,
  348. Storage& storage,
  349. std::span<const std::byte> root) noexcept;
  350. /**
  351. * Reads and publishes the root's dense collectible-to-item mapping table.
  352. * @param source Package source.
  353. * @param storage Pass storage, including scratch bytes and bounded row storage.
  354. * @param root Investment root bytes.
  355. * @param itemDefinitionCount Number of rows in the installed item index table.
  356. * @return True when every tag, class, bound, and item link validates and publishes.
  357. */
  358. [[nodiscard]] bool build_collectibles(const reader::Source& source,
  359. Storage& storage,
  360. std::span<const std::byte> root,
  361. std::uint64_t itemDefinitionCount) noexcept;
  362. /**
  363. * Walks the located item index table, then publishes every domain that depends on it.
  364. * @param source Package source.
  365. * @param storage Pass storage holding the located table blob.
  366. * @param table Located item index array.
  367. * @param rowCount Receives the dense item rows published.
  368. * @param reason Receives the step name when a stage fails.
  369. * @return True when the dense table and every dependent domain publish.
  370. */
  371. [[nodiscard]] bool build_item_rows(const reader::Source& source,
  372. Storage& storage,
  373. const tables::Array& table,
  374. std::size_t& rowCount,
  375. const char*& reason) noexcept;
  376. /** Reads and publishes every native material-requirement set from investment-root slot 96. */
  377. [[nodiscard]] bool build_material_requirements(const reader::Source& source,
  378. Storage& storage,
  379. std::span<const std::byte> root,
  380. std::uint64_t itemDefinitionCount) noexcept;
  381. } // namespace sunrise::client::content::items::packages