Skip to content

Commit

Permalink
Add update check feature
Browse files Browse the repository at this point in the history
  • Loading branch information
Kamesuta committed Feb 14, 2024
1 parent 28cdf01 commit 6a22432
Show file tree
Hide file tree
Showing 13 changed files with 185 additions and 2 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ The `config.yml` file includes the following settings, but not all items need to
- When updating the plugin, a warning will be displayed if this value does not match the plugin version.
- A `config.new.yml` file will be generated, and manual migration of settings using a merge tool is required.
- After migration, please change this value to the new version.
- `checkUpdate`: Set whether to check for plugin updates. The default is `true`.
- `language`: Set the language to be used. The default is English (`en`).
- Refer to the comments in the [config file](./src/main/resources/config.yml) for supported languages.
- `startTimeout`: After starting a server with this plugin, it will stop the server if there are no players for a certain period. The unit is seconds.
Expand Down
1 change: 1 addition & 0 deletions README_ja.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ https://github.com/Kamesuta/BungeePteroPower/assets/16362824/019fdfc5-f0fc-4532-
- プラグイン更新時、この値とプラグインのバージョンが一致しない場合、警告が表示されます。
- `config.new.yml` が生成されるためマージツールなどを用いて設定を手動で移行する必要があります。
- 移行後は、この値を新しいバージョンに変更してください。
- `checkUpdate`: プラグインの更新を確認するかどうかを設定します。デフォルトは `true` です。
- `language`: 使用する言語を設定します。デフォルトは英語(`en`)です。
- 対応している言語は[コンフィグ内のコメント](./src/main/resources/config.yml)を参照してください。
- `startTimeout`: このプラグインでサーバーを起動した後、一定時間プレイヤーがいない場合にサーバーを停止します。単位は秒です。
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>com.kamesuta</groupId>
<artifactId>BungeePteroPower</artifactId>
<version>1.5-SNAPSHOT</version>
<version>1.6-SNAPSHOT</version>
<packaging>jar</packaging>

<name>BungeePteroPower</name>
Expand Down
21 changes: 21 additions & 0 deletions src/main/java/com/kamesuta/bungeepteropower/BungeePteroPower.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
Expand All @@ -22,6 +23,10 @@ public final class BungeePteroPower extends Plugin implements BungeePteroPowerAP
* Plugin Configurations
*/
public Config config;
/**
* Version checker
*/
public UpdateChecker updateChecker;
/**
* Fallback Translations
*/
Expand Down Expand Up @@ -67,6 +72,22 @@ public void onEnable() {
// Check config
config.validateConfig(getProxy().getConsole());

// Check for updates
String runningVersion = plugin.getDescription().getVersion().replace("-SNAPSHOT", "");
updateChecker = new UpdateChecker(runningVersion);
if (config.checkUpdate) {
updateChecker.checkForUpdates().thenRun(() -> {
// Log the result when starting the plugin
if (updateChecker.isUpdateAvailable()) {
logger.info("An update is available: v" + updateChecker.getRunningVersion() + " -> v" + updateChecker.getNewVersion());
logger.info("You can download BungeePteroPower v" + updateChecker.getNewVersion() + " from " + updateChecker.getDownloadLink());
}
}).exceptionally(e -> {
logger.log(Level.WARNING, "Update check failed", e);
return null;
});
}

// Create DelayManager
delay = new DelayManager();

Expand Down
5 changes: 5 additions & 0 deletions src/main/java/com/kamesuta/bungeepteropower/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ public class Config {
* Config version
*/
public final int configVersion;
/**
* Whether to check for updates
*/
public final boolean checkUpdate;
/**
* Language
*/
Expand Down Expand Up @@ -97,6 +101,7 @@ public Config() {
try {
// Basic settings
this.configVersion = configuration.getInt("version", 0);
this.checkUpdate = configuration.getBoolean("checkUpdate", true);
this.language = configuration.getString("language");
this.startTimeout = configuration.getInt("startTimeout");
this.powerControllerType = configuration.getString("powerControllerType");
Expand Down
14 changes: 13 additions & 1 deletion src/main/java/com/kamesuta/bungeepteropower/PlayerListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,19 @@ public void onPlayerLogin(PostLoginEvent event) {
player.hasPermission("ptero.start." + server.getName());
player.hasPermission("ptero.stop." + server.getName());
}
player.hasPermission("ptero.reload");

// If the player has the permission to reload the config, notice update if available
if (player.hasPermission("ptero.reload")) {
// Show update message
if (plugin.updateChecker.isUpdateAvailable()) {
player.sendMessage(new ComponentBuilder()
.append(plugin.messages.info("update_available", plugin.updateChecker.getRunningVersion(), plugin.updateChecker.getNewVersion()))
.event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(plugin.messages.getMessage("update_available_tooltip", plugin.updateChecker.getRunningVersion(), plugin.updateChecker.getNewVersion()))))
.event(new ClickEvent(ClickEvent.Action.OPEN_URL, plugin.updateChecker.getDownloadLink()))
.create()
);
}
}
}

@EventHandler
Expand Down
123 changes: 123 additions & 0 deletions src/main/java/com/kamesuta/bungeepteropower/UpdateChecker.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package com.kamesuta.bungeepteropower;

import javax.annotation.Nullable;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
* Checks for updates via SpigotMC API
*/
public class UpdateChecker {
/**
* The resource ID of this plugin on SpigotMC
*/
private static final int ResourceId = 114883;
/**
* The current version
*/
private final String runningVersion;
/**
* The new version
*/
private String newVersion;

/**
* Create a new update checker
*
* @param runningVersion The current version
*/
public UpdateChecker(String runningVersion) {
this.runningVersion = runningVersion;
}

/**
* Check for updates
*
* @return A future that completes when the update check is finished
*/
public CompletableFuture<Void> checkForUpdates() {
// Check for updates via SpigotMC API
HttpClient client = HttpClient.newHttpClient();
// Create a request
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.spigotmc.org/legacy/update.php?resource=" + ResourceId))
.build();

// Execute request and register a callback
return client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
.thenApply(HttpResponse::body)
.thenAccept(version -> {
newVersion = version;
});
}

/**
* Returns whether an update is available
*
* @return true if an update is available
*/
public boolean isUpdateAvailable() {
if (newVersion == null) {
// If the update check has not been completed, assume there is no update
return false;
}
// Compare the versions
return compareVersions(runningVersion, newVersion);
}

/**
* Get download link
*
* @return the download link of the new version
*/
public String getDownloadLink() {
return "https://www.spigotmc.org/resources/" + ResourceId;
}

/**
* Get the current version
*
* @return the current version
*/
public String getRunningVersion() {
return runningVersion;
}

/**
* Get the new version
*
* @return the new version
*/
public @Nullable String getNewVersion() {
return newVersion;
}

/**
* Compares two versions and returns whether the new version is newer than the current version
*
* @param runningVersion The current version
* @param newVersion The new version
* @return true if the new version is newer than the current version
*/
public static boolean compareVersions(String runningVersion, String newVersion) {
// Split the running versions into integers
List<Integer> current = Arrays.stream(runningVersion.split("\\."))
.map(Integer::valueOf)
.collect(Collectors.toList());
// Split the new versions into integers
List<Integer> latest = Arrays.stream(newVersion.split("\\."))
.map(Integer::valueOf)
.collect(Collectors.toList());
// Compare the versions
int comparison = Objects.compare(current, latest, Comparator.<List<Integer>>comparingInt(List::size).thenComparing(List::hashCode));
return comparison < 0;
}
}
5 changes: 5 additions & 0 deletions src/main/resources/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
# Do not edit this value until the "/ptero check" asks you to do so.
version: 1

# Check for updates
# If true, the plugin will check for updates on startup.
# If a new version is available, a message will be sent to the console and to players with the permission "ptero.reload".
checkUpdate: true

# Language
# Supported languages: en, ja, fr, ro
# You can add your own language file in the plugins/BungeePteroPower directory.
Expand Down
3 changes: 3 additions & 0 deletions src/main/resources/messages_en.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
prefix: "[Ptero] "

update_available: "An update is available: BungeePteroPower v%s → v%s"
update_available_tooltip: "Click to download v%2$s!"

join_autostart_title: "Starting server..."
join_autostart_subtitle: "Please wait a moment and try reconnecting."
join_start: "The server %s is suspended to reduce server resources, but it can be started by clicking the button below."
Expand Down
3 changes: 3 additions & 0 deletions src/main/resources/messages_fr.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
prefix: "[Ptero] "

update_available: "Mise à jour disponible: BungeePteroPower v%s → v%s"
update_available_tooltip: "Cliquez pour télécharger v%2$s!"

join_autostart_title: "Démarrage du serveur..."
join_autostart_subtitle: "Veuillez patienter un moment et essayer de vous reconnecter."
join_start: "Le serveur %s est suspendu pour réduire les ressources du serveur, mais il peut être démarré en cliquant sur le bouton ci-dessous."
Expand Down
3 changes: 3 additions & 0 deletions src/main/resources/messages_ja.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
prefix: "[Ptero] "

update_available: "アップデートが利用可能です: BungeePteroPower v%s → v%s"
update_available_tooltip: "クリックして v%2$s をダウンロード!"

join_autostart_title: "サーバーを起動中..."
join_autostart_subtitle: "しばらく待ってから再接続してください。"
join_start: "サーバー「%s」はサーバーリソースを節約するために休止中ですが、下のボタンをクリックすると起動できます。"
Expand Down
3 changes: 3 additions & 0 deletions src/main/resources/messages_ro.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
prefix: "[Ptero] "

update_available: "Actualizare disponibilă: BungeePteroPower v%s → v%s"
update_available_tooltip: "Click pentru a descărca v%2$s!"

join_autostart_title: "Se pornește serverul..."
join_autostart_subtitle: "Vă rugăm să așteptați un moment și să încercați să vă reconectați."
join_start: "Serverul %s este suspendat pentru a reduce resursele, dar poate fi pornit făcând clic pe butonul de mai jos."
Expand Down
3 changes: 3 additions & 0 deletions src/main/resources/messages_zh-cn.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
prefix: "[Ptero] "

update_available: "可用更新: BungeePteroPower v%s → v%s"
update_available_tooltip: "点击下载 v%2$s!"

join_autostart_title: "服务器启动中..."
join_autostart_subtitle: "请稍候再尝试重新连接。"
join_start: "服务器「%s」处于休眠状态以节省资源,但您可以通过点击下方按钮来启动。"
Expand Down

0 comments on commit 6a22432

Please sign in to comment.