Збірка усіх плаґінів для WhoMine розроблених [MinersStudios](https://minersstudios.github.io).
package ua.com.minersstudios.whomine.util.misc;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import lombok.*;
import lombok.experimental.UtilityClass;
import ua.com.minersstudios.whomine.util.misc.WorldRegion;
import static java.text.MessageFormat.format;
import static org.bukkit.Bukkit.getLogger;
import static org.bukkit.Bukkit.getVersion;
import static ua.com.minersstudios.whomine.util.i18n.*;

// TODO: Handle this edge case:
// "If the value of compression scheme increases by 128, the compressed
// data is saved in a file called c.x.z.mcc, where x and z are the
// chunk's coordinates, instead of the usual position."

/**
 * Simple system that keeps track of activity on an unmodified, generated chunks,
 * and removes them if it meets criteria of "not so often visited chunk" (later, laƶy chunk).
 * Always triggers at server shutdown, if enabled (disabled by default).
 */
@UtilityClass
public class ChunkDegenerator
{
	private static boolean enabled;
	public static final String latestWorkingVersion;

	static
	{
		enabled = false; // Read enabled value from config or a command (WIP)
		latestWorkingVersion = "1.20.1";
		if (!getVersion().contains(latestWorkingVersion))
		{
			enabled = false;
			getLogger().warning(format("{0} {1}", i18n("All ChunkDegenerator instances are disabled. Request testing and patching from others, to return this functionality.",
			i18n("This is a protection against world corrupting from implementation changes, feel free to ignore this, if you're not a user of World Cleaners."))));
		}
	}

	@Getter
	@Setter
	private String worldFolder = "world";

	/**
	 * Conclude given chunk's activity by how many players visit it.
	 * @param x chunk longitude
	 * @param z chunk latitude
	 */
	private void getChunkActivity(final int x, final int z)
	{
		int regionX = x / 32;
		int regionZ = z / 32;

		File regionsDir = new File(format("{0}{1}region", worldFolder, File.pathSeparator));
		if (!regionsDir.isDirectory())
		{
			getLogger().severe(format(i18n("{0} is not a directory or does not exist. World path is probably wrong."), new Object[] { regionsDir.getAbsolutePath() }));
		}

		List<WorldRegion> worldRegions = new ArrayList<>();
		for (File f : regionsDir.listFiles())
		{
			if (!f.getName().matches("r\\.-?[0-9]+\\.-?[0-9]+\\.mca")) continue;
			if (!f.exists() || !f.isFile())
			{
				getLogger().warning(format(i18n("{0} is not a regular file."), new Object[] { f.getAbsolutePath() }));
			}
			if (!f.canRead() && !f.canWrite())
			{
				getLogger().warning(format(i18n("{0} is not writable for me. Cannot operate further."), new Object[] { f.getAbsolutePath() }));
			}
			try { worldRegions.add(new WorldRegion(f, "rw")); }
			catch (FileNotFoundException ex) {}
		}
	}
}