2018-11-06 04:33:10 +01:00
package com.songoda.ultimatestacker ;
2019-09-03 22:38:00 +02:00
import com.songoda.core.SongodaCore ;
import com.songoda.core.SongodaPlugin ;
import com.songoda.core.commands.CommandManager ;
2019-09-09 18:08:04 +02:00
import com.songoda.core.compatibility.CompatibleMaterial ;
2019-09-03 22:38:00 +02:00
import com.songoda.core.compatibility.ServerVersion ;
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 ;
2021-05-27 21:21:57 +02:00
import com.songoda.core.hooks.EntityStackerManager ;
2019-09-03 22:38:00 +02:00
import com.songoda.core.hooks.HologramManager ;
2023-04-01 15:55:37 +02:00
import com.songoda.core.hooks.ProtectionManager ;
2019-09-18 18:02:35 +02:00
import com.songoda.core.hooks.WorldGuardHook ;
2019-09-03 22:38:00 +02:00
import com.songoda.core.utils.TextUtils ;
2020-09-01 20:44:39 +02:00
import com.songoda.ultimatestacker.commands.CommandConvert ;
import com.songoda.ultimatestacker.commands.CommandGiveSpawner ;
import com.songoda.ultimatestacker.commands.CommandLootables ;
import com.songoda.ultimatestacker.commands.CommandReload ;
import com.songoda.ultimatestacker.commands.CommandRemoveAll ;
import com.songoda.ultimatestacker.commands.CommandSettings ;
import com.songoda.ultimatestacker.commands.CommandSpawn ;
2019-09-03 22:38:00 +02:00
import com.songoda.ultimatestacker.database.DataManager ;
import com.songoda.ultimatestacker.database.migrations._1_InitialMigration ;
2020-08-25 01:01:11 +02:00
import com.songoda.ultimatestacker.database.migrations._2_EntityStacks ;
import com.songoda.ultimatestacker.database.migrations._3_BlockStacks ;
2023-02-04 14:48:13 +01:00
import com.songoda.ultimatestacker.database.migrations._6_RemoveStackedEntityTable ;
2019-06-10 02:47:29 +02:00
import com.songoda.ultimatestacker.hook.StackerHook ;
import com.songoda.ultimatestacker.hook.hooks.JobsHook ;
2019-06-07 19:48:17 +02:00
import com.songoda.ultimatestacker.listeners.* ;
2020-09-09 16:12:32 +02:00
import com.songoda.ultimatestacker.listeners.entity.EntityCurrentListener ;
import com.songoda.ultimatestacker.listeners.entity.EntityListeners ;
2020-07-11 04:42:56 +02:00
import com.songoda.ultimatestacker.listeners.item.ItemCurrentListener ;
import com.songoda.ultimatestacker.listeners.item.ItemLegacyListener ;
import com.songoda.ultimatestacker.listeners.item.ItemListeners ;
2019-07-23 16:55:49 +02:00
import com.songoda.ultimatestacker.lootables.LootablesManager ;
2019-09-07 23:55:16 +02:00
import com.songoda.ultimatestacker.settings.Settings ;
2020-08-25 01:01:11 +02:00
import com.songoda.ultimatestacker.stackable.Hologramable ;
import com.songoda.ultimatestacker.stackable.block.BlockStack ;
import com.songoda.ultimatestacker.stackable.block.BlockStackManager ;
import com.songoda.ultimatestacker.stackable.entity.EntityStack ;
import com.songoda.ultimatestacker.stackable.entity.EntityStackManager ;
2020-10-26 18:41:54 +01:00
import com.songoda.ultimatestacker.stackable.entity.custom.CustomEntityManager ;
2020-08-25 01:01:11 +02:00
import com.songoda.ultimatestacker.stackable.spawner.SpawnerStack ;
import com.songoda.ultimatestacker.stackable.spawner.SpawnerStackManager ;
2018-11-06 04:33:10 +01:00
import com.songoda.ultimatestacker.tasks.StackingTask ;
2023-01-02 13:38:58 +01:00
import com.songoda.ultimatestacker.utils.Async ;
2019-09-03 22:38:00 +02:00
import com.songoda.ultimatestacker.utils.Methods ;
2023-02-04 14:48:13 +01:00
import io.lumine.mythic.bukkit.listeners.ChunkListeners ;
2019-12-27 18:42:02 +01:00
import org.apache.commons.lang.WordUtils ;
2019-06-07 19:48:17 +02:00
import org.bukkit.Bukkit ;
2022-09-19 20:26:08 +02:00
import org.bukkit.Location ;
2019-06-07 19:48:17 +02:00
import org.bukkit.Material ;
2023-01-21 16:15:24 +01:00
import org.bukkit.World ;
2023-04-05 11:57:17 +02:00
import org.bukkit.block.Block ;
2018-11-06 04:33:10 +01:00
import org.bukkit.entity.EntityType ;
2019-09-03 22:38:00 +02:00
import org.bukkit.entity.Item ;
2019-06-10 02:47:29 +02:00
import org.bukkit.entity.Player ;
2019-09-03 22:38:00 +02:00
import org.bukkit.inventory.ItemStack ;
import org.bukkit.metadata.FixedMetadataValue ;
2019-01-23 19:01:31 +01:00
import org.bukkit.plugin.PluginManager ;
2018-11-06 04:33:10 +01:00
2020-09-01 20:44:39 +02:00
import java.util.ArrayList ;
import java.util.Arrays ;
import java.util.HashSet ;
import java.util.List ;
2023-01-16 21:32:17 +01:00
import java.util.Objects ;
2020-09-01 20:44:39 +02:00
import java.util.Set ;
2020-04-26 14:42:18 +02:00
2019-09-03 22:38:00 +02:00
public class UltimateStacker extends SongodaPlugin {
2018-11-06 04:33:10 +01:00
private static UltimateStacker INSTANCE ;
2019-09-10 20:21:00 +02:00
private final static Set < String > whitelist = new HashSet ( ) ;
2020-04-26 14:42:18 +02:00
private final static Set < String > blacklist = new HashSet ( ) ;
2018-11-06 04:33:10 +01:00
2019-09-03 22:38:00 +02:00
private final Config mobFile = new Config ( this , " mobs.yml " ) ;
private final Config itemFile = new Config ( this , " items.yml " ) ;
private final Config spawnerFile = new Config ( this , " spawners.yml " ) ;
2018-11-06 04:33:10 +01:00
2019-09-03 22:38:00 +02:00
private final GuiManager guiManager = new GuiManager ( this ) ;
2019-09-10 20:21:00 +02:00
private final List < StackerHook > stackerHooks = new ArrayList < > ( ) ;
2018-11-06 04:33:10 +01:00
private EntityStackManager entityStackManager ;
private SpawnerStackManager spawnerStackManager ;
2020-08-25 01:01:11 +02:00
private BlockStackManager blockStackManager ;
2019-07-23 16:55:49 +02:00
private LootablesManager lootablesManager ;
2018-11-06 04:33:10 +01:00
private CommandManager commandManager ;
2020-10-26 18:41:54 +01:00
private CustomEntityManager customEntityManager ;
2018-11-06 04:33:10 +01:00
private StackingTask stackingTask ;
2018-11-06 05:41:58 +01:00
2019-08-02 15:59:10 +02:00
private DatabaseConnector databaseConnector ;
private DataMigrationManager dataMigrationManager ;
private DataManager dataManager ;
2018-11-06 06:09:40 +01:00
public static UltimateStacker getInstance ( ) {
return INSTANCE ;
}
2019-09-03 22:38:00 +02:00
@Override
public void onPluginLoad ( ) {
INSTANCE = this ;
2019-09-18 18:02:35 +02:00
// Register WorldGuard
WorldGuardHook . addHook ( " mob-stacking " , true ) ;
2019-09-03 22:38:00 +02:00
}
2020-04-26 14:42:18 +02:00
2019-09-03 22:38:00 +02:00
@Override
public void onPluginDisable ( ) {
2023-02-04 14:48:13 +01:00
this . stackingTask . stop ( ) ;
2023-01-16 21:32:17 +01:00
this . stackingTask = null ;
2019-08-02 15:59:10 +02:00
this . dataManager . bulkUpdateSpawners ( this . spawnerStackManager . getStacks ( ) ) ;
2023-04-07 18:58:21 +02:00
this . dataManager . bulkUpdateBlocks ( this . blockStackManager . getStacks ( ) ) ;
2019-09-03 22:38:00 +02:00
HologramManager . removeAllHolograms ( ) ;
2023-01-02 13:38:58 +01:00
Async . shutdown ( ) ;
2018-11-06 04:33:10 +01:00
}
2018-11-09 05:11:49 +01:00
@Override
2019-09-03 22:38:00 +02:00
public void onPluginEnable ( ) {
// Run Songoda Updater
2023-01-25 15:50:41 +01:00
Async . start ( ) ;
2019-09-09 18:08:04 +02:00
SongodaCore . registerPlugin ( this , 16 , CompatibleMaterial . IRON_INGOT ) ;
2019-09-03 22:38:00 +02:00
// Setup Config
2019-09-07 23:55:16 +02:00
Settings . setupConfig ( ) ;
2020-04-26 14:42:18 +02:00
this . setLocale ( Settings . LANGUGE_MODE . getString ( ) , false ) ;
2019-09-10 20:21:00 +02:00
blacklist . clear ( ) ;
whitelist . clear ( ) ;
whitelist . addAll ( Settings . ITEM_WHITELIST . getStringList ( ) ) ;
blacklist . addAll ( Settings . ITEM_BLACKLIST . getStringList ( ) ) ;
2020-04-26 14:42:18 +02:00
2019-09-03 22:38:00 +02:00
// Setup plugin commands
2019-05-23 22:15:04 +02:00
this . commandManager = new CommandManager ( this ) ;
2020-06-28 04:12:13 +02:00
this . commandManager . addMainCommand ( " us " )
2020-09-01 20:30:08 +02:00
. addSubCommands ( new CommandSettings ( this , guiManager ) ,
new CommandRemoveAll ( this ) ,
new CommandReload ( this ) ,
new CommandGiveSpawner ( this ) ,
new CommandSpawn ( this ) ,
new CommandLootables ( this ) ,
2020-09-01 20:54:43 +02:00
new CommandConvert ( guiManager )
2020-06-28 04:12:13 +02:00
) ;
2018-11-06 04:33:10 +01:00
2019-07-23 16:55:49 +02:00
this . lootablesManager = new LootablesManager ( ) ;
this . lootablesManager . createDefaultLootables ( ) ;
this . getLootablesManager ( ) . getLootManager ( ) . loadLootables ( ) ;
2019-07-08 18:39:57 +02:00
2018-11-06 04:33:10 +01:00
for ( EntityType value : EntityType . values ( ) ) {
2018-11-06 05:53:27 +01:00
if ( value . isSpawnable ( ) & & value . isAlive ( ) & & ! value . toString ( ) . contains ( " ARMOR " ) ) {
2019-09-03 22:38:00 +02:00
mobFile . addDefault ( " Mobs. " + value . name ( ) + " .Enabled " , true ) ;
2021-03-05 15:09:00 +01:00
mobFile . addDefault ( " Mobs. " + value . name ( ) + " .Display Name " , TextUtils . formatText ( value . name ( ) . toLowerCase ( ) . replace ( " _ " , " " ) , true ) ) ;
2019-09-03 22:38:00 +02:00
mobFile . addDefault ( " Mobs. " + value . name ( ) + " .Max Stack Size " , - 1 ) ;
mobFile . addDefault ( " Mobs. " + value . name ( ) + " .Kill Whole Stack " , false ) ;
2018-11-06 04:33:10 +01:00
}
}
2019-09-03 22:38:00 +02:00
mobFile . load ( ) ;
mobFile . saveChanges ( ) ;
2018-11-06 04:33:10 +01:00
for ( Material value : Material . values ( ) ) {
2019-09-03 22:38:00 +02:00
itemFile . addDefault ( " Items. " + value . name ( ) + " .Has Hologram " , true ) ;
itemFile . addDefault ( " Items. " + value . name ( ) + " .Max Stack Size " , - 1 ) ;
2019-12-27 18:42:02 +01:00
itemFile . addDefault ( " Items. " + value . name ( ) + " .Display Name " , WordUtils . capitalizeFully ( value . name ( ) . toLowerCase ( ) . replace ( " _ " , " " ) ) ) ;
2018-11-06 04:33:10 +01:00
}
2019-09-03 22:38:00 +02:00
itemFile . load ( ) ;
itemFile . saveChanges ( ) ;
2018-11-06 04:33:10 +01:00
for ( EntityType value : EntityType . values ( ) ) {
2018-11-06 05:53:27 +01:00
if ( value . isSpawnable ( ) & & value . isAlive ( ) & & ! value . toString ( ) . contains ( " ARMOR " ) ) {
2019-09-03 22:38:00 +02:00
spawnerFile . addDefault ( " Spawners. " + value . name ( ) + " .Max Stack Size " , - 1 ) ;
2021-03-05 15:09:00 +01:00
spawnerFile . addDefault ( " Spawners. " + value . name ( ) + " .Display Name " , TextUtils . formatText ( value . name ( ) . toLowerCase ( ) . replace ( " _ " , " " ) , true ) ) ;
2018-11-06 04:33:10 +01:00
}
}
2019-09-03 22:38:00 +02:00
spawnerFile . load ( ) ;
spawnerFile . saveChanges ( ) ;
2018-11-06 04:33:10 +01:00
2023-04-01 15:55:37 +02:00
if ( Bukkit . getPluginManager ( ) . isPluginEnabled ( " BentoBox " ) ) {
ProtectionManager . load ( Bukkit . getPluginManager ( ) . getPlugin ( " BentoBox " ) ) ;
}
2018-11-06 04:33:10 +01:00
this . spawnerStackManager = new SpawnerStackManager ( ) ;
2020-08-25 01:01:11 +02:00
this . entityStackManager = new EntityStackManager ( this ) ;
this . blockStackManager = new BlockStackManager ( ) ;
2020-10-26 18:41:54 +01:00
this . customEntityManager = new CustomEntityManager ( ) ;
2018-11-06 04:33:10 +01:00
2019-09-03 22:38:00 +02:00
guiManager . init ( ) ;
2019-01-23 19:01:31 +01:00
PluginManager pluginManager = Bukkit . getPluginManager ( ) ;
2019-09-03 22:38:00 +02:00
if ( ServerVersion . isServerVersionAtLeast ( ServerVersion . V1_10 ) )
2019-06-07 19:48:17 +02:00
pluginManager . registerEvents ( new BreedListeners ( this ) , this ) ;
pluginManager . registerEvents ( new BlockListeners ( this ) , this ) ;
pluginManager . registerEvents ( new DeathListeners ( this ) , this ) ;
pluginManager . registerEvents ( new ShearListeners ( this ) , this ) ;
pluginManager . registerEvents ( new InteractListeners ( this ) , this ) ;
2020-09-09 16:12:32 +02:00
if ( ServerVersion . isServerVersionAtLeast ( ServerVersion . V1_13 ) )
pluginManager . registerEvents ( new EntityCurrentListener ( this ) , this ) ;
2019-06-07 19:48:17 +02:00
pluginManager . registerEvents ( new EntityListeners ( this ) , this ) ;
pluginManager . registerEvents ( new ItemListeners ( this ) , this ) ;
2020-07-11 04:42:56 +02:00
if ( ServerVersion . isServerVersionAtLeast ( ServerVersion . V1_12 ) )
pluginManager . registerEvents ( new ItemCurrentListener ( ) , this ) ;
else
pluginManager . registerEvents ( new ItemLegacyListener ( ) , this ) ;
2019-06-07 19:48:17 +02:00
pluginManager . registerEvents ( new TameListeners ( this ) , this ) ;
2019-07-17 14:56:50 +02:00
pluginManager . registerEvents ( new SpawnerListeners ( this ) , this ) ;
2019-06-07 19:48:17 +02:00
pluginManager . registerEvents ( new SheepDyeListeners ( this ) , this ) ;
2018-11-06 04:33:10 +01:00
2019-09-07 23:55:16 +02:00
if ( Settings . CLEAR_LAG . getBoolean ( ) & & pluginManager . isPluginEnabled ( " ClearLag " ) )
2019-06-20 09:33:29 +02:00
pluginManager . registerEvents ( new ClearLagListeners ( this ) , this ) ;
2019-06-10 02:47:29 +02:00
// Register Hooks
2021-02-22 17:17:18 +01:00
if ( pluginManager . isPluginEnabled ( " Jobs " ) )
2019-06-10 02:47:29 +02:00
stackerHooks . add ( new JobsHook ( ) ) ;
2021-02-22 17:17:18 +01:00
2019-09-04 15:17:45 +02:00
HologramManager . load ( this ) ;
2021-05-27 21:21:57 +02:00
EntityStackerManager . load ( ) ;
2019-06-10 02:47:29 +02:00
2019-08-02 15:59:10 +02:00
// Database stuff, go!
try {
2019-09-07 23:55:16 +02:00
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 ( ) ;
2022-08-07 16:39:49 +02:00
int poolSize = Settings . MYSQL_POOL_SIZE . getInt ( ) ;
2019-08-02 15:59:10 +02:00
2022-08-07 16:39:49 +02:00
this . databaseConnector = new MySQLConnector ( this , hostname , port , database , username , password , useSSL , poolSize ) ;
2019-08-02 15:59:10 +02:00
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. " ) ;
Bukkit . getPluginManager ( ) . disablePlugin ( this ) ;
}
this . dataManager = new DataManager ( this . databaseConnector , this ) ;
2019-09-03 22:38:00 +02:00
this . dataMigrationManager = new DataMigrationManager ( this . databaseConnector , this . dataManager ,
2020-08-25 01:01:11 +02:00
new _1_InitialMigration ( ) ,
new _2_EntityStacks ( ) ,
2021-05-28 01:08:38 +02:00
new _3_BlockStacks ( ) ,
2023-02-04 14:48:13 +01:00
new _6_RemoveStackedEntityTable ( ) ) ;
2019-08-02 15:59:10 +02:00
this . dataMigrationManager . runMigrations ( ) ;
2020-08-25 01:01:11 +02:00
}
2019-08-02 15:59:10 +02:00
2020-08-25 01:01:11 +02:00
@Override
public void onDataLoad ( ) {
2020-11-30 20:56:38 +01:00
if ( HologramManager . isEnabled ( ) )
// Set the offset so that the holograms don't end up inside the blocks.
HologramManager . getHolograms ( ) . setPositionOffset ( . 5 , . 65 , . 5 ) ;
2020-08-25 01:01:11 +02:00
// Load current data.
final boolean useSpawnerHolo = Settings . SPAWNER_HOLOGRAMS . getBoolean ( ) ;
this . dataManager . getSpawners ( ( spawners ) - > {
this . spawnerStackManager . addSpawners ( spawners ) ;
if ( useSpawnerHolo ) {
if ( spawners . isEmpty ( ) ) return ;
for ( SpawnerStack spawner : spawners . values ( ) ) {
if ( spawner . getLocation ( ) . getWorld ( ) ! = null ) {
updateHologram ( spawner ) ;
}
}
}
} ) ;
2023-02-04 14:48:13 +01:00
this . stackingTask = new StackingTask ( this ) ;
2020-10-12 19:10:45 +02:00
final boolean useBlockHolo = Settings . BLOCK_HOLOGRAMS . getBoolean ( ) ;
2020-08-25 01:01:11 +02:00
this . dataManager . getBlocks ( ( blocks ) - > {
this . blockStackManager . addBlocks ( blocks ) ;
if ( useBlockHolo ) {
if ( blocks . isEmpty ( ) ) return ;
for ( BlockStack stack : blocks . values ( ) ) {
if ( stack . getLocation ( ) . getWorld ( ) ! = null ) {
updateHologram ( stack ) ;
}
}
}
} ) ;
2018-11-06 04:33:10 +01:00
}
2019-06-10 02:47:29 +02:00
public void addExp ( Player player , EntityStack stack ) {
for ( StackerHook stackerHook : stackerHooks ) {
stackerHook . applyExperience ( player , stack ) ;
}
}
2019-09-03 22:38:00 +02:00
@Override
public List < Config > getExtraConfig ( ) {
return Arrays . asList ( mobFile , itemFile , spawnerFile ) ;
}
2020-04-26 14:42:18 +02:00
2019-09-03 22:38:00 +02:00
@Override
public void onConfigReload ( ) {
2019-09-10 20:21:00 +02:00
blacklist . clear ( ) ;
whitelist . clear ( ) ;
whitelist . addAll ( Settings . ITEM_WHITELIST . getStringList ( ) ) ;
blacklist . addAll ( Settings . ITEM_BLACKLIST . getStringList ( ) ) ;
2020-04-26 14:42:18 +02:00
this . setLocale ( getConfig ( ) . getString ( " System.Language Mode " ) , true ) ;
2018-11-06 04:33:10 +01:00
this . locale . reloadMessages ( ) ;
2019-07-31 06:29:10 +02:00
2023-02-04 14:48:13 +01:00
this . stackingTask . stop ( ) ;
2019-07-31 06:29:10 +02:00
this . stackingTask = new StackingTask ( this ) ;
2019-09-03 22:38:00 +02:00
this . mobFile . load ( ) ;
this . itemFile . load ( ) ;
this . spawnerFile . load ( ) ;
2019-07-23 16:55:49 +02:00
this . getLootablesManager ( ) . getLootManager ( ) . loadLootables ( ) ;
2018-11-06 04:33:10 +01:00
}
2018-11-08 04:26:38 +01:00
public boolean spawnersEnabled ( ) {
2020-08-25 01:01:11 +02:00
return ! this . getServer ( ) . getPluginManager ( ) . isPluginEnabled ( " EpicSpawners " )
& & Settings . SPAWNERS_ENABLED . getBoolean ( ) ;
2018-11-08 04:26:38 +01:00
}
2018-11-06 04:33:10 +01:00
public CommandManager getCommandManager ( ) {
return commandManager ;
}
2019-07-23 16:55:49 +02:00
public LootablesManager getLootablesManager ( ) {
return lootablesManager ;
2019-07-08 18:39:57 +02:00
}
2018-11-06 04:33:10 +01:00
public EntityStackManager getEntityStackManager ( ) {
return entityStackManager ;
}
public SpawnerStackManager getSpawnerStackManager ( ) {
return spawnerStackManager ;
}
public StackingTask getStackingTask ( ) {
return stackingTask ;
}
2019-09-03 22:38:00 +02:00
public Config getMobFile ( ) {
2018-11-06 04:33:10 +01:00
return mobFile ;
}
2019-09-03 22:38:00 +02:00
public Config getItemFile ( ) {
2018-11-06 04:33:10 +01:00
return itemFile ;
}
2019-09-03 22:38:00 +02:00
public Config getSpawnerFile ( ) {
2018-11-06 05:53:27 +01:00
return spawnerFile ;
}
2019-07-31 06:29:10 +02:00
2019-08-02 15:59:10 +02:00
public DatabaseConnector getDatabaseConnector ( ) {
return databaseConnector ;
}
public DataManager getDataManager ( ) {
return dataManager ;
}
2019-09-03 22:38:00 +02:00
2020-06-03 15:44:12 +02:00
public GuiManager getGuiManager ( ) {
return guiManager ;
}
2020-08-25 01:01:11 +02:00
public BlockStackManager getBlockStackManager ( ) {
return blockStackManager ;
2019-09-03 22:38:00 +02:00
}
2020-10-26 18:41:54 +01:00
public CustomEntityManager getCustomEntityManager ( ) {
return customEntityManager ;
}
2019-09-03 22:38:00 +02:00
2020-08-25 01:01:11 +02:00
public void updateHologram ( Hologramable stack ) {
2020-08-26 15:40:51 +02:00
// Is this stack invalid?
if ( ! stack . isValid ( ) )
if ( stack instanceof BlockStack )
blockStackManager . removeBlock ( stack . getLocation ( ) ) ;
else if ( stack instanceof SpawnerStack )
spawnerStackManager . removeSpawner ( stack . getLocation ( ) ) ;
2019-09-03 22:38:00 +02:00
// are holograms enabled?
2020-08-25 01:01:11 +02:00
if ( ! stack . areHologramsEnabled ( ) & & ! HologramManager . getManager ( ) . isEnabled ( ) ) return ;
2021-12-22 23:11:16 +01:00
// update the hologram
if ( ! HologramManager . isHologramLoaded ( stack . getHologramId ( ) ) ) {
HologramManager . createHologram ( stack . getHologramId ( ) , stack . getLocation ( ) , stack . getHologramName ( ) ) ;
return ;
}
HologramManager . updateHologram ( stack . getHologramId ( ) , stack . getHologramName ( ) ) ;
2019-09-03 22:38:00 +02:00
}
2020-08-25 01:01:11 +02:00
public void removeHologram ( Hologramable stack ) {
2021-12-22 23:11:16 +01:00
HologramManager . removeHologram ( stack . getHologramId ( ) ) ;
2019-09-03 22:38:00 +02:00
}
//////// Convenient API //////////
2020-04-26 14:42:18 +02:00
2022-09-19 20:26:08 +02:00
/ * *
* Spawn a stacked item at a location
*
* @param item The item to spawn
* @param amount The amount of items to spawn
* @param location The location to spawn the item
* /
public static void spawnStackedItem ( ItemStack item , int amount , Location location ) {
2023-01-16 21:32:17 +01:00
if ( item . getType ( ) = = Material . AIR ) return ;
2023-01-21 16:15:24 +01:00
World world = location . getWorld ( ) ;
if ( world = = null ) return ;
if ( ServerVersion . isServerVersionAtLeast ( ServerVersion . V1_17 ) ) {
world . dropItem ( location , item , dropped - > {
if ( dropped . getItemStack ( ) . getType ( ) = = Material . AIR ) return ;
updateItemMeta ( dropped , item , amount ) ;
} ) ;
} else {
Item dropped = world . dropItem ( location , item ) ;
2023-01-16 21:32:17 +01:00
if ( dropped . getItemStack ( ) . getType ( ) = = Material . AIR ) return ;
2023-01-02 13:38:58 +01:00
updateItemMeta ( dropped , item , amount ) ;
2023-01-21 16:15:24 +01:00
}
2022-09-19 20:26:08 +02:00
}
2019-09-03 22:38:00 +02:00
/ * *
* Change the stacked amount for this item
2020-04-26 14:42:18 +02:00
*
* @param item item entity to update
2019-09-03 22:38:00 +02:00
* @param newAmount number of items this item represents
* /
public static void updateItemAmount ( Item item , int newAmount ) {
updateItemAmount ( item , item . getItemStack ( ) , newAmount ) ;
}
/ * *
* Change the stacked amount for this item
*
2020-06-28 04:12:13 +02:00
* @param item item entity to update
2019-09-03 22:38:00 +02:00
* @param itemStack ItemStack that will represent this item
* @param newAmount number of items this item represents
* /
public static void updateItemAmount ( Item item , ItemStack itemStack , int newAmount ) {
2020-07-11 04:42:56 +02:00
boolean blacklisted = isMaterialBlacklisted ( itemStack ) ;
if ( newAmount > ( itemStack . getMaxStackSize ( ) / 2 ) & & ! blacklisted )
itemStack . setAmount ( Math . max ( 1 , itemStack . getMaxStackSize ( ) / 2 ) ) ;
else
itemStack . setAmount ( newAmount ) ;
// If amount is 0, Minecraft change the type to AIR
if ( itemStack . getType ( ) = = Material . AIR )
return ;
updateItemMeta ( item , itemStack , newAmount ) ;
}
public static void updateItemMeta ( Item item , ItemStack itemStack , int newAmount ) {
2019-09-03 22:38:00 +02:00
Material material = itemStack . getType ( ) ;
2021-10-17 02:25:16 +02:00
if ( material = = Material . AIR )
return ;
2019-09-03 22:38:00 +02:00
String name = TextUtils . convertToInvisibleString ( " IS " ) + Methods . compileItemName ( itemStack , newAmount ) ;
boolean blacklisted = isMaterialBlacklisted ( itemStack ) ;
2019-09-18 18:33:33 +02:00
if ( newAmount > ( itemStack . getMaxStackSize ( ) / 2 ) & & ! blacklisted ) {
2019-09-03 22:38:00 +02:00
item . setMetadata ( " US_AMT " , new FixedMetadataValue ( INSTANCE , newAmount ) ) ;
} else {
item . removeMetadata ( " US_AMT " , INSTANCE ) ;
}
item . setItemStack ( itemStack ) ;
2019-09-07 23:55:16 +02:00
if ( ( blacklisted & & ! Settings . ITEM_HOLOGRAM_BLACKLIST . getBoolean ( ) )
2019-09-03 22:38:00 +02:00
| | ! INSTANCE . getItemFile ( ) . getBoolean ( " Items. " + material + " .Has Hologram " )
2019-09-07 23:55:16 +02:00
| | ! Settings . ITEM_HOLOGRAMS . getBoolean ( )
2019-09-19 22:14:22 +02:00
| | newAmount < Settings . ITEM_MIN_HOLOGRAM_SIZE . getInt ( ) )
2019-09-03 22:38:00 +02:00
return ;
item . setCustomName ( name ) ;
item . setCustomNameVisible ( true ) ;
}
/ * *
* Lookup the stacked size of this item
*
* @param item item to check
* @return stacker - corrected value for the stack size
* /
public static int getActualItemAmount ( Item item ) {
2019-09-18 18:33:33 +02:00
ItemStack itemStack = item . getItemStack ( ) ;
int amount = itemStack . getAmount ( ) ;
2020-02-23 16:48:26 +01:00
if ( /*amount >= (itemStack.getMaxStackSize() / 2) && */ item . hasMetadata ( " US_AMT " ) ) {
2019-09-03 22:38:00 +02:00
return item . getMetadata ( " US_AMT " ) . get ( 0 ) . asInt ( ) ;
} else {
return amount ;
}
}
/ * *
* Check to see if the amount stored in this itemstack is not the stacked
* amount
*
* @param item item to check
* @return true if Item . getItemStack ( ) . getAmount ( ) is different from the
* stacked amount
* /
public static boolean hasCustomAmount ( Item item ) {
if ( item . hasMetadata ( " US_AMT " ) ) {
return item . getItemStack ( ) . getAmount ( ) ! = item . getMetadata ( " US_AMT " ) . get ( 0 ) . asInt ( ) ;
}
return false ;
}
2019-09-10 20:21:00 +02:00
/ * *
* Check to see if this material is not permitted to stack
*
* @param item Item material to check
* @return true if this material will not stack
* /
public static boolean isMaterialBlacklisted ( ItemStack item ) {
CompatibleMaterial mat = CompatibleMaterial . getMaterial ( item ) ;
2020-04-26 14:42:18 +02:00
if ( mat = = null ) {
2019-09-10 20:25:48 +02:00
// this shouldn't happen, but just in case?
return item = = null ? false : ( ServerVersion . isServerVersionAtLeast ( ServerVersion . V1_13 )
2020-04-26 14:42:18 +02:00
? isMaterialBlacklisted ( item . getType ( ) ) : isMaterialBlacklisted ( item . getType ( ) , item . getData ( ) . getData ( ) ) ) ;
2019-09-10 20:21:00 +02:00
} else if ( mat . usesData ( ) ) {
return isMaterialBlacklisted ( mat . name ( ) ) | | isMaterialBlacklisted ( mat . getMaterial ( ) , mat . getData ( ) ) ;
} else {
return isMaterialBlacklisted ( mat . name ( ) ) | | isMaterialBlacklisted ( mat . getMaterial ( ) ) ;
}
}
2019-09-03 22:38:00 +02:00
/ * *
* Check to see if this material is not permitted to stack
*
* @param type Material to check
* @return true if this material will not stack
* /
2019-09-10 20:21:00 +02:00
public static boolean isMaterialBlacklisted ( String type ) {
return ! whitelist . isEmpty ( ) & & ! whitelist . contains ( type )
| | ! blacklist . isEmpty ( ) & & blacklist . contains ( type ) ;
2019-09-03 22:38:00 +02:00
}
/ * *
* Check to see if this material is not permitted to stack
*
2019-09-10 20:21:00 +02:00
* @param type Material to check
2019-09-03 22:38:00 +02:00
* @return true if this material will not stack
* /
2019-09-10 20:21:00 +02:00
public static boolean isMaterialBlacklisted ( Material type ) {
return ! whitelist . isEmpty ( ) & & ! whitelist . contains ( type . name ( ) )
| | ! blacklist . isEmpty ( ) & & blacklist . contains ( type . name ( ) ) ;
2019-09-03 22:38:00 +02:00
}
/ * *
* Check to see if this material is not permitted to stack
*
* @param type Material to check
2019-09-10 20:11:12 +02:00
* @param data data value for this item ( for 1 . 12 and older servers )
2019-09-03 22:38:00 +02:00
* @return true if this material will not stack
* /
public static boolean isMaterialBlacklisted ( Material type , byte data ) {
String combined = type . toString ( ) + " : " + data ;
return ! whitelist . isEmpty ( ) & & ! whitelist . contains ( combined )
| | ! blacklist . isEmpty ( ) & & blacklist . contains ( combined ) ;
}
2018-11-06 04:33:10 +01:00
}