notice_messages.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. /**
  2. * Bodies a group host emits. This host reads them so a container carrying one stays readable, and
  3. * acts on none of them: each one names an authority decision that belongs to whichever peer holds
  4. * the group, and answering from a body alone is how two peers end up both acting as host.
  5. */
  6. #include "notice_messages.h"
  7. #include "../../encoding/bit_raw.h"
  8. namespace sunrise::middleware::gameplay::group {
  9. namespace {
  10. namespace bits = encoding::bits;
  11. /** The protocol version is a 16-bit value field. */
  12. constexpr std::uint8_t kProtocolVersionWidth = 16;
  13. /** The boot kind is three bits. */
  14. constexpr std::uint8_t kBootKindWidth = 3;
  15. /** The boot reason is five bits. */
  16. constexpr std::uint8_t kBootReasonWidth = 5;
  17. /** The refusal kind is one bit. */
  18. constexpr std::uint8_t kRefuseKindWidth = 1;
  19. /** The refusal reason is six bits. */
  20. constexpr std::uint8_t kRefuseReasonWidth = 6;
  21. } // namespace
  22. /** Reads a peer-connect notice. */
  23. bool read_peer_connect(bits::Reader& reader, PeerConnectNotice& output) noexcept {
  24. PeerConnectNotice candidate{};
  25. std::uint64_t version = 0;
  26. if (!reader.read(kProtocolVersionWidth, version)
  27. || !bits::read_raw_u64(reader, candidate.machineId)
  28. || !bits::read_raw_u64(reader, candidate.sessionId)) {
  29. return false;
  30. }
  31. candidate.protocolVersion = static_cast<std::uint16_t>(version);
  32. output = candidate;
  33. return true;
  34. }
  35. /** Reads a session-boot notice. */
  36. bool read_session_boot(bits::Reader& reader, SessionBootNotice& output) noexcept {
  37. SessionBootNotice candidate{};
  38. std::uint64_t kind = 0;
  39. std::uint64_t reason = 0;
  40. if (!bits::read_raw_u64(reader, candidate.sessionId) || !reader.read(kBootKindWidth, kind)
  41. || !reader.read(kBootReasonWidth, reason)
  42. || !bits::read_raw_u64(reader, candidate.machineId)) {
  43. return false;
  44. }
  45. candidate.kind = static_cast<std::uint8_t>(kind);
  46. candidate.reason = static_cast<std::uint8_t>(reason);
  47. output = candidate;
  48. return true;
  49. }
  50. /** Reads a leadership delegation or a machine boot. */
  51. bool read_addressed_notice(bits::Reader& reader, bool withKind, AddressedNotice& output) noexcept {
  52. AddressedNotice candidate{};
  53. if (!bits::read_raw_u64(reader, candidate.sessionId)) {
  54. return false;
  55. }
  56. if (withKind) {
  57. std::uint64_t kind = 0;
  58. if (!reader.read(kBootKindWidth, kind)) {
  59. return false;
  60. }
  61. candidate.kind = static_cast<std::uint8_t>(kind);
  62. candidate.hasKind = true;
  63. }
  64. if (!bits::read_raw(reader, candidate.address)) {
  65. return false;
  66. }
  67. output = candidate;
  68. return true;
  69. }
  70. /** Reads a player refusal. */
  71. bool read_player_refuse(bits::Reader& reader, PlayerRefuse& output) noexcept {
  72. PlayerRefuse candidate{};
  73. std::uint64_t kind = 0;
  74. std::uint64_t reason = 0;
  75. if (!bits::read_raw_u64(reader, candidate.sessionId)
  76. || !bits::read_raw_u64(reader, candidate.playerId) || !reader.read(kRefuseKindWidth, kind)
  77. || !reader.read(kRefuseReasonWidth, reason)) {
  78. return false;
  79. }
  80. candidate.kindFlag = kind != 0;
  81. candidate.reason = static_cast<std::uint8_t>(reason);
  82. output = candidate;
  83. return true;
  84. }
  85. /** Consumes the opaque voice registration. */
  86. bool read_voice_registration(bits::Reader& reader) noexcept {
  87. // The checked build only probes whether the voice singleton exists and never reads the body.
  88. return bits::skip_raw(reader, kVoiceRegistrationBytes);
  89. }
  90. } // namespace sunrise::middleware::gameplay::group