@Listener(order = Order.LATE)
  public void onMessageChannelEventChat(MessageChannelEvent.Chat event, @First Player player) {
    Builder playerTag = Text.builder().onHover(TextActions.showText(Text.of(player.getName())));

    Optional<PlayerTag> optionalPlayerTag = PlayerTag.get(player);

    if (!optionalPlayerTag.isPresent()) {
      playerTag.append(PlayerTag.getDefault(player));
    } else {
      playerTag.append(optionalPlayerTag.get().getTag());
    }

    Text worldTag = Text.EMPTY;

    Optional<WorldTag> optionalWorldTag = WorldTag.get(player.getWorld().getProperties());

    if (optionalWorldTag.isPresent()) {
      worldTag = optionalWorldTag.get().getTag();
    }

    Builder groupTagBuilder = Text.builder();

    for (Entry<Set<Context>, List<Subject>> parent :
        player.getSubjectData().getAllParents().entrySet()) {
      for (Subject subject : parent.getValue()) {
        String group = subject.getIdentifier();

        if (group.equalsIgnoreCase("op_0")
            || group.equalsIgnoreCase("op_1")
            || group.equalsIgnoreCase("op_2")
            || group.equalsIgnoreCase("op_3")
            || group.equalsIgnoreCase("op_4")) {
          group = "op";
        }

        Optional<GroupTag> optionalGroupTag = GroupTag.get(group);

        if (optionalGroupTag.isPresent()) {
          groupTagBuilder.append(optionalGroupTag.get().getTag());
        }
      }
    }

    MessageFormatter formatter = event.getFormatter();

    String oldStr = TextSerializers.FORMATTING_CODE.serialize(formatter.getHeader().toText());

    String name = oldStr.substring(oldStr.indexOf("<"), oldStr.lastIndexOf(">") + 1);

    Text old = TextSerializers.FORMATTING_CODE.deserialize(oldStr.replace(name, ""));

    formatter.setHeader(
        TextTemplate.of(
            worldTag, groupTagBuilder.build(), playerTag.build(), old, TextColors.RESET));
  }
  @Listener
  public void onSendCommandEvent(SendCommandEvent event, @First CommandSource src) {
    String command = event.getCommand();

    if (!command.equalsIgnoreCase("say")) {
      return;
    }

    if (Sponge.getPluginManager().isLoaded("simplechat")) {
      return;
    }

    String message = event.getArguments();

    if (message == null || message.equals("")) {
      return;
    }

    MutableMessageChannel channel = MessageChannel.TO_ALL.asMutable();

    if (message.startsWith("@")) {
      channel = MessageChannel.TO_NONE.asMutable();

      String selector = message.substring(0, message.indexOf(" "));

      for (Entity entity : Selector.parse(selector).resolve(src)) {

        if (entity instanceof Player) {
          channel.addMember((MessageReceiver) entity);
        }
      }

      if (channel.getMembers().size() == 0) {
        src.sendMessage(Text.of(TextColors.RED, "Selector returned no players"));
        return;
      }

      channel.addMember(Sponge.getServer().getConsole());

      message = message.replace(selector, "");
    }

    Text text = TextSerializers.FORMATTING_CODE.deserialize(message);

    if (src instanceof Player) {
      Player player = (Player) src;

      Optional<PlayerTag> optionalPlayerTag = PlayerTag.get(player);

      if (optionalPlayerTag.isPresent()) {
        text = Text.join(optionalPlayerTag.get().getTag(), Text.of(" "), text);
      } else {
        text = Text.join(PlayerTag.getDefault(player), Text.of(" "), text);
      }
    } else {
      Optional<SingleTag> optionalTag = SingleTag.get("simpletags", "console");

      if (optionalTag.isPresent()) {
        text = Text.join(optionalTag.get().getTag(), Text.of(" "), text);
      }
    }

    channel.send(text);

    event.setCancelled(true);
  }