Merging issues

This commit is contained in:
LCastr0 2017-03-06 17:10:29 -03:00
commit ec5de0ef12
157 changed files with 12358 additions and 1403 deletions

View File

@ -2,33 +2,34 @@ package mineplex.bungee.lobbyBalancer;
import java.io.File;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import mineplex.serverdata.Region;
import mineplex.serverdata.data.MinecraftServer;
import mineplex.serverdata.servers.ServerManager;
import mineplex.serverdata.servers.ServerRepository;
import net.md_5.bungee.api.event.ServerConnectEvent;
import net.md_5.bungee.api.plugin.Listener;
import net.md_5.bungee.api.plugin.Plugin;
import net.md_5.bungee.event.EventHandler;
import com.google.common.collect.Lists;
import mineplex.serverdata.Region;
import mineplex.serverdata.data.MinecraftServer;
import mineplex.serverdata.servers.ServerManager;
import mineplex.serverdata.servers.ServerRepository;
public class LobbyBalancer implements Listener, Runnable
{
private Plugin _plugin;
private ServerRepository _repository;
private List<MinecraftServer> _sortedLobbies = Lists.newArrayList();
private List<MinecraftServer> _sortedClans = Lists.newArrayList();
private static Object _serverLock = new Object();
private int _lobbyIndex = 0;
private int _clansIndex = 0;
private final Map<LobbyType, List<MinecraftServer>> _sortedLobbyMap = new EnumMap<>(LobbyType.class);
private final Map<LobbyType, Integer> _nextIndexMap = new EnumMap<>(LobbyType.class);
private static final LobbySorter LOBBY_SORTER = new LobbySorter();
private static final Object _serverLock = new Object();
public LobbyBalancer(Plugin plugin)
{
@ -46,45 +47,42 @@ public class LobbyBalancer implements Listener, Runnable
@EventHandler
public void playerConnect(ServerConnectEvent event)
{
if (event.getTarget().getName().equalsIgnoreCase("Lobby"))
Arrays.stream(LobbyType.values())
.filter(type -> type.getConnectName().equalsIgnoreCase(event.getTarget().getName()))
.findFirst()
.ifPresent(lobbyType ->
{
synchronized (_serverLock)
{
if (_lobbyIndex >= _sortedLobbies.size() || _sortedLobbies.get(_lobbyIndex).getPlayerCount() >= _sortedLobbies.get(_lobbyIndex).getMaxPlayerCount())
_lobbyIndex = 0;
List<MinecraftServer> lobbies = _sortedLobbyMap.get(lobbyType);
event.setTarget(_plugin.getProxy().getServerInfo(_sortedLobbies.get(_lobbyIndex).getName()));
_sortedLobbies.get(_lobbyIndex).incrementPlayerCount(1);
System.out.println("Sending " + event.getPlayer().getName() + " to " + _sortedLobbies.get(_lobbyIndex).getName() + "(" + _sortedLobbies.get(_lobbyIndex).getPublicAddress() + ")");
_lobbyIndex++;
}
}
if (event.getTarget().getName().equalsIgnoreCase("ClansHub"))
int nextIndex = _nextIndexMap.getOrDefault(lobbyType, 0);
if (nextIndex >= lobbies.size())
{
synchronized (_serverLock)
{
if (_clansIndex >= _sortedClans.size() || _sortedClans.get(_clansIndex).getPlayerCount() >= _sortedClans.get(_clansIndex).getMaxPlayerCount())
_clansIndex = 0;
nextIndex = 0;
}
event.setTarget(_plugin.getProxy().getServerInfo(_sortedClans.get(_clansIndex).getName()));
_sortedClans.get(_clansIndex).incrementPlayerCount(1);
System.out.println("Sending " + event.getPlayer().getName() + " to " + _sortedClans.get(_clansIndex).getName() + "(" + _sortedClans.get(_clansIndex).getPublicAddress() + ")");
_clansIndex++;
}
MinecraftServer server = lobbies.get(nextIndex);
event.setTarget(_plugin.getProxy().getServerInfo(server.getName()));
server.incrementPlayerCount(1);
System.out.println("Sending " + event.getPlayer().getName() + " to " + server.getName() + "(" + server.getPublicAddress() + ")");
_nextIndexMap.put(lobbyType, ++nextIndex);
}
});
}
public void run()
{
loadServers();
if (!_plugin.getProxy().getServers().containsKey("ClansHub"))
for (LobbyType type : LobbyType.values())
{
_plugin.getProxy().getServers().put("ClansHub", _plugin.getProxy().constructServerInfo("ClansHub", new InetSocketAddress("lobby.mineplex.com", 25565), "LobbyBalancer", false));
if (!_plugin.getProxy().getServers().containsKey(type.getConnectName()))
{
_plugin.getProxy().getServers().put(type.getConnectName(), _plugin.getProxy().constructServerInfo(type.getConnectName(), new InetSocketAddress("lobby.mineplex.com", 25565), "LobbyBalancer", false));
}
if (!_plugin.getProxy().getServers().containsKey("Lobby"))
{
_plugin.getProxy().getServers().put("Lobby", _plugin.getProxy().constructServerInfo("Lobby", new InetSocketAddress("lobby.mineplex.com", 25565), "LobbyBalancer", false));
}
}
@ -95,8 +93,11 @@ public class LobbyBalancer implements Listener, Runnable
synchronized (_serverLock)
{
long startTime = System.currentTimeMillis();
_sortedLobbies.clear();
_sortedClans.clear();
_sortedLobbyMap.clear();
for (LobbyType type : LobbyType.values())
{
_sortedLobbyMap.put(type, new ArrayList<>());
}
for (MinecraftServer server : servers)
{
@ -106,31 +107,25 @@ public class LobbyBalancer implements Listener, Runnable
InetSocketAddress socketAddress = new InetSocketAddress(server.getPublicAddress(), server.getPort());
_plugin.getProxy().getServers().put(server.getName(), _plugin.getProxy().constructServerInfo(server.getName(), socketAddress, "LobbyBalancer", false));
if (server.getName().toUpperCase().startsWith("LOBBY-"))
if (server.getMotd() != null && server.getMotd().contains("Restarting"))
{
if (server.getMotd() == null || !server.getMotd().contains("Restarting"))
{
_sortedLobbies.add(server);
}
}
if (server.getName().toUpperCase().startsWith("CLANSHUB-"))
{
if (server.getMotd() == null || !server.getMotd().contains("Restarting"))
{
_sortedClans.add(server);
}
}
continue;
}
Collections.sort(_sortedLobbies, new LobbySorter());
Collections.sort(_sortedClans, new LobbySorter());
Arrays.stream(LobbyType.values())
.filter(type -> server.getName().toUpperCase().startsWith(type.getUppercasePrefix()))
.findFirst()
.ifPresent(type -> _sortedLobbyMap.get(type).add(server));
}
_sortedLobbyMap.values().forEach(lobbies -> Collections.sort(lobbies, LOBBY_SORTER));
long timeSpentInLock = System.currentTimeMillis() - startTime;
if (timeSpentInLock > 50)
System.out.println("[==] TIMING [==] Locked loading servers for " + timeSpentInLock + "ms");
_lobbyIndex = 0;
_nextIndexMap.clear();
}
}
}

View File

@ -0,0 +1,34 @@
package mineplex.bungee.lobbyBalancer;
public enum LobbyType
{
NORMAL("Lobby", "LOBBY-", "MainMotd"),
CLANS("ClansHub", "CLANSHUB-", "ClansMotd"),
BETA("BetaHub","BETAHUB-", "BetaMotd"),
;
private final String _connectName; // The name of the server the player is connecting to
private final String _uppercasePrefix; // The (toUpperCase()) prefix given to servers of this lobby type
private final String _redisMotdKey;
LobbyType(String connectName, String uppercasePrefix, String redisMotdKey)
{
_connectName = connectName;
_uppercasePrefix = uppercasePrefix;
_redisMotdKey = redisMotdKey;
}
public String getConnectName()
{
return _connectName;
}
public String getUppercasePrefix()
{
return _uppercasePrefix;
}
public String getRedisMotdKey()
{
return _redisMotdKey;
}
}

View File

@ -1,138 +1,82 @@
package mineplex.bungee.motd;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.EnumMap;
import java.util.Map;
import java.util.Optional;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import mineplex.serverdata.Region;
import mineplex.serverdata.data.DataRepository;
import mineplex.serverdata.redis.RedisDataRepository;
import mineplex.serverdata.servers.ConnectionData;
import mineplex.serverdata.servers.ConnectionData.ConnectionType;
import mineplex.serverdata.servers.ServerManager;
import net.md_5.bungee.api.event.ProxyPingEvent;
import net.md_5.bungee.api.plugin.Listener;
import net.md_5.bungee.api.plugin.Plugin;
import net.md_5.bungee.event.EventHandler;
import mineplex.bungee.lobbyBalancer.LobbyType;
import mineplex.serverdata.Region;
import mineplex.serverdata.data.DataRepository;
import mineplex.serverdata.redis.RedisDataRepository;
import mineplex.serverdata.servers.ServerManager;
public class MotdManager implements Listener, Runnable
{
private Plugin _plugin;
private static final String DEFAULT_HEADLINE = " §b§l§m §8§l§m[ §r §9§lMineplex§r §f§lGames§r §8§l§m ]§b§l§m §r";
private DataRepository<GlobalMotd> _repository;
private DataRepository<GlobalMotd> _secondRepository;
private Region _region;
private Random _random = new Random();
private String _firstLine = " §b§l§m §8§l§m[ §r §9§lMineplex§r §f§lGames§r §8§l§m ]§b§l§m §r";
private List<String> _motdLines;
private String _firstCLine = " §b§l§m §8§l§m[ §r §9§lMineplex§r §f§lGames§r §8§l§m ]§b§l§m §r";
private List<String> _motdCLines;
private final DataRepository<GlobalMotd> _repository;
private final Random _random = new Random();
private final Map<LobbyType, GlobalMotd> motds = new EnumMap<>(LobbyType.class);
public MotdManager(Plugin plugin)
{
_plugin = plugin;
_region = !new File("eu.dat").exists() ? Region.US : Region.EU;
_plugin.getProxy().getScheduler().schedule(_plugin, this, 5L, 30L, TimeUnit.SECONDS);
_plugin.getProxy().getPluginManager().registerListener(_plugin, this);
plugin.getProxy().getScheduler().schedule(plugin, this, 5L, 30L, TimeUnit.SECONDS);
plugin.getProxy().getPluginManager().registerListener(plugin, this);
_repository = new RedisDataRepository<GlobalMotd>(ServerManager.getConnection(true, ServerManager.SERVER_STATUS_LABEL), ServerManager.getConnection(false, ServerManager.SERVER_STATUS_LABEL),
Region.ALL, GlobalMotd.class, "globalMotd");
run();
if (new File("updateMOTD.dat").exists())
{
if (_region == Region.US)
_secondRepository = new RedisDataRepository<GlobalMotd>(new ConnectionData("10.81.1.156", 6379, ConnectionType.MASTER, "ServerStatus"), new ConnectionData("10.81.1.156", 6377, ConnectionType.SLAVE, "ServerStatus"),
Region.ALL, GlobalMotd.class, "globalMotd");
else
_secondRepository = new RedisDataRepository<GlobalMotd>(new ConnectionData("10.33.53.16", 6379, ConnectionType.MASTER, "ServerStatus"), new ConnectionData("10.33.53.16", 6377, ConnectionType.SLAVE, "ServerStatus"),
Region.ALL, GlobalMotd.class, "globalMotd");
//String motdLine = "§f§l◄ §c§lMaintenance§f§l ►";
//String motdLine = "§f§l◄ §a§lCarl the Creeper§f§l ►";
// String motdLine = " §2§l§n M O N S T E R M A Z E B E T A §f";
String motdLine = " §f> §4§lCLANS BETA §f- §c§lOpen to Everyone §f<";
// String motdLine = " §f❄ §2§lServer Maintenance §f❄ §2§lBe Back Soon §f❄";
//String motdLine = " §d§lRank Sale §a§l40% Off");
//String motdLine = " §f§l◄§c§lMAINTENANCE§f§l►");
updateMainMotd(" §f§m §8§l§m[ §r §9§lMineplex§r §f§lGames§r §8§l§m ]§f§m §r", motdLine);
System.out.println("Updated Bungee MOTD");
}
}
@EventHandler
public void serverPing(ProxyPingEvent event)
{
net.md_5.bungee.api.ServerPing serverPing = event.getResponse();
if (event.getConnection().getListener() != null && event.getConnection().getListener().getDefaultServer().equalsIgnoreCase("ClansHub"))
Optional<LobbyType> maybeType = Optional.empty();
if (event.getConnection().getListener() != null)
{
String motd = _firstCLine;
if (_motdCLines != null && _motdCLines.size() > 0)
{
motd += "\n" + _motdCLines.get(_random.nextInt(_motdCLines.size()));
maybeType = Arrays.stream(LobbyType.values())
.filter(type -> event.getConnection().getListener().getDefaultServer().equalsIgnoreCase(type.getConnectName()))
.findFirst();
}
LobbyType lobbyType = maybeType.orElse(LobbyType.NORMAL);
GlobalMotd globalMotd = motds.get(lobbyType);
String motd = DEFAULT_HEADLINE;
if (globalMotd != null && globalMotd.getHeadline() != null)
{
motd = globalMotd.getHeadline() == null ? DEFAULT_HEADLINE : globalMotd.getHeadline();
if (globalMotd.getMotd() != null)
{
motd += "\n" + globalMotd.getMotd().get(_random.nextInt(globalMotd.getMotd().size()));
}
}
event.setResponse(new net.md_5.bungee.api.ServerPing(serverPing.getVersion(), serverPing.getPlayers(), motd, serverPing.getFaviconObject()));
}
else
{
String motd = _firstLine;
if (_motdLines != null && _motdLines.size() > 0)
{
motd += "\n" + _motdLines.get(_random.nextInt(_motdLines.size()));
}
event.setResponse(new net.md_5.bungee.api.ServerPing(serverPing.getVersion(), serverPing.getPlayers(), motd, serverPing.getFaviconObject()));
}
}
@Override
public void run()
{
for (LobbyType type : LobbyType.values())
{
GlobalMotd motd = _repository.getElement("MainMotd");
GlobalMotd motd = _repository.getElement(type.getRedisMotdKey());
if (motd != null)
{
_motdLines = motd.getMotd();
_firstLine = motd.getHeadline();
motds.put(type, motd);
}
}
{
GlobalMotd motd = _repository.getElement("ClansMotd");
if (motd != null)
{
_motdCLines = motd.getMotd();
_firstCLine = motd.getHeadline();
}
else
{
_repository.addElement(new GlobalMotd("ClansMotd", "§4§lMineplex Clans§r", Arrays.asList("Default MOTD")));
}
}
}
/**
* Update the main {@link GlobalMotd} determining the MOTD for Bungee instances.
* @param motdLines - the lines to update the MOTD to.
*/
public void updateMainMotd(String headline, String motdLine)
{
List<String> motdLines = new ArrayList<String>();
motdLines.add(motdLine);
_repository.addElement(new GlobalMotd("MainMotd", headline, motdLines));
_secondRepository.addElement(new GlobalMotd("MainMotd", headline, motdLines));
}
public List<String> getMotdLines()
{
return _motdLines;
}
}

View File

@ -30,7 +30,7 @@
<build>
<resources>
<resource>
<directory/>
<directory />
<includes>
<include>ascii.png</include>
</includes>

View File

@ -1,21 +1,80 @@
package mineplex.core.common.api;
/**
* TODO: Store this in a file instead of being hardcoded
*
* @author Shaun Bennett
*/
public enum ApiHost
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import org.bukkit.configuration.file.YamlConfiguration;
public class ApiHost
{
AMPLIFIERS("10.33.53.12", 7979),
ANTISPAM("10.33.53.12", 8181),
ENDERCHEST("10.33.53.10", 8010)
;
private static final String API_HOST_FILE = "api-config.dat";
private static final Object LOCK = new Object();
private static volatile boolean LOADED = false;
private static final Map<String, ApiHost> API_HOST_MAP = new HashMap<>();
public static ApiHost getAPIHost(String identifier)
{
if (!LOADED)
{
synchronized (LOCK)
{
if (!LOADED)
{
try
{
File configFile = new File(API_HOST_FILE);
YamlConfiguration configuration = YamlConfiguration.loadConfiguration(configFile);
for (String key : configuration.getKeys(false))
{
String ip = configuration.getConfigurationSection(key).getString("ip");
// Use parseInt to catch non-ints instead of a 0
int port = Integer.parseInt(configuration.getConfigurationSection(key).getString("port"));
if (ip == null)
{
throw new NullPointerException();
}
API_HOST_MAP.put(key, new ApiHost(ip, port));
}
}
catch (Throwable t)
{
t.printStackTrace();
}
finally
{
LOADED = true;
}
}
}
}
return API_HOST_MAP.get(identifier);
}
public static ApiHost getAmplifierService()
{
return getAPIHost("AMPLIFIERS");
}
public static ApiHost getAntispamService()
{
return getAPIHost("ANTISPAM");
}
public static ApiHost getEnderchestService()
{
return getAPIHost("ENDERCHEST");
}
private String _host;
private int _port;
ApiHost(String host, int port)
private ApiHost(String host, int port)
{
_host = host;
_port = port;

View File

@ -18,7 +18,7 @@ public class EnderchestWorldLoader
public EnderchestWorldLoader()
{
String url = "http://" + ApiHost.ENDERCHEST.getHost() + ":" + ApiHost.ENDERCHEST.getPort() + "/";
String url = "http://" + ApiHost.getEnderchestService().getHost() + ":" + ApiHost.getEnderchestService().getPort() + "/";
_webCall = new ApiWebCall(url);
}
@ -26,7 +26,7 @@ public class EnderchestWorldLoader
{
TimingManager.start(TIMINGS_PREFIX + "DownloadMap");
String fileName = mapType + "_map.zip";
File f = _webCall.getFile("map/" + mapType + "/random", fileName);
File f = _webCall.getFile("map/" + mapType + "/next", fileName);
TimingManager.stop(TIMINGS_PREFIX + "DownloadMap");
TimingManager.start(TIMINGS_PREFIX + "CreateFolders");

View File

@ -4,18 +4,9 @@ import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
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.Item;
import net.minecraft.server.v1_8_R3.MathHelper;
import net.minecraft.server.v1_8_R3.MinecraftKey;
import net.minecraft.server.v1_8_R3.NBTTagCompound;
import net.minecraft.server.v1_8_R3.TileEntityFlowerPot;
import net.minecraft.server.v1_8_R3.WorldServer;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.SkullType;
@ -41,8 +32,18 @@ import org.bukkit.material.Bed;
import com.mojang.authlib.GameProfile;
import mineplex.core.common.Pair;
import mineplex.core.common.block.MultiBlockUpdaterAgent;
import mineplex.core.common.skin.SkinData;
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.Item;
import net.minecraft.server.v1_8_R3.MathHelper;
import net.minecraft.server.v1_8_R3.MinecraftKey;
import net.minecraft.server.v1_8_R3.NBTTagCompound;
import net.minecraft.server.v1_8_R3.TileEntityFlowerPot;
import net.minecraft.server.v1_8_R3.WorldServer;
public class UtilBlock
{
@ -1670,4 +1671,38 @@ public class UtilBlock
return null;
}
/**
* Returns a {@link Set} containing all the relevant data regarding beacon construction.
* Useful for adding them to block restore.
*
* @param surface
* The Location of the glass coloured block (at surface level). The beacon is placed one block below this.
* @param glassData
* The colour data value of glass that colours the beacon
*/
public static Set<Pair<Location, Pair<Material, Byte>>> getBeaconBlocks(Location surface, byte glassData)
{
Set<Pair<Location, Pair<Material, Byte>>> blocks = new HashSet<>();
for (int x = -1; x <= 1; x++)
{
for (int z = -1; z <= 1; z++)
{
blocks.add(Pair.create(surface.clone().add(x, -3, z), Pair.create(Material.IRON_BLOCK, (byte) 0)));
if (x == 0 && z == 0)
{
continue;
}
blocks.add(Pair.create(surface.clone().add(x, -1, z), Pair.create(Material.QUARTZ_BLOCK, (byte) 0)));
}
}
blocks.add(Pair.create(surface.clone().add(0, -2, 0), Pair.create(Material.BEACON, (byte) 0)));
blocks.add(Pair.create(surface.clone().add(0, -1, 0), Pair.create(Material.STAINED_GLASS, glassData)));
return blocks;
}
}

View File

@ -448,6 +448,21 @@ public class UtilInv
return false;
}
public static boolean hasSpace(Player player, int slots)
{
int slotsFree = 0;
for (int slot = 0; slot < player.getInventory().getSize(); slot++)
{
if (player.getInventory().getItem(slot) == null)
{
slotsFree++;
}
}
return slotsFree >= slots;
}
public static void give(Player player, Material material)
{
give(player, material, 1);

View File

@ -17,7 +17,7 @@ public class AntiSpamRepository extends ApiEndpoint
{
public AntiSpamRepository()
{
super(ApiHost.ANTISPAM, "/chat");
super(ApiHost.getAntispamService(), "/chat");
}
public AntiSpamApiResponse sendMessage(String source, ChatPayload payload)

View File

@ -0,0 +1,68 @@
package mineplex.core.beta;
import java.util.Set;
import java.util.UUID;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerJoinEvent;
import com.google.common.collect.ImmutableSet;
import mineplex.core.MiniPlugin;
import mineplex.core.account.CoreClientManager;
import mineplex.core.common.Rank;
import mineplex.core.powerplayclub.PowerPlayClubRepository;
public class BetaWhitelist extends MiniPlugin
{
private static final Set<UUID> EXTRA_PLAYERS = ImmutableSet.<UUID>builder()
// GI Members
.add(UUID.fromString("8506533f-1da7-4d5c-a835-a483b5a18b54")) // Awquard
.add(UUID.fromString("a8526c97-95be-4cb7-ae58-7df5d3b108a6")) // ASlime
.add(UUID.fromString("ae6d71b7-3d49-429f-b31f-5cf5af136540")) // Cabob
.add(UUID.fromString("ea1f709c-031f-4028-8f7d-2073c5a37d1a")) // CharlieHacks
.add(UUID.fromString("d3c1457a-1084-43e1-846c-addc47393b90")) // Chocobutter
.add(UUID.fromString("6b60782e-f95b-4449-a39e-0ad7fa5fdab0")) // CosmoLink
.add(UUID.fromString("18697323-50d3-47ea-a5c2-e7ac1a0d9fa0")) // Danah
.add(UUID.fromString("1cc18d8d-ab28-4354-8cce-f93fb06423bf")) // Fetch
.add(UUID.fromString("c56e5b96-8dc3-46ca-b682-24cf8467e3a1")) // KingOfWizards
.add(UUID.fromString("ea30fe99-2044-438f-bfd8-97bcc639239e")) // Mauo
.add(UUID.fromString("933b2f93-806a-4f39-88a2-935442418ae5")) // Tier4Global
.add(UUID.fromString("ac239b94-3079-4a8a-a52f-7b81c8a87b4d")) // Paddi
.add(UUID.fromString("3ced328d-f079-45e4-ad71-8c721c4a699b")) // Smaland47
.add(UUID.fromString("d51fc65b-fce9-4464-9391-b259525dc6ca")) // SnitSays
.add(UUID.fromString("12bbeda2-567a-400a-9d66-f76fab832de0")) // StoneColdKiller
.add(UUID.fromString("2e0c1d88-7f44-44f5-85b4-9ad0b2cfddce")) // Tours
.add(UUID.fromString("32aff2d0-f68c-4eb9-b5d4-139fc48b7ca6")) // Trimzon
.add(UUID.fromString("3dcfe366-fcaa-48f7-abcc-b73fb62616e1")) // gamefish32
.add(UUID.fromString("6795643a-2b61-41bf-9429-c7549fd128a8")) // umGim
.add(UUID.fromString("47ba454a-4999-42f4-a269-2f4114ceb3c7")) // falconviii
.build();
private final CoreClientManager _clientManager;
private final PowerPlayClubRepository _powerPlayClubRepository;
public BetaWhitelist(CoreClientManager clientManager, PowerPlayClubRepository powerPlayRepository)
{
super("Beta Whitelist");
_clientManager = clientManager;
_powerPlayClubRepository = powerPlayRepository;
}
@EventHandler
public void onJoin(PlayerJoinEvent event)
{
Player player = event.getPlayer();
Rank rank = _clientManager.Get(player).GetRank(true);
if ((rank != Rank.MAPDEV && rank != Rank.MAPLEAD && rank.has(Rank.ETERNAL) // If this player is Eternal+ (and not a builder),
|| _powerPlayClubRepository.getCachedData(player).isSubscribed()) // a PPC subscriber,
|| EXTRA_PLAYERS.contains(player.getUniqueId())) // or explicitly whitelisted,
{
return; // allow them in
}
// Otherwise, kick them out
event.getPlayer().kickPlayer("Sorry, you aren't whitelisted on this beta server.\n\nSubscribe to " + ChatColor.GOLD + "Power Play Club " + ChatColor.WHITE + "at " + ChatColor.GREEN + "mineplex.com/shop" + ChatColor.WHITE + "!");
}
}

View File

@ -18,22 +18,23 @@ import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPistonExtendEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.world.ChunkUnloadEvent;
import org.bukkit.plugin.java.JavaPlugin;
import mineplex.core.MiniPlugin;
import mineplex.core.ReflectivelyCreateMiniPlugin;
import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilMath;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
@ReflectivelyCreateMiniPlugin
public class BlockRestore extends MiniPlugin
{
private HashMap<Block, BlockRestoreData> _blocks = new HashMap<Block, BlockRestoreData>();
private LinkedList<BlockRestoreMap> _restoreMaps;
public BlockRestore(JavaPlugin plugin)
private BlockRestore()
{
super("Block Restore", plugin);
super("Block Restore");
_restoreMaps = new LinkedList<BlockRestoreMap>();
}

View File

@ -236,11 +236,11 @@ public class BonusManager extends MiniClientPlugin<BonusClientData> implements I
if (event.getType() != UpdateType.TICK)
return;
_animation.itemClean();
if (!_enabled)
return;
_animation.itemClean();
if (!_animationRunning)
return;

View File

@ -170,7 +170,8 @@ public class PowerPlayClubButton implements GuiItem
public static boolean isAvailable(Player player, PowerPlayClubRepository repo)
{
return !repo.getCachedData(player).getUnclaimedMonths().isEmpty();
PowerPlayData data = repo.getCachedData(player);
return data != null && !data.getUnclaimedMonths().isEmpty();
}
}

View File

@ -24,7 +24,7 @@ public class BoosterRepository extends ApiEndpoint
{
public BoosterRepository()
{
super(ApiHost.AMPLIFIERS, "/booster", new GsonBuilder().setFieldNamingStrategy(new ApiFieldNamingStrategy())
super(ApiHost.getAmplifierService(), "/booster", new GsonBuilder().setFieldNamingStrategy(new ApiFieldNamingStrategy())
// .registerTypeAdapter(PropertyMap.class, new PropertyMap.Serializer())
.setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX").create());
}

View File

@ -146,11 +146,14 @@ public class Chat extends MiniPlugin
if (event.getMessage().toLowerCase().startsWith("/me ")
|| event.getMessage().toLowerCase().startsWith("/bukkit")
|| event.getMessage().toLowerCase().startsWith("/minecraft"))
{
if (!event.getPlayer().isOp())
{
event.getPlayer().sendMessage(F.main(getName(), "Nope, not allowed!"));
event.setCancelled(true);
}
}
}
@EventHandler
public void lagTest(PlayerCommandPreprocessEvent event)

View File

@ -243,6 +243,11 @@ public class CosmeticManager extends MiniPlugin
return _boosterManager;
}
public void displayUI(Player player)
{
_shop.attemptShopOpen(player);
}
public void disableTeamArmor()
{
for (Gadget gadget : getGadgetManager().getGadgets(GadgetType.COSTUME))

View File

@ -37,10 +37,8 @@ public class TauntPage extends GadgetPage
{
addGadget(gadget, slot);
if (gadget.isActive(getPlayer()))
{
if (getPlugin().getGadgetManager().getActive(getPlayer(), GadgetType.TAUNT) == gadget)
addGlow(slot);
}
slot++;

View File

@ -5,6 +5,9 @@ import java.util.Random;
import net.minecraft.server.v1_8_R3.MathHelper;
import net.minecraft.server.v1_8_R3.Packet;
import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntity;
import org.bukkit.Material;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
public class DisguiseBlock extends DisguiseBase
@ -14,7 +17,7 @@ public class DisguiseBlock extends DisguiseBase
private int _blockId;
private int _blockData;
public DisguiseBlock(org.bukkit.entity.Entity entity, int blockId, int blockData)
public DisguiseBlock(Entity entity, int blockId, int blockData)
{
super(EntityType.FALLING_BLOCK, entity);
@ -22,6 +25,14 @@ public class DisguiseBlock extends DisguiseBase
_blockData = blockData;
}
public DisguiseBlock(Entity entity, Material material, byte data)
{
super(EntityType.FALLING_BLOCK, entity);
_blockId = material.getId();
_blockData = (int) data;
}
public int GetBlockId()
{
return _blockId;

View File

@ -87,6 +87,8 @@ import mineplex.core.gadget.gadgets.doublejump.titan.DoubleJumpTitan;
import mineplex.core.gadget.gadgets.doublejump.vampire.DoubleJumpBlood;
import mineplex.core.gadget.gadgets.doublejump.wisdom.DoubleJumpEnchant;
import mineplex.core.gadget.gadgets.gamemodifiers.GameModifierType;
import mineplex.core.gadget.gadgets.gamemodifiers.gemhunters.GameModifierMount;
import mineplex.core.gadget.gadgets.gamemodifiers.gemhunters.MountType;
import mineplex.core.gadget.gadgets.gamemodifiers.kits.KitGameModifier;
import mineplex.core.gadget.gadgets.gamemodifiers.kits.KitModifier;
import mineplex.core.gadget.gadgets.gamemodifiers.kits.KitModifierType;
@ -121,6 +123,7 @@ import mineplex.core.gadget.gadgets.morph.MorphCow;
import mineplex.core.gadget.gadgets.morph.MorphCreeper;
import mineplex.core.gadget.gadgets.morph.MorphDinnerbone;
import mineplex.core.gadget.gadgets.morph.MorphEnderman;
import mineplex.core.gadget.gadgets.morph.MorphGoldPot;
import mineplex.core.gadget.gadgets.morph.MorphGrimReaper;
import mineplex.core.gadget.gadgets.morph.MorphLoveDoctor;
import mineplex.core.gadget.gadgets.morph.MorphMetalMan;
@ -418,6 +421,7 @@ public class GadgetManager extends MiniPlugin
addGadget(new MorphSanta(this));
addGadget(new MorphDinnerbone(this));
addGadget(new MorphLoveDoctor(this));
addGadget(new MorphGoldPot(this));
// Particles
addGadget(new ParticleFoot(this));
@ -574,6 +578,12 @@ public class GadgetManager extends MiniPlugin
addGadget(new BlowAKissTaunt(this));
addGadget(new RainbowTaunt(this));
// Gem Hunters Mounts
for (MountType mount : MountType.values())
{
addGadget(new GameModifierMount(this, mount));
}
for (GadgetType gadgetType : GadgetType.values())
{
if (!_gadgets.containsKey(gadgetType))

View File

@ -7,6 +7,7 @@ import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilText;
import mineplex.core.donation.Donor;
import mineplex.core.gadget.GadgetManager;
@ -22,13 +23,19 @@ public class LockCosmeticsCommand extends CommandBase<GadgetManager>
public LockCosmeticsCommand(GadgetManager plugin)
{
super(plugin, Rank.JNR_DEV, "lockCosmetics");
super(plugin, Rank.SNR_MODERATOR, "lockCosmetics");
_plugin = plugin;
}
@Override
public void Execute(Player caller, String[] args)
{
if (!UtilServer.isTestServer())
{
UtilPlayer.message(caller, F.main("Lock Cosmetics", "This command requires a test server!"));
return;
}
// Adds all cosmetic types
if (args.length == 0)
{

View File

@ -7,6 +7,7 @@ import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilText;
import mineplex.core.donation.Donor;
import mineplex.core.gadget.GadgetManager;
@ -29,6 +30,12 @@ public class UnlockCosmeticsCommand extends CommandBase<GadgetManager>
@Override
public void Execute(Player caller, String[] args)
{
if (!UtilServer.isTestServer())
{
UtilPlayer.message(caller, F.main("Unlock Cosmetics", "This command requires a test server!"));
return;
}
// Adds all cosmetic types
if (args.length == 0)
{

View File

@ -19,7 +19,11 @@ public enum GameModifierType
MineStrike("MineStrike", new String[]{"Apply custom gun models and skin to use ingame"}, Material.TNT, 0),
SurvivalGames("Survival Games", new String[]{"Placeholder"}, Material.DIAMOND_SWORD, 0, true),
Bridges("Bridges", new String[]{"Placeholder"}, Material.IRON_PICKAXE, 0, true);
Bridges("Bridges", new String[]{"Placeholder"}, Material.IRON_PICKAXE, 0, true),
GemHunters("Gem Hunters", new String[] { "" }, Material.EMERALD, 0)
;
private String _name;
private List<String> _desc;

View File

@ -0,0 +1,23 @@
package mineplex.core.gadget.gadgets.gamemodifiers.gemhunters;
import mineplex.core.gadget.GadgetManager;
import mineplex.core.gadget.gadgets.gamemodifiers.GameModifierType;
import mineplex.core.gadget.types.GameModifierGadget;
public class GameModifierMount extends GameModifierGadget
{
private final MountType _mountType;
public GameModifierMount(GadgetManager manager, MountType mountType)
{
super(manager, GameModifierType.GemHunters, mountType.getName() + " Mount", mountType.getDescription(), -2, mountType.getMaterial(), mountType.getData(), false);
_mountType = mountType;
}
public final MountType getMountType()
{
return _mountType;
}
}

View File

@ -0,0 +1,53 @@
package mineplex.core.gadget.gadgets.gamemodifiers.gemhunters;
import org.bukkit.Material;
import org.bukkit.entity.EntityType;
public enum MountType
{
SKELETON(EntityType.HORSE, Material.BONE, (byte) 0, "Skeleton Horse", "Spooky")
;
private final EntityType _entityType;
private final Material _material;
private final byte _data;
private final String _name;
private final String[] _description;
private MountType(EntityType entityType, Material material, byte data, String name, String... description)
{
_entityType = entityType;
_material = material;
_data = data;
_name = name;
_description = description;
}
public final EntityType getEntityType()
{
return _entityType;
}
public final Material getMaterial()
{
return _material;
}
public byte getData()
{
return _data;
}
public final String getName()
{
return _name;
}
public final String[] getDescription()
{
return _description;
}
}

View File

@ -0,0 +1,132 @@
package mineplex.core.gadget.gadgets.morph;
import java.time.Month;
import java.time.YearMonth;
import java.util.HashMap;
import java.util.Map;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerPickupItemEvent;
import mineplex.core.common.util.C;
import mineplex.core.common.util.LineFormat;
import mineplex.core.common.util.UtilText;
import mineplex.core.disguise.disguises.DisguiseBlock;
import mineplex.core.gadget.GadgetManager;
import mineplex.core.gadget.gadgets.morph.managers.GoldPotHelper;
import mineplex.core.gadget.gadgets.morph.managers.UtilMorph;
import mineplex.core.gadget.types.MorphGadget;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
public class MorphGoldPot extends MorphGadget
{
private Map<Player, GoldPotHelper> _helpers = new HashMap<>();
public MorphGoldPot(GadgetManager manager)
{
super(manager, "Gold Pot Morph", UtilText.splitLinesToArray(new String[]
{
C.cGray + "They say at the end of every rainbow a leprechaun has a pot filled with gold.",
C.blankLine,
C.cWhite + "Stand still to hide in place and fill up with treasure. Players who find you will earn a reward!",
}, LineFormat.LORE),
-14,
Material.CAULDRON_ITEM, (byte) 0, YearMonth.of(2017, Month.MARCH));
}
@Override
public void enableCustom(Player player, boolean message)
{
applyArmor(player, message);
_helpers.put(player, new GoldPotHelper(player, Manager, this));
DisguiseBlock disguiseBlock = new DisguiseBlock(player, Material.CAULDRON, (byte) 0);
UtilMorph.disguise(player, disguiseBlock, Manager);
}
@Override
public void disableCustom(Player player, boolean message)
{
removeArmor(player);
if (_helpers.containsKey(player))
{
_helpers.get(player).unsolidifyPlayer();
_helpers.get(player).cleanItems(true);
_helpers.remove(player);
}
UtilMorph.undisguise(player, Manager.getDisguiseManager());
}
@EventHandler
public void onUpdate(UpdateEvent event)
{ for (GoldPotHelper goldPotHelper : _helpers.values())
{
boolean solid = goldPotHelper.updatePlayer(event.getType() == UpdateType.SEC, event.getType() == UpdateType.TICK);
if (solid)
{
goldPotHelper.solififyPlayer();
}
}
}
@EventHandler
public void onRightClick(PlayerInteractEvent event)
{
if (event.getAction() == Action.RIGHT_CLICK_BLOCK)
{
for (GoldPotHelper goldPotHelper : _helpers.values())
{
goldPotHelper.performRightClick(event.getPlayer(), event.getClickedBlock());
}
}
}
@EventHandler
public void onItemPickup(PlayerPickupItemEvent event)
{
for (GoldPotHelper goldPotHelper : _helpers.values())
{
if (goldPotHelper.getItems().contains(event.getItem()))
{
event.setCancelled(true);
}
}
}
@EventHandler
public void onPlayerMove(PlayerMoveEvent event)
{
if (!isActive(event.getPlayer()))
return;
if (_helpers.containsKey(event.getPlayer()))
{
if (!_helpers.get(event.getPlayer()).isSolid())
return;
}
Location from = event.getFrom(), to = event.getTo();
double xFrom = from.getX(), yFrom = from.getY(), zFrom = from.getZ(),
xTo = to.getX(), yTo = to.getY(), zTo = to.getZ();
if (xFrom != xTo || yFrom != yTo || zFrom != zTo)
{
if (_helpers.containsKey(event.getPlayer()))
{
_helpers.get(event.getPlayer()).unsolidifyPlayer();
}
event.getPlayer().setExp(0f);
}
}
}

View File

@ -0,0 +1,213 @@
package mineplex.core.gadget.gadgets.morph.managers;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Item;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.util.Vector;
import mineplex.core.common.currency.GlobalCurrency;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilParticle;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.disguise.disguises.DisguiseBlock;
import mineplex.core.disguise.disguises.DisguiseCat;
import mineplex.core.disguise.disguises.DisguiseChicken;
import mineplex.core.gadget.GadgetManager;
import mineplex.core.gadget.event.GadgetBlockEvent;
import mineplex.core.gadget.types.Gadget;
import mineplex.core.recharge.Recharge;
public class GoldPotHelper
{
private static final float EXP_INCREMENT = 0.2f;
private static final long COOLDOWN = 300000;
private static final int SHARDS = 250;
private static final int GEMS = 60;
private Player _player;
private GadgetManager _manager;
private Gadget _gadget;
private GoldPotStands _goldPotStands;
private Block _block;
private boolean _solid = false;
private boolean _nuggets = false;
private HashSet<Item> _items = new HashSet<>();
public GoldPotHelper(Player player, GadgetManager manager, Gadget gadget)
{
_player = player;
_manager = manager;
_gadget = gadget;
_goldPotStands = new GoldPotStands();
}
public void solififyPlayer()
{
if (_solid)
return;
Block block = _player.getLocation().getBlock();
GadgetBlockEvent event = new GadgetBlockEvent(_gadget, Collections.singletonList(block));
Bukkit.getServer().getPluginManager().callEvent(event);
if (event.isCancelled() || block.getType() != Material.AIR)
{
UtilPlayer.message(_player, F.main("Morph", "You cannot become a gold pot here!"));
return;
}
if (!Recharge.Instance.usable(_player, _gadget.getName(), true, "Your pot will be refilled with gold in %t"))
{
return;
}
UtilMorph.undisguise(_player, _manager.getDisguiseManager());
DisguiseChicken disguiseChicken = new DisguiseChicken(_player);
disguiseChicken.setSoundDisguise(new DisguiseCat(_player));
disguiseChicken.setInvisible(true);
UtilMorph.disguise(_player, disguiseChicken, _manager);
block.setType(Material.CAULDRON);
_block = block;
_goldPotStands.setBlock(_block);
_goldPotStands.createStands();
_solid = true;
UtilPlayer.message(_player, F.main("Gold Pot", "You're now filled with gold!"));
}
public void unsolidifyPlayer()
{
if (!_solid)
return;
_goldPotStands.removeStands();
UtilMorph.undisguise(_player, _manager.getDisguiseManager());
DisguiseBlock disguiseBlock = new DisguiseBlock(_player, Material.CAULDRON, (byte) 0);
UtilMorph.disguise(_player, disguiseBlock, _manager);
if (_block != null)
{
_block.setType(Material.AIR);
_block = null;
}
_solid = false;
UtilPlayer.message(_player, F.main("Gold Pot", "You're no longer filled with gold!"));
}
public boolean updatePlayer(boolean second, boolean tick)
{
boolean solidify = false;
if (second)
{
if (!_solid)
{
// Updates EXP Bar
_player.setExp(_player.getExp() + EXP_INCREMENT);
if (_player.getExp() == 1)
{
// Solidifies (or tries to)
solidify = true;
_player.setExp(0f);
}
if (_manager.isMoving(_player))
{
_player.setExp(0f);
solidify = false;
}
}
else
{
// Throws items in the air
for (int i = 1; i < 5; i++)
{
ItemStack itemStack = new ItemStack((_nuggets) ? Material.GOLD_NUGGET : Material.GOLD_INGOT);
ItemMeta itemMeta = itemStack.getItemMeta();
itemMeta.setDisplayName("DROPPED" + System.currentTimeMillis() + i);
itemStack.setItemMeta(itemMeta);
Item gold = _block.getWorld().dropItem(_block.getLocation().add(0.5, 1.5, 0.5), itemStack);
_items.add(gold);
gold.setVelocity(new Vector((Math.random()-0.5)*0.3, Math.random()-0.4, (Math.random()-0.5)*0.3));
}
_nuggets = !_nuggets;
}
}
if (tick)
{
UtilParticle.PlayParticleToAll(UtilParticle.ParticleType.ICON_CRACK.getParticle(Material.GOLD_BLOCK,
(byte) 0), _player.getLocation().add(0, 0.5, 0), 0.1f, 0.1f, 0.1f, 0.3f, 1, UtilParticle.ViewDist.LONG);
cleanItems(false);
}
return solidify;
}
public void performRightClick(Player clicked, Block block)
{
if (_block == null)
return;
if (!block.equals(_block))
return;
if (clicked.equals(_player))
return;
unsolidifyPlayer();
Recharge.Instance.use(_player, _gadget.getName(), COOLDOWN, false, false, "Cosmetics");
boolean shards = UtilMath.random.nextBoolean();
if (shards)
{
_manager.getDonationManager().rewardCurrency(GlobalCurrency.TREASURE_SHARD, clicked, _gadget.getName() + " Gold Pot Pickup Shards", SHARDS);
Bukkit.broadcastMessage(F.main("Gold Pot", F.name(clicked.getName()) + " found a gold pot worth " + F.currency(GlobalCurrency.TREASURE_SHARD, SHARDS) + "!"));
} else
{
_manager.getDonationManager().rewardCurrency(GlobalCurrency.GEM, clicked, _gadget.getName() + " Gold Pot Pickup Gems", GEMS);
Bukkit.broadcastMessage(F.main("Gold Pot", F.name(clicked.getName()) + " found a gold pot worth " + F.currency(GlobalCurrency.GEM, GEMS) + "!"));
}
}
public HashSet<Item> getItems()
{
return _items;
}
public void cleanItems(boolean force)
{
Iterator<Item> it = _items.iterator();
while (it.hasNext())
{
Item item = it.next();
if (item.getTicksLived() >= 20 || force)
{
item.remove();
it.remove();
}
}
}
public boolean isSolid()
{
return _solid;
}
}

View File

@ -0,0 +1,98 @@
package mineplex.core.gadget.gadgets.morph.managers;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.ArmorStand;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.EulerAngle;
public class GoldPotStands
{
private ArmorStand _helmet, _armsA, _armsB, _armsC;
private Block _block;
public void setBlock(Block block)
{
_block = block;
}
public void createStands()
{
if (_block == null)
{
return;
}
Location loc = _block.getLocation().clone().add(0.5, 0, 0.5);
// Spawns main armorstand
Location asHelmetGoldLoc = loc.clone().subtract(0, 1, 0);
ArmorStand asHelmetGold = loc.getWorld().spawn(asHelmetGoldLoc, ArmorStand.class);
asHelmetGold.setVisible(false);
asHelmetGold.setGravity(false);
asHelmetGold.setHelmet(new ItemStack(Material.GOLD_BLOCK));
// Spawns second armorstand
Location asArmsGoldALoc = asHelmetGoldLoc.clone();
ArmorStand asArmsGoldA = loc.getWorld().spawn(asArmsGoldALoc, ArmorStand.class);
asArmsGoldA.setVisible(false);
asArmsGoldA.setGravity(false);
asArmsGoldA.setItemInHand(new ItemStack(Material.GOLD_BLOCK));
double asArmsGoldAX = Math.toRadians(158), asArmsGoldAY = Math.toRadians(75);
EulerAngle asArmsGoldAEuler = new EulerAngle(asArmsGoldAX, asArmsGoldAY, 0);
asArmsGoldA.setRightArmPose(asArmsGoldAEuler);
// Spawns third armorstand
Location asArmsGoldBLoc = asHelmetGoldLoc.clone();
ArmorStand asArmsGoldB = loc.getWorld().spawn(asArmsGoldBLoc, ArmorStand.class);
asArmsGoldB.setVisible(false);
asArmsGoldB.setGravity(false);
asArmsGoldB.setItemInHand(new ItemStack(Material.GOLD_BLOCK));
double asArmsGoldBX = Math.toRadians(202), asArmsGoldBY = Math.toRadians(245);
EulerAngle asArmsGoldBEuler = new EulerAngle(asArmsGoldBX, asArmsGoldBY, 0);
asArmsGoldB.setRightArmPose(asArmsGoldBEuler);
// Spawns fourth armorstand
Location asArmsGoldCLoc = loc.clone().add(0.4, 0.1, 0.1);
ArmorStand asArmsGoldC = loc.getWorld().spawn(asArmsGoldCLoc, ArmorStand.class);
asArmsGoldC.setVisible(false);
asArmsGoldC.setGravity(false);
asArmsGoldC.setSmall(true);
asArmsGoldC.setItemInHand(new ItemStack(Material.GOLD_BLOCK));
double asArmsGoldCX = Math.toRadians(191), asArmsGoldCY = Math.toRadians(245);
EulerAngle asArmsGoldCEuler = new EulerAngle(asArmsGoldCX, asArmsGoldCY, 0);
asArmsGoldC.setRightArmPose(asArmsGoldCEuler);
_helmet = asHelmetGold;
_armsA = asArmsGoldA;
_armsB = asArmsGoldB;
_armsC = asArmsGoldC;
}
public void removeStands()
{
if (_helmet != null)
{
_helmet.remove();
_helmet = null;
}
if (_armsA != null)
{
_armsA.remove();
_armsA = null;
}
if (_armsB != null)
{
_armsB.remove();
_armsB = null;
}
if (_armsC != null)
{
_armsC.remove();
_armsC = null;
}
_block = null;
}
}

View File

@ -0,0 +1,81 @@
package mineplex.core.google;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import mineplex.core.MiniPlugin;
import mineplex.core.ReflectivelyCreateMiniPlugin;
@ReflectivelyCreateMiniPlugin
public class GoogleSheetsManager extends MiniPlugin
{
private static final File DATA_STORE_DIR = new File(".." + File.separatorChar + ".." + File.separatorChar + "update" + File.separatorChar + "files");
private GoogleSheetsManager()
{
super("Google Sheets");
}
public Map<String, List<List<String>>> getSheetData(String name)
{
return getSheetData(new File(DATA_STORE_DIR + File.separator + name + ".json"));
}
public Map<String, List<List<String>>> getSheetData(File file)
{
if (!file.exists())
{
return null;
}
Map<String, List<List<String>>> valuesMap = new HashMap<>();
try
{
JsonParser parser = new JsonParser();
JsonElement data = parser.parse(new FileReader(file));
JsonArray parent = data.getAsJsonObject().getAsJsonArray("data");
for (int i = 0; i < parent.size(); i++)
{
JsonObject sheet = parent.get(i).getAsJsonObject();
String name = sheet.get("name").getAsString();
JsonArray values = sheet.getAsJsonArray("values");
List<List<String>> valuesList = new ArrayList<>(values.size());
for (int j = 0; j < values.size(); j++)
{
List<String> list = new ArrayList<>();
Iterator<JsonElement> iterator = values.get(j).getAsJsonArray().iterator();
while (iterator.hasNext())
{
String value = iterator.next().getAsString();
list.add(value);
}
valuesList.add(list);
}
valuesMap.put(name, valuesList);
}
}
catch (FileNotFoundException e)
{
}
return valuesMap;
}
}

View File

@ -0,0 +1,8 @@
package mineplex.core.google;
public interface SheetObjectDeserialiser<T>
{
public T deserialise(String[] values) throws ArrayIndexOutOfBoundsException;
}

View File

@ -53,6 +53,7 @@ public class ItemBuilder
private int _amount;
private Color _color;
private short _data;
private short _durability;
private final HashMap<Enchantment, Integer> _enchants = new HashMap<Enchantment, Integer>();
private final List<String> _lore = new ArrayList<String>();
private Material _mat;
@ -90,6 +91,7 @@ public class ItemBuilder
_itemFlags.addAll(meta.getItemFlags());
_unbreakable = meta.spigot().isUnbreakable();
_durability = item.getDurability();
}
}
@ -108,6 +110,7 @@ public class ItemBuilder
_mat = mat;
_amount = amount;
_data = data;
_durability = 0;
}
public ItemBuilder(Material mat, short data)
@ -115,6 +118,13 @@ public class ItemBuilder
this(mat, 1, data);
}
public ItemBuilder setDurability(short durability)
{
_durability = durability;
return this;
}
public HashSet<ItemFlag> getItemFlags()
{
return _itemFlags;
@ -278,6 +288,7 @@ public class ItemBuilder
item.addUnsafeEnchantments(_enchants);
if (_glow) item.addEnchantment(UtilInv.getDullEnchantment(), 1);
if (_durability != 0) item.setDurability(_durability);
return item;
}
@ -298,6 +309,7 @@ public class ItemBuilder
newBuilder.setColor(_color);
// newBuilder.potion = potion;
newBuilder.setDurability(_durability);
return newBuilder;
}

View File

@ -169,8 +169,12 @@ public class PetManager extends MiniClientPlugin<PetClient>
if (player != null && player.isOnline())
{
getActivePet(playerName).setCustomNameVisible(true);
getActivePet(playerName).setCustomName(_petRenameQueue.get(playerName));
Creature activePet = getActivePet(playerName);
if (activePet != null)
{
activePet.setCustomNameVisible(true);
activePet.setCustomName(_petRenameQueue.get(playerName));
}
}
}

View File

@ -12,7 +12,12 @@ public enum GenericServer
/**
* The Clans Hubs, such as ClansHub-1
*/
CLANS_HUB("ClansHub");
CLANS_HUB("ClansHub"),
/**
* The Beta Hubs, such as BetaHub-1
*/
BETA_HUB("BetaHub"),
;
private final String _name;

View File

@ -35,6 +35,7 @@ public class PowerPlayClubRewards
.put(YearMonth.of(2016, Month.DECEMBER), new UnknownSalesPackageItem("Santa Morph"))
.put(YearMonth.of(2017, Month.JANUARY), new UnknownSalesPackageItem("Over Easy Morph"))
.put(YearMonth.of(2017, Month.FEBRUARY), new PetItem(PetType.TRUE_LOVE_PET))
.put(YearMonth.of(2017, Month.MARCH), new UnknownSalesPackageItem("Gold Pot Morph"))
.build();
public interface PowerPlayClubItem

View File

@ -12,8 +12,6 @@ import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.plugin.java.JavaPlugin;
import mineplex.core.MiniPlugin;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.core.updater.UpdateType;
import mineplex.core.account.event.ClientUnloadEvent;
import mineplex.core.common.util.F;
import mineplex.core.common.util.NautHashMap;
@ -21,6 +19,8 @@ import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTime;
import mineplex.core.common.util.UtilTime.TimeUnit;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
public class Recharge extends MiniPlugin
{
@ -207,6 +207,19 @@ public class Recharge extends MiniPlugin
}
public boolean usable(Player player, String ability, boolean inform)
{
return usable(player, ability, inform, null);
}
/**
* Checks if cooldown is over, using a custom message or not
* @param player The player to be checked
* @param ability The ability to be checked
* @param inform Should it inform the player?
* @param message The custom message (if NULL, default message will be shown)
* @return If the ability is in cooldown or not for that player
*/
public boolean usable(Player player, String ability, boolean inform, String message)
{
if (!Get(player).containsKey(ability))
return true;
@ -218,8 +231,19 @@ public class Recharge extends MiniPlugin
else
{
if (inform && !Get(player).get(ability).DisplayForce && !Get(player).get(ability).AttachItem)
{
if (message == null)
{
UtilPlayer.message(player, F.main("Recharge", "You cannot use " + F.skill(ability) + " for " +
F.time(UtilTime.convertString((Get(player).get(ability).GetRemaining()), 1, TimeUnit.FIT)) + "."));
}
else
{
UtilPlayer.message(player, F.main("Recharge", message.replace("%a", F.skill(ability))
.replace("%t", F.time(UtilTime.convertString(Get(player).get(ability).GetRemaining(),
1, TimeUnit.FIT)))));
}
}
return false;
}

View File

@ -3,28 +3,29 @@ package mineplex.core.sponsorbranding;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.ConcurrentHashMap;
import javax.imageio.ImageIO;
import mineplex.core.MiniPlugin;
import org.bukkit.Location;
import org.bukkit.block.BlockFace;
import org.bukkit.plugin.java.JavaPlugin;
import mineplex.core.MiniPlugin;
import mineplex.core.ReflectivelyCreateMiniPlugin;
/**
*
* Manager for creating billboards with branding logos
*/
@ReflectivelyCreateMiniPlugin
public class BrandingManager extends MiniPlugin
{
private ConcurrentHashMap<Integer, BrandingPost> _posts = new ConcurrentHashMap<Integer, BrandingPost>();
private ConcurrentHashMap<String, BufferedImage> _imgCache = new ConcurrentHashMap<String, BufferedImage>();
public BrandingManager(JavaPlugin plugin)
private BrandingManager()
{
super("Branding Manager", plugin);
super("Branding Manager");
}
private BufferedImage getImage(String fileName)
@ -56,6 +57,28 @@ public class BrandingManager extends MiniPlugin
return image;
}
private BufferedImage getImage(URL url)
{
if (_imgCache.containsKey(url.toString()))
{
return _imgCache.get(url.toString());
}
BufferedImage image = null;
try
{
image = ImageIO.read(url);
_imgCache.put(url.toString(), image);
}
catch (IOException e)
{
e.printStackTrace();
}
return image;
}
/**
* Generates a billboard with a stored logo
* @param location The center of the billboard
@ -75,6 +98,22 @@ public class BrandingManager extends MiniPlugin
_posts.put(_posts.size(), bp);
}
public void createPost(Location location, BlockFace facing, URL url)
{
BufferedImage image = getImage(url);
if (image == null)
{
System.out.println("ERROR! Invalid image url!");
return;
}
BrandingPost brandingPost = new BrandingPost(location, facing, image);
brandingPost.spawn();
// Umm why not use a List?
_posts.put(_posts.size(), brandingPost);
}
/**
* Clears away all existing billboards
*/

View File

@ -68,6 +68,8 @@ public class BrandingPost
int width = (int) Math.ceil(_img.getWidth() / 128);
int height = (int) Math.ceil(_img.getHeight() / 128);
Bukkit.broadcastMessage("width=" + width + " height=" + height);
switch (_facing)
{
case EAST:
@ -160,6 +162,7 @@ public class BrandingPost
ItemStack item = getMapItem(x, y, _img);
i.setItem(item);
Bukkit.broadcastMessage(x + " <- X Y -> " + y);
_ents.add(i);
}
}

View File

@ -325,7 +325,8 @@ public class TreasureLocation implements Listener
event.setTo(newTo);
}
}
else
else if (event.getFrom().getWorld().equals(_currentTreasure.getCenterBlock().getWorld()) &&
event.getTo().getWorld().equals(_currentTreasure.getCenterBlock().getWorld()))
{
Location fromLocation = event.getFrom();
Location toLocation = event.getTo();

View File

@ -6,10 +6,6 @@ import java.io.FilenameFilter;
import java.io.IOException;
import java.util.Properties;
import mineplex.core.portal.GenericServer;
import mineplex.core.portal.Intent;
import mineplex.core.updater.command.BuildVersionCommand;
import mineplex.core.updater.command.RestartServerCommand;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.StringUtils;
import org.bukkit.Bukkit;
@ -24,7 +20,11 @@ import mineplex.core.MiniPlugin;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.NautHashMap;
import mineplex.core.portal.GenericServer;
import mineplex.core.portal.Intent;
import mineplex.core.portal.Portal;
import mineplex.core.updater.command.BuildVersionCommand;
import mineplex.core.updater.command.RestartServerCommand;
import mineplex.core.updater.event.RestartServerEvent;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.serverdata.Region;
@ -38,19 +38,21 @@ public class FileUpdater extends MiniPlugin
private String _serverName;
private Region _region;
private final GenericServer _transferHub;
private boolean _needUpdate;
private boolean _enabled = true;
private Properties _buildProperties;
public FileUpdater(JavaPlugin plugin, Portal portal, String serverName, Region region)
public FileUpdater(JavaPlugin plugin, Portal portal, String serverName, Region region, GenericServer transferHub)
{
super("File Updater", plugin);
_portal = portal;
_serverName = serverName;
_region = region;
_transferHub = transferHub;
GetPluginMd5s();
@ -81,7 +83,7 @@ public class FileUpdater extends MiniPlugin
for (Player player : Bukkit.getOnlinePlayers())
{
player.sendMessage(F.main("Updater", message));
_portal.sendPlayerToGenericServer(player, GenericServer.HUB, Intent.KICK);
_portal.sendPlayerToGenericServer(player, _transferHub, Intent.KICK);
}
}
}
@ -110,7 +112,7 @@ public class FileUpdater extends MiniPlugin
{
public void run()
{
_portal.sendAllPlayersToGenericServer(GenericServer.HUB, Intent.KICK);
_portal.sendAllPlayersToGenericServer(_transferHub, Intent.KICK);
}
}, 60L);

View File

@ -46,6 +46,7 @@ import mineplex.core.memory.MemoryFix;
import mineplex.core.message.MessageManager;
import mineplex.core.monitor.LagMeter;
import mineplex.core.packethandler.PacketHandler;
import mineplex.core.portal.GenericServer;
import mineplex.core.portal.Portal;
import mineplex.core.preferences.PreferencesManager;
import mineplex.core.punish.Punish;
@ -131,7 +132,7 @@ public class Clans extends JavaPlugin
Teleport teleport = new Teleport(this, _clientManager);
Portal portal = new Portal();
new FileUpdater(this, portal, serverStatusManager.getCurrentServerName(), serverStatusManager.getRegion());
new FileUpdater(this, portal, serverStatusManager.getCurrentServerName(), serverStatusManager.getRegion(), GenericServer.CLANS_HUB);
ClansBanManager clansBans = new ClansBanManager(this, _clientManager, _donationManager);
@ -222,7 +223,7 @@ public class Clans extends JavaPlugin
}
}
BlockRestore blockRestore = new BlockRestore(this);
BlockRestore blockRestore = require(BlockRestore.class);
IgnoreManager ignoreManager = new IgnoreManager(this, _clientManager, preferenceManager, portal);

View File

@ -4,7 +4,6 @@ import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.plugin.java.JavaPlugin;
import mineplex.core.common.Constants;
import mineplex.core.CustomTagFix;
import mineplex.core.PacketsInteractionFix;
import mineplex.core.account.CoreClientManager;
@ -39,6 +38,7 @@ import mineplex.core.packethandler.PacketHandler;
import mineplex.core.party.PartyManager;
import mineplex.core.pet.PetManager;
import mineplex.core.poll.PollManager;
import mineplex.core.portal.GenericServer;
import mineplex.core.portal.Portal;
import mineplex.core.preferences.PreferencesManager;
import mineplex.core.profileCache.ProfileCacheManager;
@ -71,14 +71,18 @@ import static mineplex.core.Managers.require;
*/
public class ClansHub extends JavaPlugin
{
private String WEB_CONFIG = "webServer";
@Override
public void onEnable()
{
Bukkit.setSpawnRadius(0);
getConfig().addDefault(Constants.WEB_CONFIG_KEY, Constants.WEB_ADDRESS);
getConfig().set(Constants.WEB_CONFIG_KEY, getConfig().getString(Constants.WEB_CONFIG_KEY));
getConfig().addDefault(WEB_CONFIG, "http://accounts.mineplex.com/");
getConfig().set(WEB_CONFIG, getConfig().getString(WEB_CONFIG));
saveConfig();
String webServerAddress = getConfig().getString(WEB_CONFIG);
//Logger.initialize(this);
//Velocity Fix
@ -95,7 +99,7 @@ public class ClansHub extends JavaPlugin
Recharge.Initialize(this);
VisibilityManager.Initialize(this); Give.Initialize(this);
Punish punish = new Punish(this, clientManager);
BlockRestore blockRestore = new BlockRestore(this);
BlockRestore blockRestore = require(BlockRestore.class);
DonationManager donationManager = require(DonationManager.class);
ServerConfiguration serverConfiguration = new ServerConfiguration(this, clientManager);
@ -153,7 +157,7 @@ public class ClansHub extends JavaPlugin
Chat chat = new Chat(this, incognito, clientManager, preferenceManager, achievementManager, serverStatusManager.getCurrentServerName());
new MessageManager(this, incognito, clientManager, preferenceManager, ignoreManager, punish, friendManager, chat);
new MemoryFix(this);
new FileUpdater(this, portal, serverStatusManager.getCurrentServerName(), serverStatusManager.getRegion());
new FileUpdater(this, portal, serverStatusManager.getCurrentServerName(), serverStatusManager.getRegion(), GenericServer.CLANS_HUB);
new CustomTagFix(this, packetHandler);
new PacketsInteractionFix(this, packetHandler);
new ResourcePackManager(this, portal);

View File

@ -5,7 +5,6 @@ import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import mineplex.core.common.Constants;
import mineplex.core.CustomTagFix;
import mineplex.core.PacketsInteractionFix;
import mineplex.core.account.CoreClientManager;
@ -22,6 +21,7 @@ import mineplex.core.chatsnap.SnapshotManager;
import mineplex.core.chatsnap.SnapshotPlugin;
import mineplex.core.chatsnap.SnapshotRepository;
import mineplex.core.command.CommandCenter;
import mineplex.core.common.Constants;
import mineplex.core.common.events.ServerShutdownEvent;
import mineplex.core.creature.Creature;
import mineplex.core.customdata.CustomDataManager;
@ -47,6 +47,7 @@ import mineplex.core.party.PartyManager;
import mineplex.core.personalServer.PersonalServerManager;
import mineplex.core.pet.PetManager;
import mineplex.core.poll.PollManager;
import mineplex.core.portal.GenericServer;
import mineplex.core.portal.Portal;
import mineplex.core.preferences.PreferencesManager;
import mineplex.core.profileCache.ProfileCacheManager;
@ -116,7 +117,7 @@ public class Hub extends JavaPlugin implements IRelation
Recharge.Initialize(this);
VisibilityManager.Initialize(this); Give.Initialize(this);
Punish punish = new Punish(this, clientManager);
BlockRestore blockRestore = new BlockRestore(this);
BlockRestore blockRestore = require(BlockRestore.class);
DonationManager donationManager = require(DonationManager.class);
ServerConfiguration serverConfiguration = new ServerConfiguration(this, clientManager);
@ -182,7 +183,7 @@ public class Hub extends JavaPlugin implements IRelation
Chat chat = new Chat(this, incognito, clientManager, preferenceManager, achievementManager, serverStatusManager.getCurrentServerName());
new MessageManager(this, incognito, clientManager, preferenceManager, ignoreManager, punish, friendManager, chat);
new MemoryFix(this);
new FileUpdater(this, portal, serverStatusManager.getCurrentServerName(), serverStatusManager.getRegion());
new FileUpdater(this, portal, serverStatusManager.getCurrentServerName(), serverStatusManager.getRegion(), GenericServer.HUB);
new CustomTagFix(this, packetHandler);
new PacketsInteractionFix(this, packetHandler);
new ResourcePackManager(this, portal);
@ -225,7 +226,7 @@ public class Hub extends JavaPlugin implements IRelation
//Updates
getServer().getScheduler().scheduleSyncRepeatingTask(this, new Updater(this), 1, 1);
BrandingManager brandingManager = new BrandingManager(this);
BrandingManager brandingManager = require(BrandingManager.class);
new BillboardManager(this, brandingManager);
require(TrackManager.class);

View File

@ -4,9 +4,6 @@ import mineplex.core.MiniPlugin;
import mineplex.core.common.events.ServerShutdownEvent;
import mineplex.core.sponsorbranding.BrandingManager;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.ItemFrame;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDamageEvent;

View File

@ -254,6 +254,9 @@ public class NewsManager extends MiniPlugin
if (event.getType() != UpdateType.FASTEST)
return;
if (_news.length == 0)
return;
String text = "";
double healthPercent = 1;

View File

@ -1,12 +1,21 @@
package mineplex.staffServer;
import java.util.UUID;
import net.minecraft.server.v1_8_R3.MinecraftServer;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_8_R3.CraftServer;
import org.bukkit.plugin.java.JavaPlugin;
import org.spigotmc.SpigotConfig;
import com.mojang.authlib.GameProfile;
import mineplex.core.common.Constants;
import mineplex.core.account.CoreClientManager;
import mineplex.core.achievement.AchievementManager;
import mineplex.core.chat.Chat;
import mineplex.core.command.CommandCenter;
import mineplex.core.common.Constants;
import mineplex.core.common.Rank;
import mineplex.core.creature.Creature;
import mineplex.core.disguise.DisguiseManager;
@ -17,6 +26,7 @@ import mineplex.core.memory.MemoryFix;
import mineplex.core.monitor.LagMeter;
import mineplex.core.npc.NpcManager;
import mineplex.core.packethandler.PacketHandler;
import mineplex.core.portal.GenericServer;
import mineplex.core.portal.Portal;
import mineplex.core.powerplayclub.PowerPlayClubRepository;
import mineplex.core.preferences.PreferencesManager;
@ -29,13 +39,6 @@ import mineplex.core.updater.FileUpdater;
import mineplex.core.updater.Updater;
import mineplex.staffServer.customerSupport.CustomerSupport;
import mineplex.staffServer.salespackage.SalesPackageManager;
import net.minecraft.server.v1_8_R3.MinecraftServer;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_8_R3.CraftServer;
import org.bukkit.plugin.java.JavaPlugin;
import org.spigotmc.SpigotConfig;
import java.util.UUID;
import static mineplex.core.Managers.require;
@ -67,7 +70,7 @@ public class StaffServer extends JavaPlugin
StatsManager statsManager = new StatsManager(this, clientManager);
new Chat(this, null, clientManager, preferenceManager, new AchievementManager(statsManager, clientManager, donationManager, null, eloManager), serverStatusManager.getCurrentServerName());
new MemoryFix(this);
new FileUpdater(this, portal, serverStatusManager.getCurrentServerName(), serverStatusManager.getRegion());
new FileUpdater(this, portal, serverStatusManager.getCurrentServerName(), serverStatusManager.getRegion(), GenericServer.HUB);
require(PacketHandler.class);
require(DisguiseManager.class);

View File

@ -1,69 +1,138 @@
package nautilus.game.arcade.uhc;
import net.minecraft.server.v1_8_R3.BiomeBase;
import org.apache.commons.io.FileUtils;
import org.bukkit.Bukkit;
import org.bukkit.Difficulty;
import org.bukkit.World;
import org.bukkit.WorldCreator;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.AsyncPlayerPreLoginEvent;
import org.bukkit.plugin.java.JavaPlugin;
import org.spigotmc.WatchdogThread;
import org.zeroturnaround.zip.ZipEntrySource;
import org.zeroturnaround.zip.ZipUtil;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ThreadLocalRandom;
import java.util.logging.Level;
import java.util.zip.ZipEntry;
public class WorldGen extends JavaPlugin implements Runnable, Listener
import net.minecraft.server.v1_8_R3.BiomeBase;
import org.apache.commons.io.FileUtils;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.Difficulty;
import org.bukkit.World;
import org.bukkit.WorldBorder;
import org.bukkit.WorldCreator;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.craftbukkit.v1_8_R3.CraftWorld;
import org.bukkit.entity.Entity;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.AsyncPlayerPreLoginEvent;
import org.bukkit.event.world.ChunkUnloadEvent;
import org.bukkit.event.world.WorldInitEvent;
import org.bukkit.plugin.java.JavaPlugin;
import org.spigotmc.WatchdogThread;
import org.zeroturnaround.zip.ByteSource;
import org.zeroturnaround.zip.FileSource;
import org.zeroturnaround.zip.ZipEntrySource;
import org.zeroturnaround.zip.ZipUtil;
import org.zeroturnaround.zip.commons.IOUtils;
public class WorldGen extends JavaPlugin implements Listener
{
private static final int MIN_X = -1000;
private static final int MIN_Z = -1000;
private static final int MAX_X = 1000;
private static final int MAX_Z = 1000;
// The world will be -MAP_SIZE to MAP_SIZE large
private static final int MAP_SIZE = 1000;
private static final int VIEW_DISTANCE = 5;
private static final String API_HOST_FILE = "api-config.dat";
private static final Map<String, String> API_HOST_MAP = new HashMap<>();
static
{
try
{
File configFile = new File(API_HOST_FILE);
YamlConfiguration configuration = YamlConfiguration.loadConfiguration(configFile);
for (String key : configuration.getKeys(false))
{
String ip = configuration.getConfigurationSection(key).getString("ip");
// Use parseInt to catch non-ints instead of a 0
int port = Integer.parseInt(configuration.getConfigurationSection(key).getString("port"));
if (ip == null)
{
throw new NullPointerException();
}
API_HOST_MAP.put(key, ip + ":" + port);
}
}
catch (Throwable t)
{
t.printStackTrace();
}
}
@EventHandler
public void login(AsyncPlayerPreLoginEvent event)
{
event.setKickMessage("get out");
event.setLoginResult(AsyncPlayerPreLoginEvent.Result.KICK_OTHER);
}
@EventHandler
public void unload(ChunkUnloadEvent event)
{
event.setCancelled(true);
}
@EventHandler
public void init(WorldInitEvent event)
{
// Prevent any eager generation
event.getWorld().setKeepSpawnInMemory(false);
}
@Override
public void onEnable()
{
getLogger().info("Cleaning up other worlds");
for (World world : getServer().getWorlds())
{
world.setKeepSpawnInMemory(false);
world.setSpawnFlags(false, false);
world.setAmbientSpawnLimit(0);
world.setAnimalSpawnLimit(0);
world.setMonsterSpawnLimit(0);
world.setWaterAnimalSpawnLimit(0);
world.getEntities().forEach(Entity::remove);
for (Chunk chunk : world.getLoadedChunks())
{
chunk.unload(false, false);
}
getServer().unloadWorld(world, false);
getLogger().info("Unloaded " + world.getName());
}
getLogger().info("Replacing biomes");
BiomeBase.getBiomes()[BiomeBase.OCEAN.id] = BiomeBase.PLAINS;
BiomeBase.getBiomes()[BiomeBase.DEEP_OCEAN.id] = BiomeBase.PLAINS;
BiomeBase.getBiomes()[BiomeBase.SWAMPLAND.id] = BiomeBase.PLAINS;
BiomeBase.getBiomes()[BiomeBase.RIVER.id] = BiomeBase.PLAINS;
getLogger().info("Forcing system GC");
System.gc();
WatchdogThread.doStop();
getServer().getScheduler().runTaskTimer(this, this, 20L, 20L * 5L);
getServer().getPluginManager().registerEvents(this, this);
}
@EventHandler
public void onJoin(AsyncPlayerPreLoginEvent event)
{
event.setLoginResult(AsyncPlayerPreLoginEvent.Result.KICK_OTHER);
event.setKickMessage("Shoo, go away");
}
@Override
public void run()
{
File root = new File(".");
if (!root.exists())
{
getLogger().severe("Root folder does not exist. Aborting");
getServer().shutdown();
System.exit(0);
return;
}
@ -73,7 +142,7 @@ public class WorldGen extends JavaPlugin implements Runnable, Listener
if (!outputDirectory.mkdir())
{
getLogger().severe("Could not create output folder. Aborting");
getServer().shutdown();
System.exit(0);
return;
}
}
@ -85,6 +154,7 @@ public class WorldGen extends JavaPlugin implements Runnable, Listener
if (outputFile.exists())
{
getLogger().info("Seed " + seed + " has already been generated. Skipping");
System.exit(0);
return;
}
@ -93,30 +163,52 @@ public class WorldGen extends JavaPlugin implements Runnable, Listener
if (!outputFile.createNewFile())
{
getLogger().severe("Could not create new output file. Aborting");
getServer().shutdown();
System.exit(0);
return;
}
}
catch (IOException e)
{
getLogger().log(Level.SEVERE, "Could not create new output file. Aborting", e);
getServer().shutdown();
System.exit(0);
return;
}
File previousSession = new File("generating");
if (previousSession.exists())
{
if (!FileUtils.deleteQuietly(previousSession))
{
getLogger().severe("Could not delete previous generation session. Aborting");
System.exit(0);
return;
}
}
getLogger().info("Generating world seed " + seed);
World world = new WorldCreator("generating")
.environment(World.Environment.NORMAL)
.seed(seed)
.createWorld();
world.setDifficulty(Difficulty.HARD);
world.setKeepSpawnInMemory(false);
world.setDifficulty(Difficulty.HARD);
WorldBorder border = world.getWorldBorder();
border.setCenter(0.0, 0.0);
border.setSize(MAP_SIZE * 2);
int minChunkX = (MIN_X >> 4) - VIEW_DISTANCE;
int minChunkZ = (MIN_Z >> 4) - VIEW_DISTANCE;
int maxChunkX = (MAX_X >> 4) + VIEW_DISTANCE;
int maxChunkZ = (MAX_Z >> 4) + VIEW_DISTANCE;
int minChunkX = (-MAP_SIZE >> 4) - VIEW_DISTANCE;
int minChunkZ = (-MAP_SIZE >> 4) - VIEW_DISTANCE;
int maxChunkX = (MAP_SIZE >> 4) + VIEW_DISTANCE;
int maxChunkZ = (MAP_SIZE >> 4) + VIEW_DISTANCE;
net.minecraft.server.v1_8_R3.WorldServer nmsWorld = ((CraftWorld) world).getHandle();
//
// Field mfield = nmsWorld.getClass().getDeclaredField("M");
// mfield.setAccessible(true);
//
// HashTreeSet<NextTickListEntry> treeSet = ((HashTreeSet) mfield.get(nmsWorld));
for (int x = minChunkX; x <= maxChunkX; x++)
{
@ -124,7 +216,15 @@ public class WorldGen extends JavaPlugin implements Runnable, Listener
for (int z = minChunkZ; z <= maxChunkZ; z++)
{
world.getChunkAt(x, z).load(true);
nmsWorld.a(true);
// Manually tick blocks - this should be the equivalent of letting a full server tick run once
// between each chunk generation, except we cut out the extra useless stuff
}
// System.out.println("M: " + treeSet.size());
// System.out.println("E: " + nmsWorld.entityList.size());
// System.out.println("TE: " + nmsWorld.tileEntityList.size());
// System.out.println("C: " + nmsWorld.chunkProviderServer.chunks.size());
}
for (int x = minChunkX; x <= maxChunkX; x++)
@ -134,6 +234,11 @@ public class WorldGen extends JavaPlugin implements Runnable, Listener
{
world.getChunkAt(x, z).unload(true, false);
}
// System.out.println("M: " + treeSet.size());
// System.out.println("E: " + nmsWorld.entityList.size());
// System.out.println("TE: " + nmsWorld.tileEntityList.size());
// System.out.println("C: " + nmsWorld.chunkProviderServer.chunks.size());
}
getLogger().info("Unloading and saving world");
@ -145,10 +250,10 @@ public class WorldGen extends JavaPlugin implements Runnable, Listener
StringBuilder worldconfig = new StringBuilder();
worldconfig.append("MAP_NAME:UHC World").append(System.lineSeparator());
worldconfig.append("MAP_AUTHOR:Mineplex").append(System.lineSeparator());
worldconfig.append("MIN_X:").append(MIN_X).append(System.lineSeparator());
worldconfig.append("MIN_Z:").append(MIN_Z).append(System.lineSeparator());
worldconfig.append("MAX_X:").append(MAX_X).append(System.lineSeparator());
worldconfig.append("MAX_Z:").append(MAX_Z).append(System.lineSeparator());
worldconfig.append("MIN_X:").append(-MAP_SIZE).append(System.lineSeparator());
worldconfig.append("MIN_Z:").append(-MAP_SIZE).append(System.lineSeparator());
worldconfig.append("MAX_X:").append(MAP_SIZE).append(System.lineSeparator());
worldconfig.append("MAX_Z:").append(MAP_SIZE).append(System.lineSeparator());
for (int i = 1; i <= 60; i++)
{
worldconfig.append("TEAM_NAME:").append(i).append(System.lineSeparator());
@ -164,82 +269,68 @@ public class WorldGen extends JavaPlugin implements Runnable, Listener
if (regionFiles == null)
{
getLogger().severe("Unexpected null region files. Aborting");
getServer().shutdown();
System.exit(0);
return;
}
List<ZipEntrySource> zipEntrySourceList = new ArrayList<>();
zipEntrySourceList.add(new ZipEntrySource()
{
@Override
public String getPath()
{
return "WorldConfig.dat";
}
@Override
public ZipEntry getEntry()
{
return new ZipEntry(getPath());
}
@Override
public InputStream getInputStream() throws IOException
{
return new ByteArrayInputStream(worldconfig.toString().getBytes(StandardCharsets.UTF_8));
}
});
zipEntrySourceList.add(new ByteSource("WorldConfig.dat", worldconfig.toString().getBytes(StandardCharsets.UTF_8)));
for (File file : regionFiles)
{
zipEntrySourceList.add(new ZipEntrySource()
{
@Override
public String getPath()
{
return "region/" + file.getName();
zipEntrySourceList.add(new FileSource("region/" + file.getName(), file));
}
@Override
public ZipEntry getEntry()
{
return new ZipEntry(getPath());
}
@Override
public InputStream getInputStream() throws IOException
{
return new FileInputStream(file);
}
});
}
zipEntrySourceList.add(new ZipEntrySource()
{
@Override
public String getPath()
{
return "level.dat";
}
@Override
public ZipEntry getEntry()
{
return new ZipEntry(getPath());
}
@Override
public InputStream getInputStream() throws IOException
{
return new FileInputStream(new File(worldFolder, "level.dat"));
}
});
zipEntrySourceList.add(new FileSource("level.dat", new File(worldFolder, "level.dat")));
ZipUtil.pack(zipEntrySourceList.toArray(new ZipEntrySource[zipEntrySourceList.size()]), outputFile);
FileUtils.deleteQuietly(worldFolder);
try
{
getLogger().info("Uploading " + seed + "!");
URL url = new URL("http://" + API_HOST_MAP.get("ENDERCHEST") + "/map/uhc/upload?name=" + outputFile.getName());
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);
IOUtils.copy(new FileInputStream(outputFile), connection.getOutputStream());
connection.connect();
if (connection.getResponseCode() != 200)
{
if (connection.getResponseCode() == 409)
{
getLogger().warning("Oops - Server rejected " + seed + " because it was already generated");
if (!outputFile.delete())
{
getLogger().warning("Could not clean up " + seed);
}
}
else
{
getLogger().severe("Failed to upload " + seed + ": " + connection.getResponseCode() + " " + connection.getResponseMessage());
}
}
else
{
getLogger().info("Uploaded " + seed + "!");
if (!outputFile.delete())
{
getLogger().warning("Could not clean up " + seed);
}
}
}
catch (IOException e)
{
getLogger().log(Level.SEVERE, "An error occurred while uploading " + seed + "!", e);
}
finally
{
getLogger().info("Finished generating world seed " + seed);
}
Bukkit.shutdown();
}
}

View File

@ -10,12 +10,10 @@ import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import org.spigotmc.SpigotConfig;
import mineplex.core.common.Constants;
import mineplex.core.CustomTagFix;
import mineplex.core.FoodDupeFix;
import mineplex.core.PacketsInteractionFix;
import mineplex.core.TimingsFix;
import mineplex.core.account.CoreClientManager;
import mineplex.core.achievement.AchievementManager;
import mineplex.core.antihack.AntiHack;
@ -28,6 +26,7 @@ import mineplex.core.chatsnap.SnapshotManager;
import mineplex.core.chatsnap.SnapshotPlugin;
import mineplex.core.chatsnap.SnapshotRepository;
import mineplex.core.command.CommandCenter;
import mineplex.core.common.Constants;
import mineplex.core.common.events.ServerShutdownEvent;
import mineplex.core.common.util.FileUtil;
import mineplex.core.common.util.UtilServer;
@ -55,6 +54,7 @@ import mineplex.core.npc.NpcManager;
import mineplex.core.packethandler.PacketHandler;
import mineplex.core.pet.PetManager;
import mineplex.core.poll.PollManager;
import mineplex.core.portal.GenericServer;
import mineplex.core.portal.Portal;
import mineplex.core.preferences.PreferencesManager;
import mineplex.core.profileCache.ProfileCacheManager;
@ -138,7 +138,7 @@ public class Arcade extends JavaPlugin
LeaderboardManager leaderboardManager = new LeaderboardManager(this, _clientManager);
Teleport teleport = new Teleport(this, _clientManager);
Portal portal = new Portal();
new FileUpdater(this, portal, serverStatusManager.getCurrentServerName(), serverStatusManager.getRegion());
new FileUpdater(this, portal, serverStatusManager.getCurrentServerName(), serverStatusManager.getRegion(), GenericServer.HUB);
DisguiseManager disguiseManager = require(DisguiseManager.class);
@ -162,7 +162,7 @@ public class Arcade extends JavaPlugin
new SnapshotPlugin(this, snapshotManager, _clientManager);
new ReportPlugin(this, reportManager);
BlockRestore blockRestore = new BlockRestore(this);
BlockRestore blockRestore = require(BlockRestore.class);
ProjectileManager projectileManager = new ProjectileManager(this);
HologramManager hologramManager = new HologramManager(this, packetHandler);

View File

@ -288,7 +288,7 @@ public class ArcadeManager extends MiniPlugin implements IRelation
_conditionManager = new SkillConditionManager(plugin);
_brandingManager = new BrandingManager(plugin);
_brandingManager = require(BrandingManager.class);
_boosterManager = boosterManager;

View File

@ -414,6 +414,12 @@ public class Minestrike extends TeamGame
int amount;
String gunType = (String) event.GetLog().GetLastDamager().GetDamage().getFirst().getMetadata().get("gunType");
if (gunType == null)
{
amount = 300;
}
else
{
switch (gunType)
{
case "AWP":
@ -431,6 +437,7 @@ public class Minestrike extends TeamGame
default:
amount = 300;
}
}
_shopManager.addMoney(killer, amount, "kill with " + event.GetLog().GetLastDamager().GetReason());

View File

@ -193,7 +193,7 @@ public class PerkBoneRush extends SmashPerk implements IThrown
return;
}
if (!(target instanceof Player || data.getThrower() instanceof Player))
if (!(target instanceof Player) || !(data.getThrower() instanceof Player))
{
return;
}

View File

@ -102,11 +102,6 @@ public class PerkFishFlurry extends SmashPerk implements IThrown
return;
}
if (!Recharge.Instance.use(player, GetName(), COOLDOWN, true, true))
{
return;
}
event.setCancelled(true);
Set<Block> blocks = new HashSet<>();
@ -131,11 +126,19 @@ public class PerkFishFlurry extends SmashPerk implements IThrown
blocks.add(cur);
}
if (!blocks.isEmpty())
{
if (!Recharge.Instance.use(player, GetName(), COOLDOWN, true, true))
{
return;
}
_active.add(new DataSquidGeyser(player, blocks));
// Inform
UtilPlayer.message(player, F.main("Game", "You used " + F.skill(GetName()) + "."));
}
}
@EventHandler
public void update(UpdateEvent event)

View File

@ -169,7 +169,7 @@ public class PerkWitherImage extends SmashPerk
}
}
if (event.getTarget() != null && _skeletons.get(event.getTarget().getUniqueId()).equals(event.getEntity()))
if (event.getTarget() != null && event.getEntity().equals(_skeletons.get(event.getTarget().getUniqueId())))
{
event.setCancelled(true);
}

View File

@ -503,6 +503,12 @@ public class PerkWolf extends SmashPerk
UUID uuid = playerIterator.next();
Player player = UtilPlayer.searchExact(uuid);
if (player == null)
{
playerIterator.remove();
continue;
}
Iterator<Long> timeIterator = _repeat.get(uuid).iterator();
while (timeIterator.hasNext())

View File

@ -365,17 +365,19 @@ public abstract class UHC extends Game
UtilPlayer.message(caller, F.main("Debug", "World info for " + targetWorld.getName()));
UtilPlayer.message(caller, F.desc("Chunks", String.valueOf(chunks.length)));
UtilPlayer.message(caller, F.desc("Entities", String.valueOf(targetWorld.getEntities().size())));
UtilPlayer.message(caller, F.desc("Tile Entities", String.valueOf(Arrays.stream(chunks).map(Chunk::getTileEntities).map(Arrays::asList).flatMap(Collection::stream)
.count())));
UtilPlayer.message(caller, F.desc("Tile Entities", String.valueOf(Arrays.stream(chunks).map(Chunk::getTileEntities).map(Arrays::asList).mapToLong(Collection::size).sum())));
UtilPlayer.message(caller, F.desc("View Distance", String.valueOf(nmsWorld.spigotConfig.viewDistance)));
UtilPlayer.message(caller, F.desc("Unload queue size", String.valueOf(nmsWorld.chunkProviderServer.unloadQueue.size())));
try
{
HashTreeSet<NextTickListEntry> m = (HashTreeSet<NextTickListEntry>) nmsWorld.getClass().getField("M").get(nmsWorld);
Field f = nmsWorld.getClass().getDeclaredField("M");
f.setAccessible(true);
HashTreeSet<NextTickListEntry> m = (HashTreeSet<NextTickListEntry>) f.get(nmsWorld);
UtilPlayer.message(caller, F.desc("Pending tick", String.valueOf(m.size())));
}
catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException e)
catch (ReflectiveOperationException e)
{
e.printStackTrace();
}
@ -571,7 +573,7 @@ public abstract class UHC extends Game
}
}
});
registerDebugCommand(new DebugCommand("uhccallchunks", Rank.DEVELOPER)
registerDebugCommand(new DebugCommand("uhcallchunks", Rank.DEVELOPER)
{
@Override

View File

@ -255,6 +255,9 @@ public class WitherGame extends TeamGame implements IBlockRestorer
if (GetState() == GameState.Recruit || GetState() == GameState.Prepare)
{
Projectile proj = event.getEntity();
if (proj instanceof WitherSkull)
{
WitherSkull ws = (WitherSkull) proj;
if (ws.getShooter() instanceof Wither)
@ -263,6 +266,7 @@ public class WitherGame extends TeamGame implements IBlockRestorer
}
}
}
}
@EventHandler
public void handleCustomBlockPlace(BlockPlaceEvent event)

View File

@ -156,6 +156,8 @@ public class ProgressingKitManager implements Listener
PlayerKit playerKit = _manager.getKitProgressionManager().getDataManager().get(player.getUniqueId());
try
{
if (_manager.GetGame() != null)
{
for (Kit kit : _manager.GetGame().GetKits())
{
@ -166,6 +168,7 @@ public class ProgressingKitManager implements Listener
}
}
}
}
finally
{
_manager.getKitProgressionManager().getDataManager().remove(playerKit);

View File

@ -328,7 +328,7 @@ public class PvP extends JavaPlugin implements IPlugin, Listener
public BlockRestore GetBlockRestore()
{
if (_blockRestore == null)
_blockRestore = new BlockRestore(this);
_blockRestore = require(BlockRestore.class);
return _blockRestore;
}

View File

@ -38,6 +38,7 @@ import mineplex.core.monitor.LagMeter;
import mineplex.core.mount.MountManager;
import mineplex.core.packethandler.PacketHandler;
import mineplex.core.pet.PetManager;
import mineplex.core.portal.GenericServer;
import mineplex.core.portal.Portal;
import mineplex.core.preferences.PreferencesManager;
import mineplex.core.profileCache.ProfileCacheManager;
@ -102,7 +103,7 @@ public class Hub extends JavaPlugin
Creature creature = new Creature(this);
ServerStatusManager serverStatusManager = new ServerStatusManager(this, _clientManager, new LagMeter(this, _clientManager));
Portal portal = new Portal();
new FileUpdater(this, portal, serverStatusManager.getCurrentServerName(), serverStatusManager.getRegion());
new FileUpdater(this, portal, serverStatusManager.getCurrentServerName(), serverStatusManager.getRegion(), GenericServer.HUB);
DisguiseManager disguiseManager = require(DisguiseManager.class);
@ -117,7 +118,7 @@ public class Hub extends JavaPlugin
Chat chat = new Chat(this, incognito, _clientManager, preferenceManager, achievementManager, serverStatusManager.getCurrentServerName());
new MessageManager(this, incognito, _clientManager, preferenceManager, ignoreManager, punish, friendManager, chat);
BlockRestore blockRestore = new BlockRestore(this);
BlockRestore blockRestore = require(BlockRestore.class);
ProjectileManager projectileManager = new ProjectileManager(this);
HologramManager hologramManager = new HologramManager(this, packetHandler);

View File

@ -0,0 +1,5 @@
name: GemHunters
main: mineplex.gemhunters.GemHunters
version: 0.1
commands:
playwire:

View File

@ -0,0 +1,27 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.mineplex</groupId>
<artifactId>mineplex-plugin</artifactId>
<version>dev-SNAPSHOT</version>
<relativePath>../plugin.xml</relativePath>
</parent>
<name>GemHunters</name>
<artifactId>mineplex-game-gemhunters</artifactId>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>mineplex-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>mineplex-minecraft-game-core</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,313 @@
package mineplex.gemhunters;
import net.minecraft.server.v1_8_R3.MinecraftServer;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_8_R3.CraftWorld;
import org.bukkit.plugin.java.JavaPlugin;
import org.spigotmc.SpigotConfig;
import mineplex.core.CustomTagFix;
import mineplex.core.FoodDupeFix;
import mineplex.core.TimingsFix;
import mineplex.core.account.CoreClientManager;
import mineplex.core.achievement.AchievementManager;
import mineplex.core.antihack.AntiHack;
import mineplex.core.beta.BetaWhitelist;
import mineplex.core.blockrestore.BlockRestore;
import mineplex.core.boosters.BoosterManager;
import mineplex.core.chat.Chat;
import mineplex.core.command.CommandCenter;
import mineplex.core.common.Constants;
import mineplex.core.common.events.ServerShutdownEvent;
import mineplex.core.communities.CommunityManager;
import mineplex.core.cosmetic.CosmeticManager;
import mineplex.core.creature.Creature;
import mineplex.core.delayedtask.DelayedTask;
import mineplex.core.disguise.DisguiseManager;
import mineplex.core.donation.DonationManager;
import mineplex.core.elo.EloManager;
import mineplex.core.explosion.Explosion;
import mineplex.core.friend.FriendManager;
import mineplex.core.gadget.GadgetManager;
import mineplex.core.give.Give;
import mineplex.core.hologram.HologramManager;
import mineplex.core.ignore.IgnoreManager;
import mineplex.core.incognito.IncognitoManager;
import mineplex.core.inventory.InventoryManager;
import mineplex.core.itemstack.ItemStackFactory;
import mineplex.core.memory.MemoryFix;
import mineplex.core.menu.MenuManager;
import mineplex.core.message.MessageManager;
import mineplex.core.monitor.LagMeter;
import mineplex.core.mount.MountManager;
import mineplex.core.npc.NpcManager;
import mineplex.core.packethandler.PacketHandler;
import mineplex.core.party.PartyManager;
import mineplex.core.pet.PetManager;
import mineplex.core.portal.GenericServer;
import mineplex.core.portal.Portal;
import mineplex.core.powerplayclub.PowerPlayClubRepository;
import mineplex.core.preferences.PreferencesManager;
import mineplex.core.projectile.ProjectileManager;
import mineplex.core.punish.Punish;
import mineplex.core.recharge.Recharge;
import mineplex.core.serverConfig.ServerConfiguration;
import mineplex.core.stats.StatsManager;
import mineplex.core.status.ServerStatusManager;
import mineplex.core.teleport.Teleport;
import mineplex.core.thank.ThankManager;
import mineplex.core.twofactor.TwoFactorAuth;
import mineplex.core.updater.FileUpdater;
import mineplex.core.updater.Updater;
import mineplex.core.visibility.VisibilityManager;
import mineplex.gemhunters.beta.BetaModule;
import mineplex.gemhunters.bounties.BountyModule;
import mineplex.gemhunters.chat.ChatModule;
import mineplex.gemhunters.death.DeathModule;
import mineplex.gemhunters.death.npc.NPCManager;
import mineplex.gemhunters.economy.CashOutModule;
import mineplex.gemhunters.economy.EconomyModule;
import mineplex.gemhunters.loot.InventoryModule;
import mineplex.gemhunters.loot.LootModule;
import mineplex.gemhunters.map.ItemMapModule;
import mineplex.gemhunters.mount.MountModule;
import mineplex.gemhunters.quest.QuestModule;
import mineplex.gemhunters.safezone.SafezoneModule;
import mineplex.gemhunters.scoreboard.ScoreboardModule;
import mineplex.gemhunters.shop.ShopModule;
import mineplex.gemhunters.spawn.SpawnModule;
import mineplex.gemhunters.supplydrop.SupplyDropModule;
import mineplex.gemhunters.world.DebugListeners;
import mineplex.gemhunters.world.TimeCycle;
import mineplex.gemhunters.world.UndergroundMobs;
import mineplex.gemhunters.world.WorldListeners;
import mineplex.gemhunters.worldevent.WorldEventModule;
import mineplex.minecraft.game.core.combat.CombatManager;
import mineplex.minecraft.game.core.condition.ConditionManager;
import mineplex.minecraft.game.core.damage.DamageManager;
import static mineplex.core.Managers.require;
/**
* Gem Hunters main class <br>
*
* TODO make documentation and a nice header
*
* @author Sam
*/
public class GemHunters extends JavaPlugin
{
@Override
public void onEnable()
{
// Load configuration
getConfig().addDefault(Constants.WEB_CONFIG_KEY, Constants.WEB_ADDRESS);
getConfig().set(Constants.WEB_CONFIG_KEY, getConfig().getString(Constants.WEB_CONFIG_KEY));
saveConfig();
// Load core modules
CommandCenter.Initialize(this);
// Client Manager
CoreClientManager clientManager = new CoreClientManager(this);
// Donation Manager
DonationManager donationManager = require(DonationManager.class);
// Command Centre
CommandCenter.Instance.setClientManager(clientManager);
// Timings
require(TimingsFix.class);
// ItemStacks
ItemStackFactory.Initialize(this, false);
// Delayed Tasks
DelayedTask.Initialize(this);
// Recharge
Recharge.Initialize(this);
// Visibility
VisibilityManager.Initialize(this);
// Give
Give.Initialize(this);
// Server config
ServerConfiguration serverConfig = new ServerConfiguration(this, clientManager);
// Teleport
new Teleport(this, clientManager);
// Packets
PacketHandler packetHandler = require(PacketHandler.class);
// Vanish
IncognitoManager incognito = new IncognitoManager(this, clientManager, packetHandler);
// Preferences
PreferencesManager preferenceManager = new PreferencesManager(this, incognito, clientManager);
// Why do these depend on each other... :(
incognito.setPreferencesManager(preferenceManager);
// Server Status
ServerStatusManager serverStatusManager = new ServerStatusManager(this, clientManager, new LagMeter(this, clientManager));
// Portal
Portal portal = new Portal();
// File Updater
new FileUpdater(this, portal, serverStatusManager.getCurrentServerName(), serverStatusManager.getRegion(), GenericServer.BETA_HUB);
// Punish
Punish punish = new Punish(this, clientManager);
// Disguises
DisguiseManager disguiseManager = require(DisguiseManager.class);
// Creatures
Creature creature = new Creature(this);
// The old classic Damage Manager
DamageManager damageManager = new DamageManager(this, new CombatManager(this), new NpcManager(this, creature), disguiseManager, new ConditionManager(this));
damageManager.SetEnabled(false);
// GWEN
AntiHack antiHack = require(AntiHack.class);
Bukkit.getScheduler().runTask(this, antiHack::enableAnticheat);
// Block Restore
BlockRestore blockRestore = require(BlockRestore.class);
// Ignoring
IgnoreManager ignoreManager = new IgnoreManager(this, clientManager, preferenceManager, portal);
// Statistics
StatsManager statsManager = new StatsManager(this, clientManager);
// Elo
EloManager eloManager = new EloManager(this, clientManager);
// Achievements
AchievementManager achievementManager = new AchievementManager(statsManager, clientManager, donationManager, incognito, eloManager);
// Chat/Messaging
Chat chat = new Chat(this, incognito, clientManager, preferenceManager, achievementManager, serverStatusManager.getCurrentServerName());
new MessageManager(this, incognito, clientManager, preferenceManager, ignoreManager, punish, new FriendManager(this, clientManager, preferenceManager, portal), chat);
// Parties
new PartyManager();
// Communities
new CommunityManager(this, clientManager);
// Fixes
new MemoryFix(this);
new FoodDupeFix(this);
// Explosions
Explosion explosion = new Explosion(this, blockRestore);
explosion.SetDebris(true);
explosion.SetTemporaryDebris(false);
// Inventories
InventoryManager inventoryManager = new InventoryManager(this, clientManager);
// Reports
// SnapshotManager snapshotManager = new SnapshotManager(this, new
// SnapshotRepository(serverStatusManager.getCurrentServerName(),
// getLogger()));
// new SnapshotPlugin(this, snapshotManager, clientManager);
// new ReportPlugin(this, new ReportManager(this, snapshotManager,
// clientManager, incognito, punish, serverStatusManager.getRegion(),
// serverStatusManager.getCurrentServerName(), 1));
// Tag fix
new CustomTagFix(this, packetHandler);
// Holograms
HologramManager hologramManager = new HologramManager(this, packetHandler);
// Menus
new MenuManager(this);
// Gadgets, used for mounts, lots of managers for something really small
// :(
MountManager mountManager = new MountManager(this, clientManager, donationManager, blockRestore, disguiseManager);
PetManager petManager = new PetManager(this, clientManager, donationManager, inventoryManager, disguiseManager, creature, blockRestore);
ProjectileManager projectileManager = new ProjectileManager(this);
GadgetManager gadgetManager = new GadgetManager(this, clientManager, donationManager, inventoryManager, mountManager, petManager, preferenceManager, disguiseManager, blockRestore, projectileManager, achievementManager, packetHandler, hologramManager, incognito);
ThankManager thankManager = new ThankManager(this, clientManager, donationManager);
BoosterManager boosterManager = new BoosterManager(this, null, clientManager, donationManager, inventoryManager, thankManager);
CosmeticManager cosmeticManager = new CosmeticManager(this, clientManager, donationManager, inventoryManager, gadgetManager, mountManager, petManager, null, boosterManager);
cosmeticManager.setActive(false);
cosmeticManager.setHideParticles(true);
gadgetManager.setGadgetEnabled(false);
// Now we finally get to enable the Gem Hunters modules
// Though if any other module needs one of these it will be generated in
// order, however they are all here just for good measure.
require(BetaModule.class);
//require(DebugModule.class);
require(BountyModule.class);
require(CashOutModule.class);
require(ChatModule.class);
require(DeathModule.class);
require(EconomyModule.class);
require(InventoryModule.class);
require(LootModule.class);
require(ItemMapModule.class);
require(MountModule.class);
require(QuestModule.class);
require(SafezoneModule.class);
require(ScoreboardModule.class);
require(SpawnModule.class);
require(ShopModule.class);
require(SupplyDropModule.class);
require(WorldEventModule.class);
// An arbitrary collection of world listeners such as block place/break,
// interact events etc...
new WorldListeners(this);
new TimeCycle(this);
new UndergroundMobs(this);
new DebugListeners(this);
// Combat npc
new NPCManager(hologramManager);
// UpdateEvent!!!
new Updater(this);
// Disable spigot's item merging
for (World world : getServer().getWorlds())
{
((CraftWorld) world).getHandle().spigotConfig.itemMerge = 0;
}
// Turn off the server's debugging
MinecraftServer.getServer().getPropertyManager().setProperty("debug", false);
SpigotConfig.debug = false;
// Two-factor auth
require(TwoFactorAuth.class);
// beta whitelist
new BetaWhitelist(clientManager, new PowerPlayClubRepository(this, clientManager, donationManager));
}
@Override
public void onDisable()
{
getServer().getPluginManager().callEvent(new ServerShutdownEvent(this));
}
}

View File

@ -0,0 +1,49 @@
package mineplex.gemhunters.beta;
import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler;
import mineplex.core.MiniPlugin;
import mineplex.core.ReflectivelyCreateMiniPlugin;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
@ReflectivelyCreateMiniPlugin
public class BetaModule extends MiniPlugin
{
private static final String[] ANNOUCEMENTS = {
"Please remember this game is an early access BETA and all bugs should be reported at mineplex.com/forums/m/11929946/viewforum/8006500 .",
"Thank you for playing Gem Hunters!",
"Many more features are being added over the coming days!",
"Players in your party show up on your map!",
"Safezones are marked as green areas on your map!",
"Players that have super valuable items show up on your map!"
};
private int _lastIndex;
private BetaModule()
{
super("Beta");
}
@EventHandler
public void annouce(UpdateEvent event)
{
if (event.getType() != UpdateType.MIN_01)
{
return;
}
Bukkit.broadcastMessage(F.main(C.cRedB + "BETA", C.cYellow + ANNOUCEMENTS[_lastIndex]));
if (++_lastIndex == ANNOUCEMENTS.length)
{
_lastIndex = 0;
}
}
}

View File

@ -0,0 +1,36 @@
package mineplex.gemhunters.bounties;
import java.util.UUID;
import org.bukkit.entity.Player;
public class Bounty
{
private UUID _target;
private UUID _setter;
private int _amount;
public Bounty(Player target, Player setter, int amount)
{
_target = target.getUniqueId();
_setter = setter.getUniqueId();
_amount = amount;
}
public UUID getTarget()
{
return _target;
}
public UUID getSetter()
{
return _setter;
}
public int getAmount()
{
return _amount;
}
}

View File

@ -0,0 +1,46 @@
package mineplex.gemhunters.bounties;
import java.net.MalformedURLException;
import java.net.URL;
import org.bukkit.block.BlockFace;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import mineplex.core.MiniPlugin;
import mineplex.core.ReflectivelyCreateMiniPlugin;
import mineplex.core.sponsorbranding.BrandingManager;
@ReflectivelyCreateMiniPlugin
public class BountyModule extends MiniPlugin
{
private final BrandingManager _brandingManager;
private BountyModule()
{
super("Bounty");
_brandingManager = require(BrandingManager.class);
}
//@EventHandler
public void test(PlayerCommandPreprocessEvent event)
{
if (!event.getMessage().startsWith("/want"))
{
return;
}
try
{
event.setCancelled(true);
_brandingManager.createPost(event.getPlayer().getLocation(), BlockFace.SOUTH, new URL("http://minotar.net/helm/Moppletop.png"));
}
catch (MalformedURLException e)
{
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,75 @@
package mineplex.gemhunters.chat;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import mineplex.core.MiniPlugin;
import mineplex.core.ReflectivelyCreateMiniPlugin;
import mineplex.core.account.CoreClientManager;
import mineplex.core.chat.Chat;
import mineplex.core.common.Rank;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
/**
* This module handles player chat.
*/
@ReflectivelyCreateMiniPlugin
public class ChatModule extends MiniPlugin
{
private final CoreClientManager _clientManager;
private final Chat _chat;
private ChatModule()
{
super("Chat");
_clientManager = require(CoreClientManager.class);
_chat = require(Chat.class);
}
@EventHandler(priority = EventPriority.LOWEST)
public void playerJoin(PlayerJoinEvent event)
{
event.setJoinMessage(F.sys("Join", event.getPlayer().getName()));
}
@EventHandler(priority = EventPriority.LOWEST)
public void playerQuit(PlayerQuitEvent event)
{
event.setQuitMessage(F.sys("Quit", event.getPlayer().getName()));
}
@EventHandler(priority = EventPriority.HIGHEST)
public void chat(AsyncPlayerChatEvent event)
{
// Checks if the player has been muted/chat is silenced etc...
if (event.isCancelled())
{
return;
}
Player player = event.getPlayer();
String playerName = player.getName();
Rank rank = _clientManager.Get(player).getRealOrDisguisedRank();
String rankString = rank == Rank.ALL ? "" : rank.getTag(true, true);
// Create a message that follows the rest of the network's chat format
String message = (rankString + " " + C.cYellow + playerName + " " + C.cWhite + _chat.getFilteredMessage(player, event.getMessage())).trim();
// We will handle the broadcast
event.setCancelled(true);
for (Player other : event.getRecipients())
{
other.sendMessage(message);
}
}
}

View File

@ -0,0 +1,198 @@
package mineplex.gemhunters.death;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.entity.ItemSpawnEvent;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerPickupItemEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import com.google.common.collect.Sets;
import mineplex.core.MiniPlugin;
import mineplex.core.ReflectivelyCreateMiniPlugin;
import mineplex.core.common.util.C;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTextMiddle;
import mineplex.core.common.util.UtilTime;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.core.visibility.VisibilityManager;
import mineplex.gemhunters.death.event.PlayerCustomRespawnEvent;
import mineplex.gemhunters.spawn.SpawnModule;
/**
* This module handles anything to do with a players death
*/
@ReflectivelyCreateMiniPlugin
public class DeathModule extends MiniPlugin
{
// Some items like the cash out item (and for some reason players drop
// bones?) don't need to be dropped to avoid duplication.
private static final Set<Material> DISALLOWED_DROPS = Sets.newHashSet(Material.EMERALD, Material.MAP, Material.BONE, Material.STAINED_GLASS_PANE);
private static final int DEATH_ANIMATION_TIME = 7000;
private static final int DEATH_ANIMATION_COUNTDOWN = 2000;
private final SpawnModule _spawn;
private final Map<UUID, Long> _toRemove;
private DeathModule()
{
super("Death");
_spawn = require(SpawnModule.class);
_toRemove = new HashMap<>();
}
@EventHandler
public void join(PlayerJoinEvent event)
{
PlayerCustomRespawnEvent event2 = new PlayerCustomRespawnEvent(event.getPlayer());
UtilServer.CallEvent(event2);
}
@EventHandler
public void death(PlayerDeathEvent event)
{
Player player = event.getEntity();
// Stop the player dieing
player.setHealth(20);
player.setFoodLevel(20);
player.setExhaustion(0);
startAnimation(player);
_toRemove.put(player.getUniqueId(), System.currentTimeMillis());
}
@EventHandler
public void itemSpawn(ItemSpawnEvent event)
{
if (DISALLOWED_DROPS.contains(event.getEntity().getItemStack().getType()))
{
event.setCancelled(true);
}
}
@EventHandler
public void updateAnimations(UpdateEvent event)
{
if (event.getType() != UpdateType.SEC)
{
return;
}
Iterator<UUID> iterator = _toRemove.keySet().iterator();
while (iterator.hasNext())
{
UUID key = iterator.next();
Player player = UtilPlayer.searchExact(key);
if (player == null)
{
iterator.remove();
continue;
}
long start = _toRemove.get(key);
long end = start + DEATH_ANIMATION_TIME + 1000;
if (UtilTime.elapsed(start, DEATH_ANIMATION_TIME))
{
stopAnimation(player);
_toRemove.remove(key);
continue;
}
else if (UtilTime.elapsed(start, DEATH_ANIMATION_COUNTDOWN))
{
UtilTextMiddle.display(C.cRedB + "YOU DIED", String.valueOf((int) (end - System.currentTimeMillis()) / 1000), 0, 20, 0, player);
}
}
}
public void startAnimation(Player player)
{
UtilTextMiddle.display(C.cRedB + "YOU DIED", "Respawning shortly", 0, 60, 0, player);
VisibilityManager.Instance.setVisibility(player, false, UtilServer.getPlayers());
((CraftPlayer) player).getHandle().spectating = true;
player.setAllowFlight(true);
player.setFlying(true);
player.setGameMode(GameMode.CREATIVE);
}
public void stopAnimation(Player player)
{
UtilTextMiddle.display(C.cGreenB + "RESPAWNED", "", 0, 20, 20, player);
VisibilityManager.Instance.setVisibility(player, true, UtilServer.getPlayers());
((CraftPlayer) player).getHandle().spectating = false;
player.setFlying(false);
player.setAllowFlight(false);
player.setGameMode(GameMode.SURVIVAL);
_spawn.teleportToSpawn(player);
PlayerCustomRespawnEvent event = new PlayerCustomRespawnEvent(player);
UtilServer.CallEvent(event);
}
@EventHandler
public void itemPickup(PlayerPickupItemEvent event)
{
if (_toRemove.containsKey(event.getPlayer().getUniqueId()))
{
event.setCancelled(true);
}
}
@EventHandler
public void blockBreak(BlockBreakEvent event)
{
if (_toRemove.containsKey(event.getPlayer().getUniqueId()))
{
event.setCancelled(true);
}
}
@EventHandler
public void blockPlace(BlockPlaceEvent event)
{
if (_toRemove.containsKey(event.getPlayer().getUniqueId()))
{
event.setCancelled(true);
}
}
@EventHandler
public void inventory(InventoryClickEvent event)
{
if (_toRemove.containsKey(event.getWhoClicked().getUniqueId()))
{
event.setCancelled(true);
}
}
@EventHandler
public void playerQuit(PlayerQuitEvent event)
{
_toRemove.remove(event.getPlayer().getUniqueId());
}
}

View File

@ -0,0 +1,27 @@
package mineplex.gemhunters.death.event;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
public class PlayerCustomRespawnEvent extends PlayerEvent
{
private static final HandlerList HANDLERS = new HandlerList();
public PlayerCustomRespawnEvent(Player who)
{
super(who);
}
public HandlerList getHandlers()
{
return HANDLERS;
}
public static HandlerList getHandlerList()
{
return HANDLERS;
}
}

View File

@ -0,0 +1,238 @@
package mineplex.gemhunters.death.npc;
import java.io.File;
import java.util.List;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftLivingEntity;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Skeleton;
import org.bukkit.metadata.FixedMetadataValue;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTime;
import mineplex.core.disguise.DisguiseManager;
import mineplex.core.disguise.disguises.DisguisePlayer;
import mineplex.core.hologram.Hologram;
import mineplex.core.hologram.HologramManager;
public class CombatLogNPC
{
public final static EntityType NPC_TYPE = EntityType.VILLAGER;
private PlayerInfo _playerInfo;
private Hologram _hologram;
private DisguiseManager _disguiseManager;
private long _spawnDate;
private final long _endingTime;
private double _spawnHealth;
private boolean _creative;
private LivingEntity _npc;
private ArmorStand _stand;
private CraftLivingEntity _lastDamager;
public int getEntityId()
{
return _npc.getEntityId();
}
public CombatLogNPC(Player player, DisguiseManager disguiseManager, HologramManager hologramManager, boolean wasCreative)
{
_playerInfo = new PlayerInfo(player);
_creative = wasCreative;
_disguiseManager = disguiseManager;
_hologram = new Hologram(hologramManager, player.getEyeLocation().add(0, 1, 0), C.cYellow + UtilTime.MakeStr(NPCManager.COMBAT_LOG_DURATION) + C.cWhite + " Seconds left before despawn");
_spawnDate = 0;
_endingTime = System.currentTimeMillis() + NPCManager.COMBAT_LOG_DURATION;
_spawnHealth = player.getHealth();
_hologram.start();
}
/**
* Called when the {@code _npc} associated with this CombatLogNPC is killed
* and thus drops all the owner's items.
*/
public void onDeath(CraftLivingEntity killer)
{
Location location = _npc.getLocation();
World world = location.getWorld();
File file = new File(world.getWorldFolder(), String.format("playerdata/%s.dat", _playerInfo.getPlayerUuid()));
file.delete(); // Delete the player's .dat file so they will join with
// empty inventory/respawn on next login
if (killer != null)
{
String killerName = "Unknown";
if (killer instanceof CraftPlayer)
{
killerName = ((CraftPlayer) killer).getName();
}
else
{
killerName = UtilEnt.getName(killer);
}
// try
// {
// DataOutputStream stream = new DataOutputStream(new FileOutputStream(_userDataPath + String.format("DEATH_%s.dat", _playerInfo.getPlayerUuid())));
//
// stream.writeLong(System.currentTimeMillis());
// stream.writeInt(killerName.length());
// stream.writeBytes(killerName);
//
// stream.close();
// }
// catch (IOException e)
// {
// System.out.println(String.format("FATAL ERROR while trying to create player death lock for %s, meaning %s will not be informed that they died next time they log in.", _playerInfo.getPlayerName(), _playerInfo.getPlayerName()));
// }
UtilServer.broadcast(F.main("Death", F.elem(_playerInfo.getPlayerName()) + " was killed by " + F.elem(killerName) + " while combat logged."));
}
_playerInfo.dropItems(location);
_disguiseManager.undisguise(_npc);
}
public void update()
{
_hologram.setText("Quitting in " + UtilTime.MakeStr(Math.max(_endingTime - System.currentTimeMillis(), 0)));
}
/**
* @return true, if the {@code _npc} associated with this CombatLogNPC is
* alive, false otherwise.
*/
public boolean isAlive()
{
return _npc != null && !_npc.isDead();
}
/**
* @return the amount of time (in milliseconds) that this npc has been alive
* an spawned in.
*/
public long getAliveDuation()
{
return System.currentTimeMillis() - _spawnDate;
}
public void spawn()
{
if (_npc != null) despawn();
_npc = spawnNpc(getPlayer());
_spawnDate = System.currentTimeMillis();
}
public void despawn()
{
System.out.println("Despawning");
if (_npc != null)
{
if (_stand != null)
{
_stand.setPassenger(null);
_stand.remove();
_stand = null;
}
_npc.remove();
_npc = null;
_hologram.stop();
_hologram = null;
}
}
public void remove()
{
if (_hologram != null)
{
_hologram.stop();
_hologram = null;
}
}
public PlayerInfo getPlayerInfo()
{
return _playerInfo;
}
public Player getPlayer()
{
return _playerInfo.getPlayer();
}
public boolean matchesPlayer(Player player)
{
return _playerInfo.getPlayerName().equalsIgnoreCase(player.getName());
}
private LivingEntity spawnNpc(Player player)
{
Location spawnLoc = player.getLocation();
Skeleton skel = player.getWorld().spawn(spawnLoc, Skeleton.class);
skel.setMetadata("CombatLogNPC", new FixedMetadataValue(UtilServer.getPlugin(), player.getUniqueId().toString()));
skel.teleport(spawnLoc);
skel.setHealth(_spawnHealth);
UtilEnt.vegetate(skel);
UtilEnt.silence(skel, true);
skel.getEquipment().setHelmet(player.getInventory().getHelmet());
skel.getEquipment().setChestplate(player.getInventory().getChestplate());
skel.getEquipment().setLeggings(player.getInventory().getLeggings());
skel.getEquipment().setBoots(player.getInventory().getBoots());
skel.getEquipment().setItemInHand(player.getItemInHand());
// Get in range
List<Player> inRange = UtilPlayer.getNearby(spawnLoc, 75d);
// Disguise
DisguisePlayer disguise = new DisguisePlayer(skel, ((CraftPlayer) player).getHandle().getProfile());
_disguiseManager.disguise(disguise, attempted -> inRange.contains(attempted));
if (!UtilEnt.isGrounded(player))
{
ArmorStand stand = player.getWorld().spawn(spawnLoc.clone().subtract(0,1,0), ArmorStand.class);
stand.setVisible(false);
stand.setPassenger(skel);
stand.setGravity(false);
_stand = stand;
}
return skel;
}
public boolean wasCreative()
{
return _creative;
}
public CraftLivingEntity getLastDamager()
{
return _lastDamager;
}
public void setLastDamager(CraftLivingEntity damager)
{
_lastDamager = damager;
}
}

View File

@ -0,0 +1,262 @@
package mineplex.gemhunters.death.npc;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Sound;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftLivingEntity;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityCombustEvent;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.world.ChunkUnloadEvent;
import org.bukkit.metadata.FixedMetadataValue;
import mineplex.core.MiniPlugin;
import mineplex.core.disguise.DisguiseManager;
import mineplex.core.hologram.HologramManager;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.gemhunters.economy.PlayerCashOutCompleteEvent;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
public class NPCManager extends MiniPlugin
{
public static final long COMBAT_LOG_DURATION = 30000;
private static NPCManager _instance;
public static NPCManager getInstance()
{
return _instance;
}
private Set<CombatLogNPC> _logoutNpcs;
private Set<Integer> _toKillIds;
private Set<UUID> _cashedOutPreventNPCs = new HashSet<>();
private HologramManager _hologramManager;
public NPCManager(HologramManager hologramManager)
{
super("NPC Manager");
_instance = this;
_logoutNpcs = new HashSet<>();
_toKillIds = new HashSet<>();
_hologramManager = hologramManager;
}
@EventHandler
public void onCashOut(PlayerCashOutCompleteEvent event)
{
_cashedOutPreventNPCs.add(event.getPlayer().getUniqueId());
}
@EventHandler
public void playerQuit(PlayerQuitEvent event)
{
NPCManager.getInstance().spawnLogoutNpc(event.getPlayer());
}
@Override
public void disable()
{
log("Killing logout npcs");
// Despawn/kill all combat log NPCs on server shutdown
for (CombatLogNPC npc : _logoutNpcs)
{
npc.despawn();
}
_logoutNpcs.clear();
}
public void spawnLogoutNpc(Player player)
{
if (!_cashedOutPreventNPCs.remove(player.getUniqueId()) && !hasLogoutNpc(player))
{
CombatLogNPC npc = new CombatLogNPC(player, require(DisguiseManager.class), _hologramManager, player.getGameMode().equals(GameMode.CREATIVE));
npc.spawn();
_logoutNpcs.add(npc);
log(String.format("Spawned combat log NPC for %s!", player.getName()));
}
}
@EventHandler
public void killNpcs(PlayerJoinEvent event)
{
for (LivingEntity entity : Bukkit.getWorlds().get(0).getLivingEntities())
{
if (entity.hasMetadata("CombatLogNPC") && ((FixedMetadataValue) entity.getMetadata("CombatLogNPC").get(0)).asString().equals(event.getPlayer().getUniqueId().toString()))
{
entity.remove();
}
}
}
public void despawnLogoutNpc(Player player)
{
CombatLogNPC npc = getLogoutNpc(player);
if (npc != null)
{
_toKillIds.add(npc.getEntityId());
npc.despawn();
_logoutNpcs.remove(npc);
log(String.format("Despawned combat log NPC for %s!", player.getName()));
}
}
public boolean hasLogoutNpc(Player player)
{
return getLogoutNpc(player) != null;
}
public CombatLogNPC getLogoutNpc(Player player)
{
for (CombatLogNPC logoutNpc : _logoutNpcs)
{
if (logoutNpc.matchesPlayer(player))
{
return logoutNpc;
}
}
return null;
}
@EventHandler
public void onChunkUnload(ChunkUnloadEvent event)
{
for (Entity entity : event.getChunk().getEntities())
{
for (CombatLogNPC npc : _logoutNpcs)
{
if (entity.getEntityId() == npc.getEntityId())
{
event.setCancelled(true);
break;
}
}
}
}
@EventHandler(ignoreCancelled = true)
public void onEntityDeath(EntityDeathEvent event)
{
CombatLogNPC logoutNpc = getLogoutNpc(event.getEntity());
if (logoutNpc != null)
{
logoutNpc.onDeath(logoutNpc.getLastDamager());
event.getDrops().clear(); // Clear the entity's item drops. Manually
// drops combat log items earlier
}
}
@EventHandler(ignoreCancelled = true)
public void onEntityDamaged(CustomDamageEvent event)
{
CombatLogNPC logoutNpc = getLogoutNpc(event.GetDamageeEntity());
if (logoutNpc != null && event.GetDamagerEntity(true) != null)
{
if (logoutNpc.wasCreative())
{
event.SetCancelled("Cannot hurt creative player");
return;
}
if (event.GetDamagerPlayer(true) != null)
{
event.GetDamagerPlayer(true).playSound(event.GetDamagerPlayer(true).getLocation(), Sound.HURT_FLESH, 1, 1);
}
logoutNpc.setLastDamager(((CraftLivingEntity) event.GetDamagerEntity(true)));
event.SetKnockback(false);
}
}
@EventHandler
public void onEntityIgnite(EntityCombustEvent event)
{
if (isLogoutNpc(event.getEntity()))
{
event.setCancelled(true);
}
}
@EventHandler
public void onUpdate(UpdateEvent event)
{
if (event.getType() == UpdateType.FASTER)
{
for (CombatLogNPC npc : _logoutNpcs)
{
npc.update();
}
}
if (event.getType() == UpdateType.SEC)
{
Iterator<CombatLogNPC> iterator = _logoutNpcs.iterator();
while (iterator.hasNext())
{
CombatLogNPC npc = iterator.next();
if (Bukkit.getPlayer(npc.getPlayerInfo().getPlayerName()) != null)
{
System.out.println("{NPCMANAGER} ORIGINAL PLAYER ALIVE AND DESPAWNING");
npc.despawn();
iterator.remove();
}
else if (!npc.isAlive())
{
System.out.println("{NPCMANAGER} NOT ALIVE AND REMOVING");
npc.remove();
iterator.remove();
}
else if (npc.getAliveDuation() > COMBAT_LOG_DURATION)
{
System.out.println("{NPCMANAGER} DESPAWNING");
npc.despawn();
iterator.remove();
}
}
}
}
private boolean isLogoutNpc(Entity entity)
{
return getLogoutNpc(entity) != null;
}
private CombatLogNPC getLogoutNpc(Entity entity)
{
return getLogoutNpc(entity.getEntityId());
}
private CombatLogNPC getLogoutNpc(int entityId)
{
for (CombatLogNPC npc : _logoutNpcs)
{
if (npc.getEntityId() == entityId)
{
return npc;
}
}
return null;
}
}

View File

@ -0,0 +1,92 @@
package mineplex.gemhunters.death.npc;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import mineplex.gemhunters.loot.InventoryModule;
public class PlayerInfo
{
private String _playerName;
private UUID _playerUuid;
private ItemStack[] _armor;
private List<ItemStack> _items;
private Location _location;
public PlayerInfo(Player player)
{
_playerName = player.getName();
_playerUuid = player.getUniqueId();
_armor = player.getInventory().getArmorContents();
_items = fetchItems(player.getInventory());
_location = player.getLocation();
}
public void dropItems(Location location)
{
World world = location.getWorld();
for (ItemStack item : _items)
{
world.dropItemNaturally(location, item);
}
}
public void restore()
{
Player player = getPlayer();
player.getInventory().clear();
player.getInventory().setArmorContents(_armor);
player.getInventory().addItem(_items.toArray(new ItemStack[0]));
player.teleport(_location);
}
public String getPlayerName()
{
return _playerName;
}
public UUID getUniqueId()
{
return _playerUuid;
}
public String getPlayerUuid()
{
return _playerUuid.toString();
}
public Player getPlayer()
{
return Bukkit.getPlayerExact(_playerName);
}
private List<ItemStack> fetchItems(PlayerInventory inventory)
{
List<ItemStack> items = new ArrayList<>();
addItems(items, inventory.getContents());
return items;
}
private void addItems(List<ItemStack> items, ItemStack[] itemsToAdd)
{
for (ItemStack item : itemsToAdd)
{
if (item != null && item.getType() != Material.AIR && !item.isSimilar(InventoryModule.LOCKED))
{
items.add(item);
}
}
}
}

View File

@ -0,0 +1,276 @@
package mineplex.gemhunters.economy;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.UUID;
import org.bukkit.Material;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.inventory.ItemStack;
import mineplex.core.MiniPlugin;
import mineplex.core.ReflectivelyCreateMiniPlugin;
import mineplex.core.common.currency.GlobalCurrency;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilEvent;
import mineplex.core.common.util.UtilEvent.ActionType;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTextMiddle;
import mineplex.core.donation.DonationManager;
import mineplex.core.itemstack.ItemBuilder;
import mineplex.core.portal.GenericServer;
import mineplex.core.portal.Intent;
import mineplex.core.portal.Portal;
import mineplex.core.recharge.Recharge;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.gemhunters.spawn.event.PlayerTeleportIntoMapEvent;
@ReflectivelyCreateMiniPlugin
public class CashOutModule extends MiniPlugin
{
private static final DecimalFormat ARMOUR_STAND_FORMAT = new DecimalFormat("0.0");
private static final ItemStack CASH_OUT_ITEM = new ItemBuilder(Material.EMERALD).setTitle(C.cGreen + "Cash Out").addLore("", C.cGray + "Click to begin the process to cash out.", C.cGray + "Cashing out saves your current loot.").build();
private static final int CASH_OUT_COOLDOWN = 10000;
private static final int CASH_OUT_MAX_MOVE_DISTANCE_SQUARED = 4;
private final DonationManager _donation;
private final Map<UUID, CashOutSession> _sessions;
public CashOutModule()
{
super("Cash Out");
_donation = require(DonationManager.class);
_sessions = new HashMap<>();
}
@EventHandler
public void teleportIn(PlayerTeleportIntoMapEvent event)
{
if (event.isCancelled())
{
return;
}
event.getPlayer().getInventory().setItem(7, CASH_OUT_ITEM);
}
@EventHandler
public void playerInteract(PlayerInteractEvent event)
{
if (!UtilEvent.isAction(event, ActionType.R))
{
return;
}
Player player = event.getPlayer();
ItemStack itemStack = player.getItemInHand();
if (itemStack == null)
{
return;
}
if (!itemStack.isSimilar(CASH_OUT_ITEM))
{
return;
}
attemptCashOut(player);
}
@EventHandler
public void itemDrop(PlayerDropItemEvent event)
{
if (event.getItemDrop().getItemStack().isSimilar(CASH_OUT_ITEM))
{
event.getPlayer().sendMessage(F.main("Game", "You cannot drop the " + F.item("Cash Out Item") + "."));
event.setCancelled(true);
}
}
@EventHandler
public void inventoryClick(InventoryClickEvent event)
{
ItemStack itemStack = event.getCurrentItem();
if (itemStack == null)
{
return;
}
if (!itemStack.isSimilar(CASH_OUT_ITEM))
{
return;
}
event.setCancelled(true);
}
@EventHandler
public void playerQuit(PlayerQuitEvent event)
{
}
@EventHandler
public void update(UpdateEvent event)
{
if (event.getType() != UpdateType.TICK)
{
return;
}
Iterator<UUID> iterator = _sessions.keySet().iterator();
while (iterator.hasNext())
{
UUID key = iterator.next();
Player player = UtilPlayer.searchExact(key);
CashOutSession session = _sessions.get(key);
double current = session.getCurrent();
ArmorStand stand = session.getArmourStand();
String standName = ARMOUR_STAND_FORMAT.format(current);
if (player == null)
{
session.endSession();
iterator.remove();
continue;
}
UtilTextMiddle.display(C.cGreen + standName, UtilTextMiddle.progress((float) (1 - current / session.getMax())), 0, 10, 0, player);
stand.setCustomName(standName + " seconds");
session.setCurrent(current - 0.05);
if (session.getCurrent() <= 0)
{
PlayerCashOutCompleteEvent completeEvent = new PlayerCashOutCompleteEvent(player);
UtilServer.CallEvent(completeEvent);
_donation.rewardCurrencyUntilSuccess(GlobalCurrency.GEM, player, "Earned", completeEvent.getGems());
session.endSession();
iterator.remove();
Portal.getInstance().sendPlayerToGenericServer(player, GenericServer.BETA_HUB, Intent.FORCE_TRANSFER);
}
}
}
@EventHandler
public void updateMove(UpdateEvent event)
{
if (event.getType() != UpdateType.FAST)
{
return;
}
for (UUID key : _sessions.keySet())
{
Player player = UtilPlayer.searchExact(key);
CashOutSession session = _sessions.get(key);
if (session.getLocation().distanceSquared(player.getLocation()) > CASH_OUT_MAX_MOVE_DISTANCE_SQUARED)
{
cancelCashOut(player, "You moved!");
}
}
}
@EventHandler
public void entityDamage(EntityDamageEvent event)
{
if (!(event.getEntity() instanceof Player))
{
return;
}
Player player = (Player) event.getEntity();
if (isCashingOut(player))
{
cancelCashOut(player, "You took damage!");
}
}
@EventHandler
public void entityAttack(EntityDamageByEntityEvent event)
{
if (!(event.getDamager() instanceof Player) || event.getEntity() instanceof ArmorStand)
{
return;
}
Player player = (Player) event.getDamager();
if (isCashingOut(player))
{
cancelCashOut(player, "You attacked a player!");
}
}
public void attemptCashOut(Player player)
{
UUID key = player.getUniqueId();
if (_sessions.containsKey(key))
{
player.sendMessage(F.main("Game", "You are already cashing out."));
return;
}
if (!Recharge.Instance.use(player, "Cash Out", CASH_OUT_COOLDOWN, true, false))
{
return;
}
// Test time
_sessions.put(key, new CashOutSession(player, 10));
}
public void cancelCashOut(Player player, String message)
{
UUID key = player.getUniqueId();
CashOutSession session = _sessions.get(key);
player.sendMessage(F.main("Game", message + " Your cash out has been cancelled."));
session.endSession();
_sessions.remove(key);
}
public boolean isCashingOut(Player player)
{
return getCashOutSession(player) != null;
}
public CashOutSession getCashOutSession(Player player)
{
for (UUID key : _sessions.keySet())
{
if (key.equals(player.getUniqueId()))
{
return _sessions.get(key);
}
}
return null;
}
}

View File

@ -0,0 +1,58 @@
package mineplex.gemhunters.economy;
import org.bukkit.Location;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Player;
public class CashOutSession
{
private double _current;
private double _max;
private ArmorStand _stand;
private Location _location;
public CashOutSession(Player player, double max)
{
_current = max;
_max = max;
_stand = player.getWorld().spawn(player.getLocation().add(0, 0.5, 0), ArmorStand.class);
_stand.setCustomNameVisible(true);
_stand.setVisible(false);
_stand.setGravity(false);
_location = player.getLocation();
}
public void endSession()
{
_stand.remove();
}
public void setCurrent(double current)
{
_current = current;
}
public double getCurrent()
{
return _current;
}
public double getMax()
{
return _max;
}
public ArmorStand getArmourStand()
{
return _stand;
}
public Location getLocation()
{
return _location;
}
}

View File

@ -0,0 +1,110 @@
package mineplex.gemhunters.economy;
import java.util.UUID;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.PlayerDeathEvent;
import mineplex.core.MiniClientPlugin;
import mineplex.core.ReflectivelyCreateMiniPlugin;
import mineplex.core.common.currency.GlobalCurrency;
import mineplex.core.common.util.F;
import mineplex.core.donation.DonationManager;
import mineplex.core.donation.Donor;
import mineplex.gemhunters.death.event.PlayerCustomRespawnEvent;
import mineplex.gemhunters.economy.command.GiveGemsCommand;
import mineplex.gemhunters.spawn.event.PlayerTeleportIntoMapEvent;
@ReflectivelyCreateMiniPlugin
public class EconomyModule extends MiniClientPlugin<Integer>
{
private static final float GEM_KILL_FACTOR = 0.5F;
private static final int GEM_START_COST = 100;
private final DonationManager _donation;
public EconomyModule()
{
super("Economy");
_donation = require(DonationManager.class);
}
@Override
public void addCommands()
{
addCommand(new GiveGemsCommand(this));
}
@EventHandler
public void respawn(PlayerCustomRespawnEvent event)
{
addToStore(event.getPlayer(), null, GEM_START_COST);
}
@EventHandler
public void teleportIn(PlayerTeleportIntoMapEvent event)
{
Player player = event.getPlayer();
Donor donor = _donation.Get(event.getPlayer());
if (donor.getBalance(GlobalCurrency.GEM) >= GEM_START_COST)
{
_donation.purchaseUnknownSalesPackage(player, "Gem Hunters Access", GlobalCurrency.GEM, GEM_START_COST, false, null);
}
}
@EventHandler
public void death(PlayerDeathEvent event)
{
Player player = event.getEntity();
Entity killer = event.getEntity().getKiller();
int oldGems = getGems(player);
if (killer instanceof Player)
{
Player killerPlayer = (Player) killer;
int newGems = (int) (oldGems * GEM_KILL_FACTOR);
addToStore(killerPlayer, "Killing " + F.name(player.getName()), newGems);
}
removeFromStore(player, oldGems);
}
@EventHandler
public void cashOut(PlayerCashOutCompleteEvent event)
{
event.incrementGems(getGems(event.getPlayer()));
}
public void addToStore(Player player, String reason, int gems)
{
Set(player, Get(player) + gems);
if (reason != null)
{
player.sendMessage(F.main(_moduleName, "+" + F.currency(GlobalCurrency.GEM, gems) + " (" + reason + ")."));
}
}
public void removeFromStore(Player player, int gems)
{
addToStore(player, null, -gems);
}
public int getGems(Player player)
{
return Get(player);
}
@Override
protected Integer addPlayer(UUID uuid)
{
return 0;
}
}

View File

@ -0,0 +1,44 @@
package mineplex.gemhunters.economy;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
public class PlayerCashOutCompleteEvent extends PlayerEvent
{
private static final HandlerList HANDLERS = new HandlerList();
private int _gems;
public PlayerCashOutCompleteEvent(Player player)
{
super(player);
}
public void incrementGems(int gems)
{
_gems += gems;
}
public void setGems(int gems)
{
_gems = gems;
}
public int getGems()
{
return _gems;
}
public HandlerList getHandlers()
{
return HANDLERS;
}
public static HandlerList getHandlerList()
{
return HANDLERS;
}
}

View File

@ -0,0 +1,47 @@
package mineplex.gemhunters.economy.command;
import org.bukkit.entity.Player;
import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
import mineplex.gemhunters.economy.EconomyModule;
public class GiveGemsCommand extends CommandBase<EconomyModule>
{
public GiveGemsCommand(EconomyModule plugin)
{
super(plugin, Rank.ADMIN, "givegems");
}
@Override
public void Execute(Player caller, String[] args)
{
if (args.length < 2)
{
caller.sendMessage(F.help("/" + _aliasUsed + " <player> <amount>", "Adds an amount of gems to a player's gems earned.", Rank.ADMIN));
return;
}
Player target = UtilPlayer.searchOnline(caller, args[0], true);
if (target == null)
{
return;
}
try
{
int amount = Integer.parseInt(args[1]);
Plugin.addToStore(target, "Given by " + F.name(caller.getName()), amount);
}
catch (NumberFormatException e)
{
caller.sendMessage(F.main(Plugin.getName(), "That is not a number."));
}
}
}

View File

@ -0,0 +1,107 @@
package mineplex.gemhunters.loot;
import java.util.HashMap;
import java.util.Map;
import org.bukkit.Material;
public class ChestProperties
{
private final String _name;
private final Material _blockMaterial;
private final String _dataKey;
private final int _minAmount;
private final int _maxAmount;
private final int _maxChestPerLoc;
private final int _spawnRate;
private final int _expireRate;
private final int _spawnRadius;
private final int _maxActive;
private final Map<Integer, Integer> _spawnedIndexes;
private long _lastSpawn;
public ChestProperties(String name, Material blockMaterial, String dataKey, int minAmount, int maxAmount, int maxChestPerLoc, int spawnRate, int expireRate, int spawnRadius, int maxActive)
{
_name = name;
_blockMaterial = blockMaterial;
_dataKey = dataKey;
_minAmount = minAmount;
_maxAmount = maxAmount;
_maxChestPerLoc = maxChestPerLoc;
_spawnRate = spawnRate;
_expireRate = expireRate;
_spawnRadius = spawnRadius;
_maxActive = maxActive;
_spawnedIndexes = new HashMap<>();
setLastSpawn();
}
public final String getName()
{
return _name;
}
public final Material getBlockMaterial()
{
return _blockMaterial;
}
public final String getDataKey()
{
return _dataKey;
}
public final int getMinAmount()
{
return _minAmount;
}
public final int getMaxAmount()
{
return _maxAmount;
}
public final int getMaxChestPerLocation()
{
return _maxChestPerLoc;
}
public final int getSpawnRate()
{
return _spawnRate;
}
public final int getExpireRate()
{
return _expireRate;
}
public final int getSpawnRadius()
{
return _spawnRadius;
}
public final int getMaxActive()
{
return _maxActive;
}
public final Map<Integer, Integer> getSpawnIndexes()
{
return _spawnedIndexes;
}
public void setLastSpawn()
{
_lastSpawn = System.currentTimeMillis();
}
public long getLastSpawn()
{
return _lastSpawn;
}
}

View File

@ -0,0 +1,133 @@
package mineplex.gemhunters.loot;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import mineplex.core.MiniPlugin;
import mineplex.core.ReflectivelyCreateMiniPlugin;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilEvent;
import mineplex.core.common.util.UtilEvent.ActionType;
import mineplex.core.common.util.UtilInv;
import mineplex.core.itemstack.ItemBuilder;
import mineplex.gemhunters.death.event.PlayerCustomRespawnEvent;
@ReflectivelyCreateMiniPlugin
public class InventoryModule extends MiniPlugin
{
public static final ItemStack LOCKED = new ItemBuilder(Material.STAINED_GLASS_PANE, (byte) 15).setTitle(C.cGray + "Locked").build();
private static final int START_INDEX = 9;
private static final String ITEM_METADATA = "UNLOCKER";
private final LootModule _loot;
private final Map<UUID, Integer> _slotsUnlocked;
private InventoryModule()
{
super("Unlocker");
_loot = require(LootModule.class);
_slotsUnlocked = new HashMap<>();
}
@EventHandler
public void respawn(PlayerCustomRespawnEvent event)
{
Player player = event.getPlayer();
Inventory inv = player.getInventory();
_slotsUnlocked.put(player.getUniqueId(), 0);
for (int i = START_INDEX; i < inv.getSize(); i++)
{
inv.setItem(i, LOCKED);
}
}
@EventHandler
public void quit(PlayerQuitEvent event)
{
_slotsUnlocked.remove(event.getPlayer().getUniqueId());
}
@EventHandler
public void inventoryClick(InventoryClickEvent event)
{
Player player = (Player) event.getWhoClicked();
if (event.getClickedInventory() == null || event.getCurrentItem() == null)
{
return;
}
if (event.getCurrentItem().isSimilar(LOCKED))
{
event.setCancelled(true);
player.playSound(player.getLocation(), Sound.ITEM_BREAK, 1, 0.6F);
}
}
@EventHandler
public void interact(PlayerInteractEvent event)
{
if (!UtilEvent.isAction(event, ActionType.R))
{
return;
}
Player player = event.getPlayer();
ItemStack itemStack = player.getItemInHand();
if (itemStack == null)
{
return;
}
LootItem lootItem = _loot.fromItemStack(itemStack);
if (lootItem == null || lootItem.getMetadata() == null || !lootItem.getMetadata().equals(ITEM_METADATA))
{
return;
}
player.setItemInHand(UtilInv.decrement(itemStack));
unlockSlots(player, itemStack.getType() == Material.CHEST ? 9 : 18);
}
public void unlockSlots(Player player, int slots)
{
Inventory inv = player.getInventory();
UUID key = player.getUniqueId();
int start = START_INDEX + _slotsUnlocked.get(key);
int end = Math.min(inv.getSize(), start + slots);
int delta = end - start;
//DebugModule.getInstance().d("start=" + start);
//DebugModule.getInstance().d("end=" + end);
//DebugModule.getInstance().d("delta=" + delta);
for (int i = start; i < end; i++)
{
inv.setItem(i, null);
}
player.sendMessage(F.main(_moduleName, "You unlocked an additional " + F.count(String.valueOf(delta)) + " slots of your inventory!"));
_slotsUnlocked.put(key, _slotsUnlocked.get(key) + slots);
}
}

View File

@ -0,0 +1,90 @@
package mineplex.gemhunters.loot;
import org.bukkit.inventory.ItemStack;
import mineplex.core.common.util.UtilMath;
/**
* Represents an item that can be contained in a chest inside the Gem Hunters
* world.
*/
public class LootItem
{
private final ItemStack _itemStack;
private final int _minAmount;
private final int _maxAmount;
private final double _probability;
private final String _metadata;
public LootItem(ItemStack itemStack, int minAmount, int maxAmount, double probability, String metadata)
{
_itemStack = itemStack;
_minAmount = minAmount;
_maxAmount = maxAmount;
_probability = probability;
_metadata = metadata;
}
/**
* Returns the Minecraft {@link ItemStack} bound to this
* {@link LootItem}.<br>
* The {@link ItemStack} returned will have an amount/size between the
* minAmount and maxAmount integers (set within the constuctor's parameters)
* inclusively.
*
* @return
*/
public ItemStack getItemStack()
{
_itemStack.setAmount(_minAmount + UtilMath.r(_maxAmount - _minAmount + 1));
return _itemStack;
}
/**
* The minimum amount or size an {@link ItemStack} of this {@link LootItem}
* can have.
*
* @return
*/
public int getMinAmount()
{
return _minAmount;
}
/**
* The maximum amount or size an {@link ItemStack} of this {@link LootItem}
* can have.
*
* @return
*/
public int getMaxAmount()
{
return _maxAmount;
}
/**
* The double value of the item's probability of being chosen to when
* picking an individual chest's loot.
*
* @return
*/
public double getProbability()
{
return _probability;
}
/**
* Any metadata bound to a {@link LootItem}. Useful for determining if an
* item has a particular <i>skill</i> or <i>ability</i> attached to it which
* you can use in code.
*
* @return
*/
public String getMetadata()
{
return _metadata;
}
}

View File

@ -0,0 +1,662 @@
package mineplex.gemhunters.loot;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import org.bukkit.Bukkit;
import org.bukkit.Effect;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState;
import org.bukkit.block.Chest;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerPickupItemEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import mineplex.core.MiniPlugin;
import mineplex.core.ReflectivelyCreateMiniPlugin;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilEvent;
import mineplex.core.common.util.UtilEvent.ActionType;
import mineplex.core.common.util.UtilInv;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTime;
import mineplex.core.google.GoogleSheetsManager;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.gemhunters.economy.EconomyModule;
import mineplex.gemhunters.economy.PlayerCashOutCompleteEvent;
import mineplex.gemhunters.loot.command.SpawnChestCommand;
import mineplex.gemhunters.loot.command.UpdateLootCommand;
import mineplex.gemhunters.loot.deserialisers.ChestPropertiesDeserialiser;
import mineplex.gemhunters.loot.deserialisers.LootItemDeserialiser;
import mineplex.gemhunters.loot.event.PlayerChestOpenEvent;
import mineplex.gemhunters.loot.rewards.LootChestReward;
import mineplex.gemhunters.loot.rewards.LootGadgetReward;
import mineplex.gemhunters.loot.rewards.LootItemReward;
import mineplex.gemhunters.loot.rewards.LootRankReward;
import mineplex.gemhunters.loot.rewards.LootShardReward;
import mineplex.gemhunters.safezone.SafezoneModule;
import mineplex.gemhunters.spawn.event.PlayerTeleportIntoMapEvent;
import mineplex.gemhunters.util.SlackSheetsBot;
import mineplex.gemhunters.world.WorldDataModule;
@ReflectivelyCreateMiniPlugin
public class LootModule extends MiniPlugin
{
private static final String SHEET_FILE_NAME = "GEM_HUNTERS_CHESTS";
private static final String CHEST_MASTER_SHEET_NAME = "CHEST_MASTER";
private static final long CHEST_DESPAWN_TIME_OPENED = TimeUnit.SECONDS.toMillis(15);
private static final float CHESTS_ON_START_FACTOR = 0.333F;
private static final int MAX_SEARCH_ATTEMPTS = 40;
private static final int MAX_CHEST_CHECK_DISTANCE_SQUARED = 4;
private static final LootItemDeserialiser DESERIALISER = new LootItemDeserialiser();
private static final ChestPropertiesDeserialiser CHEST_DESERIALISER = new ChestPropertiesDeserialiser();
private static final ItemStack[] SPAWN_ITEMS = {
new ItemStack(Material.WOOD_SWORD),
new ItemStack(Material.APPLE, 3),
};
private static final String GEM_METADATA = "GEM";
private final EconomyModule _economy;
private final GoogleSheetsManager _sheets;
private final SafezoneModule _safezone;
private final WorldDataModule _worldData;
private final Map<String, Set<LootItem>> _chestLoot;
private final Map<String, ChestProperties> _chestProperties;
private final Set<SpawnedChest> _spawnedChest;
private final Set<LootItemReward> _itemRewards;
private final Set<UUID> _shownPlayers;
private LootModule()
{
super("Loot");
_economy = require(EconomyModule.class);
_sheets = require(GoogleSheetsManager.class);
_safezone = require(SafezoneModule.class);
_worldData = require(WorldDataModule.class);
_chestLoot = new HashMap<>();
_chestProperties = new HashMap<>();
_spawnedChest = new HashSet<>();
_itemRewards = new HashSet<>();
_shownPlayers = new HashSet<>();
runSyncLater(() -> {
updateChestLoot();
// Spawn some chests
for (String key : _chestProperties.keySet())
{
int max = _chestProperties.get(key).getMaxActive();
for (int i = 0; i < max * CHESTS_ON_START_FACTOR; i++)
{
addSpawnedChest(key, true);
}
}
}, 20);
}
@Override
public void addCommands()
{
addCommand(new UpdateLootCommand(this));
addCommand(new SpawnChestCommand(this));
}
@EventHandler
public void updateSpawnChests(UpdateEvent event)
{
if (event.getType() != UpdateType.SEC)
{
return;
}
// Despawn opened chests
Iterator<SpawnedChest> iterator = _spawnedChest.iterator();
while (iterator.hasNext())
{
SpawnedChest chest = iterator.next();
ChestProperties properties = chest.getProperties();
if (chest.isOpened() && UtilTime.elapsed(chest.getOpenedAt(), CHEST_DESPAWN_TIME_OPENED) || UtilTime.elapsed(chest.getSpawnedAt(), properties.getExpireRate()))
{
if (chest.getID() != -1)
{
properties.getSpawnIndexes().put(chest.getID(), properties.getSpawnIndexes().get(chest.getID()) - 1);
}
Block block = chest.getLocation().getBlock();
if (block.getState() instanceof Chest)
{
((Chest) block.getState()).getBlockInventory().clear();
}
block.getWorld().playEffect(chest.getLocation(), Effect.STEP_SOUND, block.getType());
block.setType(Material.AIR);
iterator.remove();
}
}
// Spawn new chests
for (String key : _chestProperties.keySet())
{
addSpawnedChest(key, false);
}
}
public boolean isSuitable(Block block)
{
Block up = block.getRelative(BlockFace.UP);
Block down = block.getRelative(BlockFace.DOWN);
if (block.getType() != Material.AIR || up.getType() != Material.AIR || down.getType() == Material.AIR || UtilBlock.liquid(down) || UtilBlock.liquid(up) || UtilBlock.liquid(block) || _safezone.isInSafeZone(block.getLocation()))
{
return false;
}
return true;
}
public void updateChestLoot()
{
log("Updating chest loot");
Map<String, List<List<String>>> map = _sheets.getSheetData(SHEET_FILE_NAME);
for (String key : map.keySet())
{
if (key.equals(CHEST_MASTER_SHEET_NAME))
{
int row = 0;
for (List<String> rows : map.get(key))
{
row++;
try
{
ChestProperties properties = CHEST_DESERIALISER.deserialise(rows.toArray(new String[0]));
_chestProperties.put(properties.getDataKey(), properties);
}
catch (Exception e)
{
if (row != 1)
{
SlackSheetsBot.reportParsingError(e, "Chest Loot", key, row);
}
continue;
}
}
continue;
}
Set<LootItem> items = new HashSet<>();
int row = 0;
for (List<String> rows : map.get(key))
{
row++;
try
{
items.add(DESERIALISER.deserialise(rows.toArray(new String[0])));
}
catch (Exception e)
{
if (row != 1)
{
SlackSheetsBot.reportParsingError(e, "Chest Loot", key, row);
}
continue;
}
}
_chestLoot.put(key, items);
}
log("Finished updating chest loot");
}
public void addSpawnedChest(String key, boolean force)
{
if (key.equals("PURPLE") && Bukkit.getOnlinePlayers().size() < 10)
{
return;
}
List<Location> locations = _worldData.getDataLocation(key);
ChestProperties properties = _chestProperties.get(key);
if (!force && !UtilTime.elapsed(properties.getLastSpawn(), properties.getSpawnRate()))
{
return;
}
properties.setLastSpawn();
// Only spawn more chests if we need to
int max = properties.getMaxActive();
int spawned = 0;
for (SpawnedChest chest : _spawnedChest)
{
if (chest.getProperties().getDataKey().equals(key))
{
spawned++;
}
}
// If there are too many chests of this type we can ignore it
if (spawned > max)
{
return;
}
if (locations.isEmpty())
{
return;
}
Map<Integer, Integer> spawnedIndexes = properties.getSpawnIndexes();
Location randomLocation = null;
boolean found = false;
int attempts = 0;
int index = -1;
while (index == -1 || !found && attempts < MAX_SEARCH_ATTEMPTS)
{
attempts++;
index = UtilMath.r(locations.size());
if (spawnedIndexes.getOrDefault(index, 0) >= properties.getMaxChestPerLocation())
{
continue;
}
}
if (index == -1)
{
return;
}
spawnedIndexes.put(index, spawnedIndexes.getOrDefault(index, 0) + 1);
randomLocation = locations.get(index);
int placeRadius = properties.getSpawnRadius();
Location chestToPlace = UtilAlg.getRandomLocation(randomLocation, placeRadius, 0, placeRadius);
Block block = chestToPlace.getBlock();
attempts = 0;
boolean suitable = false;
while (!suitable && attempts < MAX_SEARCH_ATTEMPTS)
{
chestToPlace = UtilAlg.getRandomLocation(randomLocation, placeRadius, 0, placeRadius);
block = chestToPlace.getBlock();
suitable = isSuitable(block);
attempts++;
}
if (!suitable)
{
return;
}
//DebugModule.getInstance().d("Spawned at " + UtilWorld.blockToStrClean(block) + " with key=" + key + " and index=" + index + " and max=" + spawned + "/" + max);
_spawnedChest.add(new SpawnedChest(chestToPlace, properties, index));
block.setType(properties.getBlockMaterial());
}
public void addSpawnedChest(Location location, String colour)
{
_spawnedChest.add(new SpawnedChest(location, _chestProperties.get(colour), -1));
}
public void fillChest(Player player, Block block, String key)
{
Set<Integer> used = new HashSet<>();
Set<LootItem> items = _chestLoot.get(key);
ChestProperties properties = _chestProperties.get(key);
Inventory inventory = null;
if (block.getType() == Material.ENDER_CHEST)
{
inventory = player.getEnderChest();
}
else
{
BlockState state = block.getState();
Chest chest = (Chest) state;
inventory = chest.getBlockInventory();
}
inventory.clear();
for (int i = 0; i < UtilMath.rRange(properties.getMinAmount(), properties.getMaxAmount()); i++)
{
LootItem lootItem = getRandomItem(items);
ItemStack itemStack = lootItem.getItemStack();
int index = getFreeIndex(inventory.getSize(), used);
inventory.setItem(index, itemStack);
}
}
public LootItem getRandomItem(Set<LootItem> items)
{
double totalWeight = 0;
for (LootItem item : items)
{
totalWeight += item.getProbability();
}
double select = Math.random() * totalWeight;
for (LootItem item : items)
{
if ((select -= item.getProbability()) <= 0)
{
return item;
}
}
return null;
}
private int getFreeIndex(int endIndex, Set<Integer> used)
{
int index = -1;
while (index == -1 || used.contains(index))
{
index = UtilMath.r(endIndex);
}
used.add(index);
return index;
}
public LootItem fromItemStack(ItemStack itemStack)
{
if (itemStack == null)
{
return null;
}
for (Set<LootItem> items : _chestLoot.values())
{
for (LootItem item : items)
{
if (item.getItemStack().isSimilar(itemStack))
{
return item;
}
}
}
return null;
}
public boolean hasChestBeenOpened(Location location)
{
for (SpawnedChest chest : _spawnedChest)
{
if (chest.getLocation().distanceSquared(location) < MAX_CHEST_CHECK_DISTANCE_SQUARED && chest.isOpened())
{
return true;
}
}
return false;
}
@EventHandler
public void chestOpen(PlayerInteractEvent event)
{
if (event.isCancelled() || !UtilEvent.isAction(event, ActionType.R_BLOCK))
{
return;
}
Player player = event.getPlayer();
Block block = event.getClickedBlock();
if (block.getType() != Material.CHEST && block.getType() != Material.ENDER_CHEST)
{
return;
}
if (hasChestBeenOpened(block.getLocation()))
{
return;
}
String key = null;
for (SpawnedChest chest : _spawnedChest)
{
if (UtilMath.offsetSquared(chest.getLocation(), block.getLocation()) < MAX_CHEST_CHECK_DISTANCE_SQUARED)
{
key = chest.getProperties().getDataKey();
chest.setOpened();
break;
}
}
if (key == null)
{
event.setCancelled(true);
return;
}
PlayerChestOpenEvent openEvent = new PlayerChestOpenEvent(player, block, _chestProperties.get(key));
UtilServer.CallEvent(openEvent);
if (openEvent.isCancelled())
{
event.setCancelled(true);
return;
}
fillChest(player, block, key);
}
@EventHandler
public void inventoryClick(InventoryClickEvent event)
{
if (event.getClickedInventory() == null)
{
return;
}
ItemStack itemStack = event.getCurrentItem();
if (itemStack == null)
{
return;
}
handleRewardItem((Player) event.getWhoClicked(), itemStack);
}
@EventHandler
public void pickupItem(PlayerPickupItemEvent event)
{
if (event.getItem() == null)
{
return;
}
handleRewardItem(event.getPlayer(), event.getItem().getItemStack());
}
public void handleRewardItem(Player player, ItemStack itemStack)
{
LootItem lootItem = fromItemStack(itemStack);
if (lootItem == null || lootItem.getMetadata() == null)
{
return;
}
LootItemReward reward = null;
for (LootItemReward storedReward : _itemRewards)
{
if (storedReward.getItemStack().isSimilar(itemStack))
{
reward = storedReward;
}
}
if (reward == null)
{
String[] metadataSplit = lootItem.getMetadata().split(" ");
String key = metadataSplit[0];
String[] values = new String[metadataSplit.length - 1];
for (int i = 1; i < metadataSplit.length; i++)
{
values[i - 1] = metadataSplit[i];
}
switch (key)
{
case "RANK_UPGRADE":
reward = new LootRankReward(itemStack);
break;
case "SHARD":
reward = new LootShardReward(Integer.parseInt(values[0]) * 1000, itemStack, Integer.parseInt(values[1]));
break;
case "CHEST":
reward = new LootChestReward(Integer.parseInt(values[0]) * 1000, itemStack, values[1], Integer.parseInt(values[2]));
break;
case "GADGET":
String gadget = "";
for (int i = 1; i < values.length; i++)
{
gadget += values[i] + " ";
}
reward = new LootGadgetReward(Integer.parseInt(values[0]) * 1000, itemStack, gadget.trim());
break;
default:
return;
}
_itemRewards.add(reward);
}
reward.collectItem(player);
}
@EventHandler
public void gemClick(PlayerInteractEvent event)
{
if (!UtilEvent.isAction(event, ActionType.R))
{
return;
}
Player player = event.getPlayer();
ItemStack itemStack = player.getItemInHand();
if (itemStack == null)
{
return;
}
LootItem lootItem = fromItemStack(itemStack);
if (lootItem == null || lootItem.getMetadata() == null || !lootItem.getMetadata().startsWith(GEM_METADATA))
{
return;
}
player.setItemInHand(UtilInv.decrement(itemStack));
int amount = Integer.parseInt(lootItem.getMetadata().split(" ")[1]);
_economy.addToStore(player, "Gem Item", amount);
}
@EventHandler
public void mapUpdate(UpdateEvent event)
{
if (event.getType() != UpdateType.SEC)
{
return;
}
_shownPlayers.clear();
for (Player player : Bukkit.getOnlinePlayers())
{
UUID key = player.getUniqueId();
for (LootItemReward itemReward : _itemRewards)
{
if (itemReward.getPlayer().equals(player))
{
_shownPlayers.add(key);
break;
}
}
}
}
@EventHandler
public void mapTeleport(PlayerTeleportIntoMapEvent event)
{
event.getPlayer().getInventory().addItem(SPAWN_ITEMS);
}
@EventHandler
public void cashOutComplete(PlayerCashOutCompleteEvent event)
{
Player player = event.getPlayer();
Iterator<LootItemReward> iterator = _itemRewards.iterator();
while (iterator.hasNext())
{
LootItemReward reward = iterator.next();
if (player.equals(reward.getPlayer()))
{
reward.success();
iterator.remove();
}
}
}
public final Set<UUID> getShownPlayers()
{
return _shownPlayers;
}
}

View File

@ -0,0 +1,59 @@
package mineplex.gemhunters.loot;
import org.bukkit.Location;
public class SpawnedChest
{
private Location _location;
private ChestProperties _properties;
private int _id;
private long _spawnedAt;
private long _openedAt;
public SpawnedChest(Location location, ChestProperties properties, int id)
{
_location = location;
_properties =properties;
_id = id;
_spawnedAt = System.currentTimeMillis();
_openedAt = 0;
}
public void setOpened()
{
_openedAt = System.currentTimeMillis();
}
public Location getLocation()
{
return _location;
}
public ChestProperties getProperties()
{
return _properties;
}
public int getID()
{
return _id;
}
public long getSpawnedAt()
{
return _spawnedAt;
}
public long getOpenedAt()
{
return _openedAt;
}
public boolean isOpened()
{
return _openedAt != 0;
}
}

View File

@ -0,0 +1,47 @@
package mineplex.gemhunters.loot.command;
import org.bukkit.DyeColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank;
import mineplex.core.common.util.F;
import mineplex.gemhunters.loot.LootModule;
public class SpawnChestCommand extends CommandBase<LootModule>
{
public SpawnChestCommand(LootModule plugin)
{
super(plugin, Rank.ADMIN, "spawnchest");
}
@Override
public void Execute(Player caller, String[] args)
{
if (args.length == 0)
{
caller.sendMessage(F.help("/" + _aliasUsed + " <colour>", "Spawns a chest at your location.", GetRequiredRank()));
return;
}
String colour = args[0].toUpperCase();
try
{
DyeColor.valueOf(colour);
}
catch (IllegalArgumentException e)
{
caller.sendMessage(F.main(Plugin.getName(), "That is not a valid colour."));
return;
}
caller.sendMessage(F.main(Plugin.getName(), "Spawned a " + colour + " chest at your location."));
caller.getLocation().getBlock().setType(Material.CHEST);
Plugin.addSpawnedChest(caller.getLocation(), colour);
}
}

View File

@ -0,0 +1,33 @@
package mineplex.gemhunters.loot.command;
import org.bukkit.entity.Player;
import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank;
import mineplex.core.common.util.F;
import mineplex.gemhunters.loot.LootModule;
/**
* An ADMIN command that allows users to retrieve the latest data from the
* google sheet and update all locally cached loot tables.
*/
public class UpdateLootCommand extends CommandBase<LootModule>
{
public UpdateLootCommand(LootModule plugin)
{
super(plugin, Rank.ADMIN, "updateloot");
}
@Override
public void Execute(Player caller, String[] args)
{
if (args.length > 1)
{
// TODO send redis message
}
caller.sendMessage(F.main(Plugin.getName(), "This command is currently disabled due to development issues."));
}
}

View File

@ -0,0 +1,43 @@
package mineplex.gemhunters.loot.deserialisers;
import org.bukkit.Material;
import mineplex.core.google.SheetObjectDeserialiser;
import mineplex.gemhunters.loot.ChestProperties;
public class ChestPropertiesDeserialiser implements SheetObjectDeserialiser<ChestProperties>
{
@Override
public ChestProperties deserialise(String[] values) throws ArrayIndexOutOfBoundsException
{
String name = values[0];
Material blockMaterial = Material.valueOf(values[1]);
String dataKey = values[2];
int minAmount = 1;
int maxAmount = 1;
String[] numbers = values[3].split("-");
if (numbers.length != 2)
{
minAmount = Integer.parseInt(String.valueOf(values[3]));
maxAmount = minAmount;
}
else
{
minAmount = Integer.parseInt(numbers[0]);
maxAmount = Integer.parseInt(numbers[1]);
}
int spawnRate = Integer.parseInt(values[4]);
int expireRate = Integer.parseInt(values[5]);
int maxChestsPerLoc = Integer.parseInt(values[6]);
int spawnRadius = Integer.parseInt(values[7]);
int maxActive = Integer.parseInt(values[8]);
return new ChestProperties(name, blockMaterial, dataKey, minAmount, maxAmount, maxChestsPerLoc, spawnRate, expireRate, spawnRadius, maxActive);
}
}

View File

@ -0,0 +1,100 @@
package mineplex.gemhunters.loot.deserialisers;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
import mineplex.core.google.SheetObjectDeserialiser;
import mineplex.core.itemstack.ItemBuilder;
import mineplex.gemhunters.loot.LootItem;
import net.md_5.bungee.api.ChatColor;
/**
* This is a {@link LootItem} deserialiser for Google Sheet interpretation.<br>
* <br>
* Arguments should follow the form:<br>
* <ul>
* <li>Material</li>
* <li>Material Data</li>
* <li>Max Durability</li>
* <li>Amount</li>
* <li>Item Name <i>(optional)</i></li>
* <li>Item Lore <i>(optional) each line separated by colons</i></li>
* <li>Enchantments <i>(optional) Has a NAME:LEVEL format with multiple
* enchantments being separated by commas</i></li>
* <li>Probability</li>
* <li>Metadata <i>(optional)</i></li>
* </ul>
* Thus derserialise is guaranteed to have at least 8 strings passed in.<br>
* If an illegal argument is passed in, derserialise will throw an exception,
* these should be handled by the caller.
*
* @see SheetObjectDeserialiser
*/
public class LootItemDeserialiser implements SheetObjectDeserialiser<LootItem>
{
@Override
public LootItem deserialise(String[] values) throws ArrayIndexOutOfBoundsException, IllegalArgumentException, NumberFormatException
{
Material material = Material.valueOf(values[0]);
byte data = values[1].equals("") ? 0 : Byte.parseByte(values[1]);
int minAmount = 1;
int maxAmount = 1;
short durability = values[2].equals("") ? 0 : Short.valueOf(values[2]);
String[] numbers = values[3].split("-");
if (numbers.length != 2)
{
minAmount = Integer.parseInt(values[3].equals("") ? "1" : values[3]);
maxAmount = minAmount;
}
else
{
minAmount = Integer.parseInt(numbers[0]);
maxAmount = Integer.parseInt(numbers[1]);
}
ItemBuilder builder = new ItemBuilder(material, data);
builder.setDurability(durability);
String title = ChatColor.translateAlternateColorCodes('&', values[4]);
builder.setTitle(title);
if (!values[5].equals(""))
{
String[] lore = values[5].split(":");
String[] colouredLore = new String[lore.length];
int loreIndex = 0;
for (String line : lore)
{
colouredLore[loreIndex++] = ChatColor.translateAlternateColorCodes('&', line);
}
builder.setLore(colouredLore);
}
String[] enchants = String.valueOf(values[6]).split(",");
for (String enchant : enchants)
{
String[] enchantData = enchant.split(":");
if (enchantData.length < 2)
{
continue;
}
builder.addEnchantment(Enchantment.getByName(enchantData[0]), Integer.parseInt(enchantData[1]));
}
double proability = Double.parseDouble(values[7]);
String metadata = values.length > 8 ? values[8] : null;
return new LootItem(builder.build(), minAmount, maxAmount, proability, metadata);
}
}

View File

@ -0,0 +1,60 @@
package mineplex.gemhunters.loot.event;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import mineplex.gemhunters.loot.ChestProperties;
public class PlayerChestOpenEvent extends PlayerEvent implements Cancellable
{
private static final HandlerList HANDLERS = new HandlerList();
private boolean _cancel;
private final Block _block;
private final ChestProperties _properties;
public PlayerChestOpenEvent(Player who, Block block, ChestProperties properties)
{
super(who);
_block = block;
_properties = properties;
}
public Block getChest()
{
return _block;
}
public ChestProperties getProperties()
{
return _properties;
}
public HandlerList getHandlers()
{
return HANDLERS;
}
public static HandlerList getHandlerList()
{
return HANDLERS;
}
@Override
public boolean isCancelled()
{
return _cancel;
}
@Override
public void setCancelled(boolean cancel)
{
_cancel = cancel;
}
}

View File

@ -0,0 +1,52 @@
package mineplex.gemhunters.loot.rewards;
import org.bukkit.inventory.ItemStack;
import mineplex.core.Managers;
import mineplex.core.common.util.Callback;
import mineplex.core.inventory.InventoryManager;
public class LootChestReward extends LootItemReward
{
private final InventoryManager _inventory;
private final String _chestName;
private final int _amount;
public LootChestReward(long cashOutDelay, ItemStack itemStack, String chestName, int amount)
{
super(chestName + " Chest", cashOutDelay, itemStack);
_inventory = Managers.require(InventoryManager.class);
_chestName = chestName;
_amount = amount;
}
@Override
public void onCollectItem()
{
}
@Override
public void onSuccessful()
{
_inventory.addItemToInventory(new Callback<Boolean>()
{
@Override
public void run(Boolean success)
{
//DebugModule.getInstance().d("Success= " + success);
}
}, _player, _chestName + " Chest", _amount);
}
@Override
public void onDeath()
{
}
}

View File

@ -0,0 +1,54 @@
package mineplex.gemhunters.loot.rewards;
import org.bukkit.inventory.ItemStack;
import mineplex.core.Managers;
import mineplex.core.common.currency.GlobalCurrency;
import mineplex.core.donation.DonationManager;
import mineplex.core.donation.Donor;
public class LootGadgetReward extends LootItemReward
{
private final DonationManager _donation;
private final String _gadget;
public LootGadgetReward(long cashOutDelay, ItemStack itemStack, String gadget)
{
super(gadget, cashOutDelay, itemStack);
_donation = Managers.require(DonationManager.class);
_gadget = gadget;
}
@Override
public void onCollectItem()
{
}
@Override
public void onSuccessful()
{
Donor donor = _donation.Get(_player);
if (donor.ownsUnknownSalesPackage(_gadget))
{
//DebugModule.getInstance().d("Shard duplicate");
_donation.rewardCurrencyUntilSuccess(GlobalCurrency.TREASURE_SHARD, _player, "Earned", (int) (500 + 1000 * Math.random()));
}
else
{
//DebugModule.getInstance().d("Adding gadget");
_donation.purchaseUnknownSalesPackage(_player, _gadget, GlobalCurrency.TREASURE_SHARD, 0, true, null);
}
}
@Override
public void onDeath()
{
}
}

View File

@ -0,0 +1,94 @@
package mineplex.gemhunters.loot.rewards;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.inventory.ItemStack;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTextMiddle;
import mineplex.core.common.util.UtilTime;
import mineplex.core.recharge.Recharge;
public abstract class LootItemReward
{
private String _name;
private long _firstItemPickup;
private long _cashOutDelay;
protected Player _player;
private ItemStack _itemStack;
public LootItemReward(String name, long cashOutDelay, ItemStack itemStack)
{
_name = name;
_firstItemPickup = 0;
_cashOutDelay = cashOutDelay;
_itemStack = itemStack;
}
public abstract void onCollectItem();
public abstract void onSuccessful();
public abstract void onDeath();
public final void collectItem(Player player)
{
if (player.equals(_player))
{
return;
}
if (_firstItemPickup == 0)
{
String title = C.cYellow + player.getName();
String subtitle = C.cGray + "Collected a " + F.elem(_name) + " reward. Killing them will drop it!";
String chatMessage = F.main("Game", title + " " + subtitle + " They will not be able to quit out of the game for " + F.time(UtilTime.MakeStr(_cashOutDelay) + "."));
UtilTextMiddle.display(title, subtitle, 20, 60, 20, UtilServer.getPlayers());
UtilServer.broadcast(chatMessage);
_firstItemPickup = System.currentTimeMillis();
}
else
{
String message = F.main("Game", F.name(player.getName()) + " now has the " + F.elem(_name) + " reward!");
UtilServer.broadcast(message);
}
Recharge.Instance.useForce(player, "Cash Out", _cashOutDelay, false);
_player = player;
onCollectItem();
}
public final void success()
{
//DebugModule.getInstance().d("Success");
onSuccessful();
}
public final void death(PlayerDeathEvent event)
{
}
public boolean isFirstPickup()
{
return _firstItemPickup == 0;
}
public Player getPlayer()
{
return _player;
}
public ItemStack getItemStack()
{
return _itemStack;
}
}

View File

@ -0,0 +1,85 @@
package mineplex.gemhunters.loot.rewards;
import java.util.concurrent.TimeUnit;
import org.bukkit.inventory.ItemStack;
import mineplex.core.Managers;
import mineplex.core.account.CoreClient;
import mineplex.core.account.CoreClientManager;
import mineplex.core.common.Rank;
import mineplex.core.common.currency.GlobalCurrency;
import mineplex.core.common.util.F;
import mineplex.core.donation.DonationManager;
public class LootRankReward extends LootItemReward
{
private static final long CASH_OUT_DELAY = TimeUnit.MINUTES.toMillis(15);
private static final int CONSOLATION_PRICE = 10000;
private final CoreClientManager _clientManager;
private final DonationManager _donation;
public LootRankReward(ItemStack itemStack)
{
super("Rank", CASH_OUT_DELAY, itemStack);
_clientManager = Managers.require(CoreClientManager.class);
_donation = Managers.require(DonationManager.class);
}
@Override
public void onCollectItem()
{
}
@Override
public void onSuccessful()
{
CoreClient client = _clientManager.Get(_player);
Rank rank = client.GetRank();
Rank newRank = null;
// I could have done this so it runs off the order of the Rank enum,
// however knowing some people that might get changed so I'm just going
// to hard code what you get.
switch (rank)
{
case ALL:
newRank = Rank.ULTRA;
break;
case ULTRA:
newRank = Rank.HERO;
break;
case HERO:
newRank = Rank.LEGEND;
break;
case LEGEND:
newRank = Rank.TITAN;
break;
case TITAN:
newRank = Rank.ETERNAL;
break;
default:
break;
}
// A suitable rank could not be found.
if (newRank == null)
{
_player.sendMessage(F.main("Loot", "Since you already have eternal ( You are lucky :) ). So instead you can have " + CONSOLATION_PRICE + " shards."));
_donation.Get(_player).addBalance(GlobalCurrency.TREASURE_SHARD, CONSOLATION_PRICE);
return;
}
client.SetRank(newRank, false);
_clientManager.getRepository().saveRank(null, _player.getName(), _player.getUniqueId(), newRank, true);
}
@Override
public void onDeath()
{
}
}

View File

@ -0,0 +1,42 @@
package mineplex.gemhunters.loot.rewards;
import org.bukkit.inventory.ItemStack;
import mineplex.core.Managers;
import mineplex.core.common.currency.GlobalCurrency;
import mineplex.core.donation.DonationManager;
public class LootShardReward extends LootItemReward
{
private final DonationManager _donation;
private final int _amount;
public LootShardReward(long cashOutDelay, ItemStack itemStack, int amount)
{
super("Shard", cashOutDelay, itemStack);
_donation = Managers.require(DonationManager.class);
_amount = amount;
}
@Override
public void onCollectItem()
{
}
@Override
public void onSuccessful()
{
_donation.rewardCurrencyUntilSuccess(GlobalCurrency.TREASURE_SHARD, _player, "Earned", _amount);
}
@Override
public void onDeath()
{
}
}

View File

@ -0,0 +1,977 @@
package mineplex.gemhunters.map;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Field;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map.Entry;
import org.apache.commons.io.FileUtils;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_8_R3.CraftChunk;
import org.bukkit.craftbukkit.v1_8_R3.CraftWorld;
import org.bukkit.craftbukkit.v1_8_R3.util.LongHash;
import org.bukkit.craftbukkit.v1_8_R3.util.LongObjectHashMap;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.block.Action;
import org.bukkit.event.entity.ItemSpawnEvent;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerItemHeldEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.event.world.ChunkLoadEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.map.MapRenderer;
import org.bukkit.map.MapView;
import com.google.common.collect.HashMultiset;
import com.google.common.collect.Iterables;
import com.google.common.collect.Multisets;
import mineplex.core.MiniPlugin;
import mineplex.core.ReflectivelyCreateMiniPlugin;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilEvent;
import mineplex.core.common.util.UtilEvent.ActionType;
import mineplex.core.common.util.UtilInv;
import mineplex.core.common.util.UtilItem;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTextBottom;
import mineplex.core.common.util.UtilTime;
import mineplex.core.common.util.UtilTime.TimeUnit;
import mineplex.core.itemstack.ItemBuilder;
import mineplex.core.portal.events.ServerTransferEvent;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.gemhunters.death.event.PlayerCustomRespawnEvent;
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.Chunk;
import net.minecraft.server.v1_8_R3.ChunkProviderServer;
import net.minecraft.server.v1_8_R3.ChunkRegionLoader;
import net.minecraft.server.v1_8_R3.IBlockData;
import net.minecraft.server.v1_8_R3.MaterialMapColor;
import net.minecraft.server.v1_8_R3.PersistentCollection;
import net.minecraft.server.v1_8_R3.WorldServer;
/**
* <b>All item map code was adapted from Clans.</b><br>
*/
@ReflectivelyCreateMiniPlugin
public class ItemMapModule extends MiniPlugin
{
// Every BLOCK_SCAN_INTERVAL we add as a new region to scan
private static final int BLOCK_SCAN_INTERVAL = 16 * 3;
// 1536 is the width of the entire world from one borderland to the other
private static final int HALF_WORLD_SIZE = 768;
// 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 Comparator<Entry<Integer, Integer>> _comparator;
private int[][] _heightMap = new int[(HALF_WORLD_SIZE * 2) + 16][];
private HashMap<Integer, Byte[][]> _map = new HashMap<Integer, Byte[][]>();
private short _mapId = -1;
private HashMap<String, MapInfo> _mapInfo = new HashMap<String, MapInfo>();
private HashMap<Integer, Integer> _scale = new HashMap<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 WorldServer _nmsWorld;
private ChunkProviderServer _chunkProviderServer;
private ChunkRegionLoader _chunkRegionLoader;
private ItemMapModule()
{
super("ItemMapManager");
_comparator = (o1, o2) ->
{
// Render the places outside the map first to speed up visual errors fixing
int outsideMap = Boolean.compare(o1.getValue() < -HALF_WORLD_SIZE, o2.getValue() < -HALF_WORLD_SIZE);
if (outsideMap != 0)
{
return -outsideMap;
}
double dist1 = 0;
double dist2 = 0;
for (Player player : UtilServer.getPlayers())
{
dist1 += getDistance(o1, player.getLocation().getX(), player.getLocation().getZ());
dist2 += getDistance(o2, player.getLocation().getX(), player.getLocation().getZ());
}
if (dist1 != dist2)
{
return Double.compare(dist1, dist2);
}
dist1 = getDistance(o1, 0, 0);
dist2 = getDistance(o2, 0, 0);
return Double.compare(dist1, dist2);
};
_scale.put(0, 1);
// _scale.put(1, 2);
_scale.put(1, 4);
_scale.put(2, 8);
_scale.put(3, 13);
// _scale.put(5, 16);
for (Entry<Integer, Integer> entry : _scale.entrySet())
{
int size = (HALF_WORLD_SIZE * 2) / entry.getValue();
Byte[][] bytes = new Byte[size][];
for (int i = 0; i < size; i++)
{
bytes[i] = new Byte[size];
}
_map.put(entry.getKey(), bytes);
}
for (int i = 0; i < _heightMap.length; i++)
{
_heightMap[i] = new int[_heightMap.length];
}
_world = Bukkit.getWorld("world");
try
{
Field chunkLoader = ChunkProviderServer.class.getDeclaredField("chunkLoader");
chunkLoader.setAccessible(true);
_nmsWorld = ((CraftWorld) _world).getHandle();
_chunkProviderServer = _nmsWorld.chunkProviderServer;
_chunkRegionLoader = (ChunkRegionLoader) chunkLoader.get(_chunkProviderServer);
if (_chunkRegionLoader == null)
{
throw new RuntimeException("Did not expect null chunkLoader");
}
}
catch (ReflectiveOperationException e)
{
throw new RuntimeException("Could not reflectively access ChunkRegionLoader", e);
}
try
{
File file = new File("world/gem_hunters_map_id");
File foundFile = null;
for (File f : new File("world/data").listFiles())
{
if (f.getName().startsWith("map_"))
{
foundFile = f;
break;
}
}
if (foundFile == null)
{
PersistentCollection collection = ((CraftWorld) _world).getHandle().worldMaps;
Field f = collection.getClass().getDeclaredField("d");
f.setAccessible(true);
((HashMap) f.get(collection)).put("map", (short) 0);
}
if (file.exists())
{
BufferedReader br = new BufferedReader(new FileReader(file));
_mapId = Short.parseShort(br.readLine());
br.close();
if (foundFile == null)
{
_mapId = -1;
file.delete();
}
else
{
for (int i = _mapId; i <= _mapId + 100; i++)
{
File file1 = new File("world/data/map_" + i + ".dat");
if (!file1.exists())
{
FileUtils.copyFile(foundFile, file1);
}
setupRenderer(Bukkit.getMap((short) i));
}
}
}
if (_mapId < 0)
{
MapView view = Bukkit.createMap(_world);
_mapId = view.getId();
setupRenderer(view);
for (int i = 0; i < 100; i++)
{
setupRenderer(Bukkit.createMap(_world));// Ensures the following 100 maps are unused
}
file.createNewFile();
PrintWriter writer = new PrintWriter(file, "UTF-8");
writer.print(_mapId);
writer.close();
}
}
catch (Exception ex)
{
ex.printStackTrace();
}
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)
{
for (MapRenderer renderer : view.getRenderers())
{
view.removeRenderer(renderer);
}
view.addRenderer(new ItemMapRenderer());
}
/**
* Get the center of the map.
*/
public int calcMapCenter(int zoom, int cord)
{
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 fDiff = mapSize - -mapCord;
int sDiff = mapSize - mapCord;
double chunkBlock = cord & 0xF;
cord -= chunkBlock;
chunkBlock /= zoom;
/*if ((fDiff < 64 || sDiff < 64) && (Math.abs(fDiff - sDiff) > 1))
{
cord += (fDiff > sDiff ? Math.floor(chunkBlock) : Math.ceil(chunkBlock));
}
else*/
{
cord += (int) Math.floor(chunkBlock) * zoom;
}
while ((fDiff < 64 || sDiff < 64) && (Math.abs(fDiff - sDiff) > 1))
{
int change = (fDiff > sDiff ? -zoom : zoom);
cord += change;
mapCord = cord / zoom;
fDiff = mapSize - -mapCord;
sDiff = mapSize - mapCord;
}
return cord;
}
private void colorWorldHeight(int scale, int startingX, int startingZ)
{
Byte[][] map = _map.get(scale);
int zoom = getZoom(scale);
for (int x = startingX; x < startingX + BLOCK_SCAN_INTERVAL; x += zoom)
{
double d0 = 0;
// Prevents ugly lines for the first line of Z
for (int addX = 0; addX < zoom; addX++)
{
for (int addZ = 0; addZ < zoom; addZ++)
{
int hX = x + addX + HALF_WORLD_SIZE;
int hZ = (startingZ - zoom) + addZ + HALF_WORLD_SIZE;
if (hX >= HALF_WORLD_SIZE * 2 || hZ >= HALF_WORLD_SIZE * 2)
{
continue;
}
d0 += _heightMap[hX + 16][hZ + 16] / (zoom * zoom);
}
}
for (int z = startingZ; z < startingZ + BLOCK_SCAN_INTERVAL; z += zoom)
{
// Water depth colors not included
double d1 = 0;
for (int addX = 0; addX < zoom; addX++)
{
for (int addZ = 0; addZ < zoom; addZ++)
{
int hX = x + addX + HALF_WORLD_SIZE;
int hZ = z + addZ + HALF_WORLD_SIZE;
if (hX >= HALF_WORLD_SIZE * 2 || hZ >= HALF_WORLD_SIZE * 2)
{
continue;
}
d1 += _heightMap[hX + 16][hZ + 16] / (zoom * zoom);
}
}
double d2 = (d1 - d0) * 4.0D / (zoom + 4) + ((x + z & 0x1) - 0.5D) * 0.4D;
byte b0 = 1;
d0 = d1;
if (d2 > 0.6D)
{
b0 = 2;
}
else if (d2 > 1.2D)
{
b0 = 3;
}
else if (d2 < -0.6D)
{
b0 = 0;
}
int origColor = map[(x + HALF_WORLD_SIZE) / zoom][(z + HALF_WORLD_SIZE) / zoom] - 1;
/*if (color < 4)
{
d2 = waterDepth * 0.1D + (k1 + j2 & 0x1) * 0.2D;
b0 = 1;
if (d2 < 0.5D)
{
b0 = 2;
}
if (d2 > 0.9D)
{
b0 = 0;
}
}*/
byte color = (byte) (origColor + b0);
if((color <= -113 || color >= 0) && color <= 127)
{
map[(x + HALF_WORLD_SIZE) / zoom][(z + HALF_WORLD_SIZE) / zoom] = color;
}
else
{
// System.out.println(String.format("Tried to set color to %s in colorWorldHeight scale: %s, sx: %s, sz: %s, x: %s, z: %s, zoom: %s",
// color, scale, startingX, startingZ, x, z, zoom));
}
}
}
}
private void drawWorldScale(int scale, int startingX, int startingZ)
{
Byte[][] first = _map.get(0);
Byte[][] second = _map.get(scale);
int zoom = getZoom(scale);
for (int x = startingX; x < startingX + BLOCK_SCAN_INTERVAL; x += zoom)
{
for (int z = startingZ; z < startingZ + BLOCK_SCAN_INTERVAL; z += zoom)
{
HashMultiset<Byte> hashmultiset = HashMultiset.create();
for (int addX = 0; addX < zoom; addX++)
{
for (int addZ = 0; addZ < zoom; addZ++)
{
int pX = x + addX + HALF_WORLD_SIZE;
int pZ = z + addZ + HALF_WORLD_SIZE;
if (pX >= first.length || pZ >= first.length)
{
continue;
}
Byte b = first[pX][pZ];
hashmultiset.add(b);
}
}
Byte color;
try
{
color = Iterables.getFirst(Multisets.copyHighestCountFirst(hashmultiset), (byte) 0);
}
catch (Exception e)
{
color = (byte) 0;
}
second[(x + HALF_WORLD_SIZE) / zoom][(z + HALF_WORLD_SIZE) / zoom] = color;
}
}
}
@EventHandler
public void dropItem(ItemSpawnEvent event)
{
if (isItemClansMap(event.getEntity().getItemStack()))
event.getEntity().remove();
}
public void removeMap(Player player)
{
for (int slot = 0; slot < player.getInventory().getSize(); slot++)
{
if (isItemClansMap(player.getInventory().getItem(slot)))
player.getInventory().setItem(slot, null);
}
}
private double getDistance(double x1, double z1, double x2, double z2)
{
x1 = (x1 - x2);
z1 = (z1 - z2);
return (x1 * x1) + (z1 * z1);
}
private double getDistance(Entry<Integer, Integer> entry, double x1, double z1)
{
return getDistance(x1, z1, entry.getKey() + (BLOCK_SCAN_INTERVAL / 2), entry.getValue() + (BLOCK_SCAN_INTERVAL / 2));
}
public Byte[][] getMap(int scale)
{
return _map.get(scale);
}
public MapInfo getMap(Player player)
{
return _mapInfo.get(player.getName());
}
public int getMapSize()
{
return HALF_WORLD_SIZE;
}
public int getZoom(int scale)
{
return _scale.get(scale);
}
//fixme So what appears to happen is that after you die, if your map is is the same then the map is frozen
@EventHandler
public void onDeath(PlayerDeathEvent event)
{
MapInfo info = getMap(event.getEntity());
info.setMap(Math.min(_mapId + 100, info.getMap() + 1));
}
@EventHandler
public void onHotbarMove(PlayerItemHeldEvent event)
{
Player player = event.getPlayer();
if (!isItemClansMap(player.getInventory().getItem(event.getNewSlot())))
return;
showZoom(player, getMap(player));
}
@EventHandler
public void onInteract(PlayerInteractEvent event)
{
if (event.getAction() == Action.PHYSICAL)
return;
if (!isItemClansMap(event.getItem()))
return;
event.setCancelled(true);
Player player = event.getPlayer();
MapInfo info = getMap(player);
boolean zoomIn = UtilEvent.isAction(event, ActionType.L);
if (!_scale.containsKey(info.getScale() + (zoomIn ? -1 : 1)))
{
return;
}
if (!info.canZoom())
{
long remainingTime = (info.getZoomCooldown() + 2500) - System.currentTimeMillis();
UtilPlayer.message(
player,
F.main("Recharge",
"You cannot use " + F.skill("Map Zoom") + " for "
+ F.time(UtilTime.convertString((remainingTime), 1, TimeUnit.FIT)) + "."));
return;
}
info.addZoom();
if (zoomIn)
{
int newScale = info.getScale() - 1;
Location loc = player.getLocation();
int zoom = getZoom(newScale);
info.setInfo(newScale, calcMapCenter(zoom, loc.getBlockX()), calcMapCenter(zoom, loc.getBlockZ()));
}
else
{
int newScale = info.getScale() + 1;
Location loc = player.getLocation();
int zoom = getZoom(newScale);
info.setInfo(newScale, calcMapCenter(zoom, loc.getBlockX()), calcMapCenter(zoom, loc.getBlockZ()));
}
showZoom(player, info);
}
@EventHandler
public void teleportIn(PlayerCustomRespawnEvent event)
{
MapInfo info = new MapInfo(_mapId);
Player player = event.getPlayer();
Location loc = player.getLocation();
int zoom = getZoom(1);
info.setInfo(1, calcMapCenter(zoom, loc.getBlockX()), calcMapCenter(zoom, loc.getBlockZ()));
_mapInfo.put(player.getName(), info);
setMap(player);
}
@EventHandler
public void onWorldChange(PlayerTeleportEvent event)
{
if (event.getFrom().getWorld() != event.getTo().getWorld() && event.getTo().getWorld().equals("world"))
{
runSyncLater(new Runnable()
{
@Override
public void run()
{
setMap(event.getPlayer());
}
}, 20);
}
}
@EventHandler
public void onQuit(PlayerQuitEvent event)
{
_mapInfo.remove(event.getPlayer().getName());
}
//@EventHandler
public void onServerTransfer(ServerTransferEvent event)
{
Player p = event.getPlayer();
p.sendMessage(C.cDRed + C.Bold + "WARNING!");
p.sendMessage(C.cYellow + "There's a bug where switching servers will freeze the Clans Map!");
p.sendMessage(C.cYellow + "If you want to play on Clans again, rejoin the Mineplex server!");
}
private void rebuildScan()
{
for (int x = -HALF_WORLD_SIZE; x < HALF_WORLD_SIZE; x += BLOCK_SCAN_INTERVAL)
{
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));
}
}
Collections.sort(_scanList, _comparator);
}
@EventHandler
public void recenterMap(UpdateEvent event)
{
if (event.getType() != UpdateType.SEC)
{
return;
}
for (Player player : Bukkit.getOnlinePlayers())
{
MapInfo info = getMap(player);
if (info == null || info.getScale() >= 3)
{
continue;
}
Location l = player.getLocation();
int zoom = getZoom(info.getScale());
double mapX = (l.getX() - info.getX()) / zoom;
double mapZ = (l.getZ() - info.getZ()) / zoom;
if (Math.abs(mapX) > 22 || Math.abs(mapZ) > 22)
{
int newX = calcMapCenter(zoom, l.getBlockX());
int newZ = calcMapCenter(zoom, l.getBlockZ());
if (Math.abs(mapX) > 22 ? newX != info.getX() : newZ != info.getZ())
{
info.setInfo(newX, newZ);
}
}
}
}
@EventHandler
public void renderMap(UpdateEvent event)
{
if (event.getType() != UpdateType.FAST)
return;
if (_scanList.isEmpty() && UtilServer.getPlayers().length > 0)
{
rebuildScan();
}
if (_scanList.size() % 20 == 0)
{
Collections.sort(_scanList, _comparator);
}
if (_scanList.isEmpty())
{
return;
}
Entry<Integer, Integer> entry = _scanList.remove(0);
int startingX = entry.getKey();
int startingZ = entry.getValue();
boolean outsideMap = startingZ < -HALF_WORLD_SIZE;
scanWorldMap(startingX, startingZ, !outsideMap, false);
if (outsideMap)
return;
for (int scale = 1; scale < _scale.size(); scale++)
{
drawWorldScale(scale, startingX, startingZ);
colorWorldHeight(scale, startingX, startingZ);
}
colorWorldHeight(0, startingX, startingZ);
}
// Let's not create hundreds of thousands of BlockPositions
// Single thread = should be thread safe
private BlockPosition.MutableBlockPosition _blockPosition = new BlockPosition.MutableBlockPosition();
// Maps the cached chunks which were loaded from disk to save IO operations
private LongObjectHashMap<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);
for (int beginX = startingX; beginX < startingX + BLOCK_SCAN_INTERVAL; beginX += 16)
{
for (int beginZ = startingZ - (startingZ > -HALF_WORLD_SIZE ? 16 : 0); beginZ < startingZ
+ (setColors ? BLOCK_SCAN_INTERVAL : 16); beginZ += 16)
{
int chunkX = beginX / 16;
int chunkZ = beginZ / 16;
net.minecraft.server.v1_8_R3.Chunk nmsChunk = _chunkProviderServer.getChunkIfLoaded(chunkX, chunkZ);
if (nmsChunk == null)
{
long key = LongHash.toLong(chunkX, chunkZ);
nmsChunk = _chunkCache.get(key);
if (nmsChunk == null)
{
if (!isFirstScan)
{
continue;
}
try
{
Object[] data = _chunkRegionLoader.loadChunk(_nmsWorld, chunkX, chunkZ);
if (data == null)
{
// Something is wrong with the chunk
System.out.println("Chunk is not generated or missing level/block data. Regenerating (" + chunkX + "," + chunkZ + ")");
nmsChunk = ((CraftChunk) _world.getChunkAt(chunkX, chunkZ)).getHandle();
}
else
{
nmsChunk = (net.minecraft.server.v1_8_R3.Chunk) data[0];
}
}
catch (IOException e)
{
throw new RuntimeException("Chunk is corrupt or not readable!", e);
}
_chunkCache.put(key, nmsChunk);
}
}
if (!nmsChunk.isEmpty())
{
for (int x = beginX; x < beginX + 16; x++)
{
for (int z = beginZ; z < beginZ + 16; z++)
{
int color = 0;
int k3 = x & 0xF;
int l3 = z & 0xF;
int l4 = nmsChunk.b(k3, l3) + 1;
IBlockData iblockdata = Blocks.AIR.getBlockData();
if (l4 > 1)
{
do
{
l4--;
_blockPosition.c(k3, l4, l3);
iblockdata = nmsChunk.getBlockData(_blockPosition);
}
while (iblockdata.getBlock().g(iblockdata) == MaterialMapColor.b && (l4 > 0));
if ((l4 > 0) && (iblockdata.getBlock().getMaterial().isLiquid()))
{
int j5 = l4 - 1;
Block block1;
do
{
_blockPosition.c(k3, j5--, l3);
block1 = nmsChunk.getType(_blockPosition);
}
while ((j5 > 0) && (block1.getMaterial().isLiquid()));
}
}
_heightMap[x + HALF_WORLD_SIZE + 16][z + HALF_WORLD_SIZE + 16] = l4;
if (setColors)
{
//color = block.f(i5).M;
_blockPosition.c(k3, l4, l3);
IBlockData data = nmsChunk.getBlockData(_blockPosition);
color = data.getBlock().g(data).M;
color = (byte) ((color * 4) + 1);
}
if (setColors && beginZ >= startingZ)
{
map[x + HALF_WORLD_SIZE][z + HALF_WORLD_SIZE] = (byte) color;
}
}
}
}
}
}
}
public void setMap(Player player)
{
for (ItemStack item : UtilInv.getItems(player))
{
if (isItemClansMap(item))
{
return;
}
}
ItemStack item = new ItemBuilder(Material.MAP, 1, (short) getMap(player).getMap()).setTitle(C.cGreen + "World Map").build();
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)
{
player.getInventory().setItem(slot, item);
}
}
/*
* Displays the action bar to a player given their zoom level. Implementation may change
*/
private void showZoom(Player player, MapInfo info)
{
UtilTextBottom.display(ZOOM_INFO[info.getScale()], player);
}
/*
* Check whether an {@link ItemStack} is also a Clans Map
*
* @param itemStack The {@link ItemStack} to check
* @returns Whether the {@link ItemStack} is also a Clans Map
*/
private boolean isItemClansMap(ItemStack itemStack)
{
return UtilItem.matchesMaterial(itemStack, Material.MAP)
&& itemStack.getDurability() >= _mapId
&& itemStack.getDurability() <= _mapId + 100;
}
}

View File

@ -0,0 +1,294 @@
package mineplex.gemhunters.map;
import java.awt.Color;
import java.util.Set;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.map.MapCanvas;
import org.bukkit.map.MapCursor;
import org.bukkit.map.MapCursorCollection;
import org.bukkit.map.MapPalette;
import org.bukkit.map.MapRenderer;
import org.bukkit.map.MapView;
import mineplex.core.Managers;
import mineplex.core.common.util.UtilTime;
import mineplex.core.party.Party;
import mineplex.core.party.PartyManager;
import mineplex.gemhunters.loot.LootModule;
import mineplex.gemhunters.safezone.SafezoneModule;
import mineplex.gemhunters.supplydrop.SupplyDrop;
import mineplex.gemhunters.supplydrop.SupplyDropModule;
import mineplex.gemhunters.worldevent.WorldEvent;
import mineplex.gemhunters.worldevent.WorldEventModule;
/**
* <b>All item map code was adapted from Clans.</b><br>
*/
public class ItemMapRenderer extends MapRenderer
{
private static final int RENDER_COOLDOWN = 10000;
private static final int STANDARD_Y = 70;
private final ItemMapModule _itemMap;
private final LootModule _loot;
private final SafezoneModule _safezone;
private final SupplyDropModule _supply;
private final WorldEventModule _worldEvent;
private final PartyManager _party;
public ItemMapRenderer()
{
super(true);
_itemMap = Managers.require(ItemMapModule.class);
_loot = Managers.require(LootModule.class);
_safezone = Managers.require(SafezoneModule.class);
_supply = Managers.require(SupplyDropModule.class);
_worldEvent = Managers.require(WorldEventModule.class);
_party = Managers.require(PartyManager.class);
}
@Override
public void render(MapView mapView, MapCanvas canvas, Player player)
{
try
{
renderNormalMap(mapView, canvas, player);
}
catch (Throwable t)
{
System.out.println("Error while rendering map");
t.printStackTrace();
}
}
private void renderNormalMap(MapView mapView, MapCanvas canvas, Player player)
{
MapInfo info = _itemMap.getMap(player);
if (info == null)
{
return;
}
int scale = info.getScale();
int zoom = _itemMap.getZoom(scale);
Byte[][] map = _itemMap.getMap(scale);
int centerX = info.getX() / zoom;
int centerZ = info.getZ() / zoom;
// We have this cooldown to squeeze out every single bit of performance
// from the server.
if (UtilTime.elapsed(info.getLastRendered(), RENDER_COOLDOWN))
{
info.setLastRendered();
for (int mapX = 0; mapX < 128; mapX++)
{
for (int mapZ = 0; mapZ < 128; mapZ++)
{
int blockX = centerX + (mapX - 64);
int blockZ = centerZ + (mapZ - 64);
int pixelX = blockX + (map.length / 2);
int pixelZ = blockZ + (map.length / 2);
Byte color;
if (!(pixelX < 0 || pixelZ < 0 || pixelX >= map.length || pixelZ >= map.length) && map[pixelX][pixelZ] != null)
{
color = map[pixelX][pixelZ];
blockX *= zoom;
blockZ *= zoom;
Location location = new Location(mapView.getWorld(), blockX, STANDARD_Y, blockZ);
boolean safezone = _safezone.isInSafeZone(location);
if (safezone)
{
boolean colorAll = scale > 0;
Color areaColor = Color.GREEN;
if (areaColor != null)
{
if (!((color <= -113 || color >= 0) && color <= 127))
{
color = (byte) 0;
System.out.println(String.format("Tried to draw invalid color %s, player: %s, mapX: %s, mapZ: %s", color, player.getName(), mapX, mapZ));
}
else
{
// int chunkBX = blockX & 0xF;
// int chunkBZ = blockZ & 0xF;
// Border
if (
_safezone.isInSafeZone(new Location(mapView.getWorld(), blockX - 1, STANDARD_Y, blockZ)) ||
_safezone.isInSafeZone(new Location(mapView.getWorld(), blockX, STANDARD_Y, blockZ - 1)) ||
_safezone.isInSafeZone(new Location(mapView.getWorld(), blockX + 16, STANDARD_Y, blockZ)) ||
_safezone.isInSafeZone(new Location(mapView.getWorld(), blockX, STANDARD_Y, blockZ + 1)))
{
Color cColor = MapPalette.getColor(color);
double clans = colorAll ? 1 : 0.8;
double base = 1 - clans;
int r = (int) ((cColor.getRed() * base) + (areaColor.getRed() * clans));
int b = (int) ((cColor.getBlue() * base) + (areaColor.getBlue() * clans));
int g = (int) ((cColor.getGreen() * base) + (areaColor.getGreen() * clans));
color = MapPalette.matchColor(r, g, b);
}
// Inside
else
{
Color cColor = MapPalette.getColor(color);
double clans = 0.065;
// Stripes
//boolean checker = (mapX + (mapZ % 4)) % 4 == 0;
double base = 1 - clans;
int r = (int) ((cColor.getRed() * base) + (areaColor.getRed() * clans));
int b = (int) ((cColor.getBlue() * base) + (areaColor.getBlue() * clans));
int g = (int) ((cColor.getGreen() * base) + (areaColor.getGreen() * clans));
color = MapPalette.matchColor(r, g, b);
}
}
}
}
}
else
{
color = (byte) 0;
}
canvas.setPixel(mapX, mapZ, color);
}
}
}
if (info.isSendMap())
{
player.sendMap(mapView);
}
MapCursorCollection cursors = canvas.getCursors();
while (cursors.size() > 0)
{
cursors.removeCursor(cursors.getCursor(0));
}
for (WorldEvent event : _worldEvent.getActiveEvents())
{
if (!event.isInProgress())
{
continue;
}
Location point = event.getCurrentLocation();
double mapX = (point.getX() - info.getX()) / zoom;
double mapZ = (point.getZ() - info.getZ()) / zoom;
// To make these appear at the edges of the map, just change it from
// 64 to something like 128 for double the map size
if (mapX > -64 && mapX < 64 && mapZ > -64 && mapZ < 64)
{
byte b0 = (byte) (int) Math.min(127, (double) (mapX * 2.0F) + 0.5D);
byte b1 = (byte) (int) Math.max(-127, (double) (mapZ * 2.0F) + 0.5D);
byte cursorType = 5; // http://i.imgur.com/wpH6PT8.png
// Those are byte 5 and 6
byte rotation = (byte) (int) ((point.getYaw() * 16D) / 360D);
MapCursor cursor = new MapCursor(b0, b1, rotation, cursorType, true);
cursors.addCursor(cursor);
}
}
SupplyDrop supplyDrop = _supply.getActive();
if (_supply.isActive())
{
Location point = supplyDrop.getCurrentLocation();
double mapX = (point.getX() - info.getX()) / zoom;
double mapZ = (point.getZ() - info.getZ()) / zoom;
// To make these appear at the edges of the map, just change it from
// 64 to something like 128 for double the map size
if (mapX > -64 && mapX < 64 && mapZ > -64 && mapZ < 64)
{
byte b0 = (byte) (int) Math.min(127, (double) (mapX * 2.0F) + 0.5D);
byte b1 = (byte) (int) Math.max(-127, (double) (mapZ * 2.0F) + 0.5D);
byte cursorType = 4; // http://i.imgur.com/wpH6PT8.png
// Those are byte 5 and 6
byte rotation = (byte) ((int) Math.floor(System.currentTimeMillis() / 1000D) % 16);
MapCursor cursor = new MapCursor(b0, b1, rotation, cursorType, true);
cursors.addCursor(cursor);
}
}
Party party = _party.getPartyByPlayer(player);
Set<UUID> shownPlayers = _loot.getShownPlayers();
for (Player other : Bukkit.getOnlinePlayers())
{
if (player.canSee(other) && other.isValid())
{
Location l = other.getLocation();
double mapX = (l.getX() - info.getX()) / zoom;
double mapZ = (l.getZ() - info.getZ()) / zoom;
if (mapX > -64 && mapX < 64 && mapZ > -64 && mapZ < 64)
{
MapCursor.Type cursorDisplay = null;
if (player.equals(other))
{
cursorDisplay = MapCursor.Type.WHITE_POINTER;
}
else if (shownPlayers.contains(other.getUniqueId()))
{
cursorDisplay = MapCursor.Type.BLUE_POINTER;
}
else if (party != null && party.isMember(other))
{
cursorDisplay = MapCursor.Type.GREEN_POINTER;
}
if (cursorDisplay == null)
{
continue;
}
byte b0 = (byte) (int) Math.min(127, (double) (mapX * 2.0F) + 0.5D);
byte b1 = (byte) (int) Math.max(-127, (double) (mapZ * 2.0F) + 0.5D);
byte rotation = (byte) (int) ((l.getYaw() * 16D) / 360D);
MapCursor cursor = new MapCursor(b0, b1, (byte) (rotation & 0xF), cursorDisplay.getValue(), true);
cursors.addCursor(cursor);
}
}
}
}
}

View File

@ -0,0 +1,124 @@
package mineplex.gemhunters.map;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import mineplex.core.common.util.UtilTime;
public class MapInfo
{
private int _scale;
private int _centerX;
private int _centerZ;
private long _lastRendered;
private boolean _sendMap;
private List<Long> _lastZooms = new ArrayList<Long>();
private int _mapId;
public MapInfo(int newId)
{
_mapId = newId;
}
public int getMap()
{
return _mapId;
}
public void setMap(int newId)
{
_mapId = newId;
}
public boolean canZoom()
{
Iterator<Long> itel = _lastZooms.iterator();
while (itel.hasNext())
{
long lastZoomed = itel.next();
if (UtilTime.elapsed(lastZoomed, 2500))
{
itel.remove();
}
}
return _lastZooms.size() < 3;
}
public void addZoom()
{
_lastZooms.add(System.currentTimeMillis());
}
public long getZoomCooldown()
{
long cooldown = 0;
for (long zoomCooldown : _lastZooms)
{
if (cooldown == 0 || zoomCooldown < cooldown)
{
cooldown = zoomCooldown;
}
}
return cooldown;
}
public long getLastRendered()
{
return _lastRendered;
}
public void setLastRendered()
{
_lastRendered = System.currentTimeMillis();
}
public void setInfo(int scale, int x, int z)
{
_lastRendered = 0;
_scale = scale;
_centerX = x;
_centerZ = z;
_sendMap = true;
}
public void setInfo(int x, int z)
{
_lastRendered = 0;
_centerX = x;
_centerZ = z;
_sendMap = true;
}
public boolean isSendMap()
{
if (_sendMap)
{
_sendMap = false;
return true;
}
return false;
}
public int getX()
{
return _centerX;
}
public int getZ()
{
return _centerZ;
}
public int getScale()
{
return _scale;
}
}

View File

@ -0,0 +1,37 @@
package mineplex.gemhunters.mount;
import org.bukkit.entity.LivingEntity;
import mineplex.core.gadget.gadgets.gamemodifiers.gemhunters.MountType;
public class MountData
{
private MountType _mountType;
private LivingEntity _entity;
public MountData()
{
}
public void setMountType(MountType mountType)
{
_mountType = mountType;
}
public MountType getMountType()
{
return _mountType;
}
public void setEntity(LivingEntity entity)
{
_entity = entity;
}
public LivingEntity getEntity()
{
return _entity;
}
}

View File

@ -0,0 +1,157 @@
package mineplex.gemhunters.mount;
import java.util.UUID;
import org.bukkit.Material;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Horse;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Tameable;
import org.bukkit.entity.Horse.Color;
import org.bukkit.entity.Horse.Style;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;
import mineplex.core.MiniClientPlugin;
import mineplex.core.ReflectivelyCreateMiniPlugin;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilEvent;
import mineplex.core.common.util.UtilEvent.ActionType;
import mineplex.core.gadget.GadgetManager;
import mineplex.core.gadget.gadgets.gamemodifiers.GameModifierType;
import mineplex.core.gadget.gadgets.gamemodifiers.gemhunters.GameModifierMount;
import mineplex.core.gadget.gadgets.gamemodifiers.gemhunters.MountType;
import mineplex.core.recharge.Recharge;
import mineplex.gemhunters.loot.LootItem;
import mineplex.gemhunters.loot.LootModule;
@ReflectivelyCreateMiniPlugin
public class MountModule extends MiniClientPlugin<MountData>
{
private static final String ITEM_METADATA = "MOUNT";
private final LootModule _loot;
private final GadgetManager _gadget;
private MountModule()
{
super("Mount");
_loot = require(LootModule.class);
_gadget = require(GadgetManager.class);
}
@Override
protected MountData addPlayer(UUID uuid)
{
return new MountData();
}
@EventHandler
public void playerInteract(PlayerInteractEvent event)
{
if (!UtilEvent.isAction(event, ActionType.R))
{
return;
}
Player player = event.getPlayer();
ItemStack itemStack = player.getItemInHand();
if (itemStack == null)
{
return;
}
LootItem lootItem = _loot.fromItemStack(itemStack);
if (lootItem == null || lootItem.getMetadata() == null || !lootItem.getMetadata().startsWith(ITEM_METADATA))
{
return;
}
int cooldown = Integer.parseInt(lootItem.getMetadata().split(" ")[1]) * 1000;
if (!Recharge.Instance.use(player, _moduleName, cooldown, true, true))
{
return;
}
spawnMount(player);
}
public void spawnMount(Player player)
{
GameModifierMount mount = ((GameModifierMount) _gadget.getActiveGameModifier(player, GameModifierType.GemHunters, g -> g != null));
MountType mountType = null;
if (mount != null)
{
mountType = mount.getMountType();
}
player.sendMessage(F.main(_moduleName, "Mounts are currently disabled."));
//spawnMount(player, mountType);
}
public void spawnMount(Player player, MountType mountType)
{
MountData data = Get(player);
LivingEntity entity = data.getEntity();
EntityType entityType = mountType == null ? EntityType.HORSE : mountType.getEntityType();
despawnMount(player);
entity = (LivingEntity) player.getWorld().spawnEntity(player.getLocation().add(0, 1, 0), entityType);
if (entity instanceof Tameable)
{
Tameable tameable = (Tameable) entity;
tameable.setOwner(player);
}
if (entity instanceof Horse)
{
Horse horse = (Horse) entity;
horse.setAdult();
horse.setAgeLock(true);
horse.setColor(Color.BROWN);
horse.setStyle(Style.NONE);
horse.setMaxDomestication(1);
horse.setJumpStrength(1);
horse.getInventory().setSaddle(new ItemStack(Material.SADDLE));
}
entity.setCustomName(player.getName() + "\'s Mount");
entity.setCustomNameVisible(true);
entity.setCanPickupItems(false);
entity.setHealth(1);
entity.setMaxHealth(1);
entity.setPassenger(player);
data.setEntity(entity);
data.setMountType(mountType);
}
public void despawnMount(Player player)
{
MountData data = Get(player);
LivingEntity entity = data.getEntity();
if (entity != null)
{
entity.remove();
}
}
public boolean isActive(Player player)
{
return Get(player).getEntity() != null;
}
}

View File

@ -0,0 +1,6 @@
package mineplex.gemhunters.mount.event;
public class MountSpawnEvent
{
}

View File

@ -0,0 +1,146 @@
package mineplex.gemhunters.quest;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerQuitEvent;
import mineplex.core.Managers;
import mineplex.core.account.CoreClientManager;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilServer;
import mineplex.core.donation.DonationManager;
import mineplex.gemhunters.economy.EconomyModule;
import mineplex.gemhunters.world.WorldDataModule;
public abstract class Quest implements Listener
{
private final int _id;
private final String _name;
private final String _description;
private final int _startCost;
private final int _completeReward;
protected final QuestModule _quest;
protected final CoreClientManager _clientManager;
protected final DonationManager _donation;
protected final EconomyModule _economy;
protected final WorldDataModule _worldData;
private final Map<UUID, Integer> _counter;
public Quest(int id, String name, String description, int startCost, int completeReward)
{
_id = id;
_name = name;
_description = description;
_startCost = startCost;
_completeReward = completeReward;
_quest = Managers.require(QuestModule.class);
_clientManager = Managers.require(CoreClientManager.class);
_donation = Managers.require(DonationManager.class);
_economy = Managers.require(EconomyModule.class);
_worldData = Managers.require(WorldDataModule.class);
_counter = new HashMap<>();
UtilServer.getServer().getPluginManager().registerEvents(this, UtilServer.getPlugin());
}
@EventHandler
public void playerQuit(PlayerQuitEvent event)
{
remove(event.getPlayer());
}
public void transfer(Player from, Player to)
{
// If the player has already been progressing this quest and is
// further than the other don't bother transferring their data.
if (get(to) >= get(from))
{
return;
}
set(to, get(from));
}
public void set(Player player, int amount)
{
_counter.put(player.getUniqueId(), amount);
}
public int get(Player player)
{
return _counter.getOrDefault(player.getUniqueId(), 0);
}
public int getAndIncrement(Player player, int amount)
{
int newAmount = get(player) + amount;
_counter.put(player.getUniqueId(), newAmount);
_quest.updateQuestItem(this, player);
return newAmount;
}
public void remove(Player player)
{
_counter.remove(player.getUniqueId());
}
public void onStart(Player player)
{
_economy.removeFromStore(player, _startCost);
}
public void onReward(Player player)
{
_economy.addToStore(player, "Completing " + F.elem(_name), _completeReward);
remove(player);
_quest.completeQuest(this, player);
}
public boolean isActive(Player player)
{
return _quest.isActive(this, player);
}
public abstract float getProgress(Player player);
public int getGoal()
{
return 1;
}
public final int getId()
{
return _id;
}
public final String getName()
{
return _name;
}
public final String getDescription()
{
return _description;
}
public final int getStartCost()
{
return _startCost;
}
public final int getCompleteReward()
{
return _completeReward;
}
}

View File

@ -0,0 +1,406 @@
package mineplex.gemhunters.quest;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Item;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerPickupItemEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.metadata.FixedMetadataValue;
import mineplex.core.MiniClientPlugin;
import mineplex.core.ReflectivelyCreateMiniPlugin;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilItem;
import mineplex.core.common.util.UtilItem.ItemAttribute;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilTextMiddle;
import mineplex.core.common.util.UtilTime;
import mineplex.core.itemstack.ItemBuilder;
import mineplex.core.menu.Menu;
import mineplex.core.recharge.Recharge;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.gemhunters.quest.types.ChestOpenerQuest;
import mineplex.gemhunters.quest.types.SamitoDQuest;
import mineplex.gemhunters.world.WorldDataModule;
import net.md_5.bungee.api.ChatColor;
@ReflectivelyCreateMiniPlugin
public class QuestModule extends MiniClientPlugin<QuestPlayerData>
{
private static final int MAX_QUESTS = 5;
private static final long RESET_QUESTS_TIME = TimeUnit.MINUTES.toMillis(15);
private static final Material MATERIAL = Material.PAPER;
private static final String ITEM_METADATA = "quest";
private final Quest[] _quests = {
new ChestOpenerQuest(0, "Chest Opener", 100, 250, 5),
new ChestOpenerQuest(1, "Grand Chest Opener", 200, 500, 20),
new ChestOpenerQuest(2, "Superior Chest Opener", 500, 750, 40),
new SamitoDQuest(3, "Give to the Homeless", "Donate " + F.count(String.valueOf(10)) + " gems to the Hobo.", 100, 300, 10)
};
private final WorldDataModule _worldData;
private QuestModule()
{
super("Quest");
_worldData = require(WorldDataModule.class);
Menu<?> menu = new QuestUI(this);
runSyncLater(() ->
{
for (Location location : _worldData.getCustomLocation("QUEST_NPC"))
{
new QuestNPC(this, location, menu);
}
}, 20);
}
@Override
protected QuestPlayerData addPlayer(UUID uuid)
{
return new QuestPlayerData();
}
@EventHandler
public void playerJoin(PlayerJoinEvent event)
{
updateQuests(event.getPlayer());
}
//@EventHandler
public void update(UpdateEvent event)
{
if (event.getType() != UpdateType.SLOW)
{
return;
}
for (Player player : Bukkit.getOnlinePlayers())
{
QuestPlayerData playerData = Get(player);
if (!UtilTime.elapsed(playerData.getLastClear(), RESET_QUESTS_TIME))
{
continue;
}
player.sendMessage(F.main(C.cYellowB + "Quest Master", "I have " + F.count(String.valueOf(MAX_QUESTS)) + " new quests for you! Come and see me to start them!"));
playerData.clear();
updateQuests(player);
}
}
@EventHandler
public void pickupItem(PlayerPickupItemEvent event)
{
if (event.isCancelled())
{
return;
}
Item item = event.getItem();
Player player = event.getPlayer();
Quest quest = fromItemStack(event.getItem().getItemStack());
if (quest == null)
{
return;
}
if (!item.hasMetadata(ITEM_METADATA))
{
return;
}
if (!Recharge.Instance.use(event.getPlayer(), "Quest Pickup " + quest.getId(), 2000, false, false))
{
event.setCancelled(true);
return;
}
boolean able = startQuest(quest, player);
if (!able)
{
event.setCancelled(true);
}
else
{
UUID owner = UUID.fromString(item.getMetadata(ITEM_METADATA).get(0).asString());
Player other = UtilPlayer.searchExact(owner);
/*
* Noting here that when a player leaves their quest progress is removed.
* However that means that if a new player picks up their quest item we
* run into a problem where that will be null. Thus the progress on that
* quest is lost.
* More complications are added when a player quits out and their NPC is
* there instead until they finally really really quit out.
* This is one massive headache in order to keep quests alive while not
* running into some serious memory leaks.
* Furthermore the time complications of this project mean that there isn't
* enough time right now to implement this (however a enough time for me
* to type this lengthy comment about it). So in true style I'm cutting
* corners and saying that if a player quits out then don't allow other
* players to be able to pickup the quest.
*/
if (other == null)
{
event.setCancelled(true);
return;
}
}
}
@EventHandler
public void dropItem(PlayerDropItemEvent event)
{
if (event.isCancelled())
{
return;
}
Player player = event.getPlayer();
Quest quest = fromItemStack(event.getItemDrop().getItemStack());
if (quest == null)
{
return;
}
cancelQuest(quest, player);
handleDroppedQuest(event.getItemDrop(), player);
}
public void handleDroppedQuest(Item item, Player player)
{
item.setMetadata(ITEM_METADATA, new FixedMetadataValue(_plugin, player.getUniqueId().toString()));
}
public void updateQuests(Player player)
{
QuestPlayerData playerData = Get(player);
List<Integer> quests = playerData.getPossibleQuests();
for (int i = 0; i < MAX_QUESTS; i++)
{
Quest quest = getRandomQuest(playerData, player);
if (quest == null)
{
player.sendMessage(F.main(_moduleName, "It seems that there was some trouble finding you a new quest. Please try again later."));
return;
}
quests.add(quest.getId());
}
}
public boolean startQuest(Quest quest, Player player)
{
if (isActive(quest, player))
{
player.sendMessage(F.main(_moduleName, "You have already accepted that quest."));
return false;
}
else if (isComplete(quest, player))
{
player.sendMessage(F.main(_moduleName, "You have already completed that quest."));
return false;
}
player.sendMessage(F.main(_moduleName, "Started " + F.name(quest.getName()) + "."));
QuestPlayerData playerData = Get(player);
playerData.getActiveQuests().add(quest.getId());
updateQuestItem(quest, player);
return true;
}
public void completeQuest(Quest quest, Player player)
{
if (!isActive(quest, player))
{
player.sendMessage(F.main(_moduleName, "This quest is not active for you."));
return;
}
player.sendMessage(F.main(_moduleName, "Completed " + F.name(quest.getName()) + "."));
QuestPlayerData playerData = Get(player);
playerData.getActiveQuests().remove(Integer.valueOf(quest.getId()));
playerData.getCompletedQuests().add(quest.getId());
updateQuestItem(quest, player);
}
public void cancelQuest(Quest quest, Player player)
{
if (!isActive(quest, player))
{
player.sendMessage(F.main(_moduleName, "This quest is not active for you."));
return;
}
player.sendMessage(F.main(_moduleName, "Dropped " + F.name(quest.getName()) + "."));
QuestPlayerData playerData = Get(player);
playerData.getActiveQuests().remove(Integer.valueOf(quest.getId()));
}
public Quest getRandomQuest(QuestPlayerData playerData, Player player)
{
int attempts = 0;
while (attempts < _quests.length * 2)
{
attempts++;
int index = UtilMath.r(_quests.length);
Quest quest = _quests[index];
if (isActive(quest, player) || isPossible(quest, player))
{
continue;
}
return quest;
}
return null;
}
public ItemStack getItemStack(Quest quest, Player player, boolean npc, boolean hasSpace)
{
ItemBuilder builder = new ItemBuilder(MATERIAL);
builder.setTitle(C.cGreen + quest.getName());
builder.addLore(C.blankLine, quest.getDescription(), C.blankLine);
boolean active = isActive(quest, player);
boolean complete = isComplete(quest, player);
if (npc)
{
if (active)
{
builder.setGlow(true);
builder.addLore(C.cRed + "You have already started this quest!");
}
else if (complete)
{
builder.addLore(C.cRed + "You have already completed this quest!");
}
else if (hasSpace)
{
builder.addLore(C.cGreen + "Click to start this quest!");
}
else
{
builder.addLore(C.cRed + "You do not have enough space in your inventory!");
}
}
else
{
builder.addLore(UtilTextMiddle.progress(quest.getProgress(player)) + C.mBody + " [" + C.cGreen + quest.get(player) + C.mBody + "/" + C.cGreen + quest.getGoal() + C.mBody + "]");
}
return builder.build();
}
public Quest fromItemStack(ItemStack itemStack)
{
Material material = itemStack.getType();
ItemMeta meta = itemStack.getItemMeta();
if (material != MATERIAL || meta == null || !meta.hasLore())
{
return null;
}
String name = ChatColor.stripColor(meta.getDisplayName());
for (Quest quest : _quests)
{
if (!quest.getName().equals(name))
{
continue;
}
return quest;
}
return null;
}
public void updateQuestItem(Quest quest, Player player)
{
ItemStack itemStack = getItemStack(quest, player, false, true);
for (ItemStack items : player.getInventory().getContents())
{
if (UtilItem.isSimilar(itemStack, items, ItemAttribute.MATERIAL, ItemAttribute.NAME, ItemAttribute.DATA))
{
player.getInventory().remove(items);
}
}
if (isActive(quest, player))
{
player.getInventory().addItem(itemStack);
}
}
public boolean isPossible(Quest quest, Player player)
{
return Get(player).getPossibleQuests().contains(quest.getId());
}
public boolean isActive(Quest quest, Player player)
{
return Get(player).getActiveQuests().contains(quest.getId());
}
public boolean isComplete(Quest quest, Player player)
{
return Get(player).getCompletedQuests().contains(quest.getId());
}
public Quest getFromId(int id)
{
for (Quest quest : _quests)
{
if (quest.getId() == id)
{
return quest;
}
}
return null;
}
}

View File

@ -0,0 +1,45 @@
package mineplex.gemhunters.quest;
import org.bukkit.Location;
import org.bukkit.entity.Villager;
import org.bukkit.entity.Villager.Profession;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.menu.Menu;
import mineplex.gemhunters.util.SimpleNPC;
public class QuestNPC extends SimpleNPC
{
private Menu<?> _questMenu;
public QuestNPC(QuestModule quest, Location spawn, Menu<?> menu)
{
super(quest.getPlugin(), spawn, Villager.class, C.cYellowB + "Quest Master", null);
_questMenu = menu;
Villager villager = (Villager) _entity;
villager.setProfession(Profession.LIBRARIAN);
}
@Override
@EventHandler
public void npcClick(PlayerInteractEntityEvent event)
{
if (!event.getRightClicked().equals(_entity))
{
return;
}
event.setCancelled(true);
event.getPlayer().sendMessage(F.main("Quest", "The Quest Master is currently disabled but will be avaiable to all players shortly."));
//_questMenu.open(event.getPlayer());/
}
}

Some files were not shown because too many files have changed in this diff Show More