mirror of
https://github.com/songoda/UltimateStacker.git
synced 2025-01-12 18:50:49 +01:00
Init
This commit is contained in:
parent
7f5148fd5c
commit
a6b5b2b8dd
142
.gitignore
vendored
Normal file
142
.gitignore
vendored
Normal 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
9
LICENSE
Normal file
@ -0,0 +1,9 @@
|
||||
Copyright (c) 2018 Brianna O’Keefe
|
||||
|
||||
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.
|
20
Read_this_before_your_first_use.txt
Normal file
20
Read_this_before_your_first_use.txt
Normal 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
51
UltimateStacker.iml
Normal 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
138
pom.xml
Normal 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>
|
375
src/main/java/com/songoda/ultimatestacker/Locale.java
Normal file
375
src/main/java/com/songoda/ultimatestacker/Locale.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
14
src/main/java/com/songoda/ultimatestacker/References.java
Normal file
14
src/main/java/com/songoda/ultimatestacker/References.java
Normal 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;
|
||||
}
|
||||
}
|
307
src/main/java/com/songoda/ultimatestacker/UltimateStacker.java
Normal file
307
src/main/java/com/songoda/ultimatestacker/UltimateStacker.java
Normal 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;
|
||||
}
|
||||
}
|
@ -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}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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.";
|
||||
}
|
||||
}
|
@ -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.";
|
||||
}
|
||||
}
|
@ -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.";
|
||||
}
|
||||
}
|
@ -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 + "\","
|
||||
+ "}";
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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()
|
||||
+ "}"
|
||||
+ "}";
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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();
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -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"));
|
||||
}
|
||||
}
|
111
src/main/java/com/songoda/ultimatestacker/utils/Methods.java
Normal file
111
src/main/java/com/songoda/ultimatestacker/utils/Methods.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
11
src/main/resources/en_US.lang
Normal file
11
src/main/resources/en_US.lang
Normal 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."
|
13
src/main/resources/plugin.yml
Normal file
13
src/main/resources/plugin.yml
Normal 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]
|
Loading…
Reference in New Issue
Block a user