| 
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -296,14 +296,14 @@
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						/**
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						 * Sort Community rooms in-place by their server's public key.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						 * @param CommunityRoom[] $rooms Rooms to sort by server pubkey.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						 * Sort Community rooms in-place by their server.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						 * @param CommunityRoom[] $rooms Rooms to sort by server.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						 */
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						public static function sort_rooms_by_pubkey(array &$rooms) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						public static function sort_rooms_by_server(array &$rooms) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							usort($rooms, function(CommunityRoom $a, CommunityRoom $b) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								return strcmp(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									$a->server->get_pubkey(),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									$b->server->get_pubkey()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									$a->server->get_pubkey() . $a->server->get_hostname(),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									$b->server->get_pubkey() . $b->server->get_hostname()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							});
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -493,7 +493,7 @@
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						 * @param string $matchee String matching room. Output parameter.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						 * @return bool True if the array matches the Community, false otherwise.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						 */
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						public function matched_by_list(array $filter, string &$matchee): bool {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						public function matched_by_list(array $filter, string &$matchee = null): bool {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							foreach ($filter as $filter_item) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								if ($this->matched_by_identifier($filter_item)) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									$matchee = $filter_item;
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -510,7 +510,7 @@
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						 * @param string[] $matchees output parameter
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						 * @return CommunityRoom[]
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						 */
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						public static function select_rooms(array $rooms, array|string $filter, array &$matchees): array {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						public static function select_rooms(array $rooms, array|string $filter, array &$matchees = null): array {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							$_matchees = [];
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							$rooms = array_values(array_filter($rooms, function(CommunityRoom $room) use ($filter, $_matchees) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								$matchee = null;
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -687,10 +687,10 @@
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						case SameHostname;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						/**
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						 * @var SamePublicKey
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						 * Strategy considering two servers to be identical if they share a SOGS public key.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						 * @var SameData
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						 * Strategy considering two servers to be identical if they share a SOGS public key and room data.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						 */
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						case SamePublicKey;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						case SameData;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						/**
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						 * Determine whether two CommunityServer instances are identical under the given criteria.
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -700,8 +700,11 @@
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						 */
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						public function should_merge_servers(CommunityServer $a, CommunityServer $b): bool {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							return match ($this) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								CommunityServerMergeStrategy::SameHostname => $a->get_hostname() == $b->get_hostname(),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								CommunityServerMergeStrategy::SamePublicKey => $a->get_pubkey() == $b->get_pubkey()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								CommunityServerMergeStrategy::SameHostname =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									$a->get_hostname() == $b->get_hostname(),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								CommunityServerMergeStrategy::SameData =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									$a->get_pubkey() == $b->get_pubkey() &&
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									CommunityServer::rooms_in_common($a, $b)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							};
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -801,6 +804,27 @@
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							usort($servers, 'CommunityServer::compare_by_pubkey');
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						/**
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						 * Return true whether the two servers given share a room.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						 */
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						public static function rooms_in_common(CommunityServer $a, CommunityServer $b): bool {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							// Rely on at least token or creation date differing.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							// Do not strictly compare room lists because the servers
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							// may have been polled at different times.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							$room_date_pairs = [];
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							$rooms = CommunityServer::enumerate_rooms([$a, $b]);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							foreach ($rooms as $room) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								$room_date_pairs[] = $room->token . "+" . $room->created;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							if (count(array_unique($room_date_pairs)) < count($rooms)) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								return true;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							return false;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						/**
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						 * Absorb candidates for the SOGS public key from a duplicate server instance.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						 */
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -830,7 +854,7 @@
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									exit(1);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								$this->merge_pubkeys_from($server);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							} else if ($strategy == CommunityServerMergeStrategy::SamePublicKey) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							} else if ($strategy == CommunityServerMergeStrategy::SameData) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								if ($this->get_pubkey() != $server->get_pubkey()) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									log_error("SamePublicKey merging: Merged servers differ in public key");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									exit(1);
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -919,10 +943,10 @@
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						 * @param CommunityServer[] $servers Servers to merge by public key.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						 * @return CommunityServer[] Servers merged by public key-
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						 */
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						public static function dedupe_by_pubkey($servers) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						public static function dedupe_by_data($servers) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							CommunityServer::sort_by_pubkey($servers);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							CommunityServer::merge_by($servers, CommunityServerMergeStrategy::SamePublicKey);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							CommunityServer::merge_by($servers, CommunityServerMergeStrategy::SameData);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							$servers = CommunityServer::ensure_merge_consistency($servers);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
				
			
			 | 
			 | 
			
				
 
 |