/** Sends an out-of-band datagram */
  public static void Netchan_OutOfBand(
      int net_socket, NetworkAddress adr, int length, byte data[]) {

    // write the packet header
    Buffer send = Buffer.allocate(Constants.MAX_MSGLEN);

    send.putInt(-1); // -1 sequence means out of band
    Buffers.Write(send, data, length);

    // send the datagram
    NET.SendPacket(net_socket, send.cursize, send.data, adr);
  }
  /**
   * tries to send an unreliable message to a connection, and handles the transmition /
   * retransmition of the reliable messages.
   *
   * <p>A 0 length will still generate a packet and deal with the reliable messages.
   */
  public static void Transmit(NetworkChannel chan, int length, byte data[]) {
    int send_reliable;
    int w1, w2;

    // check for message overflow
    if (chan.message.overflowed) {
      chan.fatal_error = true;
      Com.Printf(NET.AdrToString(chan.remote_address) + ":Outgoing message overflow\n");
      return;
    }

    send_reliable = chan.Netchan_NeedReliable() ? 1 : 0;

    if (chan.reliable_length == 0 && chan.message.cursize != 0) {
      System.arraycopy(chan.message_buf, 0, chan.reliable_buf, 0, chan.message.cursize);
      chan.reliable_length = chan.message.cursize;
      chan.message.cursize = 0;
      chan.reliable_sequence ^= 1;
    }

    // write the packet header
    Buffer send = Buffer.wrap(send_buf).order(ByteOrder.LITTLE_ENDIAN);

    w1 = (chan.outgoing_sequence & ~(1 << 31)) | (send_reliable << 31);
    w2 = (chan.incoming_sequence & ~(1 << 31)) | (chan.incoming_reliable_sequence << 31);

    chan.outgoing_sequence++;
    chan.last_sent = (int) Globals.curtime;

    send.putInt(w1);
    send.putInt(w2);

    // send the qport if we are a client
    if (chan.sock == Constants.NS_CLIENT) send.WriteShort((int) consoleQport.value);

    // copy the reliable message to the packet first
    if (send_reliable != 0) {
      Buffers.Write(send, chan.reliable_buf, chan.reliable_length);
      chan.last_reliable_sequence = chan.outgoing_sequence;
    }

    // add the unreliable part if space is available
    if (send.maxsize - send.cursize >= length) Buffers.Write(send, data, length);
    else Com.Printf("Netchan_Transmit: dumped unreliable\n");

    // send the datagram
    NET.SendPacket(chan.sock, send.cursize, send.data, chan.remote_address);

    if (showpackets.value != 0) {
      if (send_reliable != 0)
        Com.Printf(
            // "send %4i : s=%i reliable=%i ack=%i rack=%i\n"
            "send "
                + send.cursize
                + " : s="
                + (chan.outgoing_sequence - 1)
                + " reliable="
                + chan.reliable_sequence
                + " ack="
                + chan.incoming_sequence
                + " rack="
                + chan.incoming_reliable_sequence
                + "\n");
      else
        Com.Printf(
            // "send %4i : s=%i ack=%i rack=%i\n"
            "send "
                + send.cursize
                + " : s="
                + (chan.outgoing_sequence - 1)
                + " ack="
                + chan.incoming_sequence
                + " rack="
                + chan.incoming_reliable_sequence
                + "\n");
    }
  }