@Override
  public void compose(IComposer msg) {
    int timeLeft = 0;
    int days = 0;
    int months = 0;

    if (subscriptionComponent.isValid()) {
      timeLeft = subscriptionComponent.getExpire() - (int) Comet.getTime();
      days = (int) Math.ceil(timeLeft / 86400);
      months = days / 31;

      if (months >= 1) {
        months--;
      }
    } else {
      if (subscriptionComponent.exists()) {
        subscriptionComponent.delete();
      }
    }

    msg.writeString("habbo_club");

    msg.writeInt(0);
    msg.writeInt(2);
    msg.writeInt(0);
    msg.writeInt(1);
    msg.writeBoolean(subscriptionComponent.isValid());
    msg.writeBoolean(true);
    msg.writeInt(0);
    msg.writeInt(0);
    msg.writeInt(495);
  }
  public static void loadFigureData() {
    try {
      final File figureDataFile = new File("config/figuredata.xml");
      final Document furnidataDocument;

      if (!figureDataFile.exists()) {
        furnidataDocument =
            DocumentBuilderFactory.newInstance()
                .newDocumentBuilder()
                .parse(Comet.class.getResourceAsStream("/config/figuredata.xml"));
        FileUtils.copyURLToFile(Comet.class.getResource("/config/figuredata.xml"), figureDataFile);
      } else {
        furnidataDocument =
            DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(figureDataFile);
      }

      final Element furnidata =
          (Element) furnidataDocument.getElementsByTagName("figuredata").item(0);

      PlayerFigureValidator.palettes = new ConcurrentHashMap<>();
      PlayerFigureValidator.setTypes = new ConcurrentHashMap<>();

      /** Gender and club mandatories */
      PlayerFigureValidator.mandatorySetTypes = new ConcurrentHashMap<>();
      PlayerFigureValidator.mandatorySetTypes.put("m", new ConcurrentHashMap<>());
      PlayerFigureValidator.mandatorySetTypes.get("m").put(0, new ArrayList<>());
      PlayerFigureValidator.mandatorySetTypes.get("m").put(1, new ArrayList<>());
      PlayerFigureValidator.mandatorySetTypes.get("m").put(2, new ArrayList<>());
      PlayerFigureValidator.mandatorySetTypes.put("f", new ConcurrentHashMap<>());
      PlayerFigureValidator.mandatorySetTypes.get("f").put(0, new ArrayList<>());
      PlayerFigureValidator.mandatorySetTypes.get("f").put(1, new ArrayList<>());
      PlayerFigureValidator.mandatorySetTypes.get("f").put(2, new ArrayList<>());

      final NodeList palettes = furnidata.getElementsByTagName("palette");

      for (int paletteIndex = 0; paletteIndex < palettes.getLength(); ++paletteIndex) {
        final Node paletteNode = palettes.item(paletteIndex);

        if (paletteNode.getNodeType() == Node.ELEMENT_NODE) {
          final Element paletteElement = (Element) paletteNode;

          final int paletteId = Integer.valueOf(paletteElement.getAttribute("id"));
          PlayerFigureValidator.palettes.put(paletteId, new ConcurrentHashMap<>());

          final NodeList colors = paletteElement.getElementsByTagName("color");

          for (int colorIndex = 0; colorIndex < colors.getLength(); ++colorIndex) {
            final Node colorNode = colors.item(colorIndex);

            if (colorNode.getNodeType() == Node.ELEMENT_NODE) {
              final Element colorElement = (Element) colorNode;
              final int colorId = Integer.valueOf(colorElement.getAttribute("id"));

              PlayerFigureValidator.palettes
                  .get(paletteId)
                  .put(
                      colorId,
                      new PlayerFigureColor(
                          Integer.valueOf(colorElement.getAttribute("club")),
                          Integer.valueOf(colorElement.getAttribute("selectable")) == 1));
            }
          }
        }
      }

      final NodeList setTypes = furnidata.getElementsByTagName("settype");

      for (int setTypeIndex = 0; setTypeIndex < setTypes.getLength(); ++setTypeIndex) {
        final Node setTypeNode = setTypes.item(setTypeIndex);

        if (setTypeNode.getNodeType() == Node.ELEMENT_NODE) {
          final Element setTypeElement = (Element) setTypeNode;
          final String typeName = setTypeElement.getAttribute("type").toLowerCase();

          if (Integer.valueOf(setTypeElement.getAttribute("mand_m_0")) > 0) {
            PlayerFigureValidator.mandatorySetTypes.get("m").get(0).add(typeName);
          }

          if (Integer.valueOf(setTypeElement.getAttribute("mand_f_0")) > 0) {
            PlayerFigureValidator.mandatorySetTypes.get("f").get(0).add(typeName);
          }

          if (Integer.valueOf(setTypeElement.getAttribute("mand_m_1")) > 0) {
            PlayerFigureValidator.mandatorySetTypes.get("m").get(1).add(typeName);
            PlayerFigureValidator.mandatorySetTypes.get("m").get(2).add(typeName);
          }

          if (Integer.valueOf(setTypeElement.getAttribute("mand_f_1")) > 0) {
            PlayerFigureValidator.mandatorySetTypes.get("f").get(1).add(typeName);
            PlayerFigureValidator.mandatorySetTypes.get("f").get(2).add(typeName);
          }

          final Map<Integer, PlayerFigureSet> setMap = new ConcurrentHashMap<>();
          final NodeList sets = setTypeElement.getElementsByTagName("set");

          for (int setIndex = 0; setIndex < sets.getLength(); ++setIndex) {
            final Node setNode = sets.item(setIndex);

            if (setNode.getNodeType() == Node.ELEMENT_NODE) {
              final Element setElement = (Element) setNode;
              final int setId = Integer.valueOf(setElement.getAttribute("id"));

              int colorCount = 0;
              final NodeList parts = setElement.getElementsByTagName("part");

              for (int partIndex = 0; partIndex < parts.getLength(); ++partIndex) {
                final Node partNode = parts.item(partIndex);

                if (partNode.getNodeType() == Node.ELEMENT_NODE) {
                  final Element partElement = (Element) partNode;
                  final int colorIndex = Integer.valueOf(partElement.getAttribute("colorindex"));

                  if (Integer.valueOf(partElement.getAttribute("colorable")) > 0
                      && colorIndex > colorCount) {
                    colorCount = colorIndex;
                  }
                }
              }

              setMap.put(
                  setId,
                  new PlayerFigureSet(
                      setElement.getAttribute("gender").toLowerCase(),
                      Integer.valueOf(setElement.getAttribute("club")),
                      Integer.valueOf(setElement.getAttribute("colorable")) > 0,
                      Integer.valueOf(setElement.getAttribute("selectable")) > 0,
                      colorCount));
            }
          }

          PlayerFigureValidator.setTypes.put(
              typeName,
              new PlayerFigureSetType(
                  typeName, Integer.valueOf(setTypeElement.getAttribute("paletteid")), setMap));
        }
      }
    } catch (Exception e) {
      Comet.getServer().getLogger().warn("Error while initializing the PlayerFigureValidator", e);
    }
  }
  public MessageHandler() {
    this.asyncEventExecution =
        Boolean.parseBoolean(
            (String)
                Comet.getServer()
                    .getConfig()
                    .getOrDefault("comet.network.alternativePacketHandling.enabled", "false"));
    //        this.eventExecutor = asyncEventExecution ?
    // Executors.newFixedThreadPool(Integer.parseInt((String)
    // Comet.getServer().getConfig().getOrDefault("comet.network.alternativePacketHandling.threads",
    // "8"))) : null;

    if (this.asyncEventExecution) {
      switch ((String)
          Comet.getServer()
              .getConfig()
              .getOrDefault("comet.network.alternativePacketHandling.type", "threadpool")) {
        default:
          log.info("Using thread-pool event executor");
          this.eventExecutor =
              new ThreadPoolExecutor(
                  Integer.parseInt(
                      (String)
                          Comet.getServer()
                              .getConfig()
                              .getOrDefault(
                                  "comet.network.alternativePacketHandling.coreSize",
                                  "8")), // core size
                  Integer.parseInt(
                      (String)
                          Comet.getServer()
                              .getConfig()
                              .getOrDefault(
                                  "comet.network.alternativePacketHandling.maxSize",
                                  "32")), // max size
                  10 * 60, // idle timeout
                  TimeUnit.SECONDS,
                  new LinkedBlockingQueue<>());
          break;

        case "forkjoin":
          log.info("Using fork-join event executor");
          this.eventExecutor =
              new ForkJoinPool(
                  Integer.parseInt(
                      (String)
                          Comet.getServer()
                              .getConfig()
                              .getOrDefault(
                                  "comet.network.alternativePacketHandling.coreSize", 16)),
                  ForkJoinPool.defaultForkJoinWorkerThreadFactory,
                  null,
                  true);
          break;
      }
    } else {
      this.eventExecutor = null;
    }

    this.load();
  }