bap_scriptable_override_route.cpp 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576
  1. /** Scriptable Auth overrides: target eligibility and the entry points a mission script calls. */
  2. #include <cstddef>
  3. #include <cstdint>
  4. #include <mutex>
  5. #include <shared_mutex>
  6. #include <span>
  7. #include "../../state/build_data/runtime.h"
  8. #include "../activity/host_runtime.h"
  9. #include "internal.h"
  10. #include "runtime.h"
  11. namespace sunrise::server::bap {
  12. namespace {
  13. namespace layouts = state::build_data::scenarios;
  14. namespace roster_message = middleware::bap::activity_message::sensor_auth_update;
  15. namespace tables = middleware::content::packages::tables;
  16. /** @return True when a generated group owns the exact requested type-23 Auth slot. */
  17. [[nodiscard]] bool valid_state_local_type23_target(const activity::host::ScriptableTarget& target,
  18. const layouts::RosterGroup& group) noexcept {
  19. return target.stateLocalRoster && layouts::valid_roster_group(group)
  20. && target.rosterGroupIndex == activity::host::kGeneratedRosterGroupIndex
  21. && target.sdkObjectIndex != activity::host::kNoSdkObjectIndex
  22. && target.slotType == middleware::bap::activity_message::scriptable_auth::kType23SlotType
  23. && target.authSchema == middleware::bap::activity_message::scriptable_auth::kType23Schema
  24. && group.objectTag == target.objectTag && group.registryKey == target.registryKey
  25. && target.rosterSlotOffset < group.slotCount
  26. && group.slotTypes[target.rosterSlotOffset] == target.slotType
  27. && group.slotIndices[target.rosterSlotOffset] == target.slotIndex
  28. && (group.slotFlags[target.rosterSlotOffset] & roster_message::kSlotAuthFlag) != 0;
  29. }
  30. /** @return True when a canonical group owns the exact requested type-23 Auth slot. */
  31. [[nodiscard]] bool
  32. valid_canonical_type23_target(const activity::host::ScriptableTarget& target) noexcept {
  33. if (target.stateLocalRoster || target.stateLocalRegion >= 0
  34. || target.rosterGroupIndex == activity::host::kGeneratedRosterGroupIndex
  35. || target.sdkObjectIndex != activity::host::kNoSdkObjectIndex
  36. || target.slotType != middleware::bap::activity_message::scriptable_auth::kType23SlotType
  37. || target.authSchema != middleware::bap::activity_message::scriptable_auth::kType23Schema) {
  38. return false;
  39. }
  40. layouts::RosterGroup group{};
  41. return state::build_data::find_roster_group(target.rosterGroupIndex, group)
  42. && layouts::valid_roster_group(group) && group.objectTag == target.objectTag
  43. && group.registryKey == target.registryKey && target.rosterSlotOffset < group.slotCount
  44. && group.slotTypes[target.rosterSlotOffset] == target.slotType
  45. && group.slotIndices[target.rosterSlotOffset] == target.slotIndex
  46. && (group.slotFlags[target.rosterSlotOffset] & roster_message::kSlotAuthFlag) != 0;
  47. }
  48. /** @return True when a generated group owns the exact requested SDK Auth slot. */
  49. [[nodiscard]] bool valid_state_local_sdk_auth_target(const activity::host::ScriptableTarget& target,
  50. const layouts::RosterGroup& group) noexcept {
  51. return target.stateLocalRoster && layouts::valid_roster_group(group)
  52. && target.rosterGroupIndex == activity::host::kGeneratedRosterGroupIndex
  53. && target.sdkObjectIndex != activity::host::kNoSdkObjectIndex
  54. && target.slotType <= roster_message::kMaximumSlotType
  55. && target.slotIndex <= roster_message::kMaximumSlotIndex && target.authSchema != 0
  56. && group.objectTag == target.objectTag && group.registryKey == target.registryKey
  57. && target.rosterSlotOffset < group.slotCount
  58. && group.slotTypes[target.rosterSlotOffset] == target.slotType
  59. && group.slotIndices[target.rosterSlotOffset] == target.slotIndex
  60. && (group.slotFlags[target.rosterSlotOffset] & roster_message::kSlotAuthFlag) != 0;
  61. }
  62. /** @return True when a canonical roster group owns the exact requested SDK Auth slot. */
  63. [[nodiscard]] bool
  64. valid_canonical_sdk_auth_target(const activity::host::ScriptableTarget& target) noexcept {
  65. if (target.stateLocalRoster || target.stateLocalRegion >= 0
  66. || target.rosterGroupIndex == activity::host::kGeneratedRosterGroupIndex
  67. || target.sdkObjectIndex != activity::host::kNoSdkObjectIndex
  68. || target.slotType > roster_message::kMaximumSlotType
  69. || target.slotIndex > roster_message::kMaximumSlotIndex || target.authSchema == 0) {
  70. return false;
  71. }
  72. layouts::RosterGroup group{};
  73. return state::build_data::find_roster_group(target.rosterGroupIndex, group)
  74. && layouts::valid_roster_group(group) && group.objectTag == target.objectTag
  75. && group.registryKey == target.registryKey && target.rosterSlotOffset < group.slotCount
  76. && group.slotTypes[target.rosterSlotOffset] == target.slotType
  77. && group.slotIndices[target.rosterSlotOffset] == target.slotIndex
  78. && (group.slotFlags[target.rosterSlotOffset] & roster_message::kSlotAuthFlag) != 0;
  79. }
  80. /** @return True when a generated group owns the exact requested type-31 Auth slot. */
  81. [[nodiscard]] bool valid_state_local_type31_target(const activity::host::ScriptableTarget& target,
  82. const layouts::RosterGroup& group) noexcept {
  83. return target.stateLocalRoster && layouts::valid_roster_group(group)
  84. && target.rosterGroupIndex == activity::host::kGeneratedRosterGroupIndex
  85. && target.sdkObjectIndex != activity::host::kNoSdkObjectIndex
  86. && target.slotType == middleware::bap::activity_message::scriptable_auth::kType31SlotType
  87. && target.authSchema == middleware::bap::activity_message::scriptable_auth::kType31Schema
  88. && group.objectTag == target.objectTag && group.registryKey == target.registryKey
  89. && target.rosterSlotOffset < group.slotCount
  90. && group.slotTypes[target.rosterSlotOffset] == target.slotType
  91. && group.slotIndices[target.rosterSlotOffset] == target.slotIndex
  92. && (group.slotFlags[target.rosterSlotOffset] & roster_message::kSlotAuthFlag) != 0;
  93. }
  94. /** @return True when one canonical table is active; repeated publication of that table is one
  95. * target. */
  96. [[nodiscard]] bool canonical_group_occurs_once(const layouts::Definition& layout,
  97. std::uint16_t tableIndex,
  98. std::int32_t region) noexcept {
  99. if (region < 0 || layout.rosterGroupCount == 0
  100. || layout.rosterGroupCount > layout.rosterGroups.size()
  101. || layout.bubbleGroupCount > layout.bubbleGroups.size()
  102. || layout.bubbleGroupCount > layout.bubbleGroupMasks.size()) {
  103. return false;
  104. }
  105. const std::uint32_t bubble = static_cast<std::uint32_t>(region) / tables::kSliceSetIndexFactor;
  106. if (bubble >= layouts::kBubbleCapacity) {
  107. return false;
  108. }
  109. std::size_t occurrences = 0;
  110. for (std::size_t index = 0; index < layout.rosterGroupCount; ++index) {
  111. occurrences += layout.rosterGroups[index] == tableIndex ? 1U : 0U;
  112. }
  113. for (std::size_t index = 0; index < layout.bubbleGroupCount; ++index) {
  114. const bool active = (layout.bubbleGroupMasks[index] & (std::uint64_t{1} << bubble)) != 0;
  115. occurrences += active && layout.bubbleGroups[index] == tableIndex ? 1U : 0U;
  116. }
  117. return occurrences != 0;
  118. }
  119. /** Checks one canonical type-23 request while the BAP lock owns ActivityClient state. */
  120. [[nodiscard]] bool canonical_type23_available_locked(const Session& session,
  121. const activity::host::ScriptableTarget& target,
  122. std::int32_t expectedRegion,
  123. std::uint64_t expectedGeneration) noexcept {
  124. const std::int32_t region = selected_region_index_locked(session);
  125. layouts::Definition layout{};
  126. return expectedRegion >= 0 && expectedGeneration != 0 && region == expectedRegion
  127. && session.activity.bindingGeneration == expectedGeneration
  128. && valid_canonical_type23_target(target) && session_scenario_layout(session, layout)
  129. && canonical_group_occurs_once(layout, target.rosterGroupIndex, region);
  130. }
  131. /** Checks one lifetime request while the BAP lock owns ActivityClient state. */
  132. [[nodiscard]] bool lifetime_available_locked(const Session& session,
  133. std::int32_t expectedRegion,
  134. std::uint64_t expectedGeneration) noexcept {
  135. const std::int32_t region = selected_region_index_locked(session);
  136. return expectedRegion >= 0 && expectedGeneration != 0 && region == expectedRegion
  137. && session.activity.bindingGeneration == expectedGeneration;
  138. }
  139. /** Checks one generated type-23 request while the BAP lock owns ActivityClient state. */
  140. [[nodiscard]] bool
  141. state_local_type23_available_locked(const Session& session,
  142. const activity::host::ScriptableTarget& target,
  143. const layouts::RosterGroup& stateLocalRosterGroup,
  144. std::int32_t expectedRegion,
  145. std::uint64_t expectedGeneration) noexcept {
  146. const std::int32_t region = selected_region_index_locked(session);
  147. return expectedRegion >= 0 && expectedGeneration != 0
  148. && session.activity.role == ActivityClientRole::privateCurrent
  149. && region == expectedRegion && target.stateLocalRegion == expectedRegion
  150. && session.activity.bindingGeneration == expectedGeneration
  151. && valid_state_local_type23_target(target, stateLocalRosterGroup);
  152. }
  153. /** Checks one canonical SDK Auth request while the BAP lock owns ActivityClient state. */
  154. [[nodiscard]] bool
  155. canonical_sdk_auth_available_locked(const Session& session,
  156. const activity::host::ScriptableTarget& target,
  157. std::int32_t expectedRegion,
  158. std::uint64_t expectedGeneration) noexcept {
  159. const std::int32_t region = selected_region_index_locked(session);
  160. layouts::Definition layout{};
  161. return expectedRegion >= 0 && expectedGeneration != 0 && region == expectedRegion
  162. && session.activity.bindingGeneration == expectedGeneration
  163. && valid_canonical_sdk_auth_target(target) && session_scenario_layout(session, layout)
  164. && canonical_group_occurs_once(layout, target.rosterGroupIndex, region);
  165. }
  166. /** Checks one generated SDK Auth request while the BAP lock owns ActivityClient state. */
  167. [[nodiscard]] bool
  168. state_local_sdk_auth_available_locked(const Session& session,
  169. const activity::host::ScriptableTarget& target,
  170. const layouts::RosterGroup& stateLocalRosterGroup,
  171. std::int32_t expectedRegion,
  172. std::uint64_t expectedGeneration) noexcept {
  173. const std::int32_t region = selected_region_index_locked(session);
  174. return expectedRegion >= 0 && expectedGeneration != 0
  175. && session.activity.role == ActivityClientRole::privateCurrent
  176. && region == expectedRegion && target.stateLocalRegion == expectedRegion
  177. && session.activity.bindingGeneration == expectedGeneration
  178. && valid_state_local_sdk_auth_target(target, stateLocalRosterGroup);
  179. }
  180. /** @return True when a generated group owns the exact requested type-43 Auth slot. */
  181. [[nodiscard]] bool
  182. valid_state_local_authored_scene_target(const activity::host::ScriptableTarget& target,
  183. const layouts::RosterGroup& group) noexcept {
  184. return target.stateLocalRoster && layouts::valid_roster_group(group)
  185. && target.rosterGroupIndex == activity::host::kGeneratedRosterGroupIndex
  186. && target.sdkObjectIndex != activity::host::kNoSdkObjectIndex
  187. && target.slotType == roster_message::kAuthoredSceneSlotType
  188. && target.authSchema == roster_message::kAuthoredSceneAuthSchema
  189. && group.objectTag == target.objectTag && group.registryKey == target.registryKey
  190. && target.rosterSlotOffset < group.slotCount
  191. && group.slotTypes[target.rosterSlotOffset] == target.slotType
  192. && group.slotIndices[target.rosterSlotOffset] == target.slotIndex
  193. && (group.slotFlags[target.rosterSlotOffset] & roster_message::kSlotAuthFlag) != 0;
  194. }
  195. } // namespace
  196. /** Read-only check of a canonical type-23 target on one live ActivityClient generation. */
  197. bool activity_type23_override_available(const state::activity::SessionBinding& binding,
  198. const activity::host::ScriptableTarget& target,
  199. std::int32_t expectedRegion,
  200. std::uint64_t expectedGeneration) noexcept {
  201. const std::shared_lock lock(session_lock());
  202. std::size_t linkCount = 0;
  203. const Session* const session = unique_activity_link_locked(binding, linkCount);
  204. const bool available =
  205. session != nullptr
  206. && canonical_type23_available_locked(*session, target, expectedRegion, expectedGeneration);
  207. return available;
  208. }
  209. /** Queues a type-23 override only while exactly one authenticated link owns the binding. */
  210. bool request_activity_type23_override(
  211. const state::activity::SessionBinding& binding,
  212. const activity::host::ScriptableTarget& target,
  213. middleware::bap::activity_message::scriptable_auth::Type23Channel channel,
  214. float value,
  215. bool snap,
  216. std::int32_t expectedRegion,
  217. std::uint64_t expectedGeneration,
  218. const activity::host::ScriptableOutputReservation* reservation) noexcept {
  219. const std::lock_guard lock(session_lock());
  220. std::size_t linkCount = 0;
  221. const Session* const session = unique_activity_link_locked(binding, linkCount);
  222. const bool queued =
  223. session != nullptr
  224. && canonical_type23_available_locked(*session, target, expectedRegion, expectedGeneration)
  225. && activity::host::request_type23_override(
  226. binding, target, channel, value, snap, expectedGeneration, reservation);
  227. return queued;
  228. }
  229. /** Queues one activity lifetime change while exactly one authenticated link owns the binding. */
  230. bool request_activity_lifetime_override(
  231. const state::activity::SessionBinding& binding,
  232. std::uint8_t lifetimeState,
  233. std::int32_t expectedRegion,
  234. std::uint64_t expectedGeneration,
  235. const activity::host::ScriptableOutputReservation* reservation) noexcept {
  236. const std::lock_guard lock(session_lock());
  237. std::size_t linkCount = 0;
  238. const Session* const session = unique_activity_link_locked(binding, linkCount);
  239. const bool queued = session != nullptr
  240. && lifetime_available_locked(*session, expectedRegion, expectedGeneration)
  241. && activity::host::request_lifetime_override(
  242. binding, lifetimeState, expectedGeneration, reservation);
  243. return queued;
  244. }
  245. /** Queues a generated type-23 update while its exact state is live. */
  246. bool request_activity_state_local_type23_override(
  247. const state::activity::SessionBinding& binding,
  248. const activity::host::ScriptableTarget& target,
  249. const layouts::RosterGroup& stateLocalRosterGroup,
  250. middleware::bap::activity_message::scriptable_auth::Type23Channel channel,
  251. float value,
  252. bool snap,
  253. std::int32_t expectedRegion,
  254. std::uint64_t expectedGeneration,
  255. const activity::host::ScriptableOutputReservation* reservation) noexcept {
  256. const std::lock_guard lock(session_lock());
  257. std::size_t linkCount = 0;
  258. const Session* const session = unique_activity_link_locked(binding, linkCount);
  259. const bool queued =
  260. session != nullptr
  261. && state_local_type23_available_locked(
  262. *session, target, stateLocalRosterGroup, expectedRegion, expectedGeneration)
  263. && activity::host::request_state_local_type23_override(binding,
  264. target,
  265. stateLocalRosterGroup,
  266. channel,
  267. value,
  268. snap,
  269. expectedGeneration,
  270. reservation);
  271. return queued;
  272. }
  273. /** Queues one structurally compiled SDK Auth body on an exact live target. */
  274. bool request_activity_sdk_auth_override(
  275. const state::activity::SessionBinding& binding,
  276. const activity::host::ScriptableTarget& target,
  277. const layouts::RosterGroup* stateLocalRosterGroup,
  278. std::span<const std::byte> body,
  279. std::uint16_t bitCount,
  280. std::int32_t expectedRegion,
  281. std::uint64_t expectedGeneration,
  282. const activity::host::ScriptableOutputReservation* reservation,
  283. activity::host::ScriptableOverrideKind kind) noexcept {
  284. const std::lock_guard lock(session_lock());
  285. std::size_t linkCount = 0;
  286. const Session* const session = unique_activity_link_locked(binding, linkCount);
  287. const bool available =
  288. session != nullptr
  289. && (target.stateLocalRoster
  290. ? stateLocalRosterGroup != nullptr
  291. && state_local_sdk_auth_available_locked(*session,
  292. target,
  293. *stateLocalRosterGroup,
  294. expectedRegion,
  295. expectedGeneration)
  296. : stateLocalRosterGroup == nullptr
  297. && canonical_sdk_auth_available_locked(
  298. *session, target, expectedRegion, expectedGeneration));
  299. const bool queued = available
  300. && activity::host::request_sdk_auth_override(binding,
  301. target,
  302. stateLocalRosterGroup,
  303. body,
  304. bitCount,
  305. expectedGeneration,
  306. reservation,
  307. kind);
  308. return queued;
  309. }
  310. /** Queues a type-31 pulse only while exactly one authenticated link owns the binding. */
  311. bool request_activity_type31_override(
  312. const state::activity::SessionBinding& binding,
  313. const activity::host::ScriptableTarget& target,
  314. std::int32_t expectedRegion,
  315. const activity::host::ScriptableOutputReservation* reservation,
  316. bool enabled) noexcept {
  317. const std::lock_guard lock(session_lock());
  318. std::size_t linkCount = 0;
  319. const Session* const session = unique_activity_link_locked(binding, linkCount);
  320. const bool queued =
  321. expectedRegion >= 0 && session != nullptr
  322. && selected_region_index_locked(*session) == expectedRegion
  323. && activity::host::request_type31_override(binding, target, reservation, enabled);
  324. return queued;
  325. }
  326. /** Queues one generation-bound type-31 pulse for the selected live state. */
  327. bool request_activity_state_local_type31_override(
  328. const state::activity::SessionBinding& binding,
  329. const activity::host::ScriptableTarget& target,
  330. const state::build_data::scenarios::RosterGroup& stateLocalRosterGroup,
  331. std::int32_t expectedRegion,
  332. std::uint64_t expectedGeneration,
  333. const activity::host::ScriptableOutputReservation* reservation,
  334. bool enabled) noexcept {
  335. const std::lock_guard lock(session_lock());
  336. std::size_t linkCount = 0;
  337. const Session* const session = unique_activity_link_locked(binding, linkCount);
  338. const std::int32_t region = session != nullptr ? selected_region_index_locked(*session) : -1;
  339. const bool queued =
  340. expectedRegion >= 0 && expectedGeneration != 0 && session != nullptr
  341. && session->activity.role == ActivityClientRole::privateCurrent && region == expectedRegion
  342. && target.stateLocalRegion == expectedRegion
  343. && session->activity.bindingGeneration == expectedGeneration
  344. && valid_state_local_type31_target(target, stateLocalRosterGroup)
  345. && activity::host::request_state_local_type31_override(
  346. binding, target, stateLocalRosterGroup, expectedGeneration, reservation, enabled);
  347. return queued;
  348. }
  349. /** Queues one sequence restart from an exact published SDK mission seed. */
  350. bool request_activity_state_local_sequence_override(
  351. const state::activity::SessionBinding& binding,
  352. const activity::host::ScriptableTarget& target,
  353. const state::build_data::scenarios::RosterGroup& stateLocalRosterGroup,
  354. std::int32_t expectedRegion,
  355. std::uint64_t expectedGeneration,
  356. const activity::host::ScriptableOutputReservation* reservation) noexcept {
  357. const std::lock_guard lock(session_lock());
  358. std::size_t linkCount = 0;
  359. const Session* const session = unique_activity_link_locked(binding, linkCount);
  360. const std::int32_t region = session != nullptr ? selected_region_index_locked(*session) : -1;
  361. const bool queued =
  362. expectedRegion >= 0 && expectedGeneration != 0 && session != nullptr
  363. && session->activity.role == ActivityClientRole::privateCurrent && region == expectedRegion
  364. && target.stateLocalRegion == expectedRegion
  365. && session->activity.bindingGeneration == expectedGeneration
  366. && valid_state_local_sdk_auth_target(target, stateLocalRosterGroup)
  367. && target.slotType == middleware::bap::activity_message::scriptable_auth::kType5SlotType
  368. && target.authSchema == middleware::bap::activity_message::scriptable_auth::kType5Schema
  369. && activity::host::request_state_local_sequence_override(
  370. binding, target, stateLocalRosterGroup, expectedGeneration, reservation);
  371. return queued;
  372. }
  373. /** Queues one cinematic transition from an exact published SDK mission seed. */
  374. bool request_activity_state_local_cinematic_override(
  375. const state::activity::SessionBinding& binding,
  376. const activity::host::ScriptableTarget& target,
  377. const state::build_data::scenarios::RosterGroup& stateLocalRosterGroup,
  378. bool active,
  379. std::int32_t expectedRegion,
  380. std::uint64_t expectedGeneration,
  381. const activity::host::ScriptableOutputReservation* reservation) noexcept {
  382. const std::lock_guard lock(session_lock());
  383. std::size_t linkCount = 0;
  384. const Session* const session = unique_activity_link_locked(binding, linkCount);
  385. const std::int32_t region = session != nullptr ? selected_region_index_locked(*session) : -1;
  386. const bool queued =
  387. expectedRegion >= 0 && expectedGeneration != 0 && session != nullptr
  388. && session->activity.role == ActivityClientRole::privateCurrent && region == expectedRegion
  389. && target.stateLocalRegion == expectedRegion
  390. && session->activity.bindingGeneration == expectedGeneration
  391. && valid_state_local_sdk_auth_target(target, stateLocalRosterGroup)
  392. && target.slotType == middleware::bap::activity_message::scriptable_auth::kType6SlotType
  393. && target.authSchema == middleware::bap::activity_message::scriptable_auth::kType6Schema
  394. && activity::host::request_state_local_cinematic_override(
  395. binding, target, stateLocalRosterGroup, active, expectedGeneration, reservation);
  396. return queued;
  397. }
  398. /** Queues one performance start from an exact published SDK mission seed. */
  399. bool request_activity_state_local_performance_override(
  400. const state::activity::SessionBinding& binding,
  401. const activity::host::ScriptableTarget& target,
  402. const state::build_data::scenarios::RosterGroup& stateLocalRosterGroup,
  403. std::uint32_t stateNameHash,
  404. std::int32_t expectedRegion,
  405. std::uint64_t expectedGeneration,
  406. const activity::host::ScriptableOutputReservation* reservation) noexcept {
  407. const std::lock_guard lock(session_lock());
  408. std::size_t linkCount = 0;
  409. const Session* const session = unique_activity_link_locked(binding, linkCount);
  410. const std::int32_t region = session != nullptr ? selected_region_index_locked(*session) : -1;
  411. const bool queued =
  412. expectedRegion >= 0 && expectedGeneration != 0 && session != nullptr
  413. && session->activity.role == ActivityClientRole::privateCurrent && region == expectedRegion
  414. && target.stateLocalRegion == expectedRegion
  415. && session->activity.bindingGeneration == expectedGeneration
  416. && valid_state_local_sdk_auth_target(target, stateLocalRosterGroup)
  417. && target.slotType == middleware::bap::activity_message::scriptable_auth::kType42SlotType
  418. && target.authSchema == middleware::bap::activity_message::scriptable_auth::kType42Schema
  419. && activity::host::request_state_local_performance_override(
  420. binding, target, stateLocalRosterGroup, stateNameHash, expectedGeneration, reservation);
  421. return queued;
  422. }
  423. /** Queues one authored-scene activation from an exact published SDK mission seed. */
  424. bool request_activity_state_local_authored_scene_override(
  425. const state::activity::SessionBinding& binding,
  426. const activity::host::ScriptableTarget& target,
  427. const state::build_data::scenarios::RosterGroup& stateLocalRosterGroup,
  428. std::int32_t expectedRegion,
  429. std::uint64_t expectedGeneration,
  430. const activity::host::ScriptableOutputReservation* reservation,
  431. const activity::host::AuthoredSceneDependencies& dependencies,
  432. std::uint32_t eventKey,
  433. bool stop) noexcept {
  434. const std::lock_guard lock(session_lock());
  435. std::size_t linkCount = 0;
  436. const Session* const session = unique_activity_link_locked(binding, linkCount);
  437. const std::int32_t region = session != nullptr ? selected_region_index_locked(*session) : -1;
  438. const bool queued =
  439. expectedRegion >= 0 && expectedGeneration != 0 && session != nullptr
  440. && session->activity.role == ActivityClientRole::privateCurrent && region == expectedRegion
  441. && target.stateLocalRegion == expectedRegion
  442. && session->activity.bindingGeneration == expectedGeneration
  443. && valid_state_local_authored_scene_target(target, stateLocalRosterGroup)
  444. && activity::host::request_state_local_authored_scene_override(binding,
  445. target,
  446. stateLocalRosterGroup,
  447. expectedGeneration,
  448. reservation,
  449. dependencies,
  450. eventKey,
  451. stop);
  452. return queued;
  453. }
  454. /** Queues one bounded authored-dialogue line from an exact published SDK mission seed. */
  455. bool request_activity_state_local_dialogue_override(
  456. const state::activity::SessionBinding& binding,
  457. const activity::host::ScriptableTarget& target,
  458. const state::build_data::scenarios::RosterGroup& stateLocalRosterGroup,
  459. std::uint16_t cueIndex,
  460. std::uint16_t authoredCueCount,
  461. std::int32_t expectedRegion,
  462. std::uint64_t expectedGeneration,
  463. const activity::host::ScriptableOutputReservation* reservation,
  464. middleware::bap::activity_message::scriptable_auth::Type2LaneClientRef filter) noexcept {
  465. const std::lock_guard lock(session_lock());
  466. std::size_t linkCount = 0;
  467. const Session* const session = unique_activity_link_locked(binding, linkCount);
  468. const std::int32_t region = session != nullptr ? selected_region_index_locked(*session) : -1;
  469. const bool queued =
  470. expectedRegion >= 0 && expectedGeneration != 0 && session != nullptr
  471. && session->activity.role == ActivityClientRole::privateCurrent && region == expectedRegion
  472. && target.stateLocalRegion == expectedRegion
  473. && session->activity.bindingGeneration == expectedGeneration
  474. && valid_state_local_sdk_auth_target(target, stateLocalRosterGroup)
  475. && target.slotType == middleware::bap::activity_message::scriptable_auth::kType53SlotType
  476. && target.authSchema == middleware::bap::activity_message::scriptable_auth::kType53Schema
  477. && activity::host::request_state_local_dialogue_override(binding,
  478. target,
  479. stateLocalRosterGroup,
  480. cueIndex,
  481. authoredCueCount,
  482. expectedGeneration,
  483. reservation,
  484. filter);
  485. return queued;
  486. }
  487. /** Queues one objective reset from an exact published SDK mission seed. */
  488. bool request_activity_state_local_objective_reset(
  489. const state::activity::SessionBinding& binding,
  490. const activity::host::ScriptableTarget& target,
  491. const state::build_data::scenarios::RosterGroup& stateLocalRosterGroup,
  492. std::int32_t expectedRegion,
  493. std::uint64_t expectedGeneration,
  494. const activity::host::ScriptableOutputReservation* reservation) noexcept {
  495. const std::lock_guard lock(session_lock());
  496. std::size_t linkCount = 0;
  497. const Session* const session = unique_activity_link_locked(binding, linkCount);
  498. const std::int32_t region = session != nullptr ? selected_region_index_locked(*session) : -1;
  499. const bool queued =
  500. expectedRegion >= 0 && expectedGeneration != 0 && session != nullptr
  501. && session->activity.role == ActivityClientRole::privateCurrent && region == expectedRegion
  502. && target.stateLocalRegion == expectedRegion
  503. && session->activity.bindingGeneration == expectedGeneration
  504. && valid_state_local_sdk_auth_target(target, stateLocalRosterGroup)
  505. && target.slotType == middleware::bap::activity_message::scriptable_auth::kType3SlotType
  506. && target.authSchema == middleware::bap::activity_message::scriptable_auth::kType3Schema
  507. && activity::host::request_state_local_objective_reset(
  508. binding, target, stateLocalRosterGroup, expectedGeneration, reservation);
  509. return queued;
  510. }
  511. /** Queues one authored-task generation from an exact published SDK mission seed. */
  512. bool request_activity_state_local_task_override(
  513. const state::activity::SessionBinding& binding,
  514. const activity::host::ScriptableTarget& target,
  515. const state::build_data::scenarios::RosterGroup& stateLocalRosterGroup,
  516. std::int32_t expectedRegion,
  517. std::uint64_t expectedGeneration,
  518. const activity::host::ScriptableOutputReservation* reservation) noexcept {
  519. const std::lock_guard lock(session_lock());
  520. std::size_t linkCount = 0;
  521. const Session* const session = unique_activity_link_locked(binding, linkCount);
  522. const std::int32_t region = session != nullptr ? selected_region_index_locked(*session) : -1;
  523. const bool queued =
  524. expectedRegion >= 0 && expectedGeneration != 0 && session != nullptr
  525. && session->activity.role == ActivityClientRole::privateCurrent && region == expectedRegion
  526. && target.stateLocalRegion == expectedRegion
  527. && session->activity.bindingGeneration == expectedGeneration
  528. && valid_state_local_sdk_auth_target(target, stateLocalRosterGroup)
  529. && target.slotType == middleware::bap::activity_message::scriptable_auth::kType38SlotType
  530. && target.authSchema == middleware::bap::activity_message::scriptable_auth::kType38Schema
  531. && activity::host::request_state_local_task_override(
  532. binding, target, stateLocalRosterGroup, expectedGeneration, reservation);
  533. return queued;
  534. }
  535. /** Cancels one exact typed override revision while excluding activity-link publication. */
  536. bool cancel_activity_scriptable_override(const state::activity::SessionBinding& binding,
  537. std::uint64_t expectedRevision) noexcept {
  538. const std::lock_guard lock(session_lock());
  539. const bool canceled =
  540. activity::host::cancel_pending_scriptable_override(binding, expectedRevision);
  541. return canceled;
  542. }
  543. } // namespace sunrise::server::bap