bap_world_reward_queue.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. #include "../../core/logging/log.h"
  2. #include "../../state/build_data/runtime.h"
  3. #include "../../state/investment/store_internal.h"
  4. #include "internal.h"
  5. namespace sunrise::server::bap {
  6. namespace {
  7. /** Grants and retires one earned reward in the same database transaction. */
  8. bool commit_world_reward(const WorldRewardRequest& request) noexcept {
  9. state::investment::store::Transaction transaction;
  10. if (!transaction.ready()) {
  11. return false;
  12. }
  13. bool committed = false;
  14. if (request.kind == WorldRewardKind::item) {
  15. state::PendingItemAcquisition acquisition;
  16. committed =
  17. state::prepare_item_acquisition_for_item(request.itemDefinitionIndex, acquisition)
  18. && state::commit_item_acquisition(acquisition);
  19. } else {
  20. state::PendingProfileItemAcquisition acquisition;
  21. committed = state::prepare_profile_item_acquisition_for_item(
  22. request.itemDefinitionIndex, request.quantity, acquisition)
  23. && state::commit_profile_item_acquisition(acquisition);
  24. }
  25. return committed && complete_world_reward(request.id) && transaction.commit();
  26. }
  27. /** Saves the reward under its stable definition hash and earning character. */
  28. bool enqueue_world_reward(std::uint16_t definitionIndex,
  29. std::int32_t quantity,
  30. WorldRewardKind kind) noexcept {
  31. state::build_data::items::Definition definition;
  32. if (!state::build_data::find_item_definition_index(definitionIndex, definition)
  33. || !state::investment::store::enqueue_reward(
  34. definition.definitionHash, quantity, static_cast<std::uint8_t>(kind))) {
  35. return false;
  36. }
  37. if (!has_active_family4_peer()) {
  38. settle_world_reward();
  39. }
  40. return true;
  41. }
  42. } // namespace
  43. /** Saves one item reward before its pickup presentation is queued. */
  44. bool arm_world_item_acquisition(std::uint16_t itemDefinitionIndex) noexcept {
  45. return enqueue_world_reward(itemDefinitionIndex, 1, WorldRewardKind::item);
  46. }
  47. /** Saves a profile material reward before its pickup presentation is queued. */
  48. bool arm_world_profile_item_acquisition(std::uint16_t itemDefinitionIndex,
  49. std::int32_t quantity) noexcept {
  50. return quantity > 0
  51. && enqueue_world_reward(itemDefinitionIndex, quantity, WorldRewardKind::profileItem);
  52. }
  53. /** Restores the oldest reward belonging to the selected character. */
  54. bool current_world_reward(WorldRewardRequest& request) noexcept {
  55. request = {};
  56. state::investment::store::PendingReward saved;
  57. state::build_data::items::Definition definition;
  58. if (!state::investment::store::next_reward(saved)
  59. || !state::build_data::find_item_definition_hash(saved.definitionHash, definition)) {
  60. return false;
  61. }
  62. request.id = saved.id;
  63. request.quantity = saved.quantity;
  64. request.itemDefinitionIndex = definition.definitionIndex;
  65. request.kind = static_cast<WorldRewardKind>(saved.kind);
  66. return true;
  67. }
  68. /** Acknowledges exactly the reward whose inventory grant is being committed. */
  69. bool complete_world_reward(std::uint64_t id) noexcept {
  70. return state::investment::store::complete_reward(id);
  71. }
  72. /** A failed grant stays saved for a later attempt. */
  73. void settle_world_reward() noexcept {
  74. WorldRewardRequest request;
  75. if (current_world_reward(request) && commit_world_reward(request)) {
  76. arm_account_resync_everywhere();
  77. }
  78. }
  79. /** Shutdown may grant ready rewards; rewards for other characters stay in the database. */
  80. void drain_world_rewards() noexcept {
  81. WorldRewardRequest request;
  82. while (current_world_reward(request)) {
  83. if (!commit_world_reward(request)) {
  84. break;
  85. }
  86. }
  87. }
  88. } // namespace sunrise::server::bap