mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-09-21 09:05:10 -07:00
Show loaded deck messages to players joining a game (#552)
The "Player X has loaded a deck" message is only broadcast when a deck is selected, so players and spectators who join a game afterwards never see it. On game join, replay a deck-select event context privately to the joining participant for every player that already has a deck loaded, reusing the existing Event_PlayerPropertiesChanged + Context_DeckSelect mechanism so no protocol version bump is needed. - Server_AbstractPlayer: expose the sideboard-locked state - Server_Game: synthesize deck-select contexts in createGameJoinedEvent
This commit is contained in:
parent
fb482f037e
commit
82ae0ecf01
2 changed files with 43 additions and 0 deletions
|
|
@ -47,6 +47,10 @@ public:
|
|||
{
|
||||
return deck;
|
||||
}
|
||||
bool getSideboardLocked() const
|
||||
{
|
||||
return sideboardLocked;
|
||||
}
|
||||
bool getReadyStart() const
|
||||
{
|
||||
return readyStart;
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
#include <google/protobuf/descriptor.h>
|
||||
#include <libcockatrice/deck_list/deck_list.h>
|
||||
#include <libcockatrice/protocol/pb/context_connection_state_changed.pb.h>
|
||||
#include <libcockatrice/protocol/pb/context_deck_select.pb.h>
|
||||
#include <libcockatrice/protocol/pb/context_ping_changed.pb.h>
|
||||
#include <libcockatrice/protocol/pb/event_delete_arrow.pb.h>
|
||||
#include <libcockatrice/protocol/pb/event_game_closed.pb.h>
|
||||
|
|
@ -783,6 +784,44 @@ void Server_Game::createGameJoinedEvent(Server_AbstractParticipant *joiningParti
|
|||
}
|
||||
|
||||
rc.enqueuePostResponseItem(ServerMessage::GAME_EVENT_CONTAINER, prepareGameEvent(event2, -1));
|
||||
|
||||
// A newly joined player never saw the "Player X has loaded a deck" messages
|
||||
// (they are only broadcast when a deck is selected), so replay a deck-select
|
||||
// context for every player that already has a deck loaded. It is delivered
|
||||
// privately to the joining participant, whose client renders it as a log
|
||||
// entry in the same way as a fresh deck selection.
|
||||
for (auto *participant : participants.values()) {
|
||||
if (participant == joiningParticipant) {
|
||||
continue;
|
||||
}
|
||||
auto *deckOwner = qobject_cast<Server_Player *>(participant);
|
||||
if (deckOwner == nullptr) {
|
||||
continue;
|
||||
}
|
||||
const DeckList *deckList = deckOwner->getDeckList();
|
||||
if (deckList == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Event_PlayerPropertiesChanged event;
|
||||
event.mutable_player_properties()->set_sideboard_locked(deckOwner->getSideboardLocked());
|
||||
event.mutable_player_properties()->set_deck_hash(deckList->getDeckHash().toStdString());
|
||||
|
||||
Context_DeckSelect deckSelect;
|
||||
deckSelect.set_deck_hash(deckList->getDeckHash().toStdString());
|
||||
deckSelect.set_sideboard_size(deckList->getSideboardSize());
|
||||
if (getShareDecklistsOnLoad()) {
|
||||
deckSelect.set_deck_list(deckList->writeToString_Native().toStdString());
|
||||
}
|
||||
|
||||
GameEventContext context;
|
||||
context.GetReflection()
|
||||
->MutableMessage(&context, deckSelect.GetDescriptor()->FindExtensionByName("ext"))
|
||||
->CopyFrom(deckSelect);
|
||||
|
||||
rc.enqueuePostResponseItem(ServerMessage::GAME_EVENT_CONTAINER,
|
||||
prepareGameEvent(event, deckOwner->getPlayerId(), &context));
|
||||
}
|
||||
}
|
||||
|
||||
void Server_Game::sendGameEventContainer(GameEventContainer *cont,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue