mirror of
https://github.com/alexcrea/CustomAnvil.git
synced 2026-06-23 16:16:17 +02:00
update checker
This commit is contained in:
parent
d801d85242
commit
49abca2ccf
3 changed files with 234 additions and 2 deletions
|
|
@ -13,6 +13,7 @@ Here dependencies are used by custom anvil
|
||||||
- [modrinth-publish](https://github.com/cloudnode-pro/modrinth-publish) by Zefir
|
- [modrinth-publish](https://github.com/cloudnode-pro/modrinth-publish) by Zefir
|
||||||
- [discord-webhook](https://github.com/tsickert/discord-webhook) by tsickert
|
- [discord-webhook](https://github.com/tsickert/discord-webhook) by tsickert
|
||||||
- Thanks [bstats](https://bstats.org/) for keeping me motivated
|
- Thanks [bstats](https://bstats.org/) for keeping me motivated
|
||||||
|
- [ModrinthUpdateChecker](https://github.com/Clickism/ModrinthUpdateChecker) by Clickism and thanks to the modrinth team
|
||||||
|
|
||||||
### Compatibility
|
### Compatibility
|
||||||
Here is to credits all the author of plugins
|
Here is to credits all the author of plugins
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,214 @@
|
||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2025 Clickism
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||||
|
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
|
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
* OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package xyz.alexcrea.cuanvil.update;
|
||||||
|
|
||||||
|
import com.google.gson.*;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.http.HttpClient;
|
||||||
|
import java.net.http.HttpRequest;
|
||||||
|
import java.net.http.HttpResponse;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility class to check for newer versions of a project hosted on Modrinth.
|
||||||
|
*/
|
||||||
|
public class ModrinthUpdateChecker {
|
||||||
|
|
||||||
|
private static final String API_URL = "https://api.modrinth.com/v2/project/{id}/version";
|
||||||
|
|
||||||
|
private final String projectId;
|
||||||
|
private final String loader;
|
||||||
|
@Nullable
|
||||||
|
private final String minecraftVersion;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private Boolean featured = null;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public Consumer<Exception> onError = null;
|
||||||
|
@Nullable
|
||||||
|
public Function<String, String> getRawVersion = ModrinthUpdateChecker::getRawVersion;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new update checker for the given project.
|
||||||
|
* This will check the latest version for the given loader and any minecraft version.
|
||||||
|
*
|
||||||
|
* @param projectId the project ID
|
||||||
|
* @param loader the loader
|
||||||
|
*/
|
||||||
|
public ModrinthUpdateChecker(String projectId, String loader) {
|
||||||
|
this(projectId, loader, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new update checker for the given project.
|
||||||
|
* This will check the latest version for the given loader and minecraft version.
|
||||||
|
*
|
||||||
|
* @param projectId the project ID
|
||||||
|
* @param loader the loader
|
||||||
|
* @param minecraftVersion the minecraft version, or null for any version
|
||||||
|
*/
|
||||||
|
public ModrinthUpdateChecker(String projectId, String loader, @Nullable String minecraftVersion) {
|
||||||
|
this.projectId = projectId;
|
||||||
|
this.loader = loader;
|
||||||
|
this.minecraftVersion = minecraftVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check the latest version of the project for the given loader and minecraft version
|
||||||
|
* and call the consumer with it.
|
||||||
|
*
|
||||||
|
* @param consumer the consumer
|
||||||
|
*/
|
||||||
|
public void checkVersion(Consumer<String> consumer) {
|
||||||
|
try {
|
||||||
|
HttpClient client = HttpClient.newHttpClient();
|
||||||
|
HttpRequest request = HttpRequest.newBuilder()
|
||||||
|
.uri(prepareURI())
|
||||||
|
.GET()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
|
||||||
|
.thenAcceptAsync(response -> {
|
||||||
|
if (response.statusCode() != 200) {
|
||||||
|
if(onError != null)
|
||||||
|
onError.accept(new RuntimeException("wrong response status code: " + response.statusCode()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
JsonArray versionsArray = JsonParser.parseString(response.body()).getAsJsonArray();
|
||||||
|
String latestVersion = getLatestVersion(versionsArray);
|
||||||
|
if (latestVersion == null) {
|
||||||
|
if(onError != null)
|
||||||
|
onError.accept(new RuntimeException("latest version is null"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
consumer.accept(latestVersion);
|
||||||
|
});
|
||||||
|
} catch (Exception e) {
|
||||||
|
if(onError != null) onError.accept(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the latest compatible version from the versions array.
|
||||||
|
*
|
||||||
|
* @param versions the versions array
|
||||||
|
* @return the latest compatible version
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
protected String getLatestVersion(JsonArray versions) {
|
||||||
|
return versions.asList().stream().findFirst()
|
||||||
|
.map(JsonElement::getAsJsonObject)
|
||||||
|
.map(version -> version.get("version_number").getAsString())
|
||||||
|
.map(getRawVersion != null ? getRawVersion : (v -> v))
|
||||||
|
.orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the raw version from a version string.
|
||||||
|
* i.E: "fabric-1.2+1.17.1" -> "1.2"
|
||||||
|
*
|
||||||
|
* @param version the version string
|
||||||
|
* @return the raw version string
|
||||||
|
*/
|
||||||
|
public static String getRawVersion(String version) {
|
||||||
|
if (version.isEmpty()) return version;
|
||||||
|
version = version.replaceAll("^\\D+", "");
|
||||||
|
String[] split = version.split("\\+");
|
||||||
|
return split[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare this request uri based on current parameters.
|
||||||
|
* @return the request uri
|
||||||
|
*/
|
||||||
|
private URI prepareURI() {
|
||||||
|
var url = new StringBuilder(API_URL.replace("{id}", projectId));
|
||||||
|
|
||||||
|
var parameters = prepareParameters();
|
||||||
|
String[] paramArray = new String[parameters.size()];
|
||||||
|
int i = 0;
|
||||||
|
for (Map.Entry<String, String> entry : parameters.entrySet()) {
|
||||||
|
paramArray[i++] = entry.getKey() + '=' + entry.getValue();
|
||||||
|
}
|
||||||
|
url.append('?').append(String.join("&", paramArray));
|
||||||
|
|
||||||
|
return URI.create(url.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the parameters for the version request.
|
||||||
|
*
|
||||||
|
* @return a map of key-value map of the request parameters
|
||||||
|
*/
|
||||||
|
private Map<String, String> prepareParameters(){
|
||||||
|
var parameters = new HashMap<String, String>();
|
||||||
|
|
||||||
|
parameters.put("loaders", List.of(loader).toString());
|
||||||
|
if(minecraftVersion != null) parameters.put("game_versions", List.of(minecraftVersion).toString());
|
||||||
|
if(featured != null) parameters.put("featured", featured.toString());
|
||||||
|
|
||||||
|
parameters.put("include_changelog", "false");
|
||||||
|
return parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Only get featured or non-featured versions.
|
||||||
|
* Null represent no filter.
|
||||||
|
* @param featured should be restricted to featured version ? default null if not called
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public ModrinthUpdateChecker setFeatured(@Nullable Boolean featured) {
|
||||||
|
this.featured = featured;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function called on error calling the api.
|
||||||
|
* @param onError What should happen on error
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public ModrinthUpdateChecker setOnError(@Nullable Consumer<Exception> onError) {
|
||||||
|
this.onError = onError;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the function to get raw version from the modrinth version.
|
||||||
|
* If null provided raw version will act as in the identity function.
|
||||||
|
* @param getRawVersion The function transforming modrinth version to raw version
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public ModrinthUpdateChecker setGetRawVersion(@Nullable Function<String, String> getRawVersion) {
|
||||||
|
this.getRawVersion = getRawVersion;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -18,6 +18,7 @@ import xyz.alexcrea.cuanvil.listener.AnvilCloseListener
|
||||||
import xyz.alexcrea.cuanvil.listener.AnvilResultListener
|
import xyz.alexcrea.cuanvil.listener.AnvilResultListener
|
||||||
import xyz.alexcrea.cuanvil.listener.ChatEventListener
|
import xyz.alexcrea.cuanvil.listener.ChatEventListener
|
||||||
import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener
|
import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener
|
||||||
|
import xyz.alexcrea.cuanvil.update.ModrinthUpdateChecker
|
||||||
import xyz.alexcrea.cuanvil.update.PluginSetDefault
|
import xyz.alexcrea.cuanvil.update.PluginSetDefault
|
||||||
import xyz.alexcrea.cuanvil.update.UpdateHandler
|
import xyz.alexcrea.cuanvil.update.UpdateHandler
|
||||||
import xyz.alexcrea.cuanvil.util.Metrics
|
import xyz.alexcrea.cuanvil.util.Metrics
|
||||||
|
|
@ -31,8 +32,9 @@ import java.util.logging.Level
|
||||||
open class CustomAnvil : JavaPlugin() {
|
open class CustomAnvil : JavaPlugin() {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
// bstats plugin id
|
// pluginIDS
|
||||||
private const val bstatsPluginId = 20923
|
private const val bstatsPluginId = 20923
|
||||||
|
private const val modrinthPluginID = "S75Ueiq9"
|
||||||
|
|
||||||
// Permission string required to use the plugin's features
|
// Permission string required to use the plugin's features
|
||||||
const val affectedByPluginPermission = "ca.affected"
|
const val affectedByPluginPermission = "ca.affected"
|
||||||
|
|
@ -174,10 +176,25 @@ open class CustomAnvil : JavaPlugin() {
|
||||||
logger.warning("Please note CustomAnvil is a more recent version of UnsafeEnchantsPlus")
|
logger.warning("Please note CustomAnvil is a more recent version of UnsafeEnchantsPlus")
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!PlatformUtil.isPaper) {
|
val isPaper = PlatformUtil.isPaper
|
||||||
|
if(!isPaper) {
|
||||||
logger.warning("It seems you are using spigot")
|
logger.warning("It seems you are using spigot")
|
||||||
logger.warning("Please take notice that spigot is less supported than paper and derivatives")
|
logger.warning("Please take notice that spigot is less supported than paper and derivatives")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val loader = if(isPaper) "paper" else "spigot"
|
||||||
|
|
||||||
|
val version = description.version
|
||||||
|
val featured = if(version.contains("dev")) null else true
|
||||||
|
|
||||||
|
ModrinthUpdateChecker(modrinthPluginID, loader, null)
|
||||||
|
.setFeatured(featured)
|
||||||
|
.setOnError { logger.log(Level.WARNING, "error trying to fetch latest update", it) }
|
||||||
|
.checkVersion { latestver: String? ->
|
||||||
|
if(latestver == null || version.contains(latestver)) return@checkVersion
|
||||||
|
|
||||||
|
logger.warning("An update may be available: $latestver")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun registerListeners() {
|
private fun registerListeners() {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue