/**
   * Sends the server mod list to the client, or stores it for sending later.
   *
   * @param modList The {@link PluginMessage} to send to the client containing the mod list.
   * @throws IllegalArgumentException Thrown if the {@link PluginMessage} was not as expected.
   */
  public void setServerModList(PluginMessage modList) throws IllegalArgumentException {
    if (!modList.getTag().equalsIgnoreCase(ForgeConstants.FML_HANDSHAKE_TAG)
        || modList.getData()[0] != 2) {
      throw new IllegalArgumentException("modList");
    }

    this.serverModList = modList;
  }
  /**
   * Handles the Forge packet.
   *
   * @param message The Forge Handshake packet to handle.
   */
  public void handle(PluginMessage message) throws IllegalArgumentException {
    if (!message.getTag().equalsIgnoreCase(ForgeConstants.FML_HANDSHAKE_TAG)) {
      throw new IllegalArgumentException("Expecting a Forge Handshake packet.");
    }

    message.setAllowExtendedPacket(true); // FML allows extended packets so this must be enabled
    ForgeClientHandshakeState prevState = state;
    packetQueue.add(message);
    state = state.send(message, con);
    if (state != prevState) // state finished, send packets
    {
      synchronized (packetQueue) {
        while (!packetQueue.isEmpty()) {
          ForgeLogger.logClient(
              ForgeLogger.LogDirection.SENDING, prevState.name(), packetQueue.getFirst());
          con.getForgeServerHandler().receive(packetQueue.removeFirst());
        }
      }
    }
  }
  @Override
  public void handle(PluginMessage pluginMessage) throws Exception {
    if (pluginMessage.getTag().equals("BungeeCord")) {
      throw new CancelSendSignal();
    }
    // Hack around Forge race conditions
    if (pluginMessage.getTag().equals("FML") && pluginMessage.getStream().readUnsignedByte() == 1) {
      throw new CancelSendSignal();
    }

    PluginMessageEvent event =
        new PluginMessageEvent(
            con, con.getServer(), pluginMessage.getTag(), pluginMessage.getData().clone());
    if (bungee.getPluginManager().callEvent(event).isCancelled()) {
      throw new CancelSendSignal();
    }

    // TODO: Unregister as well?
    if (pluginMessage.getTag().equals("REGISTER")) {
      con.getPendingConnection().getRegisterMessages().add(pluginMessage);
    }
  }