/* * Copyright (C) 2024 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; import eu.m724.tweaks.Language; import eu.m724.tweaks.updater.cache.VersionedResource; import org.bukkit.plugin.Plugin; import org.bukkit.scheduler.BukkitRunnable; import java.io.FileOutputStream; import java.io.IOException; import java.time.LocalTime; import java.time.ZoneOffset; 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 Set resources; private final Logger logger; static final Set availableUpdates = new HashSet<>(); static LocalTime lastChecked = null; UpdateChecker(Plugin plugin, Set resources) { this.logger = Logger.getLogger(plugin.getLogger().getName() + "." + getClass().getSimpleName()); this.resources = resources; // TODO make a copy? } private void checkAll() { //logger.info("Checking for updates"); lastChecked = LocalTime.now(ZoneOffset.UTC); availableUpdates.clear(); for (VersionedResource versionedResource : Set.copyOf(resources)) { String pluginName = versionedResource.resource().plugin().getName(); //logger.info(versionedResource.resource().resourceId() + " " + versionedResource.resource().plugin().getName()); int page = versionedResource.running() != null ? versionedResource.running().page() : 1; try { VersionedResource newResource = new VersionFinder(versionedResource.resource(), page).join(); // this runs async so it's ok if (!versionedResource.equals(newResource)) { resources.remove(versionedResource); if (newResource.running() == null) { logger.info("Unable to find installed version of %s".formatted(pluginName)); if (versionedResource.running() != null) { logger.info("Did you downgrade %s? If so, clear cache".formatted(pluginName)); } } else { if (!newResource.running().equals(newResource.latest())) { availableUpdates.add(newResource); //logger.info("Update available for %s. %d -> %d".formatted(pluginName, newResource.running().updateId(), newResource.latest().updateId())); } } resources.add(newResource); } } catch (CompletionException e) { logger.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(); try (FileOutputStream outputStream = new FileOutputStream(UpdaterManager.cacheFile)) { VersionCheckCache.writeAll(outputStream, resources.stream().map(VersionedResource::running).filter(Objects::nonNull).collect(Collectors.toSet())); } catch (IOException e) { throw new RuntimeException(e); } alert(); } }