state_account_dismantle_runtime.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. #include <Windows.h>
  2. #include <array>
  3. #include <cstddef>
  4. #include <cstdint>
  5. #include "runtime.h"
  6. #include "state_account_transaction_helpers.h"
  7. #include "storage/internal.h"
  8. namespace sunrise::state {
  9. using namespace runtime::detail;
  10. /** Prepares one selected-character unequipped item removal without changing account State. */
  11. bool prepare_item_dismantle(std::uint64_t instanceSoid, PendingItemDismantle& mutation) noexcept {
  12. mutation = {};
  13. const AccountState account = account_snapshot();
  14. if (instanceSoid == 0 || !account::valid(account)) {
  15. report_dismantle("prepare", "fail", "input", 0, 0, instanceSoid, 0, 0, 0, 0, 0);
  16. return false;
  17. }
  18. std::size_t characterIndex = account.characterCount;
  19. for (std::size_t index = 0; index < account.characterCount; ++index) {
  20. if (account.characters[index].selected) {
  21. characterIndex = index;
  22. break;
  23. }
  24. }
  25. if (characterIndex >= account.characterCount
  26. || !stage_item_dismantle(account, characterIndex, instanceSoid, mutation)) {
  27. report_dismantle(
  28. "prepare", "fail", "ownership_or_resolve", 0, 0, instanceSoid, 0, 0, 0, 0, 0);
  29. return false;
  30. }
  31. report_dismantle("prepare",
  32. "ok",
  33. "ready",
  34. mutation.dismantledItem.definitionHash,
  35. mutation.characterSoid,
  36. mutation.dismantledInstanceSoid,
  37. mutation.inventoryIndex,
  38. mutation.inventoryRow,
  39. mutation.equipmentSlot,
  40. mutation.movedInventoryItemCount,
  41. mutation.afterCharacter.nextInventorySerial);
  42. return true;
  43. }
  44. /** Produces the exact character-and-profile after-image while the captured views remain current. */
  45. bool preview_item_dismantle(const PendingItemDismantle& mutation, AccountState& after) noexcept {
  46. const AccountState current = account_snapshot();
  47. const bool ready = materialize_item_dismantle(current, mutation, after);
  48. report_dismantle("preview",
  49. ready ? "ok" : "fail",
  50. ready ? "ready" : "stale_or_invalid",
  51. mutation.dismantledItem.definitionHash,
  52. mutation.characterSoid,
  53. mutation.dismantledInstanceSoid,
  54. mutation.inventoryIndex,
  55. mutation.inventoryRow,
  56. mutation.equipmentSlot,
  57. mutation.movedInventoryItemCount,
  58. mutation.afterCharacter.nextInventorySerial);
  59. return ready;
  60. }
  61. /** Commits one prepared dismantle only while its complete account views are unchanged. */
  62. bool commit_item_dismantle(PendingItemDismantle& mutation) noexcept {
  63. const PendingItemDismantle prepared = mutation;
  64. mutation = {};
  65. const auto fail = [&prepared](std::string_view reason) noexcept {
  66. report_dismantle("commit",
  67. "fail",
  68. reason,
  69. prepared.dismantledItem.definitionHash,
  70. prepared.characterSoid,
  71. prepared.dismantledInstanceSoid,
  72. prepared.inventoryIndex,
  73. prepared.inventoryRow,
  74. prepared.equipmentSlot,
  75. prepared.movedInventoryItemCount,
  76. prepared.afterCharacter.nextInventorySerial);
  77. return false;
  78. };
  79. report_dismantle("commit_begin",
  80. "ok",
  81. "ready",
  82. prepared.dismantledItem.definitionHash,
  83. prepared.characterSoid,
  84. prepared.dismantledInstanceSoid,
  85. prepared.inventoryIndex,
  86. prepared.inventoryRow,
  87. prepared.equipmentSlot,
  88. prepared.movedInventoryItemCount,
  89. prepared.afterCharacter.nextInventorySerial);
  90. AcquireSRWLockExclusive(&runtime::storage::g_stateLock);
  91. AccountState candidate{};
  92. const bool ready =
  93. materialize_item_dismantle(runtime::storage::g_state.account, prepared, candidate);
  94. if (ready) {
  95. runtime::storage::g_state.account = candidate;
  96. }
  97. ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
  98. if (!ready) {
  99. return fail("stale_or_invalid");
  100. }
  101. report_dismantle("commit_end",
  102. "ok",
  103. "published",
  104. prepared.dismantledItem.definitionHash,
  105. prepared.characterSoid,
  106. prepared.dismantledInstanceSoid,
  107. prepared.inventoryIndex,
  108. prepared.inventoryRow,
  109. prepared.equipmentSlot,
  110. prepared.movedInventoryItemCount,
  111. prepared.afterCharacter.nextInventorySerial);
  112. return true;
  113. }
  114. } // namespace sunrise::state