mirror of
https://github.com/songoda/EpicEnchants.git
synced 2024-12-31 21:48:28 +01:00
Rewrote a bit.
This commit is contained in:
parent
50f9086dc8
commit
8207ff915b
124
core/pom.xml
124
core/pom.xml
@ -1,124 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>EpicEnchants-Parent</artifactId>
|
||||
<groupId>com.songoda</groupId>
|
||||
<version>1.0.8-ALPHA</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>EpicEnchants</artifactId>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>jitpack.io</id>
|
||||
<url>https://jitpack.io</url>
|
||||
</repository>
|
||||
|
||||
<repository>
|
||||
<id>aikar</id>
|
||||
<url>https://repo.aikar.co/content/groups/aikar/</url>
|
||||
</repository>
|
||||
|
||||
<repository>
|
||||
<id>placeholderapi</id>
|
||||
<url>http://repo.extendedclip.com/content/repositories/placeholderapi/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<build>
|
||||
<defaultGoal>clean package</defaultGoal>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.7.0</version>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
<compilerArgs>
|
||||
<arg>-parameters</arg>
|
||||
</compilerArgs>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<configuration>
|
||||
<dependencyReducedPomLocation>${project.build.directory}/dependency-reduced-pom.xml</dependencyReducedPomLocation>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot</artifactId>
|
||||
<version>1.13.2</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.tr7zw</groupId>
|
||||
<artifactId>Item-NBT-API</artifactId>
|
||||
<version>master-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>co.aikar</groupId>
|
||||
<artifactId>acf-bukkit</artifactId>
|
||||
<version>0.5.0-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>net.milkbowl.vault</groupId>
|
||||
<artifactId>VaultAPI</artifactId>
|
||||
<version>1.7</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.songoda</groupId>
|
||||
<artifactId>UltimateBottles</artifactId>
|
||||
<version>1.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>me.clip</groupId>
|
||||
<artifactId>placeholderapi</artifactId>
|
||||
<version>2.9.2</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -1,67 +0,0 @@
|
||||
package com.songoda.epicenchants;
|
||||
|
||||
import com.songoda.epicenchants.objects.Placeholder;
|
||||
import org.bukkit.Effect;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.songoda.epicenchants.utils.single.GeneralUtils.color;
|
||||
|
||||
public class Action {
|
||||
private FileConfiguration config;
|
||||
|
||||
public void perform(CommandSender sender, String node, Placeholder... placeholders) {
|
||||
if (config.isString(node)) {
|
||||
getMessage(node, placeholders).forEach(sender::sendMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!config.isConfigurationSection(node)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ConfigurationSection section = config.getConfigurationSection(node);
|
||||
|
||||
if (section.isString("message") || section.isList("message")) {
|
||||
getMessage(node + ".message", placeholders).forEach(sender::sendMessage);
|
||||
}
|
||||
|
||||
if (!(sender instanceof Player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = (Player) sender;
|
||||
|
||||
if (section.isString("sound")) {
|
||||
player.playSound(player.getLocation(), Sound.valueOf(section.getString("sound").toUpperCase()), 1F, 1F);
|
||||
}
|
||||
|
||||
if (section.isString("effect")) {
|
||||
player.playEffect(player.getEyeLocation(), Effect.valueOf(section.getString("effect")), 10);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public List<String> getMessage(String node, Placeholder... placeholders) {
|
||||
List<String> output = config.isList(node) ? config.getStringList(node) : config.getString(node).isEmpty() ? Collections.emptyList() : Collections.singletonList(config.getString(node));
|
||||
|
||||
return output.stream().map(s -> {
|
||||
for (Placeholder placeholder : placeholders) {
|
||||
s = s.replace(placeholder.getPlaceholder(), placeholder.getToReplace().toString());
|
||||
}
|
||||
|
||||
return color(s);
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public void load(FileConfiguration config) {
|
||||
this.config = config;
|
||||
}
|
||||
}
|
@ -1,125 +0,0 @@
|
||||
package com.songoda.epicenchants;
|
||||
|
||||
import co.aikar.commands.BukkitCommandManager;
|
||||
import com.songoda.epicenchants.listeners.ArmorListener;
|
||||
import com.songoda.epicenchants.listeners.EntityListener;
|
||||
import com.songoda.epicenchants.listeners.PlayerListener;
|
||||
import com.songoda.epicenchants.listeners.item.BlackScrollListener;
|
||||
import com.songoda.epicenchants.listeners.item.BookListener;
|
||||
import com.songoda.epicenchants.listeners.item.DustListener;
|
||||
import com.songoda.epicenchants.listeners.item.WhiteScrollListener;
|
||||
import com.songoda.epicenchants.managers.*;
|
||||
import com.songoda.epicenchants.objects.Enchant;
|
||||
import com.songoda.epicenchants.utils.EnchantUtils;
|
||||
import com.songoda.epicenchants.utils.SpecialItems;
|
||||
import com.songoda.epicenchants.utils.objects.FastInv;
|
||||
import com.songoda.epicenchants.utils.single.ItemGroup;
|
||||
import lombok.Getter;
|
||||
import net.milkbowl.vault.economy.Economy;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.songoda.epicenchants.utils.single.GeneralUtils.color;
|
||||
import static org.bukkit.Bukkit.getConsoleSender;
|
||||
|
||||
@Getter
|
||||
public class EpicEnchants extends JavaPlugin {
|
||||
|
||||
private BukkitCommandManager commandManager;
|
||||
private EnchantManager enchantManager;
|
||||
private InfoManager infoManager;
|
||||
private GroupManager groupManager;
|
||||
private FileManager fileManager;
|
||||
private HookManager hookManager;
|
||||
|
||||
private SpecialItems specialItems;
|
||||
private Action action;
|
||||
private Economy economy;
|
||||
private EnchantUtils enchantUtils;
|
||||
private ItemGroup itemGroup;
|
||||
private int version;
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
getConsoleSender().sendMessage(color("&a============================="));
|
||||
getConsoleSender().sendMessage(color("&7" + getDescription().getName() + " " + getDescription().getVersion() + " by &5Songoda <3&7!"));
|
||||
getConsoleSender().sendMessage(color("&7Action: &aEnabling&7..."));
|
||||
|
||||
preload();
|
||||
|
||||
this.action = new Action();
|
||||
this.groupManager = new GroupManager(this);
|
||||
this.enchantManager = new EnchantManager(this);
|
||||
this.enchantUtils = new EnchantUtils(this);
|
||||
this.infoManager = new InfoManager(this);
|
||||
this.specialItems = new SpecialItems(this);
|
||||
this.economy = getServer().getServicesManager().getRegistration(Economy.class).getProvider();
|
||||
this.commandManager = new CommandManager(this);
|
||||
this.hookManager = new HookManager();
|
||||
this.itemGroup = new ItemGroup(this);
|
||||
|
||||
groupManager.loadGroups();
|
||||
enchantManager.loadEnchants();
|
||||
infoManager.loadMenus();
|
||||
action.load(fileManager.getConfiguration("actions"));
|
||||
hookManager.setup();
|
||||
|
||||
setupListeners();
|
||||
|
||||
if (!enchantManager.getValues().isEmpty()) {
|
||||
getLogger().info("Successfully loaded enchants: " + enchantManager.getValues().stream().map(Enchant::getIdentifier).collect(Collectors.joining(", ")));
|
||||
}
|
||||
|
||||
getConsoleSender().sendMessage(color("&a============================="));
|
||||
}
|
||||
|
||||
private void preload() {
|
||||
FastInv.init(this);
|
||||
this.version = Integer.parseInt(Bukkit.getServer().getBukkitVersion().split("\\.")[1]);
|
||||
this.fileManager = new FileManager(this);
|
||||
fileManager.loadFiles();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
getConsoleSender().sendMessage(color("&a============================="));
|
||||
getConsoleSender().sendMessage(color("&7" + getDescription().getName() + " " + getDescription().getVersion() + " by &5Songoda <3&7!"));
|
||||
getConsoleSender().sendMessage(color("&7Action: &cDisabling&7..."));
|
||||
getConsoleSender().sendMessage(color("&a============================="));
|
||||
}
|
||||
|
||||
private void setupListeners() {
|
||||
EpicEnchants instance = this;
|
||||
new HashSet<Listener>() {{
|
||||
add(new BookListener(instance));
|
||||
add(new ArmorListener());
|
||||
add(new PlayerListener(instance));
|
||||
add(new EntityListener(instance));
|
||||
add(new WhiteScrollListener(instance));
|
||||
add(new BlackScrollListener(instance));
|
||||
add(new DustListener(instance));
|
||||
}}.forEach(listener -> Bukkit.getPluginManager().registerEvents(listener, this));
|
||||
}
|
||||
|
||||
public void reload() {
|
||||
reloadConfig();
|
||||
|
||||
fileManager.clear();
|
||||
fileManager.loadFiles();
|
||||
|
||||
groupManager.clear();
|
||||
groupManager.loadGroups();
|
||||
|
||||
enchantManager.clear();
|
||||
enchantManager.loadEnchants();
|
||||
|
||||
infoManager.clear();
|
||||
infoManager.loadMenus();
|
||||
|
||||
action.load(fileManager.getConfiguration("actions"));
|
||||
}
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
package com.songoda.epicenchants.objects;
|
||||
|
||||
import com.songoda.epicenchants.effect.EffectExecutor;
|
||||
import com.songoda.epicenchants.enums.EventType;
|
||||
import com.songoda.epicenchants.enums.TriggerType;
|
||||
import com.songoda.epicenchants.utils.single.RomanNumber;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Event;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.songoda.epicenchants.utils.single.GeneralUtils.color;
|
||||
|
||||
@Builder
|
||||
@Getter
|
||||
public class Enchant {
|
||||
private String identifier;
|
||||
private Group group;
|
||||
private int maxLevel;
|
||||
private Set<String> conflict;
|
||||
//TODO: ISSUES
|
||||
private Set<Material> itemWhitelist;
|
||||
private Set<EffectExecutor> effectExecutors;
|
||||
private List<String> description;
|
||||
private String format;
|
||||
@Nullable private BookItem bookItem;
|
||||
|
||||
public void onAction(@NotNull Player user, @Nullable LivingEntity opponent, Event event, int level, TriggerType triggerType, EventType eventType) {
|
||||
effectExecutors.forEach(effect -> effect.testAndRun(user, opponent, level, triggerType, event, eventType));
|
||||
}
|
||||
|
||||
public BookItem getBook() {
|
||||
return bookItem != null ? bookItem : group.getBookItem();
|
||||
}
|
||||
|
||||
public String getFormat(int level, boolean roman) {
|
||||
String output = format.isEmpty() ? group.getFormat() : format;
|
||||
|
||||
output = output
|
||||
.replace("{level}", "" + (roman ? RomanNumber.toRoman(level) : level))
|
||||
.replace("{enchant}", "" + identifier)
|
||||
.replace("{group_color}", "" + group.getColor());
|
||||
|
||||
return color(output);
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
package com.songoda.epicenchants.objects;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@Builder
|
||||
public class Group {
|
||||
private String identifier;
|
||||
private String name;
|
||||
private String format;
|
||||
private String color;
|
||||
private String descriptionColor;
|
||||
private int slotsUsed;
|
||||
private BookItem bookItem;
|
||||
private int destroyRateMin, destroyRateMax, successRateMin, successRateMax;
|
||||
private int tinkererExp;
|
||||
private int order;
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
package com.songoda.epicenchants.wrappers;
|
||||
|
||||
import com.songoda.epicenchants.objects.LeveledModifier;
|
||||
import lombok.Builder;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@Builder
|
||||
public class EnchantmentWrapper {
|
||||
private LeveledModifier amplifier;
|
||||
private Enchantment enchantment;
|
||||
|
||||
public int getAmplifier(int level, @NotNull Player user, @Nullable LivingEntity opponent) {
|
||||
return (int) amplifier.get(level, 0, user, opponent);
|
||||
}
|
||||
|
||||
public Enchantment getEnchantment() {
|
||||
return enchantment;
|
||||
}
|
||||
}
|
@ -1,67 +0,0 @@
|
||||
general:
|
||||
no-permission: "&cYou do not have permission to do that."
|
||||
|
||||
command:
|
||||
book:
|
||||
received: "&7You have been given a &6{enchant} &7book."
|
||||
gave: "&7You gave {player} a &6{enchant} &7book."
|
||||
max-level: "&cThe max level for {enchant} is {max-level}."
|
||||
min-level: "&cThe min level for {enchant} is 1."
|
||||
|
||||
white-scroll:
|
||||
received: "&7You have been given a whitescroll."
|
||||
gave: "&7You gave {player} a whitescroll."
|
||||
|
||||
apply:
|
||||
invalid-item: "&cYou cannot apply {enchant} to this item."
|
||||
|
||||
reload: "&6Configuration files reload"
|
||||
give-unknown: "&cUnknown item to give: &f{unknown}."
|
||||
|
||||
black-scroll:
|
||||
success: "&aSuccessfully blackscrolled: {group_color}{enchant} {level}&a."
|
||||
no-enchants: "&cNo enchants to blackscroll."
|
||||
|
||||
white-scroll:
|
||||
already-applied: "&cThis item is already protected!"
|
||||
applied: "&aThis item is now protected!"
|
||||
|
||||
enchanter:
|
||||
cannot-afford: "&c&l(!) &r&cYou cannot afford this purchase."
|
||||
success: "&7Purchased {group_color}{group_name} &7book for &f{exp_cost} EXP&7."
|
||||
|
||||
tinkerer:
|
||||
open: "&eTrading with the tinkerer."
|
||||
cancelled: "&c&l(!) &r&cCancelled."
|
||||
accepted: "&aAccepted"
|
||||
no-items: "&c&l(!) &r&cThe tinkerer is not interested in any of your items!"
|
||||
deposited-all: "&a&l(!) &r&aDeposited {amount} items."
|
||||
|
||||
alchemist:
|
||||
max-two-items: "&c&l(!) &r&cYou may only combine 2 items at once."
|
||||
not-interested: "&c&l(!) &r&cThe alchemist is not interested in any of your items!"
|
||||
max-level-book: "&c&l(!) &r&cThe alchemist cannot combine max level books."
|
||||
max-percentage-dust: "&c&l(!) &r&cThe alchemist cannot combine 100% success rate dusts."
|
||||
highest-group-dust: "&c&l(!) &r&cThe alchemist can't accept dust of the highest tier."
|
||||
different-enchantment: "&c&l(!) &r&cThe alchemist can only combine books with the same enchantment."
|
||||
different-levels: "&c&l(!) &r&cThe alchemist can only combine books of the same level."
|
||||
different-groups: "&c&l(!) &r&cThe alchemist can only combine dusts of the same group."
|
||||
cannot-afford: "&c&l(!) You cannot afford this exchange."
|
||||
success: "&7Exchanged for &f{exp_cost} EXP&7."
|
||||
|
||||
enchants:
|
||||
invalid-material: "&cYou can not apply &6{enchant} &cto that item."
|
||||
failure: "&6{enchant} &cfailed to apply..."
|
||||
broken-failure: "&6{enchant} &cfailed to apply and broke your item..."
|
||||
success: "&aYou have successfully applied &6{enchant}."
|
||||
conflict: "&cYou cannot apply this enchant as it conflicts with another enchant."
|
||||
maxed-out: "&cYou already have that enchant maxed on this item."
|
||||
already-applied: "&cYou already have that enchant applied on this item."
|
||||
protected: "&aYour book would have broken your item, luckily it was protected!"
|
||||
|
||||
book:
|
||||
discover:
|
||||
- "&l&e(!) &r&eYou examine the {group_color}{group_name} Enchantment Book..."
|
||||
- "&eand discover &n{enchant_format}!"
|
||||
|
||||
|
@ -1,15 +0,0 @@
|
||||
first-load: true
|
||||
|
||||
language: "en_US"
|
||||
|
||||
roman-numbers: true
|
||||
|
||||
rates:
|
||||
black-scroll-min: 20
|
||||
black-scroll-max: 100
|
||||
|
||||
|
||||
commands:
|
||||
enchanter: "enchanter"
|
||||
alchemist: "alchemist"
|
||||
tinkerer: "tinkerer"
|
140
pom.xml
140
pom.xml
@ -1,41 +1,127 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0">
|
||||
<groupId>com.songoda</groupId>
|
||||
<artifactId>EpicEnchants-Parent</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<version>1.0.8-ALPHA</version>
|
||||
<modules>
|
||||
<module>core</module>
|
||||
</modules>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>private</id>
|
||||
<url>http://repo.songoda.com/repository/private/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<artifactId>EpicEnchants</artifactId>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<version>maven-version-number</version>
|
||||
<build>
|
||||
<defaultGoal>clean install</defaultGoal>
|
||||
<finalName>EpicHeads-${project.version}</finalName>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.5.1</version>
|
||||
<version>3.8.0</version>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>shaded</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<shadedArtifactAttached>false</shadedArtifactAttached>
|
||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||
<artifactSet>
|
||||
<includes>
|
||||
<include>com.songoda:songodaupdater</include>
|
||||
<include>fr.mymicky:FastInv</include>
|
||||
<include>co.aikar:acf-bukkit</include>
|
||||
</includes>
|
||||
</artifactSet>
|
||||
<filters>
|
||||
<filter>
|
||||
<artifact>*:*</artifact>
|
||||
<excludes>
|
||||
<exclude>META-INF/*.SF</exclude>
|
||||
<exclude>META-INF/*.DSA</exclude>
|
||||
<exclude>META-INF/*.RSA</exclude>
|
||||
</excludes>
|
||||
</filter>
|
||||
</filters>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
</build>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>private</id>
|
||||
<url>http://repo.songoda.com/artifactory/private/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>reserve-repo</id>
|
||||
<url>https://dl.bintray.com/theneweconomy/java/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>jitpack.io</id>
|
||||
<url>https://jitpack.io</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>aikar</id>
|
||||
<url>https://repo.aikar.co/content/groups/aikar/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot</artifactId>
|
||||
<version>1.14.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>co.aikar</groupId>
|
||||
<artifactId>acf-bukkit</artifactId>
|
||||
<version>0.5.0-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>fr.mrmicky</groupId>
|
||||
<artifactId>FastInv</artifactId>
|
||||
<version>3.0.2</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.songoda</groupId>
|
||||
<artifactId>songodaupdater</artifactId>
|
||||
<version>1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.tnemc</groupId>
|
||||
<artifactId>Reserve</artifactId>
|
||||
<version>0.1.3.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.black_ixx</groupId>
|
||||
<artifactId>playerpoints</artifactId>
|
||||
<version>2.1.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.milkbowl</groupId>
|
||||
<artifactId>vault</artifactId>
|
||||
<version>1.7.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.songoda</groupId>
|
||||
<artifactId>UltimateBottles</artifactId>
|
||||
<version>1_0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>me.clip</groupId>
|
||||
<artifactId>placeholderapi</artifactId>
|
||||
<version>2.9.2</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
224
src/main/java/com/songoda/epicenchants/EpicEnchants.java
Normal file
224
src/main/java/com/songoda/epicenchants/EpicEnchants.java
Normal file
@ -0,0 +1,224 @@
|
||||
package com.songoda.epicenchants;
|
||||
|
||||
import co.aikar.commands.BukkitCommandManager;
|
||||
import com.songoda.epicenchants.economy.Economy;
|
||||
import com.songoda.epicenchants.economy.PlayerPointsEconomy;
|
||||
import com.songoda.epicenchants.economy.ReserveEconomy;
|
||||
import com.songoda.epicenchants.economy.VaultEconomy;
|
||||
import com.songoda.epicenchants.listeners.ArmorListener;
|
||||
import com.songoda.epicenchants.listeners.EntityListener;
|
||||
import com.songoda.epicenchants.listeners.PlayerListener;
|
||||
import com.songoda.epicenchants.listeners.item.BlackScrollListener;
|
||||
import com.songoda.epicenchants.listeners.item.BookListener;
|
||||
import com.songoda.epicenchants.listeners.item.DustListener;
|
||||
import com.songoda.epicenchants.listeners.item.WhiteScrollListener;
|
||||
import com.songoda.epicenchants.managers.*;
|
||||
import com.songoda.epicenchants.objects.Enchant;
|
||||
import com.songoda.epicenchants.utils.EnchantUtils;
|
||||
import com.songoda.epicenchants.utils.Metrics;
|
||||
import com.songoda.epicenchants.utils.ServerVersion;
|
||||
import com.songoda.epicenchants.utils.SpecialItems;
|
||||
import com.songoda.epicenchants.utils.locale.Locale;
|
||||
import com.songoda.epicenchants.utils.objects.FastInv;
|
||||
import com.songoda.epicenchants.utils.settings.Setting;
|
||||
import com.songoda.epicenchants.utils.settings.SettingsManager;
|
||||
import com.songoda.epicenchants.utils.single.ItemGroup;
|
||||
import com.songoda.epicenchants.utils.updateModules.LocaleModule;
|
||||
import com.songoda.update.Plugin;
|
||||
import com.songoda.update.SongodaUpdate;
|
||||
import org.apache.commons.lang.ArrayUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.songoda.epicenchants.utils.single.GeneralUtils.color;
|
||||
import static org.bukkit.Bukkit.getConsoleSender;
|
||||
|
||||
public class EpicEnchants extends JavaPlugin {
|
||||
|
||||
private static EpicEnchants INSTANCE;
|
||||
|
||||
private EnchantManager enchantManager;
|
||||
private InfoManager infoManager;
|
||||
private GroupManager groupManager;
|
||||
private FileManager fileManager;
|
||||
private HookManager hookManager;
|
||||
private SettingsManager settingsManager;
|
||||
private BukkitCommandManager commandManager;
|
||||
|
||||
private Locale locale;
|
||||
|
||||
private ServerVersion serverVersion = ServerVersion.fromPackageName(Bukkit.getServer().getClass().getPackage().getName());
|
||||
|
||||
private SpecialItems specialItems;
|
||||
private Economy economy;
|
||||
private EnchantUtils enchantUtils;
|
||||
private ItemGroup itemGroup;
|
||||
private int version;
|
||||
|
||||
public static EpicEnchants getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
INSTANCE = this;
|
||||
|
||||
getConsoleSender().sendMessage(color("&a============================="));
|
||||
getConsoleSender().sendMessage(color("&7" + getDescription().getName() + " " + getDescription().getVersion() + " by &5Songoda <3&7!"));
|
||||
getConsoleSender().sendMessage(color("&7Action: &aEnabling&7..."));
|
||||
|
||||
// Setup Setting Manager
|
||||
this.settingsManager = new SettingsManager(this);
|
||||
this.settingsManager.setupConfig();
|
||||
|
||||
// Setup Language
|
||||
new Locale(this, "en_US");
|
||||
this.locale = Locale.getLocale(getConfig().getString("System.Language Mode"));
|
||||
|
||||
// Running Songoda Updater
|
||||
Plugin plugin = new Plugin(this, -1);
|
||||
plugin.addModule(new LocaleModule());
|
||||
SongodaUpdate.load(plugin);
|
||||
|
||||
preload();
|
||||
|
||||
this.groupManager = new GroupManager(this);
|
||||
this.enchantManager = new EnchantManager(this);
|
||||
this.enchantUtils = new EnchantUtils(this);
|
||||
this.infoManager = new InfoManager(this);
|
||||
this.specialItems = new SpecialItems(this);
|
||||
this.commandManager = new CommandManager(this);
|
||||
this.hookManager = new HookManager();
|
||||
this.itemGroup = new ItemGroup(this);
|
||||
|
||||
groupManager.loadGroups();
|
||||
enchantManager.loadEnchants();
|
||||
infoManager.loadMenus();
|
||||
hookManager.setup();
|
||||
|
||||
PluginManager pluginManager = Bukkit.getPluginManager();
|
||||
|
||||
// Listeners
|
||||
pluginManager.registerEvents(new BookListener(this), this);
|
||||
pluginManager.registerEvents(new ArmorListener(), this);
|
||||
pluginManager.registerEvents(new PlayerListener(this), this);
|
||||
pluginManager.registerEvents(new EntityListener(this), this);
|
||||
pluginManager.registerEvents(new WhiteScrollListener(this), this);
|
||||
pluginManager.registerEvents(new BlackScrollListener(this), this);
|
||||
pluginManager.registerEvents(new DustListener(this), this);
|
||||
|
||||
// Setup Economy
|
||||
if (Setting.VAULT_ECONOMY.getBoolean() && pluginManager.isPluginEnabled("Vault"))
|
||||
this.economy = new VaultEconomy();
|
||||
else if (Setting.RESERVE_ECONOMY.getBoolean() && pluginManager.isPluginEnabled("Reserve"))
|
||||
this.economy = new ReserveEconomy();
|
||||
else if (Setting.PLAYER_POINTS_ECONOMY.getBoolean() && pluginManager.isPluginEnabled("PlayerPoints"))
|
||||
this.economy = new PlayerPointsEconomy();
|
||||
|
||||
// Start Metrics
|
||||
new Metrics(this);
|
||||
|
||||
if (!enchantManager.getValues().isEmpty()) {
|
||||
getLogger().info("Successfully loaded enchants: " + enchantManager.getValues().stream().map(Enchant::getIdentifier).collect(Collectors.joining(", ")));
|
||||
}
|
||||
|
||||
getConsoleSender().sendMessage(color("&a============================="));
|
||||
}
|
||||
|
||||
private void preload() {
|
||||
FastInv.init(this);
|
||||
this.version = Integer.parseInt(Bukkit.getServer().getBukkitVersion().split("\\.")[1]);
|
||||
this.fileManager = new FileManager(this);
|
||||
fileManager.loadFiles();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
getConsoleSender().sendMessage(color("&a============================="));
|
||||
getConsoleSender().sendMessage(color("&7" + getDescription().getName() + " " + getDescription().getVersion() + " by &5Songoda <3&7!"));
|
||||
getConsoleSender().sendMessage(color("&7Action: &cDisabling&7..."));
|
||||
getConsoleSender().sendMessage(color("&a============================="));
|
||||
}
|
||||
|
||||
public void reload() {
|
||||
reloadConfig();
|
||||
|
||||
fileManager.clear();
|
||||
fileManager.loadFiles();
|
||||
|
||||
groupManager.clear();
|
||||
groupManager.loadGroups();
|
||||
|
||||
enchantManager.clear();
|
||||
enchantManager.loadEnchants();
|
||||
|
||||
infoManager.clear();
|
||||
infoManager.loadMenus();
|
||||
|
||||
this.locale = Locale.getLocale(getConfig().getString("System.Language Mode"));
|
||||
this.locale.reloadMessages();
|
||||
}
|
||||
|
||||
public ServerVersion getServerVersion() {
|
||||
return serverVersion;
|
||||
}
|
||||
|
||||
public boolean isServerVersion(ServerVersion version) {
|
||||
return serverVersion == version;
|
||||
}
|
||||
|
||||
public boolean isServerVersion(ServerVersion... versions) {
|
||||
return ArrayUtils.contains(versions, serverVersion);
|
||||
}
|
||||
|
||||
public boolean isServerVersionAtLeast(ServerVersion version) {
|
||||
return serverVersion.ordinal() >= version.ordinal();
|
||||
}
|
||||
|
||||
public EnchantManager getEnchantManager() {
|
||||
return this.enchantManager;
|
||||
}
|
||||
|
||||
public InfoManager getInfoManager() {
|
||||
return this.infoManager;
|
||||
}
|
||||
|
||||
public GroupManager getGroupManager() {
|
||||
return this.groupManager;
|
||||
}
|
||||
|
||||
public FileManager getFileManager() {
|
||||
return this.fileManager;
|
||||
}
|
||||
|
||||
public HookManager getHookManager() {
|
||||
return this.hookManager;
|
||||
}
|
||||
|
||||
public SpecialItems getSpecialItems() {
|
||||
return this.specialItems;
|
||||
}
|
||||
|
||||
public Economy getEconomy() {
|
||||
return this.economy;
|
||||
}
|
||||
|
||||
public EnchantUtils getEnchantUtils() {
|
||||
return this.enchantUtils;
|
||||
}
|
||||
|
||||
public ItemGroup getItemGroup() {
|
||||
return this.itemGroup;
|
||||
}
|
||||
|
||||
public int getVersion() {
|
||||
return this.version;
|
||||
}
|
||||
|
||||
public Locale getLocale() {
|
||||
return locale;
|
||||
}
|
||||
}
|
12
src/main/java/com/songoda/epicenchants/economy/Economy.java
Normal file
12
src/main/java/com/songoda/epicenchants/economy/Economy.java
Normal file
@ -0,0 +1,12 @@
|
||||
package com.songoda.ultimateclaims.economy;
|
||||
|
||||
import org.bukkit.OfflinePlayer;
|
||||
|
||||
public interface Economy {
|
||||
|
||||
boolean hasBalance(OfflinePlayer player, double cost);
|
||||
|
||||
boolean withdrawBalance(OfflinePlayer player, double cost);
|
||||
|
||||
boolean deposit(OfflinePlayer player, double amount);
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
package com.songoda.ultimateclaims.economy;
|
||||
|
||||
import org.black_ixx.playerpoints.PlayerPoints;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
|
||||
public class PlayerPointsEconomy implements Economy {
|
||||
|
||||
private final PlayerPoints playerPoints;
|
||||
|
||||
public PlayerPointsEconomy() {
|
||||
this.playerPoints = (PlayerPoints) Bukkit.getServer().getPluginManager().getPlugin("PlayerPoints");
|
||||
}
|
||||
|
||||
private int convertAmount(double amount) {
|
||||
return (int) Math.ceil(amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasBalance(OfflinePlayer player, double cost) {
|
||||
int amount = convertAmount(cost);
|
||||
return playerPoints.getAPI().look(player.getUniqueId()) >= amount;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean withdrawBalance(OfflinePlayer player, double cost) {
|
||||
int amount = convertAmount(cost);
|
||||
return playerPoints.getAPI().take(player.getUniqueId(), amount);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deposit(OfflinePlayer player, double amount) {
|
||||
int amt = convertAmount(amount);
|
||||
return playerPoints.getAPI().give(player.getUniqueId(), amt);
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package com.songoda.ultimateclaims.economy;
|
||||
|
||||
import net.tnemc.core.Reserve;
|
||||
import net.tnemc.core.economy.EconomyAPI;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
public class ReserveEconomy implements Economy {
|
||||
|
||||
EconomyAPI economyAPI;
|
||||
|
||||
public ReserveEconomy() {
|
||||
if (Reserve.instance().economyProvided())
|
||||
economyAPI = Reserve.instance().economy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasBalance(OfflinePlayer player, double cost) {
|
||||
return economyAPI.hasHoldings(player.getUniqueId(), new BigDecimal(cost));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean withdrawBalance(OfflinePlayer player, double cost) {
|
||||
return economyAPI.removeHoldings(player.getUniqueId(), new BigDecimal(cost));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deposit(OfflinePlayer player, double amount) {
|
||||
return economyAPI.addHoldings(player.getUniqueId(), new BigDecimal(amount));
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package com.songoda.ultimateclaims.economy;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
|
||||
public class VaultEconomy implements Economy {
|
||||
private final net.milkbowl.vault.economy.Economy vault;
|
||||
|
||||
public VaultEconomy() {
|
||||
this.vault = Bukkit.getServicesManager().
|
||||
getRegistration(net.milkbowl.vault.economy.Economy.class).getProvider();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasBalance(OfflinePlayer player, double cost) {
|
||||
return vault.has(player, cost);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean withdrawBalance(OfflinePlayer player, double cost) {
|
||||
return vault.withdrawPlayer(player, cost).transactionSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deposit(OfflinePlayer player, double amount) {
|
||||
return vault.depositPlayer(player, amount).transactionSuccess();
|
||||
}
|
||||
}
|
@ -1,13 +1,11 @@
|
||||
package com.songoda.epicenchants.events;
|
||||
|
||||
import com.songoda.epicenchants.objects.Enchant;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
@Getter
|
||||
public class EnchantApplyEvent extends Event implements Cancellable {
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private final ItemStack toEnchant;
|
||||
@ -43,4 +41,24 @@ public class EnchantApplyEvent extends Event implements Cancellable {
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
public ItemStack getToEnchant() {
|
||||
return this.toEnchant;
|
||||
}
|
||||
|
||||
public Enchant getEnchant() {
|
||||
return this.enchant;
|
||||
}
|
||||
|
||||
public int getLevel() {
|
||||
return this.level;
|
||||
}
|
||||
|
||||
public int getSuccessRate() {
|
||||
return this.successRate;
|
||||
}
|
||||
|
||||
public int getDestroyRate() {
|
||||
return this.destroyRate;
|
||||
}
|
||||
}
|
@ -2,8 +2,11 @@ package com.songoda.epicenchants.listeners;
|
||||
|
||||
import com.songoda.epicenchants.EpicEnchants;
|
||||
import com.songoda.epicenchants.enums.TriggerType;
|
||||
import de.tr7zw.itemnbtapi.NBTEntity;
|
||||
import org.bukkit.entity.*;
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.NBTEntity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Monster;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Projectile;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
@ -16,7 +16,8 @@ import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.songoda.epicenchants.enums.EventType.*;
|
||||
import static com.songoda.epicenchants.enums.EventType.OFF;
|
||||
import static com.songoda.epicenchants.enums.EventType.ON;
|
||||
import static com.songoda.epicenchants.enums.TriggerType.*;
|
||||
|
||||
public class PlayerListener implements Listener {
|
@ -24,7 +24,7 @@ public class CommandManager extends BukkitCommandManager {
|
||||
|
||||
// COMPLETIONS
|
||||
|
||||
getCommandCompletions().registerCompletion("enchants", c ->
|
||||
getCommandCompletions().registerCompletion("src/main/resources/enchants", c ->
|
||||
instance.getEnchantManager().getKeys().stream().map(s -> s.replaceAll("\\s", "_")).collect(Collectors.toList()));
|
||||
|
||||
getCommandCompletions().registerCompletion("giveType", c ->
|
@ -30,7 +30,7 @@ public class EnchantManager extends Manager<String, Enchant> {
|
||||
}
|
||||
|
||||
public void loadEnchants() {
|
||||
instance.getFileManager().getYmlFiles("enchants").forEach(file -> {
|
||||
instance.getFileManager().getYmlFiles("src/main/resources/enchants").forEach(file -> {
|
||||
try {
|
||||
loadEnchant(file);
|
||||
} catch (Exception e) {
|
@ -2,7 +2,6 @@ package com.songoda.epicenchants.managers;
|
||||
|
||||
import com.songoda.epicenchants.EpicEnchants;
|
||||
import com.songoda.epicenchants.utils.objects.FileLocation;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
@ -10,6 +9,8 @@ import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.util.*;
|
||||
|
||||
import static com.songoda.epicenchants.utils.objects.FileLocation.of;
|
||||
@ -21,18 +22,17 @@ public class FileManager extends Manager<String, FileConfiguration> {
|
||||
private final String directory;
|
||||
private final LinkedHashSet<FileLocation> files = new LinkedHashSet<>(asList(
|
||||
of("config.yml", true),
|
||||
of("menus/main-info-menu.yml", true),
|
||||
of("src/main/resources/menus/main-info-menu.yml", true),
|
||||
of("menus/enchanter-menu.yml", true, true),
|
||||
of("menus/tinkerer-menu.yml", true, true),
|
||||
of("menus/alchemist-menu.yml", true, true),
|
||||
of("menus/groups/simple-menu.yml", false),
|
||||
of("menus/groups/unique-menu.yml", false),
|
||||
of("menus/groups/elite-menu.yml", false),
|
||||
of("menus/groups/ultimate-menu.yml", false),
|
||||
of("menus/groups/legendary-menu.yml", false),
|
||||
of("enchants/example-enchant.yml", false),
|
||||
of("groups.yml", true),
|
||||
of("actions.yml", true),
|
||||
of("src/main/resources/menus/groups/simple-menu.yml", false),
|
||||
of("src/main/resources/menus/groups/unique-menu.yml", false),
|
||||
of("src/main/resources/menus/groups/elite-menu.yml", false),
|
||||
of("src/main/resources/menus/groups/ultimate-menu.yml", false),
|
||||
of("src/main/resources/menus/groups/legendary-menu.yml", false),
|
||||
of("src/main/resources/enchants/example-enchant.yml", false),
|
||||
of("src/main/resources/groups.yml", true),
|
||||
of("items/special-items.yml", true, true),
|
||||
of("items/dusts.yml", true, true)
|
||||
));
|
||||
@ -47,12 +47,14 @@ public class FileManager extends Manager<String, FileConfiguration> {
|
||||
files.forEach(fileLocation -> {
|
||||
File file = new File(instance.getDataFolder() + separator + fileLocation.getPath());
|
||||
|
||||
if (!file.exists() && (fileLocation.isRequired() || getConfiguration("config").getBoolean("first-load"))) {
|
||||
if (!file.exists() && (fileLocation.isRequired() || getConfiguration("config").getBoolean("System.First Load"))) {
|
||||
file.getParentFile().mkdirs();
|
||||
Bukkit.getConsoleSender().sendMessage("Creating file: " + fileLocation.getPath());
|
||||
|
||||
try {
|
||||
FileUtils.copyInputStreamToFile(instance.getResource(fileLocation.getResourcePath(directory)), file);
|
||||
InputStream in = instance.getResource(fileLocation.getResourcePath(directory));
|
||||
if (in != null)
|
||||
Files.copy(in, file.toPath());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@ -69,7 +71,7 @@ public class FileManager extends Manager<String, FileConfiguration> {
|
||||
}
|
||||
});
|
||||
|
||||
getConfiguration("config").set("first-load", false);
|
||||
getConfiguration("config").set("System.First Load", false);
|
||||
try {
|
||||
getConfiguration("config").save(new File(instance.getDataFolder() + separator + "config.yml"));
|
||||
} catch (IOException e) {
|
@ -1,12 +1,10 @@
|
||||
package com.songoda.epicenchants.managers;
|
||||
|
||||
import com.songoda.ultimatebottles.UltimateBottles;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@Getter
|
||||
public class HookManager {
|
||||
private UltimateBottles ultimateBottles;
|
||||
|
@ -4,7 +4,6 @@ import com.songoda.epicenchants.EpicEnchants;
|
||||
import com.songoda.epicenchants.menus.InfoMenu;
|
||||
import com.songoda.epicenchants.menus.MainInfoMenu;
|
||||
import com.songoda.epicenchants.objects.Group;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
@ -12,7 +11,7 @@ import java.util.Optional;
|
||||
|
||||
public class InfoManager extends Manager<Group, InfoMenu> {
|
||||
private final EpicEnchants instance;
|
||||
@Getter private MainInfoMenu mainInfoMenu;
|
||||
private MainInfoMenu mainInfoMenu;
|
||||
|
||||
public InfoManager(EpicEnchants instance) {
|
||||
super(instance);
|
||||
@ -25,7 +24,7 @@ public class InfoManager extends Manager<Group, InfoMenu> {
|
||||
|
||||
public void loadMenus() {
|
||||
mainInfoMenu = new MainInfoMenu(instance, instance.getFileManager().getConfiguration("menus/main-info-menu"));
|
||||
instance.getFileManager().getYmlFiles("menus/groups").forEach(file -> {
|
||||
instance.getFileManager().getYmlFiles("src/main/resources/menus/groups").forEach(file -> {
|
||||
try {
|
||||
YamlConfiguration config = YamlConfiguration.loadConfiguration(file);
|
||||
add(instance.getGroupManager().getValue(config.getString("group"))
|
||||
@ -38,4 +37,7 @@ public class InfoManager extends Manager<Group, InfoMenu> {
|
||||
});
|
||||
}
|
||||
|
||||
public MainInfoMenu getMainInfoMenu() {
|
||||
return this.mainInfoMenu;
|
||||
}
|
||||
}
|
@ -4,10 +4,10 @@ import com.songoda.epicenchants.EpicEnchants;
|
||||
import com.songoda.epicenchants.objects.Enchant;
|
||||
import com.songoda.epicenchants.objects.Group;
|
||||
import com.songoda.epicenchants.objects.Placeholder;
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.NBTItem;
|
||||
import com.songoda.epicenchants.utils.objects.FastInv;
|
||||
import com.songoda.epicenchants.utils.objects.ItemBuilder;
|
||||
import com.songoda.epicenchants.utils.single.GeneralUtils;
|
||||
import de.tr7zw.itemnbtapi.NBTItem;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
@ -18,8 +18,10 @@ import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.songoda.epicenchants.objects.Placeholder.of;
|
||||
import static com.songoda.epicenchants.utils.single.Experience.*;
|
||||
import static com.songoda.epicenchants.utils.single.GeneralUtils.*;
|
||||
import static com.songoda.epicenchants.utils.single.Experience.changeExp;
|
||||
import static com.songoda.epicenchants.utils.single.Experience.getExp;
|
||||
import static com.songoda.epicenchants.utils.single.GeneralUtils.color;
|
||||
import static com.songoda.epicenchants.utils.single.GeneralUtils.getSlots;
|
||||
|
||||
public class AlchemistMenu extends FastInv {
|
||||
private final EpicEnchants instance;
|
||||
@ -122,13 +124,13 @@ public class AlchemistMenu extends FastInv {
|
||||
NBTItem nbtItem = new NBTItem(toHandle);
|
||||
|
||||
if (!nbtItem.hasKey("book-item") && !nbtItem.hasKey("dust")) {
|
||||
instance.getAction().perform(player, "alchemist.not-interested");
|
||||
instance.getLocale().getMessage("alchemist.notinterested").sendPrefixedMessage(player);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Both slots occupied
|
||||
if (getInventory().getItem(LEFT_SLOT) != null && getInventory().getItem(RIGHT_SLOT) != null) {
|
||||
instance.getAction().perform(player, "alchemist.max-two-items");
|
||||
instance.getLocale().getMessage("alchemist.maxtwoitems").sendPrefixedMessage(player);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -141,14 +143,16 @@ public class AlchemistMenu extends FastInv {
|
||||
int level = nbtItem.getInteger("level");
|
||||
|
||||
if (enchant.getMaxLevel() == level) {
|
||||
instance.getAction().perform(player, "alchemist.max-level-book");
|
||||
instance.getLocale().getMessage("alchemist.maxlevelbook")
|
||||
.sendPrefixedMessage(player);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
Group group = instance.getGroupManager().getValue(nbtItem.getString("group")).orElseThrow(() -> new IllegalStateException("Dust without group!"));
|
||||
|
||||
if (group.getOrder() == instance.getGroupManager().getValues().stream().mapToInt(Group::getOrder).max().orElse(0) || successRate == 100) {
|
||||
instance.getAction().perform(player, "alchemist." + (successRate == 100 ? "max-percentage-dust" : "highest-group-dust"));
|
||||
instance.getLocale().getMessage("alchemist." + (successRate == 100 ? "maxpercentagedust" : "highestgroupdust"))
|
||||
.sendPrefixedMessage(player);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -162,22 +166,22 @@ public class AlchemistMenu extends FastInv {
|
||||
|
||||
if (other.hasKey("book-item")) {
|
||||
if (!nbtItem.getString("enchant").equals(other.getString("enchant"))) {
|
||||
instance.getAction().perform(player, "alchemist.different-enchantment");
|
||||
instance.getLocale().getMessage("alchemist.differentenchantment").sendPrefixedMessage(player);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!nbtItem.getInteger("level").equals(other.getInteger("level"))) {
|
||||
instance.getAction().perform(player, "alchemist.different-levels");
|
||||
instance.getLocale().getMessage("alchemist.differentlevels").sendPrefixedMessage(player);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!nbtItem.getString("group").equals(other.getString("group"))) {
|
||||
instance.getAction().perform(player, "alchemist.different-groups");
|
||||
instance.getLocale().getMessage("alchemist.differentgroups").sendPrefixedMessage(player);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (successRate == 100) {
|
||||
instance.getAction().perform(player, "alchemist.max-percentage-dust");
|
||||
instance.getLocale().getMessage("alchemist.maxpercentagedust").sendPrefixedMessage(player);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -261,14 +265,17 @@ public class AlchemistMenu extends FastInv {
|
||||
of("eco_cost", ecoCost),
|
||||
of("exp_cost", expCost)
|
||||
).build(), event -> {
|
||||
if (!instance.getEconomy().has(event.getPlayer(), ecoCost) || getExp(event.getPlayer()) < expCost) {
|
||||
instance.getAction().perform(event.getPlayer(), "alchemist.cannot-afford");
|
||||
if (!instance.getEconomy().hasBalance(event.getPlayer(), ecoCost) || getExp(event.getPlayer()) < expCost) {
|
||||
instance.getLocale().getMessage("alchemist.cannotafford").sendPrefixedMessage(event.getPlayer());
|
||||
return;
|
||||
}
|
||||
|
||||
instance.getEconomy().withdrawPlayer(event.getPlayer(), ecoCost);
|
||||
instance.getEconomy().withdrawBalance(event.getPlayer(), ecoCost);
|
||||
changeExp(event.getPlayer(), -expCost);
|
||||
instance.getAction().perform(event.getPlayer(), "alchemist.success", of("eco_cost", ecoCost), of("exp_cost", expCost));
|
||||
instance.getLocale().getMessage("alchemist.success")
|
||||
.processPlaceholder("ecocost", ecoCost)
|
||||
.processPlaceholder("expcost", expCost)
|
||||
.sendPrefixedMessage(event.getPlayer());
|
||||
|
||||
event.getPlayer().getInventory().addItem(getInventory().getItem(PREVIEW_SLOT));
|
||||
clear(RIGHT_SLOT);
|
@ -13,8 +13,10 @@ import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.songoda.epicenchants.objects.Placeholder.of;
|
||||
import static com.songoda.epicenchants.utils.single.Experience.*;
|
||||
import static com.songoda.epicenchants.utils.single.GeneralUtils.*;
|
||||
import static com.songoda.epicenchants.utils.single.Experience.changeExp;
|
||||
import static com.songoda.epicenchants.utils.single.Experience.getExp;
|
||||
import static com.songoda.epicenchants.utils.single.GeneralUtils.color;
|
||||
import static com.songoda.epicenchants.utils.single.GeneralUtils.getSlots;
|
||||
|
||||
public class EnchanterMenu extends FastInv {
|
||||
private final Map<UUID, Long> DELAY = new HashMap<>();
|
||||
@ -33,7 +35,7 @@ public class EnchanterMenu extends FastInv {
|
||||
.forEach(section -> {
|
||||
int expCost = section.getInt("exp-cost");
|
||||
int ecoCost = section.getInt("eco-cost");
|
||||
int xpLeft = expCost - player.getLevel() < 0 ? 0 : expCost - player.getLevel();
|
||||
int xpLeft = Math.max(expCost - player.getLevel(), 0);
|
||||
double ecoLeft = ecoCost - instance.getEconomy().getBalance(player) < 0 ? 0 : ecoCost - instance.getEconomy().getBalance(player);
|
||||
Group group = instance.getGroupManager().getValue(section.getString("group").toUpperCase())
|
||||
.orElseThrow(() -> new IllegalArgumentException("Invalid group set in enchanter: " + section.getString("group")));
|
||||
@ -49,17 +51,18 @@ public class EnchanterMenu extends FastInv {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!instance.getEconomy().has((player), ecoCost) || getExp(player) < expCost) {
|
||||
instance.getAction().perform(player, "enchanter.cannot-afford");
|
||||
if (!instance.getEconomy().hasBalance((player), ecoCost) || getExp(player) < expCost) {
|
||||
instance.getLocale().getMessage("enchanter.cannotafford").sendPrefixedMessage(player);
|
||||
return;
|
||||
}
|
||||
|
||||
instance.getEconomy().withdrawPlayer(player, ecoCost);
|
||||
instance.getAction().perform(player, "enchanter.success",
|
||||
of("group_name", group.getName()),
|
||||
of("group_color", group.getColor()),
|
||||
of("eco_cost", ecoCost),
|
||||
of("exp_cost", expCost));
|
||||
instance.getEconomy().withdrawBalance(player, ecoCost);
|
||||
instance.getLocale().getMessage("enchanter.success")
|
||||
.processPlaceholder("groupname", group.getName())
|
||||
.processPlaceholder("groupcolor", group.getColor())
|
||||
.processPlaceholder("ecocost", ecoCost)
|
||||
.processPlaceholder("expcost", expCost)
|
||||
.sendPrefixedMessage(player);
|
||||
|
||||
changeExp(player, -expCost);
|
||||
player.getInventory().addItem(instance.getSpecialItems().getMysteryBook(group));
|
@ -3,10 +3,10 @@ package com.songoda.epicenchants.menus;
|
||||
import com.songoda.epicenchants.EpicEnchants;
|
||||
import com.songoda.epicenchants.enums.ItemType;
|
||||
import com.songoda.epicenchants.objects.Enchant;
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.NBTCompound;
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.NBTItem;
|
||||
import com.songoda.epicenchants.utils.objects.FastInv;
|
||||
import com.songoda.epicenchants.utils.objects.ItemBuilder;
|
||||
import de.tr7zw.itemnbtapi.NBTCompound;
|
||||
import de.tr7zw.itemnbtapi.NBTItem;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
@ -14,14 +14,18 @@ import org.bukkit.event.inventory.InventoryType;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.songoda.epicenchants.enums.ItemType.*;
|
||||
import static com.songoda.epicenchants.objects.Placeholder.of;
|
||||
import static com.songoda.epicenchants.utils.single.GeneralUtils.*;
|
||||
import static com.songoda.epicenchants.utils.single.GeneralUtils.color;
|
||||
import static com.songoda.epicenchants.utils.single.GeneralUtils.getSlots;
|
||||
import static java.util.Arrays.stream;
|
||||
|
||||
public class TinkererMenu extends FastInv {
|
||||
@ -53,7 +57,7 @@ public class TinkererMenu extends FastInv {
|
||||
slotMap.keySet().forEach(slot -> getInventory().clear(slot));
|
||||
accepted.set(true);
|
||||
event.getPlayer().closeInventory();
|
||||
instance.getAction().perform(event.getPlayer(), "tinkerer.accepted");
|
||||
instance.getLocale().getMessage("tinkerer.accepted").sendPrefixedMessage(event.getPlayer());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -61,7 +65,7 @@ public class TinkererMenu extends FastInv {
|
||||
int count = (int) stream(event.getPlayer().getInventory().getContents()).filter(i -> isTinkerable(i) != NONE).count();
|
||||
|
||||
if (count == 0) {
|
||||
instance.getAction().perform(event.getPlayer(), "tinkerer.no-items");
|
||||
instance.getLocale().getMessage("tinkerer.noitems").sendPrefixedMessage(event.getPlayer());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -98,7 +102,9 @@ public class TinkererMenu extends FastInv {
|
||||
inventory.setItem(i, itemStack);
|
||||
}
|
||||
|
||||
instance.getAction().perform(event.getPlayer(), "tinkerer.deposited-all", of("amount", amount));
|
||||
instance.getLocale().getMessage("tinkerer.depositedall")
|
||||
.processPlaceholder("amount", amount)
|
||||
.sendPrefixedMessage(event.getPlayer());
|
||||
}
|
||||
});
|
||||
});
|
||||
@ -153,7 +159,7 @@ public class TinkererMenu extends FastInv {
|
||||
});
|
||||
|
||||
if (!accepted.get())
|
||||
instance.getAction().perform(event.getPlayer(), "tinkerer.cancelled");
|
||||
instance.getLocale().getMessage("tinkerer.cancelled").sendPrefixedMessage(event.getPlayer());
|
||||
});
|
||||
}
|
||||
|
||||
@ -172,7 +178,7 @@ public class TinkererMenu extends FastInv {
|
||||
return NONE;
|
||||
}
|
||||
|
||||
if (!itemStack.getEnchantments().isEmpty() || (nbtItem.getCompound("enchants") != null && !nbtItem.getCompound("enchants").getKeys().isEmpty())) {
|
||||
if (!itemStack.getEnchantments().isEmpty() || (nbtItem.getCompound("src/main/resources/enchants") != null && !nbtItem.getCompound("src/main/resources/enchants").getKeys().isEmpty())) {
|
||||
if (getExpAmount(itemStack) == 0) {
|
||||
return NONE;
|
||||
}
|
||||
@ -231,11 +237,11 @@ public class TinkererMenu extends FastInv {
|
||||
|
||||
NBTItem nbtItem = new NBTItem(itemStack);
|
||||
|
||||
if (!nbtItem.hasKey("enchants")) {
|
||||
if (!nbtItem.hasKey("src/main/resources/enchants")) {
|
||||
return total.get();
|
||||
}
|
||||
|
||||
NBTCompound enchantments = nbtItem.getCompound("enchants");
|
||||
NBTCompound enchantments = nbtItem.getCompound("src/main/resources/enchants");
|
||||
|
||||
if (enchantments == null) {
|
||||
return total.get();
|
@ -1,12 +1,12 @@
|
||||
package com.songoda.epicenchants.objects;
|
||||
|
||||
import com.songoda.epicenchants.EpicEnchants;
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.NBTItem;
|
||||
import com.songoda.epicenchants.utils.objects.ItemBuilder;
|
||||
import com.songoda.epicenchants.utils.settings.Setting;
|
||||
import com.songoda.epicenchants.utils.single.GeneralUtils;
|
||||
import com.songoda.epicenchants.utils.single.ItemGroup;
|
||||
import com.songoda.epicenchants.utils.single.RomanNumber;
|
||||
import de.tr7zw.itemnbtapi.NBTItem;
|
||||
import lombok.Builder;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@ -18,13 +18,23 @@ import java.util.stream.Collectors;
|
||||
import static com.songoda.epicenchants.utils.single.GeneralUtils.color;
|
||||
import static java.util.concurrent.ThreadLocalRandom.current;
|
||||
|
||||
@Builder
|
||||
public class BookItem {
|
||||
private EpicEnchants instance;
|
||||
private Material material;
|
||||
private String displayName;
|
||||
private List<String> lore;
|
||||
|
||||
BookItem(EpicEnchants instance, Material material, String displayName, List<String> lore) {
|
||||
this.instance = instance;
|
||||
this.material = material;
|
||||
this.displayName = displayName;
|
||||
this.lore = lore;
|
||||
}
|
||||
|
||||
public static BookItemBuilder builder() {
|
||||
return new BookItemBuilder();
|
||||
}
|
||||
|
||||
public ItemStack get(Enchant enchant) {
|
||||
return get(enchant, current().nextInt(enchant.getMaxLevel()) + 1);
|
||||
}
|
||||
@ -64,7 +74,7 @@ public class BookItem {
|
||||
|
||||
ItemBuilder itemBuilder = new ItemBuilder(material)
|
||||
.name(color(displayName
|
||||
.replace("{level}", "" + (instance.getFileManager().getConfiguration("config").getBoolean("roman-numbers") ? RomanNumber.toRoman(level) : level))
|
||||
.replace("{level}", "" + (Setting.ROMAN.getBoolean() ? RomanNumber.toRoman(level) : level))
|
||||
.replace("{enchant}", "" + enchant.getIdentifier())
|
||||
.replace("{group_color}", enchant.getGroup().getColor())
|
||||
.replace("{group_name}", enchant.getGroup().getName())
|
||||
@ -80,4 +90,42 @@ public class BookItem {
|
||||
|
||||
return nbtItem.getItem();
|
||||
}
|
||||
|
||||
public static class BookItemBuilder {
|
||||
private EpicEnchants instance;
|
||||
private Material material;
|
||||
private String displayName;
|
||||
private List<String> lore;
|
||||
|
||||
BookItemBuilder() {
|
||||
}
|
||||
|
||||
public BookItemBuilder instance(EpicEnchants instance) {
|
||||
this.instance = instance;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BookItemBuilder material(Material material) {
|
||||
this.material = material;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BookItemBuilder displayName(String displayName) {
|
||||
this.displayName = displayName;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BookItemBuilder lore(List<String> lore) {
|
||||
this.lore = lore;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BookItem build() {
|
||||
return new BookItem(instance, material, displayName, lore);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "BookItem.BookItemBuilder(instance=" + this.instance + ", material=" + this.material + ", displayName=" + this.displayName + ", lore=" + this.lore + ")";
|
||||
}
|
||||
}
|
||||
}
|
170
src/main/java/com/songoda/epicenchants/objects/Enchant.java
Normal file
170
src/main/java/com/songoda/epicenchants/objects/Enchant.java
Normal file
@ -0,0 +1,170 @@
|
||||
package com.songoda.epicenchants.objects;
|
||||
|
||||
import com.songoda.epicenchants.effect.EffectExecutor;
|
||||
import com.songoda.epicenchants.enums.EventType;
|
||||
import com.songoda.epicenchants.enums.TriggerType;
|
||||
import com.songoda.epicenchants.utils.single.RomanNumber;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Event;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.songoda.epicenchants.utils.single.GeneralUtils.color;
|
||||
|
||||
public class Enchant {
|
||||
private String identifier;
|
||||
private Group group;
|
||||
private int maxLevel;
|
||||
private Set<String> conflict;
|
||||
//TODO: ISSUES
|
||||
private Set<Material> itemWhitelist;
|
||||
private Set<EffectExecutor> effectExecutors;
|
||||
private List<String> description;
|
||||
private String format;
|
||||
@Nullable private BookItem bookItem;
|
||||
|
||||
Enchant(String identifier, Group group, int maxLevel, Set<String> conflict, Set<Material> itemWhitelist, Set<EffectExecutor> effectExecutors, List<String> description, String format, BookItem bookItem) {
|
||||
this.identifier = identifier;
|
||||
this.group = group;
|
||||
this.maxLevel = maxLevel;
|
||||
this.conflict = conflict;
|
||||
this.itemWhitelist = itemWhitelist;
|
||||
this.effectExecutors = effectExecutors;
|
||||
this.description = description;
|
||||
this.format = format;
|
||||
this.bookItem = bookItem;
|
||||
}
|
||||
|
||||
public static EnchantBuilder builder() {
|
||||
return new EnchantBuilder();
|
||||
}
|
||||
|
||||
public void onAction(@NotNull Player user, @Nullable LivingEntity opponent, Event event, int level, TriggerType triggerType, EventType eventType) {
|
||||
effectExecutors.forEach(effect -> effect.testAndRun(user, opponent, level, triggerType, event, eventType));
|
||||
}
|
||||
|
||||
public BookItem getBook() {
|
||||
return bookItem != null ? bookItem : group.getBookItem();
|
||||
}
|
||||
|
||||
public String getFormat(int level, boolean roman) {
|
||||
String output = format.isEmpty() ? group.getFormat() : format;
|
||||
|
||||
output = output
|
||||
.replace("{level}", "" + (roman ? RomanNumber.toRoman(level) : level))
|
||||
.replace("{enchant}", "" + identifier)
|
||||
.replace("{group_color}", "" + group.getColor());
|
||||
|
||||
return color(output);
|
||||
}
|
||||
|
||||
public String getIdentifier() {
|
||||
return this.identifier;
|
||||
}
|
||||
|
||||
public Group getGroup() {
|
||||
return this.group;
|
||||
}
|
||||
|
||||
public int getMaxLevel() {
|
||||
return this.maxLevel;
|
||||
}
|
||||
|
||||
public Set<String> getConflict() {
|
||||
return this.conflict;
|
||||
}
|
||||
|
||||
public Set<Material> getItemWhitelist() {
|
||||
return this.itemWhitelist;
|
||||
}
|
||||
|
||||
public Set<EffectExecutor> getEffectExecutors() {
|
||||
return this.effectExecutors;
|
||||
}
|
||||
|
||||
public List<String> getDescription() {
|
||||
return this.description;
|
||||
}
|
||||
|
||||
public String getFormat() {
|
||||
return this.format;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public BookItem getBookItem() {
|
||||
return this.bookItem;
|
||||
}
|
||||
|
||||
public static class EnchantBuilder {
|
||||
private String identifier;
|
||||
private Group group;
|
||||
private int maxLevel;
|
||||
private Set<String> conflict;
|
||||
private Set<Material> itemWhitelist;
|
||||
private Set<EffectExecutor> effectExecutors;
|
||||
private List<String> description;
|
||||
private String format;
|
||||
private BookItem bookItem;
|
||||
|
||||
EnchantBuilder() {
|
||||
}
|
||||
|
||||
public Enchant.EnchantBuilder identifier(String identifier) {
|
||||
this.identifier = identifier;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Enchant.EnchantBuilder group(Group group) {
|
||||
this.group = group;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Enchant.EnchantBuilder maxLevel(int maxLevel) {
|
||||
this.maxLevel = maxLevel;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Enchant.EnchantBuilder conflict(Set<String> conflict) {
|
||||
this.conflict = conflict;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Enchant.EnchantBuilder itemWhitelist(Set<Material> itemWhitelist) {
|
||||
this.itemWhitelist = itemWhitelist;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Enchant.EnchantBuilder effectExecutors(Set<EffectExecutor> effectExecutors) {
|
||||
this.effectExecutors = effectExecutors;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Enchant.EnchantBuilder description(List<String> description) {
|
||||
this.description = description;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Enchant.EnchantBuilder format(String format) {
|
||||
this.format = format;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Enchant.EnchantBuilder bookItem(BookItem bookItem) {
|
||||
this.bookItem = bookItem;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Enchant build() {
|
||||
return new Enchant(identifier, group, maxLevel, conflict, itemWhitelist, effectExecutors, description, format, bookItem);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "Enchant.EnchantBuilder(identifier=" + this.identifier + ", group=" + this.group + ", maxLevel=" + this.maxLevel + ", conflict=" + this.conflict + ", itemWhitelist=" + this.itemWhitelist + ", effectExecutors=" + this.effectExecutors + ", description=" + this.description + ", format=" + this.format + ", bookItem=" + this.bookItem + ")";
|
||||
}
|
||||
}
|
||||
}
|
178
src/main/java/com/songoda/epicenchants/objects/Group.java
Normal file
178
src/main/java/com/songoda/epicenchants/objects/Group.java
Normal file
@ -0,0 +1,178 @@
|
||||
package com.songoda.epicenchants.objects;
|
||||
|
||||
public class Group {
|
||||
private String identifier;
|
||||
private String name;
|
||||
private String format;
|
||||
private String color;
|
||||
private String descriptionColor;
|
||||
private int slotsUsed;
|
||||
private BookItem bookItem;
|
||||
private int destroyRateMin, destroyRateMax, successRateMin, successRateMax;
|
||||
private int tinkererExp;
|
||||
private int order;
|
||||
|
||||
Group(String identifier, String name, String format, String color, String descriptionColor, int slotsUsed, BookItem bookItem, int destroyRateMin, int destroyRateMax, int successRateMin, int successRateMax, int tinkererExp, int order) {
|
||||
this.identifier = identifier;
|
||||
this.name = name;
|
||||
this.format = format;
|
||||
this.color = color;
|
||||
this.descriptionColor = descriptionColor;
|
||||
this.slotsUsed = slotsUsed;
|
||||
this.bookItem = bookItem;
|
||||
this.destroyRateMin = destroyRateMin;
|
||||
this.destroyRateMax = destroyRateMax;
|
||||
this.successRateMin = successRateMin;
|
||||
this.successRateMax = successRateMax;
|
||||
this.tinkererExp = tinkererExp;
|
||||
this.order = order;
|
||||
}
|
||||
|
||||
public static GroupBuilder builder() {
|
||||
return new GroupBuilder();
|
||||
}
|
||||
|
||||
public String getIdentifier() {
|
||||
return this.identifier;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public String getFormat() {
|
||||
return this.format;
|
||||
}
|
||||
|
||||
public String getColor() {
|
||||
return this.color;
|
||||
}
|
||||
|
||||
public String getDescriptionColor() {
|
||||
return this.descriptionColor;
|
||||
}
|
||||
|
||||
public int getSlotsUsed() {
|
||||
return this.slotsUsed;
|
||||
}
|
||||
|
||||
public BookItem getBookItem() {
|
||||
return this.bookItem;
|
||||
}
|
||||
|
||||
public int getDestroyRateMin() {
|
||||
return this.destroyRateMin;
|
||||
}
|
||||
|
||||
public int getDestroyRateMax() {
|
||||
return this.destroyRateMax;
|
||||
}
|
||||
|
||||
public int getSuccessRateMin() {
|
||||
return this.successRateMin;
|
||||
}
|
||||
|
||||
public int getSuccessRateMax() {
|
||||
return this.successRateMax;
|
||||
}
|
||||
|
||||
public int getTinkererExp() {
|
||||
return this.tinkererExp;
|
||||
}
|
||||
|
||||
public int getOrder() {
|
||||
return this.order;
|
||||
}
|
||||
|
||||
public static class GroupBuilder {
|
||||
private String identifier;
|
||||
private String name;
|
||||
private String format;
|
||||
private String color;
|
||||
private String descriptionColor;
|
||||
private int slotsUsed;
|
||||
private BookItem bookItem;
|
||||
private int destroyRateMin;
|
||||
private int destroyRateMax;
|
||||
private int successRateMin;
|
||||
private int successRateMax;
|
||||
private int tinkererExp;
|
||||
private int order;
|
||||
|
||||
GroupBuilder() {
|
||||
}
|
||||
|
||||
public Group.GroupBuilder identifier(String identifier) {
|
||||
this.identifier = identifier;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Group.GroupBuilder name(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Group.GroupBuilder format(String format) {
|
||||
this.format = format;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Group.GroupBuilder color(String color) {
|
||||
this.color = color;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Group.GroupBuilder descriptionColor(String descriptionColor) {
|
||||
this.descriptionColor = descriptionColor;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Group.GroupBuilder slotsUsed(int slotsUsed) {
|
||||
this.slotsUsed = slotsUsed;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Group.GroupBuilder bookItem(BookItem bookItem) {
|
||||
this.bookItem = bookItem;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Group.GroupBuilder destroyRateMin(int destroyRateMin) {
|
||||
this.destroyRateMin = destroyRateMin;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Group.GroupBuilder destroyRateMax(int destroyRateMax) {
|
||||
this.destroyRateMax = destroyRateMax;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Group.GroupBuilder successRateMin(int successRateMin) {
|
||||
this.successRateMin = successRateMin;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Group.GroupBuilder successRateMax(int successRateMax) {
|
||||
this.successRateMax = successRateMax;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Group.GroupBuilder tinkererExp(int tinkererExp) {
|
||||
this.tinkererExp = tinkererExp;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Group.GroupBuilder order(int order) {
|
||||
this.order = order;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Group build() {
|
||||
return new Group(identifier, name, format, color, descriptionColor, slotsUsed, bookItem, destroyRateMin, destroyRateMax, successRateMin, successRateMax, tinkererExp, order);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "Group.GroupBuilder(identifier=" + this.identifier + ", name=" + this.name + ", format=" + this.format + ", color=" + this.color + ", descriptionColor=" + this.descriptionColor + ", slotsUsed=" + this.slotsUsed + ", bookItem=" + this.bookItem + ", destroyRateMin=" + this.destroyRateMin + ", destroyRateMax=" + this.destroyRateMax + ", successRateMin=" + this.successRateMin + ", successRateMax=" + this.successRateMax + ", tinkererExp=" + this.tinkererExp + ", order=" + this.order + ")";
|
||||
}
|
||||
}
|
||||
}
|
@ -1,8 +1,5 @@
|
||||
package com.songoda.epicenchants.objects;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public class Placeholder {
|
||||
private String placeholder;
|
||||
private Object toReplace;
|
||||
@ -15,4 +12,12 @@ public class Placeholder {
|
||||
public static Placeholder of(String placeholder, Object toReplace) {
|
||||
return new Placeholder(placeholder, toReplace);
|
||||
}
|
||||
|
||||
public String getPlaceholder() {
|
||||
return placeholder;
|
||||
}
|
||||
|
||||
public Object getToReplace() {
|
||||
return toReplace;
|
||||
}
|
||||
}
|
@ -5,11 +5,11 @@ import com.songoda.epicenchants.enums.EnchantResult;
|
||||
import com.songoda.epicenchants.enums.EventType;
|
||||
import com.songoda.epicenchants.enums.TriggerType;
|
||||
import com.songoda.epicenchants.objects.Enchant;
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.NBTCompound;
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.NBTItem;
|
||||
import com.songoda.epicenchants.utils.objects.ItemBuilder;
|
||||
import com.songoda.epicenchants.utils.settings.Setting;
|
||||
import com.songoda.epicenchants.utils.single.GeneralUtils;
|
||||
import de.tr7zw.itemnbtapi.NBTCompound;
|
||||
import de.tr7zw.itemnbtapi.NBTItem;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
@ -32,7 +32,7 @@ public class EnchantUtils {
|
||||
this.instance = instance;
|
||||
}
|
||||
|
||||
public Pair<ItemStack, EnchantResult> apply(ItemStack itemStack, Enchant enchant, int level, int successRate, int destroyRate) {
|
||||
public Tuple<ItemStack, EnchantResult> apply(ItemStack itemStack, Enchant enchant, int level, int successRate, int destroyRate) {
|
||||
boolean hasProtection = new NBTItem(itemStack).hasKey("protected");
|
||||
|
||||
Map<Enchant, Integer> currentEnchantMap = getEnchants(itemStack);
|
||||
@ -40,15 +40,15 @@ public class EnchantUtils {
|
||||
Set<String> currentConflicts = currentEnchantMap.keySet().stream().map(Enchant::getConflict).flatMap(Collection::stream).collect(Collectors.toSet());
|
||||
|
||||
if (enchant.getConflict().stream().anyMatch(currentIds::contains) || currentConflicts.contains(enchant.getIdentifier())) {
|
||||
return Pair.of(itemStack, CONFLICT);
|
||||
return Tuple.of(itemStack, CONFLICT);
|
||||
}
|
||||
|
||||
if (currentEnchantMap.entrySet().stream().anyMatch(entry -> entry.getKey().equals(enchant) && entry.getValue() == enchant.getMaxLevel())) {
|
||||
return Pair.of(itemStack, MAXED_OUT);
|
||||
return Tuple.of(itemStack, MAXED_OUT);
|
||||
}
|
||||
|
||||
if (currentEnchantMap.entrySet().stream().anyMatch(entry -> entry.getKey().equals(enchant) && entry.getValue() >= level)) {
|
||||
return Pair.of(itemStack, ALREADY_APPLIED);
|
||||
return Tuple.of(itemStack, ALREADY_APPLIED);
|
||||
}
|
||||
|
||||
if (!GeneralUtils.chance(successRate)) {
|
||||
@ -56,11 +56,11 @@ public class EnchantUtils {
|
||||
if (hasProtection) {
|
||||
NBTItem nbtItem = new ItemBuilder(itemStack).removeLore(instance.getSpecialItems().getWhiteScrollLore()).nbt();
|
||||
nbtItem.removeKey("protected");
|
||||
return Pair.of(nbtItem.getItem(), PROTECTED);
|
||||
return Tuple.of(nbtItem.getItem(), PROTECTED);
|
||||
}
|
||||
return Pair.of(new ItemStack(Material.AIR), BROKEN_FAILURE);
|
||||
return Tuple.of(new ItemStack(Material.AIR), BROKEN_FAILURE);
|
||||
}
|
||||
return Pair.of(itemStack, FAILURE);
|
||||
return Tuple.of(itemStack, FAILURE);
|
||||
}
|
||||
|
||||
ItemBuilder itemBuilder = new ItemBuilder(itemStack);
|
||||
@ -69,8 +69,8 @@ public class EnchantUtils {
|
||||
itemBuilder.removeLore(instance.getSpecialItems().getWhiteScrollLore());
|
||||
}
|
||||
|
||||
itemBuilder.removeLore(enchant.getFormat(-1, instance.getFileManager().getConfiguration("config").getBoolean("roman-numbers")).replace("-1", "").trim());
|
||||
itemBuilder.addLore(enchant.getFormat(level, instance.getFileManager().getConfiguration("config").getBoolean("roman-numbers")));
|
||||
itemBuilder.removeLore(enchant.getFormat(-1, Setting.ROMAN.getBoolean()).replace("-1", "").trim());
|
||||
itemBuilder.addLore(enchant.getFormat(level, Setting.ROMAN.getBoolean()));
|
||||
|
||||
if (hasProtection) {
|
||||
itemBuilder.addLore(instance.getSpecialItems().getWhiteScrollLore());
|
||||
@ -78,12 +78,12 @@ public class EnchantUtils {
|
||||
|
||||
NBTItem nbtItem = itemBuilder.nbt();
|
||||
|
||||
nbtItem.addCompound("enchants");
|
||||
nbtItem.addCompound("src/main/resources/enchants");
|
||||
|
||||
NBTCompound compound = nbtItem.getCompound("enchants");
|
||||
NBTCompound compound = nbtItem.getCompound("src/main/resources/enchants");
|
||||
compound.setInteger(enchant.getIdentifier(), level);
|
||||
|
||||
return Pair.of(nbtItem.getItem(), SUCCESS);
|
||||
return Tuple.of(nbtItem.getItem(), SUCCESS);
|
||||
}
|
||||
|
||||
public Map<Enchant, Integer> getEnchants(ItemStack itemStack) {
|
||||
@ -93,11 +93,11 @@ public class EnchantUtils {
|
||||
|
||||
NBTItem nbtItem = new NBTItem(itemStack);
|
||||
|
||||
if (!nbtItem.hasNBTData() || !nbtItem.hasKey("enchants")) {
|
||||
if (!nbtItem.hasNBTData() || !nbtItem.hasKey("src/main/resources/enchants")) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
NBTCompound compound = nbtItem.getCompound("enchants");
|
||||
NBTCompound compound = nbtItem.getCompound("src/main/resources/enchants");
|
||||
|
||||
if (compound == null) {
|
||||
return Collections.emptyMap();
|
||||
@ -128,11 +128,11 @@ public class EnchantUtils {
|
||||
|
||||
NBTItem nbtItem = new NBTItem(itemStack);
|
||||
|
||||
if (nbtItem.getCompound("enchants") == null || nbtItem.getCompound("enchants").getInteger(enchant.getIdentifier()) == null) {
|
||||
if (nbtItem.getCompound("src/main/resources/enchants") == null || nbtItem.getCompound("src/main/resources/enchants").getInteger(enchant.getIdentifier()) == null) {
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
nbtItem.getCompound("enchants").removeKey(enchant.getIdentifier());
|
||||
nbtItem.getCompound("src/main/resources/enchants").removeKey(enchant.getIdentifier());
|
||||
ItemBuilder output = new ItemBuilder(nbtItem.getItem());
|
||||
output.removeLore(enchant.getFormat().replace("{level}", "").trim());
|
||||
return output.build();
|
53
src/main/java/com/songoda/epicenchants/utils/Methods.java
Normal file
53
src/main/java/com/songoda/epicenchants/utils/Methods.java
Normal file
@ -0,0 +1,53 @@
|
||||
package com.songoda.epicenchants.utils;
|
||||
|
||||
import com.songoda.epicenchants.EpicEnchants;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
public class Methods {
|
||||
|
||||
public static ItemStack getGlass() {
|
||||
EpicEnchants instance = EpicEnchants.getInstance();
|
||||
return Methods.getGlass(instance.getConfig().getBoolean("Interfaces.Replace Glass Type 1 With Rainbow Glass"), instance.getConfig().getInt("Interfaces.Glass Type 1"));
|
||||
}
|
||||
|
||||
public static ItemStack getBackgroundGlass(boolean type) {
|
||||
EpicEnchants instance = EpicEnchants.getInstance();
|
||||
if (type)
|
||||
return getGlass(false, instance.getConfig().getInt("Interfaces.Glass Type 2"));
|
||||
else
|
||||
return getGlass(false, instance.getConfig().getInt("Interfaces.Glass Type 3"));
|
||||
}
|
||||
|
||||
private static ItemStack getGlass(Boolean rainbow, int type) {
|
||||
int randomNum = 1 + (int) (Math.random() * 6);
|
||||
ItemStack glass;
|
||||
if (rainbow) {
|
||||
glass = new ItemStack(EpicEnchants.getInstance().isServerVersionAtLeast(ServerVersion.V1_13) ?
|
||||
Material.LEGACY_STAINED_GLASS_PANE : Material.valueOf("STAINED_GLASS_PANE"), 1, (short) randomNum);
|
||||
} else {
|
||||
glass = new ItemStack(EpicEnchants.getInstance().isServerVersionAtLeast(ServerVersion.V1_13) ?
|
||||
Material.LEGACY_STAINED_GLASS_PANE : Material.valueOf("STAINED_GLASS_PANE"), 1, (short) type);
|
||||
}
|
||||
ItemMeta glassmeta = glass.getItemMeta();
|
||||
glassmeta.setDisplayName("§l");
|
||||
glass.setItemMeta(glassmeta);
|
||||
return glass;
|
||||
}
|
||||
|
||||
public static String formatText(String text) {
|
||||
if (text == null || text.equals(""))
|
||||
return "";
|
||||
return formatText(text, false);
|
||||
}
|
||||
|
||||
public static String formatText(String text, boolean cap) {
|
||||
if (text == null || text.equals(""))
|
||||
return "";
|
||||
if (cap)
|
||||
text = text.substring(0, 1).toUpperCase() + text.substring(1);
|
||||
return ChatColor.translateAlternateColorCodes('&', text);
|
||||
}
|
||||
}
|
695
src/main/java/com/songoda/epicenchants/utils/Metrics.java
Normal file
695
src/main/java/com/songoda/epicenchants/utils/Metrics.java
Normal file
@ -0,0 +1,695 @@
|
||||
package com.songoda.epicenchants.utils;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||
import org.bukkit.plugin.ServicePriority;
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import java.io.*;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.logging.Level;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
/**
|
||||
* bStats collects some data for plugin authors.
|
||||
* <p>
|
||||
* Check out https://bStats.org/ to learn more about bStats!
|
||||
*/
|
||||
@SuppressWarnings({"WeakerAccess", "unused"})
|
||||
public class Metrics {
|
||||
|
||||
static {
|
||||
// You can use the property to disable the check in your test environment
|
||||
if (System.getProperty("bstats.relocatecheck") == null || !System.getProperty("bstats.relocatecheck").equals("false")) {
|
||||
// Maven's Relocate is clever and changes strings, too. So we have to use this little "trick" ... :D
|
||||
final String defaultPackage = new String(
|
||||
new byte[]{'o', 'r', 'g', '.', 'b', 's', 't', 'a', 't', 's', '.', 'b', 'u', 'k', 'k', 'i', 't'});
|
||||
final String examplePackage = new String(new byte[]{'y', 'o', 'u', 'r', '.', 'p', 'a', 'c', 'k', 'a', 'g', 'e'});
|
||||
// We want to make sure nobody just copy & pastes the example and use the wrong package names
|
||||
if (Metrics.class.getPackage().getName().equals(defaultPackage) || Metrics.class.getPackage().getName().equals(examplePackage)) {
|
||||
throw new IllegalStateException("bStats Metrics class has not been relocated correctly!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The version of this bStats class
|
||||
public static final int B_STATS_VERSION = 1;
|
||||
|
||||
// The url to which the data is sent
|
||||
private static final String URL = "https://bStats.org/submitData/bukkit";
|
||||
|
||||
// Is bStats enabled on this server?
|
||||
private boolean enabled;
|
||||
|
||||
// Should failed requests be logged?
|
||||
private static boolean logFailedRequests;
|
||||
|
||||
// Should the sent data be logged?
|
||||
private static boolean logSentData;
|
||||
|
||||
// Should the response text be logged?
|
||||
private static boolean logResponseStatusText;
|
||||
|
||||
// The uuid of the server
|
||||
private static String serverUUID;
|
||||
|
||||
// The plugin
|
||||
private final Plugin plugin;
|
||||
|
||||
// A list with all custom charts
|
||||
private final List<CustomChart> charts = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param plugin The plugin which stats should be submitted.
|
||||
*/
|
||||
public Metrics(Plugin plugin) {
|
||||
if (plugin == null) {
|
||||
throw new IllegalArgumentException("Plugin cannot be null!");
|
||||
}
|
||||
this.plugin = plugin;
|
||||
|
||||
// Get the config file
|
||||
File bStatsFolder = new File(plugin.getDataFolder().getParentFile(), "bStats");
|
||||
File configFile = new File(bStatsFolder, "config.yml");
|
||||
YamlConfiguration config = YamlConfiguration.loadConfiguration(configFile);
|
||||
|
||||
// Check if the config file exists
|
||||
if (!config.isSet("serverUuid")) {
|
||||
|
||||
// Add default values
|
||||
config.addDefault("enabled", true);
|
||||
// Every server gets it's unique random id.
|
||||
config.addDefault("serverUuid", UUID.randomUUID().toString());
|
||||
// Should failed request be logged?
|
||||
config.addDefault("logFailedRequests", false);
|
||||
// Should the sent data be logged?
|
||||
config.addDefault("logSentData", false);
|
||||
// Should the response text be logged?
|
||||
config.addDefault("logResponseStatusText", false);
|
||||
|
||||
// Inform the server owners about bStats
|
||||
config.options().header(
|
||||
"bStats collects some data for plugin authors like how many servers are using their plugins.\n" +
|
||||
"To honor their work, you should not disable it.\n" +
|
||||
"This has nearly blacklist effect on the server performance!\n" +
|
||||
"Check out https://bStats.org/ to learn more :)"
|
||||
).copyDefaults(true);
|
||||
try {
|
||||
config.save(configFile);
|
||||
} catch (IOException ignored) { }
|
||||
}
|
||||
|
||||
// Load the data
|
||||
enabled = config.getBoolean("enabled", true);
|
||||
serverUUID = config.getString("serverUuid");
|
||||
logFailedRequests = config.getBoolean("logFailedRequests", false);
|
||||
logSentData = config.getBoolean("logSentData", false);
|
||||
logResponseStatusText = config.getBoolean("logResponseStatusText", false);
|
||||
|
||||
if (enabled) {
|
||||
boolean found = false;
|
||||
// Search for all other bStats Metrics classes to see if we are the first one
|
||||
for (Class<?> service : Bukkit.getServicesManager().getKnownServices()) {
|
||||
try {
|
||||
service.getField("B_STATS_VERSION"); // Our identifier :)
|
||||
found = true; // We aren't the first
|
||||
break;
|
||||
} catch (NoSuchFieldException ignored) { }
|
||||
}
|
||||
// Register our service
|
||||
Bukkit.getServicesManager().register(Metrics.class, this, plugin, ServicePriority.Normal);
|
||||
if (!found) {
|
||||
// We are the first!
|
||||
startSubmitting();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if bStats is enabled.
|
||||
*
|
||||
* @return Whether bStats is enabled or not.
|
||||
*/
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a custom chart.
|
||||
*
|
||||
* @param chart The chart to add.
|
||||
*/
|
||||
public void addCustomChart(CustomChart chart) {
|
||||
if (chart == null) {
|
||||
throw new IllegalArgumentException("Chart cannot be null!");
|
||||
}
|
||||
charts.add(chart);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the Scheduler which submits our data every 30 minutes.
|
||||
*/
|
||||
private void startSubmitting() {
|
||||
final Timer timer = new Timer(true); // We use a timer cause the Bukkit scheduler is affected by server lags
|
||||
timer.scheduleAtFixedRate(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!plugin.isEnabled()) { // Plugin was disabled
|
||||
timer.cancel();
|
||||
return;
|
||||
}
|
||||
// Nevertheless we want our code to run in the Bukkit main thread, so we have to use the Bukkit scheduler
|
||||
// Don't be afraid! The connection to the bStats server is still async, only the stats collection is sync ;)
|
||||
Bukkit.getScheduler().runTask(plugin, () -> submitData());
|
||||
}
|
||||
}, 1000 * 60 * 5, 1000 * 60 * 30);
|
||||
// Submit the data every 30 minutes, first time after 5 minutes to give other plugins enough time to start
|
||||
// WARNING: Changing the frequency has blacklist effect but your plugin WILL be blocked/deleted!
|
||||
// WARNING: Just don't do it!
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the plugin specific data.
|
||||
* This method is called using Reflection.
|
||||
*
|
||||
* @return The plugin specific data.
|
||||
*/
|
||||
public JSONObject getPluginData() {
|
||||
JSONObject data = new JSONObject();
|
||||
|
||||
String pluginName = plugin.getDescription().getName();
|
||||
String pluginVersion = plugin.getDescription().getVersion();
|
||||
|
||||
data.put("pluginName", pluginName); // Append the name of the plugin
|
||||
data.put("pluginVersion", pluginVersion); // Append the version of the plugin
|
||||
JSONArray customCharts = new JSONArray();
|
||||
for (CustomChart customChart : charts) {
|
||||
// Add the data of the custom charts
|
||||
JSONObject chart = customChart.getRequestJsonObject();
|
||||
if (chart == null) { // If the chart is null, we skip it
|
||||
continue;
|
||||
}
|
||||
customCharts.add(chart);
|
||||
}
|
||||
data.put("customCharts", customCharts);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the server specific data.
|
||||
*
|
||||
* @return The server specific data.
|
||||
*/
|
||||
private JSONObject getServerData() {
|
||||
// Minecraft specific data
|
||||
int playerAmount;
|
||||
try {
|
||||
// Around MC 1.8 the return type was changed to a collection from an array,
|
||||
// This fixes java.lang.NoSuchMethodError: org.bukkit.Bukkit.getOnlinePlayers()Ljava/util/Collection;
|
||||
Method onlinePlayersMethod = Class.forName("org.bukkit.Server").getMethod("getOnlinePlayers");
|
||||
playerAmount = onlinePlayersMethod.getReturnType().equals(Collection.class)
|
||||
? ((Collection<?>) onlinePlayersMethod.invoke(Bukkit.getServer())).size()
|
||||
: ((Player[]) onlinePlayersMethod.invoke(Bukkit.getServer())).length;
|
||||
} catch (Exception e) {
|
||||
playerAmount = Bukkit.getOnlinePlayers().size(); // Just use the new method if the Reflection failed
|
||||
}
|
||||
int onlineMode = Bukkit.getOnlineMode() ? 1 : 0;
|
||||
String bukkitVersion = Bukkit.getVersion();
|
||||
|
||||
// OS/Java specific data
|
||||
String javaVersion = System.getProperty("java.version");
|
||||
String osName = System.getProperty("os.name");
|
||||
String osArch = System.getProperty("os.arch");
|
||||
String osVersion = System.getProperty("os.version");
|
||||
int coreCount = Runtime.getRuntime().availableProcessors();
|
||||
|
||||
JSONObject data = new JSONObject();
|
||||
|
||||
data.put("serverUUID", serverUUID);
|
||||
|
||||
data.put("playerAmount", playerAmount);
|
||||
data.put("onlineMode", onlineMode);
|
||||
data.put("bukkitVersion", bukkitVersion);
|
||||
|
||||
data.put("javaVersion", javaVersion);
|
||||
data.put("osName", osName);
|
||||
data.put("osArch", osArch);
|
||||
data.put("osVersion", osVersion);
|
||||
data.put("coreCount", coreCount);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Collects the data and sends it afterwards.
|
||||
*/
|
||||
private void submitData() {
|
||||
final JSONObject data = getServerData();
|
||||
|
||||
JSONArray pluginData = new JSONArray();
|
||||
// Search for all other bStats Metrics classes to get their plugin data
|
||||
for (Class<?> service : Bukkit.getServicesManager().getKnownServices()) {
|
||||
try {
|
||||
service.getField("B_STATS_VERSION"); // Our identifier :)
|
||||
|
||||
for (RegisteredServiceProvider<?> provider : Bukkit.getServicesManager().getRegistrations(service)) {
|
||||
try {
|
||||
pluginData.add(provider.getService().getMethod("getPluginData").invoke(provider.getProvider()));
|
||||
} catch (NullPointerException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) { }
|
||||
}
|
||||
} catch (NoSuchFieldException ignored) { }
|
||||
}
|
||||
|
||||
data.put("plugins", pluginData);
|
||||
|
||||
// Create a new thread for the connection to the bStats server
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
// Send the data
|
||||
sendData(plugin, data);
|
||||
} catch (Exception e) {
|
||||
// Something went wrong! :(
|
||||
if (logFailedRequests) {
|
||||
plugin.getLogger().log(Level.WARNING, "Could not submit plugin stats of " + plugin.getName(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the data to the bStats server.
|
||||
*
|
||||
* @param plugin Any plugin. It's just used to get a logger instance.
|
||||
* @param data The data to send.
|
||||
* @throws Exception If the request failed.
|
||||
*/
|
||||
private static void sendData(Plugin plugin, JSONObject data) throws Exception {
|
||||
if (data == null) {
|
||||
throw new IllegalArgumentException("Data cannot be null!");
|
||||
}
|
||||
if (Bukkit.isPrimaryThread()) {
|
||||
throw new IllegalAccessException("This method must not be called from the main thread!");
|
||||
}
|
||||
if (logSentData) {
|
||||
plugin.getLogger().info("Sending data to bStats: " + data.toString());
|
||||
}
|
||||
HttpsURLConnection connection = (HttpsURLConnection) new URL(URL).openConnection();
|
||||
|
||||
// Compress the data to save bandwidth
|
||||
byte[] compressedData = compress(data.toString());
|
||||
|
||||
// Add headers
|
||||
connection.setRequestMethod("POST");
|
||||
connection.addRequestProperty("Accept", "application/json");
|
||||
connection.addRequestProperty("Connection", "close");
|
||||
connection.addRequestProperty("Content-Encoding", "gzip"); // We gzip our request
|
||||
connection.addRequestProperty("Content-Length", String.valueOf(compressedData.length));
|
||||
connection.setRequestProperty("Content-Type", "application/json"); // We send our data in JSON format
|
||||
connection.setRequestProperty("User-Agent", "MC-Server/" + B_STATS_VERSION);
|
||||
|
||||
// Send data
|
||||
connection.setDoOutput(true);
|
||||
DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream());
|
||||
outputStream.write(compressedData);
|
||||
outputStream.flush();
|
||||
outputStream.close();
|
||||
|
||||
InputStream inputStream = connection.getInputStream();
|
||||
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
String line;
|
||||
while ((line = bufferedReader.readLine()) != null) {
|
||||
builder.append(line);
|
||||
}
|
||||
bufferedReader.close();
|
||||
if (logResponseStatusText) {
|
||||
plugin.getLogger().info("Sent data to bStats and received response: " + builder.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gzips the given String.
|
||||
*
|
||||
* @param str The string to gzip.
|
||||
* @return The gzipped String.
|
||||
* @throws IOException If the compression failed.
|
||||
*/
|
||||
private static byte[] compress(final String str) throws IOException {
|
||||
if (str == null) {
|
||||
return null;
|
||||
}
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
GZIPOutputStream gzip = new GZIPOutputStream(outputStream);
|
||||
gzip.write(str.getBytes(StandardCharsets.UTF_8));
|
||||
gzip.close();
|
||||
return outputStream.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom chart.
|
||||
*/
|
||||
public static abstract class CustomChart {
|
||||
|
||||
// The id of the chart
|
||||
final String chartId;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
*/
|
||||
CustomChart(String chartId) {
|
||||
if (chartId == null || chartId.isEmpty()) {
|
||||
throw new IllegalArgumentException("ChartId cannot be null or empty!");
|
||||
}
|
||||
this.chartId = chartId;
|
||||
}
|
||||
|
||||
private JSONObject getRequestJsonObject() {
|
||||
JSONObject chart = new JSONObject();
|
||||
chart.put("chartId", chartId);
|
||||
try {
|
||||
JSONObject data = getChartData();
|
||||
if (data == null) {
|
||||
// If the data is null we don't send the chart.
|
||||
return null;
|
||||
}
|
||||
chart.put("data", data);
|
||||
} catch (Throwable t) {
|
||||
if (logFailedRequests) {
|
||||
Bukkit.getLogger().log(Level.WARNING, "Failed to get data for custom chart with id " + chartId, t);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return chart;
|
||||
}
|
||||
|
||||
protected abstract JSONObject getChartData() throws Exception;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom simple pie.
|
||||
*/
|
||||
public static class SimplePie extends CustomChart {
|
||||
|
||||
private final Callable<String> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public SimplePie(String chartId, Callable<String> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JSONObject getChartData() throws Exception {
|
||||
JSONObject data = new JSONObject();
|
||||
String value = callable.call();
|
||||
if (value == null || value.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
data.put("value", value);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom advanced pie.
|
||||
*/
|
||||
public static class AdvancedPie extends CustomChart {
|
||||
|
||||
private final Callable<Map<String, Integer>> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public AdvancedPie(String chartId, Callable<Map<String, Integer>> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JSONObject getChartData() throws Exception {
|
||||
JSONObject data = new JSONObject();
|
||||
JSONObject values = new JSONObject();
|
||||
Map<String, Integer> map = callable.call();
|
||||
if (map == null || map.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
boolean allSkipped = true;
|
||||
for (Map.Entry<String, Integer> entry : map.entrySet()) {
|
||||
if (entry.getValue() == 0) {
|
||||
continue; // Skip this invalid
|
||||
}
|
||||
allSkipped = false;
|
||||
values.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
if (allSkipped) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
data.put("values", values);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom drilldown pie.
|
||||
*/
|
||||
public static class DrilldownPie extends CustomChart {
|
||||
|
||||
private final Callable<Map<String, Map<String, Integer>>> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public DrilldownPie(String chartId, Callable<Map<String, Map<String, Integer>>> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JSONObject getChartData() throws Exception {
|
||||
JSONObject data = new JSONObject();
|
||||
JSONObject values = new JSONObject();
|
||||
Map<String, Map<String, Integer>> map = callable.call();
|
||||
if (map == null || map.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
boolean reallyAllSkipped = true;
|
||||
for (Map.Entry<String, Map<String, Integer>> entryValues : map.entrySet()) {
|
||||
JSONObject value = new JSONObject();
|
||||
boolean allSkipped = true;
|
||||
for (Map.Entry<String, Integer> valueEntry : map.get(entryValues.getKey()).entrySet()) {
|
||||
value.put(valueEntry.getKey(), valueEntry.getValue());
|
||||
allSkipped = false;
|
||||
}
|
||||
if (!allSkipped) {
|
||||
reallyAllSkipped = false;
|
||||
values.put(entryValues.getKey(), value);
|
||||
}
|
||||
}
|
||||
if (reallyAllSkipped) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
data.put("values", values);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom single line chart.
|
||||
*/
|
||||
public static class SingleLineChart extends CustomChart {
|
||||
|
||||
private final Callable<Integer> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public SingleLineChart(String chartId, Callable<Integer> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JSONObject getChartData() throws Exception {
|
||||
JSONObject data = new JSONObject();
|
||||
int value = callable.call();
|
||||
if (value == 0) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
data.put("value", value);
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom multi line chart.
|
||||
*/
|
||||
public static class MultiLineChart extends CustomChart {
|
||||
|
||||
private final Callable<Map<String, Integer>> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public MultiLineChart(String chartId, Callable<Map<String, Integer>> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JSONObject getChartData() throws Exception {
|
||||
JSONObject data = new JSONObject();
|
||||
JSONObject values = new JSONObject();
|
||||
Map<String, Integer> map = callable.call();
|
||||
if (map == null || map.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
boolean allSkipped = true;
|
||||
for (Map.Entry<String, Integer> entry : map.entrySet()) {
|
||||
if (entry.getValue() == 0) {
|
||||
continue; // Skip this invalid
|
||||
}
|
||||
allSkipped = false;
|
||||
values.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
if (allSkipped) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
data.put("values", values);
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom simple bar chart.
|
||||
*/
|
||||
public static class SimpleBarChart extends CustomChart {
|
||||
|
||||
private final Callable<Map<String, Integer>> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public SimpleBarChart(String chartId, Callable<Map<String, Integer>> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JSONObject getChartData() throws Exception {
|
||||
JSONObject data = new JSONObject();
|
||||
JSONObject values = new JSONObject();
|
||||
Map<String, Integer> map = callable.call();
|
||||
if (map == null || map.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
for (Map.Entry<String, Integer> entry : map.entrySet()) {
|
||||
JSONArray categoryValues = new JSONArray();
|
||||
categoryValues.add(entry.getValue());
|
||||
values.put(entry.getKey(), categoryValues);
|
||||
}
|
||||
data.put("values", values);
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom advanced bar chart.
|
||||
*/
|
||||
public static class AdvancedBarChart extends CustomChart {
|
||||
|
||||
private final Callable<Map<String, int[]>> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public AdvancedBarChart(String chartId, Callable<Map<String, int[]>> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JSONObject getChartData() throws Exception {
|
||||
JSONObject data = new JSONObject();
|
||||
JSONObject values = new JSONObject();
|
||||
Map<String, int[]> map = callable.call();
|
||||
if (map == null || map.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
boolean allSkipped = true;
|
||||
for (Map.Entry<String, int[]> entry : map.entrySet()) {
|
||||
if (entry.getValue().length == 0) {
|
||||
continue; // Skip this invalid
|
||||
}
|
||||
allSkipped = false;
|
||||
JSONArray categoryValues = new JSONArray();
|
||||
for (int categoryValue : entry.getValue()) {
|
||||
categoryValues.add(categoryValue);
|
||||
}
|
||||
values.put(entry.getKey(), categoryValues);
|
||||
}
|
||||
if (allSkipped) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
data.put("values", values);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package com.songoda.epicenchants.utils;
|
||||
|
||||
public enum ServerVersion {
|
||||
|
||||
UNKNOWN("unknown_server_version"),
|
||||
V1_7("org.bukkit.craftbukkit.v1_7"),
|
||||
V1_8("org.bukkit.craftbukkit.v1_8"),
|
||||
V1_9("org.bukkit.craftbukkit.v1_9"),
|
||||
V1_10("org.bukkit.craftbukkit.v1_10"),
|
||||
V1_11("org.bukkit.craftbukkit.v1_11"),
|
||||
V1_12("org.bukkit.craftbukkit.v1_12"),
|
||||
V1_13("org.bukkit.craftbukkit.v1_13"),
|
||||
V1_14("org.bukkit.craftbukkit.v1_14");
|
||||
|
||||
|
||||
private final String packagePrefix;
|
||||
|
||||
private ServerVersion(String packagePrefix) {
|
||||
this.packagePrefix = packagePrefix;
|
||||
}
|
||||
|
||||
public static ServerVersion fromPackageName(String packageName) {
|
||||
for (ServerVersion version : values())
|
||||
if (packageName.startsWith(version.packagePrefix)) return version;
|
||||
return ServerVersion.UNKNOWN;
|
||||
}
|
||||
}
|
@ -2,8 +2,9 @@ package com.songoda.epicenchants.utils;
|
||||
|
||||
import com.songoda.epicenchants.EpicEnchants;
|
||||
import com.songoda.epicenchants.objects.Group;
|
||||
import com.songoda.epicenchants.utils.itemnbtapi.NBTItem;
|
||||
import com.songoda.epicenchants.utils.objects.ItemBuilder;
|
||||
import de.tr7zw.itemnbtapi.NBTItem;
|
||||
import com.songoda.epicenchants.utils.settings.Setting;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@ -34,8 +35,8 @@ public class SpecialItems {
|
||||
}
|
||||
|
||||
public ItemStack getBlackScroll(Integer amount, Integer chance) {
|
||||
int successRate = chance == null ? ThreadLocalRandom.current().nextInt(instance.getFileManager().getConfiguration("config").getInt("rates.black-scroll-min"), instance.getFileManager().getConfiguration("config").getInt("rates.black-scroll-max") + 1) : chance;
|
||||
NBTItem nbtItem = new ItemBuilder(instance.getFileManager().getConfiguration("items/special-items").getConfigurationSection("black-scroll"), of("success-rate", successRate)).nbt();
|
||||
int successRate = chance == null ? ThreadLocalRandom.current().nextInt(Setting.BLACK_MIN.getInt(), Setting.BLACK_MAX.getInt() + 1) : chance;
|
||||
NBTItem nbtItem = new ItemBuilder(instance.getFileManager().getConfiguration("items/special-items").getConfigurationSection("black-scroll"), of("success-rate", successRate)).nbt ();
|
||||
|
||||
nbtItem.setBoolean("black-scroll", true);
|
||||
nbtItem.setInteger("success-rate", successRate);
|
23
src/main/java/com/songoda/epicenchants/utils/Tuple.java
Normal file
23
src/main/java/com/songoda/epicenchants/utils/Tuple.java
Normal file
@ -0,0 +1,23 @@
|
||||
package com.songoda.epicenchants.utils;
|
||||
|
||||
public class Tuple<key, value> {
|
||||
private key x;
|
||||
private value y;
|
||||
|
||||
public Tuple(key x, value y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public key getLeft() {
|
||||
return this.x;
|
||||
}
|
||||
|
||||
public value getRight() {
|
||||
return this.y;
|
||||
}
|
||||
|
||||
public static <key, value> Tuple of(key x, value y) {
|
||||
return new Tuple(x, y);
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package com.songoda.epicbuckets.utils.itemnbtapi;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
public enum ClassWrapper {
|
||||
CRAFT_ITEMSTACK("org.bukkit.craftbukkit.", ".inventory.CraftItemStack"),
|
||||
CRAFT_ENTITY("org.bukkit.craftbukkit.", ".entity.CraftEntity"),
|
||||
CRAFT_WORLD("org.bukkit.craftbukkit.", ".CraftWorld"),
|
||||
NMS_NBTBASE("net.minecraft.server.", ".NBTBase"),
|
||||
NMS_NBTTAGSTRING("net.minecraft.server.", ".NBTTagString"),
|
||||
NMS_ITEMSTACK("net.minecraft.server.", ".ItemStack"),
|
||||
NMS_NBTTAGCOMPOUND("net.minecraft.server.", ".NBTTagCompound"),
|
||||
NMS_NBTTAGLIST("net.minecraft.server.", ".NBTTagList"),
|
||||
NMS_NBTCOMPRESSEDSTREAMTOOLS("net.minecraft.server.", ".NBTCompressedStreamTools"),
|
||||
NMS_MOJANGSONPARSER("net.minecraft.server.", ".MojangsonParser"),
|
||||
NMS_TILEENTITY("net.minecraft.server.", ".TileEntity"),
|
||||
NMS_BLOCKPOSITION("net.minecraft.server.", ".BlockPosition"),
|
||||
NMS_WORLD("net.minecraft.server.", ".WorldServer"),
|
||||
NMS_ENTITY("net.minecraft.server.", ".Entity"),;
|
||||
|
||||
|
||||
private Class<?> clazz;
|
||||
|
||||
ClassWrapper(String pre, String suffix) {
|
||||
try {
|
||||
String version = Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3];
|
||||
clazz = Class.forName(pre + version + suffix);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public Class<?> getClazz() {
|
||||
return clazz;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,200 @@
|
||||
package com.songoda.epicbuckets.utils.itemnbtapi;
|
||||
|
||||
import com.songoda.epicbuckets.utils.itemnbtapi.utils.MinecraftVersion;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
public class NBTCompound {
|
||||
|
||||
private String compundName;
|
||||
private NBTCompound parent;
|
||||
|
||||
protected NBTCompound(NBTCompound owner, String name) {
|
||||
this.compundName = name;
|
||||
this.parent = owner;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return compundName;
|
||||
}
|
||||
|
||||
protected Object getCompound() {
|
||||
return parent.getCompound();
|
||||
}
|
||||
|
||||
protected void setCompound(Object compound) {
|
||||
parent.setCompound(compound);
|
||||
}
|
||||
|
||||
public NBTCompound getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
public void mergeCompound(NBTCompound comp) {
|
||||
NBTReflectionUtil.addOtherNBTCompound(this, comp);
|
||||
}
|
||||
|
||||
public void setString(String key, String value) {
|
||||
NBTReflectionUtil.setData(this, ReflectionMethod.COMPOUND_SET_STRING, key, value);
|
||||
}
|
||||
|
||||
public String getString(String key) {
|
||||
return (String) NBTReflectionUtil.getData(this, ReflectionMethod.COMPOUND_GET_STRING, key);
|
||||
}
|
||||
|
||||
protected String getContent(String key) {
|
||||
return NBTReflectionUtil.getContent(this, key);
|
||||
}
|
||||
|
||||
public void setInteger(String key, Integer value) {
|
||||
NBTReflectionUtil.setData(this, ReflectionMethod.COMPOUND_SET_INT, key, value);
|
||||
}
|
||||
|
||||
public Integer getInteger(String key) {
|
||||
return (Integer) NBTReflectionUtil.getData(this, ReflectionMethod.COMPOUND_GET_INT, key);
|
||||
}
|
||||
|
||||
public void setDouble(String key, Double value) {
|
||||
NBTReflectionUtil.setData(this, ReflectionMethod.COMPOUND_SET_DOUBLE, key, value);
|
||||
}
|
||||
|
||||
public Double getDouble(String key) {
|
||||
return (Double) NBTReflectionUtil.getData(this, ReflectionMethod.COMPOUND_GET_DOUBLE, key);
|
||||
}
|
||||
|
||||
public void setByte(String key, Byte value) {
|
||||
NBTReflectionUtil.setData(this, ReflectionMethod.COMPOUND_SET_BYTE, key, value);
|
||||
}
|
||||
|
||||
public Byte getByte(String key) {
|
||||
return (Byte) NBTReflectionUtil.getData(this, ReflectionMethod.COMPOUND_GET_BYTE, key);
|
||||
}
|
||||
|
||||
public void setShort(String key, Short value) {
|
||||
NBTReflectionUtil.setData(this, ReflectionMethod.COMPOUND_SET_SHORT, key, value);
|
||||
}
|
||||
|
||||
public Short getShort(String key) {
|
||||
return (Short) NBTReflectionUtil.getData(this, ReflectionMethod.COMPOUND_GET_SHORT, key);
|
||||
}
|
||||
|
||||
public void setLong(String key, Long value) {
|
||||
NBTReflectionUtil.setData(this, ReflectionMethod.COMPOUND_SET_LONG, key, value);
|
||||
}
|
||||
|
||||
public Long getLong(String key) {
|
||||
return (Long) NBTReflectionUtil.getData(this, ReflectionMethod.COMPOUND_GET_LONG, key);
|
||||
}
|
||||
|
||||
public void setFloat(String key, Float value) {
|
||||
NBTReflectionUtil.setData(this, ReflectionMethod.COMPOUND_SET_FLOAT, key, value);
|
||||
}
|
||||
|
||||
public Float getFloat(String key) {
|
||||
return (Float) NBTReflectionUtil.getData(this, ReflectionMethod.COMPOUND_GET_FLOAT, key);
|
||||
}
|
||||
|
||||
public void setByteArray(String key, byte[] value) {
|
||||
NBTReflectionUtil.setData(this, ReflectionMethod.COMPOUND_SET_BYTEARRAY, key, value);
|
||||
}
|
||||
|
||||
public byte[] getByteArray(String key) {
|
||||
return (byte[]) NBTReflectionUtil.getData(this, ReflectionMethod.COMPOUND_GET_BYTEARRAY, key);
|
||||
}
|
||||
|
||||
public void setIntArray(String key, int[] value) {
|
||||
NBTReflectionUtil.setData(this, ReflectionMethod.COMPOUND_SET_INTARRAY, key, value);
|
||||
}
|
||||
|
||||
public int[] getIntArray(String key) {
|
||||
return (int[]) NBTReflectionUtil.getData(this, ReflectionMethod.COMPOUND_GET_INTARRAY, key);
|
||||
}
|
||||
|
||||
public void setBoolean(String key, Boolean value) {
|
||||
NBTReflectionUtil.setData(this, ReflectionMethod.COMPOUND_SET_BOOLEAN, key, value);
|
||||
}
|
||||
|
||||
protected void set(String key, Object val) {
|
||||
NBTReflectionUtil.set(this, key, val);
|
||||
}
|
||||
|
||||
public Boolean getBoolean(String key) {
|
||||
return (Boolean) NBTReflectionUtil.getData(this, ReflectionMethod.COMPOUND_GET_BOOLEAN, key);
|
||||
}
|
||||
|
||||
public void setObject(String key, Object value) {
|
||||
NBTReflectionUtil.setObject(this, key, value);
|
||||
}
|
||||
|
||||
public <T> T getObject(String key, Class<T> type) {
|
||||
return NBTReflectionUtil.getObject(this, key, type);
|
||||
}
|
||||
|
||||
public Boolean hasKey(String key) {
|
||||
Boolean b = (Boolean) NBTReflectionUtil.getData(this, ReflectionMethod.COMPOUND_HAS_KEY, key);
|
||||
if (b == null) return false;
|
||||
return b;
|
||||
}
|
||||
|
||||
public void removeKey(String key) {
|
||||
NBTReflectionUtil.remove(this, key);
|
||||
}
|
||||
|
||||
public Set<String> getKeys() {
|
||||
return NBTReflectionUtil.getKeys(this);
|
||||
}
|
||||
|
||||
public NBTCompound addCompound(String name) {
|
||||
if (getType(name) == NBTType.NBTTagCompound) return getCompound(name);
|
||||
NBTReflectionUtil.addNBTTagCompound(this, name);
|
||||
return getCompound(name);
|
||||
}
|
||||
|
||||
public NBTCompound getCompound(String name) {
|
||||
NBTCompound next = new NBTCompound(this, name);
|
||||
if (NBTReflectionUtil.valideCompound(next)) return next;
|
||||
return null;
|
||||
}
|
||||
|
||||
public NBTList getList(String name, NBTType type) {
|
||||
return NBTReflectionUtil.getList(this, name, type);
|
||||
}
|
||||
|
||||
public NBTType getType(String name) {
|
||||
if (MinecraftVersion.getVersion() == MinecraftVersion.MC1_7_R4) return null;
|
||||
Object o = NBTReflectionUtil.getData(this, ReflectionMethod.COMPOUND_GET_TYPE, name);
|
||||
if (o == null) return null;
|
||||
return NBTType.valueOf((byte) o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder result = new StringBuilder();
|
||||
for (String key : getKeys()) {
|
||||
result.append(toString(key));
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
public String toString(String key) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
NBTCompound compound = this;
|
||||
while (compound.getParent() != null) {
|
||||
result.append(" ");
|
||||
compound = compound.getParent();
|
||||
}
|
||||
if (this.getType(key) == NBTType.NBTTagCompound) {
|
||||
return this.getCompound(key).toString();
|
||||
} else {
|
||||
return result + "-" + key + ": " + getContent(key) + System.lineSeparator();
|
||||
}
|
||||
}
|
||||
|
||||
public String asNBTString() {
|
||||
Object comp = NBTReflectionUtil.gettoCompount(getCompound(), this);
|
||||
if (comp == null) return "{}";
|
||||
return comp.toString();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package com.songoda.epicbuckets.utils.itemnbtapi;
|
||||
|
||||
public class NBTContainer extends NBTCompound {
|
||||
|
||||
private Object nbt;
|
||||
|
||||
public NBTContainer() {
|
||||
super(null, null);
|
||||
nbt = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
||||
}
|
||||
|
||||
protected NBTContainer(Object nbt) {
|
||||
super(null, null);
|
||||
this.nbt = nbt;
|
||||
}
|
||||
|
||||
public NBTContainer(String nbtString) throws IllegalArgumentException {
|
||||
super(null, null);
|
||||
try {
|
||||
nbt = ReflectionMethod.PARSE_NBT.run(null, nbtString);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
throw new IllegalArgumentException("Malformed Json: " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
protected Object getCompound() {
|
||||
return nbt;
|
||||
}
|
||||
|
||||
protected void setCompound(Object tag) {
|
||||
nbt = tag;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package com.songoda.epicbuckets.utils.itemnbtapi;
|
||||
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
public class NBTEntity extends NBTCompound {
|
||||
|
||||
private final Entity ent;
|
||||
|
||||
public NBTEntity(Entity entity) {
|
||||
super(null, null);
|
||||
ent = entity;
|
||||
}
|
||||
|
||||
protected Object getCompound() {
|
||||
return NBTReflectionUtil.getEntityNBTTagCompound(NBTReflectionUtil.getNMSEntity(ent));
|
||||
}
|
||||
|
||||
protected void setCompound(Object compound) {
|
||||
NBTReflectionUtil.setEntityNBTTag(compound, NBTReflectionUtil.getNMSEntity(ent));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
package com.songoda.epicbuckets.utils.itemnbtapi;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class NBTFile extends NBTCompound {
|
||||
|
||||
private final File file;
|
||||
private Object nbt;
|
||||
|
||||
public NBTFile(File file) throws IOException {
|
||||
super(null, null);
|
||||
this.file = file;
|
||||
if (file.exists()) {
|
||||
FileInputStream inputsteam = new FileInputStream(file);
|
||||
nbt = NBTReflectionUtil.readNBTFile(inputsteam);
|
||||
} else {
|
||||
nbt = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
||||
save();
|
||||
}
|
||||
}
|
||||
|
||||
public void save() throws IOException {
|
||||
if (!file.exists()) {
|
||||
file.getParentFile().mkdirs();
|
||||
file.createNewFile();
|
||||
}
|
||||
FileOutputStream outStream = new FileOutputStream(file);
|
||||
NBTReflectionUtil.saveNBTFile(nbt, outStream);
|
||||
}
|
||||
|
||||
public File getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
protected Object getCompound() {
|
||||
return nbt;
|
||||
}
|
||||
|
||||
protected void setCompound(Object compound) {
|
||||
nbt = compound;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
package com.songoda.epicbuckets.utils.itemnbtapi;
|
||||
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class NBTItem extends NBTCompound {
|
||||
|
||||
private ItemStack bukkitItem;
|
||||
|
||||
public NBTItem(ItemStack item) {
|
||||
super(null, null);
|
||||
if (item == null) {
|
||||
throw new NullPointerException("ItemStack can't be null!");
|
||||
}
|
||||
bukkitItem = item.clone();
|
||||
}
|
||||
|
||||
public static NBTContainer convertItemtoNBT(ItemStack item) {
|
||||
return NBTReflectionUtil.convertNMSItemtoNBTCompound(ReflectionMethod.ITEMSTACK_NMSCOPY.run(null, item));
|
||||
}
|
||||
|
||||
public static ItemStack convertNBTtoItem(NBTCompound comp) {
|
||||
return (ItemStack) ReflectionMethod.ITEMSTACK_BUKKITMIRROR.run(null, NBTReflectionUtil.convertNBTCompoundtoNMSItem(comp));
|
||||
}
|
||||
|
||||
protected Object getCompound() {
|
||||
return NBTReflectionUtil.getItemRootNBTTagCompound(ReflectionMethod.ITEMSTACK_NMSCOPY.run(null, bukkitItem));
|
||||
}
|
||||
|
||||
protected void setCompound(Object compound) {
|
||||
Object stack = ReflectionMethod.ITEMSTACK_NMSCOPY.run(null, bukkitItem);
|
||||
ReflectionMethod.ITEMSTACK_SET_TAG.run(stack, compound);
|
||||
bukkitItem = (ItemStack) ReflectionMethod.ITEMSTACK_BUKKITMIRROR.run(null, stack);
|
||||
}
|
||||
|
||||
public ItemStack getItem() {
|
||||
return bukkitItem;
|
||||
}
|
||||
|
||||
protected void setItem(ItemStack item) {
|
||||
bukkitItem = item;
|
||||
}
|
||||
|
||||
/**
|
||||
* This may return true even when the NBT is empty.
|
||||
*
|
||||
* @return Does the ItemStack have a NBTCompound.
|
||||
*/
|
||||
public boolean hasNBTData() {
|
||||
return getCompound() != null;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,127 @@
|
||||
package com.songoda.epicbuckets.utils.itemnbtapi;
|
||||
|
||||
import com.songoda.epicbuckets.utils.itemnbtapi.utils.MinecraftVersion;
|
||||
|
||||
public class NBTList {
|
||||
|
||||
private String listName;
|
||||
private NBTCompound parent;
|
||||
private NBTType type;
|
||||
private Object listObject;
|
||||
|
||||
protected NBTList(NBTCompound owner, String name, NBTType type, Object list) {
|
||||
parent = owner;
|
||||
listName = name;
|
||||
this.type = type;
|
||||
this.listObject = list;
|
||||
if (!(type == NBTType.NBTTagString || type == NBTType.NBTTagCompound)) {
|
||||
System.err.println("List types != String/Compound are currently not implemented!");
|
||||
}
|
||||
}
|
||||
|
||||
protected void save() {
|
||||
parent.set(listName, listObject);
|
||||
}
|
||||
|
||||
public NBTListCompound addCompound() {
|
||||
if (type != NBTType.NBTTagCompound) {
|
||||
new Throwable("Using Compound method on a non Compound list!").printStackTrace();
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
Object compound = ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz().newInstance();
|
||||
if (MinecraftVersion.getVersion().getVersionId() >= MinecraftVersion.MC1_14_R1.getVersionId()) {
|
||||
ReflectionMethod.LIST_ADD.run(listObject, 0, compound);
|
||||
} else {
|
||||
ReflectionMethod.LEGACY_LIST_ADD.run(listObject, compound);
|
||||
}
|
||||
return new NBTListCompound(this, compound);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public NBTListCompound getCompound(int id) {
|
||||
if (type != NBTType.NBTTagCompound) {
|
||||
new Throwable("Using Compound method on a non Compound list!").printStackTrace();
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
Object compound = ReflectionMethod.LIST_GET.run(listObject, id);
|
||||
return new NBTListCompound(this, compound);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getString(int i) {
|
||||
if (type != NBTType.NBTTagString) {
|
||||
new Throwable("Using String method on a non String list!").printStackTrace();
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return (String) ReflectionMethod.LIST_GET_STRING.run(listObject, i);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void addString(String s) {
|
||||
if (type != NBTType.NBTTagString) {
|
||||
new Throwable("Using String method on a non String list!").printStackTrace();
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (MinecraftVersion.getVersion().getVersionId() >= MinecraftVersion.MC1_14_R1.getVersionId()) {
|
||||
ReflectionMethod.LIST_ADD.run(listObject, 0,
|
||||
ClassWrapper.NMS_NBTTAGSTRING.getClazz().getConstructor(String.class).newInstance(s));
|
||||
} else {
|
||||
ReflectionMethod.LEGACY_LIST_ADD.run(listObject,
|
||||
ClassWrapper.NMS_NBTTAGSTRING.getClazz().getConstructor(String.class).newInstance(s));
|
||||
}
|
||||
save();
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void setString(int i, String s) {
|
||||
if (type != NBTType.NBTTagString) {
|
||||
new Throwable("Using String method on a non String list!").printStackTrace();
|
||||
return;
|
||||
}
|
||||
try {
|
||||
ReflectionMethod.LIST_SET.run(listObject, i,
|
||||
ClassWrapper.NMS_NBTTAGSTRING.getClazz().getConstructor(String.class).newInstance(s));
|
||||
save();
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void remove(int i) {
|
||||
try {
|
||||
ReflectionMethod.LIST_REMOVE_KEY.run(listObject, i);
|
||||
save();
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public int size() {
|
||||
try {
|
||||
return (int) ReflectionMethod.LIST_SIZE.run(listObject);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public NBTType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,102 @@
|
||||
package com.songoda.epicbuckets.utils.itemnbtapi;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class NBTListCompound {
|
||||
|
||||
private NBTList owner;
|
||||
private Object compound;
|
||||
|
||||
protected NBTListCompound(NBTList parent, Object obj) {
|
||||
owner = parent;
|
||||
compound = obj;
|
||||
}
|
||||
|
||||
public void setString(String key, String value) {
|
||||
if (value == null) {
|
||||
remove(key);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
compound.getClass().getMethod("setString", String.class, String.class).invoke(compound, key, value);
|
||||
owner.save();
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void setInteger(String key, int value) {
|
||||
try {
|
||||
compound.getClass().getMethod("setInt", String.class, int.class).invoke(compound, key, value);
|
||||
owner.save();
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public int getInteger(String value) {
|
||||
try {
|
||||
return (int) compound.getClass().getMethod("getInt", String.class).invoke(compound, value);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void setDouble(String key, double value) {
|
||||
try {
|
||||
compound.getClass().getMethod("setDouble", String.class, double.class).invoke(compound, key, value);
|
||||
owner.save();
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public double getDouble(String key) {
|
||||
try {
|
||||
return (double) compound.getClass().getMethod("getDouble", String.class).invoke(compound, key);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
public String getString(String key) {
|
||||
try {
|
||||
return (String) compound.getClass().getMethod("getString", String.class).invoke(compound, key);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public boolean hasKey(String key) {
|
||||
try {
|
||||
return (boolean) compound.getClass().getMethod("hasKey", String.class).invoke(compound, key);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Set<String> getKeys() {
|
||||
try {
|
||||
return (Set<String>) ReflectionMethod.LISTCOMPOUND_GET_KEYS.run(compound);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return new HashSet<>();
|
||||
}
|
||||
|
||||
public void remove(String key) {
|
||||
try {
|
||||
compound.getClass().getMethod("remove", String.class).invoke(compound, key);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,347 @@
|
||||
package com.songoda.epicbuckets.utils.itemnbtapi;
|
||||
|
||||
import com.songoda.epicbuckets.utils.itemnbtapi.utils.GsonWrapper;
|
||||
import com.songoda.epicbuckets.utils.itemnbtapi.utils.MinecraftVersion;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Set;
|
||||
import java.util.Stack;
|
||||
|
||||
public class NBTReflectionUtil {
|
||||
|
||||
public static Object getNMSEntity(Entity entity) {
|
||||
try {
|
||||
return ReflectionMethod.CRAFT_ENTITY_GET_HANDLE.run(ClassWrapper.CRAFT_ENTITY.getClazz().cast(entity));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Object readNBTFile(FileInputStream stream) {
|
||||
try {
|
||||
return ReflectionMethod.NBTFILE_READ.run(null, stream);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Object saveNBTFile(Object nbt, FileOutputStream stream) {
|
||||
try {
|
||||
return ReflectionMethod.NBTFILE_WRITE.run(null, nbt, stream);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public static Object getItemRootNBTTagCompound(Object nmsitem) {
|
||||
@SuppressWarnings("rawtypes")
|
||||
Class clazz = nmsitem.getClass();
|
||||
Method method;
|
||||
try {
|
||||
method = clazz.getMethod("getTag");
|
||||
Object answer = method.invoke(nmsitem);
|
||||
return answer;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public static Object convertNBTCompoundtoNMSItem(NBTCompound nbtcompound) {
|
||||
@SuppressWarnings("rawtypes")
|
||||
Class clazz = ClassWrapper.NMS_ITEMSTACK.getClazz();
|
||||
try {
|
||||
if (MinecraftVersion.getVersion().getVersionId() >= MinecraftVersion.MC1_12_R1.getVersionId()) {
|
||||
Constructor<?> constructor = clazz.getConstructor(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz());
|
||||
constructor.setAccessible(true);
|
||||
return constructor.newInstance(nbtcompound.getCompound());
|
||||
} else {
|
||||
Method method = clazz.getMethod("createStack", ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz());
|
||||
method.setAccessible(true);
|
||||
return method.invoke(null, nbtcompound.getCompound());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public static NBTContainer convertNMSItemtoNBTCompound(Object nmsitem) {
|
||||
@SuppressWarnings("rawtypes")
|
||||
Class clazz = nmsitem.getClass();
|
||||
Method method;
|
||||
try {
|
||||
method = clazz.getMethod("save", ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz());
|
||||
Object answer = method.invoke(nmsitem, ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance());
|
||||
return new NBTContainer(answer);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Object getEntityNBTTagCompound(Object NMSEntity) {
|
||||
try {
|
||||
Object nbt = ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz().newInstance();
|
||||
Object answer = ReflectionMethod.NMS_ENTITY_GET_NBT.run(NMSEntity, nbt);
|
||||
if (answer == null)
|
||||
answer = nbt;
|
||||
return answer;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Object setEntityNBTTag(Object NBTTag, Object NMSEntity) {
|
||||
try {
|
||||
ReflectionMethod.NMS_ENTITY_SET_NBT.run(NMSEntity, NBTTag);
|
||||
return NMSEntity;
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Object getTileEntityNBTTagCompound(BlockState tile) {
|
||||
try {
|
||||
Object pos = ObjectCreator.NMS_BLOCKPOSITION.getInstance(tile.getX(), tile.getY(), tile.getZ());
|
||||
Object cworld = ClassWrapper.CRAFT_WORLD.getClazz().cast(tile.getWorld());
|
||||
Object nmsworld = ReflectionMethod.CRAFT_WORLD_GET_HANDLE.run(cworld);
|
||||
Object o = ReflectionMethod.NMS_WORLD_GET_TILEENTITY.run(nmsworld, pos);
|
||||
Object tag = ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz().newInstance();
|
||||
Object answer = ReflectionMethod.TILEENTITY_GET_NBT.run(o, tag);
|
||||
if (answer == null)
|
||||
answer = tag;
|
||||
return answer;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void setTileEntityNBTTagCompound(BlockState tile, Object comp) {
|
||||
try {
|
||||
Object pos = ObjectCreator.NMS_BLOCKPOSITION.getInstance(tile.getX(), tile.getY(), tile.getZ());
|
||||
Object cworld = ClassWrapper.CRAFT_WORLD.getClazz().cast(tile.getWorld());
|
||||
Object nmsworld = ReflectionMethod.CRAFT_WORLD_GET_HANDLE.run(cworld);
|
||||
Object o = ReflectionMethod.NMS_WORLD_GET_TILEENTITY.run(nmsworld, pos);
|
||||
ReflectionMethod.TILEENTITY_SET_NBT.run(o, comp);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Object getSubNBTTagCompound(Object compound, String name) {
|
||||
@SuppressWarnings("rawtypes")
|
||||
Class c = compound.getClass();
|
||||
Method method;
|
||||
try {
|
||||
method = c.getMethod("getCompound", String.class);
|
||||
Object answer = method.invoke(compound, name);
|
||||
return answer;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void addNBTTagCompound(NBTCompound comp, String name) {
|
||||
if (name == null) {
|
||||
remove(comp, name);
|
||||
return;
|
||||
}
|
||||
Object nbttag = comp.getCompound();
|
||||
if (nbttag == null) {
|
||||
nbttag = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
||||
}
|
||||
if (!valideCompound(comp)) return;
|
||||
Object workingtag = gettoCompount(nbttag, comp);
|
||||
Method method;
|
||||
try {
|
||||
method = workingtag.getClass().getMethod("set", String.class, ClassWrapper.NMS_NBTBASE.getClazz());
|
||||
method.invoke(workingtag, name, ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz().newInstance());
|
||||
comp.setCompound(nbttag);
|
||||
return;
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
public static Boolean valideCompound(NBTCompound comp) {
|
||||
Object root = comp.getCompound();
|
||||
if (root == null) {
|
||||
root = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
||||
}
|
||||
return (gettoCompount(root, comp)) != null;
|
||||
}
|
||||
|
||||
static Object gettoCompount(Object nbttag, NBTCompound comp) {
|
||||
Stack<String> structure = new Stack<>();
|
||||
while (comp.getParent() != null) {
|
||||
structure.add(comp.getName());
|
||||
comp = comp.getParent();
|
||||
}
|
||||
while (!structure.isEmpty()) {
|
||||
nbttag = getSubNBTTagCompound(nbttag, structure.pop());
|
||||
if (nbttag == null) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return nbttag;
|
||||
}
|
||||
|
||||
public static void addOtherNBTCompound(NBTCompound comp, NBTCompound nbtcompound) {
|
||||
Object rootnbttag = comp.getCompound();
|
||||
if (rootnbttag == null) {
|
||||
rootnbttag = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
||||
}
|
||||
if (!valideCompound(comp)) return;
|
||||
Object workingtag = gettoCompount(rootnbttag, comp);
|
||||
try {
|
||||
ReflectionMethod.COMPOUND_ADD.run(workingtag, nbtcompound.getCompound());
|
||||
comp.setCompound(rootnbttag);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static String getContent(NBTCompound comp, String key) {
|
||||
Object rootnbttag = comp.getCompound();
|
||||
if (rootnbttag == null) {
|
||||
rootnbttag = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
||||
}
|
||||
if (!valideCompound(comp)) return null;
|
||||
Object workingtag = gettoCompount(rootnbttag, comp);
|
||||
Method method;
|
||||
try {
|
||||
method = workingtag.getClass().getMethod("get", String.class);
|
||||
return method.invoke(workingtag, key).toString();
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void set(NBTCompound comp, String key, Object val) {
|
||||
if (val == null) {
|
||||
remove(comp, key);
|
||||
return;
|
||||
}
|
||||
Object rootnbttag = comp.getCompound();
|
||||
if (rootnbttag == null) {
|
||||
rootnbttag = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
||||
}
|
||||
if (!valideCompound(comp)) {
|
||||
new Throwable("InvalideCompound").printStackTrace();
|
||||
return;
|
||||
}
|
||||
Object workingtag = gettoCompount(rootnbttag, comp);
|
||||
Method method;
|
||||
try {
|
||||
method = workingtag.getClass().getMethod("set", String.class, ClassWrapper.NMS_NBTBASE.getClazz());
|
||||
method.invoke(workingtag, key, val);
|
||||
comp.setCompound(rootnbttag);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static NBTList getList(NBTCompound comp, String key, NBTType type) {
|
||||
Object rootnbttag = comp.getCompound();
|
||||
if (rootnbttag == null) {
|
||||
rootnbttag = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
||||
}
|
||||
if (!valideCompound(comp)) return null;
|
||||
Object workingtag = gettoCompount(rootnbttag, comp);
|
||||
Method method;
|
||||
try {
|
||||
method = workingtag.getClass().getMethod("getList", String.class, int.class);
|
||||
return new NBTList(comp, key, type, method.invoke(workingtag, key, type.getId()));
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void setObject(NBTCompound comp, String key, Object value) {
|
||||
if (!MinecraftVersion.hasGsonSupport()) return;
|
||||
try {
|
||||
String json = GsonWrapper.getString(value);
|
||||
setData(comp, ReflectionMethod.COMPOUND_SET_STRING, key, json);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T getObject(NBTCompound comp, String key, Class<T> type) {
|
||||
if (!MinecraftVersion.hasGsonSupport()) return null;
|
||||
String json = (String) getData(comp, ReflectionMethod.COMPOUND_GET_STRING, key);
|
||||
if (json == null) {
|
||||
return null;
|
||||
}
|
||||
return GsonWrapper.deserializeJson(json, type);
|
||||
}
|
||||
|
||||
public static void remove(NBTCompound comp, String key) {
|
||||
Object rootnbttag = comp.getCompound();
|
||||
if (rootnbttag == null) {
|
||||
rootnbttag = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
||||
}
|
||||
if (!valideCompound(comp)) return;
|
||||
Object workingtag = gettoCompount(rootnbttag, comp);
|
||||
ReflectionMethod.COMPOUND_REMOVE_KEY.run(workingtag, key);
|
||||
comp.setCompound(rootnbttag);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Set<String> getKeys(NBTCompound comp) {
|
||||
Object rootnbttag = comp.getCompound();
|
||||
if (rootnbttag == null) {
|
||||
rootnbttag = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
||||
}
|
||||
if (!valideCompound(comp)) return null;
|
||||
Object workingtag = gettoCompount(rootnbttag, comp);
|
||||
return (Set<String>) ReflectionMethod.COMPOUND_GET_KEYS.run(workingtag);
|
||||
}
|
||||
|
||||
public static void setData(NBTCompound comp, ReflectionMethod type, String key, Object data) {
|
||||
if (data == null) {
|
||||
remove(comp, key);
|
||||
return;
|
||||
}
|
||||
Object rootnbttag = comp.getCompound();
|
||||
if (rootnbttag == null) {
|
||||
rootnbttag = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
||||
}
|
||||
if (!valideCompound(comp)) return;
|
||||
Object workingtag = gettoCompount(rootnbttag, comp);
|
||||
type.run(workingtag, key, data);
|
||||
comp.setCompound(rootnbttag);
|
||||
}
|
||||
|
||||
public static Object getData(NBTCompound comp, ReflectionMethod type, String key) {
|
||||
Object rootnbttag = comp.getCompound();
|
||||
if (rootnbttag == null) {
|
||||
return null;
|
||||
}
|
||||
if (!valideCompound(comp)) return null;
|
||||
Object workingtag = gettoCompount(rootnbttag, comp);
|
||||
return type.run(workingtag, key);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package com.songoda.epicbuckets.utils.itemnbtapi;
|
||||
|
||||
import org.bukkit.block.BlockState;
|
||||
|
||||
public class NBTTileEntity extends NBTCompound {
|
||||
|
||||
private final BlockState tile;
|
||||
|
||||
public NBTTileEntity(BlockState tile) {
|
||||
super(null, null);
|
||||
this.tile = tile;
|
||||
}
|
||||
|
||||
protected Object getCompound() {
|
||||
return NBTReflectionUtil.getTileEntityNBTTagCompound(tile);
|
||||
}
|
||||
|
||||
protected void setCompound(Object compound) {
|
||||
NBTReflectionUtil.setTileEntityNBTTagCompound(tile, compound);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package com.songoda.epicbuckets.utils.itemnbtapi;
|
||||
|
||||
public enum NBTType {
|
||||
NBTTagEnd(0),
|
||||
NBTTagByte(1),
|
||||
NBTTagShort(2),
|
||||
NBTTagInt(3),
|
||||
NBTTagLong(4),
|
||||
NBTTagFloat(5),
|
||||
NBTTagDouble(6),
|
||||
NBTTagByteArray(7),
|
||||
NBTTagIntArray(11),
|
||||
NBTTagString(8),
|
||||
NBTTagList(9),
|
||||
NBTTagCompound(10);
|
||||
|
||||
private final int id;
|
||||
|
||||
NBTType(int i) {
|
||||
id = i;
|
||||
}
|
||||
|
||||
public static NBTType valueOf(int id) {
|
||||
for (NBTType t : values())
|
||||
if (t.getId() == id)
|
||||
return t;
|
||||
return NBTType.NBTTagEnd;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package com.songoda.epicbuckets.utils.itemnbtapi;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
public enum ObjectCreator {
|
||||
NMS_NBTTAGCOMPOUND(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()),
|
||||
NMS_BLOCKPOSITION(ClassWrapper.NMS_BLOCKPOSITION.getClazz(), int.class, int.class, int.class);
|
||||
|
||||
private Constructor<?> construct;
|
||||
|
||||
ObjectCreator(Class<?> clazz, Class<?>... args) {
|
||||
try {
|
||||
construct = clazz.getConstructor(args);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public Object getInstance(Object... args) {
|
||||
try {
|
||||
return construct.newInstance(args);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,128 @@
|
||||
package com.songoda.epicbuckets.utils.itemnbtapi;
|
||||
|
||||
import com.songoda.epicbuckets.utils.itemnbtapi.utils.MinecraftVersion;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public enum ReflectionMethod {
|
||||
|
||||
COMPOUND_SET_FLOAT(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class, float.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setFloat")),
|
||||
COMPOUND_SET_STRING(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class, String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setString")),
|
||||
COMPOUND_SET_INT(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class, int.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setInt")),
|
||||
COMPOUND_SET_BYTEARRAY(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class, byte[].class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setByteArray")),
|
||||
COMPOUND_SET_INTARRAY(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class, int[].class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setIntArray")),
|
||||
COMPOUND_SET_LONG(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class, long.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setLong")),
|
||||
COMPOUND_SET_SHORT(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class, short.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setShort")),
|
||||
COMPOUND_SET_BYTE(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class, byte.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setByte")),
|
||||
COMPOUND_SET_DOUBLE(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class, double.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setDouble")),
|
||||
COMPOUND_SET_BOOLEAN(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class, boolean.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setBoolean")),
|
||||
COMPOUND_ADD(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "a")), //FIXME: No Spigot mapping!
|
||||
|
||||
COMPOUND_GET_FLOAT(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getFloat")),
|
||||
COMPOUND_GET_STRING(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getString")),
|
||||
COMPOUND_GET_INT(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getInt")),
|
||||
COMPOUND_GET_BYTEARRAY(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getByteArray")),
|
||||
COMPOUND_GET_INTARRAY(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getIntArray")),
|
||||
COMPOUND_GET_LONG(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getLong")),
|
||||
COMPOUND_GET_SHORT(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getShort")),
|
||||
COMPOUND_GET_BYTE(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getByte")),
|
||||
COMPOUND_GET_DOUBLE(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getDouble")),
|
||||
COMPOUND_GET_BOOLEAN(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getBoolean")),
|
||||
|
||||
COMPOUND_REMOVE_KEY(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "remove")),
|
||||
COMPOUND_HAS_KEY(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "hasKey")),
|
||||
COMPOUND_GET_TYPE(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_8_R3, new Since(MinecraftVersion.MC1_8_R3, "b"), new Since(MinecraftVersion.MC1_9_R1, "d")), //FIXME: No Spigot mapping!
|
||||
COMPOUND_GET_KEYS(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "c"), new Since(MinecraftVersion.MC1_13_R1, "getKeys")),
|
||||
|
||||
LISTCOMPOUND_GET_KEYS(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "c"), new Since(MinecraftVersion.MC1_13_R1, "getKeys")),
|
||||
LIST_REMOVE_KEY(ClassWrapper.NMS_NBTTAGLIST.getClazz(), new Class[]{int.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "a"), new Since(MinecraftVersion.MC1_9_R1, "remove")),
|
||||
LIST_SIZE(ClassWrapper.NMS_NBTTAGLIST.getClazz(), new Class[]{}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "size")),
|
||||
LIST_SET(ClassWrapper.NMS_NBTTAGLIST.getClazz(), new Class[]{int.class, ClassWrapper.NMS_NBTBASE.getClazz()}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "a"), new Since(MinecraftVersion.MC1_13_R1, "set")),
|
||||
LEGACY_LIST_ADD(ClassWrapper.NMS_NBTTAGLIST.getClazz(), new Class[]{ClassWrapper.NMS_NBTBASE.getClazz()}, MinecraftVersion.MC1_7_R4, MinecraftVersion.MC1_13_R2, new Since(MinecraftVersion.MC1_7_R4, "add")),
|
||||
LIST_ADD(ClassWrapper.NMS_NBTTAGLIST.getClazz(), new Class[]{int.class, ClassWrapper.NMS_NBTBASE.getClazz()}, MinecraftVersion.MC1_14_R1, new Since(MinecraftVersion.MC1_14_R1, "add")),
|
||||
LIST_GET_STRING(ClassWrapper.NMS_NBTTAGLIST.getClazz(), new Class[]{int.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getString")),
|
||||
LIST_GET(ClassWrapper.NMS_NBTTAGLIST.getClazz(), new Class[]{int.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "get")),
|
||||
|
||||
ITEMSTACK_SET_TAG(ClassWrapper.NMS_ITEMSTACK.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setTag")),
|
||||
ITEMSTACK_NMSCOPY(ClassWrapper.CRAFT_ITEMSTACK.getClazz(), new Class[]{ItemStack.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "asNMSCopy")),
|
||||
ITEMSTACK_BUKKITMIRROR(ClassWrapper.CRAFT_ITEMSTACK.getClazz(), new Class[]{ClassWrapper.NMS_ITEMSTACK.getClazz()}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "asCraftMirror")),
|
||||
|
||||
CRAFT_WORLD_GET_HANDLE(ClassWrapper.CRAFT_WORLD.getClazz(), new Class[]{}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getHandle")),
|
||||
NMS_WORLD_GET_TILEENTITY(ClassWrapper.NMS_WORLD.getClazz(), new Class[]{ClassWrapper.NMS_BLOCKPOSITION.getClazz()}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getTileEntity")),
|
||||
|
||||
TILEENTITY_GET_NBT(ClassWrapper.NMS_TILEENTITY.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_8_R3, new Since(MinecraftVersion.MC1_8_R3, "b"), new Since(MinecraftVersion.MC1_9_R1, "save")),
|
||||
TILEENTITY_SET_NBT(ClassWrapper.NMS_TILEENTITY.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_8_R3, new Since(MinecraftVersion.MC1_8_R3, "a"), new Since(MinecraftVersion.MC1_12_R1, "load")),
|
||||
|
||||
CRAFT_ENTITY_GET_HANDLE(ClassWrapper.CRAFT_ENTITY.getClazz(), new Class[]{}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getHandle")),
|
||||
NMS_ENTITY_SET_NBT(ClassWrapper.NMS_ENTITY.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_8_R3, new Since(MinecraftVersion.MC1_8_R3, "f")), //FIXME: No Spigot mapping!
|
||||
NMS_ENTITY_GET_NBT(ClassWrapper.NMS_ENTITY.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_8_R3, new Since(MinecraftVersion.MC1_8_R3, "e"), new Since(MinecraftVersion.MC1_12_R1, "save")),
|
||||
|
||||
NBTFILE_READ(ClassWrapper.NMS_NBTCOMPRESSEDSTREAMTOOLS.getClazz(), new Class[]{InputStream.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "a")), //FIXME: No Spigot mapping!
|
||||
NBTFILE_WRITE(ClassWrapper.NMS_NBTCOMPRESSEDSTREAMTOOLS.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), OutputStream.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "a")), //FIXME: No Spigot mapping!
|
||||
|
||||
|
||||
PARSE_NBT(ClassWrapper.NMS_MOJANGSONPARSER.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "parse")),
|
||||
|
||||
;
|
||||
|
||||
private MinecraftVersion removedAfter;
|
||||
private Since targetVersion;
|
||||
private Method method;
|
||||
private boolean loaded = false;
|
||||
private boolean compatible = false;
|
||||
|
||||
ReflectionMethod(Class<?> targetClass, Class<?>[] args, MinecraftVersion addedSince, MinecraftVersion removedAfter, Since... methodnames) {
|
||||
this.removedAfter = removedAfter;
|
||||
MinecraftVersion server = MinecraftVersion.getVersion();
|
||||
if (server.compareTo(addedSince) < 0 || (this.removedAfter != null && server.getVersionId() > this.removedAfter.getVersionId()))
|
||||
return;
|
||||
compatible = true;
|
||||
Since target = methodnames[0];
|
||||
for (Since s : methodnames) {
|
||||
if (s.version.getVersionId() <= server.getVersionId() && target.version.getVersionId() < s.version.getVersionId())
|
||||
target = s;
|
||||
}
|
||||
targetVersion = target;
|
||||
try {
|
||||
method = targetClass.getMethod(targetVersion.name, args);
|
||||
method.setAccessible(true);
|
||||
loaded = true;
|
||||
} catch (NullPointerException | NoSuchMethodException | SecurityException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
ReflectionMethod(Class<?> targetClass, Class<?>[] args, MinecraftVersion addedSince, Since... methodnames) {
|
||||
this(targetClass, args, addedSince, null, methodnames);
|
||||
}
|
||||
|
||||
public Object run(Object target, Object... args) {
|
||||
try {
|
||||
return method.invoke(target, args);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isLoaded() {
|
||||
return loaded;
|
||||
}
|
||||
|
||||
public boolean isCompatible() {
|
||||
return compatible;
|
||||
}
|
||||
|
||||
public static class Since {
|
||||
public final MinecraftVersion version;
|
||||
public final String name;
|
||||
|
||||
public Since(MinecraftVersion version, String name) {
|
||||
this.version = version;
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package com.songoda.epicbuckets.utils.itemnbtapi.utils;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
public class GsonWrapper {
|
||||
|
||||
private static final Gson gson = new Gson();
|
||||
|
||||
public static String getString(Object obj) {
|
||||
return gson.toJson(obj);
|
||||
}
|
||||
|
||||
public static <T> T deserializeJson(String json, Class<T> type) {
|
||||
try {
|
||||
if (json == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
T obj = gson.fromJson(json, type);
|
||||
return type.cast(obj);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
package com.songoda.epicbuckets.utils.itemnbtapi.utils;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
public enum MinecraftVersion {
|
||||
Unknown(Integer.MAX_VALUE),//Use the newest known mappings
|
||||
MC1_7_R4(174),
|
||||
MC1_8_R3(183),
|
||||
MC1_9_R1(191),
|
||||
MC1_9_R2(192),
|
||||
MC1_10_R1(1101),
|
||||
MC1_11_R1(1111),
|
||||
MC1_12_R1(1121),
|
||||
MC1_13_R1(1131),
|
||||
MC1_13_R2(1132),
|
||||
MC1_14_R1(1141);
|
||||
|
||||
private static MinecraftVersion version;
|
||||
private static Boolean hasGsonSupport;
|
||||
|
||||
private final int versionId;
|
||||
|
||||
MinecraftVersion(int versionId) {
|
||||
this.versionId = versionId;
|
||||
}
|
||||
|
||||
public int getVersionId() {
|
||||
return versionId;
|
||||
}
|
||||
|
||||
public static MinecraftVersion getVersion() {
|
||||
if (version != null) {
|
||||
return version;
|
||||
}
|
||||
final String ver = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
|
||||
System.out.println("[NBTAPI] Found Spigot: " + ver + "! Trying to find NMS support");
|
||||
try {
|
||||
version = MinecraftVersion.valueOf(ver.replace("v", "MC"));
|
||||
} catch (IllegalArgumentException ex) {
|
||||
version = MinecraftVersion.Unknown;
|
||||
}
|
||||
if (version != Unknown) {
|
||||
System.out.println("[NBTAPI] NMS support '" + version.name() + "' loaded!");
|
||||
} else {
|
||||
System.out.println("[NBTAPI] Wasn't able to find NMS Support! Some functions may not work!");
|
||||
}
|
||||
return version;
|
||||
}
|
||||
|
||||
public static boolean hasGsonSupport() {
|
||||
if (hasGsonSupport != null) {
|
||||
return hasGsonSupport;
|
||||
}
|
||||
try {
|
||||
System.out.println("Found Gson: " + Class.forName("com.google.gson.Gson"));
|
||||
hasGsonSupport = true;
|
||||
} catch (Exception ex) {
|
||||
hasGsonSupport = false;
|
||||
}
|
||||
return hasGsonSupport;
|
||||
}
|
||||
|
||||
}
|
302
src/main/java/com/songoda/epicenchants/utils/locale/Locale.java
Normal file
302
src/main/java/com/songoda/epicenchants/utils/locale/Locale.java
Normal file
@ -0,0 +1,302 @@
|
||||
package com.songoda.ultimateclaims.utils.locale;
|
||||
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
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 utilization of localization files.
|
||||
* Created to be used by the Songoda Team.
|
||||
*
|
||||
* @author Brianna O'Keefe - Songoda
|
||||
*/
|
||||
public class Locale {
|
||||
|
||||
private static final List<Locale> LOCALES = new ArrayList<>();
|
||||
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 final Map<String, String> nodes = new HashMap<>();
|
||||
|
||||
private static String defaultLocale;
|
||||
|
||||
private File file;
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* Instantiate the Locale class for future use
|
||||
*
|
||||
* @param name the name of the instantiated language
|
||||
*/
|
||||
private Locale(String name) {
|
||||
if (plugin == null)
|
||||
return;
|
||||
|
||||
this.name = name;
|
||||
|
||||
String fileName = name + FILE_EXTENSION;
|
||||
this.file = new File(localeFolder, fileName);
|
||||
|
||||
if (!this.reloadMessages()) return;
|
||||
|
||||
plugin.getLogger().info("Loaded locale \"" + fileName + "\"");
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the class to load all existing language files and update them.
|
||||
* This must be called before any other methods in this class as otherwise
|
||||
* the methods will fail to invoke
|
||||
*
|
||||
* @param plugin the plugin instance
|
||||
* @param defaultLocale the default language
|
||||
*/
|
||||
public Locale(JavaPlugin plugin, String defaultLocale) {
|
||||
|
||||
Locale.plugin = plugin;
|
||||
Locale.localeFolder = new File(plugin.getDataFolder(), "locales/");
|
||||
|
||||
if (!localeFolder.exists()) localeFolder.mkdirs();
|
||||
|
||||
//Save the default locale file.
|
||||
Locale.defaultLocale = defaultLocale;
|
||||
saveLocale(defaultLocale);
|
||||
|
||||
for (File file : localeFolder.listFiles()) {
|
||||
String fileName = file.getName();
|
||||
if (!fileName.endsWith(FILE_EXTENSION)) continue;
|
||||
|
||||
String name = fileName.substring(0, fileName.lastIndexOf('.'));
|
||||
|
||||
if (name.split("_").length != 2) continue;
|
||||
if (localeLoaded(name)) continue;
|
||||
|
||||
LOCALES.add(new Locale(name));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save a locale file from the InputStream, 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 saveLocale(String fileName) {
|
||||
return saveLocale(plugin.getResource(defaultLocale + FILE_EXTENSION), fileName);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Save a locale file from the InputStream, 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 saveLocale(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(in, destinationFile);
|
||||
|
||||
try (OutputStream outputStream = new FileOutputStream(destinationFile)) {
|
||||
copy(in, outputStream);
|
||||
|
||||
fileName = fileName.substring(0, fileName.lastIndexOf('.'));
|
||||
|
||||
if (fileName.split("_").length != 2) return false;
|
||||
|
||||
LOCALES.add(new Locale(fileName));
|
||||
if (defaultLocale == null) defaultLocale = fileName;
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Write new changes to existing files, if any at all
|
||||
private static boolean compareFiles(InputStream in, File existingFile) {
|
||||
InputStream defaultFile =
|
||||
in == null ? plugin.getResource((defaultLocale != null ? defaultLocale : "en_US") + FILE_EXTENSION) : in;
|
||||
|
||||
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();
|
||||
// Leave a note alerting the user of the newly added messages.
|
||||
writer.write("# New messages for " + plugin.getName() + " v" + plugin.getDescription().getVersion() + ".");
|
||||
|
||||
// If changes were found outside of the default file leave a note explaining that.
|
||||
if (in == null) {
|
||||
writer.newLine();
|
||||
writer.write("# These translations were found untranslated, join");
|
||||
writer.newLine();
|
||||
writer.write("# our translation Discord https://discord.gg/f7fpZEf");
|
||||
writer.newLine();
|
||||
writer.write("# to request an official update!");
|
||||
}
|
||||
}
|
||||
|
||||
writer.newLine();
|
||||
writer.write(defaultValue);
|
||||
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
if (in != null && !changed) compareFiles(null, existingFile);
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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 localeLoaded(String name) {
|
||||
for (Locale locale : LOCALES)
|
||||
if (locale.getName().equals(name)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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.getName().equalsIgnoreCase(name)) return locale;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.trim().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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Supply the Message object with the plugins prefix.
|
||||
*
|
||||
* @param message message to be applied
|
||||
* @return applied message
|
||||
*/
|
||||
private Message supplyPrefix(Message message) {
|
||||
return message.setPrefix(this.nodes.getOrDefault("general.nametag.prefix", "[Plugin]"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new unsaved Message
|
||||
*
|
||||
* @param message the message to create
|
||||
* @return the created message
|
||||
*/
|
||||
public Message newMessage(String message) {
|
||||
return supplyPrefix(new Message(message));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a message set for a specific node.
|
||||
*
|
||||
* @param node the node to get
|
||||
* @return the message for the specified node
|
||||
*/
|
||||
public Message getMessage(String node) {
|
||||
return this.getMessageOrDefault(node, node);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 Message getMessageOrDefault(String node, String defaultValue) {
|
||||
return supplyPrefix(new Message(this.nodes.getOrDefault(node, defaultValue)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the locale name (i.e. "en_US")
|
||||
*
|
||||
* @return the locale name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user