diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml index 66d5240..884e02f 100644 --- a/.idea/jarRepositories.xml +++ b/.idea/jarRepositories.xml @@ -1,16 +1,26 @@ - - + + + + + + - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index e95b7ea..fa2b941 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -12,5 +12,5 @@ - + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..797acea --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/README.md b/README.md index aa83235..c36d140 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # SimplifyTools -### An 'All-in-one' helper plugin for Minecraft Spigot Servers. -| Build Status | [![Build Status](https://ci.dit-services.tk/job/SimplifyTools/badge/icon)](https://ci.dit-services.tk/job/SimplifyTools/) | +### An 'All-in-one' helper plugin for Minecraft Spigot Servers with a goal of combine useful plugins to a one. +| Build Status | [![Build Status](https://ci.ditservices.hu/job/SimplifyTools/badge/icon)](https://ci.ditservices.hu/job/SimplifyTools/) | |:-------------:|:-----------------------------------------------------------------------------------------------------------------:| -| MC Version | ![ MC Version](https://ci.dit-services.tk/job/SimplifyTools/badge/icon?subject=MC&status=1.16.5&color=darkblue) | +| MC Version | ![ MC Version](https://ci.ditservices.hu/job/SimplifyTools/badge/icon?subject=MC&status=1.18.2&color=darkblue) | | Lines of code | ![ Lines of code](https://tokei.rs/b1/github/LabodiDavid/SimplifyTools?category=code) | | Files | ![ Files](https://tokei.rs/b1/github/LabodiDavid/SimplifyTools?category=files) | ## Features @@ -23,13 +23,14 @@ ![Advancement Messages preview](docs/img/4.gif) - **Logging** - A logger with fully customizable format for dis/connect, chat, commands actions. ### [Check the config file for more explanation and examples](https://github.com/LabodiDavid/SimplifyTools/blob/main/src/main/resources/config.yml) - +_________________ ### [Commands & Permissions](docs/cmd_perms.md) - +_________________ ### If you have an idea or bug report [Create an issue](https://github.com/LabodiDavid/SimplifyTools/issues/new/choose) or [Create a pull request](https://github.com/LabodiDavid/SimplifyTools/compare) - +_________________ ## Main goal -My main goal is to create a single plugin that has many features, so it's can replace so many plugins that i often use on my servers while lowering the plugins count. - +My main goal is to create a single plugin that has many features, so it's can replace plugins that i often use on my servers while lowering the plugins count. +_________________ ## 3rd party libraries used by this plugin -### [Config-Updater by tchristofferson](https://github.com/tchristofferson/Config-Updater) \ No newline at end of file +### [Config-Updater by tchristofferson](https://github.com/tchristofferson/Config-Updater) +### [SpigotUpdateChecker by JEFF-Media-GbR](https://github.com/JEFF-Media-GbR/Spigot-UpdateChecker) \ No newline at end of file diff --git a/SimplifyTools.iml b/SimplifyTools.iml index 76d178c..78cccfa 100644 --- a/SimplifyTools.iml +++ b/SimplifyTools.iml @@ -9,6 +9,9 @@ + + @@ -21,6 +24,66 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/ChangeLog.md b/docs/ChangeLog.md index baeeb81..6a70827 100644 --- a/docs/ChangeLog.md +++ b/docs/ChangeLog.md @@ -1,4 +1,8 @@ -## SimplifyTools Changelog - +# SimplifyTools - Changelog + - 1.1.0 + - Updated to 1.18.2 + - Minor changes + - Temporarily reworked Plugin Manager + - Added Update Checker (https://github.com/JEFF-Media-GbR/Spigot-UpdateChecker) - 1.0.0 - First Release - - Notice: If the /st reload command not reloading the new settings, you need to restart your MC server. + - Notice: If the /st reload command not reloading the new settings, you need to restart your MC server. diff --git a/pom.xml b/pom.xml index d7688fe..96a3494 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ tk.ditservices SimplifyTools - 1.0.0-SNAPSHOT + 1.1.0-SNAPSHOT jar SimplifyTools @@ -16,11 +16,11 @@ 1.8 UTF-8 - dit-services.tk + ditservices.hu jenkins - https://ci.dit-services.tk/job/SimplifyTools/ + https://ci.ditservices.hu/job/SimplifyTools/ @@ -52,6 +52,15 @@ org.apache.maven.plugins maven-shade-plugin 3.1.0 + + + + + com.jeff_media.updatechecker + tk.ditservices.updatechecker + + + package @@ -78,6 +87,10 @@ spigot-repo https://hub.spigotmc.org/nexus/content/repositories/snapshots/ --> + + jeff-media-public + https://hub.jeff-media.com/nexus/repository/jeff-media-public/ + sonatype https://oss.sonatype.org/content/groups/public/ @@ -89,8 +102,14 @@ org.spigotmc spigot - 1.16.5-R0.1-SNAPSHOT + 1.18.2-R0.1-SNAPSHOT provided + + com.jeff_media + SpigotUpdateChecker + 2.2.0 + compile + diff --git a/src/main/java/com/tchristofferson/configupdater/ConfigUpdater.java b/src/main/java/com/tchristofferson/configupdater/ConfigUpdater.java new file mode 100644 index 0000000..938790d --- /dev/null +++ b/src/main/java/com/tchristofferson/configupdater/ConfigUpdater.java @@ -0,0 +1,241 @@ +package com.tchristofferson.configupdater; + +import com.google.common.base.Preconditions; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.plugin.Plugin; + +import java.io.*; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.*; + +public class ConfigUpdater { + + //Used for separating keys in the keyBuilder inside parseComments method + private static final char SEPARATOR = '.'; + + public static void update(Plugin plugin, String resourceName, File toUpdate, String... ignoredSections) throws IOException { + update(plugin, resourceName, toUpdate, Arrays.asList(ignoredSections)); + } + + public static void update(Plugin plugin, String resourceName, File toUpdate, List ignoredSections) throws IOException { + Preconditions.checkArgument(toUpdate.exists(), "The toUpdate file doesn't exist!"); + + FileConfiguration defaultConfig = YamlConfiguration.loadConfiguration(new InputStreamReader(plugin.getResource(resourceName), StandardCharsets.UTF_8)); + FileConfiguration currentConfig = YamlConfiguration.loadConfiguration(toUpdate); + Map comments = parseComments(plugin, resourceName, defaultConfig); + Map ignoredSectionsValues = parseIgnoredSections(toUpdate, currentConfig, comments, ignoredSections == null ? Collections.emptyList() : ignoredSections); + + // will write updated config file "contents" to a string + StringWriter writer = new StringWriter(); + write(defaultConfig, currentConfig, new BufferedWriter(writer), comments, ignoredSectionsValues); + String value = writer.toString(); // config contents + + Path toUpdatePath = toUpdate.toPath(); + if (!value.equals(new String(Files.readAllBytes(toUpdatePath), StandardCharsets.UTF_8))) { // if updated contents are not the same as current file contents, update + Files.write(toUpdatePath, value.getBytes(StandardCharsets.UTF_8)); + } + } + + private static void write(FileConfiguration defaultConfig, FileConfiguration currentConfig, BufferedWriter writer, Map comments, Map ignoredSectionsValues) throws IOException { + //Used for converting objects to yaml, then cleared + FileConfiguration parserConfig = new YamlConfiguration(); + + keyLoop: for (String fullKey : defaultConfig.getKeys(true)) { + String indents = KeyBuilder.getIndents(fullKey, SEPARATOR); + + if (ignoredSectionsValues.isEmpty()) { + writeCommentIfExists(comments, writer, fullKey, indents); + } else { + for (Map.Entry entry : ignoredSectionsValues.entrySet()) { + if (entry.getKey().equals(fullKey)) { + writer.write(ignoredSectionsValues.get(fullKey) + "\n"); + continue keyLoop; + } else if (KeyBuilder.isSubKeyOf(entry.getKey(), fullKey, SEPARATOR)) { + continue keyLoop; + } + } + + writeCommentIfExists(comments, writer, fullKey, indents); + } + + Object currentValue = currentConfig.get(fullKey); + + if (currentValue == null) + currentValue = defaultConfig.get(fullKey); + + String[] splitFullKey = fullKey.split("[" + SEPARATOR + "]"); + String trailingKey = splitFullKey[splitFullKey.length - 1]; + + if (currentValue instanceof ConfigurationSection) { + writer.write(indents + trailingKey + ":"); + + if (!((ConfigurationSection) currentValue).getKeys(false).isEmpty()) + writer.write("\n"); + else + writer.write(" {}\n"); + + continue; + } + + parserConfig.set(trailingKey, currentValue); + String yaml = parserConfig.saveToString(); + yaml = yaml.substring(0, yaml.length() - 1).replace("\n", "\n" + indents); + String toWrite = indents + yaml + "\n"; + parserConfig.set(trailingKey, null); + writer.write(toWrite); + } + + String danglingComments = comments.get(null); + + if (danglingComments != null) + writer.write(danglingComments); + + writer.close(); + } + + //Returns a map of key comment pairs. If a key doesn't have any comments it won't be included in the map. + private static Map parseComments(Plugin plugin, String resourceName, FileConfiguration defaultConfig) throws IOException { + BufferedReader reader = new BufferedReader(new InputStreamReader(plugin.getResource(resourceName))); + Map comments = new LinkedHashMap<>(); + StringBuilder commentBuilder = new StringBuilder(); + KeyBuilder keyBuilder = new KeyBuilder(defaultConfig, SEPARATOR); + + String line; + while ((line = reader.readLine()) != null) { + String trimmedLine = line.trim(); + + //Only getting comments for keys. A list/array element comment(s) not supported + if (trimmedLine.startsWith("-")) { + continue; + } + + if (trimmedLine.isEmpty() || trimmedLine.startsWith("#")) {//Is blank line or is comment + commentBuilder.append(trimmedLine).append("\n"); + } else {//is a valid yaml key + keyBuilder.parseLine(trimmedLine); + String key = keyBuilder.toString(); + + //If there is a comment associated with the key it is added to comments map and the commentBuilder is reset + if (commentBuilder.length() > 0) { + comments.put(key, commentBuilder.toString()); + commentBuilder.setLength(0); + } + + //Remove the last key from keyBuilder if current path isn't a config section or if it is empty to prepare for the next key + if (!keyBuilder.isConfigSectionWithKeys()) { + keyBuilder.removeLastKey(); + } + } + } + + reader.close(); + + if (commentBuilder.length() > 0) + comments.put(null, commentBuilder.toString()); + + return comments; + } + + private static Map parseIgnoredSections(File toUpdate, FileConfiguration currentConfig, Map comments, List ignoredSections) throws IOException { + BufferedReader reader = new BufferedReader(new FileReader(toUpdate)); + Map ignoredSectionsValues = new LinkedHashMap<>(ignoredSections.size()); + KeyBuilder keyBuilder = new KeyBuilder(currentConfig, SEPARATOR); + StringBuilder valueBuilder = new StringBuilder(); + + String currentIgnoredSection = null; + String line; + lineLoop : while ((line = reader.readLine()) != null) { + String trimmedLine = line.trim(); + + if (trimmedLine.isEmpty() || trimmedLine.startsWith("#")) + continue; + + if (trimmedLine.startsWith("-")) { + for (String ignoredSection : ignoredSections) { + boolean isIgnoredParent = ignoredSection.equals(keyBuilder.toString()); + + if (isIgnoredParent || keyBuilder.isSubKeyOf(ignoredSection)) { + valueBuilder.append("\n").append(line); + continue lineLoop; + } + } + } + + keyBuilder.parseLine(trimmedLine); + String fullKey = keyBuilder.toString(); + + //If building the value for an ignored section and this line is no longer a part of the ignored section, + // write the valueBuilder, reset it, and set the current ignored section to null + if (currentIgnoredSection != null && !KeyBuilder.isSubKeyOf(currentIgnoredSection, fullKey, SEPARATOR)) { + ignoredSectionsValues.put(currentIgnoredSection, valueBuilder.toString()); + valueBuilder.setLength(0); + currentIgnoredSection = null; + } + + for (String ignoredSection : ignoredSections) { + boolean isIgnoredParent = ignoredSection.equals(fullKey); + + if (isIgnoredParent || keyBuilder.isSubKeyOf(ignoredSection)) { + if (valueBuilder.length() > 0) + valueBuilder.append("\n"); + + String comment = comments.get(fullKey); + + if (comment != null) { + String indents = KeyBuilder.getIndents(fullKey, SEPARATOR); + valueBuilder.append(indents).append(comment.replace("\n", "\n" + indents));//Should end with new line (\n) + valueBuilder.setLength(valueBuilder.length() - indents.length());//Get rid of trailing \n and spaces + } + + valueBuilder.append(line); + + //Set the current ignored section for future iterations of while loop + //Don't set currentIgnoredSection to any ignoredSection sub-keys + if (isIgnoredParent) + currentIgnoredSection = fullKey; + + break; + } + } + } + + reader.close(); + + if (valueBuilder.length() > 0) + ignoredSectionsValues.put(currentIgnoredSection, valueBuilder.toString()); + + return ignoredSectionsValues; + } + + private static void writeCommentIfExists(Map comments, BufferedWriter writer, String fullKey, String indents) throws IOException { + String comment = comments.get(fullKey); + + //Comments always end with new line (\n) + if (comment != null) + //Replaces all '\n' with '\n' + indents except for the last one + writer.write(indents + comment.substring(0, comment.length() - 1).replace("\n", "\n" + indents) + "\n"); + } + + //Input: 'key1.key2' Result: 'key1' + private static void removeLastKey(StringBuilder keyBuilder) { + if (keyBuilder.length() == 0) + return; + + String keyString = keyBuilder.toString(); + //Must be enclosed in brackets in case a regex special character is the separator + String[] split = keyString.split("[" + SEPARATOR + "]"); + //Makes sure begin index isn't < 0 (error). Occurs when there is only one key in the path + int minIndex = Math.max(0, keyBuilder.length() - split[split.length - 1].length() - 1); + keyBuilder.replace(minIndex, keyBuilder.length(), ""); + } + + private static void appendNewLine(StringBuilder builder) { + if (builder.length() > 0) + builder.append("\n"); + } + +} diff --git a/src/main/java/com/tchristofferson/configupdater/KeyBuilder.java b/src/main/java/com/tchristofferson/configupdater/KeyBuilder.java new file mode 100644 index 0000000..a0c5b77 --- /dev/null +++ b/src/main/java/com/tchristofferson/configupdater/KeyBuilder.java @@ -0,0 +1,116 @@ +package com.tchristofferson.configupdater; + +import org.bukkit.configuration.file.FileConfiguration; + +public class KeyBuilder implements Cloneable { + + private final FileConfiguration config; + private final char separator; + private final StringBuilder builder; + + public KeyBuilder(FileConfiguration config, char separator) { + this.config = config; + this.separator = separator; + this.builder = new StringBuilder(); + } + + private KeyBuilder(KeyBuilder keyBuilder) { + this.config = keyBuilder.config; + this.separator = keyBuilder.separator; + this.builder = new StringBuilder(keyBuilder.toString()); + } + + public void parseLine(String line) { + line = line.trim(); + String[] currentSplitLine = line.split(":"); + String key = currentSplitLine[0].replace("'", "").replace("\"", ""); + + //Checks keyBuilder path against config to see if the path is valid. + //If the path doesn't exist in the config it keeps removing last key in keyBuilder. + while (builder.length() > 0 && !config.contains(builder.toString() + separator + key)) { + removeLastKey(); + } + + //Add the separator if there is already a key inside keyBuilder + //If currentSplitLine[0] is 'key2' and keyBuilder contains 'key1' the result will be 'key1.' if '.' is the separator + if (builder.length() > 0) + builder.append(separator); + + //Appends the current key to keyBuilder + //If keyBuilder is 'key1.' and currentSplitLine[0] is 'key2' the resulting keyBuilder will be 'key1.key2' if separator is '.' + builder.append(key); + } + + public String getLastKey() { + if (builder.length() == 0) + return ""; + + return builder.toString().split("[" + separator + "]")[0]; + } + + public boolean isEmpty() { + return builder.length() == 0; + } + + //Checks to see if the full key path represented by this instance is a sub-key of the key parameter + public boolean isSubKeyOf(String parentKey) { + return isSubKeyOf(parentKey, builder.toString(), separator); + } + + //Checks to see if subKey is a sub-key of the key path this instance represents + public boolean isSubKey(String subKey) { + return isSubKeyOf(builder.toString(), subKey, separator); + } + + public static boolean isSubKeyOf(String parentKey, String subKey, char separator) { + if (parentKey.isEmpty()) + return false; + + return subKey.startsWith(parentKey) + && subKey.substring(parentKey.length()).startsWith(String.valueOf(separator)); + } + + public static String getIndents(String key, char separator) { + String[] splitKey = key.split("[" + separator + "]"); + StringBuilder builder = new StringBuilder(); + + for (int i = 1; i < splitKey.length; i++) { + builder.append(" "); + } + + return builder.toString(); + } + + public boolean isConfigSection() { + String key = builder.toString(); + return config.isConfigurationSection(key); + } + + public boolean isConfigSectionWithKeys() { + String key = builder.toString(); + return config.isConfigurationSection(key) && !config.getConfigurationSection(key).getKeys(false).isEmpty(); + } + + //Input: 'key1.key2' Result: 'key1' + public void removeLastKey() { + if (builder.length() == 0) + return; + + String keyString = builder.toString(); + //Must be enclosed in brackets in case a regex special character is the separator + String[] split = keyString.split("[" + separator + "]"); + //Makes sure begin index isn't < 0 (error). Occurs when there is only one key in the path + int minIndex = Math.max(0, builder.length() - split[split.length - 1].length() - 1); + builder.replace(minIndex, builder.length(), ""); + } + + @Override + public String toString() { + return builder.toString(); + } + + @Override + protected KeyBuilder clone() { + return new KeyBuilder(this); + } +} diff --git a/src/main/java/tk/ditservices/DITSystem.java b/src/main/java/tk/ditservices/DITSystem.java index 89f97fd..25ad93a 100644 --- a/src/main/java/tk/ditservices/DITSystem.java +++ b/src/main/java/tk/ditservices/DITSystem.java @@ -6,7 +6,7 @@ import tk.ditservices.listeners.ChatEvents; import tk.ditservices.listeners.LogChat; import tk.ditservices.listeners.LogCommand; import tk.ditservices.listeners.LogConnect; -import tk.ditservices.utils.ConfigUpdater; +import com.tchristofferson.configupdater.ConfigUpdater; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.GameRule; @@ -15,10 +15,13 @@ import org.bukkit.command.CommandExecutor; import org.bukkit.command.PluginCommand; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.event.Listener; -import org.bukkit.plugin.Plugin; import org.bukkit.plugin.java.JavaPlugin; import tk.ditservices.utils.Math; +import com.jeff_media.updatechecker.UpdateCheckSource; +import com.jeff_media.updatechecker.UpdateChecker; +import com.jeff_media.updatechecker.UserAgentBuilder; + import java.io.*; import java.util.Collections; import java.util.List; @@ -27,7 +30,7 @@ import java.util.logging.Logger; public final class DITSystem extends JavaPlugin implements CommandExecutor, Listener { private static DITSystem instance; Logger log = Bukkit.getLogger(); - private DitPluginManager dplug; + //private DitPluginManager dplug; public TabManager tab; public FileConfiguration config; @@ -39,8 +42,18 @@ public final class DITSystem extends JavaPlugin implements CommandExecutor, List instance = this; this.DIT_initialize(); this.tab = new TabManager(this,this.config); - this.dplug = new DitPluginManager(this); + //this.dplug = new DitPluginManager(this); System.out.println(this.getPrefix()+"Started running."); + + new UpdateChecker(this, UpdateCheckSource.GITHUB_RELEASE_TAG, "LabodiDavid/SimplifyTools") + .setDownloadLink("https://github.com/LabodiDavid/SimplifyTools/releases") + .setDonationLink("https://paypal.me/labodidavid") + .setChangelogLink("https://github.com/LabodiDavid/SimplifyTools/blob/main/docs/ChangeLog.md") + .setNotifyOpsOnJoin(true) + .setNotifyByPermissionOnJoin("st.admin") + .setUserAgent(new UserAgentBuilder().addPluginNameAndVersion()) + .checkEveryXHours(24) + .checkNow(); } private void DIT_initialize() { diff --git a/src/main/java/tk/ditservices/DitPluginManager.java b/src/main/java/tk/ditservices/DitPluginManager.java index f9ef744..2317f7c 100644 --- a/src/main/java/tk/ditservices/DitPluginManager.java +++ b/src/main/java/tk/ditservices/DitPluginManager.java @@ -9,15 +9,13 @@ import org.bukkit.plugin.*; import java.io.File; import java.lang.reflect.Field; import java.util.*; +/* public class DitPluginManager { private static DITSystem plugin; public DitPluginManager(DITSystem instance){ plugin = instance; } - /** - * Loads the requested plugin. - * @param pluginName Plugin name in string. - */ + public static int load(final String pluginName) { PluginManager pm = Bukkit.getServer().getPluginManager(); boolean there = false; @@ -144,6 +142,7 @@ public class DitPluginManager { } if (commandMap != null) { + for (Iterator> it = knownCommands.entrySet().iterator(); it.hasNext(); ) { Map.Entry entry = it.next(); if (entry.getValue() instanceof PluginCommand) { @@ -181,3 +180,4 @@ public class DitPluginManager { } +*/ diff --git a/src/main/java/tk/ditservices/TabManager.java b/src/main/java/tk/ditservices/TabManager.java index f85e7bd..8401eae 100644 --- a/src/main/java/tk/ditservices/TabManager.java +++ b/src/main/java/tk/ditservices/TabManager.java @@ -1,19 +1,21 @@ package tk.ditservices; +import net.minecraft.network.chat.ChatComponentText; +import net.minecraft.network.chat.IChatBaseComponent; +import net.minecraft.network.protocol.game.PacketPlayOutPlayerListHeaderFooter; +import net.minecraft.server.network.PlayerConnection; +import org.bukkit.craftbukkit.v1_18_R2.entity.CraftPlayer; import tk.ditservices.utils.Math; import tk.ditservices.utils.Server; -import net.minecraft.server.v1_16_R3.ChatComponentText; +/*import net.minecraft.server.v1_16_R3.ChatComponentText; import net.minecraft.server.v1_16_R3.IChatBaseComponent; import net.minecraft.server.v1_16_R3.PacketPlayOutPlayerListHeaderFooter; +*/ import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.craftbukkit.v1_16_R3.entity.CraftPlayer; +//import org.bukkit.craftbukkit.v1_16_R3.entity.CraftPlayer; import org.bukkit.entity.Player; - -import javax.annotation.CheckForNull; -import javax.annotation.Nullable; -import java.lang.reflect.Array; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; @@ -53,24 +55,19 @@ public class TabManager { return; } Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() { - PacketPlayOutPlayerListHeaderFooter packet = new PacketPlayOutPlayerListHeaderFooter(); int count1 = 0; //headers int count2 = 0; //footers @Override public void run() { try { //Tab code - Field a = packet.getClass().getDeclaredField("header"); - a.setAccessible(true); - Field b = packet.getClass().getDeclaredField("footer"); - b.setAccessible(true); + if (count1>=headers.size()){ count1=0; } if (count2>=footers.size()){ count2=0; } - //Re adding all lines where we replaced something like the RAM usage to every refresh //display current value. (We check those lines in the init()) if (DynamicHeaders.size()>0 && count1 < DynamicHeaders.size()){ @@ -84,12 +81,20 @@ public class TabManager { } } + PacketPlayOutPlayerListHeaderFooter packet = new PacketPlayOutPlayerListHeaderFooter(headers.get(count1),footers.get(count2)); + /*Field a = packet.getClass().getDeclaredField("header"); + a.setAccessible(true); + Field b = packet.getClass().getDeclaredField("footer"); + b.setAccessible(true); + a.set(packet, headers.get(count1)); b.set(packet,footers.get(count2)); - + */ if (Bukkit.getOnlinePlayers().size() !=0){ for (Player player : Bukkit.getOnlinePlayers()){ - ((CraftPlayer)player).getHandle().playerConnection.sendPacket(packet); + PlayerConnection pConn = ((CraftPlayer)player).getHandle().b; + //((CraftPlayer)player).getHandle().playerConnection.sendPacket(packet); + pConn.a(packet); } } if (headers.size()>1){ diff --git a/src/main/java/tk/ditservices/commands/DitCmd.java b/src/main/java/tk/ditservices/commands/DitCmd.java index d6728fe..eb13a54 100644 --- a/src/main/java/tk/ditservices/commands/DitCmd.java +++ b/src/main/java/tk/ditservices/commands/DitCmd.java @@ -91,10 +91,12 @@ public class DitCmd implements CommandExecutor { return true; } if (args[1].equalsIgnoreCase("load")) { - PluginCmd.handleLoad(sender,args); + //PluginCmd.handleLoad(sender,args); + PluginCmd.LoadPlugin(sender,args); } if (args[1].equalsIgnoreCase("unload")) { - PluginCmd.handleUnload(sender,args); + //PluginCmd.handleUnload(sender,args); + PluginCmd.UnloadPlugin(sender, args); } } } diff --git a/src/main/java/tk/ditservices/commands/PingCmd.java b/src/main/java/tk/ditservices/commands/PingCmd.java index e005479..e4a8570 100644 --- a/src/main/java/tk/ditservices/commands/PingCmd.java +++ b/src/main/java/tk/ditservices/commands/PingCmd.java @@ -5,19 +5,15 @@ import org.bukkit.command.CommandSender; import org.bukkit.command.ConsoleCommandSender; import org.bukkit.entity.Player; -import java.lang.reflect.InvocationTargetException; - public class PingCmd { public static boolean Run(CommandSender sender) { DITSystem plugin = DITSystem.getInstance(); if (sender instanceof Player) { Player player = (Player) sender; try { - Object entityPlayer = player.getClass().getMethod("getHandle").invoke(player); - int ping = (int) entityPlayer.getClass().getField("ping").get(entityPlayer); - player.sendMessage(plugin.getPrefix() + "Your response time to the server: " + ping + " ms"); + player.sendMessage(plugin.getPrefix() + "Your response time to the server: " + player.getPing() + " ms"); return true; - } catch (IllegalAccessException | IllegalArgumentException | NoSuchMethodException | SecurityException | NoSuchFieldException | InvocationTargetException e) { + } catch (IllegalArgumentException | SecurityException e) { e.printStackTrace(); } } else { diff --git a/src/main/java/tk/ditservices/commands/PluginCmd.java b/src/main/java/tk/ditservices/commands/PluginCmd.java index 66682ce..bbf6799 100644 --- a/src/main/java/tk/ditservices/commands/PluginCmd.java +++ b/src/main/java/tk/ditservices/commands/PluginCmd.java @@ -1,12 +1,44 @@ package tk.ditservices.commands; +import org.bukkit.Bukkit; +import org.bukkit.plugin.Plugin; import tk.ditservices.DITSystem; -import tk.ditservices.DitPluginManager; +//import tk.ditservices.DitPluginManager; import org.bukkit.command.CommandSender; public class PluginCmd { - public static boolean handleLoad(CommandSender sender, String[] args){ + public static boolean LoadPlugin(CommandSender sender, String[] args){ + Plugin plugin = Bukkit.getPluginManager().getPlugin(args[2]); + if (plugin == null) { + sender.sendMessage(DITSystem.getInstance().getPrefix()+"Plugin not exist!"); + return false; + } + if (plugin.isEnabled()){ + sender.sendMessage(DITSystem.getInstance().getPrefix()+"Plugin "+plugin.getName()+" already enabled!"); + return true; + } + + Bukkit.getPluginManager().enablePlugin(plugin); + sender.sendMessage(DITSystem.getInstance().getPrefix()+"Plugin "+plugin.getName()+" successfully enabled!"); + return true; + } + public static boolean UnloadPlugin(CommandSender sender, String[] args){ + Plugin plugin = Bukkit.getPluginManager().getPlugin(args[2]); + if (plugin == null) { + sender.sendMessage(DITSystem.getInstance().getPrefix()+"Plugin not exist!"); + return false; + } + if (!plugin.isEnabled()){ + sender.sendMessage(DITSystem.getInstance().getPrefix()+"Plugin "+plugin.getName()+" already disabled!"); + return true; + } + Bukkit.getPluginManager().disablePlugin(plugin); + sender.sendMessage(DITSystem.getInstance().getPrefix()+"Plugin "+plugin.getName()+" successfully disabled!"); + return true; + } + + /*public static boolean handleLoad(CommandSender sender, String[] args){ switch (DitPluginManager.load(args[2])){ case 0: sender.sendMessage(DITSystem.getInstance().getPrefix()+" Plugin loaded."); return true; case 2: sender.sendMessage(DITSystem.getInstance().getPrefix()+"Missing dependency!"); return true; @@ -26,5 +58,5 @@ public class PluginCmd { default: break; } return false; - } + }*/ } diff --git a/src/main/java/tk/ditservices/utils/AdvancementHelper.java b/src/main/java/tk/ditservices/utils/AdvancementHelper.java index ad4c801..6937e3f 100644 --- a/src/main/java/tk/ditservices/utils/AdvancementHelper.java +++ b/src/main/java/tk/ditservices/utils/AdvancementHelper.java @@ -1,5 +1,6 @@ package tk.ditservices.utils; +import net.minecraft.advancements.Advancement; import tk.ditservices.DITLog; import tk.ditservices.DITSystem; import org.bukkit.configuration.file.FileConfiguration; @@ -99,6 +100,7 @@ public class AdvancementHelper { public String[] out_type = new String[3]; private void initialize(){ + if (config.isSet("CustomAdvancement.formats.advancement")) { out_type[0] = config.getString("CustomAdvancement.formats.advancement"); } diff --git a/src/main/java/tk/ditservices/utils/ConfigUpdater.java b/src/main/java/tk/ditservices/utils/ConfigUpdater.java deleted file mode 100644 index 93eb860..0000000 --- a/src/main/java/tk/ditservices/utils/ConfigUpdater.java +++ /dev/null @@ -1,320 +0,0 @@ -/** - * Github repo: https://github.com/tchristofferson/Config-Updater - */ -package tk.ditservices.utils; - -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.configuration.serialization.ConfigurationSerializable; -import org.bukkit.plugin.Plugin; -import org.yaml.snakeyaml.Yaml; - -import java.io.*; -import java.nio.charset.StandardCharsets; -import java.util.*; -import java.util.stream.Collectors; - -/** - * A class to update/add new sections/keys to your config while keeping your current values and keeping your comments - * Algorithm: - * Read the new file and scan for comments and ignored sections, if ignored section is found it is treated as a comment. - * Read and write each line of the new config, if the old config has value for the given key it writes that value in the new config. - * If a key has an attached comment above it, it is written first. - * @author tchristofferson - */ -public class ConfigUpdater { - - /** - * Update a yaml file from a resource inside your plugin jar - * @param plugin You plugin - * @param resourceName The yaml file name to update from, typically config.yml - * @param toUpdate The yaml file to update - * @param ignoredSections List of sections to ignore and copy from the current config - * @throws IOException If an IOException occurs - */ - public static void update(Plugin plugin, String resourceName, File toUpdate, List ignoredSections) throws IOException { - BufferedReader newReader = new BufferedReader(new InputStreamReader(plugin.getResource(resourceName), StandardCharsets.UTF_8)); - List newLines = newReader.lines().collect(Collectors.toList()); - newReader.close(); - - FileConfiguration oldConfig = YamlConfiguration.loadConfiguration(toUpdate); - FileConfiguration newConfig = YamlConfiguration.loadConfiguration(new InputStreamReader(plugin.getResource(resourceName), StandardCharsets.UTF_8)); - BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(toUpdate), StandardCharsets.UTF_8)); - - List ignoredSectionsArrayList = new ArrayList<>(ignoredSections); - //ignoredSections can ONLY contain configurations sections - ignoredSectionsArrayList.removeIf(ignoredSection -> !newConfig.isConfigurationSection(ignoredSection)); - - Yaml yaml = new Yaml(); - Map comments = parseComments(newLines, ignoredSectionsArrayList, oldConfig, yaml); - write(newConfig, oldConfig, comments, ignoredSectionsArrayList, writer, yaml); - } - - //Write method doing the work. - //It checks if key has a comment associated with it and writes comment then the key and value - private static void write(FileConfiguration newConfig, FileConfiguration oldConfig, Map comments, List ignoredSections, BufferedWriter writer, Yaml yaml) throws IOException { - outer: for (String key : newConfig.getKeys(true)) { - String[] keys = key.split("\\."); - String actualKey = keys[keys.length - 1]; - String comment = comments.remove(key); - - StringBuilder prefixBuilder = new StringBuilder(); - int indents = keys.length - 1; - appendPrefixSpaces(prefixBuilder, indents); - String prefixSpaces = prefixBuilder.toString(); - - if (comment != null) { - writer.write(comment);//No \n character necessary, new line is automatically at end of comment - } - - for (String ignoredSection : ignoredSections) { - if (key.startsWith(ignoredSection)) { - continue outer; - } - } - - Object newObj = newConfig.get(key); - Object oldObj = oldConfig.get(key); - - if (newObj instanceof ConfigurationSection && oldObj instanceof ConfigurationSection) { - //write the old section - writeSection(writer, actualKey, prefixSpaces, (ConfigurationSection) oldObj); - } else if (newObj instanceof ConfigurationSection) { - //write the new section, old value is no more - writeSection(writer, actualKey, prefixSpaces, (ConfigurationSection) newObj); - } else if (oldObj != null) { - //write the old object - write(oldObj, actualKey, prefixSpaces, yaml, writer); - } else { - //write new object - write(newObj, actualKey, prefixSpaces, yaml, writer); - } - } - - String danglingComments = comments.get(null); - - if (danglingComments != null) { - writer.write(danglingComments); - } - - writer.close(); - } - - //Doesn't work with configuration sections, must be an actual object - //Auto checks if it is serializable and writes to file - private static void write(Object obj, String actualKey, String prefixSpaces, Yaml yaml, BufferedWriter writer) throws IOException { - if (obj instanceof ConfigurationSerializable) { - writer.write(prefixSpaces + actualKey + ": " + yaml.dump(((ConfigurationSerializable) obj).serialize())); - } else if (obj instanceof String || obj instanceof Character) { - if (obj instanceof String) { - String s = (String) obj; - obj = s.replace("\n", "\\n"); - } - - writer.write(prefixSpaces + actualKey + ": " + yaml.dump(obj)); - } else if (obj instanceof List) { - writeList((List) obj, actualKey, prefixSpaces, yaml, writer); - } else { - writer.write(prefixSpaces + actualKey + ": " + yaml.dump(obj)); - } - } - - //Writes a configuration section - private static void writeSection(BufferedWriter writer, String actualKey, String prefixSpaces, ConfigurationSection section) throws IOException { - if (section.getKeys(false).isEmpty()) { - writer.write(prefixSpaces + actualKey + ": {}"); - } else { - writer.write(prefixSpaces + actualKey + ":"); - } - - writer.write("\n"); - } - - //Writes a list of any object - private static void writeList(List list, String actualKey, String prefixSpaces, Yaml yaml, BufferedWriter writer) throws IOException { - writer.write(getListAsString(list, actualKey, prefixSpaces, yaml)); - } - - private static String getListAsString(List list, String actualKey, String prefixSpaces, Yaml yaml) { - StringBuilder builder = new StringBuilder(prefixSpaces).append(actualKey).append(":"); - - if (list.isEmpty()) { - builder.append(" []\n"); - return builder.toString(); - } - - builder.append("\n"); - - for (int i = 0; i < list.size(); i++) { - Object o = list.get(i); - - if (o instanceof String || o instanceof Character) { - builder.append(prefixSpaces).append("- '").append(o).append("'"); - } else if (o instanceof List) { - builder.append(prefixSpaces).append("- ").append(yaml.dump(o)); - } else { - builder.append(prefixSpaces).append("- ").append(o); - } - - if (i != list.size()) { - builder.append("\n"); - } - } - - return builder.toString(); - } - - //Key is the config key, value = comment and/or ignored sections - //Parses comments, blank lines, and ignored sections - private static Map parseComments(List lines, List ignoredSections, FileConfiguration oldConfig, Yaml yaml) { - Map comments = new HashMap<>(); - StringBuilder builder = new StringBuilder(); - StringBuilder keyBuilder = new StringBuilder(); - int lastLineIndentCount = 0; - - outer: for (String line : lines) { - if (line != null && line.trim().startsWith("-")) - continue; - - if (line == null || line.trim().equals("") || line.trim().startsWith("#")) { - builder.append(line).append("\n"); - } else { - lastLineIndentCount = setFullKey(keyBuilder, line, lastLineIndentCount); - - for (String ignoredSection : ignoredSections) { - if (keyBuilder.toString().equals(ignoredSection)) { - Object value = oldConfig.get(keyBuilder.toString()); - - if (value instanceof ConfigurationSection) - appendSection(builder, (ConfigurationSection) value, new StringBuilder(getPrefixSpaces(lastLineIndentCount)), yaml); - - continue outer; - } - } - - if (keyBuilder.length() > 0) { - comments.put(keyBuilder.toString(), builder.toString()); - builder.setLength(0); - } - } - } - - if (builder.length() > 0) { - comments.put(null, builder.toString()); - } - - return comments; - } - - private static void appendSection(StringBuilder builder, ConfigurationSection section, StringBuilder prefixSpaces, Yaml yaml) { - builder.append(prefixSpaces).append(getKeyFromFullKey(section.getCurrentPath())).append(":"); - Set keys = section.getKeys(false); - - if (keys.isEmpty()) { - builder.append(" {}\n"); - return; - } - - builder.append("\n"); - prefixSpaces.append(" "); - - for (String key : keys) { - Object value = section.get(key); - String actualKey = getKeyFromFullKey(key); - - if (value instanceof ConfigurationSection) { - appendSection(builder, (ConfigurationSection) value, prefixSpaces, yaml); - prefixSpaces.setLength(prefixSpaces.length() - 2); - } else if (value instanceof List) { - builder.append(getListAsString((List) value, actualKey, prefixSpaces.toString(), yaml)); - } else { - builder.append(prefixSpaces.toString()).append(actualKey).append(": ").append(yaml.dump(value)); - } - } - } - - //Counts spaces in front of key and divides by 2 since 1 indent = 2 spaces - private static int countIndents(String s) { - int spaces = 0; - - for (char c : s.toCharArray()) { - if (c == ' ') { - spaces += 1; - } else { - break; - } - } - - return spaces / 2; - } - - //Ex. keyBuilder = key1.key2.key3 --> key1.key2 - private static void removeLastKey(StringBuilder keyBuilder) { - String temp = keyBuilder.toString(); - String[] keys = temp.split("\\."); - - if (keys.length == 1) { - keyBuilder.setLength(0); - return; - } - - temp = temp.substring(0, temp.length() - keys[keys.length - 1].length() - 1); - keyBuilder.setLength(temp.length()); - } - - private static String getKeyFromFullKey(String fullKey) { - String[] keys = fullKey.split("\\."); - return keys[keys.length - 1]; - } - - //Updates the keyBuilder and returns configLines number of indents - private static int setFullKey(StringBuilder keyBuilder, String configLine, int lastLineIndentCount) { - int currentIndents = countIndents(configLine); - String key = configLine.trim().split(":")[0]; - - if (keyBuilder.length() == 0) { - keyBuilder.append(key); - } else if (currentIndents == lastLineIndentCount) { - //Replace the last part of the key with current key - removeLastKey(keyBuilder); - - if (keyBuilder.length() > 0) { - keyBuilder.append("."); - } - - keyBuilder.append(key); - } else if (currentIndents > lastLineIndentCount) { - //Append current key to the keyBuilder - keyBuilder.append(".").append(key); - } else { - int difference = lastLineIndentCount - currentIndents; - - for (int i = 0; i < difference + 1; i++) { - removeLastKey(keyBuilder); - } - - if (keyBuilder.length() > 0) { - keyBuilder.append("."); - } - - keyBuilder.append(key); - } - - return currentIndents; - } - - private static String getPrefixSpaces(int indents) { - StringBuilder builder = new StringBuilder(); - - for (int i = 0; i < indents; i++) { - builder.append(" "); - } - - return builder.toString(); - } - - private static void appendPrefixSpaces(StringBuilder builder, int indents) { - builder.append(getPrefixSpaces(indents)); - } -} \ No newline at end of file diff --git a/src/main/java/tk/ditservices/utils/Server.java b/src/main/java/tk/ditservices/utils/Server.java index 435ee80..04cfa64 100644 --- a/src/main/java/tk/ditservices/utils/Server.java +++ b/src/main/java/tk/ditservices/utils/Server.java @@ -1,7 +1,7 @@ package tk.ditservices.utils; import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_16_R3.entity.CraftPlayer; +import org.bukkit.craftbukkit.*; import org.bukkit.entity.Player; import java.lang.Math; @@ -37,12 +37,13 @@ public class Server { */ public static int getPlayerPing(Player player){ try { - Object entityPlayer = player.getClass().getMethod("getHandle").invoke(player); - return (int) entityPlayer.getClass().getField("ping").get(entityPlayer); - } catch (IllegalAccessException | IllegalArgumentException | NoSuchMethodException | SecurityException | NoSuchFieldException | InvocationTargetException e) { + //Object entityPlayer = player.getClass().getMethod("getHandle").invoke(player); + //return (int) entityPlayer.getClass().getField("ping").get(entityPlayer); + return player.getPing(); + } catch (IllegalArgumentException | SecurityException e) { e.printStackTrace(); + return -1; } - return -1; } /** * Get an average of the currently online player's ping. @@ -54,7 +55,7 @@ public class Server { if (Bukkit.getOnlinePlayers().size() !=0){ onlineplayers =Bukkit.getOnlinePlayers().size(); for (Player player : Bukkit.getOnlinePlayers()){ - sum += Server.getPlayerPing(player); + sum += player.getPing(); } avg = Math.floorDiv(sum,onlineplayers); diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index e0e01c6..d473264 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -72,7 +72,7 @@ CustomMsg: Saving: enabled: true onDisconnect: true # When a player disconnects - interval: 0 # Auto saving interval in SECONDS. If this set to zero it means disabled. + interval: 1800 # Auto saving interval in SECONDS. If this set to zero it means disabled. broadcastMsgProgress: '{PREFIX}Auto save in progress..' broadcastMsgDone: '{PREFIX}Auto save done.'