Add CurseForge Update checker

This commit is contained in:
PiggyPiglet
2026-02-08 21:36:49 +08:00
parent 55c52a83ac
commit 9b89f8812c
3 changed files with 130 additions and 3 deletions

View File

@@ -4,6 +4,7 @@ import at.helpch.placeholderapi.commands.PlaceholderCommandRouter;
import at.helpch.placeholderapi.configuration.ConfigManager; import at.helpch.placeholderapi.configuration.ConfigManager;
import at.helpch.placeholderapi.expansion.manager.CloudExpansionManager; import at.helpch.placeholderapi.expansion.manager.CloudExpansionManager;
import at.helpch.placeholderapi.expansion.manager.LocalExpansionManager; import at.helpch.placeholderapi.expansion.manager.LocalExpansionManager;
import at.helpch.placeholderapi.updatechecker.UpdateChecker;
import com.hypixel.hytale.event.EventPriority; import com.hypixel.hytale.event.EventPriority;
import com.hypixel.hytale.server.core.command.system.CommandSender; import com.hypixel.hytale.server.core.command.system.CommandSender;
import com.hypixel.hytale.server.core.console.ConsoleSender; import com.hypixel.hytale.server.core.console.ConsoleSender;
@@ -34,6 +35,7 @@ public class PlaceholderAPIPlugin extends JavaPlugin {
@Override @Override
protected void setup() { protected void setup() {
configManager.setup(); configManager.setup();
getEventRegistry().register(PlayerDisconnectEvent.class, localExpansionManager::onQuit); getEventRegistry().register(PlayerDisconnectEvent.class, localExpansionManager::onQuit);
getEventRegistry().register(EventPriority.LAST, BootEvent.class, this::onServerLoad); getEventRegistry().register(EventPriority.LAST, BootEvent.class, this::onServerLoad);
@@ -46,7 +48,9 @@ public class PlaceholderAPIPlugin extends JavaPlugin {
protected void start() { protected void start() {
getCommandRegistry().registerCommand(new PlaceholderCommandRouter(this)); getCommandRegistry().registerCommand(new PlaceholderCommandRouter(this));
// localExpansionManager().load(ConsoleSender.INSTANCE); if (configManager.config().checkUpdates()) {
new UpdateChecker(this).fetch();
}
super.start(); super.start();
} }

View File

@@ -26,6 +26,7 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
public final class PlaceholderAPIConfig { public final class PlaceholderAPIConfig {
private boolean checkUpdates;
private boolean cloudEnabled; private boolean cloudEnabled;
private boolean debugMode; private boolean debugMode;
private ExpansionSort cloudSorting; private ExpansionSort cloudSorting;
@@ -33,8 +34,9 @@ public final class PlaceholderAPIConfig {
private String dateFormat; private String dateFormat;
private Map<String, Object> expansions; private Map<String, Object> expansions;
public PlaceholderAPIConfig(boolean cloudEnabled, boolean debugMode, @NotNull ExpansionSort cloudSorting, public PlaceholderAPIConfig(boolean checkUpdates, boolean cloudEnabled, boolean debugMode, @NotNull ExpansionSort cloudSorting,
@NotNull BooleanValue booleanValue, @NotNull String dateFormat) { @NotNull BooleanValue booleanValue, @NotNull String dateFormat) {
this.checkUpdates = checkUpdates;
this.cloudEnabled = cloudEnabled; this.cloudEnabled = cloudEnabled;
this.debugMode = debugMode; this.debugMode = debugMode;
this.cloudSorting = cloudSorting; this.cloudSorting = cloudSorting;
@@ -43,8 +45,9 @@ public final class PlaceholderAPIConfig {
this.expansions = new HashMap<>(); this.expansions = new HashMap<>();
} }
public PlaceholderAPIConfig(boolean cloudEnabled, boolean debugMode, @NotNull ExpansionSort cloudSorting, public PlaceholderAPIConfig(boolean checkUpdates, boolean cloudEnabled, boolean debugMode, @NotNull ExpansionSort cloudSorting,
@NotNull BooleanValue booleanValue, @NotNull String dateFormat, Map<String, Object> expansions) { @NotNull BooleanValue booleanValue, @NotNull String dateFormat, Map<String, Object> expansions) {
this.checkUpdates = checkUpdates;
this.cloudEnabled = cloudEnabled; this.cloudEnabled = cloudEnabled;
this.debugMode = debugMode; this.debugMode = debugMode;
this.cloudSorting = cloudSorting; this.cloudSorting = cloudSorting;
@@ -53,6 +56,10 @@ public final class PlaceholderAPIConfig {
this.expansions = expansions; this.expansions = expansions;
} }
public boolean checkUpdates() {
return checkUpdates;
}
public boolean cloudEnabled() { public boolean cloudEnabled() {
return cloudEnabled; return cloudEnabled;
} }

View File

@@ -0,0 +1,116 @@
package at.helpch.placeholderapi.updatechecker;
import at.helpch.placeholderapi.PlaceholderAPIPlugin;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.hypixel.hytale.server.core.HytaleServer;
import com.hypixel.hytale.server.core.Message;
import com.hypixel.hytale.server.core.event.events.player.PlayerReadyEvent;
import javax.net.ssl.HttpsURLConnection;
import java.awt.*;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.URL;
import java.util.Arrays;
import java.util.concurrent.CompletableFuture;
public class UpdateChecker {
private static final String CURSEFORGE_URL = "https://api.cfwidget.com/hytale/mods/placeholder-api";
private static final int RESOURCE_ID = 6245;
private final PlaceholderAPIPlugin plugin;
private final String pluginVersion;
private String curseforgeVersion;
private boolean updateAvailable;
public UpdateChecker(PlaceholderAPIPlugin plugin) {
this.plugin = plugin;
pluginVersion = plugin.getManifest().getVersion().toString();
}
public boolean hasUpdateAvailable() {
return updateAvailable;
}
public String getCurseforgeVersion() {
return curseforgeVersion;
}
public void fetch() {
plugin.getTaskRegistry().registerTask(CompletableFuture.runAsync(() -> {
try {
HttpsURLConnection con = (HttpsURLConnection) new URI(CURSEFORGE_URL).toURL().openConnection();
con.setRequestMethod("GET");
final JsonElement json = new Gson().fromJson(new BufferedReader(new InputStreamReader(con.getInputStream())), JsonElement.class);
final String jar = json.getAsJsonObject().get("download").getAsJsonObject().get("name").getAsString();
final String[] parts = jar.split("-");
if (parts.length >= 2) {
curseforgeVersion = parts[1];
} else {
return;
}
} catch (Exception ex) {
plugin.getLogger().atInfo().log("Failed to check for updates on curseforge.");
return;
}
if (curseforgeVersion == null || curseforgeVersion.isEmpty()) {
return;
}
updateAvailable = curseforgeIsNewer();
if (!updateAvailable) {
return;
}
plugin.getLogger().atInfo().log("An update for PlaceholderAPI (v" + getCurseforgeVersion() + ") is available at:");
plugin.getLogger().atInfo().log("https://placeholderapi.com/download");
plugin.getEventRegistry().registerGlobal(PlayerReadyEvent.class, this::onJoin);
}));
}
private boolean curseforgeIsNewer() {
if (curseforgeVersion == null || curseforgeVersion.isEmpty()) {
return false;
}
int[] plV = toReadable(pluginVersion);
int[] spV = toReadable(curseforgeVersion);
if (plV[0] < spV[0]) {
return true;
} else if ((plV[1] < spV[1])) {
return true;
} else {
return plV[2] < spV[2];
}
}
private int[] toReadable(String version) {
if (version.contains("-DEV")) {
version = version.split("-DEV")[0];
}
return Arrays.stream(version.split("\\.")).mapToInt(Integer::parseInt).toArray();
}
public void onJoin(PlayerReadyEvent e) {
if (e.getPlayer().hasPermission("placeholderapi.updatenotify")) {
final Message message = Message.raw("An update for ").color(Color.CYAN)
.insert(Message.raw("Placeholder").color(Color.WHITE))
.insert(Message.raw("API").color(Color.LIGHT_GRAY))
.insert(Message.raw(" (").color(Color.YELLOW))
.insert(Message.raw("Placeholder").color(Color.WHITE))
.insert(Message.raw("API").color(Color.LIGHT_GRAY))
.insert(Message.raw(" v" + getCurseforgeVersion()).color(Color.WHITE))
.insert(Message.raw(")").color(Color.YELLOW))
.insert(Message.raw("\nis available at ").color(Color.CYAN))
.insert(Message.raw("https://placeholderapi.com/download").color(Color.YELLOW).link("https://www.curseforge.com/hytale/mods/placeholder-api").bold(true).italic(true));
e.getPlayer().sendMessage(message);
}
}
}