mirror of
https://e.coding.net/circlecloud/Soulbound.git
synced 2024-11-25 02:19:11 +00:00
初始化项目...
Signed-off-by: j502647092 <jtb1@163.com>
This commit is contained in:
commit
70d7d7f6a0
43
.gitignore
vendored
Normal file
43
.gitignore
vendored
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
# Eclipse stuff
|
||||||
|
/.classpath
|
||||||
|
/.project
|
||||||
|
/.settings
|
||||||
|
|
||||||
|
# netbeans
|
||||||
|
/nbproject
|
||||||
|
|
||||||
|
# we use maven!
|
||||||
|
/build.xml
|
||||||
|
|
||||||
|
# maven
|
||||||
|
/target
|
||||||
|
/repo
|
||||||
|
|
||||||
|
# vim
|
||||||
|
.*.sw[a-p]
|
||||||
|
|
||||||
|
# various other potential build files
|
||||||
|
/build
|
||||||
|
/bin
|
||||||
|
/dist
|
||||||
|
/manifest.mf
|
||||||
|
|
||||||
|
/world
|
||||||
|
|
||||||
|
# Mac filesystem dust
|
||||||
|
*.DS_Store
|
||||||
|
|
||||||
|
# intellij
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
*.iws
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
# Project Stuff
|
||||||
|
/src/main/resources/Soulbound
|
||||||
|
|
||||||
|
# Other Libraries
|
||||||
|
*.jar
|
||||||
|
|
||||||
|
# Atlassian Stuff
|
||||||
|
/atlassian-ide-plugin.xml
|
22
README.md
Normal file
22
README.md
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
[![Soulbound][Banner]][GitHub]
|
||||||
|
What is Soulbound?
|
||||||
|
----------------
|
||||||
|
|
||||||
|
Souldbound is a Bukkit plugin that makes it possible to have Soulbound items.
|
||||||
|
Whenever an item is soulbinded, players cannot transfer the item to other players.
|
||||||
|
|
||||||
|
How does it work?
|
||||||
|
----------------
|
||||||
|
|
||||||
|
Check out the [BukkitDev]-page for more information!
|
||||||
|
|
||||||
|
|
||||||
|
Who made this?
|
||||||
|
----------------
|
||||||
|
[![TfT_02](http://www.gravatar.com/avatar/b8914f9970e1f6ffd5281ce4770e20a7.png)](http://dev.bukkit.org/profiles/TfT_02/)
|
||||||
|
|
||||||
|
Download here: [BukkitDev]
|
||||||
|
|
||||||
|
[Banner]: https://dl.dropbox.com/u/29178507/Dev/Soulbound/title-banner.png
|
||||||
|
[BukkitDev]: http://dev.bukkit.org/server-mods/Soulbound/
|
||||||
|
[GitHub]: https://github.com/TfT-02/Soulbound
|
94
changelog.txt
Normal file
94
changelog.txt
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
Changelog:
|
||||||
|
|
||||||
|
Key:
|
||||||
|
+ Addition
|
||||||
|
= Fix
|
||||||
|
! Change
|
||||||
|
- Removal
|
||||||
|
|
||||||
|
Version 1.2.0 | Tested on CB 1.7.9-R0.1
|
||||||
|
+ Added support for giving Soulbinded kits to other players
|
||||||
|
+ Added option to have Soulbind items without adding the player name
|
||||||
|
! Changed the way UUIDs are handled, they are now hidden in the Soulbound lore :)
|
||||||
|
! Changed "Bind on Use" also triggers when enchanting
|
||||||
|
|
||||||
|
Version 1.1.9 | Tested on CB 1.7.5-R0.1
|
||||||
|
! Now using MythicDrops hook to support MythicDrops versions 1.1.2 through 3.0.0. Huge shout-out to Nunnery!
|
||||||
|
|
||||||
|
Version 1.1.8 | Tested on CB 1.7.5-R0.1
|
||||||
|
+ Added new Items config file, define items with displaynames/lore here which will be Soulbound
|
||||||
|
+ Added feature which allows you to Soulbind items when spawning in a kit
|
||||||
|
+ Added feature which allows you to Soulbind items on respawn, useful for spawnkits.
|
||||||
|
+ Added MythicDrops 1.1.2 AND 2.0.0 support. Thanks Nunnery!
|
||||||
|
+ Added UUID support
|
||||||
|
|
||||||
|
Version 1.1.7 | Tested on CB 1.6.4-R0.1
|
||||||
|
- Removed old Updater class
|
||||||
|
|
||||||
|
Version 1.1.6 | Tested on CB 1.6.4-R0.1
|
||||||
|
! Changed Updater, now uses Gravity's updater v2.0
|
||||||
|
! Changed notification messages when dependencies are found, they're hidden by default
|
||||||
|
|
||||||
|
Version 1.1.5 | Tested on CB 1.6.2-R1.0
|
||||||
|
+ Added new config option; "Delete_On_Drop"
|
||||||
|
+ Added new permission nodes soulbound.items.keep_on_death and soulbound.items.delete_on_death, both are false by default
|
||||||
|
= Fixed bug where soulbound items would disappear when dropping them by dragging them out of the inventory
|
||||||
|
= Fixed MythicDrops support, works with MythicDrops 1.1.2
|
||||||
|
! Changed config file system, files now automatically update
|
||||||
|
! Changed "Allow_Item_Drop" to "Prevent_Item_Drop"
|
||||||
|
- Removed config options "Keep_On_Death" and "Delete_On_Death". Use permissions instead!
|
||||||
|
- Removed DiabloDrops support
|
||||||
|
|
||||||
|
Version 1.1.4 | Tested on CB 1.5.2-R0.1
|
||||||
|
+ Added a new configuration option to prevent using certain commands when holding a Soulbound item
|
||||||
|
+ Added a new configuration option to Soulbind the item in hand when a certain command is used.
|
||||||
|
+ Added an option to disable the feedback messages "Inventory now Soulbound to.."
|
||||||
|
! Hoppers can no longer pickup Soulbound items
|
||||||
|
= Fixed infinite durability not working for armor and special tools
|
||||||
|
|
||||||
|
Version 1.1.3 | Tested on CB 1.5.0-R0.1
|
||||||
|
+ Added MythicDrops support
|
||||||
|
+ Added permission node which allows certain players to pickup items which are not Soulbound to that player
|
||||||
|
+ Added permission node which limit the maximum amount of Soulbound items a player can carry at once
|
||||||
|
+ Added new configuration option to let Soulbound items have infinite durability
|
||||||
|
+ Added new command to Soulbind a full inventory. /bind [player] inventory
|
||||||
|
= Fixed bug which caused the plugin to ignore cancelled SoulbindItemEvents
|
||||||
|
! Improved the Bind on Equip mechanism even more, to account for recent inventory changes in MC 1.5
|
||||||
|
|
||||||
|
Version 1.1.2 | Tested on CB 1.4.7-R1.0 & 1.5.0-R0.1
|
||||||
|
+ Added help pages, access them using /soulbound help
|
||||||
|
= Fixed bug where DiabloDrops chests where never edited. Chest generated by DiabloDrops can now also contain Soulbound items
|
||||||
|
= Fixed bug where Chainmail armor and Skulls were never Binded on Equip
|
||||||
|
= Fixed bug which caused an NPE when trying to bind with nothing in hand
|
||||||
|
= Fixed bug which would throw an ArrayIndexOutOfBounds error
|
||||||
|
= Fixed bug which allowed player to Soulbind items twice
|
||||||
|
! Improved the Bind on Equip mechanism!
|
||||||
|
|
||||||
|
Version 1.1.1 | Tested on CB 1.4.7-R1.0
|
||||||
|
+ Added API functions so other plugins can hook into Soulbound as well! (Instead of the other way round)
|
||||||
|
+ Added support for LoreLocks!
|
||||||
|
= Fixed bug with the Update Checker (I really did this time)
|
||||||
|
= Fixed bug with EpicBossRecoded when bosses had no loot defined
|
||||||
|
|
||||||
|
Version 1.1.0 | Tested on CB 1.4.7-R1.0
|
||||||
|
+ Added support for DiabloDrops! Make Legendary items Soulbound on pickup, or make armor Sets Soulbound on Equip
|
||||||
|
+ Added support for EpicBossRecoded! Drops from an EpicBoss can get flagged as "Bind on Pickup", "Bind on Equip" or "Bind on Use"
|
||||||
|
+ Added new item type "Bind on Equip", when a player equips this item it will get Soulbound to that player
|
||||||
|
+ Added new item type "Bind on Use", when a player uses (left/right click) this item it will get Soulbound to that player
|
||||||
|
! Bind on Pickup, now also binds items when clicking them in containers.
|
||||||
|
= Fixed bug where /bindonpickup was broken
|
||||||
|
= Fixed bug where items could have multiple lines with "Soulbound"
|
||||||
|
|
||||||
|
Version 1.0.1 | Tested on CB 1.4.7-R1.0
|
||||||
|
= Fixed bug with the Update Checker
|
||||||
|
|
||||||
|
Version 1.0.0 | Tested on CB 1.4.7-R1.0
|
||||||
|
+ First release
|
||||||
|
+ Added Soulbound items
|
||||||
|
+ Added Bind on Pickup items
|
||||||
|
+ Added prevent storing Soulbound in containers
|
||||||
|
+ Added prevent dropping Soulbound items
|
||||||
|
+ Added prevent dropping Soulbound items on death
|
||||||
|
+ Added keep Soulbound items after death
|
||||||
|
+ Added Metrics for stats
|
||||||
|
+ Added an update check
|
101
pom.xml
Normal file
101
pom.xml
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
<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>
|
||||||
|
<groupId>com.me.tft_02.soulbound</groupId>
|
||||||
|
<artifactId>Soulbound</artifactId>
|
||||||
|
<version>1.1.10-SNAPSHOT</version>
|
||||||
|
<name>Soulbound</name>
|
||||||
|
<url>https://github.com/TfT-02/Soulbound</url>
|
||||||
|
<issueManagement>
|
||||||
|
<system>GitHub</system>
|
||||||
|
<url>https://github.com/TfT-02/Soulbound/issues</url>
|
||||||
|
</issueManagement>
|
||||||
|
<build>
|
||||||
|
<finalName>Soulbound</finalName>
|
||||||
|
<sourceDirectory>${basedir}/src/main/java</sourceDirectory>
|
||||||
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<targetPath>.</targetPath>
|
||||||
|
<filtering>true</filtering>
|
||||||
|
<directory>${basedir}/src/</directory>
|
||||||
|
<includes>
|
||||||
|
<include>*.yml</include>
|
||||||
|
<include>.jenkins</include>
|
||||||
|
</includes>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.0</version>
|
||||||
|
<configuration>
|
||||||
|
<source>1.6</source>
|
||||||
|
<target>1.6</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
|
<version>1.5</version>
|
||||||
|
<configuration>
|
||||||
|
<artifactSet>
|
||||||
|
<includes>
|
||||||
|
<include>org.mcstats.bukkit:metrics</include>
|
||||||
|
<include>org.nunnerycode.bukkit:mythicdropsapi-lib</include>
|
||||||
|
</includes>
|
||||||
|
</artifactSet>
|
||||||
|
<relocations>
|
||||||
|
<relocation>
|
||||||
|
<pattern>org.mcstats.bukkit</pattern>
|
||||||
|
<shadedPattern>com.me.tft_02.soulbound.util</shadedPattern>
|
||||||
|
</relocation>
|
||||||
|
<relocation>
|
||||||
|
<pattern>org.nunnerycode.bukkit</pattern>
|
||||||
|
<shadedPattern>com.me.tft_02.soulbound.util</shadedPattern>
|
||||||
|
</relocation>
|
||||||
|
</relocations>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>shade</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>spigot-repo</id>
|
||||||
|
<url>https://hub.spigotmc.org/nexus/content/groups/public/</url>
|
||||||
|
</repository>
|
||||||
|
<repository>
|
||||||
|
<id>Plugin Metrics</id>
|
||||||
|
<url>http://repo.mcstats.org/content/repositories/public</url>
|
||||||
|
</repository>
|
||||||
|
<repository>
|
||||||
|
<id>mythicdrops-repo</id>
|
||||||
|
<url>http://repository-topplethenun.forge.cloudbees.com/snapshot/</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.bukkit</groupId>
|
||||||
|
<artifactId>bukkit</artifactId>
|
||||||
|
<version>1.8-R0.1-SNAPSHOT</version>
|
||||||
|
<type>jar</type>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mcstats.bukkit</groupId>
|
||||||
|
<artifactId>metrics</artifactId>
|
||||||
|
<version>R7</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
</project>
|
14
src/main/assembly/package.xml
Normal file
14
src/main/assembly/package.xml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
|
||||||
|
<id>bin</id>
|
||||||
|
<includeBaseDirectory>false</includeBaseDirectory>
|
||||||
|
<formats>
|
||||||
|
<format>zip</format>
|
||||||
|
</formats>
|
||||||
|
<files>
|
||||||
|
<file>
|
||||||
|
<source>${project.build.directory}/${artifactId}.jar</source>
|
||||||
|
<outputDirectory>/</outputDirectory>
|
||||||
|
<destName>Soulbound.jar</destName>
|
||||||
|
</file>
|
||||||
|
</files>
|
||||||
|
</assembly>
|
136
src/main/java/com/me/tft_02/soulbound/Soulbound.java
Normal file
136
src/main/java/com/me/tft_02/soulbound/Soulbound.java
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
package com.me.tft_02.soulbound;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import net.gravitydevelopment.updater.soulbound.Updater;
|
||||||
|
|
||||||
|
import org.bukkit.plugin.PluginManager;
|
||||||
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
|
import com.me.tft_02.soulbound.commands.BindCommand;
|
||||||
|
import com.me.tft_02.soulbound.commands.BindOnEquipCommand;
|
||||||
|
import com.me.tft_02.soulbound.commands.BindOnPickupCommand;
|
||||||
|
import com.me.tft_02.soulbound.commands.BindOnUseCommand;
|
||||||
|
import com.me.tft_02.soulbound.commands.SoulboundCommand;
|
||||||
|
import com.me.tft_02.soulbound.commands.UnbindCommand;
|
||||||
|
import com.me.tft_02.soulbound.config.Config;
|
||||||
|
import com.me.tft_02.soulbound.config.ItemsConfig;
|
||||||
|
import com.me.tft_02.soulbound.hooks.EpicBossRecodedListener;
|
||||||
|
import com.me.tft_02.soulbound.listeners.BlockListener;
|
||||||
|
import com.me.tft_02.soulbound.listeners.EntityListener;
|
||||||
|
import com.me.tft_02.soulbound.listeners.InventoryListener;
|
||||||
|
import com.me.tft_02.soulbound.listeners.PlayerListener;
|
||||||
|
import com.me.tft_02.soulbound.util.LogFilter;
|
||||||
|
|
||||||
|
public class Soulbound extends JavaPlugin {
|
||||||
|
/* File Paths */
|
||||||
|
private static String mainDirectory;
|
||||||
|
|
||||||
|
public static Soulbound p;
|
||||||
|
|
||||||
|
// Jar Stuff
|
||||||
|
public static File soulbound;
|
||||||
|
|
||||||
|
// Checks for hooking into other plugins
|
||||||
|
public static boolean epicBossRecodedEnabled = false;
|
||||||
|
public static boolean loreLocksEnabled = false;
|
||||||
|
public static boolean mythicDropsEnabled = false;
|
||||||
|
|
||||||
|
// Update Check
|
||||||
|
private boolean updateAvailable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run things on enable.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onEnable() {
|
||||||
|
p = this;
|
||||||
|
getLogger().setFilter(new LogFilter(this));
|
||||||
|
|
||||||
|
setupFilePaths();
|
||||||
|
|
||||||
|
loadConfigFiles();
|
||||||
|
|
||||||
|
setupEpicBossRecoded();
|
||||||
|
|
||||||
|
registerEvents();
|
||||||
|
|
||||||
|
getCommand("soulbound").setExecutor(new SoulboundCommand());
|
||||||
|
getCommand("bind").setExecutor(new BindCommand());
|
||||||
|
getCommand("bindonpickup").setExecutor(new BindOnPickupCommand());
|
||||||
|
getCommand("bindonuse").setExecutor(new BindOnUseCommand());
|
||||||
|
getCommand("bindonequip").setExecutor(new BindOnEquipCommand());
|
||||||
|
getCommand("unbind").setExecutor(new UnbindCommand());
|
||||||
|
|
||||||
|
checkForUpdates();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void registerEvents() {
|
||||||
|
PluginManager pm = getServer().getPluginManager();
|
||||||
|
pm.registerEvents(new PlayerListener(), this);
|
||||||
|
pm.registerEvents(new InventoryListener(), this);
|
||||||
|
pm.registerEvents(new EntityListener(), this);
|
||||||
|
pm.registerEvents(new BlockListener(), this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupEpicBossRecoded() {
|
||||||
|
if (getServer().getPluginManager().isPluginEnabled("EpicBossRecoded")) {
|
||||||
|
epicBossRecodedEnabled = true;
|
||||||
|
debug("EpicBossRecoded found!");
|
||||||
|
getServer().getPluginManager().registerEvents(new EpicBossRecodedListener(), this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run things on disable.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onDisable() {}
|
||||||
|
|
||||||
|
public static String getMainDirectory() {
|
||||||
|
return mainDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isUpdateAvailable() {
|
||||||
|
return updateAvailable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void debug(String message) {
|
||||||
|
getLogger().info("[Debug] " + message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup the various storage file paths
|
||||||
|
*/
|
||||||
|
private void setupFilePaths() {
|
||||||
|
soulbound = getFile();
|
||||||
|
mainDirectory = getDataFolder().getPath() + File.separator;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadConfigFiles() {
|
||||||
|
Config.getInstance();
|
||||||
|
ItemsConfig.getInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkForUpdates() {
|
||||||
|
if (!Config.getInstance().getUpdateCheckEnabled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Updater updater = new Updater(this, 53483, soulbound, Updater.UpdateType.NO_DOWNLOAD, false);
|
||||||
|
|
||||||
|
if (updater.getResult() != Updater.UpdateResult.UPDATE_AVAILABLE) {
|
||||||
|
this.updateAvailable = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updater.getLatestType().equals("beta") && !Config.getInstance().getPreferBeta()) {
|
||||||
|
this.updateAvailable = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.updateAvailable = true;
|
||||||
|
getLogger().info("Soulbound is outdated!");
|
||||||
|
getLogger().info("http://dev.bukkit.org/server-mods/soulbound/");
|
||||||
|
}
|
||||||
|
}
|
116
src/main/java/com/me/tft_02/soulbound/api/ItemAPI.java
Normal file
116
src/main/java/com/me/tft_02/soulbound/api/ItemAPI.java
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
package com.me.tft_02.soulbound.api;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import com.me.tft_02.soulbound.util.ItemUtils;
|
||||||
|
|
||||||
|
public final class ItemAPI {
|
||||||
|
private ItemAPI() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a Player is binded to an ItemStack.
|
||||||
|
* </br>
|
||||||
|
* This function is designed for API usage.
|
||||||
|
*
|
||||||
|
* @param player The Player to check
|
||||||
|
* @param itemStack The ItemStack to check
|
||||||
|
*
|
||||||
|
* @return true or false
|
||||||
|
*/
|
||||||
|
public static boolean isSoulbindedPlayer(Player player, ItemStack itemStack) {
|
||||||
|
return ItemUtils.isBindedPlayer(player, itemStack);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Soulbind an ItemStack to a Player.
|
||||||
|
* </br>
|
||||||
|
* This function is designed for API usage.
|
||||||
|
*
|
||||||
|
* @param player The Player to bind the item to
|
||||||
|
* @param itemStack The ItemStack to bind
|
||||||
|
*
|
||||||
|
* @return the soulbound ItemStack
|
||||||
|
*/
|
||||||
|
public static ItemStack soulbindItem(Player player, ItemStack itemStack) {
|
||||||
|
return ItemUtils.soulbindItem(player, itemStack);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if an itemstack is Soulbound.
|
||||||
|
* </br>
|
||||||
|
* This function is designed for API usage.
|
||||||
|
*
|
||||||
|
* @param itemStack The itemstack to check
|
||||||
|
*
|
||||||
|
* @return true or false
|
||||||
|
*/
|
||||||
|
public static boolean isSoulbound(ItemStack itemStack) {
|
||||||
|
return ItemUtils.isSoulbound(itemStack);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark an itemstack as Bind on Pickup
|
||||||
|
* </br>
|
||||||
|
* This function is designed for API usage.
|
||||||
|
*
|
||||||
|
* @param itemStack The itemstack to mark as Bind on Pickup
|
||||||
|
*
|
||||||
|
* @return the marked itemstack
|
||||||
|
*/
|
||||||
|
public static ItemStack bindOnPickupItem(ItemStack itemStack) {
|
||||||
|
return ItemUtils.bopItem(itemStack);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if an itemstack is Bind on Pickup.
|
||||||
|
* </br>
|
||||||
|
* This function is designed for API usage.
|
||||||
|
*
|
||||||
|
* @param itemStack The itemstack to check
|
||||||
|
*
|
||||||
|
* @return true or false
|
||||||
|
*/
|
||||||
|
public static boolean isBindOnPickup(ItemStack itemStack) {
|
||||||
|
return ItemUtils.isBindOnPickup(itemStack);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark an itemstack as Bind on Use
|
||||||
|
* </br>
|
||||||
|
* This function is designed for API usage.
|
||||||
|
*
|
||||||
|
* @param itemStack The itemstack to mark as Bind on Use
|
||||||
|
*
|
||||||
|
* @return the marked itemstack
|
||||||
|
*/
|
||||||
|
public static ItemStack bindOnUseItem(ItemStack itemStack) {
|
||||||
|
return ItemUtils.bouItem(itemStack);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark an itemstack as Bind on Equip
|
||||||
|
* </br>
|
||||||
|
* This function is designed for API usage.
|
||||||
|
*
|
||||||
|
* @param itemStack The itemstack to mark as Bind on Equip
|
||||||
|
*
|
||||||
|
* @return the marked itemstack
|
||||||
|
*/
|
||||||
|
public static ItemStack bindOnEquipItem(ItemStack itemStack) {
|
||||||
|
return ItemUtils.boeItem(itemStack);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Soulbound type of an itemstack.
|
||||||
|
* </br>
|
||||||
|
* This function is designed for API usage.
|
||||||
|
*
|
||||||
|
* @param itemStack The itemstack to check
|
||||||
|
*
|
||||||
|
* @return the Bind type
|
||||||
|
*/
|
||||||
|
public static String getItemType(ItemStack itemStack) {
|
||||||
|
return ItemUtils.getItemType(itemStack).toString();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,92 @@
|
|||||||
|
package com.me.tft_02.soulbound.commands;
|
||||||
|
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.command.Command;
|
||||||
|
import org.bukkit.command.CommandExecutor;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import com.me.tft_02.soulbound.Soulbound;
|
||||||
|
import com.me.tft_02.soulbound.config.Config;
|
||||||
|
import com.me.tft_02.soulbound.util.CommandUtils;
|
||||||
|
import com.me.tft_02.soulbound.util.ItemUtils;
|
||||||
|
|
||||||
|
public class BindCommand implements CommandExecutor {
|
||||||
|
String soulbound = ChatColor.GOLD + "Soulbound ";
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
@Override
|
||||||
|
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
|
||||||
|
if (CommandUtils.noConsoleUsage(sender)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sender.hasPermission("soulbound.commands.bind")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean bindFullInventory = false;
|
||||||
|
|
||||||
|
Player player = (Player) sender;
|
||||||
|
Player target;
|
||||||
|
switch (args.length) {
|
||||||
|
case 1:
|
||||||
|
target = Soulbound.p.getServer().getPlayerExact(args[0]);
|
||||||
|
|
||||||
|
if (CommandUtils.isOffline(sender, target)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if (!args[1].equalsIgnoreCase("inventory")) {
|
||||||
|
sender.sendMessage(ChatColor.RED + "Proper usage: " + ChatColor.GREEN + "/bind <player> inventory");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bindFullInventory = true;
|
||||||
|
target = Soulbound.p.getServer().getPlayerExact(args[0]);
|
||||||
|
|
||||||
|
if (CommandUtils.isOffline(sender, target)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
target = player;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bindFullInventory) {
|
||||||
|
return handleBindFullInventory(player, target);
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemStack itemInHand = player.getItemInHand();
|
||||||
|
|
||||||
|
if ((itemInHand.getType() == Material.AIR) || ItemUtils.isSoulbound(itemInHand)) {
|
||||||
|
sender.sendMessage(ChatColor.GRAY + "You can't " + soulbound + ChatColor.GRAY + "this item.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemUtils.soulbindItem(target, itemInHand);
|
||||||
|
|
||||||
|
if (ItemUtils.isSoulbound(itemInHand) && Config.getInstance().getFeedbackEnabled()) {
|
||||||
|
sender.sendMessage(ChatColor.GRAY + "Item is now " + soulbound + ChatColor.GRAY + "to " + ChatColor.DARK_AQUA + target.getName());
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean handleBindFullInventory(Player player, Player target) {
|
||||||
|
for (ItemStack itemStack : player.getInventory().getContents()) {
|
||||||
|
if (itemStack != null && itemStack.getType() != Material.AIR) {
|
||||||
|
ItemUtils.soulbindItem(target, itemStack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Config.getInstance().getFeedbackEnabled()) {
|
||||||
|
player.sendMessage(ChatColor.GRAY + "All items in " + ChatColor.DARK_AQUA + target.getName() + ChatColor.GRAY + "'s inventory are now " + soulbound + ChatColor.GRAY + "to " + ChatColor.DARK_AQUA + target.getName());
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
package com.me.tft_02.soulbound.commands;
|
||||||
|
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.command.Command;
|
||||||
|
import org.bukkit.command.CommandExecutor;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import com.me.tft_02.soulbound.util.CommandUtils;
|
||||||
|
import com.me.tft_02.soulbound.util.ItemUtils;
|
||||||
|
|
||||||
|
public class BindOnEquipCommand implements CommandExecutor {
|
||||||
|
@Override
|
||||||
|
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||||
|
if (CommandUtils.noConsoleUsage(sender)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (args.length) {
|
||||||
|
case 0:
|
||||||
|
Player player = (Player) sender;
|
||||||
|
|
||||||
|
if (!player.hasPermission("soulbound.commands.bindonequip")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemStack itemInHand = player.getItemInHand();
|
||||||
|
|
||||||
|
if ((itemInHand.getType() == Material.AIR) || ItemUtils.isSoulbound(itemInHand)) {
|
||||||
|
player.sendMessage(ChatColor.GRAY + "You can't " + ChatColor.GOLD + "Soulbound " + ChatColor.GRAY + "this item.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemUtils.unbindItem(itemInHand);
|
||||||
|
ItemUtils.boeItem(itemInHand);
|
||||||
|
|
||||||
|
if (ItemUtils.isBindOnEquip(itemInHand)) {
|
||||||
|
player.sendMessage(ChatColor.GRAY + "Item is now " + ChatColor.DARK_RED + "Bind on Equip");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
player.sendMessage(ChatColor.RED + "Cannot mark this item as " + ChatColor.DARK_RED + "Bind on Equip");
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
package com.me.tft_02.soulbound.commands;
|
||||||
|
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.command.Command;
|
||||||
|
import org.bukkit.command.CommandExecutor;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import com.me.tft_02.soulbound.util.CommandUtils;
|
||||||
|
import com.me.tft_02.soulbound.util.ItemUtils;
|
||||||
|
|
||||||
|
public class BindOnPickupCommand implements CommandExecutor {
|
||||||
|
@Override
|
||||||
|
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||||
|
if (CommandUtils.noConsoleUsage(sender)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (args.length) {
|
||||||
|
case 0:
|
||||||
|
Player player = (Player) sender;
|
||||||
|
|
||||||
|
if (!player.hasPermission("soulbound.commands.bindonpickup")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemStack itemInHand = player.getItemInHand();
|
||||||
|
|
||||||
|
if ((itemInHand.getType() == Material.AIR) || ItemUtils.isSoulbound(itemInHand)) {
|
||||||
|
player.sendMessage(ChatColor.GRAY + "You can't " + ChatColor.GOLD + "Soulbound " + ChatColor.GRAY + "this item.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemUtils.unbindItem(itemInHand);
|
||||||
|
ItemUtils.bopItem(itemInHand);
|
||||||
|
player.sendMessage(ChatColor.GRAY + "Item is now " + ChatColor.DARK_RED + "Bind on pickup");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
package com.me.tft_02.soulbound.commands;
|
||||||
|
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.command.Command;
|
||||||
|
import org.bukkit.command.CommandExecutor;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import com.me.tft_02.soulbound.util.CommandUtils;
|
||||||
|
import com.me.tft_02.soulbound.util.ItemUtils;
|
||||||
|
|
||||||
|
public class BindOnUseCommand implements CommandExecutor {
|
||||||
|
@Override
|
||||||
|
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||||
|
if (CommandUtils.noConsoleUsage(sender)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (args.length) {
|
||||||
|
case 0:
|
||||||
|
Player player = (Player) sender;
|
||||||
|
|
||||||
|
if (!player.hasPermission("soulbound.commands.bindonuse")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemStack itemInHand = player.getItemInHand();
|
||||||
|
|
||||||
|
if ((itemInHand.getType() == Material.AIR) || ItemUtils.isSoulbound(itemInHand)) {
|
||||||
|
player.sendMessage(ChatColor.GRAY + "You can't " + ChatColor.GOLD + "Soulbound " + ChatColor.GRAY + "this item.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemUtils.unbindItem(itemInHand);
|
||||||
|
ItemUtils.bouItem(itemInHand);
|
||||||
|
player.sendMessage(ChatColor.GRAY + "Item is now " + ChatColor.DARK_RED + "Bind on Use");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,134 @@
|
|||||||
|
package com.me.tft_02.soulbound.commands;
|
||||||
|
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.command.Command;
|
||||||
|
import org.bukkit.command.CommandExecutor;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import com.me.tft_02.soulbound.Soulbound;
|
||||||
|
|
||||||
|
public class SoulboundCommand implements CommandExecutor {
|
||||||
|
@Override
|
||||||
|
public boolean onCommand(CommandSender sender, Command command,
|
||||||
|
String label, String[] args) {
|
||||||
|
switch (args.length) {
|
||||||
|
case 0:
|
||||||
|
sender.sendMessage("Soulbound version "
|
||||||
|
+ Soulbound.p.getDescription().getVersion());
|
||||||
|
return printUsage(sender);
|
||||||
|
case 1:
|
||||||
|
if (args[0].equalsIgnoreCase("reload")) {
|
||||||
|
return reloadConfiguration(sender);
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
if (args[0].equalsIgnoreCase("help")
|
||||||
|
|| args[0].equalsIgnoreCase("?")) {
|
||||||
|
return helpPages(sender, args);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean reloadConfiguration(CommandSender sender) {
|
||||||
|
if (sender instanceof Player
|
||||||
|
&& !sender.hasPermission("soulbound.commands.reload")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Soulbound.p.reloadConfig();
|
||||||
|
sender.sendMessage(ChatColor.GREEN + "Configuration reloaded.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean helpPages(CommandSender sender, String[] args) {
|
||||||
|
if (!(sender instanceof Player)) {
|
||||||
|
sender.sendMessage("Can't use this from the console, sorry!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (args.length >= 2 && Integer.parseInt(args[1]) > 0) {
|
||||||
|
getHelpPage(Integer.parseInt(args[1]), sender);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void getHelpPage(int page, CommandSender sender) {
|
||||||
|
int maxPages = 2;
|
||||||
|
int nextPage = page + 1;
|
||||||
|
if (page > maxPages) {
|
||||||
|
sender.sendMessage(ChatColor.RED + "This page does not exist."
|
||||||
|
+ ChatColor.GOLD + " /help [0-" + maxPages + "]");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String dot = ChatColor.DARK_RED + "* ";
|
||||||
|
sender.sendMessage(ChatColor.GRAY + "-----[ " + ChatColor.GOLD
|
||||||
|
+ "Soulbound Help" + ChatColor.GRAY + " ]----- Page " + page
|
||||||
|
+ "/" + maxPages);
|
||||||
|
if (page == 1) {
|
||||||
|
sender.sendMessage(ChatColor.GOLD + "How does it work?");
|
||||||
|
sender.sendMessage(dot
|
||||||
|
+ ChatColor.GRAY
|
||||||
|
+ "Soulbound items are special items which are bound to a sender.");
|
||||||
|
sender.sendMessage(dot
|
||||||
|
+ ChatColor.GRAY
|
||||||
|
+ "Players are prevented from doing certain actions with Soulbound items, such as:");
|
||||||
|
sender.sendMessage(dot
|
||||||
|
+ ChatColor.GRAY
|
||||||
|
+ "dropping them on the ground, storing them in chests or giving them to other players.");
|
||||||
|
sender.sendMessage(dot
|
||||||
|
+ ChatColor.GRAY
|
||||||
|
+ "Items marked as 'Bind on Pickup' will get Soulbound as soon as they get picked up.");
|
||||||
|
sender.sendMessage(dot
|
||||||
|
+ ChatColor.GRAY
|
||||||
|
+ "Items marked as 'Bind on Use' will get Soulbound as soon as they get used.");
|
||||||
|
sender.sendMessage(dot
|
||||||
|
+ ChatColor.GRAY
|
||||||
|
+ "Items marked as 'Bind on Equip' will get Soulbound as soon as they get equipped.");
|
||||||
|
}
|
||||||
|
if (page == 2) {
|
||||||
|
sender.sendMessage(ChatColor.GOLD + "Commands:");
|
||||||
|
if (sender.hasPermission("soulbound.commands.bindonpickup")) {
|
||||||
|
sender.sendMessage(dot + ChatColor.GREEN + "/soulbound"
|
||||||
|
+ ChatColor.GRAY + " Check the status of the plugin.");
|
||||||
|
}
|
||||||
|
if (sender.hasPermission("soulbound.commands.bind")) {
|
||||||
|
sender.sendMessage(dot + ChatColor.GREEN + "/bind <sender>"
|
||||||
|
+ ChatColor.GRAY
|
||||||
|
+ " Soulbound the item currently in hand.");
|
||||||
|
sender.sendMessage(dot + ChatColor.GREEN
|
||||||
|
+ "/bind <sender> inventory" + ChatColor.GRAY
|
||||||
|
+ " Soulbound an entire inventory.");
|
||||||
|
}
|
||||||
|
if (sender.hasPermission("soulbound.commands.bindonpickup")) {
|
||||||
|
sender.sendMessage(dot + ChatColor.GREEN + "/bindonpickup"
|
||||||
|
+ ChatColor.GRAY
|
||||||
|
+ " Mark the item in hand as 'Bind on Pickup'");
|
||||||
|
}
|
||||||
|
if (sender.hasPermission("soulbound.commands.bindonuse")) {
|
||||||
|
sender.sendMessage(dot + ChatColor.GREEN + "/bindonuse"
|
||||||
|
+ ChatColor.GRAY
|
||||||
|
+ " Mark the item in hand as 'Bind on Use'");
|
||||||
|
}
|
||||||
|
if (sender.hasPermission("soulbound.commands.bindonequip")) {
|
||||||
|
sender.sendMessage(dot + ChatColor.GREEN + "/bindonequip"
|
||||||
|
+ ChatColor.GRAY
|
||||||
|
+ " Mark the item in hand as 'Bind on Equip'");
|
||||||
|
}
|
||||||
|
if (sender.hasPermission("soulbound.commands.unbind")) {
|
||||||
|
sender.sendMessage(dot + ChatColor.GREEN + "/unbind"
|
||||||
|
+ ChatColor.GRAY + " Unbind the item in hand.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (nextPage <= maxPages) {
|
||||||
|
sender.sendMessage(ChatColor.GOLD + "Type /soulbound help "
|
||||||
|
+ nextPage + " for more");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean printUsage(CommandSender sender) {
|
||||||
|
sender.sendMessage("Usage: /soulbound [reload | help]");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
package com.me.tft_02.soulbound.commands;
|
||||||
|
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.command.Command;
|
||||||
|
import org.bukkit.command.CommandExecutor;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import com.me.tft_02.soulbound.util.CommandUtils;
|
||||||
|
import com.me.tft_02.soulbound.util.ItemUtils;
|
||||||
|
|
||||||
|
public class UnbindCommand implements CommandExecutor {
|
||||||
|
@Override
|
||||||
|
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||||
|
if (CommandUtils.noConsoleUsage(sender)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (args.length) {
|
||||||
|
case 0:
|
||||||
|
Player player = (Player) sender;
|
||||||
|
|
||||||
|
if (!player.hasPermission("soulbound.commands.unbind")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemStack itemInHand = player.getItemInHand();
|
||||||
|
|
||||||
|
if ((itemInHand.getType() == Material.AIR) || !ItemUtils.isSoulbound(itemInHand)) {
|
||||||
|
player.sendMessage(ChatColor.GRAY + "You can't " + ChatColor.GOLD + "Unbind " + ChatColor.GRAY + "this item.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ItemUtils.unbindItem(itemInHand)==null ){
|
||||||
|
player.sendMessage(ChatColor.GRAY + "You can't " + ChatColor.GOLD + "Unbind " + ChatColor.GRAY + "this item.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
player.sendMessage(ChatColor.GRAY + "Item no longer Soulbound.");
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,119 @@
|
|||||||
|
package com.me.tft_02.soulbound.config;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
|
||||||
|
public abstract class AutoUpdateConfigLoader extends ConfigLoader {
|
||||||
|
public AutoUpdateConfigLoader(String relativePath, String fileName) {
|
||||||
|
super(relativePath, fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AutoUpdateConfigLoader(String fileName) {
|
||||||
|
super(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
@Override
|
||||||
|
protected void loadFile() {
|
||||||
|
super.loadFile();
|
||||||
|
FileConfiguration internalConfig = YamlConfiguration.loadConfiguration(plugin.getResource(fileName));
|
||||||
|
|
||||||
|
Set<String> configKeys = config.getKeys(true);
|
||||||
|
Set<String> internalConfigKeys = internalConfig.getKeys(true);
|
||||||
|
|
||||||
|
boolean needSave = false;
|
||||||
|
|
||||||
|
Set<String> oldKeys = new HashSet<String>(configKeys);
|
||||||
|
oldKeys.removeAll(internalConfigKeys);
|
||||||
|
|
||||||
|
Set<String> newKeys = new HashSet<String>(internalConfigKeys);
|
||||||
|
newKeys.removeAll(configKeys);
|
||||||
|
|
||||||
|
// Don't need a re-save if we have old keys sticking around?
|
||||||
|
// Would be less saving, but less... correct?
|
||||||
|
if (!newKeys.isEmpty() || !oldKeys.isEmpty()) {
|
||||||
|
needSave = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String key : oldKeys) {
|
||||||
|
plugin.debug("Removing unused key: " + key);
|
||||||
|
config.set(key, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String key : newKeys) {
|
||||||
|
plugin.debug("Adding new key: " + key + " = " + internalConfig.get(key));
|
||||||
|
config.set(key, internalConfig.get(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (needSave) {
|
||||||
|
// Get Bukkit's version of an acceptable config with new keys, and no old keys
|
||||||
|
String output = config.saveToString();
|
||||||
|
|
||||||
|
// Convert to the superior 4 space indentation
|
||||||
|
output = output.replace(" ", " ");
|
||||||
|
|
||||||
|
// Rip out Bukkit's attempt to save comments at the top of the file
|
||||||
|
while (output.indexOf('#') != -1) {
|
||||||
|
output = output.substring(output.indexOf('\n', output.indexOf('#')) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the internal config to get comments, then put them in the new one
|
||||||
|
try {
|
||||||
|
// Read internal
|
||||||
|
BufferedReader reader = new BufferedReader(new InputStreamReader(plugin.getResource(fileName)));
|
||||||
|
HashMap<String, String> comments = new HashMap<String, String>();
|
||||||
|
String temp = "";
|
||||||
|
|
||||||
|
String line;
|
||||||
|
while ((line = reader.readLine()) != null) {
|
||||||
|
if (line.contains("#")) {
|
||||||
|
temp += line + "\n";
|
||||||
|
}
|
||||||
|
else if (line.contains(":")) {
|
||||||
|
line = line.substring(0, line.indexOf(":") + 1);
|
||||||
|
if (!temp.isEmpty()) {
|
||||||
|
comments.put(line, temp);
|
||||||
|
temp = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dump to the new one
|
||||||
|
for (String key : comments.keySet()) {
|
||||||
|
if (output.indexOf(key) != -1) {
|
||||||
|
output = output.substring(0, output.indexOf(key)) + comments.get(key) + output.substring(output.indexOf(key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save it
|
||||||
|
try {
|
||||||
|
String saveName = fileName;
|
||||||
|
// At this stage we cannot guarantee that Config has been loaded, so we do the check directly here
|
||||||
|
if (!plugin.getConfig().getBoolean("General.Config_Update_Overwrite", true)) {
|
||||||
|
saveName += ".new";
|
||||||
|
}
|
||||||
|
|
||||||
|
BufferedWriter writer = new BufferedWriter(new FileWriter(new File(plugin.getDataFolder(), saveName)));
|
||||||
|
writer.write(output);
|
||||||
|
writer.flush();
|
||||||
|
writer.close();
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
89
src/main/java/com/me/tft_02/soulbound/config/Config.java
Normal file
89
src/main/java/com/me/tft_02/soulbound/config/Config.java
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
package com.me.tft_02.soulbound.config;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class Config extends AutoUpdateConfigLoader {
|
||||||
|
private static Config instance;
|
||||||
|
|
||||||
|
private Config() {
|
||||||
|
super("config.yml");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Config getInstance() {
|
||||||
|
if (instance == null) {
|
||||||
|
instance = new Config();
|
||||||
|
}
|
||||||
|
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void loadKeys() {}
|
||||||
|
|
||||||
|
/* @formatter:off */
|
||||||
|
|
||||||
|
/* GENERAL SETTINGS */
|
||||||
|
// public String getLocale() { return config.getString("General.Locale", "en_us"); }
|
||||||
|
// public int getSaveInterval() { return config.getInt("General.Save_Interval", 10); }
|
||||||
|
public boolean getStatsTrackingEnabled() { return config.getBoolean("General.Stats_Tracking", true); }
|
||||||
|
public boolean getUpdateCheckEnabled() { return config.getBoolean("General.Update_Check", true); }
|
||||||
|
public boolean getPreferBeta() { return config.getBoolean("General.Prefer_Beta", false); }
|
||||||
|
public boolean getVerboseLoggingEnabled() { return config.getBoolean("General.Verbose_Logging", false); }
|
||||||
|
public boolean getConfigOverwriteEnabled() { return config.getBoolean("General.Config_Update_Overwrite", true); }
|
||||||
|
|
||||||
|
/* @formatter:on */
|
||||||
|
|
||||||
|
/* SOULBOUND SETTINGS */
|
||||||
|
public boolean getShowNameInLore() { return config.getBoolean("Soulbound.Show_Name_In_Lore", true); }
|
||||||
|
public boolean getFeedbackEnabled() { return config.getBoolean("Soulbound.Feedback_Messages_Enabled", true); }
|
||||||
|
public boolean getPreventItemDrop() { return config.getBoolean("Soulbound.Prevent_Item_Drop", false); }
|
||||||
|
public boolean getDeleteOnDrop() { return config.getBoolean("Soulbound.Delete_On_Drop", false); }
|
||||||
|
public boolean getAllowItemStoring() { return config.getBoolean("Soulbound.Allow_Item_Storing", true); }
|
||||||
|
public boolean getInfiniteDurability() { return config.getBoolean("Soulbound.Infinite_Durability", false); }
|
||||||
|
|
||||||
|
public List<String> getBlockedCommands() { return config.getStringList("Soulbound.Blocked_Commands"); }
|
||||||
|
public List<String> getBindCommands() { return config.getStringList("Soulbound.Commands_Bind_When_Used"); }
|
||||||
|
|
||||||
|
// EpicBossRecoded config settings
|
||||||
|
|
||||||
|
public boolean getEBRBindOnPickup() { return config.getBoolean("Dependency_Plugins.EpicBossRecoded.BindOnPickup"); }
|
||||||
|
public boolean getEBRBindOnEquip() { return config.getBoolean("Dependency_Plugins.EpicBossRecoded.BindOnEquip"); }
|
||||||
|
public boolean getEBRBindOnUse() { return config.getBoolean("Dependency_Plugins.EpicBossRecoded.BindOnUse");}
|
||||||
|
|
||||||
|
// DiabloDrops config settings
|
||||||
|
|
||||||
|
public List<String> getDiabloDropsBindOnPickupTiers() { return getDiabloDropsItemTiers("BindOnPickup");}
|
||||||
|
public List<String> getDiabloDropsBindOnUseTiers() { return getDiabloDropsItemTiers("BindOnUse");}
|
||||||
|
public List<String> getDiabloDropsBindOnEquipTiers() { return getDiabloDropsItemTiers("BindOnEquip"); }
|
||||||
|
|
||||||
|
public List<String> getDiabloDropsItemTiers(String bindType) {
|
||||||
|
String[] tiersString = config.getString("Dependency_Plugins.DiabloDrops." + bindType).replaceAll(" ", "").split("[,]");
|
||||||
|
List<String> tiers = new ArrayList<String>();
|
||||||
|
|
||||||
|
for (String tier : tiersString) {
|
||||||
|
tiers.add(tier);
|
||||||
|
}
|
||||||
|
return tiers;
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoreLocks config settings
|
||||||
|
|
||||||
|
public boolean getLoreLocksBindKeys() { return config.getBoolean("Dependency_Plugins.LoreLocks.Bind_Keys"); }
|
||||||
|
|
||||||
|
// MythicDrops config settings
|
||||||
|
|
||||||
|
public List<String> getMythicDropsBindOnPickupTiers() { return getMythicDropsItemTiers("BindOnPickup"); }
|
||||||
|
public List<String> getMythicDropsBindOnUseTiers() { return getMythicDropsItemTiers("BindOnUse"); }
|
||||||
|
public List<String> getMythicDropsBindOnEquipTiers() { return getMythicDropsItemTiers("BindOnEquip"); }
|
||||||
|
|
||||||
|
public List<String> getMythicDropsItemTiers(String bindType) {
|
||||||
|
String[] tiersString = config.getString("Dependency_Plugins.MythicDrops." + bindType).replaceAll(" ", "").split("[,]");
|
||||||
|
List<String> tiers = new ArrayList<String>();
|
||||||
|
|
||||||
|
for (String tier : tiersString) {
|
||||||
|
tiers.add(tier);
|
||||||
|
}
|
||||||
|
return tiers;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,93 @@
|
|||||||
|
package com.me.tft_02.soulbound.config;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
|
||||||
|
import com.me.tft_02.soulbound.Soulbound;
|
||||||
|
|
||||||
|
public abstract class ConfigLoader {
|
||||||
|
protected static final Soulbound plugin = Soulbound.p;
|
||||||
|
protected String fileName;
|
||||||
|
protected File configFile;
|
||||||
|
protected FileConfiguration config;
|
||||||
|
|
||||||
|
public ConfigLoader(String relativePath, String fileName) {
|
||||||
|
this.fileName = fileName;
|
||||||
|
configFile = new File(plugin.getDataFolder(), relativePath + File.separator + fileName);
|
||||||
|
loadFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfigLoader(String fileName) {
|
||||||
|
this.fileName = fileName;
|
||||||
|
configFile = new File(plugin.getDataFolder(), fileName);
|
||||||
|
loadFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void loadFile() {
|
||||||
|
if (!configFile.exists()) {
|
||||||
|
plugin.debug("Creating Soulbound " + fileName + " File...");
|
||||||
|
createFile();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
plugin.debug("Loading Soulbound " + fileName + " File...");
|
||||||
|
}
|
||||||
|
|
||||||
|
config = YamlConfiguration.loadConfiguration(configFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void loadKeys();
|
||||||
|
|
||||||
|
protected void createFile() {
|
||||||
|
configFile.getParentFile().mkdirs();
|
||||||
|
|
||||||
|
InputStream inputStream = plugin.getResource(fileName);
|
||||||
|
|
||||||
|
if (inputStream == null) {
|
||||||
|
plugin.getLogger().severe("Missing resource file: '" + fileName + "' please notify the plugin authors");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
OutputStream outputStream = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
outputStream = new FileOutputStream(configFile);
|
||||||
|
|
||||||
|
int read;
|
||||||
|
byte[] bytes = new byte[1024];
|
||||||
|
|
||||||
|
while ((read = inputStream.read(bytes)) != -1) {
|
||||||
|
outputStream.write(bytes, 0, read);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (FileNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
if (outputStream != null) {
|
||||||
|
try {
|
||||||
|
outputStream.close();
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
inputStream.close();
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
155
src/main/java/com/me/tft_02/soulbound/config/ItemsConfig.java
Normal file
155
src/main/java/com/me/tft_02/soulbound/config/ItemsConfig.java
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
package com.me.tft_02.soulbound.config;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
import org.bukkit.material.MaterialData;
|
||||||
|
|
||||||
|
import com.me.tft_02.soulbound.datatypes.ActionType;
|
||||||
|
import com.me.tft_02.soulbound.datatypes.SoulbindItem;
|
||||||
|
|
||||||
|
public class ItemsConfig extends ConfigLoader {
|
||||||
|
private static ItemsConfig instance;
|
||||||
|
|
||||||
|
private List<SoulbindItem> soulbindOnCraft = new ArrayList<SoulbindItem>();
|
||||||
|
private List<SoulbindItem> soulbindOnOpenChest = new ArrayList<SoulbindItem>();
|
||||||
|
private List<SoulbindItem> soulbindOnPickupItem = new ArrayList<SoulbindItem>();
|
||||||
|
private List<SoulbindItem> soulbindOnDrop = new ArrayList<SoulbindItem>();
|
||||||
|
private List<SoulbindItem> soulbindOnRespawn = new ArrayList<SoulbindItem>();
|
||||||
|
private List<SoulbindItem> soulbindOnKit = new ArrayList<SoulbindItem>();
|
||||||
|
|
||||||
|
public ItemsConfig() {
|
||||||
|
super("items.yml");
|
||||||
|
loadKeys();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ItemsConfig getInstance() {
|
||||||
|
if (instance == null) {
|
||||||
|
instance = new ItemsConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
@Override
|
||||||
|
protected void loadKeys() {
|
||||||
|
ConfigurationSection configurationSection = config.getConfigurationSection("Items");
|
||||||
|
|
||||||
|
if (configurationSection == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<String> itemConfigSet = configurationSection.getKeys(false);
|
||||||
|
|
||||||
|
for (String itemName : itemConfigSet) {
|
||||||
|
String[] itemInfo = itemName.split("[|]");
|
||||||
|
|
||||||
|
Material itemMaterial = Material.matchMaterial(itemInfo[0]);
|
||||||
|
|
||||||
|
if (itemMaterial == null) {
|
||||||
|
plugin.getLogger().warning("Invalid material name. This item will be skipped. - " + itemInfo[0]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte itemData = (itemInfo.length == 2) ? Byte.valueOf(itemInfo[1]) : 0;
|
||||||
|
MaterialData itemMaterialData = new MaterialData(itemMaterial, itemData);
|
||||||
|
|
||||||
|
List<String> lore = new ArrayList<String>();
|
||||||
|
if (config.contains("Items." + itemName + ".Lore")) {
|
||||||
|
|
||||||
|
for (String loreEntry : config.getStringList("Items." + itemName + ".Lore")) {
|
||||||
|
lore.add(ChatColor.translateAlternateColorCodes('&', loreEntry));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String name = null;
|
||||||
|
if (config.contains("Items." + itemName + ".Name")) {
|
||||||
|
name = ChatColor.translateAlternateColorCodes('&', config.getString("Items." + itemName + ".Name"));
|
||||||
|
}
|
||||||
|
|
||||||
|
SoulbindItem soulbindItem = new SoulbindItem(itemMaterialData, name, lore);
|
||||||
|
|
||||||
|
List<String> actions = config.getStringList("Items." + itemName + ".Actions");
|
||||||
|
|
||||||
|
for (ActionType actionType : ActionType.values()) {
|
||||||
|
if (actions.contains(actionType.toString())) {
|
||||||
|
addSoulbindItem(actionType, soulbindItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addSoulbindItem(ActionType actionType, SoulbindItem soulbindItem) {
|
||||||
|
switch (actionType) {
|
||||||
|
case CRAFT:
|
||||||
|
soulbindOnCraft.add(soulbindItem);
|
||||||
|
return;
|
||||||
|
case OPEN_CHEST:
|
||||||
|
soulbindOnOpenChest.add(soulbindItem);
|
||||||
|
return;
|
||||||
|
case PICKUP_ITEM:
|
||||||
|
soulbindOnPickupItem.add(soulbindItem);
|
||||||
|
return;
|
||||||
|
case DROP_ITEM:
|
||||||
|
soulbindOnDrop.add(soulbindItem);
|
||||||
|
return;
|
||||||
|
case RESPAWN:
|
||||||
|
soulbindOnRespawn.add(soulbindItem);
|
||||||
|
return;
|
||||||
|
case KIT:
|
||||||
|
soulbindOnKit.add(soulbindItem);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<SoulbindItem> getSoulbindItems(ActionType actionType) {
|
||||||
|
switch (actionType) {
|
||||||
|
case CRAFT:
|
||||||
|
return soulbindOnCraft;
|
||||||
|
case OPEN_CHEST:
|
||||||
|
return soulbindOnOpenChest;
|
||||||
|
case PICKUP_ITEM:
|
||||||
|
return soulbindOnPickupItem;
|
||||||
|
case DROP_ITEM:
|
||||||
|
return soulbindOnDrop;
|
||||||
|
case RESPAWN:
|
||||||
|
return soulbindOnRespawn;
|
||||||
|
case KIT:
|
||||||
|
return soulbindOnKit;
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isActionItem(ItemStack itemStack, ActionType actionType) {
|
||||||
|
for (SoulbindItem soulbindItem : getSoulbindItems(actionType)) {
|
||||||
|
if (itemStack.getData().equals(soulbindItem.getMaterialData())) {
|
||||||
|
if (itemStack.hasItemMeta()) {
|
||||||
|
ItemMeta itemMeta = itemStack.getItemMeta();
|
||||||
|
|
||||||
|
if (soulbindItem.getName() != null) {
|
||||||
|
if (!itemMeta.getDisplayName().contains(soulbindItem.getName())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (soulbindItem.getLore() != null && !soulbindItem.getLore().isEmpty()) {
|
||||||
|
if (itemMeta.hasLore() || !itemMeta.getLore().containsAll(soulbindItem.getLore())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package com.me.tft_02.soulbound.datatypes;
|
||||||
|
|
||||||
|
public enum ActionType {
|
||||||
|
CRAFT,
|
||||||
|
OPEN_CHEST,
|
||||||
|
PICKUP_ITEM,
|
||||||
|
DROP_ITEM,
|
||||||
|
RESPAWN,
|
||||||
|
KIT;
|
||||||
|
};
|
@ -0,0 +1,34 @@
|
|||||||
|
package com.me.tft_02.soulbound.datatypes;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.bukkit.material.MaterialData;
|
||||||
|
|
||||||
|
public class SoulbindItem {
|
||||||
|
private MaterialData materialData;
|
||||||
|
private String name;
|
||||||
|
private List<String> lore;
|
||||||
|
|
||||||
|
public SoulbindItem(MaterialData materialData, String name, List<String> lore) {
|
||||||
|
this.materialData = materialData;
|
||||||
|
this.name = name;
|
||||||
|
this.lore = lore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MaterialData getMaterialData() {
|
||||||
|
return materialData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getLore() {
|
||||||
|
return lore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return materialData.toString() + " " + name.toString() + " " + lore.toString();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
package com.me.tft_02.soulbound.events;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.Cancellable;
|
||||||
|
import org.bukkit.event.HandlerList;
|
||||||
|
import org.bukkit.event.player.PlayerEvent;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
public class SoulbindItemEvent extends PlayerEvent implements Cancellable {
|
||||||
|
private ItemStack itemStack;
|
||||||
|
private boolean cancelled;
|
||||||
|
|
||||||
|
public SoulbindItemEvent(Player player, ItemStack itemStack) {
|
||||||
|
super(player);
|
||||||
|
|
||||||
|
this.setItemStack(itemStack);
|
||||||
|
this.cancelled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The itemStack being soulbound
|
||||||
|
*/
|
||||||
|
public ItemStack getItemStack() {
|
||||||
|
return itemStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Set the itemStack being soulbound
|
||||||
|
*/
|
||||||
|
public void setItemStack(ItemStack itemStack) {
|
||||||
|
this.itemStack = itemStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCancelled() {
|
||||||
|
return cancelled;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCancelled(boolean cancelled) {
|
||||||
|
this.cancelled = cancelled;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final HandlerList handlers = new HandlerList();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HandlerList getHandlers() {
|
||||||
|
return handlers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HandlerList getHandlerList() {
|
||||||
|
return handlers;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
package com.me.tft_02.soulbound.hooks;
|
||||||
|
|
||||||
|
//import me.ThaH3lper.com.Api.BossDeathEvent;
|
||||||
|
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import com.me.tft_02.soulbound.config.Config;
|
||||||
|
import com.me.tft_02.soulbound.util.ItemUtils;
|
||||||
|
|
||||||
|
public class EpicBossRecodedListener implements Listener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check BossDeathEvent events.
|
||||||
|
*
|
||||||
|
* @param event The event to check
|
||||||
|
*/
|
||||||
|
/* @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
|
public void onBossDeath(BossDeathEvent event) {
|
||||||
|
if (event.getDrops().isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ItemStack itemStack : event.getDrops()) {
|
||||||
|
handleEpicBossItems(itemStack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
public void handleEpicBossItems(ItemStack itemStack) {
|
||||||
|
if (Config.getInstance().getEBRBindOnEquip() && ItemUtils.isEquipable(itemStack)) {
|
||||||
|
ItemUtils.boeItem(itemStack);
|
||||||
|
}
|
||||||
|
else if (Config.getInstance().getEBRBindOnPickup()) {
|
||||||
|
ItemUtils.bopItem(itemStack);
|
||||||
|
}
|
||||||
|
else if (Config.getInstance().getEBRBindOnUse()) {
|
||||||
|
ItemUtils.bouItem(itemStack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package com.me.tft_02.soulbound.listeners;
|
||||||
|
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.block.BlockBreakEvent;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import com.me.tft_02.soulbound.util.DurabilityUtils;
|
||||||
|
|
||||||
|
public class BlockListener implements Listener {
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
||||||
|
public void onBlockBreak(BlockBreakEvent event) {
|
||||||
|
ItemStack itemStack = event.getPlayer().getItemInHand();
|
||||||
|
|
||||||
|
DurabilityUtils.handleInfiniteDurability(itemStack);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,80 @@
|
|||||||
|
package com.me.tft_02.soulbound.listeners;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.EntityType;
|
||||||
|
import org.bukkit.entity.LivingEntity;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||||
|
import org.bukkit.event.entity.EntityDamageEvent;
|
||||||
|
import org.bukkit.event.entity.EntityShootBowEvent;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import com.me.tft_02.soulbound.util.DurabilityUtils;
|
||||||
|
|
||||||
|
public class EntityListener implements Listener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check EntityDamageByEntityEvent events.
|
||||||
|
*
|
||||||
|
* @param event The event to check
|
||||||
|
*/
|
||||||
|
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
||||||
|
public void onEntityDeath(EntityDamageByEntityEvent event) {
|
||||||
|
if (event.getDamage() == 0 || event.getEntity().isDead()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.getEntity() instanceof LivingEntity) {
|
||||||
|
combatChecks(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply combat modifiers
|
||||||
|
*
|
||||||
|
* @param event The event to run the combat checks on.
|
||||||
|
*/
|
||||||
|
void combatChecks(EntityDamageByEntityEvent event) {
|
||||||
|
Entity damager = event.getDamager();
|
||||||
|
EntityType damagerType = damager.getType();
|
||||||
|
|
||||||
|
switch (damagerType) {
|
||||||
|
case PLAYER:
|
||||||
|
Player attacker = (Player) event.getDamager();
|
||||||
|
ItemStack itemInHand = attacker.getItemInHand();
|
||||||
|
|
||||||
|
DurabilityUtils.handleInfiniteDurability(itemInHand);
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
||||||
|
private void onEntityShootBow(EntityShootBowEvent event) {
|
||||||
|
Entity entity = event.getEntity();
|
||||||
|
|
||||||
|
if (entity instanceof Player) {
|
||||||
|
DurabilityUtils.handleInfiniteDurability(((Player) entity).getItemInHand());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
||||||
|
private void onEntityDamage(EntityDamageEvent event) {
|
||||||
|
if (event.getDamage() == 0 || event.getEntity().isDead()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Entity entity = event.getEntity();
|
||||||
|
|
||||||
|
if (entity instanceof Player) {
|
||||||
|
Player player = (Player) entity;
|
||||||
|
|
||||||
|
for (ItemStack itemStack : player.getInventory().getArmorContents()) {
|
||||||
|
DurabilityUtils.handleInfiniteDurability(itemStack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,179 @@
|
|||||||
|
package com.me.tft_02.soulbound.listeners;
|
||||||
|
|
||||||
|
import org.bukkit.entity.HumanEntity;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.enchantment.EnchantItemEvent;
|
||||||
|
import org.bukkit.event.inventory.CraftItemEvent;
|
||||||
|
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||||
|
import org.bukkit.event.inventory.InventoryMoveItemEvent;
|
||||||
|
import org.bukkit.event.inventory.InventoryOpenEvent;
|
||||||
|
import org.bukkit.event.inventory.InventoryPickupItemEvent;
|
||||||
|
import org.bukkit.event.inventory.InventoryType;
|
||||||
|
import org.bukkit.event.inventory.InventoryType.SlotType;
|
||||||
|
import org.bukkit.inventory.Inventory;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import com.me.tft_02.soulbound.Soulbound;
|
||||||
|
import com.me.tft_02.soulbound.config.Config;
|
||||||
|
import com.me.tft_02.soulbound.config.ItemsConfig;
|
||||||
|
import com.me.tft_02.soulbound.datatypes.ActionType;
|
||||||
|
import com.me.tft_02.soulbound.runnables.UpdateArmorTask;
|
||||||
|
import com.me.tft_02.soulbound.util.ItemUtils;
|
||||||
|
import com.me.tft_02.soulbound.util.ItemUtils.ItemType;
|
||||||
|
import com.me.tft_02.soulbound.util.Permissions;
|
||||||
|
|
||||||
|
public class InventoryListener implements Listener {
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||||
|
void onInventoryClick(InventoryClickEvent event) {
|
||||||
|
HumanEntity entity = event.getWhoClicked();
|
||||||
|
ItemStack itemStack = event.getCurrentItem();
|
||||||
|
|
||||||
|
SlotType slotType = event.getSlotType();
|
||||||
|
InventoryType inventoryType = event.getInventory().getType();
|
||||||
|
|
||||||
|
if (inventoryType == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (itemStack == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entity instanceof Player) {
|
||||||
|
Player player = (Player) entity;
|
||||||
|
switch (slotType) {
|
||||||
|
case ARMOR:
|
||||||
|
new UpdateArmorTask(player).runTaskLater(Soulbound.p, 2);
|
||||||
|
return;
|
||||||
|
case CONTAINER:
|
||||||
|
ItemType itemType = ItemUtils.getItemType(itemStack);
|
||||||
|
switch (itemType) {
|
||||||
|
case BIND_ON_PICKUP:
|
||||||
|
ItemUtils.soulbindItem(player, itemStack);
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
if (ItemUtils.isEquipable(itemStack) && event.isShiftClick()) {
|
||||||
|
new UpdateArmorTask(player).runTaskLater(Soulbound.p, 2);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
|
public void onInventoryClickEvent(InventoryClickEvent event) {
|
||||||
|
HumanEntity entity = event.getWhoClicked();
|
||||||
|
|
||||||
|
if (!(entity instanceof Player)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Player player = (Player) entity;
|
||||||
|
ItemStack itemStack = event.getCurrentItem();
|
||||||
|
InventoryType inventoryType = event.getInventory().getType();
|
||||||
|
|
||||||
|
if (inventoryType == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemType itemType = ItemUtils.getItemType(itemStack);
|
||||||
|
|
||||||
|
if (itemType != ItemType.SOULBOUND) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Config.getInstance().getAllowItemStoring() && !(inventoryType == InventoryType.CRAFTING)) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ItemUtils.isBindedPlayer(player, itemStack) || Permissions.pickupBypass(player)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
|
public void onInventoryMoveEvent(InventoryMoveItemEvent event) {
|
||||||
|
ItemStack itemStack = event.getItem();
|
||||||
|
ItemType itemType = ItemUtils.getItemType(itemStack);
|
||||||
|
|
||||||
|
if (itemType == ItemType.SOULBOUND) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
|
public void onInventoryPickupItemEvent(InventoryPickupItemEvent event) {
|
||||||
|
ItemStack itemStack = event.getItem().getItemStack();
|
||||||
|
ItemType itemType = ItemUtils.getItemType(itemStack);
|
||||||
|
|
||||||
|
if (itemType == ItemType.SOULBOUND) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
|
public void onInventoryOpen(InventoryOpenEvent event) {
|
||||||
|
HumanEntity humanEntity = event.getPlayer();
|
||||||
|
Inventory inventory = event.getInventory();
|
||||||
|
|
||||||
|
if (!(humanEntity instanceof Player)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Player player = (Player) humanEntity;
|
||||||
|
|
||||||
|
for (ItemStack itemStack : inventory.getContents()) {
|
||||||
|
if (itemStack != null && ItemsConfig.getInstance().isActionItem(itemStack, ActionType.OPEN_CHEST)) {
|
||||||
|
ItemUtils.soulbindItem(player, itemStack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check CraftItemEvent events.
|
||||||
|
*
|
||||||
|
* @param event The event to check
|
||||||
|
*/
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
|
private void onCraftItem(CraftItemEvent event) {
|
||||||
|
HumanEntity humanEntity = event.getWhoClicked();
|
||||||
|
|
||||||
|
if (!(humanEntity instanceof Player)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Player player = (Player) humanEntity;
|
||||||
|
|
||||||
|
ItemStack itemStack = event.getRecipe().getResult();
|
||||||
|
|
||||||
|
if (ItemsConfig.getInstance().isActionItem(itemStack, ActionType.CRAFT)) {
|
||||||
|
event.getInventory().setResult(ItemUtils.soulbindItem(player, itemStack));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check EnchantItemEvent events.
|
||||||
|
*
|
||||||
|
* @param event The event to check
|
||||||
|
*/
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
|
private void onEnchantItem(EnchantItemEvent event) {
|
||||||
|
Player player = event.getEnchanter();
|
||||||
|
ItemStack itemStack = event.getItem();
|
||||||
|
|
||||||
|
if (ItemUtils.isBindOnUse(itemStack)) {
|
||||||
|
ItemUtils.soulbindItem(player, itemStack);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,284 @@
|
|||||||
|
package com.me.tft_02.soulbound.listeners;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.Sound;
|
||||||
|
import org.bukkit.entity.Item;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.block.Action;
|
||||||
|
import org.bukkit.event.entity.PlayerDeathEvent;
|
||||||
|
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
|
||||||
|
import org.bukkit.event.player.PlayerDropItemEvent;
|
||||||
|
import org.bukkit.event.player.PlayerFishEvent;
|
||||||
|
import org.bukkit.event.player.PlayerInteractEvent;
|
||||||
|
import org.bukkit.event.player.PlayerJoinEvent;
|
||||||
|
import org.bukkit.event.player.PlayerPickupItemEvent;
|
||||||
|
import org.bukkit.event.player.PlayerRespawnEvent;
|
||||||
|
import org.bukkit.event.player.PlayerShearEntityEvent;
|
||||||
|
import org.bukkit.event.server.ServerCommandEvent;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import com.me.tft_02.soulbound.Soulbound;
|
||||||
|
import com.me.tft_02.soulbound.config.Config;
|
||||||
|
import com.me.tft_02.soulbound.config.ItemsConfig;
|
||||||
|
import com.me.tft_02.soulbound.datatypes.ActionType;
|
||||||
|
import com.me.tft_02.soulbound.runnables.SoulbindInventoryTask;
|
||||||
|
import com.me.tft_02.soulbound.runnables.UpdateArmorTask;
|
||||||
|
import com.me.tft_02.soulbound.runnables.UpdateInventoryTask;
|
||||||
|
import com.me.tft_02.soulbound.util.CommandUtils;
|
||||||
|
import com.me.tft_02.soulbound.util.DurabilityUtils;
|
||||||
|
import com.me.tft_02.soulbound.util.ItemUtils;
|
||||||
|
import com.me.tft_02.soulbound.util.Permissions;
|
||||||
|
import com.me.tft_02.soulbound.util.PlayerData;
|
||||||
|
|
||||||
|
public class PlayerListener implements Listener {
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||||
|
private void onPlayerJoin(PlayerJoinEvent event) {
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
|
||||||
|
if (Soulbound.p.isUpdateAvailable() && Permissions.updateCheck(player)) {
|
||||||
|
player.sendMessage(ChatColor.GOLD + "Soulbound is outdated!");
|
||||||
|
player.sendMessage(ChatColor.AQUA + "http://dev.bukkit.org/server-mods/Soulbound/");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
||||||
|
private void onItemPickup(PlayerPickupItemEvent event) {
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
Item item = event.getItem();
|
||||||
|
ItemStack itemStack = item.getItemStack();
|
||||||
|
|
||||||
|
if (ItemUtils.isSoulbound(itemStack) && !ItemUtils.isBindedPlayer(player, itemStack)) {
|
||||||
|
if (Permissions.pickupBypass(player)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
event.setCancelled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ItemUtils.isBindOnPickup(itemStack)) {
|
||||||
|
ItemUtils.soulbindItem(player, itemStack);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ItemsConfig.getInstance().isActionItem(itemStack, ActionType.PICKUP_ITEM)) {
|
||||||
|
ItemUtils.soulbindItem(player, itemStack);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
|
private void onItemDrop(PlayerDropItemEvent event) {
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
Item item = event.getItemDrop();
|
||||||
|
ItemStack itemStack = item.getItemStack();
|
||||||
|
|
||||||
|
if (Config.getInstance().getPreventItemDrop()) {
|
||||||
|
if (ItemUtils.isSoulbound(itemStack) && ItemUtils.isBindedPlayer(player, itemStack)) {
|
||||||
|
item.setPickupDelay(2 * 20);
|
||||||
|
event.setCancelled(true);
|
||||||
|
new UpdateInventoryTask(player).runTask(Soulbound.p);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Config.getInstance().getDeleteOnDrop()) {
|
||||||
|
player.playSound(player.getLocation(), Sound.ITEM_BREAK, 1.0F, 1.0F);
|
||||||
|
event.getItemDrop().remove();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ItemsConfig.getInstance().isActionItem(itemStack, ActionType.DROP_ITEM)) {
|
||||||
|
ItemUtils.soulbindItem(player, itemStack);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
|
private void onPlayerDeath(PlayerDeathEvent event) {
|
||||||
|
Player player = event.getEntity();
|
||||||
|
|
||||||
|
boolean deleteOnDeath = Permissions.deleteOnDeath(player);
|
||||||
|
boolean keepOnDeath = Permissions.keepOnDeath(player);
|
||||||
|
|
||||||
|
List<ItemStack> items = new ArrayList<ItemStack>();
|
||||||
|
|
||||||
|
if (!keepOnDeath && !deleteOnDeath) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ItemStack item : new ArrayList<ItemStack>(event.getDrops())) {
|
||||||
|
if (ItemUtils.isSoulbound(item) && ItemUtils.isBindedPlayer(player, item)) {
|
||||||
|
if (keepOnDeath) {
|
||||||
|
items.add(item);
|
||||||
|
event.getDrops().remove(item);
|
||||||
|
}
|
||||||
|
else if (deleteOnDeath) {
|
||||||
|
event.getDrops().remove(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PlayerData.storeItemsDeath(player, items);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||||
|
private void onPlayerRespawn(PlayerRespawnEvent event) {
|
||||||
|
new SoulbindInventoryTask(event.getPlayer(), ActionType.RESPAWN).runTask(Soulbound.p);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
|
private void onPlayerRespawnHighest(PlayerRespawnEvent event) {
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
boolean keepOnDeath = Permissions.keepOnDeath(player);
|
||||||
|
|
||||||
|
if (!keepOnDeath) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ItemStack> items = new ArrayList<ItemStack>();
|
||||||
|
items = PlayerData.retrieveItemsDeath(player);
|
||||||
|
if (items != null) {
|
||||||
|
for (ItemStack item : items) {
|
||||||
|
player.getInventory().addItem(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
new UpdateInventoryTask(player).runTask(Soulbound.p);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Watch PlayerInteract events.
|
||||||
|
*
|
||||||
|
* @param event The event to watch
|
||||||
|
*/
|
||||||
|
@EventHandler(priority = EventPriority.LOW)
|
||||||
|
public void onPlayerInteract(PlayerInteractEvent event) {
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
Action action = event.getAction();
|
||||||
|
ItemStack inHand = player.getItemInHand();
|
||||||
|
|
||||||
|
switch (action) {
|
||||||
|
case RIGHT_CLICK_BLOCK:
|
||||||
|
case RIGHT_CLICK_AIR:
|
||||||
|
case LEFT_CLICK_AIR:
|
||||||
|
case LEFT_CLICK_BLOCK:
|
||||||
|
if (ItemUtils.isEquipable(inHand)) {
|
||||||
|
new UpdateArmorTask(player).runTaskLater(Soulbound.p, 2);
|
||||||
|
}
|
||||||
|
else if (ItemUtils.isBindOnUse(inHand)) {
|
||||||
|
ItemUtils.soulbindItem(player, inHand);
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Monitor PlayerFishEvent events.
|
||||||
|
*
|
||||||
|
* @param event The event to monitor
|
||||||
|
*/
|
||||||
|
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
||||||
|
private void onPlayerFish(PlayerFishEvent event) {
|
||||||
|
ItemStack itemInHand = event.getPlayer().getItemInHand();
|
||||||
|
|
||||||
|
DurabilityUtils.handleInfiniteDurability(itemInHand);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Monitor PlayerShearEntityEvent events.
|
||||||
|
*
|
||||||
|
* @param event The event to monitor
|
||||||
|
*/
|
||||||
|
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
||||||
|
private void onPlayerShearEntity(PlayerShearEntityEvent event) {
|
||||||
|
ItemStack itemInHand = event.getPlayer().getItemInHand();
|
||||||
|
|
||||||
|
DurabilityUtils.handleInfiniteDurability(itemInHand);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Watch PlayerCommandPreprocessEvent events.
|
||||||
|
*
|
||||||
|
* @param event The event to watch
|
||||||
|
*/
|
||||||
|
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||||
|
public void onPlayerCommand(PlayerCommandPreprocessEvent event) {
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
ItemStack itemStack = player.getItemInHand();
|
||||||
|
String command = event.getMessage();
|
||||||
|
|
||||||
|
if (ItemUtils.isSoulbound(itemStack) && Config.getInstance().getBlockedCommands().contains(command)) {
|
||||||
|
player.sendMessage(ChatColor.RED + "You're not allowed to use " + ChatColor.GOLD + command + ChatColor.RED + " command while holding a Soulbound item.");
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Monitor PlayerCommandPreprocessEvent events.
|
||||||
|
*
|
||||||
|
* @param event The event to monitor
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||||
|
public void onPlayerCommandMonitor(PlayerCommandPreprocessEvent event) {
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
ItemStack inHand = player.getItemInHand();
|
||||||
|
String command = event.getMessage();
|
||||||
|
String[] args = CommandUtils.extractArgs(command);
|
||||||
|
|
||||||
|
if (!ItemUtils.isSoulbound(inHand) && Config.getInstance().getBindCommands().contains(command)) {
|
||||||
|
ItemUtils.soulbindItem(player, inHand);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command.contains("kit")) {
|
||||||
|
Player target;
|
||||||
|
|
||||||
|
if (args.length >= 2) {
|
||||||
|
target = Soulbound.p.getServer().getPlayer(args[1]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
target = player;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
new SoulbindInventoryTask(target, ActionType.KIT).runTask(Soulbound.p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Monitor ServerCommandEvent events.
|
||||||
|
*
|
||||||
|
* @param event The event to monitor
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||||
|
public void onServerCommand(ServerCommandEvent event) {
|
||||||
|
String command = event.getCommand();
|
||||||
|
String[] args = CommandUtils.extractArgs(command);
|
||||||
|
|
||||||
|
if (!command.contains("kit")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.length < 2) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Player target = Soulbound.p.getServer().getPlayer(args[1]);
|
||||||
|
|
||||||
|
new SoulbindInventoryTask(target, ActionType.KIT).runTask(Soulbound.p);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package com.me.tft_02.soulbound.listeners;
|
||||||
|
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.inventory.Inventory;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import com.me.tft_02.soulbound.events.SoulbindItemEvent;
|
||||||
|
import com.me.tft_02.soulbound.util.ItemUtils;
|
||||||
|
import com.me.tft_02.soulbound.util.Permissions;
|
||||||
|
|
||||||
|
public class SelfListener implements Listener {
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
|
private void onItemSoulbound(SoulbindItemEvent event) {
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
Inventory inventory = player.getInventory();
|
||||||
|
int maxAmount = Permissions.getSoulbindMaximum(player);
|
||||||
|
|
||||||
|
if (maxAmount < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
for (ItemStack itemStack : inventory.getContents()) {
|
||||||
|
if (itemStack != null && ItemUtils.isSoulbound(itemStack)) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (count >= maxAmount) {
|
||||||
|
player.sendMessage(ChatColor.RED + "Cannot Soulbind any more items, maximum amount reached! " + ChatColor.GOLD + "(" + maxAmount + ")");
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
package com.me.tft_02.soulbound.runnables;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
|
|
||||||
|
import com.me.tft_02.soulbound.config.ItemsConfig;
|
||||||
|
import com.me.tft_02.soulbound.datatypes.ActionType;
|
||||||
|
import com.me.tft_02.soulbound.util.ItemUtils;
|
||||||
|
|
||||||
|
public class SoulbindInventoryTask extends BukkitRunnable {
|
||||||
|
private Player player;
|
||||||
|
private ActionType actionType;
|
||||||
|
|
||||||
|
public SoulbindInventoryTask(Player player, ActionType actionType) {
|
||||||
|
this.player = player;
|
||||||
|
this.actionType = actionType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
for (ItemStack itemStack : player.getInventory().getContents()) {
|
||||||
|
if (itemStack != null && ItemsConfig.getInstance().isActionItem(itemStack, actionType)) {
|
||||||
|
ItemUtils.soulbindItem(player, itemStack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ItemStack itemStack : player.getInventory().getArmorContents()) {
|
||||||
|
if (itemStack != null && ItemsConfig.getInstance().isActionItem(itemStack, actionType)) {
|
||||||
|
ItemUtils.soulbindItem(player, itemStack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
package com.me.tft_02.soulbound.runnables;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
|
|
||||||
|
import com.me.tft_02.soulbound.util.ItemUtils;
|
||||||
|
import com.me.tft_02.soulbound.util.ItemUtils.ItemType;
|
||||||
|
|
||||||
|
public class UpdateArmorTask extends BukkitRunnable {
|
||||||
|
private Player player;
|
||||||
|
|
||||||
|
public UpdateArmorTask(Player player) {
|
||||||
|
this.player = player;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
handleBindOnEquip(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handleBindOnEquip(Player player) {
|
||||||
|
for (ItemStack armor : player.getInventory().getArmorContents()) {
|
||||||
|
if (armor != null && ItemUtils.getItemType(armor) == ItemType.BIND_ON_EQUIP) {
|
||||||
|
ItemUtils.soulbindItem(player, armor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
player.getInventory().setArmorContents(player.getInventory().getArmorContents());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
package com.me.tft_02.soulbound.runnables;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
|
|
||||||
|
public class UpdateInventoryTask extends BukkitRunnable {
|
||||||
|
private Player player;
|
||||||
|
|
||||||
|
public UpdateInventoryTask(Player player) {
|
||||||
|
this.player = player;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (player.isValid()) {
|
||||||
|
player.updateInventory();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
38
src/main/java/com/me/tft_02/soulbound/util/CommandUtils.java
Normal file
38
src/main/java/com/me/tft_02/soulbound/util/CommandUtils.java
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
package com.me.tft_02.soulbound.util;
|
||||||
|
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.OfflinePlayer;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
public final class CommandUtils {
|
||||||
|
|
||||||
|
public static String[] extractArgs(String command) {
|
||||||
|
String[] args = {""};
|
||||||
|
String[] split = command.split(" ", 2);
|
||||||
|
|
||||||
|
if (split.length > 1) {
|
||||||
|
args = split[1].split(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean noConsoleUsage(CommandSender sender) {
|
||||||
|
if (sender instanceof Player) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
sender.sendMessage("This command does not support console usage.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isOffline(CommandSender sender, OfflinePlayer player) {
|
||||||
|
if (player != null && player.isOnline()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
sender.sendMessage(ChatColor.RED + "This command does not work for offline players.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
package com.me.tft_02.soulbound.util;
|
||||||
|
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import com.me.tft_02.soulbound.config.Config;
|
||||||
|
|
||||||
|
public class DurabilityUtils {
|
||||||
|
|
||||||
|
public static void handleInfiniteDurability(ItemStack itemStack) {
|
||||||
|
if (Config.getInstance().getInfiniteDurability() && ItemUtils.isSoulbound(itemStack)) {
|
||||||
|
itemStack.setDurability((short) 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
435
src/main/java/com/me/tft_02/soulbound/util/ItemUtils.java
Normal file
435
src/main/java/com/me/tft_02/soulbound/util/ItemUtils.java
Normal file
@ -0,0 +1,435 @@
|
|||||||
|
package com.me.tft_02.soulbound.util;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
|
||||||
|
import com.me.tft_02.soulbound.Soulbound;
|
||||||
|
import com.me.tft_02.soulbound.config.Config;
|
||||||
|
import com.me.tft_02.soulbound.events.SoulbindItemEvent;
|
||||||
|
|
||||||
|
public class ItemUtils {
|
||||||
|
public enum ItemType {
|
||||||
|
NORMAL,
|
||||||
|
SOULBOUND,
|
||||||
|
BIND_ON_PICKUP,
|
||||||
|
BIND_ON_USE,
|
||||||
|
BIND_ON_EQUIP;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ItemStack soulbindItem(Player player, ItemStack itemStack) {
|
||||||
|
if (itemStack == null) {
|
||||||
|
return itemStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isSoulbound(itemStack)) {
|
||||||
|
return itemStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
SoulbindItemEvent soulbindItemEvent = new SoulbindItemEvent(player, itemStack);
|
||||||
|
Soulbound.p.getServer().getPluginManager().callEvent(soulbindItemEvent);
|
||||||
|
itemStack = soulbindItemEvent.getItemStack();
|
||||||
|
|
||||||
|
if (soulbindItemEvent.isCancelled()) {
|
||||||
|
return itemStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemMeta itemMeta = itemStack.getItemMeta();
|
||||||
|
List<String> itemLore = new ArrayList<String>();
|
||||||
|
|
||||||
|
if (itemMeta.hasLore()) {
|
||||||
|
List<String> oldLore = itemMeta.getLore();
|
||||||
|
oldLore.remove(ChatColor.DARK_RED + "Bind on Pickup");
|
||||||
|
oldLore.remove(ChatColor.DARK_RED + "Bind on Equip");
|
||||||
|
oldLore.remove(ChatColor.DARK_RED + "Bind on Use");
|
||||||
|
itemLore.addAll(oldLore);
|
||||||
|
}
|
||||||
|
|
||||||
|
itemLore.add(Misc.SOULBOUND_TAG + StringUtils.hideUUID(player.getUniqueId()));
|
||||||
|
|
||||||
|
if (Config.getInstance().getShowNameInLore()) {
|
||||||
|
itemLore.add(player.getName());
|
||||||
|
}
|
||||||
|
itemMeta.setLore(itemLore);
|
||||||
|
itemStack.setItemMeta(itemMeta);
|
||||||
|
return itemStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ItemStack bopItem(ItemStack itemStack) {
|
||||||
|
if (itemStack == null) {
|
||||||
|
return itemStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isBindOnPickup(itemStack)) {
|
||||||
|
return itemStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemMeta itemMeta = itemStack.getItemMeta();
|
||||||
|
|
||||||
|
List<String> itemLore = new ArrayList<String>();
|
||||||
|
if (itemMeta.hasLore()) {
|
||||||
|
itemLore.addAll(itemMeta.getLore());
|
||||||
|
}
|
||||||
|
itemLore.add(ChatColor.DARK_RED + "Bind on Pickup");
|
||||||
|
itemMeta.setLore(itemLore);
|
||||||
|
itemStack.setItemMeta(itemMeta);
|
||||||
|
return itemStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ItemStack boeItem(ItemStack itemStack) {
|
||||||
|
if (itemStack == null) {
|
||||||
|
return itemStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isBindOnEquip(itemStack)) {
|
||||||
|
return itemStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemMeta itemMeta = itemStack.getItemMeta();
|
||||||
|
|
||||||
|
List<String> itemLore = new ArrayList<String>();
|
||||||
|
if (itemMeta.hasLore()) {
|
||||||
|
itemLore.addAll(itemMeta.getLore());
|
||||||
|
}
|
||||||
|
itemLore.add(ChatColor.DARK_RED + "Bind on Equip");
|
||||||
|
itemMeta.setLore(itemLore);
|
||||||
|
itemStack.setItemMeta(itemMeta);
|
||||||
|
return itemStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ItemStack bouItem(ItemStack itemStack) {
|
||||||
|
if (itemStack == null) {
|
||||||
|
return itemStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isBindOnUse(itemStack)) {
|
||||||
|
return itemStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemMeta itemMeta = itemStack.getItemMeta();
|
||||||
|
|
||||||
|
List<String> itemLore = new ArrayList<String>();
|
||||||
|
if (itemMeta.hasLore()) {
|
||||||
|
itemLore.addAll(itemMeta.getLore());
|
||||||
|
}
|
||||||
|
itemLore.add(ChatColor.DARK_RED + "Bind on Use");
|
||||||
|
itemMeta.setLore(itemLore);
|
||||||
|
itemStack.setItemMeta(itemMeta);
|
||||||
|
return itemStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ItemStack unbindItem(ItemStack itemStack) {
|
||||||
|
if (itemStack == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemMeta itemMeta = itemStack.getItemMeta();
|
||||||
|
if (itemMeta.hasLore() && isSoulbound(itemStack)) {
|
||||||
|
List<String> oldLore = itemMeta.getLore();
|
||||||
|
int loreSize = oldLore.size();
|
||||||
|
|
||||||
|
if (loreSize <= 2) {
|
||||||
|
itemMeta.setLore(null);
|
||||||
|
itemStack.setItemMeta(itemMeta);
|
||||||
|
return itemStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> itemLore = new ArrayList<String>();
|
||||||
|
itemLore.addAll(oldLore);
|
||||||
|
int index = StringUtils.getIndexOfSoulbound(itemLore);
|
||||||
|
if (index == -1){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
itemLore.remove(index);
|
||||||
|
if (index<itemLore.size())
|
||||||
|
itemLore.remove(index);
|
||||||
|
|
||||||
|
itemMeta.setLore(itemLore);
|
||||||
|
}
|
||||||
|
|
||||||
|
itemStack.setItemMeta(itemMeta);
|
||||||
|
return itemStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isSoulbound(ItemStack itemStack) {
|
||||||
|
if (!itemStack.hasItemMeta()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemMeta itemMeta = itemStack.getItemMeta();
|
||||||
|
if (itemMeta.hasLore()) {
|
||||||
|
List<String> itemLore = itemMeta.getLore();
|
||||||
|
for (String lore : itemLore) {
|
||||||
|
if (lore.equalsIgnoreCase(Misc.SOULBOUND_TAG)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isBindOnPickup(ItemStack itemStack) {
|
||||||
|
if (!itemStack.hasItemMeta()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemMeta itemMeta = itemStack.getItemMeta();
|
||||||
|
if (itemMeta.hasLore()) {
|
||||||
|
List<String> itemLore = itemMeta.getLore();
|
||||||
|
if (itemLore.contains(ChatColor.DARK_RED + "Bind on Pickup")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isBindOnUse(ItemStack itemStack) {
|
||||||
|
if (!itemStack.hasItemMeta()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemMeta itemMeta = itemStack.getItemMeta();
|
||||||
|
if (itemMeta.hasLore()) {
|
||||||
|
List<String> itemLore = itemMeta.getLore();
|
||||||
|
if (itemLore.contains(ChatColor.DARK_RED + "Bind on Use")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isBindOnEquip(ItemStack itemStack) {
|
||||||
|
if (!itemStack.hasItemMeta()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemMeta itemMeta = itemStack.getItemMeta();
|
||||||
|
if (itemMeta.hasLore()) {
|
||||||
|
List<String> itemLore = itemMeta.getLore();
|
||||||
|
if (itemLore.contains(ChatColor.DARK_RED + "Bind on Equip")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isBindedPlayer(Player player, ItemStack itemStack) {
|
||||||
|
updateOldLore(player, itemStack);
|
||||||
|
checkNameChange(player, itemStack);
|
||||||
|
List<String> itemLore = itemStack.getItemMeta().getLore();
|
||||||
|
|
||||||
|
Soulbound.p.debug("UUID MATCH? " + player.getUniqueId().equals(StringUtils.readUUIDFromLore(itemLore)));
|
||||||
|
Soulbound.p.debug("NAME MATCH? " + itemLore.contains(player.getName()));
|
||||||
|
|
||||||
|
return player.getUniqueId().equals(StringUtils.readUUIDFromLore(itemLore)) || itemLore.contains(player.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ItemStack updateOldLore(Player player, ItemStack itemStack) {
|
||||||
|
ItemMeta itemMeta = itemStack.getItemMeta();
|
||||||
|
if (itemMeta != null) {
|
||||||
|
if (!itemMeta.hasLore()) {
|
||||||
|
return itemStack;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<String> itemLore = itemMeta.getLore();
|
||||||
|
|
||||||
|
if (itemLore.size() - 1 < StringUtils.getIndexOfSoulbound(itemLore) + 2) {
|
||||||
|
return itemStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
int indexOfSoulbound = StringUtils.getIndexOfSoulbound(itemLore);
|
||||||
|
int indexOfUniqueId = indexOfSoulbound + 2;
|
||||||
|
UUID uuid = null;
|
||||||
|
|
||||||
|
if (itemLore.get(indexOfUniqueId).contains(player.getUniqueId().toString())) {
|
||||||
|
uuid = UUID.fromString(ChatColor.stripColor(itemLore.get(indexOfUniqueId)));
|
||||||
|
itemLore.remove(indexOfUniqueId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StringUtils.readUUIDFromLore(itemLore) == null && uuid != null) {
|
||||||
|
itemLore.set(indexOfSoulbound, Misc.SOULBOUND_TAG + StringUtils.hideUUID(uuid));
|
||||||
|
}
|
||||||
|
|
||||||
|
itemMeta.setLore(itemLore);
|
||||||
|
itemStack.setItemMeta(itemMeta);
|
||||||
|
return itemStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ItemStack checkNameChange(Player player, ItemStack itemStack) {
|
||||||
|
ItemMeta itemMeta = itemStack.getItemMeta();
|
||||||
|
List<String> itemLore = itemMeta.getLore();
|
||||||
|
|
||||||
|
int indexName = StringUtils.getIndexOfSoulbound(itemLore) + 1;
|
||||||
|
|
||||||
|
if (itemLore.size() >= 2 && itemLore.contains(player.getName()) && !Config.getInstance().getShowNameInLore()) {
|
||||||
|
Soulbound.p.debug("Item lore has a player name but that's disabled in config");
|
||||||
|
Soulbound.p.debug("Going to remove what is at indexName " + indexName + " which is: " + itemLore.get(indexName));
|
||||||
|
itemLore.remove(indexName);
|
||||||
|
itemMeta.setLore(itemLore);
|
||||||
|
itemStack.setItemMeta(itemMeta);
|
||||||
|
return itemStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Config.getInstance().getShowNameInLore() && !itemLore.contains(player.getName()) && player.getUniqueId().equals(StringUtils.readUUIDFromLore(itemLore))) {
|
||||||
|
Soulbound.p.debug("Item lore doesn't have (correct) player name but it should and the UUIDs match");
|
||||||
|
itemLore.add(indexName, player.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
itemMeta.setLore(itemLore);
|
||||||
|
itemStack.setItemMeta(itemMeta);
|
||||||
|
return itemStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isNormalItem(ItemStack itemStack) {
|
||||||
|
return !itemStack.hasItemMeta() && !itemStack.getItemMeta().hasLore() || ItemUtils.getItemType(itemStack) == ItemType.NORMAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ItemType getItemType(ItemStack itemStack) {
|
||||||
|
if (itemStack == null) {
|
||||||
|
return ItemType.NORMAL;
|
||||||
|
}
|
||||||
|
else if (isSoulbound(itemStack)) {
|
||||||
|
return ItemType.SOULBOUND;
|
||||||
|
}
|
||||||
|
else if (isBindOnPickup(itemStack)) {
|
||||||
|
return ItemType.BIND_ON_PICKUP;
|
||||||
|
}
|
||||||
|
else if (isBindOnUse(itemStack)) {
|
||||||
|
return ItemType.BIND_ON_USE;
|
||||||
|
}
|
||||||
|
else if (isBindOnEquip(itemStack)) {
|
||||||
|
return ItemType.BIND_ON_EQUIP;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return ItemType.NORMAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks to see if an item is an equipable item.
|
||||||
|
*
|
||||||
|
* @param is Item to check
|
||||||
|
*
|
||||||
|
* @return true if the item is equipable, false otherwise
|
||||||
|
*/
|
||||||
|
public static boolean isEquipable(ItemStack is) {
|
||||||
|
return isMinecraftArmor(is) || is.getType() == Material.SKULL_ITEM || is.getType() == Material.JACK_O_LANTERN;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks to see if an item is a wearable armor piece.
|
||||||
|
*
|
||||||
|
* @param is Item to check
|
||||||
|
*
|
||||||
|
* @return true if the item is armor, false otherwise
|
||||||
|
*/
|
||||||
|
public static boolean isMinecraftArmor(ItemStack is) {
|
||||||
|
return isLeatherArmor(is) || isGoldArmor(is) || isIronArmor(is) || isDiamondArmor(is) || isChainmailArmor(is);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks to see if an item is a leather armor piece.
|
||||||
|
*
|
||||||
|
* @param is Item to check
|
||||||
|
*
|
||||||
|
* @return true if the item is leather armor, false otherwise
|
||||||
|
*/
|
||||||
|
public static boolean isLeatherArmor(ItemStack is) {
|
||||||
|
switch (is.getType()) {
|
||||||
|
case LEATHER_BOOTS:
|
||||||
|
case LEATHER_CHESTPLATE:
|
||||||
|
case LEATHER_HELMET:
|
||||||
|
case LEATHER_LEGGINGS:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks to see if an item is a gold armor piece.
|
||||||
|
*
|
||||||
|
* @param is Item to check
|
||||||
|
*
|
||||||
|
* @return true if the item is gold armor, false otherwise
|
||||||
|
*/
|
||||||
|
public static boolean isGoldArmor(ItemStack is) {
|
||||||
|
switch (is.getType()) {
|
||||||
|
case GOLD_BOOTS:
|
||||||
|
case GOLD_CHESTPLATE:
|
||||||
|
case GOLD_HELMET:
|
||||||
|
case GOLD_LEGGINGS:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks to see if an item is an iron armor piece.
|
||||||
|
*
|
||||||
|
* @param is Item to check
|
||||||
|
*
|
||||||
|
* @return true if the item is iron armor, false otherwise
|
||||||
|
*/
|
||||||
|
public static boolean isIronArmor(ItemStack is) {
|
||||||
|
switch (is.getType()) {
|
||||||
|
case IRON_BOOTS:
|
||||||
|
case IRON_CHESTPLATE:
|
||||||
|
case IRON_HELMET:
|
||||||
|
case IRON_LEGGINGS:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks to see if an item is a diamond armor piece.
|
||||||
|
*
|
||||||
|
* @param is Item to check
|
||||||
|
*
|
||||||
|
* @return true if the item is diamond armor, false otherwise
|
||||||
|
*/
|
||||||
|
public static boolean isDiamondArmor(ItemStack is) {
|
||||||
|
switch (is.getType()) {
|
||||||
|
case DIAMOND_BOOTS:
|
||||||
|
case DIAMOND_CHESTPLATE:
|
||||||
|
case DIAMOND_HELMET:
|
||||||
|
case DIAMOND_LEGGINGS:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks to see if an item is a chainmail armor piece.
|
||||||
|
*
|
||||||
|
* @param is Item to check
|
||||||
|
*
|
||||||
|
* @return true if the item is chainmail armor, false otherwise
|
||||||
|
*/
|
||||||
|
public static boolean isChainmailArmor(ItemStack is) {
|
||||||
|
switch (is.getType()) {
|
||||||
|
case CHAINMAIL_BOOTS:
|
||||||
|
case CHAINMAIL_CHESTPLATE:
|
||||||
|
case CHAINMAIL_HELMET:
|
||||||
|
case CHAINMAIL_LEGGINGS:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
24
src/main/java/com/me/tft_02/soulbound/util/LogFilter.java
Normal file
24
src/main/java/com/me/tft_02/soulbound/util/LogFilter.java
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package com.me.tft_02.soulbound.util;
|
||||||
|
|
||||||
|
import java.util.logging.Filter;
|
||||||
|
import java.util.logging.LogRecord;
|
||||||
|
|
||||||
|
import com.me.tft_02.soulbound.Soulbound;
|
||||||
|
|
||||||
|
public class LogFilter implements Filter {
|
||||||
|
private boolean debug;
|
||||||
|
|
||||||
|
public LogFilter(Soulbound plugin) {
|
||||||
|
// Doing a config loading lite here, because we can't depend on the config loader to have loaded before any debug messages are sent
|
||||||
|
debug = plugin.getConfig().getBoolean("General.Verbose_Logging");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isLoggable(LogRecord record) {
|
||||||
|
if (record.getMessage().contains("[Debug]") && !debug) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
7
src/main/java/com/me/tft_02/soulbound/util/Misc.java
Normal file
7
src/main/java/com/me/tft_02/soulbound/util/Misc.java
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package com.me.tft_02.soulbound.util;
|
||||||
|
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
|
||||||
|
public class Misc {
|
||||||
|
public static String SOULBOUND_TAG = ChatColor.GOLD + "Soulbound";
|
||||||
|
}
|
40
src/main/java/com/me/tft_02/soulbound/util/Permissions.java
Normal file
40
src/main/java/com/me/tft_02/soulbound/util/Permissions.java
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
package com.me.tft_02.soulbound.util;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.permissions.Permissible;
|
||||||
|
import org.bukkit.permissions.PermissionAttachmentInfo;
|
||||||
|
|
||||||
|
public class Permissions {
|
||||||
|
|
||||||
|
public static boolean keepOnDeath(Permissible permissible) {
|
||||||
|
return permissible.hasPermission("soulbound.items.keep_on_death");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean deleteOnDeath(Permissible permissible) {
|
||||||
|
return permissible.hasPermission("soulbound.items.delete_on_death");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean pickupBypass(Permissible permissible) {
|
||||||
|
return permissible.hasPermission("soulbound.pickup.bypass");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean updateCheck(Permissible permissible) {
|
||||||
|
return permissible.hasPermission("soulbound.updatecheck");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getSoulbindMaximum(Player player) {
|
||||||
|
String match = "soulbound.maximum_allowed.";
|
||||||
|
int amount = -1;
|
||||||
|
|
||||||
|
for (PermissionAttachmentInfo permission : player
|
||||||
|
.getEffectivePermissions()) {
|
||||||
|
if (permission.getPermission().startsWith(match)
|
||||||
|
&& permission.getValue()) {
|
||||||
|
amount = Integer.parseInt(permission.getPermission().split(
|
||||||
|
"[.]")[2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
}
|
40
src/main/java/com/me/tft_02/soulbound/util/PlayerData.java
Normal file
40
src/main/java/com/me/tft_02/soulbound/util/PlayerData.java
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
package com.me.tft_02.soulbound.util;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import com.me.tft_02.soulbound.Soulbound;
|
||||||
|
|
||||||
|
public class PlayerData {
|
||||||
|
Soulbound plugin;
|
||||||
|
|
||||||
|
public PlayerData(Soulbound instance) {
|
||||||
|
plugin = instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HashMap<String, List<ItemStack>> playerSoulboundItems = new HashMap<String, List<ItemStack>>();
|
||||||
|
|
||||||
|
public static void storeItemsDeath(Player player, List<ItemStack> items) {
|
||||||
|
String playerName = player.getName();
|
||||||
|
|
||||||
|
if (playerSoulboundItems.containsKey(playerName)) {
|
||||||
|
playerSoulboundItems.put(playerName, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
playerSoulboundItems.put(playerName, items);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<ItemStack> retrieveItemsDeath(Player player) {
|
||||||
|
String playerName = player.getName();
|
||||||
|
|
||||||
|
if (playerSoulboundItems.containsKey(playerName)) {
|
||||||
|
return playerSoulboundItems.get(playerName);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
49
src/main/java/com/me/tft_02/soulbound/util/StringUtils.java
Normal file
49
src/main/java/com/me/tft_02/soulbound/util/StringUtils.java
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
package com.me.tft_02.soulbound.util;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
|
||||||
|
public class StringUtils {
|
||||||
|
|
||||||
|
public static int getIndexOfSoulbound(List<String> itemLore) {
|
||||||
|
int index = -1;
|
||||||
|
|
||||||
|
for (String line : itemLore) {
|
||||||
|
if (line.contains(Misc.SOULBOUND_TAG)) {
|
||||||
|
return itemLore.indexOf(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static UUID readUUIDFromLore(List<String> itemLore) {
|
||||||
|
int index = getIndexOfSoulbound(itemLore);
|
||||||
|
|
||||||
|
if (index == -1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String line = itemLore.get(index);
|
||||||
|
line = line.substring(11);
|
||||||
|
|
||||||
|
return readUUID(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String hideUUID(UUID uuid) {
|
||||||
|
String string = uuid.toString();
|
||||||
|
string = string.replaceAll("-", ChatColor.MAGIC.toString());
|
||||||
|
StringBuilder formattedString = new StringBuilder();
|
||||||
|
|
||||||
|
for (int i = 0; i < string.length(); i++) {
|
||||||
|
formattedString.append(ChatColor.COLOR_CHAR).append(string.charAt(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
return formattedString.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static UUID readUUID(String string) {
|
||||||
|
return UUID.fromString(string.replaceAll(ChatColor.MAGIC.toString(), "-").replaceAll("§", ""));
|
||||||
|
}
|
||||||
|
}
|
50
src/main/java/config.yml
Normal file
50
src/main/java/config.yml
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
#
|
||||||
|
# Soulbound configuration
|
||||||
|
# Last updated on ${project.version}-b${BUILD_NUMBER}
|
||||||
|
#
|
||||||
|
#####
|
||||||
|
|
||||||
|
#
|
||||||
|
# Settings for Soulbound in general
|
||||||
|
###
|
||||||
|
General:
|
||||||
|
# Allow Soulbound to report on basic anonymous usage
|
||||||
|
Stats_Tracking: true
|
||||||
|
|
||||||
|
# Allow Soulbound to check if a new version is available
|
||||||
|
Update_Check: true
|
||||||
|
Prefer_Beta: false
|
||||||
|
|
||||||
|
# Should Soulbound print out debug messages?
|
||||||
|
Verbose_Logging: false
|
||||||
|
|
||||||
|
# Should Soulbound over-write configs to update, or make new ones ending in .new?
|
||||||
|
Config_Update_Overwrite: true
|
||||||
|
|
||||||
|
Soulbound:
|
||||||
|
Show_Name_In_Lore: true
|
||||||
|
Feedback_Messages_Enabled: true
|
||||||
|
Prevent_Item_Drop: false
|
||||||
|
Delete_On_Drop: false
|
||||||
|
Allow_Item_Storing: true
|
||||||
|
Infinite_Durability: false
|
||||||
|
Blocked_Commands:
|
||||||
|
/blockedcommand
|
||||||
|
Commands_Bind_When_Used:
|
||||||
|
/enchant
|
||||||
|
|
||||||
|
Dependency_Plugins:
|
||||||
|
DiabloDrops:
|
||||||
|
BindOnPickup: Legendary, Rare, Unidentified
|
||||||
|
BindOnUse: Magical
|
||||||
|
BindOnEquip: Set
|
||||||
|
EpicBossRecoded:
|
||||||
|
BindOnPickup: true
|
||||||
|
BindOnUse: false
|
||||||
|
BindOnEquip: false
|
||||||
|
LoreLocks:
|
||||||
|
Bind_Keys: true
|
||||||
|
MythicDrops:
|
||||||
|
BindOnPickup: common, uncommon, rare
|
||||||
|
BindOnUse: terric, netheric
|
||||||
|
BindOnEquip: endric
|
35
src/main/java/items.yml
Normal file
35
src/main/java/items.yml
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#
|
||||||
|
# Soulbound item configuration
|
||||||
|
#
|
||||||
|
# Items in this config file will be automatically Soulbound to the player on certain
|
||||||
|
# actions, such as dropping the item or picking it up.
|
||||||
|
#
|
||||||
|
# You can add items under "Items" using the exact material name. You can add a data value using a |
|
||||||
|
# For example, WOOL|15 would be Material.WOOL with data value 15.
|
||||||
|
#
|
||||||
|
# The bare minimum of a Soulbound item is that it has Actions
|
||||||
|
#
|
||||||
|
# Name: This is the displayname of an item
|
||||||
|
#
|
||||||
|
# Lore: List one or more lines of lore here
|
||||||
|
#
|
||||||
|
# Actions: The actions when the item should be soulbound to the player.
|
||||||
|
# Valid values are: CRAFT, OPEN_CHEST, PICKUP_ITEM, DROP_ITEM, RESPAWN, KIT
|
||||||
|
#
|
||||||
|
#
|
||||||
|
###
|
||||||
|
|
||||||
|
Items:
|
||||||
|
DIAMOND_SPADE:
|
||||||
|
Lore:
|
||||||
|
- Made from diamond,
|
||||||
|
- can dig dirt!
|
||||||
|
Actions:
|
||||||
|
- CRAFT
|
||||||
|
- OPEN_CHEST
|
||||||
|
|
||||||
|
WOOL|15:
|
||||||
|
Name: Black Piece Of Wool
|
||||||
|
Actions:
|
||||||
|
- PICKUP_ITEM
|
||||||
|
- DROP_ITEM
|
@ -0,0 +1,558 @@
|
|||||||
|
/*
|
||||||
|
* Updater for Bukkit.
|
||||||
|
*
|
||||||
|
* This class provides the means to safely and easily update a plugin, or check to see if it is updated using dev.bukkit.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.gravitydevelopment.updater.soulbound;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.BufferedOutputStream;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLConnection;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.ZipFile;
|
||||||
|
|
||||||
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
|
import com.me.tft_02.soulbound.config.Config;
|
||||||
|
|
||||||
|
import org.json.simple.JSONArray;
|
||||||
|
import org.json.simple.JSONObject;
|
||||||
|
import org.json.simple.JSONValue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check dev.bukkit.org to find updates for a given plugin, and download the updates if needed.
|
||||||
|
* <p/>
|
||||||
|
* <b>VERY, VERY IMPORTANT</b>: Because there are no standards for adding auto-update toggles in your plugin's config, this system provides NO CHECK WITH YOUR CONFIG to make sure the user has allowed auto-updating.
|
||||||
|
* <br>
|
||||||
|
* It is a <b>BUKKIT POLICY</b> that you include a boolean value in your config that prevents the auto-updater from running <b>AT ALL</b>.
|
||||||
|
* <br>
|
||||||
|
* If you fail to include this option in your config, your plugin will be <b>REJECTED</b> when you attempt to submit it to dev.bukkit.org.
|
||||||
|
* <p/>
|
||||||
|
* An example of a good configuration option would be something similar to 'auto-update: true' - if this value is set to false you may NOT run the auto-updater.
|
||||||
|
* <br>
|
||||||
|
* If you are unsure about these rules, please read the plugin submission guidelines: http://goo.gl/8iU5l
|
||||||
|
*
|
||||||
|
* @author Gravity
|
||||||
|
* @version 2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class Updater {
|
||||||
|
|
||||||
|
private Plugin plugin;
|
||||||
|
private UpdateType type;
|
||||||
|
private String versionName;
|
||||||
|
private String versionLink;
|
||||||
|
private String versionType;
|
||||||
|
private String versionGameVersion;
|
||||||
|
|
||||||
|
private boolean announce; // Whether to announce file downloads
|
||||||
|
|
||||||
|
private URL url; // Connecting to RSS
|
||||||
|
private File file; // The plugin's file
|
||||||
|
private Thread thread; // Updater thread
|
||||||
|
|
||||||
|
private int id = -1; // Project's Curse ID
|
||||||
|
private String apiKey = null; // BukkitDev ServerMods API key
|
||||||
|
private static final String TITLE_VALUE = "name"; // Gets remote file's title
|
||||||
|
private static final String LINK_VALUE = "downloadUrl"; // Gets remote file's download link
|
||||||
|
private static final String TYPE_VALUE = "releaseType"; // Gets remote file's release type
|
||||||
|
private static final String VERSION_VALUE = "gameVersion"; // Gets remote file's build version
|
||||||
|
private static final String QUERY = "/servermods/files?projectIds="; // Path to GET
|
||||||
|
private static final String HOST = "https://api.curseforge.com"; // Slugs will be appended to this to get to the project's RSS feed
|
||||||
|
|
||||||
|
private static final int BYTE_SIZE = 1024; // Used for downloading files
|
||||||
|
private YamlConfiguration config; // Config file
|
||||||
|
private String updateFolder;// The folder that downloads will be placed in
|
||||||
|
private Updater.UpdateResult result = Updater.UpdateResult.SUCCESS; // Used for determining the outcome of the update process
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gives the dev the result of the update process. Can be obtained by called getResult().
|
||||||
|
*/
|
||||||
|
public enum UpdateResult {
|
||||||
|
/**
|
||||||
|
* The updater found an update, and has readied it to be loaded the next time the server restarts/reloads.
|
||||||
|
*/
|
||||||
|
SUCCESS,
|
||||||
|
/**
|
||||||
|
* The updater did not find an update, and nothing was downloaded.
|
||||||
|
*/
|
||||||
|
NO_UPDATE,
|
||||||
|
/**
|
||||||
|
* The server administrator has disabled the updating system
|
||||||
|
*/
|
||||||
|
DISABLED,
|
||||||
|
/**
|
||||||
|
* The updater found an update, but was unable to download it.
|
||||||
|
*/
|
||||||
|
FAIL_DOWNLOAD,
|
||||||
|
/**
|
||||||
|
* For some reason, the updater was unable to contact dev.bukkit.org to download the file.
|
||||||
|
*/
|
||||||
|
FAIL_DBO,
|
||||||
|
/**
|
||||||
|
* When running the version check, the file on DBO did not contain the a version in the format 'vVersion' such as 'v1.0'.
|
||||||
|
*/
|
||||||
|
FAIL_NOVERSION,
|
||||||
|
/**
|
||||||
|
* The id provided by the plugin running the updater was invalid and doesn't exist on DBO.
|
||||||
|
*/
|
||||||
|
FAIL_BADID,
|
||||||
|
/**
|
||||||
|
* The server administrator has improperly configured their API key in the configuration
|
||||||
|
*/
|
||||||
|
FAIL_APIKEY,
|
||||||
|
/**
|
||||||
|
* The updater found an update, but because of the UpdateType being set to NO_DOWNLOAD, it wasn't downloaded.
|
||||||
|
*/
|
||||||
|
UPDATE_AVAILABLE
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows the dev to specify the type of update that will be run.
|
||||||
|
*/
|
||||||
|
public enum UpdateType {
|
||||||
|
/**
|
||||||
|
* Run a version check, and then if the file is out of date, download the newest version.
|
||||||
|
*/
|
||||||
|
DEFAULT,
|
||||||
|
/**
|
||||||
|
* Don't run a version check, just find the latest update and download it.
|
||||||
|
*/
|
||||||
|
NO_VERSION_CHECK,
|
||||||
|
/**
|
||||||
|
* Get information about the version and the download size, but don't actually download anything.
|
||||||
|
*/
|
||||||
|
NO_DOWNLOAD
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the updater
|
||||||
|
*
|
||||||
|
* @param plugin The plugin that is checking for an update.
|
||||||
|
* @param id The dev.bukkit.org id of the project
|
||||||
|
* @param file The file that the plugin is running from, get this by doing this.getFile() from within your main class.
|
||||||
|
* @param type Specify the type of update this will be. See {@link UpdateType}
|
||||||
|
* @param announce True if the program should announce the progress of new updates in console
|
||||||
|
*/
|
||||||
|
public Updater(Plugin plugin, int id, File file, UpdateType type, boolean announce) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
this.type = type;
|
||||||
|
this.announce = announce;
|
||||||
|
this.file = file;
|
||||||
|
this.id = id;
|
||||||
|
this.updateFolder = plugin.getServer().getUpdateFolder();
|
||||||
|
|
||||||
|
final File pluginFile = plugin.getDataFolder().getParentFile();
|
||||||
|
final File updaterFile = new File(pluginFile, "Updater");
|
||||||
|
final File updaterConfigFile = new File(updaterFile, "config.yml");
|
||||||
|
|
||||||
|
if (!updaterFile.exists()) {
|
||||||
|
updaterFile.mkdir();
|
||||||
|
}
|
||||||
|
if (!updaterConfigFile.exists()) {
|
||||||
|
try {
|
||||||
|
updaterConfigFile.createNewFile();
|
||||||
|
}
|
||||||
|
catch (final IOException e) {
|
||||||
|
plugin.getLogger().severe("The updater could not create a configuration in " + updaterFile.getAbsolutePath());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.config = YamlConfiguration.loadConfiguration(updaterConfigFile);
|
||||||
|
|
||||||
|
this.config.options().header("This configuration file affects all plugins using the Updater system (version 2+ - http://forums.bukkit.org/threads/96681/ )" + '\n'
|
||||||
|
+ "If you wish to use your API key, read http://wiki.bukkit.org/ServerMods_API and place it below." + '\n'
|
||||||
|
+ "Some updating systems will not adhere to the disabled value, but these may be turned off in their plugin's configuration.");
|
||||||
|
this.config.addDefault("api-key", "PUT_API_KEY_HERE");
|
||||||
|
this.config.addDefault("disable", false);
|
||||||
|
|
||||||
|
if (this.config.get("api-key", null) == null) {
|
||||||
|
this.config.options().copyDefaults(true);
|
||||||
|
try {
|
||||||
|
this.config.save(updaterConfigFile);
|
||||||
|
}
|
||||||
|
catch (final IOException e) {
|
||||||
|
plugin.getLogger().severe("The updater could not save the configuration in " + updaterFile.getAbsolutePath());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.config.getBoolean("disable")) {
|
||||||
|
this.result = UpdateResult.DISABLED;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String key = this.config.getString("api-key");
|
||||||
|
if (key.equalsIgnoreCase("PUT_API_KEY_HERE") || key.equals("")) {
|
||||||
|
key = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.apiKey = key;
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.url = new URL(Updater.HOST + Updater.QUERY + id);
|
||||||
|
}
|
||||||
|
catch (final MalformedURLException e) {
|
||||||
|
plugin.getLogger().severe("The project ID provided for updating, " + id + " is invalid.");
|
||||||
|
this.result = UpdateResult.FAIL_BADID;
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.thread = new Thread(new UpdateRunnable());
|
||||||
|
this.thread.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the result of the update process.
|
||||||
|
*/
|
||||||
|
public Updater.UpdateResult getResult() {
|
||||||
|
this.waitForThread();
|
||||||
|
return this.result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the latest version's release type (release, beta, or alpha).
|
||||||
|
*/
|
||||||
|
public String getLatestType() {
|
||||||
|
this.waitForThread();
|
||||||
|
return this.versionType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the latest version's game version.
|
||||||
|
*/
|
||||||
|
public String getLatestGameVersion() {
|
||||||
|
this.waitForThread();
|
||||||
|
return this.versionGameVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the latest version's name.
|
||||||
|
*/
|
||||||
|
public String getLatestName() {
|
||||||
|
this.waitForThread();
|
||||||
|
return this.versionName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the latest version's file link.
|
||||||
|
*/
|
||||||
|
public String getLatestFileLink() {
|
||||||
|
this.waitForThread();
|
||||||
|
return this.versionLink;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* As the result of Updater output depends on the thread's completion, it is necessary to wait for the thread to finish
|
||||||
|
* before allowing anyone to check the result.
|
||||||
|
*/
|
||||||
|
private void waitForThread() {
|
||||||
|
if ((this.thread != null) && this.thread.isAlive()) {
|
||||||
|
try {
|
||||||
|
this.thread.join();
|
||||||
|
}
|
||||||
|
catch (final InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save an update from dev.bukkit.org into the server's update folder.
|
||||||
|
*/
|
||||||
|
private void saveFile(File folder, String file, String u) {
|
||||||
|
if (!folder.exists()) {
|
||||||
|
folder.mkdir();
|
||||||
|
}
|
||||||
|
BufferedInputStream in = null;
|
||||||
|
FileOutputStream fout = null;
|
||||||
|
try {
|
||||||
|
// Download the file
|
||||||
|
final URL url = new URL(u);
|
||||||
|
final int fileLength = url.openConnection().getContentLength();
|
||||||
|
in = new BufferedInputStream(url.openStream());
|
||||||
|
fout = new FileOutputStream(folder.getAbsolutePath() + "/" + file);
|
||||||
|
|
||||||
|
final byte[] data = new byte[Updater.BYTE_SIZE];
|
||||||
|
int count;
|
||||||
|
if (this.announce) {
|
||||||
|
this.plugin.getLogger().info("About to download a new update: " + this.versionName);
|
||||||
|
}
|
||||||
|
long downloaded = 0;
|
||||||
|
while ((count = in.read(data, 0, Updater.BYTE_SIZE)) != -1) {
|
||||||
|
downloaded += count;
|
||||||
|
fout.write(data, 0, count);
|
||||||
|
final int percent = (int) ((downloaded * 100) / fileLength);
|
||||||
|
if (this.announce && ((percent % 10) == 0)) {
|
||||||
|
this.plugin.getLogger().info("Downloading update: " + percent + "% of " + fileLength + " bytes.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Just a quick check to make sure we didn't leave any files from last time...
|
||||||
|
for (final File xFile : new File(this.plugin.getDataFolder().getParent(), this.updateFolder).listFiles()) {
|
||||||
|
if (xFile.getName().endsWith(".zip")) {
|
||||||
|
xFile.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Check to see if it's a zip file, if it is, unzip it.
|
||||||
|
final File dFile = new File(folder.getAbsolutePath() + "/" + file);
|
||||||
|
if (dFile.getName().endsWith(".zip")) {
|
||||||
|
// Unzip
|
||||||
|
this.unzip(dFile.getCanonicalPath());
|
||||||
|
}
|
||||||
|
if (this.announce) {
|
||||||
|
this.plugin.getLogger().info("Finished updating.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (final Exception ex) {
|
||||||
|
this.plugin.getLogger().warning("The auto-updater tried to download a new update, but was unsuccessful.");
|
||||||
|
this.result = Updater.UpdateResult.FAIL_DOWNLOAD;
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
try {
|
||||||
|
if (in != null) {
|
||||||
|
in.close();
|
||||||
|
}
|
||||||
|
if (fout != null) {
|
||||||
|
fout.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (final Exception ex) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Part of Zip-File-Extractor, modified by Gravity for use with Bukkit
|
||||||
|
*/
|
||||||
|
private void unzip(String file) {
|
||||||
|
try {
|
||||||
|
final File fSourceZip = new File(file);
|
||||||
|
final String zipPath = file.substring(0, file.length() - 4);
|
||||||
|
ZipFile zipFile = new ZipFile(fSourceZip);
|
||||||
|
Enumeration<? extends ZipEntry> e = zipFile.entries();
|
||||||
|
while (e.hasMoreElements()) {
|
||||||
|
ZipEntry entry = e.nextElement();
|
||||||
|
File destinationFilePath = new File(zipPath, entry.getName());
|
||||||
|
destinationFilePath.getParentFile().mkdirs();
|
||||||
|
if (entry.isDirectory()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
final BufferedInputStream bis = new BufferedInputStream(zipFile.getInputStream(entry));
|
||||||
|
int b;
|
||||||
|
final byte buffer[] = new byte[Updater.BYTE_SIZE];
|
||||||
|
final FileOutputStream fos = new FileOutputStream(destinationFilePath);
|
||||||
|
final BufferedOutputStream bos = new BufferedOutputStream(fos, Updater.BYTE_SIZE);
|
||||||
|
while ((b = bis.read(buffer, 0, Updater.BYTE_SIZE)) != -1) {
|
||||||
|
bos.write(buffer, 0, b);
|
||||||
|
}
|
||||||
|
bos.flush();
|
||||||
|
bos.close();
|
||||||
|
bis.close();
|
||||||
|
final String name = destinationFilePath.getName();
|
||||||
|
if (name.endsWith(".jar") && this.pluginFile(name)) {
|
||||||
|
destinationFilePath.renameTo(new File(this.plugin.getDataFolder().getParent(), this.updateFolder + "/" + name));
|
||||||
|
}
|
||||||
|
|
||||||
|
entry = null;
|
||||||
|
destinationFilePath = null;
|
||||||
|
}
|
||||||
|
e = null;
|
||||||
|
zipFile.close();
|
||||||
|
zipFile = null;
|
||||||
|
|
||||||
|
// Move any plugin data folders that were included to the right place, Bukkit won't do this for us.
|
||||||
|
for (final File dFile : new File(zipPath).listFiles()) {
|
||||||
|
if (dFile.isDirectory()) {
|
||||||
|
if (this.pluginFile(dFile.getName())) {
|
||||||
|
final File oFile = new File(this.plugin.getDataFolder().getParent(), dFile.getName()); // Get current dir
|
||||||
|
final File[] contents = oFile.listFiles(); // List of existing files in the current dir
|
||||||
|
for (final File cFile : dFile.listFiles()) // Loop through all the files in the new dir
|
||||||
|
{
|
||||||
|
boolean found = false;
|
||||||
|
for (final File xFile : contents) // Loop through contents to see if it exists
|
||||||
|
{
|
||||||
|
if (xFile.getName().equals(cFile.getName())) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
// Move the new file into the current dir
|
||||||
|
cFile.renameTo(new File(oFile.getCanonicalFile() + "/" + cFile.getName()));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// This file already exists, so we don't need it anymore.
|
||||||
|
cFile.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dFile.delete();
|
||||||
|
}
|
||||||
|
new File(zipPath).delete();
|
||||||
|
fSourceZip.delete();
|
||||||
|
}
|
||||||
|
catch (final IOException ex) {
|
||||||
|
this.plugin.getLogger().warning("The auto-updater tried to unzip a new update file, but was unsuccessful.");
|
||||||
|
this.result = Updater.UpdateResult.FAIL_DOWNLOAD;
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
new File(file).delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the name of a jar is one of the plugins currently installed, used for extracting the correct files out of a zip.
|
||||||
|
*/
|
||||||
|
private boolean pluginFile(String name) {
|
||||||
|
for (final File file : new File("plugins").listFiles()) {
|
||||||
|
if (file.getName().equals(name)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check to see if the program should continue by evaluation whether the plugin is already updated, or shouldn't be updated
|
||||||
|
*/
|
||||||
|
private boolean versionCheck(String title) {
|
||||||
|
if (type != UpdateType.NO_VERSION_CHECK) {
|
||||||
|
String version = plugin.getDescription().getVersion();
|
||||||
|
title = title.substring(1);
|
||||||
|
|
||||||
|
String[] oldTokens = version.split("-");
|
||||||
|
String[] newTokens = title.split("-");
|
||||||
|
|
||||||
|
int oldVersion = Integer.parseInt(oldTokens[0].replaceAll("[.]", ""));
|
||||||
|
int newVersion = Integer.parseInt(newTokens[0].replaceAll("[.]", ""));
|
||||||
|
|
||||||
|
// Check versions
|
||||||
|
if (oldVersion < newVersion) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check release vs. beta & SNAPSHOT
|
||||||
|
if (newTokens.length == 1 && oldTokens.length == 3 && oldVersion == newVersion) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check beta vs. SNAPSHOT
|
||||||
|
if (version.contains("SNAPSHOT") && title.contains("beta")) {
|
||||||
|
if (Integer.parseInt(oldTokens[1].substring(8)) <= Integer.parseInt(newTokens[1].substring(4))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = UpdateResult.NO_UPDATE;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check beta vs. beta
|
||||||
|
if (version.contains("beta") && title.contains("beta")) {
|
||||||
|
if (Integer.parseInt(oldTokens[1].substring(4)) < Integer.parseInt(newTokens[1].substring(4))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = UpdateResult.NO_UPDATE;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (oldTokens.length == 3 && !version.contains("beta") && !version.contains("SNAPSHOT")) {
|
||||||
|
plugin.getLogger().warning("Could not get information about this Soulbound version; perhaps you are running a custom one?");
|
||||||
|
result = UpdateResult.FAIL_NOVERSION;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = UpdateResult.NO_UPDATE;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean read() {
|
||||||
|
try {
|
||||||
|
final URLConnection conn = this.url.openConnection();
|
||||||
|
conn.setConnectTimeout(5000);
|
||||||
|
|
||||||
|
if (this.apiKey != null) {
|
||||||
|
conn.addRequestProperty("X-API-Key", this.apiKey);
|
||||||
|
}
|
||||||
|
conn.addRequestProperty("User-Agent", "Updater (by Gravity)");
|
||||||
|
|
||||||
|
conn.setDoOutput(true);
|
||||||
|
|
||||||
|
final BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
|
||||||
|
final String response = reader.readLine();
|
||||||
|
|
||||||
|
final JSONArray array = (JSONArray) JSONValue.parse(response);
|
||||||
|
|
||||||
|
if (array.size() == 0) {
|
||||||
|
this.plugin.getLogger().warning("The updater could not find any files for the project id " + this.id);
|
||||||
|
this.result = UpdateResult.FAIL_BADID;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.versionName = (String) ((JSONObject) array.get(array.size() - 1)).get(Updater.TITLE_VALUE);
|
||||||
|
this.versionLink = (String) ((JSONObject) array.get(array.size() - 1)).get(Updater.LINK_VALUE);
|
||||||
|
this.versionType = (String) ((JSONObject) array.get(array.size() - 1)).get(Updater.TYPE_VALUE);
|
||||||
|
this.versionGameVersion = (String) ((JSONObject) array.get(array.size() - 1)).get(Updater.VERSION_VALUE);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (final IOException e) {
|
||||||
|
if (e.getMessage().contains("HTTP response code: 403")) {
|
||||||
|
this.plugin.getLogger().warning("dev.bukkit.org rejected the API key provided in plugins/Updater/config.yml");
|
||||||
|
this.plugin.getLogger().warning("Please double-check your configuration to ensure it is correct.");
|
||||||
|
this.result = UpdateResult.FAIL_APIKEY;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.plugin.getLogger().warning("The updater could not contact dev.bukkit.org for updating.");
|
||||||
|
this.plugin.getLogger().warning("If you have not recently modified your configuration and this is the first time you are seeing this message, the site may be experiencing temporary downtime.");
|
||||||
|
this.result = UpdateResult.FAIL_DBO;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Config.getInstance().getVerboseLoggingEnabled()) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class UpdateRunnable implements Runnable {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (Updater.this.url != null) {
|
||||||
|
// Obtain the results of the project's file feed
|
||||||
|
if (Updater.this.read()) {
|
||||||
|
if (Updater.this.versionCheck(Updater.this.versionName)) {
|
||||||
|
if ((Updater.this.versionLink != null) && (Updater.this.type != UpdateType.NO_DOWNLOAD)) {
|
||||||
|
String name = Updater.this.file.getName();
|
||||||
|
// If it's a zip file, it shouldn't be downloaded as the plugin's name
|
||||||
|
if (Updater.this.versionLink.endsWith(".zip")) {
|
||||||
|
final String[] split = Updater.this.versionLink.split("/");
|
||||||
|
name = split[split.length - 1];
|
||||||
|
}
|
||||||
|
Updater.this.saveFile(new File(Updater.this.plugin.getDataFolder().getParent(), Updater.this.updateFolder), name, Updater.this.versionLink);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Updater.this.result = UpdateResult.UPDATE_AVAILABLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
56
src/main/java/plugin.yml
Normal file
56
src/main/java/plugin.yml
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
name: Soulbound
|
||||||
|
version: 1.1.10-SNAPSHOT-b84
|
||||||
|
author: TfT_02
|
||||||
|
main: com.me.tft_02.soulbound.Soulbound
|
||||||
|
description: Soulbound items for your RPG servers!
|
||||||
|
softdepend: [EpicBossRecoded, LoreLocks, MythicDrops]
|
||||||
|
commands:
|
||||||
|
soulbound:
|
||||||
|
description: Usage /soulbound
|
||||||
|
permission-message: You don't have <permission>
|
||||||
|
bind:
|
||||||
|
description: Usage /bind
|
||||||
|
alias: bound
|
||||||
|
permission: soulbound.commands.bind
|
||||||
|
permission-message: You don't have <permission>
|
||||||
|
bindonpickup:
|
||||||
|
description: Usage /bindonpickup
|
||||||
|
permission: soulbound.commands.bindonpickup
|
||||||
|
permission-message: You don't have <permission>
|
||||||
|
bindonuse:
|
||||||
|
description: Usage /bindonuse
|
||||||
|
permission: soulbound.commands.bindonuse
|
||||||
|
permission-message: You don't have <permission>
|
||||||
|
bindonequip:
|
||||||
|
description: Usage /bindonequip
|
||||||
|
permission: soulbound.commands.bindonequip
|
||||||
|
permission-message: You don't have <permission>
|
||||||
|
unbind:
|
||||||
|
description: Usage /unbind
|
||||||
|
alias: unbound
|
||||||
|
permission: soulbound.commands.unbind
|
||||||
|
permission-message: You don't have <permission>
|
||||||
|
permissions:
|
||||||
|
soulbound.commands.all:
|
||||||
|
description: Gives access to the Soulbound commands
|
||||||
|
default: op
|
||||||
|
children:
|
||||||
|
soulbound.commands.bind: true
|
||||||
|
soulbound.commands.bindonpickup: true
|
||||||
|
soulbound.commands.bindonuse: true
|
||||||
|
soulbound.commands.bindonequip: true
|
||||||
|
soulbound.commands.unbind: true
|
||||||
|
soulbound.commands.reload: true
|
||||||
|
soulbound.updatecheck: true
|
||||||
|
soulbound.pickup.bypass:
|
||||||
|
description: Users with this permission will be able to pickup Soulbound items that do not belong to them.
|
||||||
|
default: false
|
||||||
|
soulbound.items.keep_on_death:
|
||||||
|
description: Users with this permission will keep their Soulbound items after dying
|
||||||
|
default: false
|
||||||
|
soulbound.items.delete_on_death:
|
||||||
|
description: Users with this permission will have their Soulbound items deleted on death
|
||||||
|
default: false
|
||||||
|
soulbound.updatecheck:
|
||||||
|
description: Users with this permission will receive a notification when there is a new version available.
|
||||||
|
default: op
|
Loading…
Reference in New Issue
Block a user