diff --git a/client/GameChatHandler.cpp b/client/GameChatHandler.cpp index 713d9a277..e93208bd9 100644 --- a/client/GameChatHandler.cpp +++ b/client/GameChatHandler.cpp @@ -47,7 +47,9 @@ void GameChatHandler::sendMessageGameplay(const std::string & messageText) void GameChatHandler::sendMessageLobby(const std::string & senderName, const std::string & messageText) { LobbyChatMessage lcm; - lcm.message = messageText; + MetaString txt; + txt.appendRawString(messageText); + lcm.message = txt; lcm.playerName = senderName; CSH->sendLobbyPack(lcm); CSH->getGlobalLobby().sendMatchChatMessage(messageText); @@ -63,8 +65,6 @@ void GameChatHandler::onNewLobbyMessageReceived(const std::string & senderName, auto * lobby = dynamic_cast(SEL); - std::string messageTextReplaced = translationReplace(messageText); - // FIXME: when can this happen? assert(lobby); assert(lobby->card); @@ -74,14 +74,14 @@ void GameChatHandler::onNewLobbyMessageReceived(const std::string & senderName, MetaString formatted = MetaString::createFromRawString("[%s] %s: %s"); formatted.replaceRawString(TextOperations::getCurrentFormattedTimeLocal()); formatted.replaceRawString(senderName); - formatted.replaceRawString(messageTextReplaced); + formatted.replaceRawString(messageText); lobby->card->chat->addNewMessage(formatted.toString()); if (!lobby->card->showChat) lobby->toggleChat(); } - chatHistory.push_back({senderName, messageTextReplaced, TextOperations::getCurrentFormattedTimeLocal()}); + chatHistory.push_back({senderName, messageText, TextOperations::getCurrentFormattedTimeLocal()}); } void GameChatHandler::onNewGameMessageReceived(PlayerColor sender, const std::string & messageText) @@ -90,43 +90,21 @@ void GameChatHandler::onNewGameMessageReceived(PlayerColor sender, const std::st std::string timeFormatted = TextOperations::getCurrentFormattedTimeLocal(); std::string playerName = ""; - std::string messageTextReplaced = translationReplace(messageText); - if (sender.isValidPlayer()) playerName = LOCPLINT->cb->getStartInfo()->playerInfos.at(sender).name; if (sender.isSpectator()) playerName = "Spectator"; // FIXME: translate? Provide nickname somewhere? - chatHistory.push_back({playerName, messageTextReplaced, timeFormatted}); + chatHistory.push_back({playerName, messageText, timeFormatted}); - LOCPLINT->cingconsole->addMessage(timeFormatted, playerName, messageTextReplaced); + LOCPLINT->cingconsole->addMessage(timeFormatted, playerName, messageText); } void GameChatHandler::onNewSystemMessageReceived(const std::string & messageText) { - std::string messageTextReplaced = translationReplace(messageText); - - chatHistory.push_back({"System", messageTextReplaced, TextOperations::getCurrentFormattedTimeLocal()}); + chatHistory.push_back({"System", messageText, TextOperations::getCurrentFormattedTimeLocal()}); if(LOCPLINT && !settings["session"]["hideSystemMessages"].Bool()) - LOCPLINT->cingconsole->addMessage(TextOperations::getCurrentFormattedTimeLocal(), "System", messageTextReplaced); -} - -std::string GameChatHandler::translationReplace(std::string txt) -{ - std::regex expr("~~([\\w\\d\\.]+)~~"); - std::string result = ""; - std::string tmp_suffix = ""; - std::smatch match; - std::string::const_iterator searchStart( txt.cbegin() ); - while(std::regex_search(searchStart, txt.cend(), match, expr) ) - { - result += match.prefix(); - result += VLC->generaltexth->translate(match.str(1)); - - searchStart = match.suffix().first; - tmp_suffix = match.suffix(); - } - return result.empty() ? txt : result + tmp_suffix; + LOCPLINT->cingconsole->addMessage(TextOperations::getCurrentFormattedTimeLocal(), "System", messageText); } diff --git a/client/GameChatHandler.h b/client/GameChatHandler.h index b74a05a0e..424e8afed 100644 --- a/client/GameChatHandler.h +++ b/client/GameChatHandler.h @@ -23,8 +23,6 @@ struct GameChatMessage class GameChatHandler : boost::noncopyable { std::vector chatHistory; - - std::string translationReplace(std::string txt); public: /// Returns all message history for current match const std::vector & getChatHistory() const; diff --git a/client/NetPacksClient.cpp b/client/NetPacksClient.cpp index 53d4304d2..6789486d0 100644 --- a/client/NetPacksClient.cpp +++ b/client/NetPacksClient.cpp @@ -915,9 +915,9 @@ void ApplyClientNetPackVisitor::visitPackageApplied(PackageApplied & pack) void ApplyClientNetPackVisitor::visitSystemMessage(SystemMessage & pack) { // usually used to receive error messages from server - logNetwork->error("System message: %s", pack.text); + logNetwork->error("System message: %s", pack.text.toString()); - CSH->getGameChat().onNewSystemMessageReceived(pack.text); + CSH->getGameChat().onNewSystemMessageReceived(pack.text.toString()); } void ApplyClientNetPackVisitor::visitPlayerBlocked(PlayerBlocked & pack) diff --git a/client/NetPacksLobbyClient.cpp b/client/NetPacksLobbyClient.cpp index a57e9ec0a..289eb2bfc 100644 --- a/client/NetPacksLobbyClient.cpp +++ b/client/NetPacksLobbyClient.cpp @@ -99,7 +99,7 @@ void ApplyOnLobbyScreenNetPackVisitor::visitLobbyClientDisconnected(LobbyClientD void ApplyOnLobbyScreenNetPackVisitor::visitLobbyChatMessage(LobbyChatMessage & pack) { - handler.getGameChat().onNewLobbyMessageReceived(pack.playerName, pack.message); + handler.getGameChat().onNewLobbyMessageReceived(pack.playerName, pack.message.toString()); } void ApplyOnLobbyScreenNetPackVisitor::visitLobbyGuiAction(LobbyGuiAction & pack) @@ -220,5 +220,5 @@ void ApplyOnLobbyScreenNetPackVisitor::visitLobbyShowMessage(LobbyShowMessage & return; lobby->buttonStart->block(false); - handler.showServerError(pack.message); + handler.showServerError(pack.message.toString()); } diff --git a/lib/networkPacks/PacksForClient.h b/lib/networkPacks/PacksForClient.h index d7d74d909..866c8a9d3 100644 --- a/lib/networkPacks/PacksForClient.h +++ b/lib/networkPacks/PacksForClient.h @@ -73,7 +73,7 @@ struct DLL_LINKAGE PackageApplied : public CPackForClient struct DLL_LINKAGE SystemMessage : public CPackForClient { - explicit SystemMessage(std::string Text) + explicit SystemMessage(MetaString Text) : text(std::move(Text)) { } @@ -81,7 +81,7 @@ struct DLL_LINKAGE SystemMessage : public CPackForClient void visitTyped(ICPackVisitor & visitor) override; - std::string text; + MetaString text; template void serialize(Handler & h) { diff --git a/lib/networkPacks/PacksForLobby.h b/lib/networkPacks/PacksForLobby.h index defb0a3c1..508c05181 100644 --- a/lib/networkPacks/PacksForLobby.h +++ b/lib/networkPacks/PacksForLobby.h @@ -11,6 +11,7 @@ #include "StartInfo.h" #include "NetPacksBase.h" +#include "../MetaString.h" class CServerHandler; class CVCMIServer; @@ -73,7 +74,7 @@ struct DLL_LINKAGE LobbyClientDisconnected : public CLobbyPackToPropagate struct DLL_LINKAGE LobbyChatMessage : public CLobbyPackToPropagate { std::string playerName; - std::string message; + MetaString message; void visitTyped(ICPackVisitor & visitor) override; @@ -333,7 +334,7 @@ struct DLL_LINKAGE LobbyForceSetPlayer : public CLobbyPackToServer struct DLL_LINKAGE LobbyShowMessage : public CLobbyPackToPropagate { - std::string message; + MetaString message; void visitTyped(ICPackVisitor & visitor) override; diff --git a/server/CVCMIServer.cpp b/server/CVCMIServer.cpp index f546f477f..445be63d8 100644 --- a/server/CVCMIServer.cpp +++ b/server/CVCMIServer.cpp @@ -16,6 +16,7 @@ #include "processors/PlayerMessageProcessor.h" #include "../lib/CHeroHandler.h" +#include "../lib/MetaString.h" #include "../lib/registerTypes/RegisterTypesLobbyPacks.h" #include "../lib/serializer/CMemorySerializer.h" #include "../lib/serializer/Connection.h" @@ -378,21 +379,35 @@ void CVCMIServer::announcePack(std::unique_ptr pack) applier->getApplier(CTypeList::getInstance().getTypeID(pack.get()))->applyOnServerAfter(this, pack.get()); } +void CVCMIServer::announceMessage(MetaString txt) +{ + logNetwork->info("Show message: %s", txt.toString()); + auto cm = std::make_unique(); + cm->message = txt; + announcePack(std::move(cm)); +} + void CVCMIServer::announceMessage(const std::string & txt) { - logNetwork->info("Show message: %s", txt); - auto cm = std::make_unique(); + MetaString str; + str.appendRawString(txt); + announceMessage(str); +} + +void CVCMIServer::announceTxt(MetaString txt, const std::string & playerName) +{ + logNetwork->info("%s says: %s", playerName, txt.toString()); + auto cm = std::make_unique(); + cm->playerName = playerName; cm->message = txt; announcePack(std::move(cm)); } void CVCMIServer::announceTxt(const std::string & txt, const std::string & playerName) { - logNetwork->info("%s says: %s", playerName, txt); - auto cm = std::make_unique(); - cm->playerName = playerName; - cm->message = txt; - announcePack(std::move(cm)); + MetaString str; + str.appendRawString(txt); + announceTxt(str, playerName); } bool CVCMIServer::passHost(int toConnectionId) diff --git a/server/CVCMIServer.h b/server/CVCMIServer.h index bc19a097b..301fe0c43 100644 --- a/server/CVCMIServer.h +++ b/server/CVCMIServer.h @@ -23,6 +23,7 @@ struct StartInfo; struct LobbyInfo; struct PlayerSettings; class PlayerColor; +class MetaString; template class CApplier; @@ -89,6 +90,7 @@ public: void announcePack(std::unique_ptr pack); bool passHost(int toConnectionId); + void announceTxt(MetaString txt, const std::string & playerName = "system"); void announceTxt(const std::string & txt, const std::string & playerName = "system"); void setPlayerConnectedId(PlayerSettings & pset, ui8 player) const; @@ -98,6 +100,7 @@ public: void clientDisconnected(std::shared_ptr c); void reconnectPlayer(int connId); + void announceMessage(MetaString txt); void announceMessage(const std::string & txt); void handleReceivedPack(std::unique_ptr pack); diff --git a/server/NetPacksLobbyServer.cpp b/server/NetPacksLobbyServer.cpp index 89a8bc45e..4e96e96a2 100644 --- a/server/NetPacksLobbyServer.cpp +++ b/server/NetPacksLobbyServer.cpp @@ -389,17 +389,33 @@ void ApplyOnServerNetPackVisitor::visitLobbyPvPAction(LobbyPvPAction & pack) std::vector randomFaction2; std::sample(allowedTowns.begin(), allowedTowns.end(), std::back_inserter(randomFaction2), 1, std::mt19937{std::random_device{}()}); + MetaString txt; + switch(pack.action) { case LobbyPvPAction::COIN: - srv.announceTxt("~~vcmi.lobby.pvp.coin.hover~~ - " + std::to_string(std::rand()%2)); + txt.appendTextID("vcmi.lobby.pvp.coin.hover"); + txt.appendRawString(" - " + std::to_string(std::rand()%2)); + srv.announceTxt(txt); break; case LobbyPvPAction::RANDOM_TOWN: - if(allowedTowns.size()) - srv.announceTxt("~~core.overview.3~~ - ~~" + VLC->townh->getById(randomFaction1[0])->getNameTextID() + "~~"); + if(!allowedTowns.size()) + break; + txt.appendTextID("core.overview.3"); + txt.appendRawString(" - "); + txt.appendTextID(VLC->townh->getById(randomFaction1[0])->getNameTextID()); + srv.announceTxt(txt); break; case LobbyPvPAction::RANDOM_TOWN_VS: - if(allowedTowns.size()) - srv.announceTxt("~~core.overview.3~~ - ~~" + VLC->townh->getById(randomFaction1[0])->getNameTextID() + "~~ ~~vcmi.lobby.pvp.versus~~ ~~" + VLC->townh->getById(randomFaction2[0])->getNameTextID() + "~~"); + if(!allowedTowns.size()) + break; + txt.appendTextID("core.overview.3"); + txt.appendRawString(" - "); + txt.appendTextID(VLC->townh->getById(randomFaction1[0])->getNameTextID()); + txt.appendRawString(" "); + txt.appendTextID("vcmi.lobby.pvp.versus"); + txt.appendRawString(" "); + txt.appendTextID(VLC->townh->getById(randomFaction2[0])->getNameTextID()); + srv.announceTxt(txt); break; } result = true; diff --git a/server/processors/PlayerMessageProcessor.cpp b/server/processors/PlayerMessageProcessor.cpp index 8eeef0d7b..b292d86a9 100644 --- a/server/processors/PlayerMessageProcessor.cpp +++ b/server/processors/PlayerMessageProcessor.cpp @@ -42,7 +42,11 @@ void PlayerMessageProcessor::playerMessage(PlayerColor player, const std::string if (handleCheatCode(message, player, currObj)) { if(!gameHandler->getPlayerSettings(player)->isControlledByAI()) - broadcastSystemMessage("~~core.genrltxt.260~~"); + { + MetaString txt; + txt.appendLocalString(EMetaText::GENERAL_TXT, 260); + broadcastSystemMessage(txt); + } if(!player.isSpectator()) gameHandler->checkVictoryLossConditionsForPlayer(player);//Player enter win code or got required art\creature @@ -614,20 +618,34 @@ void PlayerMessageProcessor::executeCheatCode(const std::string & cheatName, Pla callbacks.at(cheatName)(); } -void PlayerMessageProcessor::sendSystemMessage(std::shared_ptr connection, const std::string & message) +void PlayerMessageProcessor::sendSystemMessage(std::shared_ptr connection, MetaString message) { SystemMessage sm; sm.text = message; connection->sendPack(&sm); } -void PlayerMessageProcessor::broadcastSystemMessage(const std::string & message) +void PlayerMessageProcessor::sendSystemMessage(std::shared_ptr connection, const std::string & message) +{ + MetaString str; + str.appendRawString(message); + sendSystemMessage(connection, str); +} + +void PlayerMessageProcessor::broadcastSystemMessage(MetaString message) { SystemMessage sm; sm.text = message; gameHandler->sendToAllClients(&sm); } +void PlayerMessageProcessor::broadcastSystemMessage(const std::string & message) +{ + MetaString str; + str.appendRawString(message); + broadcastSystemMessage(str); +} + void PlayerMessageProcessor::broadcastMessage(PlayerColor playerSender, const std::string & message) { PlayerMessageClient temp_message(playerSender, message); diff --git a/server/processors/PlayerMessageProcessor.h b/server/processors/PlayerMessageProcessor.h index 6dc22591b..6e0b06716 100644 --- a/server/processors/PlayerMessageProcessor.h +++ b/server/processors/PlayerMessageProcessor.h @@ -15,6 +15,7 @@ VCMI_LIB_NAMESPACE_BEGIN class CGHeroInstance; class CGTownInstance; class CConnection; +class MetaString; VCMI_LIB_NAMESPACE_END class CGameHandler; @@ -51,9 +52,11 @@ public: void playerMessage(PlayerColor player, const std::string & message, ObjectInstanceID currObj); /// Send message to specific client with "System" as sender + void sendSystemMessage(std::shared_ptr connection, MetaString message); void sendSystemMessage(std::shared_ptr connection, const std::string & message); /// Send message to all players with "System" as sender + void broadcastSystemMessage(MetaString message); void broadcastSystemMessage(const std::string & message); /// Send message from specific player to all other players