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 org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.bukkit.craftbukkit.Main;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
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.callback.CallbackInfo;
|
||||
|
||||
import io.akarin.api.LogWrapper;
|
||||
|
||||
@Mixin(value = Main.class, remap = false)
|
||||
public class Bootstrap {
|
||||
private final static Logger logger = LogManager.getLogger("Akarin");
|
||||
|
||||
@Inject(method = "main([Ljava/lang/String;)V", at = @At("HEAD"))
|
||||
private static void configureMixin(CallbackInfo info) {
|
||||
;
|
||||
@@ -29,7 +27,7 @@ public class Bootstrap {
|
||||
args = "ldc=*** Warning, you've not updated in a while! ***"
|
||||
))
|
||||
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(
|
||||
@@ -38,7 +36,7 @@ public class Bootstrap {
|
||||
args = "ldc=*** Please download a new build as per instructions from https://paperci.emc.gs/ ***"
|
||||
))
|
||||
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(
|
||||
@@ -47,6 +45,6 @@ public class Bootstrap {
|
||||
args = "ldc=Loading libraries, please wait..."
|
||||
))
|
||||
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