@Override
  public void onAttached(GuiComponent oparent) {
    this.setSize(oparent.getWidth(), oparent.getHeight());
    this.attachComponent(new DefaultBackground("bg"));
    ButtonList list =
        new ButtonList("languages", 0, 0, this.getWidth(), (int) (this.getHeight() * 0.8f));
    list.setCallback(
        new ButtonListCallback() {
          @Override
          public void onButtonListClick(ButtonList list, Button button) {
            String code =
                button
                    .getText()
                    .substring(button.getText().indexOf('(') + 1, button.getText().indexOf(')'));
            OpenClassic.getGame().getConfig().setValue("options.language", code);
            OpenClassic.getClient().setActiveComponent(new LanguageScreen(parent));
            OpenClassic.getGame().getConfig().save();
          }
        });

    this.attachComponent(list);
    this.attachComponent(
        new Button(
                "back",
                this.getWidth() / 2 - 150,
                (int) (this.getHeight() * 0.8f),
                300,
                40,
                OpenClassic.getGame().getTranslator().translate("gui.back"))
            .setCallback(
                new ButtonCallback() {
                  @Override
                  public void onButtonClick(Button button) {
                    OpenClassic.getClient().setActiveComponent(parent);
                  }
                }));

    this.attachComponent(
        new Label(
            "title",
            this.getWidth() / 2,
            this.getHeight() / 4 - 80,
            OpenClassic.getGame().getTranslator().translate("gui.language.select"),
            true));

    String text =
        String.format(
            OpenClassic.getGame().getTranslator().translate("gui.language.current"),
            OpenClassic.getGame().getConfig().getString("options.language"));
    this.attachComponent(
        new Label(
            "current", this.getWidth() / 2, (int) (this.getHeight() * 0.8f) - 56, text, true));

    List<String> languages = new ArrayList<String>();
    for (Language language : OpenClassic.getGame().getTranslator().getLanguages()) {
      languages.add(language.getName() + " (" + language.getLangCode() + ")");
    }

    this.getComponent("languages", ButtonList.class).setContents(languages);
  }
  protected void doAttack() {
    if (this.attackTarget != null && this.attackTarget.removed) {
      this.attackTarget = null;
    }

    if (this.attackTarget == null) {
      float sqDistance = OpenClassic.getClient().getPlayer().getPosition().distanceSquared(mob.pos);
      if (sqDistance < 256) {
        this.attackTarget = ((ClientPlayer) OpenClassic.getClient().getPlayer()).getHandle();
      }
    }

    if (this.attackTarget != null) {
      float xDistance = OpenClassic.getClient().getPlayer().getPosition().getX() - mob.pos.getX();
      float yDistance = OpenClassic.getClient().getPlayer().getPosition().getY() - mob.pos.getY();
      float zDistance = OpenClassic.getClient().getPlayer().getPosition().getZ() - mob.pos.getZ();
      float sqDistance = xDistance * xDistance + yDistance * yDistance + zDistance * zDistance;

      if (sqDistance > 1024 && this.random.nextInt(100) == 0) {
        this.attackTarget = null;
      }

      if (this.attackTarget != null) {
        float distance = (float) Math.sqrt(sqDistance);
        this.mob.pos.setYaw(
            (float) (Math.atan2(zDistance, xDistance) * MathHelper.DRAD_TO_DEG) - 90);
        this.mob.pos.setPitch(
            -((float)
                (Math.atan2(yDistance, (float) Math.sqrt(distance)) * MathHelper.DRAD_TO_DEG)));
        if ((float) Math.sqrt(sqDistance) < 2 && this.attackDelay == 0) {
          this.attack(this.attackTarget);
        }
      }
    }
  }
 @Override
 public void handle(ClassicSession session, Player player, LevelPropertyMessage message) {
   if (message.getType().equals("sky")) {
     OpenClassic.getClient().getLevel().setSkyColor(message.getValue());
   } else if (message.getType().equals("fog")) {
     OpenClassic.getClient().getLevel().setFogColor(message.getValue());
   } else if (message.getType().equals("cloud")) {
     OpenClassic.getClient().getLevel().setCloudColor(message.getValue());
   } else if (message.getType().equals("raining")) {
     OpenClassic.getClient().getLevel().setRaining(message.getValue() == 1 ? true : false);
   }
 }
  @Override
  public void update(int mouseX, int mouseY) {
    String text =
        String.format(
            OpenClassic.getGame().getTranslator().translate("gui.language.current"),
            OpenClassic.getGame().getConfig().getString("options.language"));
    Label label = this.getComponent("current", Label.class);
    if (!label.getText().equals(text)) {
      label.setText(text);
    }

    super.update(mouseX, mouseY);
  }
  @Override
  public void onAttached(GuiComponent oparent) {
    this.setSize(oparent.getWidth(), oparent.getHeight());
    this.attachComponent(new TranslucentBackground("bg"));
    this.attachComponent(
        new TextBox("name", this.getWidth() / 2 - 200, this.getHeight() / 2 - 60, 30));
    this.attachComponent(
        new Button(
                "save",
                this.getWidth() / 2 - 200,
                (int) (this.getHeight() * 0.75f),
                OpenClassic.getGame().getTranslator().translate("gui.level-dump.dump"))
            .setCallback(
                new ButtonCallback() {
                  @Override
                  public void onButtonClick(Button button) {
                    OpenClassic.getClient()
                        .saveLevel(getComponent("name", TextBox.class).getText());
                    OpenClassic.getClient().setActiveComponent(parent);
                  }
                }));

    this.attachComponent(
        new Button(
                "back",
                this.getWidth() / 2 - 200,
                (int) (this.getHeight() * 0.75f) + 48,
                OpenClassic.getGame().getTranslator().translate("gui.cancel"))
            .setCallback(
                new ButtonCallback() {
                  @Override
                  public void onButtonClick(Button button) {
                    OpenClassic.getClient().setActiveComponent(parent);
                  }
                }));

    this.attachComponent(
        new Label(
            "title",
            this.getWidth() / 2,
            this.getHeight() / 4 - 60,
            OpenClassic.getGame().getTranslator().translate("gui.level-dump.name"),
            true));
    this.getComponent("save", Button.class).setActive(false);
  }
  @Override
  public void onAttached(GuiComponent oparent) {
    this.setSize(oparent.getWidth(), oparent.getHeight());
    List<String> contents = new ArrayList<String>();
    for (Server server : ServerDataStore.getServers()) {
      contents.add(server.name);
    }

    this.attachComponent(new DefaultBackground("bg"));
    ButtonList list =
        new ButtonList("servers", 0, 0, this.getWidth(), (int) (this.getHeight() * 0.8f), true);
    list.setCallback(
        new ButtonListCallback() {
          @Override
          public void onButtonListClick(ButtonList list, Button button) {
            String text = button.getText();
            int index = 0;
            for (String t : list.getContents()) {
              if (text.equals(t)) {
                break;
              }

              index++;
            }

            Server server = ServerDataStore.getServers().get(index);
            if (select) {
              getComponent("title", Label.class)
                  .setText(OpenClassic.getGame().getTranslator().translate("gui.favorites.select"));
              select = false;
              ServerDataStore.addFavorite(server.name, server.getUrl());
              ServerDataStore.saveFavorites();
            } else {
              OpenClassic.getClient().joinServer(server.getUrl());
            }
          }
        });

    this.attachComponent(list);
    this.attachComponent(
        new Button(
                "favorites",
                this.getWidth() / 2 - 412,
                (int) (this.getHeight() * 0.8f),
                200,
                40,
                OpenClassic.getGame().getTranslator().translate("gui.servers.favorites"))
            .setCallback(
                new ButtonCallback() {
                  @Override
                  public void onButtonClick(Button button) {
                    OpenClassic.getClient()
                        .setActiveComponent(new FavoriteServersScreen(ServerListScreen.this));
                  }
                }));

    this.attachComponent(
        new Button(
                "addfavorite",
                this.getWidth() / 2 - 204,
                (int) (this.getHeight() * 0.8f),
                200,
                40,
                OpenClassic.getGame().getTranslator().translate("gui.add-favorite.add"))
            .setCallback(
                new ButtonCallback() {
                  @Override
                  public void onButtonClick(Button button) {
                    Label label = getComponent("title", Label.class);
                    if (select) {
                      label.setText(
                          OpenClassic.getGame().getTranslator().translate("gui.favorites.select"));
                      select = false;
                    } else {
                      label.setText(
                          Color.GREEN
                              + OpenClassic.getGame()
                                  .getTranslator()
                                  .translate("gui.servers.select-fav"));
                      select = true;
                    }
                  }
                }));

    this.attachComponent(
        new Button(
                "url",
                this.getWidth() / 2 + 4,
                (int) (this.getHeight() * 0.8f),
                200,
                40,
                OpenClassic.getGame().getTranslator().translate("gui.servers.enter-url"))
            .setCallback(
                new ButtonCallback() {
                  @Override
                  public void onButtonClick(Button button) {
                    OpenClassic.getClient()
                        .setActiveComponent(new ServerURLScreen(ServerListScreen.this));
                  }
                }));

    this.attachComponent(
        new Button(
                "back",
                this.getWidth() / 2 + 212,
                (int) (this.getHeight() * 0.8f),
                200,
                40,
                OpenClassic.getGame().getTranslator().translate("gui.back"))
            .setCallback(
                new ButtonCallback() {
                  @Override
                  public void onButtonClick(Button button) {
                    OpenClassic.getClient().setActiveComponent(parent);
                  }
                }));

    this.attachComponent(
        new Label(
            "title",
            this.getWidth() / 2,
            this.getHeight() / 4 - 80,
            OpenClassic.getGame().getTranslator().translate("gui.favorites.select"),
            true));
    this.getComponent("servers", ButtonList.class).setContents(contents);
  }
  @Override
  public void handle(ClassicSession session, Player player, IdentificationMessage message) {
    if (session.getState() == State.IDENTIFYING) {
      PlayerLoginEvent event =
          EventManager.callEvent(
              new PlayerLoginEvent(OpenClassic.getClient().getPlayer(), session.getAddress()));
      if (event.getResult() != Result.ALLOWED) {
        OpenClassic.getClient().exitGameSession();
        OpenClassic.getClient()
            .setActiveComponent(
                new ErrorScreen(
                    OpenClassic.getGame().getTranslator().translate("disconnect.plugin-disallow"),
                    event.getKickMessage()));
        return;
      }
    }

    if (message.getVerificationKeyOrMotd().contains("-hax")) {
      ((ClassicClient) OpenClassic.getClient()).setHacks(false);
    }

    OpenClassic.getClient().setActiveComponent(null);
    OpenClassic.getClient().getProgressBar().setVisible(true);
    OpenClassic.getClient().getProgressBar().setSubtitleScaled(false);
    OpenClassic.getClient()
        .getProgressBar()
        .setTitle(OpenClassic.getGame().getTranslator().translate("progress-bar.multiplayer"));
    OpenClassic.getClient().getProgressBar().setSubtitle(message.getUsernameOrServerName());
    OpenClassic.getClient().getProgressBar().setText(message.getVerificationKeyOrMotd());
    byte op = message.getOpOrPadding();
    if (op == InternalConstants.OP) {
      player.setCanBreakUnbreakables(true);
    } else if (op == InternalConstants.NOT_OP) {
      player.setCanBreakUnbreakables(false);
    }

    if (session.getState() == State.IDENTIFYING) {
      EventManager.callEvent(new PlayerJoinEvent(OpenClassic.getClient().getPlayer(), "Joined"));
    }

    session.setState(State.PREPARING);
  }