Merge branch 'development'

This commit is contained in:
Christian Koop 2024-02-26 12:58:33 +01:00
commit 597542dc8e
No known key found for this signature in database
GPG Key ID: 89A8181384E010A3
94 changed files with 5111 additions and 4183 deletions

26
.editorconfig Normal file
View File

@ -0,0 +1,26 @@
root = true
[*]
charset = utf-8
end_of_line = lf
indent_size = 4
indent_style = space
insert_final_newline = true
# max_line_length = 120
tab_width = 4
trim_trailing_whitespace = true
ij_continuation_indent_size = 8
ij_formatter_off_tag = @formatter:off
ij_formatter_on_tag = @formatter:on
ij_formatter_tags_enabled = true
[{*.yaml,*.yml,*.json,*.graphqlconfig,*.har,*.jsb2,*.jsb3,*.webmanifest,.babelrc,.eslintrc,.prettierrc,.stylelintrc,bowerrc,jest.config}]
indent_size = 2
tab_width = 2
[{*.markdown,*.md,*.html,*.htm,*.ng,*.sht,*.shtm,*.shtml,*.ts,*.ats,*.js,*.cjs,*.bash,*.sh,*.zsh}]
indent_size = 2
tab_width = 2

1
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1 @@
custom: [ 'https://craftaro.to/+' ]

16
.github/dependabot.yml vendored Normal file
View File

@ -0,0 +1,16 @@
# Please see the documentation for all configuration options:
# https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
version: 2
updates:
- package-ecosystem: maven
directory: /
target-branch: development
schedule:
interval: monthly
- package-ecosystem: github-actions
directory: /
target-branch: development
schedule:
interval: monthly

95
.github/workflows/build.yml vendored Normal file
View File

@ -0,0 +1,95 @@
name: Build
on:
push:
branches: [ master, development ]
tags:
- 'v*'
pull_request:
types: [ opened, synchronize, reopened ]
permissions: read-all
env:
DEPLOYMENT_POM_PATH: ./EpicHoppers-API/pom.xml
DEPLOYMENT_ARTIFACT_DIR: ./EpicHoppers-API/target
DEPLOYMENT_ARTIFACT_SELECTOR: EpicHoppers-API-*.jar
PLUGIN_ARTIFACT_DIR: ./EpicHoppers-Plugin/target
PLUGIN_ARTIFACT_SELECTOR: EpicHoppers-*.jar
jobs:
Build:
name: Build + Deploy
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Prepare Workspace
uses: craftaro/GH-Commons/.github/actions/setup_workspace@master
with:
maven_username: ${{ secrets.PLUGINS_MAVEN_REPO_USERNAME }}
maven_password: ${{ secrets.PLUGINS_MAVEN_REPO_PASSWORD }}
- name: Set project version
uses: craftaro/GH-Commons/.github/actions/maven_set_project_version@master
with:
append_snapshot: ${{ github.ref_type == 'tag' && 'false' || 'true' }}
version: ${{ github.ref_type == 'tag' && github.ref_name || '' }}
increment_version: ${{ github.ref_type != 'tag' && 'patch' || '' }}
increment_version_only_if_not_snapshot_version: ${{ github.ref == 'refs/heads/development' && 'true' || 'false' }}
- name: Build with Maven
run: mvn -B -Duser.name="GitHub Actions on $GITHUB_REPOSITORY (id=$GITHUB_RUN_ID)" clean package
- name: Sign jar archives
uses: craftaro/GH-Commons/.github/actions/sign_jars@master
with:
jar_file_selector: ${{ env.DEPLOYMENT_ARTIFACT_DIR }}/${{ env.DEPLOYMENT_ARTIFACT_SELECTOR }}
keystore_gpg_encrypted: ${{ secrets.PLUGINS_JARSIGNER_KEYSTORE_GPG }}
keystore_gpg_password: ${{ secrets.PLUGINS_JARSIGNER_KEYSTORE_GPG_PASSWORD }}
keystore_password: ${{ secrets.PLUGINS_JARSIGNER_KEYSTORE_PASSWORD }}
- name: Upload Build Artifacts [API]
uses: actions/upload-artifact@v4
with:
name: ${{ github.event.repository.name }}-API
path: ${{ env.DEPLOYMENT_ARTIFACT_DIR }}/${{ env.DEPLOYMENT_ARTIFACT_SELECTOR }}
- name: Upload Build Artifacts [Plugin]
uses: actions/upload-artifact@v4
with:
name: ${{ github.event.repository.name }}
path: ${{ env.PLUGIN_ARTIFACT_DIR }}/${{ env.PLUGIN_ARTIFACT_SELECTOR }}
- name: Deploy to Maven repo
if: ${{ github.event_name == 'push' }}
uses: craftaro/GH-Commons/.github/actions/maven_deploy@master
with:
repository_url: ${{ vars.PLUGINS_MAVEN_REPO_URL_RELEASE }}
repository_url_snapshots: ${{ vars.PLUGINS_MAVEN_REPO_URL_SNAPSHOT }}
maven_pom_path: ${{ env.DEPLOYMENT_POM_PATH }}
maven_out_dir: ${{ env.DEPLOYMENT_ARTIFACT_DIR }}
- name: Deploy parent pom.xml to Maven repo
if: ${{ github.event_name == 'push' }}
uses: craftaro/GH-Commons/.github/actions/maven_deploy@master
with:
repository_url: ${{ vars.PLUGINS_MAVEN_REPO_URL_RELEASE }}
repository_url_snapshots: ${{ vars.PLUGINS_MAVEN_REPO_URL_SNAPSHOT }}
only_deploy_pom: true
maven_out_dir: ${{ env.DEPLOYMENT_ARTIFACT_DIR }}
discord_webhook:
name: Send Discord Webhook
runs-on: ubuntu-latest
needs: [ Build ]
if: ${{ always() && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/development' || github.ref_type == 'tag') }}
steps:
- uses: actions/checkout@v4
- name: Notify Webhook
uses: craftaro/GH-Commons/.github/actions/discord_send_job_results@master
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
webhook_url: ${{ secrets.DISCORD_BUILD_STATUS_WEBHOOK }}

24
.gitignore vendored
View File

@ -1,14 +1,10 @@
out/
\.idea/
/src/main/resources/META-INF/MANIFEST.MF
/EpicHoppers.iml
target/
EpicHoppers-API/EpicHoppers-API\.iml
EpicHoppers-Plugin/EpicHoppers-Plugin\.iml
*.iml
## JetBrains IDEs
/.idea/
*.iml
## Maven
/**/target/
/**/dependency-reduced-pom.xml
## Misc.
.DS_Store

70
EpicHoppers-API/pom.xml Normal file
View File

@ -0,0 +1,70 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.craftaro</groupId>
<artifactId>EpicHoppers-Parent</artifactId>
<version>5.0.1</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>EpicHoppers-API</artifactId>
<version>1.0.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.5.0</version>
<executions>
<execution>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
<configuration>
<links>
<link>https://hub.spigotmc.org/javadocs/spigot/</link>
</links>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.craftaro</groupId>
<artifactId>CraftaroCore</artifactId>
<version>${craftaro.coreVersion}</version>
<scope>provided</scope>
</dependency>
<!-- TODO: Downgrade to spigot-api 1.8 -->
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.18-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,61 @@
package com.craftaro.epichoppers;
import com.craftaro.core.database.DataManager;
import com.craftaro.epichoppers.boost.BoostManager;
import com.craftaro.epichoppers.containers.ContainerManager;
import com.craftaro.epichoppers.hopper.teleport.TeleportHandler;
import com.craftaro.epichoppers.player.PlayerDataManager;
import com.craftaro.epichoppers.hopper.levels.LevelManager;
import org.jetbrains.annotations.ApiStatus;
public class EpicHoppersApi {
private static EpicHoppersApi instance;
private final LevelManager levelManager;
private final BoostManager boostManager;
private final ContainerManager containerManager;
private final TeleportHandler teleportHandler;
private final PlayerDataManager playerDataManager;
private EpicHoppersApi(LevelManager levelManager,
BoostManager boostManager,
ContainerManager containerManager,
TeleportHandler teleportHandler,
PlayerDataManager playerDataManager) {
this.levelManager = levelManager;
this.boostManager = boostManager;
this.containerManager = containerManager;
this.teleportHandler = teleportHandler;
this.playerDataManager = playerDataManager;
}
public LevelManager getLevelManager() {
return this.levelManager;
}
public BoostManager getBoostManager() {
return this.boostManager;
}
public ContainerManager getContainerManager() {
return this.containerManager;
}
public TeleportHandler getTeleportHandler() {
return this.teleportHandler;
}
public PlayerDataManager getPlayerDataManager() {
return this.playerDataManager;
}
public static EpicHoppersApi getApi() {
return instance;
}
static void initApi(LevelManager levelManager, BoostManager boostManager, ContainerManager containerManager, TeleportHandler teleportHandler, PlayerDataManager playerDataManager) {
if (instance != null) {
throw new IllegalStateException(EpicHoppersApi.class.getSimpleName() + " already initialized");
}
instance = new EpicHoppersApi(levelManager, boostManager, containerManager, teleportHandler, playerDataManager);
}
}

View File

@ -1,6 +1,6 @@
package com.songoda.epichoppers.api.events;
package com.craftaro.epichoppers.api.events;
import com.songoda.epichoppers.hopper.Hopper;
import com.craftaro.epichoppers.hopper.Hopper;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
@ -9,13 +9,22 @@ import org.bukkit.event.HandlerList;
* Called when a hopper is accessed by a player.
*/
public class HopperAccessEvent extends HopperEvent implements Cancellable {
private static final HandlerList HANDLERS = new HandlerList();
private boolean canceled = false;
public HopperAccessEvent(Player player, Hopper hopper) {
super(player, hopper);
public HopperAccessEvent(Player who, Hopper hopper) {
super(who, hopper);
}
@Override
public boolean isCancelled() {
return this.canceled;
}
@Override
public void setCancelled(boolean cancel) {
this.canceled = cancel;
}
@Override
@ -26,15 +35,4 @@ public class HopperAccessEvent extends HopperEvent implements Cancellable {
public static HandlerList getHandlerList() {
return HANDLERS;
}
@Override
public boolean isCancelled() {
return canceled;
}
@Override
public void setCancelled(boolean canceled) {
this.canceled = canceled;
}
}
}

View File

@ -1,15 +1,14 @@
package com.songoda.epichoppers.api.events;
package com.craftaro.epichoppers.api.events;
import com.songoda.epichoppers.hopper.Hopper;
import com.craftaro.epichoppers.hopper.Hopper;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
public class HopperBreakEvent extends HopperEvent {
private static final HandlerList HANDLERS = new HandlerList();
public HopperBreakEvent(Player player, Hopper hopper) {
super(player, hopper);
public HopperBreakEvent(Player who, Hopper hopper) {
super(who, hopper);
}
@Override
@ -20,5 +19,4 @@ public class HopperBreakEvent extends HopperEvent {
public static HandlerList getHandlerList() {
return HANDLERS;
}
}

View File

@ -1,6 +1,6 @@
package com.songoda.epichoppers.api.events;
package com.craftaro.epichoppers.api.events;
import com.songoda.epichoppers.hopper.Hopper;
import com.craftaro.epichoppers.hopper.Hopper;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.player.PlayerEvent;
@ -9,7 +9,6 @@ import org.bukkit.event.player.PlayerEvent;
* Represents an abstract {@link Event} given a {@link Player} and {@link Hopper} instance
*/
public abstract class HopperEvent extends PlayerEvent {
protected final Hopper hopper;
public HopperEvent(Player who, Hopper hopper) {
@ -23,7 +22,6 @@ public abstract class HopperEvent extends PlayerEvent {
* @return the broken spawner
*/
public Hopper getHopper() {
return hopper;
return this.hopper;
}
}
}

View File

@ -1,15 +1,14 @@
package com.songoda.epichoppers.api.events;
package com.craftaro.epichoppers.api.events;
import com.songoda.epichoppers.hopper.Hopper;
import com.craftaro.epichoppers.hopper.Hopper;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
public class HopperPlaceEvent extends HopperEvent {
private static final HandlerList HANDLERS = new HandlerList();
public HopperPlaceEvent(Player player, Hopper hopper) {
super(player, hopper);
public HopperPlaceEvent(Player who, Hopper hopper) {
super(who, hopper);
}
@Override
@ -20,5 +19,4 @@ public class HopperPlaceEvent extends HopperEvent {
public static HandlerList getHandlerList() {
return HANDLERS;
}
}
}

View File

@ -0,0 +1,25 @@
package com.craftaro.epichoppers.boost;
import java.util.Objects;
import java.util.UUID;
public interface BoostData {
/**
* Gets the multiplier of the boost
* @return The multiplier
*/
int getMultiplier();
/**
* Gets the player's uuid who has the boost
* @return The player's uuid
*/
public UUID getPlayer();
/**
* Gets the end time of the boost
* @return The end time
*/
public long getEndTime();
}

View File

@ -0,0 +1,17 @@
package com.craftaro.epichoppers.boost;
import java.util.List;
import java.util.Set;
import java.util.UUID;
public interface BoostManager {
void addBoostToPlayer(BoostData data);
void removeBoostFromPlayer(BoostData data);
void addBoosts(List<BoostData> boosts);
Set<BoostData> getBoosts();
BoostData getBoost(UUID player);
}

View File

@ -0,0 +1,15 @@
package com.craftaro.epichoppers.containers;
import org.bukkit.block.Block;
import java.util.Set;
public interface ContainerManager {
Set<IContainer> getCustomContainerImplementations();
void registerCustomContainerImplementation(String requiredPlugin, IContainer container);
void registerCustomContainerImplementation(IContainer container);
CustomContainer getCustomContainer(Block block);
}

View File

@ -1,17 +1,13 @@
package com.songoda.epichoppers.containers;
package com.craftaro.epichoppers.containers;
import org.bukkit.block.Block;
import org.bukkit.inventory.ItemStack;
public abstract class CustomContainer {
private final Block block;
public CustomContainer(Block block) {
this.block = block;
}
public abstract boolean addToContainer(ItemStack itemToMove);
public abstract ItemStack[] getItems();
public abstract void removeFromContainer(ItemStack itemToMove, int amountToMove);
public abstract boolean isContainer();
}

View File

@ -1,8 +1,7 @@
package com.songoda.epichoppers.containers;
package com.craftaro.epichoppers.containers;
import org.bukkit.block.Block;
public interface IContainer {
CustomContainer getCustomContainer(Block block);
}

View File

@ -1,4 +1,4 @@
package com.songoda.epichoppers.hopper;
package com.craftaro.epichoppers.hopper;
import org.bukkit.Location;
import org.bukkit.inventory.ItemStack;
@ -8,7 +8,6 @@ import java.util.Collections;
import java.util.List;
public class Filter {
private List<ItemStack> whiteList = new ArrayList<>();
private List<ItemStack> blackList = new ArrayList<>();
private List<ItemStack> voidList = new ArrayList<>();
@ -16,65 +15,52 @@ public class Filter {
private List<ItemStack> autoSellWhiteList = new ArrayList<>();
private List<ItemStack> autoSellBlackList = new ArrayList<>();
private Location endPoint;
public List<ItemStack> getWhiteList() {
return whiteList != null ? whiteList : Collections.emptyList();
return this.whiteList != null ? this.whiteList : Collections.emptyList();
}
public void setWhiteList(List<ItemStack> whiteList) {
this.whiteList = whiteList;
}
public List<ItemStack> getBlackList() {
return blackList != null ? blackList : Collections.emptyList();
return this.blackList != null ? this.blackList : Collections.emptyList();
}
public void setBlackList(List<ItemStack> blackList) {
this.blackList = blackList;
}
public List<ItemStack> getVoidList() {
return voidList != null ? voidList : Collections.emptyList();
return this.voidList != null ? this.voidList : Collections.emptyList();
}
public void setVoidList(List<ItemStack> voidList) {
this.voidList = voidList;
}
public List<ItemStack> getAutoSellWhiteList() {
return autoSellWhiteList != null ? autoSellWhiteList : Collections.emptyList();
return this.autoSellWhiteList != null ? this.autoSellWhiteList : Collections.emptyList();
}
public void setAutoSellWhiteList(List<ItemStack> autoSellWhiteList) {
this.autoSellWhiteList = autoSellWhiteList;
}
public List<ItemStack> getAutoSellBlackList() {
return autoSellBlackList != null ? autoSellBlackList : Collections.emptyList();
return this.autoSellBlackList != null ? this.autoSellBlackList : Collections.emptyList();
}
public void setAutoSellBlackList(List<ItemStack> autoSellBlackList) {
this.autoSellBlackList = autoSellBlackList;
}
public Location getEndPoint() {
return endPoint;
return this.endPoint;
}
public void setEndPoint(Location endPoint) {
this.endPoint = endPoint;
}
@ -82,19 +68,23 @@ public class Filter {
public void addItem(ItemStack item, ItemType type) {
switch (type) {
case WHITELIST:
whiteList.add(item);
this.whiteList.add(item);
break;
case BLACKLIST:
blackList.add(item);
this.blackList.add(item);
break;
case VOID:
voidList.add(item);
this.voidList.add(item);
break;
case AUTO_SELL_WHITELIST:
autoSellWhiteList.add(item);
this.autoSellWhiteList.add(item);
break;
case AUTO_SELL_BLACKLIST:
autoSellBlackList.add(item);
this.autoSellBlackList.add(item);
break;
}
}

View File

@ -0,0 +1,58 @@
package com.craftaro.epichoppers.hopper;
import com.craftaro.core.database.Data;
import com.craftaro.epichoppers.hopper.levels.Level;
import com.craftaro.epichoppers.hopper.teleport.TeleportTrigger;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.UUID;
public interface Hopper extends Data {
Location getLocation();
Block getBlock();
Level getLevel();
void setLevel(Level level);
@Nullable UUID getLastPlayerOpened();
@NotNull UUID getPlacedBy();
void setPlacedBy(UUID placedBy);
void setLastPlayerOpened(UUID lastPlayerOpened);
TeleportTrigger getTeleportTrigger();
void setTeleportTrigger(TeleportTrigger teleportTrigger);
List<Location> getLinkedBlocks();
void addLinkedBlock(Location location, LinkType type);
void removeLinkedBlock(Location location);
void clearLinkedBlocks();
Filter getFilter();
void setActivePlayer(Player activePlayer);
void timeout(Player player);
void addDataToModuleCache(String s, Object value);
boolean isDataCachedInModuleCache(String cacheStr);
Object getDataFromModuleCache(String cacheStr);
void clearModuleCache();
}

View File

@ -1,7 +1,5 @@
package com.songoda.epichoppers.hopper;
package com.craftaro.epichoppers.hopper;
public enum ItemType {
WHITELIST, BLACKLIST, VOID, AUTO_SELL_WHITELIST, AUTO_SELL_BLACKLIST
}

View File

@ -1,6 +1,5 @@
package com.songoda.epichoppers.hopper;
package com.craftaro.epichoppers.hopper;
public enum LinkType {
REGULAR, REJECT
}

View File

@ -0,0 +1,142 @@
package com.craftaro.epichoppers.hopper.levels;
import com.craftaro.core.SongodaPlugin;
import com.craftaro.epichoppers.hopper.levels.modules.Module;
import org.bukkit.Bukkit;
import java.util.ArrayList;
import java.util.List;
public class Level {
private final ArrayList<Module> registeredModules;
private final List<String> description = new ArrayList<>();
private final int level, costExperience, costEconomy, range, amount, linkAmount;
private final boolean filter, teleport;
public Level(int level, int costExperience, int costEconomy, int range, int amount, boolean filter, boolean teleport, int linkAmount, ArrayList<Module> registeredModules) {
this.level = level;
this.costExperience = costExperience;
this.costEconomy = costEconomy;
this.range = range;
this.amount = amount;
this.filter = filter;
this.teleport = teleport;
this.linkAmount = linkAmount;
this.registeredModules = registeredModules;
buildDescription();
}
public void buildDescription() {
this.description.clear();
this.description.add(getPlugin().getLocale().getMessage("interface.hopper.range")
.processPlaceholder("range", this.range).getMessage());
this.description.add(getPlugin().getLocale().getMessage("interface.hopper.amount")
.processPlaceholder("amount", this.amount).getMessage());
if (this.linkAmount != 1) {
this.description.add(getPlugin().getLocale().getMessage("interface.hopper.linkamount")
.processPlaceholder("amount", this.linkAmount).getMessage());
}
if (this.filter) {
this.description.add(getPlugin().getLocale().getMessage("interface.hopper.filter")
.processPlaceholder("enabled", getPlugin().getLocale()
.getMessage("general.word.enabled").getMessage()).getMessage());
}
if (this.teleport) {
this.description.add(getPlugin()
.getLocale()
.getMessage("interface.hopper.teleport")
.processPlaceholder(
"enabled",
getPlugin()
.getLocale()
.getMessage("general.word.enabled")
.getMessage())
.getMessage());
}
for (Module module : this.registeredModules) {
this.description.add(module.getDescription());
}
}
public int getLevel() {
return this.level;
}
public int getRange() {
return this.range;
}
public int getAmount() {
return this.amount;
}
public boolean isFilter() {
return this.filter;
}
public boolean isTeleport() {
return this.teleport;
}
public int getLinkAmount() {
return this.linkAmount;
}
public int getCostExperience() {
return this.costExperience;
}
public int getCostEconomy() {
return this.costEconomy;
}
public List<String> getDescription() {
return new ArrayList<>(this.description);
}
public ArrayList<Module> getRegisteredModules() {
return new ArrayList<>(this.registeredModules);
}
public void addModule(Module module) {
this.registeredModules.add(module);
buildDescription();
}
public Module getModule(String name) {
if (this.registeredModules == null) {
return null;
}
for (Module module : this.registeredModules) {
if (module.getName().equals(name)) {
return module;
}
}
return null;
}
/**
* @deprecated The class needs refactoring to not even need the plugin.
* This is just a temporary workaround to get a Minecraft 1.20-beta build ready
*/
@Deprecated
private SongodaPlugin getPlugin() {
return (SongodaPlugin) Bukkit.getPluginManager().getPlugin("EpicHoppers");
}
}

View File

@ -0,0 +1,27 @@
package com.craftaro.epichoppers.hopper.levels;
import com.craftaro.epichoppers.hopper.levels.modules.Module;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.Map;
public interface LevelManager {
void addLevel(int level, int costExperience, int costEconomy, int range, int amount, boolean filter, boolean teleport, int linkAmount, ArrayList<Module> modules);
Level getLevel(int level);
Level getLevel(ItemStack item);
boolean isEpicHopper(ItemStack item);
Level getLowestLevel();
Level getHighestLevel();
boolean isLevel(int level);
Map<Integer, Level> getLevels();
void clear();
}

View File

@ -1,10 +1,11 @@
package com.songoda.epichoppers.hopper.levels.modules;
package com.craftaro.epichoppers.hopper.levels.modules;
import com.songoda.core.configuration.Config;
import com.songoda.epichoppers.EpicHoppers;
import com.songoda.epichoppers.hopper.Hopper;
import com.songoda.epichoppers.utils.Methods;
import com.songoda.epichoppers.utils.StorageContainerCache;
import com.craftaro.core.SongodaPlugin;
import com.craftaro.core.configuration.Config;
import com.craftaro.core.gui.GuiManager;
import com.craftaro.epichoppers.utils.StorageContainerCache;
import com.craftaro.epichoppers.hopper.Hopper;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
@ -16,21 +17,23 @@ import java.util.List;
import java.util.Map;
public abstract class Module {
private static final Map<String, Config> CONFIGS = new HashMap<>();
private static final Map<String, Config> configs = new HashMap<>();
protected final EpicHoppers plugin;
protected final SongodaPlugin plugin;
protected final GuiManager guiManager;
private final Config config;
public Module(EpicHoppers plugin) {
public Module(SongodaPlugin plugin, GuiManager guiManager) {
this.plugin = plugin;
if (!configs.containsKey(getName())) {
this.guiManager = guiManager;
if (!CONFIGS.containsKey(getName())) {
Config config = new Config(plugin, File.separator + "modules", getName() + ".yml");
configs.put(getName(), config);
CONFIGS.put(getName(), config);
config.load();
}
this.config = configs.get(getName());
this.config = CONFIGS.get(getName());
}
public abstract String getName();
@ -50,7 +53,7 @@ public abstract class Module {
}
public void saveData(Hopper hopper, String setting, Object value, Object toCache) {
config.set("data." + Methods.serializeLocation(hopper.getLocation()) + "." + setting, value);
this.config.set("data." + serializeLocation(hopper.getLocation()) + "." + setting, value);
modifyDataCache(hopper, setting, toCache);
}
@ -60,20 +63,34 @@ public abstract class Module {
protected Object getData(Hopper hopper, String setting) {
String cacheStr = getName() + "." + setting;
if (hopper.isDataCachedInModuleCache(cacheStr))
if (hopper.isDataCachedInModuleCache(cacheStr)) {
return hopper.getDataFromModuleCache(cacheStr);
}
Object data = config.get("data." + Methods.serializeLocation(hopper.getLocation()) + "." + setting);
Object data = this.config.get("data." + serializeLocation(hopper.getLocation()) + "." + setting);
modifyDataCache(hopper, setting, data);
return data;
}
public void clearData(Hopper hopper) {
config.set("data." + Methods.serializeLocation(hopper.getLocation()), null);
this.config.set("data." + serializeLocation(hopper.getLocation()), null);
hopper.clearModuleCache();
}
public void saveDataToFile() {
config.save();
this.config.save();
}
private static String serializeLocation(Location location) {
if (location == null || location.getWorld() == null) {
return "";
}
String w = location.getWorld().getName();
double x = location.getX();
double y = location.getY();
double z = location.getZ();
String str = w + ":" + x + ":" + y + ":" + z;
str = str.replace(".0", "").replace(".", "/");
return str;
}
}

View File

@ -0,0 +1,8 @@
package com.craftaro.epichoppers.hopper.teleport;
import com.craftaro.epichoppers.hopper.Hopper;
import org.bukkit.entity.Entity;
public interface TeleportHandler {
void tpEntity(Entity entity, Hopper hopper);
}

View File

@ -1,7 +1,5 @@
package com.songoda.epichoppers.hopper.teleport;
package com.craftaro.epichoppers.hopper.teleport;
public enum TeleportTrigger {
DISABLED, WALK_ON, SNEAK
}

View File

@ -1,15 +1,14 @@
package com.songoda.epichoppers.player;
package com.craftaro.epichoppers.player;
import com.songoda.epichoppers.hopper.Hopper;
import com.craftaro.epichoppers.hopper.Hopper;
public class PlayerData {
private Hopper lastHopper = null;
private SyncType syncType = null; // Null means off.
public Hopper getLastHopper() {
return lastHopper;
return this.lastHopper;
}
public void setLastHopper(Hopper lastHopper) {
@ -17,7 +16,7 @@ public class PlayerData {
}
public SyncType getSyncType() {
return syncType;
return this.syncType;
}
public void setSyncType(SyncType syncType) {

View File

@ -0,0 +1,11 @@
package com.craftaro.epichoppers.player;
import org.bukkit.entity.Player;
import java.util.Collection;
public interface PlayerDataManager {
PlayerData getPlayerData(Player player);
Collection<PlayerData> getRegisteredPlayers();
}

View File

@ -0,0 +1,5 @@
package com.craftaro.epichoppers.player;
public enum SyncType {
REGULAR, FILTERED
}

View File

@ -1,7 +1,5 @@
package com.songoda.epichoppers.utils;
package com.craftaro.epichoppers.utils;
public enum CostType {
ECONOMY, EXPERIENCE
}
}

View File

@ -0,0 +1,104 @@
package com.craftaro.epichoppers.utils;
import com.craftaro.core.SongodaPlugin;
import com.craftaro.core.compatibility.ServerVersion;
import com.craftaro.core.utils.TextUtils;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.ApiStatus;
@ApiStatus.Internal
public class Methods {
public static boolean isSimilarMaterial(ItemStack is1, ItemStack is2) {
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13) ||
is1.getDurability() == Short.MAX_VALUE || is2.getDurability() == Short.MAX_VALUE) {
// Durability of Short.MAX_VALUE is used in recipes if the durability should be ignored
return is1.getType() == is2.getType();
} else {
return is1.getType() == is2.getType() && (is1.getDurability() == -1 || is2.getDurability() == -1 || is1.getDurability() == is2.getDurability());
}
}
public static boolean canMove(Inventory inventory, ItemStack item) {
if (inventory.firstEmpty() != -1) {
return true;
}
final ItemMeta itemMeta = item.getItemMeta();
for (ItemStack stack : inventory) {
final ItemMeta stackMeta;
if (isSimilarMaterial(stack, item) && (stack.getAmount() + item.getAmount()) < stack.getMaxStackSize()
&& ((itemMeta == null) == ((stackMeta = stack.getItemMeta()) == null))
&& (itemMeta == null || Bukkit.getItemFactory().equals(itemMeta, stackMeta))) {
return true;
}
}
return false;
}
public static boolean canMoveReserved(Inventory inventory, ItemStack item) {
if (inventory.firstEmpty() != inventory.getSize() - 1) {
return true;
}
final ItemMeta itemMeta = item.getItemMeta();
final ItemStack[] contents = inventory.getContents();
for (int i = 0; i < 4; i++) {
final ItemStack stack = contents[i];
final ItemMeta stackMeta;
if (isSimilarMaterial(stack, item) && (stack.getAmount() + item.getAmount()) < stack.getMaxStackSize()
&& ((itemMeta == null) == ((stackMeta = stack.getItemMeta()) == null))
&& (itemMeta == null || Bukkit.getItemFactory().equals(itemMeta, stackMeta))) {
return true;
}
}
return false;
}
public static boolean canMoveReserved(ItemStack[] contents, ItemStack item) {
final ItemMeta itemMeta = item.getItemMeta();
for (int i = 0; i < contents.length - 2; i++) {
final ItemStack stack = contents[i];
if (stack == null || stack.getAmount() == 0) {
return true;
}
final ItemMeta stackMeta;
if (isSimilarMaterial(stack, item) && (stack.getAmount() + item.getAmount()) < stack.getMaxStackSize()
&& ((itemMeta == null) == ((stackMeta = stack.getItemMeta()) == null))
&& (itemMeta == null || Bukkit.getItemFactory().equals(itemMeta, stackMeta))) {
return true;
}
}
return false;
}
public static String formatName(int level) {
String name = getPlugin().getLocale()
.getMessage("general.nametag.nameformat")
.processPlaceholder("level", level)
.getMessage();
return TextUtils.formatText(name);
}
public static void doParticles(Entity entity, Location location) {
location.setX(location.getX() + .5);
location.setY(location.getY() + .5);
location.setZ(location.getZ() + .5);
entity.getWorld().spawnParticle(org.bukkit.Particle.valueOf(getPlugin().getConfig().getString("Main.Upgrade Particle Type")), location, 200, .5, .5, .5);
}
/**
* @deprecated The class needs refactoring to not even need the plugin.
* This is just a temporary workaround to get a Minecraft 1.20-beta build ready
*/
@Deprecated
private static SongodaPlugin getPlugin() {
return (SongodaPlugin) Bukkit.getPluginManager().getPlugin("EpicHoppers");
}
}

View File

@ -1,358 +1,362 @@
package com.songoda.epichoppers.utils;
import com.songoda.core.compatibility.CompatibleMaterial;
import com.songoda.core.compatibility.ServerVersion;
import com.songoda.core.nms.NmsManager;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.type.Chest;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import java.util.HashMap;
import java.util.Map;
/**
* Persistent storage intended for streamlining read/write for storage
* containers in large batches
*/
public class StorageContainerCache {
private static final Map<Block, Cache> inventoryCache = new HashMap<>();
// need to get the topmost inventory for a double chest, and save as that block
public static Cache getCachedInventory(Block b) {
Cache cache = inventoryCache.get(b);
if (cache == null) {
Material type = b.getType();
if (type == Material.CHEST || type == Material.TRAPPED_CHEST) {
Block b2 = findAdjacentDoubleChest(b);
//System.out.println("Adjacent to " + b + " = " + b2);
if (b2 != null && (cache = inventoryCache.get(b2)) != null) {
return cache;
}
}
BlockState blockState = b.getState();
if (blockState instanceof InventoryHolder) {
//System.out.println("Load " + b.getLocation());
inventoryCache.put(b, cache = new Cache(b, ((InventoryHolder) blockState).getInventory().getContents()));
}
}
return cache;
}
/**
* Look for a double chest adjacent to a chest
*
* @param block
* @return
*/
public static Block findAdjacentDoubleChest(Block block) {
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13)) {
final BlockData d = block.getBlockData();
if (d instanceof Chest) {
final Chest c = (Chest) d;
if (c.getType() != Chest.Type.SINGLE) {
// this is a double chest - check the other chest for registration data
Block other = null;
switch (c.getFacing()) {
case SOUTH:
other = block.getRelative(c.getType() != Chest.Type.RIGHT ? BlockFace.WEST : BlockFace.EAST);
break;
case NORTH:
other = block.getRelative(c.getType() != Chest.Type.RIGHT ? BlockFace.EAST : BlockFace.WEST);
break;
case EAST:
other = block.getRelative(c.getType() != Chest.Type.RIGHT ? BlockFace.SOUTH : BlockFace.NORTH);
break;
case WEST:
other = block.getRelative(c.getType() != Chest.Type.RIGHT ? BlockFace.NORTH : BlockFace.SOUTH);
break;
default:
break;
}
// double-check
if (other != null && other.getType() == block.getType()) {
return other;
}
}
}
} else {
// legacy check
Material material = block.getType();
BlockFace[] faces = new BlockFace[] {BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, BlockFace.WEST};
for (BlockFace face : faces) {
Block adjacentBlock = block.getRelative(face);
if (adjacentBlock.getType() == material) {
return adjacentBlock;
}
}
}
return null;
}
public static void update() {
inventoryCache.entrySet().stream()
.filter(e -> e.getValue().dirty)
.forEach(e -> {
//System.out.println("Update " + e.getKey().getLocation());
// setContents makes a copy of every item whether it's needed or not
//((InventoryHolder) e.getKey().getState()).getInventory().setContents(e.getValue().cachedInventory);
// so let's only update what needs to be updated.
final ItemStack[] cachedInventory = e.getValue().cachedInventory;
final boolean[] cacheChanged = e.getValue().cacheChanged;
Inventory inventory = ((InventoryHolder) e.getKey().getState()).getInventory();//.setContents();
for (int i = 0; i < cachedInventory.length; i++) {
if (cacheChanged[i]) {
inventory.setItem(i, cachedInventory[i]);
}
}
NmsManager.getWorld().updateAdjacentComparators(e.getKey());
});
inventoryCache.clear();
}
public static class Cache {
public final Material type;
public final Block block;
public ItemStack[] cachedInventory;
public boolean[] cacheChanged;
public int[] cacheAdded;
public boolean dirty;
public Cache(Material type, ItemStack[] cachedInventory) {
this.block = null;
this.type = type;
this.cachedInventory = cachedInventory;
this.cacheChanged = new boolean[cachedInventory.length];
this.cacheAdded = new int[cachedInventory.length];
}
public Cache(Block b, ItemStack[] cachedInventory) {
this.block = b;
this.type = b.getType();
this.cachedInventory = cachedInventory;
this.cacheChanged = new boolean[cachedInventory.length];
this.cacheAdded = new int[cachedInventory.length];
}
public void setDirty(boolean dirty) {
this.dirty = dirty;
}
public boolean isDirty() {
return this.dirty;
}
public void setContents(ItemStack[] items) {
if (cachedInventory == null || items.length == cachedInventory.length) {
cachedInventory = items;
for (int i = 0; i < cachedInventory.length; i++) {
cacheChanged[i] = true;
}
dirty = true;
}
}
public void setItem(int item, ItemStack itemStack) {
if (cachedInventory != null) {
cachedInventory[item] = itemStack;
cacheChanged[item] = true;
dirty = true;
}
}
public void removeItem(int item) {
if (cachedInventory != null) {
cachedInventory[item] = null;
cacheChanged[item] = true;
dirty = true;
}
}
public void removeItems(ItemStack item) {
if (cachedInventory != null && item != null) {
int toRemove = item.getAmount();
for (int i = 0; toRemove > 0 && i < cachedInventory.length; i++) {
final ItemStack cacheItem = cachedInventory[i];
if (cacheItem != null && cacheItem.getAmount() != 0 && item.isSimilar(cacheItem)) {
int have = cacheItem.getAmount();
if (have > toRemove) {
cachedInventory[i].setAmount(have - toRemove);
cacheChanged[i] = true;
toRemove = 0;
} else {
cachedInventory[i] = null;
cacheChanged[i] = true;
toRemove -= have;
}
}
}
dirty = dirty | (toRemove != item.getAmount());
}
}
/**
* Add a number of items to this container's inventory later.
*
* @param item item to add
* @param amountToAdd how many of this item to attempt to add
* @return how many items were added
*/
public int addAny(ItemStack item, int amountToAdd) {
// Don't transfer shulker boxes into other shulker boxes, that's a bad idea.
if (type.name().contains("SHULKER_BOX") && item.getType().name().contains("SHULKER_BOX"))
return 0;
int totalAdded = 0;
if (cachedInventory != null && item != null) {
final int maxStack = item.getMaxStackSize();
for (int i = 0; amountToAdd > 0 && i < cachedInventory.length; i++) {
final ItemStack cacheItem = cachedInventory[i];
if (cacheItem == null || cacheItem.getAmount() == 0) {
// free slot!
int toAdd = Math.min(maxStack, amountToAdd);
cachedInventory[i] = item.clone();
cachedInventory[i].setAmount(toAdd);
cacheChanged[i] = true;
cacheAdded[i] = toAdd;
totalAdded += toAdd;
amountToAdd -= toAdd;
} else if (maxStack > cacheItem.getAmount() && item.isSimilar(cacheItem)) {
// free space!
int toAdd = Math.min(maxStack - cacheItem.getAmount(), amountToAdd);
cachedInventory[i].setAmount(toAdd + cacheItem.getAmount());
cacheChanged[i] = true;
cacheAdded[i] += toAdd;
totalAdded += toAdd;
amountToAdd -= toAdd;
}
}
if (totalAdded != 0) {
dirty = true;
}
}
return totalAdded;
}
/**
* Add an item to this container's inventory later.
*
* @param item item to add
* @return true if the item was added
*/
public boolean addItem(ItemStack item) {
if (cachedInventory == null || item == null || item.getAmount() <= 0)
return false;
// Don't transfer shulker boxes into other shulker boxes, that's a bad idea.
if (type.name().contains("SHULKER_BOX") && item.getType().name().contains("SHULKER_BOX"))
return false;
// grab the amount to move and the max item stack size
int toAdd = item.getAmount();
final int maxStack = item.getMaxStackSize();
boolean[] check = null;
// some destination containers have special conditions
switch (type.name()) {
case "BREWING_STAND": {
// first compile a list of what slots to check
check = new boolean[5];
String typeStr = item.getType().name().toUpperCase();
if (typeStr.contains("POTION") || typeStr.contains("BOTTLE")) {
// potion bottles are the first three slots
check[0] = check[1] = check[2] = true;
}
// fuel in 5th position, input in 4th
if (item.getType() == Material.BLAZE_POWDER)
check[4] = true;
else if (CompatibleMaterial.getMaterial(item).isBrewingStandIngredient())
check[3] = true;
break;
}
case "SMOKER":
case "BLAST_FURNACE":
case "BURNING_FURNACE":
case "FURNACE": {
check = new boolean[3];
boolean isFuel = !item.getType().name().contains("LOG") && CompatibleMaterial.getMaterial(item.getType()).isFuel();
// fuel is 2nd slot, input is first
if (isFuel)
check[1] = true;
else
check[0] = true;
break;
}
default:
break;
}
// we can reduce calls to ItemStack.isSimilar() by caching what cells to look at
if (check == null) {
check = new boolean[cachedInventory.length];
for (int i = 0; toAdd > 0 && i < check.length; i++)
check[i] = true;
}
// first verify that we can add this item
for (int i = 0; toAdd > 0 && i < cachedInventory.length; i++) {
if (check[i]) {
final ItemStack cacheItem = cachedInventory[i];
if (cacheItem == null || cacheItem.getAmount() == 0) {
// free slot!
toAdd -= Math.min(maxStack, toAdd);
check[i] = true;
} else if (maxStack > cacheItem.getAmount() && item.isSimilar(cacheItem)) {
// free space!
toAdd -= Math.min(maxStack - cacheItem.getAmount(), toAdd);
check[i] = true;
} else
check[i] = false;
}
}
if (toAdd <= 0) {
// all good to add!
toAdd = item.getAmount();
for (int i = 0; toAdd > 0 && i < cachedInventory.length; i++) {
if (!check[i])
continue;
final ItemStack cacheItem = cachedInventory[i];
if (cacheItem == null || cacheItem.getAmount() == 0) {
// free slot!
int adding = Math.min(maxStack, toAdd);
cachedInventory[i] = item.clone();
cachedInventory[i].setAmount(adding);
cacheChanged[i] = true;
cacheAdded[i] = adding;
toAdd -= adding;
} else if (maxStack > cacheItem.getAmount()) {
// free space!
// (no need to check item.isSimilar(cacheItem), since we have that cached in check[])
int adding = Math.min(maxStack - cacheItem.getAmount(), toAdd);
cachedInventory[i].setAmount(adding + cacheItem.getAmount());
cacheChanged[i] = true;
cacheAdded[i] += adding;
toAdd -= adding;
}
}
dirty = true;
return true;
}
return false;
}
}
}
package com.craftaro.epichoppers.utils;
import com.craftaro.core.compatibility.CompatibleMaterial;
import com.craftaro.core.compatibility.ServerVersion;
import com.craftaro.core.nms.Nms;
import com.craftaro.third_party.com.cryptomorin.xseries.XMaterial;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.type.Chest;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.ApiStatus;
import java.util.HashMap;
import java.util.Map;
/**
* Persistent storage intended for streamlining read/write for storage
* containers in large batches
*/
@ApiStatus.Internal
public class StorageContainerCache {
private static final Map<Block, Cache> INVENTORY_CACHE = new HashMap<>();
// need to get the topmost inventory for a double chest, and save as that block
public static Cache getCachedInventory(Block block) {
Cache cache = INVENTORY_CACHE.get(block);
if (cache == null) {
Material type = block.getType();
if (type == Material.CHEST || type == Material.TRAPPED_CHEST) {
Block b2 = findAdjacentDoubleChest(block);
//System.out.println("Adjacent to " + block + " = " + b2);
if (b2 != null && (cache = INVENTORY_CACHE.get(b2)) != null) {
return cache;
}
}
BlockState blockState = block.getState();
if (blockState instanceof InventoryHolder) {
//System.out.println("Load " + block.getLocation());
INVENTORY_CACHE.put(block, cache = new Cache(block, ((InventoryHolder) blockState).getInventory().getContents()));
}
}
return cache;
}
/**
* Look for a double chest adjacent to a chest
*/
public static Block findAdjacentDoubleChest(Block block) {
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13)) {
final BlockData blockData = block.getBlockData();
if (blockData instanceof Chest) {
final Chest chest = (Chest) blockData;
if (chest.getType() != Chest.Type.SINGLE) {
// this is a double chest - check the other chest for registration data
Block other = null;
switch (chest.getFacing()) {
case SOUTH:
other = block.getRelative(chest.getType() != Chest.Type.RIGHT ? BlockFace.WEST : BlockFace.EAST);
break;
case NORTH:
other = block.getRelative(chest.getType() != Chest.Type.RIGHT ? BlockFace.EAST : BlockFace.WEST);
break;
case EAST:
other = block.getRelative(chest.getType() != Chest.Type.RIGHT ? BlockFace.SOUTH : BlockFace.NORTH);
break;
case WEST:
other = block.getRelative(chest.getType() != Chest.Type.RIGHT ? BlockFace.NORTH : BlockFace.SOUTH);
break;
default:
break;
}
// double-check
if (other != null && other.getType() == block.getType()) {
return other;
}
}
}
} else {
// legacy check
Material material = block.getType();
BlockFace[] faces = new BlockFace[]{BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, BlockFace.WEST};
for (BlockFace face : faces) {
Block adjacentBlock = block.getRelative(face);
if (adjacentBlock.getType() == material) {
return adjacentBlock;
}
}
}
return null;
}
public static void update() {
INVENTORY_CACHE.entrySet().stream()
.filter(e -> e.getValue().dirty)
.forEach(e -> {
//System.out.println("Update " + e.getKey().getLocation());
// setContents makes a copy of every item whether it's needed or not
//((InventoryHolder) e.getKey().getState()).getInventory().setContents(e.getValue().cachedInventory);
// so let's only update what needs to be updated.
final ItemStack[] cachedInventory = e.getValue().cachedInventory;
final boolean[] cacheChanged = e.getValue().cacheChanged;
Inventory inventory = ((InventoryHolder) e.getKey().getState()).getInventory();//.setContents();
for (int i = 0; i < cachedInventory.length; i++) {
if (cacheChanged[i]) {
inventory.setItem(i, cachedInventory[i]);
}
}
Nms.getImplementations().getWorld().updateAdjacentComparators(e.getKey());
});
INVENTORY_CACHE.clear();
}
public static class Cache {
public final Material type;
public final Block block;
public ItemStack[] cachedInventory;
public boolean[] cacheChanged;
public int[] cacheAdded;
public boolean dirty;
public Cache(Material type, ItemStack[] cachedInventory) {
this.block = null;
this.type = type;
this.cachedInventory = cachedInventory;
this.cacheChanged = new boolean[cachedInventory.length];
this.cacheAdded = new int[cachedInventory.length];
}
public Cache(Block block, ItemStack[] cachedInventory) {
this.block = block;
this.type = block.getType();
this.cachedInventory = cachedInventory;
this.cacheChanged = new boolean[cachedInventory.length];
this.cacheAdded = new int[cachedInventory.length];
}
public void setDirty(boolean dirty) {
this.dirty = dirty;
}
public boolean isDirty() {
return this.dirty;
}
public void setContents(ItemStack[] items) {
if (this.cachedInventory == null || items.length == this.cachedInventory.length) {
this.cachedInventory = items;
for (int i = 0; i < this.cachedInventory.length; i++) {
this.cacheChanged[i] = true;
}
this.dirty = true;
}
}
public void setItem(int item, ItemStack itemStack) {
if (this.cachedInventory != null) {
this.cachedInventory[item] = itemStack;
this.cacheChanged[item] = true;
this.dirty = true;
}
}
public void removeItem(int item) {
if (this.cachedInventory != null) {
this.cachedInventory[item] = null;
this.cacheChanged[item] = true;
this.dirty = true;
}
}
public void removeItems(ItemStack item) {
if (this.cachedInventory != null && item != null) {
int toRemove = item.getAmount();
for (int i = 0; toRemove > 0 && i < this.cachedInventory.length; i++) {
final ItemStack cacheItem = this.cachedInventory[i];
if (cacheItem != null && cacheItem.getAmount() != 0 && item.isSimilar(cacheItem)) {
int have = cacheItem.getAmount();
if (have > toRemove) {
this.cachedInventory[i].setAmount(have - toRemove);
this.cacheChanged[i] = true;
toRemove = 0;
} else {
this.cachedInventory[i] = null;
this.cacheChanged[i] = true;
toRemove -= have;
}
}
}
this.dirty = this.dirty | (toRemove != item.getAmount());
}
}
/**
* Add a number of items to this container's inventory later.
*
* @param item item to add
* @param amountToAdd how many of this item to attempt to add
* @return how many items were added
*/
public int addAny(ItemStack item, int amountToAdd) {
// Don't transfer shulker boxes into other shulker boxes, that's a bad idea.
if (this.type.name().contains("SHULKER_BOX") && item.getType().name().contains("SHULKER_BOX")) {
return 0;
}
int totalAdded = 0;
if (this.cachedInventory != null && item != null) {
final int maxStack = item.getMaxStackSize();
for (int i = 0; amountToAdd > 0 && i < this.cachedInventory.length; i++) {
final ItemStack cacheItem = this.cachedInventory[i];
if (cacheItem == null || cacheItem.getAmount() == 0) {
// free slot!
int toAdd = Math.min(maxStack, amountToAdd);
this.cachedInventory[i] = item.clone();
this.cachedInventory[i].setAmount(toAdd);
this.cacheChanged[i] = true;
this.cacheAdded[i] = toAdd;
totalAdded += toAdd;
amountToAdd -= toAdd;
} else if (maxStack > cacheItem.getAmount() && item.isSimilar(cacheItem)) {
// free space!
int toAdd = Math.min(maxStack - cacheItem.getAmount(), amountToAdd);
this.cachedInventory[i].setAmount(toAdd + cacheItem.getAmount());
this.cacheChanged[i] = true;
this.cacheAdded[i] += toAdd;
totalAdded += toAdd;
amountToAdd -= toAdd;
}
}
if (totalAdded != 0) {
this.dirty = true;
}
}
return totalAdded;
}
/**
* Add an item to this container's inventory later.
*
* @param item item to add
* @return true if the item was added
*/
public boolean addItem(ItemStack item) {
if (this.cachedInventory == null || item == null || item.getAmount() <= 0) {
return false;
}
// Don't transfer shulker boxes into other shulker boxes, that's a bad idea.
if (this.type.name().contains("SHULKER_BOX") && item.getType().name().contains("SHULKER_BOX")) {
return false;
}
// grab the amount to move and the max item stack size
int toAdd = item.getAmount();
final int maxStack = item.getMaxStackSize();
boolean[] check = null;
// some destination containers have special conditions
switch (CompatibleMaterial.getMaterial(this.type).orElse(XMaterial.AIR)) {
case BREWING_STAND: {
// first compile a list of what slots to check
check = new boolean[5];
String typeStr = item.getType().name().toUpperCase();
if (typeStr.contains("POTION") || typeStr.contains("BOTTLE")) {
// potion bottles are the first three slots
check[0] = check[1] = check[2] = true;
}
// fuel in 5th position, input in 4th
if (item.getType() == Material.BLAZE_POWDER) {
check[4] = true;
} else if (CompatibleMaterial.isBrewingStandIngredient(CompatibleMaterial.getMaterial(item.getType()).get())) {
check[3] = true;
}
break;
}
case SMOKER:
case BLAST_FURNACE:
case FURNACE: {
check = new boolean[3];
boolean isFuel = !item.getType().name().contains("LOG") && CompatibleMaterial.isFurnaceFuel(CompatibleMaterial.getMaterial(item.getType()).get());
// fuel is 2nd slot, input is first
if (isFuel) {
check[1] = true;
} else {
check[0] = true;
}
break;
}
default:
break;
}
// we can reduce calls to ItemStack.isSimilar() by caching what cells to look at
if (check == null) {
check = new boolean[this.cachedInventory.length];
for (int i = 0; toAdd > 0 && i < check.length; i++) {
check[i] = true;
}
}
// first verify that we can add this item
for (int i = 0; toAdd > 0 && i < this.cachedInventory.length; i++) {
if (check[i]) {
final ItemStack cacheItem = this.cachedInventory[i];
if (cacheItem == null || cacheItem.getAmount() == 0) {
// free slot!
toAdd -= Math.min(maxStack, toAdd);
check[i] = true;
} else if (maxStack > cacheItem.getAmount() && item.isSimilar(cacheItem)) {
// free space!
toAdd -= Math.min(maxStack - cacheItem.getAmount(), toAdd);
check[i] = true;
} else {
check[i] = false;
}
}
}
if (toAdd <= 0) {
// all good to add!
toAdd = item.getAmount();
for (int i = 0; toAdd > 0 && i < this.cachedInventory.length; i++) {
if (!check[i]) {
continue;
}
final ItemStack cacheItem = this.cachedInventory[i];
if (cacheItem == null || cacheItem.getAmount() == 0) {
// free slot!
int adding = Math.min(maxStack, toAdd);
this.cachedInventory[i] = item.clone();
this.cachedInventory[i].setAmount(adding);
this.cacheChanged[i] = true;
this.cacheAdded[i] = adding;
toAdd -= adding;
} else if (maxStack > cacheItem.getAmount()) {
// free space!
// (no need to check item.isSimilar(cacheItem), since we have that cached in check[])
int adding = Math.min(maxStack - cacheItem.getAmount(), toAdd);
this.cachedInventory[i].setAmount(adding + cacheItem.getAmount());
this.cacheChanged[i] = true;
this.cacheAdded[i] += adding;
toAdd -= adding;
}
}
this.dirty = true;
return true;
}
return false;
}
}
}

182
EpicHoppers-Plugin/pom.xml Normal file
View File

@ -0,0 +1,182 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.craftaro</groupId>
<artifactId>EpicHoppers-Parent</artifactId>
<version>5.0.1</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>EpicHoppers-Plugin</artifactId>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.4.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<finalName>${project.parent.name}-${project.version}</finalName>
<shadedArtifactAttached>false</shadedArtifactAttached>
<useDependencyReducedPomInJar>true</useDependencyReducedPomInJar>
<minimizeJar>true</minimizeJar>
<relocations>
<relocation>
<pattern>com.craftaro.core</pattern>
<shadedPattern>com.craftaro.epichoppers.core</shadedPattern>
</relocation>
</relocations>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/**</exclude>
<exclude>LICENSE</exclude>
<exclude>LICENSE.**</exclude>
</excludes>
</filter>
<filter>
<artifact>com.craftaro:CraftaroCore</artifact>
<excludeDefaults>false</excludeDefaults>
<includes>
<include>**/nms/v*/**</include>
</includes>
<excludes>
<exclude>**/third_party/org/apache/**</exclude>
<exclude>**/third_party/net/kyori/**</exclude>
<exclude>**/third_party/com/zaxxer/**</exclude>
<exclude>**/third_party/org/jooq/**</exclude>
<exclude>**/third_party/org/mariadb/**</exclude>
<exclude>**/third_party/com/h2database/**</exclude>
<exclude>**/third_party/org/h2/**</exclude>
<exclude>**/third_party/com/cryptomorin/**</exclude>
<exclude>**/third_party/org/reactivestreams/**</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
<repositories>
<repository>
<id>rosewood-repo</id>
<url>https://repo.rosewooddev.io/repository/public/</url>
</repository>
<repository>
<id>public</id>
<url>https://repo.songoda.com/repository/public/</url>
</repository>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>com.craftaro</groupId>
<artifactId>EpicHoppers-API</artifactId>
<version>1.0.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.craftaro</groupId>
<artifactId>CraftaroCore</artifactId>
<version>${craftaro.coreVersion}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.19.4-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.craftaro</groupId>
<artifactId>FabledSkyBlock</artifactId>
<version>3.0.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.craftaro</groupId>
<artifactId>EpicFarming</artifactId>
<version>4.1.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.github.brcdev-minecraft</groupId>
<artifactId>shopgui-api</artifactId>
<version>2.2.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.github.Gypopo</groupId>
<artifactId>EconomyShopGUI-API</artifactId>
<version>1.4.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.craftaro</groupId>
<artifactId>UltimateStacker-API</artifactId>
<version>1.0.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.bgsoftware</groupId>
<artifactId>wildstacker</artifactId>
<version>3.5.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>dev.rosewood</groupId>
<artifactId>rosestacker</artifactId>
<version>1.5.11</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.github.DeadSilenceIV</groupId>
<artifactId>AdvancedChestsAPI</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,289 @@
package com.craftaro.epichoppers;
import com.craftaro.core.SongodaCore;
import com.craftaro.core.SongodaPlugin;
import com.craftaro.core.commands.CommandManager;
import com.craftaro.core.configuration.Config;
import com.craftaro.core.database.DatabaseConnector;
import com.craftaro.core.gui.GuiManager;
import com.craftaro.core.hooks.EconomyManager;
import com.craftaro.core.hooks.ProtectionManager;
import com.craftaro.third_party.com.cryptomorin.xseries.XMaterial;
import com.craftaro.core.third_party.de.tr7zw.nbtapi.NBTItem;
import com.craftaro.core.utils.TextUtils;
import com.craftaro.epichoppers.boost.BoostDataImpl;
import com.craftaro.epichoppers.boost.BoostManager;
import com.craftaro.epichoppers.boost.BoostManagerImpl;
import com.craftaro.epichoppers.commands.CommandBoost;
import com.craftaro.epichoppers.commands.CommandGive;
import com.craftaro.epichoppers.commands.CommandReload;
import com.craftaro.epichoppers.commands.CommandSettings;
import com.craftaro.epichoppers.containers.ContainerManager;
import com.craftaro.epichoppers.containers.ContainerManagerImpl;
import com.craftaro.epichoppers.database.migrations._1_InitialMigration;
import com.craftaro.epichoppers.hopper.HopperImpl;
import com.craftaro.epichoppers.hopper.HopperManager;
import com.craftaro.epichoppers.hopper.levels.Level;
import com.craftaro.epichoppers.hopper.levels.LevelManager;
import com.craftaro.epichoppers.hopper.levels.LevelManagerImpl;
import com.craftaro.epichoppers.hopper.levels.modules.Module;
import com.craftaro.epichoppers.hopper.levels.modules.ModuleAutoCrafting;
import com.craftaro.epichoppers.hopper.levels.modules.ModuleAutoSell;
import com.craftaro.epichoppers.hopper.levels.modules.ModuleAutoSmelter;
import com.craftaro.epichoppers.hopper.levels.modules.ModuleBlockBreak;
import com.craftaro.epichoppers.hopper.levels.modules.ModuleMobHopper;
import com.craftaro.epichoppers.hopper.levels.modules.ModuleSuction;
import com.craftaro.epichoppers.hopper.teleport.TeleportHandler;
import com.craftaro.epichoppers.listeners.BlockListeners;
import com.craftaro.epichoppers.listeners.EntityListeners;
import com.craftaro.epichoppers.listeners.HopperListeners;
import com.craftaro.epichoppers.listeners.InteractListeners;
import com.craftaro.epichoppers.listeners.InventoryListeners;
import com.craftaro.epichoppers.player.PlayerDataManager;
import com.craftaro.epichoppers.player.PlayerDataManagerImpl;
import com.craftaro.epichoppers.settings.Settings;
import com.craftaro.epichoppers.tasks.HopTask;
import com.craftaro.epichoppers.utils.Methods;
import com.craftaro.epichoppers.hopper.teleport.TeleportHandlerImpl;
import com.craftaro.skyblock.SkyBlock;
import com.craftaro.skyblock.permission.BasicPermission;
import org.bukkit.Bukkit;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.plugin.PluginManager;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class EpicHoppers extends SongodaPlugin {
private final GuiManager guiManager = new GuiManager(this);
private final Config levelsConfig = new Config(this, "levels.yml");
private HopperManager hopperManager;
private CommandManager commandManager;
private LevelManager levelManager;
private BoostManagerImpl boostManager;
private PlayerDataManager playerDataManager;
private ContainerManager containerManager;
private TeleportHandler teleportHandler;
@Override
public void onPluginLoad() {
}
@Override
public void onPluginDisable() {
getDataManager().shutdown();
saveModules();
}
@Override
public void onPluginEnable() {
SongodaCore.registerPlugin(this, 15, XMaterial.HOPPER);
// Load Economy
EconomyManager.load();
// Load protection hook
ProtectionManager.load(this);
// Setup Config
Settings.setupConfig();
this.setLocale(Settings.LANGUGE_MODE.getString(), false);
// Set Economy & Hologram preference
EconomyManager.getManager().setPreferredHook(Settings.ECONOMY_PLUGIN.getString());
// Register commands
this.commandManager = new CommandManager(this);
this.commandManager.addMainCommand("eh")
.addSubCommands(
new CommandBoost(this),
new CommandGive(this),
new CommandReload(this),
new CommandSettings(this)
);
this.hopperManager = new HopperManager(this);
this.playerDataManager = new PlayerDataManagerImpl();
this.containerManager = new ContainerManagerImpl();
this.boostManager = new BoostManagerImpl();
initDatabase(Collections.singletonList(new _1_InitialMigration(this)));
this.loadLevelManager();
new HopTask(this);
this.teleportHandler = new TeleportHandlerImpl(this);
// Register Listeners
this.guiManager.init();
PluginManager pluginManager = Bukkit.getPluginManager();
pluginManager.registerEvents(new HopperListeners(this), this);
pluginManager.registerEvents(new EntityListeners(), this);
pluginManager.registerEvents(new BlockListeners(this), this);
pluginManager.registerEvents(new InteractListeners(this), this);
pluginManager.registerEvents(new InventoryListeners(), this);
EpicHoppersApi.initApi(this.levelManager, this.boostManager, this.containerManager, this.teleportHandler, this.playerDataManager);
// Start auto save
int saveInterval = Settings.AUTOSAVE.getInt() * 60 * 20;
Bukkit.getScheduler().runTaskTimerAsynchronously(this, this::saveModules, saveInterval, saveInterval);
// Hotfix for EH loading before FSB
Bukkit.getScheduler().runTask(this, () -> {
if (pluginManager.isPluginEnabled("FabledSkyBlock")) {
try {
SkyBlock.getInstance().getPermissionManager().registerPermission(
(BasicPermission) Class.forName("com.craftaro.epichoppers.compatibility.EpicHoppersPermission").getDeclaredConstructor().newInstance());
} catch (ReflectiveOperationException ex) {
ex.printStackTrace();
}
}
});
}
@Override
public void onDataLoad() {
// Load data from DB
this.dataManager.getAsyncPool().execute(() -> {
getLogger().info("loading data...");
long start = System.currentTimeMillis();
this.hopperManager.addHoppers(this.dataManager.loadBatch(HopperImpl.class, "placed_hoppers"));
this.boostManager.loadBoosts(this.dataManager.loadBatch(BoostDataImpl.class, "boosted_players"));
getLogger().info("Loaded " + hopperManager.getHoppers().size() + " hoppers in " + (System.currentTimeMillis() - start) + "ms");
this.hopperManager.setReady();
});
}
@Override
public void onConfigReload() {
this.setLocale(getConfig().getString("System.Language Mode"), true);
this.locale.reloadMessages();
loadLevelManager();
}
@Override
public List<Config> getExtraConfig() {
return Collections.singletonList(this.levelsConfig);
}
private void loadLevelManager() {
if (!new File(this.getDataFolder(), "levels.yml").exists()) {
this.saveResource("levels.yml", false);
}
this.levelsConfig.load();
// Load an instance of LevelManager
this.levelManager = new LevelManagerImpl();
/*
* Register Levels into LevelManager from configuration.
*/
this.levelManager.clear();
for (String levelName : this.levelsConfig.getKeys(false)) {
int level = Integer.parseInt(levelName.split("-")[1]);
ConfigurationSection levels = this.levelsConfig.getConfigurationSection(levelName);
int radius = levels.getInt("Range");
int amount = levels.getInt("Amount");
int linkAmount = levels.getInt("Link-amount", 1);
boolean filter = levels.getBoolean("Filter");
boolean teleport = levels.getBoolean("Teleport");
int costExperience = levels.getInt("Cost-xp", -1);
int costEconomy = levels.getInt("Cost-eco", -1);
int autoSell = levels.getInt("AutoSell");
ArrayList<Module> modules = new ArrayList<>();
for (String key : levels.getKeys(false)) {
if (key.equals("Suction") && levels.getInt("Suction") != 0) {
modules.add(new ModuleSuction(this, getGuiManager(), levels.getInt("Suction")));
} else if (key.equals("BlockBreak") && levels.getInt("BlockBreak") != 0) {
modules.add(new ModuleBlockBreak(this, getGuiManager(), levels.getInt("BlockBreak")));
} else if (key.equals("AutoCrafting")) {
modules.add(new ModuleAutoCrafting(this, getGuiManager()));
} else if (key.equals("AutoSell")) {
modules.add(new ModuleAutoSell(this, getGuiManager(), autoSell));
} else if (key.equals("MobHopper")) {
modules.add(new ModuleMobHopper(this, getGuiManager(), levels.getInt("MobHopper")));
} else if (key.equals("AutoSmelting")) {
modules.add(new ModuleAutoSmelter(this, getGuiManager(), levels.getInt("AutoSmelting")));
}
}
this.levelManager.addLevel(level, costExperience, costEconomy, radius, amount, filter, teleport, linkAmount, modules);
}
}
private void saveModules() {
if (this.levelManager != null) {
for (Level level : this.levelManager.getLevels().values()) {
for (Module module : level.getRegisteredModules()) {
module.saveDataToFile();
}
}
}
}
public ItemStack newHopperItem(Level level) {
ItemStack item = XMaterial.HOPPER.parseItem();
ItemMeta itemmeta = item.getItemMeta();
itemmeta.setDisplayName(TextUtils.formatText(Methods.formatName(level.getLevel())));
String line = getLocale().getMessage("general.nametag.lore").getMessage();
if (!line.isEmpty()) {
itemmeta.setLore(Arrays.asList(line.split("\n")));
}
item.setItemMeta(itemmeta);
NBTItem nbtItem = new NBTItem(item);
nbtItem.setInteger("level", level.getLevel());
return nbtItem.getItem();
}
public TeleportHandler getTeleportHandler() {
return this.teleportHandler;
}
public BoostManager getBoostManager() {
return this.boostManager;
}
public CommandManager getCommandManager() {
return this.commandManager;
}
public LevelManager getLevelManager() {
return this.levelManager;
}
public HopperManager getHopperManager() {
return this.hopperManager;
}
public PlayerDataManager getPlayerDataManager() {
return this.playerDataManager;
}
public GuiManager getGuiManager() {
return this.guiManager;
}
public ContainerManager getContainerManager() {
return this.containerManager;
}
/**
* @deprecated Use {@link #getPlugin(Class)} instead
*/
@Deprecated
public static EpicHoppers getInstance() {
return EpicHoppers.getPlugin(EpicHoppers.class);
}
}

View File

@ -0,0 +1,92 @@
package com.craftaro.epichoppers.boost;
import com.craftaro.core.database.Data;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
public class BoostDataImpl implements BoostData, Data {
private final int multiplier;
private final long endTime;
private final UUID player;
public BoostDataImpl() {
this.multiplier = 0;
this.endTime = 0;
this.player = null;
}
public BoostDataImpl(Map<String, Object> map) {
this.multiplier = (int) map.get("multiplier");
this.endTime = (long) map.get("end_time");
this.player = UUID.fromString((String) map.get("player"));
}
public BoostDataImpl(int multiplier, long endTime, UUID player) {
this.multiplier = multiplier;
this.endTime = endTime;
this.player = player;
}
public int getMultiplier() {
return this.multiplier;
}
public UUID getPlayer() {
return this.player;
}
public long getEndTime() {
return this.endTime;
}
@Override
public int hashCode() {
int result = 31 * this.multiplier;
result = 31 * result + (this.player == null ? 0 : this.player.hashCode());
result = 31 * result + (int) (this.endTime ^ (this.endTime >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof BoostDataImpl)) {
return false;
}
BoostDataImpl other = (BoostDataImpl) obj;
return this.multiplier == other.multiplier &&
this.endTime == other.endTime &&
Objects.equals(this.player, other.player);
}
@Override
public UUID getUniqueId() {
return player;
}
@Override
public Map<String, Object> serialize() {
Map<String, Object> map = new java.util.HashMap<>();
map.put("player", player.toString());
map.put("multiplier", multiplier);
map.put("end_time", endTime);
return map;
}
@Override
public Data deserialize(Map<String, Object> map) {
return new BoostDataImpl(map);
}
@Override
public String getTableName() {
return "player_boosts";
}
}

View File

@ -1,34 +1,48 @@
package com.songoda.epichoppers.boost;
package com.craftaro.epichoppers.boost;
import com.craftaro.core.database.Data;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
public class BoostManager {
public class BoostManagerImpl implements BoostManager {
private final Set<BoostData> registeredBoosts = new HashSet<>();
@Override
public void addBoostToPlayer(BoostData data) {
this.registeredBoosts.add(data);
}
@Override
public void removeBoostFromPlayer(BoostData data) {
this.registeredBoosts.remove(data);
}
@Override
public void addBoosts(List<BoostData> boosts) {
registeredBoosts.addAll(boosts);
this.registeredBoosts.addAll(boosts);
}
public void loadBoosts(Collection<BoostDataImpl> boosts) {
this.registeredBoosts.addAll(boosts);
}
@Override
public Set<BoostData> getBoosts() {
return Collections.unmodifiableSet(registeredBoosts);
return Collections.unmodifiableSet(this.registeredBoosts);
}
@Override
public BoostData getBoost(UUID player) {
if (player == null) return null;
for (BoostData boostData : registeredBoosts) {
if (player == null) {
return null;
}
for (BoostData boostData : this.registeredBoosts) {
if (boostData.getPlayer().toString().equals(player.toString())) {
if (System.currentTimeMillis() >= boostData.getEndTime()) {
removeBoostFromPlayer(boostData);

View File

@ -1,19 +1,20 @@
package com.songoda.epichoppers.commands;
package com.craftaro.epichoppers.commands;
import com.songoda.core.commands.AbstractCommand;
import com.songoda.epichoppers.EpicHoppers;
import com.songoda.epichoppers.boost.BoostData;
import com.songoda.epichoppers.utils.Methods;
import com.craftaro.core.commands.AbstractCommand;
import com.craftaro.core.utils.NumberUtils;
import com.craftaro.core.utils.TimeUtils;
import com.craftaro.epichoppers.boost.BoostDataImpl;
import com.craftaro.epichoppers.EpicHoppers;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class CommandBoost extends AbstractCommand {
private final EpicHoppers plugin;
public CommandBoost(EpicHoppers plugin) {
@ -24,11 +25,11 @@ public class CommandBoost extends AbstractCommand {
@Override
protected ReturnType runCommand(CommandSender sender, String... args) {
if (args.length < 2) {
plugin.getLocale().newMessage("&7Syntax error...").sendPrefixedMessage(sender);
this.plugin.getLocale().newMessage("&7Syntax error...").sendPrefixedMessage(sender);
return ReturnType.SYNTAX_ERROR;
}
if (!Methods.isInt(args[1])) {
plugin.getLocale().newMessage("&6" + args[1] + " &7is not a number...").sendPrefixedMessage(sender);
if (!NumberUtils.isInt(args[1])) {
this.plugin.getLocale().newMessage("&6" + args[1] + " &7is not a number...").sendPrefixedMessage(sender);
return ReturnType.SYNTAX_ERROR;
}
@ -36,7 +37,7 @@ public class CommandBoost extends AbstractCommand {
if (args.length > 2) {
for (String line : args) {
long time = Methods.parseTime(line);
long time = TimeUtils.parseTime(line);
duration += time;
}
@ -44,14 +45,14 @@ public class CommandBoost extends AbstractCommand {
Player player = Bukkit.getPlayer(args[0]);
if (player == null) {
plugin.getLocale().newMessage("&cThat player does not exist or is not online...").sendPrefixedMessage(sender);
this.plugin.getLocale().newMessage("&cThat player does not exist or is not online...").sendPrefixedMessage(sender);
return ReturnType.FAILURE;
}
BoostData boostData = new BoostData(Integer.parseInt(args[1]), duration == 0L ? Long.MAX_VALUE : System.currentTimeMillis() + duration, player.getUniqueId());
plugin.getBoostManager().addBoostToPlayer(boostData);
plugin.getLocale().newMessage("&7Successfully boosted &6" + Bukkit.getPlayer(args[0]).getName()
+ "'s &7hopper transfer rates by &6" + args[1] + "x" + (duration == 0L ? "" : (" for " + Methods.makeReadable(duration))) + "&7.").sendPrefixedMessage(sender);
BoostDataImpl boostData = new BoostDataImpl(Integer.parseInt(args[1]), duration == 0L ? Long.MAX_VALUE : System.currentTimeMillis() + duration, player.getUniqueId());
this.plugin.getBoostManager().addBoostToPlayer(boostData);
this.plugin.getLocale().newMessage("&7Successfully boosted &6" + Bukkit.getPlayer(args[0]).getName()
+ "'s &7hopper transfer rates by &6" + args[1] + "x" + (duration == 0L ? "" : (" for " + TimeUtils.makeReadable(duration))) + "&7.").sendPrefixedMessage(sender);
return ReturnType.SUCCESS;
}
@ -68,7 +69,8 @@ public class CommandBoost extends AbstractCommand {
} else if (args.length == 3) {
return Arrays.asList("1m", "1h", "1d");
}
return null;
return Collections.emptyList();
}
@Override

View File

@ -1,8 +1,8 @@
package com.songoda.epichoppers.commands;
package com.craftaro.epichoppers.commands;
import com.songoda.core.commands.AbstractCommand;
import com.songoda.epichoppers.EpicHoppers;
import com.songoda.epichoppers.hopper.levels.Level;
import com.craftaro.core.commands.AbstractCommand;
import com.craftaro.epichoppers.EpicHoppers;
import com.craftaro.epichoppers.hopper.levels.Level;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@ -12,7 +12,6 @@ import java.util.Arrays;
import java.util.List;
public class CommandGive extends AbstractCommand {
private final EpicHoppers plugin;
public CommandGive(EpicHoppers plugin) {
@ -26,29 +25,29 @@ public class CommandGive extends AbstractCommand {
return ReturnType.SYNTAX_ERROR;
}
if (Bukkit.getPlayerExact(args[0]) == null) {
plugin.getLocale().newMessage("&cThat username does not exist, or the user is not online!").sendPrefixedMessage(sender);
this.plugin.getLocale().newMessage("&cThat username does not exist, or the user is not online!").sendPrefixedMessage(sender);
return ReturnType.FAILURE;
}
Level level = plugin.getLevelManager().getLowestLevel();
Level level = this.plugin.getLevelManager().getLowestLevel();
Player player;
if (Bukkit.getPlayer(args[0]) == null) {
plugin.getLocale().newMessage("&cThat player does not exist or is currently offline.").sendPrefixedMessage(sender);
this.plugin.getLocale().newMessage("&cThat player does not exist or is currently offline.").sendPrefixedMessage(sender);
return ReturnType.FAILURE;
} else {
player = Bukkit.getPlayer(args[0]);
}
if (!plugin.getLevelManager().isLevel(Integer.parseInt(args[1]))) {
plugin.getLocale().newMessage("&cNot a valid level... The current valid levels are: &4" + level.getLevel() + "-" + plugin.getLevelManager().getHighestLevel().getLevel() + "&c.")
if (!this.plugin.getLevelManager().isLevel(Integer.parseInt(args[1]))) {
this.plugin.getLocale().newMessage("&cNot a valid level... The current valid levels are: &4" + level.getLevel() + "-" + this.plugin.getLevelManager().getHighestLevel().getLevel() + "&c.")
.sendPrefixedMessage(sender);
return ReturnType.FAILURE;
} else {
level = plugin.getLevelManager().getLevel(Integer.parseInt(args[1]));
level = this.plugin.getLevelManager().getLevel(Integer.parseInt(args[1]));
}
player.getInventory().addItem(plugin.newHopperItem(level));
plugin.getLocale().getMessage("command.give.success").processPlaceholder("level", level.getLevel()).sendPrefixedMessage(player);
player.getInventory().addItem(this.plugin.newHopperItem(level));
this.plugin.getLocale().getMessage("command.give.success").processPlaceholder("level", level.getLevel()).sendPrefixedMessage(player);
return ReturnType.SUCCESS;
}

View File

@ -1,13 +1,12 @@
package com.songoda.epichoppers.commands;
package com.craftaro.epichoppers.commands;
import com.songoda.core.commands.AbstractCommand;
import com.songoda.epichoppers.EpicHoppers;
import com.craftaro.core.commands.AbstractCommand;
import com.craftaro.epichoppers.EpicHoppers;
import org.bukkit.command.CommandSender;
import java.util.List;
public class CommandReload extends AbstractCommand {
private final EpicHoppers plugin;
public CommandReload(EpicHoppers plugin) {
@ -17,8 +16,8 @@ public class CommandReload extends AbstractCommand {
@Override
protected ReturnType runCommand(CommandSender sender, String... args) {
plugin.reloadConfig();
plugin.getLocale().getMessage("&7Configuration and Language files reloaded.").sendPrefixedMessage(sender);
this.plugin.reloadConfig();
this.plugin.getLocale().getMessage("&7Configuration and Language files reloaded.").sendPrefixedMessage(sender);
return ReturnType.SUCCESS;
}

View File

@ -1,15 +1,14 @@
package com.songoda.epichoppers.commands;
package com.craftaro.epichoppers.commands;
import com.songoda.core.commands.AbstractCommand;
import com.songoda.core.configuration.editor.PluginConfigGui;
import com.songoda.epichoppers.EpicHoppers;
import com.craftaro.core.commands.AbstractCommand;
import com.craftaro.core.configuration.editor.PluginConfigGui;
import com.craftaro.epichoppers.EpicHoppers;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.List;
public class CommandSettings extends AbstractCommand {
private final EpicHoppers plugin;
public CommandSettings(EpicHoppers plugin) {
@ -19,7 +18,7 @@ public class CommandSettings extends AbstractCommand {
@Override
protected ReturnType runCommand(CommandSender sender, String... args) {
plugin.getGuiManager().showGUI((Player) sender, new PluginConfigGui(plugin));
this.plugin.getGuiManager().showGUI((Player) sender, new PluginConfigGui(this.plugin));
return ReturnType.SUCCESS;
}

View File

@ -0,0 +1,11 @@
package com.craftaro.epichoppers.compatibility;
import com.craftaro.skyblock.permission.BasicPermission;
import com.craftaro.skyblock.permission.PermissionType;
import com.craftaro.third_party.com.cryptomorin.xseries.XMaterial;
public class EpicHoppersPermission extends BasicPermission {
public EpicHoppersPermission() {
super("EpicHoppers", XMaterial.HOPPER, PermissionType.GENERIC);
}
}

View File

@ -1,9 +1,8 @@
package com.songoda.epichoppers.containers;
package com.craftaro.epichoppers.containers;
import com.songoda.epichoppers.EpicHoppers;
import com.songoda.epichoppers.containers.impl.AdvancedChestImplementation;
import com.songoda.epichoppers.containers.impl.EpicFarmingImplementation;
import com.songoda.epichoppers.containers.impl.FabledSkyBlockImplementation;
import com.craftaro.epichoppers.containers.impl.AdvancedChestImpl;
import com.craftaro.epichoppers.containers.impl.EpicFarmingImpl;
import com.craftaro.epichoppers.containers.impl.FabledSkyBlockImpl;
import org.bukkit.Bukkit;
import org.bukkit.block.Block;
import org.bukkit.plugin.PluginManager;
@ -12,37 +11,38 @@ import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
public class ContainerManager {
private final EpicHoppers plugin;
public class ContainerManagerImpl implements ContainerManager {
private final Set<IContainer> customContainers;
public ContainerManager(EpicHoppers plugin) {
this.plugin = plugin;
public ContainerManagerImpl() {
this.customContainers = new HashSet<>();
registerCustomContainerImplementation("AdvancedChests", new AdvancedChestImplementation());
registerCustomContainerImplementation("EpicFarming", new EpicFarmingImplementation());
registerCustomContainerImplementation("FabledSkyBlock", new FabledSkyBlockImplementation());
registerCustomContainerImplementation("AdvancedChests", new AdvancedChestImpl());
registerCustomContainerImplementation("EpicFarming", new EpicFarmingImpl());
registerCustomContainerImplementation("FabledSkyBlock", new FabledSkyBlockImpl());
}
@Override
public Set<IContainer> getCustomContainerImplementations() {
return Collections.unmodifiableSet(customContainers);
return Collections.unmodifiableSet(this.customContainers);
}
@Override
public void registerCustomContainerImplementation(String requiredPlugin, IContainer container) {
PluginManager pluginManager = Bukkit.getPluginManager();
if (requiredPlugin != null && pluginManager.isPluginEnabled(requiredPlugin)) {
customContainers.add(container);
this.customContainers.add(container);
}
}
@Override
public void registerCustomContainerImplementation(IContainer container) {
registerCustomContainerImplementation(null, container);
}
@Override
public CustomContainer getCustomContainer(Block block) {
for (IContainer container : customContainers) {
for (IContainer container : this.customContainers) {
CustomContainer customContainer = container.getCustomContainer(block);
if (customContainer.isContainer()) {
return customContainer;

View File

@ -1,46 +1,48 @@
package com.songoda.epichoppers.containers.impl;
package com.craftaro.epichoppers.containers.impl;
import com.songoda.epichoppers.containers.CustomContainer;
import com.songoda.epichoppers.containers.IContainer;
import com.craftaro.epichoppers.containers.CustomContainer;
import com.craftaro.epichoppers.containers.IContainer;
import org.bukkit.block.Block;
import org.bukkit.inventory.ItemStack;
import us.lynuxcraft.deadsilenceiv.advancedchests.AdvancedChestsAPI;
import us.lynuxcraft.deadsilenceiv.advancedchests.chest.AdvancedChest;
public class AdvancedChestImplementation implements IContainer {
public class AdvancedChestImpl implements IContainer {
@Override
public CustomContainer getCustomContainer(Block block) {
return new Container(block);
}
class Container extends CustomContainer {
static class Container extends CustomContainer {
private final AdvancedChest advancedChest;
public Container(Block block) {
super(block);
this.advancedChest = AdvancedChestsAPI.getChestManager().getAdvancedChest(block.getLocation());
}
@Override
public boolean addToContainer(ItemStack itemToMove) {
return AdvancedChestsAPI.addItemToChest(advancedChest, itemToMove);
return AdvancedChestsAPI.addItemToChest(this.advancedChest, itemToMove);
}
@Override
public ItemStack[] getItems() {
return advancedChest.getAllItems().toArray(new ItemStack[0]);
return this.advancedChest.getAllItems().toArray(new ItemStack[0]);
}
@Override
public void removeFromContainer(ItemStack itemToMove, int amountToMove) {
for (ItemStack item : advancedChest.getAllItems()) {
if (item == null) return;
for (ItemStack item : this.advancedChest.getAllItems()) {
if (item == null) {
return;
}
if (itemToMove.getType() == item.getType()) {
item.setAmount(item.getAmount() - amountToMove);
if (item.getAmount() <= 0)
advancedChest.getAllItems().remove(item);
if (item.getAmount() <= 0) {
this.advancedChest.getAllItems().remove(item);
}
return;
}
}
@ -48,7 +50,7 @@ public class AdvancedChestImplementation implements IContainer {
@Override
public boolean isContainer() {
return advancedChest != null;
return this.advancedChest != null;
}
}
}

View File

@ -0,0 +1,51 @@
package com.craftaro.epichoppers.containers.impl;
import com.craftaro.third_party.com.cryptomorin.xseries.XMaterial;
import com.craftaro.epicfarming.EpicFarming;
import com.craftaro.epicfarming.core.compatibility.CompatibleMaterial;
import com.craftaro.epicfarming.farming.Farm;
import com.craftaro.epichoppers.containers.CustomContainer;
import com.craftaro.epichoppers.containers.IContainer;
import org.bukkit.block.Block;
import org.bukkit.inventory.ItemStack;
public class EpicFarmingImpl implements IContainer {
@Override
public CustomContainer getCustomContainer(Block block) {
return new Container(block);
}
static class Container extends CustomContainer {
private final Farm farm;
public Container(Block block) {
this.farm = EpicFarming.getInstance().getFarmManager().getFarm(block);
}
@Override
public boolean addToContainer(ItemStack itemToMove) {
if (!this.farm.willFit(itemToMove)) {
return false;
}
this.farm.addItem(itemToMove);
return true;
}
@Override
public ItemStack[] getItems() {
return this.farm.getItems()
.stream().filter(item -> XMaterial.matchXMaterial(item) != XMaterial.BONE_MEAL)
.toArray(ItemStack[]::new);
}
@Override
public void removeFromContainer(ItemStack itemToMove, int amountToMove) {
this.farm.removeMaterial(itemToMove.getType(), amountToMove);
}
@Override
public boolean isContainer() {
return this.farm != null;
}
}
}

View File

@ -0,0 +1,65 @@
package com.craftaro.epichoppers.containers.impl;
import com.craftaro.epichoppers.containers.CustomContainer;
import com.craftaro.epichoppers.containers.IContainer;
import com.craftaro.skyblock.SkyBlock;
import com.craftaro.skyblock.core.compatibility.CompatibleMaterial;
import com.craftaro.skyblock.stackable.Stackable;
import com.craftaro.skyblock.stackable.StackableManager;
import com.craftaro.third_party.com.cryptomorin.xseries.XMaterial;
import org.bukkit.block.Block;
import org.bukkit.inventory.ItemStack;
public class FabledSkyBlockImpl implements IContainer {
@Override
public CustomContainer getCustomContainer(Block block) {
return new Container(block);
}
static class Container extends CustomContainer {
private final Stackable stackable;
public Container(Block block) {
super();
StackableManager stackableManager = SkyBlock.getInstance().getStackableManager();
XMaterial xMaterial = XMaterial.matchXMaterial(block.getType());
this.stackable = stackableManager.getStack(block.getLocation(), xMaterial);
}
@Override
public boolean addToContainer(ItemStack itemToMove) {
if (XMaterial.matchXMaterial(itemToMove) != this.stackable.getMaterial()) {
return false;
}
this.stackable.addOne();
if (this.stackable.getMaxSize() > 0 && this.stackable.isMaxSize()) {
this.stackable.setSize(this.stackable.getMaxSize());
return false;
}
return true;
}
@Override
public ItemStack[] getItems() {
return new ItemStack[]{new ItemStack(this.stackable.getMaterial().parseMaterial(), this.stackable.getSize())};
}
@Override
public void removeFromContainer(ItemStack itemToMove, int amountToMove) {
if (XMaterial.matchXMaterial(itemToMove) != this.stackable.getMaterial()) {
return;
}
this.stackable.setSize(this.stackable.getSize() - amountToMove);
}
@Override
public boolean isContainer() {
return this.stackable != null;
}
}
}

View File

@ -0,0 +1,378 @@
package com.craftaro.epichoppers.database;
import com.craftaro.core.database.DatabaseConnector;
import com.craftaro.epichoppers.boost.BoostData;
import com.craftaro.epichoppers.boost.BoostDataImpl;
import com.craftaro.epichoppers.EpicHoppers;
import com.craftaro.epichoppers.hopper.Filter;
import com.craftaro.epichoppers.hopper.HopperImpl;
import com.craftaro.epichoppers.hopper.HopperBuilder;
import com.craftaro.epichoppers.hopper.ItemType;
import com.craftaro.epichoppers.hopper.LinkType;
import com.craftaro.epichoppers.hopper.teleport.TeleportTrigger;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin;
import org.bukkit.util.io.BukkitObjectInputStream;
import org.bukkit.util.io.BukkitObjectOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Base64;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.function.Consumer;
public class DataManagerImpl {
// public DataManagerImpl(DatabaseConnector databaseConnector, Plugin plugin) {
// super(databaseConnector, plugin);
// }
//
// @Override
// public void createBoost(BoostDataImpl boostData) {
// this.runAsync(() -> {
// try (Connection connection = this.databaseConnector.getConnection()) {
// String createBoostedPlayer = "INSERT INTO " + this.getTablePrefix() + "boosted_players (player, multiplier, end_time) VALUES (?, ?, ?)";
// PreparedStatement statement = connection.prepareStatement(createBoostedPlayer);
// statement.setString(1, boostData.getPlayer().toString());
// statement.setInt(2, boostData.getMultiplier());
// statement.setLong(3, boostData.getEndTime());
// statement.executeUpdate();
// } catch (Exception ex) {
// ex.printStackTrace();
// }
// });
// }
//
// @Override
// public void getBoosts(Consumer<List<BoostData>> callback) {
// List<BoostDataImpl> boosts = new ArrayList<>();
// this.runAsync(() -> {
// try (Connection connection = this.databaseConnector.getConnection()) {
// Statement statement = connection.createStatement();
// String selectBoostedPlayers = "SELECT * FROM " + this.getTablePrefix() + "boosted_players";
// ResultSet result = statement.executeQuery(selectBoostedPlayers);
// while (result.next()) {
// UUID player = UUID.fromString(result.getString("player"));
// int multiplier = result.getInt("multiplier");
// long endTime = result.getLong("end_time");
// boosts.add(new BoostDataImpl(multiplier, endTime, player));
// }
//
// this.sync(() -> callback.accept(boosts));
// } catch (Exception ex) {
// ex.printStackTrace();
// }
// });
// }
//
// @Override
// public void deleteBoost(BoostDataImpl boostData) {
// this.runAsync(() -> {
// try (Connection connection = this.databaseConnector.getConnection()) {
// String deleteBoost = "DELETE FROM " + this.getTablePrefix() + "boosted_players WHERE end_time = ?";
// PreparedStatement statement = connection.prepareStatement(deleteBoost);
// statement.setLong(1, boostData.getEndTime());
// statement.executeUpdate();
// } catch (Exception ex) {
// ex.printStackTrace();
// }
// });
// }
//
// @Override
// public void deleteLink(HopperImpl hopper, Location location) {
// this.runAsync(() -> {
// try (Connection connection = this.databaseConnector.getConnection()) {
// String deleteLink = "DELETE FROM " + this.getTablePrefix() + "links WHERE hopper_id = ? AND world = ? AND x = ? AND y = ? AND z = ?";
// PreparedStatement statement = connection.prepareStatement(deleteLink);
// statement.setInt(1, hopper.getId());
// statement.setString(2, location.getWorld().getName());
// statement.setInt(3, location.getBlockX());
// statement.setInt(4, location.getBlockY());
// statement.setInt(5, location.getBlockZ());
// statement.executeUpdate();
// } catch (Exception ex) {
// ex.printStackTrace();
// }
// });
// }
//
// @Override
// public void deleteLinks(HopperImpl hopper) {
// this.runAsync(() -> {
// try (Connection connection = this.databaseConnector.getConnection()) {
// String deleteHopperLinks = "DELETE FROM " + this.getTablePrefix() + "links WHERE hopper_id = ?";
// PreparedStatement statement = connection.prepareStatement(deleteHopperLinks);
// statement.setInt(1, hopper.getId());
// statement.executeUpdate();
// } catch (Exception ex) {
// ex.printStackTrace();
// }
// });
// }
//
// @Override
// public void createHoppers(List<HopperImpl> hoppers) {
// for (HopperImpl hopper : hoppers) {
// createHopper(hopper);
// }
// }
//
// @Override
// public void createHopper(HopperImpl hopper) {
// this.runAsync(() -> {
// try (Connection connection = this.databaseConnector.getConnection()) {
// String createHopper = "INSERT INTO " + this.getTablePrefix() + "placed_hoppers (level, placed_by, last_opened_by, teleport_trigger, world, x, y, z) VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
// try (PreparedStatement statement = connection.prepareStatement(createHopper)) {
// statement.setInt(1, hopper.getLevel().getLevel());
//
// statement.setString(2,
// hopper.getPlacedBy() == null ? null : hopper.getPlacedBy().toString());
//
// statement.setString(3,
// hopper.getLastPlayerOpened() == null ? null : hopper.getLastPlayerOpened().toString());
//
// statement.setString(4, hopper.getTeleportTrigger().name());
//
// statement.setString(5, hopper.getWorld().getName());
// statement.setInt(6, hopper.getX());
// statement.setInt(7, hopper.getY());
// statement.setInt(8, hopper.getZ());
// statement.executeUpdate();
// }
//
// int hopperId = this.lastInsertedId(connection, "placed_hoppers");
// hopper.setId(hopperId);
//
// Map<ItemStack, ItemType> items = new HashMap<>();
// Filter filter = hopper.getFilter();
//
// for (ItemStack item : filter.getWhiteList()) {
// items.put(item, ItemType.WHITELIST);
// }
//
// for (ItemStack item : filter.getBlackList()) {
// items.put(item, ItemType.BLACKLIST);
// }
//
// for (ItemStack item : filter.getVoidList()) {
// items.put(item, ItemType.VOID);
// }
//
// for (ItemStack item : filter.getAutoSellWhiteList()) {
// items.put(item, ItemType.AUTO_SELL_WHITELIST);
// }
//
// for (ItemStack item : filter.getAutoSellBlackList()) {
// items.put(item, ItemType.AUTO_SELL_BLACKLIST);
// }
//
// String createItem = "INSERT INTO " + this.getTablePrefix() + "items (hopper_id, item_type, item) VALUES (?, ?, ?)";
// try (PreparedStatement statement = connection.prepareStatement(createItem)) {
// for (Map.Entry<ItemStack, ItemType> entry : items.entrySet()) {
// statement.setInt(1, hopper.getId());
// statement.setString(2, entry.getValue().name());
//
// try (ByteArrayOutputStream stream = new ByteArrayOutputStream(); BukkitObjectOutputStream bukkitStream = new BukkitObjectOutputStream(stream)) {
// bukkitStream.writeObject(entry.getKey());
// statement.setString(3, Base64.getEncoder().encodeToString(stream.toByteArray()));
// } catch (IOException e) {
// e.printStackTrace();
// continue;
// }
// statement.addBatch();
// }
// statement.executeBatch();
// }
//
// Map<Location, LinkType> links = new HashMap<>();
//
// for (Location location : hopper.getLinkedBlocks()) {
// links.put(location, LinkType.REGULAR);
// }
//
// if (filter.getEndPoint() != null) {
// links.put(filter.getEndPoint(), LinkType.REJECT);
// }
//
// String createLink = "INSERT INTO " + this.getTablePrefix() + "links (hopper_id, link_type, world, x, y, z) VALUES (?, ?, ?, ?, ?, ?)";
// try (PreparedStatement statement = connection.prepareStatement(createLink)) {
// for (Map.Entry<Location, LinkType> entry : links.entrySet()) {
// statement.setInt(1, hopper.getId());
//
// statement.setString(2, entry.getValue().name());
//
// Location location = entry.getKey();
// statement.setString(3, location.getWorld().getName());
// statement.setInt(4, location.getBlockX());
// statement.setInt(5, location.getBlockY());
// statement.setInt(6, location.getBlockZ());
// statement.addBatch();
// }
// statement.executeBatch();
// }
// } catch (Exception ex) {
// ex.printStackTrace();
// }
// });
// }
//
// @Override
// public void updateHopper(HopperImpl hopper) {
// this.runAsync(() -> {
// try (Connection connection = this.databaseConnector.getConnection()) {
// String updateHopper = "UPDATE " + this.getTablePrefix() + "placed_hoppers SET level = ?, placed_by = ?, last_opened_by = ?, teleport_trigger = ? WHERE id = ?";
// PreparedStatement statement = connection.prepareStatement(updateHopper);
// statement.setInt(1, hopper.getLevel().getLevel());
// statement.setString(2, hopper.getPlacedBy().toString());
// statement.setString(3, hopper.getLastPlayerOpened().toString());
// statement.setString(4, hopper.getTeleportTrigger().name());
// statement.setInt(5, hopper.getId());
// statement.executeUpdate();
// } catch (Exception ex) {
// ex.printStackTrace();
// }
// });
// }
//
// @Override
// public void deleteHopper(HopperImpl hopper) {
// this.runAsync(() -> {
// try (Connection connection = this.databaseConnector.getConnection()) {
// String deleteHopper = "DELETE FROM " + this.getTablePrefix() + "placed_hoppers WHERE id = ?";
// try (PreparedStatement statement = connection.prepareStatement(deleteHopper)) {
// statement.setInt(1, hopper.getId());
// statement.executeUpdate();
// }
//
// String deleteHopperLinks = "DELETE FROM " + this.getTablePrefix() + "links WHERE hopper_id = ?";
// try (PreparedStatement statement = connection.prepareStatement(deleteHopperLinks)) {
// statement.setInt(1, hopper.getId());
// statement.executeUpdate();
// }
//
// String deleteItems = "DELETE FROM " + this.getTablePrefix() + "items WHERE hopper_id = ?";
// try (PreparedStatement statement = connection.prepareStatement(deleteItems)) {
// statement.setInt(1, hopper.getId());
// statement.executeUpdate();
// }
// } catch (Exception ex) {
// ex.printStackTrace();
// }
// });
// }
//
// @Override
// public void getHoppers(Consumer<Map<Integer, HopperImpl>> callback) {
// this.runAsync(() -> {
// try (Connection connection = this.databaseConnector.getConnection()) {
// Map<Integer, HopperImpl> hoppers = new HashMap<>();
//
// try (Statement statement = connection.createStatement()) {
// String selectHoppers = "SELECT * FROM " + this.getTablePrefix() + "placed_hoppers";
// ResultSet result = statement.executeQuery(selectHoppers);
// while (result.next()) {
// World world = Bukkit.getWorld(result.getString("world"));
//
// if (world == null) {
// continue;
// }
//
// int id = result.getInt("id");
// int level = result.getInt("level");
//
// String placedByStr = result.getString("placed_by");
// UUID placedBy = placedByStr == null ? null : UUID.fromString(result.getString("placed_by"));
//
// String lastOpenedByStr = result.getString("last_opened_by");
// UUID lastOpenedBy = lastOpenedByStr == null ? null : UUID.fromString(result.getString("last_opened_by"));
//
// TeleportTrigger teleportTrigger = TeleportTrigger.valueOf(result.getString("teleport_trigger"));
//
// int x = result.getInt("x");
// int y = result.getInt("y");
// int z = result.getInt("z");
// Location location = new Location(world, x, y, z);
//
// HopperImpl hopper = new HopperBuilder(location)
// .setId(id)
// .setLevel(((EpicHoppers) this.plugin).getLevelManager().getLevel(level))
// .setPlacedBy(placedBy)
// .setLastPlayerOpened(lastOpenedBy)
// .setTeleportTrigger(teleportTrigger)
// .build();
//
// hoppers.put(id, hopper);
// }
// }
//
// try (Statement statement = connection.createStatement()) {
// String selectLinks = "SELECT * FROM " + this.getTablePrefix() + "links";
// ResultSet result = statement.executeQuery(selectLinks);
// while (result.next()) {
// World world = Bukkit.getWorld(result.getString("world"));
//
// if (world == null) {
// continue;
// }
//
// int id = result.getInt("hopper_id");
// LinkType type = LinkType.valueOf(result.getString("link_type"));
//
// int x = result.getInt("x");
// int y = result.getInt("y");
// int z = result.getInt("z");
// Location location = new Location(world, x, y, z);
//
// HopperImpl hopper = hoppers.get(id);
// if (hopper == null) {
// break;
// }
//
// hopper.addLinkedBlock(location, type);
// }
// }
//
// try (Statement statement = connection.createStatement()) {
// String selectItems = "SELECT * FROM " + this.getTablePrefix() + "items";
// ResultSet result = statement.executeQuery(selectItems);
// while (result.next()) {
// int id = result.getInt("hopper_id");
// ItemType type = ItemType.valueOf(result.getString("item_type"));
//
// ItemStack item = null;
// try (BukkitObjectInputStream stream = new BukkitObjectInputStream(
// new ByteArrayInputStream(Base64.getDecoder().decode(result.getString("item"))))) {
// item = (ItemStack) stream.readObject();
// } catch (IOException | ClassNotFoundException e) {
// e.printStackTrace();
// }
//
// HopperImpl hopper = hoppers.get(id);
// if (hopper == null) {
// break;
// }
//
// if (item != null) {
// hopper.getFilter().addItem(item, type);
// }
// }
// }
// this.sync(() -> callback.accept(hoppers));
// } catch (Exception ex) {
// ex.printStackTrace();
// }
// });
// }
}

View File

@ -1,27 +1,27 @@
package com.songoda.epichoppers.database.migrations;
package com.craftaro.epichoppers.database.migrations;
import com.songoda.core.database.DataMigration;
import com.songoda.core.database.MySQLConnector;
import com.songoda.epichoppers.EpicHoppers;
import com.craftaro.core.database.DataMigration;
import com.craftaro.core.database.DatabaseConnector;
import com.craftaro.core.database.MySQLConnector;
import com.craftaro.epichoppers.EpicHoppers;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
public class _1_InitialMigration extends DataMigration {
private final EpicHoppers plugin;
public _1_InitialMigration() {
public _1_InitialMigration(EpicHoppers plugin) {
super(1);
this.plugin = plugin;
}
@Override
public void migrate(Connection connection, String tablePrefix) throws SQLException {
String autoIncrement = EpicHoppers.getInstance().getDatabaseConnector() instanceof MySQLConnector ? " AUTO_INCREMENT" : "";
// Create hoppers table
public void migrate(Connection connection, String tablePrefix) throws SQLException {// Create hoppers table
try (Statement statement = connection.createStatement()) {
statement.execute("CREATE TABLE " + tablePrefix + "placed_hoppers (" +
"id INTEGER PRIMARY KEY" + autoIncrement + ", " +
statement.execute("CREATE TABLE IF NOT EXISTS " + tablePrefix + "placed_hoppers (" +
"id INTEGER PRIMARY KEY AUTO_INCREMENT" + ", " +
"level INTEGER NOT NULL, " +
"placed_by VARCHAR(36), " +
"last_opened_by VARCHAR(36), " +
@ -35,7 +35,7 @@ public class _1_InitialMigration extends DataMigration {
// Create hopper links
try (Statement statement = connection.createStatement()) {
statement.execute("CREATE TABLE " + tablePrefix + "links (" +
statement.execute("CREATE TABLE IF NOT EXISTS " + tablePrefix + "links (" +
"hopper_id INTEGER NOT NULL, " +
"link_type TEXT NOT NULL," +
"world TEXT NOT NULL, " +
@ -48,16 +48,16 @@ public class _1_InitialMigration extends DataMigration {
// Create items
// Items are base64.
try (Statement statement = connection.createStatement()) {
statement.execute("CREATE TABLE " + tablePrefix + "items (" +
statement.execute("CREATE TABLE IF NOT EXISTS " + tablePrefix + "items (" +
"hopper_id INTEGER NOT NULL, " +
"item_type BIT NOT NULL," +
"item_type VARCHAR(20) NOT NULL," +
"item TEXT NOT NULL " +
")");
}
// Create player boosts
try (Statement statement = connection.createStatement()) {
statement.execute("CREATE TABLE " + tablePrefix + "boosted_players (" +
statement.execute("CREATE TABLE IF NOT EXISTS " + tablePrefix + "boosted_players (" +
"player VARCHAR(36) NOT NULL, " +
"multiplier INTEGER NOT NULL," +
"end_time BIGINT NOT NULL " +

View File

@ -1,15 +1,17 @@
package com.songoda.epichoppers.gui;
package com.craftaro.epichoppers.gui;
import com.songoda.core.compatibility.CompatibleMaterial;
import com.songoda.core.gui.CustomizableGui;
import com.songoda.core.gui.GuiUtils;
import com.songoda.core.utils.TextUtils;
import com.songoda.epichoppers.EpicHoppers;
import com.songoda.epichoppers.hopper.Filter;
import com.songoda.epichoppers.hopper.Hopper;
import com.songoda.epichoppers.hopper.ItemType;
import com.songoda.epichoppers.settings.Settings;
import com.songoda.epichoppers.utils.Methods;
import com.craftaro.core.SongodaPlugin;
import com.craftaro.core.gui.CustomizableGui;
import com.craftaro.core.gui.GuiUtils;
import com.craftaro.third_party.com.cryptomorin.xseries.XMaterial;
import com.craftaro.core.utils.TextUtils;
import com.craftaro.epichoppers.hopper.Filter;
import com.craftaro.epichoppers.hopper.Hopper;
import com.craftaro.epichoppers.hopper.HopperImpl;
import com.craftaro.epichoppers.hopper.ItemType;
import com.craftaro.epichoppers.settings.Settings;
import com.craftaro.epichoppers.utils.DataHelper;
import com.craftaro.epichoppers.utils.Methods;
import org.bukkit.Bukkit;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
@ -18,28 +20,26 @@ import java.util.ArrayList;
import java.util.List;
public class GUIAutoSellFilter extends CustomizableGui {
private static final List<GUIAutoSellFilter> openInventories = new ArrayList<>();
private static final List<GUIAutoSellFilter> OPEN_INVENTORIES = new ArrayList<>();
private final EpicHoppers plugin;
private final Hopper hopper;
private final HopperImpl hopper;
private final int[] whiteListSlots = {9, 10, 11, 18, 19, 20, 27, 28, 29, 36, 37, 38};
private final int[] blackListSlots = {12, 13, 14, 21, 22, 23, 30, 31, 32, 39, 40, 41};
public GUIAutoSellFilter(EpicHoppers plugin, Hopper hopper) {
public GUIAutoSellFilter(SongodaPlugin plugin, Hopper hopper) {
super(plugin, "autosell");
this.plugin = plugin;
this.hopper = hopper;
this.hopper = (HopperImpl) hopper;
setRows(6);
setTitle(TextUtils.formatText(Methods.formatName(hopper.getLevel().getLevel()) + " &8-&f AutoSell Filter"));
setDefaultItem(null);
setAcceptsItems(true);
setOnOpen((event) -> GUIAutoSellFilter.openInventories.add(this));
setOnOpen((event) -> GUIAutoSellFilter.OPEN_INVENTORIES.add(this));
setOnClose((event) -> {
GUIAutoSellFilter.openInventories.remove(this);
GUIAutoSellFilter.OPEN_INVENTORIES.remove(this);
hopper.setActivePlayer(null);
compile();
});
@ -60,15 +60,17 @@ public class GUIAutoSellFilter extends CustomizableGui {
mirrorFill("mirrorfill_8", 2, 8, true, false, glass2);
mirrorFill("mirrorfill_9", 4, 7, false, false, glass1);
setButton("back", 8, GuiUtils.createButtonItem(CompatibleMaterial.ARROW.getItem(),
setButton("back", 8, GuiUtils.createButtonItem(XMaterial.ARROW.parseItem(),
plugin.getLocale().getMessage("general.nametag.back").getMessage()),
(event) -> {
hopper.overview(guiManager, event.player);
if (this.hopper.prepareForOpeningOverviewGui(event.player)) {
this.guiManager.showGUI(event.player, new GUIOverview(plugin, hopper, event.player));
}
compile();
});
// Whitelist
ItemStack indicatorItem = CompatibleMaterial.WHITE_STAINED_GLASS_PANE.getItem();
ItemStack indicatorItem = XMaterial.WHITE_STAINED_GLASS_PANE.parseItem();
ItemMeta indicatorMeta = indicatorItem.getItemMeta();
indicatorMeta.setDisplayName(plugin.getLocale().getMessage("interface.autosell-filter.whitelist").getMessage());
indicatorItem.setItemMeta(indicatorMeta);
@ -80,13 +82,15 @@ public class GUIAutoSellFilter extends CustomizableGui {
int num = 0;
for (ItemStack m : filter.getAutoSellWhiteList()) {
if (num >= filter.getAutoSellWhiteList().size()) break;
setItem(whiteListSlots[num], new ItemStack(m));
if (num >= filter.getAutoSellWhiteList().size()) {
break;
}
setItem(this.whiteListSlots[num], new ItemStack(m));
num++;
}
// Blacklist
indicatorItem = CompatibleMaterial.BLACK_STAINED_GLASS_PANE.getItem();
indicatorItem = XMaterial.BLACK_STAINED_GLASS_PANE.parseItem();
indicatorMeta = indicatorItem.getItemMeta();
indicatorMeta.setDisplayName(plugin.getLocale().getMessage("interface.autosell-filter.blacklist").getMessage());
indicatorItem.setItemMeta(indicatorMeta);
@ -98,18 +102,24 @@ public class GUIAutoSellFilter extends CustomizableGui {
num = 0;
for (ItemStack m : filter.getAutoSellBlackList()) {
if (num >= filter.getAutoSellBlackList().size()) break;
setItem(blackListSlots[num], new ItemStack(m));
if (num >= filter.getAutoSellBlackList().size()) {
break;
}
setItem(this.blackListSlots[num], new ItemStack(m));
num++;
}
// Info item
indicatorItem = new ItemStack(CompatibleMaterial.PAPER.getMaterial());
indicatorItem = XMaterial.PAPER.parseItem();
indicatorMeta = indicatorItem.getItemMeta();
indicatorMeta.setDisplayName(plugin.getLocale().getMessage("interface.autosell-filter.infotitle").getMessage());
ArrayList<String> loreInfo = new ArrayList<>();
String[] parts = plugin.getLocale().getMessage("interface.autosell-filter.infolore").getMessage().split("\\|");
String[] parts = plugin
.getLocale()
.getMessage("interface.autosell-filter.infolore")
.getMessage()
.split("\\|");
for (String line : parts) {
loreInfo.add(TextUtils.formatText(line));
@ -127,22 +137,24 @@ public class GUIAutoSellFilter extends CustomizableGui {
}
private void compile() {
ItemStack[] items = inventory.getContents();
ItemStack[] items = this.inventory.getContents();
Filter filter = hopper.getFilter();
Filter filter = this.hopper.getFilter();
List<ItemStack> whiteListItems = new ArrayList<>();
List<ItemStack> blackListItems = new ArrayList<>();
for (int i = 0; i < items.length; i++) {
for (int slot : whiteListSlots) {
if (slot != i) continue;
for (int slot : this.whiteListSlots) {
if (slot != i) {
continue;
}
if (items[i] != null && !items[i].getType().isAir()) {
ItemStack item = items[i];
if (item.getAmount() != 1) {
item.setAmount(item.getAmount() - 1);
Bukkit.getPlayer(hopper.getLastPlayerOpened()).getInventory().addItem(item);
Bukkit.getPlayer(this.hopper.getLastPlayerOpened()).getInventory().addItem(item);
item.setAmount(1);
}
@ -150,14 +162,16 @@ public class GUIAutoSellFilter extends CustomizableGui {
}
}
for (int slot : blackListSlots) {
if (slot != i) continue;
for (int slot : this.blackListSlots) {
if (slot != i) {
continue;
}
if (items[i] != null && !items[i].getType().isAir()) {
ItemStack item = items[i];
if (item.getAmount() != 1) {
item.setAmount(item.getAmount() - 1);
Bukkit.getPlayer(hopper.getLastPlayerOpened()).getInventory().addItem(item);
Bukkit.getPlayer(this.hopper.getLastPlayerOpened()).getInventory().addItem(item);
item.setAmount(1);
}
blackListItems.add(item);
@ -167,12 +181,12 @@ public class GUIAutoSellFilter extends CustomizableGui {
filter.setAutoSellWhiteList(whiteListItems);
filter.setAutoSellBlackList(blackListItems);
plugin.getDataManager().updateItems(hopper, ItemType.AUTO_SELL_WHITELIST, whiteListItems);
plugin.getDataManager().updateItems(hopper, ItemType.AUTO_SELL_BLACKLIST, blackListItems);
DataHelper.updateItems(this.hopper, ItemType.AUTO_SELL_WHITELIST, whiteListItems);
DataHelper.updateItems(this.hopper, ItemType.AUTO_SELL_BLACKLIST, blackListItems);
}
public static void compileOpenAutoSellFilter(Hopper hopper) {
for (GUIAutoSellFilter autoSellFilter : openInventories) {
public static void compileOpenAutoSellFilter(HopperImpl hopper) {
for (GUIAutoSellFilter autoSellFilter : OPEN_INVENTORIES) {
if (autoSellFilter.hopper == hopper) {
autoSellFilter.compile();
}

View File

@ -1,21 +1,21 @@
package com.songoda.epichoppers.gui;
package com.craftaro.epichoppers.gui;
import com.songoda.core.compatibility.CompatibleMaterial;
import com.songoda.core.gui.CustomizableGui;
import com.songoda.core.gui.GuiUtils;
import com.songoda.core.utils.TextUtils;
import com.songoda.epichoppers.EpicHoppers;
import com.songoda.epichoppers.hopper.Hopper;
import com.songoda.epichoppers.hopper.levels.modules.ModuleAutoCrafting;
import com.songoda.epichoppers.settings.Settings;
import com.songoda.epichoppers.utils.Methods;
import com.craftaro.core.SongodaPlugin;
import com.craftaro.core.gui.CustomizableGui;
import com.craftaro.core.gui.GuiUtils;
import com.craftaro.third_party.com.cryptomorin.xseries.XMaterial;
import com.craftaro.core.utils.TextUtils;
import com.craftaro.epichoppers.hopper.Hopper;
import com.craftaro.epichoppers.hopper.HopperImpl;
import com.craftaro.epichoppers.hopper.levels.modules.ModuleAutoCrafting;
import com.craftaro.epichoppers.settings.Settings;
import com.craftaro.epichoppers.utils.Methods;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
public class GUICrafting extends CustomizableGui {
public GUICrafting(ModuleAutoCrafting module, Hopper hopper, Player player) {
super(EpicHoppers.getInstance(), "crafting");
public GUICrafting(ModuleAutoCrafting module, SongodaPlugin plugin, Hopper hopper, Player player) {
super(plugin, "crafting");
setRows(3);
setTitle(Methods.formatName(hopper.getLevel().getLevel()) + TextUtils.formatText(" &8-&f Crafting"));
setOnClose((event) -> {
@ -36,21 +36,23 @@ public class GUICrafting extends CustomizableGui {
mirrorFill("mirrorfill_4", 1, 0, false, true, glass2);
mirrorFill("mirrorfill_5", 1, 1, false, true, glass3);
setButton("back", 8, GuiUtils.createButtonItem(CompatibleMaterial.ARROW.getItem(),
EpicHoppers.getInstance().getLocale().getMessage("general.nametag.back").getMessage()),
setButton("back", 8, GuiUtils.createButtonItem(XMaterial.ARROW.parseItem(),
plugin.getLocale().getMessage("general.nametag.back").getMessage()),
(event) -> {
hopper.overview(guiManager, event.player);
if (((HopperImpl)hopper).prepareForOpeningOverviewGui(event.player)) {
this.guiManager.showGUI(event.player, new GUIOverview(plugin, hopper, event.player));
}
setItem(module, hopper, player);
}
);
setButton(13, module.getAutoCrafting(hopper),
(event) -> module.setAutoCrafting(hopper, player, inventory.getItem(13)));
(event) -> module.setAutoCrafting(hopper, player, this.inventory.getItem(13)));
setUnlocked(13);
}
public void setItem(ModuleAutoCrafting module, Hopper hopper, Player player) {
module.setAutoCrafting(hopper, player, inventory.getItem(13));
module.setAutoCrafting(hopper, player, this.inventory.getItem(13));
}
}

View File

@ -1,16 +1,19 @@
package com.songoda.epichoppers.gui;
package com.craftaro.epichoppers.gui;
import com.songoda.core.compatibility.CompatibleMaterial;
import com.songoda.core.gui.CustomizableGui;
import com.songoda.core.gui.GuiUtils;
import com.songoda.core.utils.TextUtils;
import com.songoda.epichoppers.EpicHoppers;
import com.songoda.epichoppers.hopper.Filter;
import com.songoda.epichoppers.hopper.Hopper;
import com.songoda.epichoppers.hopper.ItemType;
import com.songoda.epichoppers.player.SyncType;
import com.songoda.epichoppers.settings.Settings;
import com.songoda.epichoppers.utils.Methods;
import com.craftaro.core.SongodaPlugin;
import com.craftaro.core.gui.CustomizableGui;
import com.craftaro.core.gui.GuiUtils;
import com.craftaro.third_party.com.cryptomorin.xseries.XMaterial;
import com.craftaro.core.utils.TextUtils;
import com.craftaro.epichoppers.EpicHoppersApi;
import com.craftaro.epichoppers.hopper.Hopper;
import com.craftaro.epichoppers.hopper.ItemType;
import com.craftaro.epichoppers.player.SyncType;
import com.craftaro.epichoppers.settings.Settings;
import com.craftaro.epichoppers.utils.DataHelper;
import com.craftaro.epichoppers.utils.Methods;
import com.craftaro.epichoppers.hopper.Filter;
import com.craftaro.epichoppers.hopper.HopperImpl;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
@ -22,26 +25,25 @@ import java.util.ArrayList;
import java.util.List;
public class GUIFilter extends CustomizableGui {
private static final List<GUIFilter> openInventories = new ArrayList<>();
private static final List<GUIFilter> OPEN_INVENTORIES = new ArrayList<>();
private final EpicHoppers plugin;
private final SongodaPlugin plugin;
private final HopperImpl hopper;
private final Hopper hopper;
public GUIFilter(EpicHoppers plugin, Hopper hopper, Player player) {
public GUIFilter(SongodaPlugin plugin, Hopper hopper, Player player) {
super(plugin, "filter");
this.plugin = plugin;
this.hopper = hopper;
this.hopper = (HopperImpl) hopper;
setRows(6);
setTitle(TextUtils.formatText(Methods.formatName(hopper.getLevel().getLevel()) + " &8-&f Filter"));
setDefaultItem(null);
setAcceptsItems(true);
setOnOpen((event) -> GUIFilter.openInventories.add(this));
setOnOpen((event) -> GUIFilter.OPEN_INVENTORIES.add(this));
setOnClose((event) -> {
GUIFilter.openInventories.remove(this);
GUIFilter.OPEN_INVENTORIES.remove(this);
hopper.setActivePlayer(null);
compile();
});
@ -60,15 +62,17 @@ public class GUIFilter extends CustomizableGui {
mirrorFill("mirrorfill_7", 2, 7, true, false, glass1);
mirrorFill("mirrorfill_8", 2, 8, true, false, glass2);
ItemStack it = CompatibleMaterial.WHITE_STAINED_GLASS_PANE.getItem();
ItemStack it = XMaterial.WHITE_STAINED_GLASS_PANE.parseItem();
ItemMeta itm = it.getItemMeta();
itm.setDisplayName(plugin.getLocale().getMessage("interface.filter.whitelist").getMessage());
it.setItemMeta(itm);
setButton("back", 8, GuiUtils.createButtonItem(CompatibleMaterial.ARROW.getItem(),
plugin.getLocale().getMessage("general.nametag.back").getMessage()),
setButton("back", 8, GuiUtils.createButtonItem(XMaterial.ARROW.parseItem(),
plugin.getLocale().getMessage("general.nametag.back").getMessage()),
(event) -> {
hopper.overview(guiManager, event.player);
if (this.hopper.prepareForOpeningOverviewGui(event.player)) {
this.guiManager.showGUI(event.player, new GUIOverview(plugin, hopper, event.player));
}
compile();
});
@ -80,12 +84,14 @@ public class GUIFilter extends CustomizableGui {
int[] awhite = {9, 10, 18, 19, 27, 28, 36, 37};
int num = 0;
for (ItemStack m : filter.getWhiteList()) {
if (num >= filter.getWhiteList().size()) break;
if (num >= filter.getWhiteList().size()) {
break;
}
setItem(awhite[num], new ItemStack(m));
num++;
}
it = CompatibleMaterial.BLACK_STAINED_GLASS_PANE.getItem();
it = XMaterial.BLACK_STAINED_GLASS_PANE.parseItem();
itm = it.getItemMeta();
itm.setDisplayName(plugin.getLocale().getMessage("interface.filter.blacklist").getMessage());
it.setItemMeta(itm);
@ -98,12 +104,15 @@ public class GUIFilter extends CustomizableGui {
int[] ablack = {11, 12, 20, 21, 29, 30, 38, 39};
num = 0;
for (ItemStack m : filter.getBlackList()) {
if (num >= filter.getBlackList().size()) break;
if (num >= filter.getBlackList().size()) {
break;
}
setItem(ablack[num], new ItemStack(m));
num++;
}
it = new ItemStack(CompatibleMaterial.BARRIER.getMaterial());
it = XMaterial.BARRIER.parseItem();
itm = it.getItemMeta();
itm.setDisplayName(plugin.getLocale().getMessage("interface.filter.void").getMessage());
it.setItemMeta(itm);
@ -116,44 +125,46 @@ public class GUIFilter extends CustomizableGui {
int[] voidSlots = {13, 14, 22, 23, 31, 32, 40, 41};
num = 0;
for (ItemStack m : filter.getVoidList()) {
if (num >= filter.getVoidList().size()) break;
if (num >= filter.getVoidList().size()) {
break;
}
setItem(voidSlots[num], new ItemStack(m));
num++;
}
ItemStack itemInfo = new ItemStack(CompatibleMaterial.PAPER.getMaterial());
ItemMeta itemmetaInfo = itemInfo.getItemMeta();
itemmetaInfo.setDisplayName(plugin.getLocale().getMessage("interface.filter.infotitle").getMessage());
ItemStack itemInfo = XMaterial.PAPER.parseItem();
ItemMeta itemMetaInfo = itemInfo.getItemMeta();
itemMetaInfo.setDisplayName(plugin.getLocale().getMessage("interface.filter.infotitle").getMessage());
ArrayList<String> loreInfo = new ArrayList<>();
String[] parts = plugin.getLocale().getMessage("interface.filter.infolore").getMessage().split("\\|");
for (String line : parts) {
loreInfo.add(TextUtils.formatText(line));
}
itemmetaInfo.setLore(loreInfo);
itemInfo.setItemMeta(itemmetaInfo);
itemMetaInfo.setLore(loreInfo);
itemInfo.setItemMeta(itemMetaInfo);
setItem("info", 16, itemInfo);
ItemStack hook = new ItemStack(CompatibleMaterial.TRIPWIRE_HOOK.getMaterial());
ItemMeta hookmeta = hook.getItemMeta();
hookmeta.setDisplayName(plugin.getLocale().getMessage("interface.hopper.rejectsync").getMessage());
ArrayList<String> lorehook = new ArrayList<>();
ItemStack hook = XMaterial.TRIPWIRE_HOOK.parseItem();
ItemMeta hookMeta = hook.getItemMeta();
hookMeta.setDisplayName(plugin.getLocale().getMessage("interface.hopper.rejectsync").getMessage());
ArrayList<String> loreHook = new ArrayList<>();
parts = plugin.getLocale().getMessage("interface.hopper.synclore")
.processPlaceholder("amount", filter.getEndPoint() != null ? 1 : 0)
.getMessage().split("\\|");
for (String line : parts) {
lorehook.add(TextUtils.formatText(line));
loreHook.add(TextUtils.formatText(line));
}
hookmeta.setLore(lorehook);
hook.setItemMeta(hookmeta);
hookMeta.setLore(loreHook);
hook.setItemMeta(hookMeta);
setButton("reject", 43, hook,
(event) -> {
if (event.clickType == ClickType.RIGHT) {
plugin.getLocale().getMessage("event.hopper.desync").sendPrefixedMessage(player);
hopper.getFilter().setEndPoint(null);
} else {
plugin.getPlayerDataManager().getPlayerData(player).setSyncType(SyncType.FILTERED);
EpicHoppersApi.getApi().getPlayerDataManager().getPlayerData(player).setSyncType(SyncType.FILTERED);
plugin.getLocale().getMessage("event.hopper.syncnext").sendPrefixedMessage(player);
hopper.timeout(player);
}
@ -167,9 +178,9 @@ public class GUIFilter extends CustomizableGui {
}
private void compile() {
ItemStack[] items = inventory.getContents();
ItemStack[] items = this.inventory.getContents();
Filter filter = hopper.getFilter();
Filter filter = this.hopper.getFilter();
List<ItemStack> owhite = new ArrayList<>();
List<ItemStack> oblack = new ArrayList<>();
@ -181,36 +192,42 @@ public class GUIFilter extends CustomizableGui {
for (int i = 0; i < items.length; i++) {
for (int aa : awhite) {
if (aa != i) continue;
if (aa != i) {
continue;
}
if (items[i] != null && items[i].getType() != Material.AIR) {
ItemStack item = items[i];
if (item.getAmount() != 1) {
item.setAmount(item.getAmount() - 1);
Bukkit.getPlayer(hopper.getLastPlayerOpened()).getInventory().addItem(item);
Bukkit.getPlayer(this.hopper.getLastPlayerOpened()).getInventory().addItem(item);
item.setAmount(1);
}
owhite.add(item);
}
}
for (int aa : ablack) {
if (aa != i) continue;
if (aa != i) {
continue;
}
if (items[i] != null && items[i].getType() != Material.AIR) {
ItemStack item = items[i];
if (item.getAmount() != 1) {
item.setAmount(item.getAmount() - 1);
Bukkit.getPlayer(hopper.getLastPlayerOpened()).getInventory().addItem(item);
Bukkit.getPlayer(this.hopper.getLastPlayerOpened()).getInventory().addItem(item);
item.setAmount(1);
}
oblack.add(item);
}
}
for (int aa : avoid) {
if (aa != i) continue;
if (aa != i) {
continue;
}
if (items[i] != null && items[i].getType() != Material.AIR) {
ItemStack item = items[i];
if (item.getAmount() != 1) {
item.setAmount(item.getAmount() - 1);
Bukkit.getPlayer(hopper.getLastPlayerOpened()).getInventory().addItem(item);
Bukkit.getPlayer(this.hopper.getLastPlayerOpened()).getInventory().addItem(item);
item.setAmount(1);
}
ovoid.add(item);
@ -220,13 +237,13 @@ public class GUIFilter extends CustomizableGui {
filter.setWhiteList(owhite);
filter.setBlackList(oblack);
filter.setVoidList(ovoid);
plugin.getDataManager().updateItems(hopper, ItemType.WHITELIST, owhite);
plugin.getDataManager().updateItems(hopper, ItemType.BLACKLIST, oblack);
plugin.getDataManager().updateItems(hopper, ItemType.VOID, ovoid);
DataHelper.updateItems(this.hopper, ItemType.WHITELIST, owhite);
DataHelper.updateItems(this.hopper, ItemType.BLACKLIST, oblack);
DataHelper.updateItems(this.hopper, ItemType.VOID, ovoid);
}
public static void compileOpenGuiFilter(Hopper hopper) {
for (GUIFilter guiFilter : openInventories) {
public static void compileOpenGuiFilter(HopperImpl hopper) {
for (GUIFilter guiFilter : OPEN_INVENTORIES) {
if (guiFilter.hopper == hopper) {
guiFilter.compile();
}

View File

@ -0,0 +1,302 @@
package com.craftaro.epichoppers.gui;
import com.craftaro.core.SongodaPlugin;
import com.craftaro.core.compatibility.ServerVersion;
import com.craftaro.core.gui.CustomizableGui;
import com.craftaro.core.gui.GuiUtils;
import com.craftaro.third_party.com.cryptomorin.xseries.XMaterial;
import com.craftaro.core.utils.NumberUtils;
import com.craftaro.core.utils.TextUtils;
import com.craftaro.core.utils.TimeUtils;
import com.craftaro.epichoppers.EpicHoppers;
import com.craftaro.epichoppers.EpicHoppersApi;
import com.craftaro.epichoppers.boost.BoostData;
import com.craftaro.epichoppers.boost.BoostDataImpl;
import com.craftaro.epichoppers.hopper.Hopper;
import com.craftaro.epichoppers.hopper.HopperImpl;
import com.craftaro.epichoppers.hopper.levels.Level;
import com.craftaro.epichoppers.hopper.levels.modules.Module;
import com.craftaro.epichoppers.hopper.teleport.TeleportTrigger;
import com.craftaro.epichoppers.player.SyncType;
import com.craftaro.epichoppers.settings.Settings;
import com.craftaro.epichoppers.utils.CostType;
import com.craftaro.epichoppers.utils.DataHelper;
import com.craftaro.epichoppers.utils.Methods;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class GUIOverview extends CustomizableGui {
private final SongodaPlugin plugin;
private final HopperImpl hopper;
private final Player player;
private int task;
public GUIOverview(SongodaPlugin plugin, Hopper hopper, Player player) {
super(plugin, "overview");
this.plugin = plugin;
this.hopper = (HopperImpl) hopper;
this.player = player;
setRows(3);
setTitle(Methods.formatName(hopper.getLevel().getLevel()));
runTask();
constructGUI();
this.setOnClose(action -> {
hopper.setActivePlayer(null);
Bukkit.getScheduler().cancelTask(this.task);
});
}
private void constructGUI() {
ItemStack glass1 = GuiUtils.getBorderItem(Settings.GLASS_TYPE_1.getMaterial());
ItemStack glass2 = GuiUtils.getBorderItem(Settings.GLASS_TYPE_2.getMaterial());
ItemStack glass3 = GuiUtils.getBorderItem(Settings.GLASS_TYPE_3.getMaterial());
setDefaultItem(glass1);
mirrorFill("mirrorfill_1", 0, 0, true, true, glass2);
mirrorFill("mirrorfill_2", 0, 1, true, true, glass2);
mirrorFill("mirrorfill_3", 0, 2, true, true, glass3);
mirrorFill("mirrorfill_4", 1, 0, false, true, glass2);
mirrorFill("mirrorfill_5", 1, 1, false, true, glass3);
EpicHoppersApi.getApi().getPlayerDataManager().getPlayerData(this.player).setLastHopper(this.hopper);
Level level = this.hopper.getLevel();
Level nextLevel = EpicHoppersApi.getApi().getLevelManager().getHighestLevel().getLevel() > level.getLevel() ? EpicHoppersApi.getApi().getLevelManager().getLevel(level.getLevel() + 1) : null;
ItemStack pearl = new ItemStack(Material.ENDER_PEARL, 1);
ItemMeta pearlMeta = pearl.getItemMeta();
pearlMeta.setDisplayName(this.plugin.getLocale().getMessage("interface.hopper.perltitle").getMessage());
ArrayList<String> lorePearl = new ArrayList<>();
String[] parts = this.plugin.getLocale().getMessage("interface.hopper.perllore2")
.processPlaceholder(
"type",
this.hopper.getTeleportTrigger() == TeleportTrigger.DISABLED
? this.plugin.getLocale().getMessage("general.word.disabled").getMessage()
: this.hopper.getTeleportTrigger().name()
)
.getMessage()
.split("\\|");
for (String line : parts) {
lorePearl.add(TextUtils.formatText(line));
}
pearlMeta.setLore(lorePearl);
pearl.setItemMeta(pearlMeta);
ItemStack filter = new ItemStack(ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13) ? Material.COMPARATOR : Material.valueOf("REDSTONE_COMPARATOR"), 1);
ItemMeta filterMeta = filter.getItemMeta();
filterMeta.setDisplayName(this.plugin.getLocale().getMessage("interface.hopper.filtertitle").getMessage());
ArrayList<String> loreFilter = new ArrayList<>();
parts = this.plugin.getLocale().getMessage("interface.hopper.filterlore").getMessage().split("\\|");
for (String line : parts) {
loreFilter.add(TextUtils.formatText(line));
}
filterMeta.setLore(loreFilter);
filter.setItemMeta(filterMeta);
ItemStack item = new ItemStack(Material.HOPPER, 1);
ItemMeta itemmeta = item.getItemMeta();
itemmeta.setDisplayName(this.plugin.getLocale().getMessage("interface.hopper.currentlevel").processPlaceholder("level", level.getLevel()).getMessage());
List<String> lore = level.getDescription();
if (this.plugin.getConfig().getBoolean("Main.Allow hopper Upgrading")) {
lore.add("");
if (nextLevel == null) {
lore.add(this.plugin.getLocale().getMessage("interface.hopper.alreadymaxed").getMessage());
} else {
lore.add(this.plugin.getLocale().getMessage("interface.hopper.nextlevel").processPlaceholder("level", nextLevel.getLevel()).getMessage());
lore.addAll(nextLevel.getDescription());
}
}
BoostData boostData = EpicHoppersApi.getApi().getBoostManager().getBoost(this.hopper.getPlacedBy());
if (boostData != null) {
parts = this.plugin.getLocale().getMessage("interface.hopper.boostedstats")
.processPlaceholder("amount", Integer.toString(boostData.getMultiplier()))
.processPlaceholder("time", TimeUtils.makeReadable(boostData.getEndTime() - System.currentTimeMillis()))
.getMessage().split("\\|");
lore.add("");
for (String line : parts) {
lore.add(TextUtils.formatText(line));
}
}
itemmeta.setLore(lore);
item.setItemMeta(itemmeta);
ItemStack hook = new ItemStack(Material.TRIPWIRE_HOOK, 1);
ItemMeta hookMeta = hook.getItemMeta();
hookMeta.setDisplayName(this.plugin.getLocale().getMessage("interface.hopper.synchopper").getMessage());
ArrayList<String> loreHook = new ArrayList<>();
parts = this.plugin.getLocale().getMessage("interface.hopper.synclore")
.processPlaceholder("amount", this.hopper.getLinkedBlocks().stream().distinct().count())
.getMessage().split("\\|");
for (String line : parts) {
loreHook.add(TextUtils.formatText(line));
}
hookMeta.setLore(loreHook);
hook.setItemMeta(hookMeta);
Map<Integer, Integer[]> layouts = new HashMap<>();
layouts.put(1, new Integer[]{22});
layouts.put(2, new Integer[]{22, 4});
layouts.put(3, new Integer[]{22, 3, 5});
layouts.put(4, new Integer[]{23, 3, 5, 21});
layouts.put(5, new Integer[]{23, 3, 5, 21, 22});
layouts.put(6, new Integer[]{23, 3, 4, 5, 21, 22});
layouts.put(7, new Integer[]{23, 3, 4, 5, 21, 22, 12});
layouts.put(8, new Integer[]{23, 3, 4, 5, 21, 22, 12, 14});
layouts.put(9, new Integer[]{23, 3, 4, 5, 21, 22, 12, 14, 20});
layouts.put(10, new Integer[]{23, 3, 4, 5, 21, 22, 12, 14, 20, 24});
int amount = 1;
boolean canFilter = level.isFilter() || this.player.hasPermission("EpicHoppers.Filter");
boolean canTeleport = level.isTeleport() || this.player.hasPermission("EpicHoppers.Teleport");
if (canFilter) {
amount++;
}
if (canTeleport) {
amount++;
}
List<Module> modules = level.getRegisteredModules()
.stream()
.filter(module -> module.getGUIButton(this.hopper) != null)
.collect(Collectors.toList());
amount += modules.size();
Integer[] layout = layouts.get(amount);
for (int ii = 0; ii < amount; ii++) {
int slot = layout[ii];
if (ii == 0) {
setButton("sync", slot, hook,
(event) -> {
if (this.hopper.getLastPlayerOpened() != null && !this.hopper.getLastPlayerOpened().equals(this.player.getUniqueId())) {
this.plugin.getLocale().getMessage("event.hopper.syncdidnotplace").sendPrefixedMessage(this.player);
return;
}
this.hopper.clearLinkedBlocks();
DataHelper.deleteLinks(this.hopper);
if (event.clickType == ClickType.RIGHT) {
this.plugin.getLocale().getMessage("event.hopper.desync").sendPrefixedMessage(this.player);
constructGUI();
return;
} else {
EpicHoppersApi.getApi().getPlayerDataManager().getPlayerData(this.player).setSyncType(SyncType.REGULAR);
this.plugin.getLocale().getMessage("event.hopper.syncnext").sendPrefixedMessage(this.player);
if (level.getLinkAmount() > 1) {
this.plugin.getLocale().getMessage("event.hopper.syncstart")
.processPlaceholder("amount", level.getLinkAmount())
.sendPrefixedMessage(this.player);
}
this.hopper.timeout(this.player);
}
this.player.closeInventory();
});
} else if (canTeleport) {
setButton("teleport", slot, pearl,
(event) -> {
if (event.clickType == ClickType.LEFT) {
if (this.hopper.getLinkedBlocks() != null) {
EpicHoppersApi.getApi().getTeleportHandler().tpEntity(this.player, this.hopper);
this.player.closeInventory();
}
} else {
if (this.hopper.getTeleportTrigger() == TeleportTrigger.DISABLED) {
this.hopper.setTeleportTrigger(TeleportTrigger.SNEAK);
} else if (this.hopper.getTeleportTrigger() == TeleportTrigger.SNEAK) {
this.hopper.setTeleportTrigger(TeleportTrigger.WALK_ON);
} else if (this.hopper.getTeleportTrigger() == TeleportTrigger.WALK_ON) {
this.hopper.setTeleportTrigger(TeleportTrigger.DISABLED);
}
EpicHoppers.getPlugin(EpicHoppers.class).getDataManager().save(this.hopper);
constructGUI();
}
});
canTeleport = false;
} else if (canFilter) {
setButton("filter", slot, filter, (event) -> {
this.hopper.setActivePlayer(this.player);
this.guiManager.showGUI(this.player, new GUIFilter(this.plugin, this.hopper, this.player));
});
canFilter = false;
} else {
if (modules.isEmpty()) {
break;
}
Module module = modules.get(0);
modules.remove(module);
setButton(module.getName().toLowerCase().replace(" ", "_"), slot, module.getGUIButton(this.hopper),
(event) -> module.runButtonPress(this.player, this.hopper, event.clickType));
}
}
if (Settings.HOPPER_UPGRADING.getBoolean()) {
if (Settings.UPGRADE_WITH_XP.getBoolean()
&& level.getCostExperience() != -1
&& this.player.hasPermission("EpicHoppers.Upgrade.XP")) {
setButton("upgrade_xp", 1, 2, GuiUtils.createButtonItem(
Settings.XP_ICON.getMaterial(XMaterial.EXPERIENCE_BOTTLE),
this.plugin.getLocale().getMessage("interface.hopper.upgradewithxp").getMessage(),
nextLevel != null
? this.plugin.getLocale().getMessage("interface.hopper.upgradewithxplore")
.processPlaceholder("cost", nextLevel.getCostExperience()).getMessage()
: this.plugin.getLocale().getMessage("interface.hopper.alreadymaxed").getMessage()),
(event) -> {
this.hopper.upgrade(this.player, CostType.EXPERIENCE);
if (this.hopper.prepareForOpeningOverviewGui(this.player)) {
this.guiManager.showGUI(event.player, new GUIOverview(this.plugin, this.hopper, event.player));
}
});
}
if (Settings.UPGRADE_WITH_ECONOMY.getBoolean()
&& level.getCostEconomy() != -1
&& this.player.hasPermission("EpicHoppers.Upgrade.ECO")) {
setButton("upgrade_economy", 1, 6, GuiUtils.createButtonItem(
Settings.ECO_ICON.getMaterial(XMaterial.SUNFLOWER),
this.plugin.getLocale().getMessage("interface.hopper.upgradewitheconomy").getMessage(),
nextLevel != null
? this.plugin.getLocale().getMessage("interface.hopper.upgradewitheconomylore")
.processPlaceholder("cost", NumberUtils.formatNumber(nextLevel.getCostEconomy())).getMessage()
: this.plugin.getLocale().getMessage("interface.hopper.alreadymaxed").getMessage()),
(event) -> {
this.hopper.upgrade(this.player, CostType.ECONOMY);
if (this.hopper.prepareForOpeningOverviewGui(this.player)) {
this.guiManager.showGUI(this.player, new GUIOverview(this.plugin, this.hopper, this.player));
}
});
}
}
setItem("hopper", 13, item);
this.hopper.setLastPlayerOpened(this.player.getUniqueId());
}
private void runTask() {
this.task = Bukkit.getScheduler().scheduleSyncRepeatingTask(this.plugin, () -> {
if (!this.inventory.getViewers().isEmpty()) {
this.constructGUI();
}
}, 5L, 5L);
}
}

View File

@ -0,0 +1,125 @@
package com.craftaro.epichoppers.gui;
import com.craftaro.core.SongodaPlugin;
import com.craftaro.core.compatibility.CompatibleMaterial;
import com.craftaro.core.gui.CustomizableGui;
import com.craftaro.core.gui.GuiUtils;
import com.craftaro.third_party.com.cryptomorin.xseries.XMaterial;
import com.craftaro.core.utils.TextUtils;
import com.craftaro.epichoppers.hopper.Hopper;
import com.craftaro.epichoppers.hopper.HopperImpl;
import com.craftaro.epichoppers.hopper.levels.modules.ModuleAutoSmelter;
import com.craftaro.epichoppers.settings.Settings;
import com.craftaro.epichoppers.utils.Methods;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class GUISmeltable extends CustomizableGui {
private final SongodaPlugin plugin;
private final HopperImpl hopper;
private final int maxPages;
private final ModuleAutoSmelter moduleAutoSmelter;
private static final List<XMaterial> BURNABLES = Arrays
.stream(XMaterial.values())
.filter(material -> CompatibleMaterial.getFurnaceResult(material) != null)
.collect(Collectors.toList());
public GUISmeltable(ModuleAutoSmelter moduleAutoSmelter, SongodaPlugin plugin, Hopper hopper) {
super(plugin, "smeltable");
this.plugin = plugin;
this.hopper = (HopperImpl) hopper;
this.moduleAutoSmelter = moduleAutoSmelter;
int smeltables = BURNABLES.size();
this.maxPages = (int) Math.ceil(smeltables / 32.);
setTitle(Methods.formatName(hopper.getLevel().getLevel()) + TextUtils.formatText(" &7-&f Smelting"));
setRows(6);
this.setOnPage((event) -> showPage());
showPage();
this.setOnClose((event) -> hopper.setActivePlayer(null));
}
void showPage() {
ItemStack glass1 = GuiUtils.getBorderItem(Settings.GLASS_TYPE_1.getMaterial());
ItemStack glass2 = GuiUtils.getBorderItem(Settings.GLASS_TYPE_2.getMaterial());
ItemStack glass3 = GuiUtils.getBorderItem(Settings.GLASS_TYPE_3.getMaterial());
setDefaultItem(glass1);
mirrorFill("mirrorfill_1", 0, 0, true, true, glass2);
mirrorFill("mirrorfill_2", 0, 1, true, true, glass2);
mirrorFill("mirrorfill_3", 0, 2, true, true, glass3);
mirrorFill("mirrorfill_4", 1, 0, true, true, glass2);
int smeltableIndex = this.page == 1 ? 0 : 32 * (this.page - 1);
for (int i = 9; i < 45; i++) {
if (i == 9 || i == 17 || i == 44 || i == 36) {
continue;
}
setItem(i, null);
clearActions(i);
if (smeltableIndex >= (BURNABLES.size() - 1)) {
continue;
}
XMaterial burnable = BURNABLES.get(smeltableIndex);
setButton(i, getItemStack(burnable, this.moduleAutoSmelter.isSmeltable(this.hopper, burnable)), (event) -> {
this.moduleAutoSmelter.toggleSmeltable(this.hopper, burnable);
setItem(event.slot, getItemStack(burnable, this.moduleAutoSmelter.isSmeltable(this.hopper, burnable)));
});
smeltableIndex++;
}
clearActions(51);
if (this.page < this.maxPages) {
setButton("next", 51, GuiUtils.createButtonItem(XMaterial.ARROW,
this.plugin.getLocale().getMessage("general.nametag.next").getMessage()),
(event) -> {
this.page++;
showPage();
});
}
clearActions(47);
if (this.page > 1) {
setButton("back", 47, GuiUtils.createButtonItem(XMaterial.ARROW,
this.plugin.getLocale().getMessage("general.nametag.back").getMessage()),
(event) -> {
this.page--;
showPage();
});
}
setButton("exit", 49, GuiUtils.createButtonItem(XMaterial.OAK_DOOR,
this.plugin.getLocale().getMessage("general.nametag.exit").getMessage()),
(event) -> {
if (this.hopper.prepareForOpeningOverviewGui(event.player)) {
this.guiManager.showGUI(event.player, new GUIOverview(this.plugin, this.hopper, event.player));
}
});
}
public ItemStack getItemStack(XMaterial material, boolean enabled) {
ItemStack item = material.parseItem();
ItemMeta meta = item.getItemMeta();
meta.setDisplayName(TextUtils.formatText("&e" + material.name()));
meta.setLore(Arrays.asList(TextUtils.formatText(" &7-> &e" + CompatibleMaterial.getFurnaceResult(material).getType().name()),
TextUtils.formatText("&7Enabled: &6" + String.valueOf(enabled).toLowerCase() + "&7."),
"",
this.plugin.getLocale().getMessage("interface.hopper.toggle").getMessage()));
item.setItemMeta(meta);
return item;
}
}

View File

@ -1,7 +1,7 @@
package com.songoda.epichoppers.hopper;
package com.craftaro.epichoppers.hopper;
import com.songoda.epichoppers.hopper.levels.Level;
import com.songoda.epichoppers.hopper.teleport.TeleportTrigger;
import com.craftaro.epichoppers.hopper.levels.Level;
import com.craftaro.epichoppers.hopper.teleport.TeleportTrigger;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.block.Block;
@ -9,15 +9,14 @@ import org.bukkit.block.Block;
import java.util.UUID;
public class HopperBuilder {
private final HopperImpl hopper;
private final Hopper hopper;
public HopperBuilder(Location location) {
this.hopper = new Hopper(location);
public HopperBuilder(Location location, UUID owner) {
this.hopper = new HopperImpl(location, owner);
}
public HopperBuilder(Block block) {
this(block.getLocation());
public HopperBuilder(Block block, UUID owner) {
this(block.getLocation(), owner);
}
public HopperBuilder setId(int id) {
@ -31,8 +30,9 @@ public class HopperBuilder {
}
public HopperBuilder addLinkedBlocks(LinkType type, Location... linkedBlocks) {
for (Location location : linkedBlocks)
hopper.addLinkedBlock(location, type);
for (Location location : linkedBlocks) {
this.hopper.addLinkedBlock(location, type);
}
return this;
}
@ -65,7 +65,7 @@ public class HopperBuilder {
return this;
}
public Hopper build() {
public HopperImpl build() {
return this.hopper;
}
}

View File

@ -0,0 +1,506 @@
package com.craftaro.epichoppers.hopper;
import com.craftaro.core.SongodaPlugin;
import com.craftaro.core.compatibility.CompatibleParticleHandler;
import com.craftaro.core.compatibility.ServerVersion;
import com.craftaro.core.database.Data;
import com.craftaro.core.database.DataManager;
import com.craftaro.core.database.SerializedLocation;
import com.craftaro.core.hooks.EconomyManager;
import com.craftaro.third_party.com.cryptomorin.xseries.XSound;
import com.craftaro.third_party.org.jooq.impl.DSL;
import com.craftaro.core.utils.ItemUtils;
import com.craftaro.epichoppers.EpicHoppers;
import com.craftaro.epichoppers.EpicHoppersApi;
import com.craftaro.epichoppers.api.events.HopperAccessEvent;
import com.craftaro.epichoppers.hopper.levels.Level;
import com.craftaro.epichoppers.hopper.levels.LevelManager;
import com.craftaro.epichoppers.player.PlayerData;
import com.craftaro.epichoppers.player.PlayerDataManager;
import com.craftaro.epichoppers.utils.CostType;
import com.craftaro.epichoppers.utils.DataHelper;
import com.craftaro.epichoppers.utils.Methods;
import com.craftaro.epichoppers.hopper.teleport.TeleportTrigger;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.io.BukkitObjectInputStream;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder;
import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.Base64;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
/**
* FIXME: Needs heavy refactoring to only have one responsibility.
*/
public class HopperImpl implements Hopper {
// Id for database use.
private int id;
private final Location location;
private Level level = getLevelManager().getLowestLevel();
private UUID lastPlayerOpened = null;
private UUID placedBy;
private final List<Location> linkedBlocks = new ArrayList<>();
private Filter filter = new Filter();
private TeleportTrigger teleportTrigger = TeleportTrigger.DISABLED;
private int transferTick = 0;
private int syncId = -1;
private Player activePlayer;
private final Map<String, Object> moduleCache = new HashMap<>();
/**
* Default constructor for database use.
*/
public HopperImpl() {
this.location = null;
}
/**
* Constructor for creating a new hopper.
*/
public HopperImpl(Location location, UUID placedBy) {
this.placedBy = placedBy;
this.location = location;
this.id = EpicHoppers.getPlugin(EpicHoppers.class).getDataManager().getNextId("placed_hoppers");
}
/**
* Constructor for database use.
*/
public HopperImpl(Map<String, Object> map) {
this.id = (int) map.get("id");
this.location = SerializedLocation.of(map);
this.level = getLevelManager().getLevel((int) map.get("level"));
this.placedBy = UUID.fromString((String) map.get("placed_by"));
this.lastPlayerOpened = map.get("last_opened_by") != null ? UUID.fromString((String) map.get("last_opened_by")) : null;
DataManager dataManager = EpicHoppers.getPlugin(EpicHoppers.class).getDataManager();
dataManager.getDatabaseConnector().connectDSL(dslContext -> {
//Load links
dslContext.select().from(DSL.table(dataManager.getTablePrefix() + "links")).where(DSL.field("hopper_id").eq(id)).fetch().forEach(record -> {
LinkType type = LinkType.valueOf(record.get("link_type", String.class));
if (type == LinkType.REJECT) {
this.filter.setEndPoint(new Location(Bukkit.getWorld(record.get("world", String.class)),
record.get("x", Double.class),
record.get("y", Double.class),
record.get("z", Double.class)));
return;
} else {
this.linkedBlocks.add(new Location(Bukkit.getWorld(record.get("world", String.class)),
record.get("x", Double.class),
record.get("y", Double.class),
record.get("z", Double.class)));
}
});
//Load filtered items
dslContext.select().from(DSL.table(dataManager.getTablePrefix() + "items")).where(DSL.field("hopper_id").eq(id)).fetch().stream().filter(Objects::nonNull).filter(record -> record.get("item", String.class) != null).forEach(record -> {
ItemStack itemStack = null;
try (ByteArrayInputStream inputStream = new ByteArrayInputStream(Base64Coder.decodeLines(record.get("item", String.class)));
BukkitObjectInputStream dataInput = new BukkitObjectInputStream(inputStream);
) {
itemStack = (ItemStack) dataInput.readObject();
} catch (Exception e) {
e.printStackTrace();
return;
}
ItemType type = ItemType.valueOf(record.get("item_type", String.class));
filter.addItem(itemStack, type);
});
});
}
@ApiStatus.Internal
public boolean prepareForOpeningOverviewGui(Player player) {
if (this.lastPlayerOpened != null &&
this.lastPlayerOpened != player.getUniqueId() &&
Bukkit.getPlayer(this.lastPlayerOpened) != null) {
Bukkit.getPlayer(this.lastPlayerOpened).closeInventory();
}
HopperAccessEvent accessEvent = new HopperAccessEvent(player, this);
Bukkit.getPluginManager().callEvent(accessEvent);
if (accessEvent.isCancelled()) {
return false;
}
if (this.placedBy == null) {
this.placedBy = player.getUniqueId();
Bukkit.getScheduler().scheduleSyncDelayedTask(EpicHoppers.getPlugin(EpicHoppers.class), () -> {
EpicHoppers.getPlugin(EpicHoppers.class).getDataManager().save(this);
}, 2);
}
if (!player.hasPermission("epichoppers.overview")) {
return false;
}
setActivePlayer(player);
return true;
}
@ApiStatus.Internal
public void forceClose() {
if (this.activePlayer != null) {
this.activePlayer.closeInventory();
}
}
public void dropItems() {
Inventory inventory = ((InventoryHolder) this.location.getBlock().getState()).getInventory();
World world = this.location.getWorld();
for (ItemStack itemStack : inventory.getContents()) {
if (itemStack == null || itemStack.getType() == Material.AIR) {
continue;
}
world.dropItemNaturally(this.location, itemStack);
}
}
public void upgrade(Player player, CostType type) {
if (!getLevelManager().getLevels().containsKey(this.level.getLevel() + 1)) {
return;
}
Level level = getLevelManager().getLevel(this.level.getLevel() + 1);
int cost = type == CostType.ECONOMY ? level.getCostEconomy() : level.getCostExperience();
if (type == CostType.ECONOMY) {
if (!EconomyManager.isEnabled()) {
player.sendMessage("Economy not enabled.");
return;
}
if (!EconomyManager.hasBalance(player, cost)) {
getPlugin().getLocale().getMessage("event.upgrade.cannotafford").sendPrefixedMessage(player);
return;
}
EconomyManager.withdrawBalance(player, cost);
upgradeFinal(level, player);
} else if (type == CostType.EXPERIENCE) {
if (player.getLevel() >= cost || player.getGameMode() == GameMode.CREATIVE) {
if (player.getGameMode() != GameMode.CREATIVE) {
player.setLevel(player.getLevel() - cost);
}
upgradeFinal(level, player);
} else {
getPlugin().getLocale().getMessage("event.upgrade.cannotafford").sendPrefixedMessage(player);
}
}
}
private void upgradeFinal(Level level, Player player) {
this.level = level;
EpicHoppers.getPlugin(EpicHoppers.class).getDataManager().save(this);
//TODO save items/links
syncName();
if (getLevelManager().getHighestLevel() != level) {
getPlugin().getLocale().getMessage("event.upgrade.success")
.processPlaceholder("level", level.getLevel()).sendPrefixedMessage(player);
} else {
getPlugin().getLocale().getMessage("event.upgrade.maxed")
.processPlaceholder("level", level.getLevel()).sendPrefixedMessage(player);
}
Location loc = this.location.clone().add(.5, .5, .5);
if (!getUpgradeParticleType().trim().isEmpty()) {
CompatibleParticleHandler.spawnParticles(
CompatibleParticleHandler.ParticleType.getParticle(getUpgradeParticleType()),
loc, 100, .5, .5, .5);
}
if (getLevelManager().getHighestLevel() != level) {
XSound.ENTITY_PLAYER_LEVELUP.play(player, .6f, 15);
} else {
XSound.ENTITY_PLAYER_LEVELUP.play(player, 2, 25);
XSound.BLOCK_NOTE_BLOCK_CHIME.play(player, 2, 25);
Bukkit.getScheduler().scheduleSyncDelayedTask(getPlugin(), () -> XSound.BLOCK_NOTE_BLOCK_CHIME.play(player, 1.2f, 35), 5);
Bukkit.getScheduler().scheduleSyncDelayedTask(getPlugin(), () -> XSound.BLOCK_NOTE_BLOCK_CHIME.play(player, 1.8f, 35), 10);
}
}
private void syncName() {
org.bukkit.block.Hopper hopper = (org.bukkit.block.Hopper) this.location.getBlock().getState();
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_10)) {
hopper.setCustomName(Methods.formatName(this.level.getLevel()));
}
hopper.update(true);
}
public void timeout(Player player) {
this.syncId = Bukkit.getScheduler().scheduleSyncDelayedTask(getPlugin(), () -> {
PlayerData playerData = getPlayerDataManager().getPlayerData(player);
if (playerData.getSyncType() != null && playerData.getLastHopper() == this) {
getPlugin().getLocale().getMessage("event.hopper.synctimeout").sendPrefixedMessage(player);
playerData.setSyncType(null);
}
}, getLinkTimeoutFromPluginConfig() * this.level.getLinkAmount());
}
public void link(Block toLink, boolean filtered, Player player) {
if (this.location.getWorld().equals(toLink.getLocation().getWorld())
&& !player.hasPermission("EpicHoppers.Override")
&& !player.hasPermission("EpicHoppers.Admin")
&& this.location.distance(toLink.getLocation()) > this.level.getRange()) {
getPlugin().getLocale().getMessage("event.hopper.syncoutofrange").sendPrefixedMessage(player);
return;
}
if (this.linkedBlocks.contains(toLink.getLocation())) {
getPlugin().getLocale().getMessage("event.hopper.already").sendPrefixedMessage(player);
return;
}
if (!filtered) {
this.linkedBlocks.add(toLink.getLocation());
DataHelper.createLink(this, toLink.getLocation(), LinkType.REGULAR);
} else {
this.filter.setEndPoint(toLink.getLocation());
DataHelper.createLink(this, toLink.getLocation(), LinkType.REJECT);
getPlugin().getLocale().getMessage("event.hopper.syncsuccess").sendPrefixedMessage(player);
getPlayerDataManager().getPlayerData(player).setSyncType(null);
return;
}
this.lastPlayerOpened = player.getUniqueId();
if (this.level.getLinkAmount() > 1) {
if (this.linkedBlocks.size() >= this.level.getLinkAmount()) {
getPlugin().getLocale().getMessage("event.hopper.syncdone").sendPrefixedMessage(player);
cancelSync(player);
return;
}
getPlugin().getLocale().getMessage("event.hopper.syncsuccessmore")
.processPlaceholder("amount", this.level.getLinkAmount() - this.linkedBlocks.size())
.sendPrefixedMessage(player);
return;
}
getPlugin().getLocale().getMessage("event.hopper.syncsuccess").sendPrefixedMessage(player);
cancelSync(player);
}
/**
* Ticks a hopper to determine when it can transfer items next
*
* @param maxTick The maximum amount the hopper can be ticked before next transferring items
* @param allowLooping If true, the hopper is allowed to transfer items if the tick is also valid
* @return true if the hopper should transfer an item, otherwise false
*/
public boolean tryTick(int maxTick, boolean allowLooping) {
this.transferTick++;
if (this.transferTick >= maxTick) {
if (allowLooping) {
this.transferTick = 0;
return true;
} else {
this.transferTick = maxTick;
}
}
return false;
}
public Location getLocation() {
return this.location.clone();
}
public Block getBlock() {
return this.location.getBlock();
}
public World getWorld() {
return this.location.getWorld();
}
public int getX() {
return this.location.getBlockX();
}
public int getY() {
return this.location.getBlockY();
}
public int getZ() {
return this.location.getBlockZ();
}
public Level getLevel() {
return this.level;
}
public void setLevel(Level level) {
this.level = level;
}
public @NotNull UUID getPlacedBy() {
return this.placedBy;
}
public void setPlacedBy(UUID placedBy) {
this.placedBy = placedBy;
}
public UUID getLastPlayerOpened() {
return this.lastPlayerOpened;
}
public void setLastPlayerOpened(UUID uuid) {
this.lastPlayerOpened = uuid;
}
public TeleportTrigger getTeleportTrigger() {
return this.teleportTrigger;
}
public void setTeleportTrigger(TeleportTrigger teleportTrigger) {
this.teleportTrigger = teleportTrigger;
}
public List<Location> getLinkedBlocks() {
return new ArrayList<>(this.linkedBlocks);
}
public void addLinkedBlock(Location location, LinkType type) {
if (type == LinkType.REGULAR) {
this.linkedBlocks.add(location);
} else {
this.filter.setEndPoint(location);
}
}
public void removeLinkedBlock(Location location) {
this.linkedBlocks.remove(location);
}
public void clearLinkedBlocks() {
this.linkedBlocks.clear();
}
public Filter getFilter() {
return this.filter;
}
public void setFilter(Filter filter) {
this.filter = filter;
}
public Object getDataFromModuleCache(String key) {
return this.moduleCache.getOrDefault(key, null);
}
public void addDataToModuleCache(String key, Object data) {
this.moduleCache.put(key, data);
}
public boolean isDataCachedInModuleCache(String key) {
return this.moduleCache.containsKey(key);
}
public void removeDataFromModuleCache(String key) {
this.moduleCache.remove(key);
}
public void clearModuleCache() {
this.moduleCache.clear();
}
public void cancelSync(Player player) {
Bukkit.getScheduler().cancelTask(this.syncId);
getPlayerDataManager().getPlayerData(player).setSyncType(null);
}
@Override
public int getId() {
return this.id;
}
@Override
public Map<String, Object> serialize() {
Map<String, Object> map = new LinkedHashMap<>();
map.put("id", this.id);
map.put("level", this.level.getLevel());
map.put("placed_by", this.placedBy.toString());
map.put("last_opened_by", this.lastPlayerOpened == null ? null : this.lastPlayerOpened.toString());
map.put("teleport_trigger", this.teleportTrigger.name());
map.putAll(SerializedLocation.of(this.location));
return map;
}
@Override
public Data deserialize(Map<String, Object> map) {
return new HopperImpl(map);
}
@Override
public String getTableName() {
return "placed_hoppers";
}
public void setId(int id) {
this.id = id;
}
public Player getActivePlayer() {
return this.activePlayer;
}
public void setActivePlayer(Player activePlayer) {
this.activePlayer = activePlayer;
}
private LevelManager getLevelManager() {
return EpicHoppersApi.getApi().getLevelManager();
}
private PlayerDataManager getPlayerDataManager() {
return EpicHoppersApi.getApi().getPlayerDataManager();
}
/**
* @deprecated The class needs refactoring to not even need the plugin.
* This is just a temporary workaround to get a Minecraft 1.20-beta build ready
*/
@Deprecated
private long getLinkTimeoutFromPluginConfig() {
return getPlugin().getConfig().getLong("Main.Timeout When Syncing Hoppers");
}
/**
* @deprecated The class needs refactoring to not even need the plugin.
* This is just a temporary workaround to get a Minecraft 1.20-beta build ready
*/
@Deprecated
private String getUpgradeParticleType() {
return getPlugin().getConfig().getString("Main.Upgrade Particle Type");
}
/**
* @deprecated The class needs refactoring to not even need the plugin.
* This is just a temporary workaround to get a Minecraft 1.20-beta build ready
*/
@Deprecated
private SongodaPlugin getPlugin() {
return (SongodaPlugin) Bukkit.getPluginManager().getPlugin("EpicHoppers");
}
}

View File

@ -0,0 +1,133 @@
package com.craftaro.epichoppers.hopper;
import com.craftaro.epichoppers.EpicHoppers;
import com.craftaro.epichoppers.hopper.levels.Level;
import com.craftaro.epichoppers.hopper.levels.modules.Module;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class HopperManager {
private final Map<Location, HopperImpl> registeredHoppers = new HashMap<>();
private final EpicHoppers plugin;
protected boolean ready;
public HopperManager(EpicHoppers plugin) {
this.plugin = plugin;
}
/**
* Sets {@link #isReady()} to {@code true}.<br>
* <b>Called by {@link EpicHoppers#onDataLoad()}</b>
*/
public void setReady() {
this.ready = true;
}
/**
* @return true, if all the data has been loaded from the DB
*/
public boolean isReady() {
return this.ready;
}
public HopperImpl addHopper(HopperImpl hopper) {
this.registeredHoppers.put(roundLocation(hopper.getLocation()), hopper);
return hopper;
}
@Deprecated
public void addHopper(Location location, HopperImpl hopper) {
this.registeredHoppers.put(roundLocation(location), hopper);
}
public void addHoppers(Collection<HopperImpl> hoppers) {
for (HopperImpl hopper : hoppers) {
this.registeredHoppers.put(hopper.getLocation(), hopper);
}
}
/**
* Removes a hopper and unlinks it from any other hoppers
*
* @param location The location of the hopper to remove
* @return The removed hopper, or null if none was removed
*/
public HopperImpl removeHopper(Location location) {
HopperImpl removed = this.registeredHoppers.remove(location);
for (HopperImpl hopper : this.registeredHoppers.values()) {
hopper.removeLinkedBlock(location);
}
for (Level level : this.plugin.getLevelManager().getLevels().values()) {
for (Module module : level.getRegisteredModules()) {
module.clearData(removed);
}
}
return removed;
}
public HopperImpl getHopper(Location location, UUID createForIfNotExists) {
if (!this.registeredHoppers.containsKey(location = roundLocation(location))) {
if (!this.ready) {
throw new IllegalStateException("Hoppers are still being loaded");
}
if (createForIfNotExists == null) {
return null;
}
HopperImpl hopper = addHopper(new HopperImpl(location, createForIfNotExists));
this.plugin.getDataManager().save(hopper);
this.registeredHoppers.put(location, hopper);
return hopper;
}
return this.registeredHoppers.get(location);
}
public HopperImpl getHopper(Block block, UUID createForIfNotExists) {
return getHopper(block.getLocation(), createForIfNotExists);
}
/**
* <em>Returns {@code false} if {@link #isReady()} is false too</em>
*/
public boolean isHopper(Location location) {
return this.registeredHoppers.containsKey(roundLocation(location));
}
public Map<Location, HopperImpl> getHoppers() {
return Collections.unmodifiableMap(this.registeredHoppers);
}
public HopperImpl getHopperFromPlayer(Player player) {
if (!this.ready) {
throw new IllegalStateException("Hoppers are still being loaded");
}
for (HopperImpl hopper : this.registeredHoppers.values()) {
if (hopper.getLastPlayerOpened() == player.getUniqueId()) {
return hopper;
}
}
return null;
}
private Location roundLocation(Location location) {
location = location.clone();
location.setX(location.getBlockX());
location.setY(location.getBlockY());
location.setZ(location.getBlockZ());
return location;
}
}

View File

@ -1,9 +1,9 @@
package com.songoda.epichoppers.hopper.levels;
package com.craftaro.epichoppers.hopper.levels;
import com.songoda.core.nms.NmsManager;
import com.songoda.core.nms.nbt.NBTCore;
import com.songoda.core.third_party.de.tr7zw.nbtapi.NBTItem;
import com.songoda.epichoppers.hopper.levels.modules.Module;
import com.craftaro.core.nms.NmsManager;
import com.craftaro.core.nms.nbt.NBTCore;
import com.craftaro.core.third_party.de.tr7zw.nbtapi.NBTItem;
import com.craftaro.epichoppers.hopper.levels.modules.Module;
import org.bukkit.ChatColor;
import org.bukkit.inventory.ItemStack;
@ -13,25 +13,26 @@ import java.util.Map;
import java.util.NavigableMap;
import java.util.TreeMap;
public class LevelManager {
public class LevelManagerImpl implements LevelManager {
private final NavigableMap<Integer, Level> registeredLevels = new TreeMap<>();
@Override
public void addLevel(int level, int costExperience, int costEconomy, int range, int amount, boolean filter, boolean teleport, int linkAmount, ArrayList<Module> modules) {
registeredLevels.put(level, new Level(level, costExperience, costEconomy, range, amount, filter, teleport, linkAmount, modules));
this.registeredLevels.put(level, new Level(level, costExperience, costEconomy, range, amount, filter, teleport, linkAmount, modules));
}
@Override
public Level getLevel(int level) {
return registeredLevels.get(level);
return this.registeredLevels.get(level);
}
@Override
public Level getLevel(ItemStack item) {
NBTItem nbtItem = new NBTItem(item);
if (nbtItem.hasKey("level"))
if (nbtItem.hasTag("level")) {
return getLevel(nbtItem.getInteger("level"));
}
// Legacy trash.
if (item.hasItemMeta() && item.getItemMeta().getDisplayName().contains(":")) {
@ -42,11 +43,13 @@ public class LevelManager {
return getLowestLevel();
}
@Override
public boolean isEpicHopper(ItemStack item) {
NBTCore nbt = NmsManager.getNbt();
if (nbt.of(item).has("level"))
if (nbt.of(item).has("level")) {
return true;
}
return item.hasItemMeta()
// Legacy Trash.
@ -54,26 +57,31 @@ public class LevelManager {
}
@Override
public Level getLowestLevel() {
return registeredLevels.firstEntry().getValue();
return this.registeredLevels.firstEntry().getValue();
}
@Override
public Level getHighestLevel() {
return registeredLevels.lastEntry().getValue();
return this.registeredLevels.lastEntry().getValue();
}
@Override
public boolean isLevel(int level) {
return registeredLevels.containsKey(level);
return this.registeredLevels.containsKey(level);
}
@Override
public Map<Integer, Level> getLevels() {
return Collections.unmodifiableMap(registeredLevels);
return Collections.unmodifiableMap(this.registeredLevels);
}
@Override
public void clear() {
registeredLevels.clear();
this.registeredLevels.clear();
}
}

View File

@ -1,13 +1,15 @@
package com.songoda.epichoppers.hopper.levels.modules;
package com.craftaro.epichoppers.hopper.levels.modules;
import com.songoda.core.compatibility.CompatibleMaterial;
import com.songoda.core.utils.TextUtils;
import com.songoda.epichoppers.EpicHoppers;
import com.songoda.epichoppers.gui.GUICrafting;
import com.songoda.epichoppers.hopper.Hopper;
import com.songoda.epichoppers.settings.Settings;
import com.songoda.epichoppers.utils.Methods;
import com.songoda.epichoppers.utils.StorageContainerCache;
import com.craftaro.core.SongodaPlugin;
import com.craftaro.core.gui.GuiManager;
import com.craftaro.third_party.com.cryptomorin.xseries.XMaterial;
import com.craftaro.core.utils.TextUtils;
import com.craftaro.epichoppers.hopper.Hopper;
import com.craftaro.epichoppers.hopper.HopperImpl;
import com.craftaro.epichoppers.settings.Settings;
import com.craftaro.epichoppers.utils.Methods;
import com.craftaro.epichoppers.gui.GUICrafting;
import com.craftaro.epichoppers.utils.StorageContainerCache;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
@ -31,15 +33,15 @@ import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
public class ModuleAutoCrafting extends Module {
private static final Map<ItemStack, Recipes> CACHED_RECIPES = new ConcurrentHashMap<>();
private static final Map<Hopper, ItemStack> CACHED_CRAFTING = new ConcurrentHashMap<>();
private static final ItemStack NO_CRAFT = new ItemStack(Material.AIR);
private static final Map<ItemStack, Recipes> cachedRecipes = new ConcurrentHashMap<>();
private static final Map<Hopper, ItemStack> cachedCrafting = new ConcurrentHashMap<>();
private static final ItemStack noCraft = new ItemStack(Material.AIR);
private boolean crafterEjection;
private final boolean crafterEjection;
public ModuleAutoCrafting(EpicHoppers plugin) {
super(plugin);
crafterEjection = Settings.AUTOCRAFT_JAM_EJECT.getBoolean();
public ModuleAutoCrafting(SongodaPlugin plugin, GuiManager guiManager) {
super(plugin, guiManager);
this.crafterEjection = Settings.AUTOCRAFT_JAM_EJECT.getBoolean();
}
@Override
@ -50,8 +52,9 @@ public class ModuleAutoCrafting extends Module {
@Override
public void run(Hopper hopper, StorageContainerCache.Cache hopperCache) {
final ItemStack toCraft;
if (hopper == null || (toCraft = getAutoCrafting(hopper)) == null || toCraft.getType() == Material.AIR)
if (hopper == null || (toCraft = getAutoCrafting(hopper)) == null || toCraft.getType() == Material.AIR) {
return;
}
synchronized (hopperCache) { //TODO: Check if this is required
ItemStack[] items = hopperCache.cachedInventory;
@ -67,8 +70,12 @@ public class ModuleAutoCrafting extends Module {
for (int i = 0; i < items.length; i++) {
ItemStack item = items[i];
if (item == null) continue;
if (item.hasItemMeta() && item.getItemMeta().hasDisplayName()) continue;
if (item == null) {
continue;
}
if (item.hasItemMeta() && item.getItemMeta().hasDisplayName()) {
continue;
}
boolean sameMaterial = Methods.isSimilarMaterial(item, ingredient.item);
@ -82,7 +89,9 @@ public class ModuleAutoCrafting extends Module {
}
// Still doesn't not match --> Skip this item
if (!sameMaterial) continue;
if (!sameMaterial) {
continue;
}
}
if (item.getAmount() >= amount) {
@ -95,7 +104,9 @@ public class ModuleAutoCrafting extends Module {
}
// Not enough ingredients for this recipe
if (amount != 0) continue recipeLoop;
if (amount != 0) {
continue recipeLoop;
}
}
boolean freeSlotAfterRemovingIngredients =
@ -105,14 +116,14 @@ public class ModuleAutoCrafting extends Module {
recipe.result.isSimilar(item)));
// jam check: is this hopper gummed up?
if (crafterEjection && !freeSlotAfterRemovingIngredients) {
if (this.crafterEjection && !freeSlotAfterRemovingIngredients) {
// Crafter can't function if there's nowhere to put the output
// ¯\_()_/¯
for (int i = 0; i < items.length; i++) {
if (!slotsToAlter.containsKey(i)) {
// and yeet into space!
hopper.getWorld().dropItemNaturally(hopper.getLocation(), items[i]);
hopper.getLocation().getWorld().dropItemNaturally(hopper.getLocation(), items[i]);
items[i] = null;
freeSlotAfterRemovingIngredients = true;
@ -178,25 +189,25 @@ public class ModuleAutoCrafting extends Module {
@Override
public ItemStack getGUIButton(Hopper hopper) {
ItemStack crafting = CompatibleMaterial.CRAFTING_TABLE.getItem();
ItemMeta craftingmeta = crafting.getItemMeta();
craftingmeta.setDisplayName(EpicHoppers.getInstance().getLocale().getMessage("interface.hopper.craftingtitle")
ItemStack crafting = XMaterial.CRAFTING_TABLE.parseItem();
ItemMeta craftingMeta = crafting.getItemMeta();
craftingMeta.setDisplayName(this.plugin.getLocale().getMessage("interface.hopper.craftingtitle")
.getMessage());
ArrayList<String> lorecrafting = new ArrayList<>();
String[] parts = EpicHoppers.getInstance().getLocale().getMessage("interface.hopper.craftinglore")
String[] parts = this.plugin.getLocale().getMessage("interface.hopper.craftinglore")
.getMessage().split("\\|");
for (String line : parts) {
lorecrafting.add(TextUtils.formatText(line));
}
craftingmeta.setLore(lorecrafting);
crafting.setItemMeta(craftingmeta);
craftingMeta.setLore(lorecrafting);
crafting.setItemMeta(craftingMeta);
return crafting;
}
@Override
public void runButtonPress(Player player, Hopper hopper, ClickType type) {
hopper.setActivePlayer(player);
EpicHoppers.getInstance().getGuiManager().showGUI(player, new GUICrafting(this, hopper, player));
this.guiManager.showGUI(player, new GUICrafting(this, this.plugin, hopper, player));
}
@Override
@ -205,26 +216,30 @@ public class ModuleAutoCrafting extends Module {
if (itemStack != null && itemStack.getType() != Material.AIR) {
return getRecipes(itemStack).getPossibleIngredientTypes();
}
return Collections.EMPTY_LIST;
return Collections.emptyList();
}
@Override
public String getDescription() {
return EpicHoppers.getInstance().getLocale().getMessage("interface.hopper.crafting").processPlaceholder("enabled",
EpicHoppers.getInstance().getLocale().getMessage("general.word.enabled").getMessage()).getMessage();
return this.plugin.getLocale()
.getMessage("interface.hopper.crafting")
.processPlaceholder("enabled", this.plugin.getLocale().getMessage("general.word.enabled").getMessage())
.getMessage();
}
@Override
public void clearData(Hopper hopper) {
super.clearData(hopper);
cachedCrafting.remove(hopper);
CACHED_CRAFTING.remove(hopper);
}
private Recipes getRecipes(ItemStack toCraft) {
Recipes recipes = cachedRecipes.get(toCraft);
Recipes recipes = CACHED_RECIPES.get(toCraft);
if (Settings.AUTOCRAFT_BLACKLIST.getStringList().stream()
.anyMatch(r -> r.equalsIgnoreCase(toCraft.getType().name())))
.anyMatch(r -> r.equalsIgnoreCase(toCraft.getType().name()))) {
return new Recipes();
}
if (recipes == null) {
try {
recipes = new Recipes(Bukkit.getServer().getRecipesFor(toCraft));
@ -238,32 +253,37 @@ public class ModuleAutoCrafting extends Module {
Recipe recipe = recipeIterator.next();
ItemStack stack = recipe.getResult();
if (Methods.isSimilarMaterial(stack, toCraft))
if (Methods.isSimilarMaterial(stack, toCraft)) {
recipes.addRecipe(recipe);
}
} catch (Throwable ignored) {
}
}
}
cachedRecipes.put(toCraft, recipes);
CACHED_RECIPES.put(toCraft, recipes);
}
return recipes;
}
public ItemStack getAutoCrafting(Hopper hopper) {
if (cachedCrafting.containsKey(hopper))
return cachedCrafting.get(hopper);
if (CACHED_CRAFTING.containsKey(hopper)) {
return CACHED_CRAFTING.get(hopper);
}
Object autocrafting = getData(hopper, "autocrafting");
ItemStack toCraft = autocrafting instanceof ItemStack ? (ItemStack) autocrafting : decode((String) autocrafting);
cachedCrafting.put(hopper, toCraft == null ? noCraft : toCraft);
CACHED_CRAFTING.put(hopper, toCraft == null ? NO_CRAFT : toCraft);
return toCraft;
}
public void setAutoCrafting(Hopper hopper, Player player, ItemStack autoCrafting) {
saveData(hopper, "autocrafting", autoCrafting == null ? null : encode(autoCrafting), autoCrafting);
cachedCrafting.put(hopper, autoCrafting == null ? noCraft : autoCrafting);
if (autoCrafting == null) return;
CACHED_CRAFTING.put(hopper, autoCrafting == null ? NO_CRAFT : autoCrafting);
if (autoCrafting == null) {
return;
}
int excess = autoCrafting.getAmount() - 1;
autoCrafting.setAmount(1);
if (excess > 0 && player != null) {
@ -285,7 +305,7 @@ public class ModuleAutoCrafting extends Module {
1, Short.parseShort(autoCraftingParts.length == 2 ? autoCraftingParts[1] : "0"));
}
private final static class Recipes {
private static final class Recipes {
private final List<SimpleRecipe> recipes = new ArrayList<>();
// Used for the blacklist to ensure that items are not going to get transferred
private final List<Material> possibleIngredientTypes = new ArrayList<>();
@ -298,11 +318,11 @@ public class ModuleAutoCrafting extends Module {
}
public List<SimpleRecipe> getRecipes() {
return Collections.unmodifiableList(recipes);
return Collections.unmodifiableList(this.recipes);
}
public List<Material> getPossibleIngredientTypes() {
return Collections.unmodifiableList(possibleIngredientTypes);
return Collections.unmodifiableList(this.possibleIngredientTypes);
}
public void addRecipe(Recipe recipe) {
@ -315,19 +335,21 @@ public class ModuleAutoCrafting extends Module {
}
// Skip unsupported recipe type
if (simpleRecipe == null) return;
if (simpleRecipe == null) {
return;
}
this.recipes.add(simpleRecipe);
// Keep a list of all possible ingredients.
for (SimpleRecipe.SimpleIngredient ingredient : simpleRecipe.ingredients) {
if (!possibleIngredientTypes.contains(ingredient.item.getType())) {
possibleIngredientTypes.add(ingredient.item.getType());
if (!this.possibleIngredientTypes.contains(ingredient.item.getType())) {
this.possibleIngredientTypes.add(ingredient.item.getType());
}
for (ItemStack material : ingredient.alternativeTypes) {
if (!possibleIngredientTypes.contains(material.getType())) {
possibleIngredientTypes.add(material.getType());
if (!this.possibleIngredientTypes.contains(material.getType())) {
this.possibleIngredientTypes.add(material.getType());
}
}
}
@ -338,15 +360,15 @@ public class ModuleAutoCrafting extends Module {
}
public boolean hasRecipes() {
return !recipes.isEmpty();
return !this.recipes.isEmpty();
}
public void clearRecipes() {
recipes.clear();
this.recipes.clear();
}
}
private final static class SimpleRecipe {
private static final class SimpleRecipe {
private final SimpleIngredient[] ingredients;
private final ItemStack result;
@ -384,7 +406,9 @@ public class ModuleAutoCrafting extends Module {
} catch (NoSuchMethodError ignore) { // Method missing in Spigot 1.12.2
}
if (item == null) continue;
if (item == null) {
continue;
}
processIngredient(ingredients, item, rChoice);
}
@ -449,26 +473,29 @@ public class ModuleAutoCrafting extends Module {
}
public int getAdditionalAmount() {
return additionalAmount;
return this.additionalAmount;
}
public void addAdditionalAmount(int amountToAdd) {
additionalAmount += amountToAdd;
this.additionalAmount += amountToAdd;
}
/**
* Like {@link #equals(Object)} but ignores {@link #additionalAmount} and {@link ItemStack#getAmount()}
*
* @return If two {@link SimpleIngredient} objects are equal
* while ignoring any item amounts, true otherwise false
* while ignoring any item amounts, true otherwise false
*/
public boolean isSimilar(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
SimpleIngredient that = (SimpleIngredient) o;
return item.isSimilar(that.item) &&
Arrays.equals(alternativeTypes, that.alternativeTypes);
return this.item.isSimilar(that.item) && Arrays.equals(this.alternativeTypes, that.alternativeTypes);
}
}
}

View File

@ -1,15 +1,18 @@
package com.songoda.epichoppers.hopper.levels.modules;
package com.craftaro.epichoppers.hopper.levels.modules;
import com.songoda.core.compatibility.CompatibleMaterial;
import com.songoda.core.hooks.EconomyManager;
import com.songoda.core.utils.TextUtils;
import com.songoda.epichoppers.EpicHoppers;
import com.songoda.epichoppers.gui.GUIAutoSellFilter;
import com.songoda.epichoppers.hopper.Filter;
import com.songoda.epichoppers.hopper.Hopper;
import com.songoda.epichoppers.settings.Settings;
import com.songoda.epichoppers.utils.Methods;
import com.songoda.epichoppers.utils.StorageContainerCache;
import com.craftaro.core.SongodaPlugin;
import com.craftaro.core.gui.GuiManager;
import com.craftaro.core.hooks.EconomyManager;
import com.craftaro.third_party.com.cryptomorin.xseries.XMaterial;
import com.craftaro.core.utils.NumberUtils;
import com.craftaro.core.utils.TextUtils;
import com.craftaro.epichoppers.hopper.Hopper;
import com.craftaro.epichoppers.hopper.HopperImpl;
import com.craftaro.epichoppers.settings.Settings;
import com.craftaro.epichoppers.utils.Methods;
import com.craftaro.epichoppers.gui.GUIAutoSellFilter;
import com.craftaro.epichoppers.hopper.Filter;
import com.craftaro.epichoppers.utils.StorageContainerCache;
import me.gypopo.economyshopgui.api.EconomyShopGUIHook;
import org.bukkit.Bukkit;
import org.bukkit.Material;
@ -25,13 +28,14 @@ import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class ModuleAutoSell extends Module {
private static final Map<Hopper, Boolean> CACHED_NOTIFICATIONS = new ConcurrentHashMap<>();
private final int timeOut;
private final int hopperTickRate;
private static final Map<Hopper, Boolean> cachedNotifications = new ConcurrentHashMap<>();
public ModuleAutoSell(EpicHoppers plugin, int timeOut) {
super(plugin);
public ModuleAutoSell(SongodaPlugin plugin, GuiManager guiManager, int timeOut) {
super(plugin, guiManager);
this.timeOut = timeOut * 20;
this.hopperTickRate = Settings.HOP_TICKS.getInt();
}
@ -46,15 +50,19 @@ public class ModuleAutoSell extends Module {
int currentTime = getTime(hopper);
if (currentTime == -9999) return;
if (currentTime == -9999) {
return;
}
int subtract = getTime(hopper) - hopperTickRate;
int subtract = getTime(hopper) - this.hopperTickRate;
if (subtract <= 0) {
int amountSold = 0;
double totalValue = 0;
if (!EconomyManager.isEnabled()) return;
if (!EconomyManager.isEnabled()) {
return;
}
OfflinePlayer player = Bukkit.getOfflinePlayer(hopper.getPlacedBy());
@ -62,18 +70,22 @@ public class ModuleAutoSell extends Module {
for (int i = 0; i < hopperCache.cachedInventory.length; i++) {
final ItemStack itemStack = hopperCache.cachedInventory[i];
if (itemStack == null) continue;
if (itemStack == null) {
continue;
}
Filter filter = hopper.getFilter();
if (filter.getAutoSellWhiteList().isEmpty()) {
// Check blacklist
if (filter.getAutoSellBlackList().stream().anyMatch(item -> Methods.isSimilarMaterial(itemStack, item)))
if (filter.getAutoSellBlackList().stream().anyMatch(item -> Methods.isSimilarMaterial(itemStack, item))) {
continue;
}
} else {
// Check whitelist
if (filter.getAutoSellWhiteList().stream().noneMatch(item -> Methods.isSimilarMaterial(itemStack, item)))
if (filter.getAutoSellWhiteList().stream().noneMatch(item -> Methods.isSimilarMaterial(itemStack, item))) {
continue;
}
}
// Get the value from config or ShopGuiPlus or EconomyShopGui
@ -99,11 +111,13 @@ public class ModuleAutoSell extends Module {
ex.printStackTrace();
}
} else {
value = Settings.AUTOSELL_PRICES.getStringList().stream().filter(line -> CompatibleMaterial.valueOf(line.split(",")[0]) == CompatibleMaterial.getMaterial(itemStack)).findFirst()
value = Settings.AUTOSELL_PRICES.getStringList().stream().filter(line -> XMaterial.valueOf(line.split(",")[0]).isSimilar(itemStack)).findFirst()
.map(s -> Double.valueOf(s.split(",")[1])).orElse(0.0);
}
if (value <= 0) continue;
if (value <= 0) {
continue;
}
double sellingFor = value * itemStack.getAmount();
@ -112,15 +126,16 @@ public class ModuleAutoSell extends Module {
hopperCache.removeItem(i);
}
if (totalValue != 0)
if (totalValue != 0) {
EconomyManager.deposit(player, totalValue);
}
if (totalValue != 0 && player.isOnline() && isNotifying(hopper)) {
plugin.getLocale().getMessage("event.hopper.autosell")
this.plugin.getLocale().getMessage("event.hopper.autosell")
.processPlaceholder("items", amountSold)
.processPlaceholder("amount", Methods.formatEconomy(totalValue)).sendPrefixedMessage(player.getPlayer());
.processPlaceholder("amount", NumberUtils.formatNumber(totalValue)).sendPrefixedMessage(player.getPlayer());
}
modifyDataCache(hopper, "time", timeOut);
modifyDataCache(hopper, "time", this.timeOut);
return;
}
@ -129,18 +144,21 @@ public class ModuleAutoSell extends Module {
@Override
public ItemStack getGUIButton(Hopper hopper) {
ItemStack sellItem = CompatibleMaterial.SUNFLOWER.getItem();
ItemStack sellItem = XMaterial.SUNFLOWER.parseItem();
ItemMeta sellMeta = sellItem.getItemMeta();
sellMeta.setDisplayName(EpicHoppers.getInstance().getLocale().getMessage("interface.hopper.selltitle").getMessage());
sellMeta.setDisplayName(this.plugin.getLocale().getMessage("interface.hopper.selltitle").getMessage());
ArrayList<String> loreSell = new ArrayList<>();
String[] parts = EpicHoppers.getInstance().getLocale().getMessage("interface.hopper.selllore")
.processPlaceholder("timeleft", getTime(hopper) == -9999 ? "\u221E" : (int) Math.floor(getTime(hopper) / 20))
.processPlaceholder("state", isNotifying(hopper)).getMessage().split("\\|");
String[] parts = this.plugin.getLocale().getMessage("interface.hopper.selllore")
.processPlaceholder("timeleft", getTime(hopper) == -9999 ? "" : (int) Math.floor(getTime(hopper) / 20))
.processPlaceholder("state", isNotifying(hopper))
.getMessage()
.split("\\|");
for (String line : parts)
for (String line : parts) {
loreSell.add(TextUtils.formatText(line));
}
sellMeta.setLore(loreSell);
sellItem.setItemMeta(sellMeta);
@ -151,7 +169,7 @@ public class ModuleAutoSell extends Module {
public void runButtonPress(Player player, Hopper hopper, ClickType type) {
if (type == ClickType.LEFT) {
if (getTime(hopper) == -9999) {
saveData(hopper, "time", timeOut);
saveData(hopper, "time", this.timeOut);
} else {
saveData(hopper, "time", -9999);
}
@ -160,7 +178,7 @@ public class ModuleAutoSell extends Module {
} else if (type == ClickType.SHIFT_LEFT || type == ClickType.SHIFT_RIGHT) {
// Any shift click opens AutoSell filter configuration GUI
hopper.setActivePlayer(player);
EpicHoppers.getInstance().getGuiManager().showGUI(player, new GUIAutoSellFilter(EpicHoppers.getInstance(), hopper));
this.guiManager.showGUI(player, new GUIAutoSellFilter(this.plugin, hopper));
}
}
@ -171,33 +189,37 @@ public class ModuleAutoSell extends Module {
@Override
public String getDescription() {
return EpicHoppers.getInstance().getLocale().getMessage("interface.hopper.autosell")
.processPlaceholder("seconds", (int) Math.floor(timeOut / 20)).getMessage();
return this.plugin.getLocale()
.getMessage("interface.hopper.autosell")
.processPlaceholder("seconds", (int) Math.floor(this.timeOut / 20))
.getMessage();
}
@Override
public void clearData(Hopper hopper) {
super.clearData(hopper);
cachedNotifications.remove(hopper);
CACHED_NOTIFICATIONS.remove(hopper);
}
private boolean isNotifying(Hopper hopper) {
Boolean enabled = cachedNotifications.get(hopper);
Boolean enabled = CACHED_NOTIFICATIONS.get(hopper);
if (enabled == null) {
Object notifications = getData(hopper, "notifications");
cachedNotifications.put(hopper, enabled = notifications != null && (boolean) notifications);
CACHED_NOTIFICATIONS.put(hopper, enabled = notifications != null && (boolean) notifications);
}
return enabled;
}
public void setNotifying(Hopper hopper, boolean enable) {
saveData(hopper, "notifications", enable);
cachedNotifications.put(hopper, enable);
CACHED_NOTIFICATIONS.put(hopper, enable);
}
private int getTime(Hopper hopper) {
Object time = getData(hopper, "time");
if (time == null) return -9999;
if (time == null) {
return -9999;
}
return (int) time;
}
}

View File

@ -0,0 +1,180 @@
package com.craftaro.epichoppers.hopper.levels.modules;
import com.craftaro.core.SongodaPlugin;
import com.craftaro.core.compatibility.CompatibleMaterial;
import com.craftaro.core.gui.GuiManager;
import com.craftaro.third_party.com.cryptomorin.xseries.XMaterial;
import com.craftaro.core.utils.TextUtils;
import com.craftaro.epichoppers.hopper.Hopper;
import com.craftaro.epichoppers.hopper.HopperImpl;
import com.craftaro.epichoppers.settings.Settings;
import com.craftaro.epichoppers.gui.GUISmeltable;
import com.craftaro.epichoppers.utils.StorageContainerCache;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.FurnaceRecipe;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.Recipe;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class ModuleAutoSmelter extends Module {
private final int timeOut;
private final int hopperTickRate;
public ModuleAutoSmelter(SongodaPlugin plugin, GuiManager guiManager, int timeOut) {
super(plugin, guiManager);
this.timeOut = timeOut * 20;
this.hopperTickRate = Settings.HOP_TICKS.getInt();
}
@Override
public String getName() {
return "AutoSmelter";
}
@Override
public void run(Hopper hopper, StorageContainerCache.Cache hopperCache) {
if (!isEnabled(hopper)) {
return;
}
int currentTime = getTime(hopper);
if (currentTime == -9999) {
return;
}
int subtract = currentTime - this.hopperTickRate;
if (subtract <= 0) {
for (int i = 0; i < 5; i++) {
final ItemStack itemStack = hopperCache.cachedInventory[i];
if (itemStack == null) {
continue;
}
XMaterial material = CompatibleMaterial.getMaterial(itemStack.getType()).get();
if (!isSmeltable(hopper, material)) {
continue;
}
XMaterial input = CompatibleMaterial.getMaterial(itemStack.getType()).get();
ItemStack result = CompatibleMaterial.getFurnaceResult(input);
if (hopperCache.addItem(result)) {
if (itemStack.getAmount() == 1) {
hopperCache.setItem(i, null);
} else {
itemStack.setAmount(itemStack.getAmount() - 1);
hopperCache.dirty = hopperCache.cacheChanged[i] = true;
}
break;
}
}
modifyDataCache(hopper, "time", this.timeOut);
return;
}
modifyDataCache(hopper, "time", subtract);
}
@Override
public ItemStack getGUIButton(Hopper hopper) {
ItemStack block = XMaterial.IRON_INGOT.parseItem();
ItemMeta blockMeta = block.getItemMeta();
blockMeta.setDisplayName(this.plugin.getLocale().getMessage("interface.hopper.smelttitle").getMessage());
ArrayList<String> loreBlock = new ArrayList<>();
String[] parts = this.plugin.getLocale().getMessage("interface.hopper.smeltlore")
.processPlaceholder("timeleft", getTime(hopper) == -9999 ? "" : (int) Math.floor(getTime(hopper) / 20.0))
.processPlaceholder("enabled", isEnabled(hopper) ?
this.plugin.getLocale().getMessage("general.word.enabled").getMessage() :
this.plugin.getLocale().getMessage("general.word.disabled").getMessage()
)
.getMessage()
.split("\\|");
for (String line : parts) {
loreBlock.add(TextUtils.formatText(line));
}
blockMeta.setLore(loreBlock);
block.setItemMeta(blockMeta);
return block;
}
public void runButtonPress(Player player, Hopper hopper, ClickType type) {
if (type == ClickType.LEFT) {
hopper.setActivePlayer(player);
this.guiManager.showGUI(player, new GUISmeltable(this, this.plugin, hopper));
} else if (type == ClickType.RIGHT) {
toggleEnabled(hopper);
}
}
@Override
public List<Material> getBlockedItems(Hopper hopper) {
if (getTime(hopper) == -9999) {
return Collections.emptyList();
}
List<Material> blockedItems = new ArrayList<>();
for (XMaterial material : XMaterial.values()) {
if (CompatibleMaterial.getFurnaceResult(material) != null && isSmeltable(hopper, material)) {
blockedItems.add(material.parseMaterial());
}
}
return blockedItems;
}
@Override
public String getDescription() {
return this.plugin.getLocale().getMessage("interface.hopper.autosmelt")
.processPlaceholder("ticks", (int) Math.floor(this.timeOut / 20.0)).getMessage();
}
private int getTime(Hopper hopper) {
Object time = getData(hopper, "time");
if (time == null) {
return -9999;
}
return (int) time;
}
private boolean isEnabled(Hopper hopper) {
Object obj = getData(hopper, "time");
if (obj == null) {
return false;
}
return ((int) obj) != -9999;
}
public boolean isSmeltable(Hopper hopper, XMaterial material) {
Object obj = getData(hopper, material.name());
if (obj == null) {
return false;
}
return ((boolean) obj);
}
private void toggleEnabled(Hopper hopper) {
if (isEnabled(hopper)) {
saveData(hopper, "time", -9999);
} else {
saveData(hopper, "time", this.timeOut);
}
}
public void toggleSmeltable(Hopper hopper, XMaterial material) {
saveData(hopper, material.name(), !isSmeltable(hopper, material));
}
}

View File

@ -1,11 +1,14 @@
package com.songoda.epichoppers.hopper.levels.modules;
package com.craftaro.epichoppers.hopper.levels.modules;
import com.songoda.core.compatibility.ServerVersion;
import com.songoda.core.utils.TextUtils;
import com.songoda.epichoppers.EpicHoppers;
import com.songoda.epichoppers.hopper.Hopper;
import com.songoda.epichoppers.settings.Settings;
import com.songoda.epichoppers.utils.StorageContainerCache;
import com.craftaro.core.SongodaPlugin;
import com.craftaro.core.compatibility.ServerVersion;
import com.craftaro.core.gui.GuiManager;
import com.craftaro.core.utils.TextUtils;
import com.craftaro.epichoppers.hopper.Hopper;
import com.craftaro.epichoppers.hopper.HopperImpl;
import com.craftaro.epichoppers.settings.Settings;
import com.craftaro.epichoppers.EpicHoppersApi;
import com.craftaro.epichoppers.utils.StorageContainerCache;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Particle;
@ -25,13 +28,13 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Stream;
public class ModuleBlockBreak extends Module {
private static final Map<Hopper, Boolean> CACHED_BLOCKS = new ConcurrentHashMap<>();
private final int ticksPerBreak;
private final Map<Hopper, Integer> blockTick = new HashMap<>();
private static final Map<Hopper, Boolean> cachedBlocks = new ConcurrentHashMap<>();
public ModuleBlockBreak(EpicHoppers plugin, int amount) {
super(plugin);
public ModuleBlockBreak(SongodaPlugin plugin, GuiManager guiManager, int amount) {
super(plugin, guiManager);
this.ticksPerBreak = amount;
}
@ -42,47 +45,51 @@ public class ModuleBlockBreak extends Module {
@Override
public void run(Hopper hopper, StorageContainerCache.Cache hopperCache) {
if (!isEnabled(hopper))
if (!isEnabled(hopper)) {
return;
}
// don't try to break stuff if we can't grab stuff
// (for simplicity, just assume that no empty slots mean there's a good chance we won't be able to pick something new up)
if (Stream.of(hopperCache.cachedInventory)
.allMatch(item -> item != null && item.getAmount() > 0))
if (Stream.of(hopperCache.cachedInventory).allMatch(item -> item != null && item.getAmount() > 0)) {
return;
}
Integer tick = blockTick.get(hopper);
Integer tick = this.blockTick.get(hopper);
if (tick == null) {
blockTick.put(hopper, 1);
this.blockTick.put(hopper, 1);
return;
} else if (tick < ticksPerBreak) {
blockTick.put(hopper, tick + 1);
} else if (tick < this.ticksPerBreak) {
this.blockTick.put(hopper, tick + 1);
return;
} else {
blockTick.put(hopper, 0);
this.blockTick.put(hopper, 0);
}
Block above = hopper.getLocation().getBlock().getRelative(0, 1, 0);
// Don't break farm items from custom containers
if (plugin.getContainerManager().getCustomContainer(above) != null)
if (EpicHoppersApi.getApi().getContainerManager().getCustomContainer(above) != null) {
return;
}
// don't break blacklisted blocks, fluids, or containers
if (Settings.BLOCKBREAK_BLACKLIST.getStringList().contains(above.getType().name())
|| above.getType() == Material.WATER
|| above.getType() == Material.LAVA
|| above.getType() == Material.AIR)
|| above.getType() == Material.AIR) {
return;
}
if (Settings.ALLOW_BLOCKBREAK_CONTAINERS.getBoolean()
&& above.getState() instanceof InventoryHolder)
&& above.getState() instanceof InventoryHolder) {
return;
}
// Let's break the block!
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_9))
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_9)) {
above.getWorld().playSound(above.getLocation(), Sound.BLOCK_STONE_BREAK, 1F, 1F);
}
Location locationAbove = above.getLocation();
locationAbove.add(.5, .5, .5);
@ -106,35 +113,36 @@ public class ModuleBlockBreak extends Module {
}
}
boolean waterlogged = false;
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13)
boolean waterlogged = ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13)
&& above.getBlockData() instanceof org.bukkit.block.data.Waterlogged
&& ((org.bukkit.block.data.Waterlogged) above.getBlockData()).isWaterlogged()) {
waterlogged = true;
}
&& ((org.bukkit.block.data.Waterlogged) above.getBlockData()).isWaterlogged();
above.breakNaturally(new ItemStack(Material.DIAMOND_PICKAXE));
if (waterlogged)
if (waterlogged) {
above.setType(Material.WATER);
}
}
@Override
public ItemStack getGUIButton(Hopper hopper) {
ItemStack block = new ItemStack(Material.IRON_ORE, 1);
ItemMeta blockmeta = block.getItemMeta();
blockmeta.setDisplayName(plugin.getLocale().getMessage("interface.hopper.blocktitle").getMessage());
ArrayList<String> loreblock = new ArrayList<>();
String[] parts = plugin.getLocale().getMessage("interface.hopper.blocklore")
ItemMeta blockMeta = block.getItemMeta();
blockMeta.setDisplayName(this.plugin.getLocale().getMessage("interface.hopper.blocktitle").getMessage());
ArrayList<String> loreBlock = new ArrayList<>();
String[] parts = this.plugin.getLocale()
.getMessage("interface.hopper.blocklore")
.processPlaceholder("enabled", isEnabled(hopper)
? plugin.getLocale().getMessage("general.word.enabled").getMessage()
: plugin.getLocale().getMessage("general.word.disabled").getMessage())
.getMessage().split("\\|");
? this.plugin.getLocale().getMessage("general.word.enabled").getMessage()
: this.plugin.getLocale().getMessage("general.word.disabled").getMessage()
)
.getMessage()
.split("\\|");
for (String line : parts) {
loreblock.add(TextUtils.formatText(line));
loreBlock.add(TextUtils.formatText(line));
}
blockmeta.setLore(loreblock);
block.setItemMeta(blockmeta);
blockMeta.setLore(loreBlock);
block.setItemMeta(blockMeta);
return block;
}
@ -150,26 +158,26 @@ public class ModuleBlockBreak extends Module {
@Override
public String getDescription() {
return plugin.getLocale().getMessage("interface.hopper.blockbreak")
.processPlaceholder("ticks", ticksPerBreak).getMessage();
return this.plugin.getLocale().getMessage("interface.hopper.blockbreak")
.processPlaceholder("ticks", this.ticksPerBreak).getMessage();
}
@Override
public void clearData(Hopper hopper) {
super.clearData(hopper);
cachedBlocks.remove(hopper);
CACHED_BLOCKS.remove(hopper);
}
public void setEnabled(Hopper hopper, boolean enable) {
saveData(hopper, "blockbreak", enable);
cachedBlocks.put(hopper, enable);
CACHED_BLOCKS.put(hopper, enable);
}
public boolean isEnabled(Hopper hopper) {
Boolean enabled = cachedBlocks.get(hopper);
Boolean enabled = CACHED_BLOCKS.get(hopper);
if (enabled == null) {
Object isBlockBreaking = getData(hopper, "blockbreak");
cachedBlocks.put(hopper, enabled = isBlockBreaking != null && (boolean) isBlockBreaking);
CACHED_BLOCKS.put(hopper, enabled = isBlockBreaking != null && (boolean) isBlockBreaking);
}
return enabled;
}

View File

@ -0,0 +1,106 @@
package com.craftaro.epichoppers.hopper.levels.modules;
import com.craftaro.core.SongodaPlugin;
import com.craftaro.core.gui.GuiManager;
import com.craftaro.core.utils.TextUtils;
import com.craftaro.epichoppers.hopper.Hopper;
import com.craftaro.epichoppers.hopper.HopperImpl;
import com.craftaro.epichoppers.utils.StorageContainerCache;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ModuleMobHopper extends Module {
private final int amount;
private final Map<Block, Integer> blockTick = new HashMap<>();
public ModuleMobHopper(SongodaPlugin plugin, GuiManager guiManager, int amount) {
super(plugin, guiManager);
this.amount = amount;
}
@Override
public String getName() {
return "MobHopper";
}
@Override
public void run(Hopper hopper, StorageContainerCache.Cache hopperCache) {
Block block = hopper.getLocation().getBlock();
if (!this.blockTick.containsKey(block)) {
this.blockTick.put(block, 1);
return;
}
int tick = this.blockTick.get(block);
int put = tick + 1;
this.blockTick.put(block, put);
if (tick < this.amount || !isEnabled(hopper)) {
return;
}
hopper.getLocation().getWorld().getNearbyEntities(hopper.getLocation(), 5, 5, 5).stream()
.filter(entity -> entity instanceof LivingEntity && !(entity instanceof Player) &&
!(entity instanceof ArmorStand)).limit(1).forEach(entity -> {
Location location = hopper.getLocation().add(.5, 1, .5);
if (location.getBlock().getType() != Material.AIR) {
return;
}
entity.teleport(location);
((LivingEntity) entity).damage(99999999);
});
this.blockTick.remove(block);
}
@Override
public ItemStack getGUIButton(Hopper hopper) {
ItemStack block = new ItemStack(Material.ROTTEN_FLESH, 1);
ItemMeta blockMeta = block.getItemMeta();
blockMeta.setDisplayName(this.plugin.getLocale().getMessage("interface.hopper.mobtitle").getMessage());
ArrayList<String> loreBlock = new ArrayList<>();
String[] parts = this.plugin.getLocale().getMessage("interface.hopper.moblore").processPlaceholder("enabled",
isEnabled(hopper) ? this.plugin.getLocale().getMessage("general.word.enabled").getMessage()
: this.plugin.getLocale().getMessage("general.word.disabled").getMessage()).getMessage().split("\\|");
for (String line : parts) {
loreBlock.add(TextUtils.formatText(line));
}
blockMeta.setLore(loreBlock);
block.setItemMeta(blockMeta);
return block;
}
@Override
public void runButtonPress(Player player, Hopper hopper, ClickType type) {
saveData(hopper, "mobhopper", !isEnabled(hopper));
}
@Override
public List<Material> getBlockedItems(Hopper hopper) {
return null;
}
@Override
public String getDescription() {
return this.plugin.getLocale()
.getMessage("interface.hopper.mobhopper")
.processPlaceholder("ticks", this.amount)
.getMessage();
}
public boolean isEnabled(Hopper hopper) {
Object isMobHopper = getData(hopper, "mobhopper");
return isMobHopper != null && (boolean) isMobHopper;
}
}

View File

@ -1,16 +1,20 @@
package com.songoda.epichoppers.hopper.levels.modules;
package com.craftaro.epichoppers.hopper.levels.modules;
import com.bgsoftware.wildstacker.api.WildStackerAPI;
import com.songoda.core.compatibility.CompatibleMaterial;
import com.songoda.core.compatibility.CompatibleParticleHandler;
import com.songoda.core.locale.Locale;
import com.songoda.core.utils.TextUtils;
import com.songoda.epichoppers.EpicHoppers;
import com.songoda.epichoppers.hopper.Hopper;
import com.songoda.epichoppers.settings.Settings;
import com.songoda.epichoppers.utils.Methods;
import com.songoda.epichoppers.utils.StorageContainerCache;
import com.songoda.ultimatestacker.UltimateStacker;
import com.craftaro.core.SongodaPlugin;
import com.craftaro.core.compatibility.CompatibleParticleHandler;
import com.craftaro.core.gui.GuiManager;
import com.craftaro.core.locale.Locale;
import com.craftaro.third_party.com.cryptomorin.xseries.XMaterial;
import com.craftaro.core.utils.TextUtils;
import com.craftaro.epichoppers.hopper.Hopper;
import com.craftaro.epichoppers.hopper.HopperImpl;
import com.craftaro.epichoppers.settings.Settings;
import com.craftaro.epichoppers.utils.Methods;
import com.craftaro.epichoppers.utils.StorageContainerCache;
import com.craftaro.ultimatestacker.api.UltimateStackerApi;
import dev.rosewood.rosestacker.api.RoseStackerAPI;
import dev.rosewood.rosestacker.stack.StackedItem;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.EntityType;
@ -31,16 +35,16 @@ import java.util.UUID;
import java.util.stream.Collectors;
public class ModuleSuction extends Module {
private static final List<UUID> BLACKLIST = new ArrayList<>();
private static final boolean WILD_STACKER = Bukkit.getPluginManager().isPluginEnabled("WildStacker");
private static final boolean ULTIMATE_STACKER = Bukkit.getPluginManager().isPluginEnabled("UltimateStacker");
private static final boolean ROSE_STACKER = Bukkit.getPluginManager().isPluginEnabled("RoseStacker");
private final int maxSearchRadius;
private static List<UUID> blacklist = new ArrayList<>();
private static final boolean wildStacker = Bukkit.getPluginManager().isPluginEnabled("WildStacker");
private static final boolean ultimateStacker = Bukkit.getPluginManager().isPluginEnabled("UltimateStacker");
public ModuleSuction(EpicHoppers plugin, int amount) {
super(plugin);
public ModuleSuction(SongodaPlugin plugin, GuiManager guiManager, int amount) {
super(plugin, guiManager);
this.maxSearchRadius = amount;
}
@ -53,7 +57,9 @@ public class ModuleSuction extends Module {
public void run(Hopper hopper, StorageContainerCache.Cache hopperCache) {
double radius = getRadius(hopper) + .5;
if (!isEnabled(hopper)) return;
if (!isEnabled(hopper)) {
return;
}
Set<Item> itemsToSuck = hopper.getLocation().getWorld().getNearbyEntities(hopper.getLocation().add(0.5, 0.5, 0.5), radius, radius, radius)
.stream()
@ -64,8 +70,9 @@ public class ModuleSuction extends Module {
.map(Item.class::cast)
.collect(Collectors.toSet());
if (itemsToSuck.isEmpty())
if (itemsToSuck.isEmpty()) {
return;
}
boolean filterEndpoint = hopper.getFilter().getEndPoint() != null;
@ -76,7 +83,6 @@ public class ModuleSuction extends Module {
}
for (Item item : itemsToSuck) {
ItemStack itemStack = item.getItemStack();
if (item.getPickupDelay() == 0) {
@ -84,21 +90,23 @@ public class ModuleSuction extends Module {
continue;
}
if (itemStack.getType().name().contains("SHULKER_BOX"))
if (itemStack.getType().name().contains("SHULKER_BOX")) {
return;
}
if (itemStack.hasItemMeta() && itemStack.getItemMeta().hasDisplayName() &&
itemStack.getItemMeta().getDisplayName().startsWith("***")) {
return; //Compatibility with Shop instance: https://www.spigotmc.org/resources/shop-a-simple-intuitive-shop-instance.9628/
}
if (blacklist.contains(item.getUniqueId()))
if (BLACKLIST.contains(item.getUniqueId())) {
return;
}
// respect filter if no endpoint
if (!filterEndpoint
&& !(hopper.getFilter().getWhiteList().isEmpty() && hopper.getFilter().getBlackList().isEmpty())) {
// this hopper has a filter with no rejection endpoint, so don't absorb disalowed items
// this hopper has a filter with no rejection endpoint, so don't absorb disallowed items
// whitelist has priority
if (!hopper.getFilter().getWhiteList().isEmpty()) {
// is this item on the whitelist?
@ -117,28 +125,30 @@ public class ModuleSuction extends Module {
if (Settings.EMIT_INVENTORYPICKUPITEMEVENT.getBoolean()) {
hopperInventory.setContents(hopperCache.cachedInventory);
InventoryPickupItemEvent pickupevent = new InventoryPickupItemEvent(hopperInventory, item);
Bukkit.getPluginManager().callEvent(pickupevent);
if (pickupevent.isCancelled())
InventoryPickupItemEvent pickupEvent = new InventoryPickupItemEvent(hopperInventory, item);
Bukkit.getPluginManager().callEvent(pickupEvent);
if (pickupEvent.isCancelled()) {
continue;
}
}
// try to add the items to the hopper
int toAdd, added = hopperCache.addAny(itemStack, toAdd = getActualItemAmount(item));
if (added == 0)
if (added == 0) {
return;
}
// items added ok!
if (added == toAdd)
if (added == toAdd) {
item.remove();
else {
} else {
// update the item's total
updateAmount(item, toAdd - added);
// wait before trying to add again
blacklist.add(item.getUniqueId());
Bukkit.getScheduler().runTaskLater(EpicHoppers.getInstance(),
() -> blacklist.remove(item.getUniqueId()), 10L);
BLACKLIST.add(item.getUniqueId());
Bukkit.getScheduler().runTaskLater(this.plugin,
() -> BLACKLIST.remove(item.getUniqueId()), 10L);
}
float xx = (float) (0 + (Math.random() * .1));
@ -150,32 +160,37 @@ public class ModuleSuction extends Module {
}
private int getActualItemAmount(Item item) {
if (ultimateStacker) {
return com.songoda.ultimatestacker.utils.Methods.getActualItemAmount(item);
} else if (wildStacker)
if (ULTIMATE_STACKER) {
return UltimateStackerApi.getStackedItemManager().getActualItemAmount(item);
} else if (WILD_STACKER) {
return WildStackerAPI.getItemAmount(item);
else
return item.getItemStack().getAmount();
} else if(ROSE_STACKER) {
StackedItem stackedItem = RoseStackerAPI.getInstance().getStackedItem(item);
if (stackedItem != null) {
return stackedItem.getStackSize();
}
}
return item.getItemStack().getAmount();
}
private void updateAmount(Item item, int amount) {
if (ultimateStacker) {
UltimateStacker.updateItemAmount(item, item.getItemStack(), amount);
} else if (wildStacker)
if (ULTIMATE_STACKER) {
UltimateStackerApi.getStackedItemManager().updateStack(item, amount);
} else if (WILD_STACKER) {
WildStackerAPI.getStackedItem(item).setStackAmount(amount, true);
else
} else {
item.getItemStack().setAmount(Math.min(amount, item.getItemStack().getMaxStackSize()));
}
}
public static boolean isBlacklisted(UUID uuid) {
return blacklist.contains(uuid);
return BLACKLIST.contains(uuid);
}
@Override
public ItemStack getGUIButton(Hopper hopper) {
Locale locale = EpicHoppers.getInstance().getLocale();
ItemStack item = CompatibleMaterial.CAULDRON.getItem();
Locale locale = this.plugin.getLocale();
ItemStack item = XMaterial.CAULDRON.parseItem();
ItemMeta meta = item.getItemMeta();
meta.setDisplayName(locale.getMessage("interface.hopper.suctiontitle").getMessage());
List<String> lore = new ArrayList<>();
@ -196,7 +211,7 @@ public class ModuleSuction extends Module {
toggleEnabled(hopper);
} else if (type == ClickType.RIGHT) {
int setRadius = getRadius(hopper);
if (setRadius >= maxSearchRadius) {
if (setRadius >= this.maxSearchRadius) {
setRadius(hopper, 1);
} else {
setRadius(hopper, ++setRadius);
@ -216,7 +231,7 @@ public class ModuleSuction extends Module {
private int getRadius(Hopper hopper) {
Object foundRadius = getData(hopper, "radius");
return foundRadius == null ? maxSearchRadius : (int) foundRadius;
return foundRadius == null ? this.maxSearchRadius : (int) foundRadius;
}
private void setRadius(Hopper hopper, int radius) {
@ -230,7 +245,9 @@ public class ModuleSuction extends Module {
@Override
public String getDescription() {
return EpicHoppers.getInstance().getLocale().getMessage("interface.hopper.suction")
.processPlaceholder("suction", maxSearchRadius).getMessage();
return this.plugin.getLocale()
.getMessage("interface.hopper.suction")
.processPlaceholder("suction", this.maxSearchRadius)
.getMessage();
}
}

View File

@ -1,11 +1,12 @@
package com.songoda.epichoppers.hopper.teleport;
package com.craftaro.epichoppers.hopper.teleport;
import com.songoda.core.compatibility.CompatibleSound;
import com.songoda.core.compatibility.ServerVersion;
import com.songoda.epichoppers.EpicHoppers;
import com.songoda.epichoppers.hopper.Hopper;
import com.songoda.epichoppers.settings.Settings;
import com.songoda.epichoppers.utils.Methods;
import com.craftaro.core.compatibility.ServerVersion;
import com.craftaro.third_party.com.cryptomorin.xseries.XSound;
import com.craftaro.epichoppers.EpicHoppers;
import com.craftaro.epichoppers.hopper.Hopper;
import com.craftaro.epichoppers.hopper.HopperImpl;
import com.craftaro.epichoppers.settings.Settings;
import com.craftaro.epichoppers.utils.Methods;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
@ -20,45 +21,65 @@ import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class TeleportHandler {
public class TeleportHandlerImpl implements TeleportHandler {
private final Map<UUID, Long> lastTeleports = new HashMap<>();
private final EpicHoppers plugin;
public TeleportHandler(EpicHoppers plugin) {
public TeleportHandlerImpl(EpicHoppers plugin) {
this.plugin = plugin;
Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, this::teleportRunner, 0,
Settings.TELEPORT_TICKS.getLong());
Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, this::teleportRunner, 0, Settings.TELEPORT_TICKS.getLong());
}
@Override
public void tpEntity(Entity entity, Hopper hopper) {
if (hopper == null || !this.plugin.getHopperManager().isHopper(hopper.getLocation())) {
return;
}
Hopper lastHopper = this.getChain(hopper, 1);
if (!hopper.equals(lastHopper)) {
this.doTeleport(entity, lastHopper.getLocation());
}
}
private void teleportRunner() {
if (!plugin.getHopperManager().isReady())
if (!this.plugin.getHopperManager().isReady()) {
return;
}
for (World world : Bukkit.getWorlds()) {
for (Entity entity : world.getEntities()) {
if (!(entity instanceof LivingEntity) || entity.getType() == EntityType.ARMOR_STAND)
if (!(entity instanceof LivingEntity) || entity.getType() == EntityType.ARMOR_STAND) {
continue;
}
if (!Settings.TELEPORT.getBoolean()
|| (entity instanceof Player && !entity.hasPermission("EpicHoppers.Teleport")))
|| (entity instanceof Player && !entity.hasPermission("EpicHoppers.Teleport"))) {
continue;
}
Location location = entity.getLocation().getBlock().getRelative(BlockFace.DOWN).getLocation();
if (!this.plugin.getHopperManager().isHopper(location))
if (!this.plugin.getHopperManager().isHopper(location)) {
continue;
}
Hopper hopper = this.plugin.getHopperManager().getHopper(location);
HopperImpl hopper = this.plugin.getHopperManager().getHopper(location, null);
if (hopper.getTeleportTrigger() != TeleportTrigger.WALK_ON)
if (hopper == null) {
continue;
}
if (hopper.getTeleportTrigger() != TeleportTrigger.WALK_ON) {
continue;
}
if (this.lastTeleports.containsKey(entity.getUniqueId())) {
long duration = (new Date()).getTime() - new Date(this.lastTeleports.get(entity.getUniqueId())).getTime();
if (duration <= 5 * 1000)
if (duration <= 5 * 1000) {
continue;
}
}
this.tpEntity(entity, hopper);
@ -67,15 +88,6 @@ public class TeleportHandler {
}
}
public void tpEntity(Entity entity, Hopper hopper) {
if (hopper == null || !this.plugin.getHopperManager().isHopper(hopper.getLocation()))
return;
Hopper lastHopper = this.getChain(hopper, 1);
if (!hopper.equals(lastHopper))
this.doTeleport(entity, lastHopper.getLocation());
}
/**
* Recursively gets the next hopper in the linked hopper chain
*
@ -84,14 +96,16 @@ public class TeleportHandler {
* @return The hopper at the end of the chain (or up to 15 in depth)
*/
private Hopper getChain(Hopper lastHopper, int currentChainLength) {
if (currentChainLength > 15)
if (currentChainLength > 15) {
return lastHopper;
}
for (Location nextHopperLocation : lastHopper.getLinkedBlocks()) {
if (nextHopperLocation.getBlock().getState() instanceof org.bukkit.block.Hopper) {
Hopper hopper = this.plugin.getHopperManager().getHopper(nextHopperLocation);
if (hopper != null)
Hopper hopper = this.plugin.getHopperManager().getHopper(nextHopperLocation, null);
if (hopper != null) {
return this.getChain(hopper, currentChainLength + 1);
}
}
}
@ -110,6 +124,6 @@ public class TeleportHandler {
entity.teleport(location);
CompatibleSound.ENTITY_ENDERMAN_TELEPORT.play(entity.getWorld(), entity.getLocation(), 10, 10);
XSound.ENTITY_ENDERMAN_TELEPORT.play(entity.getLocation(), 10, 10);
}
}

View File

@ -0,0 +1,188 @@
package com.craftaro.epichoppers.listeners;
import com.craftaro.core.compatibility.ServerVersion;
import com.craftaro.epichoppers.EpicHoppers;
import com.craftaro.epichoppers.api.events.HopperBreakEvent;
import com.craftaro.epichoppers.api.events.HopperPlaceEvent;
import com.craftaro.epichoppers.gui.GUIAutoSellFilter;
import com.craftaro.epichoppers.gui.GUIFilter;
import com.craftaro.epichoppers.hopper.HopperImpl;
import com.craftaro.epichoppers.hopper.HopperBuilder;
import com.craftaro.epichoppers.hopper.levels.Level;
import com.craftaro.epichoppers.settings.Settings;
import com.craftaro.epichoppers.utils.DataHelper;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
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.BlockBreakEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.permissions.PermissionAttachmentInfo;
import java.util.Objects;
public class BlockListeners implements Listener {
private final EpicHoppers plugin;
private static final boolean hasMinHeight = ServerVersion.isServerVersionAtLeast(ServerVersion.V1_16);
public BlockListeners(EpicHoppers plugin) {
this.plugin = plugin;
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onBlockPlace(BlockPlaceEvent e) {
Player player = e.getPlayer();
if (e.getBlock().getType() != Material.HOPPER) {
return;
}
if (Settings.DISABLED_WORLDS.getStringList().contains(player.getWorld().getName())) {
return;
}
int amt = count(e.getBlock().getChunk());
int max = maxHoppers(player);
if (max != -1 && amt > max) {
player.sendMessage(this.plugin.getLocale().getMessage("event.hopper.toomany").processPlaceholder("amount", max).getMessage());
e.setCancelled(true);
return;
}
ItemStack item = e.getItemInHand().clone();
if (Settings.ALLOW_NORMAL_HOPPERS.getBoolean() && !this.plugin.getLevelManager().isEpicHopper(item)) {
return;
}
if (!this.plugin.getHopperManager().isReady()) {
player.sendMessage(this.plugin.getLocale().getMessage("event.hopper.notready").getMessage());
e.setCancelled(true);
return;
}
HopperImpl hopper = this.plugin.getHopperManager().addHopper(
new HopperBuilder(e.getBlock(), player.getUniqueId())
.setLevel(this.plugin.getLevelManager().getLevel(item))
.setLastPlayerOpened(player).build());
HopperPlaceEvent hopperPlaceEvent = new HopperPlaceEvent(player, hopper);
Bukkit.getPluginManager().callEvent(hopperPlaceEvent);
this.plugin.getDataManager().save(hopper);
}
private int maxHoppers(Player player) {
int limit = -1;
for (PermissionAttachmentInfo permissionAttachmentInfo : player.getEffectivePermissions()) {
if (!permissionAttachmentInfo.getPermission().toLowerCase().startsWith("epichoppers.limit")) {
continue;
}
int num = Integer.parseInt(permissionAttachmentInfo.getPermission().split("\\.")[2]);
if (num > limit) {
limit = num;
}
}
if (limit == -1) {
limit = Settings.MAX_CHUNK.getInt();
}
return limit;
}
private int count(Chunk chunk) {
int count = 0;
for (int x = 0; x < 16; x++) {
for (int z = 0; z < 16; z++) {
for (int y = getMinHeight(chunk.getWorld()); y < chunk.getWorld().getMaxHeight(); y++) {
if (chunk.getBlock(x, y, z).getType() == Material.HOPPER) {
count++;
}
}
}
}
return count;
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onBlockBreak(BlockBreakEvent event) {
Block block = event.getBlock();
Player player = event.getPlayer();
if (event.getBlock().getType() != Material.HOPPER) {
return;
}
if (!this.plugin.getHopperManager().isReady()) {
player.sendMessage(this.plugin.getLocale().getMessage("event.hopper.notready").getMessage());
event.setCancelled(true);
return;
}
if (!this.plugin.getHopperManager().isHopper(block.getLocation())) {
return;
}
HopperImpl hopper = this.plugin.getHopperManager().getHopper(block, player.getUniqueId());
GUIFilter.compileOpenGuiFilter(hopper);
GUIAutoSellFilter.compileOpenAutoSellFilter(hopper);
Level level = hopper.getLevel();
if (level.getLevel() > 1 || Settings.ALLOW_NORMAL_HOPPERS.getBoolean()) {
HopperBreakEvent hopperBreakEvent = new HopperBreakEvent(player, hopper);
Bukkit.getPluginManager().callEvent(hopperBreakEvent);
event.setCancelled(true);
ItemStack item = this.plugin.newHopperItem(level);
hopper.dropItems();
event.getBlock().setType(Material.AIR);
event.getBlock().getLocation().getWorld().dropItemNaturally(event.getBlock().getLocation(), item);
}
hopper.forceClose();
hopper.getFilter().getWhiteList()
.stream()
.filter(Objects::nonNull)
.forEach(item -> event.getBlock().getWorld().dropItemNaturally(event.getBlock().getLocation(), item));
hopper.getFilter().getBlackList()
.stream()
.filter(Objects::nonNull)
.forEach(item -> event.getBlock().getWorld().dropItemNaturally(event.getBlock().getLocation(), item));
hopper.getFilter().getVoidList()
.stream()
.filter(Objects::nonNull)
.forEach(item -> event.getBlock().getWorld().dropItemNaturally(event.getBlock().getLocation(), item));
hopper.getFilter().getAutoSellWhiteList()
.stream()
.filter(Objects::nonNull)
.forEach(item -> event.getBlock().getWorld().dropItemNaturally(event.getBlock().getLocation(), item));
hopper.getFilter().getAutoSellBlackList()
.stream()
.filter(Objects::nonNull)
.forEach(item -> event.getBlock().getWorld().dropItemNaturally(event.getBlock().getLocation(), item));
this.plugin.getHopperManager().removeHopper(block.getLocation());
this.plugin.getDataManager().delete(hopper);
DataHelper.deleteLinks(hopper);
DataHelper.deleteItems(hopper);
this.plugin.getPlayerDataManager().getPlayerData(player).setSyncType(null);
}
public int getMinHeight(World world) {
return hasMinHeight ? world.getMinHeight() : 0;
}
}

View File

@ -1,16 +1,16 @@
package com.songoda.epichoppers.listeners;
package com.craftaro.epichoppers.listeners;
import com.songoda.epichoppers.hopper.levels.modules.ModuleSuction;
import com.craftaro.epichoppers.hopper.levels.modules.ModuleSuction;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerPickupItemEvent;
public class EntityListeners implements Listener {
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onPlayerPickup(PlayerPickupItemEvent event) {
if (ModuleSuction.isBlacklisted(event.getItem().getUniqueId()))
if (ModuleSuction.isBlacklisted(event.getItem().getUniqueId())) {
event.setCancelled(true);
}
}
}

View File

@ -1,14 +1,14 @@
package com.songoda.epichoppers.listeners;
package com.craftaro.epichoppers.listeners;
import com.songoda.core.compatibility.ServerVersion;
import com.songoda.core.nms.NmsManager;
import com.songoda.epichoppers.EpicHoppers;
import com.songoda.epichoppers.hopper.Hopper;
import com.songoda.epichoppers.hopper.levels.modules.Module;
import com.songoda.epichoppers.hopper.levels.modules.ModuleAutoCrafting;
import com.songoda.epichoppers.settings.Settings;
import com.songoda.epichoppers.utils.HopperDirection;
import com.songoda.epichoppers.utils.Methods;
import com.craftaro.core.compatibility.ServerVersion;
import com.craftaro.core.nms.NmsManager;
import com.craftaro.epichoppers.hopper.HopperImpl;
import com.craftaro.epichoppers.settings.Settings;
import com.craftaro.epichoppers.EpicHoppers;
import com.craftaro.epichoppers.hopper.levels.modules.Module;
import com.craftaro.epichoppers.hopper.levels.modules.ModuleAutoCrafting;
import com.craftaro.epichoppers.utils.HopperDirection;
import com.craftaro.epichoppers.utils.Methods;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.BlockState;
@ -20,11 +20,7 @@ import org.bukkit.event.inventory.InventoryMoveItemEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
/**
* Created by songoda on 4/18/2017.
*/
public class HopperListeners implements Listener {
private final EpicHoppers plugin;
public HopperListeners(EpicHoppers plugin) {
@ -40,15 +36,17 @@ public class HopperListeners implements Listener {
Location sourceLocation = source.getHolder() instanceof BlockState ? ((BlockState) source.getHolder()).getLocation() : null;
Location destinationLocation = destination.getHolder() instanceof BlockState ? ((BlockState) destination.getHolder()).getLocation() : null;
if (sourceLocation != null && Settings.ALLOW_NORMAL_HOPPERS.getBoolean() && !plugin.getHopperManager().isHopper(sourceLocation))
if (sourceLocation != null && Settings.ALLOW_NORMAL_HOPPERS.getBoolean() && !this.plugin.getHopperManager().isHopper(sourceLocation)) {
return;
}
// Hopper minecarts should be able to take care of themselves
// HopperImpl minecarts should be able to take care of themselves
// Let EpicHoppers take over if the hopper is pointing down though
if (destination.getHolder() instanceof HopperMinecart
&& source.getHolder() instanceof org.bukkit.block.Hopper
&& HopperDirection.getDirection(((org.bukkit.block.Hopper) source.getHolder()).getRawData()) != HopperDirection.DOWN)
&& HopperDirection.getDirection(((org.bukkit.block.Hopper) source.getHolder()).getRawData()) != HopperDirection.DOWN) {
return;
}
// Shulker boxes have a mind of their own and relentlessly steal items from hoppers
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_11)
@ -58,7 +56,7 @@ public class HopperListeners implements Listener {
return;
}
// Hopper going into minecarts
// HopperImpl going into minecarts
if (destination.getHolder() instanceof Minecart && source.getHolder() instanceof org.bukkit.block.Hopper) {
event.setCancelled(true);
return;
@ -66,14 +64,16 @@ public class HopperListeners implements Listener {
// Special cases when a hopper is picking up items
if (destination.getHolder() instanceof org.bukkit.block.Hopper) {
if (destinationLocation != null && Settings.ALLOW_NORMAL_HOPPERS.getBoolean() && !plugin.getHopperManager().isHopper(destinationLocation))
if (destinationLocation != null && Settings.ALLOW_NORMAL_HOPPERS.getBoolean() && !this.plugin.getHopperManager().isHopper(destinationLocation)) {
return;
}
// Calling HopperManager#getHopper() automatically creates a new Hopper and we don't need to iterate over default-valued hoppers
if (!plugin.getHopperManager().isHopper(destinationLocation))
// Calling HopperManager#getHopper() automatically creates a new HopperImpl and we don't need to iterate over default-valued hoppers
if (!this.plugin.getHopperManager().isHopper(destinationLocation)) {
return;
}
Hopper toHopper = plugin.getHopperManager().getHopper(destinationLocation);
HopperImpl toHopper = this.plugin.getHopperManager().getHopper(destinationLocation, null);
// minecraft 1.8 doesn't have a method to get the hopper's location from the inventory, so we use the holder instead
final ItemStack toMove = event.getItem();
@ -153,11 +153,13 @@ public class HopperListeners implements Listener {
}
}
if (!(source.getHolder() instanceof org.bukkit.block.Hopper))
if (!(source.getHolder() instanceof org.bukkit.block.Hopper)) {
return;
}
if (destinationLocation == null)
if (destinationLocation == null) {
return;
}
// Handle hopper push events elsewhere
event.setCancelled(true);

View File

@ -1,14 +1,16 @@
package com.songoda.epichoppers.listeners;
package com.craftaro.epichoppers.listeners;
import com.songoda.core.hooks.ProtectionManager;
import com.songoda.core.hooks.WorldGuardHook;
import com.songoda.epichoppers.EpicHoppers;
import com.songoda.epichoppers.hopper.Hopper;
import com.songoda.epichoppers.hopper.teleport.TeleportTrigger;
import com.songoda.epichoppers.player.PlayerData;
import com.songoda.epichoppers.player.SyncType;
import com.songoda.epichoppers.settings.Settings;
import com.songoda.skyblock.SkyBlock;
import com.craftaro.core.hooks.ProtectionManager;
import com.craftaro.core.hooks.WorldGuardHook;
import com.craftaro.epichoppers.hopper.Hopper;
import com.craftaro.epichoppers.settings.Settings;
import com.craftaro.epichoppers.EpicHoppers;
import com.craftaro.epichoppers.gui.GUIOverview;
import com.craftaro.epichoppers.hopper.HopperImpl;
import com.craftaro.epichoppers.hopper.teleport.TeleportTrigger;
import com.craftaro.epichoppers.player.PlayerData;
import com.craftaro.epichoppers.player.SyncType;
import com.craftaro.skyblock.SkyBlock;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
@ -22,11 +24,7 @@ import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerToggleSneakEvent;
import org.bukkit.inventory.InventoryHolder;
/**
* Created by songoda on 3/14/2017.
*/
public class InteractListeners implements Listener {
private final EpicHoppers plugin;
public InteractListeners(EpicHoppers plugin) {
@ -36,17 +34,19 @@ public class InteractListeners implements Listener {
@EventHandler
public void onPlayerToggleSneakEvent(PlayerToggleSneakEvent event) {
Player player = event.getPlayer();
if (player.isSneaking() && plugin.getHopperManager().isReady()) {
if (player.isSneaking() && this.plugin.getHopperManager().isReady()) {
Location location = player.getLocation().getBlock().getRelative(BlockFace.SELF).getLocation();
Location down = location.getBlock().getRelative(BlockFace.DOWN).getLocation();
if (plugin.getHopperManager().isHopper(down)) {
Hopper hopper = plugin.getHopperManager().getHopper(down);
if (hopper.getTeleportTrigger() == TeleportTrigger.SNEAK)
plugin.getTeleportHandler().tpEntity(player, hopper);
} else if (plugin.getHopperManager().isHopper(location)) {
Hopper hopper = plugin.getHopperManager().getHopper(location);
if (hopper.getTeleportTrigger() == TeleportTrigger.SNEAK)
plugin.getTeleportHandler().tpEntity(player, hopper);
if (this.plugin.getHopperManager().isHopper(down)) {
HopperImpl hopper = this.plugin.getHopperManager().getHopper(down, player.getUniqueId());
if (hopper.getTeleportTrigger() == TeleportTrigger.SNEAK) {
this.plugin.getTeleportHandler().tpEntity(player, hopper);
}
} else if (this.plugin.getHopperManager().isHopper(location)) {
HopperImpl hopper = this.plugin.getHopperManager().getHopper(location, player.getUniqueId());
if (hopper.getTeleportTrigger() == TeleportTrigger.SNEAK) {
this.plugin.getTeleportHandler().tpEntity(player, hopper);
}
}
}
}
@ -58,12 +58,12 @@ public class InteractListeners implements Listener {
|| event.getClickedBlock() == null
|| player.isSneaking()
|| !player.hasPermission("EpicHoppers.overview")
|| !(event.getClickedBlock().getState() instanceof InventoryHolder || event.getClickedBlock().getType().equals(Material.ENDER_CHEST))) {
|| !(event.getClickedBlock().getState() instanceof InventoryHolder || event.getClickedBlock().getType() == Material.ENDER_CHEST)) {
return;
}
if (Settings.USE_PROTECTION_PLUGINS.getBoolean() && ProtectionManager.canInteract(player, event.getClickedBlock().getLocation()) && WorldGuardHook.isInteractAllowed(event.getClickedBlock().getLocation())) {
player.sendMessage(plugin.getLocale().getMessage("event.general.protected").getPrefixedMessage());
player.sendMessage(this.plugin.getLocale().getMessage("event.general.protected").getPrefixedMessage());
return;
}
@ -71,26 +71,30 @@ public class InteractListeners implements Listener {
SkyBlock skyBlock = SkyBlock.getInstance();
if (skyBlock.getWorldManager().isIslandWorld(event.getPlayer().getWorld()) &&
!skyBlock.getPermissionManager().hasPermission(event.getPlayer(), skyBlock.getIslandManager().getIslandAtLocation(event.getClickedBlock().getLocation()), "EpicHoppers"))
!skyBlock.getPermissionManager().hasPermission(event.getPlayer(), skyBlock.getIslandManager().getIslandAtLocation(event.getClickedBlock().getLocation()), "EpicHoppers")) {
return;
}
}
PlayerData playerData = plugin.getPlayerDataManager().getPlayerData(player);
PlayerData playerData = this.plugin.getPlayerDataManager().getPlayerData(player);
if (playerData.getSyncType() == null) {
if (event.getClickedBlock().getType() == Material.HOPPER) {
if (!plugin.getHopperManager().isReady()) {
player.sendMessage(plugin.getLocale().getMessage("event.hopper.notready").getMessage());
if (!this.plugin.getHopperManager().isReady()) {
player.sendMessage(this.plugin.getLocale().getMessage("event.hopper.notready").getMessage());
event.setCancelled(true);
return;
}
if (Settings.ALLOW_NORMAL_HOPPERS.getBoolean() && !plugin.getHopperManager().isHopper(event.getClickedBlock().getLocation()))
if (Settings.ALLOW_NORMAL_HOPPERS.getBoolean() && !this.plugin.getHopperManager().isHopper(event.getClickedBlock().getLocation())) {
return;
}
Hopper hopper = plugin.getHopperManager().getHopper(event.getClickedBlock());
HopperImpl hopper = this.plugin.getHopperManager().getHopper(event.getClickedBlock(), player.getUniqueId());
if (!player.getInventory().getItemInHand().getType().name().contains("PICKAXE")) {
hopper.overview(plugin.getGuiManager(), player);
if (hopper.prepareForOpeningOverviewGui(player)) {
this.plugin.getGuiManager().showGUI(player, new GUIOverview(this.plugin, hopper, player));
}
event.setCancelled(true);
return;
}
@ -98,15 +102,14 @@ public class InteractListeners implements Listener {
return;
}
if (event.getClickedBlock().getState() instanceof InventoryHolder
|| (event.getClickedBlock().getType().equals(Material.ENDER_CHEST)
&& Settings.ENDERCHESTS.getBoolean())) {
Hopper hopper = playerData.getLastHopper();
if (event.getClickedBlock().getState() instanceof InventoryHolder ||
(event.getClickedBlock().getType() == Material.ENDER_CHEST && Settings.ENDERCHESTS.getBoolean())) {
HopperImpl hopper = (HopperImpl) playerData.getLastHopper();
if (event.getClickedBlock().getLocation().equals(playerData.getLastHopper().getLocation())) {
if (!hopper.getLinkedBlocks().isEmpty()) {
plugin.getLocale().getMessage("event.hopper.syncfinish").sendPrefixedMessage(player);
this.plugin.getLocale().getMessage("event.hopper.syncfinish").sendPrefixedMessage(player);
} else {
plugin.getLocale().getMessage("event.hopper.synccanceled").sendPrefixedMessage(player);
this.plugin.getLocale().getMessage("event.hopper.synccanceled").sendPrefixedMessage(player);
}
hopper.cancelSync(player);
} else if (playerData.getSyncType() != null) {

View File

@ -0,0 +1,31 @@
package com.craftaro.epichoppers.listeners;
import org.bukkit.Material;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryAction;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.ItemStack;
public class InventoryListeners implements Listener {
@EventHandler
public void onInventoryClick(InventoryClickEvent event) {
if (event.getCurrentItem() == null ||
event.getRawSlot() > event.getView().getTopInventory().getSize() - 1 ||
!event.getCurrentItem().hasItemMeta()) {
return;
}
if (event.getSlot() == 64537 ||
event.getInventory().getType() != InventoryType.ANVIL ||
event.getAction() == InventoryAction.NOTHING ||
event.getCurrentItem().getType() == Material.AIR) {
return;
}
ItemStack item = event.getCurrentItem();
if (item.getType() == Material.HOPPER) {
event.setCancelled(true);
}
}
}

View File

@ -1,4 +1,4 @@
package com.songoda.epichoppers.player;
package com.craftaro.epichoppers.player;
import org.bukkit.entity.Player;
@ -8,19 +8,20 @@ import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class PlayerDataManager {
public class PlayerDataManagerImpl implements PlayerDataManager {
private final Map<UUID, PlayerData> registeredPlayers = new HashMap<>();
private PlayerData getPlayerData(UUID uuid) {
return registeredPlayers.computeIfAbsent(uuid, u -> new PlayerData());
return this.registeredPlayers.computeIfAbsent(uuid, u -> new PlayerData());
}
@Override
public PlayerData getPlayerData(Player player) {
return getPlayerData(player.getUniqueId());
}
@Override
public Collection<PlayerData> getRegisteredPlayers() {
return Collections.unmodifiableCollection(registeredPlayers.values());
return Collections.unmodifiableCollection(this.registeredPlayers.values());
}
}

View File

@ -1,157 +1,155 @@
package com.songoda.epichoppers.settings;
package com.craftaro.epichoppers.settings;
import com.songoda.core.compatibility.CompatibleMaterial;
import com.songoda.core.configuration.Config;
import com.songoda.core.configuration.ConfigSetting;
import com.songoda.core.hooks.EconomyManager;
import com.songoda.epichoppers.EpicHoppers;
import com.craftaro.core.compatibility.CompatibleMaterial;
import com.craftaro.core.configuration.Config;
import com.craftaro.core.configuration.ConfigSetting;
import com.craftaro.core.hooks.EconomyManager;
import com.craftaro.epichoppers.EpicHoppers;
import java.util.Arrays;
import java.util.stream.Collectors;
public class Settings {
private static final Config CONFIG = EpicHoppers.getPlugin(EpicHoppers.class).getCoreConfig();
private static final Config config = EpicHoppers.getInstance().getCoreConfig();
public static final ConfigSetting HOPPER_UPGRADING = new ConfigSetting(config, "Main.Allow hopper Upgrading", true,
public static final ConfigSetting HOPPER_UPGRADING = new ConfigSetting(CONFIG, "Main.Allow hopper Upgrading", true,
"Should hoppers be upgradable?");
public static final ConfigSetting UPGRADE_WITH_ECONOMY = new ConfigSetting(config, "Main.Upgrade With Economy", true,
public static final ConfigSetting UPGRADE_WITH_ECONOMY = new ConfigSetting(CONFIG, "Main.Upgrade With Economy", true,
"Should you be able to upgrade hoppers with economy?");
public static final ConfigSetting UPGRADE_WITH_XP = new ConfigSetting(config, "Main.Upgrade With XP", true,
public static final ConfigSetting UPGRADE_WITH_XP = new ConfigSetting(CONFIG, "Main.Upgrade With XP", true,
"Should you be able to upgrade hoppers with experience?");
public static final ConfigSetting ALLOW_NORMAL_HOPPERS = new ConfigSetting(config, "Main.Allow Normal Hoppers", false,
public static final ConfigSetting ALLOW_NORMAL_HOPPERS = new ConfigSetting(CONFIG, "Main.Allow Normal Hoppers", false,
"Should natural hoppers not be epic hoppers?");
public static final ConfigSetting DISABLED_WORLDS = new ConfigSetting(config, "Main.Disabled Worlds",
public static final ConfigSetting DISABLED_WORLDS = new ConfigSetting(CONFIG, "Main.Disabled Worlds",
Arrays.asList("example1", "example2"),
"Worlds where epic hoppers cannot be placed.",
"Any placed Epic Hopper will just be converted to a normal one.");
"Any placed Epic HopperImpl will just be converted to a normal one.");
public static final ConfigSetting TELEPORT = new ConfigSetting(config, "Main.Allow Players To Teleport Through Hoppers", true,
public static final ConfigSetting TELEPORT = new ConfigSetting(CONFIG, "Main.Allow Players To Teleport Through Hoppers", true,
"Should players be able to teleport through hoppers?");
public static final ConfigSetting ENDERCHESTS = new ConfigSetting(config, "Main.Support Enderchests", true,
public static final ConfigSetting ENDERCHESTS = new ConfigSetting(CONFIG, "Main.Support Enderchests", true,
"Should hoppers dump items into a player enderchests?");
public static final ConfigSetting UPGRADE_PARTICLE_TYPE = new ConfigSetting(config, "Main.Upgrade Particle Type", "SPELL_WITCH",
public static final ConfigSetting UPGRADE_PARTICLE_TYPE = new ConfigSetting(CONFIG, "Main.Upgrade Particle Type", "SPELL_WITCH",
"The type of particle shown when a hopper is upgraded.");
public static final ConfigSetting HOP_TICKS = new ConfigSetting(config, "Main.Amount of Ticks Between Hops", 8L,
public static final ConfigSetting HOP_TICKS = new ConfigSetting(CONFIG, "Main.Amount of Ticks Between Hops", 8L,
"The amount of ticks between hopper transfers.");
public static final ConfigSetting AUTOSAVE = new ConfigSetting(config, "Main.Auto Save Interval In Seconds", 15,
public static final ConfigSetting AUTOSAVE = new ConfigSetting(CONFIG, "Main.Auto Save Interval In Seconds", 15,
"The amount of time in between saving to file.",
"This is purely a safety function to prevent against unplanned crashes or",
"restarts. With that said it is advised to keep this enabled.",
"If however you enjoy living on the edge, feel free to turn it off.");
public static final ConfigSetting TELEPORT_TICKS = new ConfigSetting(config, "Main.Amount of Ticks Between Teleport", 10L,
public static final ConfigSetting TELEPORT_TICKS = new ConfigSetting(CONFIG, "Main.Amount of Ticks Between Teleport", 10L,
"The cooldown between teleports. It prevents players",
"from getting stuck in a teleport loop.");
public static final ConfigSetting LINK_TIMEOUT = new ConfigSetting(config, "Main.Timeout When Syncing Hoppers", 300L,
public static final ConfigSetting LINK_TIMEOUT = new ConfigSetting(CONFIG, "Main.Timeout When Syncing Hoppers", 300L,
"The amount of time in ticks a player has between hitting the hopper",
"Link button and performing the link. When the time is up the link event is canceled.");
public static final ConfigSetting MAX_CHUNK = new ConfigSetting(config, "Main.Max Hoppers Per Chunk", -1,
public static final ConfigSetting MAX_CHUNK = new ConfigSetting(CONFIG, "Main.Max Hoppers Per Chunk", -1,
"The maximum amount of hoppers per chunk.");
public static final ConfigSetting USE_PROTECTION_PLUGINS = new ConfigSetting(config, "Main.Use Protection Plugins", true,
public static final ConfigSetting USE_PROTECTION_PLUGINS = new ConfigSetting(CONFIG, "Main.Use Protection Plugins", true,
"Should we use protection plugins?");
public static final ConfigSetting BLOCKBREAK_PARTICLE = new ConfigSetting(config, "Main.BlockBreak Particle Type", "LAVA",
public static final ConfigSetting BLOCKBREAK_PARTICLE = new ConfigSetting(CONFIG, "Main.BlockBreak Particle Type", "LAVA",
"The particle shown when the block break module performs a block break.");
public static final ConfigSetting BLOCKBREAK_BLACKLIST = new ConfigSetting(config, "Main.BlockBreak Blacklisted Blocks",
public static final ConfigSetting BLOCKBREAK_BLACKLIST = new ConfigSetting(CONFIG, "Main.BlockBreak Blacklisted Blocks",
Arrays.asList("BEDROCK", "END_PORTAL", "ENDER_PORTAL", "END_PORTAL_FRAME", "ENDER_PORTAL_FRAME", "PISTON_HEAD", "PISTON_EXTENSION", "RAIL", "RAILS", "ACTIVATOR_RAIL", "DETECTOR_RAIL", "POWERED_RAIL"),
"Anything listed here will not be broken by the block break module.");
public static final ConfigSetting ALLOW_BLOCKBREAK_CONTAINERS = new ConfigSetting(config, "Main.Allow BlockBreak Containers", false,
public static final ConfigSetting ALLOW_BLOCKBREAK_CONTAINERS = new ConfigSetting(CONFIG, "Main.Allow BlockBreak Containers", false,
"Allow BlockBreak to break containers.");
public static final ConfigSetting AUTOCRAFT_JAM_EJECT = new ConfigSetting(config, "Main.AutoCraft Jam Eject", false,
public static final ConfigSetting AUTOCRAFT_JAM_EJECT = new ConfigSetting(CONFIG, "Main.AutoCraft Jam Eject", false,
"AutoCraft module needs a free slot to craft items with.",
"Normally, crafting hoppers won't grab items that would fill that slot.",
"This option ejects items if that last slot is forcibly filled");
public static final ConfigSetting AUTOCRAFT_BLACKLIST = new ConfigSetting(config, "Main.AutoCraft Blacklist", Arrays.asList("BEDROCK", "EGG"),
public static final ConfigSetting AUTOCRAFT_BLACKLIST = new ConfigSetting(CONFIG, "Main.AutoCraft Blacklist", Arrays.asList("BEDROCK", "EGG"),
"Anything listed here will not be able to be auto crafted.");
public static final ConfigSetting AUTOSELL_PRICES = new ConfigSetting(config, "Main.AutoSell Prices",
public static final ConfigSetting AUTOSELL_PRICES = new ConfigSetting(CONFIG, "Main.AutoSell Prices",
Arrays.asList("STONE,0.50", "COBBLESTONE,0.20", "IRON_ORE,0.35", "COAL_ORE,0.20"),
"These are the prices used by the auto sell module.");
public static final ConfigSetting AUTOSELL_SHOPGUIPLUS = new ConfigSetting(config, "Main.Use ShopGuiPlus for Prices", false,
public static final ConfigSetting AUTOSELL_SHOPGUIPLUS = new ConfigSetting(CONFIG, "Main.Use ShopGuiPlus for Prices", false,
"Should prices be grabbed from ShopGuiPlus?",
"If ShopGuiPlus is not enabled or the player is offline the default price list will be used (or EconomyShopGUI if enabled).",
"If this is something that you do not want then you should empty the default list.");
public static final ConfigSetting AUTOSELL_ECONOMY_SHOP_GUI = new ConfigSetting(config, "Main.Use EconomyShopGUI for Prices", false,
public static final ConfigSetting AUTOSELL_ECONOMY_SHOP_GUI = new ConfigSetting(CONFIG, "Main.Use EconomyShopGUI for Prices", false,
"Should prices be grabbed from EconomyShopGUI?",
"If 'Use ShopGuiPlus for Prices' is enabled and the player is online, this will be ignored.");
public static final ConfigSetting ECONOMY_PLUGIN = new ConfigSetting(config, "Main.Economy", EconomyManager.getEconomy() == null ? "Vault" : EconomyManager.getEconomy().getName(),
public static final ConfigSetting ECONOMY_PLUGIN = new ConfigSetting(CONFIG, "Main.Economy", EconomyManager.getEconomy() == null ? "Vault" : EconomyManager.getEconomy().getName(),
"Which economy plugin should be used?",
"Supported plugins you have installed: \"" + EconomyManager.getManager().getRegisteredPlugins().stream().collect(Collectors.joining("\", \"")) + "\".");
public static final ConfigSetting EMIT_INVENTORYPICKUPITEMEVENT = new ConfigSetting(config, "Main.Emit InventoryPickupItemEvent", false,
public static final ConfigSetting EMIT_INVENTORYPICKUPITEMEVENT = new ConfigSetting(CONFIG, "Main.Emit InventoryPickupItemEvent", false,
"This event is used by other plugin to modify or monitor the behavior when a hopper picks up items on the ground.",
"However it is a high frequency event and may have an impact on your server performance which is why it is disabled by default.",
"If you absolutely need this enable it but be aware of the potential performance impact.");
public static final ConfigSetting ECO_ICON = new ConfigSetting(config, "Interfaces.Economy Icon", "SUNFLOWER");
public static final ConfigSetting XP_ICON = new ConfigSetting(config, "Interfaces.XP Icon", "EXPERIENCE_BOTTLE");
public static final ConfigSetting ECO_ICON = new ConfigSetting(CONFIG, "Interfaces.Economy Icon", "SUNFLOWER");
public static final ConfigSetting XP_ICON = new ConfigSetting(CONFIG, "Interfaces.XP Icon", "EXPERIENCE_BOTTLE");
public static final ConfigSetting GLASS_TYPE_1 = new ConfigSetting(config, "Interfaces.Glass Type 1", "GRAY_STAINED_GLASS_PANE");
public static final ConfigSetting GLASS_TYPE_2 = new ConfigSetting(config, "Interfaces.Glass Type 2", "BLUE_STAINED_GLASS_PANE");
public static final ConfigSetting GLASS_TYPE_3 = new ConfigSetting(config, "Interfaces.Glass Type 3", "LIGHT_BLUE_STAINED_GLASS_PANE");
public static final ConfigSetting GLASS_TYPE_1 = new ConfigSetting(CONFIG, "Interfaces.Glass Type 1", "GRAY_STAINED_GLASS_PANE");
public static final ConfigSetting GLASS_TYPE_2 = new ConfigSetting(CONFIG, "Interfaces.Glass Type 2", "BLUE_STAINED_GLASS_PANE");
public static final ConfigSetting GLASS_TYPE_3 = new ConfigSetting(CONFIG, "Interfaces.Glass Type 3", "LIGHT_BLUE_STAINED_GLASS_PANE");
public static final ConfigSetting LANGUGE_MODE = new ConfigSetting(config, "System.Language Mode", "en_US",
public static final ConfigSetting LANGUGE_MODE = new ConfigSetting(CONFIG, "System.Language Mode", "en_US",
"The enabled language file.",
"More language files (if available) can be found in the plugins data folder.");
public static final ConfigSetting MYSQL_ENABLED = new ConfigSetting(config, "MySQL.Enabled", false, "Set to 'true' to use MySQL instead of SQLite for data storage.");
public static final ConfigSetting MYSQL_HOSTNAME = new ConfigSetting(config, "MySQL.Hostname", "localhost");
public static final ConfigSetting MYSQL_PORT = new ConfigSetting(config, "MySQL.Port", 3306);
public static final ConfigSetting MYSQL_DATABASE = new ConfigSetting(config, "MySQL.Database", "your-database");
public static final ConfigSetting MYSQL_USERNAME = new ConfigSetting(config, "MySQL.Username", "user");
public static final ConfigSetting MYSQL_PASSWORD = new ConfigSetting(config, "MySQL.Password", "pass");
public static final ConfigSetting MYSQL_USE_SSL = new ConfigSetting(config, "MySQL.Use SSL", false);
public static final ConfigSetting MYSQL_POOL_SIZE = new ConfigSetting(config, "MySQL.Pool Size", 3, "Determines the number of connections the pool is using. Increase this value if you are getting timeout errors when more players online.");
public static final ConfigSetting MYSQL_ENABLED = new ConfigSetting(CONFIG, "MySQL.Enabled", false, "Set to 'true' to use MySQL instead of SQLite for data storage.");
public static final ConfigSetting MYSQL_HOSTNAME = new ConfigSetting(CONFIG, "MySQL.Hostname", "localhost");
public static final ConfigSetting MYSQL_PORT = new ConfigSetting(CONFIG, "MySQL.Port", 3306);
public static final ConfigSetting MYSQL_DATABASE = new ConfigSetting(CONFIG, "MySQL.Database", "your-database");
public static final ConfigSetting MYSQL_USERNAME = new ConfigSetting(CONFIG, "MySQL.Username", "user");
public static final ConfigSetting MYSQL_PASSWORD = new ConfigSetting(CONFIG, "MySQL.Password", "pass");
public static final ConfigSetting MYSQL_USE_SSL = new ConfigSetting(CONFIG, "MySQL.Use SSL", false);
public static final ConfigSetting MYSQL_POOL_SIZE = new ConfigSetting(CONFIG, "MySQL.Pool Size", 3, "Determines the number of connections the pool is using. Increase this value if you are getting timeout errors when more players online.");
/**
* In order to set dynamic economy comment correctly, this needs to be
* called after EconomyManager load
*/
public static void setupConfig() {
config.load();
config.setAutoremove(true).setAutosave(true);
CONFIG.load();
CONFIG.setAutoremove(true).setAutosave(true);
// convert glass pane settings
int color;
if ((color = GLASS_TYPE_1.getInt(-1)) != -1) {
config.set(GLASS_TYPE_1.getKey(), CompatibleMaterial.getGlassPaneColor(color).name());
CONFIG.set(GLASS_TYPE_1.getKey(), CompatibleMaterial.getGlassPaneForColor(color).name());
}
if ((color = GLASS_TYPE_2.getInt(-1)) != -1) {
config.set(GLASS_TYPE_2.getKey(), CompatibleMaterial.getGlassPaneColor(color).name());
CONFIG.set(GLASS_TYPE_2.getKey(), CompatibleMaterial.getGlassPaneForColor(color).name());
}
if ((color = GLASS_TYPE_3.getInt(-1)) != -1) {
config.set(GLASS_TYPE_3.getKey(), CompatibleMaterial.getGlassPaneColor(color).name());
CONFIG.set(GLASS_TYPE_3.getKey(), CompatibleMaterial.getGlassPaneForColor(color).name());
}
// convert economy settings
if (config.getBoolean("Economy.Use Vault Economy") && EconomyManager.getManager().isEnabled("Vault")) {
config.set("Main.Economy", "Vault");
} else if (config.getBoolean("Economy.Use Reserve Economy") && EconomyManager.getManager().isEnabled("Reserve")) {
config.set("Main.Economy", "Reserve");
} else if (config.getBoolean("Economy.Use Player Points Economy") && EconomyManager.getManager().isEnabled("PlayerPoints")) {
config.set("Main.Economy", "PlayerPoints");
if (CONFIG.getBoolean("Economy.Use Vault Economy") && EconomyManager.getManager().isEnabled("Vault")) {
CONFIG.set("Main.Economy", "Vault");
} else if (CONFIG.getBoolean("Economy.Use Reserve Economy") && EconomyManager.getManager().isEnabled("Reserve")) {
CONFIG.set("Main.Economy", "Reserve");
} else if (CONFIG.getBoolean("Economy.Use Player Points Economy") && EconomyManager.getManager().isEnabled("PlayerPoints")) {
CONFIG.set("Main.Economy", "PlayerPoints");
}
config.saveChanges();
CONFIG.saveChanges();
}
}

View File

@ -1,14 +1,16 @@
package com.songoda.epichoppers.tasks;
package com.craftaro.epichoppers.tasks;
import com.songoda.epichoppers.EpicHoppers;
import com.songoda.epichoppers.boost.BoostData;
import com.songoda.epichoppers.containers.CustomContainer;
import com.songoda.epichoppers.hopper.levels.modules.Module;
import com.songoda.epichoppers.hopper.levels.modules.ModuleAutoCrafting;
import com.songoda.epichoppers.settings.Settings;
import com.songoda.epichoppers.utils.HopperDirection;
import com.songoda.epichoppers.utils.Methods;
import com.songoda.epichoppers.utils.StorageContainerCache;
import com.craftaro.epichoppers.boost.BoostData;
import com.craftaro.epichoppers.boost.BoostDataImpl;
import com.craftaro.epichoppers.containers.CustomContainer;
import com.craftaro.epichoppers.hopper.HopperImpl;
import com.craftaro.epichoppers.hopper.levels.modules.ModuleAutoCrafting;
import com.craftaro.epichoppers.settings.Settings;
import com.craftaro.epichoppers.utils.HopperDirection;
import com.craftaro.epichoppers.utils.Methods;
import com.craftaro.epichoppers.EpicHoppers;
import com.craftaro.epichoppers.hopper.levels.modules.Module;
import com.craftaro.epichoppers.utils.StorageContainerCache;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
@ -33,13 +35,8 @@ import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
/**
* Created by songoda on 3/14/2017.
*/
public class HopTask extends BukkitRunnable {
// Hop to the bop to the be bop top.
private EpicHoppers plugin;
private final EpicHoppers plugin;
private final int hopTicks;
public HopTask(EpicHoppers plugin) {
@ -50,22 +47,24 @@ public class HopTask extends BukkitRunnable {
@Override
public void run() {
for (final com.songoda.epichoppers.hopper.Hopper hopper : plugin.getHopperManager().getHoppers().values()) {
for (final HopperImpl hopper : this.plugin.getHopperManager().getHoppers().values()) {
try {
// Get this hoppers location.
// Get this hopper's location.
Location location = hopper.getLocation();
// Skip if chunk is not loaded.
if (location.getWorld() == null || !location.getWorld().isChunkLoaded(location.getBlockX() >> 4, location.getBlockZ() >> 4))
if (location.getWorld() == null || !location.getWorld().isChunkLoaded(location.getBlockX() >> 4, location.getBlockZ() >> 4)) {
continue;
}
// Get Hopper Block.
// Get HopperImpl Block.
Block block = location.getBlock();
// If block is not a hopper continue.
if (block.getType() != Material.HOPPER)
if (block.getType() != Material.HOPPER) {
continue;
}
// If hopper block is powered, update its redstone state and continue.
if (block.getBlockPower() > 0) {
@ -73,11 +72,12 @@ public class HopTask extends BukkitRunnable {
continue;
}
if (!hopper.tryTick(this.hopTicks, true))
if (!hopper.tryTick(this.hopTicks, true)) {
continue;
}
// Amount to be moved.
BoostData boostData = plugin.getBoostManager().getBoost(hopper.getPlacedBy());
BoostData boostData = this.plugin.getBoostManager().getBoost(hopper.getPlacedBy());
int maxToMove = hopper.getLevel().getAmount() * (boostData == null ? 1 : boostData.getMultiplier());
// Get hopper state data.
@ -99,8 +99,9 @@ public class HopTask extends BukkitRunnable {
// Add banned materials to list.
List<Material> materials = module.getBlockedItems(hopper);
if (materials != null && !materials.isEmpty())
if (materials != null && !materials.isEmpty()) {
blockedMaterials.addAll(materials);
}
} catch (Exception ex) {
ex.printStackTrace();
}
@ -124,16 +125,18 @@ public class HopTask extends BukkitRunnable {
|| (hopperCache.cacheChanged[i] && item.getAmount() - hopperCache.cacheAdded[i] < maxToMove)
// skip if blocked or voidlisted
|| blockedMaterials.contains(item.getType())
|| hopper.getFilter().getVoidList().stream().anyMatch(itemStack -> Methods.isSimilarMaterial(itemStack, item)))
|| hopper.getFilter().getVoidList().stream().anyMatch(itemStack -> Methods.isSimilarMaterial(itemStack, item))) {
continue;
}
doProcess = true;
break;
}
if (!doProcess)
if (!doProcess) {
continue;
}
CustomContainer container = plugin.getContainerManager().getCustomContainer(pointingLocation.getBlock());
CustomContainer container = this.plugin.getContainerManager().getCustomContainer(pointingLocation.getBlock());
if (container != null) {
for (int i = 0; i < 5; i++) {
final ItemStack item = hopperCache.cachedInventory[i];
@ -165,22 +168,26 @@ public class HopTask extends BukkitRunnable {
}
private void debt(ItemStack item, int amountToMove, InventoryHolder currentHolder) {
if (item.getAmount() - amountToMove > 0)
if (item.getAmount() - amountToMove > 0) {
item.setAmount(item.getAmount() - amountToMove);
else
} else {
currentHolder.getInventory().removeItem(item);
}
}
private StorageContainerCache.Cache getFilterEndpoint(com.songoda.epichoppers.hopper.Hopper hopper) {
private StorageContainerCache.Cache getFilterEndpoint(HopperImpl hopper) {
// Get endpoint location.
Location endPoint = hopper.getFilter().getEndPoint();
// Check for null.
if (endPoint == null) return null;
if (endPoint == null) {
return null;
}
// Make sure chunk is loaded.
if (!endPoint.getWorld().isChunkLoaded(endPoint.getBlockX() >> 4, endPoint.getBlockZ() >> 4))
if (!endPoint.getWorld().isChunkLoaded(endPoint.getBlockX() >> 4, endPoint.getBlockZ() >> 4)) {
return null;
}
// Fetch Cache
StorageContainerCache.Cache cache = StorageContainerCache.getCachedInventory(endPoint.getBlock());
@ -194,7 +201,7 @@ public class HopTask extends BukkitRunnable {
return cache;
}
private void pullItemsFromContainers(com.songoda.epichoppers.hopper.Hopper toHopper, StorageContainerCache.Cache hopperCache, int maxToMove) {
private void pullItemsFromContainers(HopperImpl toHopper, StorageContainerCache.Cache hopperCache, int maxToMove) {
// Grab items from the container above (includes storage/hopper minecarts, EpicFarming farm items and AdvancedChests chest)
// If the container above is a hopper, ignore it if it's pointing down
Block above = toHopper.getBlock().getRelative(BlockFace.UP);
@ -202,7 +209,7 @@ public class HopTask extends BukkitRunnable {
Collection<Entity> nearbyEntities = null;
StorageContainerCache.Cache aboveCache = null;
CustomContainer container = plugin.getContainerManager().getCustomContainer(above);
CustomContainer container = this.plugin.getContainerManager().getCustomContainer(above);
if ((container != null)
|| (above.getType() != Material.AIR)
&& (above.getType() != Material.HOPPER || HopperDirection.getDirection(above.getState().getRawData()) != HopperDirection.DOWN)
@ -223,8 +230,9 @@ public class HopTask extends BukkitRunnable {
pullableSlots = IntStream.rangeClosed(0, contents.length - 1).toArray();
} else {
if ((aboveInvHolder = this.getRandomInventoryHolderFromEntities(nearbyEntities)) == null
|| ((Minecart) aboveInvHolder).getLocation().getBlockY() + 1 == above.getY())
|| ((Minecart) aboveInvHolder).getLocation().getBlockY() + 1 == above.getY()) {
return;
}
if (aboveInvHolder instanceof StorageMinecart) {
pullableSlots = IntStream.rangeClosed(0, 26).toArray();
} else {
@ -243,13 +251,15 @@ public class HopTask extends BukkitRunnable {
final ItemStack toMove = contents[i];
// If item is invalid, try the next slot.
if (toMove == null || toMove.getAmount() == 0)
if (toMove == null || toMove.getAmount() == 0) {
continue;
}
// if we're not moving the item that we're trying to craft, we need to verify that we're not trying to fill the last slot
// (filling every slot leaves no room for the crafter to function)
if (toCraft != null && !Methods.isSimilarMaterial(toMove, toCraft) && !Methods.canMoveReserved(hopperCache.cachedInventory, toMove))
if (toCraft != null && !Methods.isSimilarMaterial(toMove, toCraft) && !Methods.canMoveReserved(hopperCache.cachedInventory, toMove)) {
continue;
}
// respect whitelist/blacklist filters
if (toHopper.getFilter().getEndPoint() == null
@ -285,9 +295,9 @@ public class HopTask extends BukkitRunnable {
if (aboveCache != null) {
aboveCache.removeItems(itemToMove);
} else {
if (container != null)
if (container != null) {
container.removeFromContainer(itemToMove, amountToMove);
else {
} else {
this.debt(itemToMove, amountToMove, aboveInvHolder);
}
}
@ -297,7 +307,7 @@ public class HopTask extends BukkitRunnable {
}
}
private void pushItemsIntoContainers(com.songoda.epichoppers.hopper.Hopper hopper, StorageContainerCache.Cache hopperCache, int maxToMove, Collection<Material> blockedMaterials, HopperDirection hopperDirection) {
private void pushItemsIntoContainers(HopperImpl hopper, StorageContainerCache.Cache hopperCache, int maxToMove, Collection<Material> blockedMaterials, HopperDirection hopperDirection) {
// Filter target, if any
StorageContainerCache.Cache filterCache = getFilterEndpoint(hopper);
@ -309,9 +319,7 @@ public class HopTask extends BukkitRunnable {
// Add container that the hopper is attached to physically.
final Location pointingLocation = hopper.getLocation().add(hopperDirection.getX(), hopperDirection.getY(), hopperDirection.getZ());
if (!linkedContainers.contains(pointingLocation)
&& pointingLocation.getWorld().isChunkLoaded(
pointingLocation.getBlockX() >> 4,
pointingLocation.getBlockZ() >> 4)) {
&& pointingLocation.getWorld().isChunkLoaded(pointingLocation.getBlockX() >> 4, pointingLocation.getBlockZ() >> 4)) {
switch (pointingLocation.getBlock().getType().name()) {
case "AIR":
case "RAILS":
@ -330,8 +338,9 @@ public class HopTask extends BukkitRunnable {
for (Location targetLocation : linkedContainers) {
// Don't check if it's not in a loaded chunk
if (!targetLocation.getWorld().isChunkLoaded(targetLocation.getBlockX() >> 4, targetLocation.getBlockZ() >> 4))
if (!targetLocation.getWorld().isChunkLoaded(targetLocation.getBlockX() >> 4, targetLocation.getBlockZ() >> 4)) {
continue;
}
// special case for ender chests
final Block targetBlock = targetLocation.getBlock();
@ -343,8 +352,9 @@ public class HopTask extends BukkitRunnable {
StorageContainerCache.Cache cache = new StorageContainerCache.Cache(targetBlock.getType(), destinationInventory.getContents());
if (tryPush(hopper, hopperCache, cache, filterCache, maxToMove, blockedMaterials)) {
// update inventory and exit
if (cache.isDirty())
if (cache.isDirty()) {
destinationInventory.setContents(cache.cachedInventory);
}
return;
}
}
@ -352,7 +362,7 @@ public class HopTask extends BukkitRunnable {
continue;
}
CustomContainer container = plugin.getContainerManager().getCustomContainer(targetLocation.getBlock());
CustomContainer container = this.plugin.getContainerManager().getCustomContainer(targetLocation.getBlock());
if (container != null && tryPushCustomContainer(hopper, hopperCache, container, filterCache, maxToMove, blockedMaterials)) {
return;
}
@ -366,8 +376,9 @@ public class HopTask extends BukkitRunnable {
}
// Now attempt to push items into this container and exit on success
if (tryPush(hopper, hopperCache, targetCache, filterCache, maxToMove, blockedMaterials))
if (tryPush(hopper, hopperCache, targetCache, filterCache, maxToMove, blockedMaterials)) {
return;
}
}
// if we've gotten this far, check if we can push into a minecart
@ -377,15 +388,16 @@ public class HopTask extends BukkitRunnable {
.map(InventoryHolder.class::cast).collect(Collectors.toSet())) {
StorageContainerCache.Cache cache = new StorageContainerCache.Cache(Material.CHEST, minecartInventory.getInventory().getContents());
if (tryPush(hopper, hopperCache, cache, filterCache, maxToMove, blockedMaterials)) {
if (cache.isDirty())
if (cache.isDirty()) {
minecartInventory.getInventory().setContents(cache.cachedInventory);
}
return;
}
}
}
}
private boolean tryPushCustomContainer(com.songoda.epichoppers.hopper.Hopper hopper,
private boolean tryPushCustomContainer(HopperImpl hopper,
StorageContainerCache.Cache hopperCache,
CustomContainer container,
StorageContainerCache.Cache filterCache,
@ -401,8 +413,9 @@ public class HopTask extends BukkitRunnable {
|| (hopperCache.cacheChanged[i] && item.getAmount() - hopperCache.cacheAdded[i] < maxToMove)
// skip if blocked or voidlisted
|| blockedMaterials.contains(item.getType())
|| hopper.getFilter().getVoidList().stream().anyMatch(itemStack -> Methods.isSimilarMaterial(itemStack, item)))
|| hopper.getFilter().getVoidList().stream().anyMatch(itemStack -> Methods.isSimilarMaterial(itemStack, item))) {
continue;
}
// Create item that will be moved.
ItemStack itemToMove = item.clone();
@ -431,7 +444,7 @@ public class HopTask extends BukkitRunnable {
return false;
}
private boolean tryPush(com.songoda.epichoppers.hopper.Hopper hopper,
private boolean tryPush(HopperImpl hopper,
StorageContainerCache.Cache hopperCache,
StorageContainerCache.Cache targetCache,
StorageContainerCache.Cache filterCache,
@ -449,8 +462,9 @@ public class HopTask extends BukkitRunnable {
|| (hopperCache.cacheChanged[i] && item.getAmount() - hopperCache.cacheAdded[i] < maxToMove)
// skip if blocked or voidlisted
|| blockedMaterials.contains(item.getType())
|| hopper.getFilter().getVoidList().stream().anyMatch(itemStack -> Methods.isSimilarMaterial(itemStack, item)))
|| hopper.getFilter().getVoidList().stream().anyMatch(itemStack -> Methods.isSimilarMaterial(itemStack, item))) {
continue;
}
// Create item that will be moved.
ItemStack itemToMove = item.clone();
@ -479,7 +493,7 @@ public class HopTask extends BukkitRunnable {
return false;
}
private void processVoidFilter(com.songoda.epichoppers.hopper.Hopper hopper, StorageContainerCache.Cache hopperCache, int maxToMove) {
private void processVoidFilter(HopperImpl hopper, StorageContainerCache.Cache hopperCache, int maxToMove) {
// Loop over hopper inventory to process void filtering.
if (!hopper.getFilter().getVoidList().isEmpty()) {
ItemStack[] hopperContents = hopperCache.cachedInventory;
@ -506,8 +520,9 @@ public class HopTask extends BukkitRunnable {
* @return A set of valid pullable slots
*/
private int[] getPullableSlots(Material material, int contentsLength) {
if (material.name().contains("SHULKER_BOX"))
if (material.name().contains("SHULKER_BOX")) {
return IntStream.rangeClosed(0, 26).toArray();
}
switch (material.name()) {
case "BARREL":
@ -542,10 +557,12 @@ public class HopTask extends BukkitRunnable {
List<InventoryHolder> inventoryHolders = new ArrayList<>();
entities.stream().filter(e -> e.getType() == EntityType.MINECART_CHEST || e.getType() == EntityType.MINECART_HOPPER)
.forEach(e -> inventoryHolders.add((InventoryHolder) e));
if (inventoryHolders.isEmpty())
if (inventoryHolders.isEmpty()) {
return null;
if (inventoryHolders.size() == 1)
}
if (inventoryHolders.size() == 1) {
return inventoryHolders.get(0);
}
return inventoryHolders.get(ThreadLocalRandom.current().nextInt(inventoryHolders.size()));
}
}
}

View File

@ -0,0 +1,115 @@
package com.craftaro.epichoppers.utils;
import com.craftaro.core.database.DatabaseConnector;
import com.craftaro.third_party.org.jooq.Query;
import com.craftaro.third_party.org.jooq.impl.DSL;
import com.craftaro.core.utils.ItemSerializer;
import com.craftaro.epichoppers.EpicHoppers;
import com.craftaro.epichoppers.hopper.Hopper;
import com.craftaro.epichoppers.hopper.HopperImpl;
import com.craftaro.epichoppers.hopper.ItemType;
import com.craftaro.epichoppers.hopper.LinkType;
import org.bukkit.Location;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.io.BukkitObjectOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.Base64;
import java.util.List;
public class DataHelper {
public static void createLink(HopperImpl hopper, Location location, LinkType type) {
EpicHoppers.getPlugin(EpicHoppers.class).getDataManager().getDatabaseConnector().connectDSL(dslContext -> {
dslContext.insertInto(DSL.table(EpicHoppers.getPlugin(EpicHoppers.class).getDataManager().getTablePrefix() + "links"))
.columns(
DSL.field("hopper_id"),
DSL.field("link_type"),
DSL.field("world"),
DSL.field("x"),
DSL.field("y"),
DSL.field("z"))
.values(
hopper.getId(),
type.name(),
location.getWorld().getName(),
location.getBlockX(),
location.getBlockY(),
location.getBlockZ())
.execute();
});
}
public static void updateItems(HopperImpl hopper, ItemType type, List<ItemStack> items) {
DatabaseConnector databaseConnector = EpicHoppers.getPlugin(EpicHoppers.class).getDataManager().getDatabaseConnector();
String tablePrefix = EpicHoppers.getPlugin(EpicHoppers.class).getDataManager().getTablePrefix();
try (Connection connection = databaseConnector.getConnection()) {
String clearItems = "DELETE FROM " + tablePrefix + "items WHERE hopper_id = ? AND item_type = ?";
try (PreparedStatement statement = connection.prepareStatement(clearItems)) {
statement.setInt(1, hopper.getId());
statement.setString(2, type.name());
statement.executeUpdate();
}
String createItem = "INSERT INTO " + tablePrefix + "items (hopper_id, item_type, item) VALUES (?, ?, ?)";
try (PreparedStatement statement = connection.prepareStatement(createItem)) {
for (ItemStack item : items) {
statement.setInt(1, hopper.getId());
statement.setString(2, type.name());
try (ByteArrayOutputStream stream = new ByteArrayOutputStream(); BukkitObjectOutputStream bukkitStream = new BukkitObjectOutputStream(stream)) {
bukkitStream.writeObject(item);
statement.setString(3, Base64.getEncoder().encodeToString(stream.toByteArray()));
} catch (IOException e) {
e.printStackTrace();
continue;
}
statement.addBatch();
}
statement.executeBatch();
}
} catch (Exception ex) {
ex.printStackTrace();
}
//Recreate with jooq
// EpicHoppers.getPlugin(EpicHoppers.class).getDataManager().getDatabaseConnector().connectDSL(dslContext -> {
// dslContext.deleteFrom(DSL.table(EpicHoppers.getPlugin(EpicHoppers.class).getDataManager().getTablePrefix() + "items"))
// .where(DSL.field("hopper_id").eq(hopper.getId()))
// .and(DSL.field("item_type").eq(type.name()))
// .execute();
//
// dslContext.batch(
// items.stream().map(item -> dslContext.insertInto(DSL.table(EpicHoppers.getPlugin(EpicHoppers.class).getDataManager().getTablePrefix() + "items"))
// .columns(
// DSL.field("hopper_id"),
// DSL.field("item_type"),
// DSL.field("item"))
// .values(
// hopper.getId(),
// type.name(),
// Base64.getEncoder().encodeToString(ItemSerializer.serializeItem(item)))
// ).toArray(Query[]::new)
// ).execute();
// });
}
public static void deleteLinks(Hopper hopper) {
EpicHoppers.getPlugin(EpicHoppers.class).getDataManager().getDatabaseConnector().connectDSL(dslContext -> {
dslContext.deleteFrom(DSL.table(EpicHoppers.getPlugin(EpicHoppers.class).getDataManager().getTablePrefix() + "links"))
.where(DSL.field("hopper_id").eq(hopper.getId()))
.execute();
});
}
public static void deleteItems(HopperImpl hopper) {
EpicHoppers.getPlugin(EpicHoppers.class).getDataManager().getDatabaseConnector().connectDSL(dslContext -> {
dslContext.deleteFrom(DSL.table(EpicHoppers.getPlugin(EpicHoppers.class).getDataManager().getTablePrefix() + "items"))
.where(DSL.field("hopper_id").eq(hopper.getId()))
.execute();
});
}
}

View File

@ -1,10 +1,9 @@
package com.songoda.epichoppers.utils;
package com.craftaro.epichoppers.utils;
import org.bukkit.Location;
import org.bukkit.block.BlockFace;
public enum HopperDirection {
DOWN(0, 8, 0, -1, 0),
NORTH(2, 10, 0, 0, -1),
SOUTH(3, 11, 0, 0, 1),
@ -28,9 +27,11 @@ public enum HopperDirection {
}
public static HopperDirection getDirection(int value) {
for (HopperDirection hopperDirection : HopperDirection.values())
if (hopperDirection.getPowered() == value || hopperDirection.getUnpowered() == value)
for (HopperDirection hopperDirection : HopperDirection.values()) {
if (hopperDirection.getPowered() == value || hopperDirection.getUnpowered() == value) {
return hopperDirection;
}
}
return null;
}
@ -54,22 +55,22 @@ public enum HopperDirection {
}
public int getX() {
return x;
return this.x;
}
public int getY() {
return y;
return this.y;
}
public int getZ() {
return z;
return this.z;
}
public int getUnpowered() {
return unpowered;
return this.unpowered;
}
public int getPowered() {
return powered;
return this.powered;
}
}
}

View File

@ -1,9 +1,12 @@
name: EpicHoppers
description: EpicHoppers
main: com.songoda.epichoppers.EpicHoppers
name: ${project.parent.name}
description: ${project.parent.description}
version: ${project.version}
api-version: 1.13
main: com.craftaro.epichoppers.EpicHoppers
softdepend:
- ASkyBlock
- AdvancedChests
- ASkyBlock
- EconomyShopGUI
- EconomyShopGUI-Premium
- EpicFarming
@ -16,14 +19,15 @@ softdepend:
- RedProtect
- Reserve
- Towny
- USkyBlock
- UltimateStacker
- USkyBlock
- Vault
- WildStacker
- WorldGuard
version: maven-version-number
author: Songoda
api-version: 1.13
author: Craftaro
website: ${project.parent.url}
commands:
eh:
description: View information on this plugin.

654
LICENSE
View File

@ -1,327 +1,327 @@
Creative Commons Attribution-NonCommercial-NoDerivatives 4.0
International Public License
By exercising the Licensed Rights (defined below), You accept and agree
to be bound by the terms and conditions of this Creative Commons
Attribution-NonCommercial-NoDerivatives 4.0 International Public
License ("Public License"). To the extent this Public License may be
interpreted as a contract, You are granted the Licensed Rights in
consideration of Your acceptance of these terms and conditions, and the
Licensor grants You such rights in consideration of benefits the
Licensor receives from making the Licensed Material available under
these terms and conditions.
Section 1 -- Definitions.
a. Adapted Material means material subject to Copyright and Similar
Rights that is derived from or based upon the Licensed Material
and in which the Licensed Material is translated, altered,
arranged, transformed, or otherwise modified in a manner requiring
permission under the Copyright and Similar Rights held by the
Licensor. For purposes of this Public License, where the Licensed
Material is a musical work, performance, or sound recording,
Adapted Material is always produced where the Licensed Material is
synched in timed relation with a moving image.
b. Copyright and Similar Rights means copyright and/or similar rights
closely related to copyright including, without limitation,
performance, broadcast, sound recording, and Sui Generis Database
Rights, without regard to how the rights are labeled or
categorized. For purposes of this Public License, the rights
specified in Section 2(b)(1)-(2) are not Copyright and Similar
Rights.
c. Effective Technological Measures means those measures that, in the
absence of proper authority, may not be circumvented under laws
fulfilling obligations under Article 11 of the WIPO Copyright
Treaty adopted on December 20, 1996, and/or similar international
agreements.
d. Exceptions and Limitations means fair use, fair dealing, and/or
any other exception or limitation to Copyright and Similar Rights
that applies to Your use of the Licensed Material.
e. Licensed Material means the artistic or literary work, database,
or other material to which the Licensor applied this Public
License.
f. Licensed Rights means the rights granted to You subject to the
terms and conditions of this Public License, which are limited to
all Copyright and Similar Rights that apply to Your use of the
Licensed Material and that the Licensor has authority to license.
g. Licensor means the individual(s) or entity(ies) granting rights
under this Public License.
h. NonCommercial means not primarily intended for or directed towards
commercial advantage or monetary compensation. For purposes of
this Public License, the exchange of the Licensed Material for
other material subject to Copyright and Similar Rights by digital
file-sharing or similar means is NonCommercial provided there is
no payment of monetary compensation in connection with the
exchange.
i. Share means to provide material to the public by any means or
process that requires permission under the Licensed Rights, such
as reproduction, public display, public performance, distribution,
dissemination, communication, or importation, and to make material
available to the public including in ways that members of the
public may access the material from a place and at a time
individually chosen by them.
j. Sui Generis Database Rights means rights other than copyright
resulting from Directive 96/9/EC of the European Parliament and of
the Council of 11 March 1996 on the legal protection of databases,
as amended and/or succeeded, as well as other essentially
equivalent rights anywhere in the world.
k. You means the individual or entity exercising the Licensed Rights
under this Public License. Your has a corresponding meaning.
Section 2 -- Scope.
a. License grant.
1. Subject to the terms and conditions of this Public License,
the Licensor hereby grants You a worldwide, royalty-free,
non-sublicensable, non-exclusive, irrevocable license to
exercise the Licensed Rights in the Licensed Material to:
a. reproduce and Share the Licensed Material, in whole or
in part, for NonCommercial purposes only; and
b. produce and reproduce, but not Share, Adapted Material
for NonCommercial purposes only.
2. Exceptions and Limitations. For the avoidance of doubt, where
Exceptions and Limitations apply to Your use, this Public
License does not apply, and You do not need to comply with
its terms and conditions.
3. Term. The term of this Public License is specified in Section
6(a).
4. Media and formats; technical modifications allowed. The
Licensor authorizes You to exercise the Licensed Rights in
all media and formats whether now known or hereafter created,
and to make technical modifications necessary to do so. The
Licensor waives and/or agrees not to assert any right or
authority to forbid You from making technical modifications
necessary to exercise the Licensed Rights, including
technical modifications necessary to circumvent Effective
Technological Measures. For purposes of this Public License,
simply making modifications authorized by this Section 2(a)
(4) never produces Adapted Material.
5. Downstream recipients.
a. Offer from the Licensor -- Licensed Material. Every
recipient of the Licensed Material automatically
receives an offer from the Licensor to exercise the
Licensed Rights under the terms and conditions of this
Public License.
b. No downstream restrictions. You may not offer or impose
any additional or different terms or conditions on, or
apply any Effective Technological Measures to, the
Licensed Material if doing so restricts exercise of the
Licensed Rights by any recipient of the Licensed
Material.
6. No endorsement. Nothing in this Public License constitutes or
may be construed as permission to assert or imply that You
are, or that Your use of the Licensed Material is, connected
with, or sponsored, endorsed, or granted official status by,
the Licensor or others designated to receive attribution as
provided in Section 3(a)(1)(A)(i).
b. Other rights.
1. Moral rights, such as the right of integrity, are not
licensed under this Public License, nor are publicity,
privacy, and/or other similar personality rights; however, to
the extent possible, the Licensor waives and/or agrees not to
assert any such rights held by the Licensor to the limited
extent necessary to allow You to exercise the Licensed
Rights, but not otherwise.
2. Patent and trademark rights are not licensed under this
Public License.
3. To the extent possible, the Licensor waives any right to
collect royalties from You for the exercise of the Licensed
Rights, whether directly or through a collecting society
under any voluntary or waivable statutory or compulsory
licensing scheme. In all other cases the Licensor expressly
reserves any right to collect such royalties, including when
the Licensed Material is used other than for NonCommercial
purposes.
Section 3 -- License Conditions.
Your exercise of the Licensed Rights is expressly made subject to the
following conditions.
a. Attribution.
1. If You Share the Licensed Material, You must:
a. retain the following if it is supplied by the Licensor
with the Licensed Material:
i. identification of the creator(s) of the Licensed
Material and any others designated to receive
attribution, in any reasonable manner requested by
the Licensor (including by pseudonym if
designated);
ii. a copyright notice;
iii. a notice that refers to this Public License;
iv. a notice that refers to the disclaimer of
warranties;
v. a URI or hyperlink to the Licensed Material to the
extent reasonably practicable;
b. indicate if You modified the Licensed Material and
retain an indication of any previous modifications; and
c. indicate the Licensed Material is licensed under this
Public License, and include the text of, or the URI or
hyperlink to, this Public License.
For the avoidance of doubt, You do not have permission under
this Public License to Share Adapted Material.
2. You may satisfy the conditions in Section 3(a)(1) in any
reasonable manner based on the medium, means, and context in
which You Share the Licensed Material. For example, it may be
reasonable to satisfy the conditions by providing a URI or
hyperlink to a resource that includes the required
information.
3. If requested by the Licensor, You must remove any of the
information required by Section 3(a)(1)(A) to the extent
reasonably practicable.
Section 4 -- Sui Generis Database Rights.
Where the Licensed Rights include Sui Generis Database Rights that
apply to Your use of the Licensed Material:
a. for the avoidance of doubt, Section 2(a)(1) grants You the right
to extract, reuse, reproduce, and Share all or a substantial
portion of the contents of the database for NonCommercial purposes
only and provided You do not Share Adapted Material;
b. if You include all or a substantial portion of the database
contents in a database in which You have Sui Generis Database
Rights, then the database in which You have Sui Generis Database
Rights (but not its individual contents) is Adapted Material; and
c. You must comply with the conditions in Section 3(a) if You Share
all or a substantial portion of the contents of the database.
For the avoidance of doubt, this Section 4 supplements and does not
replace Your obligations under this Public License where the Licensed
Rights include other Copyright and Similar Rights.
Section 5 -- Disclaimer of Warranties and Limitation of Liability.
a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
c. The disclaimer of warranties and limitation of liability provided
above shall be interpreted in a manner that, to the extent
possible, most closely approximates an absolute disclaimer and
waiver of all liability.
Section 6 -- Term and Termination.
a. This Public License applies for the term of the Copyright and
Similar Rights licensed here. However, if You fail to comply with
this Public License, then Your rights under this Public License
terminate automatically.
b. Where Your right to use the Licensed Material has terminated under
Section 6(a), it reinstates:
1. automatically as of the date the violation is cured, provided
it is cured within 30 days of Your discovery of the
violation; or
2. upon express reinstatement by the Licensor.
For the avoidance of doubt, this Section 6(b) does not affect any
right the Licensor may have to seek remedies for Your violations
of this Public License.
c. For the avoidance of doubt, the Licensor may also offer the
Licensed Material under separate terms or conditions or stop
distributing the Licensed Material at any time; however, doing so
will not terminate this Public License.
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
License.
Section 7 -- Other Terms and Conditions.
a. The Licensor shall not be bound by any additional or different
terms or conditions communicated by You unless expressly agreed.
b. Any arrangements, understandings, or agreements regarding the
Licensed Material not stated herein are separate from and
independent of the terms and conditions of this Public License.
Section 8 -- Interpretation.
a. For the avoidance of doubt, this Public License does not, and
shall not be interpreted to, reduce, limit, restrict, or impose
conditions on any use of the Licensed Material that could lawfully
be made without permission under this Public License.
b. To the extent possible, if any provision of this Public License is
deemed unenforceable, it shall be automatically reformed to the
minimum extent necessary to make it enforceable. If the provision
cannot be reformed, it shall be severed from this Public License
without affecting the enforceability of the remaining terms and
conditions.
c. No term or condition of this Public License will be waived and no
failure to comply consented to unless expressly agreed to by the
Licensor.
d. Nothing in this Public License constitutes or may be interpreted
as a limitation upon, or waiver of, any privileges and immunities
that apply to the Licensor or You, including from the legal
processes of any jurisdiction or authority.
=======================================================================
Creative Commons Attribution-NonCommercial-NoDerivatives 4.0
International Public License
By exercising the Licensed Rights (defined below), You accept and agree
to be bound by the terms and conditions of this Creative Commons
Attribution-NonCommercial-NoDerivatives 4.0 International Public
License ("Public License"). To the extent this Public License may be
interpreted as a contract, You are granted the Licensed Rights in
consideration of Your acceptance of these terms and conditions, and the
Licensor grants You such rights in consideration of benefits the
Licensor receives from making the Licensed Material available under
these terms and conditions.
Section 1 -- Definitions.
a. Adapted Material means material subject to Copyright and Similar
Rights that is derived from or based upon the Licensed Material
and in which the Licensed Material is translated, altered,
arranged, transformed, or otherwise modified in a manner requiring
permission under the Copyright and Similar Rights held by the
Licensor. For purposes of this Public License, where the Licensed
Material is a musical work, performance, or sound recording,
Adapted Material is always produced where the Licensed Material is
synched in timed relation with a moving image.
b. Copyright and Similar Rights means copyright and/or similar rights
closely related to copyright including, without limitation,
performance, broadcast, sound recording, and Sui Generis Database
Rights, without regard to how the rights are labeled or
categorized. For purposes of this Public License, the rights
specified in Section 2(b)(1)-(2) are not Copyright and Similar
Rights.
c. Effective Technological Measures means those measures that, in the
absence of proper authority, may not be circumvented under laws
fulfilling obligations under Article 11 of the WIPO Copyright
Treaty adopted on December 20, 1996, and/or similar international
agreements.
d. Exceptions and Limitations means fair use, fair dealing, and/or
any other exception or limitation to Copyright and Similar Rights
that applies to Your use of the Licensed Material.
e. Licensed Material means the artistic or literary work, database,
or other material to which the Licensor applied this Public
License.
f. Licensed Rights means the rights granted to You subject to the
terms and conditions of this Public License, which are limited to
all Copyright and Similar Rights that apply to Your use of the
Licensed Material and that the Licensor has authority to license.
g. Licensor means the individual(s) or entity(ies) granting rights
under this Public License.
h. NonCommercial means not primarily intended for or directed towards
commercial advantage or monetary compensation. For purposes of
this Public License, the exchange of the Licensed Material for
other material subject to Copyright and Similar Rights by digital
file-sharing or similar means is NonCommercial provided there is
no payment of monetary compensation in connection with the
exchange.
i. Share means to provide material to the public by any means or
process that requires permission under the Licensed Rights, such
as reproduction, public display, public performance, distribution,
dissemination, communication, or importation, and to make material
available to the public including in ways that members of the
public may access the material from a place and at a time
individually chosen by them.
j. Sui Generis Database Rights means rights other than copyright
resulting from Directive 96/9/EC of the European Parliament and of
the Council of 11 March 1996 on the legal protection of databases,
as amended and/or succeeded, as well as other essentially
equivalent rights anywhere in the world.
k. You means the individual or entity exercising the Licensed Rights
under this Public License. Your has a corresponding meaning.
Section 2 -- Scope.
a. License grant.
1. Subject to the terms and conditions of this Public License,
the Licensor hereby grants You a worldwide, royalty-free,
non-sublicensable, non-exclusive, irrevocable license to
exercise the Licensed Rights in the Licensed Material to:
a. reproduce and Share the Licensed Material, in whole or
in part, for NonCommercial purposes only; and
b. produce and reproduce, but not Share, Adapted Material
for NonCommercial purposes only.
2. Exceptions and Limitations. For the avoidance of doubt, where
Exceptions and Limitations apply to Your use, this Public
License does not apply, and You do not need to comply with
its terms and conditions.
3. Term. The term of this Public License is specified in Section
6(a).
4. Media and formats; technical modifications allowed. The
Licensor authorizes You to exercise the Licensed Rights in
all media and formats whether now known or hereafter created,
and to make technical modifications necessary to do so. The
Licensor waives and/or agrees not to assert any right or
authority to forbid You from making technical modifications
necessary to exercise the Licensed Rights, including
technical modifications necessary to circumvent Effective
Technological Measures. For purposes of this Public License,
simply making modifications authorized by this Section 2(a)
(4) never produces Adapted Material.
5. Downstream recipients.
a. Offer from the Licensor -- Licensed Material. Every
recipient of the Licensed Material automatically
receives an offer from the Licensor to exercise the
Licensed Rights under the terms and conditions of this
Public License.
b. No downstream restrictions. You may not offer or impose
any additional or different terms or conditions on, or
apply any Effective Technological Measures to, the
Licensed Material if doing so restricts exercise of the
Licensed Rights by any recipient of the Licensed
Material.
6. No endorsement. Nothing in this Public License constitutes or
may be construed as permission to assert or imply that You
are, or that Your use of the Licensed Material is, connected
with, or sponsored, endorsed, or granted official status by,
the Licensor or others designated to receive attribution as
provided in Section 3(a)(1)(A)(i).
b. Other rights.
1. Moral rights, such as the right of integrity, are not
licensed under this Public License, nor are publicity,
privacy, and/or other similar personality rights; however, to
the extent possible, the Licensor waives and/or agrees not to
assert any such rights held by the Licensor to the limited
extent necessary to allow You to exercise the Licensed
Rights, but not otherwise.
2. Patent and trademark rights are not licensed under this
Public License.
3. To the extent possible, the Licensor waives any right to
collect royalties from You for the exercise of the Licensed
Rights, whether directly or through a collecting society
under any voluntary or waivable statutory or compulsory
licensing scheme. In all other cases the Licensor expressly
reserves any right to collect such royalties, including when
the Licensed Material is used other than for NonCommercial
purposes.
Section 3 -- License Conditions.
Your exercise of the Licensed Rights is expressly made subject to the
following conditions.
a. Attribution.
1. If You Share the Licensed Material, You must:
a. retain the following if it is supplied by the Licensor
with the Licensed Material:
i. identification of the creator(s) of the Licensed
Material and any others designated to receive
attribution, in any reasonable manner requested by
the Licensor (including by pseudonym if
designated);
ii. a copyright notice;
iii. a notice that refers to this Public License;
iv. a notice that refers to the disclaimer of
warranties;
v. a URI or hyperlink to the Licensed Material to the
extent reasonably practicable;
b. indicate if You modified the Licensed Material and
retain an indication of any previous modifications; and
c. indicate the Licensed Material is licensed under this
Public License, and include the text of, or the URI or
hyperlink to, this Public License.
For the avoidance of doubt, You do not have permission under
this Public License to Share Adapted Material.
2. You may satisfy the conditions in Section 3(a)(1) in any
reasonable manner based on the medium, means, and context in
which You Share the Licensed Material. For example, it may be
reasonable to satisfy the conditions by providing a URI or
hyperlink to a resource that includes the required
information.
3. If requested by the Licensor, You must remove any of the
information required by Section 3(a)(1)(A) to the extent
reasonably practicable.
Section 4 -- Sui Generis Database Rights.
Where the Licensed Rights include Sui Generis Database Rights that
apply to Your use of the Licensed Material:
a. for the avoidance of doubt, Section 2(a)(1) grants You the right
to extract, reuse, reproduce, and Share all or a substantial
portion of the contents of the database for NonCommercial purposes
only and provided You do not Share Adapted Material;
b. if You include all or a substantial portion of the database
contents in a database in which You have Sui Generis Database
Rights, then the database in which You have Sui Generis Database
Rights (but not its individual contents) is Adapted Material; and
c. You must comply with the conditions in Section 3(a) if You Share
all or a substantial portion of the contents of the database.
For the avoidance of doubt, this Section 4 supplements and does not
replace Your obligations under this Public License where the Licensed
Rights include other Copyright and Similar Rights.
Section 5 -- Disclaimer of Warranties and Limitation of Liability.
a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
c. The disclaimer of warranties and limitation of liability provided
above shall be interpreted in a manner that, to the extent
possible, most closely approximates an absolute disclaimer and
waiver of all liability.
Section 6 -- Term and Termination.
a. This Public License applies for the term of the Copyright and
Similar Rights licensed here. However, if You fail to comply with
this Public License, then Your rights under this Public License
terminate automatically.
b. Where Your right to use the Licensed Material has terminated under
Section 6(a), it reinstates:
1. automatically as of the date the violation is cured, provided
it is cured within 30 days of Your discovery of the
violation; or
2. upon express reinstatement by the Licensor.
For the avoidance of doubt, this Section 6(b) does not affect any
right the Licensor may have to seek remedies for Your violations
of this Public License.
c. For the avoidance of doubt, the Licensor may also offer the
Licensed Material under separate terms or conditions or stop
distributing the Licensed Material at any time; however, doing so
will not terminate this Public License.
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
License.
Section 7 -- Other Terms and Conditions.
a. The Licensor shall not be bound by any additional or different
terms or conditions communicated by You unless expressly agreed.
b. Any arrangements, understandings, or agreements regarding the
Licensed Material not stated herein are separate from and
independent of the terms and conditions of this Public License.
Section 8 -- Interpretation.
a. For the avoidance of doubt, this Public License does not, and
shall not be interpreted to, reduce, limit, restrict, or impose
conditions on any use of the Licensed Material that could lawfully
be made without permission under this Public License.
b. To the extent possible, if any provision of this Public License is
deemed unenforceable, it shall be automatically reformed to the
minimum extent necessary to make it enforceable. If the provision
cannot be reformed, it shall be severed from this Public License
without affecting the enforceability of the remaining terms and
conditions.
c. No term or condition of this Public License will be waived and no
failure to comply consented to unless expressly agreed to by the
Licensor.
d. Nothing in this Public License constitutes or may be interpreted
as a limitation upon, or waiver of, any privileges and immunities
that apply to the Licensor or You, including from the legal
processes of any jurisdiction or authority.
=======================================================================

196
pom.xml
View File

@ -1,181 +1,65 @@
<project xmlns="http://maven.apache.org/POM/4.0.0">
<groupId>com.songoda</groupId>
<artifactId>EpicHoppers</artifactId>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<version>4.7.9</version>
<build>
<defaultGoal>clean install</defaultGoal>
<finalName>EpicHoppers-${project.version}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<groupId>com.craftaro</groupId>
<artifactId>EpicHoppers-Parent</artifactId>
<packaging>pom</packaging>
<version>5.0.1</version>
<!-- Run 'mvn versions:set -DgenerateBackupPoms=false -DnewVersion=X.Y.Z-DEV' to update version recursively -->
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<modules>
<module>EpicHoppers-API</module>
<module>EpicHoppers-Plugin</module>
</modules>
<plugin>
<groupId>com.google.code.maven-replacer-plugin</groupId>
<artifactId>replacer</artifactId>
<version>1.5.3</version>
<name>EpicHoppers</name>
<description>Connect hoppers over long distances, filter out unwanted items, auto break blocks, auto sell items and much more.</description>
<url>https://craftaro.com/marketplace/product/15</url>
<executions>
<execution>
<phase>prepare-package</phase>
<goals>
<goal>replace</goal>
</goals>
</execution>
</executions>
<properties>
<craftaro.coreVersion>3.0.0-SNAPSHOT</craftaro.coreVersion>
<configuration>
<file>${project.build.directory}/classes/plugin.yml</file>
<replacements>
<replacement>
<token>maven-version-number</token>
<value>${project.version}</value>
</replacement>
</replacements>
</configuration>
</plugin>
<maven.compiler.release>8</maven.compiler.release>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.3.0</version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<executions>
<execution>
<id>shaded</id>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<sonar.host.url>https://sonarcloud.io</sonar.host.url>
<sonar.moduleKey>${project.groupId}:${project.artifactId}</sonar.moduleKey>
</properties>
<configuration>
<shadedArtifactAttached>false</shadedArtifactAttached>
<createDependencyReducedPom>false</createDependencyReducedPom>
<issueManagement>
<url>https://discord.gg/craftaro</url>
<system>Discord server</system>
</issueManagement>
<artifactSet>
<includes>
<include>com.songoda:SongodaCore</include>
</includes>
</artifactSet>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
<relocations>
<relocation>
<pattern>com.songoda.core</pattern>
<shadedPattern>${project.groupId}.epichoppers.core</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<pluginRepositories>
<pluginRepository>
<id>apache.snapshots</id>
<url>https://repository.apache.org/snapshots/</url>
</pluginRepository>
</pluginRepositories>
<scm>
<url>https://github.com/craftaro/EpicHoppers</url>
<connection>scm:git:git://github.com/craftaro/EpicHoppers.git</connection>
</scm>
<repositories>
<repository>
<id>public</id>
<url>https://repo.songoda.com/repository/public/</url>
<id>craftaro-minecraft-plugins</id>
<url>https://repo.craftaro.com/repository/minecraft-plugins/</url>
</repository>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
<repository>
<id>spigotmc-repo</id>
<id>SpigotMC</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
</repositories>
<dependencies>
<!-- Dev dependencies -->
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.19.4-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.songoda</groupId>
<artifactId>skyblock</artifactId>
<version>2.3.30</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.songoda</groupId>
<artifactId>SongodaCore</artifactId>
<version>2.6.20</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.songoda</groupId>
<artifactId>EpicFarming</artifactId>
<version>3.0.24</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.github.brcdev-minecraft</groupId>
<artifactId>shopgui-api</artifactId>
<version>2.2.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.github.Gypopo</groupId>
<artifactId>EconomyShopGUI-API</artifactId>
<version>1.4.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.songoda</groupId>
<artifactId>UltimateStacker</artifactId>
<version>2.1.6</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.bgsoftware</groupId>
<artifactId>wildstacker</artifactId>
<version>3.5.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.github.DeadSilenceIV</groupId>
<artifactId>AdvancedChestsAPI</artifactId>
<version>2.2</version>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>24.0.1</version>
<scope>provided</scope>
</dependency>
</dependencies>

View File

@ -1,321 +0,0 @@
package com.songoda.epichoppers;
import com.songoda.core.SongodaCore;
import com.songoda.core.SongodaPlugin;
import com.songoda.core.commands.CommandManager;
import com.songoda.core.compatibility.CompatibleMaterial;
import com.songoda.core.configuration.Config;
import com.songoda.core.database.DataMigrationManager;
import com.songoda.core.database.DatabaseConnector;
import com.songoda.core.database.MySQLConnector;
import com.songoda.core.database.SQLiteConnector;
import com.songoda.core.gui.GuiManager;
import com.songoda.core.hooks.EconomyManager;
import com.songoda.core.hooks.ProtectionManager;
import com.songoda.core.locale.Locale;
import com.songoda.core.third_party.de.tr7zw.nbtapi.NBTItem;
import com.songoda.core.utils.TextUtils;
import com.songoda.epichoppers.boost.BoostManager;
import com.songoda.epichoppers.commands.CommandBoost;
import com.songoda.epichoppers.commands.CommandGive;
import com.songoda.epichoppers.commands.CommandReload;
import com.songoda.epichoppers.commands.CommandSettings;
import com.songoda.epichoppers.containers.ContainerManager;
import com.songoda.epichoppers.database.DataManager;
import com.songoda.epichoppers.database.migrations._1_InitialMigration;
import com.songoda.epichoppers.hopper.HopperManager;
import com.songoda.epichoppers.hopper.levels.Level;
import com.songoda.epichoppers.hopper.levels.LevelManager;
import com.songoda.epichoppers.hopper.levels.modules.Module;
import com.songoda.epichoppers.hopper.levels.modules.ModuleAutoCrafting;
import com.songoda.epichoppers.hopper.levels.modules.ModuleAutoSell;
import com.songoda.epichoppers.hopper.levels.modules.ModuleAutoSmelter;
import com.songoda.epichoppers.hopper.levels.modules.ModuleBlockBreak;
import com.songoda.epichoppers.hopper.levels.modules.ModuleMobHopper;
import com.songoda.epichoppers.hopper.levels.modules.ModuleSuction;
import com.songoda.epichoppers.hopper.teleport.TeleportHandler;
import com.songoda.epichoppers.listeners.BlockListeners;
import com.songoda.epichoppers.listeners.EntityListeners;
import com.songoda.epichoppers.listeners.HopperListeners;
import com.songoda.epichoppers.listeners.InteractListeners;
import com.songoda.epichoppers.listeners.InventoryListeners;
import com.songoda.epichoppers.player.PlayerDataManager;
import com.songoda.epichoppers.settings.Settings;
import com.songoda.epichoppers.tasks.HopTask;
import com.songoda.epichoppers.utils.Methods;
import com.songoda.skyblock.SkyBlock;
import com.songoda.skyblock.permission.BasicPermission;
import org.bukkit.Bukkit;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.plugin.PluginManager;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class EpicHoppers extends SongodaPlugin {
private static EpicHoppers INSTANCE;
private final GuiManager guiManager = new GuiManager(this);
private final Config levelsConfig = new Config(this, "levels.yml");
private HopperManager hopperManager;
private CommandManager commandManager;
private LevelManager levelManager;
private BoostManager boostManager;
private PlayerDataManager playerDataManager;
private ContainerManager containerManager;
private TeleportHandler teleportHandler;
private DatabaseConnector databaseConnector;
private DataManager dataManager;
public static EpicHoppers getInstance() {
return INSTANCE;
}
@Override
public void onPluginLoad() {
INSTANCE = this;
}
@Override
public void onPluginDisable() {
this.databaseConnector.closeConnection();
saveModules();
}
@Override
public void onPluginEnable() {
// Run Songoda Updater
SongodaCore.registerPlugin(this, 15, CompatibleMaterial.HOPPER);
// Load Economy
EconomyManager.load();
// Load protection hook
ProtectionManager.load(this);
// Setup Config
Settings.setupConfig();
this.setLocale(Settings.LANGUGE_MODE.getString(), false);
// Set Economy & Hologram preference
EconomyManager.getManager().setPreferredHook(Settings.ECONOMY_PLUGIN.getString());
// Register commands
this.commandManager = new CommandManager(this);
this.commandManager.addMainCommand("eh")
.addSubCommands(
new CommandBoost(this),
new CommandGive(this),
new CommandReload(this),
new CommandSettings(this)
);
this.hopperManager = new HopperManager();
this.playerDataManager = new PlayerDataManager();
this.containerManager = new ContainerManager(this);
this.boostManager = new BoostManager();
// Database stuff, go!
try {
if (Settings.MYSQL_ENABLED.getBoolean()) {
String hostname = Settings.MYSQL_HOSTNAME.getString();
int port = Settings.MYSQL_PORT.getInt();
String database = Settings.MYSQL_DATABASE.getString();
String username = Settings.MYSQL_USERNAME.getString();
String password = Settings.MYSQL_PASSWORD.getString();
boolean useSSL = Settings.MYSQL_USE_SSL.getBoolean();
int poolSize = Settings.MYSQL_POOL_SIZE.getInt();
this.databaseConnector = new MySQLConnector(this, hostname, port, database, username, password, useSSL, poolSize);
this.getLogger().info("Data handler connected using MySQL.");
} else {
this.databaseConnector = new SQLiteConnector(this);
this.getLogger().info("Data handler connected using SQLite.");
}
} catch (Exception ex) {
this.getLogger().severe("Fatal error trying to connect to database. Please make sure all your connection settings are correct and try again. Plugin has been disabled.");
this.emergencyStop();
}
this.dataManager = new DataManager(this.databaseConnector, this);
DataMigrationManager dataMigrationManager = new DataMigrationManager(this.databaseConnector, this.dataManager,
new _1_InitialMigration());
dataMigrationManager.runMigrations();
this.loadLevelManager();
new HopTask(this);
this.teleportHandler = new TeleportHandler(this);
// Register Listeners
guiManager.init();
PluginManager pluginManager = Bukkit.getPluginManager();
pluginManager.registerEvents(new HopperListeners(this), this);
pluginManager.registerEvents(new EntityListeners(), this);
pluginManager.registerEvents(new BlockListeners(this), this);
pluginManager.registerEvents(new InteractListeners(this), this);
pluginManager.registerEvents(new InventoryListeners(), this);
// Start auto save
int saveInterval = Settings.AUTOSAVE.getInt() * 60 * 20;
Bukkit.getScheduler().runTaskTimerAsynchronously(this, this::saveModules, saveInterval, saveInterval);
// Hotfix for EH loading before FSB
Bukkit.getScheduler().runTask(this, () -> {
if (pluginManager.isPluginEnabled("FabledSkyBlock")) {
try {
SkyBlock.getInstance().getPermissionManager().registerPermission(
(BasicPermission) Class.forName("com.songoda.epichoppers.compatibility.EpicHoppersPermission").getDeclaredConstructor().newInstance());
} catch (ReflectiveOperationException ex) {
ex.printStackTrace();
}
}
});
}
@Override
public void onDataLoad() {
// Load data from DB
this.dataManager.getHoppers((hoppers) -> {
this.hopperManager.addHoppers(hoppers.values());
this.dataManager.getBoosts((boosts) -> this.boostManager.addBoosts(boosts));
this.hopperManager.setReady();
});
}
@Override
public void onConfigReload() {
this.setLocale(getConfig().getString("System.Language Mode"), true);
this.locale.reloadMessages();
loadLevelManager();
}
@Override
public List<Config> getExtraConfig() {
return Collections.singletonList(levelsConfig);
}
private void loadLevelManager() {
if (!new File(this.getDataFolder(), "levels.yml").exists())
this.saveResource("levels.yml", false);
levelsConfig.load();
// Load an instance of LevelManager
levelManager = new LevelManager();
/*
* Register Levels into LevelManager from configuration.
*/
levelManager.clear();
for (String levelName : levelsConfig.getKeys(false)) {
int level = Integer.parseInt(levelName.split("-")[1]);
ConfigurationSection levels = levelsConfig.getConfigurationSection(levelName);
int radius = levels.getInt("Range");
int amount = levels.getInt("Amount");
int linkAmount = levels.getInt("Link-amount", 1);
boolean filter = levels.getBoolean("Filter");
boolean teleport = levels.getBoolean("Teleport");
int costExperience = levels.getInt("Cost-xp", -1);
int costEconomy = levels.getInt("Cost-eco", -1);
int autoSell = levels.getInt("AutoSell");
ArrayList<Module> modules = new ArrayList<>();
for (String key : levels.getKeys(false)) {
if (key.equals("Suction") && levels.getInt("Suction") != 0) {
modules.add(new ModuleSuction(this, levels.getInt("Suction")));
} else if (key.equals("BlockBreak") && levels.getInt("BlockBreak") != 0) {
modules.add(new ModuleBlockBreak(this, levels.getInt("BlockBreak")));
} else if (key.equals("AutoCrafting")) {
modules.add(new ModuleAutoCrafting(this));
} else if (key.equals("AutoSell")) {
modules.add(new ModuleAutoSell(this, autoSell));
} else if (key.equals("MobHopper")) {
modules.add(new ModuleMobHopper(this, levels.getInt("MobHopper")));
} else if (key.equals("AutoSmelting")) {
modules.add(new ModuleAutoSmelter(this, levels.getInt("AutoSmelting")));
}
}
levelManager.addLevel(level, costExperience, costEconomy, radius, amount, filter, teleport, linkAmount, modules);
}
}
private void saveModules() {
if (levelManager != null) {
for (Level level : levelManager.getLevels().values()) {
for (Module module : level.getRegisteredModules()) {
module.saveDataToFile();
}
}
}
}
public ItemStack newHopperItem(Level level) {
ItemStack item = new ItemStack(CompatibleMaterial.HOPPER.getMaterial());
ItemMeta itemmeta = item.getItemMeta();
itemmeta.setDisplayName(TextUtils.formatText(Methods.formatName(level.getLevel())));
String line = getLocale().getMessage("general.nametag.lore").getMessage();
if (!line.isEmpty()) {
itemmeta.setLore(Arrays.asList(line.split("\n")));
}
item.setItemMeta(itemmeta);
NBTItem nbtItem = new NBTItem(item);
nbtItem.setInteger("level", level.getLevel());
return nbtItem.getItem();
}
@Override
public Locale getLocale() {
return locale;
}
public TeleportHandler getTeleportHandler() {
return teleportHandler;
}
public BoostManager getBoostManager() {
return boostManager;
}
public CommandManager getCommandManager() {
return commandManager;
}
public LevelManager getLevelManager() {
return levelManager;
}
public HopperManager getHopperManager() {
return hopperManager;
}
public PlayerDataManager getPlayerDataManager() {
return playerDataManager;
}
public GuiManager getGuiManager() {
return guiManager;
}
public DataManager getDataManager() {
return dataManager;
}
public DatabaseConnector getDatabaseConnector() {
return databaseConnector;
}
public ContainerManager getContainerManager() {
return containerManager;
}
}

View File

@ -1,50 +0,0 @@
package com.songoda.epichoppers.boost;
import java.util.Objects;
import java.util.UUID;
public class BoostData {
private final int multiplier;
private final long endTime;
private final UUID player;
public BoostData(int multiplier, long endTime, UUID player) {
this.multiplier = multiplier;
this.endTime = endTime;
this.player = player;
}
public int getMultiplier() {
return multiplier;
}
public UUID getPlayer() {
return player;
}
public long getEndTime() {
return endTime;
}
@Override
public int hashCode() {
int result = 31 * multiplier;
result = 31 * result + (this.player == null ? 0 : player.hashCode());
result = 31 * result + (int) (endTime ^ (endTime >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof BoostData)) return false;
BoostData other = (BoostData) obj;
return multiplier == other.multiplier && endTime == other.endTime
&& Objects.equals(player, other.player);
}
}

View File

@ -1,13 +0,0 @@
package com.songoda.epichoppers.compatibility;
import com.songoda.skyblock.core.compatibility.CompatibleMaterial;
import com.songoda.skyblock.permission.BasicPermission;
import com.songoda.skyblock.permission.PermissionType;
public class EpicHoppersPermission extends BasicPermission {
public EpicHoppersPermission() {
super("EpicHoppers", CompatibleMaterial.HOPPER, PermissionType.GENERIC);
}
}

View File

@ -1,52 +0,0 @@
package com.songoda.epichoppers.containers.impl;
import com.songoda.epicfarming.EpicFarming;
import com.songoda.epicfarming.core.compatibility.CompatibleMaterial;
import com.songoda.epicfarming.farming.Farm;
import com.songoda.epichoppers.containers.CustomContainer;
import com.songoda.epichoppers.containers.IContainer;
import org.bukkit.block.Block;
import org.bukkit.inventory.ItemStack;
public class EpicFarmingImplementation implements IContainer {
@Override
public CustomContainer getCustomContainer(Block block) {
return new Container(block);
}
class Container extends CustomContainer {
private final Farm farm;
public Container(Block block) {
super(block);
this.farm = EpicFarming.getInstance().getFarmManager().getFarm(block);
}
@Override
public boolean addToContainer(ItemStack itemToMove) {
if (!farm.willFit(itemToMove)) {
return false;
}
farm.addItem(itemToMove);
return true;
}
@Override
public ItemStack[] getItems() {
return farm.getItems()
.stream().filter(i -> CompatibleMaterial.getMaterial(i) != CompatibleMaterial.BONE_MEAL)
.toArray(ItemStack[]::new);
}
@Override
public void removeFromContainer(ItemStack itemToMove, int amountToMove) {
farm.removeMaterial(itemToMove.getType(), amountToMove);
}
@Override
public boolean isContainer() {
return farm != null;
}
}
}

View File

@ -1,66 +0,0 @@
package com.songoda.epichoppers.containers.impl;
import com.songoda.epichoppers.containers.CustomContainer;
import com.songoda.epichoppers.containers.IContainer;
import com.songoda.skyblock.SkyBlock;
import com.songoda.skyblock.core.compatibility.CompatibleMaterial;
import com.songoda.skyblock.stackable.Stackable;
import com.songoda.skyblock.stackable.StackableManager;
import org.bukkit.block.Block;
import org.bukkit.inventory.ItemStack;
public class FabledSkyBlockImplementation implements IContainer {
@Override
public CustomContainer getCustomContainer(Block block) {
return new Container(block);
}
class Container extends CustomContainer {
private final Stackable stackable;
public Container(Block block) {
super(block);
StackableManager stackableManager = SkyBlock.getInstance().getStackableManager();
CompatibleMaterial compatibleMaterial = CompatibleMaterial.getMaterial(block);
this.stackable = stackableManager.getStack(block.getLocation(), compatibleMaterial);
}
@Override
public boolean addToContainer(ItemStack itemToMove) {
if (CompatibleMaterial.getMaterial(itemToMove) != stackable.getMaterial()) {
return false;
}
stackable.addOne();
if (stackable.getMaxSize() > 0 && stackable.isMaxSize()) {
stackable.setSize(stackable.getMaxSize());
return false;
}
return true;
}
@Override
public ItemStack[] getItems() {
ItemStack[] array = { new ItemStack(stackable.getMaterial().getMaterial(), stackable.getSize()) };
return array;
}
@Override
public void removeFromContainer(ItemStack itemToMove, int amountToMove) {
if (CompatibleMaterial.getMaterial(itemToMove) != stackable.getMaterial()) {
return;
}
stackable.setSize(stackable.getSize() - amountToMove);
}
@Override
public boolean isContainer() {
return stackable != null;
}
}
}

View File

@ -1,407 +0,0 @@
package com.songoda.epichoppers.database;
import com.songoda.core.database.DataManagerAbstract;
import com.songoda.core.database.DatabaseConnector;
import com.songoda.epichoppers.EpicHoppers;
import com.songoda.epichoppers.boost.BoostData;
import com.songoda.epichoppers.hopper.Filter;
import com.songoda.epichoppers.hopper.Hopper;
import com.songoda.epichoppers.hopper.HopperBuilder;
import com.songoda.epichoppers.hopper.ItemType;
import com.songoda.epichoppers.hopper.LinkType;
import com.songoda.epichoppers.hopper.teleport.TeleportTrigger;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin;
import org.bukkit.util.io.BukkitObjectInputStream;
import org.bukkit.util.io.BukkitObjectOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Base64;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.function.Consumer;
public class DataManager extends DataManagerAbstract {
public DataManager(DatabaseConnector databaseConnector, Plugin plugin) {
super(databaseConnector, plugin);
}
public void createBoost(BoostData boostData) {
this.runAsync(() -> {
try (Connection connection = this.databaseConnector.getConnection()){
String createBoostedPlayer = "INSERT INTO " + this.getTablePrefix() + "boosted_players (player, multiplier, end_time) VALUES (?, ?, ?)";
PreparedStatement statement = connection.prepareStatement(createBoostedPlayer);
statement.setString(1, boostData.getPlayer().toString());
statement.setInt(2, boostData.getMultiplier());
statement.setLong(3, boostData.getEndTime());
statement.executeUpdate();
} catch (Exception ex) {
ex.printStackTrace();
}
});
}
public void getBoosts(Consumer<List<BoostData>> callback) {
List<BoostData> boosts = new ArrayList<>();
this.runAsync(() -> {
try (Connection connection = this.databaseConnector.getConnection()){
Statement statement = connection.createStatement();
String selectBoostedPlayers = "SELECT * FROM " + this.getTablePrefix() + "boosted_players";
ResultSet result = statement.executeQuery(selectBoostedPlayers);
while (result.next()) {
UUID player = UUID.fromString(result.getString("player"));
int multiplier = result.getInt("multiplier");
long endTime = result.getLong("end_time");
boosts.add(new BoostData(multiplier, endTime, player));
}
this.sync(() -> callback.accept(boosts));
} catch (Exception ex) {
ex.printStackTrace();
}
});
}
public void deleteBoost(BoostData boostData) {
this.runAsync(() -> {
try (Connection connection = this.databaseConnector.getConnection()){
String deleteBoost = "DELETE FROM " + this.getTablePrefix() + "boosted_players WHERE end_time = ?";
PreparedStatement statement = connection.prepareStatement(deleteBoost);
statement.setLong(1, boostData.getEndTime());
statement.executeUpdate();
} catch (Exception ex) {
ex.printStackTrace();
}
});
}
public void createLink(Hopper hopper, Location location, LinkType type) {
this.runAsync(() -> {
try (Connection connection = this.databaseConnector.getConnection()){
String createLink = "INSERT INTO " + this.getTablePrefix() + "links (hopper_id, link_type, world, x, y, z) VALUES (?, ?, ?, ?, ?, ?)";
PreparedStatement statement = connection.prepareStatement(createLink);
statement.setInt(1, hopper.getId());
statement.setString(2, type.name());
statement.setString(3, location.getWorld().getName());
statement.setInt(4, location.getBlockX());
statement.setInt(5, location.getBlockY());
statement.setInt(6, location.getBlockZ());
statement.executeUpdate();
} catch (Exception ex) {
ex.printStackTrace();
}
});
}
public void updateItems(Hopper hopper, ItemType type, List<ItemStack> items) {
this.runAsync(() -> {
try (Connection connection = this.databaseConnector.getConnection()){
String clearItems = "DELETE FROM " + this.getTablePrefix() + "items WHERE hopper_id = ? AND item_type = ?";
try (PreparedStatement statement = connection.prepareStatement(clearItems)) {
statement.setInt(1, hopper.getId());
statement.setString(2, type.name());
statement.executeUpdate();
}
String createItem = "INSERT INTO " + this.getTablePrefix() + "items (hopper_id, item_type, item) VALUES (?, ?, ?)";
try (PreparedStatement statement = connection.prepareStatement(createItem)) {
for (ItemStack item : items) {
statement.setInt(1, hopper.getId());
statement.setString(2, type.name());
try (ByteArrayOutputStream stream = new ByteArrayOutputStream(); BukkitObjectOutputStream bukkitStream = new BukkitObjectOutputStream(stream)) {
bukkitStream.writeObject(item);
statement.setString(3, Base64.getEncoder().encodeToString(stream.toByteArray()));
} catch (IOException e) {
e.printStackTrace();
continue;
}
statement.addBatch();
}
statement.executeBatch();
}
} catch (Exception ex) {
ex.printStackTrace();
}
});
}
public void deleteLink(Hopper hopper, Location location) {
this.runAsync(() -> {
try (Connection connection = this.databaseConnector.getConnection()){
String deleteLink = "DELETE FROM " + this.getTablePrefix() + "links WHERE hopper_id = ? AND world = ? AND x = ? AND y = ? AND z = ?";
PreparedStatement statement = connection.prepareStatement(deleteLink);
statement.setInt(1, hopper.getId());
statement.setString(2, location.getWorld().getName());
statement.setInt(3, location.getBlockX());
statement.setInt(4, location.getBlockY());
statement.setInt(5, location.getBlockZ());
statement.executeUpdate();
} catch (Exception ex) {
ex.printStackTrace();
}
});
}
public void deleteLinks(Hopper hopper) {
this.runAsync(() -> {
try (Connection connection = this.databaseConnector.getConnection()){
String deleteHopperLinks = "DELETE FROM " + this.getTablePrefix() + "links WHERE hopper_id = ?";
PreparedStatement statement = connection.prepareStatement(deleteHopperLinks);
statement.setInt(1, hopper.getId());
statement.executeUpdate();
} catch (Exception ex) {
ex.printStackTrace();
}
});
}
public void createHoppers(List<Hopper> hoppers) {
for (Hopper hopper : hoppers)
createHopper(hopper);
}
public void createHopper(Hopper hopper) {
this.runAsync(() -> {
try (Connection connection = this.databaseConnector.getConnection()){
String createHopper = "INSERT INTO " + this.getTablePrefix() + "placed_hoppers (level, placed_by, last_opened_by, teleport_trigger, world, x, y, z) VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
try (PreparedStatement statement = connection.prepareStatement(createHopper)) {
statement.setInt(1, hopper.getLevel().getLevel());
statement.setString(2,
hopper.getPlacedBy() == null ? null : hopper.getPlacedBy().toString());
statement.setString(3,
hopper.getLastPlayerOpened() == null ? null : hopper.getLastPlayerOpened().toString());
statement.setString(4, hopper.getTeleportTrigger().name());
statement.setString(5, hopper.getWorld().getName());
statement.setInt(6, hopper.getX());
statement.setInt(7, hopper.getY());
statement.setInt(8, hopper.getZ());
statement.executeUpdate();
}
int hopperId = this.lastInsertedId(connection, "placed_hoppers");
hopper.setId(hopperId);
Map<ItemStack, ItemType> items = new HashMap<>();
Filter filter = hopper.getFilter();
for (ItemStack item : filter.getWhiteList())
items.put(item, ItemType.WHITELIST);
for (ItemStack item : filter.getBlackList())
items.put(item, ItemType.BLACKLIST);
for (ItemStack item : filter.getVoidList())
items.put(item, ItemType.VOID);
for (ItemStack item : filter.getAutoSellWhiteList())
items.put(item, ItemType.AUTO_SELL_WHITELIST);
for (ItemStack item : filter.getAutoSellBlackList())
items.put(item, ItemType.AUTO_SELL_BLACKLIST);
String createItem = "INSERT INTO " + this.getTablePrefix() + "items (hopper_id, item_type, item) VALUES (?, ?, ?)";
try (PreparedStatement statement = connection.prepareStatement(createItem)) {
for (Map.Entry<ItemStack, ItemType> entry : items.entrySet()) {
statement.setInt(1, hopper.getId());
statement.setString(2, entry.getValue().name());
try (ByteArrayOutputStream stream = new ByteArrayOutputStream(); BukkitObjectOutputStream bukkitStream = new BukkitObjectOutputStream(stream)) {
bukkitStream.writeObject(entry.getKey());
statement.setString(3, Base64.getEncoder().encodeToString(stream.toByteArray()));
} catch (IOException e) {
e.printStackTrace();
continue;
}
statement.addBatch();
}
statement.executeBatch();
}
Map<Location, LinkType> links = new HashMap<>();
for (Location location : hopper.getLinkedBlocks())
links.put(location, LinkType.REGULAR);
if (filter.getEndPoint() != null)
links.put(filter.getEndPoint(), LinkType.REJECT);
String createLink = "INSERT INTO " + this.getTablePrefix() + "links (hopper_id, link_type, world, x, y, z) VALUES (?, ?, ?, ?, ?, ?)";
try (PreparedStatement statement = connection.prepareStatement(createLink)) {
for (Map.Entry<Location, LinkType> entry : links.entrySet()) {
statement.setInt(1, hopper.getId());
statement.setString(2, entry.getValue().name());
Location location = entry.getKey();
statement.setString(3, location.getWorld().getName());
statement.setInt(4, location.getBlockX());
statement.setInt(5, location.getBlockY());
statement.setInt(6, location.getBlockZ());
statement.addBatch();
}
statement.executeBatch();
}
} catch (Exception ex) {
ex.printStackTrace();
}
});
}
public void updateHopper(Hopper hopper) {
this.runAsync(() -> {
try (Connection connection = this.databaseConnector.getConnection()){
String updateHopper = "UPDATE " + this.getTablePrefix() + "placed_hoppers SET level = ?, placed_by = ?, last_opened_by = ?, teleport_trigger = ? WHERE id = ?";
PreparedStatement statement = connection.prepareStatement(updateHopper);
statement.setInt(1, hopper.getLevel().getLevel());
statement.setString(2, hopper.getPlacedBy().toString());
statement.setString(3, hopper.getLastPlayerOpened().toString());
statement.setString(4, hopper.getTeleportTrigger().name());
statement.setInt(5, hopper.getId());
statement.executeUpdate();
} catch (Exception ex) {
ex.printStackTrace();
}
});
}
public void deleteHopper(Hopper hopper) {
this.runAsync(() -> {
try (Connection connection = this.databaseConnector.getConnection()){
String deleteHopper = "DELETE FROM " + this.getTablePrefix() + "placed_hoppers WHERE id = ?";
try (PreparedStatement statement = connection.prepareStatement(deleteHopper)) {
statement.setInt(1, hopper.getId());
statement.executeUpdate();
}
String deleteHopperLinks = "DELETE FROM " + this.getTablePrefix() + "links WHERE hopper_id = ?";
try (PreparedStatement statement = connection.prepareStatement(deleteHopperLinks)) {
statement.setInt(1, hopper.getId());
statement.executeUpdate();
}
String deleteItems = "DELETE FROM " + this.getTablePrefix() + "items WHERE hopper_id = ?";
try (PreparedStatement statement = connection.prepareStatement(deleteItems)) {
statement.setInt(1, hopper.getId());
statement.executeUpdate();
}
} catch (Exception ex) {
ex.printStackTrace();
}
});
}
public void getHoppers(Consumer<Map<Integer, Hopper>> callback) {
this.runAsync(() -> {
try (Connection connection = this.databaseConnector.getConnection()){
Map<Integer, Hopper> hoppers = new HashMap<>();
try (Statement statement = connection.createStatement()) {
String selectHoppers = "SELECT * FROM " + this.getTablePrefix() + "placed_hoppers";
ResultSet result = statement.executeQuery(selectHoppers);
while (result.next()) {
World world = Bukkit.getWorld(result.getString("world"));
if (world == null)
continue;
int id = result.getInt("id");
int level = result.getInt("level");
String placedByStr = result.getString("placed_by");
UUID placedBy = placedByStr == null ? null : UUID.fromString(result.getString("placed_by"));
String lastOpenedByStr = result.getString("last_opened_by");
UUID lastOpenedBy = lastOpenedByStr == null ? null : UUID.fromString(result.getString("last_opened_by"));
TeleportTrigger teleportTrigger = TeleportTrigger.valueOf(result.getString("teleport_trigger"));
int x = result.getInt("x");
int y = result.getInt("y");
int z = result.getInt("z");
Location location = new Location(world, x, y, z);
Hopper hopper = new HopperBuilder(location)
.setId(id)
.setLevel(EpicHoppers.getInstance().getLevelManager().getLevel(level))
.setPlacedBy(placedBy)
.setLastPlayerOpened(lastOpenedBy)
.setTeleportTrigger(teleportTrigger)
.build();
hoppers.put(id, hopper);
}
}
try (Statement statement = connection.createStatement()) {
String selectLinks = "SELECT * FROM " + this.getTablePrefix() + "links";
ResultSet result = statement.executeQuery(selectLinks);
while (result.next()) {
World world = Bukkit.getWorld(result.getString("world"));
if (world == null)
continue;
int id = result.getInt("hopper_id");
LinkType type = LinkType.valueOf(result.getString("link_type"));
int x = result.getInt("x");
int y = result.getInt("y");
int z = result.getInt("z");
Location location = new Location(world, x, y, z);
Hopper hopper = hoppers.get(id);
if (hopper == null) break;
hopper.addLinkedBlock(location, type);
}
}
try (Statement statement = connection.createStatement()) {
String selectItems = "SELECT * FROM " + this.getTablePrefix() + "items";
ResultSet result = statement.executeQuery(selectItems);
while (result.next()) {
int id = result.getInt("hopper_id");
ItemType type = ItemType.valueOf(result.getString("item_type"));
ItemStack item = null;
try (BukkitObjectInputStream stream = new BukkitObjectInputStream(
new ByteArrayInputStream(Base64.getDecoder().decode(result.getString("item"))))) {
item = (ItemStack) stream.readObject();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
Hopper hopper = hoppers.get(id);
if (hopper == null) break;
if (item != null)
hopper.getFilter().addItem(item, type);
}
}
this.sync(() -> callback.accept(hoppers));
} catch (Exception ex) {
ex.printStackTrace();
}
});
}
}

View File

@ -1,276 +0,0 @@
package com.songoda.epichoppers.gui;
import com.songoda.core.compatibility.CompatibleMaterial;
import com.songoda.core.compatibility.ServerVersion;
import com.songoda.core.gui.CustomizableGui;
import com.songoda.core.gui.GuiUtils;
import com.songoda.core.utils.TextUtils;
import com.songoda.epichoppers.EpicHoppers;
import com.songoda.epichoppers.boost.BoostData;
import com.songoda.epichoppers.hopper.Hopper;
import com.songoda.epichoppers.hopper.levels.Level;
import com.songoda.epichoppers.hopper.levels.modules.Module;
import com.songoda.epichoppers.player.SyncType;
import com.songoda.epichoppers.settings.Settings;
import com.songoda.epichoppers.utils.CostType;
import com.songoda.epichoppers.utils.Methods;
import com.songoda.epichoppers.hopper.teleport.TeleportTrigger;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class GUIOverview extends CustomizableGui {
private final EpicHoppers plugin;
private final Hopper hopper;
private final Player player;
private int task;
public GUIOverview(EpicHoppers plugin, Hopper hopper, Player player) {
super(plugin, "overview");
this.plugin = plugin;
this.hopper = hopper;
this.player = player;
setRows(3);
setTitle(Methods.formatName(hopper.getLevel().getLevel()));
runTask();
constructGUI();
this.setOnClose(action -> {
hopper.setActivePlayer(null);
Bukkit.getScheduler().cancelTask(task);
});
}
private void constructGUI() {
ItemStack glass1 = GuiUtils.getBorderItem(Settings.GLASS_TYPE_1.getMaterial());
ItemStack glass2 = GuiUtils.getBorderItem(Settings.GLASS_TYPE_2.getMaterial());
ItemStack glass3 = GuiUtils.getBorderItem(Settings.GLASS_TYPE_3.getMaterial());
setDefaultItem(glass1);
mirrorFill("mirrorfill_1", 0, 0, true, true, glass2);
mirrorFill("mirrorfill_2", 0, 1, true, true, glass2);
mirrorFill("mirrorfill_3", 0, 2, true, true, glass3);
mirrorFill("mirrorfill_4", 1, 0, false, true, glass2);
mirrorFill("mirrorfill_5", 1, 1, false, true, glass3);
plugin.getPlayerDataManager().getPlayerData(player).setLastHopper(hopper);
Level level = hopper.getLevel();
Level nextLevel = plugin.getLevelManager().getHighestLevel().getLevel() > level.getLevel() ? plugin.getLevelManager().getLevel(level.getLevel() + 1) : null;
ItemStack perl = new ItemStack(Material.ENDER_PEARL, 1);
ItemMeta perlmeta = perl.getItemMeta();
perlmeta.setDisplayName(plugin.getLocale().getMessage("interface.hopper.perltitle").getMessage());
ArrayList<String> loreperl = new ArrayList<>();
String[] parts = plugin.getLocale().getMessage("interface.hopper.perllore2")
.processPlaceholder("type", hopper.getTeleportTrigger() == TeleportTrigger.DISABLED
? plugin.getLocale().getMessage("general.word.disabled").getMessage()
: hopper.getTeleportTrigger().name()).getMessage().split("\\|");
for (String line : parts) {
loreperl.add(TextUtils.formatText(line));
}
perlmeta.setLore(loreperl);
perl.setItemMeta(perlmeta);
ItemStack filter = new ItemStack(ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13) ? Material.COMPARATOR : Material.valueOf("REDSTONE_COMPARATOR"), 1);
ItemMeta filtermeta = filter.getItemMeta();
filtermeta.setDisplayName(plugin.getLocale().getMessage("interface.hopper.filtertitle").getMessage());
ArrayList<String> lorefilter = new ArrayList<>();
parts = plugin.getLocale().getMessage("interface.hopper.filterlore").getMessage().split("\\|");
for (String line : parts) {
lorefilter.add(TextUtils.formatText(line));
}
filtermeta.setLore(lorefilter);
filter.setItemMeta(filtermeta);
ItemStack item = new ItemStack(Material.HOPPER, 1);
ItemMeta itemmeta = item.getItemMeta();
itemmeta.setDisplayName(plugin.getLocale().getMessage("interface.hopper.currentlevel").processPlaceholder("level", level.getLevel()).getMessage());
List<String> lore = level.getDescription();
if (plugin.getConfig().getBoolean("Main.Allow hopper Upgrading")) {
lore.add("");
if (nextLevel == null)
lore.add(plugin.getLocale().getMessage("interface.hopper.alreadymaxed").getMessage());
else {
lore.add(plugin.getLocale().getMessage("interface.hopper.nextlevel").processPlaceholder("level", nextLevel.getLevel()).getMessage());
lore.addAll(nextLevel.getDescription());
}
}
BoostData boostData = plugin.getBoostManager().getBoost(hopper.getPlacedBy());
if (boostData != null) {
parts = plugin.getLocale().getMessage("interface.hopper.boostedstats")
.processPlaceholder("amount", Integer.toString(boostData.getMultiplier()))
.processPlaceholder("time", Methods.makeReadable(boostData.getEndTime() - System.currentTimeMillis()))
.getMessage().split("\\|");
lore.add("");
for (String line : parts)
lore.add(TextUtils.formatText(line));
}
itemmeta.setLore(lore);
item.setItemMeta(itemmeta);
ItemStack hook = new ItemStack(Material.TRIPWIRE_HOOK, 1);
ItemMeta hookmeta = hook.getItemMeta();
hookmeta.setDisplayName(plugin.getLocale().getMessage("interface.hopper.synchopper").getMessage());
ArrayList<String> lorehook = new ArrayList<>();
parts = plugin.getLocale().getMessage("interface.hopper.synclore")
.processPlaceholder("amount", hopper.getLinkedBlocks().stream().distinct().count())
.getMessage().split("\\|");
for (String line : parts) {
lorehook.add(TextUtils.formatText(line));
}
hookmeta.setLore(lorehook);
hook.setItemMeta(hookmeta);
Map<Integer, Integer[]> layouts = new HashMap<>();
layouts.put(1, new Integer[]{22});
layouts.put(2, new Integer[]{22, 4});
layouts.put(3, new Integer[]{22, 3, 5});
layouts.put(4, new Integer[]{23, 3, 5, 21});
layouts.put(5, new Integer[]{23, 3, 5, 21, 22});
layouts.put(6, new Integer[]{23, 3, 4, 5, 21, 22});
layouts.put(7, new Integer[]{23, 3, 4, 5, 21, 22, 12});
layouts.put(8, new Integer[]{23, 3, 4, 5, 21, 22, 12, 14});
layouts.put(9, new Integer[]{23, 3, 4, 5, 21, 22, 12, 14, 20});
layouts.put(10, new Integer[]{23, 3, 4, 5, 21, 22, 12, 14, 20, 24});
int amount = 1;
boolean canFilter = level.isFilter() || player.hasPermission("EpicHoppers.Filter");
boolean canTeleport = level.isTeleport() || player.hasPermission("EpicHoppers.Teleport");
if (canFilter) amount++;
if (canTeleport) amount++;
List<Module> modules = level.getRegisteredModules().stream().filter(module ->
module.getGUIButton(hopper) != null).collect(Collectors.toList());
amount += modules.size();
Integer[] layout = layouts.get(amount);
for (int ii = 0; ii < amount; ii++) {
int slot = layout[ii];
if (ii == 0) {
setButton("sync", slot, hook,
(event) -> {
if (hopper.getLastPlayerOpened() != null && !hopper.getLastPlayerOpened().equals(player.getUniqueId())) {
plugin.getLocale().getMessage("event.hopper.syncdidnotplace").sendPrefixedMessage(player);
return;
}
hopper.clearLinkedBlocks();
plugin.getDataManager().deleteLinks(hopper);
if (event.clickType == ClickType.RIGHT) {
plugin.getLocale().getMessage("event.hopper.desync").sendPrefixedMessage(player);
constructGUI();
return;
} else {
plugin.getPlayerDataManager().getPlayerData(player).setSyncType(SyncType.REGULAR);
plugin.getLocale().getMessage("event.hopper.syncnext").sendPrefixedMessage(player);
if (level.getLinkAmount() > 1)
plugin.getLocale().getMessage("event.hopper.syncstart")
.processPlaceholder("amount", level.getLinkAmount())
.sendPrefixedMessage(player);
hopper.timeout(player);
}
player.closeInventory();
});
} else if (canTeleport) {
setButton("teleport", slot, perl,
(event) -> {
if (event.clickType == ClickType.LEFT) {
if (hopper.getLinkedBlocks() != null) {
plugin.getTeleportHandler().tpEntity(player, hopper);
player.closeInventory();
}
} else {
if (hopper.getTeleportTrigger() == TeleportTrigger.DISABLED) {
hopper.setTeleportTrigger(TeleportTrigger.SNEAK);
} else if (hopper.getTeleportTrigger() == TeleportTrigger.SNEAK) {
hopper.setTeleportTrigger(TeleportTrigger.WALK_ON);
} else if (hopper.getTeleportTrigger() == TeleportTrigger.WALK_ON) {
hopper.setTeleportTrigger(TeleportTrigger.DISABLED);
}
plugin.getDataManager().updateHopper(hopper);
constructGUI();
}
});
canTeleport = false;
} else if (canFilter) {
setButton("filter", slot, filter, (event) -> {
hopper.setActivePlayer(player);
guiManager.showGUI(player, new GUIFilter(plugin, hopper, player));
});
canFilter = false;
} else {
if (modules.isEmpty()) break;
Module module = modules.get(0);
modules.remove(module);
setButton(module.getName().toLowerCase().replace(" ", "_"), slot, module.getGUIButton(hopper),
(event) -> module.runButtonPress(player, hopper, event.clickType));
}
}
if (Settings.HOPPER_UPGRADING.getBoolean()) {
if (Settings.UPGRADE_WITH_XP.getBoolean()
&& level.getCostExperience() != -1
&& player.hasPermission("EpicHoppers.Upgrade.XP")) {
setButton("upgrade_xp", 1, 2, GuiUtils.createButtonItem(
Settings.XP_ICON.getMaterial(CompatibleMaterial.EXPERIENCE_BOTTLE),
plugin.getLocale().getMessage("interface.hopper.upgradewithxp").getMessage(),
nextLevel != null
? plugin.getLocale().getMessage("interface.hopper.upgradewithxplore")
.processPlaceholder("cost", nextLevel.getCostExperience()).getMessage()
: plugin.getLocale().getMessage("interface.hopper.alreadymaxed").getMessage()),
(event) -> {
hopper.upgrade(player, CostType.EXPERIENCE);
hopper.overview(guiManager, player);
});
}
if (Settings.UPGRADE_WITH_ECONOMY.getBoolean()
&& level.getCostEconomy() != -1
&& player.hasPermission("EpicHoppers.Upgrade.ECO")) {
setButton("upgrade_economy", 1, 6, GuiUtils.createButtonItem(
Settings.ECO_ICON.getMaterial(CompatibleMaterial.SUNFLOWER),
plugin.getLocale().getMessage("interface.hopper.upgradewitheconomy").getMessage(),
nextLevel != null
? plugin.getLocale().getMessage("interface.hopper.upgradewitheconomylore")
.processPlaceholder("cost", Methods.formatEconomy(nextLevel.getCostEconomy())).getMessage()
: plugin.getLocale().getMessage("interface.hopper.alreadymaxed").getMessage()),
(event) -> {
hopper.upgrade(player, CostType.ECONOMY);
hopper.overview(guiManager, player);
});
}
}
setItem("hopper", 13, item);
hopper.setLastPlayerOpened(player.getUniqueId());
}
private void runTask() {
task = Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, () -> {
if (!inventory.getViewers().isEmpty())
this.constructGUI();
}, 5L, 5L);
}
}

View File

@ -1,112 +0,0 @@
package com.songoda.epichoppers.gui;
import com.songoda.core.compatibility.CompatibleMaterial;
import com.songoda.core.gui.CustomizableGui;
import com.songoda.core.gui.GuiUtils;
import com.songoda.core.utils.TextUtils;
import com.songoda.epichoppers.EpicHoppers;
import com.songoda.epichoppers.hopper.Hopper;
import com.songoda.epichoppers.hopper.levels.modules.ModuleAutoSmelter;
import com.songoda.epichoppers.settings.Settings;
import com.songoda.epichoppers.utils.Methods;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class GUISmeltable extends CustomizableGui {
private final EpicHoppers plugin;
private final Hopper hopper;
private int maxPages;
private ModuleAutoSmelter moduleAutoSmelter;
private static List<CompatibleMaterial> burnables = Arrays.stream(CompatibleMaterial.values())
.filter(m -> m.getBurnResult() != null).collect(Collectors.toList());
public GUISmeltable(ModuleAutoSmelter moduleAutoSmelter, EpicHoppers plugin, Hopper hopper) {
super(plugin, "smeltable");
this.plugin = plugin;
this.hopper = hopper;
this.moduleAutoSmelter = moduleAutoSmelter;
int smeltables = burnables.size();
maxPages = (int) Math.ceil(smeltables / 32.);
setTitle(Methods.formatName(hopper.getLevel().getLevel()) + TextUtils.formatText(" &7-&f Smelting"));
setRows(6);
this.setOnPage((event) -> showPage());
showPage();
this.setOnClose((event) -> hopper.setActivePlayer(null));
}
void showPage() {
ItemStack glass1 = GuiUtils.getBorderItem(Settings.GLASS_TYPE_1.getMaterial());
ItemStack glass2 = GuiUtils.getBorderItem(Settings.GLASS_TYPE_2.getMaterial());
ItemStack glass3 = GuiUtils.getBorderItem(Settings.GLASS_TYPE_3.getMaterial());
setDefaultItem(glass1);
mirrorFill("mirrorfill_1", 0, 0, true, true, glass2);
mirrorFill("mirrorfill_2", 0, 1, true, true, glass2);
mirrorFill("mirrorfill_3", 0, 2, true, true, glass3);
mirrorFill("mirrorfill_4", 1, 0, true, true, glass2);
int smeltableIndex = page == 1 ? 0 : 32 * (page - 1);
for (int i = 9; i < 45; i++) {
if (i == 9 || i == 17 || i == 44 || i == 36) continue;
setItem(i, null);
clearActions(i);
if (smeltableIndex >= (burnables.size() - 1)) continue;
CompatibleMaterial burnable = burnables.get(smeltableIndex);
setButton(i, getItemStack(burnable, moduleAutoSmelter.isSmeltable(hopper, burnable)), (event) -> {
moduleAutoSmelter.toggleSmeltable(hopper, burnable);
setItem(event.slot, getItemStack(burnable, moduleAutoSmelter.isSmeltable(hopper, burnable)));
});
smeltableIndex++;
}
clearActions(51);
if (page < maxPages) {
setButton("next", 51, GuiUtils.createButtonItem(CompatibleMaterial.ARROW,
plugin.getLocale().getMessage("general.nametag.next").getMessage()),
(event) -> {
page++;
showPage();
});
}
clearActions(47);
if (page > 1) {
setButton("back", 47, GuiUtils.createButtonItem(CompatibleMaterial.ARROW,
plugin.getLocale().getMessage("general.nametag.back").getMessage()),
(event) -> {
page--;
showPage();
});
}
setButton("exit", 49, GuiUtils.createButtonItem(CompatibleMaterial.OAK_DOOR,
plugin.getLocale().getMessage("general.nametag.exit").getMessage()),
(event) -> hopper.overview(plugin.getGuiManager(), event.player));
}
public ItemStack getItemStack(CompatibleMaterial material, boolean enabled) {
ItemStack item = material.getItem();
ItemMeta meta = item.getItemMeta();
meta.setDisplayName(TextUtils.formatText("&e" + material.name()));
meta.setLore(Arrays.asList(TextUtils.formatText(" &7-> &e" + material.getBurnResult().name()),
TextUtils.formatText("&7Enabled: &6" + String.valueOf(enabled).toLowerCase() + "&7."),
"",
plugin.getLocale().getMessage("interface.hopper.toggle").getMessage()));
item.setItemMeta(meta);
return item;
}
}

View File

@ -1,361 +0,0 @@
package com.songoda.epichoppers.hopper;
import com.songoda.core.compatibility.CompatibleParticleHandler;
import com.songoda.core.compatibility.CompatibleSound;
import com.songoda.core.compatibility.ServerVersion;
import com.songoda.core.gui.GuiManager;
import com.songoda.core.hooks.EconomyManager;
import com.songoda.epichoppers.EpicHoppers;
import com.songoda.epichoppers.api.events.HopperAccessEvent;
import com.songoda.epichoppers.gui.GUIOverview;
import com.songoda.epichoppers.hopper.levels.Level;
import com.songoda.epichoppers.hopper.teleport.TeleportTrigger;
import com.songoda.epichoppers.player.PlayerData;
import com.songoda.epichoppers.settings.Settings;
import com.songoda.epichoppers.utils.CostType;
import com.songoda.epichoppers.utils.Methods;
import org.bukkit.*;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
/**
* Created by songoda on 3/14/2017.
*/
public class Hopper {
// Id for database use.
private int id;
private final Location location;
private Level level = EpicHoppers.getInstance().getLevelManager().getLowestLevel();
private UUID lastPlayerOpened = null;
private UUID placedBy = null;
private final List<Location> linkedBlocks = new ArrayList<>();
private Filter filter = new Filter();
private TeleportTrigger teleportTrigger = TeleportTrigger.DISABLED;
private int transferTick = 0;
private int syncId = -1;
private Player activePlayer;
private final Map<String, Object> moduleCache = new HashMap<>();
public Hopper(Location location) {
this.location = location;
}
public void overview(GuiManager guiManager, Player player) {
if (lastPlayerOpened != null
&& lastPlayerOpened != player.getUniqueId()
&& Bukkit.getPlayer(lastPlayerOpened) != null) {
Bukkit.getPlayer(lastPlayerOpened).closeInventory();
}
HopperAccessEvent accessEvent = new HopperAccessEvent(player, this);
Bukkit.getPluginManager().callEvent(accessEvent);
if (accessEvent.isCancelled()) {
return;
}
if (placedBy == null) placedBy = player.getUniqueId();
EpicHoppers instance = EpicHoppers.getInstance();
if (!player.hasPermission("epichoppers.overview")) return;
setActivePlayer(player);
guiManager.showGUI(player, new GUIOverview(instance, this, player));
}
public void forceClose() {
if (activePlayer != null)
activePlayer.closeInventory();
}
public void dropItems() {
Inventory inventory = ((InventoryHolder) location.getBlock().getState()).getInventory();
World world = location.getWorld();
for (ItemStack itemStack : inventory.getContents()) {
if (itemStack == null || itemStack.getType() == Material.AIR) {
continue;
}
world.dropItemNaturally(location, itemStack);
}
}
public void upgrade(Player player, CostType type) {
EpicHoppers plugin = EpicHoppers.getInstance();
if (!plugin.getLevelManager().getLevels().containsKey(this.level.getLevel() + 1)) return;
Level level = plugin.getLevelManager().getLevel(this.level.getLevel() + 1);
int cost = type == CostType.ECONOMY ? level.getCostEconomy() : level.getCostExperience();
if (type == CostType.ECONOMY) {
if (!EconomyManager.isEnabled()) {
player.sendMessage("Economy not enabled.");
return;
}
if (!EconomyManager.hasBalance(player, cost)) {
plugin.getLocale().getMessage("event.upgrade.cannotafford").sendPrefixedMessage(player);
return;
}
EconomyManager.withdrawBalance(player, cost);
upgradeFinal(level, player);
} else if (type == CostType.EXPERIENCE) {
if (player.getLevel() >= cost || player.getGameMode() == GameMode.CREATIVE) {
if (player.getGameMode() != GameMode.CREATIVE) {
player.setLevel(player.getLevel() - cost);
}
upgradeFinal(level, player);
} else {
plugin.getLocale().getMessage("event.upgrade.cannotafford").sendPrefixedMessage(player);
}
}
}
private void upgradeFinal(Level level, Player player) {
EpicHoppers plugin = EpicHoppers.getInstance();
this.level = level;
plugin.getDataManager().updateHopper(this);
syncName();
if (plugin.getLevelManager().getHighestLevel() != level) {
plugin.getLocale().getMessage("event.upgrade.success")
.processPlaceholder("level", level.getLevel()).sendPrefixedMessage(player);
} else {
plugin.getLocale().getMessage("event.upgrade.maxed")
.processPlaceholder("level", level.getLevel()).sendPrefixedMessage(player);
}
Location loc = location.clone().add(.5, .5, .5);
if (!Settings.UPGRADE_PARTICLE_TYPE.getString().trim().isEmpty()) {
CompatibleParticleHandler.spawnParticles(
CompatibleParticleHandler.ParticleType.getParticle(Settings.UPGRADE_PARTICLE_TYPE.getString()),
loc, 100, .5, .5, .5);
}
if (plugin.getLevelManager().getHighestLevel() != level) {
player.playSound(player.getLocation(), CompatibleSound.ENTITY_PLAYER_LEVELUP.getSound(), 0.6F, 15.0F);
} else {
player.playSound(player.getLocation(), CompatibleSound.ENTITY_PLAYER_LEVELUP.getSound(), 2F, 25.0F);
player.playSound(player.getLocation(), CompatibleSound.BLOCK_NOTE_BLOCK_CHIME.getSound(), 2F, 25.0F);
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, () -> player.playSound(player.getLocation(), CompatibleSound.BLOCK_NOTE_BLOCK_CHIME.getSound(), 1.2F, 35.0F), 5L);
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, () -> player.playSound(player.getLocation(), CompatibleSound.BLOCK_NOTE_BLOCK_CHIME.getSound(), 1.8F, 35.0F), 10L);
}
}
private void syncName() {
org.bukkit.block.Hopper hopper = (org.bukkit.block.Hopper) location.getBlock().getState();
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_10))
hopper.setCustomName(Methods.formatName(level.getLevel()));
hopper.update(true);
}
public void timeout(Player player) {
EpicHoppers instance = EpicHoppers.getInstance();
syncId = Bukkit.getScheduler().scheduleSyncDelayedTask(instance, () -> {
PlayerData playerData = instance.getPlayerDataManager().getPlayerData(player);
if (playerData.getSyncType() != null && playerData.getLastHopper() == this) {
instance.getLocale().getMessage("event.hopper.synctimeout").sendPrefixedMessage(player);
playerData.setSyncType(null);
}
}, Settings.LINK_TIMEOUT.getLong() * level.getLinkAmount());
}
public void link(Block toLink, boolean filtered, Player player) {
EpicHoppers instance = EpicHoppers.getInstance();
if (location.getWorld().equals(toLink.getLocation().getWorld())
&& !player.hasPermission("EpicHoppers.Override")
&& !player.hasPermission("EpicHoppers.Admin")
&& location.distance(toLink.getLocation()) > level.getRange()) {
instance.getLocale().getMessage("event.hopper.syncoutofrange").sendPrefixedMessage(player);
return;
}
if (linkedBlocks.contains(toLink.getLocation())) {
instance.getLocale().getMessage("event.hopper.already").sendPrefixedMessage(player);
return;
}
if (!filtered) {
this.linkedBlocks.add(toLink.getLocation());
instance.getDataManager().createLink(this, toLink.getLocation(), LinkType.REGULAR);
} else {
this.filter.setEndPoint(toLink.getLocation());
instance.getDataManager().createLink(this, toLink.getLocation(), LinkType.REJECT);
instance.getLocale().getMessage("event.hopper.syncsuccess").sendPrefixedMessage(player);
instance.getPlayerDataManager().getPlayerData(player).setSyncType(null);
return;
}
this.lastPlayerOpened = player.getUniqueId();
if (level.getLinkAmount() > 1) {
if (linkedBlocks.size() >= level.getLinkAmount()) {
instance.getLocale().getMessage("event.hopper.syncdone").sendPrefixedMessage(player);
cancelSync(player);
return;
}
instance.getLocale().getMessage("event.hopper.syncsuccessmore")
.processPlaceholder("amount", level.getLinkAmount() - linkedBlocks.size())
.sendPrefixedMessage(player);
return;
}
instance.getLocale().getMessage("event.hopper.syncsuccess").sendPrefixedMessage(player);
cancelSync(player);
}
/**
* Ticks a hopper to determine when it can transfer items next
*
* @param maxTick The maximum amount the hopper can be ticked before next transferring items
* @param allowLooping If true, the hopper is allowed to transfer items if the tick is also valid
* @return true if the hopper should transfer an item, otherwise false
*/
public boolean tryTick(int maxTick, boolean allowLooping) {
this.transferTick++;
if (this.transferTick >= maxTick) {
if (allowLooping) {
this.transferTick = 0;
return true;
} else {
this.transferTick = maxTick;
}
}
return false;
}
public Location getLocation() {
return location.clone();
}
public Block getBlock() {
return location.getBlock();
}
public World getWorld() {
return location.getWorld();
}
public int getX() {
return location.getBlockX();
}
public int getY() {
return location.getBlockY();
}
public int getZ() {
return location.getBlockZ();
}
public Level getLevel() {
return level;
}
public void setLevel(Level level) {
this.level = level;
}
public UUID getPlacedBy() {
return placedBy;
}
public void setPlacedBy(UUID placedBy) {
this.placedBy = placedBy;
}
public UUID getLastPlayerOpened() {
return lastPlayerOpened;
}
public void setLastPlayerOpened(UUID uuid) {
lastPlayerOpened = uuid;
}
public TeleportTrigger getTeleportTrigger() {
return teleportTrigger;
}
public void setTeleportTrigger(TeleportTrigger teleportTrigger) {
this.teleportTrigger = teleportTrigger;
}
public List<Location> getLinkedBlocks() {
return new ArrayList<>(linkedBlocks);
}
public void addLinkedBlock(Location location, LinkType type) {
if (type == LinkType.REGULAR)
linkedBlocks.add(location);
else
filter.setEndPoint(location);
}
public void removeLinkedBlock(Location location) {
this.linkedBlocks.remove(location);
}
public void clearLinkedBlocks() {
this.linkedBlocks.clear();
}
public Filter getFilter() {
return filter;
}
public void setFilter(Filter filter) {
this.filter = filter;
}
public Object getDataFromModuleCache(String key) {
return this.moduleCache.getOrDefault(key, null);
}
public void addDataToModuleCache(String key, Object data) {
this.moduleCache.put(key, data);
}
public boolean isDataCachedInModuleCache(String key) {
return this.moduleCache.containsKey(key);
}
public void removeDataFromModuleCache(String key) {
this.moduleCache.remove(key);
}
public void clearModuleCache() {
this.moduleCache.clear();
}
public void cancelSync(Player player) {
Bukkit.getScheduler().cancelTask(syncId);
EpicHoppers.getInstance().getPlayerDataManager().getPlayerData(player).setSyncType(null);
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Player getActivePlayer() {
return activePlayer;
}
public void setActivePlayer(Player activePlayer) {
this.activePlayer = activePlayer;
}
}

View File

@ -1,117 +0,0 @@
package com.songoda.epichoppers.hopper;
import com.songoda.epichoppers.EpicHoppers;
import com.songoda.epichoppers.hopper.levels.Level;
import com.songoda.epichoppers.hopper.levels.modules.Module;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public class HopperManager {
protected boolean ready;
private final Map<Location, Hopper> registeredHoppers = new HashMap<>();
/**
* Sets {@link #isReady()} to {@code true}.<br>
* <b>Called by {@link EpicHoppers#onDataLoad()}</b>
*/
public void setReady() {
this.ready = true;
}
/**
* @return true, if all the data has been loaded from the DB
*/
public boolean isReady() {
return this.ready;
}
public Hopper addHopper(Hopper hopper) {
registeredHoppers.put(roundLocation(hopper.getLocation()), hopper);
return hopper;
}
@Deprecated
public void addHopper(Location location, Hopper hopper) {
registeredHoppers.put(roundLocation(location), hopper);
}
public void addHoppers(Collection<Hopper> hoppers) {
for (Hopper hopper : hoppers)
registeredHoppers.put(hopper.getLocation(), hopper);
}
/**
* Removes a hopper and unlinks it from any other hoppers
*
* @param location The location of the hopper to remove
* @return The removed hopper, or null if none was removed
*/
public Hopper removeHopper(Location location) {
Hopper removed = this.registeredHoppers.remove(location);
for (Hopper hopper : this.registeredHoppers.values())
hopper.removeLinkedBlock(location);
for (Level level : EpicHoppers.getInstance().getLevelManager().getLevels().values())
for (Module module : level.getRegisteredModules())
module.clearData(removed);
return removed;
}
public Hopper getHopper(Location location) {
if (!registeredHoppers.containsKey(location = roundLocation(location))) {
if (!this.ready) {
throw new IllegalStateException("Hoppers are still being loaded");
}
Hopper hopper = addHopper(new Hopper(location));
EpicHoppers.getInstance().getDataManager().createHopper(hopper);
}
return registeredHoppers.get(location);
}
public Hopper getHopper(Block block) {
return getHopper(block.getLocation());
}
/**
* <em>Returns {@code false} if {@link #isReady()} is false too</em>
*/
public boolean isHopper(Location location) {
return registeredHoppers.containsKey(roundLocation(location));
}
public Map<Location, Hopper> getHoppers() {
return Collections.unmodifiableMap(registeredHoppers);
}
public Hopper getHopperFromPlayer(Player player) {
if (!this.ready) {
throw new IllegalStateException("Hoppers are still being loaded");
}
for (Hopper hopper : registeredHoppers.values()) {
if (hopper.getLastPlayerOpened() == player.getUniqueId()) {
return hopper;
}
}
return null;
}
private Location roundLocation(Location location) {
location = location.clone();
location.setX(location.getBlockX());
location.setY(location.getBlockY());
location.setZ(location.getBlockZ());
return location;
}
}

View File

@ -1,119 +0,0 @@
package com.songoda.epichoppers.hopper.levels;
import com.songoda.epichoppers.EpicHoppers;
import com.songoda.epichoppers.hopper.levels.modules.Module;
import java.util.ArrayList;
import java.util.List;
public class Level {
private final ArrayList<Module> registeredModules;
private final List<String> description = new ArrayList<>();
private final int level, costExperience, costEconomy, range, amount, linkAmount;
private final boolean filter, teleport;
public Level(int level, int costExperience, int costEconomy, int range, int amount, boolean filter, boolean teleport, int linkAmount, ArrayList<Module> registeredModules) {
this.level = level;
this.costExperience = costExperience;
this.costEconomy = costEconomy;
this.range = range;
this.amount = amount;
this.filter = filter;
this.teleport = teleport;
this.linkAmount = linkAmount;
this.registeredModules = registeredModules;
buildDescription();
}
public void buildDescription() {
EpicHoppers instance = EpicHoppers.getInstance();
description.clear();
description.add(instance.getLocale().getMessage("interface.hopper.range")
.processPlaceholder("range", range).getMessage());
description.add(instance.getLocale().getMessage("interface.hopper.amount")
.processPlaceholder("amount", amount).getMessage());
if (linkAmount != 1)
description.add(instance.getLocale().getMessage("interface.hopper.linkamount")
.processPlaceholder("amount", linkAmount).getMessage());
if (filter)
description.add(instance.getLocale().getMessage("interface.hopper.filter")
.processPlaceholder("enabled", EpicHoppers.getInstance().getLocale()
.getMessage("general.word.enabled").getMessage()).getMessage());
if (teleport)
description.add(instance.getLocale().getMessage("interface.hopper.teleport")
.processPlaceholder("enabled", EpicHoppers.getInstance()
.getLocale().getMessage("general.word.enabled").getMessage()).getMessage());
for (Module module : registeredModules) {
description.add(module.getDescription());
}
}
public int getLevel() {
return level;
}
public int getRange() {
return range;
}
public int getAmount() {
return amount;
}
public boolean isFilter() {
return filter;
}
public boolean isTeleport() {
return teleport;
}
public int getLinkAmount() {
return linkAmount;
}
public int getCostExperience() {
return costExperience;
}
public int getCostEconomy() {
return costEconomy;
}
public List<String> getDescription() {
return new ArrayList<>(description);
}
public ArrayList<Module> getRegisteredModules() {
return new ArrayList<>(registeredModules);
}
public void addModule(Module module) {
registeredModules.add(module);
buildDescription();
}
public Module getModule(String name) {
return registeredModules == null ? null :
registeredModules.stream().filter(module -> module.getName().equals(name)).findFirst().orElse(null);
}
}

View File

@ -1,147 +0,0 @@
package com.songoda.epichoppers.hopper.levels.modules;
import com.songoda.core.compatibility.CompatibleMaterial;
import com.songoda.core.utils.TextUtils;
import com.songoda.epichoppers.EpicHoppers;
import com.songoda.epichoppers.gui.GUISmeltable;
import com.songoda.epichoppers.hopper.Hopper;
import com.songoda.epichoppers.settings.Settings;
import com.songoda.epichoppers.utils.StorageContainerCache;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class ModuleAutoSmelter extends Module {
private final int timeOut;
private final int hopperTickRate;
public ModuleAutoSmelter(EpicHoppers plugin, int timeOut) {
super(plugin);
this.timeOut = timeOut * 20;
this.hopperTickRate = Settings.HOP_TICKS.getInt();
}
@Override
public String getName() {
return "AutoSmelter";
}
@Override
public void run(Hopper hopper, StorageContainerCache.Cache hopperCache) {
if (!isEnabled(hopper)) return;
int currentTime = getTime(hopper);
if (currentTime == -9999) return;
int subtract = currentTime - hopperTickRate;
if (subtract <= 0) {
for (int i = 0; i < 5; i++) {
final ItemStack itemStack = hopperCache.cachedInventory[i];
if (itemStack == null) continue;
CompatibleMaterial material = CompatibleMaterial.getMaterial(itemStack);
if (!isSmeltable(hopper, material)) continue;
CompatibleMaterial result = CompatibleMaterial.getMaterial(itemStack).getBurnResult();
if (hopperCache.addItem(result.getItem())) {
if (itemStack.getAmount() == 1) {
hopperCache.setItem(i, null);
} else {
itemStack.setAmount(itemStack.getAmount() - 1);
hopperCache.dirty = hopperCache.cacheChanged[i] = true;
}
break;
}
}
modifyDataCache(hopper, "time", timeOut);
return;
}
modifyDataCache(hopper, "time", subtract);
}
@Override
public ItemStack getGUIButton(Hopper hopper) {
ItemStack block = CompatibleMaterial.IRON_INGOT.getItem();
ItemMeta blockmeta = block.getItemMeta();
blockmeta.setDisplayName(plugin.getLocale().getMessage("interface.hopper.smelttitle").getMessage());
ArrayList<String> loreblock = new ArrayList<>();
String[] parts = plugin.getLocale().getMessage("interface.hopper.smeltlore").processPlaceholder("timeleft",
getTime(hopper) == -9999 ? "\u221E" : (int) Math.floor(getTime(hopper) / 20.0)).processPlaceholder("enabled",
isEnabled(hopper) ? EpicHoppers.getInstance().getLocale().getMessage("general.word.enabled").getMessage()
: EpicHoppers.getInstance().getLocale().getMessage("general.word.disabled").getMessage()).getMessage().split("\\|");
for (String line : parts) {
loreblock.add(TextUtils.formatText(line));
}
blockmeta.setLore(loreblock);
block.setItemMeta(blockmeta);
return block;
}
public void runButtonPress(Player player, Hopper hopper, ClickType type) {
if (type == ClickType.LEFT) {
hopper.setActivePlayer(player);
EpicHoppers.getInstance().getGuiManager().showGUI(player, new GUISmeltable(this, plugin, hopper));
} else if (type == ClickType.RIGHT)
toggleEnabled(hopper);
}
@Override
public List<Material> getBlockedItems(Hopper hopper) {
if (getTime(hopper) == -9999)
return Collections.emptyList();
List<Material> blockedItems = new ArrayList<>();
for (CompatibleMaterial material : CompatibleMaterial.values())
if (material.getBurnResult() != null && isSmeltable(hopper, material))
blockedItems.add(material.getMaterial());
return blockedItems;
}
@Override
public String getDescription() {
return plugin.getLocale().getMessage("interface.hopper.autosmelt")
.processPlaceholder("ticks", (int) Math.floor(timeOut / 20.0)).getMessage();
}
private int getTime(Hopper hopper) {
Object time = getData(hopper, "time");
if (time == null) return -9999;
return (int) time;
}
private boolean isEnabled(Hopper hopper) {
Object obj = getData(hopper, "time");
if (obj == null) return false;
return ((int) obj) != -9999;
}
public boolean isSmeltable(Hopper hopper, CompatibleMaterial material) {
Object obj = getData(hopper, material.name());
if (obj == null) return false;
return ((boolean) obj);
}
private void toggleEnabled(Hopper hopper) {
if (isEnabled(hopper))
saveData(hopper, "time", -9999);
else
saveData(hopper, "time", timeOut);
}
public void toggleSmeltable(Hopper hopper, CompatibleMaterial material) {
saveData(hopper, material.name(), !isSmeltable(hopper, material));
}
}

View File

@ -1,100 +0,0 @@
package com.songoda.epichoppers.hopper.levels.modules;
import com.songoda.core.utils.TextUtils;
import com.songoda.epichoppers.EpicHoppers;
import com.songoda.epichoppers.hopper.Hopper;
import com.songoda.epichoppers.utils.StorageContainerCache;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ModuleMobHopper extends Module {
private final int amount;
private final Map<Block, Integer> blockTick = new HashMap<>();
public ModuleMobHopper(EpicHoppers plugin, int amount) {
super(plugin);
this.amount = amount;
}
@Override
public String getName() {
return "MobHopper";
}
@Override
public void run(Hopper hopper, StorageContainerCache.Cache hopperCache) {
Block block = hopper.getLocation().getBlock();
if (!blockTick.containsKey(block)) {
blockTick.put(block, 1);
return;
}
int tick = blockTick.get(block);
int put = tick + 1;
blockTick.put(block, put);
if (tick < amount || !isEnabled(hopper)) return;
hopper.getWorld().getNearbyEntities(hopper.getLocation(), 5, 5, 5).stream()
.filter(entity -> entity instanceof LivingEntity && !(entity instanceof Player) &&
!(entity instanceof ArmorStand)).limit(1).forEach(entity -> {
Location location = hopper.getLocation().add(.5, 1, .5);
if (location.getBlock().getType() != Material.AIR) return;
entity.teleport(location);
((LivingEntity) entity).damage(99999999);
});
blockTick.remove(block);
}
@Override
public ItemStack getGUIButton(Hopper hopper) {
ItemStack block = new ItemStack(Material.ROTTEN_FLESH, 1);
ItemMeta blockmeta = block.getItemMeta();
blockmeta.setDisplayName(plugin.getLocale().getMessage("interface.hopper.mobtitle").getMessage());
ArrayList<String> loreblock = new ArrayList<>();
String[] parts = plugin.getLocale().getMessage("interface.hopper.moblore").processPlaceholder("enabled",
isEnabled(hopper) ? EpicHoppers.getInstance().getLocale().getMessage("general.word.enabled").getMessage()
: EpicHoppers.getInstance().getLocale().getMessage("general.word.disabled").getMessage()).getMessage().split("\\|");
for (String line : parts) {
loreblock.add(TextUtils.formatText(line));
}
blockmeta.setLore(loreblock);
block.setItemMeta(blockmeta);
return block;
}
@Override
public void runButtonPress(Player player, Hopper hopper, ClickType type) {
saveData(hopper, "mobhopper", !isEnabled(hopper));
}
@Override
public List<Material> getBlockedItems(Hopper hopper) {
return null;
}
@Override
public String getDescription() {
return plugin.getLocale().getMessage("interface.hopper.mobhopper")
.processPlaceholder("ticks", amount).getMessage();
}
public boolean isEnabled(Hopper hopper) {
Object isMobHopper = getData(hopper, "mobhopper");
return isMobHopper != null && (boolean) isMobHopper;
}
}

View File

@ -1,170 +0,0 @@
package com.songoda.epichoppers.listeners;
import com.songoda.core.compatibility.ServerVersion;
import com.songoda.epichoppers.EpicHoppers;
import com.songoda.epichoppers.api.events.HopperBreakEvent;
import com.songoda.epichoppers.api.events.HopperPlaceEvent;
import com.songoda.epichoppers.gui.GUIAutoSellFilter;
import com.songoda.epichoppers.gui.GUIFilter;
import com.songoda.epichoppers.hopper.Hopper;
import com.songoda.epichoppers.hopper.HopperBuilder;
import com.songoda.epichoppers.hopper.levels.Level;
import com.songoda.epichoppers.settings.Settings;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
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.BlockBreakEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.permissions.PermissionAttachmentInfo;
/**
* Created by songoda on 3/14/2017.
*/
public class BlockListeners implements Listener {
private final EpicHoppers plugin;
private static final boolean hasMinHeight = ServerVersion.isServerVersionAtLeast(ServerVersion.V1_16);
public BlockListeners(EpicHoppers plugin) {
this.plugin = plugin;
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onBlockPlace(BlockPlaceEvent e) {
Player player = e.getPlayer();
if (e.getBlock().getType() != Material.HOPPER)
return;
if (Settings.DISABLED_WORLDS.getStringList().contains(player.getWorld().getName()))
return;
int amt = count(e.getBlock().getChunk());
int max = maxHoppers(player);
if (max != -1 && amt > max) {
player.sendMessage(plugin.getLocale().getMessage("event.hopper.toomany").processPlaceholder("amount", max).getMessage());
e.setCancelled(true);
return;
}
ItemStack item = e.getItemInHand().clone();
if (Settings.ALLOW_NORMAL_HOPPERS.getBoolean() && !plugin.getLevelManager().isEpicHopper(item))
return;
if (!plugin.getHopperManager().isReady()) {
player.sendMessage(plugin.getLocale().getMessage("event.hopper.notready").getMessage());
e.setCancelled(true);
return;
}
Hopper hopper = plugin.getHopperManager().addHopper(
new HopperBuilder(e.getBlock())
.setLevel(plugin.getLevelManager().getLevel(item))
.setPlacedBy(player)
.setLastPlayerOpened(player).build());
HopperPlaceEvent hopperPlaceEvent = new HopperPlaceEvent(player, hopper);
Bukkit.getPluginManager().callEvent(hopperPlaceEvent);
EpicHoppers.getInstance().getDataManager().createHopper(hopper);
}
private int maxHoppers(Player player) {
int limit = -1;
for (PermissionAttachmentInfo permissionAttachmentInfo : player.getEffectivePermissions()) {
if (!permissionAttachmentInfo.getPermission().toLowerCase().startsWith("epichoppers.limit")) continue;
int num = Integer.parseInt(permissionAttachmentInfo.getPermission().split("\\.")[2]);
if (num > limit)
limit = num;
}
if (limit == -1) limit = Settings.MAX_CHUNK.getInt();
return limit;
}
private int count(Chunk c) {
int count = 0;
for (int x = 0; x < 16; x++) {
for (int z = 0; z < 16; z++) {
for (int y = getMinHeight(c.getWorld()); y < c.getWorld().getMaxHeight(); y++) {
if (c.getBlock(x, y, z).getType() == Material.HOPPER) count++;
}
}
}
return count;
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onBlockBreak(BlockBreakEvent event) {
Block block = event.getBlock();
Player player = event.getPlayer();
if (event.getBlock().getType() != Material.HOPPER) return;
if (!plugin.getHopperManager().isReady()) {
player.sendMessage(plugin.getLocale().getMessage("event.hopper.notready").getMessage());
event.setCancelled(true);
return;
}
if (Settings.ALLOW_NORMAL_HOPPERS.getBoolean() && !plugin.getHopperManager().isHopper(block.getLocation()))
return;
Hopper hopper = plugin.getHopperManager().getHopper(block);
GUIFilter.compileOpenGuiFilter(hopper);
GUIAutoSellFilter.compileOpenAutoSellFilter(hopper);
Level level = hopper.getLevel();
if (level.getLevel() > 1 || Settings.ALLOW_NORMAL_HOPPERS.getBoolean()) {
HopperBreakEvent hopperBreakEvent = new HopperBreakEvent(player, hopper);
Bukkit.getPluginManager().callEvent(hopperBreakEvent);
event.setCancelled(true);
ItemStack item = plugin.newHopperItem(level);
hopper.dropItems();
event.getBlock().setType(Material.AIR);
event.getBlock().getLocation().getWorld().dropItemNaturally(event.getBlock().getLocation(), item);
}
hopper.forceClose();
hopper.getFilter().getWhiteList().stream()
.filter(m -> m != null)
.forEach(m -> event.getBlock().getWorld().dropItemNaturally(event.getBlock().getLocation(), m));
hopper.getFilter().getBlackList().stream()
.filter(m -> m != null)
.forEach(m -> event.getBlock().getWorld().dropItemNaturally(event.getBlock().getLocation(), m));
hopper.getFilter().getVoidList().stream().
filter(m -> m != null)
.forEach(m -> event.getBlock().getWorld().dropItemNaturally(event.getBlock().getLocation(), m));
hopper.getFilter().getAutoSellWhiteList().stream()
.filter(m -> m != null)
.forEach(m -> event.getBlock().getWorld().dropItemNaturally(event.getBlock().getLocation(), m));
hopper.getFilter().getAutoSellBlackList().stream()
.filter(m -> m != null)
.forEach(m -> event.getBlock().getWorld().dropItemNaturally(event.getBlock().getLocation(), m));
plugin.getHopperManager().removeHopper(block.getLocation());
plugin.getDataManager().deleteHopper(hopper);
plugin.getPlayerDataManager().getPlayerData(player).setSyncType(null);
}
public int getMinHeight(World world) {
return hasMinHeight ? world.getMinHeight() : 0;
}
}

View File

@ -1,34 +0,0 @@
package com.songoda.epichoppers.listeners;
import org.bukkit.Material;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryAction;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.ItemStack;
/**
* Created by songoda on 3/14/2017.
*/
public class InventoryListeners implements Listener {
@EventHandler
public void onInventoryClick(InventoryClickEvent event) {
if (event.getCurrentItem() == null) return;
if (event.getRawSlot() > event.getView().getTopInventory().getSize() - 1) return;
if (!event.getCurrentItem().hasItemMeta()) return;
if (event.getSlot() != 64537
&& event.getInventory().getType() == InventoryType.ANVIL
&& event.getAction() != InventoryAction.NOTHING
&& event.getCurrentItem().getType() != Material.AIR) {
ItemStack item = event.getCurrentItem();
if (item.getType() == Material.HOPPER) {
event.setCancelled(true);
}
}
}
}

View File

@ -1,8 +0,0 @@
package com.songoda.epichoppers.player;
public enum SyncType {
REGULAR,
FILTERED
}

View File

@ -1,194 +0,0 @@
package com.songoda.epichoppers.utils;
import com.songoda.core.compatibility.ServerVersion;
import com.songoda.core.utils.TextUtils;
import com.songoda.epichoppers.EpicHoppers;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import java.text.DecimalFormat;
import java.util.concurrent.TimeUnit;
/**
* Created by songoda on 2/24/2017.
*/
public class Methods {
public static boolean isSimilarMaterial(ItemStack is1, ItemStack is2) {
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13) ||
is1.getDurability() == Short.MAX_VALUE || is2.getDurability() == Short.MAX_VALUE) {
// Durability of Short.MAX_VALUE is used in recipes if the durability should be ignored
return is1.getType() == is2.getType();
} else {
return is1.getType() == is2.getType() && (is1.getDurability() == -1 || is2.getDurability() == -1 || is1.getDurability() == is2.getDurability());
}
}
public static boolean canMove(Inventory inventory, ItemStack item) {
if (inventory.firstEmpty() != -1) return true;
final ItemMeta itemMeta = item.getItemMeta();
for (ItemStack stack : inventory) {
final ItemMeta stackMeta;
if (isSimilarMaterial(stack, item) && (stack.getAmount() + item.getAmount()) < stack.getMaxStackSize()
&& ((itemMeta == null) == ((stackMeta = stack.getItemMeta()) == null))
&& (itemMeta == null || Bukkit.getItemFactory().equals(itemMeta, stackMeta))) {
return true;
}
}
return false;
}
public static boolean canMoveReserved(Inventory inventory, ItemStack item) {
if (inventory.firstEmpty() != inventory.getSize() - 1) return true;
final ItemMeta itemMeta = item.getItemMeta();
final ItemStack[] contents = inventory.getContents();
for (int i = 0; i < 4; i++) {
final ItemStack stack = contents[i];
final ItemMeta stackMeta;
if (isSimilarMaterial(stack, item) && (stack.getAmount() + item.getAmount()) < stack.getMaxStackSize()
&& ((itemMeta == null) == ((stackMeta = stack.getItemMeta()) == null))
&& (itemMeta == null || Bukkit.getItemFactory().equals(itemMeta, stackMeta))) {
return true;
}
}
return false;
}
public static boolean canMoveReserved(ItemStack[] contents, ItemStack item) {
final ItemMeta itemMeta = item.getItemMeta();
for (int i = 0; i < contents.length - 2; i++) {
final ItemStack stack = contents[i];
if (stack == null || stack.getAmount() == 0)
return true;
final ItemMeta stackMeta;
if (isSimilarMaterial(stack, item) && (stack.getAmount() + item.getAmount()) < stack.getMaxStackSize()
&& ((itemMeta == null) == ((stackMeta = stack.getItemMeta()) == null))
&& (itemMeta == null || Bukkit.getItemFactory().equals(itemMeta, stackMeta))) {
return true;
}
}
return false;
}
public static String formatName(int level) {
EpicHoppers instance = EpicHoppers.getInstance();
String name = instance.getLocale().getMessage("general.nametag.nameformat")
.processPlaceholder("level", level).getMessage();
return TextUtils.formatText(name);
}
public static void doParticles(Entity entity, Location location) {
EpicHoppers instance = EpicHoppers.getInstance();
location.setX(location.getX() + .5);
location.setY(location.getY() + .5);
location.setZ(location.getZ() + .5);
entity.getWorld().spawnParticle(org.bukkit.Particle.valueOf(instance.getConfig().getString("Main.Upgrade Particle Type")), location, 200, .5, .5, .5);
}
/**
* Serializes the location specified.
*
* @param location The location that is to be saved.
* @return The serialized data.
*/
public static String serializeLocation(Location location) {
if (location == null || location.getWorld() == null)
return "";
String w = location.getWorld().getName();
double x = location.getX();
double y = location.getY();
double z = location.getZ();
String str = w + ":" + x + ":" + y + ":" + z;
str = str.replace(".0", "").replace(".", "/");
return str;
}
/**
* Makes the specified Unix Epoch time human readable as per the format settings in the Arconix config.
*
* @param time The time to convert.
* @return A human readable string representing to specified time.
*/
public static String makeReadable(Long time) {
if (time == null)
return "";
StringBuilder sb = new StringBuilder();
long days = TimeUnit.MILLISECONDS.toDays(time);
long hours = TimeUnit.MILLISECONDS.toHours(time) - TimeUnit.DAYS.toHours(TimeUnit.MILLISECONDS.toDays(time));
long minutes = TimeUnit.MILLISECONDS.toMinutes(time) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(time));
long seconds = TimeUnit.MILLISECONDS.toSeconds(time) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(time));
if (days != 0L)
sb.append(" ").append(days).append("d");
if (hours != 0L)
sb.append(" ").append(hours).append("h");
if (minutes != 0L)
sb.append(" ").append(minutes).append("m");
if (seconds != 0L)
sb.append(" ").append(seconds).append("s");
return sb.toString().trim();
}
public static long parseTime(String input) {
long result = 0;
StringBuilder number = new StringBuilder();
for (int i = 0; i < input.length(); i++) {
char c = input.charAt(i);
if (Character.isDigit(c)) {
number.append(c);
} else if (Character.isLetter(c) && (number.length() > 0)) {
result += convert(Integer.parseInt(number.toString()), c);
number = new StringBuilder();
}
}
return result;
}
private static long convert(long value, char unit) {
switch (unit) {
case 'd':
return value * 1000 * 60 * 60 * 24;
case 'h':
return value * 1000 * 60 * 60;
case 'm':
return value * 1000 * 60;
case 's':
return value * 1000;
default:
return 0;
}
}
/**
* Formats the specified double into the Economy format specified in the Arconix config.
*
* @param amt The double to format.
* @return The economy formatted double.
*/
public static String formatEconomy(double amt) {
DecimalFormat formatter = new DecimalFormat(amt == Math.ceil(amt) ? "#,###" : "#,###.00");
return formatter.format(amt);
}
public static boolean isInt(String number) {
if (number == null || number.equals(""))
return false;
try {
Integer.parseInt(number);
} catch (NumberFormatException e) {
return false;
}
return true;
}
}