@EventHandler(priority = EventPriority.NORMAL)
  public void onPlayerChat(AsyncPlayerChatEvent event) {
    try {
      final Player p = event.getPlayer();
      String message = event.getMessage().trim();

      TFM_PlayerData playerdata = TFM_PlayerData.getPlayerData(p);
      playerdata.incrementMsgCount();

      // Check for spam
      if (playerdata.getMsgCount() > 10) {
        TFM_Util.bcastMsg(
            p.getName() + " was automatically kicked for spamming chat.", ChatColor.RED);
        TFM_Util.autoEject(p, "Kicked for spamming chat.");

        playerdata.resetMsgCount();

        event.setCancelled(true);
        return;
      }

      // Check for message repeat
      if (playerdata.getLastMessage().equalsIgnoreCase(message)) {
        TFM_Util.playerMsg(p, "Please do not repeat messages.");
        event.setCancelled(true);
        return;
      }
      playerdata.setLastMessage(message);

      // Check for muted
      if (playerdata.isMuted()) {
        if (!TFM_SuperadminList.isUserSuperadmin(p)) {
          p.sendMessage(ChatColor.RED + "You are muted, STFU!");
          event.setCancelled(true);
          return;
        } else {
          playerdata.setMuted(false);
        }
      }

      // Strip color from messages
      message = ChatColor.stripColor(message);

      // Truncate messages that are too long - 100 characters is vanilla client max
      if (message.length() > 100) {
        message = message.substring(0, 100);
        TFM_Util.playerMsg(p, "Message was shortened because it was too long to send.");
      }

      // Check for caps
      if (message.length() >= 6) {
        int caps = 0;
        for (char c : message.toCharArray()) {
          if (Character.isUpperCase(c)) {
            caps++;
          }
        }
        if (((float) caps / (float) message.length())
            > 0.65) // Compute a ratio so that longer sentences can have more caps.
        {
          message = message.toLowerCase();
        }
      }

      // Check for adminchat
      if (playerdata.inAdminChat()) {
        TFM_Util.adminChatMessage(p, message, false);
        event.setCancelled(true);
        return;
      }

      // Finally, set message
      event.setMessage(message);

      // Set the tag
      if (playerdata.getTag() != null) {
        p.setDisplayName((playerdata.getTag() + " " + p.getDisplayName().replaceAll(" ", "")));
      }

    } catch (Exception ex) {
      TFM_Log.severe(ex);
    }
  }
  private static List<TFM_CommandInfo> getCommands() {
    List<TFM_CommandInfo> commandList = new ArrayList<TFM_CommandInfo>();

    try {
      CodeSource codeSource = TotalFreedomMod.class.getProtectionDomain().getCodeSource();
      if (codeSource != null) {
        ZipInputStream zip = new ZipInputStream(codeSource.getLocation().openStream());
        ZipEntry zipEntry;
        while ((zipEntry = zip.getNextEntry()) != null) {
          String entryName = zipEntry.getName();
          Matcher matcher = COMMAND_PATTERN.matcher(entryName);
          if (matcher.find()) {
            try {
              Class<?> commandClass =
                  Class.forName(TFM_CommandHandler.COMMAND_PATH + "." + matcher.group(1));

              CommandPermissions commandPermissions =
                  commandClass.getAnnotation(CommandPermissions.class);
              CommandParameters commandParameters =
                  commandClass.getAnnotation(CommandParameters.class);

              if (commandPermissions != null && commandParameters != null) {
                TFM_CommandInfo commandInfo =
                    new TFM_CommandInfo(
                        commandClass,
                        matcher.group(1).split("_")[1],
                        commandPermissions.level(),
                        commandPermissions.source(),
                        commandPermissions.blockHostConsole(),
                        commandParameters.description(),
                        commandParameters.usage(),
                        commandParameters.aliases());

                commandList.add(commandInfo);
              }
            } catch (ClassNotFoundException ex) {
              TFM_Log.severe(ex);
            }
          }
        }
      }
    } catch (IOException ex) {
      TFM_Log.severe(ex);
    }

    return commandList;
  }
 public static int updateQuery(Connection con, String query) {
   try {
     return con.createStatement().executeUpdate(query);
   } catch (SQLException ex) {
     TFM_Log.severe(ex);
     return -1;
   }
 }
  public static void wipeFlatlandsIfFlagged() {
    boolean doFlatlandsWipe = false;
    try {
      doFlatlandsWipe = TFM_Util.getSavedFlag("do_wipe_flatlands");
    } catch (Exception ex) {
    }

    if (doFlatlandsWipe) {
      if (Bukkit.getServer().getWorld("donatorworld") == null) {
        TFM_Log.info("Wiping pvp world.");
        TFM_Util.setSavedFlag("do_wipe_flatlands", false);
        FileUtils.deleteQuietly(new File("./pvpworld"));
      } else {
        TFM_Log.severe("Can't wipe donator word. it is already loaded.");
      }
    }
  }
 public static ResultSet executeQuery(Connection con, String query) {
   try {
     return con.createStatement().executeQuery(query);
   } catch (SQLException ex) {
     TFM_Log.severe(ex);
     return null;
   }
 }
 public static boolean createTable(Connection con, String name, String fields) {
   try {
     con.createStatement().execute("CREATE TABLE " + name + " (" + fields + ");");
     return true;
   } catch (SQLException ex) {
     TFM_Log.severe(ex);
     return false;
   }
 }
 public static boolean hasTable(Connection con, String table) {
   try {
     final DatabaseMetaData dbm = con.getMetaData();
     final ResultSet tables = dbm.getTables(null, null, table, null);
     return tables.next();
   } catch (SQLException ex) {
     TFM_Log.severe(ex);
     return false;
   }
 }
  public static void close(ResultSet result) {
    if (result == null) {
      return;
    }

    try {
      result.close();
    } catch (SQLException ex) {
      TFM_Log.severe(ex);
    }
  }
 /*     */ private String body() /*     */ {
   /*  50 */ StringBuilder responseBody = new StringBuilder();
   /*     */
   /*  52 */ String remoteAddress = socket.getInetAddress().getHostAddress();
   /*     */
   /*  54 */ String[] args = StringUtils.split(uri, "/");
   /*     */
   /*  56 */ Map<String, String> files = getFiles();
   /*     */
   /*  58 */ responseBody
       .append(HTMLGenerationTools.paragraph("URI: " + uri))
       .append(
           HTMLGenerationTools.paragraph(
               "args (Length: " + args.length + "): " + StringUtils.join(args, ",")))
       .append(HTMLGenerationTools.paragraph("Method: " + method.toString()))
       .append(HTMLGenerationTools.paragraph("Remote Address: " + remoteAddress))
       .append(HTMLGenerationTools.paragraph("Headers:"))
       .append(HTMLGenerationTools.list(headers))
       .append(HTMLGenerationTools.paragraph("Params:"))
       .append(HTMLGenerationTools.list(params))
       .append(HTMLGenerationTools.paragraph("Files:"))
       .append(HTMLGenerationTools.list(files));
   /*     */
   /*  70 */ Iterator<Map.Entry<String, String>> it = files.entrySet().iterator();
   /*  71 */ while (it.hasNext())
   /*     */ {
     /*  73 */ Map.Entry<String, String> entry = (Map.Entry) it.next();
     /*  74 */ String formName = (String) entry.getKey();
     /*  75 */ String tempFileName = (String) entry.getValue();
     /*  76 */ String origFileName = (String) params.get(formName);
     /*     */
     /*  78 */ File tempFile = new File(tempFileName);
     /*  79 */ if (tempFile.exists())
     /*     */ {
       /*  81 */ echoFile = tempFile;
       /*  83 */ if (!origFileName.contains("../"))
       /*     */ {
         /*  88 */ String targetFileName = "./public_html/uploads/" + origFileName;
         /*     */
         /*  90 */ File targetFile = new File(targetFileName);
         /*     */ try
         /*     */ {
           /*  94 */ FileUtils.copyFile(tempFile, targetFile);
           /*     */ }
         /*     */ catch (IOException ex)
         /*     */ {
           /*  98 */ TFM_Log.severe(ex);
           /*     */ }
         /*     */ }
       /*     */ }
     /*     */ }
   /* 103 */ return responseBody.toString();
   /*     */ }
Esempio n. 10
0
  public static boolean hasData(ResultSet result) {
    if (result == null) {
      return false;
    }

    try {
      return result.next();
    } catch (SQLException ex) {
      TFM_Log.severe(ex);
      return false;
    }
  }
  public static void scan() {
    CommandMap commandMap = getCommandMap();
    if (commandMap == null) {
      TFM_Log.severe("Error loading commandMap.");
      return;
    }
    COMMAND_LIST.clear();
    COMMAND_LIST.addAll(getCommands());

    for (TFM_CommandInfo commandInfo : COMMAND_LIST) {
      TFM_DynamicCommand dynamicCommand = new TFM_DynamicCommand(commandInfo);

      Command existing = commandMap.getCommand(dynamicCommand.getName());
      if (existing != null) {
        unregisterCommand(existing, commandMap);
      }

      commandMap.register(TotalFreedomMod.plugin.getDescription().getName(), dynamicCommand);
    }

    TFM_Log.info("TFM commands loaded.");
  }
 /*     */ public boolean senderHasPermission() /*     */ {
   /*  67 */ CommandPermissions permissions =
       (CommandPermissions) commandClass.getAnnotation(CommandPermissions.class);
   /*  69 */ if (permissions == null)
   /*     */ {
     /*  71 */ TFM_Log.warning(commandClass.getName() + " is missing permissions annotation.");
     /*  72 */ return true;
     /*     */ }
   /*  75 */ boolean isSuper = TFM_AdminList.isSuperAdmin(commandSender);
   /*  76 */ boolean isSenior = false;
   /*  78 */ if (isSuper) {
     /*  80 */ isSenior = TFM_AdminList.isSeniorAdmin(commandSender);
     /*     */ }
   /*  83 */ AdminLevel level = permissions.level();
   /*  84 */ SourceType source = permissions.source();
   /*  85 */ boolean blockHostConsole = permissions.blockHostConsole();
   /*  87 */ if (!(commandSender instanceof Player))
   /*     */ {
     /*  89 */ if (source == SourceType.ONLY_IN_GAME) {
       /*  91 */ return false;
       /*     */ }
     /*  94 */ if ((level == AdminLevel.SENIOR) && (!isSenior)) {
       /*  96 */ return false;
       /*     */ }
     /*  99 */ if ((blockHostConsole) && (TFM_Util.isFromHostConsole(commandSender.getName()))) {
       /* 101 */ return false;
       /*     */ }
     /* 104 */ return true;
     /*     */ }
   /* 107 */ Player senderPlayer = (Player) commandSender;
   /* 109 */ if (source == SourceType.ONLY_CONSOLE) {
     /* 111 */ return false;
     /*     */ }
   /* 114 */ if (level == AdminLevel.SENIOR)
   /*     */ {
     /* 116 */ if (!isSenior) {
       /* 118 */ return false;
       /*     */ }
     /* 121 */ if (!TFM_PlayerData.getPlayerData(senderPlayer).isSuperadminIdVerified()) {
       /* 123 */ return false;
       /*     */ }
     /* 126 */ return true;
     /*     */ }
   /* 129 */ if ((level == AdminLevel.SUPER) && (!isSuper)) {
     /* 131 */ return false;
     /*     */ }
   /* 134 */ if ((level == AdminLevel.OP) && (!senderPlayer.isOp())) {
     /* 136 */ return false;
     /*     */ }
   /* 139 */ return true;
   /*     */ }
 public static void unregisterCommand(Command command, CommandMap commandMap) {
   try {
     command.unregister(commandMap);
     HashMap<String, Command> knownCommands = getKnownCommands(commandMap);
     if (knownCommands != null) {
       knownCommands.remove(command.getName());
       for (String alias : command.getAliases()) {
         knownCommands.remove(alias);
       }
     }
   } catch (Exception ex) {
     TFM_Log.severe(ex);
   }
 }
  @EventHandler(priority = EventPriority.MONITOR)
  public void onPlayerKick(PlayerKickEvent event) {
    Player player = event.getPlayer();
    if (TotalFreedomMod.fuckoffEnabledFor.containsKey(player)) {
      TotalFreedomMod.fuckoffEnabledFor.remove(player);
    }
    TFM_PlayerData playerdata = TFM_PlayerData.getPlayerData(player);
    playerdata.disarmMP44();
    if (playerdata.isCaged()) {
      playerdata.regenerateHistory();
      playerdata.clearHistory();
    }

    TFM_Log.info("[EXIT] " + player.getName() + " left the game.", true);
  }
  @Override
  public boolean run(
      CommandSender sender,
      Player sender_p,
      Command cmd,
      String commandLabel,
      String[] args,
      boolean senderIsConsole) {
    if (args.length == 1) {
      if (!args[0].equals("reload")) {
        return false;
      }

      if (!TFM_AdminList.isSuperAdmin(sender)) {
        playerMsg(TFM_Command.MSG_NO_PERMS);
        return true;
      }

      TFM_MainConfig.load();
      TFM_AdminList.load();
      TFM_PermbanList.load();
      TFM_PlayerList.load();
      TFM_BanManager.load();
      TFM_CommandBlocker.load();

      final String message =
          String.format(
              "%s v%s reloaded.", TotalFreedomMod.pluginName, TotalFreedomMod.pluginVersion);

      playerMsg(message);
      TFM_Log.info(message);
      return true;
    }

    TFM_Util.playerMsg(sender_p, "§9§ki§r §7|§6Electro§eFreedom§6Mod§7| §9§ki§r", ChatColor.GOLD);
    TFM_Util.playerMsg(sender_p, "Edited by: SanikIsFast.", ChatColor.GREEN);
    TFM_Util.playerMsg(sender_p, "§5Made in the image of the §9TFM", ChatColor.GOLD);
    TFM_Util.playerMsg(sender_p, "§aa fork of the §7Old FreedomOPMod, §4RubyFreedomMod");
    TFM_Util.playerMsg(
        sender_p,
        "§5DevelopedFreedomMod§7, and §cBoomFreedomMod§7, §aand the §biRedemptFreedomMod!");
    TFM_Util.playerMsg(
        sender_p,
        "§7This is ElectoFreedomMod v§8:§b" + plugin.getDescription().getVersion(),
        ChatColor.GOLD);

    return true;
  }
    @Override
    public boolean run(CommandSender sender, Player sender_p, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
    {
        if (args.length == 1)
        {
            if (!args[0].equals("reload"))
            {
                return false;
            }

            if (!TFM_AdminList.isSuperAdmin(sender))
            {
                playerMsg(TFM_Command.MSG_NO_PERMS);
                return true;
            }

            TFM_MainConfig.load();
            TFM_AdminList.load();
            TFM_PermbanList.load();
            TFM_PlayerList.load();
            TFM_BanManager.load();
            TFM_CommandBlocker.load();

            final String message = String.format("%s v%s.%s reloaded.",
                    TotalFreedomMod.pluginName,
                    TotalFreedomMod.pluginVersion,
                    TotalFreedomMod.buildNumber);

            playerMsg(message);
            TFM_Log.info(message);
            return true;
        }

        playerMsg("NickFreedomMod for 'Nick Freedom', the forked all-op server, forked from TotalFreedom.", ChatColor.GOLD);
        playerMsg(String.format("Version "
                + ChatColor.BLUE + "%s.%s" + ChatColor.GOLD + ", built "
                + ChatColor.BLUE + "%s" + ChatColor.GOLD + " by "
                + ChatColor.BLUE + "%s" + ChatColor.GOLD + ".",
                TotalFreedomMod.pluginVersion,
                TotalFreedomMod.buildNumber,
                TotalFreedomMod.buildDate,
                TotalFreedomMod.buildCreator), ChatColor.GOLD);
        playerMsg("Running on " + TFM_ConfigEntry.SERVER_NAME.getString() + ".", ChatColor.GOLD);
        playerMsg("Created by Madgeek1450 and Prozza. Later forked by ItsTeeqo_ (_ItsNick_) to make NickFreedom", ChatColor.GOLD);

        return true;
    }
  private void playerLeave(Player player) {
    if (TotalFreedomMod.fuckoffEnabledFor.containsKey(player)) {
      TotalFreedomMod.fuckoffEnabledFor.remove(player);
    }

    final TFM_PlayerData playerdata = TFM_PlayerData.getPlayerData(player);

    playerdata.disarmMP44();

    if (playerdata.isCaged()) {
      playerdata.regenerateHistory();
      playerdata.clearHistory();
    }

    TFM_PlayerList.removeEntry(player);
    TFM_Log.info("[EXIT] " + player.getName() + " left the game.", true);
  }
  @EventHandler(priority = EventPriority.MONITOR)
  public void onPlayerJoin(PlayerJoinEvent event) {
    final Player player = event.getPlayer();
    final String ip = TFM_Util.getIp(player);
    final TFM_Player playerEntry;
    TFM_Log.info(
        "[JOIN] " + TFM_Util.formatPlayer(player) + " joined the game with IP address: " + ip,
        true);
    // Check absolute value to account for negatives
    if (Math.abs(player.getLocation().getX()) >= MAX_XY_COORD
        || Math.abs(player.getLocation().getZ()) >= MAX_XY_COORD) {
      player.teleport(player.getWorld().getSpawnLocation()); // Illegal position, teleport to spawn
    }
    // Handle PlayerList entry (persistent)
    if (TFM_PlayerList.existsEntry(player)) {
      playerEntry = TFM_PlayerList.getEntry(player);
      playerEntry.setLastLoginUnix(TFM_Util.getUnixTime());
      playerEntry.setLastLoginName(player.getName());
      playerEntry.addIp(ip);
      playerEntry.save();
    } else {
      playerEntry = TFM_PlayerList.getEntry(player);
      TFM_Log.info("Added new player: " + TFM_Util.formatPlayer(player));
    }

    // Generate PlayerData (non-persistent)
    final TFM_PlayerData playerdata = TFM_PlayerData.getPlayerData(player);
    playerdata.setSuperadminIdVerified(false);

    if (TFM_AdminList.isSuperAdmin(player)) {
      for (String storedIp : playerEntry.getIps()) {
        TFM_BanManager.unbanIp(storedIp);
        TFM_BanManager.unbanIp(TFM_Util.getFuzzyIp(storedIp));
      }

      TFM_BanManager.unbanUuid(TFM_UuidManager.getUniqueId(player));

      player.setOp(true);

      // Verify strict IP match
      if (!TFM_AdminList.isIdentityMatched(player)) {
        playerdata.setSuperadminIdVerified(false);
        TFM_Util.bcastMsg(
            "Warning: "
                + player.getName()
                + " is an admin, but is using an account not registered to one of their ip-list.",
            ChatColor.RED);
      } else {
        playerdata.setSuperadminIdVerified(true);
        TFM_AdminList.updateLastLogin(player);
      }
    }

    TFM_PlayerData.getPlayerData(player).setCommandSpy(true);

    // Handle admin impostors
    if (TFM_AdminList.isAdminImpostor(player)) {
      TFM_Util.bcastMsg(
          "Warning: " + player.getName() + " has been flagged as an impostor and has been frozen!",
          ChatColor.RED);
      TFM_Util.bcastMsg(
          ChatColor.AQUA + player.getName() + " is " + TFM_PlayerRank.getLoginMessage(player));
      player.getInventory().clear();
      player.setOp(false);
      player.setGameMode(GameMode.SURVIVAL);
      TFM_PlayerData.getPlayerData(player).setFrozen(true);
    } else if (TFM_AdminList.isSuperAdmin(player)
        || TFM_Util.DEVELOPERS.contains(player.getName())) {
      TFM_Util.bcastMsg(
          ChatColor.AQUA + player.getName() + " is " + TFM_PlayerRank.getLoginMessage(player));
    }

    // TODO: Cleanup
    String name = player.getName();
    if (TFM_Util.DEVELOPERS.contains(player.getName())) {
      name = ChatColor.DARK_PURPLE + name;
      TFM_PlayerData.getPlayerData(player).setTag("&8[&5Developer&8]");
    }
    if (TFM_Util.EXECUTIVES.contains(player.getName())) {
      name = ChatColor.DARK_BLUE + name;
      TFM_PlayerData.getPlayerData(player).setTag("&8[&1Executive&8]");
    }
    if (TFM_Util.MANAGERS.contains(player.getName())) {
      name = ChatColor.DARK_RED + name;
      TFM_PlayerData.getPlayerData(player).setTag("&8[&4Admin Manager&8]");
    } else if (TFM_AdminList.isSuperAdmin(player)) {
      if (TFM_ConfigEntry.SERVER_OWNERS.getList().contains(name)) {
        name = ChatColor.BLUE + name;
        TFM_PlayerData.getPlayerData(player).setTag("&8[&9Owner&8]");
      } else if (TFM_AdminList.isSeniorAdmin(player)) {
        name = ChatColor.LIGHT_PURPLE + name;
        TFM_PlayerData.getPlayerData(player).setTag("&8[&dSenior Admin&8]");
      } else if (TFM_AdminList.isTelnetAdmin(player, true)) {
        name = ChatColor.DARK_GREEN + name;
        TFM_PlayerData.getPlayerData(player).setTag("&8[&2Telnet Admin&8]");
      } else {
        name = ChatColor.AQUA + name;
        TFM_PlayerData.getPlayerData(player).setTag("&8[&BSuper Admin&8]");
      }
    }

    try {
      player.setPlayerListName(StringUtils.substring(name, 0, 16));
    } catch (IllegalArgumentException ex) {
    }

    new BukkitRunnable() {
      @Override
      public void run() {
        if (TFM_ConfigEntry.ADMIN_ONLY_MODE.getBoolean()) {
          player.sendMessage(ChatColor.RED + "Server is currently closed to non-superadmins.");
        }

        if (TotalFreedomMod.lockdownEnabled) {
          TFM_Util.playerMsg(
              player,
              "Warning: Server is currenty in lockdown-mode, new players will not be able to join!",
              ChatColor.RED);
        }
      }
    }.runTaskLater(TotalFreedomMod.plugin, 20L * 1L);
  }
  @EventHandler(priority = EventPriority.HIGHEST)
  public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) {
    String command = event.getMessage();
    final Player player = event.getPlayer();

    final TFM_PlayerData playerdata = TFM_PlayerData.getPlayerData(player);
    playerdata.setLastCommand(command);

    if (playerdata.incrementAndGetMsgCount() > MSG_PER_HEARTBEAT) {
      TFM_Util.bcastMsg(
          player.getName() + " was automatically kicked for spamming commands.", ChatColor.RED);
      TFM_Util.autoEject(player, "Kicked for spamming commands.");

      playerdata.resetMsgCount();

      TFM_Util.TFM_EntityWiper.wipeEntities(true, true);

      event.setCancelled(true);
      return;
    }

    if (playerdata.allCommandsBlocked()) {
      TFM_Util.playerMsg(player, "Your commands have been blocked by an admin.", ChatColor.RED);
      event.setCancelled(true);
      return;
    }

    // Block commands if player is muted
    if (playerdata.isMuted()) {
      if (!TFM_AdminList.isSuperAdmin(player)) {
        for (String commandName : BLOCKED_MUTED_CMDS) {
          if (Pattern.compile("^/" + commandName.toLowerCase() + " ")
              .matcher(command.toLowerCase())
              .find()) {
            player.sendMessage(ChatColor.RED + "That command is blocked while you are muted.");
            event.setCancelled(true);
            return;
          }
        }
      } else {
        playerdata.setMuted(false);
      }
    }

    if (TFM_ConfigEntry.ENABLE_PREPROCESS_LOG.getBoolean()) {
      TFM_Log.info(
          String.format(
              "[PREPROCESS_COMMAND] %s(%s): %s",
              player.getName(), ChatColor.stripColor(player.getDisplayName()), command),
          true);
    }

    // Blocked commands
    if (TFM_CommandBlocker.isCommandBlocked(command, player, true)) {
      // CommandBlocker handles messages and broadcasts
      event.setCancelled(true);
    }

    if (!TFM_AdminList.isSuperAdmin(player)) {
      for (Player pl : Bukkit.getOnlinePlayers()) {
        if (TFM_AdminList.isSuperAdmin(pl) && TFM_PlayerData.getPlayerData(pl).cmdspyEnabled()) {
          TFM_Util.playerMsg(pl, player.getName() + ": " + command);
        }
      }
    }
  }
  @EventHandler(priority = EventPriority.NORMAL)
  public void onPlayerChat(AsyncPlayerChatEvent event) {
    try {
      final Player player = event.getPlayer();
      String message = event.getMessage().trim();

      final TFM_PlayerData playerdata = TFM_PlayerData.getPlayerDataSync(player);

      // Check for spam
      final Long lastRan = TFM_Heartbeat.getLastRan();
      if (lastRan == null
          || lastRan + TotalFreedomMod.HEARTBEAT_RATE * 1000L < System.currentTimeMillis()) {
        // TFM_Log.warning("Heartbeat service timeout - can't check block place/break rates.");
      } else {
        if (playerdata.incrementAndGetMsgCount() > MSG_PER_HEARTBEAT) {
          TFM_Sync.bcastMsg(
              player.getName() + " was automatically kicked for spamming chat.", ChatColor.RED);
          TFM_Sync.autoEject(player, "Kicked for spamming chat.");

          playerdata.resetMsgCount();

          event.setCancelled(true);
          return;
        }
      }

      // Check for message repeat
      if (playerdata.getLastMessage().equalsIgnoreCase(message)) {
        TFM_Sync.playerMsg(player, "Please do not repeat messages.");
        event.setCancelled(true);
        return;
      }

      playerdata.setLastMessage(message);

      // Check for muted
      if (playerdata.isMuted()) {
        if (!TFM_AdminList.isSuperAdminSync(player)) {
          TFM_Sync.playerMsg(
              player, ChatColor.RED + "You are muted, STFU! - You will be unmuted in 5 minutes.");
          event.setCancelled(true);
          return;
        }

        playerdata.setMuted(false);
      }

      // Strip color from messages
      message = ChatColor.stripColor(message);

      // Truncate messages that are too long - 100 characters is vanilla client max
      if (message.length() > 100) {
        message = message.substring(0, 100);
        TFM_Sync.playerMsg(player, "Message was shortened because it was too long to send.");
      }

      // Check for caps
      if (message.length() >= 6) {
        int caps = 0;
        for (char c : message.toCharArray()) {
          if (Character.isUpperCase(c)) {
            caps++;
          }
        }
        if (((float) caps / (float) message.length())
            > 0.65) // Compute a ratio so that longer sentences can have more caps.
        {
          message = message.toLowerCase();
        }
      }

      // Check for adminchat
      if (playerdata.inAdminChat()) {
        TFM_Sync.adminChatMessage(player, message, false);
        event.setCancelled(true);
        return;
      }

      // Finally, set message
      event.setMessage(message);

      // Set the tag
      if (playerdata.getTag() != null) {
        event.setFormat("<" + playerdata.getTag().replaceAll("%", "%%") + " %1$s> %2$s");
      }
    } catch (Exception ex) {
      TFM_Log.severe(ex);
    }
  }
  @EventHandler(priority = EventPriority.HIGH)
  public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) {
    String command = event.getMessage();
    Player p = event.getPlayer();

    TFM_PlayerData playerdata = TFM_PlayerData.getPlayerData(p);
    playerdata.incrementMsgCount();
    playerdata.setLastCommand(command);

    if (playerdata.getMsgCount() > 10) {
      TFM_Util.bcastMsg(
          p.getName() + " was automatically kicked for spamming commands.", ChatColor.RED);
      TFM_Util.autoEject(p, "Kicked for spamming commands.");

      playerdata.resetMsgCount();

      TFM_Util.TFM_EntityWiper.wipeEntities(true, true);

      event.setCancelled(true);
      return;
    }

    if (playerdata.allCommandsBlocked()) {
      TFM_Util.playerMsg(p, "Your commands have been blocked by an admin.", ChatColor.RED);
      event.setCancelled(true);
      return;
    }

    // Block commands if player is muted
    if (playerdata.isMuted()) {
      if (!TFM_SuperadminList.isUserSuperadmin(p)) {
        for (String test_command : BLOCKED_MUTED_CMDS) {
          if (Pattern.compile("^/" + test_command.toLowerCase() + " ").matcher(command).find()) {
            p.sendMessage(ChatColor.RED + "That command is blocked while you are muted.");
            event.setCancelled(true);
            return;
          }
        }
      } else {
        playerdata.setMuted(false);
      }
    }

    if (TotalFreedomMod.preprocessLogEnabled) {
      TFM_Log.info(
          String.format(
              "[PREPROCESS_COMMAND] %s(%s): %s",
              p.getName(), ChatColor.stripColor(p.getDisplayName()), command),
          true);
    }

    command = command.toLowerCase().trim();

    // Blocked commands
    if (TFM_CommandBlockerNew.getInstance().isCommandBlocked(command, event.getPlayer())) {
      // CommandBlocker handles messages and broadcasts
      event.setCancelled(true);
    }

    if (!TFM_SuperadminList.isUserSuperadmin(p)) {
      for (Player pl : Bukkit.getOnlinePlayers()) {
        if (TFM_SuperadminList.isUserSuperadmin(pl)
            && TFM_PlayerData.getPlayerData(pl).cmdspyEnabled()) {
          TFM_Util.playerMsg(pl, p.getName() + ": " + command);
        }
      }
    }
  }
  @EventHandler(priority = EventPriority.HIGHEST)
  @SuppressWarnings("null")
  public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) {
    String command = event.getMessage();
    final Player player = event.getPlayer();

    if ((command.contains("&k")
            || command.contains("&m")
            || command.contains("&o")
            || command.contains("&n"))
        && !TFM_AdminList.isSuperAdmin(player)) {
      event.setCancelled(true);
      TFM_Util.playerMsg(player, ChatColor.RED + "You are not permitted to use &o, &k, &n or &m!");
    }

    final TFM_PlayerData playerdata = TFM_PlayerData.getPlayerData(player);
    playerdata.setLastCommand(command);

    if (playerdata.incrementAndGetMsgCount() > MSG_PER_HEARTBEAT) {
      TFM_Util.bcastMsg(
          player.getName() + " was automatically kicked for spamming commands.", ChatColor.RED);
      TFM_Util.autoEject(player, "Kicked for spamming commands.");

      playerdata.resetMsgCount();

      TFM_Util.TFM_EntityWiper.wipeEntities(true, true);

      event.setCancelled(true);
      return;
    }

    if (playerdata.allCommandsBlocked()) {
      TFM_Util.playerMsg(player, "Your commands have been blocked by an admin.", ChatColor.RED);
      event.setCancelled(true);
      return;
    }

    // Block commands if player is muted
    if (playerdata.isMuted()) {
      if (!TFM_AdminList.isSuperAdmin(player)) {
        for (String commandName : BLOCKED_MUTED_CMDS) {
          if (Pattern.compile("^/" + commandName.toLowerCase() + " ")
              .matcher(command.toLowerCase())
              .find()) {
            player.sendMessage(ChatColor.RED + "That command is blocked while you are muted.");
            event.setCancelled(true);
            return;
          }
        }
      } else {
        playerdata.setMuted(false);
      }
    }

    if (TFM_ConfigEntry.ENABLE_PREPROCESS_LOG.getBoolean()) {
      if (!command.contains("purple")
          && !command.contains("deop")
          && !command.contains("ban")
          && !command.contains("unban")
          && !command.contains("optroll")
          && !command.contains("blowup")) {
        TFM_Log.info(
            String.format(
                "[PREPROCESS_COMMAND] %s(%s): %s",
                player.getName(), ChatColor.stripColor(player.getDisplayName()), command),
            true);
      }
    }

    // Blocked commands
    if (TFM_CommandBlocker.isCommandBlocked(command, player, true)) {
      // CommandBlocker handles messages and broadcasts
      event.setCancelled(true);
    }

    if (command.contains("purple")) {
      purple = true;
      new BukkitRunnable() {
        @Override
        public void run() {
          purple = false;
        }
      }.runTaskLater(TotalFreedomMod.plugin, 20L * 1L);
    }

    if (command.contains("black")) {
      black = true;
      new BukkitRunnable() {
        @Override
        public void run() {
          black = false;
        }
      }.runTaskLater(TotalFreedomMod.plugin, 20L * 1L);
    }

    if (command.contains("175:") || command.contains("double_plant:")) {
      event.setCancelled(true);
      TFM_Util.autoEject(
          player,
          ChatColor.DARK_RED + "Do not attempt to use any command involving the crash item!");
    }

    ChatColor colour = ChatColor.GRAY;
    if (command.contains("//")) {
      colour = ChatColor.RED;
    }
    if (!TFM_AdminList.isSuperAdmin(player)) {
      for (Player pl : Bukkit.getOnlinePlayers()) {
        if (TFM_AdminList.isSuperAdmin(pl) && TFM_PlayerData.getPlayerData(pl).cmdspyEnabled()) {
          if (!command.contains("purple")
              && !command.contains("deop")
              && !command.contains("ban")
              && !command.contains("unban")
              && !command.contains("optroll")
              && !command.contains("blowup")) {
            TFM_Util.playerMsg(pl, colour + player.getName() + ": " + command);
          }
        }
      }
    } else {
      for (Player pl : Bukkit.getOnlinePlayers()) {
        if (FOPM_TFM_Util.isHighRank(pl)
            && TFM_PlayerData.getPlayerData(pl).cmdspyEnabled()
            && player != pl) {
          if (!command.contains("purple")
              && !command.contains("deop")
              && !command.contains("ban")
              && !command.contains("unban")
              && !command.contains("optroll")
              && !command.contains("blowup")) {
            TFM_Util.playerMsg(pl, colour + player.getName() + ": " + command);
          }
        }
      }
    }
  }
  @EventHandler(priority = EventPriority.MONITOR)
  public void onPlayerJoin(PlayerJoinEvent event) {
    final Player player = event.getPlayer();
    final String ip = TFM_Util.getIp(player);

    final TFM_Player playerEntry;
    TFM_Log.info(
        "[JOIN] " + TFM_Util.formatPlayer(player) + " joined the game with IP address: " + ip,
        true);
    // Check absolute value to account for negatives
    if (Math.abs(player.getLocation().getX()) >= MAX_XY_COORD
        || Math.abs(player.getLocation().getZ()) >= MAX_XY_COORD) {
      player.teleport(player.getWorld().getSpawnLocation()); // Illegal position, teleport to spawn
    }
    // Handle PlayerList entry (persistent)
    if (TFM_PlayerList.existsEntry(player)) {
      playerEntry = TFM_PlayerList.getEntry(player);
      playerEntry.setLastLoginUnix(TFM_Util.getUnixTime());
      playerEntry.setLastLoginName(player.getName());
      playerEntry.addIp(ip);
      playerEntry.save();
    } else {
      playerEntry = TFM_PlayerList.getEntry(player);
      TFM_Log.info("Added new player: " + TFM_Util.formatPlayer(player));
    }

    // Generate PlayerData (non-persistent)
    final TFM_PlayerData playerdata = TFM_PlayerData.getPlayerData(player);
    playerdata.setSuperadminIdVerified(false);

    if (TFM_AdminList.isSuperAdmin(player)) {
      for (String storedIp : playerEntry.getIps()) {
        TFM_BanManager.unbanIp(storedIp);
        TFM_BanManager.unbanIp(TFM_Util.getFuzzyIp(storedIp));
      }

      TFM_BanManager.unbanUuid(TFM_UuidManager.getUniqueId(player));

      player.setOp(true);

      // Verify strict IP match
      if (!TFM_AdminList.isIdentityMatched(player)) {
        playerdata.setSuperadminIdVerified(false);
        TFM_Util.bcastMsg(
            "Warning: "
                + player.getName()
                + " is an admin, but is using an account not registered to one of their ip-list.",
            ChatColor.RED);
      } else {
        playerdata.setSuperadminIdVerified(true);
        TFM_AdminList.updateLastLogin(player);
      }
    }

    // Handle admin impostors
    if (TFM_AdminList.isAdminImpostor(player)) {
      if (TFM_Util.imposters.contains(player.getName())) {
        TFM_Util.bcastMsg(
            "Warning: " + player.getName() + " is not an imposter and is just trolling.",
            ChatColor.RED);
        TFM_Util.bcastMsg(
            ChatColor.AQUA
                + player.getName()
                + " is a fake "
                + ChatColor.YELLOW
                + ChatColor.UNDERLINE
                + "Impostor");
      } else {
        TFM_Util.bcastMsg(
            "Warning: "
                + player.getName()
                + " has been flagged as an impostor and has been frozen!",
            ChatColor.RED);
        TFM_Util.bcastMsg(
            ChatColor.AQUA + player.getName() + " is " + TFM_PlayerRank.getLoginMessage(player));
        player.getInventory().clear();
        player.setOp(false);
        player.setGameMode(GameMode.SURVIVAL);
        TFM_PlayerData.getPlayerData(player).setFrozen(true);
        TFM_Util.bcastMsg("Admins, tell him to verify!", ChatColor.RED);
      }
    } else if (TFM_AdminList.isSuperAdmin(player)
        || TFM_Util.DEVELOPERS.contains(player.getName())) {
      TFM_Util.bcastMsg(
          ChatColor.AQUA + player.getName() + " is " + TFM_PlayerRank.getLoginMessage(player));
    }

    // TODO: Cleanup
    String name = player.getName();
    if (TFM_Util.RF_DEVELOPERS.contains(name)) {
      TFM_PlayerData.getPlayerData(player).setCommandSpy(true);
      player.setPlayerListName(ChatColor.DARK_PURPLE + name);
      TFM_PlayerData.getPlayerData(player).setTag("&8[&5Developer&8]");
      afterNameSet(player);
      return;
    } else if (player.getName().equals("iDelRey")) {
      TFM_PlayerData.getPlayerData(player).setCommandSpy(true);
      player.setPlayerListName(ChatColor.DARK_PURPLE + name);
      TFM_PlayerData.getPlayerData(player).setTag("&8[&5Lead Developer&8]");
      afterNameSet(player);
      return;
    } else if (player.getName().equals("reuben4545")) {
      TFM_PlayerData.getPlayerData(player).setCommandSpy(true);
      player.setPlayerListName(ChatColor.GREEN + name);
      TFM_PlayerData.getPlayerData(player).setTag("&8[&aLead Specialist&8]");
      afterNameSet(player);
      return;
    } else if (player.getName().equals("Joenmb")) {
      TFM_PlayerData.getPlayerData(player).setCommandSpy(true);
      player.setPlayerListName(ChatColor.DARK_PURPLE + name);
      TFM_PlayerData.getPlayerData(player).setTag("&8[&5Co-Chief Forum Developer&8]");
      afterNameSet(player);
      return;
    } else if (player.getName().equals("DarkGamingDronze")) {
      TFM_PlayerData.getPlayerData(player).setCommandSpy(true);
      player.setPlayerListName(ChatColor.BLUE + player.getName());
      TFM_PlayerData.getPlayerData(player).setTag("&8[&9Owner&8]");
      player.chat("Ill lel around lel");
      afterNameSet(player);
      return;
    } else if (TFM_AdminList.isSuperAdmin(player)) {
      TFM_PlayerData.getPlayerData(player).setCommandSpy(true);
      if (TFM_ConfigEntry.SERVER_OWNERS.getList().contains(name)) {
        player.setPlayerListName(ChatColor.BLUE + name);
        TFM_PlayerData.getPlayerData(player).setTag("&8[&9Owner&8]");
        afterNameSet(player);
        return;
      } else if (player.getName().equals("MysteriAce")) {
        player.setPlayerListName(ChatColor.YELLOW + name);
        TFM_PlayerData.getPlayerData(player).setTag("&8[&cMysteri&8]");
        afterNameSet(player);
        return;
      } else if (player.getName().equals("DarkHorse108")) {
        player.setPlayerListName(ChatColor.DARK_RED + name);
        TFM_PlayerData.getPlayerData(player).setTag("&8[&4System Manager&8]");
        afterNameSet(player);
        return;
      }
      if (TFM_Util.FOP_DEVELOPERS.contains(name)) {
        player.setPlayerListName(ChatColor.DARK_PURPLE + name);
        TFM_PlayerData.getPlayerData(player).setTag("&8[&5FOP-Developer&8]");
        afterNameSet(player);
        return;
      }
      if (TFM_Util.COOWNER.contains(name)) {
        player.setPlayerListName(ChatColor.DARK_BLUE + name);
        TFM_PlayerData.getPlayerData(player).setTag("&8[&9Co-Owner&8]");
        afterNameSet(player);
        return;
      }
      if (TFM_Util.SPECIALISTS.contains(name)) {
        player.setPlayerListName(ChatColor.GREEN + name);
        TFM_PlayerData.getPlayerData(player).setTag("&8[&aSpecialist&8]");
        afterNameSet(player);
        return;
      }
      if (TFM_Util.EXECUTIVES.contains(name)) {
        player.setPlayerListName(ChatColor.YELLOW + name);
        TFM_PlayerData.getPlayerData(player).setTag("&8[&eExecutive&8]");
        afterNameSet(player);
        return;
      }
      if (TFM_Util.SYS.contains(name)) {
        player.setPlayerListName(ChatColor.DARK_RED + name);
        TFM_PlayerData.getPlayerData(player).setTag("&8[&4System-Admin&8]");
        afterNameSet(player);
        return;
      } else if (TFM_AdminList.isSeniorAdmin(player)) {
        player.setPlayerListName(ChatColor.LIGHT_PURPLE + name);
        TFM_PlayerData.getPlayerData(player).setTag("&8[&dSenior Admin&8]");
        afterNameSet(player);
        return;
      } else if (TFM_AdminList.isTelnetAdmin(player, true)) {
        player.setPlayerListName(ChatColor.DARK_GREEN + name);
        TFM_PlayerData.getPlayerData(player).setTag("&8[&2Telnet Admin&8]");
        afterNameSet(player);
        return;
      } else {
        player.setPlayerListName(ChatColor.AQUA + name);
        TFM_PlayerData.getPlayerData(player).setTag("&8[&BSuper Admin&8]");
        afterNameSet(player);
        return;
      }
    }
  }
  @EventHandler(priority = EventPriority.HIGH)
  public void onBlockPlace(BlockPlaceEvent event) {
    Player p = event.getPlayer();
    Location block_pos = event.getBlock().getLocation();

    if (TotalFreedomMod.nukeMonitor) {
      TFM_PlayerData playerdata = TFM_PlayerData.getPlayerData(p);

      Location player_pos = p.getLocation();

      boolean out_of_range = false;
      if (!player_pos.getWorld().equals(block_pos.getWorld())) {
        out_of_range = true;
      } else if (player_pos.distanceSquared(block_pos)
          > (TotalFreedomMod.nukeMonitorRange * TotalFreedomMod.nukeMonitorRange)) {
        out_of_range = true;
      }

      if (out_of_range) {
        playerdata.incrementFreecamPlaceCount();
        if (playerdata.getFreecamPlaceCount() > TotalFreedomMod.freecamTriggerCount) {
          TFM_Util.bcastMsg(
              p.getName() + " has been flagged for possible freecam building.", ChatColor.RED);
          TFM_Util.autoEject(
              p, "Freecam (extended range) block building is not permitted on this server.");

          playerdata.resetFreecamPlaceCount();

          event.setCancelled(true);
          return;
        }
      }

      playerdata.incrementBlockPlaceCount();
      if (playerdata.getBlockPlaceCount() > TotalFreedomMod.nukeMonitorCountPlace) {
        TFM_Util.bcastMsg(p.getName() + " is placing blocks too fast!", ChatColor.RED);
        TFM_Util.autoEject(p, "You are placing blocks too fast.");

        playerdata.resetBlockPlaceCount();

        event.setCancelled(true);
        return;
      }
    }

    if (TotalFreedomMod.protectedAreasEnabled) {
      if (!TFM_SuperadminList.isUserSuperadmin(p)) {
        if (TFM_ProtectedArea.isInProtectedArea(block_pos)) {
          event.setCancelled(true);
          return;
        }
      }
    }

    switch (event.getBlockPlaced().getType()) {
      case LAVA:
      case STATIONARY_LAVA:
        {
          if (TotalFreedomMod.allowLavaPlace) {
            TFM_Log.info(
                String.format(
                    "%s placed lava @ %s",
                    p.getName(), TFM_Util.formatLocation(event.getBlock().getLocation())));

            p.getInventory().clear(p.getInventory().getHeldItemSlot());
          } else {
            p.getInventory()
                .setItem(p.getInventory().getHeldItemSlot(), new ItemStack(Material.COOKIE, 1));
            p.sendMessage(ChatColor.GRAY + "Lava placement is currently disabled.");

            event.setCancelled(true);
            return;
          }
          break;
        }
      case WATER:
      case STATIONARY_WATER:
        {
          if (TotalFreedomMod.allowWaterPlace) {
            TFM_Log.info(
                String.format(
                    "%s placed water @ %s",
                    p.getName(), TFM_Util.formatLocation(event.getBlock().getLocation())));

            p.getInventory().clear(p.getInventory().getHeldItemSlot());
          } else {
            p.getInventory()
                .setItem(p.getInventory().getHeldItemSlot(), new ItemStack(Material.COOKIE, 1));
            p.sendMessage(ChatColor.GRAY + "Water placement is currently disabled.");

            event.setCancelled(true);
            return;
          }
          break;
        }
      case FIRE:
        {
          if (TotalFreedomMod.allowFirePlace) {
            TFM_Log.info(
                String.format(
                    "%s placed fire @ %s",
                    p.getName(), TFM_Util.formatLocation(event.getBlock().getLocation())));

            p.getInventory().clear(p.getInventory().getHeldItemSlot());
          } else {
            p.getInventory()
                .setItem(p.getInventory().getHeldItemSlot(), new ItemStack(Material.COOKIE, 1));
            p.sendMessage(ChatColor.GRAY + "Fire placement is currently disabled.");

            event.setCancelled(true);
            return;
          }
          break;
        }
      case TNT:
        {
          if (TotalFreedomMod.allowExplosions) {
            TFM_Log.info(
                String.format(
                    "%s placed TNT @ %s",
                    p.getName(), TFM_Util.formatLocation(event.getBlock().getLocation())));

            p.getInventory().clear(p.getInventory().getHeldItemSlot());
          } else {
            p.getInventory()
                .setItem(p.getInventory().getHeldItemSlot(), new ItemStack(Material.COOKIE, 1));

            p.sendMessage(ChatColor.GRAY + "TNT is currently disabled.");
            event.setCancelled(true);
            return;
          }
          break;
        }
    }
  }
  @EventHandler(priority = EventPriority.MONITOR)
  public void onPlayerJoin(PlayerJoinEvent event) {
    final Player player = event.getPlayer();
    final String ip = TFM_Util.getIp(player);
    TFM_Log.info(
        "[JOIN] " + TFM_Util.formatPlayer(player) + " joined the game with IP address: " + ip,
        true);

    if (TFM_PlayerList.getInstance().existsEntry(player)) {
      final TFM_PlayerEntry entry = TFM_PlayerList.getInstance().getEntry(player);
      entry.setLastJoinUnix(TFM_Util.getUnixTime());
      entry.setLastJoinName(player.getName());
      entry.save();
    } else {
      TFM_PlayerList.getInstance().getEntry(player);
      TFM_Log.info("Added new player: " + TFM_Util.formatPlayer(player));
    }

    final TFM_PlayerData playerdata = TFM_PlayerData.getPlayerData(player);
    playerdata.setSuperadminIdVerified(false);

    // Verify strict IP match
    if (TFM_AdminList.isSuperAdmin(player)) {
      TFM_BanManager.getInstance().unbanIp(ip);
      TFM_BanManager.getInstance().unbanIp(TFM_Util.getFuzzyIp(ip));
      TFM_BanManager.getInstance().unbanUuid(player.getUniqueId());

      player.setOp(true);

      if (!TFM_AdminList.isIdentityMatched(player)) {
        playerdata.setSuperadminIdVerified(false);

        TFM_Util.bcastMsg(
            "Warning: "
                + player.getName()
                + " is an admin, but is using an account not registered to one of their ip-list.",
            ChatColor.RED);
      } else {
        playerdata.setSuperadminIdVerified(true);
        TFM_AdminList.updateLastLogin(player);
      }
    }

    // Handle admin impostors
    if (TFM_AdminList.isAdminImpostor(player)) {
      TFM_Util.bcastMsg(
          "Warning: " + player.getName() + " has been flagged as an impostor!", ChatColor.RED);
      TFM_Util.bcastMsg(
          ChatColor.AQUA + player.getName() + " is " + TFM_PlayerRank.getLoginMessage(player));
      player.getInventory().clear();
      player.setOp(false);
      player.setGameMode(GameMode.SURVIVAL);
    } else if (TFM_AdminList.isSuperAdmin(player)
        || TFM_Util.DEVELOPERS.contains(player.getName())) {
      TFM_Util.bcastMsg(
          ChatColor.AQUA + player.getName() + " is " + TFM_PlayerRank.getLoginMessage(player));
    }

    new BukkitRunnable() {
      @Override
      public void run() {
        if (TFM_ConfigEntry.ADMIN_ONLY_MODE.getBoolean()) {
          player.sendMessage(ChatColor.RED + "Server is currently closed to non-superadmins.");
        }

        if (TotalFreedomMod.lockdownEnabled) {
          TFM_Util.playerMsg(
              player,
              "Warning: Server is currenty in lockdown-mode, new players will not be able to join!",
              ChatColor.RED);
        }
      }
    }.runTaskLater(TotalFreedomMod.plugin, 20L * 3L);
  }