This commit is contained in:
Brianna O'Keefe 2018-11-05 22:33:10 -05:00
parent 7f5148fd5c
commit a6b5b2b8dd
34 changed files with 2691 additions and 0 deletions

142
.gitignore vendored Normal file
View File

@ -0,0 +1,142 @@
\.idea/compiler\.xml
\.idea/libraries/Arconix\.xml
\.idea/libraries/Maven__br_net_fabiozumbi12_RedProtect_7_3_0\.xml
\.idea/libraries/Maven__com_google_code_gson_gson_2_2_4\.xml
\.idea/libraries/Maven__com_google_guava_guava_17_0\.xml
\.idea/libraries/Maven__com_googlecode_json_simple_json_simple_1_1_1\.xml
\.idea/libraries/Maven__com_massivecraft_factions_LATEST\.xml
\.idea/libraries/Maven__com_massivecraft_factionsuuid_LATEST\.xml
\.idea/libraries/Maven__com_palmergames_bukkit_towny_LATEST\.xml
\.idea/libraries/Maven__com_plotsquared_RELEASE\.xml
\.idea/libraries/Maven__com_sk89q_worldedit_LATEST\.xml
\.idea/libraries/Maven__com_sk89q_worldguard_6_2_2\.xml
\.idea/libraries/Maven__com_songoda_arconix_LATEST\.xml
\.idea/libraries/Maven__com_songoda_epicspawners_LATEST\.xml
\.idea/libraries/Maven__com_wasteofplastic_askyblock_3_0_6_8\.xml
\.idea/libraries/Maven__commons_lang_commons_lang_2_6\.xml
\.idea/libraries/Maven__javax_persistence_persistence_api_1_0\.xml
\.idea/libraries/Maven__junit_junit_4_10\.xml
\.idea/libraries/Maven__me_markeh_factionsframework_1_2_0\.xml
\.idea/libraries/Maven__me_ryanhamshire_GriefPrevention_LATEST\.xml
\.idea/libraries/Maven__net_milkbowl_vault_VaultAPI_1_6\.xml
\.idea/libraries/Maven__org_avaje_ebean_2_8_1\.xml
\.idea/libraries/Maven__org_bukkit_bukkit_1_9_R0_1_SNAPSHOT\.xml
\.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_1\.xml
\.idea/libraries/Maven__org_kingdoms_LATEST\.xml
\.idea/libraries/Maven__org_spigotmc_spigot_1_13_2\.xml
\.idea/libraries/Maven__org_yaml_snakeyaml_1_15\.xml
\.idea/libraries/Maven__us_talabrek_ultimateskyblock_LATEST\.xml
\.idea/libraries/spigot_1_12_2\.xml
\.idea/misc\.xml
\.idea/modules\.xml
\.idea/uiDesigner\.xml
\.idea/workspace\.xml
out/production/UltimateStacker/com/songoda/ultimatestacker/stack/Stack\.class
out/production/UltimateStacker/com/songoda/ultimatestacker/stack/StackManager\.class
out/production/UltimateStacker/com/songoda/ultimatestacker/tasks/StackingTask\.class
out/production/UltimateStacker/com/songoda/ultimatestacker/UltimateStacker\.class
out/production/UltimateStacker/plugin\.yml
target/classes/com/songoda/ultimatestacker/command/AbstractCommand\.class
target/classes/com/songoda/ultimatestacker/command/AbstractCommand\$ReturnType\.class
target/classes/com/songoda/ultimatestacker/command/CommandManager\.class
target/classes/com/songoda/ultimatestacker/command/commands/CommandGive\.class
target/classes/com/songoda/ultimatestacker/command/commands/CommandReload\.class
target/classes/com/songoda/ultimatestacker/command/commands/CommandUltimateStacker\.class
target/classes/com/songoda/ultimatestacker/entity/EntityStack\.class
target/classes/com/songoda/ultimatestacker/entity/EntityStackManager\.class
target/classes/com/songoda/ultimatestacker/events/BlockListeners\.class
target/classes/com/songoda/ultimatestacker/events/DeathListeners\.class
target/classes/com/songoda/ultimatestacker/events/DropListeners\.class
target/classes/com/songoda/ultimatestacker/events/ShearListeners\.class
target/classes/com/songoda/ultimatestacker/events/SpawnerListeners\.class
target/classes/com/songoda/ultimatestacker/handlers/HologramHandler\.class
target/classes/com/songoda/ultimatestacker/Locale\.class
target/classes/com/songoda/ultimatestacker/References\.class
target/classes/com/songoda/ultimatestacker/spawner/SpawnerStack\.class
target/classes/com/songoda/ultimatestacker/spawner/SpawnerStackManager\.class
target/classes/com/songoda/ultimatestacker/storage/Storage\.class
target/classes/com/songoda/ultimatestacker/storage/StorageItem\.class
target/classes/com/songoda/ultimatestacker/storage/StorageRow\.class
target/classes/com/songoda/ultimatestacker/storage/types/StorageMysql\.class
target/classes/com/songoda/ultimatestacker/storage/types/StorageYaml\.class
target/classes/com/songoda/ultimatestacker/tasks/StackingTask\.class
target/classes/com/songoda/ultimatestacker/UltimateStacker\.class
target/classes/com/songoda/ultimatestacker/utils/Methods\.class
target/classes/com/songoda/ultimatestacker/utils/MySQLDatabase\.class
target/classes/com/songoda/ultimatestacker/utils/SettingsManager\.class
target/classes/com/songoda/ultimatestacker/utils/SettingsManager\$settings\.class
target/classes/en_US\.lang
target/classes/plugin\.yml
target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles\.lst
target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles\.lst

9
LICENSE Normal file
View File

@ -0,0 +1,9 @@
Copyright (c) 2018 Brianna OKeefe
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software with minimal restriction, including the rights to use, copy, modify or merge while excluding the rights to publish, (re)distribute, sub-license, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The same distribution rights and limitations above shall similarly apply to any and all source code, and other means that can be used to emulate this work.
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,20 @@
Hey loves,
Thanks for downloading our plugin ^_^ In order to
run it you will need a plugin called arconix. It
basically takes a bunch of methods that we use all
over the place throughout our plugin lineup and
stores it in one place so we don't have to write
new code every time we need to get something simple
done. So make sure to stay up to date with the latest
updates for it.
Link to download:
https://gitlab.com/Songoda/Arconix/-/jobs/artifacts/master/download?job=build
If you need help you can always join our
discord in which is listed at the bottom of all of
our plugin pages.
Enjoy <3
Brianna & The Songoda Team.

51
UltimateStacker.iml Normal file
View File

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="minecraft" name="Minecraft">
<configuration>
<autoDetectTypes>
<platformType>SPIGOT</platformType>
</autoDetectTypes>
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="spigot-1.12.2" level="project" />
<orderEntry type="library" name="Arconix" level="project" />
<orderEntry type="library" name="Maven: org.spigotmc:spigot:1.13.2" level="project" />
<orderEntry type="library" name="Maven: com.songoda:arconix:LATEST" level="project" />
<orderEntry type="library" name="Maven: org:kingdoms:LATEST" level="project" />
<orderEntry type="library" name="Maven: net.milkbowl.vault:VaultAPI:1.6" level="project" />
<orderEntry type="library" name="Maven: org.bukkit:bukkit:1.9-R0.1-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: commons-lang:commons-lang:2.6" level="project" />
<orderEntry type="library" name="Maven: com.googlecode.json-simple:json-simple:1.1.1" level="project" />
<orderEntry type="library" name="Maven: junit:junit:4.10" level="project" />
<orderEntry type="library" name="Maven: org.hamcrest:hamcrest-core:1.1" level="project" />
<orderEntry type="library" name="Maven: com.google.guava:guava:17.0" level="project" />
<orderEntry type="library" name="Maven: com.google.code.gson:gson:2.2.4" level="project" />
<orderEntry type="library" name="Maven: org.avaje:ebean:2.8.1" level="project" />
<orderEntry type="library" name="Maven: javax.persistence:persistence-api:1.0" level="project" />
<orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.15" level="project" />
<orderEntry type="library" name="Maven: me.ryanhamshire:GriefPrevention:LATEST" level="project" />
<orderEntry type="library" name="Maven: com.sk89q:worldedit:LATEST" level="project" />
<orderEntry type="library" name="Maven: com.sk89q:worldguard:6.2.2" level="project" />
<orderEntry type="library" name="Maven: com:plotsquared:RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.palmergames.bukkit:towny:LATEST" level="project" />
<orderEntry type="library" name="Maven: com.wasteofplastic:askyblock:3.0.6.8" level="project" />
<orderEntry type="library" name="Maven: us.talabrek:ultimateskyblock:LATEST" level="project" />
<orderEntry type="library" name="Maven: me.markeh:factionsframework:1.2.0" level="project" />
<orderEntry type="library" name="Maven: br.net.fabiozumbi12:RedProtect:7.3.0" level="project" />
<orderEntry type="library" name="Maven: com.songoda:epicspawners:LATEST" level="project" />
<orderEntry type="library" name="Maven: com.massivecraft:factions:LATEST" level="project" />
<orderEntry type="library" name="Maven: com.massivecraft:factionsuuid:LATEST" level="project" />
</component>
</module>

138
pom.xml Normal file
View File

@ -0,0 +1,138 @@
<project xmlns="http://maven.apache.org/POM/4.0.0">
<groupId>com.songoda</groupId>
<artifactId>UltimateStacker</artifactId>
<modelVersion>4.0.0</modelVersion>
<version>1.0.2</version>
<build>
<defaultGoal>clean package</defaultGoal>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>EpicAnchors-API/src/main/java</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<version>3.6.1</version>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<sourceDirectory>src/main/java</sourceDirectory>
</build>
<repositories>
<repository>
<id>private</id>
<url>http://repo.songoda.com/repository/private</url>
</repository>
<repository>
<id>vault</id>
<url>http://nexus.hc.to/content/repositories/pub_releases</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot</artifactId>
<version>1.13.2</version>
</dependency>
<dependency>
<groupId>com.songoda</groupId>
<artifactId>arconix</artifactId>
<version>LATEST</version>
</dependency>
<dependency>
<groupId>org</groupId>
<artifactId>kingdoms</artifactId>
<version>LATEST</version>
</dependency>
<dependency>
<groupId>net.milkbowl.vault</groupId>
<artifactId>VaultAPI</artifactId>
<version>LATEST</version>
</dependency>
<dependency>
<groupId>me.ryanhamshire</groupId>
<artifactId>GriefPrevention</artifactId>
<version>LATEST</version>
</dependency>
<dependency>
<groupId>com.sk89q</groupId>
<artifactId>worldedit</artifactId>
<version>LATEST</version>
</dependency>
<dependency>
<groupId>com.sk89q</groupId>
<artifactId>worldguard</artifactId>
<version>6.2.2</version>
</dependency>
<dependency>
<groupId>com</groupId>
<artifactId>plotsquared</artifactId>
<version>RELEASE</version>
</dependency>
<dependency>
<groupId>com.palmergames.bukkit</groupId>
<artifactId>towny</artifactId>
<version>LATEST</version>
</dependency>
<dependency>
<groupId>com.wasteofplastic</groupId>
<artifactId>askyblock</artifactId>
<version>3.0.6.8</version>
</dependency>
<dependency>
<groupId>us.talabrek</groupId>
<artifactId>ultimateskyblock</artifactId>
<version>LATEST</version>
</dependency>
<dependency>
<groupId>me.markeh</groupId>
<artifactId>factionsframework</artifactId>
<version>1.2.0</version>
</dependency>
<dependency>
<groupId>br.net.fabiozumbi12</groupId>
<artifactId>RedProtect</artifactId>
<version>7.3.0</version>
</dependency>
<dependency>
<groupId>com.songoda</groupId>
<artifactId>epicspawners</artifactId>
<version>LATEST</version>
</dependency>
<dependency>
<groupId>com.massivecraft</groupId>
<artifactId>factions</artifactId>
<version>LATEST</version>
</dependency>
<dependency>
<groupId>com.massivecraft</groupId>
<artifactId>factionsuuid</artifactId>
<version>LATEST</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,375 @@
package com.songoda.ultimatestacker;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import org.bukkit.ChatColor;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
* Assists in the creation of multiple localizations and languages,
* as well as the generation of default .lang files
*
* @author Parker Hawke - 2008Choco
*/
public class Locale {
private static final List<Locale> LOCALES = Lists.newArrayList();
private static final Pattern NODE_PATTERN = Pattern.compile("(\\w+(?:\\.{1}\\w+)*)\\s*=\\s*\"(.*)\"");
private static final String FILE_EXTENSION = ".lang";
private static JavaPlugin plugin;
private static File localeFolder;
private static String defaultLocale;
private final Map<String, String> nodes = new HashMap<>();
private final File file;
private final String name, region;
private Locale(String name, String region) {
if (plugin == null)
throw new IllegalStateException("Cannot generate locales without first initializing the class (Locale#init(JavaPlugin))");
this.name = name.toLowerCase();
this.region = region.toUpperCase();
String fileName = name + "_" + region + FILE_EXTENSION;
this.file = new File(localeFolder, fileName);
if (this.reloadMessages()) return;
plugin.getLogger().info("Loaded locale " + fileName);
}
/**
* Initialize the locale class to generate information and search for localizations.
* This must be called before any other methods in the Locale class can be invoked.
* Note that this will also call {@link #searchForLocales()}, so there is no need to
* invoke it for yourself after the initialization
*
* @param plugin the plugin instance
*/
public static void init(JavaPlugin plugin) {
Locale.plugin = plugin;
if (localeFolder == null) {
localeFolder = new File(plugin.getDataFolder(), "locales/");
}
localeFolder.mkdirs();
Locale.searchForLocales();
}
/**
* Find all .lang file locales under the "locales" folder
*/
public static void searchForLocales() {
if (!localeFolder.exists()) localeFolder.mkdirs();
for (File file : localeFolder.listFiles()) {
String name = file.getName();
if (!name.endsWith(".lang")) continue;
String fileName = name.substring(0, name.lastIndexOf('.'));
String[] localeValues = fileName.split("_");
if (localeValues.length != 2) continue;
if (localeExists(localeValues[0] + "_" + localeValues[1])) continue;
LOCALES.add(new Locale(localeValues[0], localeValues[1]));
plugin.getLogger().info("Found and loaded locale \"" + fileName + "\"");
}
}
/**
* Get a locale by its entire proper name (i.e. "en_US")
*
* @param name the full name of the locale
* @return locale of the specified name
*/
public static Locale getLocale(String name) {
for (Locale locale : LOCALES)
if (locale.getLanguageTag().equalsIgnoreCase(name)) return locale;
return null;
}
/**
* Get a locale from the cache by its name (i.e. "en" from "en_US")
*
* @param name the name of the language
* @return locale of the specified language. Null if not cached
*/
public static Locale getLocaleByName(String name) {
for (Locale locale : LOCALES)
if (locale.getName().equalsIgnoreCase(name)) return locale;
return null;
}
/**
* Get a locale from the cache by its region (i.e. "US" from "en_US")
*
* @param region the name of the region
* @return locale of the specified region. Null if not cached
*/
public static Locale getLocaleByRegion(String region) {
for (Locale locale : LOCALES)
if (locale.getRegion().equalsIgnoreCase(region)) return locale;
return null;
}
/**
* Check whether a locale exists and is registered or not
*
* @param name the whole language tag (i.e. "en_US")
* @return true if it exists
*/
public static boolean localeExists(String name) {
for (Locale locale : LOCALES)
if (locale.getLanguageTag().equals(name)) return true;
return false;
}
/**
* Get an immutable list of all currently loaded locales
*
* @return list of all locales
*/
public static List<Locale> getLocales() {
return ImmutableList.copyOf(LOCALES);
}
/**
* Save a default locale file from the project source directory, to the locale folder
*
* @param in file to save
* @param fileName the name of the file to save
* @return true if the operation was successful, false otherwise
*/
public static boolean saveDefaultLocale(InputStream in, String fileName) {
if (!localeFolder.exists()) localeFolder.mkdirs();
if (!fileName.endsWith(FILE_EXTENSION))
fileName = (fileName.lastIndexOf(".") == -1 ? fileName : fileName.substring(0, fileName.lastIndexOf('.'))) + FILE_EXTENSION;
File destinationFile = new File(localeFolder, fileName);
if (destinationFile.exists()) {
return compareFiles(plugin.getResource(fileName), destinationFile);
}
try (OutputStream outputStream = new FileOutputStream(destinationFile)) {
copy(in == null ? plugin.getResource(fileName) : in, outputStream);
fileName = fileName.substring(0, fileName.lastIndexOf('.'));
String[] localeValues = fileName.split("_");
if (localeValues.length != 2) return false;
LOCALES.add(new Locale(localeValues[0], localeValues[1]));
if (defaultLocale == null) defaultLocale = fileName;
return true;
} catch (IOException e) {
return false;
}
}
/**
* Save a default locale file from the project source directory, to the locale folder
*
* @param fileName the name of the file to save
* @return true if the operation was successful, false otherwise
*/
public static boolean saveDefaultLocale(String fileName) {
return saveDefaultLocale(null, fileName);
}
/**
* Clear all current locale data
*/
public static void clearLocaleData() {
for (Locale locale : LOCALES)
locale.nodes.clear();
LOCALES.clear();
}
// Write new changes to existing files, if any at all
private static boolean compareFiles(InputStream defaultFile, File existingFile) {
// Look for default
if (defaultFile == null) {
defaultFile = plugin.getResource(defaultLocale != null ? defaultLocale : "en_US");
if (defaultFile == null) return false; // No default at all
}
boolean changed = false;
List<String> defaultLines, existingLines;
try (BufferedReader defaultReader = new BufferedReader(new InputStreamReader(defaultFile));
BufferedReader existingReader = new BufferedReader(new FileReader(existingFile));
BufferedWriter writer = new BufferedWriter(new FileWriter(existingFile, true))) {
defaultLines = defaultReader.lines().collect(Collectors.toList());
existingLines = existingReader.lines().map(s -> s.split("\\s*=")[0]).collect(Collectors.toList());
for (String defaultValue : defaultLines) {
if (defaultValue.isEmpty() || defaultValue.startsWith("#")) continue;
String key = defaultValue.split("\\s*=")[0];
if (!existingLines.contains(key)) {
if (!changed) {
writer.newLine();
writer.newLine();
writer.write("# New messages for " + plugin.getName() + " v" + plugin.getDescription().getVersion());
}
writer.newLine();
writer.write(defaultValue);
changed = true;
}
}
} catch (IOException e) {
return false;
}
return changed;
}
private static void copy(InputStream input, OutputStream output) {
int n;
byte[] buffer = new byte[1024 * 4];
try {
while ((n = input.read(buffer)) != -1) {
output.write(buffer, 0, n);
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Get the name of the language that this locale is based on.
* (i.e. "en" for English, or "fr" for French)
*
* @return the name of the language
*/
public String getName() {
return name;
}
/**
* Get the name of the region that this locale is from.
* (i.e. "US" for United States or "CA" for Canada)
*
* @return the name of the region
*/
public String getRegion() {
return region;
}
/**
* Return the entire locale tag (i.e. "en_US")
*
* @return the language tag
*/
public String getLanguageTag() {
return name + "_" + region;
}
/**
* Get the file that represents this locale
*
* @return the locale file (.lang)
*/
public File getFile() {
return file;
}
/**
* Get a message set for a specific node
*
* @param node the node to get
* @return the message for the specified node
*/
public String getMessage(String node) {
return ChatColor.translateAlternateColorCodes('&', this.getMessageOrDefault(node, node));
}
/**
* Get a message set for a specific node and replace its params with a supplied arguments.
*
* @param node the node to get
* @param args the replacement arguments
* @return the message for the specified node
*/
public String getMessage(String node, Object... args) {
String message = getMessage(node);
for (Object arg : args) {
message = message.replaceFirst("\\%.*?\\%", arg.toString());
}
return message;
}
/**
* Get a message set for a specific node
*
* @param node the node to get
* @param defaultValue the default value given that a value for the node was not found
* @return the message for the specified node. Default if none found
*/
public String getMessageOrDefault(String node, String defaultValue) {
return this.nodes.getOrDefault(node, defaultValue);
}
/**
* Get the key-value map of nodes to messages
*
* @return node-message map
*/
public Map<String, String> getMessageNodeMap() {
return ImmutableMap.copyOf(nodes);
}
/**
* Clear the previous message cache and load new messages directly from file
*
* @return reload messages from file
*/
public boolean reloadMessages() {
if (!this.file.exists()) {
plugin.getLogger().warning("Could not find file for locale " + this.name);
return false;
}
this.nodes.clear(); // Clear previous data (if any)
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
String line;
for (int lineNumber = 0; (line = reader.readLine()) != null; lineNumber++) {
if (line.isEmpty() || line.startsWith("#") /* Comment */) continue;
Matcher matcher = NODE_PATTERN.matcher(line);
if (!matcher.find()) {
System.err.println("Invalid locale syntax at (line=" + lineNumber + ")");
continue;
}
nodes.put(matcher.group(1), matcher.group(2));
}
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
}

View File

@ -0,0 +1,14 @@
package com.songoda.ultimatestacker;
public class References {
private String prefix;
public References() {
prefix = UltimateStacker.getInstance().getLocale().getMessage("general.nametag.prefix") + " ";
}
public String getPrefix() {
return this.prefix;
}
}

View File

@ -0,0 +1,307 @@
package com.songoda.ultimatestacker;
import com.songoda.arconix.api.methods.formatting.TextComponent;
import com.songoda.arconix.api.methods.serialize.Serialize;
import com.songoda.arconix.api.utils.ConfigWrapper;
import com.songoda.ultimatestacker.command.CommandManager;
import com.songoda.ultimatestacker.entity.EntityStack;
import com.songoda.ultimatestacker.events.*;
import com.songoda.ultimatestacker.handlers.HologramHandler;
import com.songoda.ultimatestacker.spawner.SpawnerStack;
import com.songoda.ultimatestacker.spawner.SpawnerStackManager;
import com.songoda.ultimatestacker.storage.Storage;
import com.songoda.ultimatestacker.storage.StorageItem;
import com.songoda.ultimatestacker.storage.StorageRow;
import com.songoda.ultimatestacker.storage.types.StorageMysql;
import com.songoda.ultimatestacker.storage.types.StorageYaml;
import com.songoda.ultimatestacker.entity.EntityStackManager;
import com.songoda.ultimatestacker.tasks.StackingTask;
import com.songoda.ultimatestacker.utils.SettingsManager;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.plugin.java.JavaPlugin;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.UUID;
public class UltimateStacker extends JavaPlugin {
private static UltimateStacker INSTANCE;
private References references;
private ConfigWrapper mobFile = new ConfigWrapper(this, "", "mobs.yml");
private ConfigWrapper itemFile = new ConfigWrapper(this, "", "items.yml");
private ConfigWrapper spawnerFile = new ConfigWrapper(this, "", "spawners.yml");
private Locale locale;
private SettingsManager settingsManager;
private EntityStackManager entityStackManager;
private SpawnerStackManager spawnerStackManager;
private CommandManager commandManager;
private StackingTask stackingTask;
private HologramHandler hologramHandler;
private Storage storage;
public void onDisable() {
this.saveToFile();
this.storage.closeConnection();
ConsoleCommandSender console = Bukkit.getConsoleSender();
console.sendMessage(TextComponent.formatText("&a============================="));
console.sendMessage(TextComponent.formatText("&7UltimateStacker " + this.getDescription().getVersion() + " by &5Brianna <3!"));
console.sendMessage(TextComponent.formatText("&7Action: &cDisabling&7..."));
console.sendMessage(TextComponent.formatText("&a============================="));
}
public void onEnable() {
INSTANCE = this;
ConsoleCommandSender console = Bukkit.getConsoleSender();
console.sendMessage(TextComponent.formatText("&a============================="));
console.sendMessage(TextComponent.formatText("&7UltimateStacker " + this.getDescription().getVersion() + " by &5Brianna <3&7!"));
console.sendMessage(TextComponent.formatText("&7Action: &aEnabling&7..."));
this.settingsManager = new SettingsManager(this);
this.commandManager = new CommandManager(this);
settingsManager.updateSettings();
for (EntityType value : EntityType.values()) {
if (value.isSpawnable() && value.isAlive() && !value.toString().toLowerCase().contains("armor")) {
mobFile.getConfig().addDefault("Mobs." + value.name() + ".Enabled", true);
mobFile.getConfig().addDefault("Mobs." + value.name() + ".Max Stack Size", -1);
}
}
mobFile.getConfig().options().copyDefaults(true);
mobFile.saveConfig();
for (Material value : Material.values()) {
if (!value.isBlock()) {
itemFile.getConfig().addDefault("Items." + value.name() + ".Has Hologram", true);
itemFile.getConfig().addDefault("Items." + value.name() + ".Max Stack Size", -1);
itemFile.getConfig().addDefault("Items." + value.name() + ".Display Name", TextComponent.formatText(value.name().toLowerCase().replace("_", " "), true));
}
}
itemFile.getConfig().options().copyDefaults(true);
itemFile.saveConfig();
for (EntityType value : EntityType.values()) {
if (value.isSpawnable() && value.isAlive() && !value.toString().toLowerCase().contains("armor")) {
spawnerFile.getConfig().addDefault("Spawners." + value.name() + ".Max Stack Size", -1);
spawnerFile.getConfig().addDefault("Spawners." + value.name() + ".Display Name", TextComponent.formatText(value.name().toLowerCase().replace("_", " "), true));
}
}
spawnerFile.getConfig().options().copyDefaults(true);
spawnerFile.saveConfig();
getConfig().options().copyDefaults(true);
saveConfig();
String langMode = getConfig().getString("System.Language Mode");
Locale.init(this);
Locale.saveDefaultLocale("en_US");
this.locale = Locale.getLocale(getConfig().getString("System.Language Mode", langMode));
if (getConfig().getBoolean("System.Download Needed Data Files")) {
this.update();
}
this.references = new References();
this.spawnerStackManager = new SpawnerStackManager();
this.entityStackManager = new EntityStackManager();
this.stackingTask = new StackingTask(this);
this.stackingTask.startTask();
checkStorage();
Bukkit.getScheduler().runTaskLater(this, () -> {
if (storage.containsGroup("entities")) {
for (StorageRow row : storage.getRowsByGroup("entities")) {
Entity entity = getEntityByUniqueId(UUID.fromString(row.getKey()));
if (entity == null) continue;
EntityStack stack = new EntityStack(
entity,
row.get("amount").asInt());
this.entityStackManager.addStack(stack);
}
}
if (storage.containsGroup("spawners")) {
for (StorageRow row : storage.getRowsByGroup("spawners")) {
try {
Location location = Serialize.getInstance().unserializeLocation(row.getKey());
if (location.getWorld() == null || !location.getBlock().getType().name().contains("SPAWNER")) {
if (location.getWorld() != null && !location.getBlock().getType().name().contains("SPAWNER")) {
this.hologramHandler.despawn(location.getBlock());
}
}
SpawnerStack stack = new SpawnerStack(
location,
row.get("amount").asInt());
this.spawnerStackManager.addSpawner(stack);
} catch (Exception e) {
console.sendMessage("Failed to load spawner.");
e.printStackTrace();
}
}
}
for (SpawnerStack stack : spawnerStackManager.getStacks()) {
storage.prepareSaveItem("spawners", new StorageItem("location", Serialize.getInstance().serializeLocation(stack.getLocation())),
new StorageItem("amount", stack.getAmount()));
}
// Save data initially so that if the person reloads again fast they don't lose all their data.
this.saveToFile();
}, 10);
this.hologramHandler = new HologramHandler(this);
Bukkit.getPluginManager().registerEvents(new SpawnerListeners(this), this);
Bukkit.getPluginManager().registerEvents(new BlockListeners(this), this);
Bukkit.getPluginManager().registerEvents(new DeathListeners(this), this);
Bukkit.getPluginManager().registerEvents(new ShearListeners(this), this);
Bukkit.getPluginManager().registerEvents(new DropListeners(this), this);
Bukkit.getScheduler().runTaskTimerAsynchronously(this, this::saveToFile, 6000, 6000);
console.sendMessage(TextComponent.formatText("&a============================="));
}
private void update() {
try {
URL url = new URL("http://update.songoda.com/index.php?plugin=" + getDescription().getName() + "&version=" + getDescription().getVersion());
URLConnection urlConnection = url.openConnection();
InputStream is = urlConnection.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
int numCharsRead;
char[] charArray = new char[1024];
StringBuffer sb = new StringBuffer();
while ((numCharsRead = isr.read(charArray)) > 0) {
sb.append(charArray, 0, numCharsRead);
}
String jsonString = sb.toString();
JSONObject json = (JSONObject) new JSONParser().parse(jsonString);
JSONArray files = (JSONArray) json.get("neededFiles");
for (Object o : files) {
JSONObject file = (JSONObject) o;
switch ((String) file.get("type")) {
case "locale":
InputStream in = new URL((String) file.get("link")).openStream();
Locale.saveDefaultLocale(in, (String) file.get("name"));
break;
}
}
} catch (Exception e) {
System.out.println("Failed to update.");
//e.printStackTrace();
}
}
private void checkStorage() {
if (getConfig().getBoolean("Database.Activate Mysql Support")) {
this.storage = new StorageMysql(this);
} else {
this.storage = new StorageYaml(this);
}
}
private void saveToFile() {
this.storage.closeConnection();
checkStorage();
for (EntityStack stack : entityStackManager.getStacks().values()) {
storage.prepareSaveItem("entities", new StorageItem("uuid", stack.getEntity().getUniqueId().toString()),
new StorageItem("amount", stack.getAmount()));
}
for (SpawnerStack stack : spawnerStackManager.getStacks()) {
storage.prepareSaveItem("spawners", new StorageItem("location", Serialize.getInstance().serializeLocation(stack.getLocation())),
new StorageItem("amount", stack.getAmount()));
}
storage.doSave();
}
public void reload() {
String langMode = getConfig().getString("System.Language Mode");
this.locale = Locale.getLocale(getConfig().getString("System.Language Mode", langMode));
this.locale.reloadMessages();
this.mobFile = new ConfigWrapper(this, "", "mobs.yml");
this.itemFile = new ConfigWrapper(this, "", "items.yml");
this.spawnerFile = new ConfigWrapper(this, "", "spawners.yml");
this.references = new References();
this.reloadConfig();
}
public Entity getEntityByUniqueId(UUID uniqueId) {
for (World world : Bukkit.getWorlds()) {
for (Entity entity : world.getLivingEntities()) {
if (entity.getUniqueId().equals(uniqueId))
return entity;
}
}
return null;
}
public HologramHandler getHologramHandler() {
return hologramHandler;
}
public References getReferences() {
return references;
}
public Locale getLocale() {
return locale;
}
public CommandManager getCommandManager() {
return commandManager;
}
public EntityStackManager getEntityStackManager() {
return entityStackManager;
}
public SpawnerStackManager getSpawnerStackManager() {
return spawnerStackManager;
}
public StackingTask getStackingTask() {
return stackingTask;
}
public ConfigWrapper getMobFile() {
return mobFile;
}
public ConfigWrapper getItemFile() {
return itemFile;
}
public static UltimateStacker getInstance() {
return INSTANCE;
}
}

View File

@ -0,0 +1,39 @@
package com.songoda.ultimatestacker.command;
import com.songoda.ultimatestacker.UltimateStacker;
import org.bukkit.command.CommandSender;
public abstract class AbstractCommand {
private final AbstractCommand parent;
private final String command;
private final boolean noConsole;
protected AbstractCommand(String command, AbstractCommand parent, boolean noConsole) {
this.command = command;
this.parent = parent;
this.noConsole = noConsole;
}
public AbstractCommand getParent() {
return parent;
}
public String getCommand() {
return command;
}
public boolean isNoConsole() {
return noConsole;
}
protected abstract ReturnType runCommand(UltimateStacker instance, CommandSender sender, String... args);
public abstract String getPermissionNode();
public abstract String getSyntax();
public abstract String getDescription();
public enum ReturnType {SUCCESS, FAILURE, SYNTAX_ERROR}
}

View File

@ -0,0 +1,77 @@
package com.songoda.ultimatestacker.command;
import com.songoda.arconix.api.methods.formatting.TextComponent;
import com.songoda.ultimatestacker.UltimateStacker;
import com.songoda.ultimatestacker.command.AbstractCommand;
import com.songoda.ultimatestacker.command.commands.*;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class CommandManager implements CommandExecutor {
private UltimateStacker instance;
private static final List<AbstractCommand> commands = new ArrayList<>();
public CommandManager(UltimateStacker instance) {
this.instance = instance;
instance.getCommand("UltimateStacker").setExecutor(this);
AbstractCommand commandUltimateStacker = addCommand(new CommandUltimateStacker());
addCommand(new CommandReload(commandUltimateStacker));
addCommand(new CommandGive(commandUltimateStacker));
}
private AbstractCommand addCommand(AbstractCommand abstractCommand) {
commands.add(abstractCommand);
return abstractCommand;
}
@Override
public boolean onCommand(CommandSender commandSender, Command command, String s, String[] strings) {
for (AbstractCommand abstractCommand : commands) {
if (abstractCommand.getCommand().equalsIgnoreCase(command.getName())) {
if (strings.length == 0) {
processRequirements(abstractCommand, commandSender, strings);
return true;
}
} else if (strings.length != 0 && abstractCommand.getParent() != null && abstractCommand.getParent().getCommand().equalsIgnoreCase(command.getName())) {
String cmd = strings[0];
if (cmd.equalsIgnoreCase(abstractCommand.getCommand())) {
processRequirements(abstractCommand, commandSender, strings);
return true;
}
}
}
commandSender.sendMessage(instance.getReferences().getPrefix() + TextComponent.formatText("&7The command you entered does not exist or is spelt incorrectly."));
return true;
}
private void processRequirements(AbstractCommand command, CommandSender sender, String[] strings) {
if (!(sender instanceof Player) && command.isNoConsole()) {
sender.sendMessage("You must be a player to use this command.");
return;
}
if (command.getPermissionNode() == null || sender.hasPermission(command.getPermissionNode())) {
AbstractCommand.ReturnType returnType = command.runCommand(instance, sender, strings);
if (returnType == AbstractCommand.ReturnType.SYNTAX_ERROR) {
sender.sendMessage(instance.getReferences().getPrefix() + TextComponent.formatText("&cInvalid Syntax!"));
sender.sendMessage(instance.getReferences().getPrefix() + TextComponent.formatText("&7The valid syntax is: &6" + command.getSyntax() + "&7."));
}
return;
}
sender.sendMessage(instance.getReferences().getPrefix() + instance.getLocale().getMessage("event.general.nopermission"));
}
public List<AbstractCommand> getCommands() {
return Collections.unmodifiableList(commands);
}
}

View File

@ -0,0 +1,76 @@
package com.songoda.ultimatestacker.command.commands;
import com.songoda.arconix.api.methods.formatting.TextComponent;
import com.songoda.ultimatestacker.UltimateStacker;
import com.songoda.ultimatestacker.command.AbstractCommand;
import com.songoda.ultimatestacker.utils.Methods;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
public class CommandGive extends AbstractCommand {
public CommandGive(AbstractCommand abstractCommand) {
super("givespawner", abstractCommand, false);
}
@Override
protected ReturnType runCommand(UltimateStacker instance, CommandSender sender, String... args) {
if (args.length != 4) return ReturnType.SYNTAX_ERROR;
if (Bukkit.getPlayer(args[1]) == null && !args[1].trim().toLowerCase().equals("all")) {
sender.sendMessage("Not a player...");
return ReturnType.SYNTAX_ERROR;
}
EntityType type = null;
for (EntityType types : EntityType.values()) {
String input = args[2].toUpperCase().replace("_", "").replace(" ", "");
String compare = types.name().toUpperCase().replace("_", "").replace(" ", "");
if (input.equals(compare))
type = types;
}
if (type == null) {
sender.sendMessage(instance.getReferences().getPrefix() + TextComponent.formatText(instance.getReferences().getPrefix() + "&7The entity Type &6" + args[2] + " &7does not exist. Try one of these:"));
StringBuilder list = new StringBuilder();
for (EntityType types : EntityType.values()) {
list.append(types.name().toUpperCase().replace(" ", "_")).append("&7, &6");
}
sender.sendMessage(TextComponent.formatText("&6" + list));
} else {
int amt = Integer.parseInt(args[3]);
ItemStack itemStack = Methods.getSpawnerItem(type, amt);
if (!args[1].trim().toLowerCase().equals("all")) {
Player player = Bukkit.getOfflinePlayer(args[1]).getPlayer();
player.getInventory().addItem(itemStack);
player.sendMessage(TextComponent.formatText(instance.getLocale().getMessage("command.give.success", Methods.compileSpawnerName(type, amt))));
} else {
for (Player player : Bukkit.getOnlinePlayers()) {
player.getInventory().addItem(itemStack);
player.sendMessage(TextComponent.formatText(instance.getLocale().getMessage("command.give.success", Methods.compileSpawnerName(type, amt))));
}
}
}
return ReturnType.SUCCESS;
}
@Override
public String getPermissionNode() {
return "ultimatestacker.admin";
}
@Override
public String getSyntax() {
return "/us givespawner <player/all> <type> <level>";
}
@Override
public String getDescription() {
return "Gives an operator the ability to spawn a spawner of his or her choice.";
}
}

View File

@ -0,0 +1,35 @@
package com.songoda.ultimatestacker.command.commands;
import com.songoda.arconix.api.methods.formatting.TextComponent;
import com.songoda.ultimatestacker.UltimateStacker;
import com.songoda.ultimatestacker.command.AbstractCommand;
import org.bukkit.command.CommandSender;
public class CommandReload extends AbstractCommand {
public CommandReload(AbstractCommand parent) {
super("reload", parent, false);
}
@Override
protected ReturnType runCommand(UltimateStacker instance, CommandSender sender, String... args) {
instance.reload();
sender.sendMessage(TextComponent.formatText(instance.getReferences().getPrefix() + "&7Configuration and Language files reloaded."));
return ReturnType.SUCCESS;
}
@Override
public String getPermissionNode() {
return "ultimatestacker.admin";
}
@Override
public String getSyntax() {
return "/us reload";
}
@Override
public String getDescription() {
return "Reload the Configuration and Language files.";
}
}

View File

@ -0,0 +1,43 @@
package com.songoda.ultimatestacker.command.commands;
import com.songoda.arconix.api.methods.formatting.TextComponent;
import com.songoda.ultimatestacker.UltimateStacker;
import com.songoda.ultimatestacker.command.AbstractCommand;
import org.bukkit.command.CommandSender;
public class CommandUltimateStacker extends AbstractCommand {
public CommandUltimateStacker() {
super("UltimateStacker", null, false);
}
@Override
protected ReturnType runCommand(UltimateStacker instance, CommandSender sender, String... args) {
sender.sendMessage("");
sender.sendMessage(TextComponent.formatText(instance.getReferences().getPrefix() + "&7Version " + instance.getDescription().getVersion() + " Created with <3 by &5&l&oBrianna"));
for (AbstractCommand command : instance.getCommandManager().getCommands()) {
if (command.getPermissionNode() == null || sender.hasPermission(command.getPermissionNode())) {
sender.sendMessage(TextComponent.formatText("&8 - &a" + command.getSyntax() + "&7 - " + command.getDescription()));
}
}
sender.sendMessage("");
return ReturnType.SUCCESS;
}
@Override
public String getPermissionNode() {
return null;
}
@Override
public String getSyntax() {
return "/UltimateStacker";
}
@Override
public String getDescription() {
return "Displays this page.";
}
}

View File

@ -0,0 +1,51 @@
package com.songoda.ultimatestacker.entity;
import com.songoda.arconix.api.methods.formatting.TextComponent;
import com.songoda.ultimatestacker.utils.Methods;
import org.bukkit.entity.Entity;
public class EntityStack {
private Entity entity;
private int amount;
public EntityStack(Entity entity, int amount) {
this.entity = entity;
this.amount = amount;
}
public void updateStack() {
entity.setCustomNameVisible(true);
entity.setCustomName(Methods.compileEntityName(entity, amount));
}
public Entity getEntity() {
return entity;
}
protected void setEntity(Entity entity) {
this.entity = entity;
}
public void addAmount(int amount) {
this.amount = this.amount + amount;
updateStack();
}
public int getAmount() {
return amount;
}
public void setAmount(int amount) {
this.amount = amount;
updateStack();
}
@Override
public String toString() {
return "EntityStack:{"
+ "Entity:\"" + entity.getUniqueId().toString() + "\","
+ "Amount:\"" + amount + "\","
+ "}";
}
}

View File

@ -0,0 +1,50 @@
package com.songoda.ultimatestacker.entity;
import org.bukkit.entity.Entity;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class EntityStackManager {
// These are all stacked mobs loaded into memory.
private static final Map<UUID, EntityStack> stacks = new HashMap<>();
public EntityStack addStack (EntityStack stack) {
stacks.put(stack.getEntity().getUniqueId(), stack);
return stack;
}
public EntityStack addStack(Entity entity, int amount) {
return stacks.put(entity.getUniqueId(), new EntityStack(entity, amount));
}
public EntityStack getStack(Entity entity) {
return stacks.get(entity.getUniqueId());
}
public boolean isStacked(Entity entity) {
return stacks.containsKey(entity.getUniqueId());
}
public EntityStack removeStack(Entity entity) {
return stacks.remove(entity.getUniqueId());
}
public Map<UUID, EntityStack> getStacks() {
return Collections.unmodifiableMap(stacks);
}
public EntityStack updateStack(Entity oldEntity, Entity newEntity) {
EntityStack stack = stacks.remove(oldEntity.getUniqueId());
if (stack == null) return null;
stack.setEntity(newEntity);
stacks.put(newEntity.getUniqueId(), stack);
return stack;
}
}

View File

@ -0,0 +1,145 @@
package com.songoda.ultimatestacker.events;
import com.songoda.ultimatestacker.UltimateStacker;
import com.songoda.ultimatestacker.spawner.SpawnerStack;
import com.songoda.ultimatestacker.utils.Methods;
import org.apache.commons.lang.math.NumberUtils;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.CreatureSpawner;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BlockStateMeta;
public class BlockListeners implements Listener {
private final UltimateStacker instance;
public BlockListeners(UltimateStacker instance) {
this.instance = instance;
}
@EventHandler
public void onSpawnerInteract(PlayerInteractEvent event) {
Block block = event.getClickedBlock();
Player player = event.getPlayer();
ItemStack item = event.getPlayer().getInventory().getItemInMainHand();
if (block == null || item == null || block.getType() != Material.SPAWNER || item.getType() != Material.SPAWNER || event.getAction() == Action.LEFT_CLICK_BLOCK) return;
if (!instance.getConfig().getBoolean("Main.Stack Spawners")) return;
BlockStateMeta bsm = (BlockStateMeta) item.getItemMeta();
CreatureSpawner cs = (CreatureSpawner) bsm.getBlockState();
EntityType itemType = cs.getSpawnedType();
int itemAmount = getSpawnerAmount(item);
int specific = instance.getItemFile().getConfig().getInt("Spawners." + itemType.name() + ".Max Stack Size");
int maxStackSize = specific == -1 ? instance.getConfig().getInt("Spawners.Max Stack Size") : specific;
cs = (CreatureSpawner)block.getState();
EntityType blockType = cs.getSpawnedType();
event.setCancelled(true);
if (itemType == blockType) {
SpawnerStack stack = instance.getSpawnerStackManager().getSpawner(block);
if (player.isSneaking()) return;
if (event.getAction() == Action.RIGHT_CLICK_BLOCK) {
if (stack.getAmount() == maxStackSize) return;
if ((stack.getAmount() + itemAmount) > maxStackSize) {
ItemStack newItem = Methods.getSpawnerItem(blockType, (stack.getAmount() + itemAmount) - maxStackSize);
if (player.getInventory().firstEmpty() == -1)
block.getLocation().getWorld().dropItemNaturally(block.getLocation().add(.5, 0, .5), newItem);
else
player.getInventory().addItem(newItem);
itemAmount = maxStackSize - stack.getAmount();
}
stack.setAmount(stack.getAmount() + itemAmount);
instance.getHologramHandler().updateHologram(stack);
}
}
Methods.takeItem(player, itemAmount);
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(instance, () -> instance.getHologramHandler().processChange(block), 10L);
}
@EventHandler
public void onSpawnerPlace(BlockPlaceEvent event) {
Block block = event.getBlock();
if (block == null || block.getType() != Material.SPAWNER) return;
if (!instance.getConfig().getBoolean("Main.Stack Spawners")) return;
SpawnerStack stack = instance.getSpawnerStackManager().addSpawner(new SpawnerStack(block.getLocation(), getSpawnerAmount(event.getItemInHand())));
instance.getHologramHandler().updateHologram(stack);
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(instance, () -> instance.getHologramHandler().processChange(block), 1L);
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onBlockBreak(BlockBreakEvent event) {
Block block = event.getBlock();
if (block.getType() != Material.SPAWNER) return;
if (!instance.getConfig().getBoolean("Main.Stack Spawners")) return;
CreatureSpawner cs = (CreatureSpawner)block.getState();
EntityType blockType = cs.getSpawnedType();
Player player = event.getPlayer();
ItemStack item = player.getInventory().getItemInMainHand();
SpawnerStack stack = instance.getSpawnerStackManager().getSpawner(block);
event.setCancelled(true);
int amt = 1;
if (player.isSneaking()) {
event.setCancelled(false);
amt = stack.getAmount();
instance.getHologramHandler().despawn(block);
instance.getSpawnerStackManager().removeSpawner(block.getLocation());
} else {
if (stack.getAmount() <= 1) {
event.setCancelled(false);
instance.getHologramHandler().despawn(block);
instance.getSpawnerStackManager().removeSpawner(block.getLocation());
} else {
stack.setAmount(stack.getAmount() - 1);
instance.getHologramHandler().updateHologram(stack);
}
}
if (item != null && (item.getEnchantments().containsKey(Enchantment.SILK_TOUCH) && player.hasPermission("ultimatestacker.spawner.silktouch") || player.hasPermission("ultimatestacker.spawner.nosilkdrop")))
block.getWorld().dropItemNaturally(block.getLocation(), Methods.getSpawnerItem(blockType, amt));
}
public int getSpawnerAmount(ItemStack item) {
if (!item.hasItemMeta() || !item.getItemMeta().hasDisplayName()) return 1;
if (item.getItemMeta().getDisplayName().contains(":")) {
return NumberUtils.toInt(item.getItemMeta().getDisplayName().replace("\u00A7", "").split(":")[0], 0);
}
return 1;
}
}

View File

@ -0,0 +1,66 @@
package com.songoda.ultimatestacker.events;
import com.songoda.ultimatestacker.entity.EntityStack;
import com.songoda.ultimatestacker.UltimateStacker;
import com.songoda.ultimatestacker.entity.EntityStackManager;
import org.bukkit.entity.*;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDeathEvent;
public class DeathListeners implements Listener {
private final UltimateStacker instance;
public DeathListeners(UltimateStacker instance) {
this.instance = instance;
}
@EventHandler
public void onEntityDeath(EntityDeathEvent event) {
LivingEntity killed = event.getEntity();
EntityStackManager stackManager = instance.getEntityStackManager();
if (!stackManager.isStacked(killed)) return;
killed.setCustomName(null);
killed.setCustomNameVisible(false);
EntityStack stack = stackManager.getStack(killed);
if (instance.getConfig().getBoolean("Entity.Kill Whole Stack On Death")) {
for (int i = 1; i < stack.getAmount(); i ++) {
LivingEntity newEntity = newEntity(killed);
newEntity.damage(99999);
}
} else {
Entity newEntity = newEntity(killed);
stack = stackManager.updateStack(killed, newEntity);
stack.addAmount(-1);
if (stack.getAmount() <= 1) {
stackManager.removeStack(newEntity);
newEntity.setCustomNameVisible(false);
newEntity.setCustomName(null);
}
}
}
private LivingEntity newEntity(LivingEntity killed) {
LivingEntity newEntity = (LivingEntity)killed.getWorld().spawnEntity(killed.getLocation(), killed.getType());
newEntity.setVelocity(killed.getVelocity());
if (killed instanceof Ageable && !((Ageable) killed).isAdult()) {
((Ageable) newEntity).setBaby();
}
if (killed instanceof Sheep) {
((Sheep) newEntity).setColor(((Sheep) killed).getColor());
}
if (killed instanceof Villager) {
((Villager)newEntity).setProfession(((Villager)killed).getProfession());
}
return newEntity;
}
}

View File

@ -0,0 +1,23 @@
package com.songoda.ultimatestacker.events;
import com.songoda.ultimatestacker.UltimateStacker;
import org.bukkit.Bukkit;
import org.bukkit.entity.*;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.inventory.ItemStack;
public class DropListeners implements Listener {
private final UltimateStacker instance;
public DropListeners(UltimateStacker instance) {
this.instance = instance;
}
@EventHandler
public void onDrop(PlayerDropItemEvent event) {
Item dropped = event.getItemDrop();
}
}

View File

@ -0,0 +1,65 @@
package com.songoda.ultimatestacker.events;
import com.songoda.ultimatestacker.entity.EntityStack;
import com.songoda.ultimatestacker.UltimateStacker;
import com.songoda.ultimatestacker.entity.EntityStackManager;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Sheep;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerShearEntityEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.material.Wool;
import org.bukkit.util.Vector;
import java.util.concurrent.ThreadLocalRandom;
public class ShearListeners implements Listener {
private UltimateStacker instance;
public ShearListeners(UltimateStacker instance) {
this.instance = instance;
}
@EventHandler
public void onShearSheap(PlayerShearEntityEvent event) {
Entity entity = event.getEntity();
if (!(entity instanceof Sheep)) return;
EntityStackManager stackManager = instance.getEntityStackManager();
if (!stackManager.isStacked(entity)) return;
LivingEntity sheep = (LivingEntity) entity;
event.setCancelled(true);
Entity newEntity = sheep.getWorld().spawnEntity(sheep.getLocation(), sheep.getType());
((Sheep) newEntity).setSheared(true);
newEntity.setVelocity(getRandomVector());
((Sheep) newEntity).setAge(((Sheep) sheep).getAge());
((Sheep) newEntity).setColor(((Sheep) sheep).getColor());
int num = (int) Math.round(1 + (Math.random() * 3));
Wool woolColor = new Wool(((Sheep) sheep).getColor());
ItemStack wool = woolColor.toItemStack(num);
sheep.getLocation().getWorld().dropItemNaturally(sheep.getEyeLocation(), wool);
EntityStack stack = stackManager.getStack(sheep);
stack.addAmount(-1);
if (stack.getAmount() <= 1) {
stackManager.removeStack(entity);
sheep.setCustomNameVisible(false);
sheep.setCustomName(null);
((Sheep) sheep).setSheared(false);
}
}
private Vector getRandomVector() {
return new Vector(ThreadLocalRandom.current().nextDouble(-1, 1.01), 0, ThreadLocalRandom.current().nextDouble(-1, 1.01)).normalize().multiply(0.5);
}
}

View File

@ -0,0 +1,63 @@
package com.songoda.ultimatestacker.events;
import com.songoda.ultimatestacker.UltimateStacker;
import com.songoda.ultimatestacker.entity.EntityStack;
import com.songoda.ultimatestacker.utils.Methods;
import org.bukkit.Bukkit;
import org.bukkit.entity.Entity;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.SpawnerSpawnEvent;
import java.util.List;
public class SpawnerListeners implements Listener {
private UltimateStacker instance;
public SpawnerListeners(UltimateStacker instance) {
this.instance = instance;
}
@EventHandler
public void onSpawner(SpawnerSpawnEvent event) {
/*
Entity initalEntity = event.getEntity();
if (!instance.getConfig().getBoolean("Main.Stack Entities")) return;
List<Entity> entityList = Methods.getSimilarEntitesAroundEntity(initalEntity);
if (entityList.size() == 0) return;
int maxEntityStackSize = instance.getConfig().getInt("Entity.Max Stack Size");
for (Entity entity : entityList) {
EntityStack stack = instance.getEntityStackManager().getStack(entity);
//If a stack was found add 1 to this stack.
if (stack != null && stack.getAmount() < maxEntityStackSize) {
stack.addAmount(1);
stack.updateStack();
initalEntity.remove();
event.setCancelled(true);
return;
}
}
Bukkit.broadcastMessage(entityList.size() + 1 + "");
if ((entityList.size() + 1) >= instance.getConfig().getInt("Entity.Min Stack Amount")) {
EntityStack stack = instance.getEntityStackManager().addStack(new EntityStack(initalEntity, entityList.size() + 1));
stack.updateStack();
for (Entity entity : entityList) {
entity.remove();
}
entityList.size();
}
*/
}
}

View File

@ -0,0 +1,69 @@
package com.songoda.ultimatestacker.handlers;
import com.songoda.arconix.api.hologram.HologramObject;
import com.songoda.arconix.plugin.Arconix;
import com.songoda.ultimatestacker.UltimateStacker;
import com.songoda.ultimatestacker.spawner.SpawnerStack;
import com.songoda.ultimatestacker.utils.Methods;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.CreatureSpawner;
import java.util.Collection;
/**
* Created by songoda on 3/12/2017.
*/
public class HologramHandler {
private final UltimateStacker instance;
public HologramHandler(UltimateStacker instance) {
this.instance = instance;
loadHolograms();
}
private void loadHolograms() {
Collection<SpawnerStack> spawners = instance.getSpawnerStackManager().getStacks();
if (spawners.size() == 0) return;
for (SpawnerStack spawner : spawners) {
if (spawner.getLocation().getWorld() == null) continue;
updateHologram(spawner);
}
}
public void updateHologram(SpawnerStack spawner) {
if (spawner == null) return;
Location location = spawner.getLocation().add(0.5, 1, 0.5);
if (!instance.getConfig().getBoolean("Spawners.Holograms Enabled")) return;
addHologram(location, spawner);
}
public void despawn(Block b) {
Location location = b.getLocation().add(0.5, 1, 0.5);
Arconix.pl().getApi().packetLibrary.getHologramManager().removeHologram(location, 1);
}
private void addHologram(Location location, SpawnerStack spawner) {
int amount = spawner.getAmount();
CreatureSpawner creatureSpawner = (CreatureSpawner)spawner.getLocation().getBlock().getState();
String name = Methods.compileSpawnerName(creatureSpawner.getSpawnedType(), amount);
HologramObject hologram = new HologramObject(null, location, name);
Arconix.pl().getApi().packetLibrary.getHologramManager().addHologram(hologram);
}
public void processChange(Block block) {
if (!block.getType().name().contains("SPAWNER")) return;
SpawnerStack spawner = instance.getSpawnerStackManager().getSpawner(block);
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(instance, () -> updateHologram(spawner), 1L);
}
}

View File

@ -0,0 +1,44 @@
package com.songoda.ultimatestacker.spawner;
import org.bukkit.Location;
import org.bukkit.block.CreatureSpawner;
public class SpawnerStack {
private final Location location;
private int amount;
public SpawnerStack(Location location, int amount) {
this.location = location;
setAmount(amount);
}
public Location getLocation() {
return location.clone();
}
public int getAmount() {
return amount;
}
public void setAmount(int amount) {
this.amount = amount;
CreatureSpawner creatureSpawner = (CreatureSpawner)location.getBlock().getState();
creatureSpawner.setSpawnCount(4 * amount);
creatureSpawner.update();
}
@Override
public String toString() {
return "SpawnerStack:{"
+ "Amount:\"" + amount + "\","
+ "Location:{"
+ "World:\"" + location.getWorld().getName() + "\","
+ "X:" + location.getBlockX() + ","
+ "Y:" + location.getBlockY() + ","
+ "Z:" + location.getBlockZ()
+ "}"
+ "}";
}
}

View File

@ -0,0 +1,42 @@
package com.songoda.ultimatestacker.spawner;
import org.bukkit.Location;
import org.bukkit.block.Block;
import java.util.*;
public class SpawnerStackManager {
private static final Map<Location, SpawnerStack> registeredSpawners = new HashMap<>();
public SpawnerStack addSpawner(SpawnerStack spawnerStack) {
return registeredSpawners.put(roundLocation(spawnerStack.getLocation()), spawnerStack);
}
public SpawnerStack removeSpawner(Location location) {
return registeredSpawners.remove(roundLocation(location));
}
public SpawnerStack getSpawner(Location location) {
if (!registeredSpawners.containsKey(roundLocation(location))) {
return addSpawner(new SpawnerStack(roundLocation(location), 1));
}
return registeredSpawners.get(location);
}
public SpawnerStack getSpawner(Block block) {
return this.getSpawner(block.getLocation());
}
public Collection<SpawnerStack> getStacks() {
return Collections.unmodifiableCollection(registeredSpawners.values());
}
private Location roundLocation(Location location) {
location = location.clone();
location.setX(location.getBlockX());
location.setY(location.getBlockY());
location.setZ(location.getBlockZ());
return location;
}
}

View File

@ -0,0 +1,31 @@
package com.songoda.ultimatestacker.storage;
import com.songoda.arconix.api.utils.ConfigWrapper;
import com.songoda.ultimatestacker.UltimateStacker;
import java.util.List;
public abstract class Storage {
protected final UltimateStacker instance;
protected final ConfigWrapper dataFile;
public Storage(UltimateStacker instance) {
this.instance = instance;
this.dataFile = new ConfigWrapper(instance, "", "data.yml");
this.dataFile.createNewFile(null, "UltimateStacker Data File");
this.dataFile.getConfig().options().copyDefaults(true);
this.dataFile.saveConfig();
}
public abstract boolean containsGroup(String group);
public abstract List<StorageRow> getRowsByGroup(String group);
public abstract void prepareSaveItem(String group, StorageItem... items);
public abstract void doSave();
public abstract void closeConnection();
}

View File

@ -0,0 +1,75 @@
package com.songoda.ultimatestacker.storage;
import org.bukkit.Material;
import org.bukkit.entity.EntityType;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class StorageItem {
private final Object object;
private String key = null;
public StorageItem(Object object) {
this.object = object;
}
public StorageItem(String key, Object object) {
this.key = key;
this.object = object;
}
public StorageItem(String key, List<Material> material) {
String object = "";
for (Material m : material) {
object += m.name() + ";";
}
this.key = key;
this.object = object;
}
public StorageItem(String key, Map<EntityType, Integer> entityKills) {
String object = "";
for (Map.Entry<EntityType, Integer> entry : entityKills.entrySet()) {
object += entry.getKey().name() + ":" + entry.getValue() + ";";
}
this.key = key;
this.object = object;
}
public String getKey() {
return key;
}
public String asString() {
if (object == null) return null;
return (String) object;
}
public boolean asBoolean() {
if (object == null) return false;
return (boolean) object;
}
public int asInt() {
if (object == null) return 0;
return (int) object;
}
public Object asObject() {
return object;
}
public List<Material> asMaterialList() {
List<Material> list = new ArrayList<>();
if (object == null) return list;
String[] stack = ((String) object).split(";");
for (String item : stack) {
if (item.equals("")) continue;
list.add(Material.valueOf(item));
}
return list;
}
}

View File

@ -0,0 +1,29 @@
package com.songoda.ultimatestacker.storage;
import java.util.Collections;
import java.util.Map;
public class StorageRow {
private final String key;
private final Map<String, StorageItem> items;
public StorageRow(String key, Map<String, StorageItem> items) {
this.key = key;
this.items = items;
}
public String getKey() {
return key;
}
public Map<String, StorageItem> getItems() {
return Collections.unmodifiableMap(items);
}
public StorageItem get(String key) {
if (!items.containsKey(key) || items.get(key).asObject().toString().equals("")) return new StorageItem(null);
return items.get(key);
}
}

View File

@ -0,0 +1,124 @@
package com.songoda.ultimatestacker.storage.types;
import com.songoda.ultimatestacker.UltimateStacker;
import com.songoda.ultimatestacker.storage.Storage;
import com.songoda.ultimatestacker.storage.StorageItem;
import com.songoda.ultimatestacker.storage.StorageRow;
import com.songoda.ultimatestacker.utils.MySQLDatabase;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class StorageMysql extends Storage {
private MySQLDatabase database;
private static List<String> toSave = new ArrayList<>();
public StorageMysql(UltimateStacker instance) {
super(instance);
this.database = new MySQLDatabase(instance);
}
@Override
public boolean containsGroup(String group) {
try {
DatabaseMetaData dbm = database.getConnection().getMetaData();
ResultSet rs = dbm.getTables(null, null, instance.getConfig().getString("Database.Prefix") + group, null);
if (rs.next()) {
return true;
}
} catch (SQLException e) {
e.printStackTrace();
}
return false;
}
@Override
public List<StorageRow> getRowsByGroup(String group) {
List<StorageRow> rows = new ArrayList<>();
try {
ResultSet set = database.getConnection().createStatement().executeQuery(String.format("SELECT * FROM `" + instance.getConfig().getString("Database.Prefix") + "%s`", group));
while (set.next()) {
Map<String, StorageItem> items = new HashMap<>();
String key = set.getString(1);
for (int i = 2; i <= set.getMetaData().getColumnCount(); i++) {
if (set.getObject(i) == null || set.getObject(i) == "") continue;
StorageItem item = new StorageItem(set.getObject(i));
items.put(set.getMetaData().getColumnName(i), item);
}
StorageRow row = new StorageRow(key, items);
rows.add(row);
}
} catch (SQLException e) {
e.printStackTrace();
}
return rows;
}
@Override
public void prepareSaveItem(String group, StorageItem... items) {
StringBuilder sql = new StringBuilder(String.format("INSERT INTO `" + instance.getConfig().getString("Database.Prefix") + "%s`", group));
sql.append(" (");
for (StorageItem item : items) {
if (item == null || item.asObject() == null) continue;
sql.append(String.format("`%s`, ", item.getKey()));
}
sql = new StringBuilder(sql.substring(0, sql.length() - 2));
sql.append(") VALUES (");
for (StorageItem item : items) {
if (item == null || item.asObject() == null) continue;
sql.append(String.format("'%s', ", item.asObject().toString()));
}
sql = new StringBuilder(sql.substring(0, sql.length() - 2));
sql.append(");");
toSave.add(sql.toString());
}
@Override
public void doSave() {
try {
// Clear database
database.getConnection().createStatement().execute("TRUNCATE `" + instance.getConfig().getString("Database.Prefix") + "entities`");
database.getConnection().createStatement().execute("TRUNCATE `" + instance.getConfig().getString("Database.Prefix") + "spawners`");
Statement stmt = database.getConnection().createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
for (String line : toSave) {
stmt.addBatch(line);
}
stmt.executeBatch();
toSave.clear();
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public void closeConnection() {
try {
database.getConnection().close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,102 @@
package com.songoda.ultimatestacker.storage.types;
import com.songoda.ultimatestacker.UltimateStacker;
import com.songoda.ultimatestacker.storage.Storage;
import com.songoda.ultimatestacker.storage.StorageItem;
import com.songoda.ultimatestacker.storage.StorageRow;
import org.apache.commons.io.FileUtils;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.MemorySection;
import java.io.File;
import java.io.IOException;
import java.util.*;
public class StorageYaml extends Storage {
private static final Map<String, Object> toSave = new HashMap<>();
public StorageYaml(UltimateStacker instance) {
super(instance);
}
@Override
public boolean containsGroup(String group) {
return dataFile.getConfig().contains("data." + group);
}
@Override
public List<StorageRow> getRowsByGroup(String group) {
List<StorageRow> rows = new ArrayList<>();
ConfigurationSection currentSection = dataFile.getConfig().getConfigurationSection("data." + group);
for (String key : currentSection.getKeys(false)) {
Map<String, StorageItem> items = new HashMap<>();
ConfigurationSection currentSection2 = dataFile.getConfig().getConfigurationSection("data." + group + "." + key);
for (String key2 : currentSection2.getKeys(false)) {
String path = "data." + group + "." + key + "." + key2;
items.put(key2, new StorageItem(dataFile.getConfig().get(path) instanceof MemorySection
? convertToInLineList(path) : dataFile.getConfig().get(path)));
}
if (items.isEmpty()) continue;
StorageRow row = new StorageRow(key, items);
rows.add(row);
}
return rows;
}
private String convertToInLineList(String path) {
StringBuilder converted = new StringBuilder();
for (String key : dataFile.getConfig().getConfigurationSection(path).getKeys(false)) {
converted.append(key).append(":").append(dataFile.getConfig().getInt(path + "." + key)).append(";");
}
return converted.toString();
}
@Override
public void prepareSaveItem(String group, StorageItem... items) {
for (StorageItem item : items) {
if (item == null || item.asObject() == null) continue;
toSave.put("data." + group + "." + items[0].asString() + "." + item.getKey(), item.asObject());
}
}
@Override
public void doSave() {
try {
dataFile.getConfig().set("data", null); // Clear file
File data = new File(instance.getDataFolder() + "/data.yml");
File dataClone = new File(instance.getDataFolder() + "/data-backup-" + System.currentTimeMillis() + ".yml");
try {
FileUtils.copyFile(data, dataClone);
} catch (IOException e) {
e.printStackTrace();
}
Deque<File> backups = new ArrayDeque<>();
for (File file : Objects.requireNonNull(instance.getDataFolder().listFiles())) {
if (file.getName().toLowerCase().contains("data-backup")) {
backups.add(file);
}
}
if (backups.size() > 5) {
backups.getFirst().delete();
}
for (Map.Entry<String, Object> entry : toSave.entrySet()) {
dataFile.getConfig().set(entry.getKey(), entry.getValue());
}
dataFile.saveConfig();
toSave.clear();
} catch (NullPointerException e) {
e.printStackTrace();
}
}
@Override
public void closeConnection() {
dataFile.saveConfig();
}
}

View File

@ -0,0 +1,142 @@
package com.songoda.ultimatestacker.tasks;
import com.songoda.arconix.api.methods.formatting.TextComponent;
import com.songoda.ultimatestacker.UltimateStacker;
import com.songoda.ultimatestacker.entity.EntityStack;
import com.songoda.ultimatestacker.entity.EntityStackManager;
import com.songoda.ultimatestacker.utils.Methods;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.*;
import org.bukkit.inventory.ItemStack;
import org.bukkit.scheduler.BukkitRunnable;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;
public class StackingTask extends BukkitRunnable {
private final UltimateStacker instance;
private Class<?> clazzItemStack, clazzItem, clazzCraftItemStack;
private Method methodGetItem, methodAsNMSCopy;
private Field fieldMaxStackSize;
public StackingTask(UltimateStacker instance) {
this.instance = instance;
try {
String ver = Bukkit.getServer().getClass().getPackage().getName().substring(23);
clazzCraftItemStack = Class.forName("org.bukkit.craftbukkit." + ver + ".inventory.CraftItemStack");
clazzItemStack = Class.forName("net.minecraft.server." + ver + ".ItemStack");
clazzItem = Class.forName("net.minecraft.server." + ver + ".Item");
methodAsNMSCopy = clazzCraftItemStack.getMethod("asNMSCopy", ItemStack.class);
methodGetItem = clazzItemStack.getDeclaredMethod("getItem");
fieldMaxStackSize = clazzItem.getDeclaredField("maxStackSize");
fieldMaxStackSize.setAccessible(true);
} catch (ReflectiveOperationException e) {
e.printStackTrace();
}
}
@Override
public void run() {
int maxItemStackSize = instance.getConfig().getInt("Item.Max Stack Size");
int maxEntityStackSize = instance.getConfig().getInt("Entity.Max Stack Size");
EntityStackManager stackManager = instance.getEntityStackManager();
for (World world : Bukkit.getWorlds()) {
nextEntity:
for (Entity entityO : world.getEntities()) {
if (entityO instanceof Item && instance.getConfig().getBoolean( "Main.Stack Items")) {
ItemStack item = ((Item) entityO).getItemStack();
if (entityO.isCustomNameVisible() && !entityO.getCustomName().contains(TextComponent.convertToInvisibleString("IS")) || item.hasItemMeta() && item.getItemMeta().hasDisplayName()) continue;
if (item.getMaxStackSize() != maxItemStackSize && item.getMaxStackSize() != 1)
setMax(item, false);
int size = item.getAmount();
String name = TextComponent.convertToInvisibleString("IS") + Methods.compileItemName(item.getType(), size);
if (instance.getItemFile().getConfig().getBoolean("Items." + item.getType().name() + ".Has Hologram")) {
entityO.setCustomName(name);
entityO.setCustomNameVisible(true);
}
continue;
}
if (!(entityO instanceof LivingEntity) || !instance.getConfig().getBoolean("Main.Stack Entities"))
continue;
LivingEntity initalEntity = (LivingEntity) entityO;
if (initalEntity.isDead()
|| !initalEntity.isValid()
|| initalEntity instanceof ArmorStand
|| stackManager.isStacked(initalEntity)) continue;
ConfigurationSection configurationSection = UltimateStacker.getInstance().getMobFile().getConfig();
if (!configurationSection.getBoolean("Mobs." + initalEntity.getType().name() + ".Enabled"))
continue;
if (configurationSection.getInt("Mobs." + initalEntity.getType().name() + ".Max Stack Size") != -1)
maxEntityStackSize = configurationSection.getInt("Mobs." + initalEntity.getType().name() + ".Max Stack Size");
List<Entity> entityList = Methods.getSimilarEntitesAroundEntity(initalEntity);
for (Entity entity : entityList) {
EntityStack stack = stackManager.getStack(entity);
//If a stack was found add 1 to this stack.
if (stack != null && stack.getAmount() < maxEntityStackSize) {
stack.addAmount(1);
stack.updateStack();
initalEntity.remove();
continue nextEntity;
}
}
entityList.removeIf(stackManager::isStacked);
if (entityList.size() < instance.getConfig().getInt("Entity.Min Stack Amount") - 1) continue;
//If stack was never found make a new one.
EntityStack stack = stackManager.addStack(new EntityStack(initalEntity, entityList.size() + 1));
for (Entity entity : entityList) {
if (stackManager.isStacked(entity)) continue;
entity.remove();
}
stack.updateStack();
}
}
}
public ItemStack setMax(ItemStack item, boolean reset) {
try {
int specific = instance.getItemFile().getConfig().getInt("Items." + item.getType().name() + ".Max Stack Size");
int maxItemStackSize = specific == -1 ? instance.getConfig().getInt("Item.Max Stack Size") : specific;
Object objItemStack = methodGetItem.invoke(methodAsNMSCopy.invoke(null, item));
fieldMaxStackSize.set(objItemStack, reset ? new ItemStack(item.getType()).getMaxStackSize() : maxItemStackSize);
} catch(ReflectiveOperationException e) {
e.printStackTrace();
}
return item;
}
public void startTask() {
new StackingTask(instance).runTaskTimer(instance, 0, instance.getConfig().getInt("Main.Stack Search Tick Speed"));
}
}

View File

@ -0,0 +1,111 @@
package com.songoda.ultimatestacker.utils;
import com.songoda.arconix.api.methods.formatting.TextComponent;
import com.songoda.ultimatestacker.UltimateStacker;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.block.CreatureSpawner;
import org.bukkit.entity.*;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BlockStateMeta;
import org.bukkit.inventory.meta.ItemMeta;
import java.util.List;
public class Methods {
public static List<Entity> getSimilarEntitesAroundEntity(Entity initalEntity) {
//Create a list of all entities around the initial entity.
List<Entity> entityList = initalEntity.getNearbyEntities(5, 5, 5);
//Remove entities of a different type.
entityList.removeIf(entity1 -> entity1.getType() != initalEntity.getType()
|| entity1 == initalEntity);
if (initalEntity instanceof Ageable) {
if (((Ageable) initalEntity).isAdult()) {
entityList.removeIf(entity -> !((Ageable) entity).isAdult());
} else {
entityList.removeIf(entity -> ((Ageable) entity).isAdult());
}
}
if (initalEntity instanceof Sheep) {
Sheep sheep = ((Sheep) initalEntity);
if (sheep.isSheared()) {
entityList.removeIf(entity -> !sheep.isSheared());
} else {
entityList.removeIf(entity -> sheep.isSheared());
}
entityList.removeIf(entity -> ((Sheep) entity).getColor() != sheep.getColor());
}
if (initalEntity instanceof Villager) {
Villager villager = ((Villager)initalEntity);
entityList.removeIf(entity -> ((Villager) entity).getProfession() != villager.getProfession());
}
return entityList;
}
public static String compileSpawnerName(EntityType entityType, int amount) {
String nameFormat = UltimateStacker.getInstance().getConfig().getString("Spawners.Name Format");
String displayName = TextComponent.formatText(UltimateStacker.getInstance().getItemFile().getConfig().getString("Spawners." + entityType.name() + ".Display Name"));
nameFormat = nameFormat.replace("{TYPE}", displayName);
nameFormat = nameFormat.replace("{AMT}", Integer.toString(amount));
String info = TextComponent.convertToInvisibleString(amount + ":");
return info + TextComponent.formatText(nameFormat).trim();
}
public static String compileItemName(Material type, int amount) {
String nameFormat = UltimateStacker.getInstance().getConfig().getString("Item.Name Format");
String displayName = TextComponent.formatText(UltimateStacker.getInstance().getItemFile().getConfig().getString("Items." + type.name() + ".Display Name"));
nameFormat = nameFormat.replace("{TYPE}", displayName);
nameFormat = nameFormat.replace("{AMT}", Integer.toString(amount));
String info = TextComponent.convertToInvisibleString(amount + ":");
return info + TextComponent.formatText(nameFormat).trim();
}
public static String compileEntityName(Entity entity, int amount) {
String nameFormat = UltimateStacker.getInstance().getConfig().getString("Entity.Name Format");
String displayName = TextComponent.formatText(entity.getType().name().toLowerCase().replace("_", " "), true);
nameFormat = nameFormat.replace("{TYPE}", displayName);
nameFormat = nameFormat.replace("{AMT}", Integer.toString(amount));
String info = TextComponent.convertToInvisibleString(amount + ":");
return info + TextComponent.formatText(nameFormat).trim();
}
public static void takeItem(Player player, int amount) {
if (player.getGameMode() == GameMode.CREATIVE) return;
ItemStack item = player.getInventory().getItemInHand();
if (item == null) return;
int result = item.getAmount() - amount;
item.setAmount(result);
player.setItemInHand(result > 0 ? item : null);
}
public static ItemStack getSpawnerItem(EntityType entityType, int amount) {
ItemStack item = new ItemStack(Material.SPAWNER, 1);
ItemMeta meta = item.getItemMeta();
meta.setDisplayName(Methods.compileSpawnerName(entityType, amount));
CreatureSpawner cs = (CreatureSpawner) ((BlockStateMeta)meta).getBlockState();
cs.setSpawnedType(entityType);
((BlockStateMeta) meta).setBlockState(cs);
item.setItemMeta(meta);
return item;
}
}

View File

@ -0,0 +1,50 @@
package com.songoda.ultimatestacker.utils;
import com.songoda.ultimatestacker.UltimateStacker;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class MySQLDatabase {
private final UltimateStacker instance;
private Connection connection;
public MySQLDatabase(UltimateStacker instance) {
this.instance = instance;
try {
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://" + instance.getConfig().getString("Database.IP") + ":" + instance.getConfig().getString("Database.Port") + "/" + instance.getConfig().getString("Database.Database Name") + "?autoReconnect=true&useSSL=false";
this.connection = DriverManager.getConnection(url, instance.getConfig().getString("Database.Username"), instance.getConfig().getString("Database.Password"));
createTables();
} catch (ClassNotFoundException | SQLException e) {
System.out.println("Database connection failed.");
}
}
private void createTables() {
try {
connection.createStatement().execute("CREATE TABLE IF NOT EXISTS `" + instance.getConfig().getString("Database.Prefix") + "entities` (\n" +
"\t`uuid` TEXT NULL,\n" +
"\t`amount` INT NULL,\n" +
")");
connection.createStatement().execute("CREATE TABLE IF NOT EXISTS `" + instance.getConfig().getString("Database.Prefix") + "spawners` (\n" +
"\t`location` TEXT NULL,\n" +
"\t`amount` INT NULL,\n" +
")");
} catch (SQLException e) {
e.printStackTrace();
}
}
public Connection getConnection() {
return connection;
}
}

View File

@ -0,0 +1,59 @@
package com.songoda.ultimatestacker.utils;
import com.songoda.ultimatestacker.UltimateStacker;
import org.bukkit.event.Listener;
/**
* Created by songo on 6/4/2017.
*/
public class SettingsManager implements Listener {
private final UltimateStacker instance;
public SettingsManager(UltimateStacker instance) {
this.instance = instance;
instance.getServer().getPluginManager().registerEvents(this, instance);
}
public void updateSettings() {
for (settings s : settings.values()) {
instance.getConfig().addDefault(s.setting, s.option);
}
}
public enum settings {
o1("Main.Stack Items", true),
o2("Main.Stack Entities", true),
o22("Main.Stack Spawners", true),
o3("Main.Stack Search Tick Speed", 5),
o4("Entity.Max Stack Size", 15),
oo("Entity.Min Stack Amount", 5),
o5("Entity.Kill Whole Stack On Death", false),
NAME_FORMAT_ENTITY("Entity.Name Format", "&f{TYPE} &6{AMT}x"),
o6("Item.Max Stack Size", 250),
NAME_FORMAT_ITEM("Item.Name Format", "&f{TYPE} &6{AMT}x"),
o7("Spawners.Holograms Enabled", true),
o8("Spawners.Max Stack Size", 5),
NAME_FORMAT_SPAWNER("Spawners.Name Format", "&f{TYPE} Spawner &6{AMT}x"),
DATABASE_SUPPORT("Database.Activate Mysql Support", false),
DATABASE_IP("Database.IP", "127.0.0.1"),
DATABASE_PORT("Database.Port", 3306),
DATABASE_NAME("Database.Database Name", "UltimateStacker"),
DATABASE_PREFIX("Database.Prefix", "US-"),
DATABASE_USERNAME("Database.Username", "PUT_USERNAME_HERE"),
DATABASE_PASSWORD("Database.Password", "PUT_PASSWORD_HERE"),
DOWNLOAD_FILES("System.Download Needed Data Files", true),
LANGUGE_MODE("System.Language Mode", "en_US");
private String setting;
private Object option;
settings(String setting, Object option) {
this.setting = setting;
this.option = option;
}
}
}

View File

@ -0,0 +1,11 @@
#General Messages
general.nametag.prefix = "&8[&6UltimateStacker&8]"
#Command Messages
command.give.success = "&7You have been given a &6%type%7."
#Event Messages
event.general.nopermission = "&cYou do not have permission to do that."

View File

@ -0,0 +1,13 @@
name: UltimateStacker
description: UltimateStacker
version: 1
depend: [Arconix]
main: com.songoda.ultimatestacker.UltimateStacker
author: songoda
api-version: 1.13
commands:
UltimateStacker:
description: I have no idea.
default: true
aliases: [us]
usage: /<command> [reload]