1.19.4 Update by TrueOG Network
This commit is contained in:
1 parent
454506a1b8
commit
e2e4b8c713
11 files changed
+44
-220
No files matched your search
@@ -0,0 +1,3 @@
|
||||
[submodule "libs/Utilities-OG"]
|
||||
path = libs/Utilities-OG
|
||||
url = https://github.com/NotAlexNoyle/Utilities-OG
|
||||
Executable
+4
@@ -0,0 +1,4 @@
|
||||
#!/usr/bin/bash
|
||||
|
||||
# Fetch all submodule content.
|
||||
git submodule update --force --recursive --init --remote
|
||||
@@ -38,6 +38,7 @@ repositories {
|
||||
dependencies {
|
||||
compileOnly("org.purpurmc.purpur:purpur-api:1.19.4-R0.1-SNAPSHOT") // Declare purpur API version to be packaged.
|
||||
compileOnly("io.github.miniplaceholders:miniplaceholders-api:2.2.3") // Import MiniPlaceholders API.
|
||||
implementation(project(":libs:Utilities-OG")) // Import source-based Utilities-OG API.
|
||||
}
|
||||
|
||||
tasks.withType<AbstractArchiveTask>().configureEach {
|
||||
|
||||
Submodule
+1
Submodule libs/Utilities-OG added at 22e35ff81a.
+9
-1
@@ -1 +1,9 @@
|
||||
rootProject.name "MCShared-OG"
|
||||
rootProject.name = "MCShared-OG"
|
||||
|
||||
// Execute bootstrap.sh
|
||||
exec {
|
||||
workingDir(rootDir)
|
||||
commandLine("sh", "bootstrap.sh")
|
||||
}
|
||||
|
||||
include("libs:Utilities-OG")
|
||||
@@ -103,7 +103,7 @@ public class CommentedYamlConfiguration extends YamlConfiguration {
|
||||
if (comment != null) {
|
||||
// Insert comment as new value in the file; will be converted back to a comment when saved by the
|
||||
// FileManager.
|
||||
this.set(plugin.getDescription().getName() + "_COMMENT_" + numOfComments, comment.replace(":", "_COLON_")
|
||||
this.set(plugin.getPluginMeta().getName() + "_COMMENT_" + numOfComments, comment.replace(":", "_COLON_")
|
||||
.replace("|", "_VERT_").replace("-", "_HYPHEN_").replace(" ", "_SPACE_"));
|
||||
numOfComments++;
|
||||
}
|
||||
@@ -120,7 +120,7 @@ public class CommentedYamlConfiguration extends YamlConfiguration {
|
||||
public void set(String path, Object value, String... comments) {
|
||||
for (String comment : comments) {
|
||||
// Insert comment as new value in the file; will be converted back to a comment when saved.
|
||||
this.set(plugin.getDescription().getName() + "_COMMENT_" + numOfComments, comment.replace(":", "_COLON_")
|
||||
this.set(plugin.getPluginMeta().getName() + "_COMMENT_" + numOfComments, comment.replace(":", "_COLON_")
|
||||
.replace("|", "_VERT_").replace("-", "_HYPHEN_").replace(" ", "_SPACE_"));
|
||||
numOfComments++;
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ public class FileManager {
|
||||
// This workaround allows the comment to be saved when using Bukkit's YamlConfiguration class.
|
||||
reworkedConfiguration.append(currentLine.replace(":", "_COLON_").replace("|", "_VERT_")
|
||||
.replace("-", "_HYPHEN_").replace(" ", "_SPACE_")
|
||||
.replaceFirst("#", plugin.getDescription().getName() + "_COMMENT_" + numOfComments + ": "));
|
||||
.replaceFirst("#", plugin.getPluginMeta().getName() + "_COMMENT_" + numOfComments + ": "));
|
||||
numOfComments++;
|
||||
} else {
|
||||
reworkedConfiguration.append(currentLine);
|
||||
@@ -170,7 +170,7 @@ public class FileManager {
|
||||
String[] lines = configString.split("\n");
|
||||
StringBuilder config = new StringBuilder();
|
||||
for (String line : lines) {
|
||||
if (line.startsWith(plugin.getDescription().getName() + "_COMMENT")) {
|
||||
if (line.startsWith(plugin.getPluginMeta().getName() + "_COMMENT")) {
|
||||
// Rework comment line so it is converted back to a normal comment.
|
||||
String comment = ("#" + line.substring(line.indexOf(": ") + 2)).replace("_COLON_", ":")
|
||||
.replace("_HYPHEN_", "-").replace("_VERT_", "|").replace("_SPACE_", " ");
|
||||
|
||||
@@ -2,11 +2,13 @@ package com.hm.mcshared.particle;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import com.hm.mcshared.particle.ReflectionUtils.PackageType;
|
||||
|
||||
import me.barny1094875.utilitiesog.UtilitiesOG;
|
||||
import net.kyori.adventure.text.TextComponent;
|
||||
|
||||
/**
|
||||
* Class used to send fancy messages to the player; can be titles, hoverable chat messages or action bar messages. All
|
||||
* methods are static and this class cannot be instanciated.
|
||||
@@ -122,18 +124,18 @@ public final class FancyMessageSender {
|
||||
// Prior to version 1.8.3.
|
||||
parsedMainMessage = PackageType.MINECRAFT_SERVER.getClass(NESTED_CHAT_SERIALIZER)
|
||||
.getMethod("a", String.class)
|
||||
.invoke(null, ChatColor.translateAlternateColorCodes('&', titleJson));
|
||||
.invoke(null, UtilitiesOG.trueogTextInterpreter(player, titleJson));
|
||||
parsedSubMessage = PackageType.MINECRAFT_SERVER.getClass(NESTED_CHAT_SERIALIZER)
|
||||
.getMethod("a", String.class)
|
||||
.invoke(null, ChatColor.translateAlternateColorCodes('&', subtitleJson));
|
||||
.invoke(null, UtilitiesOG.trueogTextInterpreter(player, subtitleJson));
|
||||
titleClass = PackageType.MINECRAFT_SERVER.getClass(ENUM_TITLE_ACTION);
|
||||
} else {
|
||||
parsedMainMessage = PackageType.MINECRAFT_SERVER
|
||||
.getClass(CLASS_CHAT_BASE_COMPONENT + "$" + NESTED_CHAT_SERIALIZER).getMethod("a", String.class)
|
||||
.invoke(null, ChatColor.translateAlternateColorCodes('&', titleJson));
|
||||
.invoke(null, UtilitiesOG.trueogTextInterpreter(player, titleJson));
|
||||
parsedSubMessage = PackageType.MINECRAFT_SERVER
|
||||
.getClass(CLASS_CHAT_BASE_COMPONENT + "$" + NESTED_CHAT_SERIALIZER).getMethod("a", String.class)
|
||||
.invoke(null, ChatColor.translateAlternateColorCodes('&', subtitleJson));
|
||||
.invoke(null, UtilitiesOG.trueogTextInterpreter(player, subtitleJson));
|
||||
titleClass = PackageType.MINECRAFT_SERVER.getClass(CLASS_PACKET_PLAY_OUT_TITLE + "$" + ENUM_TITLE_ACTION);
|
||||
}
|
||||
|
||||
@@ -157,8 +159,8 @@ public final class FancyMessageSender {
|
||||
|
||||
// Send the message packet through the PlayerConnection (title).
|
||||
PackageType.MINECRAFT_SERVER.getClass(CLASS_PLAYER_CONNECTION)
|
||||
.getMethod(METHOD_SEND_PACKET, PackageType.MINECRAFT_SERVER.getClass(CLASS_PACKET))
|
||||
.invoke(playerConnection, packetPlayOutChatMainTitle);
|
||||
.getMethod(METHOD_SEND_PACKET, PackageType.MINECRAFT_SERVER.getClass(CLASS_PACKET))
|
||||
.invoke(playerConnection, packetPlayOutChatMainTitle);
|
||||
|
||||
Object packetPlayOutChatSubTitle = ReflectionUtils
|
||||
.getConstructor(PackageType.MINECRAFT_SERVER.getClass(CLASS_PACKET_PLAY_OUT_TITLE),
|
||||
@@ -168,8 +170,8 @@ public final class FancyMessageSender {
|
||||
|
||||
// Send the message packet through the PlayerConnection (subtitle).
|
||||
PackageType.MINECRAFT_SERVER.getClass(CLASS_PLAYER_CONNECTION)
|
||||
.getMethod(METHOD_SEND_PACKET, PackageType.MINECRAFT_SERVER.getClass(CLASS_PACKET))
|
||||
.invoke(playerConnection, packetPlayOutChatSubTitle);
|
||||
.getMethod(METHOD_SEND_PACKET, PackageType.MINECRAFT_SERVER.getClass(CLASS_PACKET))
|
||||
.invoke(playerConnection, packetPlayOutChatSubTitle);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -193,12 +195,10 @@ public final class FancyMessageSender {
|
||||
if (PackageType.getServerVersion().startsWith("1_8_R1")) {
|
||||
// Prior to version 1.8.3.
|
||||
parsedMessage = PackageType.MINECRAFT_SERVER.getClass(NESTED_CHAT_SERIALIZER).getMethod("a", String.class)
|
||||
.invoke(null, ChatColor.translateAlternateColorCodes('&', json));
|
||||
.invoke(null, UtilitiesOG.trueogTextInterpreter(player, json));
|
||||
} else {
|
||||
parsedMessage = Class
|
||||
.forName(PackageType.MINECRAFT_SERVER + "." + CLASS_CHAT_BASE_COMPONENT + "$" + NESTED_CHAT_SERIALIZER)
|
||||
.getMethod("a", String.class)
|
||||
.invoke(null, ChatColor.translateAlternateColorCodes('&', json));
|
||||
TextComponent textComponent = UtilitiesOG.trueogTextInterpreter(player, json);
|
||||
parsedMessage = textComponent;
|
||||
}
|
||||
|
||||
Object packetPlayOutChat;
|
||||
@@ -237,8 +237,8 @@ public final class FancyMessageSender {
|
||||
|
||||
// Send the message packet through the PlayerConnection.
|
||||
PackageType.MINECRAFT_SERVER.getClass(CLASS_PLAYER_CONNECTION)
|
||||
.getMethod(METHOD_SEND_PACKET, PackageType.MINECRAFT_SERVER.getClass(CLASS_PACKET))
|
||||
.invoke(playerConnection, packetPlayOutChat);
|
||||
.getMethod(METHOD_SEND_PACKET, PackageType.MINECRAFT_SERVER.getClass(CLASS_PACKET))
|
||||
.invoke(playerConnection, packetPlayOutChat);
|
||||
}
|
||||
|
||||
private static String constructTextJson(String text) {
|
||||
|
||||
@@ -624,7 +624,7 @@ public enum ParticleEffect {
|
||||
throw new IllegalArgumentException("There is no water at the center location");
|
||||
}
|
||||
new ParticlePacket(this, offsetX, offsetY, offsetZ, speed, amount, isLongDistance(center, players), null)
|
||||
.sendTo(center, players);
|
||||
.sendTo(center, players);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -864,7 +864,7 @@ public enum ParticleEffect {
|
||||
throw new ParticleDataException("The particle data type is incorrect");
|
||||
}
|
||||
new ParticlePacket(this, offsetX, offsetY, offsetZ, speed, amount, isLongDistance(center, players), data)
|
||||
.sendTo(center, players);
|
||||
.sendTo(center, players);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -90,7 +90,7 @@ public final class ReflectionUtils {
|
||||
* @throws NoSuchMethodException If the desired constructor with the specified arguments cannot be found
|
||||
*/
|
||||
public static Object instantiateObject(Class<?> clazz, Object... arguments) throws InstantiationException,
|
||||
IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException {
|
||||
IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException {
|
||||
|
||||
return getConstructor(clazz, DataType.getPrimitive(arguments)).newInstance(arguments);
|
||||
}
|
||||
@@ -233,7 +233,7 @@ public final class ReflectionUtils {
|
||||
*/
|
||||
public static Object invokeMethod(Object instance, String className, PackageType packageType, String methodName,
|
||||
Object... arguments) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException,
|
||||
NoSuchMethodException, ClassNotFoundException {
|
||||
NoSuchMethodException, ClassNotFoundException {
|
||||
|
||||
return invokeMethod(instance, packageType.getClass(className), methodName, arguments);
|
||||
}
|
||||
@@ -313,7 +313,7 @@ public final class ReflectionUtils {
|
||||
*/
|
||||
public static Object getValue(Object instance, String className, PackageType packageType, boolean declared,
|
||||
String fieldName) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException,
|
||||
SecurityException, ClassNotFoundException {
|
||||
SecurityException, ClassNotFoundException {
|
||||
|
||||
return getValue(instance, packageType.getClass(className), declared, fieldName);
|
||||
}
|
||||
@@ -376,7 +376,7 @@ public final class ReflectionUtils {
|
||||
*/
|
||||
public static void setValue(Object instance, String className, PackageType packageType, boolean declared,
|
||||
String fieldName, Object value) throws IllegalArgumentException, IllegalAccessException,
|
||||
NoSuchFieldException, SecurityException, ClassNotFoundException {
|
||||
NoSuchFieldException, SecurityException, ClassNotFoundException {
|
||||
|
||||
setValue(instance, packageType.getClass(className), declared, fieldName, value);
|
||||
}
|
||||
|
||||
@@ -1,193 +0,0 @@
|
||||
package com.hm.mcshared.update;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.FutureTask;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.w3c.dom.Document;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
/**
|
||||
* Class used to check for newer versions of a plugin by retrieving a version tag in a pom.xml file. For instance
|
||||
* versions 2.0, 1.2 and 1.1.1 are all considered newer than 1.1.
|
||||
* <p>
|
||||
* If a newer version is available, the information will be logged in the server's console and a message will be sent
|
||||
* when players with a specific permission join the game.
|
||||
* <p>
|
||||
* This class implements the org.bukkit.event.Listener class. To use it, simply create an instance of this class and
|
||||
* register events to the server's PluginManager (for instance in your plugin class extending JavaPlugin:
|
||||
* getServer().getPluginManager().registerEvents(updateChecker, this);).
|
||||
*
|
||||
* @author Pyves
|
||||
*/
|
||||
public class UpdateChecker implements Listener {
|
||||
|
||||
private final JavaPlugin plugin;
|
||||
private final String pomLink;
|
||||
private final String downloadLink;
|
||||
private final String notificationPermission;
|
||||
private final String chatHeader;
|
||||
|
||||
// Marked as volatile to ensure that once the updateCheckerFutureTask is done, the version is visible to the main
|
||||
// thread of execution.
|
||||
private volatile String version;
|
||||
|
||||
private Boolean updateNeeded = null;
|
||||
private FutureTask<Boolean> updateCheckerFutureTask;
|
||||
|
||||
/**
|
||||
* Creates an instance of the UpdateChecker class.
|
||||
*
|
||||
* @param plugin The plugin involved in the version checking.
|
||||
* @param pomLink The link to the plugin's pom.xml. For instance
|
||||
* https://raw.githubusercontent.com/PyvesB/AdvancedAchievements/master/pom.xml can be used.
|
||||
* @param notificationPermission Only players with this permissions will be notified in game.
|
||||
* @param chatHeader Header of the message to display in the chat when notifying that an update is available.
|
||||
* @param downloadLink The link from which the plugin can be downloaded; will be displayed in the server's console
|
||||
* and in game to users with notificationPermission.
|
||||
*/
|
||||
public UpdateChecker(JavaPlugin plugin, String pomLink, String notificationPermission, String chatHeader,
|
||||
String downloadLink) {
|
||||
this.plugin = plugin;
|
||||
this.pomLink = pomLink;
|
||||
this.notificationPermission = notificationPermission;
|
||||
this.chatHeader = chatHeader;
|
||||
this.downloadLink = downloadLink;
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens to PlayerJoinEvents and informs players with a specific permission that an update is available.
|
||||
*
|
||||
* @param event Event sent to this listener method.
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||
// Check if OP to display new version message if needed.
|
||||
if (isUpdateNeeded() && event.getPlayer().hasPermission(notificationPermission)) {
|
||||
event.getPlayer().sendMessage(chatHeader + plugin.getDescription().getName() + " update available: v"
|
||||
+ version + ". Download at " + downloadLink);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Launches a new thread to asynchronously check whether an update is available.
|
||||
*/
|
||||
public void launchUpdateCheckerTask() {
|
||||
updateCheckerFutureTask = new FutureTask<>(new Callable<Boolean>() {
|
||||
|
||||
@Override
|
||||
public Boolean call() throws Exception {
|
||||
|
||||
return checkForUpdate();
|
||||
}
|
||||
});
|
||||
// Run the FutureTask in a new thread.
|
||||
new Thread(updateCheckerFutureTask).start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the plugin needs to be updated. Will always return false if launchUpdateCheckerTask has not yet
|
||||
* been called or the asynchronous call has not yet completed.
|
||||
*
|
||||
* @return true is an update is available, false otherwise.
|
||||
*/
|
||||
public boolean isUpdateNeeded() {
|
||||
// Completion of the FutureTask has not yet been checked.
|
||||
if (updateNeeded == null) {
|
||||
if (updateCheckerFutureTask.isDone()) {
|
||||
try {
|
||||
// Retrieve result of the FutureTask.
|
||||
updateNeeded = updateCheckerFutureTask.get();
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
// Error during execution; assume that no updates are available.
|
||||
updateNeeded = false;
|
||||
plugin.getLogger()
|
||||
.severe("Error while checking for " + plugin.getDescription().getName() + " update.");
|
||||
}
|
||||
} else {
|
||||
// FutureTask not yet completed; indicate that no updates are available. If an OP joins before the task
|
||||
// completes, he will not be notified; this is both an unlikely and non critical scenario.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return updateNeeded;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the version tag of the plugin parsed from the specified pom.xml. Will be null if launchUpdateCheckerTask
|
||||
* has not yet been called or the asynchronous call has not yet completed.
|
||||
*
|
||||
* @return The version tag of the plugin parsed from the specified pom.xml.
|
||||
*/
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a new version of the plugin is available, and logs in the server's console if a new version is found.
|
||||
*
|
||||
* @return True if an update is available, false otherwise.
|
||||
*
|
||||
* @throws ParserConfigurationException
|
||||
* @throws IOException
|
||||
* @throws SAXException
|
||||
*/
|
||||
private boolean checkForUpdate() throws SAXException, IOException, ParserConfigurationException {
|
||||
plugin.getLogger().info("Checking for plugin update...");
|
||||
|
||||
Document document = null;
|
||||
|
||||
URL filesFeed = new URL(pomLink);
|
||||
try (InputStream pomInput = filesFeed.openConnection().getInputStream()) {
|
||||
document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(pomInput);
|
||||
}
|
||||
|
||||
// Retrieve version information.
|
||||
version = document.getElementsByTagName("version").item(0).getTextContent();
|
||||
|
||||
if (version.equals(plugin.getDescription().getVersion())) {
|
||||
return false;
|
||||
}
|
||||
// Version of current plugin.
|
||||
String[] pluginVersion = plugin.getDescription().getVersion().split("\\.");
|
||||
|
||||
// Version of the pom.xml file.
|
||||
String[] onlineVersion = version.split("\\.");
|
||||
|
||||
// Compare version numbers.
|
||||
for (int i = 0; i < Math.min(pluginVersion.length, onlineVersion.length); i++) {
|
||||
if (Integer.parseInt(pluginVersion[i]) > Integer.parseInt(onlineVersion[i])) {
|
||||
return false;
|
||||
} else if (Integer.parseInt(pluginVersion[i]) < Integer.parseInt(onlineVersion[i])) {
|
||||
logUpdate();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Both versions have the same prefix; additional length check (for instance pluginVersion = 2.2 and
|
||||
// onlineVersion = 2.2.1).
|
||||
if (pluginVersion.length < onlineVersion.length) {
|
||||
logUpdate();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs in the server's console if a new version is found. The new version number and download links are printed.
|
||||
*/
|
||||
private void logUpdate() {
|
||||
plugin.getLogger().warning("Update available: v" + version + "! Download at " + downloadLink);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user