Merge branch 'project-cosmetics' of https://github.com/Mineplex-LLC/Minecraft-PC into project-cosmetics

This commit is contained in:
LCastr0 2016-05-25 12:20:18 -03:00
commit e52ff13712
54 changed files with 1929 additions and 859 deletions

View File

@ -0,0 +1,111 @@
package mineplex.core.common.util;
import org.bukkit.Bukkit;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
/**
* Utilities for interleaving Bukkit scheduler operations as
* intermediate and terminal operations in a {@link CompletionStage}
* pipeline.
* <p>
* Any {@link Function}s returned by methods are suitable for use
* in {@link CompletionStage#thenCompose(Function)}
*
* @see CompletableFuture#thenCompose(Function)
*/
public class BukkitFuture
{
private static final Plugin LOADING_PLUGIN = JavaPlugin.getProvidingPlugin(BukkitFuture.class);
private static void runBlocking(Runnable action)
{
Bukkit.getScheduler().runTask(LOADING_PLUGIN, action);
}
/**
* Finalize a {@link CompletionStage} by consuming its value
* on the main thread.
*
* @param action the {@link Consumer} to call on the main thread
* @return a {@link Function} to be passed as an argument to
* {@link CompletionStage#thenCompose(Function)}
* @see CompletableFuture#thenCompose(Function)
*/
public static <T> Function<T, CompletionStage<Void>> accept(Consumer<? super T> action)
{
return val ->
{
CompletableFuture<Void> future = new CompletableFuture<>();
runBlocking(() ->
{
action.accept(val);
future.complete(null);
});
return future;
};
}
/**
* Finalize a {@link CompletionStage} by executing code on the
* main thread after its completion.
*
* @param action the {@link Runnable} that will execute
* @return a {@link Function} to be passed as an argument to
* {@link CompletionStage#thenCompose(Function)}
* @see CompletableFuture#thenCompose(Function)
*/
public static <T> Function<T, CompletionStage<Void>> run(Runnable action)
{
return val ->
{
CompletableFuture<Void> future = new CompletableFuture<>();
runBlocking(() ->
{
action.run();
future.complete(null);
});
return future;
};
}
/**
* Transform a value contained within a {@link CompletionStage}
* by executing a mapping {@link Function} on the main thread.
*
* @param fn the {@link Function} used to transform the value
* @return a {@link Function} to be passed as an argument to
* {@link CompletionStage#thenCompose(Function)}
* @see CompletableFuture#thenCompose(Function)
*/
public static <T,U> Function<T, CompletionStage<U>> map(Function<? super T,? extends U> fn)
{
return val ->
{
CompletableFuture<U> future = new CompletableFuture<>();
runBlocking(() -> future.complete(fn.apply(val)));
return future;
};
}
/**
* Create a {@link CompletionStage} from a supplier executed on the
* main thread.
*
* @param supplier the supplier to run on the main thread
* @return a {@link CompletionStage} whose value will be supplied
* during the next Minecraft tick
*/
public static <T> CompletionStage<T> supply(Supplier<T> supplier)
{
CompletableFuture<T> future = new CompletableFuture<>();
runBlocking(() -> future.complete(supplier.get()));
return future;
}
}

View File

@ -10,6 +10,8 @@ import org.bukkit.World.Environment;
import org.bukkit.WorldBorder; import org.bukkit.WorldBorder;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.BlockFace; import org.bukkit.block.BlockFace;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity;
import org.bukkit.entity.Entity;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
@ -28,7 +30,12 @@ public class UtilWorld
if (chunk == null) if (chunk == null)
return ""; return "";
return chunk.getWorld().getName() + "," + chunk.getX() + "," + chunk.getZ(); return chunkToStr(chunk.getWorld().getName(), chunk.getX(), chunk.getZ());
}
public static String chunkToStr(String world, int x, int z)
{
return world + "," + x + "," + z;
} }
public static String chunkToStrClean(Chunk chunk) public static String chunkToStrClean(Chunk chunk)
@ -289,4 +296,15 @@ public class UtilWorld
return startX >= minX && startZ <= maxX && endX >= minZ && endZ <= maxZ; return startX >= minX && startZ <= maxX && endX >= minZ && endZ <= maxZ;
} }
public static double distanceSquared(Entity a, Entity b)
{
if (a.getWorld() != b.getWorld())
throw new IllegalArgumentException("Different worlds: " + a.getWorld().getName() + " and " + b.getWorld().getName());
net.minecraft.server.v1_8_R3.Entity entityA = ((CraftEntity) a).getHandle();
net.minecraft.server.v1_8_R3.Entity entityB = ((CraftEntity) b).getHandle();
double dx = entityA.locX - entityB.locX;
double dy = entityA.locY - entityB.locY;
double dz = entityA.locZ - entityB.locZ;
return (dx * dx) + (dy * dy) + (dz * dz);
}
} }

View File

@ -491,7 +491,7 @@ public class CoreClientManager extends MiniPlugin
} }
} }
@EventHandler(priority = EventPriority.HIGHEST) @EventHandler(priority = EventPriority.MONITOR)
public void Quit(PlayerQuitEvent event) public void Quit(PlayerQuitEvent event)
{ {
// When an account is logged in to this server and the same account name logs in // When an account is logged in to this server and the same account name logs in

View File

@ -103,6 +103,11 @@ public class Creature extends MiniPlugin
event.setDroppedExp(0); event.setDroppedExp(0);
List<ItemStack> drops = event.getDrops(); List<ItemStack> drops = event.getDrops();
if (event.getEntity().hasMetadata("Creature.DoNotDrop"))
{
drops.clear();
return;
}
if (event.getEntityType() == EntityType.PLAYER) if (event.getEntityType() == EntityType.PLAYER)
drops.add(ItemStackFactory.Instance.CreateStack(Material.BONE, 1)); drops.add(ItemStackFactory.Instance.CreateStack(Material.BONE, 1));

View File

@ -0,0 +1,291 @@
package mineplex.core.database;
import com.google.common.collect.ImmutableMap;
import mineplex.serverdata.database.DBPool;
import java.sql.*;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
/**
* A SQL-backed repository supporting {@link String} keys and
* values of type {@link V}
* <p>
* Each java primitive (sans char) and String are supported by default.
* Serializing functions for any additional types can be supplied
* to {@link PlayerKeyValueRepository(String, Serializer, Deserializer)}.
* For example, if {@link String} was not supported, one could use:
* <p>
* {@code new PlayerKeyValueRepository("tableName", PreparedStatement::setString, ResultSet::getString, "VARCHAR(255)")}
* <p>
* NOTE: EACH CONSTRUCTOR IS BLOCKING, and initializes a backing table
* if one does not yet exist
*
* @param <V> The value type to use for this repository
*/
public class PlayerKeyValueRepository<V>
{
private static final ImmutableMap<Class<?>, ValueMapper<?>> PRIM_MAPPERS = ImmutableMap.<Class<?>, 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"))
.build();
private final String _tableName;
private final ValueMapper<V> _mapper;
/**
* Build a PlayerKeyValueRepository with the given class'
* built-in deserializer.
*
* @param tableName the underlying table's name
* @param clazz the type of values to used
* @throws IllegalArgumentException if the provided class isn't a supported type
*/
@SuppressWarnings("unchecked") // java's generics are garbage.
public PlayerKeyValueRepository(String tableName, Class<V> clazz) // we could infer the type parameter at runtime, but it's super ugly
{
this(tableName, (ValueMapper<V>) PRIM_MAPPERS.get(clazz));
}
/**
* Build a PlayerKeyValueRepository with an explicit deserializer.
* This is the constructor to use if the type you're deserializing
* isn't supported by default.
*
* @param tableName the underlying table's name
* @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<V> serializer, Deserializer<V> deserializer, String columnDef)
{
this(tableName, new ValueMapper<V>(serializer, deserializer, columnDef));
}
private PlayerKeyValueRepository(String tableName, ValueMapper<V> mapper)
{
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();
}
}
/**
* Get all value for a player's key
*
* @param uuid the {@link UUID} of the player
* @return a CompletableFuture containing all key/value pairs
* associated with the player
*/
public CompletableFuture<V> get(UUID uuid, String key)
{
return CompletableFuture.supplyAsync(() ->
{
try (Connection conn = DBPool.getAccount().getConnection())
{
PreparedStatement stmt = conn.prepareStatement("SELECT kvValue FROM " + _tableName + " WHERE accountId = (SELECT id FROM accounts WHERE uuid=?) AND kvKey=?");
stmt.setString(1, uuid.toString());
stmt.setString(2, key);
ResultSet set = stmt.executeQuery();
if (set.next())
{
return _mapper._deserializer.read(set, 1);
}
return null;
} catch (SQLException ignored) {}
return null; // yuck
});
}
/**
* Get all key/value pairs for a player
*
* @param uuid the {@link UUID} of the player
* @return a CompletableFuture containing all key/value pairs
* associated with the player
*/
public CompletableFuture<Map<String,V>> getAll(UUID uuid)
{
return CompletableFuture.supplyAsync(() ->
{
try (Connection conn = DBPool.getAccount().getConnection())
{
PreparedStatement stmt = conn.prepareStatement("SELECT kvKey, kvValue FROM " + _tableName + " WHERE accountId = (SELECT id FROM accounts WHERE uuid=?)");
stmt.setString(1, uuid.toString());
ResultSet set = stmt.executeQuery();
Map<String, V> results = new HashMap<>();
while (set.next())
{
results.put(set.getString(1), _mapper._deserializer.read(set, 2));
}
return results;
} catch (SQLException ignored) {}
return new HashMap<>(); // yuck
});
}
/**
* Insert a key/value pair for a player
*
* @param uuid the {@link UUID} of the player
* @param key the key to insert
* @param value the value to insert
* @return a {@link CompletableFuture} whose value indicates
* success or failure
*/
public CompletableFuture<Boolean> put(UUID uuid, String key, V value)
{
return CompletableFuture.supplyAsync(() ->
{
try (Connection conn = DBPool.getAccount().getConnection())
{
PreparedStatement stmt = conn.prepareStatement("REPLACE INTO " + _tableName + " (accountId, kvKey, kvValue) SELECT accounts.id, ?, ? FROM accounts WHERE uuid=?");
stmt.setString(1, key);
_mapper._serializer.write(stmt, 2, value);
stmt.setString(3, uuid.toString());
stmt.executeUpdate();
return true;
} catch (SQLException ignored) {}
return false;
});
}
/**
* Insert many key/value pairs for a player
*
* @param uuid the {@link UUID} of the player
* @param values the map whose entries will be inserted for the
* player
* @return a {@link CompletableFuture} whose value indicates
* success or failure
*/
public CompletableFuture<Boolean> putAll(UUID uuid, Map<String,V> values)
{
return CompletableFuture.supplyAsync(() ->
{
try (Connection conn = DBPool.getAccount().getConnection())
{
PreparedStatement stmt = conn.prepareStatement("REPLACE INTO " + _tableName + " (accountId, kvKey, kvValue) SELECT accounts.id, ?, ? FROM accounts WHERE uuid=?");
stmt.setString(3, uuid.toString());
for (Map.Entry<String, V> entry : values.entrySet())
{
stmt.setString(1, entry.getKey());
_mapper._serializer.write(stmt, 2, entry.getValue());
stmt.addBatch();
}
stmt.executeBatch();
return true;
} catch (SQLException ignored) {}
return false;
});
}
/**
* Remove a key's value for a player
*
* @param uuid the {@link UUID} of the player
* @param key the key to remove
* @return a {@link CompletableFuture} whose value indicates
* success or failure
*/
public CompletableFuture<Boolean> remove(UUID uuid, String key)
{
return CompletableFuture.supplyAsync(() ->
{
try (Connection conn = DBPool.getAccount().getConnection())
{
PreparedStatement stmt = conn.prepareStatement("DELETE FROM " + _tableName + " WHERE accountId=(SELECT id FROM accounts WHERE uuid=?) AND kvKey=?");
stmt.setString(1, uuid.toString());
stmt.setString(2, key);
stmt.executeUpdate();
return true;
} catch (SQLException ignored) {}
return false;
});
}
/**
* Remove all key/value pairs for a player
*
* @param uuid the {@link UUID} of the player
* @return a {@link CompletableFuture} whose value indicates
* success or failure
*/
public CompletableFuture<Boolean> removeAll(UUID uuid)
{
return CompletableFuture.supplyAsync(() ->
{
try (Connection conn = DBPool.getAccount().getConnection())
{
PreparedStatement stmt = conn.prepareStatement("DELETE FROM " + _tableName + " WHERE accountId=(SELECT id FROM accounts WHERE uuid=?)");
stmt.setString(1, uuid.toString());
stmt.executeUpdate();
return true;
} catch (SQLException ignored) {}
return false;
});
}
private static class ValueMapper<V>
{
private final Serializer<V> _serializer;
private final Deserializer<V> _deserializer;
private final String _columnDef;
private ValueMapper(Serializer<V> serializer, Deserializer<V> deserializer, String columnDef)
{
_serializer = serializer;
_deserializer = deserializer;
_columnDef = columnDef;
}
}
@FunctionalInterface
public interface Serializer<V>
{
void write(PreparedStatement statement, int index, V value) throws SQLException;
}
@FunctionalInterface
public interface Deserializer<V>
{
V read(ResultSet resultSet, int index) throws SQLException;
}
}

View File

@ -1,47 +0,0 @@
package mineplex.core.incognito.events;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
/**
* Called when an Incognito player is getting hidden from all other players.
*/
public class IncognitoHidePlayerEvent extends Event
{
private static final HandlerList handlers = new HandlerList();
private Player _player;
private boolean _cancelled;
public IncognitoHidePlayerEvent(Player player)
{
_player = player;
}
public Player getPlayer()
{
return _player;
}
public void setCancelled(boolean cancelled)
{
_cancelled = cancelled;
}
public boolean isCancelled()
{
return _cancelled;
}
public HandlerList getHandlers()
{
return handlers;
}
public static HandlerList getHandlerList()
{
return handlers;
}
}

View File

@ -1,73 +1,72 @@
package mineplex.game.clans; package mineplex.game.clans;
import com.google.common.collect.Sets;
import mineplex.core.MiniPlugin; import mineplex.core.MiniPlugin;
import mineplex.core.common.util.UtilItem;
import mineplex.core.itemstack.ItemStackFactory; import mineplex.core.itemstack.ItemStackFactory;
import mineplex.core.common.util.F; import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer; import mineplex.core.common.util.UtilPlayer;
import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import java.util.Set;
public class Farming extends MiniPlugin public class Farming extends MiniPlugin
{ {
private static final Set<Material> PLANTABLE = Sets.newHashSet(
Material.WHEAT,
Material.SUGAR_CANE_BLOCK,
Material.PUMPKIN_STEM,
Material.MELON_STEM,
Material.COCOA,
Material.CARROT,
Material.POTATO
);
public Farming(JavaPlugin plugin) public Farming(JavaPlugin plugin)
{ {
super("Farming", plugin); super("Farming", plugin);
} }
@EventHandler @EventHandler (ignoreCancelled = true)
public void BlockBreak(BlockBreakEvent event) public void BlockBreak(BlockBreakEvent event)
{ {
if (event.isCancelled())
return;
if (event.getBlock().getType() != Material.LEAVES) if (event.getBlock().getType() != Material.LEAVES)
return; return;
if (event.getPlayer().getItemInHand() != null) if (UtilItem.matchesMaterial(event.getPlayer().getItemInHand(), Material.SHEARS))
if (event.getPlayer().getItemInHand().getType() == Material.SHEARS)
return; return;
Location dropLocation = event.getBlock().getLocation().add(0.5, 0.5, 0.5);
if (Math.random() > 0.9) if (Math.random() > 0.9)
event.getBlock().getWorld().dropItemNaturally( event.getBlock().getWorld().dropItemNaturally(dropLocation, ItemStackFactory.Instance.CreateStack(Material.APPLE));
event.getBlock().getLocation().add(0.5, 0.5, 0.5),
ItemStackFactory.Instance.CreateStack(Material.APPLE));
if (Math.random() > 0.999) if (Math.random() > 0.999)
event.getBlock().getWorld().dropItemNaturally( event.getBlock().getWorld().dropItemNaturally(dropLocation, ItemStackFactory.Instance.CreateStack(Material.GOLDEN_APPLE));
event.getBlock().getLocation().add(0.5, 0.5, 0.5),
ItemStackFactory.Instance.CreateStack(Material.GOLDEN_APPLE));
} }
@SuppressWarnings("deprecation") @EventHandler (ignoreCancelled = true)
@EventHandler
public void BlockPlace(BlockPlaceEvent event) public void BlockPlace(BlockPlaceEvent event)
{ {
if (event.isCancelled()) if (!PLANTABLE.contains(event.getBlock().getType()))
return; return;
if ( double blockY = event.getBlock().getLocation().getY();
event.getBlock().getTypeId() != 59 && double seaLevel = event.getBlock().getWorld().getSeaLevel();
event.getBlock().getTypeId() != 83 &&
event.getBlock().getTypeId() != 104 &&
event.getBlock().getTypeId() != 105 &&
event.getBlock().getTypeId() != 127 &&
event.getBlock().getTypeId() != 141 &&
event.getBlock().getTypeId() != 142
)
return;
if (event.getBlock().getLocation().getY() < event.getBlock().getWorld().getSeaLevel() - 12) if (blockY < seaLevel - 12)
{ {
UtilPlayer.message(event.getPlayer(), F.main(getName(), "You cannot plant " + UtilPlayer.message(event.getPlayer(), F.main(getName(), "You cannot plant " +
F.item(ItemStackFactory.Instance.GetName(event.getPlayer().getItemInHand(), true)) + " this deep underground.")); F.item(ItemStackFactory.Instance.GetName(event.getPlayer().getItemInHand(), true)) + " this deep underground."));
event.setCancelled(true); event.setCancelled(true);
} }
else if (blockY > seaLevel + 24)
else if (event.getBlock().getLocation().getY() > event.getBlock().getWorld().getSeaLevel() + 24)
{ {
UtilPlayer.message(event.getPlayer(), F.main(getName(), "You cannot plant " + UtilPlayer.message(event.getPlayer(), F.main(getName(), "You cannot plant " +
F.item(ItemStackFactory.Instance.GetName(event.getPlayer().getItemInHand(), true)) + " at this altitude.")); F.item(ItemStackFactory.Instance.GetName(event.getPlayer().getItemInHand(), true)) + " at this altitude."));

View File

@ -114,7 +114,6 @@ public class ClansAdmin
UtilPlayer.message(caller, F.help("/c x demote <player>", "Demote Player in Mimic", Rank.CMOD)); UtilPlayer.message(caller, F.help("/c x demote <player>", "Demote Player in Mimic", Rank.CMOD));
UtilPlayer.message(caller, F.help("/c x kick <player>", "Kick Player from Mimic", Rank.CMOD)); UtilPlayer.message(caller, F.help("/c x kick <player>", "Kick Player from Mimic", Rank.CMOD));
UtilPlayer.message(caller, F.help("/c x ally <clan>", "Send Alliance to Mimic", Rank.CMOD)); UtilPlayer.message(caller, F.help("/c x ally <clan>", "Send Alliance to Mimic", Rank.CMOD));
UtilPlayer.message(caller, F.help("/c x trust <clan>", "Give Trust to Clan", Rank.CMOD));
UtilPlayer.message(caller, F.help("/c x neutral <clan>", "Set Neutrality", Rank.CMOD)); UtilPlayer.message(caller, F.help("/c x neutral <clan>", "Set Neutrality", Rank.CMOD));
UtilPlayer.message(caller, F.help("/c x enemy <clan>", "Start Invasion", Rank.CMOD)); UtilPlayer.message(caller, F.help("/c x enemy <clan>", "Start Invasion", Rank.CMOD));
UtilPlayer.message(caller, F.help("/c x rename <name>", "Change the name of Mimic", Rank.CMOD)); UtilPlayer.message(caller, F.help("/c x rename <name>", "Change the name of Mimic", Rank.CMOD));
@ -379,12 +378,6 @@ public class ClansAdmin
if (target == null) if (target == null)
return; return;
if (target.getName().equals(caller.getName()))
{
UtilPlayer.message(caller, F.main("Clans Admin", "You cannot invite yourself."));
return;
}
//Inform //Inform
clan.inform(caller.getName() + " invited " + target.getName() + " to join Clan " + clan.getName() + ".", caller.getName()); clan.inform(caller.getName() + " invited " + target.getName() + " to join Clan " + clan.getName() + ".", caller.getName());
UtilPlayer.message(caller, F.main("Clans Admin", "You invited " + target.getName() + " to join " + F.elem("Clan " + clan.getName()) + ".")); UtilPlayer.message(caller, F.main("Clans Admin", "You invited " + target.getName() + " to join " + F.elem("Clan " + clan.getName()) + "."));

View File

@ -304,15 +304,39 @@ public class ClansGame extends MiniPlugin
return; return;
} }
// Banners/String
if (player.getGameMode() != GameMode.CREATIVE && player.getItemInHand() != null)
{
if (player.getItemInHand().getType() == Material.BANNER || player.getItemInHand().getType() == Material.STRING)
{
Location destLocation = event.getClickedBlock().getRelative(event.getBlockFace()).getLocation();
ClanTerritory territory = _clans.getClanUtility().getClaim(destLocation);
if (territory != null)
{
if (territory.Owner.equals("Shops") || territory.Owner.equals("Fields") || territory.Owner.equals("Spawn") || territory.Owner.equals("Borderlands")) {
// Disallow
event.setCancelled(true);
// Inform
UtilPlayer.message(player, F.main("Clans", "You cannot place that in " + F.elem(_clans.getClanUtility().getOwnerStringRel(destLocation, player)) + "."));
return;
}
}
}
}
ClanRelation access = _clans.getClanUtility().getAccess(player, loc); ClanRelation access = _clans.getClanUtility().getAccess(player, loc);
ClanInfo clan = _clans.getClan(player); 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); ClanInfo blockClan = _clans.getClanUtility().getClaim(loc) == null ? null : _clans.getClan(_clans.getClanUtility().getClaim(loc).Owner);
if (blockClan.equals(mimicClan)) access = ClanRelation.SELF;
// Doors, chests, & furnaces // Doors, chests, & furnaces
if (blockClan != null && !blockClan.equals(clan) && (event.getAction() == Action.RIGHT_CLICK_BLOCK && (loc.getBlock().getType().name().contains("DOOR") || UtilItem.doesHaveGUI(loc.getBlock().getType())))) 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()))))
{ {
UtilPlayer.message(player, F.main("Clans", "You are not allowed to use that here.")); UtilPlayer.message(player, F.main("Clans", "You are not allowed to use that here."));
event.setCancelled(true); event.setCancelled(true);
return;
} }
// Hoe Return // Hoe Return

View File

@ -44,7 +44,7 @@ import mineplex.game.clans.clans.commands.*;
import mineplex.game.clans.clans.data.PlayerClan; import mineplex.game.clans.clans.data.PlayerClan;
import mineplex.game.clans.clans.event.ClansPlayerDeathEvent; import mineplex.game.clans.clans.event.ClansPlayerDeathEvent;
import mineplex.game.clans.clans.gui.ClanShop; import mineplex.game.clans.clans.gui.ClanShop;
import mineplex.game.clans.clans.invsee.Invsee; import mineplex.game.clans.clans.invsee.InvseeManager;
import mineplex.game.clans.clans.loot.LootManager; import mineplex.game.clans.clans.loot.LootManager;
import mineplex.game.clans.clans.map.ItemMapManager; import mineplex.game.clans.clans.map.ItemMapManager;
import mineplex.game.clans.clans.nameblacklist.ClansBlacklist; import mineplex.game.clans.clans.nameblacklist.ClansBlacklist;
@ -260,7 +260,7 @@ public class ClansManager extends MiniClientPlugin<ClientClan>implements IRelati
new TntGeneratorManager(plugin, this); new TntGeneratorManager(plugin, this);
new SupplyDropManager(plugin, this); new SupplyDropManager(plugin, this);
new Invsee(this); new InvseeManager(this);
_explosion = new Explosion(plugin, blockRestore); _explosion = new Explosion(plugin, blockRestore);
_warPointEvasion = new WarPointEvasion(plugin); _warPointEvasion = new WarPointEvasion(plugin);
@ -556,19 +556,6 @@ public class ClansManager extends MiniClientPlugin<ClientClan>implements IRelati
} }
} }
@EventHandler
public void onPlayerKick(PlayerKickEvent event)
{
// Players using wind blade should not get kicked
if (event.getPlayer().getItemInHand() != null && event.getPlayer().getItemInHand().getItemMeta() != null && (C.cGold + "Wind Blade").equals(event.getPlayer().getItemInHand().getItemMeta().getDisplayName()))
{
if (event.getReason().contains("flying is not enabled"))
{
event.setCancelled(true);
}
}
}
@EventHandler @EventHandler
public void StaffIncognito(IncognitoStatusChangeEvent event) public void StaffIncognito(IncognitoStatusChangeEvent event)
{ {
@ -1175,7 +1162,7 @@ public class ClansManager extends MiniClientPlugin<ClientClan>implements IRelati
@EventHandler @EventHandler
public void hubCommand(PlayerCommandPreprocessEvent event) public void hubCommand(PlayerCommandPreprocessEvent event)
{ {
if (event.getMessage().toLowerCase().startsWith("/lobby") || event.getMessage().toLowerCase().startsWith("/hub") || event.getMessage().toLowerCase().startsWith("/leave")) if (event.getMessage().toLowerCase().equals("/lobby") || event.getMessage().toLowerCase().equals("/hub") || event.getMessage().toLowerCase().equals("/leave"))
{ {
Portal.getInstance().sendPlayerToServer(event.getPlayer(), "Lobby"); Portal.getInstance().sendPlayerToServer(event.getPlayer(), "Lobby");
event.setCancelled(true); event.setCancelled(true);

View File

@ -4,6 +4,7 @@ import java.util.ArrayList;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.stream.Collectors;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.Chunk; import org.bukkit.Chunk;
@ -28,6 +29,11 @@ import mineplex.game.clans.spawn.Spawn;
public class ClansUtility public class ClansUtility
{ {
// The maximum number of clans to search before exiting early. Inclusive
private static final int MAX_CLAN_SEARCH = 10;
// The maximum number of players to search before exiting early. Inclusive
private static final int MAX_PLAYER_SEARCH = 10;
private ClansManager _clansManager; private ClansManager _clansManager;
public ClansUtility(ClansManager clans) public ClansUtility(ClansManager clans)
@ -113,55 +119,79 @@ public class ClansUtility
public ClanInfo searchClanPlayer(Player caller, String name, boolean inform) public ClanInfo searchClanPlayer(Player caller, String name, boolean inform)
{ {
// CLAN // CLAN
LinkedList<ClanInfo> clanMatchList = new LinkedList<ClanInfo>(); List<ClanInfo> clanMatchList = new ArrayList<>(MAX_CLAN_SEARCH);
for (ClanInfo cur : _clansManager.getClanMap().values()) for (ClanInfo cur : _clansManager.getClanMap().values())
{ {
if (cur.getName().equalsIgnoreCase(name)) return cur; if (cur.getName().equalsIgnoreCase(name)) return cur;
if (cur.getName().toLowerCase().contains(name.toLowerCase())) clanMatchList.add(cur); if (cur.getName().toLowerCase().contains(name.toLowerCase())) clanMatchList.add(cur);
if (clanMatchList.size() > MAX_CLAN_SEARCH) break;
} }
if (clanMatchList.size() == 1) return clanMatchList.get(0); if (clanMatchList.size() == 1) return clanMatchList.get(0);
// No / Non-Unique
String clanMatchString = "None";
if (clanMatchList.size() > 1)
{
for (ClanInfo cur : clanMatchList)
clanMatchString += cur.getName() + " ";
}
// PLAYER // PLAYER
LinkedList<ClanInfo> playerMatchList = new LinkedList<ClanInfo>(); List<ClanInfo> playerMatchList = new ArrayList<>(MAX_PLAYER_SEARCH);
for (ClanInfo clanInfo : _clansManager.getClanMap().values()) outer: for (ClanInfo clanInfo : _clansManager.getClanMap().values())
{ {
for (ClansPlayer player : clanInfo.getMembers().values()) for (ClansPlayer player : clanInfo.getMembers().values())
{ {
if (player.getPlayerName().equalsIgnoreCase(name)) return clanInfo; if (player.getPlayerName().equalsIgnoreCase(name)) return clanInfo;
if (player.getPlayerName().toLowerCase().contains(name.toLowerCase())) playerMatchList.add(clanInfo); if (player.getPlayerName().toLowerCase().contains(name.toLowerCase()))
{
playerMatchList.add(clanInfo);
// No duplicate results please
continue outer;
}
if (playerMatchList.size() > MAX_PLAYER_SEARCH) break outer;
} }
} }
if (playerMatchList.size() == 1) return playerMatchList.get(0); if (playerMatchList.size() == 1) return playerMatchList.get(0);
// No / Non-Unique
String playerMatchString = "None";
if (playerMatchList.size() > 1)
{
for (ClanInfo cur : playerMatchList)
playerMatchString += cur.getName() + " ";
}
if (inform) if (inform)
{ {
UtilPlayer.message(caller, F.main("Clan Search", "" + C.mCount + (clanMatchList.size() + playerMatchList.size()) + C.mBody + " matches for [" + C.mElem + name + C.mBody + "].")); UtilPlayer.message(caller, F.main("Clan Search", "" + C.mCount + (clanMatchList.size() + playerMatchList.size()) + C.mBody + " matches for [" + C.mElem + name + C.mBody + "]."));
UtilPlayer.message(caller, F.desc("Matches via Clan", clanMatchString)); if (clanMatchList.size() > MAX_CLAN_SEARCH)
UtilPlayer.message(caller, F.desc("Matches via Player", playerMatchString)); {
UtilPlayer.message(caller, F.main("Clan Search", "Too many clans matched. Try a more specific search"));
}
else if (clanMatchList.size() == 0)
{
UtilPlayer.message(caller, F.main("Clan Search", "No clans matched. Try a more specific search"));
}
else
{
StringBuilder clanMatchString = new StringBuilder();
for (ClanInfo clanInfo : clanMatchList)
{
clanMatchString.append(clanInfo.getName()).append(" ");
}
UtilPlayer.message(caller, F.desc("Matches via Clan", clanMatchString.toString()));
}
if (playerMatchList.size() > MAX_PLAYER_SEARCH)
{
UtilPlayer.message(caller, F.main("Clan Search", "Too many players matched. Try a more specific search"));
}
else if (playerMatchList.size() == 0)
{
UtilPlayer.message(caller, F.main("Clan Search", "No players matched. Try a more specific search"));
}
else
{
StringBuilder playerMatchString = new StringBuilder();
for (ClanInfo clanInfo : playerMatchList)
{
playerMatchString.append(clanInfo.getName()).append(" ");
}
UtilPlayer.message(caller, F.desc("Matches via Player", playerMatchString.toString()));
}
} }
return null; return null;
@ -259,9 +289,15 @@ public class ClansUtility
public boolean isSafe(Location loc) public boolean isSafe(Location loc)
{ {
if (!_clansManager.getClaimMap().containsKey(UtilWorld.chunkToStr(loc.getChunk()))) return false; // Fix for PC-279
// Do not change to getChunk
// PlayerList#updatePlayers -> iterator -> PlayerVelocityEvent -> getChunk -> loadChunk -> loadPersistentEntities -> addTracker -> ITERATE ON SAME SET
int chunkX = loc.getBlockX() >> 4;
int chunkZ = loc.getBlockZ() >> 4;
String chunkStr = UtilWorld.chunkToStr(loc.getWorld().getName(), chunkX, chunkZ);
if (!_clansManager.getClaimMap().containsKey(chunkStr)) return false;
return _clansManager.getClaimMap().get(UtilWorld.chunkToStr(loc.getChunk())).isSafe(loc); return _clansManager.getClaimMap().get(chunkStr).isSafe(loc);
} }
public boolean isChunkHome(ClanInfo clan, Chunk chunk) public boolean isChunkHome(ClanInfo clan, Chunk chunk)

View File

@ -233,7 +233,6 @@ public class ClansCommand extends CommandBase<ClansManager>
UtilPlayer.message(caller, F.help("/c neutral <clan>", "Request Neutrality with Clan", Rank.ADMIN)); UtilPlayer.message(caller, F.help("/c neutral <clan>", "Request Neutrality with Clan", Rank.ADMIN));
UtilPlayer.message(caller, F.help("/c enemy <clan>", "Declare ClanWar with Clan", Rank.ADMIN)); UtilPlayer.message(caller, F.help("/c enemy <clan>", "Declare ClanWar with Clan", Rank.ADMIN));
UtilPlayer.message(caller, F.help("/c ally <clan>", "Send Alliance to Clan", Rank.ADMIN)); UtilPlayer.message(caller, F.help("/c ally <clan>", "Send Alliance to Clan", Rank.ADMIN));
UtilPlayer.message(caller, F.help("/c trust <clan>", "Give Trust to Clan", Rank.ADMIN));
UtilPlayer.message(caller, F.help("/c claim", "Claim Territory", Rank.ADMIN)); UtilPlayer.message(caller, F.help("/c claim", "Claim Territory", Rank.ADMIN));
UtilPlayer.message(caller, F.help("/c unclaim (all)", "Unclaim Territory", Rank.ADMIN)); UtilPlayer.message(caller, F.help("/c unclaim (all)", "Unclaim Territory", Rank.ADMIN));

View File

@ -269,6 +269,8 @@ public class ClanMainPage extends ClanPageBase
{ {
String enemyName = clanWar.getClanA().equals(clan.getName()) ? clanWar.getClanB() : clanWar.getClanA(); String enemyName = clanWar.getClanA().equals(clan.getName()) ? clanWar.getClanB() : clanWar.getClanA();
final ClanInfo enemy = getPlugin().getClan(enemyName); final ClanInfo enemy = getPlugin().getClan(enemyName);
if (enemy != null)
{
String itemName = enemyName; String itemName = enemyName;
Material material = USE_RESOURCE_ICONS ? ClanIcon.WAR.getMaterial() : Material.DIAMOND_SWORD; Material material = USE_RESOURCE_ICONS ? ClanIcon.WAR.getMaterial() : Material.DIAMOND_SWORD;
byte data = USE_RESOURCE_ICONS ? ClanIcon.WAR.getData() : 0; byte data = USE_RESOURCE_ICONS ? ClanIcon.WAR.getData() : 0;
@ -290,6 +292,11 @@ public class ClanMainPage extends ClanPageBase
} }
}, warPoints); }, warPoints);
} }
else
{
System.err.println("Could not find enemy clan: " + enemyName);
}
}
private void addAllyButton(int slot, final ClanInfo ally) private void addAllyButton(int slot, final ClanInfo ally)
{ {

View File

@ -1,23 +0,0 @@
package mineplex.game.clans.clans.invsee;
import mineplex.core.MiniPlugin;
import mineplex.game.clans.clans.ClansManager;
import mineplex.game.clans.clans.invsee.commands.InvseeCommand;
public class Invsee extends MiniPlugin
{
private ClansManager _clansManager;
public Invsee(ClansManager clansManager)
{
super("Inventory Viewer", clansManager.getPlugin());
_clansManager = clansManager;
}
public void addCommands()
{
addCommand(new InvseeCommand(this));
}
}

View File

@ -0,0 +1,63 @@
package mineplex.game.clans.clans.invsee;
import mineplex.core.MiniPlugin;
import mineplex.core.common.util.UtilServer;
import mineplex.game.clans.clans.ClansManager;
import mineplex.game.clans.clans.invsee.commands.InvseeCommand;
import mineplex.game.clans.clans.invsee.ui.InvseeInventory;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class InvseeManager extends MiniPlugin
{
private final Map<UUID, InvseeInventory> _viewing = new HashMap<>();
public InvseeManager(ClansManager manager)
{
super("Invsee Manager", manager.getPlugin());
}
@Override
public void addCommands()
{
addCommand(new InvseeCommand(this));
}
public void doInvsee(OfflinePlayer target, Player requester)
{
InvseeInventory invseeInventory = _viewing.computeIfAbsent(target.getUniqueId(), key -> new InvseeInventory(this, target));
invseeInventory.addAndShowViewer(requester);
}
public boolean isBeingInvseen(OfflinePlayer player)
{
return _viewing.containsKey(player.getUniqueId());
}
public boolean isInvseeing(Player player)
{
for (InvseeInventory invseeInventory : _viewing.values())
{
if (invseeInventory.isViewer(player))
{
return true;
}
}
return false;
}
public void close(UUID target)
{
InvseeInventory invseeInventory = _viewing.remove(target);
if (invseeInventory == null)
{
log("Expected non-null inventory when closing " + target);
return;
}
UtilServer.Unregister(invseeInventory);
}
}

View File

@ -1,50 +1,94 @@
package mineplex.game.clans.clans.invsee.commands; package mineplex.game.clans.clans.invsee.commands;
import com.mojang.authlib.GameProfile;
import mineplex.core.command.CommandBase; import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank; import mineplex.core.common.Rank;
import mineplex.core.common.util.F; import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer; import mineplex.core.common.util.UtilPlayer;
import mineplex.game.clans.clans.invsee.Invsee; import mineplex.game.clans.clans.invsee.InvseeManager;
import mineplex.game.clans.clans.invsee.ui.InvseeInventory; import net.minecraft.server.v1_8_R3.MinecraftServer;
import net.minecraft.server.v1_8_R3.NBTTagCompound;
import net.minecraft.server.v1_8_R3.WorldNBTStorage;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
public class InvseeCommand extends CommandBase<Invsee> import java.util.UUID;
public class InvseeCommand extends CommandBase<InvseeManager>
{ {
public InvseeCommand(Invsee plugin) public InvseeCommand(InvseeManager plugin)
{ {
super(plugin, Rank.ADMIN, "invsee"); super(plugin, Rank.ADMIN, "invsee");
} }
@SuppressWarnings("deprecation")
@Override @Override
public void Execute(Player caller, String[] args) public void Execute(Player caller, String[] args)
{ {
if (args.length == 0) if (args.length == 0)
{ {
UtilPlayer.message(caller, F.help("/invsee <Player>", "View a player's inventory", Rank.ADMIN)); UtilPlayer.message(caller, F.help("/invsee <playername/playeruuid>", "View a player's inventory", Rank.ADMIN));
return;
} }
else UUID uuid = null;
try
{ {
String name = args[0]; uuid = UUID.fromString(args[0]);
}
OfflinePlayer player = Bukkit.getServer().getPlayer(name); catch (IllegalArgumentException failed)
if (player == null)
{ {
player = Bukkit.getServer().getOfflinePlayer(name);
} }
if (player == null) OfflinePlayer exactPlayer = Bukkit.getServer().getPlayerExact(args[0]);
if (exactPlayer == null)
{ {
UtilPlayer.message(caller, F.main("Clans", "Specified player is neither online nor offline. Perhaps they changed their name?")); if (uuid == null)
{
// We don't want to open the wrong OfflinePlayer's inventory, so if we can't fetch the UUID then abort
GameProfile gameProfile = MinecraftServer.getServer().getUserCache().getProfile(args[0]);
if (gameProfile == null)
{
UtilPlayer.message(caller, F.main("Invsee", "Player is offline and we could not find the UUID. Aborting"));
return;
}
uuid = gameProfile.getId();
}
if (uuid == null)
{
UtilPlayer.message(caller, F.main("Invsee", "Something has gone very wrong. Please report the username/uuid you tried to look up"));
return;
}
// We need to check if we actually have data on this player
// fixme main thread file IO but it's what the server does...?
NBTTagCompound compound = ((WorldNBTStorage) MinecraftServer.getServer().worlds.get(0).getDataManager()).getPlayerData(uuid.toString());
if (compound == null)
{
UtilPlayer.message(caller, F.main("Invsee", "The player exists, but has never joined this server. No inventory to show"));
return;
}
exactPlayer = Bukkit.getServer().getOfflinePlayer(uuid);
}
if (exactPlayer == null)
{
UtilPlayer.message(caller, F.main("Invsee", "Could not load offline player data. Does the player exist?"));
return;
}
if (exactPlayer.getUniqueId().equals(caller.getUniqueId()))
{
UtilPlayer.message(caller, F.main("Invsee", "You cannot invsee yourself!"));
return;
}
if (Plugin.isBeingInvseen(caller))
{
UtilPlayer.message(caller, F.main("Invsee", "You cannot use invsee right now. Someone is invseeing you!"));
return;
}
if (exactPlayer.isOnline() && Plugin.isInvseeing((Player) exactPlayer))
{
UtilPlayer.message(caller, F.main("Invsee", "You cannot use invsee right now. That person is currently using invsee!"));
return; return;
} }
new InvseeInventory(player).ShowTo(caller); Plugin.doInvsee(exactPlayer, caller);
} }
}
} }

View File

@ -1,99 +1,407 @@
package mineplex.game.clans.clans.invsee.ui; package mineplex.game.clans.clans.invsee.ui;
import mineplex.core.common.util.*;
import mineplex.core.itemstack.ItemStackFactory;
import mineplex.game.clans.clans.ClansManager;
import mineplex.game.clans.clans.invsee.InvseeManager;
import net.minecraft.server.v1_8_R3.*;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_8_R3.inventory.CraftInventory;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.*;
import org.bukkit.event.inventory.InventoryCloseEvent; import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta;
import mineplex.core.common.util.C; import java.io.File;
import mineplex.core.common.util.UtilCollections; import java.io.FileOutputStream;
import mineplex.core.common.util.UtilServer; import java.util.*;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
public class InvseeInventory implements Listener public class InvseeInventory implements Listener
{ {
private OfflinePlayer _player; private final InvseeManager _invseeManager;
// This is the UUID of the target player. This should stay constant. Use this for comparison
private final UUID _uuid;
// This is the current player. It will switch when the player joins/quits
private OfflinePlayer _targetPlayer;
// This is the inventory of said player. If the player is not online then this inventory is a fake PlayerInventory
private net.minecraft.server.v1_8_R3.PlayerInventory _playerInventory;
// This is the set of all admins viewing this player
private Set<Player> _viewers = new HashSet<>();
// This is the inventory that all admins will be looking at
private Inventory _inventory; private Inventory _inventory;
// This is whether the target player should be allowed to open any inventories
private boolean _canOpenInventory = true;
private boolean _online; public InvseeInventory(InvseeManager manager, OfflinePlayer player)
private Player _admin;
public InvseeInventory(OfflinePlayer player)
{ {
_online = (_player = player) instanceof Player; _invseeManager = manager;
_uuid = player.getUniqueId();
_targetPlayer = player;
_inventory = UtilServer.getServer().createInventory(null, 54, player.getName() + " " + (_online ? C.cGreen + "ONLINE" : C.cRed + "OFFLINE")); _inventory = UtilServer.getServer().createInventory(null, 6 * 9, player.getName());
for (int index = 38; index < 45; index++)
{
_inventory.setItem(index, ItemStackFactory.Instance.CreateStack(Material.STAINED_GLASS_PANE, (byte) 14, 1, C.Bold));
}
_inventory.setItem(47, ItemStackFactory.Instance.CreateStack(Material.STONE_BUTTON, (byte) 0, 1, C.cGreenB + "Inventory Control", generateLore(_canOpenInventory)));
_inventory.setItem(48, ItemStackFactory.Instance.CreateStack(Material.STAINED_GLASS_PANE, (byte) 14, 1, C.Bold));
UtilServer.RegisterEvents(this); UtilServer.RegisterEvents(this);
updateInventory();
update(true);
} }
public void ShowTo(Player admin) private String[] generateLore(boolean canOpenInventory)
{ {
_admin = admin; return UtilText.splitLinesToArray(new String[]{
admin.openInventory(_inventory); C.cYellow + "Left-Click" + C.cWhite + " to force close any open inventories the target has open",
"",
C.cYellow + "Right-Click" + C.cWhite + " to " + (canOpenInventory ? "disable inventory opening" : "enable inventory opening")
}, LineFormat.LORE);
} }
@EventHandler /*
public void quit(PlayerQuitEvent event) * Add the player to the list of viewers and open the inventory for him
*/
public void addAndShowViewer(Player requester)
{ {
if (_online && event.getPlayer().equals(_player)) _viewers.add(requester);
requester.openInventory(_inventory);
}
/*
* Check whether the given player is currently viewing this InvseeInventory
*/
public boolean isViewer(Player check)
{ {
_admin.closeInventory(); return _viewers.contains(check);
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void on(PlayerJoinEvent event)
{
if (_uuid.equals(event.getPlayer().getUniqueId()))
{
_targetPlayer = event.getPlayer();
updateInventory();
} }
} }
@EventHandler @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void update(UpdateEvent event) public void on(PlayerQuitEvent event)
{ {
if (event.getType() != UpdateType.TICK) // If a viewer quit, this will clean it up
_viewers.remove(event.getPlayer());
if (_viewers.size() == 0)
{ {
_invseeManager.close(_uuid);
}
else
{
// This should always work
_targetPlayer = Bukkit.getOfflinePlayer(_uuid);
updateInventory();
}
}
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void on(InventoryOpenEvent event)
{
if (event.getPlayer().getUniqueId().equals(_targetPlayer.getUniqueId()) && !_canOpenInventory)
{
event.setCancelled(true);
}
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void on(InventoryCloseEvent event)
{
if (_inventory.equals(event.getInventory()))
{
_viewers.remove(event.getPlayer());
if (_viewers.size() == 0)
{
_invseeManager.close(_uuid);
}
}
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void on(InventoryDragEvent event)
{
if (_inventory.equals(event.getInventory()))
{
ClansManager.getInstance().runSync(() ->
{
update(false);
saveInventory();
});
}
else if (event.getWhoClicked().getUniqueId().equals(_targetPlayer.getUniqueId()))
{
ClansManager.getInstance().runSync(() ->
{
update(true);
saveInventory();
});
}
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void on(InventoryClickEvent event)
{
if (_inventory.equals(event.getClickedInventory()))
{
if (event.getCurrentItem() != null && event.getCurrentItem().getType() == Material.STAINED_GLASS_PANE
&& event.getCurrentItem().getItemMeta() != null
&& event.getCurrentItem().getItemMeta().getDisplayName() != null
&& event.getCurrentItem().getItemMeta().getDisplayName().equals(C.Bold))
{
event.setCancelled(true);
return;
}
if (event.getCurrentItem() != null && event.getCurrentItem().getType() == Material.STONE_BUTTON
&& event.getCurrentItem().getItemMeta() != null
&& event.getCurrentItem().getItemMeta().getDisplayName() != null
&& event.getCurrentItem().getItemMeta().getDisplayName().equals(C.cGreenB + "Inventory Control"))
{
event.setCancelled(true);
if (event.getClick() == ClickType.LEFT)
{
if (_targetPlayer.isOnline())
{
((Player) _targetPlayer).closeInventory();
}
}
else if (event.getClick() == ClickType.RIGHT)
{
if (_targetPlayer.isOnline())
{
_canOpenInventory = !_canOpenInventory;
ItemMeta meta = event.getCurrentItem().getItemMeta();
meta.setLore(Arrays.asList(generateLore(_canOpenInventory)));
event.getCurrentItem().setItemMeta(meta);
if (!_canOpenInventory)
{
((Player) _targetPlayer).closeInventory();
}
}
}
return; return;
} }
if (_online) if (MAPPING_INVENTORY_REVERSE.containsKey(event.getRawSlot()))
{ {
if (!UtilCollections.equal(_inventory.getContents(), ((Player) _player).getInventory().getContents())) ClansManager.getInstance().runSync(() ->
{ {
_inventory.setContents(((Player) _player).getInventory().getContents()); update(false);
saveInventory();
});
}
else if (MAPPING_CRAFTING_REVERSE.containsKey(event.getRawSlot()))
{
if (_targetPlayer.isOnline())
{
ClansManager.getInstance().runSync(() ->
{
update(false);
});
}
}
else if (event.getRawSlot() == 49)
{
if (_targetPlayer.isOnline())
{
ClansManager.getInstance().runSync(() ->
{
update(false);
});
}
}
}
else
{
if (event.getWhoClicked().getUniqueId().equals(_targetPlayer.getUniqueId()))
{
ClansManager.getInstance().runSync(() ->
{
update(true);
});
} }
} }
} }
@EventHandler /*
public void inventoryClick(InventoryClickEvent event) * Updates the inventory instance
*/
private void updateInventory()
{ {
if (event.getClickedInventory().equals(((Player) _player).getInventory())) if (_targetPlayer.isOnline())
{ {
_inventory.setContents(((Player) _player).getInventory().getContents()); _playerInventory = ((CraftPlayer) _targetPlayer).getHandle().inventory;
} }
else if (event.getClickedInventory().equals(_inventory)) else
{ {
if (_online) NBTTagCompound compound = ((WorldNBTStorage) MinecraftServer.getServer().worlds.get(0).getDataManager()).getPlayerData(_uuid.toString());
// Should not matter if null
_playerInventory = new PlayerInventory(null);
if (compound.hasKeyOfType("Inventory", 9))
{ {
((Player) _player).getInventory().setContents(_inventory.getContents()); _playerInventory.b(compound.getList("Inventory", 10));
} }
} }
} }
@EventHandler private void saveInventory()
public void closeInventory(InventoryCloseEvent event)
{ {
if (event.getInventory().equals(_inventory)) if (!_targetPlayer.isOnline())
{ {
UtilServer.Unregister(this); try
{
WorldNBTStorage worldNBTStorage = ((WorldNBTStorage) MinecraftServer.getServer().worlds.get(0).getDataManager());
NBTTagCompound compound = worldNBTStorage.getPlayerData(_uuid.toString());
compound.set("Inventory", new NBTTagList());
_playerInventory.a(compound.getList("Inventory", 10));
File file = new File(worldNBTStorage.getPlayerDir(), _targetPlayer.getUniqueId().toString() + ".dat.tmp");
File file1 = new File(worldNBTStorage.getPlayerDir(), _targetPlayer.getUniqueId().toString() + ".dat");
NBTCompressedStreamTools.a(compound, new FileOutputStream(file));
if (file1.exists())
{
file1.delete();
}
if (!_online) file.renameTo(file1);
}
catch (Exception var5)
{ {
// save offline inv _invseeManager.log("Failed to save player inventory for " + _targetPlayer.getName());
for (Player player : _viewers)
{
UtilPlayer.message(player, F.main("Invsee", "Could not save inventory for " + _targetPlayer.getName()));
}
var5.printStackTrace(System.out);
} }
} }
} }
/*
* Update the player inventory and invsee inventory.
*
* @param targetClick If true, then it means the player being invseen has modified their inventory. Otherwise, it's the admin who has modified something
*/
private void update(boolean targetClick)
{
IInventory iInventoryThis = ((CraftInventory) _inventory).getInventory();
if (targetClick)
{
// Update items on hotbar
for (int otherSlot = 0; otherSlot < 9; otherSlot++)
{
iInventoryThis.setItem(MAPPING_INVENTORY.get(otherSlot), _playerInventory.getItem(otherSlot));
}
// Update main inventory
for (int otherSlot = 9; otherSlot < 36; otherSlot++)
{
iInventoryThis.setItem(MAPPING_INVENTORY.get(otherSlot), _playerInventory.getItem(otherSlot));
}
// Update armor
for (int otherSlot = 36; otherSlot < 40; otherSlot++)
{
iInventoryThis.setItem(MAPPING_INVENTORY.get(otherSlot), _playerInventory.getItem(otherSlot));
}
if (_targetPlayer.isOnline())
{
ContainerPlayer containerPlayer = (ContainerPlayer) ((CraftPlayer) _targetPlayer).getHandle().defaultContainer;
for (int craftingIndex = 0; craftingIndex < 4; craftingIndex++)
{
iInventoryThis.setItem(MAPPING_CRAFTING.get(craftingIndex), containerPlayer.craftInventory.getItem(craftingIndex));
}
}
iInventoryThis.setItem(49, _playerInventory.getCarried());
}
else
{
// Update items on hotbar
for (int otherSlot = 0; otherSlot < 9; otherSlot++)
{
_playerInventory.setItem(otherSlot, iInventoryThis.getItem(MAPPING_INVENTORY.get(otherSlot)));
}
// Update main inventory
for (int otherSlot = 9; otherSlot < 36; otherSlot++)
{
_playerInventory.setItem(otherSlot, iInventoryThis.getItem(MAPPING_INVENTORY.get(otherSlot)));
}
// Update armor
for (int otherSlot = 36; otherSlot < 40; otherSlot++)
{
_playerInventory.setItem(otherSlot, iInventoryThis.getItem(MAPPING_INVENTORY.get(otherSlot)));
}
if (_targetPlayer.isOnline())
{
ContainerPlayer containerPlayer = (ContainerPlayer) ((CraftPlayer) _targetPlayer).getHandle().defaultContainer;
for (int craftingIndex = 0; craftingIndex < 4; craftingIndex++)
{
containerPlayer.craftInventory.setItem(craftingIndex, iInventoryThis.getItem(MAPPING_CRAFTING.get(craftingIndex)));
}
}
_playerInventory.setCarried(iInventoryThis.getItem(49));
}
for (Player viewing : _viewers)
{
viewing.updateInventory();
}
if (_targetPlayer.isOnline())
{
((Player) _targetPlayer).updateInventory();
}
}
// Maps slot indices of player inventories to slot indices of double chests
private static final Map<Integer, Integer> MAPPING_INVENTORY = new HashMap<>();
private static final Map<Integer, Integer> MAPPING_INVENTORY_REVERSE = new HashMap<>();
// Maps slot indices of player inventories to slot indices of crafting window
private static final Map<Integer, Integer> MAPPING_CRAFTING = new HashMap<>();
private static final Map<Integer, Integer> MAPPING_CRAFTING_REVERSE = new HashMap<>();
static
{
int[] inventoryMapping = new int[]
{
27, 28, 29, 30, 31, 32, 33, 34, 35, //Hotbar
0, 1, 2, 3, 4, 5, 6, 7, 8, // Top row inventory
9, 10, 11, 12, 13, 14, 15, 16, 17, //Second row inventory
18, 19, 20, 21, 22, 23, 24, 25, 26, //Third row inventory
53, 52, 51, 50 //Armor
};
int[] craftingMapping = new int[]
{
36, 37, //Top crafting
45, 46 //Bottom crafting
};
for (int i = 0; i < inventoryMapping.length; i++)
{
MAPPING_INVENTORY.put(i, inventoryMapping[i]);
MAPPING_INVENTORY_REVERSE.put(inventoryMapping[i], i);
}
for (int i = 0; i < craftingMapping.length; i++)
{
MAPPING_CRAFTING.put(i, craftingMapping[i]);
MAPPING_CRAFTING_REVERSE.put(craftingMapping[i], i);
}
}
} }

View File

@ -1,30 +1,26 @@
package mineplex.game.clans.clans.map; package mineplex.game.clans.clans.map;
import java.io.BufferedReader; import java.io.*;
import java.io.File;
import java.io.FileReader;
import java.io.PrintWriter;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.ArrayList; import java.util.*;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry; import java.util.Map.Entry;
import mineplex.core.common.util.*;
import mineplex.game.clans.tutorial.TutorialManager; import mineplex.game.clans.tutorial.TutorialManager;
import mineplex.game.clans.tutorial.map.TutorialMapManager; import net.minecraft.server.v1_8_R3.*;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.craftbukkit.v1_8_R3.CraftChunk; import org.bukkit.craftbukkit.v1_8_R3.CraftChunk;
import org.bukkit.craftbukkit.v1_8_R3.CraftWorld; 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.ItemFrame;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.block.Action; import org.bukkit.event.block.Action;
import org.bukkit.event.entity.ItemSpawnEvent; import org.bukkit.event.entity.ItemSpawnEvent;
import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.entity.PlayerDeathEvent;
@ -35,6 +31,8 @@ import org.bukkit.event.player.PlayerItemHeldEvent;
import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerTeleportEvent; 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.Inventory;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.map.MapRenderer; import org.bukkit.map.MapRenderer;
@ -46,13 +44,6 @@ import com.google.common.collect.Iterables;
import com.google.common.collect.Multisets; import com.google.common.collect.Multisets;
import mineplex.core.MiniPlugin; 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.common.util.UtilTime.TimeUnit;
import mineplex.core.itemstack.ItemBuilder; import mineplex.core.itemstack.ItemBuilder;
import mineplex.core.portal.ServerTransferEvent; import mineplex.core.portal.ServerTransferEvent;
@ -62,27 +53,77 @@ import mineplex.game.clans.clans.ClansManager;
import mineplex.game.clans.clans.ClansUtility; import mineplex.game.clans.clans.ClansUtility;
import mineplex.game.clans.clans.map.events.PlayerGetMapEvent; import mineplex.game.clans.clans.map.events.PlayerGetMapEvent;
import mineplex.game.clans.clans.worldevent.WorldEventManager; 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 <x> ticks
*/
public class ItemMapManager extends MiniPlugin public class ItemMapManager extends MiniPlugin
{ {
private int _blocksScan = 16 * 3; // 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 ClansUtility _clansUtility; private ClansUtility _clansUtility;
private Comparator<Entry<Integer, Integer>> _comparator; private Comparator<Entry<Integer, Integer>> _comparator;
private int _halfMapSize = 1536 / 2; private int[][] _heightMap = new int[(HALF_WORLD_SIZE * 2) + 16][];
private int[][] _heightMap = new int[(_halfMapSize * 2) + 16][];
private boolean _loadWorld = true;
private HashMap<Integer, Byte[][]> _map = new HashMap<Integer, Byte[][]>(); private HashMap<Integer, Byte[][]> _map = new HashMap<Integer, Byte[][]>();
private short _mapId = -1; private short _mapId = -1;
private HashMap<String, MapInfo> _mapInfo = new HashMap<String, MapInfo>(); private HashMap<String, MapInfo> _mapInfo = new HashMap<String, MapInfo>();
private HashMap<Integer, Integer> _scale = new HashMap<Integer, Integer>(); private HashMap<Integer, Integer> _scale = new HashMap<Integer, Integer>();
private ArrayList<Entry<Integer, Integer>> _scanList = new ArrayList<Entry<Integer, Integer>>(); // 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<Entry<Integer, Integer>> _scanList = new LinkedList<Entry<Integer, Integer>>();
private World _world; private World _world;
private WorldServer _nmsWorld;
private ChunkProviderServer _chunkProviderServer;
private ChunkRegionLoader _chunkRegionLoader;
private WorldEventManager _eventManager; private WorldEventManager _eventManager;
private TutorialManager _tutorial; private TutorialManager _tutorial;
@ -94,14 +135,10 @@ public class ItemMapManager extends MiniPlugin
_eventManager = eventManager; _eventManager = eventManager;
_tutorial = tutorial; _tutorial = tutorial;
_comparator = new Comparator<Entry<Integer, Integer>>() _comparator = (o1, o2) ->
{
@Override
public int compare(Entry<Integer, Integer> o1, Entry<Integer, Integer> o2)
{ {
// Render the places outside the map first to speed up visual errors fixing // Render the places outside the map first to speed up visual errors fixing
int outsideMap = Boolean.compare(o1.getValue() < -_halfMapSize, o2.getValue() < -_halfMapSize); int outsideMap = Boolean.compare(o1.getValue() < -HALF_WORLD_SIZE, o2.getValue() < -HALF_WORLD_SIZE);
if (outsideMap != 0) if (outsideMap != 0)
{ {
@ -127,17 +164,8 @@ public class ItemMapManager extends MiniPlugin
return Double.compare(dist1, dist2); 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(0, 1);
// _scale.put(1, 2); // _scale.put(1, 2);
_scale.put(1, 4); _scale.put(1, 4);
@ -147,7 +175,7 @@ public class ItemMapManager extends MiniPlugin
for (Entry<Integer, Integer> entry : _scale.entrySet()) for (Entry<Integer, Integer> entry : _scale.entrySet())
{ {
int size = (_halfMapSize * 2) / entry.getValue(); int size = (HALF_WORLD_SIZE * 2) / entry.getValue();
Byte[][] bytes = new Byte[size][]; Byte[][] bytes = new Byte[size][];
for (int i = 0; i < size; i++) for (int i = 0; i < size; i++)
@ -165,6 +193,23 @@ public class ItemMapManager extends MiniPlugin
_world = Bukkit.getWorld("world"); _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 try
{ {
File file = new File("world/clans_map_id"); File file = new File("world/clans_map_id");
@ -238,6 +283,58 @@ public class ItemMapManager extends MiniPlugin
} }
rebuildScan(); 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<Integer, Integer> 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) private void setupRenderer(MapView view)
@ -256,10 +353,7 @@ public class ItemMapManager extends MiniPlugin
if (!(event.getRightClicked() instanceof ItemFrame)) if (!(event.getRightClicked() instanceof ItemFrame))
return; return;
ItemStack item = event.getPlayer().getItemInHand(); if (!isItemClansMap(event.getPlayer().getItemInHand()))
if (item == null || item.getType() != Material.MAP || item.getDurability() < _mapId
|| item.getDurability() > _mapId + 100)
return; return;
event.setCancelled(true); event.setCancelled(true);
@ -270,7 +364,7 @@ public class ItemMapManager extends MiniPlugin
*/ */
public int calcMapCenter(int zoom, int cord) public int calcMapCenter(int zoom, int cord)
{ {
int mapSize = _halfMapSize / zoom; // This is how large the map is in pixels int mapSize = HALF_WORLD_SIZE / 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 int mapCord = cord / zoom; // This is pixels from true center of map, not held map
@ -309,7 +403,7 @@ public class ItemMapManager extends MiniPlugin
Byte[][] map = _map.get(scale); Byte[][] map = _map.get(scale);
int zoom = getZoom(scale); int zoom = getZoom(scale);
for (int x = startingX; x < startingX + _blocksScan; x += zoom) for (int x = startingX; x < startingX + BLOCK_SCAN_INTERVAL; x += zoom)
{ {
double d0 = 0; double d0 = 0;
@ -319,10 +413,10 @@ public class ItemMapManager extends MiniPlugin
{ {
for (int addZ = 0; addZ < zoom; addZ++) for (int addZ = 0; addZ < zoom; addZ++)
{ {
int hX = x + addX + _halfMapSize; int hX = x + addX + HALF_WORLD_SIZE;
int hZ = (startingZ - zoom) + addZ + _halfMapSize; int hZ = (startingZ - zoom) + addZ + HALF_WORLD_SIZE;
if (hX >= _halfMapSize * 2 || hZ >= _halfMapSize * 2) if (hX >= HALF_WORLD_SIZE * 2 || hZ >= HALF_WORLD_SIZE * 2)
{ {
continue; continue;
} }
@ -331,7 +425,7 @@ public class ItemMapManager extends MiniPlugin
} }
} }
for (int z = startingZ; z < startingZ + _blocksScan; z += zoom) for (int z = startingZ; z < startingZ + BLOCK_SCAN_INTERVAL; z += zoom)
{ {
// Water depth colors not included // Water depth colors not included
double d1 = 0; double d1 = 0;
@ -340,10 +434,10 @@ public class ItemMapManager extends MiniPlugin
{ {
for (int addZ = 0; addZ < zoom; addZ++) for (int addZ = 0; addZ < zoom; addZ++)
{ {
int hX = x + addX + _halfMapSize; int hX = x + addX + HALF_WORLD_SIZE;
int hZ = z + addZ + _halfMapSize; int hZ = z + addZ + HALF_WORLD_SIZE;
if (hX >= _halfMapSize * 2 || hZ >= _halfMapSize * 2) if (hX >= HALF_WORLD_SIZE * 2 || hZ >= HALF_WORLD_SIZE * 2)
{ {
continue; continue;
} }
@ -370,7 +464,7 @@ public class ItemMapManager extends MiniPlugin
b0 = 0; b0 = 0;
} }
int origColor = map[(x + _halfMapSize) / zoom][(z + _halfMapSize) / zoom] - 1; int origColor = map[(x + HALF_WORLD_SIZE) / zoom][(z + HALF_WORLD_SIZE) / zoom] - 1;
/*if (color < 4) /*if (color < 4)
{ {
@ -388,7 +482,7 @@ public class ItemMapManager extends MiniPlugin
}*/ }*/
byte color = (byte) (origColor + b0); byte color = (byte) (origColor + b0);
map[(x + _halfMapSize) / zoom][(z + _halfMapSize) / zoom] = color; map[(x + HALF_WORLD_SIZE) / zoom][(z + HALF_WORLD_SIZE) / zoom] = color;
} }
} }
} }
@ -399,9 +493,9 @@ public class ItemMapManager extends MiniPlugin
Byte[][] second = _map.get(scale); Byte[][] second = _map.get(scale);
int zoom = getZoom(scale); int zoom = getZoom(scale);
for (int x = startingX; x < startingX + _blocksScan; x += zoom) for (int x = startingX; x < startingX + BLOCK_SCAN_INTERVAL; x += zoom)
{ {
for (int z = startingZ; z < startingZ + _blocksScan; z += zoom) for (int z = startingZ; z < startingZ + BLOCK_SCAN_INTERVAL; z += zoom)
{ {
HashMultiset<Byte> hashmultiset = HashMultiset.create(); HashMultiset<Byte> hashmultiset = HashMultiset.create();
@ -409,8 +503,8 @@ public class ItemMapManager extends MiniPlugin
{ {
for (int addZ = 0; addZ < zoom; addZ++) for (int addZ = 0; addZ < zoom; addZ++)
{ {
int pX = x + addX + _halfMapSize; int pX = x + addX + HALF_WORLD_SIZE;
int pZ = z + addZ + _halfMapSize; int pZ = z + addZ + HALF_WORLD_SIZE;
if (pX >= first.length || pZ >= first.length) if (pX >= first.length || pZ >= first.length)
{ {
@ -432,7 +526,7 @@ public class ItemMapManager extends MiniPlugin
{ {
color = (byte) 0; color = (byte) 0;
} }
second[(x + _halfMapSize) / zoom][(z + _halfMapSize) / zoom] = color; second[(x + HALF_WORLD_SIZE) / zoom][(z + HALF_WORLD_SIZE) / zoom] = color;
} }
} }
} }
@ -440,27 +534,18 @@ public class ItemMapManager extends MiniPlugin
@EventHandler @EventHandler
public void dropItem(ItemSpawnEvent event) public void dropItem(ItemSpawnEvent event)
{ {
ItemStack item = event.getEntity().getItemStack(); if (isItemClansMap(event.getEntity().getItemStack()))
if (item != null && item.getType() == Material.MAP && item.getDurability() >= _mapId
&& item.getDurability() <= _mapId + 100)
{
event.getEntity().remove(); event.getEntity().remove();
} }
}
public void removeMap(Player player) public void removeMap(Player player)
{ {
for (int slot = 0; slot < player.getInventory().getSize(); slot++) for (int slot = 0; slot < player.getInventory().getSize(); slot++)
{ {
ItemStack item = player.getInventory().getItem(slot); if (isItemClansMap(player.getInventory().getItem(slot)))
if (item != null && item.getType() == Material.MAP && item.getDurability() >= _mapId && item.getDurability() <= _mapId + 100)
{
player.getInventory().setItem(slot, null); player.getInventory().setItem(slot, null);
} }
} }
}
public ClansUtility getClansUtility() public ClansUtility getClansUtility()
{ {
@ -477,7 +562,7 @@ public class ItemMapManager extends MiniPlugin
private double getDistance(Entry<Integer, Integer> entry, double x1, double z1) private double getDistance(Entry<Integer, Integer> entry, double x1, double z1)
{ {
return getDistance(x1, z1, entry.getKey() + (_blocksScan / 2), entry.getValue() + (_blocksScan / 2)); return getDistance(x1, z1, entry.getKey() + (BLOCK_SCAN_INTERVAL / 2), entry.getValue() + (BLOCK_SCAN_INTERVAL / 2));
} }
public Byte[][] getMap(int scale) public Byte[][] getMap(int scale)
@ -492,7 +577,7 @@ public class ItemMapManager extends MiniPlugin
public int getMapSize() public int getMapSize()
{ {
return _halfMapSize; return HALF_WORLD_SIZE;
} }
public int getZoom(int scale) public int getZoom(int scale)
@ -500,35 +585,7 @@ public class ItemMapManager extends MiniPlugin
return _scale.get(scale); return _scale.get(scale);
} }
@EventHandler //fixme So what appears to happen is that after you die, if your map is is the same then the map is frozen
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 @EventHandler
public void onDeath(PlayerDeathEvent event) public void onDeath(PlayerDeathEvent event)
{ {
@ -542,14 +599,10 @@ public class ItemMapManager extends MiniPlugin
{ {
Player player = event.getPlayer(); Player player = event.getPlayer();
ItemStack item = player.getInventory().getItem(event.getNewSlot()); if (!isItemClansMap(player.getInventory().getItem(event.getNewSlot())))
if (item == null || item.getType() != Material.MAP || item.getDurability() < _mapId
|| item.getDurability() > _mapId + 100)
return; return;
showZoom(player, getMap(player)); showZoom(player, getMap(player));
} }
@EventHandler @EventHandler
@ -558,10 +611,7 @@ public class ItemMapManager extends MiniPlugin
if (event.getAction() == Action.PHYSICAL) if (event.getAction() == Action.PHYSICAL)
return; return;
ItemStack item = event.getItem(); if (!isItemClansMap(event.getItem()))
if (item == null || item.getType() != Material.MAP || item.getDurability() < _mapId
|| item.getDurability() > _mapId + 100)
return; return;
event.setCancelled(true); event.setCancelled(true);
@ -666,36 +716,11 @@ public class ItemMapManager extends MiniPlugin
private void rebuildScan() private void rebuildScan()
{ {
for (int x = -_halfMapSize; x < _halfMapSize; x += _blocksScan) for (int x = -HALF_WORLD_SIZE; x < HALF_WORLD_SIZE; x += BLOCK_SCAN_INTERVAL)
{ {
for (int z = -_halfMapSize - 16; z < _halfMapSize; z += (z < -_halfMapSize ? 16 : _blocksScan)) for (int z = -HALF_WORLD_SIZE - 16; z < HALF_WORLD_SIZE; z += (z < -HALF_WORLD_SIZE ? 16 : BLOCK_SCAN_INTERVAL))
{ {
_scanList.add(new HashMap.SimpleEntry(x, z)); _scanList.add(new HashMap.SimpleEntry<>(x, z));
}
}
if (!_loadWorld)
{
Iterator<Entry<Integer, Integer>> itel = _scanList.iterator();
while (itel.hasNext())
{
Entry<Integer, Integer> 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();
}
} }
} }
@ -744,101 +769,117 @@ public class ItemMapManager extends MiniPlugin
if (event.getType() != UpdateType.FAST) if (event.getType() != UpdateType.FAST)
return; return;
if (_scanList.isEmpty()) if (_scanList.isEmpty() && UtilServer.getPlayers().length > 0)
{ {
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(); rebuildScan();
} }
else if (_scanList.size() % 20 == 0)
if (_scanList.size() % 20 == 0)
{ {
Collections.sort(_scanList, _comparator); Collections.sort(_scanList, _comparator);
} }
if (_scanList.isEmpty()) if (_scanList.isEmpty())
{
return; return;
}
Entry<Integer, Integer> entry = _scanList.remove(0); Entry<Integer, Integer> entry = _scanList.remove(0);
int startingX = entry.getKey(); int startingX = entry.getKey();
int startingZ = entry.getValue(); int startingZ = entry.getValue();
boolean outsideMap = startingZ < -_halfMapSize; boolean outsideMap = startingZ < -HALF_WORLD_SIZE;
scanWorldMap(startingX, startingZ, !outsideMap); scanWorldMap(startingX, startingZ, !outsideMap, false);
if (outsideMap) if (outsideMap)
{
return; return;
}
for (int scale = 1; scale < _scale.size(); scale++) for (int scale = 1; scale < _scale.size(); scale++)
{
if (scale == 3 && _loadWorld)
continue;
if (!outsideMap)
{ {
drawWorldScale(scale, startingX, startingZ); drawWorldScale(scale, startingX, startingZ);
}
colorWorldHeight(scale, startingX, startingZ); colorWorldHeight(scale, startingX, startingZ);
} }
colorWorldHeight(0, startingX, startingZ); colorWorldHeight(0, startingX, startingZ);
} }
public void scanWorldMap(int startingX, int startingZ, boolean setColors)
// 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<Chunk> _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)
{ {
Byte[][] map = _map.get(0); 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 > -_halfMapSize ? 16 : 0); beginZ < startingZ for (int beginZ = startingZ - (startingZ > -HALF_WORLD_SIZE ? 16 : 0); beginZ < startingZ
+ (setColors ? _blocksScan : 16); beginZ += 16) + (setColors ? BLOCK_SCAN_INTERVAL : 16); beginZ += 16)
{ {
Chunk chunk = _world.getChunkAt(beginX / 16, beginZ / 16); int chunkX = beginX / 16;
boolean loaded = false; int chunkZ = beginZ / 16;
net.minecraft.server.v1_8_R3.Chunk nmsChunk = _chunkProviderServer.getChunkIfLoaded(chunkX, chunkZ);
if (!chunk.isLoaded()) if (nmsChunk == null)
{ {
if (_loadWorld) long key = LongHash.toLong(chunkX, chunkZ);
nmsChunk = _chunkCache.get(key);
if (nmsChunk == null)
{ {
loaded = chunk.load(); if (!isFirstScan)
}
else
{ {
continue; 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);
}
} }
net.minecraft.server.v1_8_R3.Chunk nmsChunk = ((CraftChunk) chunk).getHandle(); if (!nmsChunk.isEmpty())
{
for (int x = beginX; x < beginX + 16; x++) for (int x = beginX; x < beginX + 16; x++)
{ {
for (int z = beginZ; z < beginZ + 16; z++) for (int z = beginZ; z < beginZ + 16; z++)
{ {
int color = 0; int color = 0;
if (!nmsChunk.isEmpty())
{
int k3 = x & 0xF; int k3 = x & 0xF;
int l3 = z & 0xF; int l3 = z & 0xF;
@ -850,7 +891,8 @@ public class ItemMapManager extends MiniPlugin
do do
{ {
l4--; l4--;
iblockdata= nmsChunk.getBlockData(new BlockPosition(k3, l4, l3)); _blockPosition.c(k3, l4, l3);
iblockdata = nmsChunk.getBlockData(_blockPosition);
} }
while (iblockdata.getBlock().g(iblockdata) == MaterialMapColor.b && (l4 > 0)); while (iblockdata.getBlock().g(iblockdata) == MaterialMapColor.b && (l4 > 0));
@ -860,33 +902,30 @@ public class ItemMapManager extends MiniPlugin
Block block1; Block block1;
do do
{ {
block1 = nmsChunk.getType(new BlockPosition(k3, j5--, l3)); _blockPosition.c(k3, j5--, l3);
block1 = nmsChunk.getType(_blockPosition);
} }
while ((j5 > 0) && (block1.getMaterial().isLiquid())); while ((j5 > 0) && (block1.getMaterial().isLiquid()));
} }
} }
_heightMap[x + _halfMapSize + 16][z + _halfMapSize + 16] = l4; _heightMap[x + HALF_WORLD_SIZE + 16][z + HALF_WORLD_SIZE + 16] = l4;
if (setColors) if (setColors)
{ {
//color = block.f(i5).M; //color = block.f(i5).M;
IBlockData data = nmsChunk.getBlockData(new BlockPosition(k3, l4, l3)); _blockPosition.c(k3, l4, l3);
IBlockData data = nmsChunk.getBlockData(_blockPosition);
color = data.getBlock().g(data).M; color = data.getBlock().g(data).M;
color = (byte) ((color * 4) + 1); color = (byte) ((color * 4) + 1);
} }
}
if (setColors && beginZ >= startingZ) if (setColors && beginZ >= startingZ)
{ {
map[x + _halfMapSize][z + _halfMapSize] = (byte) color; map[x + HALF_WORLD_SIZE][z + HALF_WORLD_SIZE] = (byte) color;
} }
} }
if (loaded)
{
chunk.unload();
} }
} }
} }
@ -901,7 +940,7 @@ public class ItemMapManager extends MiniPlugin
for (ItemStack item : UtilInv.getItems(player)) for (ItemStack item : UtilInv.getItems(player))
{ {
if (item.getType() == Material.MAP && (item.getDurability() >= _mapId && item.getDurability() <= _mapId + 100)) if (isItemClansMap(item))
{ {
return; return;
} }
@ -909,62 +948,38 @@ public class ItemMapManager extends MiniPlugin
ItemStack item = new ItemBuilder(Material.MAP, 1, (short) getMap(player).getMap()).setTitle("Clans Map").build(); ItemStack item = new ItemBuilder(Material.MAP, 1, (short) getMap(player).getMap()).setTitle("Clans Map").build();
int slot = player.getInventory().firstEmpty(); int slot = CLANS_MAP_SLOT;
ItemStack mapSlot = player.getInventory().getItem(slot);
if (mapSlot != null && mapSlot.getType() != Material.AIR)
{
slot = player.getInventory().firstEmpty();
}
if (slot >= 0) if (slot >= 0)
{ {
ItemStack mapSlot = player.getInventory().getItem(8);
if (mapSlot == null || mapSlot.getType() == Material.AIR)
{
slot = 8;
}
player.getInventory().setItem(slot, item); 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) private void showZoom(Player player, MapInfo info)
{ {
String progressBar = C.cBlue + ""; UtilTextBottom.display(ZOOM_INFO[info.getScale()], player);
}
boolean colorChange = false; /*
* Check whether an {@link ItemStack} is also a Clans Map
for (int i = 2; i >= 0; i--) *
* @param itemStack The {@link ItemStack} to check
* @returns Whether the {@link ItemStack} is also a Clans Map
*/
private boolean isItemClansMap(ItemStack itemStack)
{ {
if (!colorChange && i < info.getScale()) return UtilItem.matchesMaterial(itemStack, Material.MAP)
{ && itemStack.getDurability() >= _mapId
progressBar += C.cGray; && itemStack.getDurability() <= _mapId + 100;
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);
}
} }

View File

@ -4,6 +4,9 @@ import org.bukkit.entity.Player;
import org.bukkit.event.Event; import org.bukkit.event.Event;
import org.bukkit.event.HandlerList; import org.bukkit.event.HandlerList;
/*
* This event is called when a Player is about to receive a Clans Map
*/
public class PlayerGetMapEvent extends Event public class PlayerGetMapEvent extends Event
{ {
private static final HandlerList handlers = new HandlerList(); private static final HandlerList handlers = new HandlerList();

View File

@ -73,7 +73,7 @@ public class MurderManager extends MiniClientPlugin<ClientMurder>
} }
} }
@EventHandler @EventHandler (ignoreCancelled = true)
public void onPickup(PlayerPickupItemEvent event) public void onPickup(PlayerPickupItemEvent event)
{ {
refreshClient(event.getPlayer()); refreshClient(event.getPlayer());

View File

@ -131,7 +131,7 @@ public class ObserverManager extends MiniPlugin
} }
} }
@EventHandler @EventHandler (priority = EventPriority.LOWEST)
public void onPickup(PlayerPickupItemEvent event) public void onPickup(PlayerPickupItemEvent event)
{ {
ObserverData data = _observerMap.get(event.getPlayer()); ObserverData data = _observerMap.get(event.getPlayer());

View File

@ -197,18 +197,7 @@ public class ClansRegions extends MiniPlugin
{ {
int x = chunkX + xOffset; int x = chunkX + xOffset;
int z = chunkZ + zOffset; int z = chunkZ + zOffset;
Chunk chunk; String chunkStr = location.getWorld().getName() + "," + x + "," + z;
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) if (addNegative)
{ {

View File

@ -132,7 +132,7 @@ public class SiegeWeaponRepository extends MinecraftRepository
public void updateWeapon(SiegeWeaponToken token) public void updateWeapon(SiegeWeaponToken token)
{ {
System.out.println("Siege Repo> Updating weapon " + token.UniqueId); // System.out.println("Siege Repo> Updating weapon " + token.UniqueId);
_siegeManager.runAsync(() -> _siegeManager.runAsync(() ->
executeUpdate(UPDATE_WEAPON, executeUpdate(UPDATE_WEAPON,

View File

@ -27,6 +27,7 @@ import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.world.ChunkUnloadEvent; import org.bukkit.event.world.ChunkUnloadEvent;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.util.EulerAngle; import org.bukkit.util.EulerAngle;
import org.spigotmc.event.entity.EntityDismountEvent; import org.spigotmc.event.entity.EntityDismountEvent;
@ -559,6 +560,7 @@ public abstract class SiegeWeapon implements Listener
{ {
entity.setCustomName(Integer.toString(_uniqueId)); entity.setCustomName(Integer.toString(_uniqueId));
entity.setCustomNameVisible(false); entity.setCustomNameVisible(false);
entity.setMetadata("Creature.DoNotDrop", new FixedMetadataValue(_clans.getPlugin(), true));
_comprisedOf.add(entity); _comprisedOf.add(entity);
@ -569,6 +571,8 @@ public abstract class SiegeWeapon implements Listener
{ {
Entity entity = _entityMapping.get(uniqueName); Entity entity = _entityMapping.get(uniqueName);
entity.removeMetadata("Creature.DoNotDrop", _clans.getPlugin());
_entityMapping.remove(uniqueName); _entityMapping.remove(uniqueName);
_comprisedOf.remove(entity); _comprisedOf.remove(entity);

View File

@ -113,7 +113,7 @@ public class GoldManager extends MiniPlugin
} }
} }
@EventHandler @EventHandler (ignoreCancelled = true)
public void onPickup(PlayerPickupItemEvent event) public void onPickup(PlayerPickupItemEvent event)
{ {
if (_itemSet.contains(event.getItem())) if (_itemSet.contains(event.getItem()))

View File

@ -868,6 +868,12 @@ public class Gameplay extends MiniPlugin
} }
} }
if (_blockRestore.contains(event.getClickedBlock()))
{
UtilPlayer.message(player, F.main("Repair", "You cannot repair using that anvil"));
return;
}
// Repair! // Repair!
UtilPlayer.message(player, F.main("Repair", "You repaired " + F.item(item.getItemMeta().getDisplayName()) + ".")); UtilPlayer.message(player, F.main("Repair", "You repaired " + F.item(item.getItemMeta().getDisplayName()) + "."));
item.setDurability((short) 0); item.setDurability((short) 0);

View File

@ -29,7 +29,7 @@ import mineplex.minecraft.game.core.damage.CustomDamageEvent;
* @author MrTwiggy * @author MrTwiggy
* *
*/ */
public class CustomItem public class CustomItem implements Listener
{ {
private static final ChatColor TITLE_COLOR = ChatColor.GOLD; // Chat color private static final ChatColor TITLE_COLOR = ChatColor.GOLD; // Chat color
@ -73,6 +73,7 @@ public class CustomItem
_material = material; _material = material;
_attributes = new AttributeContainer(); _attributes = new AttributeContainer();
_uuid = UUID.randomUUID().toString(); _uuid = UUID.randomUUID().toString();
UtilServer.RegisterEvents(this);
} }
public CustomItem(Material material) public CustomItem(Material material)

View File

@ -1,8 +1,12 @@
package mineplex.game.clans.items.attributes; package mineplex.game.clans.items.attributes;
import mineplex.game.clans.clans.ClansManager;
import mineplex.game.clans.clans.ClansUtility;
import mineplex.game.clans.items.generation.ValueDistribution; import mineplex.game.clans.items.generation.ValueDistribution;
import mineplex.minecraft.game.core.damage.CustomDamageEvent; import mineplex.minecraft.game.core.damage.CustomDamageEvent;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerInteractEvent;
@ -127,4 +131,21 @@ public abstract class ItemAttribute
} }
return s; return s;
} }
protected boolean isTeammate(Entity attacker, Entity defender)
{
if (attacker == null || defender == null) return false;
// Don't count attacks towards teammates
if (attacker instanceof Player && defender instanceof Player)
{
ClansUtility.ClanRelation relation = ClansManager.getInstance().getRelation((Player) attacker, (Player) defender);
if (relation == ClansUtility.ClanRelation.ALLY
|| relation == ClansUtility.ClanRelation.SAFE
|| relation == ClansUtility.ClanRelation.SELF)
{
return true;
}
}
return false;
}
} }

View File

@ -41,6 +41,7 @@ public class FlamingAttribute extends AttackAttribute
if(attacker instanceof Player && ClansManager.getInstance().isSafe((Player) attacker)) return; if(attacker instanceof Player && ClansManager.getInstance().isSafe((Player) attacker)) return;
if(defender instanceof Player && ClansManager.getInstance().isSafe((Player) defender)) return; if(defender instanceof Player && ClansManager.getInstance().isSafe((Player) defender)) return;
if(attacker instanceof Player && ((Player)attacker).getGameMode().equals(GameMode.CREATIVE)) return; if(attacker instanceof Player && ((Player)attacker).getGameMode().equals(GameMode.CREATIVE)) return;
if (isTeammate(attacker, defender)) return;
defender.setFireTicks(_fireDuration); defender.setFireTicks(_fireDuration);
} }

View File

@ -54,6 +54,7 @@ public class FrostedAttribute extends ItemAttribute
if (victim != null) if (victim != null)
{ {
if (isTeammate(event.GetDamagerPlayer(true), victim)) return;
victim.addPotionEffect(generateSlowEffect()); // Slow attacking player victim.addPotionEffect(generateSlowEffect()); // Slow attacking player
} }
} }

View File

@ -42,6 +42,7 @@ public class HasteAttribute extends AttackAttribute
@Override @Override
public void triggerAttack(Entity attacker, Entity defender) public void triggerAttack(Entity attacker, Entity defender)
{ {
if (isTeammate(attacker, defender)) return;
if (attacker instanceof Player) if (attacker instanceof Player)
{ {
Player player = (Player) attacker; Player player = (Player) attacker;

View File

@ -28,6 +28,7 @@ public class JaggedAttribute extends AttackAttribute {
@Override @Override
public void triggerAttack(Entity attacker, Entity defender) { public void triggerAttack(Entity attacker, Entity defender) {
if (isTeammate(attacker, defender)) return;
defender.setVelocity(new Vector(0, 0, 0)); defender.setVelocity(new Vector(0, 0, 0));
if (defender instanceof LivingEntity) if (defender instanceof LivingEntity)
((LivingEntity) defender).addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 20, 1, false, false)); ((LivingEntity) defender).addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 20, 1, false, false));

View File

@ -38,6 +38,8 @@ public class VampiricAttribute extends ItemAttribute
{ {
Player damager = event.GetDamagerPlayer(false); Player damager = event.GetDamagerPlayer(false);
if (isTeammate(damager, event.GetDamageePlayer())) return;
double damage = event.GetDamage(); double damage = event.GetDamage();
double healAmount = damage * (_healPercent / 100d); double healAmount = damage * (_healPercent / 100d);
heal(damager, healAmount); heal(damager, healAmount);

View File

@ -1,5 +1,6 @@
package mineplex.game.clans.items.legendaries; package mineplex.game.clans.items.legendaries;
import mineplex.core.recharge.Recharge;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.Sound; import org.bukkit.Sound;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -14,7 +15,7 @@ import mineplex.minecraft.game.core.damage.CustomDamageEvent;
public class GiantsBroadsword extends LegendaryItem public class GiantsBroadsword extends LegendaryItem
{ {
public static final int SLOW_AMPLIFIER = 43; public static final int SLOW_AMPLIFIER = 43;
public static final int REGEN_AMPLIFIER = 3; public static final int REGEN_AMPLIFIER = 1;
public GiantsBroadsword() public GiantsBroadsword()
{ {
@ -60,6 +61,7 @@ public class GiantsBroadsword extends LegendaryItem
private void buffPlayer(Player player) private void buffPlayer(Player player)
{ {
grantPotionEffect(player, PotionEffectType.SLOW, 40, SLOW_AMPLIFIER); grantPotionEffect(player, PotionEffectType.SLOW, 40, SLOW_AMPLIFIER);
grantPotionEffect(player, PotionEffectType.REGENERATION, 2, REGEN_AMPLIFIER); //Regen if (Recharge.Instance.use(player, "Giants Broadsword Regen", 250L, false, false, false))
grantPotionEffect(player, PotionEffectType.REGENERATION, 5, REGEN_AMPLIFIER); //Regen
} }
} }

View File

@ -31,7 +31,7 @@ public class HyperAxe extends LegendaryItem
C.cWhite + "blade can rip through any opponent.", C.cWhite + "blade can rip through any opponent.",
C.cWhite + " ", C.cWhite + " ",
C.cWhite + "Hit delay is reduced by " + C.cYellow + "50%", C.cWhite + "Hit delay is reduced by " + C.cYellow + "50%",
C.cWhite + "Deals " + C.cYellow + "10 Damage" + C.cWhite + " with attack", C.cWhite + "Deals " + C.cYellow + "3 Damage" + C.cWhite + " with attack",
C.cYellow + "Right-Click" + C.cWhite + " to use " + C.cGreen + "Dash", C.cYellow + "Right-Click" + C.cWhite + " to use " + C.cGreen + "Dash",
}, Material.RECORD_3); }, Material.RECORD_3);
_speedAmount = amountGen.generateIntValue(); _speedAmount = amountGen.generateIntValue();

View File

@ -1,11 +1,6 @@
package mineplex.game.clans.items.legendaries; package mineplex.game.clans.items.legendaries;
import org.bukkit.Location; import mineplex.core.common.util.C;
import org.bukkit.Material;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import mineplex.core.common.util.UtilAction; import mineplex.core.common.util.UtilAction;
import mineplex.core.common.util.UtilAlg; import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilMath; import mineplex.core.common.util.UtilMath;
@ -18,6 +13,12 @@ import mineplex.core.common.util.UtilWorld;
import mineplex.game.clans.clans.ClansManager; import mineplex.game.clans.clans.ClansManager;
import mineplex.minecraft.game.core.damage.CustomDamageEvent; import mineplex.minecraft.game.core.damage.CustomDamageEvent;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
public class MagneticMaul extends LegendaryItem public class MagneticMaul extends LegendaryItem
{ {
public static final double PULL_RANGE = 10d; public static final double PULL_RANGE = 10d;
@ -27,8 +28,10 @@ public class MagneticMaul extends LegendaryItem
public MagneticMaul() public MagneticMaul()
{ {
super("Magnetic Maul", new String[]{ super("Magnetic Maul", new String[] {
C.cWhite + "This brutal weapon allows you to pull your enemies towards you with magnetic force!"
+ " ",
C.cYellow + "Right-Click" + C.cWhite + " to use Maul."
}, Material.RECORD_5); }, Material.RECORD_5);
} }

View File

@ -1,17 +1,6 @@
package mineplex.game.clans.items.legendaries; package mineplex.game.clans.items.legendaries;
import org.bukkit.GameMode; import java.util.HashMap;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.Vector;
import mineplex.core.common.util.C; import mineplex.core.common.util.C;
import mineplex.core.common.util.F; import mineplex.core.common.util.F;
@ -20,26 +9,37 @@ import mineplex.core.common.util.RGBData;
import mineplex.core.common.util.UtilBlock; import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilCollections; import mineplex.core.common.util.UtilCollections;
import mineplex.core.common.util.UtilColor; import mineplex.core.common.util.UtilColor;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilParticle; import mineplex.core.common.util.UtilParticle;
import mineplex.core.common.util.UtilParticle.ParticleType; import mineplex.core.common.util.UtilParticle.ParticleType;
import mineplex.core.common.util.UtilParticle.ViewDist; import mineplex.core.common.util.UtilParticle.ViewDist;
import mineplex.core.incognito.IncognitoManager;
import mineplex.core.common.util.UtilPlayer; import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer; import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilShapes; import mineplex.core.common.util.UtilShapes;
import mineplex.core.common.util.UtilText; import mineplex.core.common.util.UtilText;
import mineplex.core.common.util.UtilTime;
import mineplex.core.common.util.UtilTime.TimeUnit;
import mineplex.core.recharge.Recharge; import mineplex.core.recharge.Recharge;
import mineplex.game.clans.clans.ClansManager; import mineplex.game.clans.clans.ClansManager;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.Vector;
public class MeridianScepter extends LegendaryItem public class MeridianScepter extends LegendaryItem
{ {
private long _lastFire = System.currentTimeMillis();
private long _interactWait; private long _interactWait;
private RGBData[] colors = { UtilColor.RgbPurple, UtilColor.RgbPurple.Lighten(), UtilColor.RgbPurple.Darken() }; private RGBData[] colors = { UtilColor.RgbPurple, UtilColor.RgbPurple.Lighten(), UtilColor.RgbPurple.Darken() };
private int _witherDamageTimes = 5; private HashMap<AttackAnimation, Integer> _animations = new HashMap<AttackAnimation, Integer>();
public MeridianScepter() public MeridianScepter()
{ {
@ -101,20 +101,13 @@ public class MeridianScepter extends LegendaryItem
// If they are less than 0.5 blocks away // If they are less than 0.5 blocks away
if (player.getEyeLocation().subtract(0, .3, 0).distance(projectile) <= 2) if (player.getEyeLocation().subtract(0, .3, 0).distance(projectile) <= 2)
{ {
player.addPotionEffect(new PotionEffect(PotionEffectType.WITHER, 20 * _witherDamageTimes, 0)); AttackAnimation aa = new AttackAnimation(player, shooter);
int i = UtilServer.getServer().getScheduler().scheduleSyncRepeatingTask(UtilServer.getPlugin(), () -> {
aa.update();
}, 0, 1);
_animations.put(aa, i);
int time = 0; UtilPlayer.message(player, F.main("Clans", F.elem(shooter.getName()) + " hit you with a " + F.elem("Meridian Scepter") + C.mBody + "."));
for (int i = 0; i < _witherDamageTimes; i++)
{
UtilServer.getServer().getScheduler().scheduleSyncDelayedTask(UtilServer.getPlugin(), () -> {
ClansManager.getInstance().getDamageManager().NewDamageEvent(player, shooter, null,
DamageCause.CUSTOM, 1.75, false, true, true,
shooter.getName(), "Meridian Scepter");
}, ++time * 20);
}
UtilPlayer.message(player, F.main("Clans", F.elem(player.getName()) + " hit you with a " + F.elem("Meridian Scepter") + C.mBody + "."));
UtilPlayer.message(shooter, F.main("Clans", "You hit " + F.elem(player.getName()) + " with your " + F.elem("Meridian Scepter") + C.mBody + ".")); UtilPlayer.message(shooter, F.main("Clans", "You hit " + F.elem(player.getName()) + " with your " + F.elem("Meridian Scepter") + C.mBody + "."));
} }
} }
@ -258,4 +251,68 @@ public class MeridianScepter extends LegendaryItem
UtilParticle.PlayParticleToAll(ParticleType.RED_DUST, loc, UtilCollections.random(colors).ToVector(), 1f, 0, ViewDist.LONG); UtilParticle.PlayParticleToAll(ParticleType.RED_DUST, loc, UtilCollections.random(colors).ToVector(), 1f, 0, ViewDist.LONG);
} }
} }
private class AttackAnimation
{
private Player _hit, _shooter;
private double _step;
private double _radius;
private long _start, _lastStepIncrease;
public AttackAnimation(Player hit, Player shooter)
{
_step = 0;
_start = System.currentTimeMillis();
_lastStepIncrease = System.currentTimeMillis();
_hit = hit;
_shooter = shooter;
_radius = 2;
}
public void update()
{
if (_hit == null)
{
end();
return;
}
if (UtilTime.elapsed(_lastStepIncrease, UtilTime.convert(1, TimeUnit.SECONDS, TimeUnit.MILLISECONDS)))
{
_step++;
_lastStepIncrease = System.currentTimeMillis();
}
drawHelix();
if (UtilTime.elapsed(_start, 4000))
{
_hit.getWorld().strikeLightningEffect(_hit.getLocation());
ClansManager.getInstance().getDamageManager().NewDamageEvent(_hit, _shooter, null,
DamageCause.CUSTOM, 6, false, true, true,
_shooter.getName(), "Meridian Scepter");
ClansManager.getInstance().getCondition().Factory().Blind("Meridian Scepter", _hit, _shooter, 1, 0, true, true, true);
end();
return;
}
}
private void end()
{
int id = _animations.remove(this);
Bukkit.getScheduler().cancelTask(id);
}
private void drawHelix()
{
double height = Math.min(_step * 2, 8D);
for (double y = 0; y <= height; y += .5)
{
double x = _radius * Math.cos(y);
double z = _radius * Math.sin(y);
Location play = _hit.getLocation().add(x, y, z);
UtilParticle.PlayParticleToAll(ParticleType.WITCH_MAGIC, play, null, 0, 3, ViewDist.MAX);
}
}
}
} }

View File

@ -1,9 +1,14 @@
package mineplex.game.clans.items.legendaries; package mineplex.game.clans.items.legendaries;
import mineplex.game.clans.items.GearManager;
import mineplex.game.clans.items.PlayerGear;
import net.minecraft.server.v1_8_R3.PlayerConnection;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.Sound; import org.bukkit.Sound;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause; import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import mineplex.core.common.util.C; import mineplex.core.common.util.C;
@ -16,13 +21,29 @@ import mineplex.core.common.util.UtilParticle.ParticleType;
import mineplex.core.common.util.UtilParticle.ViewDist; import mineplex.core.common.util.UtilParticle.ViewDist;
import mineplex.core.common.util.UtilPlayer; import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilTextBottom; import mineplex.core.common.util.UtilTextBottom;
import mineplex.core.common.util.UtilTextMiddle;
import mineplex.core.common.util.UtilTime; import mineplex.core.common.util.UtilTime;
import mineplex.core.recharge.Recharge; import mineplex.core.recharge.Recharge;
import mineplex.minecraft.game.core.damage.CustomDamageEvent; import mineplex.minecraft.game.core.damage.CustomDamageEvent;
import java.lang.reflect.Field;
public class WindBlade extends LegendaryItem public class WindBlade extends LegendaryItem
{ {
private static final Field G_FIELD;
static
{
try
{
G_FIELD = PlayerConnection.class.getDeclaredField("g");
G_FIELD.setAccessible(true);
}
catch (ReflectiveOperationException exception)
{
throw new RuntimeException("Could not reflectively access field", exception);
}
}
public static final double FLIGHT_VELOCITY = 0.75d; public static final double FLIGHT_VELOCITY = 0.75d;
private double _power; private double _power;
@ -32,7 +53,7 @@ public class WindBlade extends LegendaryItem
public WindBlade() public WindBlade()
{ {
super("Wind Blade", new String[] { super("Wind Blade", new String[]{
C.cWhite + "Long ago, a race of cloud dwellers", C.cWhite + "Long ago, a race of cloud dwellers",
C.cWhite + "terrorized the skies. A remnant of", C.cWhite + "terrorized the skies. A remnant of",
C.cWhite + "their tyranny, this airy blade is", C.cWhite + "their tyranny, this airy blade is",
@ -129,12 +150,35 @@ public class WindBlade extends LegendaryItem
event.AddMod("Wind Blade", 6); event.AddMod("Wind Blade", 6);
} }
@EventHandler
public void onFall(CustomDamageEvent event)
{
if (event.GetDamageePlayer() != null && event.GetCause() == EntityDamageEvent.DamageCause.FALL)
{
PlayerGear playerGear = GearManager.getInstance().getPlayerGear(event.GetDamageePlayer());
if (playerGear.getWeapon() instanceof WindBlade)
{
event.SetCancelled("Wind Blade No Fall Damage");
}
}
}
private void propelPlayer(Player player) private void propelPlayer(Player player)
{ {
Vector direction = player.getLocation().getDirection().normalize(); Vector direction = player.getLocation().getDirection().normalize();
direction.multiply(FLIGHT_VELOCITY); direction.multiply(FLIGHT_VELOCITY);
player.setVelocity(direction); player.setVelocity(direction);
PlayerConnection connection = ((CraftPlayer) player).getHandle().playerConnection;
try
{
G_FIELD.set(connection, 0);
}
catch (IllegalAccessException e)
{
new RuntimeException("Could not update g field", e).printStackTrace();
}
} }
private boolean canPropel(Player player) private boolean canPropel(Player player)

View File

@ -213,6 +213,15 @@ public class Spawn extends MiniPlugin
} }
} }
@EventHandler
public void ignoreVelocity(PlayerVelocityEvent event)
{
if (_clansManager.getClanUtility().isSafe(event.getPlayer()))
{
event.setCancelled(true);
}
}
@EventHandler @EventHandler
public void onSkill(SkillTriggerEvent event) public void onSkill(SkillTriggerEvent event)
{ {
@ -391,13 +400,13 @@ public class Spawn extends MiniPlugin
if (isInSpawn(victim)) if (isInSpawn(victim))
{ {
event.SetCancelled("Safe Zone"); event.SetCancelled("Safe Zone");
attemptNotify(attacker, "You cannot attack players who are in spawn!"); attemptNotify(attacker, "You cannot attack players who are in a safe zone!");
return; return;
} }
else if (isInSpawn(attacker) && !isCombatTagged(attacker)) else if (isInSpawn(attacker) && !isCombatTagged(attacker))
{ {
event.SetCancelled("Safe Zone"); event.SetCancelled("Safe Zone");
attemptNotify(attacker, "You cannot attack untagged players while in spawn!"); attemptNotify(attacker, "You cannot attack untagged players while in a safe zone!");
return; return;
} }
} }

View File

@ -2,6 +2,7 @@ package mineplex.game.clans.tutorial;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.LinkedList;
import java.util.Stack; import java.util.Stack;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -25,7 +26,7 @@ public class TutorialWorldManager extends MiniPlugin
private final World _tutorialWorld; private final World _tutorialWorld;
private final Schematic _schematic; private final Schematic _schematic;
private Stack<TutorialRegion> _regionStack; private LinkedList<TutorialRegion> _regionStack;
private TutorialRegion _centerRegion; private TutorialRegion _centerRegion;
public TutorialWorldManager(JavaPlugin plugin, String worldName, String schematicName) throws IOException public TutorialWorldManager(JavaPlugin plugin, String worldName, String schematicName) throws IOException
@ -56,7 +57,7 @@ public class TutorialWorldManager extends MiniPlugin
private void populateRegionStack() private void populateRegionStack()
{ {
_regionStack = new Stack<>(); _regionStack = new LinkedList<>();
// Populate the stack with 100 available tutorial regions // Populate the stack with 100 available tutorial regions
for (int x = 0; x < 10; x++) for (int x = 0; x < 10; x++)

View File

@ -10,14 +10,16 @@ public class FinishCommand extends CommandBase<TutorialManager>
{ {
public FinishCommand(TutorialManager plugin) public FinishCommand(TutorialManager plugin)
{ {
super(plugin, Rank.JNR_DEV, "finish", "end"); super(plugin, Rank.ALL, "finish", "end");
} }
@Override @Override
public void Execute(Player caller, String[] args) public void Execute(Player caller, String[] args)
{
boolean testServer = Plugin.getPlugin().getConfig().getString("serverstatus.group").equalsIgnoreCase("Testing");
if (_commandCenter.GetClientManager().hasRank(caller, testServer ? Rank.ALL : Rank.JNR_DEV))
{ {
Plugin.finishTutorial(caller); Plugin.finishTutorial(caller);
}
} }
} }

View File

@ -1,19 +1,17 @@
package mineplex.game.clans.tutorial.command; package mineplex.game.clans.tutorial.command;
import org.bukkit.entity.Player;
import mineplex.core.command.CommandBase;
import mineplex.core.command.MultiCommandBase; import mineplex.core.command.MultiCommandBase;
import mineplex.core.common.Rank; import mineplex.core.common.Rank;
import mineplex.core.common.util.F; import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer; import mineplex.core.common.util.UtilPlayer;
import mineplex.game.clans.tutorial.TutorialManager; import mineplex.game.clans.tutorial.TutorialManager;
import org.bukkit.entity.Player;
public class TutorialCommand extends MultiCommandBase<TutorialManager> public class TutorialCommand extends MultiCommandBase<TutorialManager>
{ {
public TutorialCommand(TutorialManager plugin) public TutorialCommand(TutorialManager plugin)
{ {
super(plugin, Rank.JNR_DEV, "tutorial", "tut"); super(plugin, Rank.ALL, "tutorial", "tut");
AddCommand(new StartCommand(plugin)); AddCommand(new StartCommand(plugin));
AddCommand(new FinishCommand(plugin)); AddCommand(new FinishCommand(plugin));
@ -24,4 +22,14 @@ public class TutorialCommand extends MultiCommandBase<TutorialManager>
{ {
UtilPlayer.message(caller, F.main("Tutorial", "/tutorial start <name>")); UtilPlayer.message(caller, F.main("Tutorial", "/tutorial start <name>"));
} }
@Override
public void Execute(Player caller, String[] args)
{
boolean testServer = Plugin.getPlugin().getConfig().getString("serverstatus.group").equalsIgnoreCase("Testing");
if (_commandCenter.GetClientManager().hasRank(caller, testServer ? Rank.ALL : Rank.JNR_DEV))
{
super.Execute(caller, args);
}
}
} }

View File

@ -1,5 +1,7 @@
package mineplex.game.clans.tutorial.tutorials.clans.objective.goals.attackenemy; package mineplex.game.clans.tutorial.tutorials.clans.objective.goals.attackenemy;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
@ -8,6 +10,8 @@ import mineplex.core.common.util.UtilInv;
import mineplex.game.clans.clans.siege.events.LoadSiegeWeaponEvent; import mineplex.game.clans.clans.siege.events.LoadSiegeWeaponEvent;
import mineplex.game.clans.tutorial.objective.ObjectiveGoal; import mineplex.game.clans.tutorial.objective.ObjectiveGoal;
import mineplex.game.clans.tutorial.tutorials.clans.objective.AttackEnemyObjective; import mineplex.game.clans.tutorial.tutorials.clans.objective.AttackEnemyObjective;
import org.bukkit.event.EventPriority;
import org.bukkit.event.block.BlockPlaceEvent;
public class LoadCannonGoal extends ObjectiveGoal<AttackEnemyObjective> public class LoadCannonGoal extends ObjectiveGoal<AttackEnemyObjective>
{ {
@ -43,4 +47,15 @@ public class LoadCannonGoal extends ObjectiveGoal<AttackEnemyObjective>
finish(event.getPlayer()); finish(event.getPlayer());
} }
@EventHandler (priority = EventPriority.MONITOR)
public void onBlockPlace(BlockPlaceEvent event)
{
if (!contains(event.getPlayer()))
{
return;
}
UtilPlayer.message(event.getPlayer(), F.main("Clans", "Are you sure? That's the only TNT you have!"));
event.setCancelled(true);
}
} }

View File

@ -1,25 +1,67 @@
package mineplex.game.clans.world; package mineplex.game.clans.world;
import java.util.ArrayList; import java.util.*;
import java.util.HashMap;
import org.bukkit.Bukkit; import mineplex.core.common.util.UtilWorld;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType; import org.bukkit.entity.EntityType;
import org.bukkit.entity.Item;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import mineplex.core.MiniPlugin; import mineplex.core.MiniPlugin;
import mineplex.core.common.util.UtilMath;
import mineplex.core.updater.UpdateType; import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent; import mineplex.core.updater.event.UpdateEvent;
import mineplex.game.clans.clans.ClansManager;
public class WorldManager extends MiniPlugin public class WorldManager extends MiniPlugin
{ {
private static final Map<EntityType, Integer> CULL_LIMITS = new HashMap<>();
private static final Set<EntityType> MINECART_TYPES = new HashSet<>();
private static final int MIN_RANGE = 64;
private static final int MIN_RANGE_SQUARED = MIN_RANGE * MIN_RANGE;
static
{
// Animals
CULL_LIMITS.put(EntityType.BAT, 50);
CULL_LIMITS.put(EntityType.CHICKEN, 150);
CULL_LIMITS.put(EntityType.COW, 150);
CULL_LIMITS.put(EntityType.HORSE, 50);
CULL_LIMITS.put(EntityType.IRON_GOLEM, 50);
CULL_LIMITS.put(EntityType.MUSHROOM_COW, 50);
CULL_LIMITS.put(EntityType.OCELOT, 50);
CULL_LIMITS.put(EntityType.PIG, 150);
CULL_LIMITS.put(EntityType.RABBIT, 50);
CULL_LIMITS.put(EntityType.SHEEP, 150);
CULL_LIMITS.put(EntityType.WOLF, 150);
// Monsters
CULL_LIMITS.put(EntityType.CAVE_SPIDER, 100);
CULL_LIMITS.put(EntityType.CREEPER, 100);
CULL_LIMITS.put(EntityType.ENDERMAN, 50);
CULL_LIMITS.put(EntityType.ENDERMITE, 50);
CULL_LIMITS.put(EntityType.SILVERFISH, 50);
CULL_LIMITS.put(EntityType.SKELETON, 100);
CULL_LIMITS.put(EntityType.SLIME, 50);
CULL_LIMITS.put(EntityType.SPIDER, 100);
CULL_LIMITS.put(EntityType.ZOMBIE, 100);
// Nether
CULL_LIMITS.put(EntityType.BLAZE, 50);
CULL_LIMITS.put(EntityType.GHAST, 50);
CULL_LIMITS.put(EntityType.MAGMA_CUBE, 50);
CULL_LIMITS.put(EntityType.PIG_ZOMBIE, 50);
MINECART_TYPES.add(EntityType.MINECART);
MINECART_TYPES.add(EntityType.MINECART_CHEST);
MINECART_TYPES.add(EntityType.MINECART_COMMAND);
MINECART_TYPES.add(EntityType.MINECART_FURNACE);
MINECART_TYPES.add(EntityType.MINECART_HOPPER);
MINECART_TYPES.add(EntityType.MINECART_MOB_SPAWNER);
MINECART_TYPES.add(EntityType.MINECART_TNT);
}
public WorldManager(JavaPlugin plugin) public WorldManager(JavaPlugin plugin)
{ {
super("Clan World Manager", plugin); super("Clan World Manager", plugin);
@ -33,118 +75,77 @@ public class WorldManager extends MiniPlugin
for (World world : getPlugin().getServer().getWorlds()) for (World world : getPlugin().getServer().getWorlds())
{ {
HashMap<EntityType, ArrayList<Entity>> _ents = new HashMap<EntityType, ArrayList<Entity>>(); List<Player> players = world.getPlayers();
Map<EntityType, Set<Entity>> entities = new HashMap<>();
for (EntityType type : EntityType.values()) for (Entity entity : world.getEntities())
_ents.put(type, new ArrayList<Entity>());
for (Entity ent : world.getEntities())
{ {
if (ent.getCustomName() == null) if (entity.getCustomName() != null)
{
continue;
}
EntityType entityType = entity.getType();
if (entityType == EntityType.ARROW)
{
if (entity.getTicksLived() > 800)
{
entity.remove();
}
}
else if (entityType == EntityType.DROPPED_ITEM)
{
if (entity.getTicksLived() > 2400)
{
entity.remove();
}
}
else if (CULL_LIMITS.containsKey(entityType))
{ {
boolean cull = true; boolean cull = true;
for (Player player : players)
for (Player player : world.getPlayers())
{ {
if (player.getLocation().distance(ent.getLocation()) <= 64) // Using NMS because this is going to be called quite a few times
// and each getLocation() call creates a new Location object
if (UtilWorld.distanceSquared(player, entity) <= MIN_RANGE_SQUARED)
{ {
cull = false; cull = false;
break; break;
} }
} }
if (cull) if (cull)
{ {
_ents.get(ent.getType()).add(ent); entities.computeIfAbsent(entityType, key -> new HashSet<>()).add(entity);
} }
} }
} else if (MINECART_TYPES.contains(entityType))
for (EntityType type : _ents.keySet())
{ {
ArrayList<Entity> ents = _ents.get(type); if (entity.getTicksLived() > 800)
//Clean Old Arrows
if (type == EntityType.ARROW)
{ {
for (Entity ent : ents) entity.remove();
if (ent.getTicksLived() > 800) }
ent.remove(); }
} }
//Clean Old Items for (Map.Entry<EntityType, Set<Entity>> entry : entities.entrySet())
if (type == EntityType.DROPPED_ITEM)
{ {
for (Entity ent : ents) cull(entry.getKey(), entry.getValue(), CULL_LIMITS.get(entry.getKey()));
if (ent.getTicksLived() > 2400) }
ent.remove(); }
} }
//Animals private void cull(EntityType type, Set<Entity> ents, int limit)
else if (type == EntityType.BAT) cull(ents, 50);
else if (type == EntityType.CHICKEN) cull(ents, 150);
else if (type == EntityType.COW) cull(ents, 150);
else if (type == EntityType.HORSE) cull(ents, 50);
else if (type == EntityType.IRON_GOLEM) cull(ents, 50);
else if (type == EntityType.MUSHROOM_COW) cull(ents, 50);
else if (type == EntityType.OCELOT) cull(ents, 50);
else if (type == EntityType.PIG) cull(ents, 150);
else if (type == EntityType.RABBIT) cull(ents, 50);
else if (type == EntityType.SHEEP) cull(ents, 150);
else if (type == EntityType.WOLF) cull(ents, 150);
//Monster
else if (type == EntityType.CAVE_SPIDER) cull(ents, 100);
else if (type == EntityType.CREEPER) cull(ents, 100);
else if (type == EntityType.ENDERMAN) cull(ents, 50);
else if (type == EntityType.ENDERMITE) cull(ents, 50);
else if (type == EntityType.SILVERFISH) cull(ents, 50);
else if (type == EntityType.SKELETON) cull(ents, 100);
else if (type == EntityType.SLIME) cull(ents, 50);
else if (type == EntityType.SPIDER) cull(ents, 100);
else if (type == EntityType.ZOMBIE) cull(ents, 100);
//Nether
else if (type == EntityType.BLAZE) cull(ents, 50);
else if (type == EntityType.GHAST) cull(ents, 50);
else if (type == EntityType.MAGMA_CUBE) cull(ents, 50);
else if (type == EntityType.PIG_ZOMBIE) cull(ents, 50);
//Clean Old Minecarts
if (type == EntityType.MINECART ||
type == EntityType.MINECART_CHEST ||
type == EntityType.MINECART_COMMAND ||
type == EntityType.MINECART_FURNACE ||
type == EntityType.MINECART_HOPPER ||
type == EntityType.MINECART_MOB_SPAWNER ||
type == EntityType.MINECART_TNT)
{
for (Entity ent : ents)
if (ent.getTicksLived() > 800)
ent.remove();
}
}
}
}
public void cull(ArrayList<Entity> ents, int limit)
{ {
Iterator<Entity> iterator = ents.iterator();
int culled = 0; int culled = 0;
EntityType type = null; while (iterator.hasNext() && ents.size() > limit)
while (ents.size() > limit)
{ {
Entity ent = ents.remove(UtilMath.r(ents.size())); Entity entity = iterator.next();
entity.remove();
type = ent.getType(); iterator.remove();
ent.remove();
culled++; culled++;
} }
log("Culled " + culled + " " + type);
if (type != null)
{
System.out.println("Culled " + culled + " " + type);
}
} }
} }

View File

@ -78,7 +78,7 @@ public class Leap extends SkillActive
{ {
//Action //Action
if (!wallkick) if (!wallkick)
UtilAction.velocity(player, 1.2, 0.2, 1, true); UtilAction.velocity(player, 1 + 0.15 * level, 0.2, 1, true);
else else
{ {
Vector vec = player.getLocation().getDirection(); Vector vec = player.getLocation().getDirection();

View File

@ -60,11 +60,6 @@ public class Recall extends Skill
{ {
Player player = event.getPlayer(); Player player = event.getPlayer();
if (!(player.getOpenInventory().getTopInventory() instanceof CraftInventoryCrafting))
{
return;
}
int level = getLevel(player); int level = getLevel(player);
if (level == 0) if (level == 0)
return; return;
@ -92,6 +87,7 @@ public class Recall extends Skill
if (health == null) if (health == null)
return; return;
Factory.runSync(() -> {
//Heal //Heal
double newHealth = Math.min(health.getLast(), player.getHealth() + 3 + level); double newHealth = Math.min(health.getLast(), player.getHealth() + 3 + level);
player.setHealth(newHealth); player.setHealth(newHealth);
@ -117,19 +113,9 @@ public class Recall extends Skill
ViewDist.LONGER, UtilServer.getPlayers()); ViewDist.LONGER, UtilServer.getPlayers());
current = current.add(UtilAlg.getTrajectory(current, target).multiply(0.1)); current = current.add(UtilAlg.getTrajectory(current, target).multiply(0.1));
} }
});
} }
@EventHandler
public void closeInv(InventoryCloseEvent event)
{
if (getLevel(event.getPlayer()) == 0)
{
return;
}
event.getPlayer().getInventory().addItem(event.getPlayer().getItemOnCursor());
event.getPlayer().setItemOnCursor(null);
}
@EventHandler @EventHandler
public void storeLocation(UpdateEvent event) public void storeLocation(UpdateEvent event)

View File

@ -2,6 +2,7 @@ package mineplex.minecraft.game.classcombat.Skill.Brute;
import java.util.HashMap; import java.util.HashMap;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.Sound; import org.bukkit.Sound;
@ -167,18 +168,20 @@ public class Takedown extends SkillActive
int damage = 3 + (level); int damage = 3 + (level);
//Damage Event //Damage Event
Factory.Damage().NewDamageEvent(damagee, damager, null, CustomDamageEvent customDamageEvent = Factory.Damage().NewDamageEvent(damagee, damager, null,
DamageCause.CUSTOM, damage, false, true, false, DamageCause.CUSTOM, damage, false, true, false,
damager.getName(), GetName()); damager.getName(), GetName());
if (!customDamageEvent.IsCancelled())
{
//Damage Event //Damage Event
Factory.Damage().NewDamageEvent(damager, damagee, null, Factory.Damage().NewDamageEvent(damager, damagee, null,
DamageCause.CUSTOM, damage/2, false, true, false, DamageCause.CUSTOM, damage / 2, false, true, false,
damager.getName(), GetName() + " Recoil"); damager.getName(), GetName() + " Recoil");
//Conditions //Conditions
Factory.Condition().Factory().Slow(GetName(), damagee, damager, 2.5 + 0.5*level, 3, false, true, true, true); Factory.Condition().Factory().Slow(GetName(), damagee, damager, 2.5 + 0.5 * level, 3, false, true, true, true);
Factory.Condition().Factory().Slow(GetName(), damager, damager, 2.5 + 0.5*level, 3, false, true, true, true); Factory.Condition().Factory().Slow(GetName(), damager, damager, 2.5 + 0.5 * level, 3, false, true, true, true);
//Inform //Inform
UtilPlayer.message(damager, F.main(GetClassType().name(), "You hit " + F.name(UtilEnt.getName(damagee)) + " with " + F.skill(GetName(level)) + ".")); UtilPlayer.message(damager, F.main(GetClassType().name(), "You hit " + F.name(UtilEnt.getName(damagee)) + " with " + F.skill(GetName(level)) + "."));
@ -187,6 +190,7 @@ public class Takedown extends SkillActive
//Sound //Sound
damager.getWorld().playSound(damager.getLocation(), Sound.ZOMBIE_WOOD, 1f, 0.5f); damager.getWorld().playSound(damager.getLocation(), Sound.ZOMBIE_WOOD, 1f, 0.5f);
} }
}
@EventHandler @EventHandler
public void Particle(UpdateEvent event) public void Particle(UpdateEvent event)

View File

@ -1,5 +1,6 @@
package mineplex.minecraft.game.classcombat.Skill.Knight; package mineplex.minecraft.game.classcombat.Skill.Knight;
import mineplex.minecraft.game.core.condition.events.ConditionExpireEvent;
import org.bukkit.Effect; import org.bukkit.Effect;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.Sound; import org.bukkit.Sound;
@ -22,6 +23,10 @@ import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent; import mineplex.core.updater.event.UpdateEvent;
import mineplex.minecraft.game.classcombat.Skill.SkillActive; import mineplex.minecraft.game.classcombat.Skill.SkillActive;
import mineplex.minecraft.game.classcombat.Skill.SkillFactory; import mineplex.minecraft.game.classcombat.Skill.SkillFactory;
import org.bukkit.event.player.PlayerQuitEvent;
import java.util.HashMap;
import java.util.Map;
public class HoldPosition extends SkillActive public class HoldPosition extends SkillActive
{ {
@ -47,10 +52,13 @@ public class HoldPosition extends SkillActive
}); });
} }
private final Map<Player, Integer> _foodLevel = new HashMap<>();
@Override @Override
public boolean CustomCheck(Player player, int level) public boolean CustomCheck(Player player, int level)
{ {
if (player.getLocation().getBlock().getTypeId() == 8 || player.getLocation().getBlock().getTypeId() == 9) Material type = player.getLocation().getBlock().getType();
if (type == Material.WATER || type == Material.STATIONARY_WATER)
{ {
UtilPlayer.message(player, F.main("Skill", "You cannot use " + F.skill(GetName()) + " in water.")); UtilPlayer.message(player, F.main("Skill", "You cannot use " + F.skill(GetName()) + " in water."));
return false; return false;
@ -75,6 +83,8 @@ public class HoldPosition extends SkillActive
//Effect //Effect
player.getWorld().playSound(player.getLocation(), Sound.ENDERMAN_SCREAM, 1.5f, 0f); player.getWorld().playSound(player.getLocation(), Sound.ENDERMAN_SCREAM, 1.5f, 0f);
player.getWorld().playEffect(player.getLocation(), Effect.STEP_SOUND, 49); player.getWorld().playEffect(player.getLocation(), Effect.STEP_SOUND, 49);
_foodLevel.put(player, player.getFoodLevel());
} }
@EventHandler(priority = EventPriority.HIGH) @EventHandler(priority = EventPriority.HIGH)
@ -123,6 +133,30 @@ public class HoldPosition extends SkillActive
} }
} }
@EventHandler
public void on(ConditionExpireEvent event)
{
if (event.getCondition().GetReason().equals(GetName()) && event.getCondition().GetEnt() instanceof Player)
{
if (event.getCondition().GetType() == ConditionType.DAMAGE_RESISTANCE)
{
Player player = ((Player) event.getCondition().GetEnt());
if (_foodLevel.get(player) != null)
{
player.setFoodLevel(_foodLevel.get(player));
}
// Could be null value. Sanity check
_foodLevel.remove(player);
}
}
}
@EventHandler
public void on(PlayerQuitEvent event)
{
_foodLevel.remove(event.getPlayer());
}
@Override @Override
public void Reset(Player player) public void Reset(Player player)
{ {

View File

@ -7,6 +7,7 @@ import java.util.Map.Entry;
import java.util.WeakHashMap; import java.util.WeakHashMap;
import mineplex.core.MiniPlugin; import mineplex.core.MiniPlugin;
import mineplex.core.common.util.UtilServer;
import mineplex.core.recharge.Recharge; import mineplex.core.recharge.Recharge;
import mineplex.core.updater.event.UpdateEvent; import mineplex.core.updater.event.UpdateEvent;
import mineplex.core.updater.UpdateType; import mineplex.core.updater.UpdateType;
@ -18,6 +19,7 @@ import mineplex.core.common.util.UtilTime;
import mineplex.core.common.util.UtilTime.TimeUnit; import mineplex.core.common.util.UtilTime.TimeUnit;
import mineplex.minecraft.game.core.condition.Condition.ConditionType; import mineplex.minecraft.game.core.condition.Condition.ConditionType;
import mineplex.minecraft.game.core.condition.events.ConditionApplyEvent; import mineplex.minecraft.game.core.condition.events.ConditionApplyEvent;
import mineplex.minecraft.game.core.condition.events.ConditionExpireEvent;
import mineplex.minecraft.game.core.damage.DamageManager; import mineplex.minecraft.game.core.damage.DamageManager;
import org.bukkit.Material; import org.bukkit.Material;
@ -189,9 +191,13 @@ public class ConditionManager extends MiniPlugin
Condition cond = conditionIterator.next(); Condition cond = conditionIterator.next();
if (cond.Tick()) if (cond.Tick())
{
ConditionExpireEvent conditionExpireEvent = new ConditionExpireEvent(cond);
UtilServer.CallEvent(conditionExpireEvent);
conditionIterator.remove(); conditionIterator.remove();
} }
} }
}
/** Indicators **/ /** Indicators **/
for (LivingEntity ent : _activeConditions.keySet()) for (LivingEntity ent : _activeConditions.keySet())

View File

@ -0,0 +1,33 @@
package mineplex.minecraft.game.core.condition.events;
import mineplex.minecraft.game.core.condition.Condition;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
public class ConditionExpireEvent extends Event
{
private static final HandlerList handlers = new HandlerList();
private Condition _cond;
public ConditionExpireEvent(Condition cond)
{
_cond = cond;
}
public HandlerList getHandlers()
{
return handlers;
}
public static HandlerList getHandlerList()
{
return handlers;
}
public Condition getCondition()
{
return _cond;
}
}

View File

@ -171,36 +171,38 @@ public class DamageManager extends MiniPlugin
} }
*/ */
public void NewDamageEvent(LivingEntity damagee, LivingEntity damager, Projectile proj, public CustomDamageEvent NewDamageEvent(LivingEntity damagee, LivingEntity damager, Projectile proj,
DamageCause cause, double damage, boolean knockback, boolean ignoreRate, boolean ignoreArmor, DamageCause cause, double damage, boolean knockback, boolean ignoreRate, boolean ignoreArmor,
String source, String reason) String source, String reason)
{ {
NewDamageEvent(damagee, damager, proj, return NewDamageEvent(damagee, damager, proj,
cause, damage, knockback, ignoreRate, ignoreArmor, cause, damage, knockback, ignoreRate, ignoreArmor,
source, reason, false); source, reason, false);
} }
public void NewDamageEvent(LivingEntity damagee, LivingEntity damager, Projectile proj, public CustomDamageEvent NewDamageEvent(LivingEntity damagee, LivingEntity damager, Projectile proj,
DamageCause cause, double damage, boolean knockback, boolean ignoreRate, boolean ignoreArmor, DamageCause cause, double damage, boolean knockback, boolean ignoreRate, boolean ignoreArmor,
String source, String reason, boolean cancelled) String source, String reason, boolean cancelled)
{ {
NewDamageEvent(damagee, damager, proj, null, cause, damage, knockback, ignoreRate, ignoreArmor, source, reason, cancelled); return NewDamageEvent(damagee, damager, proj, null, cause, damage, knockback, ignoreRate, ignoreArmor, source, reason, cancelled);
} }
public void NewDamageEvent(LivingEntity damagee, LivingEntity damager, Projectile proj, Location knockbackOrigin, public CustomDamageEvent NewDamageEvent(LivingEntity damagee, LivingEntity damager, Projectile proj, Location knockbackOrigin,
DamageCause cause, double damage, boolean knockback, boolean ignoreRate, boolean ignoreArmor, DamageCause cause, double damage, boolean knockback, boolean ignoreRate, boolean ignoreArmor,
String source, String reason) String source, String reason)
{ {
NewDamageEvent(damagee, damager, proj, knockbackOrigin, cause, damage, knockback, ignoreRate, ignoreArmor, source, return NewDamageEvent(damagee, damager, proj, knockbackOrigin, cause, damage, knockback, ignoreRate, ignoreArmor, source,
reason, false); reason, false);
} }
public void NewDamageEvent(LivingEntity damagee, LivingEntity damager, Projectile proj, Location knockbackOrigin, public CustomDamageEvent NewDamageEvent(LivingEntity damagee, LivingEntity damager, Projectile proj, Location knockbackOrigin,
DamageCause cause, double damage, boolean knockback, boolean ignoreRate, boolean ignoreArmor, DamageCause cause, double damage, boolean knockback, boolean ignoreRate, boolean ignoreArmor,
String source, String reason, boolean cancelled) String source, String reason, boolean cancelled)
{ {
_plugin.getServer().getPluginManager().callEvent(new CustomDamageEvent(damagee, damager, proj, knockbackOrigin, cause, CustomDamageEvent customDamageEvent = new CustomDamageEvent(damagee, damager, proj, knockbackOrigin, cause,
damage, knockback, ignoreRate, ignoreArmor, source, reason, cancelled)); damage, knockback, ignoreRate, ignoreArmor, source, reason, cancelled);
_plugin.getServer().getPluginManager().callEvent(customDamageEvent);
return customDamageEvent;
} }
@EventHandler(priority = EventPriority.LOW) @EventHandler(priority = EventPriority.LOW)
@ -351,8 +353,15 @@ public class DamageManager extends MiniPlugin
} }
} }
} }
}
//Debug /*
* Should only be used to debug the damage event
* No modification of the event should take place
*/
@EventHandler (priority = EventPriority.MONITOR)
public void debugDamageEvent(CustomDamageEvent event)
{
DisplayDamage(event); DisplayDamage(event);
} }
@ -529,7 +538,7 @@ public class DamageManager extends MiniPlugin
} }
} }
@EventHandler @EventHandler (priority = EventPriority.MONITOR)
public void DamageSound(CustomDamageEvent event) public void DamageSound(CustomDamageEvent event)
{ {
if (event.IsCancelled()) if (event.IsCancelled())

View File

@ -1,8 +1,5 @@
package nautilus.game.arcade; package nautilus.game.arcade;
import java.util.AbstractMap;
import java.util.Map.Entry;
import mineplex.core.common.MinecraftVersion; import mineplex.core.common.MinecraftVersion;
import mineplex.core.common.Pair; import mineplex.core.common.Pair;
import mineplex.core.game.GameCategory; import mineplex.core.game.GameCategory;
@ -74,7 +71,6 @@ import nautilus.game.arcade.game.games.valentines.Valentines;
import nautilus.game.arcade.game.games.wither.WitherGame; import nautilus.game.arcade.game.games.wither.WitherGame;
import nautilus.game.arcade.game.games.wizards.Wizards; import nautilus.game.arcade.game.games.wizards.Wizards;
import nautilus.game.arcade.game.games.zombiesurvival.ZombieSurvival; import nautilus.game.arcade.game.games.zombiesurvival.ZombieSurvival;
import org.bukkit.Material; import org.bukkit.Material;
public enum GameType public enum GameType
@ -100,7 +96,7 @@ public enum GameType
DragonsTeams(DragonsTeams.class, GameDisplay.DragonsTeams), DragonsTeams(DragonsTeams.class, GameDisplay.DragonsTeams),
Draw(Draw.class, GameDisplay.Draw, new Pair[] Draw(Draw.class, GameDisplay.Draw, new Pair[]
{ {
Pair.create(MinecraftVersion.ALL, "http://chivebox.com/mineplex/ResDrawMyThing.zip") Pair.create(MinecraftVersion.ALL, "http://file.mineplex.com/ResDrawMyThing.zip")
}, true), }, true),
ElytraRings(ElytraRings.class, GameDisplay.ElytraRings), ElytraRings(ElytraRings.class, GameDisplay.ElytraRings),
Evolution(Evolution.class, GameDisplay.Evolution), Evolution(Evolution.class, GameDisplay.Evolution),
@ -117,8 +113,8 @@ public enum GameType
MilkCow(MilkCow.class, GameDisplay.MilkCow), MilkCow(MilkCow.class, GameDisplay.MilkCow),
MineStrike(MineStrike.class, GameDisplay.MineStrike, new Pair[] MineStrike(MineStrike.class, GameDisplay.MineStrike, new Pair[]
{ {
Pair.create(MinecraftVersion.Version1_8, "http://chivebox.com/mineplex/ResMinestrike.zip"), Pair.create(MinecraftVersion.Version1_8, "http://file.mineplex.com/ResMinestrike.zip"),
Pair.create(MinecraftVersion.Version1_9, "http://chivebox.com/mineplex/ResMinestrike19.zip") Pair.create(MinecraftVersion.Version1_9, "http://file.mineplex.com/ResMinestrike19.zip")
}, true), }, true),
MineWare(MineWare.class, GameDisplay.MineWare), MineWare(MineWare.class, GameDisplay.MineWare),
MinecraftLeague(MinecraftLeague.class, GameDisplay.Minecraft_League), MinecraftLeague(MinecraftLeague.class, GameDisplay.Minecraft_League),

View File

@ -140,7 +140,7 @@ public class MiscManager implements Listener
@EventHandler @EventHandler
public void HubCommand(PlayerCommandPreprocessEvent event) public void HubCommand(PlayerCommandPreprocessEvent event)
{ {
if (event.getMessage().toLowerCase().startsWith("/lobby") || event.getMessage().toLowerCase().startsWith("/hub") || event.getMessage().toLowerCase().startsWith("/leave")) if (event.getMessage().toLowerCase().equals("/lobby") || event.getMessage().toLowerCase().equals("/hub") || event.getMessage().toLowerCase().equals("/leave"))
{ {
Manager.GetPortal().sendPlayerToServer(event.getPlayer(), "Lobby"); Manager.GetPortal().sendPlayerToServer(event.getPlayer(), "Lobby");
event.setCancelled(true); event.setCancelled(true);