diff --git a/builds/vs2010/sanguosha.ts b/builds/vs2010/sanguosha.ts index 71de51135..6c8a438e5 100644 --- a/builds/vs2010/sanguosha.ts +++ b/builds/vs2010/sanguosha.ts @@ -2805,59 +2805,59 @@ Room - + disconnected 断开 - + Computer %1 电脑 %1 - + <font color=#000000>Player <b>%1</b> left the game</font> <font color=#000000>玩家 %1 离开了游戏</font> - + Hello, I'm a robot 大家好,我是一个机器人 - + <font color=#EEB422>Player <b>%1</b> joined the game</font> <font color=#EEB422>玩家 <b>%1</b> 加入了游戏</font> - + Unable to parse player 不可分析的玩家 - + Server is not waiting for reply from %1 服务器无法获取 %1 的响应 - + Reply command should be %1 instead of %2 应答指令应为 %1 而不是 %2 - + Reply serial should be %1 instead of %2 玩家序号应为 %1 而不是 %2 - + Card cannot be parsed: %1 卡牌字符串无法解析: %1 - + <font color=#EEB422>The network delay of player <b>%1</b> is %2 milliseconds.</font> <font color=#EEB422>玩家 <b>%1</b> 的网络延迟为 %2 毫秒</font> diff --git a/src/server/room.cpp b/src/server/room.cpp index 08bdba68a..58bbcb27b 100644 --- a/src/server/room.cpp +++ b/src/server/room.cpp @@ -888,7 +888,7 @@ bool Room::notifyMoveFocus(const QList &players, CommandType com } bool Room::askForSkillInvoke(ServerPlayer *player, const QString &skill_name, const QVariant &data) { - while (isPaused()) {} + tryPause(); notifyMoveFocus(player, S_COMMAND_INVOKE_SKILL); bool invoked = false; @@ -936,7 +936,7 @@ bool Room::askForSkillInvoke(ServerPlayer *player, const QString &skill_name, co } QString Room::askForChoice(ServerPlayer *player, const QString &skill_name, const QString &choices, const QVariant &data) { - while (isPaused()) {} + tryPause(); notifyMoveFocus(player, S_COMMAND_MULTIPLE_CHOICE); QStringList validChoices = choices.split("+"); @@ -1014,7 +1014,7 @@ bool Room::askForNullification(const Card *trick, ServerPlayer *from, ServerPlay bool Room::_askForNullification(const Card *trick, ServerPlayer *from, ServerPlayer *to, bool positive, _NullificationAiHelper aiHelper) { - while (isPaused()) {} + tryPause(); _m_roomState.setCurrentCardUseReason(CardUseStruct::CARD_USE_REASON_RESPONSE_USE); QString trick_name = trick->objectName(); @@ -1110,7 +1110,7 @@ bool Room::_askForNullification(const Card *trick, ServerPlayer *from, ServerPla int Room::askForCardChosen(ServerPlayer *player, ServerPlayer *who, const QString &flags, const QString &reason, bool handcard_visible, Card::HandlingMethod method, const QList &disabled_ids) { - while (isPaused()) {} + tryPause(); notifyMoveFocus(player, S_COMMAND_CHOOSE_CARD); if (handcard_visible && !who->isKongcheng()) { @@ -1184,7 +1184,7 @@ const Card *Room::askForCard(ServerPlayer *player, const QString &pattern, const const QVariant &data, Card::HandlingMethod method, ServerPlayer *to, bool isRetrial, const QString &skill_name, bool isProvision) { Q_ASSERT(pattern != "slash" || method != Card::MethodUse); // use askForUseSlashTo instead - while (isPaused()) {} + tryPause(); notifyMoveFocus(player, S_COMMAND_RESPONSE_CARD); _m_roomState.setCurrentCardUsePattern(pattern); @@ -1348,7 +1348,7 @@ const Card *Room::askForCard(ServerPlayer *player, const QString &pattern, const const Card *Room::askForUseCard(ServerPlayer *player, const QString &pattern, const QString &prompt, int notice_index, Card::HandlingMethod method, bool addHistory) { Q_ASSERT(method != Card::MethodResponse); - while (isPaused()) {} + tryPause(); notifyMoveFocus(player, S_COMMAND_RESPONSE_CARD); _m_roomState.setCurrentCardUsePattern(pattern); @@ -1432,7 +1432,7 @@ const Card *Room::askForUseSlashTo(ServerPlayer *slasher, ServerPlayer *victim, } int Room::askForAG(ServerPlayer *player, const QList &card_ids, bool refusable, const QString &reason) { - while (isPaused()) {} + tryPause(); notifyMoveFocus(player, S_COMMAND_AMAZING_GRACE); Q_ASSERT(card_ids.length() > 0); @@ -1463,7 +1463,7 @@ int Room::askForAG(ServerPlayer *player, const QList &card_ids, bool refusa const Card *Room::askForCardShow(ServerPlayer *player, ServerPlayer *requestor, const QString &reason) { Q_ASSERT(!player->isKongcheng()); - while (isPaused()) {} + tryPause(); notifyMoveFocus(player, S_COMMAND_SHOW_CARD); const Card *card = NULL; @@ -1489,7 +1489,7 @@ const Card *Room::askForCardShow(ServerPlayer *player, ServerPlayer *requestor, } const Card *Room::askForSinglePeach(ServerPlayer *player, ServerPlayer *dying) { - while (isPaused()) {} + tryPause(); notifyMoveFocus(player, S_COMMAND_ASK_PEACH); _m_roomState.setCurrentCardUseReason(CardUseStruct::CARD_USE_REASON_RESPONSE_USE); @@ -1707,9 +1707,11 @@ bool Room::canPause(ServerPlayer *player) const{ return true; } -bool Room::isPaused() const{ - if (!canPause(getOwner())) return false; - return game_paused; +void Room::tryPause() { + if (!canPause(getOwner())) return; + QMutexLocker locker(&m_mutex); + while (game_paused) + m_waitCond.wait(locker.mutex()); } int Room::getLack() const{ @@ -1879,7 +1881,7 @@ void Room::setFixedDistance(Player *from, const Player *to, int distance) { } void Room::reverseFor3v3(const Card *card, ServerPlayer *player, QList &list) { - while (isPaused()) {} + tryPause(); notifyMoveFocus(player, S_COMMAND_CHOOSE_DIRECTION); bool isClockwise = false; @@ -2111,6 +2113,7 @@ bool Room::trustCommand(ServerPlayer *player, const Json::Value &) { bool Room::pauseCommand(ServerPlayer *player, const Json::Value &arg) { if (!canPause(player)) return false; bool pause = arg.asBool(); + QMutexLocker locker(&m_mutex); if (game_paused != pause) { Json::Value arg(Json::arrayValue); arg[0] = (int)S_GAME_EVENT_PAUSE; @@ -2118,6 +2121,8 @@ bool Room::pauseCommand(ServerPlayer *player, const Json::Value &arg) { doNotify(player, S_COMMAND_LOG_EVENT, arg); game_paused = pause; + if (!game_paused) + m_waitCond.wakeAll(); } return true; } @@ -4279,7 +4284,7 @@ void Room::setEmotion(ServerPlayer *target, const QString &emotion) { #include void Room::activate(ServerPlayer *player, CardUseStruct &card_use) { - while (isPaused()) {} + tryPause(); if (player->getPhase() != Player::Play) return; if (player->hasFlag("Global_PlayPhaseTerminated")) { @@ -4333,7 +4338,7 @@ void Room::activate(ServerPlayer *player, CardUseStruct &card_use) { } void Room::askForLuckCard() { - while (isPaused()) {} + tryPause(); QList players; foreach (ServerPlayer *player, m_players) { @@ -4442,7 +4447,7 @@ void Room::askForLuckCard() { } Card::Suit Room::askForSuit(ServerPlayer *player, const QString &reason) { - while (isPaused()) {} + tryPause(); notifyMoveFocus(player, S_COMMAND_CHOOSE_SUIT); AI *ai = player->getAI(); @@ -4469,7 +4474,7 @@ Card::Suit Room::askForSuit(ServerPlayer *player, const QString &reason) { } QString Room::askForKingdom(ServerPlayer *player) { - while (isPaused()) {} + tryPause(); notifyMoveFocus(player, S_COMMAND_CHOOSE_KINGDOM); QString result = "wei"; @@ -4499,7 +4504,7 @@ bool Room::askForDiscard(ServerPlayer *player, const QString &reason, int discar bool optional, bool include_equip, const QString &prompt, const QString &pattern) { if (!player->isAlive()) return false; - while (isPaused()) {} + tryPause(); notifyMoveFocus(player, S_COMMAND_DISCARD_CARD); min_num = qMin(min_num, discard_num); ExpPattern exp_pattern(pattern); @@ -4618,7 +4623,7 @@ const Card *Room::askForExchange(ServerPlayer *player, const QString &reason, in bool include_equip, const QString &prompt, bool optional, const QString &pattern) { if (!player->isAlive()) return NULL; - while (isPaused()) {} + tryPause(); notifyMoveFocus(player, S_COMMAND_EXCHANGE_CARD); min_num = qMin(min_num, discard_num); @@ -4693,7 +4698,7 @@ ServerPlayer *Room::getLord() const{ void Room::askForGuanxing(ServerPlayer *zhuge, const QList &cards, GuanxingType guanxing_type) { QList top_cards, bottom_cards; - while (isPaused()) {} + tryPause(); notifyMoveFocus(zhuge, S_COMMAND_SKILL_GUANXING); AI *ai = zhuge->getAI(); @@ -4789,7 +4794,7 @@ void Room::returnToTopDrawPile(const QList &cards) { int Room::doGongxin(ServerPlayer *shenlvmeng, ServerPlayer *target, QList enabled_ids, QString skill_name) { Q_ASSERT(!target->isKongcheng()); - while (isPaused()) {} + tryPause(); notifyMoveFocus(shenlvmeng, S_COMMAND_SKILL_GONGXIN); LogMessage log; @@ -4850,7 +4855,7 @@ const Card *Room::askForPindian(ServerPlayer *player, ServerPlayer *from, Server if (!from->isAlive() || !to->isAlive()) return NULL; Q_ASSERT(!player->isKongcheng()); - while (isPaused()) {} + tryPause(); notifyMoveFocus(player, S_COMMAND_PINDIAN); if (player->getHandcardNum() == 1) @@ -4883,7 +4888,7 @@ QList Room::askForPindianRace(ServerPlayer *from, ServerPlayer *to if (!from->isAlive() || !to->isAlive()) return QList() << NULL << NULL; Q_ASSERT(!from->isKongcheng() && !to->isKongcheng()); - while (isPaused()) {} + tryPause(); Countdown countdown; countdown.m_max = ServerInfo.getCommandTimeout(S_COMMAND_PINDIAN, S_CLIENT_INSTANCE); countdown.m_type = Countdown::S_COUNTDOWN_USE_SPECIFIED; @@ -4958,7 +4963,7 @@ ServerPlayer *Room::askForPlayerChosen(ServerPlayer *player, const QListgetAI(); ServerPlayer *choice = NULL; @@ -5016,7 +5021,7 @@ void Room::_setupChooseGeneralRequestArgs(ServerPlayer *player) { } QString Room::askForGeneral(ServerPlayer *player, const QStringList &generals, QString default_choice) { - while (isPaused()) {} + tryPause(); notifyMoveFocus(player, S_COMMAND_CHOOSE_GENERAL); if (generals.length() == 1) @@ -5262,7 +5267,7 @@ void Room::sendCompulsoryTriggerLog(ServerPlayer *player, const QString &skill_n void Room::showCard(ServerPlayer *player, int card_id, ServerPlayer *only_viewer) { if (getCardOwner(card_id) != player) return; - while (isPaused()) {} + tryPause(); notifyMoveFocus(player); Json::Value show_arg(Json::arrayValue); show_arg[0] = toJsonString(player->objectName()); @@ -5292,7 +5297,7 @@ void Room::showCard(ServerPlayer *player, int card_id, ServerPlayer *only_viewer void Room::showAllCards(ServerPlayer *player, ServerPlayer *to) { if (player->isKongcheng()) return; - while (isPaused()) {} + tryPause(); Json::Value gongxinArgs(Json::arrayValue); gongxinArgs[0] = toJsonString(player->objectName()); @@ -5420,7 +5425,7 @@ bool Room::askForYiji(ServerPlayer *guojia, QList &cards, const QString &sk else reason.m_reason = CardMoveReason::S_REASON_GIVE; } - while (isPaused()) {} + tryPause(); notifyMoveFocus(guojia, S_COMMAND_SKILL_YIJI); ServerPlayer *target = NULL; @@ -5507,7 +5512,7 @@ QString Room::generatePlayerName() { } QString Room::askForOrder(ServerPlayer *player, const QString &default_choice) { - while (isPaused()) {} + tryPause(); notifyMoveFocus(player, S_COMMAND_CHOOSE_ORDER); if (player->getAI()) @@ -5522,7 +5527,7 @@ QString Room::askForOrder(ServerPlayer *player, const QString &default_choice) { } QString Room::askForRole(ServerPlayer *player, const QStringList &roles, const QString &scheme) { - while (isPaused()) {} + tryPause(); notifyMoveFocus(player, S_COMMAND_CHOOSE_ROLE_3V3); QStringList squeezed = roles.toSet().toList(); diff --git a/src/server/room.h b/src/server/room.h index d22c89c9f..618cd00ae 100644 --- a/src/server/room.h +++ b/src/server/room.h @@ -18,6 +18,7 @@ struct LogMessage; #include "room-state.h" #include #include +#include class Room: public QThread { Q_OBJECT @@ -41,7 +42,7 @@ class Room: public QThread { bool isFull() const; bool isFinished() const; bool canPause(ServerPlayer *p) const; - bool isPaused() const; + void tryPause(); int getLack() const; QString getMode() const; const Scenario *getScenario() const; @@ -496,6 +497,9 @@ class Room: public QThread { Json::Value m_fillAGarg; Json::Value m_takeAGargs; + QWaitCondition m_waitCond; + mutable QMutex m_mutex; + static QString generatePlayerName(); void prepareForStart(); void assignGeneralsForPlayers(const QList &to_assign); diff --git a/src/server/roomthread.cpp b/src/server/roomthread.cpp index 828c7472f..1e6754fc1 100644 --- a/src/server/roomthread.cpp +++ b/src/server/roomthread.cpp @@ -644,7 +644,7 @@ bool RoomThread::trigger(TriggerEvent triggerEvent, Room *room, ServerPlayer *ta triggered.append(skill); current_priority = skill->getPriority(triggerEvent); if (skill->triggerable(target)) { - while (room->isPaused()) {} + room->tryPause(); broken = skill->trigger(triggerEvent, room, target, data); if (broken) break; i = 0; @@ -672,7 +672,7 @@ bool RoomThread::trigger(TriggerEvent triggerEvent, Room *room, ServerPlayer *ta throw throwed_event; } - while (room->isPaused()) {} + room->tryPause(); return broken; } diff --git a/src/server/roomthread1v1.cpp b/src/server/roomthread1v1.cpp index e725b154d..c27764789 100644 --- a/src/server/roomthread1v1.cpp +++ b/src/server/roomthread1v1.cpp @@ -113,7 +113,7 @@ void RoomThread1v1::run() { } void RoomThread1v1::askForTakeGeneral(ServerPlayer *player) { - while (room->isPaused()) {} + room->tryPause(); QString name; if (general_names.length() == 1) @@ -171,7 +171,7 @@ void RoomThread1v1::takeGeneral(ServerPlayer *player, const QString &name) { } void RoomThread1v1::startArrange(QList players) { - while (room->isPaused()) {} + room->tryPause(); QList online = players; foreach (ServerPlayer *player, players) { if (!player->isOnline()) { @@ -201,7 +201,7 @@ void RoomThread1v1::startArrange(QList players) { } void RoomThread1v1::askForFirstGeneral(QList players) { - while (room->isPaused()) {} + room->tryPause(); QList online = players; foreach (ServerPlayer *player, players) { if (!player->isOnline()) { diff --git a/src/server/roomthread3v3.cpp b/src/server/roomthread3v3.cpp index ca0f01c64..c8b5d7790 100644 --- a/src/server/roomthread3v3.cpp +++ b/src/server/roomthread3v3.cpp @@ -115,7 +115,7 @@ void RoomThread3v3::run() { } void RoomThread3v3::askForTakeGeneral(ServerPlayer *player) { - while (room->isPaused()) {} + room->tryPause(); QString name; if (general_names.length() == 1 || player->getState() != "online") @@ -154,7 +154,7 @@ void RoomThread3v3::takeGeneral(ServerPlayer *player, const QString &name) { } void RoomThread3v3::startArrange(QList &players) { - while (room->isPaused()) {} + room->tryPause(); QList online = players; foreach (ServerPlayer *player, players) { if (!player->isOnline()) { diff --git a/src/server/roomthreadxmode.cpp b/src/server/roomthreadxmode.cpp index c981475e7..ca43196f3 100644 --- a/src/server/roomthreadxmode.cpp +++ b/src/server/roomthreadxmode.cpp @@ -83,7 +83,7 @@ void RoomThreadXMode::run() { } void RoomThreadXMode::startArrange(QList &players, QList &to_arrange) { - while (room->isPaused()) {} + room->tryPause(); QList online; QList online_index; for (int i = 0; i < players.length(); i++) {