diff --git a/README.md b/README.md index fcb92cc..3143bd8 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ![CoreProtect](https://userfolio.com/uploads/coreprotect-banner-v19.png) -[![Artistic License 2.0](https://img.shields.io/github/license/PlayPro/CoreProtect?&logo=github)](License) +[![Artistic License 2.0](https://img.shields.io/github/license/PlayPro/CoreProtect?&logo=github)](LICENSE) [![Join us on Discord](https://img.shields.io/discord/348680641560313868.svg?label=&logo=discord&logoColor=ffffff&color=7389D8&labelColor=6A7EC2)](https://discord.gg/b4DZ4jy) [![Netlify Status](https://api.netlify.com/api/v1/badges/c1d26a0f-65c5-4e4b-95d7-e08af671ab67/deploy-status)](https://app.netlify.com/sites/coreprotect/deploys) diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..18bc68e --- /dev/null +++ b/build.gradle @@ -0,0 +1,87 @@ +import org.apache.tools.ant.filters.ReplaceTokens + +plugins { + id 'java' + id 'com.github.johnrengelman.shadow' version '6.0.0' + id 'com.palantir.git-version' version '0.12.3' +} + +group = 'net.coreprotect' +String projectVersion = '20.0' +String projectBranch = '' +version = projectVersion // `version` might be modified, we don't always want that (e.g. plugin.yml) +description = 'Provides block protection for your server.' +sourceCompatibility = '1.8' + +if (System.getenv("BUILD_NUMBER") != null) { + // Being built in Jenkins, append Build ID + version += "-${System.getenv("BUILD_NUMBER")}" +} else if (!(version ==~ '^[^.]*\\.[^.]*\\.[^.]*$')) { // Thanks https://stackoverflow.com/a/9949200/1709894 + // Append the Git hash if 'version' has less than two periods + version += "-${gitVersion()}" +} +logger.info("Building version $version") + +repositories { + jcenter() + maven { url = 'https://hub.spigotmc.org/nexus/content/groups/public/' } + maven { url = 'https://oss.sonatype.org/content/repositories/snapshots/' } + maven { url = 'https://papermc.io/repo/repository/maven-public/' } + maven { url = 'https://repo.codemc.org/repository/maven-public/' } + maven { url = 'https://maven.sk89q.com/repo/' } +} + +dependencies { + compileOnly('com.sk89q.worldedit:worldedit-bukkit:7.0.0-SNAPSHOT') { + exclude group: 'org.bukkit' + } + compileOnly 'org.spigotmc:spigot-api:1.17-R0.1-SNAPSHOT' + implementation 'org.bstats:bstats-bukkit-lite:1.7' +} + +jar { + archiveClassifier.set("original") +} + +artifacts { + archives shadowJar +} + +shadowJar { + dependencies { + // #toString because #getGroup technically returns an Object + relocate('org.bstats', project.group.toString()) + } + archiveClassifier.set(null) +} + +ext { + author = 'Intelli' + + resourceTokens = [ + 'project.version': projectVersion, + 'project.branch': projectBranch, + ] +} + +processResources { + include 'plugin.yml' + // Whole lotta boilerplate to get the same functionality as Maven here. + // Replace this if Gradle ever lets us configure the filter before filtering. + filter(new Transformer() { + @Override + String transform(String s) { + ReplaceTokens replaceTokens = new ReplaceTokens(new StringReader(s)) + replaceTokens.setBeginToken('${') + replaceTokens.setEndToken('}') + resourceTokens.forEach { key, val -> + def token = new ReplaceTokens.Token() + token.setKey(key.toString()) + token.setValue(val.toString()) + replaceTokens.addConfiguredToken(token) + } + return replaceTokens.readLines().join('\n') + } + }) +} + diff --git a/pom.xml b/pom.xml new file mode 100755 index 0000000..3595732 --- /dev/null +++ b/pom.xml @@ -0,0 +1,124 @@ + + 4.0.0 + net.coreprotect + CoreProtect + 20.0 + + + UTF-8 + + + + + src/main/java + + **/*.java + + + + src/main/resources + true + + + + + maven-compiler-plugin + 3.8.1 + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-shade-plugin + 3.2.4 + + + package + + shade + + + + + *:*:*:* + + **/*.java + **/*.c + META-INF/maven/** + META-INF/services/** + + + + + + org.bstats + net.coreprotect + + + + + + + + + + + + spigot-repo + https://hub.spigotmc.org/nexus/content/groups/public/ + + + paper-repo + https://papermc.io/repo/repository/maven-public/ + + + codemc-repo + https://repo.codemc.org/repository/maven-public/ + + + sk89q-repo + http://maven.sk89q.com/repo/ + + + + + org.spigotmc + spigot-api + 1.17-R0.1-SNAPSHOT + provided + + + + org.bstats + bstats-bukkit-lite + 1.8 + compile + + + com.sk89q.worldedit + worldedit-bukkit + 7.0.0-SNAPSHOT + provided + + + org.bukkit + bukkit + + + + + \ No newline at end of file diff --git a/src/main/java/net/coreprotect/CoreProtect.java b/src/main/java/net/coreprotect/CoreProtect.java new file mode 100755 index 0000000..aa778ef --- /dev/null +++ b/src/main/java/net/coreprotect/CoreProtect.java @@ -0,0 +1,199 @@ +package net.coreprotect; + +import java.io.File; + +import org.bstats.bukkit.MetricsLite; +import org.bukkit.Bukkit; +import org.bukkit.plugin.PluginDescriptionFile; +import org.bukkit.plugin.java.JavaPlugin; + +import net.coreprotect.command.CommandHandler; +import net.coreprotect.command.TabHandler; +import net.coreprotect.config.Config; +import net.coreprotect.config.ConfigHandler; +import net.coreprotect.consumer.Consumer; +import net.coreprotect.consumer.process.Process; +import net.coreprotect.language.Language; +import net.coreprotect.language.Phrase; +import net.coreprotect.listener.ListenerHandler; +import net.coreprotect.thread.CacheHandler; +import net.coreprotect.thread.NetworkHandler; +import net.coreprotect.utility.Chat; +import net.coreprotect.utility.Color; +import net.coreprotect.utility.Util; + +public final class CoreProtect extends JavaPlugin { + + private static CoreProtect instance; + + /** + * Get the instance of CoreProtect + * + * @return This CoreProtect instance + */ + public static CoreProtect getInstance() { + return instance; + } + + private CoreProtectAPI api = new CoreProtectAPI(); + + /** + * Get the CoreProtect API + * + * @return The CoreProtect API + */ + public CoreProtectAPI getAPI() { + return api; + } + + @Override + public void onEnable() { + instance = this; + ConfigHandler.path = this.getDataFolder().getPath() + File.separator; + Language.loadPhrases(); + + boolean start = performVersionChecks(); + if (start) { + try { + Consumer.initialize(); // Prepare consumer (keep this here) + new ListenerHandler(this); + getCommand("coreprotect").setExecutor(CommandHandler.getInstance()); + getCommand("coreprotect").setTabCompleter(new TabHandler()); + getCommand("core").setExecutor(CommandHandler.getInstance()); + getCommand("core").setTabCompleter(new TabHandler()); + getCommand("co").setExecutor(CommandHandler.getInstance()); + getCommand("co").setTabCompleter(new TabHandler()); + + boolean exists = (new File(ConfigHandler.path)).exists(); + if (!exists) { + new File(ConfigHandler.path).mkdir(); + } + start = ConfigHandler.performInitialization(true); // Perform any necessary initialization + } + catch (Exception e) { + e.printStackTrace(); + start = false; + } + } + + if (start) { + PluginDescriptionFile pluginDescription = this.getDescription(); + Util.sendConsoleComponentStartup(Bukkit.getServer().getConsoleSender(), Phrase.build(Phrase.ENABLE_SUCCESS, ConfigHandler.EDITION_NAME)); + if (Config.getGlobal().MYSQL) { + Chat.console(Phrase.build(Phrase.USING_MYSQL)); + } + else { + Chat.console(Phrase.build(Phrase.USING_SQLITE)); + } + + Chat.console("--------------------"); + Chat.console(Phrase.build(Phrase.ENJOY_COREPROTECT, pluginDescription.getName())); + Chat.console(Phrase.build(Phrase.LINK_DISCORD, "www.coreprotect.net/discord/")); + Chat.console("--------------------"); + + getServer().getScheduler().scheduleSyncDelayedTask(this, () -> { + try { + Thread networkHandler = new Thread(new NetworkHandler(true, true)); + networkHandler.start(); + } + catch (Exception e) { + e.printStackTrace(); + } + }, 0); + + Thread cacheCleanUpThread = new Thread(new CacheHandler()); + cacheCleanUpThread.start(); + + Consumer.startConsumer(); + + // Enabling bStats + try { + new MetricsLite(this, 2876); + } + catch (Exception e) { + // Failed to connect to bStats server or something else went wrong. + } + } + else { + Chat.console(Phrase.build(Phrase.ENABLE_FAILED, ConfigHandler.EDITION_NAME)); + getServer().getPluginManager().disablePlugin(this); + } + } + + @Override + public void onDisable() { + safeShutdown(this); + } + + private static boolean performVersionChecks() { + try { + String[] bukkitVersion = Bukkit.getServer().getBukkitVersion().split("-|\\."); + if (Util.newVersion(bukkitVersion[0] + "." + bukkitVersion[1], ConfigHandler.SPIGOT_VERSION)) { + Chat.console(Phrase.build(Phrase.VERSION_REQUIRED, "Spigot", ConfigHandler.SPIGOT_VERSION)); + return false; + } + String[] javaVersion = (System.getProperty("java.version").replaceAll("[^0-9.]", "") + ".0").split("\\."); + if (Util.newVersion(javaVersion[0] + "." + javaVersion[1], ConfigHandler.JAVA_VERSION)) { + Chat.console(Phrase.build(Phrase.VERSION_REQUIRED, "Java", ConfigHandler.JAVA_VERSION)); + return false; + } + + if (ConfigHandler.EDITION_BRANCH.length() == 0) { + Chat.sendConsoleMessage(Color.RED + "[CoreProtect] " + Phrase.build(Phrase.INVALID_BRANCH_1)); + Chat.sendConsoleMessage(Color.GREY + "[CoreProtect] " + Phrase.build(Phrase.INVALID_BRANCH_2)); + Chat.sendConsoleMessage(Color.GREY + "[CoreProtect] " + Phrase.build(Phrase.INVALID_BRANCH_3)); + return false; + } + + ConfigHandler.SERVER_VERSION = Integer.parseInt(bukkitVersion[1]); + } + catch (Exception e) { + e.printStackTrace(); + return false; + } + + return true; + } + + private static void safeShutdown(CoreProtect plugin) { + try { + ConfigHandler.serverRunning = false; + long shutdownTime = System.currentTimeMillis(); + long alertTime = shutdownTime + (10 * 1000); + if (ConfigHandler.converterRunning) { + Chat.console(Phrase.build(Phrase.FINISHING_CONVERSION)); + } + else { + Chat.console(Phrase.build(Phrase.FINISHING_LOGGING)); + } + + while ((Consumer.isRunning() || ConfigHandler.converterRunning) && !ConfigHandler.purgeRunning) { + long time = System.currentTimeMillis(); + if (time >= alertTime) { + if (!ConfigHandler.converterRunning) { + int consumerId = (Consumer.currentConsumer == 1) ? 1 : 0; + int consumerCount = Consumer.getConsumerSize(consumerId) + Process.getCurrentConsumerSize(); + Chat.console(Phrase.build(Phrase.LOGGING_ITEMS, String.format("%,d", consumerCount))); + } + alertTime = alertTime + (30 * 1000); + } + else if (!ConfigHandler.databaseReachable && (time - shutdownTime) >= (5 * 60 * 1000)) { + Chat.console(Phrase.build(Phrase.DATABASE_UNREACHABLE)); + break; + } + else if ((time - shutdownTime) >= (15 * 60 * 1000)) { + Chat.console(Phrase.build(Phrase.LOGGING_TIME_LIMIT)); + break; + } + + Thread.sleep(100); + } + + Chat.console(Phrase.build(Phrase.DISABLE_SUCCESS, "CoreProtect v" + plugin.getDescription().getVersion())); + } + catch (Exception e) { + e.printStackTrace(); + } + } + +} diff --git a/src/main/java/net/coreprotect/CoreProtectAPI.java b/src/main/java/net/coreprotect/CoreProtectAPI.java new file mode 100755 index 0000000..d2862cc --- /dev/null +++ b/src/main/java/net/coreprotect/CoreProtectAPI.java @@ -0,0 +1,515 @@ +package net.coreprotect; + +import java.sql.Connection; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Server; +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.block.data.BlockData; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; + +import net.coreprotect.config.Config; +import net.coreprotect.consumer.Queue; +import net.coreprotect.database.Database; +import net.coreprotect.database.Lookup; +import net.coreprotect.database.Rollback; +import net.coreprotect.database.lookup.BlockLookupAPI; +import net.coreprotect.language.Phrase; +import net.coreprotect.listener.player.InventoryChangeListener; +import net.coreprotect.utility.Chat; +import net.coreprotect.utility.Util; + +public class CoreProtectAPI extends Queue { + + public class ParseResult { + String[] parse; + + public ParseResult(String[] data) { + parse = data; + } + + public int getActionId() { + return Integer.parseInt(parse[7]); + } + + public String getActionString() { + int actionID = Integer.parseInt(parse[7]); + String result = "unknown"; + + if (actionID == 0) { + result = "break"; + } + else if (actionID == 1) { + result = "place"; + } + else if (actionID == 2) { + result = "click"; + } + else if (actionID == 3) { + result = "kill"; + } + + return result; + } + + @Deprecated + public int getData() { + return Integer.parseInt(parse[6]); + } + + public String getPlayer() { + return parse[1]; + } + + @Deprecated + public int getTime() { + return Integer.parseInt(parse[0]); + } + + public long getTimestamp() { + return Long.parseLong(parse[0]) * 1000L; + } + + public Material getType() { + int actionID = this.getActionId(); + int type = Integer.parseInt(parse[5]); + String typeName; + + if (actionID == 3) { + typeName = Util.getEntityType(type).name(); + } + else { + typeName = Util.getType(type).name().toLowerCase(Locale.ROOT); + typeName = Util.nameFilter(typeName, this.getData()); + } + + return Util.getType(typeName); + } + + public BlockData getBlockData() { + String blockData = parse[12]; + if (blockData.length() == 0) { + return getType().createBlockData(); + } + return Bukkit.getServer().createBlockData(blockData); + } + + public int getX() { + return Integer.parseInt(parse[2]); + } + + public int getY() { + return Integer.parseInt(parse[3]); + } + + public int getZ() { + return Integer.parseInt(parse[4]); + } + + public boolean isRolledBack() { + return Integer.parseInt(parse[8]) == 1; + } + + public String worldName() { + return Util.getWorldName(Integer.parseInt(parse[9])); + } + } + + private static List parseList(List list) { + List result = new ArrayList<>(); + + if (list != null) { + for (Object value : list) { + if (value instanceof Material || value instanceof EntityType) { + result.add(value); + } + else if (value instanceof Integer) { + Material material = Util.getType((Integer) value); + result.add(material); + } + } + } + + return result; + } + + public int APIVersion() { + return 7; + } + + public List blockLookup(Block block, int time) { + if (Config.getGlobal().API_ENABLED) { + return BlockLookupAPI.performLookup(block, time); + } + return null; + } + + public boolean hasPlaced(String user, Block block, int time, int offset) { + // Determine if a user has placed a block at this location in the last # of seconds. + boolean match = false; + + if (Config.getGlobal().API_ENABLED) { + int unixTimestamp = (int) (System.currentTimeMillis() / 1000L); + int offsetTime = unixTimestamp - offset; + List check = blockLookup(block, time); + + for (String[] value : check) { + ParseResult result = parseResult(value); + if (user.equalsIgnoreCase(result.getPlayer()) && result.getActionId() == 1 && result.getTime() <= offsetTime) { + match = true; + break; + } + } + } + + return match; + } + + public boolean hasRemoved(String user, Block block, int time, int offset) { + // Determine if a user has removed a block at this location in the last # of seconds. + boolean match = false; + + if (Config.getGlobal().API_ENABLED) { + int unixTimestamp = (int) (System.currentTimeMillis() / 1000L); + int offsetTime = unixTimestamp - offset; + List check = blockLookup(block, time); + + for (String[] value : check) { + ParseResult result = parseResult(value); + if (user.equalsIgnoreCase(result.getPlayer()) && result.getActionId() == 0 && result.getTime() <= offsetTime) { + match = true; + break; + } + } + } + + return match; + } + + public boolean isEnabled() { + return Config.getGlobal().API_ENABLED; + } + + public boolean logChat(Player player, String message) { + if (Config.getGlobal().API_ENABLED && player != null && Config.getConfig(player.getWorld()).PLAYER_MESSAGES) { + if (message != null) { + if (message.length() > 0 && !message.startsWith("/")) { + int time = (int) (System.currentTimeMillis() / 1000L); + + Queue.queuePlayerChat(player, message, time); + return true; + } + } + } + + return false; + } + + public boolean logCommand(Player player, String command) { + if (Config.getGlobal().API_ENABLED && player != null && Config.getConfig(player.getWorld()).PLAYER_COMMANDS) { + if (command != null) { + if (command.length() > 0 && command.startsWith("/")) { + int time = (int) (System.currentTimeMillis() / 1000L); + + Queue.queuePlayerCommand(player, command, time); + return true; + } + } + } + + return false; + } + + public boolean logInteraction(String user, Location location) { + if (Config.getGlobal().API_ENABLED) { + if (user != null && location != null) { + if (user.length() > 0) { + Queue.queuePlayerInteraction(user, location.getBlock().getState()); + return true; + } + } + } + + return false; + } + + public boolean logContainerTransaction(String user, Location location) { + if (Config.getGlobal().API_ENABLED) { + return InventoryChangeListener.inventoryTransaction(user, location, null); + } + return false; + } + + public boolean logPlacement(String user, Location location, Material type, BlockData blockData) { + if (Config.getGlobal().API_ENABLED) { + if (user != null && location != null) { + if (user.length() > 0) { + Block block = location.getBlock(); + BlockState blockState = block.getState(); + String blockDataString = null; + + if (blockData != null) { + blockDataString = blockData.getAsString(); + } + + Queue.queueBlockPlace(user, blockState, block.getType(), null, type, -1, 0, blockDataString); + return true; + } + } + } + return false; + } + + @Deprecated + public boolean logPlacement(String user, Location location, Material type, byte data) { + if (Config.getGlobal().API_ENABLED) { + if (user != null && location != null) { + if (user.length() > 0) { + Queue.queueBlockPlace(user, location.getBlock().getState(), location.getBlock().getType(), null, type, data, 1, null); + return true; + } + } + } + + return false; + } + + public boolean logRemoval(String user, Location location, Material type, BlockData blockData) { + if (Config.getGlobal().API_ENABLED) { + if (user != null && location != null) { + if (user.length() > 0) { + String blockDataString = null; + + if (blockData != null) { + blockDataString = blockData.getAsString(); + } + + Block block = location.getBlock(); + Database.containerBreakCheck(user, block.getType(), block, null, location); + Queue.queueBlockBreak(user, location.getBlock().getState(), type, blockDataString, 0); + return true; + } + } + } + return false; + } + + @Deprecated + public boolean logRemoval(String user, Location location, Material type, byte data) { + if (Config.getGlobal().API_ENABLED) { + if (user != null && location != null) { + if (user.length() > 0) { + Queue.queueBlockBreak(user, location.getBlock().getState(), type, type.createBlockData().getAsString(), data); + return true; + } + } + } + + return false; + } + + public ParseResult parseResult(String[] results) { + return new ParseResult(results); + } + + public List performLookup(int time, List restrictUsers, List excludeUsers, List restrictBlocks, List excludeBlocks, List actionList, int radius, Location radiusLocation) { + if (Config.getGlobal().API_ENABLED) { + return processData(time, radius, radiusLocation, parseList(restrictBlocks), parseList(excludeBlocks), restrictUsers, excludeUsers, actionList, 0, 1, -1, -1, false); + } + return null; + } + + @Deprecated + public List performLookup(String user, int time, int radius, Location location, List restrict, List exclude) { + if (Config.getGlobal().API_ENABLED) { + return processData(user, time, radius, location, parseList(restrict), parseList(exclude), 0, 1, -1, -1, false); + } + return null; + } + + public List performPartialLookup(int time, List restrictUsers, List excludeUsers, List restrictBlocks, List excludeBlocks, List actionList, int radius, Location radiusLocation, int limitOffset, int limitCount) { + if (Config.getGlobal().API_ENABLED) { + return processData(time, radius, radiusLocation, parseList(restrictBlocks), parseList(excludeBlocks), restrictUsers, excludeUsers, actionList, 0, 1, limitOffset, limitCount, true); + } + return null; + } + + @Deprecated + public List performPartialLookup(String user, int time, int radius, Location location, List restrict, List exclude, int limitOffset, int limitCount) { + if (Config.getGlobal().API_ENABLED) { + return processData(user, time, radius, location, parseList(restrict), parseList(exclude), 0, 1, limitOffset, limitCount, true); + } + return null; + } + + public void performPurge(int time) { + Server server = Bukkit.getServer(); + server.dispatchCommand(server.getConsoleSender(), "co purge t:" + time + "s"); + } + + public List performRestore(int time, List restrictUsers, List excludeUsers, List restrictBlocks, List excludeBlocks, List actionList, int radius, Location radiusLocation) { + if (Config.getGlobal().API_ENABLED) { + return processData(time, radius, radiusLocation, parseList(restrictBlocks), parseList(excludeBlocks), restrictUsers, excludeUsers, actionList, 1, 2, -1, -1, false); + } + return null; + } + + @Deprecated + public List performRestore(String user, int time, int radius, Location location, List restrict, List exclude) { + if (Config.getGlobal().API_ENABLED) { + return processData(user, time, radius, location, parseList(restrict), parseList(exclude), 1, 2, -1, -1, false); + } + return null; + } + + public List performRollback(int time, List restrictUsers, List excludeUsers, List restrictBlocks, List excludeBlocks, List actionList, int radius, Location radiusLocation) { + if (Config.getGlobal().API_ENABLED) { + return processData(time, radius, radiusLocation, parseList(restrictBlocks), parseList(excludeBlocks), restrictUsers, excludeUsers, actionList, 0, 2, -1, -1, false); + } + return null; + } + + @Deprecated + public List performRollback(String user, int time, int radius, Location location, List restrict, List exclude) { + if (Config.getGlobal().API_ENABLED) { + return processData(user, time, radius, location, parseList(restrict), parseList(exclude), 0, 2, -1, -1, false); + } + return null; + } + + private List processData(int time, int radius, Location location, List restrictBlocks, List excludeBlocks, List restrictUsers, List excludeUsers, List actionList, int action, int lookup, int offset, int rowCount, boolean useLimit) { + // You need to either specify time/radius or time/user + List result = new ArrayList<>(); + List uuids = new ArrayList<>(); + + if (restrictUsers == null) { + restrictUsers = new ArrayList<>(); + } + + if (excludeUsers == null) { + excludeUsers = new ArrayList<>(); + } + + if (actionList == null) { + actionList = new ArrayList<>(); + } + + if (actionList.size() == 0 && restrictBlocks.size() > 0) { + boolean addedMaterial = false; + boolean addedEntity = false; + + for (Object argBlock : restrictBlocks) { + if (argBlock instanceof Material && !addedMaterial) { + actionList.add(0); + actionList.add(1); + addedMaterial = true; + } + else if (argBlock instanceof EntityType && !addedEntity) { + actionList.add(3); + addedEntity = true; + } + } + } + + if (actionList.size() == 0) { + actionList.add(0); + actionList.add(1); + } + + actionList.removeIf(actionListItem -> actionListItem > 3); + + if (restrictUsers.size() == 0) { + restrictUsers.add("#global"); + } + + int unixTimestamp = (int) (System.currentTimeMillis() / 1000L); + int timePeriod = unixTimestamp - time; + + if (radius < 1) { + radius = -1; + } + + if (restrictUsers.contains("#global") && radius == -1) { + return null; + } + + if (radius > -1 && location == null) { + return null; + } + + try { + Connection connection = Database.getConnection(false, 1000); + if (connection != null) { + Statement statement = connection.createStatement(); + boolean restrictWorld = false; + + if (radius > 0) { + restrictWorld = true; + } + + if (location == null) { + restrictWorld = false; + } + + Integer[] argRadius = null; + if (location != null && radius > 0) { + int xMin = location.getBlockX() - radius; + int xMax = location.getBlockX() + radius; + int zMin = location.getBlockZ() - radius; + int zMax = location.getBlockZ() + radius; + argRadius = new Integer[] { radius, xMin, xMax, -1, -1, zMin, zMax, 0 }; + } + + if (lookup == 1) { + if (location != null) { + restrictWorld = true; + } + + if (useLimit) { + result = Lookup.performPartialLookup(statement, null, uuids, restrictUsers, restrictBlocks, excludeBlocks, excludeUsers, actionList, location, argRadius, timePeriod, offset, rowCount, restrictWorld, true); + } + else { + result = Lookup.performLookup(statement, null, uuids, restrictUsers, restrictBlocks, excludeBlocks, excludeUsers, actionList, location, argRadius, timePeriod, restrictWorld, true); + } + } + else { + if (!Bukkit.isPrimaryThread()) { + boolean verbose = false; + result = Rollback.performRollbackRestore(statement, null, uuids, restrictUsers, null, restrictBlocks, excludeBlocks, excludeUsers, actionList, location, argRadius, timePeriod, restrictWorld, false, verbose, action, 0); + } + } + + statement.close(); + connection.close(); + } + } + catch (Exception e) { + e.printStackTrace(); + } + + return result; + } + + @Deprecated + private List processData(String user, int time, int radius, Location location, List restrictBlocks, List excludeBlocks, int action, int lookup, int offset, int rowCount, boolean useLimit) { + ArrayList restrictUsers = new ArrayList<>(); + if (user != null) { + restrictUsers.add(user); + } + + return processData(time, radius, location, restrictBlocks, excludeBlocks, restrictUsers, null, null, action, lookup, offset, rowCount, useLimit); + } + + public void testAPI() { + Chat.console(Phrase.build(Phrase.API_TEST)); + } + +} diff --git a/src/main/java/net/coreprotect/bukkit/BukkitAdapter.java b/src/main/java/net/coreprotect/bukkit/BukkitAdapter.java new file mode 100644 index 0000000..15c0311 --- /dev/null +++ b/src/main/java/net/coreprotect/bukkit/BukkitAdapter.java @@ -0,0 +1,139 @@ +package net.coreprotect.bukkit; + +import java.util.List; +import java.util.Map; + +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.block.Sign; +import org.bukkit.block.data.BlockData; +import org.bukkit.block.data.Directional; +import org.bukkit.entity.Entity; +import org.bukkit.entity.ItemFrame; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import net.coreprotect.config.ConfigHandler; +import net.coreprotect.utility.Util; + +public class BukkitAdapter implements BukkitInterface { + + public static BukkitInterface ADAPTER; + public static final int BUKKIT_v1_13 = 13; + public static final int BUKKIT_v1_14 = 14; + public static final int BUKKIT_v1_15 = 15; + public static final int BUKKIT_v1_16 = 16; + public static final int BUKKIT_v1_17 = 17; + + public static void loadAdapter() { + switch (ConfigHandler.SERVER_VERSION) { + case BUKKIT_v1_13: + case BUKKIT_v1_14: + BukkitAdapter.ADAPTER = new BukkitAdapter(); + break; + case BUKKIT_v1_15: + BukkitAdapter.ADAPTER = new Bukkit_v1_15(); + break; + case BUKKIT_v1_16: + BukkitAdapter.ADAPTER = new Bukkit_v1_16(); + break; + case BUKKIT_v1_17: + default: + BukkitAdapter.ADAPTER = new Bukkit_v1_17(); + break; + } + } + + @Override + public String parseLegacyName(String name) { + return name; + } + + @Override + public int getLegacyBlockId(Material material) { + return -1; + } + + @Override + public boolean getEntityMeta(LivingEntity entity, List info) { + return false; + } + + @Override + public boolean setEntityMeta(Entity entity, Object value, int count) { + return false; + } + + @Override + public boolean getItemMeta(ItemMeta itemMeta, List> list, List>> metadata, int slot) { + return false; + } + + @Override + public boolean setItemMeta(Material rowType, ItemStack itemstack, List> map) { + return false; + } + + @Override + public boolean isAttached(Block block, Block scanBlock, BlockData blockData, int scanMin) { + if (blockData instanceof Directional) { + return (scanMin < 5 && scanBlock.getRelative(((Directional) blockData).getFacing().getOppositeFace()).getLocation().equals(block.getLocation())); + } + + return true; // unvalidated attachments default to true + } + + @Override + public boolean isWall(BlockData blockData) { + return false; + } + + @Override + public void sendSignChange(Player player, Sign sign) { + return; + } + + @Override + public int getMinHeight(World world) { + return 0; + } + + @Override + public Material getBucketContents(Material material) { + return Material.AIR; + } + + @Override + public boolean isItemFrame(Material material) { + return (material == Material.ITEM_FRAME); + } + + @Override + public Material getFrameType(Entity entity) { + return Material.ITEM_FRAME; + } + + @Override + public Class getFrameClass(Material material) { + return ItemFrame.class; + } + + @Override + public boolean isGlowing(Sign sign) { + return false; + } + + @Override + public void setGlowing(Sign sign, boolean set) { + return; + } + + @Override + public boolean isInvisible(Material material) { + return Util.isAir(material); + } + +} diff --git a/src/main/java/net/coreprotect/bukkit/BukkitInterface.java b/src/main/java/net/coreprotect/bukkit/BukkitInterface.java new file mode 100644 index 0000000..75d3425 --- /dev/null +++ b/src/main/java/net/coreprotect/bukkit/BukkitInterface.java @@ -0,0 +1,53 @@ +package net.coreprotect.bukkit; + +import java.util.List; +import java.util.Map; + +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.block.Sign; +import org.bukkit.block.data.BlockData; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +public interface BukkitInterface { + + public Material getBucketContents(Material material); + + public Material getFrameType(Entity entity); + + public Class getFrameClass(Material material); + + public String parseLegacyName(String name); + + public boolean getEntityMeta(LivingEntity entity, List info); + + public boolean setEntityMeta(Entity entity, Object value, int count); + + public boolean getItemMeta(ItemMeta itemMeta, List> list, List>> metadata, int slot); + + public boolean setItemMeta(Material rowType, ItemStack itemstack, List> map); + + public boolean isAttached(Block block, Block scanBlock, BlockData blockData, int scanMin); + + public boolean isWall(BlockData blockData); + + public boolean isItemFrame(Material material); + + public boolean isGlowing(Sign sign); + + public boolean isInvisible(Material material); + + public int getMinHeight(World world); + + public int getLegacyBlockId(Material material); + + public void sendSignChange(Player player, Sign sign); + + public void setGlowing(Sign sign, boolean b); + +} diff --git a/src/main/java/net/coreprotect/bukkit/Bukkit_v1_15.java b/src/main/java/net/coreprotect/bukkit/Bukkit_v1_15.java new file mode 100644 index 0000000..c58f6ed --- /dev/null +++ b/src/main/java/net/coreprotect/bukkit/Bukkit_v1_15.java @@ -0,0 +1,105 @@ +package net.coreprotect.bukkit; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.bukkit.Material; +import org.bukkit.block.Sign; +import org.bukkit.entity.Bee; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.SuspiciousStewMeta; +import org.bukkit.potion.PotionEffect; + +public class Bukkit_v1_15 extends BukkitAdapter implements BukkitInterface { + + @Override + public boolean getEntityMeta(LivingEntity entity, List info) { + if (entity instanceof Bee) { + Bee bee = (Bee) entity; + info.add(bee.getAnger()); + info.add(bee.hasNectar()); + info.add(bee.hasStung()); + } + else { + return false; + } + + return true; + } + + @Override + public boolean setEntityMeta(Entity entity, Object value, int count) { + if (entity instanceof Bee) { + Bee bee = (Bee) entity; + if (count == 0) { + int set = (int) value; + bee.setAnger(set); + } + else if (count == 1) { + boolean set = (Boolean) value; + bee.setHasNectar(set); + } + else if (count == 2) { + boolean set = (Boolean) value; + bee.setHasStung(set); + } + } + else { + return false; + } + + return true; + } + + @Override + public boolean getItemMeta(ItemMeta itemMeta, List> list, List>> metadata, int slot) { + if (itemMeta instanceof SuspiciousStewMeta) { + SuspiciousStewMeta meta = (SuspiciousStewMeta) itemMeta; + SuspiciousStewMeta subMeta = meta.clone(); + meta.clearCustomEffects(); + list.add(meta.serialize()); + metadata.add(list); + + if (subMeta.hasCustomEffects()) { + for (PotionEffect effect : subMeta.getCustomEffects()) { + list = new ArrayList<>(); + list.add(effect.serialize()); + metadata.add(list); + } + } + } + else { + return false; + } + + return true; + } + + @Override + public boolean setItemMeta(Material rowType, ItemStack itemstack, List> map) { + if ((rowType == Material.SUSPICIOUS_STEW)) { + for (Map suspiciousStewData : map) { + SuspiciousStewMeta meta = (SuspiciousStewMeta) itemstack.getItemMeta(); + PotionEffect effect = new PotionEffect(suspiciousStewData); + meta.addCustomEffect(effect, true); + itemstack.setItemMeta(meta); + } + } + else { + return false; + } + + return true; + } + + @Override + public void sendSignChange(Player player, Sign sign) { + player.sendSignChange(sign.getLocation(), sign.getLines(), sign.getColor()); + } + +} diff --git a/src/main/java/net/coreprotect/bukkit/Bukkit_v1_16.java b/src/main/java/net/coreprotect/bukkit/Bukkit_v1_16.java new file mode 100644 index 0000000..32b8778 --- /dev/null +++ b/src/main/java/net/coreprotect/bukkit/Bukkit_v1_16.java @@ -0,0 +1,118 @@ +package net.coreprotect.bukkit; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; + +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.data.BlockData; +import org.bukkit.block.data.Directional; +import org.bukkit.block.data.FaceAttachable; +import org.bukkit.block.data.type.Wall; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Piglin; +import org.bukkit.entity.Zoglin; + +import net.coreprotect.model.BlockGroup; + +public class Bukkit_v1_16 extends Bukkit_v1_15 implements BukkitInterface { + + public Bukkit_v1_16() { + BlockGroup.TRACK_TOP = new HashSet<>(Arrays.asList(Material.TORCH, Material.REDSTONE_TORCH, Material.BAMBOO, Material.BAMBOO_SAPLING, Material.CORNFLOWER, Material.LILY_OF_THE_VALLEY, Material.WITHER_ROSE, Material.SWEET_BERRY_BUSH, Material.SCAFFOLDING, Material.OAK_SAPLING, Material.SPRUCE_SAPLING, Material.BIRCH_SAPLING, Material.JUNGLE_SAPLING, Material.ACACIA_SAPLING, Material.DARK_OAK_SAPLING, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.GRASS, Material.FERN, Material.DEAD_BUSH, Material.DANDELION, Material.POPPY, Material.BLUE_ORCHID, Material.ALLIUM, Material.AZURE_BLUET, Material.RED_TULIP, Material.ORANGE_TULIP, Material.WHITE_TULIP, Material.PINK_TULIP, Material.OXEYE_DAISY, Material.BROWN_MUSHROOM, Material.RED_MUSHROOM, Material.REDSTONE_WIRE, Material.WHEAT, Material.ACACIA_SIGN, Material.BIRCH_SIGN, Material.DARK_OAK_SIGN, Material.JUNGLE_SIGN, Material.OAK_SIGN, Material.SPRUCE_SIGN, Material.WHITE_BANNER, Material.ORANGE_BANNER, Material.MAGENTA_BANNER, Material.LIGHT_BLUE_BANNER, Material.YELLOW_BANNER, Material.LIME_BANNER, Material.PINK_BANNER, Material.GRAY_BANNER, Material.LIGHT_GRAY_BANNER, Material.CYAN_BANNER, Material.PURPLE_BANNER, Material.BLUE_BANNER, Material.BROWN_BANNER, Material.GREEN_BANNER, Material.RED_BANNER, Material.BLACK_BANNER, Material.RAIL, Material.IRON_DOOR, Material.SNOW, Material.CACTUS, Material.SUGAR_CANE, Material.REPEATER, Material.PUMPKIN_STEM, Material.MELON_STEM, Material.CARROT, Material.POTATO, Material.COMPARATOR, Material.ACTIVATOR_RAIL, Material.SUNFLOWER, Material.LILAC, Material.TALL_GRASS, Material.LARGE_FERN, Material.ROSE_BUSH, Material.PEONY, Material.NETHER_WART, Material.CHORUS_PLANT, Material.CHORUS_FLOWER, Material.KELP, Material.SOUL_TORCH, Material.TWISTING_VINES, Material.CRIMSON_FUNGUS, Material.WARPED_FUNGUS, Material.CRIMSON_ROOTS, Material.WARPED_ROOTS, Material.NETHER_SPROUTS, Material.CRIMSON_SIGN, Material.WARPED_SIGN)); + BlockGroup.TRACK_BOTTOM = new HashSet<>(Arrays.asList(Material.WEEPING_VINES)); + BlockGroup.TRACK_SIDE = new HashSet<>(Arrays.asList(Material.WALL_TORCH, Material.REDSTONE_WALL_TORCH, Material.RAIL, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.ACTIVATOR_RAIL, Material.WHITE_BED, Material.ORANGE_BED, Material.MAGENTA_BED, Material.LIGHT_BLUE_BED, Material.YELLOW_BED, Material.LIME_BED, Material.PINK_BED, Material.GRAY_BED, Material.LIGHT_GRAY_BED, Material.CYAN_BED, Material.PURPLE_BED, Material.BLUE_BED, Material.BROWN_BED, Material.GREEN_BED, Material.RED_BED, Material.BLACK_BED, Material.LADDER, Material.ACACIA_WALL_SIGN, Material.BIRCH_WALL_SIGN, Material.DARK_OAK_WALL_SIGN, Material.JUNGLE_WALL_SIGN, Material.OAK_WALL_SIGN, Material.SPRUCE_WALL_SIGN, Material.VINE, Material.COCOA, Material.TRIPWIRE_HOOK, Material.WHITE_WALL_BANNER, Material.ORANGE_WALL_BANNER, Material.MAGENTA_WALL_BANNER, Material.LIGHT_BLUE_WALL_BANNER, Material.YELLOW_WALL_BANNER, Material.LIME_WALL_BANNER, Material.PINK_WALL_BANNER, Material.GRAY_WALL_BANNER, Material.LIGHT_GRAY_WALL_BANNER, Material.CYAN_WALL_BANNER, Material.PURPLE_WALL_BANNER, Material.BLUE_WALL_BANNER, Material.BROWN_WALL_BANNER, Material.GREEN_WALL_BANNER, Material.RED_WALL_BANNER, Material.BLACK_WALL_BANNER, Material.SOUL_WALL_TORCH, Material.CRIMSON_WALL_SIGN, Material.WARPED_WALL_SIGN)); + BlockGroup.DOORS = new HashSet<>(Arrays.asList(Material.OAK_DOOR, Material.SPRUCE_DOOR, Material.BIRCH_DOOR, Material.JUNGLE_DOOR, Material.ACACIA_DOOR, Material.DARK_OAK_DOOR, Material.CRIMSON_DOOR, Material.WARPED_DOOR)); + BlockGroup.BUTTONS = new HashSet<>(Arrays.asList(Material.STONE_BUTTON, Material.OAK_BUTTON, Material.ACACIA_BUTTON, Material.BIRCH_BUTTON, Material.DARK_OAK_BUTTON, Material.JUNGLE_BUTTON, Material.SPRUCE_BUTTON, Material.POLISHED_BLACKSTONE_BUTTON, Material.CRIMSON_BUTTON, Material.WARPED_BUTTON)); + BlockGroup.PRESSURE_PLATES = new HashSet<>(Arrays.asList(Material.STONE_PRESSURE_PLATE, Material.ACACIA_PRESSURE_PLATE, Material.BIRCH_PRESSURE_PLATE, Material.DARK_OAK_PRESSURE_PLATE, Material.HEAVY_WEIGHTED_PRESSURE_PLATE, Material.JUNGLE_PRESSURE_PLATE, Material.LIGHT_WEIGHTED_PRESSURE_PLATE, Material.OAK_PRESSURE_PLATE, Material.SPRUCE_PRESSURE_PLATE, Material.CRIMSON_PRESSURE_PLATE, Material.WARPED_PRESSURE_PLATE, Material.POLISHED_BLACKSTONE_PRESSURE_PLATE)); + BlockGroup.VINES = new HashSet<>(Arrays.asList(Material.VINE, Material.WEEPING_VINES, Material.TWISTING_VINES)); + BlockGroup.LIGHTABLES = new HashSet<>(Arrays.asList(Material.CAMPFIRE, Material.SOUL_CAMPFIRE)); + BlockGroup.FIRE = new HashSet<>(Arrays.asList(Material.FIRE, Material.SOUL_FIRE)); + BlockGroup.LANTERNS = new HashSet<>(Arrays.asList(Material.LANTERN, Material.SOUL_LANTERN)); + BlockGroup.SOUL_BLOCKS = new HashSet<>(Arrays.asList(Material.SOUL_SAND, Material.SOUL_SOIL)); + BlockGroup.INTERACT_BLOCKS = new HashSet<>(Arrays.asList(Material.SPRUCE_FENCE_GATE, Material.BIRCH_FENCE_GATE, Material.JUNGLE_FENCE_GATE, Material.DARK_OAK_FENCE_GATE, Material.ACACIA_FENCE_GATE, Material.DISPENSER, Material.NOTE_BLOCK, Material.CHEST, Material.FURNACE, Material.LEVER, Material.REPEATER, Material.ACACIA_TRAPDOOR, Material.BIRCH_TRAPDOOR, Material.DARK_OAK_TRAPDOOR, Material.JUNGLE_TRAPDOOR, Material.SPRUCE_TRAPDOOR, Material.OAK_TRAPDOOR, Material.OAK_FENCE_GATE, Material.BREWING_STAND, Material.ANVIL, Material.CHIPPED_ANVIL, Material.DAMAGED_ANVIL, Material.ENDER_CHEST, Material.TRAPPED_CHEST, Material.COMPARATOR, Material.HOPPER, Material.DROPPER, Material.SHULKER_BOX, Material.BLACK_SHULKER_BOX, Material.BLUE_SHULKER_BOX, Material.BROWN_SHULKER_BOX, Material.CYAN_SHULKER_BOX, Material.GRAY_SHULKER_BOX, Material.GREEN_SHULKER_BOX, Material.LIGHT_BLUE_SHULKER_BOX, Material.LIME_SHULKER_BOX, Material.MAGENTA_SHULKER_BOX, Material.ORANGE_SHULKER_BOX, Material.PINK_SHULKER_BOX, Material.PURPLE_SHULKER_BOX, Material.RED_SHULKER_BOX, Material.LIGHT_GRAY_SHULKER_BOX, Material.WHITE_SHULKER_BOX, Material.YELLOW_SHULKER_BOX, Material.BARREL, Material.BLAST_FURNACE, Material.GRINDSTONE, Material.LOOM, Material.SMOKER, Material.CARTOGRAPHY_TABLE, Material.CRIMSON_FENCE_GATE, Material.WARPED_FENCE_GATE, Material.CRIMSON_TRAPDOOR, Material.WARPED_TRAPDOOR)); + BlockGroup.SAFE_INTERACT_BLOCKS = new HashSet<>(Arrays.asList(Material.LEVER, Material.ACACIA_TRAPDOOR, Material.BIRCH_TRAPDOOR, Material.DARK_OAK_TRAPDOOR, Material.JUNGLE_TRAPDOOR, Material.SPRUCE_TRAPDOOR, Material.OAK_TRAPDOOR, Material.OAK_FENCE_GATE, Material.SPRUCE_FENCE_GATE, Material.BIRCH_FENCE_GATE, Material.JUNGLE_FENCE_GATE, Material.DARK_OAK_FENCE_GATE, Material.ACACIA_FENCE_GATE, Material.CRIMSON_FENCE_GATE, Material.WARPED_FENCE_GATE, Material.CRIMSON_TRAPDOOR, Material.WARPED_TRAPDOOR)); + BlockGroup.UPDATE_STATE = new HashSet<>(Arrays.asList(Material.TORCH, Material.WALL_TORCH, Material.REDSTONE_WIRE, Material.RAIL, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.FURNACE, Material.BLAST_FURNACE, Material.SMOKER, Material.LEVER, Material.REDSTONE_TORCH, Material.REDSTONE_WALL_TORCH, Material.GLOWSTONE, Material.JACK_O_LANTERN, Material.REPEATER, Material.REDSTONE_LAMP, Material.BEACON, Material.COMPARATOR, Material.DAYLIGHT_DETECTOR, Material.REDSTONE_BLOCK, Material.HOPPER, Material.CHEST, Material.TRAPPED_CHEST, Material.ACTIVATOR_RAIL, Material.SOUL_TORCH, Material.SOUL_WALL_TORCH, Material.SHROOMLIGHT, Material.RESPAWN_ANCHOR, Material.CRYING_OBSIDIAN, Material.TARGET)); + BlockGroup.NON_ATTACHABLE = new HashSet<>(Arrays.asList(Material.AIR, Material.CAVE_AIR, Material.BARRIER, Material.CORNFLOWER, Material.LILY_OF_THE_VALLEY, Material.WITHER_ROSE, Material.SWEET_BERRY_BUSH, Material.OAK_SAPLING, Material.SPRUCE_SAPLING, Material.BIRCH_SAPLING, Material.JUNGLE_SAPLING, Material.ACACIA_SAPLING, Material.DARK_OAK_SAPLING, Material.WATER, Material.LAVA, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.GRASS, Material.FERN, Material.DEAD_BUSH, Material.DANDELION, Material.POPPY, Material.BLUE_ORCHID, Material.ALLIUM, Material.AZURE_BLUET, Material.RED_TULIP, Material.ORANGE_TULIP, Material.WHITE_TULIP, Material.PINK_TULIP, Material.OXEYE_DAISY, Material.BROWN_MUSHROOM, Material.RED_MUSHROOM, Material.TORCH, Material.WALL_TORCH, Material.REDSTONE_WIRE, Material.LADDER, Material.RAIL, Material.LEVER, Material.REDSTONE_TORCH, Material.REDSTONE_WALL_TORCH, Material.SNOW, Material.SUGAR_CANE, Material.NETHER_PORTAL, Material.REPEATER, Material.KELP, Material.CHORUS_FLOWER, Material.CHORUS_PLANT, Material.SOUL_TORCH, Material.SOUL_WALL_TORCH)); + } + + @Override + public boolean getEntityMeta(LivingEntity entity, List info) { + if (entity instanceof Piglin) { + Piglin piglin = (Piglin) entity; + info.add(piglin.isBaby()); + } + else if (entity instanceof Zoglin) { + Zoglin zoglin = (Zoglin) entity; + info.add(zoglin.isBaby()); + } + else if (super.getEntityMeta(entity, info)) { + return true; + } + else { + return false; + } + + return true; + } + + @Override + public boolean setEntityMeta(Entity entity, Object value, int count) { + if (entity instanceof Piglin) { + Piglin piglin = (Piglin) entity; + if (count == 0) { + boolean set = (Boolean) value; + piglin.setBaby(set); + } + } + else if (entity instanceof Zoglin) { + Zoglin zoglin = (Zoglin) entity; + if (count == 0) { + boolean set = (Boolean) value; + zoglin.setBaby(set); + } + } + else if (super.setEntityMeta(entity, value, count)) { + return true; + } + else { + return false; + } + + return true; + } + + @Override + public boolean isAttached(Block block, Block scanBlock, BlockData blockData, int scanMin) { + if (blockData instanceof Directional && blockData instanceof FaceAttachable) { + Directional directional = (Directional) blockData; + FaceAttachable faceAttachable = (FaceAttachable) blockData; + + boolean scanButton = false; + switch (faceAttachable.getAttachedFace()) { + case WALL: + scanButton = (scanMin < 5 && scanBlock.getRelative(directional.getFacing().getOppositeFace()).getLocation().equals(block.getLocation())); + break; + case FLOOR: + scanButton = (scanMin == 5); + break; + case CEILING: + scanButton = (scanMin == 6); + break; + default: + break; + } + + return scanButton; + } + + return true; // unvalidated attachments default to true + } + + @Override + public boolean isWall(BlockData blockData) { + return (blockData instanceof Wall); + } + +} diff --git a/src/main/java/net/coreprotect/bukkit/Bukkit_v1_17.java b/src/main/java/net/coreprotect/bukkit/Bukkit_v1_17.java new file mode 100644 index 0000000..5fb2048 --- /dev/null +++ b/src/main/java/net/coreprotect/bukkit/Bukkit_v1_17.java @@ -0,0 +1,222 @@ +package net.coreprotect.bukkit; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Map; + +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.block.Sign; +import org.bukkit.block.data.BlockData; +import org.bukkit.block.data.type.PointedDripstone; +import org.bukkit.entity.Axolotl; +import org.bukkit.entity.Entity; +import org.bukkit.entity.GlowItemFrame; +import org.bukkit.entity.Goat; +import org.bukkit.entity.ItemFrame; +import org.bukkit.entity.LivingEntity; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.BundleMeta; +import org.bukkit.inventory.meta.ItemMeta; + +import net.coreprotect.model.BlockGroup; +import net.coreprotect.utility.Util; + +public class Bukkit_v1_17 extends Bukkit_v1_16 implements BukkitInterface { + + public Bukkit_v1_17() { + BlockGroup.TRACK_ANY = new HashSet<>(Arrays.asList(Material.MOVING_PISTON, Material.LEVER, Material.BELL, Material.SMALL_AMETHYST_BUD, Material.MEDIUM_AMETHYST_BUD, Material.LARGE_AMETHYST_BUD, Material.AMETHYST_CLUSTER, Material.GLOW_LICHEN)); + BlockGroup.TRACK_TOP = new HashSet<>(Arrays.asList(Material.TORCH, Material.REDSTONE_TORCH, Material.BAMBOO, Material.BAMBOO_SAPLING, Material.CORNFLOWER, Material.LILY_OF_THE_VALLEY, Material.WITHER_ROSE, Material.SWEET_BERRY_BUSH, Material.SCAFFOLDING, Material.OAK_SAPLING, Material.SPRUCE_SAPLING, Material.BIRCH_SAPLING, Material.JUNGLE_SAPLING, Material.ACACIA_SAPLING, Material.DARK_OAK_SAPLING, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.GRASS, Material.FERN, Material.DEAD_BUSH, Material.DANDELION, Material.POPPY, Material.BLUE_ORCHID, Material.ALLIUM, Material.AZURE_BLUET, Material.RED_TULIP, Material.ORANGE_TULIP, Material.WHITE_TULIP, Material.PINK_TULIP, Material.OXEYE_DAISY, Material.BROWN_MUSHROOM, Material.RED_MUSHROOM, Material.REDSTONE_WIRE, Material.WHEAT, Material.ACACIA_SIGN, Material.BIRCH_SIGN, Material.DARK_OAK_SIGN, Material.JUNGLE_SIGN, Material.OAK_SIGN, Material.SPRUCE_SIGN, Material.WHITE_BANNER, Material.ORANGE_BANNER, Material.MAGENTA_BANNER, Material.LIGHT_BLUE_BANNER, Material.YELLOW_BANNER, Material.LIME_BANNER, Material.PINK_BANNER, Material.GRAY_BANNER, Material.LIGHT_GRAY_BANNER, Material.CYAN_BANNER, Material.PURPLE_BANNER, Material.BLUE_BANNER, Material.BROWN_BANNER, Material.GREEN_BANNER, Material.RED_BANNER, Material.BLACK_BANNER, Material.RAIL, Material.IRON_DOOR, Material.SNOW, Material.CACTUS, Material.SUGAR_CANE, Material.REPEATER, Material.PUMPKIN_STEM, Material.MELON_STEM, Material.CARROT, Material.POTATO, Material.COMPARATOR, Material.ACTIVATOR_RAIL, Material.SUNFLOWER, Material.LILAC, Material.TALL_GRASS, Material.LARGE_FERN, Material.ROSE_BUSH, Material.PEONY, Material.NETHER_WART, Material.CHORUS_PLANT, Material.CHORUS_FLOWER, Material.KELP, Material.SOUL_TORCH, Material.TWISTING_VINES, Material.CRIMSON_FUNGUS, Material.WARPED_FUNGUS, Material.CRIMSON_ROOTS, Material.WARPED_ROOTS, Material.NETHER_SPROUTS, Material.CRIMSON_SIGN, Material.WARPED_SIGN, Material.AZALEA, Material.FLOWERING_AZALEA, Material.SMALL_DRIPLEAF, Material.BIG_DRIPLEAF)); + BlockGroup.TRACK_TOP_BOTTOM = new HashSet<>(Arrays.asList(Material.POINTED_DRIPSTONE, Material.BIG_DRIPLEAF_STEM)); + BlockGroup.TRACK_BOTTOM = new HashSet<>(Arrays.asList(Material.WEEPING_VINES, Material.CAVE_VINES, Material.CAVE_VINES_PLANT, Material.HANGING_ROOTS)); + BlockGroup.VINES = new HashSet<>(Arrays.asList(Material.VINE, Material.WEEPING_VINES, Material.TWISTING_VINES, Material.CAVE_VINES)); + BlockGroup.CANDLES = new HashSet<>(Arrays.asList(Material.CANDLE, Material.BLACK_CANDLE, Material.BLUE_CANDLE, Material.BROWN_CANDLE, Material.CYAN_CANDLE, Material.GRAY_CANDLE, Material.GREEN_CANDLE, Material.LIGHT_BLUE_CANDLE, Material.LIGHT_GRAY_CANDLE, Material.LIME_CANDLE, Material.MAGENTA_CANDLE, Material.ORANGE_CANDLE, Material.PINK_CANDLE, Material.PURPLE_CANDLE, Material.RED_CANDLE, Material.WHITE_CANDLE, Material.YELLOW_CANDLE, Material.CANDLE_CAKE, Material.BLACK_CANDLE_CAKE, Material.BLUE_CANDLE_CAKE, Material.BROWN_CANDLE_CAKE, Material.CYAN_CANDLE_CAKE, Material.GRAY_CANDLE_CAKE, Material.GREEN_CANDLE_CAKE, Material.LIGHT_BLUE_CANDLE_CAKE, Material.LIGHT_GRAY_CANDLE_CAKE, Material.LIME_CANDLE_CAKE, Material.MAGENTA_CANDLE_CAKE, Material.ORANGE_CANDLE_CAKE, Material.PINK_CANDLE_CAKE, Material.PURPLE_CANDLE_CAKE, Material.RED_CANDLE_CAKE, Material.WHITE_CANDLE_CAKE, Material.YELLOW_CANDLE_CAKE)); + BlockGroup.AMETHYST = new HashSet<>(Arrays.asList(Material.SMALL_AMETHYST_BUD, Material.MEDIUM_AMETHYST_BUD, Material.LARGE_AMETHYST_BUD, Material.AMETHYST_CLUSTER)); + BlockGroup.UPDATE_STATE = new HashSet<>(Arrays.asList(Material.TORCH, Material.WALL_TORCH, Material.REDSTONE_WIRE, Material.RAIL, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.FURNACE, Material.BLAST_FURNACE, Material.SMOKER, Material.LEVER, Material.REDSTONE_TORCH, Material.REDSTONE_WALL_TORCH, Material.GLOWSTONE, Material.JACK_O_LANTERN, Material.REPEATER, Material.REDSTONE_LAMP, Material.BEACON, Material.COMPARATOR, Material.DAYLIGHT_DETECTOR, Material.REDSTONE_BLOCK, Material.HOPPER, Material.CHEST, Material.TRAPPED_CHEST, Material.ACTIVATOR_RAIL, Material.SOUL_TORCH, Material.SOUL_WALL_TORCH, Material.SHROOMLIGHT, Material.RESPAWN_ANCHOR, Material.CRYING_OBSIDIAN, Material.TARGET, Material.SMALL_AMETHYST_BUD, Material.MEDIUM_AMETHYST_BUD, Material.LARGE_AMETHYST_BUD, Material.AMETHYST_CLUSTER, Material.CAVE_VINES, Material.CAVE_VINES_PLANT, Material.GLOW_LICHEN, Material.LIGHT, Material.LAVA_CAULDRON)); + BlockGroup.NON_ATTACHABLE = new HashSet<>(Arrays.asList(Material.AIR, Material.CAVE_AIR, Material.BARRIER, Material.CORNFLOWER, Material.LILY_OF_THE_VALLEY, Material.WITHER_ROSE, Material.SWEET_BERRY_BUSH, Material.OAK_SAPLING, Material.SPRUCE_SAPLING, Material.BIRCH_SAPLING, Material.JUNGLE_SAPLING, Material.ACACIA_SAPLING, Material.DARK_OAK_SAPLING, Material.WATER, Material.LAVA, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.GRASS, Material.FERN, Material.DEAD_BUSH, Material.DANDELION, Material.POPPY, Material.BLUE_ORCHID, Material.ALLIUM, Material.AZURE_BLUET, Material.RED_TULIP, Material.ORANGE_TULIP, Material.WHITE_TULIP, Material.PINK_TULIP, Material.OXEYE_DAISY, Material.BROWN_MUSHROOM, Material.RED_MUSHROOM, Material.TORCH, Material.WALL_TORCH, Material.REDSTONE_WIRE, Material.LADDER, Material.RAIL, Material.LEVER, Material.REDSTONE_TORCH, Material.REDSTONE_WALL_TORCH, Material.SNOW, Material.SUGAR_CANE, Material.NETHER_PORTAL, Material.REPEATER, Material.KELP, Material.CHORUS_FLOWER, Material.CHORUS_PLANT, Material.SOUL_TORCH, Material.SOUL_WALL_TORCH, Material.LIGHT, Material.SMALL_DRIPLEAF, Material.BIG_DRIPLEAF, Material.BIG_DRIPLEAF_STEM, Material.GLOW_LICHEN, Material.HANGING_ROOTS)); + BlockGroup.VERTICAL_TOP_BOTTOM = new HashSet<>(Arrays.asList(Material.BIG_DRIPLEAF_STEM)); + } + + @Override + public String parseLegacyName(String name) { + switch (name) { + case "GRASS_PATH": + name = "DIRT_PATH"; + break; + default: + break; + } + + return name; + } + + @Override + public int getLegacyBlockId(Material material) { + switch (material) { + case DIRT_PATH: + return Util.getBlockId("GRASS_PATH", false); + default: + return -1; + } + } + + @Override + public boolean getEntityMeta(LivingEntity entity, List info) { + if (entity instanceof Axolotl) { + Axolotl axolotl = (Axolotl) entity; + info.add(axolotl.getVariant()); + } + else if (entity instanceof Goat) { + Goat goat = (Goat) entity; + info.add(goat.isScreaming()); + } + else if (super.getEntityMeta(entity, info)) { + return true; + } + else { + return false; + } + + return true; + } + + @Override + public boolean setEntityMeta(Entity entity, Object value, int count) { + if (entity instanceof Axolotl) { + Axolotl axolotl = (Axolotl) entity; + if (count == 0) { + org.bukkit.entity.Axolotl.Variant set = (org.bukkit.entity.Axolotl.Variant) value; + axolotl.setVariant(set); + } + } + else if (entity instanceof Goat) { + Goat goat = (Goat) entity; + if (count == 0) { + boolean set = (Boolean) value; + goat.setScreaming(set); + } + } + else if (super.setEntityMeta(entity, value, count)) { + return true; + } + else { + return false; + } + + return true; + } + + @Override + public boolean getItemMeta(ItemMeta itemMeta, List> list, List>> metadata, int slot) { + if (itemMeta instanceof BundleMeta) { + BundleMeta meta = (BundleMeta) itemMeta; + BundleMeta subMeta = (BundleMeta) meta.clone(); + meta.setItems(null); + list.add(meta.serialize()); + metadata.add(list); + + if (subMeta.hasItems()) { + list = new ArrayList<>(); + for (ItemStack itemStack : subMeta.getItems()) { + Map itemMap = Util.serializeItemStack(itemStack, slot); + if (itemMap.size() > 0) { + list.add(itemMap); + } + } + metadata.add(list); + } + } + else if (super.getItemMeta(itemMeta, list, metadata, slot)) { + return true; + } + else { + return false; + } + + return true; + } + + @Override + public boolean setItemMeta(Material rowType, ItemStack itemstack, List> map) { + if ((rowType == Material.BUNDLE)) { + BundleMeta meta = (BundleMeta) itemstack.getItemMeta(); + for (Map itemData : map) { + ItemStack itemStack = Util.unserializeItemStack(itemData); + if (itemStack != null) { + meta.addItem(itemStack); + } + } + itemstack.setItemMeta(meta); + } + else if (super.setItemMeta(rowType, itemstack, map)) { + return true; + } + else { + return false; + } + + return true; + } + + @Override + public boolean isAttached(Block block, Block scanBlock, BlockData blockData, int scanMin) { + if (blockData instanceof PointedDripstone) { + PointedDripstone pointedDripstone = (PointedDripstone) blockData; + BlockFace blockFace = pointedDripstone.getVerticalDirection(); + boolean adjacent = scanBlock.getRelative(blockFace.getOppositeFace()).getLocation().equals(block.getLocation()); + if (!adjacent) { + return false; + } + } + else if (!super.isAttached(block, scanBlock, blockData, scanMin)) { + return false; + } + + return true; + } + + @Override + public int getMinHeight(World world) { + return world.getMinHeight(); + } + + @Override + public Material getBucketContents(Material material) { + return (material == Material.POWDER_SNOW_BUCKET ? Material.POWDER_SNOW : Material.AIR); + } + + @Override + public boolean isItemFrame(Material material) { + return (material == Material.ITEM_FRAME || material == Material.GLOW_ITEM_FRAME); + } + + @Override + public Material getFrameType(Entity entity) { + return (entity instanceof GlowItemFrame) ? Material.GLOW_ITEM_FRAME : Material.ITEM_FRAME; + } + + @Override + public Class getFrameClass(Material material) { + return (material == Material.GLOW_ITEM_FRAME) ? GlowItemFrame.class : ItemFrame.class; + } + + @Override + public boolean isGlowing(Sign sign) { + return sign.isGlowingText(); + } + + @Override + public void setGlowing(Sign sign, boolean set) { + sign.setGlowingText(set); + } + + @Override + public boolean isInvisible(Material material) { + return material.isAir() || material == Material.LIGHT; + } + +} diff --git a/src/main/java/net/coreprotect/command/ApplyCommand.java b/src/main/java/net/coreprotect/command/ApplyCommand.java new file mode 100755 index 0000000..f40a294 --- /dev/null +++ b/src/main/java/net/coreprotect/command/ApplyCommand.java @@ -0,0 +1,47 @@ +package net.coreprotect.command; + +import java.util.List; + +import org.bukkit.Location; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; + +import net.coreprotect.config.ConfigHandler; +import net.coreprotect.language.Phrase; +import net.coreprotect.language.Selector; +import net.coreprotect.utility.Chat; +import net.coreprotect.utility.Color; +import net.coreprotect.utility.Util; + +public class ApplyCommand { + protected static void runCommand(CommandSender user, Command command, boolean permission, String[] args) { + try { + if (ConfigHandler.lastRollback.get(user.getName()) != null) { + List list = ConfigHandler.lastRollback.get(user.getName()); + int time = (Integer) list.get(0); + args = (String[]) list.get(1); + Location location = (Location) list.get(2); + boolean valid = false; + for (int i = 0; i < args.length; i++) { + if (args[i].equals("#preview")) { + valid = true; + args[i] = args[i].replaceAll("#preview", ""); + } + } + if (!valid) { + Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_ROLLBACK, Selector.FIRST)); + } + else { + ConfigHandler.lastRollback.remove(user.getName()); + RollbackRestoreCommand.runCommand(user, command, permission, args, location, time); + } + } + else { + Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_ROLLBACK, Selector.FIRST)); + } + } + catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/src/main/java/net/coreprotect/command/CancelCommand.java b/src/main/java/net/coreprotect/command/CancelCommand.java new file mode 100755 index 0000000..6e3c20b --- /dev/null +++ b/src/main/java/net/coreprotect/command/CancelCommand.java @@ -0,0 +1,47 @@ +package net.coreprotect.command; + +import java.util.List; + +import org.bukkit.Location; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; + +import net.coreprotect.config.ConfigHandler; +import net.coreprotect.language.Phrase; +import net.coreprotect.language.Selector; +import net.coreprotect.utility.Chat; +import net.coreprotect.utility.Color; +import net.coreprotect.utility.Util; + +public class CancelCommand { + protected static void runCommand(CommandSender user, Command command, boolean permission, String[] args) { + try { + if (ConfigHandler.lastRollback.get(user.getName()) != null) { + List list = ConfigHandler.lastRollback.get(user.getName()); + int time = (Integer) list.get(0); + args = (String[]) list.get(1); + Location location = (Location) list.get(2); + boolean valid = false; + for (int i = 0; i < args.length; i++) { + if (args[i].equals("#preview")) { + valid = true; + args[i] = args[i].replaceAll("#preview", "#preview_cancel"); + } + } + if (!valid) { + Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_ROLLBACK, Selector.FIRST)); + } + else { + ConfigHandler.lastRollback.remove(user.getName()); + RollbackRestoreCommand.runCommand(user, command, permission, args, location, time); + } + } + else { + Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_ROLLBACK, Selector.FIRST)); + } + } + catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/src/main/java/net/coreprotect/command/CommandHandler.java b/src/main/java/net/coreprotect/command/CommandHandler.java new file mode 100755 index 0000000..e4d025a --- /dev/null +++ b/src/main/java/net/coreprotect/command/CommandHandler.java @@ -0,0 +1,1197 @@ +package net.coreprotect.command; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Locale; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.command.BlockCommandSender; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; + +import net.coreprotect.bukkit.BukkitAdapter; +import net.coreprotect.config.Config; +import net.coreprotect.config.ConfigHandler; +import net.coreprotect.language.Phrase; +import net.coreprotect.language.Selector; +import net.coreprotect.model.BlockGroup; +import net.coreprotect.thread.NetworkHandler; +import net.coreprotect.utility.Chat; +import net.coreprotect.utility.Color; +import net.coreprotect.utility.Util; + +public class CommandHandler implements CommandExecutor { + private static CommandHandler instance; + private static ConcurrentHashMap versionAlert = new ConcurrentHashMap<>(); + protected static Set naturalBlocks = BlockGroup.NATURAL_BLOCKS; + + public static CommandHandler getInstance() { + if (instance == null) { + instance = new CommandHandler(); + } + return instance; + } + + protected static String[] parsePage(String[] argumentArray) { + if (argumentArray.length == 2) { + argumentArray[1] = argumentArray[1].replaceFirst("page:", ""); + } + + return argumentArray; + } + + protected static List parseAction(String[] inputArguments) { + String[] argumentArray = inputArguments.clone(); + List result = new ArrayList<>(); + int count = 0; + int next = 0; + for (String argument : argumentArray) { + if (count > 0) { + argument = argument.trim().toLowerCase(Locale.ROOT); + argument = argument.replaceAll("\\\\", ""); + argument = argument.replaceAll("'", ""); + + if (argument.equals("a:") || argument.equals("action:")) { + next = 1; + } + else if (next == 1 || argument.startsWith("a:") || argument.startsWith("action:")) { + result.clear(); + argument = argument.replaceAll("action:", ""); + argument = argument.replaceAll("a:", ""); + if (argument.startsWith("#")) { + argument = argument.replaceFirst("#", ""); + } + if (argument.equals("broke") || argument.equals("break") || argument.equals("remove") || argument.equals("destroy") || argument.equals("block-break") || argument.equals("block-remove") || argument.equals("-block") || argument.equals("block-")) { + result.add(0); + } + else if (argument.equals("placed") || argument.equals("place") || argument.equals("block-place") || argument.equals("+block") || argument.equals("block+")) { + result.add(1); + } + else if (argument.equals("block") || argument.equals("block-change") || argument.equals("change")) { + result.add(0); + result.add(1); + } + else if (argument.equals("click") || argument.equals("clicks") || argument.equals("interact") || argument.equals("interaction") || argument.equals("player-interact") || argument.equals("player-interaction") || argument.equals("player-click")) { + result.add(2); + } + else if (argument.equals("death") || argument.equals("deaths") || argument.equals("entity-death") || argument.equals("entity-deaths") || argument.equals("kill") || argument.equals("kills") || argument.equals("entity-kill") || argument.equals("entity-kills")) { + result.add(3); + } + else if (argument.equals("container") || argument.equals("container-change") || argument.equals("containers") || argument.equals("chest") || argument.equals("transaction") || argument.equals("transactions")) { + result.add(4); + } + else if (argument.equals("-container") || argument.equals("container-") || argument.equals("remove-container")) { + result.add(4); + result.add(0); + } + else if (argument.equals("+container") || argument.equals("container+") || argument.equals("container-add") || argument.equals("add-container")) { + result.add(4); + result.add(1); + } + else if (argument.equals("chat")) { + result.add(6); + } + else if (argument.equals("command") || argument.equals("commands")) { + result.add(7); + } + else if (argument.equals("login") || argument.equals("+session") || argument.equals("session+") || argument.equals("+connection") || argument.equals("connection+")) { + result.add(8); + result.add(1); + } + else if (argument.equals("logout") || argument.equals("-session") || argument.equals("session-") || argument.equals("-connection") || argument.equals("connection-")) { + result.add(8); + result.add(0); + } + else if (argument.equals("session") || argument.equals("sessions") || argument.equals("connection") || argument.equals("connections")) { + result.add(8); + } + else if (argument.equals("username") || argument.equals("usernames") || argument.equals("user") || argument.equals("users") || argument.equals("name") || argument.equals("names") || argument.equals("uuid") || argument.equals("uuids") || argument.equals("username-change") || argument.equals("username-changes") || argument.equals("name-change") || argument.equals("name-changes")) { + result.add(9); + } + else if (argument.equals("sign")) { + result.add(10); + } + else if (argument.equals("item") || argument.equals("items")) { + result.add(4); + result.add(11); + } + else if (argument.equals("-item") || argument.equals("item-") || argument.equals("-items") || argument.equals("items-")) { + result.add(4); + result.add(11); + result.add(0); + } + else if (argument.equals("+item") || argument.equals("item+") || argument.equals("+items") || argument.equals("items+")) { + result.add(4); + result.add(11); + result.add(1); + } + else if (argument.equals("inv") || argument.equals("inventory") || argument.equals("inventories")) { + result.add(11); + } + else if (argument.equals("-inv") || argument.equals("inv-") || argument.equals("-inventory") || argument.equals("inventory-") || argument.equals("-inventories") || argument.equals("drop") || argument.equals("drops") || argument.equals("deposit") || argument.equals("deposits") || argument.equals("deposited")) { + result.add(11); + result.add(0); + } + else if (argument.equals("+inv") || argument.equals("inv+") || argument.equals("+inventory") || argument.equals("inventory+") || argument.equals("+inventories") || argument.equals("pickup") || argument.equals("pickups") || argument.equals("withdraw") || argument.equals("withdraws") || argument.equals("withdrew")) { + result.add(11); + result.add(1); + } + else { + result.add(-1); + } + next = 0; + } + else { + next = 0; + } + } + count++; + } + return result; + } + + protected static Location parseCoordinates(Location location, String[] inputArguments, int worldId) { + String[] argumentArray = inputArguments.clone(); + int count = 0; + int next = 0; + for (String argument : argumentArray) { + if (count > 0) { + argument = argument.trim().toLowerCase(Locale.ROOT); + argument = argument.replaceAll("\\\\", ""); + argument = argument.replaceAll("'", ""); + + if (argument.equals("position:") || argument.equals("location:") || argument.equals("c:") || argument.equals("coord:") || argument.equals("coords:") || argument.equals("cord:") || argument.equals("cords:") || argument.equals("coordinate:") || argument.equals("coordinates:") || argument.equals("cordinate:") || argument.equals("cordinates:")) { + next = 2; + } + else if (next == 2 || argument.startsWith("c:") || argument.startsWith("coord:") || argument.startsWith("coords:") || argument.startsWith("cord:") || argument.startsWith("cords:") || argument.startsWith("coordinate:") || argument.startsWith("coordinates:") || argument.startsWith("cordinate:") || argument.startsWith("cordinates:")) { + argument = argument.replaceAll("coordinates:", ""); + argument = argument.replaceAll("coordinate:", ""); + argument = argument.replaceAll("cordinates:", ""); + argument = argument.replaceAll("cordinate:", ""); + argument = argument.replaceAll("coords:", ""); + argument = argument.replaceAll("coord:", ""); + argument = argument.replaceAll("cords:", ""); + argument = argument.replaceAll("cord:", ""); + argument = argument.replaceAll("c:", ""); + if (argument.contains(",")) { + String[] i2 = argument.split(","); + double x = 0.00; + double y = 0.00; + double z = 0.00; + int cCount = 0; + for (String coord : i2) { + coord = coord.replaceAll("[^0-9.\\-]", ""); + if (coord.length() > 0 && !coord.equals(".") && !coord.equals("-") && coord.indexOf('.') == coord.lastIndexOf('.')) { + double parsedCoord = Double.parseDouble(coord); + if (cCount == 0) { + x = parsedCoord; + } + else if (cCount == 1) { + z = parsedCoord; + } + else if (cCount == 2) { + y = z; + z = parsedCoord; + } + cCount++; + } + } + if (cCount > 1) { + if (location == null && worldId > 0) { + location = new Location(Bukkit.getWorld(Util.getWorldName(worldId)), 0, 0, 0); + } + if (location != null) { + int worldMaxHeight = location.getWorld().getMaxHeight() - 1; + int worldMinHeight = BukkitAdapter.ADAPTER.getMinHeight(location.getWorld()); + + if (y < worldMinHeight) { + y = Double.valueOf(worldMinHeight); + } + if (y > worldMaxHeight) { + y = Double.valueOf(worldMaxHeight); + } + + location.setX(x); + location.setY(y); + location.setZ(z); + } + } + } + next = 0; + } + else { + next = 0; + } + } + count++; + } + return location; + } + + protected static boolean parseCount(String[] inputArguments) { + String[] argumentArray = inputArguments.clone(); + boolean result = false; + int count = 0; + for (String argument : argumentArray) { + if (count > 0) { + argument = argument.trim().toLowerCase(Locale.ROOT); + argument = argument.replaceAll("\\\\", ""); + argument = argument.replaceAll("'", ""); + if (argument.equals("#count") || argument.equals("#sum")) { + result = true; + } + } + count++; + } + return result; + } + + protected static List parseExcluded(CommandSender player, String[] inputArguments, List argAction) { + String[] argumentArray = inputArguments.clone(); + List excluded = new ArrayList<>(); + int count = 0; + int next = 0; + for (String argument : argumentArray) { + if (count > 0) { + argument = argument.trim().toLowerCase(Locale.ROOT); + argument = argument.replaceAll("\\\\", ""); + argument = argument.replaceAll("'", ""); + + if (argument.equals("e:") || argument.equals("exclude:")) { + next = 5; + } + else if (next == 5 || argument.startsWith("e:") || argument.startsWith("exclude:")) { + argument = argument.replaceAll("exclude:", ""); + argument = argument.replaceAll("e:", ""); + if (argument.contains(",")) { + String[] i2 = argument.split(","); + for (String i3 : i2) { + if (i3.equals("#natural")) { + excluded.addAll(naturalBlocks); + } + else { + Material i3_material = Util.getType(i3); + if (i3_material != null && (i3_material.isBlock() || argAction.contains(4))) { + excluded.add(i3_material); + } + else { + EntityType i3_entity = Util.getEntityType(i3); + if (i3_entity != null) { + excluded.add(i3_entity); + } + else if (i3_material != null) { + excluded.add(i3_material); + } + } + } + } + if (argument.endsWith(",")) { + next = 5; + } + else { + next = 0; + } + } + else { + if (argument.equals("#natural")) { + excluded.addAll(naturalBlocks); + } + else { + Material iMaterial = Util.getType(argument); + if (iMaterial != null && (iMaterial.isBlock() || argAction.contains(4))) { + excluded.add(iMaterial); + } + else { + EntityType iEntity = Util.getEntityType(argument); + if (iEntity != null) { + excluded.add(iEntity); + } + else if (iMaterial != null) { + excluded.add(iMaterial); + } + } + } + next = 0; + } + } + else { + next = 0; + } + } + count++; + } + return excluded; + } + + protected static List parseExcludedUsers(CommandSender player, String[] inputArguments) { + String[] argumentArray = inputArguments.clone(); + List excluded = new ArrayList<>(); + int count = 0; + int next = 0; + for (String argument : argumentArray) { + if (count > 0) { + argument = argument.trim().toLowerCase(Locale.ROOT); + argument = argument.replaceAll("\\\\", ""); + argument = argument.replaceAll("'", ""); + + if (argument.equals("e:") || argument.equals("exclude:")) { + next = 5; + } + else if (next == 5 || argument.startsWith("e:") || argument.startsWith("exclude:")) { + argument = argument.replaceAll("exclude:", ""); + argument = argument.replaceAll("e:", ""); + if (argument.contains(",")) { + String[] i2 = argument.split(","); + for (String i3 : i2) { + boolean isBlock = false; + if (i3.equals("#natural")) { + isBlock = true; + } + else { + Material i3_material = Util.getType(i3); + if (i3_material != null) { + isBlock = true; + } + else { + EntityType i3Entity = Util.getEntityType(i3); + if (i3Entity != null) { + isBlock = true; + } + } + } + if (!isBlock) { + excluded.add(i3); + } + } + if (argument.endsWith(",")) { + next = 5; + } + else { + next = 0; + } + } + else { + boolean isBlock = false; + if (argument.equals("#natural")) { + isBlock = true; + } + else { + Material iMaterial = Util.getType(argument); + if (iMaterial != null) { + isBlock = true; + } + else { + EntityType entityType = Util.getEntityType(argument); + if (entityType != null) { + isBlock = true; + } + } + } + if (!isBlock) { + excluded.add(argument); + } + next = 0; + } + } + else { + next = 0; + } + } + count++; + } + return excluded; + } + + protected static boolean parseForceGlobal(String[] inputArguments) { + String[] argumentArray = inputArguments.clone(); + boolean result = false; + int count = 0; + int next = 0; + for (String argument : argumentArray) { + if (count > 0) { + argument = argument.trim().toLowerCase(Locale.ROOT); + argument = argument.replaceAll("\\\\", ""); + argument = argument.replaceAll("'", ""); + + if (argument.equals("r:") || argument.equals("radius:")) { + next = 2; + } + else if (next == 2 || argument.startsWith("r:") || argument.startsWith("radius:")) { + argument = argument.replaceAll("radius:", ""); + argument = argument.replaceAll("r:", ""); + if (argument.equals("#global") || argument.equals("global") || argument.equals("off") || argument.equals("-1") || argument.equals("none") || argument.equals("false")) { + result = true; + } + else if (argument.startsWith("#")) { + int worldId = Util.matchWorld(argument); + if (worldId > 0) { + result = true; + } + } + next = 0; + } + else { + next = 0; + } + } + count++; + } + return result; + } + + protected static Location parseLocation(CommandSender user, String[] argumentArray) { + Location location = null; + if (user instanceof Player) { + location = ((Player) user).getLocation(); + } + else if (user instanceof BlockCommandSender) { + location = ((BlockCommandSender) user).getBlock().getLocation(); + } + + return parseCoordinates(location, argumentArray, parseWorld(argumentArray, true, true)); + } + + protected static int parseNoisy(String[] inputArguments) { + String[] argumentArray = inputArguments.clone(); + int noisy = 0; + int count = 0; + if (Config.getGlobal().VERBOSE) { + noisy = 1; + } + for (String argument : argumentArray) { + if (count > 0) { + argument = argument.trim().toLowerCase(Locale.ROOT); + argument = argument.replaceAll("\\\\", ""); + argument = argument.replaceAll("'", ""); + + if (argument.equals("n") || argument.equals("noisy") || argument.equals("v") || argument.equals("verbose") || argument.equals("#v") || argument.equals("#verbose")) { + noisy = 1; + } + else if (argument.equals("#silent")) { + noisy = 0; + } + } + count++; + } + return noisy; + } + + protected static int parsePreview(String[] inputArguments) { + String[] argumentArray = inputArguments.clone(); + int result = 0; + int count = 0; + for (String argument : argumentArray) { + if (count > 0) { + argument = argument.trim().toLowerCase(Locale.ROOT); + argument = argument.replaceAll("\\\\", ""); + argument = argument.replaceAll("'", ""); + if (argument.equals("#preview")) { + result = 1; + } + else if (argument.equals("#preview_cancel")) { + result = 2; + } + } + count++; + } + return result; + } + + protected static Integer[] parseRadius(String[] inputArguments, CommandSender user, Location location) { + String[] argumentArray = inputArguments.clone(); + Integer[] radius = null; + int count = 0; + int next = 0; + for (String argument : argumentArray) { + if (count > 0) { + argument = argument.trim().toLowerCase(Locale.ROOT); + argument = argument.replaceAll("\\\\", ""); + argument = argument.replaceAll("'", ""); + + if (argument.equals("r:") || argument.equals("radius:")) { + next = 2; + } + else if (next == 2 || argument.startsWith("r:") || argument.startsWith("radius:")) { + argument = argument.replaceAll("radius:", ""); + argument = argument.replaceAll("r:", ""); + if (argument.equals("#worldedit") || argument.equals("#we")) { + if (user.getServer().getPluginManager().getPlugin("WorldEdit") != null) { + Integer[] worldEditResult = WorldEditHandler.runWorldEditCommand(user); + if (worldEditResult != null) { + radius = worldEditResult; + } + } + } + else if ((argument.startsWith("#") && argument.length() > 1) || argument.equals("global") || argument.equals("off") || argument.equals("-1") || argument.equals("none") || argument.equals("false")) { + // radius = -2; + } + else { + int rcount = 0; + int r_x = 0; + int r_y = -1; + int r_z = 0; + String[] r_dat = new String[] { argument }; + boolean validRadius = false; + if (argument.contains("x")) { + r_dat = argument.split("x"); + } + for (String value : r_dat) { + String i4 = value.replaceAll("[^0-9.]", ""); + if (i4.length() > 0 && i4.length() == value.length() && i4.replaceAll("[^0-9]", "").length() > 0 && i4.indexOf('.') == i4.lastIndexOf('.')) { + double a1 = Double.parseDouble(i4); + if (rcount == 0) { // x + r_x = (int) a1; + r_z = (int) a1; + } + else if (rcount == 1) { // y + r_y = (int) a1; + } + else if (rcount == 2) { // z + r_z = (int) a1; + } + validRadius = true; + } + rcount++; + } + if (location != null) { + int xmin = location.getBlockX() - r_x; + int xmax = location.getBlockX() + r_x; + int ymin = -1; + int ymax = -1; + int zmin = location.getBlockZ() - r_z; + int zmax = location.getBlockZ() + r_z; + if (r_y > -1) { + ymin = location.getBlockY() - r_y; + ymax = location.getBlockY() + r_y; + } + int max = r_x; + if (r_y > max) { + max = r_y; + } + if (r_z > max) { + max = r_z; + } + if (validRadius) { + radius = new Integer[] { max, xmin, xmax, ymin, ymax, zmin, zmax, 0 }; + } + else { + radius = new Integer[] { -1 }; + } + } + } + next = 0; + } + else { + next = 0; + } + } + count++; + } + return radius; + } + + protected static List parseRestricted(CommandSender player, String[] inputArguments, List argAction) { + String[] argumentArray = inputArguments.clone(); + List restricted = new ArrayList<>(); + int count = 0; + int next = 0; + for (String argument : argumentArray) { + if (count > 0) { + argument = argument.trim().toLowerCase(Locale.ROOT); + argument = argument.replaceAll("\\\\", ""); + argument = argument.replaceAll("'", ""); + + if (argument.equals("i:") || argument.equals("include:") || argument.equals("item:") || argument.equals("items:") || argument.equals("b:") || argument.equals("block:") || argument.equals("blocks:")) { + next = 4; + } + else if (next == 4 || argument.startsWith("i:") || argument.startsWith("include:") || argument.startsWith("item:") || argument.startsWith("items:") || argument.startsWith("b:") || argument.startsWith("block:") || argument.startsWith("blocks:")) { + argument = argument.replaceAll("include:", ""); + argument = argument.replaceAll("i:", ""); + argument = argument.replaceAll("items:", ""); + argument = argument.replaceAll("item:", ""); + argument = argument.replaceAll("blocks:", ""); + argument = argument.replaceAll("block:", ""); + argument = argument.replaceAll("b:", ""); + if (argument.contains(",")) { + String[] i2 = argument.split(","); + for (String i3 : i2) { + if (i3.equals("#natural")) { + restricted.addAll(naturalBlocks); + } + else { + Material i3_material = Util.getType(i3); + if (i3_material != null && (i3_material.isBlock() || argAction.contains(4))) { + restricted.add(i3_material); + } + else { + EntityType i3_entity = Util.getEntityType(i3); + if (i3_entity != null) { + restricted.add(i3_entity); + } + else if (i3_material != null) { + restricted.add(i3_material); + } + else { + Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.INVALID_INCLUDE, i3)); + // Functions.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.MISSING_PARAMETERS, "/co help include")); + return null; + } + } + } + } + if (argument.endsWith(",")) { + next = 4; + } + else { + next = 0; + } + } + else { + if (argument.equals("#natural")) { + restricted.addAll(naturalBlocks); + } + else { + Material material = Util.getType(argument); + if (material != null && (material.isBlock() || argAction.contains(4))) { + restricted.add(material); + } + else { + EntityType entityType = Util.getEntityType(argument); + if (entityType != null) { + restricted.add(entityType); + } + else if (material != null) { + restricted.add(material); + } + else { + Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.INVALID_INCLUDE, argument)); + // Functions.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.MISSING_PARAMETERS, "/co help include")); + return null; + } + } + } + next = 0; + } + } + else { + next = 0; + } + } + count++; + } + return restricted; + } + + protected static int parseTime(String[] inputArguments) { + String[] argumentArray = inputArguments.clone(); + int time = 0; + int count = 0; + int next = 0; + double w = 0; + double d = 0; + double h = 0; + double m = 0; + double s = 0; + for (String argument : argumentArray) { + if (count > 0) { + argument = argument.trim().toLowerCase(Locale.ROOT); + argument = argument.replaceAll("\\\\", ""); + argument = argument.replaceAll("'", ""); + + if (argument.equals("t:") || argument.equals("time:")) { + next = 1; + } + else if (next == 1 || argument.startsWith("t:") || argument.startsWith("time:")) { + // time arguments + argument = argument.replaceAll("time:", ""); + argument = argument.replaceAll("t:", ""); + argument = argument.replaceAll("y", "y:"); + argument = argument.replaceAll("m", "m:"); + argument = argument.replaceAll("w", "w:"); + argument = argument.replaceAll("d", "d:"); + argument = argument.replaceAll("h", "h:"); + argument = argument.replaceAll("s", "s:"); + String[] i2 = argument.split(":"); + for (String i3 : i2) { + if (i3.endsWith("w")) { + String i4 = i3.replaceAll("[^0-9.]", ""); + if (i4.length() > 0 && i4.replaceAll("[^0-9]", "").length() > 0 && i4.indexOf('.') == i4.lastIndexOf('.')) { + w = Double.parseDouble(i4); + } + } + else if (i3.endsWith("d")) { + String i4 = i3.replaceAll("[^0-9.]", ""); + if (i4.length() > 0 && i4.replaceAll("[^0-9]", "").length() > 0 && i4.indexOf('.') == i4.lastIndexOf('.')) { + d = Double.parseDouble(i4); + } + } + else if (i3.endsWith("h")) { + String i4 = i3.replaceAll("[^0-9.]", ""); + if (i4.length() > 0 && i4.replaceAll("[^0-9]", "").length() > 0 && i4.indexOf('.') == i4.lastIndexOf('.')) { + h = Double.parseDouble(i4); + } + } + else if (i3.endsWith("m")) { + String i4 = i3.replaceAll("[^0-9.]", ""); + if (i4.length() > 0 && i4.replaceAll("[^0-9]", "").length() > 0 && i4.indexOf('.') == i4.lastIndexOf('.')) { + m = Double.parseDouble(i4); + } + } + else if (i3.endsWith("s")) { + String i4 = i3.replaceAll("[^0-9.]", ""); + if (i4.length() > 0 && i4.replaceAll("[^0-9]", "").length() > 0 && i4.indexOf('.') == i4.lastIndexOf('.')) { + s = Double.parseDouble(i4); + } + } + } + double rs = ((w * 7 * 24 * 60 * 60) + (d * 24 * 60 * 60) + (h * 60 * 60) + (m * 60) + s); + time = (int) rs; + next = 0; + } + else { + next = 0; + } + } + count++; + } + return time; + } + + private static String timeString(BigDecimal input) { + return input.stripTrailingZeros().toPlainString(); + } + + protected static String parseTimeString(String[] inputArguments) { + String[] argumentArray = inputArguments.clone(); + String time = ""; + int count = 0; + int next = 0; + BigDecimal w = new BigDecimal(0); + BigDecimal d = new BigDecimal(0); + BigDecimal h = new BigDecimal(0); + BigDecimal m = new BigDecimal(0); + BigDecimal s = new BigDecimal(0); + for (String argument : argumentArray) { + if (count > 0) { + argument = argument.trim().toLowerCase(Locale.ROOT); + argument = argument.replaceAll("\\\\", ""); + argument = argument.replaceAll("'", ""); + + if (argument.equals("t:") || argument.equals("time:")) { + next = 1; + } + else if (next == 1 || argument.startsWith("t:") || argument.startsWith("time:")) { + // time arguments + argument = argument.replaceAll("time:", ""); + argument = argument.replaceAll("t:", ""); + argument = argument.replaceAll("y", "y:"); + argument = argument.replaceAll("m", "m:"); + argument = argument.replaceAll("w", "w:"); + argument = argument.replaceAll("d", "d:"); + argument = argument.replaceAll("h", "h:"); + argument = argument.replaceAll("s", "s:"); + String[] i2 = argument.split(":"); + for (String i3 : i2) { + if (i3.endsWith("w")) { + String i4 = i3.replaceAll("[^0-9.]", ""); + if (i4.length() > 0 && i4.replaceAll("[^0-9]", "").length() > 0 && i4.indexOf('.') == i4.lastIndexOf('.')) { + w = new BigDecimal(i4); + time = time + " " + Phrase.build(Phrase.TIME_WEEKS, timeString(w), (w.doubleValue() == 1 ? Selector.FIRST : Selector.SECOND)); + } + } + else if (i3.endsWith("d")) { + String i4 = i3.replaceAll("[^0-9.]", ""); + if (i4.length() > 0 && i4.replaceAll("[^0-9]", "").length() > 0 && i4.indexOf('.') == i4.lastIndexOf('.')) { + d = new BigDecimal(i4); + time = time + " " + Phrase.build(Phrase.TIME_DAYS, timeString(d), (d.doubleValue() == 1 ? Selector.FIRST : Selector.SECOND)); + } + } + else if (i3.endsWith("h")) { + String i4 = i3.replaceAll("[^0-9.]", ""); + if (i4.length() > 0 && i4.replaceAll("[^0-9]", "").length() > 0 && i4.indexOf('.') == i4.lastIndexOf('.')) { + h = new BigDecimal(i4); + time = time + " " + Phrase.build(Phrase.TIME_HOURS, timeString(h), (h.doubleValue() == 1 ? Selector.FIRST : Selector.SECOND)); + } + } + else if (i3.endsWith("m")) { + String i4 = i3.replaceAll("[^0-9.]", ""); + if (i4.length() > 0 && i4.replaceAll("[^0-9]", "").length() > 0 && i4.indexOf('.') == i4.lastIndexOf('.')) { + m = new BigDecimal(i4); + time = time + " " + Phrase.build(Phrase.TIME_MINUTES, timeString(m), (m.doubleValue() == 1 ? Selector.FIRST : Selector.SECOND)); + } + } + else if (i3.endsWith("s")) { + String i4 = i3.replaceAll("[^0-9.]", ""); + if (i4.length() > 0 && i4.replaceAll("[^0-9]", "").length() > 0 && i4.indexOf('.') == i4.lastIndexOf('.')) { + s = new BigDecimal(i4); + time = time + " " + Phrase.build(Phrase.TIME_SECONDS, timeString(s), (s.doubleValue() == 1 ? Selector.FIRST : Selector.SECOND)); + } + } + } + next = 0; + } + else { + next = 0; + } + } + count++; + } + + if (time.startsWith(" ")) { + time = time.substring(1); + } + + return time; + } + + protected static int parseRows(String[] inputArguments) { + String[] argumentArray = inputArguments.clone(); + int rows = 0; + int count = 0; + int next = 0; + + for (String argument : argumentArray) { + if (count > 0) { + argument = argument.trim().toLowerCase(Locale.ROOT); + argument = argument.replaceAll("\\\\", ""); + argument = argument.replaceAll("'", ""); + + if (argument.equals("rows:")) { + next = 1; + } + else if (next == 1 || argument.startsWith("rows:")) { + argument = argument.replaceAll("rows:", "").trim(); + if (!argument.startsWith("-")) { + String i2 = argument.replaceAll("[^0-9]", ""); + if (i2.length() > 0 && i2.length() < 10) { + rows = Integer.parseInt(i2); + } + } + + next = 0; + } + else { + next = 0; + } + } + count++; + } + + return rows; + } + + private static void parseUser(List users, String string) { + string = string.trim(); + if (string.contains(",")) { + String[] data = string.split(","); + for (String user : data) { + validUserCheck(users, user); + } + } + else { + validUserCheck(users, string); + } + } + + protected static List parseUsers(String[] inputArguments) { + String[] argumentArray = inputArguments.clone(); + List users = new ArrayList<>(); + int count = 0; + int next = 0; + for (String argument : argumentArray) { + if (count > 0) { + argument = argument.trim().toLowerCase(Locale.ROOT); + argument = argument.replaceAll("\\\\", ""); + argument = argument.replaceAll("'", ""); + + if (next == 2) { + if (argument.endsWith(",")) { + next = 2; + } + else { + next = 0; + } + } + else if (argument.equals("p:") || argument.equals("user:") || argument.equals("users:") || argument.equals("u:")) { + next = 1; + } + else if (next == 1 || argument.startsWith("p:") || argument.startsWith("user:") || argument.startsWith("users:") || argument.startsWith("u:")) { + argument = argument.replaceAll("user:", ""); + argument = argument.replaceAll("users:", ""); + argument = argument.replaceAll("p:", ""); + argument = argument.replaceAll("u:", ""); + if (argument.contains(",")) { + String[] i2 = argument.split(","); + for (String i3 : i2) { + parseUser(users, i3); + } + if (argument.endsWith(",")) { + next = 1; + } + else { + next = 0; + } + } + else { + parseUser(users, argument); + next = 0; + } + } + else if (argument.endsWith(",") || argument.endsWith(":")) { + next = 2; + } + else if (argument.contains(":")) { + next = 0; + } + else { + parseUser(users, argument); + next = 0; + } + } + count++; + } + return users; + } + + protected static int parseWorld(String[] inputArguments, boolean processWorldEdit, boolean requireLoaded) { + String[] argumentArray = inputArguments.clone(); + int world_id = 0; + int count = 0; + int next = 0; + for (String argument : argumentArray) { + if (count > 0) { + argument = argument.trim(); + argument = argument.replaceAll("\\\\", ""); + argument = argument.replaceAll("'", ""); + + String inputProcessed = argument.toLowerCase(Locale.ROOT); + if (inputProcessed.equals("r:") || inputProcessed.equals("radius:")) { + next = 2; + } + else if (next == 2 || inputProcessed.startsWith("r:") || inputProcessed.startsWith("radius:")) { + argument = argument.replaceAll("radius:", "").replaceAll("r:", ""); + inputProcessed = argument.toLowerCase(Locale.ROOT); + if ((processWorldEdit && (inputProcessed.equals("#worldedit") || inputProcessed.equals("#we"))) || inputProcessed.equals("#global") || inputProcessed.equals("global") || inputProcessed.equals("off") || inputProcessed.equals("-1") || inputProcessed.equals("none") || inputProcessed.equals("false")) { + world_id = 0; + } + else if (inputProcessed.startsWith("#")) { + world_id = Util.matchWorld(inputProcessed); + if (world_id == -1 && !requireLoaded) { + world_id = ConfigHandler.worlds.getOrDefault(argument.replaceFirst("#", ""), -1); + } + } + next = 0; + } + else { + next = 0; + } + } + count++; + } + return world_id; + } + + protected static boolean parseWorldEdit(String[] inputArguments) { + String[] argumentArray = inputArguments.clone(); + boolean result = false; + int count = 0; + int next = 0; + for (String argument : argumentArray) { + if (count > 0) { + argument = argument.trim().toLowerCase(Locale.ROOT); + argument = argument.replaceAll("\\\\", ""); + argument = argument.replaceAll("'", ""); + + if (argument.equals("r:") || argument.equals("radius:")) { + next = 2; + } + else if (next == 2 || argument.startsWith("r:") || argument.startsWith("radius:")) { + argument = argument.replaceAll("radius:", ""); + argument = argument.replaceAll("r:", ""); + if (argument.equals("#worldedit") || argument.equals("#we")) { + result = true; + } + next = 0; + } + else { + next = 0; + } + } + count++; + } + return result; + } + + protected static String parseWorldName(String[] inputArguments, boolean processWorldEdit) { + String[] argumentArray = inputArguments.clone(); + String worldName = ""; + int count = 0; + int next = 0; + for (String argument : argumentArray) { + if (count > 0) { + argument = argument.trim().toLowerCase(Locale.ROOT); + argument = argument.replaceAll("\\\\", ""); + argument = argument.replaceAll("'", ""); + + if (argument.equals("r:") || argument.equals("radius:")) { + next = 2; + } + else if (next == 2 || argument.startsWith("r:") || argument.startsWith("radius:")) { + argument = argument.replaceAll("radius:", ""); + argument = argument.replaceAll("r:", ""); + if ((processWorldEdit && (argument.equals("#worldedit") || argument.equals("#we"))) || argument.equals("#global") || argument.equals("global") || argument.equals("off") || argument.equals("-1") || argument.equals("none") || argument.equals("false")) { + worldName = ""; + } + else if (argument.startsWith("#")) { + worldName = argument.replaceFirst("#", ""); + } + next = 0; + } + else { + next = 0; + } + } + count++; + } + return worldName; + } + + private static void validUserCheck(List users, String user) { + List badUsers = Arrays.asList("n", "noisy", "v", "verbose", "#v", "#verbose", "#silent", "#preview", "#preview_cancel", "#count", "#sum"); + String check = user.replaceAll("[\\s'\"]", ""); + if (check.equals(user) && check.length() > 0) { + if (user.equalsIgnoreCase("#global")) { + user = "#global"; + } + if (!badUsers.contains(user.toLowerCase(Locale.ROOT))) { + users.add(user); + } + } + } + + @Override + public boolean onCommand(CommandSender user, Command command, String commandLabel, String[] argumentArray) { + String commandName = command.getName().toLowerCase(Locale.ROOT); + + if (commandName.equals("core") || commandName.equals("coreprotect") || commandName.equals("co")) { + int resultc = argumentArray.length; + if (resultc > -1) { + String corecommand = "help"; + if (resultc > 0) { + corecommand = argumentArray[0].toLowerCase(Locale.ROOT); + } + boolean permission = false; + if (!permission) { + if (user.hasPermission("coreprotect.rollback") && (corecommand.equals("rollback") || corecommand.equals("rb") || corecommand.equals("ro") || corecommand.equals("apply") || corecommand.equals("cancel"))) { + permission = true; + } + else if (user.hasPermission("coreprotect.restore") && (corecommand.equals("restore") || corecommand.equals("rs") || corecommand.equals("re") || corecommand.equals("undo") || corecommand.equals("apply") || corecommand.equals("cancel"))) { + permission = true; + } + else if (user.hasPermission("coreprotect.inspect") && (corecommand.equals("i") || corecommand.equals("inspect"))) { + permission = true; + } + else if (user.hasPermission("coreprotect.help") && corecommand.equals("help")) { + permission = true; + } + else if (user.hasPermission("coreprotect.purge") && corecommand.equals("purge")) { + permission = true; + } + else if (user.hasPermission("coreprotect.lookup") && (corecommand.equals("l") || corecommand.equals("lookup") || corecommand.equals("near"))) { + permission = true; + } + else if (user.hasPermission("coreprotect.lookup.near") && corecommand.equals("near")) { + permission = true; + } + else if (user.hasPermission("coreprotect.teleport") && (corecommand.equals("tp") || corecommand.equals("teleport"))) { + permission = true; + } + else if (user.hasPermission("coreprotect.reload") && corecommand.equals("reload")) { + permission = true; + } + else if (user.hasPermission("coreprotect.status") && (corecommand.equals("status") || corecommand.equals("stats") || corecommand.equals("version"))) { + permission = true; + } + } + + if (corecommand.equals("rollback") || corecommand.equals("restore") || corecommand.equals("rb") || corecommand.equals("rs") || corecommand.equals("ro") || corecommand.equals("re")) { + RollbackRestoreCommand.runCommand(user, command, permission, argumentArray, null, 0); + } + else if (corecommand.equals("apply")) { + ApplyCommand.runCommand(user, command, permission, argumentArray); + } + else if (corecommand.equals("cancel")) { + CancelCommand.runCommand(user, command, permission, argumentArray); + } + else if (corecommand.equals("undo")) { + UndoCommand.runCommand(user, command, permission, argumentArray); + } + else if (corecommand.equals("help")) { + HelpCommand.runCommand(user, permission, argumentArray); + } + else if (corecommand.equals("purge")) { + PurgeCommand.runCommand(user, permission, argumentArray); + } + else if (corecommand.equals("inspect") || corecommand.equals("i")) { + InspectCommand.runCommand(user, permission, argumentArray); + } + else if (corecommand.equals("lookup") || corecommand.equals("l")) { + LookupCommand.runCommand(user, command, permission, argumentArray); + } + else if (corecommand.equals("near")) { + LookupCommand.runCommand(user, command, permission, new String[] { "near", "r:5x5" }); + } + else if (corecommand.equals("teleport") || corecommand.equals("tp")) { + TeleportCommand.runCommand(user, permission, argumentArray); + } + else if (corecommand.equals("status") || corecommand.equals("stats") || corecommand.equals("version")) { + StatusCommand.runCommand(user, permission, argumentArray); + } + else if (corecommand.equals("reload")) { + ReloadCommand.runCommand(user, permission, argumentArray); + } + else { + Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.COMMAND_NOT_FOUND, Color.WHITE, "/co " + corecommand)); + } + } + else { + Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.MISSING_PARAMETERS, Color.WHITE, "/co ")); + } + + if (user.isOp() && versionAlert.get(user.getName()) == null) { + String latestVersion = NetworkHandler.latestVersion(); + if (latestVersion != null) { + versionAlert.put(user.getName(), true); + class updateAlert implements Runnable { + @Override + public void run() { + try { + Thread.sleep(5000); + Chat.sendMessage(user, Color.WHITE + "----- " + Color.DARK_AQUA + Phrase.build(Phrase.UPDATE_HEADER, "CoreProtect") + Color.WHITE + " -----"); + Chat.sendMessage(user, Color.DARK_AQUA + Phrase.build(Phrase.UPDATE_NOTICE, Color.WHITE, "CoreProtect v" + latestVersion)); + Chat.sendMessage(user, Color.DARK_AQUA + Phrase.build(Phrase.LINK_DOWNLOAD, Color.WHITE, "www.coreprotect.net/download/")); + } + catch (Exception e) { + e.printStackTrace(); + } + } + } + (new Thread(new updateAlert())).start(); + } + } + + return true; + } + + return false; + } +} diff --git a/src/main/java/net/coreprotect/command/HelpCommand.java b/src/main/java/net/coreprotect/command/HelpCommand.java new file mode 100755 index 0000000..fdbd588 --- /dev/null +++ b/src/main/java/net/coreprotect/command/HelpCommand.java @@ -0,0 +1,129 @@ +package net.coreprotect.command; + +import java.util.Locale; + +import org.bukkit.command.CommandSender; + +import net.coreprotect.language.Phrase; +import net.coreprotect.language.Selector; +import net.coreprotect.utility.Chat; +import net.coreprotect.utility.Color; + +public class HelpCommand { + protected static void runCommand(CommandSender player, boolean permission, String[] args) { + int resultc = args.length; + if (permission) { + if (resultc > 1) { + String helpcommand_original = args[1]; + String helpcommand = args[1].toLowerCase(Locale.ROOT); + helpcommand = helpcommand.replaceAll("[^a-zA-Z]", ""); + Chat.sendMessage(player, Color.WHITE + "----- " + Color.DARK_AQUA + Phrase.build(Phrase.HELP_HEADER, "CoreProtect") + Color.WHITE + " -----"); + if (helpcommand.equals("help")) { + Chat.sendMessage(player, Color.DARK_AQUA + "/co help " + Color.WHITE + "- " + Phrase.build(Phrase.HELP_LIST)); + } + else if (helpcommand.equals("inspect") || helpcommand.equals("inspector") || helpcommand.equals("in")) { + Chat.sendMessage(player, Color.DARK_AQUA + Phrase.build(Phrase.HELP_INSPECT_1)); + Chat.sendMessage(player, "* " + Phrase.build(Phrase.HELP_INSPECT_2)); + Chat.sendMessage(player, "* " + Phrase.build(Phrase.HELP_INSPECT_3)); + Chat.sendMessage(player, "* " + Phrase.build(Phrase.HELP_INSPECT_4)); + Chat.sendMessage(player, "* " + Phrase.build(Phrase.HELP_INSPECT_5)); + Chat.sendMessage(player, "* " + Phrase.build(Phrase.HELP_INSPECT_6)); + Chat.sendMessage(player, Color.GREY + Color.ITALIC + Phrase.build(Phrase.HELP_INSPECT_7)); + } + else if (helpcommand.equals("params") || helpcommand.equals("param") || helpcommand.equals("parameters") || helpcommand.equals("parameter")) { + Chat.sendMessage(player, Color.DARK_AQUA + "/co lookup " + Color.GREY + " " + Color.WHITE + "- " + Phrase.build(Phrase.HELP_PARAMS_1, Selector.FIRST)); + Chat.sendMessage(player, Color.DARK_AQUA + "| " + Color.GREY + "u: " + Color.WHITE + "- " + Phrase.build(Phrase.HELP_PARAMS_2, Selector.FIRST)); + Chat.sendMessage(player, Color.DARK_AQUA + "| " + Color.GREY + "t: