FlexConnect/src/main/java/fi/flexplex/connect/util/FileChangeListener.java

69 lines
2.7 KiB
Java

package fi.flexplex.connect.util;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Paths;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import org.bukkit.Bukkit;
import fi.flexplex.connect.FlexConnect;
import fi.flexplex.connect.event.AsyncWhitelistChangedEvent;
public final class FileChangeListener {
final FlexConnect flexConnect;
final Thread thread;
boolean isRunning = true;
// Bukkit API does not provide good way to detect whitelist changes. So we need this quite interesting solution...
public FileChangeListener(final FlexConnect flexConnect, final String...files) {
this.flexConnect = flexConnect;
this.thread = new Thread() {
@Override
public void run() {
try {
final WatchService service = FileSystems.getDefault().newWatchService();
Paths.get(flexConnect.getServer().getWorldContainer().getPath()).register(service, StandardWatchEventKinds.ENTRY_MODIFY);
long lastRun = 0;
while (isRunning) {
final WatchKey key = service.take();
for (final WatchEvent<?> event : key.pollEvents()) {
final String fileName = String.valueOf(event.context());
for (final String file : files) {
if (file.equals(fileName)) {
// Cooldown because file change events are called quite many times
if (lastRun + 100 < System.currentTimeMillis()) {
Bukkit.getScheduler().runTaskLaterAsynchronously(
flexConnect,
() -> Bukkit.getPluginManager().callEvent(new AsyncWhitelistChangedEvent()),
20
);
lastRun = System.currentTimeMillis();
}
break;
}
}
}
key.reset();
}
} catch (final IOException e) {
e.printStackTrace();
} catch (final InterruptedException e) {
e.printStackTrace();
Thread.currentThread().interrupt();
}
}
};
this.thread.start();
}
public void stop() {
this.isRunning = false;
}
}