tweaks724/src/main/java/eu/m724/tweaks/updater/backend/UpdateChecker.java
2025-01-20 08:10:38 +01:00

103 lines
3.6 KiB
Java

/*
* Copyright (C) 2025 Minecon724
* Tweaks724 is licensed under the GNU General Public License. See the LICENSE.md file
* in the project root for the full license text.
*/
package eu.m724.tweaks.updater.backend;
import eu.m724.tweaks.DebugLogger;
import eu.m724.tweaks.Language;
import eu.m724.tweaks.updater.object.VersionedResource;
import org.bukkit.scheduler.BukkitRunnable;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.CompletionException;
import java.util.logging.Logger;
import java.util.stream.Collectors;
public class UpdateChecker extends BukkitRunnable {
private final Logger logger;
private final File cacheFile;
private final Set<VersionedResource> resources;
private final Set<VersionedResource> availableUpdates = new HashSet<>();
private long lastChecked = -1;
public UpdateChecker(Logger logger, File cacheFile, Set<VersionedResource> resources) {
this.logger = logger;
this.cacheFile = cacheFile;
this.resources = resources; // TODO make a copy?
}
private void checkAll() {
DebugLogger.fine("Checking for updates");
lastChecked = System.currentTimeMillis();
availableUpdates.clear();
for (VersionedResource versionedResource : Set.copyOf(resources)) {
String pluginName = versionedResource.resource().plugin().getName();
int page = versionedResource.running() != null ? versionedResource.running().page() : 1;
try {
VersionedResource newResource = new VersionScanner(versionedResource.resource(), page).join(); // this runs async so it's ok
if (!versionedResource.equals(newResource)) {
resources.remove(versionedResource);
if (newResource.running() == null) {
DebugLogger.warning("Unable to find installed version of %s", pluginName);
if (versionedResource.running() != null) {
DebugLogger.warning("Did you downgrade %s? If so, clear cache", pluginName);
}
} else {
if (!newResource.running().equals(newResource.latest())) {
availableUpdates.add(newResource);
}
}
resources.add(newResource);
}
} catch (CompletionException e) {
DebugLogger.severe("Unable to refresh %s: %s".formatted(pluginName, e.getMessage()));
}
}
}
private void alert() {
int n = availableUpdates.size();
if (n == 0) return;
logger.info(Language.getString("updateAvailableNotice", n));
availableUpdates.stream()
.map(u -> "- %s (%s -> %s)".formatted(u.resource().name(), u.running().label(), u.latest().label()))
.forEach(logger::info);
}
@Override
public void run() {
checkAll();
DebugLogger.finer("Done checking, now saving");
cacheFile.getParentFile().mkdirs();
try (FileOutputStream outputStream = new FileOutputStream(cacheFile)) {
VersionCache.writeAll(outputStream, resources.stream().map(VersionedResource::running).filter(Objects::nonNull).collect(Collectors.toSet()));
} catch (IOException e) {
throw new RuntimeException(e);
}
alert();
}
public long getLastChecked() {
return lastChecked;
}
public Set<VersionedResource> getAvailableUpdates() {
return availableUpdates;
}
}