What is the proper way to send an RPC to every entity in a query?

What is the proper way to send an RPC to every entity in a query?
My code example is the iteration over all entities that had a connection state change occurrence, though my question need not apply to that in particular.

//================================================================
  [BurstCompile]
  public void OnUpdate(ref SystemState state)
  {
    var ecb = new EntityCommandBuffer(Allocator.Temp);
    foreach (var (connectionState, connectedEntity) in SystemAPI.Query<ConnectionState>().WithEntityAccess()) {
      bool isPlayer = SystemAPI.HasComponent<PlayerComponent>(connectedEntity);    
      bool isAdmin = SystemAPI.HasComponent<AdminComponent>(connectedEntity);
      bool isGameMaster = SystemAPI.HasComponent<GameMasterComponent>(connectedEntity);
      PlayerInfoComponent playerInfo = SystemAPI.GetComponent<PlayerInfoComponent>(connectedEntity);

      var sendLocalizedTextMessageEntity = ecb.CreateEntity();
      LocalizableTextMessageRPC message = get_localizable_text_message(playerInfo, connectionState);
      ecb.AddComponent(sendLocalizedTextMessageEntity, message);

      ecb.AddComponent(sendLocalizedTextMessageEntity, new SendRpcCommandRequest {       
        TargetConnection = m_AdminQuery
      });
      if (isPlayer || isGameMaster) {
        ecb.AddComponent(sendLocalizedTextMessageEntity, new SendRpcCommandRequest {
          TargetConnection = m_GameMasterQuery
        });
      }

      if (connectionState.CurrentState == ConnectionState.State.Connected) {
        Debug.Log($"NetworkId: {connectionState.NetworkId} {connectionState.CurrentState.ToFixedString()}");
      
      }    
      if (connectionState.CurrentState == ConnectionState.State.Disconnected) {
        Debug.Log($"NetworkId: {connectionState.NetworkId} {connectionState.CurrentState.ToFixedString()} Reason: {connectionState.DisconnectReason.ToFixedString()}");
      
        //clean up
        ecb.RemoveComponent<ConnectionState>(connectedEntity);
        if (isAdmin) {
          ecb.RemoveComponent<AdminComponent>(connectedEntity);
        }
        if (isGameMaster) {
          ecb.RemoveComponent<GameMasterComponent>(connectedEntity);
        }
        if (isPlayer) {
          ecb.RemoveComponent<PlayerComponent>(connectedEntity);
        }
        ecb.RemoveComponent<PlayerInfoComponent>(connectedEntity);
      }    
    }
    ecb.Playback(state.EntityManager);
  }

Obviously, assigning a query to TargetConnection isn’t going to work. Normally I’d send to a single Entity in that spot. Is there a cleaner (more code compact way, or method I didn’t notice) way to specify a query’s worth of entities as the target connection? Or will I have to iterate over every entity in the query and target each one explicitly? (The m_AdminQuery and m_GameMasterQuety are all connected entities that have the Admin and GameMasterComponent tags respectively. This will presumably result in sending the rpc to itself also, preferably I’d not send the message to itself, but I don’t really care if it does.)

Hey!

You’ll need to iterate over each yeah.

Also: 1.2 exposed the NetCodeConnectionEvent API, so you can slightly simplify this code by no longer having to add and remove the optional ConnectionState component. Example:

       foreach (var evt in SystemAPI.GetSingleton<NetworkStreamDriver>().ConnectionEventsForTick)
       {
            UnityEngine.Debug.Log($"[{state.WorldUnmanaged.Name}] {evt.Id.ToFixedString()} entered state {evt.State.ToFixedString()}");
            switch (evt.State)
            {
                case ConnectionState.State.Connected:
                    // Do whatever.
                    break;
                case ConnectionState.State.Disconnected:
                    // Do whatever.
                    break;
            }
       }

We made sure the evt field contains the same information you’d like to be fetching manually, which may save a few lines of code too.

EDIT: Just discovered that more changelog entries were not added correctly to 1.2, so this new feature is missing an entry.

In what ways would converting over to the ConnectionEventsForTick require updating/changing the original OnCreate and RequireForUpdate filtering?

//================================================================
  [BurstCompile]
  public void OnCreate(ref SystemState state)
  {
    m_AdminQuery = state.GetEntityQuery(ComponentType.ReadOnly<AdminComponent>());
    m_GameMasterQuery = state.GetEntityQuery(ComponentType.ReadOnly<GameMasterComponent>());
    var builder = new EntityQueryBuilder(Allocator.Temp).WithAll<ConnectionState>();
    EntityQuery connectionStateChangeQuery = state.GetEntityQuery(builder);
    connectionStateChangeQuery.AddChangedVersionFilter(ComponentType.ReadOnly<ConnectionState>());
    state.RequireForUpdate(connectionStateChangeQuery);
  }