Multiplayer: Send an error message when connecting to a full room

This commit is contained in:
James Rowe 2018-04-20 01:34:37 -06:00 committed by zhupengfei
parent a9c9ffd32c
commit e040bc9355
No known key found for this signature in database
GPG key ID: DD129E108BD09378
7 changed files with 42 additions and 7 deletions

View file

@ -22,6 +22,8 @@ const ConnectionError UNABLE_TO_CONNECT(
QT_TR_NOOP("Unable to connect to the host. Verify that the connection settings are correct. If " 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 " "you still cannot connect, contact the room host and verify that the host is "
"properly configured with the external port forwarded.")); "properly configured with the external port forwarded."));
const ConnectionError 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 COULD_NOT_CREATE_ROOM(
QT_TR_NOOP("Creating a room failed. Please retry. Restarting Citra might be necessary.")); QT_TR_NOOP("Creating a room failed. Please retry. Restarting Citra might be necessary."));
const ConnectionError HOST_BANNED( const ConnectionError HOST_BANNED(

View file

@ -27,6 +27,7 @@ extern const ConnectionError IP_ADDRESS_NOT_VALID;
extern const ConnectionError PORT_NOT_VALID; extern const ConnectionError PORT_NOT_VALID;
extern const ConnectionError NO_INTERNET; extern const ConnectionError NO_INTERNET;
extern const ConnectionError UNABLE_TO_CONNECT; extern const ConnectionError UNABLE_TO_CONNECT;
extern const ConnectionError ROOM_IS_FULL;
extern const ConnectionError COULD_NOT_CREATE_ROOM; extern const ConnectionError COULD_NOT_CREATE_ROOM;
extern const ConnectionError HOST_BANNED; extern const ConnectionError HOST_BANNED;
extern const ConnectionError WRONG_VERSION; extern const ConnectionError WRONG_VERSION;

View file

@ -102,6 +102,9 @@ void MultiplayerState::OnNetworkStateChanged(const Network::RoomMember::State& s
case Network::RoomMember::State::MacCollision: case Network::RoomMember::State::MacCollision:
NetworkMessage::ShowError(NetworkMessage::MAC_COLLISION); NetworkMessage::ShowError(NetworkMessage::MAC_COLLISION);
break; break;
case Network::RoomMember::State::RoomIsFull:
NetworkMessage::ShowError(NetworkMessage::ROOM_IS_FULL);
break;
case Network::RoomMember::State::WrongPassword: case Network::RoomMember::State::WrongPassword:
NetworkMessage::ShowError(NetworkMessage::WRONG_PASSWORD); NetworkMessage::ShowError(NetworkMessage::WRONG_PASSWORD);
break; break;

View file

@ -68,6 +68,11 @@ public:
*/ */
bool IsValidMacAddress(const MacAddress& address) const; bool IsValidMacAddress(const MacAddress& address) const;
/**
* Sends a ID_ROOM_IS_FULL message telling the client that the room is full.
*/
void SendRoomIsFull(ENetPeer* client);
/** /**
* Sends a ID_ROOM_NAME_COLLISION message telling the client that the name is invalid. * Sends a ID_ROOM_NAME_COLLISION message telling the client that the name is invalid.
*/ */
@ -193,6 +198,13 @@ void Room::RoomImpl::StartLoop() {
} }
void Room::RoomImpl::HandleJoinRequest(const ENetEvent* event) { void Room::RoomImpl::HandleJoinRequest(const ENetEvent* event) {
{
std::lock_guard<std::mutex> lock(member_mutex);
if (members.size() >= room_information.member_slots) {
SendRoomIsFull(event->peer);
return;
}
}
Packet packet; Packet packet;
packet.Append(event->packet->data, event->packet->dataLength); packet.Append(event->packet->data, event->packet->dataLength);
packet.IgnoreBytes(sizeof(u8)); // Ignore the message type packet.IgnoreBytes(sizeof(u8)); // Ignore the message type
@ -295,6 +307,16 @@ void Room::RoomImpl::SendWrongPassword(ENetPeer* client) {
enet_host_flush(server); enet_host_flush(server);
} }
void Room::RoomImpl::SendRoomIsFull(ENetPeer* client) {
Packet packet;
packet << static_cast<u8>(IdRoomIsFull);
ENetPacket* enet_packet =
enet_packet_create(packet.GetData(), packet.GetDataSize(), ENET_PACKET_FLAG_RELIABLE);
enet_peer_send(client, 0, enet_packet);
enet_host_flush(server);
}
void Room::RoomImpl::SendVersionMismatch(ENetPeer* client) { void Room::RoomImpl::SendVersionMismatch(ENetPeer* client) {
Packet packet; Packet packet;
packet << static_cast<u8>(IdVersionMismatch); packet << static_cast<u8>(IdVersionMismatch);
@ -527,7 +549,9 @@ bool Room::Create(const std::string& name, const std::string& server_address, u1
} }
address.port = server_port; address.port = server_port;
room_impl->server = enet_host_create(&address, max_connections, NumChannels, 0, 0); // In order to send the room is full message to the connecting client, we need to leave one slot
// open so enet won't reject the incoming connection without telling us
room_impl->server = enet_host_create(&address, max_connections + 1, NumChannels, 0, 0);
if (!room_impl->server) { if (!room_impl->server) {
return false; return false;
} }

View file

@ -57,7 +57,8 @@ enum RoomMessageTypes : u8 {
IdMacCollision, IdMacCollision,
IdVersionMismatch, IdVersionMismatch,
IdWrongPassword, IdWrongPassword,
IdCloseRoom IdCloseRoom,
IdRoomIsFull,
}; };
/// This is what a server [person creating a server] would use. /// This is what a server [person creating a server] would use.

View file

@ -154,6 +154,9 @@ void RoomMember::RoomMemberImpl::MemberLoop() {
HandleJoinPacket(&event); // Get the MAC Address for the client HandleJoinPacket(&event); // Get the MAC Address for the client
SetState(State::Joined); SetState(State::Joined);
break; break;
case IdRoomIsFull:
SetState(State::RoomIsFull);
break;
case IdNameCollision: case IdNameCollision:
SetState(State::NameCollision); SetState(State::NameCollision);
break; break;

View file

@ -58,7 +58,8 @@ public:
MacCollision, ///< Somebody is already using that mac-address MacCollision, ///< Somebody is already using that mac-address
WrongVersion, ///< The room version is not the same as for this RoomMember WrongVersion, ///< The room version is not the same as for this RoomMember
WrongPassword, ///< The password doesn't match the one from the Room WrongPassword, ///< The password doesn't match the one from the Room
CouldNotConnect ///< The room is not responding to a connection attempt CouldNotConnect, ///< The room is not responding to a connection attempt
RoomIsFull ///< Room is already at the maximum number of players
}; };
struct MemberInformation { struct MemberInformation {