mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	network, citra_qt: Give moderation permission to community mods
Based on the `roles` payload in the JWT, the rooms will now give mod permission to Citra Community Moderators. To notify the client of its permissions, a new response, IdJoinSuccessAsMod is added, and there's now a new RoomMember::State called Moderator.
This commit is contained in:
		
							parent
							
								
									94be4050bc
								
							
						
					
					
						commit
						9d062d63da
					
				
					 15 changed files with 73 additions and 27 deletions
				
			
		|  | @ -155,6 +155,12 @@ public: | |||
|      */ | ||||
|     void SendJoinSuccess(ENetPeer* client, MacAddress mac_address); | ||||
| 
 | ||||
|     /**
 | ||||
|      * Notifies the member that its connection attempt was successful, | ||||
|      * and it is now part of the room, and it has been granted mod permissions. | ||||
|      */ | ||||
|     void SendJoinSuccessAsMod(ENetPeer* client, MacAddress mac_address); | ||||
| 
 | ||||
|     /**
 | ||||
|      * Sends a IdHostKicked message telling the client that they have been kicked. | ||||
|      */ | ||||
|  | @ -401,7 +407,11 @@ void Room::RoomImpl::HandleJoinRequest(const ENetEvent* event) { | |||
| 
 | ||||
|     // Notify everyone that the room information has changed.
 | ||||
|     BroadcastRoomInformation(); | ||||
|     SendJoinSuccess(event->peer, preferred_mac); | ||||
|     if (HasModPermission(event->peer)) { | ||||
|         SendJoinSuccessAsMod(event->peer, preferred_mac); | ||||
|     } else { | ||||
|         SendJoinSuccess(event->peer, preferred_mac); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void Room::RoomImpl::HandleModKickPacket(const ENetEvent* event) { | ||||
|  | @ -588,10 +598,11 @@ bool Room::RoomImpl::HasModPermission(const ENetPeer* client) const { | |||
|     if (sending_member == members.end()) { | ||||
|         return false; | ||||
|     } | ||||
|     if (sending_member->user_data.username != room_information.host_username) { | ||||
|         return false; | ||||
|     } | ||||
|     return true; | ||||
|     if (sending_member->user_data.moderator) // Community moderator
 | ||||
|         return true; | ||||
|     if (sending_member->user_data.username == room_information.host_username) // Room host
 | ||||
|         return true; | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| void Room::RoomImpl::SendNameCollision(ENetPeer* client) { | ||||
|  | @ -665,6 +676,16 @@ void Room::RoomImpl::SendJoinSuccess(ENetPeer* client, MacAddress mac_address) { | |||
|     enet_host_flush(server); | ||||
| } | ||||
| 
 | ||||
| void Room::RoomImpl::SendJoinSuccessAsMod(ENetPeer* client, MacAddress mac_address) { | ||||
|     Packet packet; | ||||
|     packet << static_cast<u8>(IdJoinSuccessAsMod); | ||||
|     packet << mac_address; | ||||
|     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::SendUserKicked(ENetPeer* client) { | ||||
|     Packet packet; | ||||
|     packet << static_cast<u8>(IdHostKicked); | ||||
|  |  | |||
|  | @ -74,6 +74,7 @@ enum RoomMessageTypes : u8 { | |||
|     IdModBanListResponse, | ||||
|     IdModPermissionDenied, | ||||
|     IdModNoSuchUser, | ||||
|     IdJoinSuccessAsMod, | ||||
| }; | ||||
| 
 | ||||
| /// Types of system status messages
 | ||||
|  |  | |||
|  | @ -151,7 +151,7 @@ void RoomMember::RoomMemberImpl::SetError(const Error new_error) { | |||
| } | ||||
| 
 | ||||
| bool RoomMember::RoomMemberImpl::IsConnected() const { | ||||
|     return state == State::Joining || state == State::Joined; | ||||
|     return state == State::Joining || state == State::Joined || state == State::Moderator; | ||||
| } | ||||
| 
 | ||||
| void RoomMember::RoomMemberImpl::MemberLoop() { | ||||
|  | @ -176,12 +176,17 @@ void RoomMember::RoomMemberImpl::MemberLoop() { | |||
|                     HandleRoomInformationPacket(&event); | ||||
|                     break; | ||||
|                 case IdJoinSuccess: | ||||
|                 case IdJoinSuccessAsMod: | ||||
|                     // The join request was successful, we are now in the room.
 | ||||
|                     // If we joined successfully, there must be at least one client in the room: us.
 | ||||
|                     ASSERT_MSG(member_information.size() > 0, | ||||
|                                "We have not yet received member information."); | ||||
|                     HandleJoinPacket(&event); // Get the MAC Address for the client
 | ||||
|                     SetState(State::Joined); | ||||
|                     if (event.packet->data[0] == IdJoinSuccessAsMod) { | ||||
|                         SetState(State::Moderator); | ||||
|                     } else { | ||||
|                         SetState(State::Joined); | ||||
|                     } | ||||
|                     break; | ||||
|                 case IdModBanListResponse: | ||||
|                     HandleModBanListResponsePacket(&event); | ||||
|  | @ -232,7 +237,7 @@ void RoomMember::RoomMemberImpl::MemberLoop() { | |||
|                 enet_packet_destroy(event.packet); | ||||
|                 break; | ||||
|             case ENET_EVENT_TYPE_DISCONNECT: | ||||
|                 if (state == State::Joined) { | ||||
|                 if (state == State::Joined || state == State::Moderator) { | ||||
|                     SetState(State::Idle); | ||||
|                     SetError(Error::LostConnection); | ||||
|                 } | ||||
|  | @ -331,7 +336,6 @@ void RoomMember::RoomMemberImpl::HandleJoinPacket(const ENetEvent* event) { | |||
| 
 | ||||
|     // Parse the MAC Address from the packet
 | ||||
|     packet >> mac_address; | ||||
|     SetState(State::Joined); | ||||
| } | ||||
| 
 | ||||
| void RoomMember::RoomMemberImpl::HandleWifiPackets(const ENetEvent* event) { | ||||
|  |  | |||
|  | @ -59,7 +59,8 @@ public: | |||
|         Uninitialized, ///< Not initialized
 | ||||
|         Idle,          ///< Default state (i.e. not connected)
 | ||||
|         Joining,       ///< The client is attempting to join a room.
 | ||||
|         Joined, ///< The client is connected to the room and is ready to send/receive packets.
 | ||||
|         Joined,    ///< The client is connected to the room and is ready to send/receive packets.
 | ||||
|         Moderator, ///< The client is connnected to the room and is granted mod permissions.
 | ||||
|     }; | ||||
| 
 | ||||
|     enum class Error : u8 { | ||||
|  | @ -270,6 +271,8 @@ static const char* GetStateStr(const RoomMember::State& s) { | |||
|         return "Joining"; | ||||
|     case RoomMember::State::Joined: | ||||
|         return "Joined"; | ||||
|     case RoomMember::State::Moderator: | ||||
|         return "Moderator"; | ||||
|     } | ||||
|     return "Unknown"; | ||||
| } | ||||
|  |  | |||
|  | @ -13,6 +13,7 @@ struct UserData { | |||
|     std::string username; | ||||
|     std::string display_name; | ||||
|     std::string avatar_url; | ||||
|     bool moderator = false; ///< Whether the user is a Citra Moderator.
 | ||||
| }; | ||||
| 
 | ||||
| /**
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue