Skip to content

Commit

Permalink
Add Version Checker
Browse files Browse the repository at this point in the history
Adds a version checker as defined in #3
  • Loading branch information
stumper66 committed Nov 13, 2024
1 parent 93f55bf commit 2611a5a
Show file tree
Hide file tree
Showing 10 changed files with 396 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package io.github.arcaneplugins.blackwidow.lib.cmdblocking;

import java.io.FileNotFoundException;
import java.io.InputStream;
import java.net.URI;
import java.util.Scanner;
import java.util.function.Consumer;

public class UpdateChecker {
public UpdateChecker(String resourceName){
this.resourceName = resourceName;
}

private final String resourceName;
private String errorMessage;

public boolean hadError(){
return errorMessage != null;
}

public String getErrorMessage(){
return errorMessage;
}

public boolean getLatestVersion(Consumer<String> consumer){

try (InputStream inputStream = new URI(
"https://hangar.papermc.io/api/v1/projects/" +
resourceName + "/latest?channel=Release")
.toURL().openStream()){

final Scanner scanner = new Scanner(inputStream);
if (scanner.hasNext()){
consumer.accept(scanner.next());
}
return true;
}
catch (FileNotFoundException e){
errorMessage = "Error checking for latest version, file not found: " + e.getMessage();
}
catch (Exception e){
errorMessage = "Error checking for latest version. " + e.getMessage();
}

return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import io.github.arcaneplugins.blackwidow.plugin.bukkit.component.cmdblocking.CmdBlocker;
import io.github.arcaneplugins.blackwidow.plugin.bukkit.listener.ListenerManager;
import io.github.arcaneplugins.blackwidow.plugin.bukkit.logic.LogicManager;
import io.github.arcaneplugins.blackwidow.plugin.bukkit.logic.BukkitVersionChecker;
import io.github.arcaneplugins.blackwidow.plugin.bukkit.util.ClassUtil;
import io.github.arcaneplugins.blackwidow.plugin.bukkit.util.DebugCategory;
import io.github.arcaneplugins.blackwidow.plugin.bukkit.util.ExceptionUtil;
Expand Down Expand Up @@ -54,6 +55,7 @@ public final class BlackWidow extends JavaPlugin {
private final LogicManager logicManager = new LogicManager(this);
private final EnumSet<DebugCategory> debugCategories = EnumSet.noneOf(DebugCategory.class);
private final MiniMessage miniMessage = MiniMessage.miniMessage();
public final BukkitVersionChecker bukkitVersionChecker = new BukkitVersionChecker(this);

private boolean usingPaper = false;
private BukkitAudiences adventure = null;
Expand Down Expand Up @@ -97,6 +99,7 @@ public void onEnable() {
loadComponents();
listenerManager().load();
commandManager().load();
bukkitVersionChecker.load(true);
} catch (Exception ex) {
ExceptionUtil.logException(this, ex, "An error occurred whilst enabling BlackWidow.");
return;
Expand Down Expand Up @@ -149,6 +152,7 @@ public void softReload() {
loadConfigs();
logicManager().load();
loadComponents();
bukkitVersionChecker.load(false);
} catch (Exception ex) {
ExceptionUtil.logException(this, ex, "An error occurred whilst performing a soft-reload.");
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,21 @@ public final void load() {
"this issue ASAP, as a manually-adjusted file version can cause instability.");
}
if (installedVer < latestVer) {
int lastVersion = installedFileVersion();
plugin().getLogger().info("Config '" + fileName() + "' is outdated, automatically upgrading.");
while (installedVer < latestFileVersion()) {
plugin().getLogger().info("Upgrading '" + fileName() + "' from v" +
installedVer + " to v" + (installedVer + 1) + ".");
upgradeFile();
write();
installedVer = installedFileVersion();
if (installedVer == lastVersion){
// prevent potential endless loop
plugin().getLogger().warning("There was an error upgrading the file version, " +
"the version number was not incremented");
break;
}
lastVersion = installedVer;
}
} else if (installedVer > latestVer) {
plugin().getLogger().warning("Config '" + fileName() + "' apparently has version '" + installedVer +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@
import io.github.arcaneplugins.blackwidow.plugin.bukkit.BlackWidow;
import io.github.arcaneplugins.blackwidow.plugin.bukkit.cfg.YamlCfg;
import io.github.arcaneplugins.blackwidow.plugin.bukkit.util.DebugCategory;
import org.spongepowered.configurate.CommentedConfigurationNode;
import org.spongepowered.configurate.ConfigurateException;
import org.spongepowered.configurate.serialize.SerializationException;

import java.util.Collections;
import java.util.Objects;
Expand All @@ -32,7 +34,7 @@ public final class Settings extends YamlCfg {
// REMEMBER TO UPDATE THE METHOD BELOW 'upgradeFile' IF THIS IS INCREMENTED.
// ALSO REMEMBER TO UPDATE THE FILE ITSELF - BOTH THE 'original' AND 'installed' VALUES SHOULD MATCH THIS.
// <<< !!! WARNING !!! NOTICE THIS MESSAGE !!! >>>
private static final int LATEST_FILE_VERSION = 1;
private static final int LATEST_FILE_VERSION = 2;

public Settings(
final BlackWidow plugin
Expand Down Expand Up @@ -81,10 +83,21 @@ public void upgradeFile() {
//noinspection SwitchStatementWithTooFewBranches
switch (installedVer) {
case 1 -> {
// Do nothing.
final CommentedConfigurationNode rootNode = root().node("cmd-blocking");
final CommentedConfigurationNode newNode = rootNode.node("update-checker");
try {
newNode.act(n -> {
newNode.node("enabled").set(Boolean.class, true);
newNode.node("run-on-startup").set(Boolean.class, true);
newNode.node("repeat-timer-duration-mins").set(Integer.class, 60);
newNode.node("log-updates").set(Boolean.class, true);
newNode.node("notify-players-with-permission").set(Boolean.class, true);
});

//noinspection UnnecessaryBreak
break;
root().node("do-not-touch", "version").node("installed").set(2);
} catch (SerializationException e) {
plugin().getLogger().warning("");
}
}
default -> throw new IllegalArgumentException("No upgrade logic defined for file version v" + installedVer);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,13 @@
import io.github.arcaneplugins.blackwidow.plugin.bukkit.BlackWidow;
import io.github.arcaneplugins.blackwidow.plugin.bukkit.listener.bukkit.PlayerCommandPreprocessListener;
import io.github.arcaneplugins.blackwidow.plugin.bukkit.listener.bukkit.PlayerCommandSendListener;
import io.github.arcaneplugins.blackwidow.plugin.bukkit.listener.bukkit.PlayerJoinListener;
import io.github.arcaneplugins.blackwidow.plugin.bukkit.listener.paper.AsyncPlayerCommandSendListener;
import org.bukkit.event.Listener;

import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;

public final class ListenerManager {

Expand All @@ -39,9 +41,10 @@ public ListenerManager(
}

private void constructListeners() {
listeners().add(
new PlayerCommandPreprocessListener(plugin())
);
listeners().addAll(List.of(
new PlayerCommandPreprocessListener(plugin()),
new PlayerJoinListener(plugin())
));

listeners().add(
plugin().usingPaper() && plugin().usePaperFeatures() ?
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package io.github.arcaneplugins.blackwidow.plugin.bukkit.listener.bukkit;

import io.github.arcaneplugins.blackwidow.plugin.bukkit.BlackWidow;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;

public class PlayerJoinListener implements Listener {
private final BlackWidow plugin;

public PlayerJoinListener(final BlackWidow plugin){
this.plugin = plugin;
}

@EventHandler(ignoreCancelled = true)
public void handle(final PlayerJoinEvent event){
if (!plugin.bukkitVersionChecker.getNotifyPlayers()) {
return;
}

final String message = plugin.bukkitVersionChecker.getNotifyMessage();
if (message == null){
return;
}

event.getPlayer().sendMessage(message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
package io.github.arcaneplugins.blackwidow.plugin.bukkit.logic;

import io.github.arcaneplugins.blackwidow.lib.cmdblocking.UpdateChecker;
import io.github.arcaneplugins.blackwidow.plugin.bukkit.BlackWidow;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitTask;
import org.spongepowered.configurate.CommentedConfigurationNode;

import java.io.InvalidObjectException;

public class BukkitVersionChecker {
public BukkitVersionChecker(final BlackWidow plugin){
this.plugin = plugin;
}

private final BlackWidow plugin;
private BukkitTask notifyTask;
boolean logUpdates;
private boolean notifyPlayers;
private String notifyMessage;
private int lastTimerDuration;

public void load(final boolean isStartup){
final CommentedConfigurationNode settings = plugin.settings().root()
.node("cmd-blocking", "update-checker");

final boolean enabled = settings.node("enabled").getBoolean(true);
final boolean runOnStartup = settings.node("run-on-startup").getBoolean(true);
final int repeatTimerDuration = settings.node("repeat-timer-duration-mins").getInt();
logUpdates = settings.node("log-updates").getBoolean(true);
notifyPlayers = settings.node("notify-players-with-permission").getBoolean(true);

if (!enabled){
disableChecker();
return;
}

startTimerIfNeeded(repeatTimerDuration);

if (runOnStartup && isStartup){
getLatestVersion();
}
}

public boolean getNotifyPlayers(){
return notifyPlayers;
}

public String getNotifyMessage(){
return notifyMessage;
}

private void disableChecker(){
if (notifyTask != null && !notifyTask.isCancelled()){
notifyTask.cancel();
notifyTask = null;
}
}

private void startTimerIfNeeded(final int repeatTimerDuration){
if (repeatTimerDuration <= 0){
disableChecker();
return;
}

if (notifyTask != null && !notifyTask.isCancelled()
&& repeatTimerDuration == lastTimerDuration){
return;
}

disableChecker();

final BukkitRunnable runnable = new BukkitRunnable() {
@Override
public void run() {
getLatestVersion();
}
};

lastTimerDuration = repeatTimerDuration;
final long delay = repeatTimerDuration * 20L * 60L;
this.notifyTask = runnable.runTaskTimerAsynchronously(plugin, delay, delay);
}

private void getLatestVersion(){
new BukkitRunnable() {
@Override
public void run() {
checkForLatestVersion();
}
}.runTaskAsynchronously(plugin);
}

private void checkForLatestVersion(){
// this function
final UpdateChecker updateChecker = new UpdateChecker("BlackWidow");

try{
updateChecker.getLatestVersion(latestVersion -> {
//noinspection deprecation
final String currentVersion = plugin.getDescription().getVersion()
.split(" ")[0];

if (latestVersion == null && logUpdates){
plugin.getLogger().warning("Error check for latest version, string was null");
return;
}

final VersionInfo thisVersion;
final VersionInfo hangarVersion;
boolean isOutOfDate;
boolean isNewerVersion = false;
boolean wasUpToDate = false;

try{
thisVersion = new VersionInfo(currentVersion);
hangarVersion = new VersionInfo(latestVersion);

isOutOfDate = (thisVersion.compareTo(hangarVersion) < 0);
isNewerVersion = (thisVersion.compareTo(hangarVersion) > 0);
}
catch (InvalidObjectException e){
plugin.getLogger().warning("Got exception creating version objects: " + e.getMessage());
isOutOfDate = !currentVersion.equals(latestVersion);
}

if (isNewerVersion){
notifyMessage = "Your BlackWindow version is a pre-release. Latest release version is " + latestVersion + ". (You're running " + currentVersion + ")";
}
else if (isOutOfDate){
notifyMessage = "Your BlackWidow version is outdated! Please update to " + latestVersion + " as soon as possible. (You're running " + currentVersion + ")";
}
else{
notifyMessage = "Your BlackWidow version is up to date (You're running " + currentVersion + ")";
wasUpToDate = true;
}

if (logUpdates){
plugin.getLogger().info(notifyMessage);
}

if (!wasUpToDate){
notifyPlayers();
}
});
}
catch (Exception e){
plugin.getLogger().warning("Error getting latest version: " + e.getMessage());
}
}

private void notifyPlayers(){
if (!notifyPlayers || notifyMessage == null){
return;
}

final String requiredPermission = "blackwidow.notifyupdates";

for (final Player player : Bukkit.getOnlinePlayers()){
if (!player.isValid()){
continue;
}
if (!player.hasPermission(requiredPermission)){
continue;
}

player.sendMessage(notifyMessage);
}
}
}
Loading

0 comments on commit 2611a5a

Please sign in to comment.