From d7f6cc3951c22142abd405dc9bd59d27d4f65a5e Mon Sep 17 00:00:00 2001 From: Vitor Kiguchi Date: Sat, 29 Feb 2020 20:29:36 -0300 Subject: [PATCH 1/6] game_list_p.h: Specify the context for tr --- src/citra_qt/game_list_p.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/citra_qt/game_list_p.h b/src/citra_qt/game_list_p.h index f4656e5b5b..acb9dbf668 100644 --- a/src/citra_qt/game_list_p.h +++ b/src/citra_qt/game_list_p.h @@ -89,18 +89,18 @@ static QString GetQStringLongTitleFromSMDH(const Loader::SMDH& smdh, static QString GetRegionFromSMDH(const Loader::SMDH& smdh) { using GameRegion = Loader::SMDH::GameRegion; static const std::map regions_map = { - {GameRegion::Japan, QT_TR_NOOP("Japan")}, - {GameRegion::NorthAmerica, QT_TR_NOOP("North America")}, - {GameRegion::Europe, QT_TR_NOOP("Europe")}, - {GameRegion::Australia, QT_TR_NOOP("Australia")}, - {GameRegion::China, QT_TR_NOOP("China")}, - {GameRegion::Korea, QT_TR_NOOP("Korea")}, - {GameRegion::Taiwan, QT_TR_NOOP("Taiwan")}}; + {GameRegion::Japan, QT_TRANSLATE_NOOP("GameRegion", "Japan")}, + {GameRegion::NorthAmerica, QT_TRANSLATE_NOOP("GameRegion", "North America")}, + {GameRegion::Europe, QT_TRANSLATE_NOOP("GameRegion", "Europe")}, + {GameRegion::Australia, QT_TRANSLATE_NOOP("GameRegion", "Australia")}, + {GameRegion::China, QT_TRANSLATE_NOOP("GameRegion", "China")}, + {GameRegion::Korea, QT_TRANSLATE_NOOP("GameRegion", "Korea")}, + {GameRegion::Taiwan, QT_TRANSLATE_NOOP("GameRegion", "Taiwan")}}; std::vector regions = smdh.GetRegions(); if (regions.empty()) { - return QObject::tr("Invalid region"); + return QCoreApplication::translate("GameRegion", "Invalid region"); } const bool region_free = @@ -108,14 +108,14 @@ static QString GetRegionFromSMDH(const Loader::SMDH& smdh) { return std::find(regions.begin(), regions.end(), it.first) != regions.end(); }); if (region_free) { - return QObject::tr("Region free"); + return QCoreApplication::translate("GameRegion", "Region free"); } const QString separator = UISettings::values.game_list_single_line_mode ? QStringLiteral(", ") : QStringLiteral("\n"); - QString result = QObject::tr(regions_map.at(regions.front())); + QString result = QCoreApplication::translate("GameRegion", regions_map.at(regions.front())); for (auto region = ++regions.begin(); region != regions.end(); ++region) { - result += separator + QObject::tr(regions_map.at(*region)); + result += separator + QCoreApplication::translate("GameRegion", regions_map.at(*region)); } return result; } From c9b6233f597fbef2736eaa33efd4a3f0990795b2 Mon Sep 17 00:00:00 2001 From: Vitor Kiguchi Date: Sat, 29 Feb 2020 20:48:58 -0300 Subject: [PATCH 2/6] NetworkMessage: create ErrorManager class to provide a context to tr --- src/citra_qt/multiplayer/chat_room.cpp | 2 +- src/citra_qt/multiplayer/direct_connect.cpp | 7 +-- src/citra_qt/multiplayer/host_room.cpp | 11 ++-- src/citra_qt/multiplayer/lobby.cpp | 2 +- src/citra_qt/multiplayer/message.cpp | 48 +++++++++-------- src/citra_qt/multiplayer/message.h | 58 +++++++++++---------- src/citra_qt/multiplayer/state.cpp | 27 +++++----- 7 files changed, 82 insertions(+), 73 deletions(-) diff --git a/src/citra_qt/multiplayer/chat_room.cpp b/src/citra_qt/multiplayer/chat_room.cpp index 9e80d5abf5..4407369784 100644 --- a/src/citra_qt/multiplayer/chat_room.cpp +++ b/src/citra_qt/multiplayer/chat_room.cpp @@ -226,7 +226,7 @@ void ChatRoom::SendModerationRequest(Network::RoomMessageTypes type, const std:: return member.nickname == nickname; }); if (it == members.end()) { - NetworkMessage::ShowError(NetworkMessage::NO_SUCH_USER); + NetworkMessage::ErrorManager::ShowError(NetworkMessage::ErrorManager::NO_SUCH_USER); return; } room->SendModerationRequest(type, nickname); diff --git a/src/citra_qt/multiplayer/direct_connect.cpp b/src/citra_qt/multiplayer/direct_connect.cpp index aef2378b39..2ce935f23e 100644 --- a/src/citra_qt/multiplayer/direct_connect.cpp +++ b/src/citra_qt/multiplayer/direct_connect.cpp @@ -56,7 +56,7 @@ void DirectConnectWindow::RetranslateUi() { void DirectConnectWindow::Connect() { if (!ui->nickname->hasAcceptableInput()) { - NetworkMessage::ShowError(NetworkMessage::USERNAME_NOT_VALID); + NetworkMessage::ErrorManager::ShowError(NetworkMessage::ErrorManager::USERNAME_NOT_VALID); return; } if (const auto member = Network::GetRoomMember().lock()) { @@ -75,11 +75,12 @@ void DirectConnectWindow::Connect() { break; case ConnectionType::IP: if (!ui->ip->hasAcceptableInput()) { - NetworkMessage::ShowError(NetworkMessage::IP_ADDRESS_NOT_VALID); + NetworkMessage::ErrorManager::ShowError( + NetworkMessage::ErrorManager::IP_ADDRESS_NOT_VALID); return; } if (!ui->port->hasAcceptableInput()) { - NetworkMessage::ShowError(NetworkMessage::PORT_NOT_VALID); + NetworkMessage::ErrorManager::ShowError(NetworkMessage::ErrorManager::PORT_NOT_VALID); return; } break; diff --git a/src/citra_qt/multiplayer/host_room.cpp b/src/citra_qt/multiplayer/host_room.cpp index 09398cc477..49eb5480d9 100644 --- a/src/citra_qt/multiplayer/host_room.cpp +++ b/src/citra_qt/multiplayer/host_room.cpp @@ -104,19 +104,19 @@ std::unique_ptr HostRoomWindow::CreateVerifyBacken void HostRoomWindow::Host() { if (!ui->username->hasAcceptableInput()) { - NetworkMessage::ShowError(NetworkMessage::USERNAME_NOT_VALID); + NetworkMessage::ErrorManager::ShowError(NetworkMessage::ErrorManager::USERNAME_NOT_VALID); return; } if (!ui->room_name->hasAcceptableInput()) { - NetworkMessage::ShowError(NetworkMessage::ROOMNAME_NOT_VALID); + NetworkMessage::ErrorManager::ShowError(NetworkMessage::ErrorManager::ROOMNAME_NOT_VALID); return; } if (!ui->port->hasAcceptableInput()) { - NetworkMessage::ShowError(NetworkMessage::PORT_NOT_VALID); + NetworkMessage::ErrorManager::ShowError(NetworkMessage::ErrorManager::PORT_NOT_VALID); return; } if (ui->game_list->currentIndex() == -1) { - NetworkMessage::ShowError(NetworkMessage::GAME_NOT_SELECTED); + NetworkMessage::ErrorManager::ShowError(NetworkMessage::ErrorManager::GAME_NOT_SELECTED); return; } if (auto member = Network::GetRoomMember().lock()) { @@ -147,7 +147,8 @@ void HostRoomWindow::Host() { Settings::values.citra_username, game_name.toStdString(), game_id, CreateVerifyBackend(is_public), ban_list); if (!created) { - NetworkMessage::ShowError(NetworkMessage::COULD_NOT_CREATE_ROOM); + NetworkMessage::ErrorManager::ShowError( + NetworkMessage::ErrorManager::COULD_NOT_CREATE_ROOM); LOG_ERROR(Network, "Could not create room!"); ui->host->setEnabled(true); return; diff --git a/src/citra_qt/multiplayer/lobby.cpp b/src/citra_qt/multiplayer/lobby.cpp index 9e00f267b4..dce015597b 100644 --- a/src/citra_qt/multiplayer/lobby.cpp +++ b/src/citra_qt/multiplayer/lobby.cpp @@ -128,7 +128,7 @@ void Lobby::OnJoinRoom(const QModelIndex& source) { index = source.parent(); } if (!ui->nickname->hasAcceptableInput()) { - NetworkMessage::ShowError(NetworkMessage::USERNAME_NOT_VALID); + NetworkMessage::ErrorManager::ShowError(NetworkMessage::ErrorManager::USERNAME_NOT_VALID); return; } diff --git a/src/citra_qt/multiplayer/message.cpp b/src/citra_qt/multiplayer/message.cpp index 28d692c1e3..7bf5b7efc9 100644 --- a/src/citra_qt/multiplayer/message.cpp +++ b/src/citra_qt/multiplayer/message.cpp @@ -8,46 +8,50 @@ #include "citra_qt/multiplayer/message.h" namespace NetworkMessage { -const ConnectionError USERNAME_NOT_VALID( +const ConnectionError ErrorManager::USERNAME_NOT_VALID( QT_TR_NOOP("Username is not valid. Must be 4 to 20 alphanumeric characters.")); -const ConnectionError ROOMNAME_NOT_VALID( +const ConnectionError ErrorManager::ROOMNAME_NOT_VALID( QT_TR_NOOP("Room name is not valid. Must be 4 to 20 alphanumeric characters.")); -const ConnectionError USERNAME_NOT_VALID_SERVER( +const ConnectionError ErrorManager::USERNAME_NOT_VALID_SERVER( QT_TR_NOOP("Username is already in use or not valid. Please choose another.")); -const ConnectionError IP_ADDRESS_NOT_VALID(QT_TR_NOOP("IP is not a valid IPv4 address.")); -const ConnectionError PORT_NOT_VALID(QT_TR_NOOP("Port must be a number between 0 to 65535.")); -const ConnectionError GAME_NOT_SELECTED(QT_TR_NOOP( +const ConnectionError ErrorManager::IP_ADDRESS_NOT_VALID( + QT_TR_NOOP("IP is not a valid IPv4 address.")); +const ConnectionError ErrorManager::PORT_NOT_VALID( + QT_TR_NOOP("Port must be a number between 0 to 65535.")); +const ConnectionError ErrorManager::GAME_NOT_SELECTED(QT_TR_NOOP( "You must choose a Preferred Game to host a room. If you do not have any games in your game " "list yet, add a game folder by clicking on the plus icon in the game list.")); -const ConnectionError NO_INTERNET( +const ConnectionError ErrorManager::NO_INTERNET( QT_TR_NOOP("Unable to find an internet connection. Check your internet settings.")); -const ConnectionError UNABLE_TO_CONNECT( +const ConnectionError ErrorManager::UNABLE_TO_CONNECT( QT_TR_NOOP("Unable to connect to the host. Verify that the connection settings are correct. If " "you still cannot connect, contact the room host and verify that the host is " "properly configured with the external port forwarded.")); -const ConnectionError ROOM_IS_FULL( +const ConnectionError ErrorManager::ROOM_IS_FULL( QT_TR_NOOP("Unable to connect to the room because it is already full.")); -const ConnectionError COULD_NOT_CREATE_ROOM( +const ConnectionError ErrorManager::COULD_NOT_CREATE_ROOM( QT_TR_NOOP("Creating a room failed. Please retry. Restarting Citra might be necessary.")); -const ConnectionError HOST_BANNED( +const ConnectionError ErrorManager::HOST_BANNED( QT_TR_NOOP("The host of the room has banned you. Speak with the host to unban you " "or try a different room.")); -const ConnectionError WRONG_VERSION( +const ConnectionError ErrorManager::WRONG_VERSION( QT_TR_NOOP("Version mismatch! Please update to the latest version of Citra. If the problem " "persists, contact the room host and ask them to update the server.")); -const ConnectionError WRONG_PASSWORD(QT_TR_NOOP("Incorrect password.")); -const ConnectionError GENERIC_ERROR( +const ConnectionError ErrorManager::WRONG_PASSWORD(QT_TR_NOOP("Incorrect password.")); +const ConnectionError ErrorManager::GENERIC_ERROR( QT_TR_NOOP("An unknown error occured. If this error continues to occur, please open an issue")); -const ConnectionError LOST_CONNECTION(QT_TR_NOOP("Connection to room lost. Try to reconnect.")); -const ConnectionError HOST_KICKED(QT_TR_NOOP("You have been kicked by the room host.")); -const ConnectionError MAC_COLLISION( +const ConnectionError ErrorManager::LOST_CONNECTION( + QT_TR_NOOP("Connection to room lost. Try to reconnect.")); +const ConnectionError ErrorManager::HOST_KICKED( + QT_TR_NOOP("You have been kicked by the room host.")); +const ConnectionError ErrorManager::MAC_COLLISION( QT_TR_NOOP("MAC address is already in use. Please choose another.")); -const ConnectionError CONSOLE_ID_COLLISION(QT_TR_NOOP( +const ConnectionError ErrorManager::CONSOLE_ID_COLLISION(QT_TR_NOOP( "Your Console ID conflicted with someone else's in the room.\n\nPlease go to Emulation " "> Configure > System to regenerate your Console ID.")); -const ConnectionError PERMISSION_DENIED( +const ConnectionError ErrorManager::PERMISSION_DENIED( QT_TR_NOOP("You do not have enough permission to perform this action.")); -const ConnectionError NO_SUCH_USER(QT_TR_NOOP( +const ConnectionError ErrorManager::NO_SUCH_USER(QT_TR_NOOP( "The user you are trying to kick/ban could not be found.\nThey may have left the room.")); static bool WarnMessage(const std::string& title, const std::string& text) { @@ -56,8 +60,8 @@ static bool WarnMessage(const std::string& title, const std::string& text) { QMessageBox::Ok | QMessageBox::Cancel); } -void ShowError(const ConnectionError& e) { - QMessageBox::critical(nullptr, QObject::tr("Error"), QObject::tr(e.GetString().c_str())); +void ErrorManager::ShowError(const ConnectionError& e) { + QMessageBox::critical(nullptr, tr("Error"), tr(e.GetString().c_str())); } bool WarnCloseRoom() { diff --git a/src/citra_qt/multiplayer/message.h b/src/citra_qt/multiplayer/message.h index 7b1caa5fd9..49a31997dd 100644 --- a/src/citra_qt/multiplayer/message.h +++ b/src/citra_qt/multiplayer/message.h @@ -20,34 +20,36 @@ private: std::string err; }; -/// When the nickname is considered invalid by the client -extern const ConnectionError USERNAME_NOT_VALID; -extern const ConnectionError ROOMNAME_NOT_VALID; -/// When the nickname is considered invalid by the room server -extern const ConnectionError USERNAME_NOT_VALID_SERVER; -extern const ConnectionError IP_ADDRESS_NOT_VALID; -extern const ConnectionError PORT_NOT_VALID; -extern const ConnectionError GAME_NOT_SELECTED; -extern const ConnectionError NO_INTERNET; -extern const ConnectionError UNABLE_TO_CONNECT; -extern const ConnectionError ROOM_IS_FULL; -extern const ConnectionError COULD_NOT_CREATE_ROOM; -extern const ConnectionError HOST_BANNED; -extern const ConnectionError WRONG_VERSION; -extern const ConnectionError WRONG_PASSWORD; -extern const ConnectionError GENERIC_ERROR; -extern const ConnectionError LOST_CONNECTION; -extern const ConnectionError HOST_KICKED; -extern const ConnectionError MAC_COLLISION; -extern const ConnectionError CONSOLE_ID_COLLISION; -extern const ConnectionError PERMISSION_DENIED; -extern const ConnectionError NO_SUCH_USER; - -/** - * Shows a standard QMessageBox with a error message - */ -void ShowError(const ConnectionError& e); - +class ErrorManager : QObject { + Q_OBJECT +public: + /// When the nickname is considered invalid by the client + static const ConnectionError USERNAME_NOT_VALID; + static const ConnectionError ROOMNAME_NOT_VALID; + /// When the nickname is considered invalid by the room server + static const ConnectionError USERNAME_NOT_VALID_SERVER; + static const ConnectionError IP_ADDRESS_NOT_VALID; + static const ConnectionError PORT_NOT_VALID; + static const ConnectionError GAME_NOT_SELECTED; + static const ConnectionError NO_INTERNET; + static const ConnectionError UNABLE_TO_CONNECT; + static const ConnectionError ROOM_IS_FULL; + static const ConnectionError COULD_NOT_CREATE_ROOM; + static const ConnectionError HOST_BANNED; + static const ConnectionError WRONG_VERSION; + static const ConnectionError WRONG_PASSWORD; + static const ConnectionError GENERIC_ERROR; + static const ConnectionError LOST_CONNECTION; + static const ConnectionError HOST_KICKED; + static const ConnectionError MAC_COLLISION; + static const ConnectionError CONSOLE_ID_COLLISION; + static const ConnectionError PERMISSION_DENIED; + static const ConnectionError NO_SUCH_USER; + /** + * Shows a standard QMessageBox with a error message + */ + static void ShowError(const ConnectionError& e); +}; /** * Show a standard QMessageBox with a warning message about leaving the room * return true if the user wants to close the network connection diff --git a/src/citra_qt/multiplayer/state.cpp b/src/citra_qt/multiplayer/state.cpp index 591434c5ec..6fa6d18095 100644 --- a/src/citra_qt/multiplayer/state.cpp +++ b/src/citra_qt/multiplayer/state.cpp @@ -131,43 +131,44 @@ void MultiplayerState::OnNetworkError(const Network::RoomMember::Error& error) { LOG_DEBUG(Frontend, "Network Error: {}", Network::GetErrorStr(error)); switch (error) { case Network::RoomMember::Error::LostConnection: - NetworkMessage::ShowError(NetworkMessage::LOST_CONNECTION); + NetworkMessage::ErrorManager::ShowError(NetworkMessage::ErrorManager::LOST_CONNECTION); break; case Network::RoomMember::Error::HostKicked: - NetworkMessage::ShowError(NetworkMessage::HOST_KICKED); + NetworkMessage::ErrorManager::ShowError(NetworkMessage::ErrorManager::HOST_KICKED); break; case Network::RoomMember::Error::CouldNotConnect: - NetworkMessage::ShowError(NetworkMessage::UNABLE_TO_CONNECT); + NetworkMessage::ErrorManager::ShowError(NetworkMessage::ErrorManager::UNABLE_TO_CONNECT); break; case Network::RoomMember::Error::NameCollision: - NetworkMessage::ShowError(NetworkMessage::USERNAME_NOT_VALID_SERVER); + NetworkMessage::ErrorManager::ShowError( + NetworkMessage::ErrorManager::USERNAME_NOT_VALID_SERVER); break; case Network::RoomMember::Error::MacCollision: - NetworkMessage::ShowError(NetworkMessage::MAC_COLLISION); + NetworkMessage::ErrorManager::ShowError(NetworkMessage::ErrorManager::MAC_COLLISION); break; case Network::RoomMember::Error::ConsoleIdCollision: - NetworkMessage::ShowError(NetworkMessage::CONSOLE_ID_COLLISION); + NetworkMessage::ErrorManager::ShowError(NetworkMessage::ErrorManager::CONSOLE_ID_COLLISION); break; case Network::RoomMember::Error::RoomIsFull: - NetworkMessage::ShowError(NetworkMessage::ROOM_IS_FULL); + NetworkMessage::ErrorManager::ShowError(NetworkMessage::ErrorManager::ROOM_IS_FULL); break; case Network::RoomMember::Error::WrongPassword: - NetworkMessage::ShowError(NetworkMessage::WRONG_PASSWORD); + NetworkMessage::ErrorManager::ShowError(NetworkMessage::ErrorManager::WRONG_PASSWORD); break; case Network::RoomMember::Error::WrongVersion: - NetworkMessage::ShowError(NetworkMessage::WRONG_VERSION); + NetworkMessage::ErrorManager::ShowError(NetworkMessage::ErrorManager::WRONG_VERSION); break; case Network::RoomMember::Error::HostBanned: - NetworkMessage::ShowError(NetworkMessage::HOST_BANNED); + NetworkMessage::ErrorManager::ShowError(NetworkMessage::ErrorManager::HOST_BANNED); break; case Network::RoomMember::Error::UnknownError: - NetworkMessage::ShowError(NetworkMessage::UNABLE_TO_CONNECT); + NetworkMessage::ErrorManager::ShowError(NetworkMessage::ErrorManager::UNABLE_TO_CONNECT); break; case Network::RoomMember::Error::PermissionDenied: - NetworkMessage::ShowError(NetworkMessage::PERMISSION_DENIED); + NetworkMessage::ErrorManager::ShowError(NetworkMessage::ErrorManager::PERMISSION_DENIED); break; case Network::RoomMember::Error::NoSuchUser: - NetworkMessage::ShowError(NetworkMessage::NO_SUCH_USER); + NetworkMessage::ErrorManager::ShowError(NetworkMessage::ErrorManager::NO_SUCH_USER); break; } } From 7b93b51040f8137546fa9e185dbd727e8b358718 Mon Sep 17 00:00:00 2001 From: tbsp Date: Wed, 1 Apr 2020 08:09:28 -0700 Subject: [PATCH 3/6] Added user IP to log events for join/left/kicked/banned --- src/network/room.cpp | 42 +++++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/src/network/room.cpp b/src/network/room.cpp index e1b6b77d3b..c12ebda5ef 100644 --- a/src/network/room.cpp +++ b/src/network/room.cpp @@ -196,7 +196,7 @@ public: * Sends a system message to all the connected clients. */ void SendStatusMessage(StatusMessageTypes type, const std::string& nickname, - const std::string& username); + const std::string& username, const std::string& ip); /** * Sends the information about the room, along with the list of members @@ -374,6 +374,7 @@ void Room::RoomImpl::HandleJoinRequest(const ENetEvent* event) { } member.user_data = verify_backend->LoadUserData(uid, token); + std::string ip; { std::lock_guard lock(ban_list_mutex); @@ -389,7 +390,7 @@ void Room::RoomImpl::HandleJoinRequest(const ENetEvent* event) { // Check IP ban char ip_raw[256]; enet_address_get_host_ip(&event->peer->address, ip_raw, sizeof(ip_raw) - 1); - std::string ip = ip_raw; + ip = ip_raw; if (std::find(ip_ban_list.begin(), ip_ban_list.end(), ip) != ip_ban_list.end()) { SendUserBanned(event->peer); @@ -398,7 +399,7 @@ void Room::RoomImpl::HandleJoinRequest(const ENetEvent* event) { } // Notify everyone that the user has joined. - SendStatusMessage(IdMemberJoin, member.nickname, member.user_data.username); + SendStatusMessage(IdMemberJoin, member.nickname, member.user_data.username, ip); { std::lock_guard lock(member_mutex); @@ -427,7 +428,7 @@ void Room::RoomImpl::HandleModKickPacket(const ENetEvent* event) { std::string nickname; packet >> nickname; - std::string username; + std::string username, ip; { std::lock_guard lock(member_mutex); const auto target_member = @@ -443,12 +444,16 @@ void Room::RoomImpl::HandleModKickPacket(const ENetEvent* event) { username = target_member->user_data.username; + char ip_raw[256]; + enet_address_get_host_ip(&target_member->peer->address, ip_raw, sizeof(ip_raw) - 1); + ip = ip_raw; + enet_peer_disconnect(target_member->peer, 0); members.erase(target_member); } // Announce the change to all clients. - SendStatusMessage(IdMemberKicked, nickname, username); + SendStatusMessage(IdMemberKicked, nickname, username, ip); BroadcastRoomInformation(); } @@ -465,9 +470,7 @@ void Room::RoomImpl::HandleModBanPacket(const ENetEvent* event) { std::string nickname; packet >> nickname; - std::string username; - std::string ip; - + std::string username, ip; { std::lock_guard lock(member_mutex); const auto target_member = @@ -511,7 +514,7 @@ void Room::RoomImpl::HandleModBanPacket(const ENetEvent* event) { } // Announce the change to all clients. - SendStatusMessage(IdMemberBanned, nickname, username); + SendStatusMessage(IdMemberBanned, nickname, username, ip); BroadcastRoomInformation(); } @@ -546,7 +549,7 @@ void Room::RoomImpl::HandleModUnbanPacket(const ENetEvent* event) { } if (unbanned) { - SendStatusMessage(IdAddressUnbanned, address, ""); + SendStatusMessage(IdAddressUnbanned, address, "", ""); } else { SendModNoSuchUser(event->peer); } @@ -763,7 +766,7 @@ void Room::RoomImpl::SendCloseMessage() { } void Room::RoomImpl::SendStatusMessage(StatusMessageTypes type, const std::string& nickname, - const std::string& username) { + const std::string& username, const std::string& ip) { Packet packet; packet << static_cast(IdStatusMessage); packet << static_cast(type); @@ -784,16 +787,16 @@ void Room::RoomImpl::SendStatusMessage(StatusMessageTypes type, const std::strin switch (type) { case IdMemberJoin: - LOG_INFO(Network, "{} has joined.", display_name); + LOG_INFO(Network, "[{}] {} has joined.", ip, display_name); break; case IdMemberLeave: - LOG_INFO(Network, "{} has left.", display_name); + LOG_INFO(Network, "[{}] {} has left.", ip, display_name); break; case IdMemberKicked: - LOG_INFO(Network, "{} has been kicked.", display_name); + LOG_INFO(Network, "[{}] {} has been kicked.", ip, display_name); break; case IdMemberBanned: - LOG_INFO(Network, "{} has been banned.", display_name); + LOG_INFO(Network, "[{}] {} has been banned.", ip, display_name); break; case IdAddressUnbanned: LOG_INFO(Network, "{} has been unbanned.", display_name); @@ -976,7 +979,7 @@ void Room::RoomImpl::HandleGameNamePacket(const ENetEvent* event) { void Room::RoomImpl::HandleClientDisconnection(ENetPeer* client) { // Remove the client from the members list. - std::string nickname, username; + std::string nickname, username, ip; { std::lock_guard lock(member_mutex); auto member = std::find_if(members.begin(), members.end(), [client](const Member& member) { @@ -985,6 +988,11 @@ void Room::RoomImpl::HandleClientDisconnection(ENetPeer* client) { if (member != members.end()) { nickname = member->nickname; username = member->user_data.username; + + char ip_raw[256]; + enet_address_get_host_ip(&member->peer->address, ip_raw, sizeof(ip_raw) - 1); + ip = ip_raw; + members.erase(member); } } @@ -992,7 +1000,7 @@ void Room::RoomImpl::HandleClientDisconnection(ENetPeer* client) { // Announce the change to all clients. enet_peer_disconnect(client, 0); if (!nickname.empty()) - SendStatusMessage(IdMemberLeave, nickname, username); + SendStatusMessage(IdMemberLeave, nickname, username, ip); BroadcastRoomInformation(); } From eb78fe0c1051f2e60ebb771881b0a86fd77094e7 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Tue, 7 Apr 2020 15:38:24 +0100 Subject: [PATCH 4/6] Revert one change from #4844 This fixes #5067 by reverting a speculative change made in a previous PR. From this one can conclude that, for disabled textures, black (0,0,0,1) is the correct colour and clear (0,0,0,0) is not. --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 862dcac00a..4ac9e36c2a 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -756,7 +756,7 @@ bool RasterizerOpenGL::Draw(bool accelerate, bool is_indexed) { state.texture_units[texture_index].texture_2d = default_texture; } } else { - state.texture_units[texture_index].texture_2d = default_texture; + state.texture_units[texture_index].texture_2d = 0; } } From 263e5be78e63bb4a02df72090c14a118fe374059 Mon Sep 17 00:00:00 2001 From: Valentin Vanelslande Date: Tue, 14 Apr 2020 07:33:49 -0500 Subject: [PATCH 5/6] Fix Luigi's Mansion can't remove amiibo bug (#5200) * Fix Luigi's Mansion can't remove amiibo bug --- src/core/hle/service/nfc/nfc.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/core/hle/service/nfc/nfc.cpp b/src/core/hle/service/nfc/nfc.cpp index 86eb6daeb8..3610b5416a 100644 --- a/src/core/hle/service/nfc/nfc.cpp +++ b/src/core/hle/service/nfc/nfc.cpp @@ -323,10 +323,12 @@ void Module::SyncTagState() { // detected on Scanning->TagInRange? nfc_tag_state = TagState::TagInRange; tag_in_range_event->Signal(); - } else if (!amiibo_in_range && nfc_tag_state == TagState::TagInRange) { - nfc_tag_state = TagState::TagOutOfRange; + } else if (!amiibo_in_range && + (nfc_tag_state == TagState::TagInRange || nfc_tag_state == TagState::TagDataLoaded || + nfc_tag_state == TagState::Unknown6)) { // TODO (wwylele): If a tag is removed during TagDataLoaded/Unknown6, should this event // signals early? + nfc_tag_state = TagState::TagOutOfRange; tag_out_of_range_event->Signal(); } } From 9ae37da292931547c8aa2bdf3829574ec3438542 Mon Sep 17 00:00:00 2001 From: Sebastian Valle Date: Wed, 15 Apr 2020 07:35:19 -0500 Subject: [PATCH 6/6] Kernel/Process: Fixed scheduling multiple processes in the SysCore using Dynarmic (#5193) * Kernel/Process: Notify the CPUs that a new pagetable has been set every time the process they're executing changes. Previously the page table would only be changed when the current CPU's page table was changed, this lead to stale JIT states and the PC going to 0 when context-switching a different core inside the ThreadManager::SwitchContext function because the JIT for a new pagetable is only constructed upon receiving the change notification. * Kernel/Process: Use the relevant CPU's last process to determine when to switch its current process. Previously it was checking the kernel's current_process variable, which gets overwritten every time a CPU runs its slice. The rescheduling happens after all CPUs have run their slice so the code was effectively only checking the last CPU's process. --- src/core/arm/arm_interface.h | 6 +++++- src/core/arm/dynarmic/arm_dynarmic.cpp | 6 +++--- src/core/arm/dynarmic/arm_dynarmic.h | 2 +- src/core/arm/dyncom/arm_dyncom.cpp | 2 +- src/core/arm/dyncom/arm_dyncom.h | 2 +- src/core/hle/kernel/kernel.cpp | 4 +++- src/core/hle/kernel/thread.cpp | 6 +++--- 7 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h index 22443295bb..6595b53c49 100644 --- a/src/core/arm/arm_interface.h +++ b/src/core/arm/arm_interface.h @@ -11,6 +11,10 @@ #include "core/arm/skyeye_common/vfp/asm_vfp.h" #include "core/core_timing.h" +namespace Memory { +struct PageTable; +}; + /// Generic ARM11 CPU interface class ARM_Interface : NonCopyable { public: @@ -73,7 +77,7 @@ public: virtual void InvalidateCacheRange(u32 start_address, std::size_t length) = 0; /// Notify CPU emulation that page tables have changed - virtual void PageTableChanged() = 0; + virtual void PageTableChanged(Memory::PageTable* new_page_table) = 0; /** * Set the Program Counter to an address diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp index 55da53b142..df5de7131b 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic.cpp @@ -153,7 +153,7 @@ ARM_Dynarmic::ARM_Dynarmic(Core::System* system, Memory::MemorySystem& memory, u std::shared_ptr timer) : ARM_Interface(id, timer), system(*system), memory(memory), cb(std::make_unique(*this)) { - PageTableChanged(); + PageTableChanged(memory.GetCurrentPageTable()); } ARM_Dynarmic::~ARM_Dynarmic() = default; @@ -287,8 +287,8 @@ void ARM_Dynarmic::InvalidateCacheRange(u32 start_address, std::size_t length) { jit->InvalidateCacheRange(start_address, length); } -void ARM_Dynarmic::PageTableChanged() { - current_page_table = memory.GetCurrentPageTable(); +void ARM_Dynarmic::PageTableChanged(Memory::PageTable* new_page_table) { + current_page_table = new_page_table; auto iter = jits.find(current_page_table); if (iter != jits.end()) { diff --git a/src/core/arm/dynarmic/arm_dynarmic.h b/src/core/arm/dynarmic/arm_dynarmic.h index c403f438e4..44f2ee3751 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.h +++ b/src/core/arm/dynarmic/arm_dynarmic.h @@ -52,7 +52,7 @@ public: void ClearInstructionCache() override; void InvalidateCacheRange(u32 start_address, std::size_t length) override; - void PageTableChanged() override; + void PageTableChanged(Memory::PageTable* new_page_table) override; private: void ServeBreak(); diff --git a/src/core/arm/dyncom/arm_dyncom.cpp b/src/core/arm/dyncom/arm_dyncom.cpp index fa1aa598db..c2c291df01 100644 --- a/src/core/arm/dyncom/arm_dyncom.cpp +++ b/src/core/arm/dyncom/arm_dyncom.cpp @@ -95,7 +95,7 @@ void ARM_DynCom::InvalidateCacheRange(u32, std::size_t) { ClearInstructionCache(); } -void ARM_DynCom::PageTableChanged() { +void ARM_DynCom::PageTableChanged(Memory::PageTable*) { ClearInstructionCache(); } diff --git a/src/core/arm/dyncom/arm_dyncom.h b/src/core/arm/dyncom/arm_dyncom.h index f5360b3075..38659eac0a 100644 --- a/src/core/arm/dyncom/arm_dyncom.h +++ b/src/core/arm/dyncom/arm_dyncom.h @@ -30,7 +30,7 @@ public: void ClearInstructionCache() override; void InvalidateCacheRange(u32 start_address, std::size_t length) override; - void PageTableChanged() override; + void PageTableChanged(Memory::PageTable* new_page_table) override; void SetPC(u32 pc) override; u32 GetPC() const override; diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 995cfc6582..8b2d89ead8 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -67,13 +67,15 @@ void KernelSystem::SetCurrentProcessForCPU(std::shared_ptr process, u32 SetCurrentMemoryPageTable(&process->vm_manager.page_table); } else { stored_processes[core_id] = process; + thread_managers[core_id]->cpu->PageTableChanged(&process->vm_manager.page_table); } } void KernelSystem::SetCurrentMemoryPageTable(Memory::PageTable* page_table) { memory.SetCurrentPageTable(page_table); if (current_cpu != nullptr) { - current_cpu->PageTableChanged(); // notify the CPU the page table in memory has changed + // Notify the CPU the page table in memory has changed + current_cpu->PageTableChanged(page_table); } } diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index c86a0fb86d..b2255c2265 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -75,11 +75,13 @@ void Thread::Stop() { void ThreadManager::SwitchContext(Thread* new_thread) { Thread* previous_thread = GetCurrentThread(); + Process* previous_process = nullptr; Core::Timing& timing = kernel.timing; // Save context for previous thread if (previous_thread) { + previous_process = previous_thread->owner_process; previous_thread->last_running_ticks = timing.GetGlobalTicks(); cpu->SaveContext(previous_thread->context); @@ -99,14 +101,12 @@ void ThreadManager::SwitchContext(Thread* new_thread) { // Cancel any outstanding wakeup events for this thread timing.UnscheduleEvent(ThreadWakeupEventType, new_thread->thread_id); - auto previous_process = kernel.GetCurrentProcess(); - current_thread = SharedFrom(new_thread); ready_queue.remove(new_thread->current_priority, new_thread); new_thread->status = ThreadStatus::Running; - if (previous_process.get() != current_thread->owner_process) { + if (previous_process != current_thread->owner_process) { kernel.SetCurrentProcessForCPU(SharedFrom(current_thread->owner_process), cpu->GetID()); }