mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2025-04-24 18:40:34 +08:00
Specialized Fabric and Sponge version checkers (#2125)
Affects issues: - Close #936 - Close #2093.
This commit is contained in:
parent
bcfd52d76b
commit
4d151d45fa
@ -42,16 +42,16 @@ import java.util.Optional;
|
||||
@Singleton
|
||||
public class VersionChecker implements SubSystem {
|
||||
|
||||
private final VersionNumber currentVersion;
|
||||
private final Locale locale;
|
||||
private final PlanConfig config;
|
||||
private final PluginLogger logger;
|
||||
private final RunnableFactory runnableFactory;
|
||||
private final ErrorLogger errorLogger;
|
||||
protected final VersionNumber currentVersion;
|
||||
protected final Locale locale;
|
||||
protected final PlanConfig config;
|
||||
protected final PluginLogger logger;
|
||||
protected final RunnableFactory runnableFactory;
|
||||
protected final ErrorLogger errorLogger;
|
||||
|
||||
private static final String DOWNLOAD_ICON_HTML = "<i class=\"fa fa-fw fa-download\"></i> ";
|
||||
|
||||
private VersionInfo newVersionAvailable;
|
||||
protected VersionInfo newVersionAvailable;
|
||||
|
||||
@Inject
|
||||
public VersionChecker(
|
||||
@ -74,9 +74,20 @@ public class VersionChecker implements SubSystem {
|
||||
return newVersionAvailable != null;
|
||||
}
|
||||
|
||||
private void checkForUpdates() {
|
||||
protected Optional<List<VersionInfo>> loadVersionInfo() {
|
||||
try {
|
||||
List<VersionInfo> versions = VersionInfoLoader.load();
|
||||
return Optional.of(VersionInfoLoader.load());
|
||||
} catch (IOException e) {
|
||||
errorLogger.warn(e, ErrorContext.builder()
|
||||
.related(locale.getString(PluginLang.VERSION_FAIL_READ_VERSIONS))
|
||||
.whatToDo("Allow Plan to check for updates from Github/versions.txt or disable update check.")
|
||||
.build());
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
private void checkForUpdates() {
|
||||
loadVersionInfo().ifPresent(versions -> {
|
||||
if (config.isFalse(PluginSettings.NOTIFY_ABOUT_DEV_RELEASES)) {
|
||||
versions = Lists.filter(versions, VersionInfo::isRelease);
|
||||
}
|
||||
@ -84,9 +95,9 @@ public class VersionChecker implements SubSystem {
|
||||
if (newestVersion.getVersion().isNewerThan(currentVersion)) {
|
||||
newVersionAvailable = newestVersion;
|
||||
String notification = locale.getString(
|
||||
PluginLang.VERSION_AVAILABLE,
|
||||
newestVersion.getVersion().asString(),
|
||||
newestVersion.getChangeLogUrl()
|
||||
PluginLang.VERSION_AVAILABLE,
|
||||
newestVersion.getVersion().asString(),
|
||||
newestVersion.getChangeLogUrl()
|
||||
) + (newestVersion.isRelease() ? "" : locale.getString(PluginLang.VERSION_AVAILABLE_DEV));
|
||||
logger.info("§a----------------------------------------");
|
||||
logger.info("§a" + notification);
|
||||
@ -94,14 +105,10 @@ public class VersionChecker implements SubSystem {
|
||||
} else {
|
||||
logger.info(locale.getString(PluginLang.VERSION_NEWEST));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
errorLogger.warn(e, ErrorContext.builder()
|
||||
.related(locale.getString(PluginLang.VERSION_FAIL_READ_VERSIONS))
|
||||
.whatToDo("Allow Plan to check for updates from Github/versions.txt or disable update check.")
|
||||
.build());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void enable() {
|
||||
if (config.isFalse(PluginSettings.CHECK_FOR_UPDATES)) {
|
||||
|
@ -75,4 +75,14 @@ public class VersionInfo implements Comparable<VersionInfo> {
|
||||
public int compareTo(VersionInfo o) {
|
||||
return this.version.compareTo(o.version);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "VersionInfo{" +
|
||||
"release=" + release +
|
||||
", version=" + version +
|
||||
", downloadUrl='" + downloadUrl + '\'' +
|
||||
", changeLogUrl='" + changeLogUrl + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
@ -23,7 +23,7 @@ import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class VersionNumber implements Comparable<VersionNumber> {
|
||||
private static final Pattern MATCH_NUMBERS = Pattern.compile("([0-9][0-9]*)");
|
||||
private static final Pattern MATCH_NUMBERS = Pattern.compile("([0-9]+)");
|
||||
|
||||
private final String version;
|
||||
private final List<Long> versionNumbers;
|
||||
|
@ -24,6 +24,7 @@ import com.djrapitops.plan.identification.ServerServerInfo;
|
||||
import com.djrapitops.plan.settings.ConfigSystem;
|
||||
import com.djrapitops.plan.settings.FabricConfigSystem;
|
||||
import com.djrapitops.plan.storage.database.DBSystem;
|
||||
import com.djrapitops.plan.version.VersionChecker;
|
||||
import dagger.Binds;
|
||||
import dagger.Module;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
@ -31,6 +32,7 @@ import net.playeranalytics.plan.FabricServerShutdownSave;
|
||||
import net.playeranalytics.plan.gathering.FabricSensor;
|
||||
import net.playeranalytics.plan.gathering.listeners.FabricListenerSystem;
|
||||
import net.playeranalytics.plan.storage.database.FabricDBSystem;
|
||||
import net.playeranalytics.plan.version.FabricVersionChecker;
|
||||
|
||||
/**
|
||||
* Module for binding Fabric-specific classes as interface implementations.
|
||||
@ -60,4 +62,7 @@ public interface FabricSuperClassBindingModule {
|
||||
|
||||
@Binds
|
||||
ServerSensor<?> bindGenericsServerSensor(ServerSensor<ServerWorld> sensor);
|
||||
|
||||
@Binds
|
||||
VersionChecker bindVersionChecker(FabricVersionChecker versionChecker);
|
||||
}
|
||||
|
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* This file is part of Player Analytics (Plan).
|
||||
*
|
||||
* Plan is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License v3 as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Plan is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package net.playeranalytics.plan.version;
|
||||
|
||||
import com.djrapitops.plan.settings.config.PlanConfig;
|
||||
import com.djrapitops.plan.settings.locale.Locale;
|
||||
import com.djrapitops.plan.utilities.logging.ErrorLogger;
|
||||
import com.djrapitops.plan.version.VersionChecker;
|
||||
import com.djrapitops.plan.version.VersionInfo;
|
||||
import net.playeranalytics.plugin.scheduling.RunnableFactory;
|
||||
import net.playeranalytics.plugin.server.PluginLogger;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* System for checking if new Version is available when the System initializes, altering the link for Fabric.
|
||||
*/
|
||||
@Singleton
|
||||
public class FabricVersionChecker extends VersionChecker {
|
||||
@Inject
|
||||
public FabricVersionChecker(
|
||||
@Named("currentVersion") String currentVersion,
|
||||
Locale locale,
|
||||
PlanConfig config,
|
||||
PluginLogger logger,
|
||||
RunnableFactory runnableFactory,
|
||||
ErrorLogger errorLogger
|
||||
) {
|
||||
super(currentVersion, locale, config, logger, runnableFactory, errorLogger);
|
||||
}
|
||||
|
||||
public Optional<VersionInfo> getNewVersionAvailable() {
|
||||
if (newVersionAvailable == null) {
|
||||
return Optional.empty();
|
||||
} else {
|
||||
return Optional.of(new VersionInfo(
|
||||
newVersionAvailable.isRelease(),
|
||||
newVersionAvailable.getVersion(),
|
||||
newVersionAvailable.getDownloadUrl().replace("Plan-", "PlanFabric-"),
|
||||
newVersionAvailable.getChangeLogUrl()
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
@ -30,6 +30,8 @@ import com.djrapitops.plan.storage.database.DBSystem;
|
||||
import com.djrapitops.plan.storage.database.SpongeDBSystem;
|
||||
import com.djrapitops.plan.storage.file.PlanFiles;
|
||||
import com.djrapitops.plan.storage.file.SpongePlanFiles;
|
||||
import com.djrapitops.plan.version.SpongeVersionChecker;
|
||||
import com.djrapitops.plan.version.VersionChecker;
|
||||
import dagger.Binds;
|
||||
import dagger.Module;
|
||||
import org.spongepowered.api.world.World;
|
||||
@ -65,4 +67,7 @@ public interface SpongeSuperClassBindingModule {
|
||||
|
||||
@Binds
|
||||
ServerSensor<?> bindGenericsServerSensor(ServerSensor<World> sensor);
|
||||
|
||||
@Binds
|
||||
VersionChecker bindVersionChecker(SpongeVersionChecker versionChecker);
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* This file is part of Player Analytics (Plan).
|
||||
*
|
||||
* Plan is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License v3 as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Plan is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.djrapitops.plan.version;
|
||||
|
||||
import com.djrapitops.plan.settings.config.PlanConfig;
|
||||
import com.djrapitops.plan.settings.locale.Locale;
|
||||
import com.djrapitops.plan.settings.locale.lang.PluginLang;
|
||||
import com.djrapitops.plan.utilities.logging.ErrorContext;
|
||||
import com.djrapitops.plan.utilities.logging.ErrorLogger;
|
||||
import com.djrapitops.plan.version.ore.OreVersionInfoLoader;
|
||||
import net.playeranalytics.plugin.scheduling.RunnableFactory;
|
||||
import net.playeranalytics.plugin.server.PluginLogger;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* System for checking if new Version is available when the System initializes, using the Ore API.
|
||||
*/
|
||||
@Singleton
|
||||
public class SpongeVersionChecker extends VersionChecker {
|
||||
@Inject
|
||||
public SpongeVersionChecker(
|
||||
@Named("currentVersion") String currentVersion,
|
||||
Locale locale,
|
||||
PlanConfig config,
|
||||
PluginLogger logger,
|
||||
RunnableFactory runnableFactory,
|
||||
ErrorLogger errorLogger
|
||||
) {
|
||||
super(currentVersion, locale, config, logger, runnableFactory, errorLogger);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Optional<List<VersionInfo>> loadVersionInfo() {
|
||||
try {
|
||||
return Optional.of(OreVersionInfoLoader.load());
|
||||
} catch (IOException e) {
|
||||
errorLogger.warn(e, ErrorContext.builder()
|
||||
.related(locale.getString(PluginLang.VERSION_FAIL_READ_VERSIONS))
|
||||
.whatToDo("Allow Plan to check for updates from Ore or disable update check.")
|
||||
.build());
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* This file is part of Player Analytics (Plan).
|
||||
*
|
||||
* Plan is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License v3 as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Plan is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.djrapitops.plan.version.ore;
|
||||
|
||||
public class OreTagDto {
|
||||
private final String name;
|
||||
private final String data;
|
||||
|
||||
public OreTagDto(String name, String data) {
|
||||
this.name = name;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "OreTagDto{" +
|
||||
"name='" + name + '\'' +
|
||||
", data='" + data + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* This file is part of Player Analytics (Plan).
|
||||
*
|
||||
* Plan is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License v3 as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Plan is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.djrapitops.plan.version.ore;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class OreVersionDto {
|
||||
private final String name;
|
||||
private final List<OreTagDto> tags;
|
||||
|
||||
public OreVersionDto(String name, List<OreTagDto> tags) {
|
||||
this.name = name;
|
||||
this.tags = tags;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public List<OreTagDto> getTags() {
|
||||
return tags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "OreVersionDto{" +
|
||||
"name='" + name + '\'' +
|
||||
", tags=" + tags +
|
||||
'}';
|
||||
}
|
||||
}
|
@ -0,0 +1,116 @@
|
||||
/*
|
||||
* This file is part of Player Analytics (Plan).
|
||||
*
|
||||
* Plan is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License v3 as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Plan is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.djrapitops.plan.version.ore;
|
||||
|
||||
import com.djrapitops.plan.version.VersionInfo;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Utility for loading version information from Ore, Sponge's plugin repository
|
||||
*/
|
||||
public class OreVersionInfoLoader {
|
||||
private static final String ORE_AUTHENTICATE_URL = "https://ore.spongepowered.org/api/v2/authenticate";
|
||||
private static final String ORE_VERSIONS_URL = "https://ore.spongepowered.org/api/v2/projects/plan/versions";
|
||||
private static final String ORE_DOWNLOAD_URL = "https://ore.spongepowered.org/AuroraLS3/Plan/versions/%s/download";
|
||||
private static final String ORE_CHANGE_LOG_URL = "https://ore.spongepowered.org/AuroraLS3/Plan/versions/%s#change-log";
|
||||
|
||||
private OreVersionInfoLoader() {
|
||||
/* Static method class */
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads version information from Ore, using its Web API.
|
||||
*
|
||||
* @return List of VersionInfo, newest version first.
|
||||
* @throws IOException If API can not be accessed.
|
||||
*/
|
||||
public static List<VersionInfo> load() throws IOException {
|
||||
List<VersionInfo> versionInfo = new ArrayList<>();
|
||||
|
||||
String session = newOreSession();
|
||||
|
||||
List<OreVersionDto> versions = loadOreVersions(session);
|
||||
versions.forEach(i -> {
|
||||
boolean isRelease = i.getTags().stream().anyMatch(t -> t.getName().equals("Channel") && t.getData().equals("Release"));
|
||||
String spacedVersion = i.getName().replace('-', ' ');
|
||||
String download = String.format(ORE_DOWNLOAD_URL, i.getName());
|
||||
String changeLog = String.format(ORE_CHANGE_LOG_URL, i.getName());
|
||||
versionInfo.add(new VersionInfo(isRelease, spacedVersion, download, changeLog));
|
||||
});
|
||||
|
||||
Collections.sort(versionInfo);
|
||||
return versionInfo;
|
||||
}
|
||||
|
||||
private static List<OreVersionDto> loadOreVersions(String session) throws IOException {
|
||||
URL url = new URL(ORE_VERSIONS_URL);
|
||||
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
try {
|
||||
connection.setDoOutput(true);
|
||||
connection.setRequestMethod("GET");
|
||||
connection.setRequestProperty("Authorization", String.format("OreApi session=\"%s\"", session));
|
||||
connection.connect();
|
||||
try (InputStream in = connection.getInputStream()) {
|
||||
JsonArray versions = new JsonParser().parse(readInputFully(in)).getAsJsonObject().get("result").getAsJsonArray();
|
||||
|
||||
return new Gson().getAdapter(new TypeToken<List<OreVersionDto>>() {}).fromJsonTree(versions);
|
||||
}
|
||||
} finally {
|
||||
connection.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
private static String newOreSession() throws IOException {
|
||||
URL url = new URL(ORE_AUTHENTICATE_URL);
|
||||
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
try {
|
||||
connection.setDoOutput(true);
|
||||
connection.setRequestMethod("POST");
|
||||
connection.connect();
|
||||
try (InputStream in = connection.getInputStream()) {
|
||||
return new JsonParser().parse(readInputFully(in)).getAsJsonObject().get("session").getAsString();
|
||||
}
|
||||
} finally {
|
||||
connection.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
// I want Java 9 already...
|
||||
private static String readInputFully(InputStream in) throws IOException {
|
||||
try (ByteArrayOutputStream buf = new ByteArrayOutputStream(512)) {
|
||||
int b;
|
||||
while ((b = in.read()) != -1) {
|
||||
buf.write((byte) b);
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user