// Called from the main thread only
  private void syncedSendPacket(Packet packet, MCCraftPacket[] packetWrappers) {
    int packetId = -1;
    try {
      packetId = packet.b();
    } catch (Exception e) {
      return;
    }

    try {
      if (!PacketListeners.canSend(getPlayer(), packet, packetWrappers, packetId)) {
        return;
      } else {
        if (packet instanceof Packet51MapChunk) {
          Packet51MapChunk chunk = (Packet51MapChunk) packet;
          if (chunk.buffer == null) {
            ChunkCompressionThread.sendPacket(player, packet);
            return;
          }
        }
        super.sendPacket(packet);
      }
    } catch (NullPointerException npe) {
      if (packet != null) {
        throw new RuntimeException(
            "Null pointer exception thrown when trying to process packet of type "
                + packet.getClass().getName(),
            npe);
      } else {
        throw npe;
      }
    }
  }
  // This may not catch 100% of packets, but should get most of them, a small number may end up
  // being compressed by main thread
  @SuppressWarnings("unchecked")
  public void manageChunkQueue(boolean flag1) {
    List<ChunkCoordIntPair> playerChunkQueue = player.chunkCoordIntPairQueue;

    try {
      if (!playerChunkQueue.isEmpty()) {
        chunkUpdateQueue.addAll(playerChunkQueue);
        playerChunkQueue.clear();
      }
    } catch (ConcurrentModificationException e) {
      // seems to be called from a separate thread during teleports (rogue plugins?)
    }

    int chunkCompressionThreadSize = ChunkCompressionThread.getPlayerQueueSize(this.player);
    if (!chunkUpdateQueue.isEmpty()
        && (lowPriorityCount()
                + chunkCompressionThreadSize
                + MapChunkThread.getQueueLength(this.player))
            < 4) {
      ChunkCoordIntPair playerChunk = getPlayerChunk();
      Iterator<ChunkCoordIntPair> i = chunkUpdateQueue.iterator();
      ChunkCoordIntPair first = i.next();
      while (first != null && !activeChunks.contains(first)) {
        i.remove();
        if (i.hasNext()) {
          first = i.next();
        } else {
          first = null;
        }
      }
      if (first != null) {
        if (updateCounter.get() > 0) {
          int cx = playerChunk.x;
          int cz = playerChunk.z;
          boolean chunkFound = false;
          for (int c = 0; c < spiralx.length; c++) {
            ChunkCoordIntPair testChunk = new ChunkCoordIntPair(spiralx[c] + cx, spiralz[c] + cz);
            if (chunkUpdateQueue.contains(testChunk)) {
              first = testChunk;
              chunkFound = true;
              break;
            }
          }
          if (!chunkFound) {
            updateCounter.decrementAndGet();
          }
        }
        chunkUpdateQueue.remove(first);
        MapChunkThread.sendPacketMapChunk(first, this.player, this.player.world);
        sendChunkTiles(first.x, first.z, player);
      }
    }
  }