@@ -565,17 +565,24 @@ void SpeedrunTimer::Start() {
565565 g_speedrun.lastMap = map;
566566 g_speedrun.visitedMaps .push_back (map);
567567
568- // Generate unique speedrun ID
569- if (ed25519_create_seed (g_speedrun.speedrunId ) != 0 ) {
570- // Fallback: use timestamp + random if crypto fails
571- auto now = std::chrono::system_clock::now ().time_since_epoch ();
572- uint64_t timestamp = std::chrono::duration_cast<std::chrono::milliseconds>(now).count ();
573- *(uint64_t *)(g_speedrun.speedrunId ) = timestamp;
574- for (int i = 8 ; i < 16 ; i++) {
575- g_speedrun.speedrunId [i] = (uint8_t )(Math::RandomNumber (0 , 255 ));
568+ // Generate unique speedrun ID. ed25519 seeds are 32 bytes; create_seed
569+ // must not write directly into our 16-byte buffer. Generate into a
570+ // temporary 32-byte seed and copy the first 16 bytes.
571+ {
572+ uint8_t seed[32 ];
573+ if (ed25519_create_seed (seed) == 0 ) {
574+ memcpy (g_speedrun.speedrunId , seed, 16 );
575+ } else {
576+ // Fallback: use timestamp + random if crypto fails
577+ auto now = std::chrono::system_clock::now ().time_since_epoch ();
578+ uint64_t timestamp = std::chrono::duration_cast<std::chrono::milliseconds>(now).count ();
579+ memcpy (g_speedrun.speedrunId , ×tamp, sizeof (timestamp));
580+ for (int i = 8 ; i < 16 ; i++) {
581+ g_speedrun.speedrunId [i] = (uint8_t )(Math::RandomNumber (0 , 255 ));
582+ }
576583 }
584+ g_speedrun.hasSpeedrunId = true ;
577585 }
578- g_speedrun.hasSpeedrunId = true ;
579586 SpeedrunTimer::WriteIdToDemo (); // Write to current demo if recording
580587
581588 sendCoopPacket (PacketType::START);
0 commit comments