From 9ae9ed1d4ed6f0a98c52cc01ec54d4b4a0027f60 Mon Sep 17 00:00:00 2001 From: flan Date: Sat, 16 Aug 2025 19:42:28 +0200 Subject: [PATCH] Send shown pictures on join MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes an issue where currently shown pictures would not reappear after reconnecting. A prominent example is player sprites in all FC Caverns areas (Yume 2kki) not being shown until the player changes effects. Entering FC Caverns currently triggers a reconnect which means the issue is fairly easy to encounter. Small note about packet order: `ri` is currently sent before `pns`[0], which means it's possible for the client to attempt to send shown pictures before it receives allowed picture names and prefixes. The only case I can think of when the client doesn't already have picture names from the previous join is during the initial game launch. An alternative would be to send pictures when `pns` is received, that way the initial issue would be solved and the code wouldn't depend on when or in which order packets are sent. This is not done here because pictures can persist between map changes (RPG Maker 2003 1.12 and newer, `erase_on_map_change`). `Pns` packets are not resent during room changes and as such would cause the picture not to be displayed after changing maps. One example can be seen in the EasyRPG test suite[1] (TestGame-2003, Image operations → third character from the right, red armor) with server picture_prefixes set to `number`. I could not find any examples of allowed persistent pictures in games currently hosted on YNO. [0]: https://github.com/ynoproject/ynoserver/blob/53388b29437d92f59cbacfe1c1107354da4465b2/server/room.go#L134-L161 [1]: https://github.com/EasyRPG/TestGame/tree/978550540ebb348a000e576989e5b57d8c5904b5/TestGame-2003 --- src/multiplayer/game_multiplayer.cpp | 21 +++++++++++++++++++++ src/multiplayer/game_multiplayer.h | 1 + 2 files changed, 22 insertions(+) diff --git a/src/multiplayer/game_multiplayer.cpp b/src/multiplayer/game_multiplayer.cpp index ccd8688e9..61f94456f 100644 --- a/src/multiplayer/game_multiplayer.cpp +++ b/src/multiplayer/game_multiplayer.cpp @@ -168,6 +168,9 @@ void Game_Multiplayer::InitConnection() { Connect(room_id); // wrong room, reconnect return; } + // Game_Multiplayer::Connect runs before the pictures from + // the previous map are erased so we can't call it there + SendShownPictures(); // set this to true to enable players entering switching_room = false; Web_API::OnRoomSwitch(); @@ -705,6 +708,24 @@ void Game_Multiplayer::PictureErased(int pic_id) { } } +void Game_Multiplayer::SendShownPictures() { + auto scene_map = Scene::Find(Scene::SceneType::Map); + if (!scene_map || !scene_map->IsInitialized()) return; + + for (auto& sp : sync_picture_cache) { + int id = sp.first; + auto* pic = Main_Data::game_pictures->GetPicturePtr(id); + if (pic == nullptr || !pic->Exists()) continue; + auto params = pic->GetShowParams(); + if (!IsPictureSynced(id, params.name)) continue; + + auto& p = Main_Data::game_player; + connection.SendPacketAsync(id, params, + Game_Map::GetPositionX(), Game_Map::GetPositionY(), + p->GetPanX(), p->GetPanY()); + } +} + bool Game_Multiplayer::IsBattleAnimSynced(int anim_id) { bool anim_synced = false; diff --git a/src/multiplayer/game_multiplayer.h b/src/multiplayer/game_multiplayer.h index c3435c3a3..d539fe437 100644 --- a/src/multiplayer/game_multiplayer.h +++ b/src/multiplayer/game_multiplayer.h @@ -125,6 +125,7 @@ class Game_Multiplayer { void SpawnOtherPlayer(int id); void ResetRepeatingFlash(); void InitConnection(); + void SendShownPictures(); }; inline Game_Multiplayer& GMI() { return Game_Multiplayer::Instance(); }