squad_objective_auth.h 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. #pragma once
  2. #include <array>
  3. #include <cstddef>
  4. #include <cstdint>
  5. #include <span>
  6. #include "../../encoding/bit_writer.h"
  7. #include "auth_fields.h"
  8. #include "scriptable_auth_body.h"
  9. #include "squad_auth_body.h"
  10. // Type-1 squad Auth that assigns the squad to a native combat objective. Root .0 names the
  11. // objective, .13 carries the revision that invalidates its cost pass, .16 links a task group.
  12. // Counts, profile and spawn generation stay absent so the placement is untouched.
  13. namespace sunrise::middleware::bap::activity_message::squad_objective {
  14. namespace fields = auth_fields;
  15. inline constexpr std::uint32_t kSchema = squad_auth::kSchema;
  16. inline constexpr std::size_t kBits = 153;
  17. inline constexpr std::size_t kBytes = 20;
  18. /** Absent presence bits for fields .1 to .12. */
  19. inline constexpr std::uint8_t kAbsentMiddleFieldCount = 12;
  20. /** Root .15 is present and zero. Meaning unverified. */
  21. inline constexpr std::uint8_t kField15Width = 6;
  22. /** Root .16 task group: 5 bits with bias one, so -1 requests costs without a link. */
  23. inline constexpr std::uint8_t kTaskGroupWidth = 5;
  24. inline constexpr std::int32_t kTaskGroupBias = 1;
  25. inline constexpr std::int32_t kNoTaskGroup = -1;
  26. /** One objective sensor carries this many task groups. */
  27. inline constexpr std::int32_t kTaskGroupCount = 24;
  28. /** Root .18 active, 2 bits, written as the active wire value. */
  29. inline constexpr std::uint8_t kActiveWidth = 2;
  30. inline constexpr std::uint32_t kActiveValue = 2;
  31. /** Root .19 mode, 3 bits with bias one. Reserve keeps the counts for a delivery. */
  32. inline constexpr std::uint8_t kModeWidth = 3;
  33. inline constexpr std::uint32_t kModeBias = 1;
  34. struct Request final {
  35. std::uint32_t registryKey{};
  36. std::uint32_t revision{};
  37. std::uint16_t objectiveIndex{};
  38. std::int32_t taskGroup{kNoTaskGroup};
  39. bool reserved{};
  40. };
  41. /**
  42. * Encodes the objective assignment.
  43. * @param output Exactly kBytes.
  44. * @return False on an out-of-range revision, index or task group.
  45. */
  46. [[nodiscard]] inline bool encode(const Request& request, std::span<std::byte> output) noexcept {
  47. if (output.size() != kBytes || request.registryKey == 0 || request.revision == 0
  48. || request.revision > fields::kMaximumCounter
  49. || request.objectiveIndex > fields::kMaximumClientRefIndex
  50. || request.taskGroup < kNoTaskGroup || request.taskGroup >= kTaskGroupCount) {
  51. return false;
  52. }
  53. const auto mode = static_cast<std::uint32_t>(request.reserved ? squad_auth::Mode::reserve
  54. : squad_auth::Mode::mode2);
  55. encoding::bits::Writer writer(output);
  56. std::size_t written = 0;
  57. const std::array<fields::Field, 13> tail{{
  58. {0, kAbsentMiddleFieldCount},
  59. {1, fields::kPresenceWidth}, // .13 present
  60. {request.revision, fields::kCounterWidth},
  61. {0, fields::kPresenceWidth}, // .14 absent
  62. {1, fields::kPresenceWidth}, // .15 present
  63. {0, kField15Width},
  64. {1, fields::kPresenceWidth}, // .16 present
  65. {static_cast<std::uint32_t>(request.taskGroup + kTaskGroupBias), kTaskGroupWidth},
  66. {0, fields::kPresenceWidth}, // .17 absent
  67. {kActiveValue, kActiveWidth},
  68. {mode + kModeBias, kModeWidth},
  69. {1, fields::kPresenceWidth}, // .20 present
  70. {fields::kClientRefAbsentKey, 32}, // no name
  71. }};
  72. return writer.write(1, fields::kPresenceWidth)
  73. && fields::write_client_ref(
  74. writer, request.registryKey, scriptable_auth::kType3SlotType, request.objectiveIndex)
  75. && fields::write_fields(writer, tail)
  76. && fields::finish_exact(writer, kBits, kBytes, written);
  77. }
  78. } // namespace sunrise::middleware::bap::activity_message::squad_objective