| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238 |
- #include <array>
- #include <cstddef>
- #include <cstdint>
- #include <limits>
- #include <span>
- #include <string_view>
- #include "../../../middleware/bap/activity_message/auth_fields.h"
- #include "../../../middleware/bap/activity_message/auth_schema_catalog.h"
- #include "mission_script_lua_internal.h"
- namespace sunrise::server::activity::mission::lua_vm::detail {
- namespace format = state::activity_sdk::format;
- namespace scriptable_auth = middleware::bap::activity_message::scriptable_auth;
- namespace auth_fields = middleware::bap::activity_message::auth_fields;
- namespace auth_catalog = middleware::bap::activity_message::auth_schema_catalog;
- /** Positive 31-bit generations and revisions are the counters every typed Auth body accepts. */
- [[nodiscard]] bool valid_counter(lua_Integer value) noexcept {
- return value > 0 && value <= auth_fields::kMaximumCounter;
- }
- /**
- * Reads one optional slot-handle argument into a ClientRef.
- * @param slotType Slot type the referenced slot must have.
- * @param output Left unset when the argument is nil.
- * @return False when the argument is present but stale or of another type.
- */
- [[nodiscard]] bool optional_slot_reference(lua_State* state,
- const char* name,
- std::uint32_t slotType,
- scriptable_auth::Type2LaneClientRef& output) {
- lua_getfield(state, 2, name);
- bool valid = true;
- if (!lua_isnil(state, -1)) {
- const auto* const handle =
- static_cast<const SlotHandle*>(luaL_checkudata(state, -1, kSlotMetatable));
- SlotDefinition definition{};
- valid = current_slot(state, *handle, definition) && definition.slotType == slotType
- && definition.slotIndex <= auth_fields::kMaximumClientRefIndex;
- if (valid) {
- output = {definition.registryKey,
- static_cast<std::int8_t>(slotType),
- static_cast<std::int16_t>(definition.slotIndex)};
- }
- }
- lua_pop(state, 1);
- return valid;
- }
- /** Stages one authored native Auth body on the guarded message-5 route. */
- [[nodiscard]] int queue_slot_auth(lua_State* state,
- const SlotDefinition& slot,
- std::uint32_t schema,
- std::size_t bitCount,
- std::span<const std::byte> body,
- IntentKind kind,
- bool active) {
- Impl* const impl = impl_from_state(state);
- std::array<std::byte, 32> sdkBuildSha256{};
- if (!decode_sdk_build_sha256(std::string_view(impl->identity.sdkBuildId.data()),
- sdkBuildSha256)) {
- return luaL_error(state, "loaded SDK generation identity is invalid");
- }
- CallFrame& frame = active_frame(state);
- Intent intent{};
- intent.kind = kind;
- intent.active = active;
- intent.sdkBuildSha256 = sdkBuildSha256;
- intent.firstRow = slot.nativeRow;
- if (kind == IntentKind::runActorProgram && active) {
- if (impl->definitions.resolveActorProgramSource == nullptr
- || !impl->definitions.resolveActorProgramSource(
- impl->definitions.context, slot.nativeRow, intent.secondRow)) {
- return luaL_error(state, "actor creation has no exact authored source");
- }
- }
- intent.objectTag = slot.objectTag;
- intent.registryKey = slot.registryKey;
- intent.authSchema = schema;
- intent.authBitCount = static_cast<std::uint16_t>(bitCount);
- intent.slotIndex = static_cast<std::uint16_t>(slot.slotIndex);
- intent.slotType = static_cast<std::uint8_t>(slot.slotType);
- intent.authByteCount = static_cast<std::uint16_t>(body.size());
- try {
- intent.authBody.assign(body.begin(), body.end());
- } catch (const std::bad_alloc&) {
- return luaL_error(state, "mission Auth body allocation failed");
- }
- return queue_intent(state, frame, intent);
- }
- /** Reads one integer field from a generated directive declaration. */
- [[nodiscard]] lua_Integer directive_integer(lua_State* state, int table, const char* field) {
- lua_getfield(state, table, field);
- const lua_Integer value = luaL_checkinteger(state, -1);
- lua_pop(state, 1);
- return value;
- }
- /** Reads one Slot row member, its syntax methods, and its authorized actions. */
- [[nodiscard]] int slot_index(lua_State* state) {
- const auto* const handle =
- static_cast<const SlotHandle*>(luaL_checkudata(state, 1, kSlotMetatable));
- SlotDefinition definition{};
- if (!current_slot(state, *handle, definition)) {
- return luaL_error(state, "activity slot is stale");
- }
- const std::string_view key = lua_string_view(state, 2);
- if (key == "row") {
- lua_pushinteger(state, definition.localRow);
- } else if (key == "applied") {
- lua_pushcfunction(state, &slot_applied);
- } else if (key == "id") {
- lua_pushlstring(state, definition.id.data(), definition.id.size());
- } else if (key == "name") {
- lua_pushlstring(state, definition.name.data(), definition.name.size());
- } else if (key == "object_id") {
- lua_pushlstring(state, definition.objectId.data(), definition.objectId.size());
- } else if (key == "object_tag") {
- lua_pushinteger(state, definition.objectTag);
- } else if (key == "registry_key") {
- lua_pushinteger(state, definition.registryKey);
- } else if (key == "slot_index") {
- lua_pushinteger(state, definition.slotIndex);
- } else if (key == "slot_type") {
- lua_pushinteger(state, definition.slotType);
- } else if (key == "component_class") {
- lua_pushinteger(state, definition.componentClass);
- } else if (key == "sense_schema") {
- lua_pushinteger(state, definition.senseSchema);
- } else if (key == "auth_schema") {
- lua_pushinteger(state, definition.authSchema);
- } else if (key == "sense_schema_id") {
- lua_pushlstring(state, definition.senseSchemaId.data(), definition.senseSchemaId.size());
- } else if (key == "auth_schema_id") {
- lua_pushlstring(state, definition.authSchemaId.data(), definition.authSchemaId.size());
- } else if (key == "auth_type" || key == "auth_min_bits" || key == "auth_max_bits"
- || key == "auth_component_offset" || key == "auth_dynamic"
- || key == "auth_writable") {
- const auth_catalog::Type* const auth = auth_catalog::find(
- static_cast<std::uint8_t>(definition.slotType), definition.authSchema);
- if (auth == nullptr) {
- lua_pushnil(state);
- } else if (key == "auth_type") {
- lua_pushlstring(state, auth->name.data(), auth->name.size());
- } else if (key == "auth_min_bits") {
- lua_pushinteger(state, auth->minimumBits);
- } else if (key == "auth_max_bits") {
- lua_pushinteger(state, auth->maximumBits);
- } else if (key == "auth_component_offset") {
- if (auth->hasContiguousMirror) {
- lua_pushinteger(state, auth->componentOffset);
- } else {
- lua_pushnil(state);
- }
- } else if (key == "auth_dynamic") {
- lua_pushboolean(state, auth->hasDynamicBody);
- } else {
- lua_pushboolean(state, auth->writable);
- }
- } else if (key == "flags") {
- lua_pushinteger(state, definition.flags);
- } else if (key == "set_object_filter") {
- lua_pushcfunction(state, &slot_set_object_filter);
- } else if (key == "watch_damage") {
- lua_pushcfunction(state, &slot_watch_damage);
- } else if (key == "set_object_active") {
- lua_pushcfunction(state, &slot_set_object_active);
- } else if (key == "set_channel") {
- lua_pushcfunction(state, &slot_set_channel);
- } else if (key == "transition") {
- lua_pushcfunction(state, &slot_transition);
- } else if (key == "set_occupancy_condition") {
- lua_pushcfunction(state, &slot_set_occupancy_condition);
- } else if (key == "generate_map") {
- lua_pushcfunction(state, &slot_generate_map);
- } else if (key == "set_directive") {
- lua_pushcfunction(state, &slot_set_directive);
- } else if (key == "clear_directives") {
- lua_pushcfunction(state, &slot_clear_directives);
- } else if (key == "set_darkness_zone") {
- lua_pushcfunction(state, &slot_set_darkness_zone);
- } else if (key == "set_music_section") {
- lua_pushcfunction(state, &slot_set_music_section);
- } else if (key == "set_interactable_object") {
- lua_pushcfunction(state, &slot_set_interactable_object);
- } else if (key == "set_ghost_link") {
- lua_pushcfunction(state, &slot_set_ghost_link);
- } else if (key == "ghost_link") {
- lua_pushcfunction(state, &slot_ghost_link);
- } else if (key == "set_public_event_state") {
- lua_pushcfunction(state, &slot_set_public_event_state);
- } else if (key == "assign_combat_objective") {
- lua_pushcfunction(state, &slot_assign_combat_objective);
- } else if (key == "play_actor_path") {
- lua_pushcfunction(state, &slot_play_actor_path);
- } else if (key == "play_actor_action") {
- lua_pushcfunction(state, &slot_play_actor_action);
- } else if (key == "retire_actor") {
- lua_pushcfunction(state, &slot_retire_actor);
- } else if (key == "bind_combatant_to_squad") {
- lua_pushcfunction(state, &slot_bind_combatant_to_squad);
- } else if (key == "run_atoms") {
- lua_pushcfunction(state, &slot_run_atoms);
- } else if (key == "fire_trigger") {
- lua_pushcfunction(state, &slot_fire_trigger);
- } else if (key == "disarm_trigger") {
- lua_pushcfunction(state, &slot_disarm_trigger);
- } else if (key == "play_sequence") {
- lua_pushcfunction(state,
- exact_combatant_slot(definition) ? &slot_play_actor_sequence
- : &slot_play_sequence);
- } else if (key == "sequences") {
- lua_pushcfunction(state, &slot_actor_sequences);
- } else if (key == "set_cinematic_active") {
- lua_pushcfunction(state, &slot_set_cinematic_active);
- } else if (key == "reset_objectives") {
- lua_pushcfunction(state, &slot_reset_objectives);
- } else if (key == "advance_task") {
- lua_pushcfunction(state, &slot_advance_task);
- } else if (key == "play_dialogue_cue") {
- lua_pushcfunction(state, &slot_play_dialogue_cue);
- } else if (key == "play_performance") {
- lua_pushcfunction(state, &slot_play_performance);
- } else {
- lua_pushnil(state);
- }
- return 1;
- }
- void register_slot_metatables(lua_State* state) {
- register_metatable(state, kSlotMetatable, &slot_index);
- }
- } // namespace sunrise::server::activity::mission::lua_vm::detail
|