Skip to content

Commit 8476f9b

Browse files
committed
Merge branch 'lobby' into dev
Conflicts: src/dialog/mainwindow.cpp src/dialog/mainwindow.h style-sheet/sanguosha.qss
2 parents 6827dd4 + 838e714 commit 8476f9b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+2455
-755
lines changed

QSanguosha.pro

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ SOURCES += \
2727
src/core/player.cpp \
2828
src/core/protocol.cpp \
2929
src/core/record-analysis.cpp \
30+
src/core/roomconfig.cpp \
3031
src/core/roomstate.cpp \
3132
src/core/settings.cpp \
3233
src/core/skill.cpp \
@@ -78,8 +79,11 @@ SOURCES += \
7879
src/server/generalselector.cpp \
7980
src/server/room.cpp \
8081
src/server/roomthread.cpp \
81-
src/server/server.cpp \
8282
src/server/serverplayer.cpp \
83+
src/server/server.cpp \
84+
src/server/server-lobby.cpp \
85+
src/server/server-room.cpp \
86+
src/server/lobbyplayer.cpp \
8387
src/ui/button.cpp \
8488
src/ui/cardcontainer.cpp \
8589
src/ui/carditem.cpp \
@@ -114,6 +118,8 @@ SOURCES += \
114118
src/ui/graphicspixmaphoveritem.cpp \
115119
src/ui/heroskincontainer.cpp \
116120
src/ui/skinitem.cpp \
121+
src/ui/lobbyscene.cpp \
122+
src/ui/tile.cpp \
117123
src/util/detector.cpp \
118124
src/util/nativesocket.cpp \
119125
src/util/recorder.cpp \
@@ -135,6 +141,7 @@ HEADERS += \
135141
src/core/player.h \
136142
src/core/protocol.h \
137143
src/core/record-analysis.h \
144+
src/core/roomconfig.h \
138145
src/core/roomstate.h \
139146
src/core/settings.h \
140147
src/core/skill.h \
@@ -186,8 +193,9 @@ HEADERS += \
186193
src/server/generalselector.h \
187194
src/server/room.h \
188195
src/server/roomthread.h \
189-
src/server/server.h \
190196
src/server/serverplayer.h \
197+
src/server/server.h \
198+
src/server/lobbyplayer.h \
191199
src/ui/button.h \
192200
src/ui/cardcontainer.h \
193201
src/ui/carditem.h \
@@ -222,6 +230,8 @@ HEADERS += \
222230
src/ui/graphicspixmaphoveritem.h \
223231
src/ui/heroskincontainer.h \
224232
src/ui/skinitem.h \
233+
src/ui/lobbyscene.h \
234+
src/ui/tile.h \
225235
src/util/detector.h \
226236
src/util/nativesocket.h \
227237
src/util/recorder.h \

src/client/client.cpp

Lines changed: 149 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@
4141
using namespace QSanProtocol;
4242

4343
Client *ClientInstance = NULL;
44+
QHash<CommandType, Client::Callback> Client::callbacks;
45+
QHash<CommandType, Client::Callback> Client::interactions;
4446

4547
Client::Client(QObject *parent, const QString &filename)
4648
: QObject(parent), m_isDiscardActionRefusable(true),
@@ -50,104 +52,101 @@ Client::Client(QObject *parent, const QString &filename)
5052
ClientInstance = this;
5153
m_isGameOver = false;
5254

53-
callbacks[S_COMMAND_CHECK_VERSION] = &Client::checkVersion;
54-
callbacks[S_COMMAND_SETUP] = &Client::setup;
55-
callbacks[S_COMMAND_NETWORK_DELAY_TEST] = &Client::networkDelayTest;
56-
callbacks[S_COMMAND_ADD_PLAYER] = &Client::addPlayer;
57-
callbacks[S_COMMAND_REMOVE_PLAYER] = &Client::removePlayer;
58-
callbacks[S_COMMAND_START_IN_X_SECONDS] = &Client::startInXs;
59-
callbacks[S_COMMAND_ARRANGE_SEATS] = &Client::arrangeSeats;
60-
callbacks[S_COMMAND_WARN] = &Client::warn;
61-
callbacks[S_COMMAND_SPEAK] = &Client::speak;
62-
63-
callbacks[S_COMMAND_GAME_START] = &Client::startGame;
64-
callbacks[S_COMMAND_GAME_OVER] = &Client::gameOver;
65-
66-
callbacks[S_COMMAND_CHANGE_HP] = &Client::hpChange;
67-
callbacks[S_COMMAND_CHANGE_MAXHP] = &Client::maxhpChange;
68-
callbacks[S_COMMAND_KILL_PLAYER] = &Client::killPlayer;
69-
callbacks[S_COMMAND_REVIVE_PLAYER] = &Client::revivePlayer;
70-
callbacks[S_COMMAND_SHOW_CARD] = &Client::showCard;
71-
callbacks[S_COMMAND_UPDATE_CARD] = &Client::updateCard;
72-
callbacks[S_COMMAND_SET_MARK] = &Client::setMark;
73-
callbacks[S_COMMAND_LOG_SKILL] = &Client::log;
74-
callbacks[S_COMMAND_ATTACH_SKILL] = &Client::attachSkill;
75-
callbacks[S_COMMAND_MOVE_FOCUS] = &Client::moveFocus;
76-
callbacks[S_COMMAND_SET_EMOTION] = &Client::setEmotion;
77-
callbacks[S_COMMAND_INVOKE_SKILL] = &Client::skillInvoked;
78-
callbacks[S_COMMAND_SHOW_ALL_CARDS] = &Client::showAllCards;
79-
callbacks[S_COMMAND_LOG_EVENT] = &Client::handleGameEvent;
80-
callbacks[S_COMMAND_ADD_HISTORY] = &Client::addHistory;
81-
callbacks[S_COMMAND_ANIMATE] = &Client::animate;
82-
callbacks[S_COMMAND_FIXED_DISTANCE] = &Client::setFixedDistance;
83-
callbacks[S_COMMAND_CARD_LIMITATION] = &Client::cardLimitation;
84-
callbacks[S_COMMAND_DISABLE_SHOW] = &Client::disableShow;
85-
callbacks[S_COMMAND_NULLIFICATION_ASKED] = &Client::setNullification;
86-
callbacks[S_COMMAND_ENABLE_SURRENDER] = &Client::enableSurrender;
87-
callbacks[S_COMMAND_EXCHANGE_KNOWN_CARDS] = &Client::exchangeKnownCards;
88-
callbacks[S_COMMAND_SET_KNOWN_CARDS] = &Client::setKnownCards;
89-
callbacks[S_COMMAND_VIEW_GENERALS] = &Client::viewGenerals;
90-
callbacks[S_COMMAND_SET_DASHBOARD_SHADOW] = &Client::setDashboardShadow;
91-
callbacks[S_COMMAND_UPDATE_STATE_ITEM] = &Client::updateStateItem;
92-
callbacks[S_COMMAND_AVAILABLE_CARDS] = &Client::setAvailableCards;
93-
callbacks[S_COMMAND_GET_CARD] = &Client::getCards;
94-
callbacks[S_COMMAND_LOSE_CARD] = &Client::loseCards;
95-
callbacks[S_COMMAND_SET_PROPERTY] = &Client::updateProperty;
96-
callbacks[S_COMMAND_RESET_PILE] = &Client::resetPiles;
97-
callbacks[S_COMMAND_UPDATE_PILE] = &Client::setPileNumber;
98-
callbacks[S_COMMAND_CARD_FLAG] = &Client::setCardFlag;
99-
callbacks[S_COMMAND_UPDATE_HANDCARD_NUM] = &Client::setHandcardNum;
100-
callbacks[S_COMMAND_MIRROR_GUANXING_STEP] = &Client::mirrorGuanxingStep;
55+
if (callbacks.isEmpty()) {
56+
callbacks[S_COMMAND_CHECK_VERSION] = &Client::checkVersion;
57+
callbacks[S_COMMAND_SETUP] = &Client::setup;
58+
callbacks[S_COMMAND_NETWORK_DELAY_TEST] = &Client::networkDelayTest;
59+
callbacks[S_COMMAND_ADD_PLAYER] = &Client::addPlayer;
60+
callbacks[S_COMMAND_REMOVE_PLAYER] = &Client::removePlayer;
61+
callbacks[S_COMMAND_START_IN_X_SECONDS] = &Client::startInXs;
62+
callbacks[S_COMMAND_ARRANGE_SEATS] = &Client::arrangeSeats;
63+
callbacks[S_COMMAND_WARN] = &Client::warn;
64+
callbacks[S_COMMAND_SPEAK] = &Client::speak;
65+
callbacks[S_COMMAND_GAME_START] = &Client::startGame;
66+
callbacks[S_COMMAND_GAME_OVER] = &Client::gameOver;
67+
callbacks[S_COMMAND_CHANGE_HP] = &Client::hpChange;
68+
callbacks[S_COMMAND_CHANGE_MAXHP] = &Client::maxhpChange;
69+
callbacks[S_COMMAND_KILL_PLAYER] = &Client::killPlayer;
70+
callbacks[S_COMMAND_REVIVE_PLAYER] = &Client::revivePlayer;
71+
callbacks[S_COMMAND_SHOW_CARD] = &Client::showCard;
72+
callbacks[S_COMMAND_UPDATE_CARD] = &Client::updateCard;
73+
callbacks[S_COMMAND_SET_MARK] = &Client::setMark;
74+
callbacks[S_COMMAND_LOG_SKILL] = &Client::log;
75+
callbacks[S_COMMAND_ATTACH_SKILL] = &Client::attachSkill;
76+
callbacks[S_COMMAND_MOVE_FOCUS] = &Client::moveFocus;
77+
callbacks[S_COMMAND_SET_EMOTION] = &Client::setEmotion;
78+
callbacks[S_COMMAND_INVOKE_SKILL] = &Client::skillInvoked;
79+
callbacks[S_COMMAND_SHOW_ALL_CARDS] = &Client::showAllCards;
80+
callbacks[S_COMMAND_LOG_EVENT] = &Client::handleGameEvent;
81+
callbacks[S_COMMAND_ADD_HISTORY] = &Client::addHistory;
82+
callbacks[S_COMMAND_ANIMATE] = &Client::animate;
83+
callbacks[S_COMMAND_FIXED_DISTANCE] = &Client::setFixedDistance;
84+
callbacks[S_COMMAND_CARD_LIMITATION] = &Client::cardLimitation;
85+
callbacks[S_COMMAND_DISABLE_SHOW] = &Client::disableShow;
86+
callbacks[S_COMMAND_NULLIFICATION_ASKED] = &Client::setNullification;
87+
callbacks[S_COMMAND_ENABLE_SURRENDER] = &Client::enableSurrender;
88+
callbacks[S_COMMAND_EXCHANGE_KNOWN_CARDS] = &Client::exchangeKnownCards;
89+
callbacks[S_COMMAND_SET_KNOWN_CARDS] = &Client::setKnownCards;
90+
callbacks[S_COMMAND_VIEW_GENERALS] = &Client::viewGenerals;
91+
callbacks[S_COMMAND_SET_DASHBOARD_SHADOW] = &Client::setDashboardShadow;
92+
callbacks[S_COMMAND_UPDATE_STATE_ITEM] = &Client::updateStateItem;
93+
callbacks[S_COMMAND_AVAILABLE_CARDS] = &Client::setAvailableCards;
94+
callbacks[S_COMMAND_GET_CARD] = &Client::getCards;
95+
callbacks[S_COMMAND_LOSE_CARD] = &Client::loseCards;
96+
callbacks[S_COMMAND_SET_PROPERTY] = &Client::updateProperty;
97+
callbacks[S_COMMAND_RESET_PILE] = &Client::resetPiles;
98+
callbacks[S_COMMAND_UPDATE_PILE] = &Client::setPileNumber;
99+
callbacks[S_COMMAND_CARD_FLAG] = &Client::setCardFlag;
100+
callbacks[S_COMMAND_UPDATE_HANDCARD_NUM] = &Client::setHandcardNum;
101+
callbacks[S_COMMAND_MIRROR_GUANXING_STEP] = &Client::mirrorGuanxingStep;
102+
callbacks[S_COMMAND_ENTER_LOBBY] = &Client::enterLobby;
103+
callbacks[S_COMMAND_ROOM_LIST] = &Client::updateRoomList;
104+
105+
callbacks[S_COMMAND_FILL_AMAZING_GRACE] = &Client::fillAG;
106+
callbacks[S_COMMAND_TAKE_AMAZING_GRACE] = &Client::takeAG;
107+
callbacks[S_COMMAND_CLEAR_AMAZING_GRACE] = &Client::clearAG;
108+
109+
// 3v3 mode & 1v1 mode
110+
callbacks[S_COMMAND_FILL_GENERAL] = &Client::fillGenerals;
111+
callbacks[S_COMMAND_TAKE_GENERAL] = &Client::takeGeneral;
112+
callbacks[S_COMMAND_RECOVER_GENERAL] = &Client::recoverGeneral;
113+
callbacks[S_COMMAND_REVEAL_GENERAL] = &Client::revealGeneral;
114+
}
101115

102116
// interactive methods
103-
interactions[S_COMMAND_CHOOSE_GENERAL] = &Client::askForGeneral;
104-
interactions[S_COMMAND_CHOOSE_PLAYER] = &Client::askForPlayerChosen;
105-
interactions[S_COMMAND_CHOOSE_DIRECTION] = &Client::askForDirection;
106-
interactions[S_COMMAND_EXCHANGE_CARD] = &Client::askForExchange;
107-
interactions[S_COMMAND_ASK_PEACH] = &Client::askForSinglePeach;
108-
interactions[S_COMMAND_SKILL_GUANXING] = &Client::askForGuanxing;
109-
interactions[S_COMMAND_SKILL_GONGXIN] = &Client::askForGongxin;
110-
interactions[S_COMMAND_SKILL_YIJI] = &Client::askForYiji;
111-
interactions[S_COMMAND_PLAY_CARD] = &Client::activate;
112-
interactions[S_COMMAND_DISCARD_CARD] = &Client::askForDiscard;
113-
interactions[S_COMMAND_CHOOSE_SUIT] = &Client::askForSuit;
114-
interactions[S_COMMAND_CHOOSE_KINGDOM] = &Client::askForKingdom;
115-
interactions[S_COMMAND_RESPONSE_CARD] = &Client::askForCardOrUseCard;
116-
interactions[S_COMMAND_INVOKE_SKILL] = &Client::askForSkillInvoke;
117-
interactions[S_COMMAND_MULTIPLE_CHOICE] = &Client::askForChoice;
118-
interactions[S_COMMAND_NULLIFICATION] = &Client::askForNullification;
119-
interactions[S_COMMAND_SHOW_CARD] = &Client::askForCardShow;
120-
interactions[S_COMMAND_AMAZING_GRACE] = &Client::askForAG;
121-
interactions[S_COMMAND_PINDIAN] = &Client::askForPindian;
122-
interactions[S_COMMAND_CHOOSE_CARD] = &Client::askForCardChosen;
123-
interactions[S_COMMAND_CHOOSE_ORDER] = &Client::askForOrder;
124-
interactions[S_COMMAND_SURRENDER] = &Client::askForSurrender;
125-
interactions[S_COMMAND_LUCK_CARD] = &Client::askForLuckCard;
126-
interactions[S_COMMAND_TRIGGER_ORDER] = &Client::askForTriggerOrder;
127-
128-
callbacks[S_COMMAND_FILL_AMAZING_GRACE] = &Client::fillAG;
129-
callbacks[S_COMMAND_TAKE_AMAZING_GRACE] = &Client::takeAG;
130-
callbacks[S_COMMAND_CLEAR_AMAZING_GRACE] = &Client::clearAG;
131-
132-
// 3v3 mode & 1v1 mode
133-
interactions[S_COMMAND_ARRANGE_GENERAL] = &Client::startArrange;
134-
135-
callbacks[S_COMMAND_FILL_GENERAL] = &Client::fillGenerals;
136-
callbacks[S_COMMAND_TAKE_GENERAL] = &Client::takeGeneral;
137-
callbacks[S_COMMAND_RECOVER_GENERAL] = &Client::recoverGeneral;
138-
callbacks[S_COMMAND_REVEAL_GENERAL] = &Client::revealGeneral;
117+
if (interactions.isEmpty()) {
118+
interactions[S_COMMAND_CHOOSE_GENERAL] = &Client::askForGeneral;
119+
interactions[S_COMMAND_CHOOSE_PLAYER] = &Client::askForPlayerChosen;
120+
interactions[S_COMMAND_CHOOSE_DIRECTION] = &Client::askForDirection;
121+
interactions[S_COMMAND_EXCHANGE_CARD] = &Client::askForExchange;
122+
interactions[S_COMMAND_ASK_PEACH] = &Client::askForSinglePeach;
123+
interactions[S_COMMAND_SKILL_GUANXING] = &Client::askForGuanxing;
124+
interactions[S_COMMAND_SKILL_GONGXIN] = &Client::askForGongxin;
125+
interactions[S_COMMAND_SKILL_YIJI] = &Client::askForYiji;
126+
interactions[S_COMMAND_PLAY_CARD] = &Client::activate;
127+
interactions[S_COMMAND_DISCARD_CARD] = &Client::askForDiscard;
128+
interactions[S_COMMAND_CHOOSE_SUIT] = &Client::askForSuit;
129+
interactions[S_COMMAND_CHOOSE_KINGDOM] = &Client::askForKingdom;
130+
interactions[S_COMMAND_RESPONSE_CARD] = &Client::askForCardOrUseCard;
131+
interactions[S_COMMAND_INVOKE_SKILL] = &Client::askForSkillInvoke;
132+
interactions[S_COMMAND_MULTIPLE_CHOICE] = &Client::askForChoice;
133+
interactions[S_COMMAND_NULLIFICATION] = &Client::askForNullification;
134+
interactions[S_COMMAND_SHOW_CARD] = &Client::askForCardShow;
135+
interactions[S_COMMAND_AMAZING_GRACE] = &Client::askForAG;
136+
interactions[S_COMMAND_PINDIAN] = &Client::askForPindian;
137+
interactions[S_COMMAND_CHOOSE_CARD] = &Client::askForCardChosen;
138+
interactions[S_COMMAND_CHOOSE_ORDER] = &Client::askForOrder;
139+
interactions[S_COMMAND_SURRENDER] = &Client::askForSurrender;
140+
interactions[S_COMMAND_LUCK_CARD] = &Client::askForLuckCard;
141+
interactions[S_COMMAND_TRIGGER_ORDER] = &Client::askForTriggerOrder;
142+
143+
// 3v3 mode & 1v1 mode
144+
interactions[S_COMMAND_ARRANGE_GENERAL] = &Client::startArrange;
145+
}
139146

140147
m_noNullificationThisTime = false;
141148
m_noNullificationTrickName = ".";
142149

143-
Self = new ClientPlayer(this);
144-
Self->setScreenName(Config.UserName);
145-
Self->setProperty("avatar", Config.UserAvatar);
146-
connect(Self, SIGNAL(phase_changed()), this, SLOT(alertFocus()));
147-
connect(Self, SIGNAL(role_changed(QString)), this, SLOT(notifyRoleChange(QString)));
148-
149-
players << Self;
150-
151150
if (!filename.isEmpty()) {
152151
socket = NULL;
153152
recorder = NULL;
@@ -181,7 +180,8 @@ Client::Client(QObject *parent, const QString &filename)
181180
}
182181

183182
Client::~Client() {
184-
ClientInstance = NULL;
183+
if (ClientInstance == this)
184+
ClientInstance = NULL;
185185
}
186186

187187
void Client::updateCard(const QVariant &val) {
@@ -261,6 +261,22 @@ void Client::signup() {
261261
}
262262
}
263263

264+
void Client::restart()
265+
{
266+
m_isGameOver = false;
267+
foreach (const ClientPlayer *player, players) {
268+
delete player;
269+
}
270+
players.clear();
271+
272+
notifyServer(S_COMMAND_SIGNUP);
273+
}
274+
275+
void Client::toggleReady()
276+
{
277+
notifyServer(S_COMMAND_TOGGLE_READY);
278+
}
279+
264280
void Client::networkDelayTest(const QVariant &) {
265281
notifyServer(S_COMMAND_NETWORK_DELAY_TEST);
266282
}
@@ -321,14 +337,31 @@ void Client::setup(const QVariant &setup_json) {
321337

322338
QString setup_str = setup_json.toString();
323339
if (ServerInfo.parse(setup_str)) {
324-
emit server_connected();
340+
Self = new ClientPlayer(this);
341+
Self->setScreenName(Config.UserName);
342+
Self->setProperty("avatar", Config.UserAvatar);
343+
connect(Self, SIGNAL(phase_changed()), this, SLOT(alertFocus()));
344+
connect(Self, SIGNAL(role_changed(QString)), this, SLOT(notifyRoleChange(QString)));
345+
346+
players << Self;
347+
348+
emit roomServerConnected();
325349
notifyServer(S_COMMAND_TOGGLE_READY);
326-
}
327-
else {
350+
} else {
328351
QMessageBox::warning(NULL, tr("Warning"), tr("Setup string can not be parsed: %1").arg(setup_str));
329352
}
330353
}
331354

355+
void Client::enterLobby(const QVariant &)
356+
{
357+
emit lobbyServerConnected();
358+
}
359+
360+
void Client::updateRoomList(const QVariant &list)
361+
{
362+
emit roomListChanged(list);
363+
}
364+
332365
void Client::disconnectFromHost() {
333366
if (socket) {
334367
socket->disconnectFromHost();
@@ -580,6 +613,17 @@ void Client::arrange(const QStringList &order) {
580613
request(QString("arrange %1").arg(order.join("+")));
581614
}
582615

616+
void Client::fetchRoomList(int page)
617+
{
618+
notifyServer(S_COMMAND_ROOM_LIST, page);
619+
}
620+
621+
void Client::requestNewRoom()
622+
{
623+
RoomConfig config(SettingsInstance);
624+
notifyServer(S_COMMAND_CREATE_ROOM, config.toVariant());
625+
}
626+
583627
void Client::onPlayerResponseCard(const Card *card, const QList<const Player *> &targets) {
584628
if ((status & ClientStatusBasicMask) == Responding)
585629
_m_roomState.setCurrentCardUsePattern(QString());
@@ -614,7 +658,7 @@ void Client::startInXs(const QVariant &left_seconds) {
614658

615659
emit start_in_xs();
616660
if (seconds == 0 && Sanguosha->getScenario(ServerInfo.GameMode) == NULL) {
617-
emit avatars_hiden();
661+
emit avatars_hidden();
618662
}
619663
}
620664

@@ -1089,6 +1133,11 @@ void Client::onPlayerChangeSkin(int skin_id, bool is_head)
10891133
notifyServer(S_COMMAND_CHANGE_SKIN, args);
10901134
}
10911135

1136+
void Client::onPlayerChooseRoom(int room_id)
1137+
{
1138+
notifyServer(S_COMMAND_ENTER_ROOM, room_id);
1139+
}
1140+
10921141
void Client::trust() {
10931142
notifyServer(S_COMMAND_TRUST);
10941143

@@ -1148,7 +1197,7 @@ int Client::alivePlayerCount() const{
11481197
}
11491198

11501199
ClientPlayer *Client::getPlayer(const QString &name) {
1151-
if (name == Self->objectName() ||
1200+
if ((Self != NULL && name == Self->objectName()) ||
11521201
name == QSanProtocol::S_PLAYER_SELF_REFERENCE_ID)
11531202
return Self;
11541203
else
@@ -1300,7 +1349,6 @@ void Client::askForExchange(const QVariant &exchange) {
13001349
}
13011350

13021351
void Client::gameOver(const QVariant &arg) {
1303-
disconnectFromHost();
13041352
m_isGameOver = true;
13051353
setStatus(Client::NotActive);
13061354

@@ -1890,6 +1938,8 @@ void Client::speak(const QVariant &speak) {
18901938
title = from->getGeneralName();
18911939
title = Sanguosha->translate(title);
18921940
title.append(QString("(%1)").arg(from->screenName()));
1941+
} else {
1942+
title = who;
18931943
}
18941944

18951945
title = QString("<b>%1</b>").arg(title);

0 commit comments

Comments
 (0)