Refactor versioning
This commit is contained in:
8
sources/src/main/java/io/akarin/api/LogWrapper.java
Normal file
8
sources/src/main/java/io/akarin/api/LogWrapper.java
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
package io.akarin.api;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
public abstract class LogWrapper {
|
||||||
|
public final static Logger logger = LogManager.getLogger("Akarin");
|
||||||
|
}
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
package io.akarin.api.mixin;
|
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.command.defaults.VersionCommand;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Overwrite;
|
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
|
|
||||||
@Mixin(value = VersionCommand.class, remap = false)
|
|
||||||
public class MixinVersionCommand {
|
|
||||||
@Shadow private static int getFromRepo(String repo, String hash) { return 0; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Match current version with repository and calculate the distance
|
|
||||||
* @param repo
|
|
||||||
* @param verInfo
|
|
||||||
* @return Version distance from lastest
|
|
||||||
*/
|
|
||||||
@Overwrite
|
|
||||||
private static int getDistance(String repo, String verInfo) {
|
|
||||||
verInfo = verInfo.replace("\"", "");
|
|
||||||
return getFromRepo("Akarin-project/Akarin", verInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A workaround for unexpected calling
|
|
||||||
* @param currentVer
|
|
||||||
* @return Version distance from lastest
|
|
||||||
*/
|
|
||||||
@Overwrite
|
|
||||||
private static int getFromJenkins(int currentVer) {
|
|
||||||
String[] parts = Bukkit.getVersion().substring("git-Akarin-".length()).split("[-\\s]");
|
|
||||||
return getFromRepo("Akarin-project/Akarin", parts[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Shadow private void setVersionMessage(String msg) {}
|
|
||||||
private static boolean customVersion;
|
|
||||||
|
|
||||||
@Overwrite
|
|
||||||
private void obtainVersion() {
|
|
||||||
// Skipping if detected
|
|
||||||
if (customVersion) return;
|
|
||||||
|
|
||||||
String version = Bukkit.getVersion();
|
|
||||||
if (version == null) version = "Unique"; // Custom - > Unique
|
|
||||||
|
|
||||||
if (version.startsWith("git-Akarin-")) {
|
|
||||||
String[] parts = version.substring("git-Akarin-".length()).split("[-\\s]");
|
|
||||||
int distance = getDistance(null, parts[0]);
|
|
||||||
switch (distance) {
|
|
||||||
case -1:
|
|
||||||
setVersionMessage("Error obtaining version information");
|
|
||||||
break;
|
|
||||||
case 0:
|
|
||||||
setVersionMessage("You are running the latest version");
|
|
||||||
break;
|
|
||||||
case -2:
|
|
||||||
setVersionMessage("Unknown version");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
setVersionMessage("You are " + distance + " version(s) behind");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
customVersion = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2,8 +2,6 @@ package io.akarin.server.mixin.core;
|
|||||||
|
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
import org.bukkit.craftbukkit.Main;
|
import org.bukkit.craftbukkit.Main;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
@@ -11,10 +9,10 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
|||||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
import io.akarin.api.LogWrapper;
|
||||||
|
|
||||||
@Mixin(value = Main.class, remap = false)
|
@Mixin(value = Main.class, remap = false)
|
||||||
public class Bootstrap {
|
public class Bootstrap {
|
||||||
private final static Logger logger = LogManager.getLogger("Akarin");
|
|
||||||
|
|
||||||
@Inject(method = "main([Ljava/lang/String;)V", at = @At("HEAD"))
|
@Inject(method = "main([Ljava/lang/String;)V", at = @At("HEAD"))
|
||||||
private static void configureMixin(CallbackInfo info) {
|
private static void configureMixin(CallbackInfo info) {
|
||||||
;
|
;
|
||||||
@@ -29,7 +27,7 @@ public class Bootstrap {
|
|||||||
args = "ldc=*** Warning, you've not updated in a while! ***"
|
args = "ldc=*** Warning, you've not updated in a while! ***"
|
||||||
))
|
))
|
||||||
private static void notifyUpdate(PrintStream stream, String text) {
|
private static void notifyUpdate(PrintStream stream, String text) {
|
||||||
logger.warn("You've not updated in a while, the current version may outdated");
|
LogWrapper.logger.warn("You've not updated in a while, the current version may outdated");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Redirect(method = "main", at = @At(
|
@Redirect(method = "main", at = @At(
|
||||||
@@ -38,7 +36,7 @@ public class Bootstrap {
|
|||||||
args = "ldc=*** Please download a new build as per instructions from https://paperci.emc.gs/ ***"
|
args = "ldc=*** Please download a new build as per instructions from https://paperci.emc.gs/ ***"
|
||||||
))
|
))
|
||||||
private static void notifyWebsite(PrintStream stream, String text) {
|
private static void notifyWebsite(PrintStream stream, String text) {
|
||||||
logger.warn("Visit our website for latest information https://akarin.io/");
|
LogWrapper.logger.warn("Visit our website for latest information https://akarin.io/");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Redirect(method = "main", at = @At(
|
@Redirect(method = "main", at = @At(
|
||||||
@@ -47,6 +45,6 @@ public class Bootstrap {
|
|||||||
args = "ldc=Loading libraries, please wait..."
|
args = "ldc=Loading libraries, please wait..."
|
||||||
))
|
))
|
||||||
private static void notifyLoading(PrintStream stream, String text) {
|
private static void notifyLoading(PrintStream stream, String text) {
|
||||||
logger.info("Loading libraries, please wait..");
|
LogWrapper.logger.info("Loading libraries, please wait..");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,144 @@
|
|||||||
|
package io.akarin.server.mixin.core;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.command.defaults.VersionCommand;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Overwrite;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
|
||||||
|
import io.akarin.api.LogWrapper;
|
||||||
|
import net.minecraft.server.MCUtil;
|
||||||
|
|
||||||
|
@Mixin(value = VersionCommand.class, remap = false)
|
||||||
|
public class MixinVersionCommand {
|
||||||
|
@Shadow private static int getFromRepo(String repo, String hash) { return 0; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Match current version with repository and calculate the distance
|
||||||
|
* @param repo
|
||||||
|
* @param verInfo
|
||||||
|
* @return Version distance from lastest
|
||||||
|
*/
|
||||||
|
@Overwrite
|
||||||
|
private static int getDistance(String repo, String verInfo) {
|
||||||
|
verInfo = verInfo.replace("\"", "");
|
||||||
|
return getFromRepo("Akarin-project/Akarin", verInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A workaround for unexpected calling
|
||||||
|
* @param currentVer
|
||||||
|
* @return Version distance from lastest
|
||||||
|
*/
|
||||||
|
@Overwrite
|
||||||
|
private static int getFromJenkins(int currentVer) {
|
||||||
|
String[] parts = Bukkit.getVersion().substring("git-Akarin-".length()).split("[-\\s]");
|
||||||
|
return getFromRepo("Akarin-project/Akarin", parts[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Shadow private boolean hasVersion;
|
||||||
|
@Shadow private String versionMessage;
|
||||||
|
@Shadow private @Final Set<CommandSender> versionWaiters;
|
||||||
|
|
||||||
|
private volatile boolean versionObtaining;
|
||||||
|
private long lastCheckMillis;
|
||||||
|
|
||||||
|
// The name can lead to misunderstand,
|
||||||
|
// this method doesn't send the whole version message (e.g. 'This server is running {} version' or 'Previous version'),
|
||||||
|
// it is only responsible for checking the version distance!
|
||||||
|
@Overwrite
|
||||||
|
private void sendVersion(CommandSender sender) {
|
||||||
|
// Skipping if already detected a custom version identifier (e.g. 'git-Akarin-')
|
||||||
|
// This should be lying in 'obtainVersion' method, but bump for faster returning
|
||||||
|
if (customVersion) return;
|
||||||
|
|
||||||
|
if (versionObtaining) return;
|
||||||
|
// The volatile guarantees the safety between different threads.
|
||||||
|
// Remembers that we are still on main thread now,
|
||||||
|
// it's not guarantee that what time the last check ends,
|
||||||
|
// but it's guarantee that only one request will be accepted at the same time.
|
||||||
|
// After this, de-sync operations are safety - without lock -
|
||||||
|
// (this is really a special case that we cancel new tasks instead let them wait).
|
||||||
|
versionObtaining = true;
|
||||||
|
|
||||||
|
if (hasVersion) {
|
||||||
|
long current = System.currentTimeMillis();
|
||||||
|
if (current - lastCheckMillis > 7200000 /* 2 hours */) {
|
||||||
|
lastCheckMillis = current;
|
||||||
|
obtainVersion(sender);
|
||||||
|
/* TODO Option: legacy-versioning-compat */ currentSender = sender;
|
||||||
|
} else {
|
||||||
|
sender.sendMessage(versionMessage);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private CommandSender currentSender;
|
||||||
|
private boolean customVersion;
|
||||||
|
|
||||||
|
@Overwrite
|
||||||
|
private void obtainVersion() {
|
||||||
|
if (false /* TODO Option: legacy-versioning-compat */) {
|
||||||
|
/* TODO Option: legacy-versioning-compat = true */
|
||||||
|
LogWrapper.logger.warn("A legacy version lookup caught, legacy-versioning-compat enabled forcely!");
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
} else {
|
||||||
|
obtainVersion(currentSender);
|
||||||
|
currentSender = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void obtainVersion(CommandSender sender) {
|
||||||
|
// We post all things because a custom version is rare (expiring is not rare),
|
||||||
|
// and we'd better post this task as early as we can, since it's a will (horrible destiny).
|
||||||
|
MCUtil.scheduleAsyncTask(() -> {
|
||||||
|
// This should be lying in 'sendVersion' method, but comes here for relax main thread
|
||||||
|
versionWaiters.add(sender);
|
||||||
|
|
||||||
|
String version = Bukkit.getVersion();
|
||||||
|
if (version == null) {
|
||||||
|
version = "Unique"; // Custom - > Unique
|
||||||
|
customVersion = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (version.startsWith("git-Akarin-")) {
|
||||||
|
|
||||||
|
String[] parts = version.substring("git-Akarin-".length()).split("[-\\s]");
|
||||||
|
int distance = getDistance(null, parts[0]);
|
||||||
|
switch (distance) {
|
||||||
|
case -1:
|
||||||
|
setVersionMessage("Error obtaining version information");
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
setVersionMessage("You are running the latest version");
|
||||||
|
break;
|
||||||
|
case -2:
|
||||||
|
setVersionMessage("Unknown version");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
setVersionMessage("You are " + distance + " version(s) behind");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
customVersion = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
versionObtaining = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Overwrite
|
||||||
|
private void setVersionMessage(String message) {
|
||||||
|
versionMessage = message;
|
||||||
|
hasVersion = true;
|
||||||
|
|
||||||
|
for (CommandSender sender : versionWaiters) {
|
||||||
|
sender.sendMessage(versionMessage);
|
||||||
|
}
|
||||||
|
versionWaiters.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user