diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/BukkitFuture.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/BukkitFuture.java index e63644ac2..5591e918a 100644 --- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/BukkitFuture.java +++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/BukkitFuture.java @@ -6,6 +6,7 @@ import org.bukkit.plugin.java.JavaPlugin; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; +import java.util.function.BiConsumer; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; @@ -94,6 +95,20 @@ public class BukkitFuture }; } + /** + * Finalize a {@link CompletionStage} by executing code on the + * main thread after its normal or exceptional completion. + * + * @param action the {@link BiConsumer} that will execute + * @return a {@link BiConsumer} to be passed as an argument to + * {@link CompletionStage#whenComplete(BiConsumer)} + * @see CompletableFuture#whenComplete(BiConsumer) + */ + public static BiConsumer complete(BiConsumer action) + { + return (val, throwable) -> runBlocking(() -> action.accept(val, throwable)); + } + /** * Create a {@link CompletionStage} from a supplier executed on the * main thread. diff --git a/Plugins/Mineplex.Core/src/mineplex/core/database/PlayerKeyValueRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/database/PlayerKeyValueRepository.java index e0148bd0a..3ea3adda9 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/database/PlayerKeyValueRepository.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/database/PlayerKeyValueRepository.java @@ -1,13 +1,18 @@ package mineplex.core.database; +import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableMap; import mineplex.serverdata.database.DBPool; -import java.sql.*; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; import java.util.HashMap; import java.util.Map; import java.util.UUID; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; /** * A SQL-backed repository supporting {@link String} keys and @@ -20,22 +25,31 @@ import java.util.concurrent.CompletableFuture; *

* {@code new PlayerKeyValueRepository("tableName", PreparedStatement::setString, ResultSet::getString, "VARCHAR(255)")} *

- * NOTE: EACH CONSTRUCTOR IS BLOCKING, and initializes a backing table - * if one does not yet exist + * Compatible backing table schemas can be written as follows (replace $VARS as appropriate): + *

+ *     CREATE TABLE IF NOT EXISTS $TABLE_NAME (
+ *         accountId INT NOT NULL,
+ *         kvKey VARCHAR(255) NOT NULL,
+ *         kvValue $VALUE_COLUMN_TYPE
+ *         PRIMARY KEY (accountId,kvKey),
+ *         INDEX acc_ind (accountId),
+ *         FOREIGN KEY (accountId) REFERENCES accounts(id)
+ *     )}
+ * 

* * @param The value type to use for this repository */ public class PlayerKeyValueRepository { private static final ImmutableMap, ValueMapper> PRIM_MAPPERS = ImmutableMap., ValueMapper>builder() - .put(String.class, new ValueMapper<>(PreparedStatement::setString, ResultSet::getString, "VARCHAR(255)")) - .put(Boolean.class, new ValueMapper<>(PreparedStatement::setBoolean, ResultSet::getBoolean, "BOOL")) - .put(Byte.class, new ValueMapper<>(PreparedStatement::setByte, ResultSet::getByte, "TINYINT")) - .put(Short.class, new ValueMapper<>(PreparedStatement::setShort, ResultSet::getShort, "SMALLINT")) - .put(Integer.class, new ValueMapper<>(PreparedStatement::setInt, ResultSet::getInt, "INTEGER")) - .put(Long.class, new ValueMapper<>(PreparedStatement::setLong, ResultSet::getLong, "BIGINT")) - .put(Float.class, new ValueMapper<>(PreparedStatement::setFloat, ResultSet::getFloat, "REAL")) - .put(Double.class, new ValueMapper<>(PreparedStatement::setDouble, ResultSet::getDouble, "DOUBLE")) + .put(String.class, new ValueMapper<>(PreparedStatement::setString, ResultSet::getString)) + .put(Boolean.class, new ValueMapper<>(PreparedStatement::setBoolean, ResultSet::getBoolean)) + .put(Byte.class, new ValueMapper<>(PreparedStatement::setByte, ResultSet::getByte)) + .put(Short.class, new ValueMapper<>(PreparedStatement::setShort, ResultSet::getShort)) + .put(Integer.class, new ValueMapper<>(PreparedStatement::setInt, ResultSet::getInt)) + .put(Long.class, new ValueMapper<>(PreparedStatement::setLong, ResultSet::getLong)) + .put(Float.class, new ValueMapper<>(PreparedStatement::setFloat, ResultSet::getFloat)) + .put(Double.class, new ValueMapper<>(PreparedStatement::setDouble, ResultSet::getDouble)) .build(); private final String _tableName; private final ValueMapper _mapper; @@ -51,7 +65,11 @@ public class PlayerKeyValueRepository @SuppressWarnings("unchecked") // java's generics are garbage. public PlayerKeyValueRepository(String tableName, Class clazz) // we could infer the type parameter at runtime, but it's super ugly { - this(tableName, (ValueMapper) PRIM_MAPPERS.get(clazz)); + ValueMapper mapper = (ValueMapper) PRIM_MAPPERS.get(clazz); + Preconditions.checkNotNull(mapper, "Unsupported value type: " + clazz.getName() + ". (use the other constructor)"); + + this._tableName = tableName; + this._mapper = mapper; } /** @@ -63,35 +81,11 @@ public class PlayerKeyValueRepository * @param serializer the serializing function used to insert values * @param deserializer the deserializing function used to retrieve * values - * @param columnDef the value type's SQL datatype declaration, e.g., {@code "VARCHAR(255)"} for Strings. */ - public PlayerKeyValueRepository(String tableName, Serializer serializer, Deserializer deserializer, String columnDef) - { - this(tableName, new ValueMapper(serializer, deserializer, columnDef)); - } - - private PlayerKeyValueRepository(String tableName, ValueMapper mapper) + public PlayerKeyValueRepository(String tableName, Serializer serializer, Deserializer deserializer) { this._tableName = tableName; - this._mapper = mapper; - - // Create a table to back this repository - try (Connection conn = DBPool.getAccount().getConnection()) - { - Statement stmt = conn.createStatement(); - stmt.executeUpdate("CREATE TABLE IF NOT EXISTS " + _tableName + "(" - + "accountId INT NOT NULL," - + "kvKey VARCHAR(255) NOT NULL," - + "kvValue " + _mapper._columnDef + "," - + "PRIMARY KEY (accountId,kvKey)," - + "INDEX acc_ind (accountId)," - + "FOREIGN KEY (accountId) REFERENCES accounts(id) ON DELETE NO ACTION ON UPDATE NO ACTION" - + ")"); - } - catch (SQLException e) - { - e.printStackTrace(); - } + this._mapper = new ValueMapper(serializer, deserializer); } /** @@ -117,9 +111,11 @@ public class PlayerKeyValueRepository return _mapper._deserializer.read(set, 1); } return null; - } catch (SQLException ignored) {} - - return null; // yuck + } + catch (SQLException e) + { + throw new CompletionException(e); + } }); } @@ -146,9 +142,11 @@ public class PlayerKeyValueRepository results.put(set.getString(1), _mapper._deserializer.read(set, 2)); } return results; - } catch (SQLException ignored) {} - - return new HashMap<>(); // yuck + } + catch (SQLException e) + { + throw new CompletionException(e); + } }); } @@ -161,7 +159,7 @@ public class PlayerKeyValueRepository * @return a {@link CompletableFuture} whose value indicates * success or failure */ - public CompletableFuture put(UUID uuid, String key, V value) + public CompletableFuture put(UUID uuid, String key, V value) { return CompletableFuture.supplyAsync(() -> { @@ -172,11 +170,13 @@ public class PlayerKeyValueRepository _mapper._serializer.write(stmt, 2, value); stmt.setString(3, uuid.toString()); stmt.executeUpdate(); - return true; + return null; - } catch (SQLException ignored) {} - - return false; + } + catch (SQLException e) + { + throw new CompletionException(e); + } }); } @@ -189,7 +189,7 @@ public class PlayerKeyValueRepository * @return a {@link CompletableFuture} whose value indicates * success or failure */ - public CompletableFuture putAll(UUID uuid, Map values) + public CompletableFuture putAll(UUID uuid, Map values) { return CompletableFuture.supplyAsync(() -> { @@ -205,11 +205,13 @@ public class PlayerKeyValueRepository stmt.addBatch(); } stmt.executeBatch(); - return true; + return null; - } catch (SQLException ignored) {} - - return false; + } + catch (SQLException e) + { + throw new CompletionException(e); + } }); } @@ -221,7 +223,7 @@ public class PlayerKeyValueRepository * @return a {@link CompletableFuture} whose value indicates * success or failure */ - public CompletableFuture remove(UUID uuid, String key) + public CompletableFuture remove(UUID uuid, String key) { return CompletableFuture.supplyAsync(() -> { @@ -231,11 +233,13 @@ public class PlayerKeyValueRepository stmt.setString(1, uuid.toString()); stmt.setString(2, key); stmt.executeUpdate(); - return true; + return null; - } catch (SQLException ignored) {} - - return false; + } + catch (SQLException e) + { + throw new CompletionException(e); + } }); } @@ -246,7 +250,7 @@ public class PlayerKeyValueRepository * @return a {@link CompletableFuture} whose value indicates * success or failure */ - public CompletableFuture removeAll(UUID uuid) + public CompletableFuture removeAll(UUID uuid) { return CompletableFuture.supplyAsync(() -> { @@ -255,11 +259,13 @@ public class PlayerKeyValueRepository PreparedStatement stmt = conn.prepareStatement("DELETE FROM " + _tableName + " WHERE accountId=(SELECT id FROM accounts WHERE uuid=?)"); stmt.setString(1, uuid.toString()); stmt.executeUpdate(); - return true; + return null; - } catch (SQLException ignored) {} - - return false; + } + catch (SQLException e) + { + throw new CompletionException(e); + } }); } @@ -267,13 +273,11 @@ public class PlayerKeyValueRepository { private final Serializer _serializer; private final Deserializer _deserializer; - private final String _columnDef; - private ValueMapper(Serializer serializer, Deserializer deserializer, String columnDef) + private ValueMapper(Serializer serializer, Deserializer deserializer) { _serializer = serializer; _deserializer = deserializer; - _columnDef = columnDef; } } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/packethandler/PacketHandler.java b/Plugins/Mineplex.Core/src/mineplex/core/packethandler/PacketHandler.java index 5e76bf104..3018daa85 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/packethandler/PacketHandler.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/packethandler/PacketHandler.java @@ -31,7 +31,7 @@ public class PacketHandler extends MiniPlugin super("PacketHandler", plugin); } - @EventHandler(priority = EventPriority.MONITOR) + @EventHandler(priority = EventPriority.LOWEST) public void onPlayerJoin(PlayerJoinEvent event) { _playerVerifierMap.put(event.getPlayer(), new PacketVerifier(event.getPlayer(), this)); diff --git a/Plugins/Mineplex.Core/src/mineplex/core/punish/Command/PunishCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/punish/Command/PunishCommand.java index b578a2566..9f566aa2a 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/punish/Command/PunishCommand.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/punish/Command/PunishCommand.java @@ -24,7 +24,13 @@ public class PunishCommand extends CommandBase @Override public void Execute(final Player caller, String[] args) - { + { + Rank playerRank = this.Plugin.GetClients().Get(caller).GetRank(); + if (playerRank == Rank.JNR_DEV || playerRank == Rank.DEVELOPER) + { + return; + } + if (args == null || args.length < 2) { Plugin.Help(caller); diff --git a/Plugins/Mineplex.Core/src/mineplex/core/scoreboard/PlayerScoreboard.java b/Plugins/Mineplex.Core/src/mineplex/core/scoreboard/PlayerScoreboard.java index befaa88e7..6a63bf257 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/scoreboard/PlayerScoreboard.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/scoreboard/PlayerScoreboard.java @@ -56,16 +56,6 @@ public class PlayerScoreboard String rankName = _manager.getClients().Get(player).GetRank().Name; String otherRankName = _manager.getClients().Get(otherPlayer).GetRank().Name; - if (!_manager.getClients().Get(player).GetRank().has(Rank.ULTRA) && _manager.getDonation().Get(player.getName()).OwnsUltraPackage()) - { - rankName = Rank.ULTRA.Name; - } - - if (!_manager.getClients().Get(otherPlayer).GetRank().has(Rank.ULTRA) && _manager.getDonation().Get(otherPlayer.getName()).OwnsUltraPackage()) - { - otherRankName = Rank.ULTRA.Name; - } - //Add Other to Self _scoreboard.getTeam(otherRankName).addPlayer(otherPlayer); diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansGame.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansGame.java index 8247f16c0..11f7fdf5d 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansGame.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansGame.java @@ -329,7 +329,7 @@ public class ClansGame extends MiniPlugin ClanInfo clan = _clans.getClan(player); ClanInfo mimicClan = _clans.getClanAdmin().getMimic(player, false); ClanInfo blockClan = _clans.getClanUtility().getClaim(loc) == null ? null : _clans.getClan(_clans.getClanUtility().getClaim(loc).Owner); - if (blockClan.equals(mimicClan)) access = ClanRelation.SELF; + if (blockClan != null && blockClan.equals(mimicClan)) access = ClanRelation.SELF; // Doors, chests, & furnaces if (blockClan != null && (!blockClan.equals(clan) && !blockClan.equals(mimicClan)) && (event.getAction() == Action.RIGHT_CLICK_BLOCK && (loc.getBlock().getType().name().contains("DOOR") || UtilItem.doesHaveGUI(loc.getBlock().getType())))) diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansManager.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansManager.java index 69af91170..1375dba32 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansManager.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansManager.java @@ -81,6 +81,7 @@ import mineplex.minecraft.game.classcombat.Class.ClientClass; import mineplex.minecraft.game.classcombat.Class.IPvpClass; import mineplex.minecraft.game.classcombat.Class.repository.token.CustomBuildToken; import mineplex.minecraft.game.classcombat.Condition.SkillConditionManager; +import mineplex.minecraft.game.classcombat.Skill.Mage.events.FissureModifyBlockEvent; import mineplex.minecraft.game.classcombat.Skill.SkillFactory; import mineplex.minecraft.game.classcombat.item.ItemFactory; import mineplex.minecraft.game.classcombat.shop.ClassCombatShop; @@ -99,6 +100,7 @@ import org.bukkit.entity.Horse; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; import org.bukkit.event.block.Action; import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.SignChangeEvent; @@ -240,8 +242,6 @@ public class ClansManager extends MiniClientPluginimplements IRelati _damageManager = new DamageManager(plugin, _combatManager, _npcManager, _disguiseManager, _condition); _damageManager.addCommand(new KillCommand(_damageManager)); - addCommand(new QueryCommand(this)); - _worldEvent = new WorldEventManager(plugin, this, _damageManager, _lootManager, blockRestore, _clanRegions, null); _taskManager = new TaskManager(plugin, _clientManager, webServerAddress); @@ -310,6 +310,15 @@ public class ClansManager extends MiniClientPluginimplements IRelati ClanTerritory territory = _clanUtility.getClaim(location); return territory == null || !territory.Safe; }); + registerEvents(new Listener() + { + @EventHandler + public void on(FissureModifyBlockEvent event) + { + Material targetType = event.getTargetBlock().getType(); + event.setCancelled(targetType == Material.POTATO || targetType == Material.CARROT); + } + }); _worldEvent.setFactory(skillManager); _classManager = new ClassManager(plugin, _clientManager, donationManager, skillManager, itemFactory, webServerAddress); diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/commands/QueryCommand.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/commands/QueryCommand.java deleted file mode 100644 index 8e95c06e0..000000000 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/commands/QueryCommand.java +++ /dev/null @@ -1,53 +0,0 @@ -package mineplex.game.clans.clans.commands; - -import org.bukkit.entity.Player; - -import mineplex.core.command.CommandBase; -import mineplex.core.common.Rank; -import mineplex.core.common.util.Callback; -import mineplex.core.common.util.F; -import mineplex.core.common.util.UtilPlayer; -import mineplex.core.database.MinecraftRepository; -import mineplex.game.clans.clans.ClanInfo; -import mineplex.game.clans.clans.ClansManager; -import mineplex.serverdata.database.DBPool; -import mineplex.serverdata.database.RepositoryBase; - -public class QueryCommand extends CommandBase -{ - private ClansManager _clansManager; - - public QueryCommand(ClansManager plugin) - { - super(plugin, Rank.JNR_DEV, "query"); - _clansManager = plugin; - } - - @Override - public void Execute(final Player caller, String[] args) - { - if (args.length == 0) - { - UtilPlayer.message(caller, F.main(Plugin.getName(), "Query missing.")); - return; - } - - final String query = F.combine(args, 0, null, false); - - new MinecraftRepository(Plugin.getPlugin(), DBPool.getAccount()) { - protected void initialize() - { - executeUpdate(query); - } - - protected void update() - { - } - }; - } - - public static void message(Player player, String message) - { - UtilPlayer.message(player, F.main("Clans", message)); - } -} diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/invsee/commands/InvseeCommand.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/invsee/commands/InvseeCommand.java index 00f0e24b8..36b0466a8 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/invsee/commands/InvseeCommand.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/invsee/commands/InvseeCommand.java @@ -19,7 +19,7 @@ public class InvseeCommand extends CommandBase { public InvseeCommand(InvseeManager plugin) { - super(plugin, Rank.ADMIN, "invsee"); + super(plugin, Rank.CMOD, "invsee"); } @Override @@ -27,7 +27,7 @@ public class InvseeCommand extends CommandBase { if (args.length == 0) { - UtilPlayer.message(caller, F.help("/invsee ", "View a player's inventory", Rank.ADMIN)); + UtilPlayer.message(caller, F.help("/invsee ", "View a player's inventory", Rank.CMOD)); return; } UUID uuid = null; diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/map/ItemMapManager.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/map/ItemMapManager.java index 04e2fb410..f73eb2280 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/map/ItemMapManager.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/map/ItemMapManager.java @@ -1,26 +1,30 @@ package mineplex.game.clans.clans.map; -import java.io.*; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.PrintWriter; import java.lang.reflect.Field; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Iterator; import java.util.Map.Entry; -import mineplex.core.common.util.*; import mineplex.game.clans.tutorial.TutorialManager; -import net.minecraft.server.v1_8_R3.*; +import mineplex.game.clans.tutorial.map.TutorialMapManager; import org.apache.commons.io.FileUtils; import org.bukkit.Bukkit; +import org.bukkit.Chunk; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.World; import org.bukkit.craftbukkit.v1_8_R3.CraftChunk; import org.bukkit.craftbukkit.v1_8_R3.CraftWorld; -import org.bukkit.craftbukkit.v1_8_R3.util.LongHash; -import org.bukkit.craftbukkit.v1_8_R3.util.LongObjectHashMap; import org.bukkit.entity.ItemFrame; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; import org.bukkit.event.block.Action; import org.bukkit.event.entity.ItemSpawnEvent; import org.bukkit.event.entity.PlayerDeathEvent; @@ -31,8 +35,6 @@ import org.bukkit.event.player.PlayerItemHeldEvent; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerTeleportEvent; -import org.bukkit.event.world.ChunkLoadEvent; -import org.bukkit.event.world.ChunkUnloadEvent; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import org.bukkit.map.MapRenderer; @@ -44,6 +46,13 @@ import com.google.common.collect.Iterables; import com.google.common.collect.Multisets; import mineplex.core.MiniPlugin; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilInv; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTextBottom; +import mineplex.core.common.util.UtilTime; import mineplex.core.common.util.UtilTime.TimeUnit; import mineplex.core.itemstack.ItemBuilder; import mineplex.core.portal.ServerTransferEvent; @@ -53,119 +62,82 @@ import mineplex.game.clans.clans.ClansManager; import mineplex.game.clans.clans.ClansUtility; import mineplex.game.clans.clans.map.events.PlayerGetMapEvent; import mineplex.game.clans.clans.worldevent.WorldEventManager; +import net.minecraft.server.v1_8_R3.Block; +import net.minecraft.server.v1_8_R3.BlockPosition; +import net.minecraft.server.v1_8_R3.Blocks; +import net.minecraft.server.v1_8_R3.IBlockData; +import net.minecraft.server.v1_8_R3.MaterialMapColor; +import net.minecraft.server.v1_8_R3.PersistentCollection; -/* - * This class manages what the Clans map will show. - * It will scan all relevant chunks (eg players nearby) every ticks - */ public class ItemMapManager extends MiniPlugin { - // Every BLOCK_SCAN_INTERVAL we add as a new region to scan - private static final int BLOCK_SCAN_INTERVAL = 16 * 3; - // 1536 is the width of the entire world from one borderland to the other - private static final int HALF_WORLD_SIZE = 1536 / 2; - // This slot is where the Clans Map will go by default - private static final int CLANS_MAP_SLOT = 8; - - private static final String[] ZOOM_INFO; - - static - { - ZOOM_INFO = new String[4]; - for (int zoomLevel = 0; zoomLevel <= 3; zoomLevel++) - { - StringBuilder progressBar = new StringBuilder(C.cBlue); - - boolean colorChange = false; - for (int i = 2; i >= 0; i--) - { - if (!colorChange && i < zoomLevel) - { - progressBar.append(C.cGray); - colorChange = true; - } - char c; - switch (i) - { - case 0: - c = '█'; - break; - case 1: - c = '▆'; - break; - default: - c = '▄'; - break; - } - for (int a = 0; a < 4; a++) - { - progressBar.append(c); - } - - if (i > 0) - { - progressBar.append(" "); - } - } - ZOOM_INFO[zoomLevel] = progressBar.toString(); - } - } - + private int _blocksScan = 16 * 3; private ClansUtility _clansUtility; private Comparator> _comparator; - private int[][] _heightMap = new int[(HALF_WORLD_SIZE * 2) + 16][]; + private int _halfMapSize = 1536 / 2; + private int[][] _heightMap = new int[(_halfMapSize * 2) + 16][]; + private boolean _loadWorld = true; private HashMap _map = new HashMap(); private short _mapId = -1; private HashMap _mapInfo = new HashMap(); private HashMap _scale = new HashMap(); - // Use LinkedList because operations are either add(Entry) which is O(1) and remove(0) which is O(1) on LinkedList but O(n) on ArrayList - private LinkedList> _scanList = new LinkedList>(); + private ArrayList> _scanList = new ArrayList>(); private World _world; - private WorldServer _nmsWorld; - private ChunkProviderServer _chunkProviderServer; - private ChunkRegionLoader _chunkRegionLoader; private WorldEventManager _eventManager; private TutorialManager _tutorial; public ItemMapManager(ClansManager clansManager, TutorialManager tutorial, WorldEventManager eventManager) { super("ItemMapManager", clansManager.getPlugin()); - + _clansUtility = clansManager.getClanUtility(); _eventManager = eventManager; _tutorial = tutorial; - _comparator = (o1, o2) -> + _comparator = new Comparator>() { - // Render the places outside the map first to speed up visual errors fixing - int outsideMap = Boolean.compare(o1.getValue() < -HALF_WORLD_SIZE, o2.getValue() < -HALF_WORLD_SIZE); - if (outsideMap != 0) + @Override + public int compare(Entry o1, Entry o2) { - return -outsideMap; - } + // Render the places outside the map first to speed up visual errors fixing + int outsideMap = Boolean.compare(o1.getValue() < -_halfMapSize, o2.getValue() < -_halfMapSize); - double dist1 = 0; - double dist2 = 0; + if (outsideMap != 0) + { + return -outsideMap; + } - for (Player player : UtilServer.getPlayers()) - { - dist1 += getDistance(o1, player.getLocation().getX(), player.getLocation().getZ()); - dist2 += getDistance(o2, player.getLocation().getX(), player.getLocation().getZ()); - } + double dist1 = 0; + double dist2 = 0; + + for (Player player : UtilServer.getPlayers()) + { + dist1 += getDistance(o1, player.getLocation().getX(), player.getLocation().getZ()); + dist2 += getDistance(o2, player.getLocation().getX(), player.getLocation().getZ()); + } + + if (dist1 != dist2) + { + return Double.compare(dist1, dist2); + } + + dist1 = getDistance(o1, 0, 0); + dist2 = getDistance(o2, 0, 0); - if (dist1 != dist2) - { return Double.compare(dist1, dist2); + } - - dist1 = getDistance(o1, 0, 0); - dist2 = getDistance(o2, 0, 0); - - return Double.compare(dist1, dist2); - }; + for (int x = -_halfMapSize; x < _halfMapSize; x += _blocksScan) + { + for (int z = -_halfMapSize - 16; z < _halfMapSize; z += (z < -_halfMapSize ? 16 : _blocksScan)) + { + _scanList.add(new HashMap.SimpleEntry(x, z)); + } + } + _scale.put(0, 1); // _scale.put(1, 2); _scale.put(1, 4); @@ -175,7 +147,7 @@ public class ItemMapManager extends MiniPlugin for (Entry entry : _scale.entrySet()) { - int size = (HALF_WORLD_SIZE * 2) / entry.getValue(); + int size = (_halfMapSize * 2) / entry.getValue(); Byte[][] bytes = new Byte[size][]; for (int i = 0; i < size; i++) @@ -193,23 +165,6 @@ public class ItemMapManager extends MiniPlugin _world = Bukkit.getWorld("world"); - try - { - Field chunkLoader = ChunkProviderServer.class.getDeclaredField("chunkLoader"); - chunkLoader.setAccessible(true); - _nmsWorld = ((CraftWorld) _world).getHandle(); - _chunkProviderServer = _nmsWorld.chunkProviderServer; - _chunkRegionLoader = (ChunkRegionLoader) chunkLoader.get(_chunkProviderServer); - if (_chunkRegionLoader == null) - { - throw new RuntimeException("Did not expect null chunkLoader"); - } - } - catch (ReflectiveOperationException e) - { - throw new RuntimeException("Could not reflectively access ChunkRegionLoader", e); - } - try { File file = new File("world/clans_map_id"); @@ -283,58 +238,6 @@ public class ItemMapManager extends MiniPlugin } rebuildScan(); - initialScan(); - } - - private void initialScan() - { - System.out.println("Beginning initial scan. There are " + _scanList.size() + " regions to scan"); - - // How many regions before logging an update (Currently set to every 20%) - int logPer = _scanList.size() / 5; - - while (!_scanList.isEmpty()) - { - Entry entry = _scanList.remove(0); - if (_scanList.size() % logPer == 0) - { - System.out.println("Running initial render... " + _scanList.size() + " sections to go"); - } - - int startingX = entry.getKey(); - int startingZ = entry.getValue(); - - boolean outsideMap = startingZ < -HALF_WORLD_SIZE; - - scanWorldMap(startingX, startingZ, !outsideMap, true); - - if (outsideMap) - { - continue; - } - - for (int scale = 1; scale < _scale.size(); scale++) - { - if (scale == 3) - continue; - - drawWorldScale(scale, startingX, startingZ); - colorWorldHeight(scale, startingX, startingZ); - } - - colorWorldHeight(0, startingX, startingZ); - } - - for (int x = -HALF_WORLD_SIZE; x < HALF_WORLD_SIZE; x += BLOCK_SCAN_INTERVAL) - { - for (int z = -HALF_WORLD_SIZE; z < HALF_WORLD_SIZE; z += BLOCK_SCAN_INTERVAL) - { - drawWorldScale(3, x, z); - colorWorldHeight(3, x, z); - } - } - - System.out.println("Finished first map scan and render"); } private void setupRenderer(MapView view) @@ -353,7 +256,10 @@ public class ItemMapManager extends MiniPlugin if (!(event.getRightClicked() instanceof ItemFrame)) return; - if (!isItemClansMap(event.getPlayer().getItemInHand())) + ItemStack item = event.getPlayer().getItemInHand(); + + if (item == null || item.getType() != Material.MAP || item.getDurability() < _mapId + || item.getDurability() > _mapId + 100) return; event.setCancelled(true); @@ -364,7 +270,7 @@ public class ItemMapManager extends MiniPlugin */ public int calcMapCenter(int zoom, int cord) { - int mapSize = HALF_WORLD_SIZE / zoom; // This is how large the map is in pixels + int mapSize = _halfMapSize / zoom; // This is how large the map is in pixels int mapCord = cord / zoom; // This is pixels from true center of map, not held map @@ -403,7 +309,7 @@ public class ItemMapManager extends MiniPlugin Byte[][] map = _map.get(scale); int zoom = getZoom(scale); - for (int x = startingX; x < startingX + BLOCK_SCAN_INTERVAL; x += zoom) + for (int x = startingX; x < startingX + _blocksScan; x += zoom) { double d0 = 0; @@ -413,10 +319,10 @@ public class ItemMapManager extends MiniPlugin { for (int addZ = 0; addZ < zoom; addZ++) { - int hX = x + addX + HALF_WORLD_SIZE; - int hZ = (startingZ - zoom) + addZ + HALF_WORLD_SIZE; + int hX = x + addX + _halfMapSize; + int hZ = (startingZ - zoom) + addZ + _halfMapSize; - if (hX >= HALF_WORLD_SIZE * 2 || hZ >= HALF_WORLD_SIZE * 2) + if (hX >= _halfMapSize * 2 || hZ >= _halfMapSize * 2) { continue; } @@ -425,7 +331,7 @@ public class ItemMapManager extends MiniPlugin } } - for (int z = startingZ; z < startingZ + BLOCK_SCAN_INTERVAL; z += zoom) + for (int z = startingZ; z < startingZ + _blocksScan; z += zoom) { // Water depth colors not included double d1 = 0; @@ -434,10 +340,10 @@ public class ItemMapManager extends MiniPlugin { for (int addZ = 0; addZ < zoom; addZ++) { - int hX = x + addX + HALF_WORLD_SIZE; - int hZ = z + addZ + HALF_WORLD_SIZE; + int hX = x + addX + _halfMapSize; + int hZ = z + addZ + _halfMapSize; - if (hX >= HALF_WORLD_SIZE * 2 || hZ >= HALF_WORLD_SIZE * 2) + if (hX >= _halfMapSize * 2 || hZ >= _halfMapSize * 2) { continue; } @@ -464,7 +370,7 @@ public class ItemMapManager extends MiniPlugin b0 = 0; } - int origColor = map[(x + HALF_WORLD_SIZE) / zoom][(z + HALF_WORLD_SIZE) / zoom] - 1; + int origColor = map[(x + _halfMapSize) / zoom][(z + _halfMapSize) / zoom] - 1; /*if (color < 4) { @@ -482,7 +388,7 @@ public class ItemMapManager extends MiniPlugin }*/ byte color = (byte) (origColor + b0); - map[(x + HALF_WORLD_SIZE) / zoom][(z + HALF_WORLD_SIZE) / zoom] = color; + map[(x + _halfMapSize) / zoom][(z + _halfMapSize) / zoom] = color; } } } @@ -493,9 +399,9 @@ public class ItemMapManager extends MiniPlugin Byte[][] second = _map.get(scale); int zoom = getZoom(scale); - for (int x = startingX; x < startingX + BLOCK_SCAN_INTERVAL; x += zoom) + for (int x = startingX; x < startingX + _blocksScan; x += zoom) { - for (int z = startingZ; z < startingZ + BLOCK_SCAN_INTERVAL; z += zoom) + for (int z = startingZ; z < startingZ + _blocksScan; z += zoom) { HashMultiset hashmultiset = HashMultiset.create(); @@ -503,8 +409,8 @@ public class ItemMapManager extends MiniPlugin { for (int addZ = 0; addZ < zoom; addZ++) { - int pX = x + addX + HALF_WORLD_SIZE; - int pZ = z + addZ + HALF_WORLD_SIZE; + int pX = x + addX + _halfMapSize; + int pZ = z + addZ + _halfMapSize; if (pX >= first.length || pZ >= first.length) { @@ -526,7 +432,7 @@ public class ItemMapManager extends MiniPlugin { color = (byte) 0; } - second[(x + HALF_WORLD_SIZE) / zoom][(z + HALF_WORLD_SIZE) / zoom] = color; + second[(x + _halfMapSize) / zoom][(z + _halfMapSize) / zoom] = color; } } } @@ -534,16 +440,25 @@ public class ItemMapManager extends MiniPlugin @EventHandler public void dropItem(ItemSpawnEvent event) { - if (isItemClansMap(event.getEntity().getItemStack())) - event.getEntity().remove(); - } + ItemStack item = event.getEntity().getItemStack(); + if (item != null && item.getType() == Material.MAP && item.getDurability() >= _mapId + && item.getDurability() <= _mapId + 100) + { + event.getEntity().remove(); + } + } + public void removeMap(Player player) { for (int slot = 0; slot < player.getInventory().getSize(); slot++) { - if (isItemClansMap(player.getInventory().getItem(slot))) + ItemStack item = player.getInventory().getItem(slot); + + if (item != null && item.getType() == Material.MAP && item.getDurability() >= _mapId && item.getDurability() <= _mapId + 100) + { player.getInventory().setItem(slot, null); + } } } @@ -562,7 +477,7 @@ public class ItemMapManager extends MiniPlugin private double getDistance(Entry entry, double x1, double z1) { - return getDistance(x1, z1, entry.getKey() + (BLOCK_SCAN_INTERVAL / 2), entry.getValue() + (BLOCK_SCAN_INTERVAL / 2)); + return getDistance(x1, z1, entry.getKey() + (_blocksScan / 2), entry.getValue() + (_blocksScan / 2)); } public Byte[][] getMap(int scale) @@ -577,7 +492,7 @@ public class ItemMapManager extends MiniPlugin public int getMapSize() { - return HALF_WORLD_SIZE; + return _halfMapSize; } public int getZoom(int scale) @@ -585,7 +500,35 @@ public class ItemMapManager extends MiniPlugin return _scale.get(scale); } - //fixme So what appears to happen is that after you die, if your map is is the same then the map is frozen + @EventHandler + public void preventMapMoveInventories(InventoryClickEvent event) + { + Inventory inv = event.getClickedInventory(); + + if (inv == null) + return; + + // Yeah, the loop looks a little weird.. + for (ItemStack item : new ItemStack[] + { + event.getCurrentItem(), event.getCursor() + }) + { + if (item == null || item.getType() != Material.MAP || item.getDurability() < _mapId + || item.getDurability() > _mapId + 100) + continue; + + if (inv.getHolder() instanceof Player ? !event.isShiftClick() : Objects.equal(event.getCurrentItem(), item)) + continue; + + event.setCancelled(true); + + UtilPlayer.message(event.getWhoClicked(), + F.main("Inventory", "You cannot move " + F.item("Clans Map") + " between inventories.")); + return; + } + } + @EventHandler public void onDeath(PlayerDeathEvent event) { @@ -599,10 +542,14 @@ public class ItemMapManager extends MiniPlugin { Player player = event.getPlayer(); - if (!isItemClansMap(player.getInventory().getItem(event.getNewSlot()))) + ItemStack item = player.getInventory().getItem(event.getNewSlot()); + + if (item == null || item.getType() != Material.MAP || item.getDurability() < _mapId + || item.getDurability() > _mapId + 100) return; showZoom(player, getMap(player)); + } @EventHandler @@ -611,7 +558,10 @@ public class ItemMapManager extends MiniPlugin if (event.getAction() == Action.PHYSICAL) return; - if (!isItemClansMap(event.getItem())) + ItemStack item = event.getItem(); + + if (item == null || item.getType() != Material.MAP || item.getDurability() < _mapId + || item.getDurability() > _mapId + 100) return; event.setCancelled(true); @@ -716,11 +666,36 @@ public class ItemMapManager extends MiniPlugin private void rebuildScan() { - for (int x = -HALF_WORLD_SIZE; x < HALF_WORLD_SIZE; x += BLOCK_SCAN_INTERVAL) + for (int x = -_halfMapSize; x < _halfMapSize; x += _blocksScan) { - for (int z = -HALF_WORLD_SIZE - 16; z < HALF_WORLD_SIZE; z += (z < -HALF_WORLD_SIZE ? 16 : BLOCK_SCAN_INTERVAL)) + for (int z = -_halfMapSize - 16; z < _halfMapSize; z += (z < -_halfMapSize ? 16 : _blocksScan)) { - _scanList.add(new HashMap.SimpleEntry<>(x, z)); + _scanList.add(new HashMap.SimpleEntry(x, z)); + } + } + + if (!_loadWorld) + { + Iterator> itel = _scanList.iterator(); + + while (itel.hasNext()) + { + Entry entry = itel.next(); + boolean removeEntry = true; + + for (Player player : UtilServer.getPlayers()) + { + if (Math.sqrt(getDistance(entry, player.getLocation().getX(), player.getLocation().getZ())) < 200) + { + removeEntry = false; + break; + } + } + + if (removeEntry) + { + itel.remove(); + } } } @@ -769,117 +744,101 @@ public class ItemMapManager extends MiniPlugin if (event.getType() != UpdateType.FAST) return; - if (_scanList.isEmpty() && UtilServer.getPlayers().length > 0) + if (_scanList.isEmpty()) { + if (_loadWorld) + { + for (int x = -_halfMapSize; x < _halfMapSize; x += _blocksScan) + { + for (int z = -_halfMapSize; z < _halfMapSize; z += _blocksScan) + { + drawWorldScale(3, x, z); + colorWorldHeight(3, x, z); + } + } + + System.out.print("Finished first map scan and render"); + } + + _loadWorld = false; + + if (UtilServer.getPlayers().length == 0) + return; + rebuildScan(); } - - if (_scanList.size() % 20 == 0) + else if (_scanList.size() % 20 == 0) { Collections.sort(_scanList, _comparator); } - + if (_scanList.isEmpty()) - { return; - } Entry entry = _scanList.remove(0); int startingX = entry.getKey(); int startingZ = entry.getValue(); - boolean outsideMap = startingZ < -HALF_WORLD_SIZE; - - scanWorldMap(startingX, startingZ, !outsideMap, false); + boolean outsideMap = startingZ < -_halfMapSize; + scanWorldMap(startingX, startingZ, !outsideMap); + if (outsideMap) + { return; + } for (int scale = 1; scale < _scale.size(); scale++) { - drawWorldScale(scale, startingX, startingZ); + if (scale == 3 && _loadWorld) + continue; + + if (!outsideMap) + { + drawWorldScale(scale, startingX, startingZ); + } + colorWorldHeight(scale, startingX, startingZ); } - + colorWorldHeight(0, startingX, startingZ); } - - // Let's not create hundreds of thousands of BlockPositions - // Single thread = should be thread safe - private BlockPosition.MutableBlockPosition _blockPosition = new BlockPosition.MutableBlockPosition(); - - // Maps the cached chunks which were loaded from disk to save IO operations - private LongObjectHashMap _chunkCache = new LongObjectHashMap<>(); - - /* - * Remove the cached chunks when the real chunks are loaded in - */ - @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) - public void LoadChunk(ChunkLoadEvent event) - { - _chunkCache.remove(LongHash.toLong(event.getChunk().getX(), event.getChunk().getZ())); - } - - /* - * Given a particular coordinate, this method will scan up to BLOCK_SCAN_INTERVAL and record the color of ever 16th block - * If a chunk has not been loaded, the following steps will be taken: - * * Attempt to load the chunk from disk. - * * If the chunk could not be loaded, generate it froms scratch - * Otherwise, the loaded chunk will be used - */ - public void scanWorldMap(int startingX, int startingZ, boolean setColors, boolean isFirstScan) + public void scanWorldMap(int startingX, int startingZ, boolean setColors) { Byte[][] map = _map.get(0); - for (int beginX = startingX; beginX < startingX + BLOCK_SCAN_INTERVAL; beginX += 16) + + for (int beginX = startingX; beginX < startingX + _blocksScan; beginX += 16) { - for (int beginZ = startingZ - (startingZ > -HALF_WORLD_SIZE ? 16 : 0); beginZ < startingZ - + (setColors ? BLOCK_SCAN_INTERVAL : 16); beginZ += 16) + for (int beginZ = startingZ - (startingZ > -_halfMapSize ? 16 : 0); beginZ < startingZ + + (setColors ? _blocksScan : 16); beginZ += 16) { - int chunkX = beginX / 16; - int chunkZ = beginZ / 16; - net.minecraft.server.v1_8_R3.Chunk nmsChunk = _chunkProviderServer.getChunkIfLoaded(chunkX, chunkZ); - if (nmsChunk == null) + Chunk chunk = _world.getChunkAt(beginX / 16, beginZ / 16); + boolean loaded = false; + + if (!chunk.isLoaded()) { - long key = LongHash.toLong(chunkX, chunkZ); - nmsChunk = _chunkCache.get(key); - if (nmsChunk == null) + if (_loadWorld) { - if (!isFirstScan) - { - continue; - } - try - { - Object[] data = _chunkRegionLoader.loadChunk(_nmsWorld, chunkX, chunkZ); - if (data == null) - { - // Something is wrong with the chunk - System.out.println("Chunk is not generated or missing level/block data. Regenerating (" + chunkX + "," + chunkZ + ")"); - nmsChunk = ((CraftChunk) _world.getChunkAt(chunkX, chunkZ)).getHandle(); - } - else - { - nmsChunk = (net.minecraft.server.v1_8_R3.Chunk) data[0]; - } - } - catch (IOException e) - { - throw new RuntimeException("Chunk is corrupt or not readable!", e); - } - _chunkCache.put(key, nmsChunk); + loaded = chunk.load(); + } + else + { + continue; } } - if (!nmsChunk.isEmpty()) - { - for (int x = beginX; x < beginX + 16; x++) - { - for (int z = beginZ; z < beginZ + 16; z++) - { - int color = 0; + net.minecraft.server.v1_8_R3.Chunk nmsChunk = ((CraftChunk) chunk).getHandle(); + for (int x = beginX; x < beginX + 16; x++) + { + for (int z = beginZ; z < beginZ + 16; z++) + { + int color = 0; + + if (!nmsChunk.isEmpty()) + { int k3 = x & 0xF; int l3 = z & 0xF; @@ -891,8 +850,7 @@ public class ItemMapManager extends MiniPlugin do { l4--; - _blockPosition.c(k3, l4, l3); - iblockdata = nmsChunk.getBlockData(_blockPosition); + iblockdata= nmsChunk.getBlockData(new BlockPosition(k3, l4, l3)); } while (iblockdata.getBlock().g(iblockdata) == MaterialMapColor.b && (l4 > 0)); @@ -902,30 +860,33 @@ public class ItemMapManager extends MiniPlugin Block block1; do { - _blockPosition.c(k3, j5--, l3); - block1 = nmsChunk.getType(_blockPosition); + block1 = nmsChunk.getType(new BlockPosition(k3, j5--, l3)); } while ((j5 > 0) && (block1.getMaterial().isLiquid())); } } - _heightMap[x + HALF_WORLD_SIZE + 16][z + HALF_WORLD_SIZE + 16] = l4; + _heightMap[x + _halfMapSize + 16][z + _halfMapSize + 16] = l4; if (setColors) { //color = block.f(i5).M; - _blockPosition.c(k3, l4, l3); - IBlockData data = nmsChunk.getBlockData(_blockPosition); + IBlockData data = nmsChunk.getBlockData(new BlockPosition(k3, l4, l3)); color = data.getBlock().g(data).M; color = (byte) ((color * 4) + 1); } - - if (setColors && beginZ >= startingZ) - { - map[x + HALF_WORLD_SIZE][z + HALF_WORLD_SIZE] = (byte) color; - } } + + if (setColors && beginZ >= startingZ) + { + map[x + _halfMapSize][z + _halfMapSize] = (byte) color; + } + } + + if (loaded) + { + chunk.unload(); } } } @@ -937,10 +898,10 @@ public class ItemMapManager extends MiniPlugin PlayerGetMapEvent event = UtilServer.CallEvent(new PlayerGetMapEvent(player)); if (event.isCancelled()) return; - + for (ItemStack item : UtilInv.getItems(player)) { - if (isItemClansMap(item)) + if (item.getType() == Material.MAP && (item.getDurability() >= _mapId && item.getDurability() <= _mapId + 100)) { return; } @@ -948,38 +909,62 @@ public class ItemMapManager extends MiniPlugin ItemStack item = new ItemBuilder(Material.MAP, 1, (short) getMap(player).getMap()).setTitle("Clans Map").build(); - int slot = CLANS_MAP_SLOT; - - ItemStack mapSlot = player.getInventory().getItem(slot); - if (mapSlot != null && mapSlot.getType() != Material.AIR) - { - slot = player.getInventory().firstEmpty(); - } + int slot = player.getInventory().firstEmpty(); if (slot >= 0) { + ItemStack mapSlot = player.getInventory().getItem(8); + + if (mapSlot == null || mapSlot.getType() == Material.AIR) + { + slot = 8; + } + player.getInventory().setItem(slot, item); } } - /* - * Displays the action bar to a player given their zoom level. Implementation may change - */ private void showZoom(Player player, MapInfo info) { - UtilTextBottom.display(ZOOM_INFO[info.getScale()], player); + String progressBar = C.cBlue + ""; + + boolean colorChange = false; + + for (int i = 2; i >= 0; i--) + { + if (!colorChange && i < info.getScale()) + { + progressBar += C.cGray; + colorChange = true; + } + + char c; + + switch (i) + { + case 0: + c = '█'; + break; + case 1: + c = '▆'; + break; + default: + c = '▄'; + break; + } + + for (int a = 0; a < 4; a++) + { + progressBar += c; + } + + if (i > 0) + { + progressBar += " "; + } + } + + UtilTextBottom.display(progressBar, player); } - /* - * Check whether an {@link ItemStack} is also a Clans Map - * - * @param itemStack The {@link ItemStack} to check - * @returns Whether the {@link ItemStack} is also a Clans Map - */ - private boolean isItemClansMap(ItemStack itemStack) - { - return UtilItem.matchesMaterial(itemStack, Material.MAP) - && itemStack.getDurability() >= _mapId - && itemStack.getDurability() <= _mapId + 100; - } } diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/map/ItemMapRenderer.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/map/ItemMapRenderer.java index 955249127..746f48e7e 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/map/ItemMapRenderer.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/map/ItemMapRenderer.java @@ -50,7 +50,7 @@ public class ItemMapRenderer extends MapRenderer // } // else // { - renderNormalMap(mapView, canvas, player); + renderNormalMap(mapView, canvas, player); // } } @@ -135,7 +135,7 @@ public class ItemMapRenderer extends MapRenderer if (_manager.getClansUtility().relPT(player, chunk) == ClansUtility.ClanRelation.SAFE) clanColor2 = new Color(50, 150, 255); } - else if (owningClan.getName().equals("Spawn")) + else if (owningClan.getName().equals("Spawn")) { clanColor = Color.WHITE; clanColor2 = new Color(0, 255, 100); diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/map/events/PlayerGetMapEvent.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/map/events/PlayerGetMapEvent.java index e13645b8a..5e5bccc4a 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/map/events/PlayerGetMapEvent.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/map/events/PlayerGetMapEvent.java @@ -4,9 +4,6 @@ import org.bukkit.entity.Player; import org.bukkit.event.Event; import org.bukkit.event.HandlerList; -/* - * This event is called when a Player is about to receive a Clans Map - */ public class PlayerGetMapEvent extends Event { private static final HandlerList handlers = new HandlerList(); diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/regions/ClansRegions.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/regions/ClansRegions.java index 6c9424634..797f63f24 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/regions/ClansRegions.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/regions/ClansRegions.java @@ -197,7 +197,18 @@ public class ClansRegions extends MiniPlugin { int x = chunkX + xOffset; int z = chunkZ + zOffset; - String chunkStr = location.getWorld().getName() + "," + x + "," + z; + Chunk chunk; + try + { //Corrupted chunk will hold up whole server + chunk = location.getWorld().getChunkAt(x, z); + } + catch(Exception e) + { + System.out.println("UNABLE TO LOAD CHUNK AT " + x + " , " + z); + e.printStackTrace(); + continue; + } + String chunkStr = UtilWorld.chunkToStr(chunk); if (addNegative) { diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/command/WorldEventCommand.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/command/WorldEventCommand.java index 7a830d9c6..73d55f096 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/command/WorldEventCommand.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/command/WorldEventCommand.java @@ -10,7 +10,7 @@ public class WorldEventCommand extends MultiCommandBase { public WorldEventCommand(WorldEventManager plugin) { - super(plugin, Rank.SNR_MODERATOR, "worldevent", "we", "event"); + super(plugin, Rank.ADMIN, "worldevent", "we", "event"); AddCommand(new StartCommand(Plugin)); AddCommand(new ClearCommand(Plugin)); diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/TutorialWorldManager.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/TutorialWorldManager.java index e6714847a..40ac68fc6 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/TutorialWorldManager.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/TutorialWorldManager.java @@ -2,7 +2,6 @@ package mineplex.game.clans.tutorial; import java.io.File; import java.io.IOException; -import java.util.LinkedList; import java.util.Stack; import org.bukkit.Bukkit; @@ -26,7 +25,7 @@ public class TutorialWorldManager extends MiniPlugin private final World _tutorialWorld; private final Schematic _schematic; - private LinkedList _regionStack; + private Stack _regionStack; private TutorialRegion _centerRegion; public TutorialWorldManager(JavaPlugin plugin, String worldName, String schematicName) throws IOException @@ -57,7 +56,7 @@ public class TutorialWorldManager extends MiniPlugin private void populateRegionStack() { - _regionStack = new LinkedList<>(); + _regionStack = new Stack<>(); // Populate the stack with 100 available tutorial regions for (int x = 0; x < 10; x++) diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/world/WorldManager.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/world/WorldManager.java index e6b7bf983..e302d1a26 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/world/WorldManager.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/world/WorldManager.java @@ -146,6 +146,9 @@ public class WorldManager extends MiniPlugin iterator.remove(); culled++; } - log("Culled " + culled + " " + type); + if (culled != 0) + { + log("Culled " + culled + " " + type); + } } } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java index d97b30e75..0df7f3c6b 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java @@ -535,16 +535,6 @@ public class HubManager extends MiniClientPlugin String rankName = _clientManager.Get(player).GetRank().Name; String otherRankName = _clientManager.Get(otherPlayer).GetRank().Name; - if (!_clientManager.Get(player).GetRank().has(Rank.ULTRA) && _donationManager.Get(player.getName()).OwnsUltraPackage()) - { - rankName = Rank.ULTRA.Name; - } - - if (!_clientManager.Get(otherPlayer).GetRank().has(Rank.ULTRA) && _donationManager.Get(otherPlayer.getName()).OwnsUltraPackage()) - { - otherRankName = Rank.ULTRA.Name; - } - //Add Other to Self board.getTeam(otherRankName).addPlayer(otherPlayer); diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/BillboardManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/BillboardManager.java index 0d60f7abb..adfa01b62 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/BillboardManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/BillboardManager.java @@ -31,7 +31,7 @@ public class BillboardManager extends MiniPlugin private void generateBoards() { - _branding.createPost(new Location(Bukkit.getWorld("world"), -6, 78, -35), BlockFace.SOUTH, "logitech.jpg"); + } @EventHandler diff --git a/Plugins/Mineplex.Minecraft.Game.ClassCombat/src/mineplex/minecraft/game/classcombat/Skill/Assassin/Leap.java b/Plugins/Mineplex.Minecraft.Game.ClassCombat/src/mineplex/minecraft/game/classcombat/Skill/Assassin/Leap.java index f1dcbb780..06bdda17a 100644 --- a/Plugins/Mineplex.Minecraft.Game.ClassCombat/src/mineplex/minecraft/game/classcombat/Skill/Assassin/Leap.java +++ b/Plugins/Mineplex.Minecraft.Game.ClassCombat/src/mineplex/minecraft/game/classcombat/Skill/Assassin/Leap.java @@ -78,7 +78,7 @@ public class Leap extends SkillActive { //Action if (!wallkick) - UtilAction.velocity(player, 1 + 0.15 * level, 0.2, 1, true); + UtilAction.velocity(player, 1.2, 0.2, 1, true); else { Vector vec = player.getLocation().getDirection(); diff --git a/Plugins/Mineplex.Minecraft.Game.ClassCombat/src/mineplex/minecraft/game/classcombat/Skill/Mage/FissureData.java b/Plugins/Mineplex.Minecraft.Game.ClassCombat/src/mineplex/minecraft/game/classcombat/Skill/Mage/FissureData.java index 45833b8d1..8fd59a6d1 100644 --- a/Plugins/Mineplex.Minecraft.Game.ClassCombat/src/mineplex/minecraft/game/classcombat/Skill/Mage/FissureData.java +++ b/Plugins/Mineplex.Minecraft.Game.ClassCombat/src/mineplex/minecraft/game/classcombat/Skill/Mage/FissureData.java @@ -8,6 +8,8 @@ import mineplex.core.common.util.UtilBlock; import mineplex.core.common.util.UtilMath; import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.minecraft.game.classcombat.Skill.Mage.events.FissureModifyBlockEvent; import org.bukkit.Effect; import org.bukkit.Location; import org.bukkit.block.Block; @@ -122,6 +124,11 @@ public class FissureData { return false; } + FissureModifyBlockEvent event = UtilServer.CallEvent(new FissureModifyBlockEvent(block)); + if (event.isCancelled()) + { + return false; + } if (block.getType().toString().contains("BANNER")) return false; if (block.getRelative(BlockFace.UP).getType().toString().contains("BANNER")) diff --git a/Plugins/Mineplex.Minecraft.Game.ClassCombat/src/mineplex/minecraft/game/classcombat/Skill/Mage/events/FissureModifyBlockEvent.java b/Plugins/Mineplex.Minecraft.Game.ClassCombat/src/mineplex/minecraft/game/classcombat/Skill/Mage/events/FissureModifyBlockEvent.java new file mode 100644 index 000000000..fe34bd51e --- /dev/null +++ b/Plugins/Mineplex.Minecraft.Game.ClassCombat/src/mineplex/minecraft/game/classcombat/Skill/Mage/events/FissureModifyBlockEvent.java @@ -0,0 +1,46 @@ +package mineplex.minecraft.game.classcombat.Skill.Mage.events; + +import org.bukkit.block.Block; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +public class FissureModifyBlockEvent extends Event implements Cancellable +{ + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private final Block _targetBlock; + + private boolean _cancelled; + + public FissureModifyBlockEvent(Block targetBlock) + { + this._targetBlock = targetBlock; + } + + public boolean isCancelled() + { + return this._cancelled; + } + + public void setCancelled(boolean cancelled) + { + this._cancelled = cancelled; + } + + public Block getTargetBlock() + { + return this._targetBlock; + } + + @Override + public HandlerList getHandlers() + { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() + { + return HANDLER_LIST; + } +} diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/speedbuilders/SpeedBuilders.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/speedbuilders/SpeedBuilders.java index c890be418..da4406b2c 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/speedbuilders/SpeedBuilders.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/speedbuilders/SpeedBuilders.java @@ -182,9 +182,6 @@ public class SpeedBuilders extends SoloGame InventoryClick = true; - manager.getBrandingManager().reset(); - manager.getBrandingManager().createPost(new Location(Bukkit.getWorld("world"), 17, 103, -11), BlockFace.WEST, "logitech.jpg"); - registerStatTrackers( new DependableTracker(this), new FirstBuildTracker(this),