mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-09-24 02:13:02 -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;
|
return deck;
|
||||||
}
|
}
|
||||||
|
bool getSideboardLocked() const
|
||||||
|
{
|
||||||
|
return sideboardLocked;
|
||||||
|
}
|
||||||
bool getReadyStart() const
|
bool getReadyStart() const
|
||||||
{
|
{
|
||||||
return readyStart;
|
return readyStart;
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@
|
||||||
#include <google/protobuf/descriptor.h>
|
#include <google/protobuf/descriptor.h>
|
||||||
#include <libcockatrice/deck_list/deck_list.h>
|
#include <libcockatrice/deck_list/deck_list.h>
|
||||||
#include <libcockatrice/protocol/pb/context_connection_state_changed.pb.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/context_ping_changed.pb.h>
|
||||||
#include <libcockatrice/protocol/pb/event_delete_arrow.pb.h>
|
#include <libcockatrice/protocol/pb/event_delete_arrow.pb.h>
|
||||||
#include <libcockatrice/protocol/pb/event_game_closed.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));
|
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,
|
void Server_Game::sendGameEventContainer(GameEventContainer *cont,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue