Преглед изворни кода

Revert "Publish authored cinematic state before its controller authority"

This reverts commit a312bdcfaec05af86ab62ff87cea6b29ff3911aa.
Millie пре 3 дана
родитељ
комит
647fe3fd1d

+ 1 - 13
MISSION_EMBER_POST_OPUS.md

@@ -36,16 +36,4 @@ Installed DLL SHA-256: `be4ea67c9399c4f08c41eac25f9ed2f27152dff9876b449e8d0d60e7
 
 ## Scope correction
 
-Loading suppression is now limited to 1AU using the native loading activity reader above. The corrected Release DLL built successfully, and offline signature/call validation passed. The initial installation was deferred while the game was running; the correction is now installed with the ending-state candidate below. The scope-only installer is `/tmp/install-ember-loading-scope.py` and preserves settings, saves and scripts.
-
-## Ending-state candidate — 15:30
-
-Latest live log: state selected at t538613, cinematic queued at t538623 and staged at t538659, with no cinematic-start incident. Read-only native registry capture at `build/first-encounter-audit/reactor-runtime-20260906-151812` contains nine groups, gameplay Apex and globals, but no ending bookend group or type-6 controller. Thus the earlier lease deadlock is past; staging alone has not instantiated the movie controller.
-
-Message 1 previously always encoded per-bubble state zero (`0x80` after signed bias). It now carries the selected plan's authored state ordinal: STM 1 -> `0x81`, CNN 2 -> `0x82`. That state message precedes a pending seed roster; keepalives and refreshes preserve it. The transition-subset gate also recognises a held sibling world instead of requiring exact equality with its state ordinal. This is an evidence-based candidate; native playback must still be tested.
-
-Release build and all 22 portable tests pass. Added coverage for gameplay, both bookends and the initial cinematic's biased state value. DLL installed after the game closed, with no launch or save/script edits. The pending loading-suppression scope correction is included.
-
-The screen distortion is still unresolved and has NOT been implemented by this candidate. Reference frame 23:40 is saved at `/tmp/ember-reference/surge-screen.jpg`. Existing type-5 sequence Auth supplies no client references; whether the alarm effect needs an authored anchor or participant binding remains unproven. Do not claim an arbitrary heat/damage hop-on is the exact beam screen effect.
-
-DLL SHA-256: `fce6fd3e4b5451a797dee5fa962ed11337c5bd10e796c13d38638abb5405ccdf`. Backup: `/home/millie/Documents/Sunrise-builds/mission-ember/build/loading-scope-install-backup-20260906-153021`.
+Loading suppression is now limited to 1AU using the native loading activity reader above. The corrected Release DLL built successfully, and offline signature/call validation passed. Installation was deferred because the game was running; the installed DLL still has the earlier global override until this build is copied after the game closes. The scope-only installer is `/tmp/install-ember-loading-scope.py` and preserves settings, saves and scripts.

+ 1 - 2
Sunrise/src/server/bap/encrypted/activity_transaction/activity_transaction_notifications.cpp

@@ -102,8 +102,7 @@ namespace {
                                  std::size_t& written,
                                  bool allowEntityRetirement) noexcept {
     bool staged = push::activity::append_global_state_notification(
-                      scratch, session.activity.session, key, nonce, response, written,
-                      session.activityMissionSeed.configured ? &session.activityMissionSeed.plan : nullptr)
+                      scratch, session.activity.session, key, nonce, response, written)
                   && push::activity::append_world_globals_notification(
                       scratch, session.activity.session.sessionId, key, nonce, response, written);
     bool stagedMembership = false;

+ 1 - 11
Sunrise/src/server/bap/encrypted/push/activity/activity_global_state_push.cpp

@@ -13,7 +13,6 @@
 #include "../../../../../state/activity/runtime.h"
 #include "../../../../../state/build_data/runtime.h"
 #include "activity_arrival.h"
-#include "mission_seed_world_change.h"
 #include "activity_notification_frame.h"
 
 namespace sunrise::server::bap::encrypted::push::activity {
@@ -108,22 +107,13 @@ bool append_global_state_notification(Scratch& scratch,
                                       std::span<const std::byte, state::kAesKeySize> key,
                                       std::array<std::byte, state::kBapNonceSize>& nonce,
                                       std::span<std::byte> response,
-                                      std::size_t& written,
-                                      const ActivityMissionSeedPlan* selected) noexcept {
+                                      std::size_t& written) noexcept {
     message::GlobalActivityState body{};
     state::activity::destination::DestinationSelection selection{};
     if (written > response.size() || !resolve_state(binding, body, selection)) {
         return false;
     }
 
-    if (selected != nullptr && selected->bubbleOrdinal < body.bubbleCount) {
-        // Message 1 owns the native per-bubble state ordinal. Registering a roster
-        // for bookend 1 while this remains zero leaves its controller uninstantiated.
-        body.bubbleStates[selected->bubbleOrdinal] = mission_seed_state_wire_byte(
-            selected->effectiveRegion, selected->sliceSetIndex,
-            middleware::content::packages::tables::kSliceSetIndexFactor);
-    }
-
     const std::size_t initialWritten = written;
     auto initialNonce = nonce;
     std::size_t messageSize = 0;

+ 1 - 2
Sunrise/src/server/bap/encrypted/push/activity/activity_global_state_push.h

@@ -42,7 +42,6 @@ append_global_state_notification(Scratch& scratch,
                                  std::span<const std::byte, state::kAesKeySize> key,
                                  std::array<std::byte, state::kBapNonceSize>& nonce,
                                  std::span<std::byte> response,
-                                 std::size_t& written,
-                                 const ActivityMissionSeedPlan* selected = nullptr) noexcept;
+                                 std::size_t& written) noexcept;
 
 } // namespace sunrise::server::bap::encrypted::push::activity

+ 1 - 2
Sunrise/src/server/bap/encrypted/push/activity/activity_keepalive_push.cpp

@@ -341,8 +341,7 @@ bool consume_activity_keepalive(Session& session,
         return delivered;
     }
     published = append_global_state_notification(
-        scratch, session.activity.session, key, nextSendNonce, scratch.framed, framedSize,
-        session.activityMissionSeed.configured ? &session.activityMissionSeed.plan : nullptr);
+        scratch, session.activity.session, key, nextSendNonce, scratch.framed, framedSize);
     const bool appendedReplicationEpoch =
         append_replication_epoch(session, scratch, key, nextSendNonce, scratch.framed, framedSize);
     published = appendedReplicationEpoch || published;

+ 2 - 4
Sunrise/src/server/bap/encrypted/push/activity/activity_mission_seed_roster.cpp

@@ -500,10 +500,8 @@ MissionSeedRosterResult append_initial_mission_seed(Session& session,
     }
     const bool transitionPublication =
         !lease.fullSetPublished
-        && ((!lease.scriptSelected && !publicRegion)
-            || !mission_seed_arrival_window_closed(
-                heldRegion, selectedRegion, plan.sliceSetIndex,
-                middleware::content::packages::tables::kSliceSetIndexFactor));
+        && ((!lease.scriptSelected && !publicRegion) || heldRegion < 0
+            || static_cast<std::uint32_t>(heldRegion) != selectedRegion);
     for (std::size_t source = 0; source < foldGroupCount; ++source) {
         const layouts::RosterGroup& candidate = materialized[source];
         if (!layouts::valid_roster_group(candidate)) {

+ 1 - 6
Sunrise/src/server/bap/encrypted/push/activity/activity_roster_push.cpp

@@ -1,4 +1,3 @@
-#include "activity_global_state_push.h"
 #include "activity_roster_push.h"
 
 #include <Windows.h>
@@ -446,11 +445,7 @@ bool append_roster_notification(
         && stagedMissionSeed.bindingGeneration == session.activity.bindingGeneration
         && stagedMissionSeed.revision != stagedMissionSeed.publishedRevision
         && !stagedMissionSeed.regionArrivalPending;
-    // Publish the authored state ordinal before its roster and cinematic authority.
-    // This also prevents a later keepalive from restoring the default gameplay state.
-    bool encoded = !missionSeedPending || append_global_state_notification(
-        scratch, session.activity.session, key, nonce, response, written, &stagedMissionSeed.plan);
-    encoded = encoded && message::encode_sensor_auth_update(snapshot, scratch.responseBody, messageSize);
+    bool encoded = message::encode_sensor_auth_update(snapshot, scratch.responseBody, messageSize);
     // An unsolicited body identical to the last delivered one is skipped. A solicited one never
     // is. The repeat check knows only this host's own history, and a slice-set teardown clears
     // the client's mirror without telling us, which is exactly when it asks again.

+ 0 - 7
Sunrise/src/server/bap/encrypted/push/activity/mission_seed_world_change.h

@@ -72,11 +72,4 @@ mission_seed_arrival_window_closed(std::int32_t heldRegion,
         && !mission_seed_arrival_window_closed(heldRegion, newRegion, newSliceSet, factor);
 }
 
-/** Message 1 uses a bias-128 signed state ordinal, not a state-presence boolean. */
-[[nodiscard]] constexpr std::uint8_t mission_seed_state_wire_byte(
-    std::uint32_t region, std::uint32_t sliceSet, std::uint32_t factor) noexcept {
-    return factor != 0 && region >= sliceSet && region - sliceSet < factor
-        && region - sliceSet < 128 ? static_cast<std::uint8_t>(128 + region - sliceSet) : 128;
-}
-
 } // namespace sunrise::server::bap::encrypted::push::activity

+ 0 - 7
tests/mission_seed_world_change_test.cpp

@@ -107,13 +107,6 @@ void arrival_window_stays_open_across_a_real_slice_set_change() {
 } // namespace
 
 int main() {
-    assert(seed::mission_seed_state_wire_byte(0, 0, 8) == 0x80);
-    assert(seed::mission_seed_state_wire_byte(1, 0, 8) == 0x81);
-    assert(seed::mission_seed_state_wire_byte(2, 0, 8) == 0x82);
-    assert(seed::mission_seed_state_wire_byte(49, 48, 8) == 0x81);
-    assert(seed::mission_seed_state_wire_byte(64, 64, 8) == 0x80);
-    assert(seed::mission_seed_state_wire_byte(0, 64, 8) == 0x80);
-
     // Real full-mission case: the last explicit seed is the landing, but ordinary
     // traversal already brought the player to Apex before selecting its ending.
     assert(!seed::mission_seed_selection_needs_arrival(64, 64, 0, 1, 0, 8));