diff --git a/Plugins/Mineplex.Core/src/mineplex/core/chat/Chat.java b/Plugins/Mineplex.Core/src/mineplex/core/chat/Chat.java index ffbafc0b6..fcdb2aafa 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/chat/Chat.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/chat/Chat.java @@ -337,7 +337,7 @@ public class Chat extends MiniPlugin !Recharge.Instance.use(sender, "All Chat Message", 3000, false, false)) { UtilPlayer.message(sender, C.cYellow + "You can only chat once every 3 seconds to prevent spam."); - UtilPlayer.message(sender, C.cYellow + "FREE $5 Gift Card with code " + C.cGreen + "Mineplex5 " + C.cYellow + "on any rank " + C.cGreen + "http://goo.gl/z7bOh2 !"); + UtilPlayer.message(sender, C.cYellow + "Buy a Rank at " + C.cGreen + "www.mineplex.com/shop" + C.cYellow + " to remove this limit!"); event.setCancelled(true); } else if (!_clientManager.Get(sender).GetRank().has(Rank.MODERATOR) && diff --git a/Plugins/Mineplex.Core/src/mineplex/core/database/PlayerKeyValueRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/database/PlayerKeyValueRepository.java index 9325679ae..3ea3adda9 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/database/PlayerKeyValueRepository.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/database/PlayerKeyValueRepository.java @@ -4,11 +4,15 @@ 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 @@ -110,7 +114,7 @@ public class PlayerKeyValueRepository } catch (SQLException e) { - throw new RuntimeException(e); + throw new CompletionException(e); } }); } @@ -141,7 +145,7 @@ public class PlayerKeyValueRepository } catch (SQLException e) { - throw new RuntimeException(e); + throw new CompletionException(e); } }); } @@ -155,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(() -> { @@ -166,12 +170,12 @@ public class PlayerKeyValueRepository _mapper._serializer.write(stmt, 2, value); stmt.setString(3, uuid.toString()); stmt.executeUpdate(); - return true; + return null; } catch (SQLException e) { - throw new RuntimeException(e); + throw new CompletionException(e); } }); } @@ -206,7 +210,7 @@ public class PlayerKeyValueRepository } catch (SQLException e) { - throw new RuntimeException(e); + throw new CompletionException(e); } }); } @@ -219,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(() -> { @@ -229,12 +233,12 @@ public class PlayerKeyValueRepository stmt.setString(1, uuid.toString()); stmt.setString(2, key); stmt.executeUpdate(); - return true; + return null; } catch (SQLException e) { - throw new RuntimeException(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,12 +259,12 @@ 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 e) { - throw new RuntimeException(e); + throw new CompletionException(e); } }); } 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.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/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++)