Various minor

New plugin updater and versioning
In game changelog
fix login teleporting
This commit is contained in:
Jesse Boyd 2017-08-09 15:04:59 +10:00
parent b280644661
commit ac9042bbe4
No known key found for this signature in database
GPG Key ID: 59F1DE6293AF6E1F
15 changed files with 241 additions and 267 deletions

4
.gitignore vendored
View File

@ -5,6 +5,7 @@
Sponge/build
Core/build
Bukkit/build
Nukkit/build
### Maven ###
/mvn
@ -137,4 +138,5 @@ Nukkit/build/dependency-cache/
checkstyle.xml
classes/
p2error.txt
*.bat
*.bat
Nukkit/build/resources/main/plugin.yml

View File

@ -10,7 +10,7 @@ targetCompatibility = 1.7
processResources {
from('src/main/resources') {
include 'plotsquared.properties'
include 'plugin.properties'
expand(
version: "${project.parent.version}",
name: project.parent.name,

View File

@ -70,6 +70,7 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@ -95,10 +96,8 @@ public class PS{
// Current thread
private final Thread thread;
// Platform / Version / Update URL
private final String platform;
private final int[] version;
private int[] lastVersion;
public URL update;
private Updater updater;
private PlotVersion version;
// WorldEdit instance
public WorldEdit worldedit;
// Files and configuration
@ -130,8 +129,7 @@ public class PS{
this.thread = Thread.currentThread();
this.IMP = iPlotMain;
this.logger = iPlotMain;
this.platform = platform;
this.version = this.IMP.getPluginVersion();
Settings.PLATFORM = platform;
try {
new ReflectionUtils(this.IMP.getNMSPackage());
try {
@ -248,21 +246,19 @@ public class PS{
// Check for updates
if (Settings.Enabled_Components.UPDATER) {
TaskManager.runTaskAsync(new Runnable() {
updater = new Updater();
TaskManager.IMP.taskAsync(new Runnable() {
@Override
public void run() {
URL url = Updater.getUpdate();
if (url != null) {
PS.this.update = url;
} else if (PS.this.lastVersion == null) {
PS.log("&aThanks for installing " + IMP.getPluginName() + "!");
} else if (!get().checkVersion(PS.this.lastVersion, PS.this.version)) {
PS.log("&aThanks for updating from " + StringMan.join(PS.this.lastVersion, ".") + " to " + StringMan
.join(PS.this.version, ".") + "!");
DBFunc.updateTables(PS.this.lastVersion);
}
updater.update(getPlatform(), getVersion());
}
});
TaskManager.IMP.taskRepeatAsync(new Runnable() {
@Override
public void run() {
updater.update(getPlatform(), getVersion());
}
}, 36000);
}
// World generators:
@ -359,6 +355,14 @@ public class PS{
return logger;
}
/**
* The plugin updater
* @return
*/
public Updater getUpdater() {
return updater;
}
public PlotAreaManager getPlotAreaManager() {
return manager;
}
@ -445,19 +449,11 @@ public class PS{
&& version[1] == version2[1] && version[2] >= version2[2];
}
/**
* Get the last PlotSquared version.
* @return last version in config or null
*/
public int[] getLastVersion() {
return this.lastVersion;
}
/**
* Get the current PlotSquared version.
* @return current version in config or null
*/
public int[] getVersion() {
public PlotVersion getVersion() {
return this.version;
}
@ -468,7 +464,7 @@ public class PS{
* @return the server implementation
*/
public String getPlatform() {
return this.platform;
return Settings.PLATFORM;
}
public PlotManager getPlotManager(Plot plot) {
@ -1463,6 +1459,10 @@ public class PS{
return sb.toString();
}
public File getJarFile() {
return jarFile;
}
public boolean update(PlotPlayer sender, URL url) {
try {
String name = this.jarFile.getName();
@ -1640,25 +1640,36 @@ public class PS{
String lastVersionString = this.config.getString("version");
if (lastVersionString != null) {
String[] split = lastVersionString.split("\\.");
this.lastVersion = new int[]{Integer.parseInt(split[0]), Integer.parseInt(split[1]), Integer.parseInt(split[2])};
}
if (lastVersion != null && checkVersion(new int[]{3, 4, 0}, lastVersion)) {
Settings.convertLegacy(configFile);
if (config.contains("worlds")) {
ConfigurationSection worldSection = config.getConfigurationSection("worlds");
worlds.set("worlds", worldSection);
try {
worlds.save(worldsFile);
} catch (IOException e) {
PS.debug("Failed to save " + IMP.getPluginName() + " worlds.yml");
e.printStackTrace();
int[] lastVersion = new int[]{Integer.parseInt(split[0]), Integer.parseInt(split[1]), Integer.parseInt(split[2])};
if (checkVersion(new int[]{3, 4, 0}, lastVersion)) {
Settings.convertLegacy(configFile);
if (config.contains("worlds")) {
ConfigurationSection worldSection = config.getConfigurationSection("worlds");
worlds.set("worlds", worldSection);
try {
worlds.save(worldsFile);
} catch (IOException e) {
PS.debug("Failed to save " + IMP.getPluginName() + " worlds.yml");
e.printStackTrace();
}
}
Settings.save(configFile);
}
} else {
Settings.load(configFile);
}
Settings.VERSION = StringMan.join(this.version, ".");
Settings.PLATFORM = platform;
Settings.load(configFile);
try {
InputStream stream = getClass().getResourceAsStream("/plugin.properties");
java.util.Scanner scanner = new java.util.Scanner(stream).useDelimiter("\\A");
String versionString = scanner.next().trim();
scanner.close();
this.version = new PlotVersion(versionString);
Settings.DATE = new Date(100 + version.year, version.month, version.day).toGMTString();
Settings.BUILD = "https://ci.athion.net/job/PlotSquared/" + version.build;
Settings.COMMIT = "https://github.com/IntellectualSites/PlotSquared/commit/" + Integer.toHexString(version.hash);
System.out.println("Version is " + this.version);
} catch (Throwable ignore) {
ignore.printStackTrace();
}
Settings.save(configFile);
config = YamlConfiguration.loadConfiguration(configFile);
}
@ -1762,7 +1773,9 @@ public class PS{
* Setup the style.yml file
*/
private void setupStyle() {
this.style.set("version", StringMan.join(this.version, "."));
if (this.version != null) {
this.style.set("version", this.version.toString());
}
Map<String, Object> o = new HashMap<>(4);
o.put("color.1", "6");
o.put("color.2", "7");

View File

@ -0,0 +1,28 @@
package com.intellectualcrafters.plot;
public class PlotVersion {
public final int year, month, day, hash, build;
public PlotVersion(String version) {
String[] split = version.substring(version.indexOf('=') + 1).split("-");
if (split[0].equals("unknown")) {
this.year = month = day = hash = build = 0;
return;
}
String[] date = split[0].split("\\.");
this.year = Integer.parseInt(date[0]);
this.month = Integer.parseInt(date[1]);
this.day = Integer.parseInt(date[2]);
this.hash = Integer.parseInt(split[1], 16);
this.build = Integer.parseInt(split[2]);
}
@Override
public String toString() {
return "PlotSquared-" + year + "." + month + "." + day + "-" + Integer.toHexString(hash) + "-" + build;
}
public boolean isNewer(PlotVersion other) {
return other.build < this.build;
}
}

View File

@ -1,54 +1,73 @@
package com.intellectualcrafters.plot;
import com.intellectualcrafters.json.JSONArray;
import com.intellectualcrafters.json.JSONObject;
import com.intellectualcrafters.plot.util.HttpUtil;
import com.intellectualcrafters.plot.util.StringMan;
import java.net.MalformedURLException;
import com.intellectualcrafters.plot.util.MainUtil;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.Arrays;
import static com.intellectualcrafters.plot.PS.log;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.util.Scanner;
public class Updater {
public static URL getUpdate() {
String str = HttpUtil.readUrl("https://api.github.com/repos/IntellectualSites/PlotSquared/releases/latest");
JSONObject release = new JSONObject(str);
JSONArray assets = (JSONArray) release.get("assets");
String downloadURL = String.format(PS.imp().getPluginName() + "-%s.jar", PS.get().getPlatform());
for (int i = 0; i < assets.length(); i++) {
JSONObject asset = assets.getJSONObject(i);
String name = asset.getString("name");
if (downloadURL.equals(name)) {
try {
String[] split = release.getString("name").split("\\.");
int[] version;
if (split.length == 3) {
version = new int[]{Integer.parseInt(split[0]), Integer.parseInt(split[1]), Integer.parseInt(split[2])};
} else {
version = new int[]{Integer.parseInt(split[0]), Integer.parseInt(split[1]), 0};
}
// If current version >= update
if (PS.get().checkVersion(PS.get().getVersion(), version)) {
if (!PS.get().IMP.getPluginVersionString().contains("-SNAPSHOT") || !Arrays.equals(PS.get().getVersion(), version)) {
PS.debug("&7" + PS.imp().getPluginName() + " is already up to date!");
return null;
}
}
log("&6" + PS.imp().getPluginName() + " " + StringMan.join(split, ".") + " is available:");
log("&8 - &3Use: &7/plot update");
log("&8 - &3Or: &7" + downloadURL);
return new URL(asset.getString("browser_download_url"));
} catch (MalformedURLException e) {
e.printStackTrace();
log("&dCould not check for updates (1)");
log("&7 - Manually check for updates: https://github.com/IntellectualSites/PlotSquared/releases");
}
PlotVersion newVersion;
private String changes;
public String getChanges() {
if (changes == null) {
try (Scanner scanner = new Scanner(new URL("http://empcraft.com/plots/cl?" + Integer.toHexString(PS.get().getVersion().hash)).openStream(), "UTF-8")) {
changes = scanner.useDelimiter("\\A").next();
} catch (IOException e) {
e.printStackTrace();
return "";
}
}
log("You are running the latest version of " + PS.imp().getPluginName() + "!");
return null;
return changes;
}
}
public boolean isOutdated() {
return newVersion != null;
}
public void update(String platform, PlotVersion currentVersion) {
if (currentVersion == null || platform == null) {
return;
}
try {
String downloadUrl = "https://ci.athion.net/job/PlotSquared/lastSuccessfulBuild/artifact/target/PlotSquared-%platform%-%version%.jar";
String versionUrl = "http://empcraft.com/plots/version.php?%platform%";
URL url = new URL(versionUrl.replace("%platform%", platform));
try (Scanner reader = new Scanner(url.openStream())) {
String versionString = reader.next();
PlotVersion version = new PlotVersion(versionString);
if (version.isNewer(newVersion != null ? newVersion : currentVersion)) {
newVersion = version;
URL download = new URL(downloadUrl.replaceAll("%platform%", platform).replaceAll("%version%", versionString));
try (ReadableByteChannel rbc = Channels.newChannel(download.openStream())) {
File jarFile = PS.get().getJarFile();
File finalFile = new File(jarFile.getParent(), "update" + File.separator + jarFile.getName());
File outFile = new File(jarFile.getParent(), "update" + File.separator + jarFile.getName().replace(".jar", ".part"));
boolean exists = outFile.exists();
if (exists) {
outFile.delete();
} else {
File outFileParent = outFile.getParentFile();
if (!outFileParent.exists()) {
outFileParent.mkdirs();
}
}
try (FileOutputStream fos = new FileOutputStream(outFile)) {
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
}
outFile.renameTo(finalFile);
PS.debug("Updated PlotSquared to " + versionString);
MainUtil.sendAdmin("&7Restart to update PlotSquared with these changes: &c/plot changelog &7or&c " + "http://empcraft.com/plot/cl?" + Integer.toHexString(currentVersion.hash));
}
}
}
} catch (Throwable ignore) {
}
}
}

View File

@ -0,0 +1,40 @@
package com.intellectualcrafters.plot.commands;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.Updater;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.util.MainUtil;
import com.plotsquared.general.commands.CommandDeclaration;
import java.io.IOException;
import java.net.URL;
import java.util.Scanner;
@CommandDeclaration(
command = "changelog",
permission = "plots.admin.command.changelog",
description = "View the changelog",
usage = "/plot changelog",
requiredType = RequiredType.NONE,
aliases = {"cl"},
category = CommandCategory.ADMINISTRATION)
public class Changelog extends SubCommand {
@Override
public boolean onCommand(PlotPlayer player, String[] args) {
try {
Updater updater = PS.get().getUpdater();
String changes = updater != null ? updater.getChanges() : null;
if (changes == null) {
try (Scanner scanner = new Scanner(new URL("http://empcraft.com/plots/cl?" + Integer.toHexString(PS.get().getVersion().hash)).openStream(), "UTF-8")) {
changes = scanner.useDelimiter("\\A").next();
}
}
changes = changes.replaceAll("#([0-9]+)", "github.com/IntellectualSites/PlotSquared/pulls/$1");
MainUtil.sendMessage(player, changes);
} catch (IOException e) {
throw new RuntimeException(e);
}
return true;
}
}

View File

@ -44,7 +44,7 @@ public class MainCommand extends Command {
new Confirm();
new Template();
new Download();
new Update();
new Changelog();
new Template();
new Setup();
new Area();

View File

@ -5,7 +5,6 @@ import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.util.HttpUtil;
import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.StringMan;
import com.intellectualcrafters.plot.util.TaskManager;
import com.plotsquared.general.commands.CommandDeclaration;
@ -21,7 +20,7 @@ public class PluginCmd extends SubCommand {
TaskManager.IMP.taskAsync(new Runnable() {
@Override
public void run() {
MainUtil.sendMessage(player, String.format("$2>> $1&l" + PS.imp().getPluginName() + " $2($1Version$2: $1%s$2)", StringMan.join(PS.get().getVersion(), ".")));
MainUtil.sendMessage(player, String.format("$2>> $1&l" + PS.imp().getPluginName() + " $2($1Version$2: $1%s$2)", PS.get().getVersion()));
MainUtil.sendMessage(player, "$2>> $1&lAuthors$2: $1Citymonstret $2& $1Empire92 $2& $1MattBDev");
MainUtil.sendMessage(player, "$2>> $1&lWiki$2: $1https://github.com/IntellectualCrafters/PlotSquared/wiki");
MainUtil.sendMessage(player, "$2>> $1&lNewest Version$2: $1" + getNewestVersionString());

View File

@ -1,51 +0,0 @@
package com.intellectualcrafters.plot.commands;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.Updater;
import com.intellectualcrafters.plot.config.C;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.util.MainUtil;
import com.plotsquared.general.commands.CommandDeclaration;
import java.net.MalformedURLException;
import java.net.URL;
@CommandDeclaration(
command = "update",
permission = "plots.admin.command.update",
description = "Update the plugin",
usage = "/plot update",
requiredType = RequiredType.NONE,
aliases = {"updateplugin"},
category = CommandCategory.ADMINISTRATION)
public class Update extends SubCommand {
@Override
public boolean onCommand(PlotPlayer player, String[] args) {
URL url;
if (args.length == 0) {
url = Updater.getUpdate();
} else if (args.length == 1) {
try {
url = new URL(args[0]);
} catch (MalformedURLException ignored) {
MainUtil.sendMessage(player, "&cInvalid URL: " + args[0]);
MainUtil.sendMessage(player, C.COMMAND_SYNTAX, "/plot update [url]");
return false;
}
} else {
MainUtil.sendMessage(player, C.COMMAND_SYNTAX, getUsage().replaceAll("\\{label\\}", "plot"));
return false;
}
if (url == null) {
MainUtil.sendMessage(player, "&cNo update found!");
MainUtil.sendMessage(player, "&cTo manually specify an update URL: /plot update <url>");
return false;
}
if (PS.get().update(player, url) && (url == PS.get().update)) {
PS.get().update = null;
}
return true;
}
}

View File

@ -20,9 +20,13 @@ public class Settings extends Config {
@Final
public static final String WIKI = "https://github.com/IntellectualSites/PlotSquared/wiki";
@Final
public static String VERSION = null; // These values are set from PS before loading
public static String DATE; // These values are set from P2 before loading
@Final
public static String PLATFORM = null; // These values are set from PS before loading
public static String BUILD; // These values are set from P2 before loading
@Final
public static String COMMIT; // These values are set from P2 before loading
@Final
public static String PLATFORM; // These values are set from P2 before loading
@Comment("Show additional information in console")
public static boolean DEBUG = true;
@ -293,7 +297,7 @@ public class Settings extends Config {
public static boolean COMMANDS = true;
@Comment("The UUID cacher is used to resolve player names")
public static boolean UUID_CACHE = true;
@Comment("Notify players of updates")
@Comment("The plugin auto updater")
public static boolean UPDATER = true;
@Comment("Stores user metadata in a database")
public static boolean PERSISTENT_META = true;

View File

@ -405,22 +405,22 @@ public abstract class PlotPlayer implements CommandCaller, OfflinePlotPlayer {
*/
public void unregister() {
Plot plot = getCurrentPlot();
if (plot != null && Settings.Enabled_Components.PERSISTENT_META && plot.getArea() instanceof SinglePlotArea) {
PlotId id = plot.getId();
int x = id.x;
int z = id.y;
ByteBuffer buffer = ByteBuffer.allocate(13);
buffer.putShort((short) x);
buffer.putShort((short) z);
Location loc = getLocation();
buffer.putInt(loc.getX());
buffer.put((byte) loc.getY());
buffer.putInt(loc.getZ());
setPersistentMeta("quitLoc", buffer.array());
} else if (hasPersistentMeta("quitLoc")) {
removePersistentMeta("quitLoc");
}
if (plot != null) {
if (Settings.Enabled_Components.PERSISTENT_META) {
if (plot.getArea() instanceof SinglePlotArea) {
PlotId id = plot.getId();
int x = id.x;
int z = id.y;
ByteBuffer buffer = ByteBuffer.allocate(13);
buffer.putShort((short) x);
buffer.putShort((short) z);
Location loc = getLocation();
buffer.putInt(loc.getX());
buffer.put((byte) loc.getY());
buffer.putInt(loc.getZ());
setPersistentMeta("quitLoc", buffer.array());
}
}
EventUtil.manager.callLeave(this, plot);
}
if (Settings.Enabled_Components.BAN_DELETER && isBanned()) {

View File

@ -70,12 +70,6 @@ public abstract class EventUtil {
MainUtil.sendMessage(player, C.WORLDEDIT_BYPASSED);
}
}
if (PS.get().update != null && Permissions.hasPermission(player, C.PERMISSION_ADMIN_UPDATE) && Settings.Enabled_Components.UPDATER) {
if (PS.get().getJavaVersion() < 1.8) {
MainUtil.sendMessage(player, C.CONSOLE_JAVA_OUTDATED.f(PS.get().IMP.getPluginName()));
}
MainUtil.sendMessage(player, "&6An update for " + PS.imp().getPluginName() + " is available: &7/plot update");
}
final Plot plot = player.getCurrentPlot();
if (Settings.Teleport.ON_LOGIN && plot != null) {
TaskManager.runTask(new Runnable() {

View File

@ -112,6 +112,15 @@ public class MainUtil {
}
}
public static void sendAdmin(final String s) {
for (final PlotPlayer player : UUIDHandler.getPlayers().values()) {
if (player.hasPermission(C.PERMISSION_ADMIN.s())) {
player.sendMessage(s);
}
}
PS.debug(s);
}
public static void upload(UUID uuid, String file, String extension, final RunnableVal<OutputStream> writeTask, final RunnableVal<URL> whenDone) {
if (writeTask == null) {
PS.debug("&cWrite task cannot be null");

View File

@ -1,93 +0,0 @@
package com.intellectualcrafters.plot;
import com.intellectualcrafters.json.JSONArray;
import com.intellectualcrafters.json.JSONObject;
import com.intellectualcrafters.plot.util.StringMan;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Arrays;
import org.junit.Test;
public class UpdaterTest {
private static String readUrl(String urlString) {
BufferedReader reader = null;
try {
URL url = new URL(urlString);
reader = new BufferedReader(new InputStreamReader(url.openStream()));
StringBuilder buffer = new StringBuilder();
int read;
char[] chars = new char[1024];
while ((read = reader.read(chars)) != -1) {
buffer.append(chars, 0, read);
}
return buffer.toString();
} catch (IOException e) {
System.out.println("&dCould not check for updates (0)");
e.printStackTrace();
} finally {
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
@Test
public void getUpdate() throws Exception {
String str = readUrl("https://api.github.com/repos/IntellectualSites/PlotSquared/releases/latest");
JSONObject release = new JSONObject(str);
JSONArray assets = (JSONArray) release.get("assets");
System.out.println(assets.toString());
String downloadURL = String.format("PlotSquared-%s.jar", "Bukkit");
for (int i = 0; i < assets.length(); i++) {
System.out.println(i);
JSONObject asset = assets.getJSONObject(i);
String name = asset.getString("name");
System.out.println(name);
System.out.println(downloadURL);
if (downloadURL.equals(name)) {
try {
String[] split = release.getString("name").split("\\.");
int[] version;
if (split.length == 3) {
version = new int[]{Integer.parseInt(split[0]), Integer.parseInt(split[1]), Integer.parseInt(split[2])};
} else {
version = new int[]{Integer.parseInt(split[0]), Integer.parseInt(split[1]), 0};
}
System.out.println(Arrays.toString(version));
URL url = new URL(asset.getString("browser_download_url"));
// If current version >= update
if (checkVersion(new int[]{3, 3, 1}, version)) {
System.out.println("&7PlotSquared is already up to date!");
return;
}
System.out.println("&6PlotSquared " + StringMan.join(split, ".") + " is available:");
System.out.println("&8 - &3Use: &7/plot update");
System.out.println("&8 - &3Or: &7" + downloadURL);
return;
} catch (MalformedURLException e) {
e.printStackTrace();
System.out.println("&dCould not check for updates (1)");
System.out.println("&7 - Manually check for updates: https://github.com/IntellectualSites/PlotSquared/releases");
}
}
}
System.out.println("You are running the latest version of PlotSquared");
return;
}
public boolean checkVersion(int[] version, int... version2) {
return version[0] > version2[0] || version[0] == version2[0] && version[1] > version2[1] || version[0] == version2[0]
&& version[1] == version2[1] && version[2] >= version2[2];
}
}

View File

@ -1,5 +1,3 @@
import org.ajoberstar.grgit.Grgit
buildscript {
repositories {
mavenCentral()
@ -14,11 +12,23 @@ buildscript {
group = 'com.intellectualcrafters'
def revision = ""
def buildNumber = ""
def date = ""
ext {
git = Grgit.open()
revision = "${git.head().abbreviatedId}"
git = org.ajoberstar.grgit.Grgit.open(file(".git"))
date = git.head().date.format("yy.MM.dd")
revision = "-${git.head().abbreviatedId}"
parents = git.head().parentIds;
index = 0; // Offset to match CI
for (;parents != null && !parents.isEmpty();index++) {
parents = git.getResolve().toCommit(parents.get(0)).getParentIds()
}
buildNumber = "-${index}"
}
version = "3.5.1-SNAPSHOT-${revision}"
version = date + revision + buildNumber
description = rootProject.name
if ( project.hasProperty("lzNoVersion") ) { // gradle build -PlzNoVersion
version = "unknown";