network/room_member: Add moderation functions

To allow for passing moderation errors around without impacting the State, this commit also separates the previous State enum into two enums: State, and Error. The State enum now only contains generic states like disconnected or connected, and the Error enum describes the specific error happened.

citra_qt/multiplayer/{state, message} is changed accordingly.
This commit is contained in:
zhupengfei
2018-11-24 16:13:46 +08:00
parent 38f86cce94
commit 7acd2664dd
6 changed files with 251 additions and 56 deletions

View File

@@ -36,11 +36,16 @@ const ConnectionError WRONG_PASSWORD(QT_TR_NOOP("Incorrect password."));
const ConnectionError 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(
QT_TR_NOOP("MAC address is already in use. Please choose another."));
const ConnectionError 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(
QT_TR_NOOP("You do not have enough permission to perform this action."));
const ConnectionError 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) {
return QMessageBox::Ok == QMessageBox::warning(nullptr, QObject::tr(title.c_str()),

View File

@@ -36,8 +36,11 @@ 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

View File

@@ -27,9 +27,13 @@ MultiplayerState::MultiplayerState(QWidget* parent, QStandardItemModel* game_lis
[this](const Network::RoomMember::State& state) { emit NetworkStateChanged(state); });
connect(this, &MultiplayerState::NetworkStateChanged, this,
&MultiplayerState::OnNetworkStateChanged);
error_callback_handle = member->BindOnError(
[this](const Network::RoomMember::Error& error) { emit NetworkError(error); });
connect(this, &MultiplayerState::NetworkError, this, &MultiplayerState::OnNetworkError);
}
qRegisterMetaType<Network::RoomMember::State>();
qRegisterMetaType<Network::RoomMember::Error>();
qRegisterMetaType<Common::WebResult>();
announce_multiplayer_session = std::make_shared<Core::AnnounceMultiplayerSession>();
announce_multiplayer_session->BindErrorCallback(
@@ -52,6 +56,12 @@ MultiplayerState::~MultiplayerState() {
member->Unbind(state_callback_handle);
}
}
if (error_callback_handle) {
if (auto member = Network::GetRoomMember().lock()) {
member->Unbind(error_callback_handle);
}
}
}
void MultiplayerState::Close() {
@@ -88,41 +98,8 @@ void MultiplayerState::retranslateUi() {
void MultiplayerState::OnNetworkStateChanged(const Network::RoomMember::State& state) {
LOG_DEBUG(Frontend, "Network State: {}", Network::GetStateStr(state));
bool is_connected = false;
switch (state) {
case Network::RoomMember::State::LostConnection:
NetworkMessage::ShowError(NetworkMessage::LOST_CONNECTION);
break;
case Network::RoomMember::State::CouldNotConnect:
NetworkMessage::ShowError(NetworkMessage::UNABLE_TO_CONNECT);
break;
case Network::RoomMember::State::NameCollision:
NetworkMessage::ShowError(NetworkMessage::USERNAME_NOT_VALID_SERVER);
break;
case Network::RoomMember::State::MacCollision:
NetworkMessage::ShowError(NetworkMessage::MAC_COLLISION);
break;
case Network::RoomMember::State::ConsoleIdCollision:
NetworkMessage::ShowError(NetworkMessage::CONSOLE_ID_COLLISION);
break;
case Network::RoomMember::State::RoomIsFull:
NetworkMessage::ShowError(NetworkMessage::ROOM_IS_FULL);
break;
case Network::RoomMember::State::WrongPassword:
NetworkMessage::ShowError(NetworkMessage::WRONG_PASSWORD);
break;
case Network::RoomMember::State::WrongVersion:
NetworkMessage::ShowError(NetworkMessage::WRONG_VERSION);
break;
case Network::RoomMember::State::Error:
NetworkMessage::ShowError(NetworkMessage::UNABLE_TO_CONNECT);
break;
case Network::RoomMember::State::Joined:
is_connected = true;
if (state == Network::RoomMember::State::Joined) {
OnOpenNetworkRoom();
break;
}
if (is_connected) {
status_icon->setPixmap(QIcon::fromTheme("connected").pixmap(16));
status_text->setText(tr("Connected"));
leave_room->setEnabled(true);
@@ -137,6 +114,51 @@ void MultiplayerState::OnNetworkStateChanged(const Network::RoomMember::State& s
current_state = state;
}
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);
break;
case Network::RoomMember::Error::HostKicked:
NetworkMessage::ShowError(NetworkMessage::HOST_KICKED);
break;
case Network::RoomMember::Error::CouldNotConnect:
NetworkMessage::ShowError(NetworkMessage::UNABLE_TO_CONNECT);
break;
case Network::RoomMember::Error::NameCollision:
NetworkMessage::ShowError(NetworkMessage::USERNAME_NOT_VALID_SERVER);
break;
case Network::RoomMember::Error::MacCollision:
NetworkMessage::ShowError(NetworkMessage::MAC_COLLISION);
break;
case Network::RoomMember::Error::ConsoleIdCollision:
NetworkMessage::ShowError(NetworkMessage::CONSOLE_ID_COLLISION);
break;
case Network::RoomMember::Error::RoomIsFull:
NetworkMessage::ShowError(NetworkMessage::ROOM_IS_FULL);
break;
case Network::RoomMember::Error::WrongPassword:
NetworkMessage::ShowError(NetworkMessage::WRONG_PASSWORD);
break;
case Network::RoomMember::Error::WrongVersion:
NetworkMessage::ShowError(NetworkMessage::WRONG_VERSION);
break;
case Network::RoomMember::Error::HostBanned:
NetworkMessage::ShowError(NetworkMessage::HOST_BANNED);
break;
case Network::RoomMember::Error::UnknownError:
NetworkMessage::ShowError(NetworkMessage::UNABLE_TO_CONNECT);
break;
case Network::RoomMember::Error::PermissionDenied:
NetworkMessage::ShowError(NetworkMessage::PERMISSION_DENIED);
break;
case Network::RoomMember::Error::NoSuchUser:
NetworkMessage::ShowError(NetworkMessage::NO_SUCH_USER);
break;
}
}
void MultiplayerState::OnAnnounceFailed(const Common::WebResult& result) {
announce_multiplayer_session->Stop();
QMessageBox::warning(

View File

@@ -40,6 +40,7 @@ public:
public slots:
void OnNetworkStateChanged(const Network::RoomMember::State& state);
void OnNetworkError(const Network::RoomMember::Error& error);
void OnViewLobby();
void OnCreateRoom();
bool OnCloseRoom();
@@ -50,6 +51,7 @@ public slots:
signals:
void NetworkStateChanged(const Network::RoomMember::State&);
void NetworkError(const Network::RoomMember::Error&);
void AnnounceFailed(const Common::WebResult&);
private:
@@ -65,6 +67,7 @@ private:
std::shared_ptr<Core::AnnounceMultiplayerSession> announce_multiplayer_session;
Network::RoomMember::State current_state = Network::RoomMember::State::Uninitialized;
Network::RoomMember::CallbackHandle<Network::RoomMember::State> state_callback_handle;
Network::RoomMember::CallbackHandle<Network::RoomMember::Error> error_callback_handle;
};
Q_DECLARE_METATYPE(Common::WebResult);