package xyz.nkomarn.Harbor.task; import org.bukkit.Bukkit; import org.bukkit.GameMode; import org.bukkit.World; import org.bukkit.entity.Player; import org.bukkit.metadata.MetadataValue; import xyz.nkomarn.Harbor.Harbor; import xyz.nkomarn.Harbor.util.Afk; import xyz.nkomarn.Harbor.util.Config; import xyz.nkomarn.Harbor.util.Messages; import java.util.HashSet; import java.util.List; import java.util.Set; import static java.util.stream.Collectors.toList; public class Checker implements Runnable { public static final Set<World> SKIPPING_WORLDS = new HashSet<>(); @Override public void run() { Bukkit.getWorlds().stream().filter(this::validateWorld).forEach(this::checkWorld); } private void checkWorld(final World world) { final int sleeping = getSleeping(world).size(); final int needed = getNeeded(world); if (sleeping > 0 && needed > 0) { final double sleepingPercentage = Math.min(1, (double) sleeping / getSkipAmount(world)); Messages.sendBossBarMessage(world, Config.getString("messages.bossbar.players-sleeping.message"), Config.getString("messages.bossbar.players-sleeping.color"), sleepingPercentage); Messages.sendActionBarMessage(world, Config.getString("messages.actionbar.players-sleeping")); } else if (needed == 0 && sleeping > 0) { Messages.sendBossBarMessage(world, Config.getString("messages.bossbar.night-skipping.message"), Config.getString("messages.bossbar.night-skipping.color"), 1); Messages.sendActionBarMessage(world, Config.getString("messages.actionbar.night-skipping")); if (!Config.getBoolean("night-skip.enabled")) return; if (Config.getBoolean("night-skip.instant-skip")) { Bukkit.getScheduler().runTask(Harbor.getHarbor(), () -> world.setTime(Config.getInteger("night-skip.daytime-ticks"))); Messages.sendRandomChatMessage(world, "messages.chat.night-skipped"); } else { SKIPPING_WORLDS.add(world); new AccelerateNightTask(world).runTaskTimer(Harbor.getHarbor(), 1, 1); } } } private boolean validateWorld(final World world) { return !isBlacklisted(world) && !SKIPPING_WORLDS.contains(world) && isNight(world); } private boolean isBlacklisted(final World world) { if (Config.getBoolean("whitelist-mode")) { return !Config.getConfig().getStringList("blacklisted-worlds").contains(world.getName()); } return Config.getConfig().getStringList("blacklisted-worlds").contains(world.getName()); } private boolean isNight(final World world) { return world.getTime() > 12950 || world.getTime() < 23950; } public static boolean isVanished(final Player player) { for (MetadataValue meta : player.getMetadata("vanished")) if (meta.asBoolean()) return true; return false; } public static List<Player> getSleeping(final World world) { return world.getPlayers().stream().filter(Player::isSleeping).collect(toList()); } public static int getSkipAmount(final World world) { return (int) Math.ceil(getPlayers(world) * (Config.getDouble("night-skip.percentage") / 100)); } public static int getPlayers(final World world) { return Math.max(0, world.getPlayers().size() - getExcluded(world).size()); } public static int getNeeded(final World world) { return Math.max(0, (int) Math.ceil((getPlayers(world)) * (Config.getDouble("night-skip.percentage") / 100) - getSleeping(world).size())); } private static List<Player> getExcluded(final World world) { return world.getPlayers().stream().filter(Checker::isExcluded).collect(toList()); } private static boolean isExcluded(final Player player) { final boolean excludedByAdventure = Config.getBoolean("exclusions.exclude-adventure") && player.getGameMode() == GameMode.ADVENTURE; final boolean excludedByCreative = Config.getBoolean("exclusions.exclude-creative") && player.getGameMode() == GameMode.CREATIVE; final boolean excludedBySpectator = Config.getBoolean("exclusions.exclude-spectator") && player.getGameMode() == GameMode.SPECTATOR; final boolean excludedByPermission = Config.getBoolean("exclusions.ignored-permission") && player.hasPermission("harbor.ignored"); final boolean excludedByVanish = Config.getBoolean("exclusions.exclude-vanished") && isVanished(player); return excludedByAdventure || excludedByCreative || excludedBySpectator || excludedByPermission || excludedByVanish || Afk.isAfk(player) || player.isSleepingIgnored(); } }